xref: /freebsd/sys/dev/bxe/bxe_stats.c (revision 685dc743dc3b5645e34836464128e1c0558b404b)
14e400768SDavid Christensen /*-
27282444bSPedro F. Giffuni  * SPDX-License-Identifier: BSD-2-Clause
37282444bSPedro F. Giffuni  *
4e36ffbddSDavid C Somayajulu  * Copyright (c) 2007-2014 QLogic Corporation. All rights reserved.
54e400768SDavid Christensen  *
64e400768SDavid Christensen  * Redistribution and use in source and binary forms, with or without
74e400768SDavid Christensen  * modification, are permitted provided that the following conditions
84e400768SDavid Christensen  * are met:
94e400768SDavid Christensen  *
104e400768SDavid Christensen  * 1. Redistributions of source code must retain the above copyright
114e400768SDavid Christensen  *    notice, this list of conditions and the following disclaimer.
124e400768SDavid Christensen  * 2. Redistributions in binary form must reproduce the above copyright
134e400768SDavid Christensen  *    notice, this list of conditions and the following disclaimer in the
144e400768SDavid Christensen  *    documentation and/or other materials provided with the distribution.
154e400768SDavid Christensen  *
164e400768SDavid Christensen  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS'
174e400768SDavid Christensen  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
184e400768SDavid Christensen  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
194e400768SDavid Christensen  * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
204e400768SDavid Christensen  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
214e400768SDavid Christensen  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
224e400768SDavid Christensen  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
234e400768SDavid Christensen  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
244e400768SDavid Christensen  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
254e400768SDavid Christensen  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
264e400768SDavid Christensen  * THE POSSIBILITY OF SUCH DAMAGE.
274e400768SDavid Christensen  */
284e400768SDavid Christensen 
294e400768SDavid Christensen #include <sys/cdefs.h>
304e400768SDavid Christensen #include "bxe.h"
314e400768SDavid Christensen #include "bxe_stats.h"
324e400768SDavid Christensen 
334e400768SDavid Christensen #ifdef __i386__
344e400768SDavid Christensen #define BITS_PER_LONG 32
354e400768SDavid Christensen #else
364e400768SDavid Christensen #define BITS_PER_LONG 64
374e400768SDavid Christensen #endif
384e400768SDavid Christensen 
397a1297c8SDavid C Somayajulu 
404e400768SDavid Christensen static inline long
bxe_hilo(uint32_t * hiref)414e400768SDavid Christensen bxe_hilo(uint32_t *hiref)
424e400768SDavid Christensen {
434e400768SDavid Christensen     uint32_t lo = *(hiref + 1);
444e400768SDavid Christensen #if (BITS_PER_LONG == 64)
454e400768SDavid Christensen     uint32_t hi = *hiref;
464e400768SDavid Christensen     return (HILO_U64(hi, lo));
474e400768SDavid Christensen #else
484e400768SDavid Christensen     return (lo);
494e400768SDavid Christensen #endif
504e400768SDavid Christensen }
514e400768SDavid Christensen 
524e400768SDavid Christensen static inline uint16_t
bxe_get_port_stats_dma_len(struct bxe_softc * sc)534e400768SDavid Christensen bxe_get_port_stats_dma_len(struct bxe_softc *sc)
544e400768SDavid Christensen {
554e400768SDavid Christensen     uint16_t res = 0;
564e400768SDavid Christensen     uint32_t size;
574e400768SDavid Christensen 
584e400768SDavid Christensen     /* 'newest' convention - shmem2 contains the size of the port stats */
594e400768SDavid Christensen     if (SHMEM2_HAS(sc, sizeof_port_stats)) {
604e400768SDavid Christensen         size = SHMEM2_RD(sc, sizeof_port_stats);
614e400768SDavid Christensen         if (size) {
624e400768SDavid Christensen             res = size;
634e400768SDavid Christensen         }
644e400768SDavid Christensen 
654e400768SDavid Christensen         /* prevent newer BC from causing buffer overflow */
664e400768SDavid Christensen         if (res > sizeof(struct host_port_stats)) {
674e400768SDavid Christensen             res = sizeof(struct host_port_stats);
684e400768SDavid Christensen         }
694e400768SDavid Christensen     }
704e400768SDavid Christensen 
714e400768SDavid Christensen     /*
724e400768SDavid Christensen      * Older convention - all BCs support the port stats fields up until
734e400768SDavid Christensen      * the 'not_used' field
744e400768SDavid Christensen      */
754e400768SDavid Christensen     if (!res) {
764e400768SDavid Christensen         res = (offsetof(struct host_port_stats, not_used) + 4);
774e400768SDavid Christensen 
784e400768SDavid Christensen         /* if PFC stats are supported by the MFW, DMA them as well */
794e400768SDavid Christensen         if (sc->devinfo.bc_ver >= REQ_BC_VER_4_PFC_STATS_SUPPORTED) {
804e400768SDavid Christensen             res += (offsetof(struct host_port_stats, pfc_frames_rx_lo) -
814e400768SDavid Christensen                     offsetof(struct host_port_stats, pfc_frames_tx_hi) + 4);
824e400768SDavid Christensen         }
834e400768SDavid Christensen     }
844e400768SDavid Christensen 
854e400768SDavid Christensen     res >>= 2;
864e400768SDavid Christensen 
874e400768SDavid Christensen     DBASSERT(sc, !(res > 2 * DMAE_LEN32_RD_MAX), ("big stats dmae length\n"));
884e400768SDavid Christensen     return (res);
894e400768SDavid Christensen }
904e400768SDavid Christensen 
914e400768SDavid Christensen /*
924e400768SDavid Christensen  * Init service functions
934e400768SDavid Christensen  */
944e400768SDavid Christensen 
954e400768SDavid Christensen static void
bxe_dp_stats(struct bxe_softc * sc)964e400768SDavid Christensen bxe_dp_stats(struct bxe_softc *sc)
974e400768SDavid Christensen {
984e400768SDavid Christensen     int i;
994e400768SDavid Christensen 
1004e400768SDavid Christensen     BLOGD(sc, DBG_STATS,
1014e400768SDavid Christensen           "dumping stats:\n"
1024e400768SDavid Christensen           "  fw_stats_req\n"
1034e400768SDavid Christensen           "    hdr\n"
1044e400768SDavid Christensen           "      cmd_num %d\n"
1054e400768SDavid Christensen           "      reserved0 %d\n"
1064e400768SDavid Christensen           "      drv_stats_counter %d\n"
1074e400768SDavid Christensen           "      reserved1 %d\n"
1084e400768SDavid Christensen           "      stats_counters_addrs %x %x\n",
1094e400768SDavid Christensen           sc->fw_stats_req->hdr.cmd_num,
1104e400768SDavid Christensen           sc->fw_stats_req->hdr.reserved0,
1114e400768SDavid Christensen           sc->fw_stats_req->hdr.drv_stats_counter,
1124e400768SDavid Christensen           sc->fw_stats_req->hdr.reserved1,
1134e400768SDavid Christensen           sc->fw_stats_req->hdr.stats_counters_addrs.hi,
1144e400768SDavid Christensen           sc->fw_stats_req->hdr.stats_counters_addrs.lo);
1154e400768SDavid Christensen 
1164e400768SDavid Christensen     for (i = 0; i < sc->fw_stats_req->hdr.cmd_num; i++) {
1174e400768SDavid Christensen         BLOGD(sc, DBG_STATS,
1184e400768SDavid Christensen               "query[%d]\n"
1194e400768SDavid Christensen               "  kind %d\n"
1204e400768SDavid Christensen               "  index %d\n"
1214e400768SDavid Christensen               "  funcID %d\n"
1224e400768SDavid Christensen               "  reserved %d\n"
1234e400768SDavid Christensen               "  address %x %x\n",
1244e400768SDavid Christensen               i,
1254e400768SDavid Christensen               sc->fw_stats_req->query[i].kind,
1264e400768SDavid Christensen               sc->fw_stats_req->query[i].index,
1274e400768SDavid Christensen               sc->fw_stats_req->query[i].funcID,
1284e400768SDavid Christensen               sc->fw_stats_req->query[i].reserved,
1294e400768SDavid Christensen               sc->fw_stats_req->query[i].address.hi,
1304e400768SDavid Christensen               sc->fw_stats_req->query[i].address.lo);
1314e400768SDavid Christensen     }
1324e400768SDavid Christensen }
1334e400768SDavid Christensen 
1344e400768SDavid Christensen /*
1354e400768SDavid Christensen  * Post the next statistics ramrod. Protect it with the lock in
1364e400768SDavid Christensen  * order to ensure the strict order between statistics ramrods
1374e400768SDavid Christensen  * (each ramrod has a sequence number passed in a
1384e400768SDavid Christensen  * sc->fw_stats_req->hdr.drv_stats_counter and ramrods must be
1394e400768SDavid Christensen  * sent in order).
1404e400768SDavid Christensen  */
1414e400768SDavid Christensen static void
bxe_storm_stats_post(struct bxe_softc * sc)1424e400768SDavid Christensen bxe_storm_stats_post(struct bxe_softc *sc)
1434e400768SDavid Christensen {
1444e400768SDavid Christensen     int rc;
1454e400768SDavid Christensen 
1464e400768SDavid Christensen     if (!sc->stats_pending) {
1474e400768SDavid Christensen         BXE_STATS_LOCK(sc);
1484e400768SDavid Christensen 
1494e400768SDavid Christensen         if (sc->stats_pending) {
1504e400768SDavid Christensen             BXE_STATS_UNLOCK(sc);
1514e400768SDavid Christensen             return;
1524e400768SDavid Christensen         }
1534e400768SDavid Christensen 
1544e400768SDavid Christensen         sc->fw_stats_req->hdr.drv_stats_counter =
1554e400768SDavid Christensen             htole16(sc->stats_counter++);
1564e400768SDavid Christensen 
1574e400768SDavid Christensen         BLOGD(sc, DBG_STATS,
1584e400768SDavid Christensen               "sending statistics ramrod %d\n",
1594e400768SDavid Christensen               le16toh(sc->fw_stats_req->hdr.drv_stats_counter));
1604e400768SDavid Christensen 
1614e400768SDavid Christensen         /* adjust the ramrod to include VF queues statistics */
1624e400768SDavid Christensen         // XXX bxe_iov_adjust_stats_req(sc);
1634e400768SDavid Christensen 
1644e400768SDavid Christensen         bxe_dp_stats(sc);
1654e400768SDavid Christensen 
1664e400768SDavid Christensen         /* send FW stats ramrod */
1674e400768SDavid Christensen         rc = bxe_sp_post(sc, RAMROD_CMD_ID_COMMON_STAT_QUERY, 0,
1684e400768SDavid Christensen                          U64_HI(sc->fw_stats_req_mapping),
1694e400768SDavid Christensen                          U64_LO(sc->fw_stats_req_mapping),
1704e400768SDavid Christensen                          NONE_CONNECTION_TYPE);
1714e400768SDavid Christensen         if (rc == 0) {
1724e400768SDavid Christensen             sc->stats_pending = 1;
1734e400768SDavid Christensen         }
1744e400768SDavid Christensen 
1754e400768SDavid Christensen         BXE_STATS_UNLOCK(sc);
1764e400768SDavid Christensen     }
1774e400768SDavid Christensen }
1784e400768SDavid Christensen 
1794e400768SDavid Christensen static void
bxe_hw_stats_post(struct bxe_softc * sc)1804e400768SDavid Christensen bxe_hw_stats_post(struct bxe_softc *sc)
1814e400768SDavid Christensen {
1824ef8ebfdSDavid C Somayajulu     struct dmae_cmd *dmae = &sc->stats_dmae;
1834e400768SDavid Christensen     uint32_t *stats_comp = BXE_SP(sc, stats_comp);
1844e400768SDavid Christensen     int loader_idx;
1854e400768SDavid Christensen     uint32_t opcode;
1864e400768SDavid Christensen 
1874e400768SDavid Christensen     *stats_comp = DMAE_COMP_VAL;
1884e400768SDavid Christensen     if (CHIP_REV_IS_SLOW(sc)) {
1894e400768SDavid Christensen         return;
1904e400768SDavid Christensen     }
1914e400768SDavid Christensen 
1924e400768SDavid Christensen     /* Update MCP's statistics if possible */
1934e400768SDavid Christensen     if (sc->func_stx) {
1944e400768SDavid Christensen         memcpy(BXE_SP(sc, func_stats), &sc->func_stats,
1954e400768SDavid Christensen                sizeof(sc->func_stats));
1964e400768SDavid Christensen     }
1974e400768SDavid Christensen 
1984e400768SDavid Christensen     /* loader */
1994e400768SDavid Christensen     if (sc->executer_idx) {
2004e400768SDavid Christensen         loader_idx = PMF_DMAE_C(sc);
2014e400768SDavid Christensen         opcode =  bxe_dmae_opcode(sc, DMAE_SRC_PCI, DMAE_DST_GRC,
2024e400768SDavid Christensen                                   TRUE, DMAE_COMP_GRC);
2034e400768SDavid Christensen         opcode = bxe_dmae_opcode_clr_src_reset(opcode);
2044e400768SDavid Christensen 
2054ef8ebfdSDavid C Somayajulu         memset(dmae, 0, sizeof(struct dmae_cmd));
2064e400768SDavid Christensen         dmae->opcode = opcode;
2074e400768SDavid Christensen         dmae->src_addr_lo = U64_LO(BXE_SP_MAPPING(sc, dmae[0]));
2084e400768SDavid Christensen         dmae->src_addr_hi = U64_HI(BXE_SP_MAPPING(sc, dmae[0]));
2094e400768SDavid Christensen         dmae->dst_addr_lo = ((DMAE_REG_CMD_MEM +
2104ef8ebfdSDavid C Somayajulu                               sizeof(struct dmae_cmd) *
2114e400768SDavid Christensen                               (loader_idx + 1)) >> 2);
2124e400768SDavid Christensen         dmae->dst_addr_hi = 0;
2134ef8ebfdSDavid C Somayajulu         dmae->len = sizeof(struct dmae_cmd) >> 2;
2144e400768SDavid Christensen         if (CHIP_IS_E1(sc)) {
2154e400768SDavid Christensen             dmae->len--;
2164e400768SDavid Christensen         }
2174e400768SDavid Christensen         dmae->comp_addr_lo = (dmae_reg_go_c[loader_idx + 1] >> 2);
2184e400768SDavid Christensen         dmae->comp_addr_hi = 0;
2194e400768SDavid Christensen         dmae->comp_val = 1;
2204e400768SDavid Christensen 
2214e400768SDavid Christensen         *stats_comp = 0;
2224e400768SDavid Christensen         bxe_post_dmae(sc, dmae, loader_idx);
2234e400768SDavid Christensen     } else if (sc->func_stx) {
2244e400768SDavid Christensen         *stats_comp = 0;
2254e400768SDavid Christensen         bxe_post_dmae(sc, dmae, INIT_DMAE_C(sc));
2264e400768SDavid Christensen     }
2274e400768SDavid Christensen }
2284e400768SDavid Christensen 
2294e400768SDavid Christensen static int
bxe_stats_comp(struct bxe_softc * sc)2304e400768SDavid Christensen bxe_stats_comp(struct bxe_softc *sc)
2314e400768SDavid Christensen {
2324e400768SDavid Christensen     uint32_t *stats_comp = BXE_SP(sc, stats_comp);
2334e400768SDavid Christensen     int cnt = 10;
2344e400768SDavid Christensen 
2354e400768SDavid Christensen     while (*stats_comp != DMAE_COMP_VAL) {
2364e400768SDavid Christensen         if (!cnt) {
2374e400768SDavid Christensen             BLOGE(sc, "Timeout waiting for stats finished\n");
238*36baf17eSDavid C Somayajulu 	    BXE_SET_ERROR_BIT(sc, BXE_ERR_STATS_TO);
239*36baf17eSDavid C Somayajulu             taskqueue_enqueue_timeout(taskqueue_thread,
240*36baf17eSDavid C Somayajulu                 &sc->sp_err_timeout_task, hz/10);
2414e400768SDavid Christensen             break;
242*36baf17eSDavid C Somayajulu 
2434e400768SDavid Christensen         }
2444e400768SDavid Christensen 
2454e400768SDavid Christensen         cnt--;
2464e400768SDavid Christensen         DELAY(1000);
2474e400768SDavid Christensen     }
2484e400768SDavid Christensen 
2494e400768SDavid Christensen     return (1);
2504e400768SDavid Christensen }
2514e400768SDavid Christensen 
2524e400768SDavid Christensen /*
2534e400768SDavid Christensen  * Statistics service functions
2544e400768SDavid Christensen  */
2554e400768SDavid Christensen 
2564e400768SDavid Christensen static void
bxe_stats_pmf_update(struct bxe_softc * sc)2574e400768SDavid Christensen bxe_stats_pmf_update(struct bxe_softc *sc)
2584e400768SDavid Christensen {
2594ef8ebfdSDavid C Somayajulu     struct dmae_cmd *dmae;
2604e400768SDavid Christensen     uint32_t opcode;
2614e400768SDavid Christensen     int loader_idx = PMF_DMAE_C(sc);
2624e400768SDavid Christensen     uint32_t *stats_comp = BXE_SP(sc, stats_comp);
2634e400768SDavid Christensen 
2642bd40797SEric Davis     if (sc->devinfo.bc_ver <= 0x06001400) {
2652bd40797SEric Davis         /*
2662bd40797SEric Davis          * Bootcode v6.0.21 fixed a GRC timeout that occurs when accessing
2672bd40797SEric Davis          * BRB registers while the BRB block is in reset. The DMA transfer
2682bd40797SEric Davis          * below triggers this issue resulting in the DMAE to stop
2692bd40797SEric Davis          * functioning. Skip this initial stats transfer for old bootcode
2702bd40797SEric Davis          * versions <= 6.0.20.
2712bd40797SEric Davis          */
2722bd40797SEric Davis         return;
2732bd40797SEric Davis     }
2742bd40797SEric Davis 
2754e400768SDavid Christensen     /* sanity */
2764e400768SDavid Christensen     if (!sc->port.pmf || !sc->port.port_stx) {
2774e400768SDavid Christensen         BLOGE(sc, "BUG!\n");
2784e400768SDavid Christensen         return;
2794e400768SDavid Christensen     }
2804e400768SDavid Christensen 
2814e400768SDavid Christensen     sc->executer_idx = 0;
2824e400768SDavid Christensen 
2834e400768SDavid Christensen     opcode = bxe_dmae_opcode(sc, DMAE_SRC_GRC, DMAE_DST_PCI, FALSE, 0);
2844e400768SDavid Christensen 
2854e400768SDavid Christensen     dmae = BXE_SP(sc, dmae[sc->executer_idx++]);
2864e400768SDavid Christensen     dmae->opcode = bxe_dmae_opcode_add_comp(opcode, DMAE_COMP_GRC);
2874e400768SDavid Christensen     dmae->src_addr_lo = (sc->port.port_stx >> 2);
2884e400768SDavid Christensen     dmae->src_addr_hi = 0;
2894e400768SDavid Christensen     dmae->dst_addr_lo = U64_LO(BXE_SP_MAPPING(sc, port_stats));
2904e400768SDavid Christensen     dmae->dst_addr_hi = U64_HI(BXE_SP_MAPPING(sc, port_stats));
2914e400768SDavid Christensen     dmae->len = DMAE_LEN32_RD_MAX;
2924e400768SDavid Christensen     dmae->comp_addr_lo = (dmae_reg_go_c[loader_idx] >> 2);
2934e400768SDavid Christensen     dmae->comp_addr_hi = 0;
2944e400768SDavid Christensen     dmae->comp_val = 1;
2954e400768SDavid Christensen 
2964e400768SDavid Christensen     dmae = BXE_SP(sc, dmae[sc->executer_idx++]);
2974e400768SDavid Christensen     dmae->opcode = bxe_dmae_opcode_add_comp(opcode, DMAE_COMP_PCI);
2984e400768SDavid Christensen     dmae->src_addr_lo = ((sc->port.port_stx >> 2) + DMAE_LEN32_RD_MAX);
2994e400768SDavid Christensen     dmae->src_addr_hi = 0;
3004e400768SDavid Christensen     dmae->dst_addr_lo = U64_LO(BXE_SP_MAPPING(sc, port_stats) +
3014e400768SDavid Christensen                                DMAE_LEN32_RD_MAX * 4);
3024e400768SDavid Christensen     dmae->dst_addr_hi = U64_HI(BXE_SP_MAPPING(sc, port_stats) +
3034e400768SDavid Christensen                                DMAE_LEN32_RD_MAX * 4);
3044e400768SDavid Christensen     dmae->len = (bxe_get_port_stats_dma_len(sc) - DMAE_LEN32_RD_MAX);
3054e400768SDavid Christensen 
3064e400768SDavid Christensen     dmae->comp_addr_lo = U64_LO(BXE_SP_MAPPING(sc, stats_comp));
3074e400768SDavid Christensen     dmae->comp_addr_hi = U64_HI(BXE_SP_MAPPING(sc, stats_comp));
3084e400768SDavid Christensen     dmae->comp_val = DMAE_COMP_VAL;
3094e400768SDavid Christensen 
3104e400768SDavid Christensen     *stats_comp = 0;
3114e400768SDavid Christensen     bxe_hw_stats_post(sc);
3124e400768SDavid Christensen     bxe_stats_comp(sc);
3134e400768SDavid Christensen }
3144e400768SDavid Christensen 
3154e400768SDavid Christensen static void
bxe_port_stats_init(struct bxe_softc * sc)3164e400768SDavid Christensen bxe_port_stats_init(struct bxe_softc *sc)
3174e400768SDavid Christensen {
3184ef8ebfdSDavid C Somayajulu     struct dmae_cmd *dmae;
3194e400768SDavid Christensen     int port = SC_PORT(sc);
3204e400768SDavid Christensen     uint32_t opcode;
3214e400768SDavid Christensen     int loader_idx = PMF_DMAE_C(sc);
3224e400768SDavid Christensen     uint32_t mac_addr;
3234e400768SDavid Christensen     uint32_t *stats_comp = BXE_SP(sc, stats_comp);
3244e400768SDavid Christensen 
3254e400768SDavid Christensen     /* sanity */
3264e400768SDavid Christensen     if (!sc->link_vars.link_up || !sc->port.pmf) {
3274e400768SDavid Christensen         BLOGE(sc, "BUG!\n");
3284e400768SDavid Christensen         return;
3294e400768SDavid Christensen     }
3304e400768SDavid Christensen 
3314e400768SDavid Christensen     sc->executer_idx = 0;
3324e400768SDavid Christensen 
3334e400768SDavid Christensen     /* MCP */
3344e400768SDavid Christensen     opcode = bxe_dmae_opcode(sc, DMAE_SRC_PCI, DMAE_DST_GRC,
3354e400768SDavid Christensen                              TRUE, DMAE_COMP_GRC);
3364e400768SDavid Christensen 
3374e400768SDavid Christensen     if (sc->port.port_stx) {
3384e400768SDavid Christensen         dmae = BXE_SP(sc, dmae[sc->executer_idx++]);
3394e400768SDavid Christensen         dmae->opcode = opcode;
3404e400768SDavid Christensen         dmae->src_addr_lo = U64_LO(BXE_SP_MAPPING(sc, port_stats));
3414e400768SDavid Christensen         dmae->src_addr_hi = U64_HI(BXE_SP_MAPPING(sc, port_stats));
3424e400768SDavid Christensen         dmae->dst_addr_lo = sc->port.port_stx >> 2;
3434e400768SDavid Christensen         dmae->dst_addr_hi = 0;
3444e400768SDavid Christensen         dmae->len = bxe_get_port_stats_dma_len(sc);
3454e400768SDavid Christensen         dmae->comp_addr_lo = dmae_reg_go_c[loader_idx] >> 2;
3464e400768SDavid Christensen         dmae->comp_addr_hi = 0;
3474e400768SDavid Christensen         dmae->comp_val = 1;
3484e400768SDavid Christensen     }
3494e400768SDavid Christensen 
3504e400768SDavid Christensen     if (sc->func_stx) {
3514e400768SDavid Christensen         dmae = BXE_SP(sc, dmae[sc->executer_idx++]);
3524e400768SDavid Christensen         dmae->opcode = opcode;
3534e400768SDavid Christensen         dmae->src_addr_lo = U64_LO(BXE_SP_MAPPING(sc, func_stats));
3544e400768SDavid Christensen         dmae->src_addr_hi = U64_HI(BXE_SP_MAPPING(sc, func_stats));
3554e400768SDavid Christensen         dmae->dst_addr_lo = (sc->func_stx >> 2);
3564e400768SDavid Christensen         dmae->dst_addr_hi = 0;
3574e400768SDavid Christensen         dmae->len = (sizeof(struct host_func_stats) >> 2);
3584e400768SDavid Christensen         dmae->comp_addr_lo = (dmae_reg_go_c[loader_idx] >> 2);
3594e400768SDavid Christensen         dmae->comp_addr_hi = 0;
3604e400768SDavid Christensen         dmae->comp_val = 1;
3614e400768SDavid Christensen     }
3624e400768SDavid Christensen 
3634e400768SDavid Christensen     /* MAC */
3644e400768SDavid Christensen     opcode = bxe_dmae_opcode(sc, DMAE_SRC_GRC, DMAE_DST_PCI,
3654e400768SDavid Christensen                              TRUE, DMAE_COMP_GRC);
3664e400768SDavid Christensen 
3674e400768SDavid Christensen     /* EMAC is special */
3684e400768SDavid Christensen     if (sc->link_vars.mac_type == ELINK_MAC_TYPE_EMAC) {
3694e400768SDavid Christensen         mac_addr = (port ? GRCBASE_EMAC1 : GRCBASE_EMAC0);
3704e400768SDavid Christensen 
3714e400768SDavid Christensen         /* EMAC_REG_EMAC_RX_STAT_AC (EMAC_REG_EMAC_RX_STAT_AC_COUNT)*/
3724e400768SDavid Christensen         dmae = BXE_SP(sc, dmae[sc->executer_idx++]);
3734e400768SDavid Christensen         dmae->opcode = opcode;
3744e400768SDavid Christensen         dmae->src_addr_lo = (mac_addr + EMAC_REG_EMAC_RX_STAT_AC) >> 2;
3754e400768SDavid Christensen         dmae->src_addr_hi = 0;
3764e400768SDavid Christensen         dmae->dst_addr_lo = U64_LO(BXE_SP_MAPPING(sc, mac_stats));
3774e400768SDavid Christensen         dmae->dst_addr_hi = U64_HI(BXE_SP_MAPPING(sc, mac_stats));
3784e400768SDavid Christensen         dmae->len = EMAC_REG_EMAC_RX_STAT_AC_COUNT;
3794e400768SDavid Christensen         dmae->comp_addr_lo = (dmae_reg_go_c[loader_idx] >> 2);
3804e400768SDavid Christensen         dmae->comp_addr_hi = 0;
3814e400768SDavid Christensen         dmae->comp_val = 1;
3824e400768SDavid Christensen 
3834e400768SDavid Christensen         /* EMAC_REG_EMAC_RX_STAT_AC_28 */
3844e400768SDavid Christensen         dmae = BXE_SP(sc, dmae[sc->executer_idx++]);
3854e400768SDavid Christensen         dmae->opcode = opcode;
3864e400768SDavid Christensen         dmae->src_addr_lo = ((mac_addr + EMAC_REG_EMAC_RX_STAT_AC_28) >> 2);
3874e400768SDavid Christensen         dmae->src_addr_hi = 0;
3884e400768SDavid Christensen         dmae->dst_addr_lo = U64_LO(BXE_SP_MAPPING(sc, mac_stats) +
3894e400768SDavid Christensen                                    offsetof(struct emac_stats,
3904e400768SDavid Christensen                                             rx_stat_falsecarriererrors));
3914e400768SDavid Christensen         dmae->dst_addr_hi = U64_HI(BXE_SP_MAPPING(sc, mac_stats) +
3924e400768SDavid Christensen                                    offsetof(struct emac_stats,
3934e400768SDavid Christensen                                             rx_stat_falsecarriererrors));
3944e400768SDavid Christensen         dmae->len = 1;
3954e400768SDavid Christensen         dmae->comp_addr_lo = (dmae_reg_go_c[loader_idx] >> 2);
3964e400768SDavid Christensen         dmae->comp_addr_hi = 0;
3974e400768SDavid Christensen         dmae->comp_val = 1;
3984e400768SDavid Christensen 
3994e400768SDavid Christensen         /* EMAC_REG_EMAC_TX_STAT_AC (EMAC_REG_EMAC_TX_STAT_AC_COUNT)*/
4004e400768SDavid Christensen         dmae = BXE_SP(sc, dmae[sc->executer_idx++]);
4014e400768SDavid Christensen         dmae->opcode = opcode;
4024e400768SDavid Christensen         dmae->src_addr_lo = ((mac_addr + EMAC_REG_EMAC_TX_STAT_AC) >> 2);
4034e400768SDavid Christensen         dmae->src_addr_hi = 0;
4044e400768SDavid Christensen         dmae->dst_addr_lo = U64_LO(BXE_SP_MAPPING(sc, mac_stats) +
4054e400768SDavid Christensen                                    offsetof(struct emac_stats,
4064e400768SDavid Christensen                                             tx_stat_ifhcoutoctets));
4074e400768SDavid Christensen         dmae->dst_addr_hi = U64_HI(BXE_SP_MAPPING(sc, mac_stats) +
4084e400768SDavid Christensen                                    offsetof(struct emac_stats,
4094e400768SDavid Christensen                                             tx_stat_ifhcoutoctets));
4104e400768SDavid Christensen         dmae->len = EMAC_REG_EMAC_TX_STAT_AC_COUNT;
4114e400768SDavid Christensen         dmae->comp_addr_lo = (dmae_reg_go_c[loader_idx] >> 2);
4124e400768SDavid Christensen         dmae->comp_addr_hi = 0;
4134e400768SDavid Christensen         dmae->comp_val = 1;
4144e400768SDavid Christensen     } else {
4154e400768SDavid Christensen         uint32_t tx_src_addr_lo, rx_src_addr_lo;
4164e400768SDavid Christensen         uint16_t rx_len, tx_len;
4174e400768SDavid Christensen 
4184e400768SDavid Christensen         /* configure the params according to MAC type */
4194e400768SDavid Christensen         switch (sc->link_vars.mac_type) {
4204e400768SDavid Christensen         case ELINK_MAC_TYPE_BMAC:
4214e400768SDavid Christensen             mac_addr = (port) ? NIG_REG_INGRESS_BMAC1_MEM :
4224e400768SDavid Christensen                                 NIG_REG_INGRESS_BMAC0_MEM;
4234e400768SDavid Christensen 
4244e400768SDavid Christensen             /* BIGMAC_REGISTER_TX_STAT_GTPKT ..
4254e400768SDavid Christensen                BIGMAC_REGISTER_TX_STAT_GTBYT */
4264e400768SDavid Christensen             if (CHIP_IS_E1x(sc)) {
4274e400768SDavid Christensen                 tx_src_addr_lo =
4284e400768SDavid Christensen                     ((mac_addr + BIGMAC_REGISTER_TX_STAT_GTPKT) >> 2);
4294e400768SDavid Christensen                 tx_len = ((8 + BIGMAC_REGISTER_TX_STAT_GTBYT -
4304e400768SDavid Christensen                            BIGMAC_REGISTER_TX_STAT_GTPKT) >> 2);
4314e400768SDavid Christensen                 rx_src_addr_lo =
4324e400768SDavid Christensen                     ((mac_addr + BIGMAC_REGISTER_RX_STAT_GR64) >> 2);
4334e400768SDavid Christensen                 rx_len = ((8 + BIGMAC_REGISTER_RX_STAT_GRIPJ -
4344e400768SDavid Christensen                            BIGMAC_REGISTER_RX_STAT_GR64) >> 2);
4354e400768SDavid Christensen             } else {
4364e400768SDavid Christensen                 tx_src_addr_lo =
4374e400768SDavid Christensen                     ((mac_addr + BIGMAC2_REGISTER_TX_STAT_GTPOK) >> 2);
4384e400768SDavid Christensen                 tx_len = ((8 + BIGMAC2_REGISTER_TX_STAT_GTBYT -
4394e400768SDavid Christensen                            BIGMAC2_REGISTER_TX_STAT_GTPOK) >> 2);
4404e400768SDavid Christensen                 rx_src_addr_lo =
4414e400768SDavid Christensen                     ((mac_addr + BIGMAC2_REGISTER_RX_STAT_GR64) >> 2);
4424e400768SDavid Christensen                 rx_len = ((8 + BIGMAC2_REGISTER_RX_STAT_GRIPJ -
4434e400768SDavid Christensen                            BIGMAC2_REGISTER_RX_STAT_GR64) >> 2);
4444e400768SDavid Christensen             }
4454e400768SDavid Christensen 
4464e400768SDavid Christensen             break;
4474e400768SDavid Christensen 
4484e400768SDavid Christensen         case ELINK_MAC_TYPE_UMAC: /* handled by MSTAT */
4494e400768SDavid Christensen         case ELINK_MAC_TYPE_XMAC: /* handled by MSTAT */
4504e400768SDavid Christensen         default:
4514e400768SDavid Christensen             mac_addr = (port) ? GRCBASE_MSTAT1 : GRCBASE_MSTAT0;
4524e400768SDavid Christensen             tx_src_addr_lo = ((mac_addr + MSTAT_REG_TX_STAT_GTXPOK_LO) >> 2);
4534e400768SDavid Christensen             rx_src_addr_lo = ((mac_addr + MSTAT_REG_RX_STAT_GR64_LO) >> 2);
4544e400768SDavid Christensen             tx_len =
4554e400768SDavid Christensen                 (sizeof(sc->sp->mac_stats.mstat_stats.stats_tx) >> 2);
4564e400768SDavid Christensen             rx_len =
4574e400768SDavid Christensen                 (sizeof(sc->sp->mac_stats.mstat_stats.stats_rx) >> 2);
4584e400768SDavid Christensen             break;
4594e400768SDavid Christensen         }
4604e400768SDavid Christensen 
4614e400768SDavid Christensen         /* TX stats */
4624e400768SDavid Christensen         dmae = BXE_SP(sc, dmae[sc->executer_idx++]);
4634e400768SDavid Christensen         dmae->opcode = opcode;
4644e400768SDavid Christensen         dmae->src_addr_lo = tx_src_addr_lo;
4654e400768SDavid Christensen         dmae->src_addr_hi = 0;
4664e400768SDavid Christensen         dmae->len = tx_len;
4674e400768SDavid Christensen         dmae->dst_addr_lo = U64_LO(BXE_SP_MAPPING(sc, mac_stats));
4684e400768SDavid Christensen         dmae->dst_addr_hi = U64_HI(BXE_SP_MAPPING(sc, mac_stats));
4694e400768SDavid Christensen         dmae->comp_addr_lo = dmae_reg_go_c[loader_idx] >> 2;
4704e400768SDavid Christensen         dmae->comp_addr_hi = 0;
4714e400768SDavid Christensen         dmae->comp_val = 1;
4724e400768SDavid Christensen 
4734e400768SDavid Christensen         /* RX stats */
4744e400768SDavid Christensen         dmae = BXE_SP(sc, dmae[sc->executer_idx++]);
4754e400768SDavid Christensen         dmae->opcode = opcode;
4764e400768SDavid Christensen         dmae->src_addr_hi = 0;
4774e400768SDavid Christensen         dmae->src_addr_lo = rx_src_addr_lo;
4784e400768SDavid Christensen         dmae->dst_addr_lo =
4794e400768SDavid Christensen             U64_LO(BXE_SP_MAPPING(sc, mac_stats) + (tx_len << 2));
4804e400768SDavid Christensen         dmae->dst_addr_hi =
4814e400768SDavid Christensen             U64_HI(BXE_SP_MAPPING(sc, mac_stats) + (tx_len << 2));
4824e400768SDavid Christensen         dmae->len = rx_len;
4834e400768SDavid Christensen         dmae->comp_addr_lo = dmae_reg_go_c[loader_idx] >> 2;
4844e400768SDavid Christensen         dmae->comp_addr_hi = 0;
4854e400768SDavid Christensen         dmae->comp_val = 1;
4864e400768SDavid Christensen     }
4874e400768SDavid Christensen 
4884e400768SDavid Christensen     /* NIG */
4894e400768SDavid Christensen     if (!CHIP_IS_E3(sc)) {
4904e400768SDavid Christensen         dmae = BXE_SP(sc, dmae[sc->executer_idx++]);
4914e400768SDavid Christensen         dmae->opcode = opcode;
4924e400768SDavid Christensen         dmae->src_addr_lo =
4934e400768SDavid Christensen             (port ? NIG_REG_STAT1_EGRESS_MAC_PKT0 :
4944e400768SDavid Christensen                     NIG_REG_STAT0_EGRESS_MAC_PKT0) >> 2;
4954e400768SDavid Christensen         dmae->src_addr_hi = 0;
4964e400768SDavid Christensen         dmae->dst_addr_lo = U64_LO(BXE_SP_MAPPING(sc, nig_stats) +
4974e400768SDavid Christensen                                    offsetof(struct nig_stats,
4984e400768SDavid Christensen                                             egress_mac_pkt0_lo));
4994e400768SDavid Christensen         dmae->dst_addr_hi = U64_HI(BXE_SP_MAPPING(sc, nig_stats) +
5004e400768SDavid Christensen                                    offsetof(struct nig_stats,
5014e400768SDavid Christensen                                             egress_mac_pkt0_lo));
5024e400768SDavid Christensen         dmae->len = ((2 * sizeof(uint32_t)) >> 2);
5034e400768SDavid Christensen         dmae->comp_addr_lo = (dmae_reg_go_c[loader_idx] >> 2);
5044e400768SDavid Christensen         dmae->comp_addr_hi = 0;
5054e400768SDavid Christensen         dmae->comp_val = 1;
5064e400768SDavid Christensen 
5074e400768SDavid Christensen         dmae = BXE_SP(sc, dmae[sc->executer_idx++]);
5084e400768SDavid Christensen         dmae->opcode = opcode;
5094e400768SDavid Christensen         dmae->src_addr_lo =
5104e400768SDavid Christensen             (port ? NIG_REG_STAT1_EGRESS_MAC_PKT1 :
5114e400768SDavid Christensen                     NIG_REG_STAT0_EGRESS_MAC_PKT1) >> 2;
5124e400768SDavid Christensen         dmae->src_addr_hi = 0;
5134e400768SDavid Christensen         dmae->dst_addr_lo = U64_LO(BXE_SP_MAPPING(sc, nig_stats) +
5144e400768SDavid Christensen                                    offsetof(struct nig_stats,
5154e400768SDavid Christensen                                             egress_mac_pkt1_lo));
5164e400768SDavid Christensen         dmae->dst_addr_hi = U64_HI(BXE_SP_MAPPING(sc, nig_stats) +
5174e400768SDavid Christensen                                    offsetof(struct nig_stats,
5184e400768SDavid Christensen                                             egress_mac_pkt1_lo));
5194e400768SDavid Christensen         dmae->len = ((2 * sizeof(uint32_t)) >> 2);
5204e400768SDavid Christensen         dmae->comp_addr_lo = (dmae_reg_go_c[loader_idx] >> 2);
5214e400768SDavid Christensen         dmae->comp_addr_hi = 0;
5224e400768SDavid Christensen         dmae->comp_val = 1;
5234e400768SDavid Christensen     }
5244e400768SDavid Christensen 
5254e400768SDavid Christensen     dmae = BXE_SP(sc, dmae[sc->executer_idx++]);
5264e400768SDavid Christensen     dmae->opcode = bxe_dmae_opcode(sc, DMAE_SRC_GRC, DMAE_DST_PCI,
5274e400768SDavid Christensen                                    TRUE, DMAE_COMP_PCI);
5284e400768SDavid Christensen     dmae->src_addr_lo =
5294e400768SDavid Christensen         (port ? NIG_REG_STAT1_BRB_DISCARD :
5304e400768SDavid Christensen                 NIG_REG_STAT0_BRB_DISCARD) >> 2;
5314e400768SDavid Christensen     dmae->src_addr_hi = 0;
5324e400768SDavid Christensen     dmae->dst_addr_lo = U64_LO(BXE_SP_MAPPING(sc, nig_stats));
5334e400768SDavid Christensen     dmae->dst_addr_hi = U64_HI(BXE_SP_MAPPING(sc, nig_stats));
5344e400768SDavid Christensen     dmae->len = (sizeof(struct nig_stats) - 4*sizeof(uint32_t)) >> 2;
5354e400768SDavid Christensen 
5364e400768SDavid Christensen     dmae->comp_addr_lo = U64_LO(BXE_SP_MAPPING(sc, stats_comp));
5374e400768SDavid Christensen     dmae->comp_addr_hi = U64_HI(BXE_SP_MAPPING(sc, stats_comp));
5384e400768SDavid Christensen     dmae->comp_val = DMAE_COMP_VAL;
5394e400768SDavid Christensen 
5404e400768SDavid Christensen     *stats_comp = 0;
5414e400768SDavid Christensen }
5424e400768SDavid Christensen 
5434e400768SDavid Christensen static void
bxe_func_stats_init(struct bxe_softc * sc)5444e400768SDavid Christensen bxe_func_stats_init(struct bxe_softc *sc)
5454e400768SDavid Christensen {
5464ef8ebfdSDavid C Somayajulu     struct dmae_cmd *dmae = &sc->stats_dmae;
5474e400768SDavid Christensen     uint32_t *stats_comp = BXE_SP(sc, stats_comp);
5484e400768SDavid Christensen 
5494e400768SDavid Christensen     /* sanity */
5504e400768SDavid Christensen     if (!sc->func_stx) {
5514e400768SDavid Christensen         BLOGE(sc, "BUG!\n");
5524e400768SDavid Christensen         return;
5534e400768SDavid Christensen     }
5544e400768SDavid Christensen 
5554e400768SDavid Christensen     sc->executer_idx = 0;
5564ef8ebfdSDavid C Somayajulu     memset(dmae, 0, sizeof(struct dmae_cmd));
5574e400768SDavid Christensen 
5584e400768SDavid Christensen     dmae->opcode = bxe_dmae_opcode(sc, DMAE_SRC_PCI, DMAE_DST_GRC,
5594e400768SDavid Christensen                                    TRUE, DMAE_COMP_PCI);
5604e400768SDavid Christensen     dmae->src_addr_lo = U64_LO(BXE_SP_MAPPING(sc, func_stats));
5614e400768SDavid Christensen     dmae->src_addr_hi = U64_HI(BXE_SP_MAPPING(sc, func_stats));
5624e400768SDavid Christensen     dmae->dst_addr_lo = (sc->func_stx >> 2);
5634e400768SDavid Christensen     dmae->dst_addr_hi = 0;
5644e400768SDavid Christensen     dmae->len = (sizeof(struct host_func_stats) >> 2);
5654e400768SDavid Christensen     dmae->comp_addr_lo = U64_LO(BXE_SP_MAPPING(sc, stats_comp));
5664e400768SDavid Christensen     dmae->comp_addr_hi = U64_HI(BXE_SP_MAPPING(sc, stats_comp));
5674e400768SDavid Christensen     dmae->comp_val = DMAE_COMP_VAL;
5684e400768SDavid Christensen 
5694e400768SDavid Christensen     *stats_comp = 0;
5704e400768SDavid Christensen }
5714e400768SDavid Christensen 
5724e400768SDavid Christensen static void
bxe_stats_start(struct bxe_softc * sc)5734e400768SDavid Christensen bxe_stats_start(struct bxe_softc *sc)
5744e400768SDavid Christensen {
5754e400768SDavid Christensen     /*
5764e400768SDavid Christensen      * VFs travel through here as part of the statistics FSM, but no action
5774e400768SDavid Christensen      * is required
5784e400768SDavid Christensen      */
5794e400768SDavid Christensen     if (IS_VF(sc)) {
5804e400768SDavid Christensen         return;
5814e400768SDavid Christensen     }
5824e400768SDavid Christensen 
5834e400768SDavid Christensen     if (sc->port.pmf) {
5844e400768SDavid Christensen         bxe_port_stats_init(sc);
5854e400768SDavid Christensen     }
5864e400768SDavid Christensen 
5874e400768SDavid Christensen     else if (sc->func_stx) {
5884e400768SDavid Christensen         bxe_func_stats_init(sc);
5894e400768SDavid Christensen     }
5904e400768SDavid Christensen 
5914e400768SDavid Christensen     bxe_hw_stats_post(sc);
5924e400768SDavid Christensen     bxe_storm_stats_post(sc);
5934e400768SDavid Christensen }
5944e400768SDavid Christensen 
5954e400768SDavid Christensen static void
bxe_stats_pmf_start(struct bxe_softc * sc)5964e400768SDavid Christensen bxe_stats_pmf_start(struct bxe_softc *sc)
5974e400768SDavid Christensen {
5984e400768SDavid Christensen     bxe_stats_comp(sc);
5994e400768SDavid Christensen     bxe_stats_pmf_update(sc);
6004e400768SDavid Christensen     bxe_stats_start(sc);
6014e400768SDavid Christensen }
6024e400768SDavid Christensen 
6034e400768SDavid Christensen static void
bxe_stats_restart(struct bxe_softc * sc)6044e400768SDavid Christensen bxe_stats_restart(struct bxe_softc *sc)
6054e400768SDavid Christensen {
6064e400768SDavid Christensen     /*
6074e400768SDavid Christensen      * VFs travel through here as part of the statistics FSM, but no action
6084e400768SDavid Christensen      * is required
6094e400768SDavid Christensen      */
6104e400768SDavid Christensen     if (IS_VF(sc)) {
6114e400768SDavid Christensen         return;
6124e400768SDavid Christensen     }
6134e400768SDavid Christensen 
6144e400768SDavid Christensen     bxe_stats_comp(sc);
6154e400768SDavid Christensen     bxe_stats_start(sc);
6164e400768SDavid Christensen }
6174e400768SDavid Christensen 
6184e400768SDavid Christensen static void
bxe_bmac_stats_update(struct bxe_softc * sc)6194e400768SDavid Christensen bxe_bmac_stats_update(struct bxe_softc *sc)
6204e400768SDavid Christensen {
6214e400768SDavid Christensen     struct host_port_stats *pstats = BXE_SP(sc, port_stats);
6224e400768SDavid Christensen     struct bxe_eth_stats *estats = &sc->eth_stats;
6234e400768SDavid Christensen     struct {
6244e400768SDavid Christensen         uint32_t lo;
6254e400768SDavid Christensen         uint32_t hi;
6264e400768SDavid Christensen     } diff;
6274e400768SDavid Christensen 
6284e400768SDavid Christensen     if (CHIP_IS_E1x(sc)) {
6294e400768SDavid Christensen         struct bmac1_stats *new = BXE_SP(sc, mac_stats.bmac1_stats);
6304e400768SDavid Christensen 
6314e400768SDavid Christensen         /* the macros below will use "bmac1_stats" type */
6324e400768SDavid Christensen         UPDATE_STAT64(rx_stat_grerb, rx_stat_ifhcinbadoctets);
6334e400768SDavid Christensen         UPDATE_STAT64(rx_stat_grfcs, rx_stat_dot3statsfcserrors);
6344e400768SDavid Christensen         UPDATE_STAT64(rx_stat_grund, rx_stat_etherstatsundersizepkts);
6354e400768SDavid Christensen         UPDATE_STAT64(rx_stat_grovr, rx_stat_dot3statsframestoolong);
6364e400768SDavid Christensen         UPDATE_STAT64(rx_stat_grfrg, rx_stat_etherstatsfragments);
6374e400768SDavid Christensen         UPDATE_STAT64(rx_stat_grjbr, rx_stat_etherstatsjabbers);
6384e400768SDavid Christensen         UPDATE_STAT64(rx_stat_grxcf, rx_stat_maccontrolframesreceived);
6394e400768SDavid Christensen         UPDATE_STAT64(rx_stat_grxpf, rx_stat_xoffstateentered);
6404e400768SDavid Christensen         UPDATE_STAT64(rx_stat_grxpf, rx_stat_mac_xpf);
6414e400768SDavid Christensen 
6424e400768SDavid Christensen         UPDATE_STAT64(tx_stat_gtxpf, tx_stat_outxoffsent);
6434e400768SDavid Christensen         UPDATE_STAT64(tx_stat_gtxpf, tx_stat_flowcontroldone);
6444e400768SDavid Christensen         UPDATE_STAT64(tx_stat_gt64, tx_stat_etherstatspkts64octets);
6454e400768SDavid Christensen         UPDATE_STAT64(tx_stat_gt127,
6464e400768SDavid Christensen                       tx_stat_etherstatspkts65octetsto127octets);
6474e400768SDavid Christensen         UPDATE_STAT64(tx_stat_gt255,
6484e400768SDavid Christensen                       tx_stat_etherstatspkts128octetsto255octets);
6494e400768SDavid Christensen         UPDATE_STAT64(tx_stat_gt511,
6504e400768SDavid Christensen                       tx_stat_etherstatspkts256octetsto511octets);
6514e400768SDavid Christensen         UPDATE_STAT64(tx_stat_gt1023,
6524e400768SDavid Christensen                       tx_stat_etherstatspkts512octetsto1023octets);
6534e400768SDavid Christensen         UPDATE_STAT64(tx_stat_gt1518,
6544e400768SDavid Christensen                       tx_stat_etherstatspkts1024octetsto1522octets);
6554e400768SDavid Christensen         UPDATE_STAT64(tx_stat_gt2047, tx_stat_mac_2047);
6564e400768SDavid Christensen         UPDATE_STAT64(tx_stat_gt4095, tx_stat_mac_4095);
6574e400768SDavid Christensen         UPDATE_STAT64(tx_stat_gt9216, tx_stat_mac_9216);
6584e400768SDavid Christensen         UPDATE_STAT64(tx_stat_gt16383, tx_stat_mac_16383);
6594e400768SDavid Christensen         UPDATE_STAT64(tx_stat_gterr,
6604e400768SDavid Christensen                       tx_stat_dot3statsinternalmactransmiterrors);
6614e400768SDavid Christensen         UPDATE_STAT64(tx_stat_gtufl, tx_stat_mac_ufl);
6624e400768SDavid Christensen     } else {
6634e400768SDavid Christensen         struct bmac2_stats *new = BXE_SP(sc, mac_stats.bmac2_stats);
6644e400768SDavid Christensen         struct bxe_fw_port_stats_old *fwstats = &sc->fw_stats_old;
6654e400768SDavid Christensen 
6664e400768SDavid Christensen         /* the macros below will use "bmac2_stats" type */
6674e400768SDavid Christensen         UPDATE_STAT64(rx_stat_grerb, rx_stat_ifhcinbadoctets);
6684e400768SDavid Christensen         UPDATE_STAT64(rx_stat_grfcs, rx_stat_dot3statsfcserrors);
6694e400768SDavid Christensen         UPDATE_STAT64(rx_stat_grund, rx_stat_etherstatsundersizepkts);
6704e400768SDavid Christensen         UPDATE_STAT64(rx_stat_grovr, rx_stat_dot3statsframestoolong);
6714e400768SDavid Christensen         UPDATE_STAT64(rx_stat_grfrg, rx_stat_etherstatsfragments);
6724e400768SDavid Christensen         UPDATE_STAT64(rx_stat_grjbr, rx_stat_etherstatsjabbers);
6734e400768SDavid Christensen         UPDATE_STAT64(rx_stat_grxcf, rx_stat_maccontrolframesreceived);
6744e400768SDavid Christensen         UPDATE_STAT64(rx_stat_grxpf, rx_stat_xoffstateentered);
6754e400768SDavid Christensen         UPDATE_STAT64(rx_stat_grxpf, rx_stat_mac_xpf);
6764e400768SDavid Christensen         UPDATE_STAT64(tx_stat_gtxpf, tx_stat_outxoffsent);
6774e400768SDavid Christensen         UPDATE_STAT64(tx_stat_gtxpf, tx_stat_flowcontroldone);
6784e400768SDavid Christensen         UPDATE_STAT64(tx_stat_gt64, tx_stat_etherstatspkts64octets);
6794e400768SDavid Christensen         UPDATE_STAT64(tx_stat_gt127,
6804e400768SDavid Christensen                       tx_stat_etherstatspkts65octetsto127octets);
6814e400768SDavid Christensen         UPDATE_STAT64(tx_stat_gt255,
6824e400768SDavid Christensen                       tx_stat_etherstatspkts128octetsto255octets);
6834e400768SDavid Christensen         UPDATE_STAT64(tx_stat_gt511,
6844e400768SDavid Christensen                       tx_stat_etherstatspkts256octetsto511octets);
6854e400768SDavid Christensen         UPDATE_STAT64(tx_stat_gt1023,
6864e400768SDavid Christensen                       tx_stat_etherstatspkts512octetsto1023octets);
6874e400768SDavid Christensen         UPDATE_STAT64(tx_stat_gt1518,
6884e400768SDavid Christensen                       tx_stat_etherstatspkts1024octetsto1522octets);
6894e400768SDavid Christensen         UPDATE_STAT64(tx_stat_gt2047, tx_stat_mac_2047);
6904e400768SDavid Christensen         UPDATE_STAT64(tx_stat_gt4095, tx_stat_mac_4095);
6914e400768SDavid Christensen         UPDATE_STAT64(tx_stat_gt9216, tx_stat_mac_9216);
6924e400768SDavid Christensen         UPDATE_STAT64(tx_stat_gt16383, tx_stat_mac_16383);
6934e400768SDavid Christensen         UPDATE_STAT64(tx_stat_gterr,
6944e400768SDavid Christensen                       tx_stat_dot3statsinternalmactransmiterrors);
6954e400768SDavid Christensen         UPDATE_STAT64(tx_stat_gtufl, tx_stat_mac_ufl);
6964e400768SDavid Christensen 
6974e400768SDavid Christensen         /* collect PFC stats */
6984e400768SDavid Christensen         pstats->pfc_frames_tx_hi = new->tx_stat_gtpp_hi;
6994e400768SDavid Christensen         pstats->pfc_frames_tx_lo = new->tx_stat_gtpp_lo;
7004e400768SDavid Christensen         ADD_64(pstats->pfc_frames_tx_hi, fwstats->pfc_frames_tx_hi,
7014e400768SDavid Christensen                pstats->pfc_frames_tx_lo, fwstats->pfc_frames_tx_lo);
7024e400768SDavid Christensen 
7034e400768SDavid Christensen         pstats->pfc_frames_rx_hi = new->rx_stat_grpp_hi;
7044e400768SDavid Christensen         pstats->pfc_frames_rx_lo = new->rx_stat_grpp_lo;
7054e400768SDavid Christensen         ADD_64(pstats->pfc_frames_rx_hi, fwstats->pfc_frames_rx_hi,
7064e400768SDavid Christensen                pstats->pfc_frames_rx_lo, fwstats->pfc_frames_rx_lo);
7074e400768SDavid Christensen     }
7084e400768SDavid Christensen 
7094e400768SDavid Christensen     estats->pause_frames_received_hi = pstats->mac_stx[1].rx_stat_mac_xpf_hi;
7104e400768SDavid Christensen     estats->pause_frames_received_lo = pstats->mac_stx[1].rx_stat_mac_xpf_lo;
7114e400768SDavid Christensen 
7124e400768SDavid Christensen     estats->pause_frames_sent_hi = pstats->mac_stx[1].tx_stat_outxoffsent_hi;
7134e400768SDavid Christensen     estats->pause_frames_sent_lo = pstats->mac_stx[1].tx_stat_outxoffsent_lo;
7144e400768SDavid Christensen 
7154e400768SDavid Christensen     estats->pfc_frames_received_hi = pstats->pfc_frames_rx_hi;
7164e400768SDavid Christensen     estats->pfc_frames_received_lo = pstats->pfc_frames_rx_lo;
7174e400768SDavid Christensen     estats->pfc_frames_sent_hi = pstats->pfc_frames_tx_hi;
7184e400768SDavid Christensen     estats->pfc_frames_sent_lo = pstats->pfc_frames_tx_lo;
7194e400768SDavid Christensen }
7204e400768SDavid Christensen 
7214e400768SDavid Christensen static void
bxe_mstat_stats_update(struct bxe_softc * sc)7224e400768SDavid Christensen bxe_mstat_stats_update(struct bxe_softc *sc)
7234e400768SDavid Christensen {
7244e400768SDavid Christensen     struct host_port_stats *pstats = BXE_SP(sc, port_stats);
7254e400768SDavid Christensen     struct bxe_eth_stats *estats = &sc->eth_stats;
7264e400768SDavid Christensen     struct mstat_stats *new = BXE_SP(sc, mac_stats.mstat_stats);
7274e400768SDavid Christensen 
7284e400768SDavid Christensen     ADD_STAT64(stats_rx.rx_grerb, rx_stat_ifhcinbadoctets);
7294e400768SDavid Christensen     ADD_STAT64(stats_rx.rx_grfcs, rx_stat_dot3statsfcserrors);
7304e400768SDavid Christensen     ADD_STAT64(stats_rx.rx_grund, rx_stat_etherstatsundersizepkts);
7314e400768SDavid Christensen     ADD_STAT64(stats_rx.rx_grovr, rx_stat_dot3statsframestoolong);
7324e400768SDavid Christensen     ADD_STAT64(stats_rx.rx_grfrg, rx_stat_etherstatsfragments);
7334e400768SDavid Christensen     ADD_STAT64(stats_rx.rx_grxcf, rx_stat_maccontrolframesreceived);
7344e400768SDavid Christensen     ADD_STAT64(stats_rx.rx_grxpf, rx_stat_xoffstateentered);
7354e400768SDavid Christensen     ADD_STAT64(stats_rx.rx_grxpf, rx_stat_mac_xpf);
7364e400768SDavid Christensen     ADD_STAT64(stats_tx.tx_gtxpf, tx_stat_outxoffsent);
7374e400768SDavid Christensen     ADD_STAT64(stats_tx.tx_gtxpf, tx_stat_flowcontroldone);
7384e400768SDavid Christensen 
7394e400768SDavid Christensen     /* collect pfc stats */
7404e400768SDavid Christensen     ADD_64(pstats->pfc_frames_tx_hi, new->stats_tx.tx_gtxpp_hi,
7414e400768SDavid Christensen            pstats->pfc_frames_tx_lo, new->stats_tx.tx_gtxpp_lo);
7424e400768SDavid Christensen     ADD_64(pstats->pfc_frames_rx_hi, new->stats_rx.rx_grxpp_hi,
7434e400768SDavid Christensen            pstats->pfc_frames_rx_lo, new->stats_rx.rx_grxpp_lo);
7444e400768SDavid Christensen 
7454e400768SDavid Christensen     ADD_STAT64(stats_tx.tx_gt64, tx_stat_etherstatspkts64octets);
7464e400768SDavid Christensen     ADD_STAT64(stats_tx.tx_gt127, tx_stat_etherstatspkts65octetsto127octets);
7474e400768SDavid Christensen     ADD_STAT64(stats_tx.tx_gt255, tx_stat_etherstatspkts128octetsto255octets);
7484e400768SDavid Christensen     ADD_STAT64(stats_tx.tx_gt511, tx_stat_etherstatspkts256octetsto511octets);
7494e400768SDavid Christensen     ADD_STAT64(stats_tx.tx_gt1023,
7504e400768SDavid Christensen                tx_stat_etherstatspkts512octetsto1023octets);
7514e400768SDavid Christensen     ADD_STAT64(stats_tx.tx_gt1518,
7524e400768SDavid Christensen                tx_stat_etherstatspkts1024octetsto1522octets);
7534e400768SDavid Christensen     ADD_STAT64(stats_tx.tx_gt2047, tx_stat_mac_2047);
7544e400768SDavid Christensen 
7554e400768SDavid Christensen     ADD_STAT64(stats_tx.tx_gt4095, tx_stat_mac_4095);
7564e400768SDavid Christensen     ADD_STAT64(stats_tx.tx_gt9216, tx_stat_mac_9216);
7574e400768SDavid Christensen     ADD_STAT64(stats_tx.tx_gt16383, tx_stat_mac_16383);
7584e400768SDavid Christensen 
7594e400768SDavid Christensen     ADD_STAT64(stats_tx.tx_gterr, tx_stat_dot3statsinternalmactransmiterrors);
7604e400768SDavid Christensen     ADD_STAT64(stats_tx.tx_gtufl, tx_stat_mac_ufl);
7614e400768SDavid Christensen 
7624e400768SDavid Christensen     estats->etherstatspkts1024octetsto1522octets_hi =
7634e400768SDavid Christensen         pstats->mac_stx[1].tx_stat_etherstatspkts1024octetsto1522octets_hi;
7644e400768SDavid Christensen     estats->etherstatspkts1024octetsto1522octets_lo =
7654e400768SDavid Christensen         pstats->mac_stx[1].tx_stat_etherstatspkts1024octetsto1522octets_lo;
7664e400768SDavid Christensen 
7674e400768SDavid Christensen     estats->etherstatspktsover1522octets_hi =
7684e400768SDavid Christensen         pstats->mac_stx[1].tx_stat_mac_2047_hi;
7694e400768SDavid Christensen     estats->etherstatspktsover1522octets_lo =
7704e400768SDavid Christensen         pstats->mac_stx[1].tx_stat_mac_2047_lo;
7714e400768SDavid Christensen 
7724e400768SDavid Christensen     ADD_64(estats->etherstatspktsover1522octets_hi,
7734e400768SDavid Christensen            pstats->mac_stx[1].tx_stat_mac_4095_hi,
7744e400768SDavid Christensen            estats->etherstatspktsover1522octets_lo,
7754e400768SDavid Christensen            pstats->mac_stx[1].tx_stat_mac_4095_lo);
7764e400768SDavid Christensen 
7774e400768SDavid Christensen     ADD_64(estats->etherstatspktsover1522octets_hi,
7784e400768SDavid Christensen            pstats->mac_stx[1].tx_stat_mac_9216_hi,
7794e400768SDavid Christensen            estats->etherstatspktsover1522octets_lo,
7804e400768SDavid Christensen            pstats->mac_stx[1].tx_stat_mac_9216_lo);
7814e400768SDavid Christensen 
7824e400768SDavid Christensen     ADD_64(estats->etherstatspktsover1522octets_hi,
7834e400768SDavid Christensen            pstats->mac_stx[1].tx_stat_mac_16383_hi,
7844e400768SDavid Christensen            estats->etherstatspktsover1522octets_lo,
7854e400768SDavid Christensen            pstats->mac_stx[1].tx_stat_mac_16383_lo);
7864e400768SDavid Christensen 
7874e400768SDavid Christensen     estats->pause_frames_received_hi = pstats->mac_stx[1].rx_stat_mac_xpf_hi;
7884e400768SDavid Christensen     estats->pause_frames_received_lo = pstats->mac_stx[1].rx_stat_mac_xpf_lo;
7894e400768SDavid Christensen 
7904e400768SDavid Christensen     estats->pause_frames_sent_hi = pstats->mac_stx[1].tx_stat_outxoffsent_hi;
7914e400768SDavid Christensen     estats->pause_frames_sent_lo = pstats->mac_stx[1].tx_stat_outxoffsent_lo;
7924e400768SDavid Christensen 
7934e400768SDavid Christensen     estats->pfc_frames_received_hi = pstats->pfc_frames_rx_hi;
7944e400768SDavid Christensen     estats->pfc_frames_received_lo = pstats->pfc_frames_rx_lo;
7954e400768SDavid Christensen     estats->pfc_frames_sent_hi = pstats->pfc_frames_tx_hi;
7964e400768SDavid Christensen     estats->pfc_frames_sent_lo = pstats->pfc_frames_tx_lo;
7974e400768SDavid Christensen }
7984e400768SDavid Christensen 
7994e400768SDavid Christensen static void
bxe_emac_stats_update(struct bxe_softc * sc)8004e400768SDavid Christensen bxe_emac_stats_update(struct bxe_softc *sc)
8014e400768SDavid Christensen {
8024e400768SDavid Christensen     struct emac_stats *new = BXE_SP(sc, mac_stats.emac_stats);
8034e400768SDavid Christensen     struct host_port_stats *pstats = BXE_SP(sc, port_stats);
8044e400768SDavid Christensen     struct bxe_eth_stats *estats = &sc->eth_stats;
8054e400768SDavid Christensen 
8064e400768SDavid Christensen     UPDATE_EXTEND_STAT(rx_stat_ifhcinbadoctets);
8074e400768SDavid Christensen     UPDATE_EXTEND_STAT(tx_stat_ifhcoutbadoctets);
8084e400768SDavid Christensen     UPDATE_EXTEND_STAT(rx_stat_dot3statsfcserrors);
8094e400768SDavid Christensen     UPDATE_EXTEND_STAT(rx_stat_dot3statsalignmenterrors);
8104e400768SDavid Christensen     UPDATE_EXTEND_STAT(rx_stat_dot3statscarriersenseerrors);
8114e400768SDavid Christensen     UPDATE_EXTEND_STAT(rx_stat_falsecarriererrors);
8124e400768SDavid Christensen     UPDATE_EXTEND_STAT(rx_stat_etherstatsundersizepkts);
8134e400768SDavid Christensen     UPDATE_EXTEND_STAT(rx_stat_dot3statsframestoolong);
8144e400768SDavid Christensen     UPDATE_EXTEND_STAT(rx_stat_etherstatsfragments);
8154e400768SDavid Christensen     UPDATE_EXTEND_STAT(rx_stat_etherstatsjabbers);
8164e400768SDavid Christensen     UPDATE_EXTEND_STAT(rx_stat_maccontrolframesreceived);
8174e400768SDavid Christensen     UPDATE_EXTEND_STAT(rx_stat_xoffstateentered);
8184e400768SDavid Christensen     UPDATE_EXTEND_STAT(rx_stat_xonpauseframesreceived);
8194e400768SDavid Christensen     UPDATE_EXTEND_STAT(rx_stat_xoffpauseframesreceived);
8204e400768SDavid Christensen     UPDATE_EXTEND_STAT(tx_stat_outxonsent);
8214e400768SDavid Christensen     UPDATE_EXTEND_STAT(tx_stat_outxoffsent);
8224e400768SDavid Christensen     UPDATE_EXTEND_STAT(tx_stat_flowcontroldone);
8234e400768SDavid Christensen     UPDATE_EXTEND_STAT(tx_stat_etherstatscollisions);
8244e400768SDavid Christensen     UPDATE_EXTEND_STAT(tx_stat_dot3statssinglecollisionframes);
8254e400768SDavid Christensen     UPDATE_EXTEND_STAT(tx_stat_dot3statsmultiplecollisionframes);
8264e400768SDavid Christensen     UPDATE_EXTEND_STAT(tx_stat_dot3statsdeferredtransmissions);
8274e400768SDavid Christensen     UPDATE_EXTEND_STAT(tx_stat_dot3statsexcessivecollisions);
8284e400768SDavid Christensen     UPDATE_EXTEND_STAT(tx_stat_dot3statslatecollisions);
8294e400768SDavid Christensen     UPDATE_EXTEND_STAT(tx_stat_etherstatspkts64octets);
8304e400768SDavid Christensen     UPDATE_EXTEND_STAT(tx_stat_etherstatspkts65octetsto127octets);
8314e400768SDavid Christensen     UPDATE_EXTEND_STAT(tx_stat_etherstatspkts128octetsto255octets);
8324e400768SDavid Christensen     UPDATE_EXTEND_STAT(tx_stat_etherstatspkts256octetsto511octets);
8334e400768SDavid Christensen     UPDATE_EXTEND_STAT(tx_stat_etherstatspkts512octetsto1023octets);
8344e400768SDavid Christensen     UPDATE_EXTEND_STAT(tx_stat_etherstatspkts1024octetsto1522octets);
8354e400768SDavid Christensen     UPDATE_EXTEND_STAT(tx_stat_etherstatspktsover1522octets);
8364e400768SDavid Christensen     UPDATE_EXTEND_STAT(tx_stat_dot3statsinternalmactransmiterrors);
8374e400768SDavid Christensen 
8384e400768SDavid Christensen     estats->pause_frames_received_hi =
8394e400768SDavid Christensen         pstats->mac_stx[1].rx_stat_xonpauseframesreceived_hi;
8404e400768SDavid Christensen     estats->pause_frames_received_lo =
8414e400768SDavid Christensen         pstats->mac_stx[1].rx_stat_xonpauseframesreceived_lo;
8424e400768SDavid Christensen     ADD_64(estats->pause_frames_received_hi,
8434e400768SDavid Christensen            pstats->mac_stx[1].rx_stat_xoffpauseframesreceived_hi,
8444e400768SDavid Christensen            estats->pause_frames_received_lo,
8454e400768SDavid Christensen            pstats->mac_stx[1].rx_stat_xoffpauseframesreceived_lo);
8464e400768SDavid Christensen 
8474e400768SDavid Christensen     estats->pause_frames_sent_hi =
8484e400768SDavid Christensen         pstats->mac_stx[1].tx_stat_outxonsent_hi;
8494e400768SDavid Christensen     estats->pause_frames_sent_lo =
8504e400768SDavid Christensen         pstats->mac_stx[1].tx_stat_outxonsent_lo;
8514e400768SDavid Christensen     ADD_64(estats->pause_frames_sent_hi,
8524e400768SDavid Christensen            pstats->mac_stx[1].tx_stat_outxoffsent_hi,
8534e400768SDavid Christensen            estats->pause_frames_sent_lo,
8544e400768SDavid Christensen            pstats->mac_stx[1].tx_stat_outxoffsent_lo);
8554e400768SDavid Christensen }
8564e400768SDavid Christensen 
8574e400768SDavid Christensen static int
bxe_hw_stats_update(struct bxe_softc * sc)8584e400768SDavid Christensen bxe_hw_stats_update(struct bxe_softc *sc)
8594e400768SDavid Christensen {
8604e400768SDavid Christensen     struct nig_stats *new = BXE_SP(sc, nig_stats);
8614e400768SDavid Christensen     struct nig_stats *old = &(sc->port.old_nig_stats);
8624e400768SDavid Christensen     struct host_port_stats *pstats = BXE_SP(sc, port_stats);
8634e400768SDavid Christensen     struct bxe_eth_stats *estats = &sc->eth_stats;
8644e400768SDavid Christensen     uint32_t lpi_reg, nig_timer_max;
8654e400768SDavid Christensen     struct {
8664e400768SDavid Christensen         uint32_t lo;
8674e400768SDavid Christensen         uint32_t hi;
8684e400768SDavid Christensen     } diff;
8694e400768SDavid Christensen 
8704e400768SDavid Christensen     switch (sc->link_vars.mac_type) {
8714e400768SDavid Christensen     case ELINK_MAC_TYPE_BMAC:
8724e400768SDavid Christensen         bxe_bmac_stats_update(sc);
8734e400768SDavid Christensen         break;
8744e400768SDavid Christensen 
8754e400768SDavid Christensen     case ELINK_MAC_TYPE_EMAC:
8764e400768SDavid Christensen         bxe_emac_stats_update(sc);
8774e400768SDavid Christensen         break;
8784e400768SDavid Christensen 
8794e400768SDavid Christensen     case ELINK_MAC_TYPE_UMAC:
8804e400768SDavid Christensen     case ELINK_MAC_TYPE_XMAC:
8814e400768SDavid Christensen         bxe_mstat_stats_update(sc);
8824e400768SDavid Christensen         break;
8834e400768SDavid Christensen 
8844e400768SDavid Christensen     case ELINK_MAC_TYPE_NONE: /* unreached */
8854e400768SDavid Christensen         BLOGD(sc, DBG_STATS,
8864e400768SDavid Christensen               "stats updated by DMAE but no MAC active\n");
8874e400768SDavid Christensen         return (-1);
8884e400768SDavid Christensen 
8894e400768SDavid Christensen     default: /* unreached */
8904e400768SDavid Christensen         BLOGE(sc, "stats update failed, unknown MAC type\n");
8914e400768SDavid Christensen     }
8924e400768SDavid Christensen 
8934e400768SDavid Christensen     ADD_EXTEND_64(pstats->brb_drop_hi, pstats->brb_drop_lo,
8944e400768SDavid Christensen                   new->brb_discard - old->brb_discard);
8954e400768SDavid Christensen     ADD_EXTEND_64(estats->brb_truncate_hi, estats->brb_truncate_lo,
8964e400768SDavid Christensen                   new->brb_truncate - old->brb_truncate);
8974e400768SDavid Christensen 
8984e400768SDavid Christensen     if (!CHIP_IS_E3(sc)) {
8994e400768SDavid Christensen         UPDATE_STAT64_NIG(egress_mac_pkt0,
9004e400768SDavid Christensen                           etherstatspkts1024octetsto1522octets);
9014e400768SDavid Christensen         UPDATE_STAT64_NIG(egress_mac_pkt1,
9024e400768SDavid Christensen                           etherstatspktsover1522octets);
9034e400768SDavid Christensen     }
9044e400768SDavid Christensen 
9054e400768SDavid Christensen     memcpy(old, new, sizeof(struct nig_stats));
9064e400768SDavid Christensen 
9074e400768SDavid Christensen     memcpy(&(estats->rx_stat_ifhcinbadoctets_hi), &(pstats->mac_stx[1]),
9084e400768SDavid Christensen            sizeof(struct mac_stx));
9094e400768SDavid Christensen     estats->brb_drop_hi = pstats->brb_drop_hi;
9104e400768SDavid Christensen     estats->brb_drop_lo = pstats->brb_drop_lo;
9114e400768SDavid Christensen 
9124e400768SDavid Christensen     pstats->host_port_stats_counter++;
9134e400768SDavid Christensen 
9144e400768SDavid Christensen     if (CHIP_IS_E3(sc)) {
9154e400768SDavid Christensen         lpi_reg = (SC_PORT(sc)) ?
9164e400768SDavid Christensen                       MISC_REG_CPMU_LP_SM_ENT_CNT_P1 :
9174e400768SDavid Christensen                       MISC_REG_CPMU_LP_SM_ENT_CNT_P0;
9184e400768SDavid Christensen         estats->eee_tx_lpi += REG_RD(sc, lpi_reg);
9194e400768SDavid Christensen     }
9204e400768SDavid Christensen 
9214e400768SDavid Christensen     if (!BXE_NOMCP(sc)) {
9224e400768SDavid Christensen         nig_timer_max = SHMEM_RD(sc, port_mb[SC_PORT(sc)].stat_nig_timer);
9234e400768SDavid Christensen         if (nig_timer_max != estats->nig_timer_max) {
9244e400768SDavid Christensen             estats->nig_timer_max = nig_timer_max;
925*36baf17eSDavid C Somayajulu 	    /*NOTE: not setting error bit */
9264e400768SDavid Christensen             BLOGE(sc, "invalid NIG timer max (%u)\n",
9274e400768SDavid Christensen                   estats->nig_timer_max);
9284e400768SDavid Christensen         }
9294e400768SDavid Christensen     }
9304e400768SDavid Christensen 
9314e400768SDavid Christensen     return (0);
9324e400768SDavid Christensen }
9334e400768SDavid Christensen 
9344e400768SDavid Christensen static int
bxe_storm_stats_validate_counters(struct bxe_softc * sc)9354e400768SDavid Christensen bxe_storm_stats_validate_counters(struct bxe_softc *sc)
9364e400768SDavid Christensen {
9374e400768SDavid Christensen     struct stats_counter *counters = &sc->fw_stats_data->storm_counters;
9384e400768SDavid Christensen     uint16_t cur_stats_counter;
9394e400768SDavid Christensen 
9404e400768SDavid Christensen     /*
9414e400768SDavid Christensen      * Make sure we use the value of the counter
9424e400768SDavid Christensen      * used for sending the last stats ramrod.
9434e400768SDavid Christensen      */
9444e400768SDavid Christensen     BXE_STATS_LOCK(sc);
9454e400768SDavid Christensen     cur_stats_counter = (sc->stats_counter - 1);
9464e400768SDavid Christensen     BXE_STATS_UNLOCK(sc);
9474e400768SDavid Christensen 
9484e400768SDavid Christensen     /* are storm stats valid? */
9494e400768SDavid Christensen     if (le16toh(counters->xstats_counter) != cur_stats_counter) {
9504e400768SDavid Christensen         BLOGD(sc, DBG_STATS,
9514e400768SDavid Christensen               "stats not updated by xstorm, "
9524e400768SDavid Christensen               "counter 0x%x != stats_counter 0x%x\n",
9534e400768SDavid Christensen               le16toh(counters->xstats_counter), sc->stats_counter);
9544e400768SDavid Christensen         return (-EAGAIN);
9554e400768SDavid Christensen     }
9564e400768SDavid Christensen 
9574e400768SDavid Christensen     if (le16toh(counters->ustats_counter) != cur_stats_counter) {
9584e400768SDavid Christensen         BLOGD(sc, DBG_STATS,
9594e400768SDavid Christensen               "stats not updated by ustorm, "
9604e400768SDavid Christensen               "counter 0x%x != stats_counter 0x%x\n",
9614e400768SDavid Christensen               le16toh(counters->ustats_counter), sc->stats_counter);
9624e400768SDavid Christensen         return (-EAGAIN);
9634e400768SDavid Christensen     }
9644e400768SDavid Christensen 
9654e400768SDavid Christensen     if (le16toh(counters->cstats_counter) != cur_stats_counter) {
9664e400768SDavid Christensen         BLOGD(sc, DBG_STATS,
9674e400768SDavid Christensen               "stats not updated by cstorm, "
9684e400768SDavid Christensen               "counter 0x%x != stats_counter 0x%x\n",
9694e400768SDavid Christensen               le16toh(counters->cstats_counter), sc->stats_counter);
9704e400768SDavid Christensen         return (-EAGAIN);
9714e400768SDavid Christensen     }
9724e400768SDavid Christensen 
9734e400768SDavid Christensen     if (le16toh(counters->tstats_counter) != cur_stats_counter) {
9744e400768SDavid Christensen         BLOGD(sc, DBG_STATS,
9754e400768SDavid Christensen               "stats not updated by tstorm, "
9764e400768SDavid Christensen               "counter 0x%x != stats_counter 0x%x\n",
9774e400768SDavid Christensen               le16toh(counters->tstats_counter), sc->stats_counter);
9784e400768SDavid Christensen         return (-EAGAIN);
9794e400768SDavid Christensen     }
9804e400768SDavid Christensen 
9814e400768SDavid Christensen     return (0);
9824e400768SDavid Christensen }
9834e400768SDavid Christensen 
9844e400768SDavid Christensen static int
bxe_storm_stats_update(struct bxe_softc * sc)9854e400768SDavid Christensen bxe_storm_stats_update(struct bxe_softc *sc)
9864e400768SDavid Christensen {
9874e400768SDavid Christensen     struct tstorm_per_port_stats *tport =
9884e400768SDavid Christensen         &sc->fw_stats_data->port.tstorm_port_statistics;
9894e400768SDavid Christensen     struct tstorm_per_pf_stats *tfunc =
9904e400768SDavid Christensen         &sc->fw_stats_data->pf.tstorm_pf_statistics;
9914e400768SDavid Christensen     struct host_func_stats *fstats = &sc->func_stats;
9924e400768SDavid Christensen     struct bxe_eth_stats *estats = &sc->eth_stats;
9934e400768SDavid Christensen     struct bxe_eth_stats_old *estats_old = &sc->eth_stats_old;
9944e400768SDavid Christensen     int i;
9954e400768SDavid Christensen 
9964e400768SDavid Christensen     /* vfs stat counter is managed by pf */
9974e400768SDavid Christensen     if (IS_PF(sc) && bxe_storm_stats_validate_counters(sc)) {
9984e400768SDavid Christensen         return (-EAGAIN);
9994e400768SDavid Christensen     }
10004e400768SDavid Christensen 
10014e400768SDavid Christensen     estats->error_bytes_received_hi = 0;
10024e400768SDavid Christensen     estats->error_bytes_received_lo = 0;
10034e400768SDavid Christensen 
10044e400768SDavid Christensen     for (i = 0; i < sc->num_queues; i++) {
10054e400768SDavid Christensen         struct bxe_fastpath *fp = &sc->fp[i];
10064e400768SDavid Christensen         struct tstorm_per_queue_stats *tclient =
10074e400768SDavid Christensen             &sc->fw_stats_data->queue_stats[i].tstorm_queue_statistics;
10084e400768SDavid Christensen         struct tstorm_per_queue_stats *old_tclient = &fp->old_tclient;
10094e400768SDavid Christensen         struct ustorm_per_queue_stats *uclient =
10104e400768SDavid Christensen             &sc->fw_stats_data->queue_stats[i].ustorm_queue_statistics;
10114e400768SDavid Christensen         struct ustorm_per_queue_stats *old_uclient = &fp->old_uclient;
10124e400768SDavid Christensen         struct xstorm_per_queue_stats *xclient =
10134e400768SDavid Christensen             &sc->fw_stats_data->queue_stats[i].xstorm_queue_statistics;
10144e400768SDavid Christensen         struct xstorm_per_queue_stats *old_xclient = &fp->old_xclient;
10154e400768SDavid Christensen         struct bxe_eth_q_stats *qstats = &fp->eth_q_stats;
10164e400768SDavid Christensen         struct bxe_eth_q_stats_old *qstats_old = &fp->eth_q_stats_old;
10174e400768SDavid Christensen 
10184e400768SDavid Christensen         uint32_t diff;
10194e400768SDavid Christensen 
10204e400768SDavid Christensen         BLOGD(sc, DBG_STATS,
10214e400768SDavid Christensen               "queue[%d]: ucast_sent 0x%x bcast_sent 0x%x mcast_sent 0x%x\n",
10224e400768SDavid Christensen               i, xclient->ucast_pkts_sent, xclient->bcast_pkts_sent,
10234e400768SDavid Christensen               xclient->mcast_pkts_sent);
10244e400768SDavid Christensen 
10254e400768SDavid Christensen         BLOGD(sc, DBG_STATS, "---------------\n");
10264e400768SDavid Christensen 
10274e400768SDavid Christensen         UPDATE_QSTAT(tclient->rcv_bcast_bytes,
10284e400768SDavid Christensen                      total_broadcast_bytes_received);
10294e400768SDavid Christensen         UPDATE_QSTAT(tclient->rcv_mcast_bytes,
10304e400768SDavid Christensen                      total_multicast_bytes_received);
10314e400768SDavid Christensen         UPDATE_QSTAT(tclient->rcv_ucast_bytes,
10324e400768SDavid Christensen                      total_unicast_bytes_received);
10334e400768SDavid Christensen 
10344e400768SDavid Christensen         /*
10354e400768SDavid Christensen          * sum to total_bytes_received all
10364e400768SDavid Christensen          * unicast/multicast/broadcast
10374e400768SDavid Christensen          */
10384e400768SDavid Christensen         qstats->total_bytes_received_hi =
10394e400768SDavid Christensen             qstats->total_broadcast_bytes_received_hi;
10404e400768SDavid Christensen         qstats->total_bytes_received_lo =
10414e400768SDavid Christensen             qstats->total_broadcast_bytes_received_lo;
10424e400768SDavid Christensen 
10434e400768SDavid Christensen         ADD_64(qstats->total_bytes_received_hi,
10444e400768SDavid Christensen                qstats->total_multicast_bytes_received_hi,
10454e400768SDavid Christensen                qstats->total_bytes_received_lo,
10464e400768SDavid Christensen                qstats->total_multicast_bytes_received_lo);
10474e400768SDavid Christensen 
10484e400768SDavid Christensen         ADD_64(qstats->total_bytes_received_hi,
10494e400768SDavid Christensen                qstats->total_unicast_bytes_received_hi,
10504e400768SDavid Christensen                qstats->total_bytes_received_lo,
10514e400768SDavid Christensen                qstats->total_unicast_bytes_received_lo);
10524e400768SDavid Christensen 
10534e400768SDavid Christensen         qstats->valid_bytes_received_hi = qstats->total_bytes_received_hi;
10544e400768SDavid Christensen         qstats->valid_bytes_received_lo = qstats->total_bytes_received_lo;
10554e400768SDavid Christensen 
10564e400768SDavid Christensen         UPDATE_EXTEND_TSTAT(rcv_ucast_pkts, total_unicast_packets_received);
10574e400768SDavid Christensen         UPDATE_EXTEND_TSTAT(rcv_mcast_pkts, total_multicast_packets_received);
10584e400768SDavid Christensen         UPDATE_EXTEND_TSTAT(rcv_bcast_pkts, total_broadcast_packets_received);
10594e400768SDavid Christensen         UPDATE_EXTEND_E_TSTAT(pkts_too_big_discard,
10604e400768SDavid Christensen                               etherstatsoverrsizepkts, 32);
10614e400768SDavid Christensen         UPDATE_EXTEND_E_TSTAT(no_buff_discard, no_buff_discard, 16);
10624e400768SDavid Christensen 
10634e400768SDavid Christensen         SUB_EXTEND_USTAT(ucast_no_buff_pkts, total_unicast_packets_received);
10644e400768SDavid Christensen         SUB_EXTEND_USTAT(mcast_no_buff_pkts,
10654e400768SDavid Christensen                          total_multicast_packets_received);
10664e400768SDavid Christensen         SUB_EXTEND_USTAT(bcast_no_buff_pkts,
10674e400768SDavid Christensen                          total_broadcast_packets_received);
10684e400768SDavid Christensen         UPDATE_EXTEND_E_USTAT(ucast_no_buff_pkts, no_buff_discard);
10694e400768SDavid Christensen         UPDATE_EXTEND_E_USTAT(mcast_no_buff_pkts, no_buff_discard);
10704e400768SDavid Christensen         UPDATE_EXTEND_E_USTAT(bcast_no_buff_pkts, no_buff_discard);
10714e400768SDavid Christensen 
10724e400768SDavid Christensen         UPDATE_QSTAT(xclient->bcast_bytes_sent,
10734e400768SDavid Christensen                      total_broadcast_bytes_transmitted);
10744e400768SDavid Christensen         UPDATE_QSTAT(xclient->mcast_bytes_sent,
10754e400768SDavid Christensen                      total_multicast_bytes_transmitted);
10764e400768SDavid Christensen         UPDATE_QSTAT(xclient->ucast_bytes_sent,
10774e400768SDavid Christensen                      total_unicast_bytes_transmitted);
10784e400768SDavid Christensen 
10794e400768SDavid Christensen         /*
10804e400768SDavid Christensen          * sum to total_bytes_transmitted all
10814e400768SDavid Christensen          * unicast/multicast/broadcast
10824e400768SDavid Christensen          */
10834e400768SDavid Christensen         qstats->total_bytes_transmitted_hi =
10844e400768SDavid Christensen             qstats->total_unicast_bytes_transmitted_hi;
10854e400768SDavid Christensen         qstats->total_bytes_transmitted_lo =
10864e400768SDavid Christensen             qstats->total_unicast_bytes_transmitted_lo;
10874e400768SDavid Christensen 
10884e400768SDavid Christensen         ADD_64(qstats->total_bytes_transmitted_hi,
10894e400768SDavid Christensen                qstats->total_broadcast_bytes_transmitted_hi,
10904e400768SDavid Christensen                qstats->total_bytes_transmitted_lo,
10914e400768SDavid Christensen                qstats->total_broadcast_bytes_transmitted_lo);
10924e400768SDavid Christensen 
10934e400768SDavid Christensen         ADD_64(qstats->total_bytes_transmitted_hi,
10944e400768SDavid Christensen                qstats->total_multicast_bytes_transmitted_hi,
10954e400768SDavid Christensen                qstats->total_bytes_transmitted_lo,
10964e400768SDavid Christensen                qstats->total_multicast_bytes_transmitted_lo);
10974e400768SDavid Christensen 
10984e400768SDavid Christensen         UPDATE_EXTEND_XSTAT(ucast_pkts_sent,
10994e400768SDavid Christensen                             total_unicast_packets_transmitted);
11004e400768SDavid Christensen         UPDATE_EXTEND_XSTAT(mcast_pkts_sent,
11014e400768SDavid Christensen                             total_multicast_packets_transmitted);
11024e400768SDavid Christensen         UPDATE_EXTEND_XSTAT(bcast_pkts_sent,
11034e400768SDavid Christensen                             total_broadcast_packets_transmitted);
11044e400768SDavid Christensen 
11054e400768SDavid Christensen         UPDATE_EXTEND_TSTAT(checksum_discard,
11064e400768SDavid Christensen                             total_packets_received_checksum_discarded);
11074e400768SDavid Christensen         UPDATE_EXTEND_TSTAT(ttl0_discard,
11084e400768SDavid Christensen                             total_packets_received_ttl0_discarded);
11094e400768SDavid Christensen 
11104e400768SDavid Christensen         UPDATE_EXTEND_XSTAT(error_drop_pkts,
11114e400768SDavid Christensen                             total_transmitted_dropped_packets_error);
11124e400768SDavid Christensen 
11134e400768SDavid Christensen         /* TPA aggregations completed */
11144e400768SDavid Christensen         UPDATE_EXTEND_E_USTAT(coalesced_events, total_tpa_aggregations);
11154e400768SDavid Christensen         /* Number of network frames aggregated by TPA */
11164e400768SDavid Christensen         UPDATE_EXTEND_E_USTAT(coalesced_pkts, total_tpa_aggregated_frames);
11174e400768SDavid Christensen         /* Total number of bytes in completed TPA aggregations */
11184e400768SDavid Christensen         UPDATE_QSTAT(uclient->coalesced_bytes, total_tpa_bytes);
11194e400768SDavid Christensen 
11204e400768SDavid Christensen         UPDATE_ESTAT_QSTAT_64(total_tpa_bytes);
11214e400768SDavid Christensen 
11224e400768SDavid Christensen         UPDATE_FSTAT_QSTAT(total_bytes_received);
11234e400768SDavid Christensen         UPDATE_FSTAT_QSTAT(total_bytes_transmitted);
11244e400768SDavid Christensen         UPDATE_FSTAT_QSTAT(total_unicast_packets_received);
11254e400768SDavid Christensen         UPDATE_FSTAT_QSTAT(total_multicast_packets_received);
11264e400768SDavid Christensen         UPDATE_FSTAT_QSTAT(total_broadcast_packets_received);
11274e400768SDavid Christensen         UPDATE_FSTAT_QSTAT(total_unicast_packets_transmitted);
11284e400768SDavid Christensen         UPDATE_FSTAT_QSTAT(total_multicast_packets_transmitted);
11294e400768SDavid Christensen         UPDATE_FSTAT_QSTAT(total_broadcast_packets_transmitted);
11304e400768SDavid Christensen         UPDATE_FSTAT_QSTAT(valid_bytes_received);
11314e400768SDavid Christensen     }
11324e400768SDavid Christensen 
11334e400768SDavid Christensen     ADD_64(estats->total_bytes_received_hi,
11344e400768SDavid Christensen            estats->rx_stat_ifhcinbadoctets_hi,
11354e400768SDavid Christensen            estats->total_bytes_received_lo,
11364e400768SDavid Christensen            estats->rx_stat_ifhcinbadoctets_lo);
11374e400768SDavid Christensen 
11384e400768SDavid Christensen     ADD_64_LE(estats->total_bytes_received_hi,
11394e400768SDavid Christensen               tfunc->rcv_error_bytes.hi,
11404e400768SDavid Christensen               estats->total_bytes_received_lo,
11414e400768SDavid Christensen               tfunc->rcv_error_bytes.lo);
11424e400768SDavid Christensen 
11434e400768SDavid Christensen     ADD_64_LE(estats->error_bytes_received_hi,
11444e400768SDavid Christensen               tfunc->rcv_error_bytes.hi,
11454e400768SDavid Christensen               estats->error_bytes_received_lo,
11464e400768SDavid Christensen               tfunc->rcv_error_bytes.lo);
11474e400768SDavid Christensen 
11484e400768SDavid Christensen     UPDATE_ESTAT(etherstatsoverrsizepkts, rx_stat_dot3statsframestoolong);
11494e400768SDavid Christensen 
11504e400768SDavid Christensen     ADD_64(estats->error_bytes_received_hi,
11514e400768SDavid Christensen            estats->rx_stat_ifhcinbadoctets_hi,
11524e400768SDavid Christensen            estats->error_bytes_received_lo,
11534e400768SDavid Christensen            estats->rx_stat_ifhcinbadoctets_lo);
11544e400768SDavid Christensen 
11554e400768SDavid Christensen     if (sc->port.pmf) {
11564e400768SDavid Christensen         struct bxe_fw_port_stats_old *fwstats = &sc->fw_stats_old;
11574e400768SDavid Christensen         UPDATE_FW_STAT(mac_filter_discard);
11584e400768SDavid Christensen         UPDATE_FW_STAT(mf_tag_discard);
11594e400768SDavid Christensen         UPDATE_FW_STAT(brb_truncate_discard);
11604e400768SDavid Christensen         UPDATE_FW_STAT(mac_discard);
11614e400768SDavid Christensen     }
11624e400768SDavid Christensen 
11634e400768SDavid Christensen     fstats->host_func_stats_start = ++fstats->host_func_stats_end;
11644e400768SDavid Christensen 
11654e400768SDavid Christensen     sc->stats_pending = 0;
11664e400768SDavid Christensen 
11674e400768SDavid Christensen     return (0);
11684e400768SDavid Christensen }
11694e400768SDavid Christensen 
11704e400768SDavid Christensen static void
bxe_net_stats_update(struct bxe_softc * sc)11714e400768SDavid Christensen bxe_net_stats_update(struct bxe_softc *sc)
11724e400768SDavid Christensen {
11734e400768SDavid Christensen 
1174df360178SGleb Smirnoff     for (int i = 0; i < sc->num_queues; i++)
1175df360178SGleb Smirnoff         if_inc_counter(sc->ifp, IFCOUNTER_IQDROPS,
1176df360178SGleb Smirnoff 	    le32toh(sc->fp[i].old_tclient.checksum_discard));
11774e400768SDavid Christensen }
11784e400768SDavid Christensen 
1179df360178SGleb Smirnoff uint64_t
bxe_get_counter(if_t ifp,ift_counter cnt)1180df360178SGleb Smirnoff bxe_get_counter(if_t ifp, ift_counter cnt)
1181df360178SGleb Smirnoff {
1182df360178SGleb Smirnoff 	struct bxe_softc *sc;
1183df360178SGleb Smirnoff 	struct bxe_eth_stats *estats;
1184df360178SGleb Smirnoff 
1185df360178SGleb Smirnoff 	sc = if_getsoftc(ifp);
1186df360178SGleb Smirnoff 	estats = &sc->eth_stats;
1187df360178SGleb Smirnoff 
1188df360178SGleb Smirnoff 	switch (cnt) {
1189df360178SGleb Smirnoff 	case IFCOUNTER_IPACKETS:
1190df360178SGleb Smirnoff 		return (bxe_hilo(&estats->total_unicast_packets_received_hi) +
1191df360178SGleb Smirnoff 		    bxe_hilo(&estats->total_multicast_packets_received_hi) +
1192df360178SGleb Smirnoff 		    bxe_hilo(&estats->total_broadcast_packets_received_hi));
1193df360178SGleb Smirnoff 	case IFCOUNTER_OPACKETS:
1194df360178SGleb Smirnoff 		return (bxe_hilo(&estats->total_unicast_packets_transmitted_hi) +
1195df360178SGleb Smirnoff 		    bxe_hilo(&estats->total_multicast_packets_transmitted_hi) +
1196df360178SGleb Smirnoff 		    bxe_hilo(&estats->total_broadcast_packets_transmitted_hi));
1197df360178SGleb Smirnoff 	case IFCOUNTER_IBYTES:
1198df360178SGleb Smirnoff 		return (bxe_hilo(&estats->total_bytes_received_hi));
1199df360178SGleb Smirnoff 	case IFCOUNTER_OBYTES:
1200df360178SGleb Smirnoff 		return (bxe_hilo(&estats->total_bytes_transmitted_hi));
1201df360178SGleb Smirnoff 	case IFCOUNTER_IERRORS:
1202df360178SGleb Smirnoff 		return (bxe_hilo(&estats->rx_stat_etherstatsundersizepkts_hi) +
12034e400768SDavid Christensen 		    bxe_hilo(&estats->etherstatsoverrsizepkts_hi) +
12044e400768SDavid Christensen 		    bxe_hilo(&estats->brb_drop_hi) +
12054e400768SDavid Christensen 		    bxe_hilo(&estats->brb_truncate_hi) +
12064e400768SDavid Christensen 		    bxe_hilo(&estats->rx_stat_dot3statsfcserrors_hi) +
12074e400768SDavid Christensen 		    bxe_hilo(&estats->rx_stat_dot3statsalignmenterrors_hi) +
1208717568adSMarcel Moolenaar 		    bxe_hilo(&estats->no_buff_discard_hi));
1209df360178SGleb Smirnoff 	case IFCOUNTER_OERRORS:
1210df360178SGleb Smirnoff 		return (bxe_hilo(&estats->rx_stat_dot3statscarriersenseerrors_hi) +
1211717568adSMarcel Moolenaar 		    bxe_hilo(&estats->tx_stat_dot3statsinternalmactransmiterrors_hi));
1212df360178SGleb Smirnoff 	case IFCOUNTER_IMCASTS:
1213df360178SGleb Smirnoff 		return (bxe_hilo(&estats->total_multicast_packets_received_hi));
1214df360178SGleb Smirnoff 	case IFCOUNTER_COLLISIONS:
1215df360178SGleb Smirnoff 		return (bxe_hilo(&estats->tx_stat_etherstatscollisions_hi) +
12164e400768SDavid Christensen 		    bxe_hilo(&estats->tx_stat_dot3statslatecollisions_hi) +
1217717568adSMarcel Moolenaar 		    bxe_hilo(&estats->tx_stat_dot3statsexcessivecollisions_hi));
1218df360178SGleb Smirnoff 	default:
1219df360178SGleb Smirnoff 		return (if_get_counter_default(ifp, cnt));
1220df360178SGleb Smirnoff 	}
12214e400768SDavid Christensen }
12224e400768SDavid Christensen 
12234e400768SDavid Christensen static void
bxe_drv_stats_update(struct bxe_softc * sc)12244e400768SDavid Christensen bxe_drv_stats_update(struct bxe_softc *sc)
12254e400768SDavid Christensen {
12264e400768SDavid Christensen     struct bxe_eth_stats *estats = &sc->eth_stats;
12274e400768SDavid Christensen     int i;
12284e400768SDavid Christensen 
12294e400768SDavid Christensen     for (i = 0; i < sc->num_queues; i++) {
12304e400768SDavid Christensen         struct bxe_eth_q_stats *qstats = &sc->fp[i].eth_q_stats;
12314e400768SDavid Christensen         struct bxe_eth_q_stats_old *qstats_old = &sc->fp[i].eth_q_stats_old;
12324e400768SDavid Christensen 
12334e400768SDavid Christensen         UPDATE_ESTAT_QSTAT(rx_calls);
12344e400768SDavid Christensen         UPDATE_ESTAT_QSTAT(rx_pkts);
12354e400768SDavid Christensen         UPDATE_ESTAT_QSTAT(rx_tpa_pkts);
12366dbbc5f6SDavid C Somayajulu         UPDATE_ESTAT_QSTAT(rx_erroneous_jumbo_sge_pkts);
12376dbbc5f6SDavid C Somayajulu         UPDATE_ESTAT_QSTAT(rx_bxe_service_rxsgl);
1238bfdeba0cSDavid C Somayajulu         UPDATE_ESTAT_QSTAT(rx_jumbo_sge_pkts);
12394e400768SDavid Christensen         UPDATE_ESTAT_QSTAT(rx_soft_errors);
12404e400768SDavid Christensen         UPDATE_ESTAT_QSTAT(rx_hw_csum_errors);
12414e400768SDavid Christensen         UPDATE_ESTAT_QSTAT(rx_ofld_frames_csum_ip);
12424e400768SDavid Christensen         UPDATE_ESTAT_QSTAT(rx_ofld_frames_csum_tcp_udp);
12434e400768SDavid Christensen         UPDATE_ESTAT_QSTAT(rx_budget_reached);
12444e400768SDavid Christensen         UPDATE_ESTAT_QSTAT(tx_pkts);
12454e400768SDavid Christensen         UPDATE_ESTAT_QSTAT(tx_soft_errors);
12464e400768SDavid Christensen         UPDATE_ESTAT_QSTAT(tx_ofld_frames_csum_ip);
12474e400768SDavid Christensen         UPDATE_ESTAT_QSTAT(tx_ofld_frames_csum_tcp);
12484e400768SDavid Christensen         UPDATE_ESTAT_QSTAT(tx_ofld_frames_csum_udp);
12494e400768SDavid Christensen         UPDATE_ESTAT_QSTAT(tx_ofld_frames_lso);
12504e400768SDavid Christensen         UPDATE_ESTAT_QSTAT(tx_ofld_frames_lso_hdr_splits);
12514e400768SDavid Christensen         UPDATE_ESTAT_QSTAT(tx_encap_failures);
12524e400768SDavid Christensen         UPDATE_ESTAT_QSTAT(tx_hw_queue_full);
12534e400768SDavid Christensen         UPDATE_ESTAT_QSTAT(tx_hw_max_queue_depth);
12544e400768SDavid Christensen         UPDATE_ESTAT_QSTAT(tx_dma_mapping_failure);
12554e400768SDavid Christensen         UPDATE_ESTAT_QSTAT(tx_max_drbr_queue_depth);
12564e400768SDavid Christensen         UPDATE_ESTAT_QSTAT(tx_window_violation_std);
12574e400768SDavid Christensen         UPDATE_ESTAT_QSTAT(tx_window_violation_tso);
12584e400768SDavid Christensen         //UPDATE_ESTAT_QSTAT(tx_unsupported_tso_request_ipv6);
12594e400768SDavid Christensen         //UPDATE_ESTAT_QSTAT(tx_unsupported_tso_request_not_tcp);
12604e400768SDavid Christensen         UPDATE_ESTAT_QSTAT(tx_chain_lost_mbuf);
12614e400768SDavid Christensen         UPDATE_ESTAT_QSTAT(tx_frames_deferred);
12624e400768SDavid Christensen         UPDATE_ESTAT_QSTAT(tx_queue_xoff);
12634e400768SDavid Christensen 
12644e400768SDavid Christensen         /* mbuf driver statistics */
12654e400768SDavid Christensen         UPDATE_ESTAT_QSTAT(mbuf_defrag_attempts);
12664e400768SDavid Christensen         UPDATE_ESTAT_QSTAT(mbuf_defrag_failures);
12674e400768SDavid Christensen         UPDATE_ESTAT_QSTAT(mbuf_rx_bd_alloc_failed);
12684e400768SDavid Christensen         UPDATE_ESTAT_QSTAT(mbuf_rx_bd_mapping_failed);
12694e400768SDavid Christensen         UPDATE_ESTAT_QSTAT(mbuf_rx_tpa_alloc_failed);
12704e400768SDavid Christensen         UPDATE_ESTAT_QSTAT(mbuf_rx_tpa_mapping_failed);
12714e400768SDavid Christensen         UPDATE_ESTAT_QSTAT(mbuf_rx_sge_alloc_failed);
12724e400768SDavid Christensen         UPDATE_ESTAT_QSTAT(mbuf_rx_sge_mapping_failed);
12734e400768SDavid Christensen 
12744e400768SDavid Christensen         /* track the number of allocated mbufs */
12754e400768SDavid Christensen         UPDATE_ESTAT_QSTAT(mbuf_alloc_tx);
12764e400768SDavid Christensen         UPDATE_ESTAT_QSTAT(mbuf_alloc_rx);
12774e400768SDavid Christensen         UPDATE_ESTAT_QSTAT(mbuf_alloc_sge);
12784e400768SDavid Christensen         UPDATE_ESTAT_QSTAT(mbuf_alloc_tpa);
12794e400768SDavid Christensen     }
12804e400768SDavid Christensen }
12814e400768SDavid Christensen 
12824e400768SDavid Christensen static uint8_t
bxe_edebug_stats_stopped(struct bxe_softc * sc)12834e400768SDavid Christensen bxe_edebug_stats_stopped(struct bxe_softc *sc)
12844e400768SDavid Christensen {
12854e400768SDavid Christensen     uint32_t val;
12864e400768SDavid Christensen 
12874e400768SDavid Christensen     if (SHMEM2_HAS(sc, edebug_driver_if[1])) {
12884e400768SDavid Christensen         val = SHMEM2_RD(sc, edebug_driver_if[1]);
12894e400768SDavid Christensen 
12904e400768SDavid Christensen         if (val == EDEBUG_DRIVER_IF_OP_CODE_DISABLE_STAT) {
12914e400768SDavid Christensen             return (TRUE);
12924e400768SDavid Christensen         }
12934e400768SDavid Christensen     }
12944e400768SDavid Christensen 
12954e400768SDavid Christensen     return (FALSE);
12964e400768SDavid Christensen }
12974e400768SDavid Christensen 
12984e400768SDavid Christensen static void
bxe_stats_update(struct bxe_softc * sc)12994e400768SDavid Christensen bxe_stats_update(struct bxe_softc *sc)
13004e400768SDavid Christensen {
13014e400768SDavid Christensen     uint32_t *stats_comp = BXE_SP(sc, stats_comp);
13024e400768SDavid Christensen 
13034e400768SDavid Christensen     if (bxe_edebug_stats_stopped(sc)) {
13044e400768SDavid Christensen         return;
13054e400768SDavid Christensen     }
13064e400768SDavid Christensen 
13074e400768SDavid Christensen     if (IS_PF(sc)) {
13084e400768SDavid Christensen         if (*stats_comp != DMAE_COMP_VAL) {
13094e400768SDavid Christensen             return;
13104e400768SDavid Christensen         }
13114e400768SDavid Christensen 
13124e400768SDavid Christensen         if (sc->port.pmf) {
13134e400768SDavid Christensen             bxe_hw_stats_update(sc);
13144e400768SDavid Christensen         }
13154e400768SDavid Christensen 
13164e400768SDavid Christensen         if (bxe_storm_stats_update(sc)) {
13174e400768SDavid Christensen             if (sc->stats_pending++ == 3) {
1318cd01c7a8SXin LI 		if (if_getdrvflags(sc->ifp) & IFF_DRV_RUNNING) {
1319*36baf17eSDavid C Somayajulu 		    BLOGE(sc, "Storm stats not updated for 3 times, resetting\n");
1320*36baf17eSDavid C Somayajulu 		    BXE_SET_ERROR_BIT(sc, BXE_ERR_STATS_TO);
1321*36baf17eSDavid C Somayajulu 		    taskqueue_enqueue_timeout(taskqueue_thread,
1322*36baf17eSDavid C Somayajulu                             &sc->sp_err_timeout_task, hz/10);
1323e3a36fb0SDavid C Somayajulu 		}
13244e400768SDavid Christensen             }
13254e400768SDavid Christensen             return;
13264e400768SDavid Christensen         }
13274e400768SDavid Christensen     } else {
13284e400768SDavid Christensen         /*
13294e400768SDavid Christensen          * VF doesn't collect HW statistics, and doesn't get completions,
13304e400768SDavid Christensen          * performs only update.
13314e400768SDavid Christensen          */
13324e400768SDavid Christensen         bxe_storm_stats_update(sc);
13334e400768SDavid Christensen     }
13344e400768SDavid Christensen 
13354e400768SDavid Christensen     bxe_net_stats_update(sc);
13364e400768SDavid Christensen     bxe_drv_stats_update(sc);
13374e400768SDavid Christensen 
13384e400768SDavid Christensen     /* vf is done */
13394e400768SDavid Christensen     if (IS_VF(sc)) {
13404e400768SDavid Christensen         return;
13414e400768SDavid Christensen     }
13424e400768SDavid Christensen 
13434e400768SDavid Christensen     bxe_hw_stats_post(sc);
13444e400768SDavid Christensen     bxe_storm_stats_post(sc);
13454e400768SDavid Christensen }
13464e400768SDavid Christensen 
13474e400768SDavid Christensen static void
bxe_port_stats_stop(struct bxe_softc * sc)13484e400768SDavid Christensen bxe_port_stats_stop(struct bxe_softc *sc)
13494e400768SDavid Christensen {
13504ef8ebfdSDavid C Somayajulu     struct dmae_cmd *dmae;
13514e400768SDavid Christensen     uint32_t opcode;
13524e400768SDavid Christensen     int loader_idx = PMF_DMAE_C(sc);
13534e400768SDavid Christensen     uint32_t *stats_comp = BXE_SP(sc, stats_comp);
13544e400768SDavid Christensen 
13554e400768SDavid Christensen     sc->executer_idx = 0;
13564e400768SDavid Christensen 
13574e400768SDavid Christensen     opcode = bxe_dmae_opcode(sc, DMAE_SRC_PCI, DMAE_DST_GRC, FALSE, 0);
13584e400768SDavid Christensen 
13594e400768SDavid Christensen     if (sc->port.port_stx) {
13604e400768SDavid Christensen         dmae = BXE_SP(sc, dmae[sc->executer_idx++]);
13614e400768SDavid Christensen 
13624e400768SDavid Christensen         if (sc->func_stx) {
13634e400768SDavid Christensen             dmae->opcode = bxe_dmae_opcode_add_comp(opcode, DMAE_COMP_GRC);
13644e400768SDavid Christensen         } else {
13654e400768SDavid Christensen             dmae->opcode = bxe_dmae_opcode_add_comp(opcode, DMAE_COMP_PCI);
13664e400768SDavid Christensen         }
13674e400768SDavid Christensen 
13684e400768SDavid Christensen         dmae->src_addr_lo = U64_LO(BXE_SP_MAPPING(sc, port_stats));
13694e400768SDavid Christensen         dmae->src_addr_hi = U64_HI(BXE_SP_MAPPING(sc, port_stats));
13704e400768SDavid Christensen         dmae->dst_addr_lo = sc->port.port_stx >> 2;
13714e400768SDavid Christensen         dmae->dst_addr_hi = 0;
13724e400768SDavid Christensen         dmae->len = bxe_get_port_stats_dma_len(sc);
13734e400768SDavid Christensen         if (sc->func_stx) {
13744e400768SDavid Christensen             dmae->comp_addr_lo = (dmae_reg_go_c[loader_idx] >> 2);
13754e400768SDavid Christensen             dmae->comp_addr_hi = 0;
13764e400768SDavid Christensen             dmae->comp_val = 1;
13774e400768SDavid Christensen         } else {
13784e400768SDavid Christensen             dmae->comp_addr_lo = U64_LO(BXE_SP_MAPPING(sc, stats_comp));
13794e400768SDavid Christensen             dmae->comp_addr_hi = U64_HI(BXE_SP_MAPPING(sc, stats_comp));
13804e400768SDavid Christensen             dmae->comp_val = DMAE_COMP_VAL;
13814e400768SDavid Christensen 
13824e400768SDavid Christensen             *stats_comp = 0;
13834e400768SDavid Christensen         }
13844e400768SDavid Christensen     }
13854e400768SDavid Christensen 
13864e400768SDavid Christensen     if (sc->func_stx) {
13874e400768SDavid Christensen         dmae = BXE_SP(sc, dmae[sc->executer_idx++]);
13884e400768SDavid Christensen         dmae->opcode = bxe_dmae_opcode_add_comp(opcode, DMAE_COMP_PCI);
13894e400768SDavid Christensen         dmae->src_addr_lo = U64_LO(BXE_SP_MAPPING(sc, func_stats));
13904e400768SDavid Christensen         dmae->src_addr_hi = U64_HI(BXE_SP_MAPPING(sc, func_stats));
13914e400768SDavid Christensen         dmae->dst_addr_lo = (sc->func_stx >> 2);
13924e400768SDavid Christensen         dmae->dst_addr_hi = 0;
13934e400768SDavid Christensen         dmae->len = (sizeof(struct host_func_stats) >> 2);
13944e400768SDavid Christensen         dmae->comp_addr_lo = U64_LO(BXE_SP_MAPPING(sc, stats_comp));
13954e400768SDavid Christensen         dmae->comp_addr_hi = U64_HI(BXE_SP_MAPPING(sc, stats_comp));
13964e400768SDavid Christensen         dmae->comp_val = DMAE_COMP_VAL;
13974e400768SDavid Christensen 
13984e400768SDavid Christensen         *stats_comp = 0;
13994e400768SDavid Christensen     }
14004e400768SDavid Christensen }
14014e400768SDavid Christensen 
14024e400768SDavid Christensen static void
bxe_stats_stop(struct bxe_softc * sc)14034e400768SDavid Christensen bxe_stats_stop(struct bxe_softc *sc)
14044e400768SDavid Christensen {
14054e400768SDavid Christensen     uint8_t update = FALSE;
14064e400768SDavid Christensen 
14074e400768SDavid Christensen     bxe_stats_comp(sc);
14084e400768SDavid Christensen 
14094e400768SDavid Christensen     if (sc->port.pmf) {
14104e400768SDavid Christensen         update = bxe_hw_stats_update(sc) == 0;
14114e400768SDavid Christensen     }
14124e400768SDavid Christensen 
14134e400768SDavid Christensen     update |= bxe_storm_stats_update(sc) == 0;
14144e400768SDavid Christensen 
14154e400768SDavid Christensen     if (update) {
14164e400768SDavid Christensen         bxe_net_stats_update(sc);
14174e400768SDavid Christensen 
14184e400768SDavid Christensen         if (sc->port.pmf) {
14194e400768SDavid Christensen             bxe_port_stats_stop(sc);
14204e400768SDavid Christensen         }
14214e400768SDavid Christensen 
14224e400768SDavid Christensen         bxe_hw_stats_post(sc);
14234e400768SDavid Christensen         bxe_stats_comp(sc);
14244e400768SDavid Christensen     }
14254e400768SDavid Christensen }
14264e400768SDavid Christensen 
14274e400768SDavid Christensen static void
bxe_stats_do_nothing(struct bxe_softc * sc)14284e400768SDavid Christensen bxe_stats_do_nothing(struct bxe_softc *sc)
14294e400768SDavid Christensen {
14304e400768SDavid Christensen     return;
14314e400768SDavid Christensen }
14324e400768SDavid Christensen 
14334e400768SDavid Christensen static const struct {
14344e400768SDavid Christensen     void (*action)(struct bxe_softc *sc);
14354e400768SDavid Christensen     enum bxe_stats_state next_state;
14364e400768SDavid Christensen } bxe_stats_stm[STATS_STATE_MAX][STATS_EVENT_MAX] = {
14374e400768SDavid Christensen     {
14384e400768SDavid Christensen     /* DISABLED PMF */ { bxe_stats_pmf_update, STATS_STATE_DISABLED },
14394e400768SDavid Christensen     /*      LINK_UP */ { bxe_stats_start,      STATS_STATE_ENABLED },
14404e400768SDavid Christensen     /*      UPDATE  */ { bxe_stats_do_nothing, STATS_STATE_DISABLED },
14414e400768SDavid Christensen     /*      STOP    */ { bxe_stats_do_nothing, STATS_STATE_DISABLED }
14424e400768SDavid Christensen     },
14434e400768SDavid Christensen     {
14444e400768SDavid Christensen     /* ENABLED  PMF */ { bxe_stats_pmf_start,  STATS_STATE_ENABLED },
14454e400768SDavid Christensen     /*      LINK_UP */ { bxe_stats_restart,    STATS_STATE_ENABLED },
14464e400768SDavid Christensen     /*      UPDATE  */ { bxe_stats_update,     STATS_STATE_ENABLED },
14474e400768SDavid Christensen     /*      STOP    */ { bxe_stats_stop,       STATS_STATE_DISABLED }
14484e400768SDavid Christensen     }
14494e400768SDavid Christensen };
14504e400768SDavid Christensen 
bxe_stats_handle(struct bxe_softc * sc,enum bxe_stats_event event)14514e400768SDavid Christensen void bxe_stats_handle(struct bxe_softc     *sc,
14524e400768SDavid Christensen                       enum bxe_stats_event event)
14534e400768SDavid Christensen {
14544e400768SDavid Christensen     enum bxe_stats_state state;
14554e400768SDavid Christensen 
14564e400768SDavid Christensen     if (__predict_false(sc->panic)) {
14574e400768SDavid Christensen         return;
14584e400768SDavid Christensen     }
14594e400768SDavid Christensen 
14604e400768SDavid Christensen     BXE_STATS_LOCK(sc);
14614e400768SDavid Christensen     state = sc->stats_state;
14624e400768SDavid Christensen     sc->stats_state = bxe_stats_stm[state][event].next_state;
14634e400768SDavid Christensen     BXE_STATS_UNLOCK(sc);
14644e400768SDavid Christensen 
14654e400768SDavid Christensen     bxe_stats_stm[state][event].action(sc);
14664e400768SDavid Christensen 
14674e400768SDavid Christensen     if (event != STATS_EVENT_UPDATE) {
14684e400768SDavid Christensen         BLOGD(sc, DBG_STATS,
14694e400768SDavid Christensen               "state %d -> event %d -> state %d\n",
14704e400768SDavid Christensen               state, event, sc->stats_state);
14714e400768SDavid Christensen     }
14724e400768SDavid Christensen }
14734e400768SDavid Christensen 
14744e400768SDavid Christensen static void
bxe_port_stats_base_init(struct bxe_softc * sc)14754e400768SDavid Christensen bxe_port_stats_base_init(struct bxe_softc *sc)
14764e400768SDavid Christensen {
14774ef8ebfdSDavid C Somayajulu     struct dmae_cmd *dmae;
14784e400768SDavid Christensen     uint32_t *stats_comp = BXE_SP(sc, stats_comp);
14794e400768SDavid Christensen 
14804e400768SDavid Christensen     /* sanity */
14814e400768SDavid Christensen     if (!sc->port.pmf || !sc->port.port_stx) {
14824e400768SDavid Christensen         BLOGE(sc, "BUG!\n");
14834e400768SDavid Christensen         return;
14844e400768SDavid Christensen     }
14854e400768SDavid Christensen 
14864e400768SDavid Christensen     sc->executer_idx = 0;
14874e400768SDavid Christensen 
14884e400768SDavid Christensen     dmae = BXE_SP(sc, dmae[sc->executer_idx++]);
14894e400768SDavid Christensen     dmae->opcode = bxe_dmae_opcode(sc, DMAE_SRC_PCI, DMAE_DST_GRC,
14904e400768SDavid Christensen                                    TRUE, DMAE_COMP_PCI);
14914e400768SDavid Christensen     dmae->src_addr_lo = U64_LO(BXE_SP_MAPPING(sc, port_stats));
14924e400768SDavid Christensen     dmae->src_addr_hi = U64_HI(BXE_SP_MAPPING(sc, port_stats));
14934e400768SDavid Christensen     dmae->dst_addr_lo = (sc->port.port_stx >> 2);
14944e400768SDavid Christensen     dmae->dst_addr_hi = 0;
14954e400768SDavid Christensen     dmae->len = bxe_get_port_stats_dma_len(sc);
14964e400768SDavid Christensen     dmae->comp_addr_lo = U64_LO(BXE_SP_MAPPING(sc, stats_comp));
14974e400768SDavid Christensen     dmae->comp_addr_hi = U64_HI(BXE_SP_MAPPING(sc, stats_comp));
14984e400768SDavid Christensen     dmae->comp_val = DMAE_COMP_VAL;
14994e400768SDavid Christensen 
15004e400768SDavid Christensen     *stats_comp = 0;
15014e400768SDavid Christensen     bxe_hw_stats_post(sc);
15024e400768SDavid Christensen     bxe_stats_comp(sc);
15034e400768SDavid Christensen }
15044e400768SDavid Christensen 
15054e400768SDavid Christensen /*
15064e400768SDavid Christensen  * This function will prepare the statistics ramrod data the way
15074e400768SDavid Christensen  * we will only have to increment the statistics counter and
15084e400768SDavid Christensen  * send the ramrod each time we have to.
15094e400768SDavid Christensen  */
15104e400768SDavid Christensen static void
bxe_prep_fw_stats_req(struct bxe_softc * sc)15114e400768SDavid Christensen bxe_prep_fw_stats_req(struct bxe_softc *sc)
15124e400768SDavid Christensen {
15134e400768SDavid Christensen     int i;
15144e400768SDavid Christensen     int first_queue_query_index;
15154e400768SDavid Christensen     struct stats_query_header *stats_hdr = &sc->fw_stats_req->hdr;
15164e400768SDavid Christensen     bus_addr_t cur_data_offset;
15174e400768SDavid Christensen     struct stats_query_entry *cur_query_entry;
15184e400768SDavid Christensen 
15194e400768SDavid Christensen     stats_hdr->cmd_num = sc->fw_stats_num;
15204e400768SDavid Christensen     stats_hdr->drv_stats_counter = 0;
15214e400768SDavid Christensen 
15224e400768SDavid Christensen     /*
15234e400768SDavid Christensen      * The storm_counters struct contains the counters of completed
15244e400768SDavid Christensen      * statistics requests per storm which are incremented by FW
15254e400768SDavid Christensen      * each time it completes hadning a statistics ramrod. We will
15264e400768SDavid Christensen      * check these counters in the timer handler and discard a
15274e400768SDavid Christensen      * (statistics) ramrod completion.
15284e400768SDavid Christensen      */
15294e400768SDavid Christensen     cur_data_offset = (sc->fw_stats_data_mapping +
15304e400768SDavid Christensen                        offsetof(struct bxe_fw_stats_data, storm_counters));
15314e400768SDavid Christensen 
15324e400768SDavid Christensen     stats_hdr->stats_counters_addrs.hi = htole32(U64_HI(cur_data_offset));
15334e400768SDavid Christensen     stats_hdr->stats_counters_addrs.lo = htole32(U64_LO(cur_data_offset));
15344e400768SDavid Christensen 
15354e400768SDavid Christensen     /*
15364e400768SDavid Christensen      * Prepare the first stats ramrod (will be completed with
15374e400768SDavid Christensen      * the counters equal to zero) - init counters to somethig different.
15384e400768SDavid Christensen      */
15394e400768SDavid Christensen     memset(&sc->fw_stats_data->storm_counters, 0xff,
15404e400768SDavid Christensen            sizeof(struct stats_counter));
15414e400768SDavid Christensen 
15424e400768SDavid Christensen     /**** Port FW statistics data ****/
15434e400768SDavid Christensen     cur_data_offset = (sc->fw_stats_data_mapping +
15444e400768SDavid Christensen                        offsetof(struct bxe_fw_stats_data, port));
15454e400768SDavid Christensen 
15464e400768SDavid Christensen     cur_query_entry = &sc->fw_stats_req->query[BXE_PORT_QUERY_IDX];
15474e400768SDavid Christensen 
15484e400768SDavid Christensen     cur_query_entry->kind = STATS_TYPE_PORT;
15494e400768SDavid Christensen     /* For port query index is a DONT CARE */
15504e400768SDavid Christensen     cur_query_entry->index = SC_PORT(sc);
15514e400768SDavid Christensen     /* For port query funcID is a DONT CARE */
15524e400768SDavid Christensen     cur_query_entry->funcID = htole16(SC_FUNC(sc));
15534e400768SDavid Christensen     cur_query_entry->address.hi = htole32(U64_HI(cur_data_offset));
15544e400768SDavid Christensen     cur_query_entry->address.lo = htole32(U64_LO(cur_data_offset));
15554e400768SDavid Christensen 
15564e400768SDavid Christensen     /**** PF FW statistics data ****/
15574e400768SDavid Christensen     cur_data_offset = (sc->fw_stats_data_mapping +
15584e400768SDavid Christensen                        offsetof(struct bxe_fw_stats_data, pf));
15594e400768SDavid Christensen 
15604e400768SDavid Christensen     cur_query_entry = &sc->fw_stats_req->query[BXE_PF_QUERY_IDX];
15614e400768SDavid Christensen 
15624e400768SDavid Christensen     cur_query_entry->kind = STATS_TYPE_PF;
15634e400768SDavid Christensen     /* For PF query index is a DONT CARE */
15644e400768SDavid Christensen     cur_query_entry->index = SC_PORT(sc);
15654e400768SDavid Christensen     cur_query_entry->funcID = htole16(SC_FUNC(sc));
15664e400768SDavid Christensen     cur_query_entry->address.hi = htole32(U64_HI(cur_data_offset));
15674e400768SDavid Christensen     cur_query_entry->address.lo = htole32(U64_LO(cur_data_offset));
15684e400768SDavid Christensen 
15694e400768SDavid Christensen     /**** Clients' queries ****/
15704e400768SDavid Christensen     cur_data_offset = (sc->fw_stats_data_mapping +
15714e400768SDavid Christensen                        offsetof(struct bxe_fw_stats_data, queue_stats));
15724e400768SDavid Christensen 
15734e400768SDavid Christensen     /*
15744e400768SDavid Christensen      * First queue query index depends whether FCoE offloaded request will
15754e400768SDavid Christensen      * be included in the ramrod
15764e400768SDavid Christensen      */
15774e400768SDavid Christensen     first_queue_query_index = (BXE_FIRST_QUEUE_QUERY_IDX - 1);
15784e400768SDavid Christensen 
15794e400768SDavid Christensen     for (i = 0; i < sc->num_queues; i++) {
15804e400768SDavid Christensen         cur_query_entry =
15814e400768SDavid Christensen             &sc->fw_stats_req->query[first_queue_query_index + i];
15824e400768SDavid Christensen 
15834e400768SDavid Christensen         cur_query_entry->kind = STATS_TYPE_QUEUE;
15844e400768SDavid Christensen         cur_query_entry->index = bxe_stats_id(&sc->fp[i]);
15854e400768SDavid Christensen         cur_query_entry->funcID = htole16(SC_FUNC(sc));
15864e400768SDavid Christensen         cur_query_entry->address.hi = htole32(U64_HI(cur_data_offset));
15874e400768SDavid Christensen         cur_query_entry->address.lo = htole32(U64_LO(cur_data_offset));
15884e400768SDavid Christensen 
15894e400768SDavid Christensen         cur_data_offset += sizeof(struct per_queue_stats);
15904e400768SDavid Christensen     }
15914e400768SDavid Christensen }
15924e400768SDavid Christensen 
15934e400768SDavid Christensen void
bxe_stats_init(struct bxe_softc * sc)15944e400768SDavid Christensen bxe_stats_init(struct bxe_softc *sc)
15954e400768SDavid Christensen {
15964e400768SDavid Christensen     int /*abs*/port = SC_PORT(sc);
15974e400768SDavid Christensen     int mb_idx = SC_FW_MB_IDX(sc);
15984e400768SDavid Christensen     int i;
15994e400768SDavid Christensen 
16004e400768SDavid Christensen     sc->stats_pending = 0;
16014e400768SDavid Christensen     sc->executer_idx = 0;
16024e400768SDavid Christensen     sc->stats_counter = 0;
16034e400768SDavid Christensen 
16044e400768SDavid Christensen     /* port and func stats for management */
16054e400768SDavid Christensen     if (!BXE_NOMCP(sc)) {
16064e400768SDavid Christensen         sc->port.port_stx = SHMEM_RD(sc, port_mb[port].port_stx);
16074e400768SDavid Christensen         sc->func_stx = SHMEM_RD(sc, func_mb[mb_idx].fw_mb_param);
16084e400768SDavid Christensen     } else {
16094e400768SDavid Christensen         sc->port.port_stx = 0;
16104e400768SDavid Christensen         sc->func_stx = 0;
16114e400768SDavid Christensen     }
16124e400768SDavid Christensen 
16134e400768SDavid Christensen     BLOGD(sc, DBG_STATS, "port_stx 0x%x func_stx 0x%x\n",
16144e400768SDavid Christensen           sc->port.port_stx, sc->func_stx);
16154e400768SDavid Christensen 
16164e400768SDavid Christensen     /* pmf should retrieve port statistics from SP on a non-init*/
16174e400768SDavid Christensen     if (!sc->stats_init && sc->port.pmf && sc->port.port_stx) {
16184e400768SDavid Christensen         bxe_stats_handle(sc, STATS_EVENT_PMF);
16194e400768SDavid Christensen     }
16204e400768SDavid Christensen 
16214e400768SDavid Christensen     port = SC_PORT(sc);
16224e400768SDavid Christensen     /* port stats */
16234e400768SDavid Christensen     memset(&(sc->port.old_nig_stats), 0, sizeof(struct nig_stats));
16244e400768SDavid Christensen     sc->port.old_nig_stats.brb_discard =
16254e400768SDavid Christensen         REG_RD(sc, NIG_REG_STAT0_BRB_DISCARD + port*0x38);
16264e400768SDavid Christensen     sc->port.old_nig_stats.brb_truncate =
16274e400768SDavid Christensen         REG_RD(sc, NIG_REG_STAT0_BRB_TRUNCATE + port*0x38);
16284e400768SDavid Christensen     if (!CHIP_IS_E3(sc)) {
16294e400768SDavid Christensen         REG_RD_DMAE(sc, NIG_REG_STAT0_EGRESS_MAC_PKT0 + port*0x50,
16304e400768SDavid Christensen                     &(sc->port.old_nig_stats.egress_mac_pkt0_lo), 2);
16314e400768SDavid Christensen         REG_RD_DMAE(sc, NIG_REG_STAT0_EGRESS_MAC_PKT1 + port*0x50,
16324e400768SDavid Christensen                     &(sc->port.old_nig_stats.egress_mac_pkt1_lo), 2);
16334e400768SDavid Christensen     }
16344e400768SDavid Christensen 
16354e400768SDavid Christensen     /* function stats */
16364e400768SDavid Christensen     for (i = 0; i < sc->num_queues; i++) {
16374e400768SDavid Christensen         memset(&sc->fp[i].old_tclient, 0, sizeof(sc->fp[i].old_tclient));
16384e400768SDavid Christensen         memset(&sc->fp[i].old_uclient, 0, sizeof(sc->fp[i].old_uclient));
16394e400768SDavid Christensen         memset(&sc->fp[i].old_xclient, 0, sizeof(sc->fp[i].old_xclient));
16404e400768SDavid Christensen         if (sc->stats_init) {
16414e400768SDavid Christensen             memset(&sc->fp[i].eth_q_stats, 0,
16424e400768SDavid Christensen                    sizeof(sc->fp[i].eth_q_stats));
16434e400768SDavid Christensen             memset(&sc->fp[i].eth_q_stats_old, 0,
16444e400768SDavid Christensen                    sizeof(sc->fp[i].eth_q_stats_old));
16454e400768SDavid Christensen         }
16464e400768SDavid Christensen     }
16474e400768SDavid Christensen 
16484e400768SDavid Christensen     /* prepare statistics ramrod data */
16494e400768SDavid Christensen     bxe_prep_fw_stats_req(sc);
16504e400768SDavid Christensen 
16514e400768SDavid Christensen     if (sc->stats_init) {
16524e400768SDavid Christensen         memset(&sc->net_stats_old, 0, sizeof(sc->net_stats_old));
16534e400768SDavid Christensen         memset(&sc->fw_stats_old, 0, sizeof(sc->fw_stats_old));
16544e400768SDavid Christensen         memset(&sc->eth_stats_old, 0, sizeof(sc->eth_stats_old));
16554e400768SDavid Christensen         memset(&sc->eth_stats, 0, sizeof(sc->eth_stats));
16564e400768SDavid Christensen         memset(&sc->func_stats, 0, sizeof(sc->func_stats));
16574e400768SDavid Christensen 
16584e400768SDavid Christensen         /* Clean SP from previous statistics */
16594e400768SDavid Christensen         if (sc->func_stx) {
16604e400768SDavid Christensen             memset(BXE_SP(sc, func_stats), 0, sizeof(struct host_func_stats));
16614e400768SDavid Christensen             bxe_func_stats_init(sc);
16624e400768SDavid Christensen             bxe_hw_stats_post(sc);
16634e400768SDavid Christensen             bxe_stats_comp(sc);
16644e400768SDavid Christensen         }
16654e400768SDavid Christensen     }
16664e400768SDavid Christensen 
16674e400768SDavid Christensen     sc->stats_state = STATS_STATE_DISABLED;
16684e400768SDavid Christensen 
16694e400768SDavid Christensen     if (sc->port.pmf && sc->port.port_stx) {
16704e400768SDavid Christensen         bxe_port_stats_base_init(sc);
16714e400768SDavid Christensen     }
16724e400768SDavid Christensen 
1673453130d9SPedro F. Giffuni     /* mark the end of statistics initialization */
16744e400768SDavid Christensen     sc->stats_init = FALSE;
16754e400768SDavid Christensen }
16764e400768SDavid Christensen 
16774e400768SDavid Christensen void
bxe_save_statistics(struct bxe_softc * sc)16784e400768SDavid Christensen bxe_save_statistics(struct bxe_softc *sc)
16794e400768SDavid Christensen {
16804e400768SDavid Christensen     int i;
16814e400768SDavid Christensen 
16824e400768SDavid Christensen     /* save queue statistics */
16834e400768SDavid Christensen     for (i = 0; i < sc->num_queues; i++) {
16844e400768SDavid Christensen         struct bxe_fastpath *fp = &sc->fp[i];
16854e400768SDavid Christensen         struct bxe_eth_q_stats *qstats = &fp->eth_q_stats;
16864e400768SDavid Christensen         struct bxe_eth_q_stats_old *qstats_old = &fp->eth_q_stats_old;
16874e400768SDavid Christensen 
16884e400768SDavid Christensen         UPDATE_QSTAT_OLD(total_unicast_bytes_received_hi);
16894e400768SDavid Christensen         UPDATE_QSTAT_OLD(total_unicast_bytes_received_lo);
16904e400768SDavid Christensen         UPDATE_QSTAT_OLD(total_broadcast_bytes_received_hi);
16914e400768SDavid Christensen         UPDATE_QSTAT_OLD(total_broadcast_bytes_received_lo);
16924e400768SDavid Christensen         UPDATE_QSTAT_OLD(total_multicast_bytes_received_hi);
16934e400768SDavid Christensen         UPDATE_QSTAT_OLD(total_multicast_bytes_received_lo);
16944e400768SDavid Christensen         UPDATE_QSTAT_OLD(total_unicast_bytes_transmitted_hi);
16954e400768SDavid Christensen         UPDATE_QSTAT_OLD(total_unicast_bytes_transmitted_lo);
16964e400768SDavid Christensen         UPDATE_QSTAT_OLD(total_broadcast_bytes_transmitted_hi);
16974e400768SDavid Christensen         UPDATE_QSTAT_OLD(total_broadcast_bytes_transmitted_lo);
16984e400768SDavid Christensen         UPDATE_QSTAT_OLD(total_multicast_bytes_transmitted_hi);
16994e400768SDavid Christensen         UPDATE_QSTAT_OLD(total_multicast_bytes_transmitted_lo);
17004e400768SDavid Christensen         UPDATE_QSTAT_OLD(total_tpa_bytes_hi);
17014e400768SDavid Christensen         UPDATE_QSTAT_OLD(total_tpa_bytes_lo);
17024e400768SDavid Christensen     }
17034e400768SDavid Christensen 
17044e400768SDavid Christensen     /* store port firmware statistics */
17054e400768SDavid Christensen     if (sc->port.pmf) {
17064e400768SDavid Christensen         struct bxe_eth_stats *estats = &sc->eth_stats;
17074e400768SDavid Christensen         struct bxe_fw_port_stats_old *fwstats = &sc->fw_stats_old;
17084e400768SDavid Christensen         struct host_port_stats *pstats = BXE_SP(sc, port_stats);
17094e400768SDavid Christensen 
17104e400768SDavid Christensen         fwstats->pfc_frames_rx_hi = pstats->pfc_frames_rx_hi;
17114e400768SDavid Christensen         fwstats->pfc_frames_rx_lo = pstats->pfc_frames_rx_lo;
17124e400768SDavid Christensen         fwstats->pfc_frames_tx_hi = pstats->pfc_frames_tx_hi;
17134e400768SDavid Christensen         fwstats->pfc_frames_tx_lo = pstats->pfc_frames_tx_lo;
17144e400768SDavid Christensen 
17154e400768SDavid Christensen         if (IS_MF(sc)) {
17164e400768SDavid Christensen             UPDATE_FW_STAT_OLD(mac_filter_discard);
17174e400768SDavid Christensen             UPDATE_FW_STAT_OLD(mf_tag_discard);
17184e400768SDavid Christensen             UPDATE_FW_STAT_OLD(brb_truncate_discard);
17194e400768SDavid Christensen             UPDATE_FW_STAT_OLD(mac_discard);
17204e400768SDavid Christensen         }
17214e400768SDavid Christensen     }
17224e400768SDavid Christensen }
17234e400768SDavid Christensen 
17244e400768SDavid Christensen void
bxe_afex_collect_stats(struct bxe_softc * sc,void * void_afex_stats,uint32_t stats_type)17254e400768SDavid Christensen bxe_afex_collect_stats(struct bxe_softc *sc,
17264e400768SDavid Christensen                        void             *void_afex_stats,
17274e400768SDavid Christensen                        uint32_t         stats_type)
17284e400768SDavid Christensen {
17294e400768SDavid Christensen     int i;
17304e400768SDavid Christensen     struct afex_stats *afex_stats = (struct afex_stats *)void_afex_stats;
17314e400768SDavid Christensen     struct bxe_eth_stats *estats = &sc->eth_stats;
17324e400768SDavid Christensen 
17334e400768SDavid Christensen     memset(afex_stats, 0, sizeof(struct afex_stats));
17344e400768SDavid Christensen 
17354e400768SDavid Christensen     for (i = 0; i < sc->num_queues; i++) {
17364e400768SDavid Christensen         struct bxe_eth_q_stats *qstats = &sc->fp[i].eth_q_stats;
17374e400768SDavid Christensen 
17384e400768SDavid Christensen         ADD_64(afex_stats->rx_unicast_bytes_hi,
17394e400768SDavid Christensen                qstats->total_unicast_bytes_received_hi,
17404e400768SDavid Christensen                afex_stats->rx_unicast_bytes_lo,
17414e400768SDavid Christensen                qstats->total_unicast_bytes_received_lo);
17424e400768SDavid Christensen 
17434e400768SDavid Christensen         ADD_64(afex_stats->rx_broadcast_bytes_hi,
17444e400768SDavid Christensen                qstats->total_broadcast_bytes_received_hi,
17454e400768SDavid Christensen                afex_stats->rx_broadcast_bytes_lo,
17464e400768SDavid Christensen                qstats->total_broadcast_bytes_received_lo);
17474e400768SDavid Christensen 
17484e400768SDavid Christensen         ADD_64(afex_stats->rx_multicast_bytes_hi,
17494e400768SDavid Christensen                qstats->total_multicast_bytes_received_hi,
17504e400768SDavid Christensen                afex_stats->rx_multicast_bytes_lo,
17514e400768SDavid Christensen                qstats->total_multicast_bytes_received_lo);
17524e400768SDavid Christensen 
17534e400768SDavid Christensen         ADD_64(afex_stats->rx_unicast_frames_hi,
17544e400768SDavid Christensen                qstats->total_unicast_packets_received_hi,
17554e400768SDavid Christensen                afex_stats->rx_unicast_frames_lo,
17564e400768SDavid Christensen                qstats->total_unicast_packets_received_lo);
17574e400768SDavid Christensen 
17584e400768SDavid Christensen         ADD_64(afex_stats->rx_broadcast_frames_hi,
17594e400768SDavid Christensen                qstats->total_broadcast_packets_received_hi,
17604e400768SDavid Christensen                afex_stats->rx_broadcast_frames_lo,
17614e400768SDavid Christensen                qstats->total_broadcast_packets_received_lo);
17624e400768SDavid Christensen 
17634e400768SDavid Christensen         ADD_64(afex_stats->rx_multicast_frames_hi,
17644e400768SDavid Christensen                qstats->total_multicast_packets_received_hi,
17654e400768SDavid Christensen                afex_stats->rx_multicast_frames_lo,
17664e400768SDavid Christensen                qstats->total_multicast_packets_received_lo);
17674e400768SDavid Christensen 
17684e400768SDavid Christensen         /*
17694e400768SDavid Christensen          * sum to rx_frames_discarded all discarded
17704e400768SDavid Christensen          * packets due to size, ttl0 and checksum
17714e400768SDavid Christensen          */
17724e400768SDavid Christensen         ADD_64(afex_stats->rx_frames_discarded_hi,
17734e400768SDavid Christensen                qstats->total_packets_received_checksum_discarded_hi,
17744e400768SDavid Christensen                afex_stats->rx_frames_discarded_lo,
17754e400768SDavid Christensen                qstats->total_packets_received_checksum_discarded_lo);
17764e400768SDavid Christensen 
17774e400768SDavid Christensen         ADD_64(afex_stats->rx_frames_discarded_hi,
17784e400768SDavid Christensen                qstats->total_packets_received_ttl0_discarded_hi,
17794e400768SDavid Christensen                afex_stats->rx_frames_discarded_lo,
17804e400768SDavid Christensen                qstats->total_packets_received_ttl0_discarded_lo);
17814e400768SDavid Christensen 
17824e400768SDavid Christensen         ADD_64(afex_stats->rx_frames_discarded_hi,
17834e400768SDavid Christensen                qstats->etherstatsoverrsizepkts_hi,
17844e400768SDavid Christensen                afex_stats->rx_frames_discarded_lo,
17854e400768SDavid Christensen                qstats->etherstatsoverrsizepkts_lo);
17864e400768SDavid Christensen 
17874e400768SDavid Christensen         ADD_64(afex_stats->rx_frames_dropped_hi,
17884e400768SDavid Christensen                qstats->no_buff_discard_hi,
17894e400768SDavid Christensen                afex_stats->rx_frames_dropped_lo,
17904e400768SDavid Christensen                qstats->no_buff_discard_lo);
17914e400768SDavid Christensen 
17924e400768SDavid Christensen         ADD_64(afex_stats->tx_unicast_bytes_hi,
17934e400768SDavid Christensen                qstats->total_unicast_bytes_transmitted_hi,
17944e400768SDavid Christensen                afex_stats->tx_unicast_bytes_lo,
17954e400768SDavid Christensen                qstats->total_unicast_bytes_transmitted_lo);
17964e400768SDavid Christensen 
17974e400768SDavid Christensen         ADD_64(afex_stats->tx_broadcast_bytes_hi,
17984e400768SDavid Christensen                qstats->total_broadcast_bytes_transmitted_hi,
17994e400768SDavid Christensen                afex_stats->tx_broadcast_bytes_lo,
18004e400768SDavid Christensen                qstats->total_broadcast_bytes_transmitted_lo);
18014e400768SDavid Christensen 
18024e400768SDavid Christensen         ADD_64(afex_stats->tx_multicast_bytes_hi,
18034e400768SDavid Christensen                qstats->total_multicast_bytes_transmitted_hi,
18044e400768SDavid Christensen                afex_stats->tx_multicast_bytes_lo,
18054e400768SDavid Christensen                qstats->total_multicast_bytes_transmitted_lo);
18064e400768SDavid Christensen 
18074e400768SDavid Christensen         ADD_64(afex_stats->tx_unicast_frames_hi,
18084e400768SDavid Christensen                qstats->total_unicast_packets_transmitted_hi,
18094e400768SDavid Christensen                afex_stats->tx_unicast_frames_lo,
18104e400768SDavid Christensen                qstats->total_unicast_packets_transmitted_lo);
18114e400768SDavid Christensen 
18124e400768SDavid Christensen         ADD_64(afex_stats->tx_broadcast_frames_hi,
18134e400768SDavid Christensen                qstats->total_broadcast_packets_transmitted_hi,
18144e400768SDavid Christensen                afex_stats->tx_broadcast_frames_lo,
18154e400768SDavid Christensen                qstats->total_broadcast_packets_transmitted_lo);
18164e400768SDavid Christensen 
18174e400768SDavid Christensen         ADD_64(afex_stats->tx_multicast_frames_hi,
18184e400768SDavid Christensen                qstats->total_multicast_packets_transmitted_hi,
18194e400768SDavid Christensen                afex_stats->tx_multicast_frames_lo,
18204e400768SDavid Christensen                qstats->total_multicast_packets_transmitted_lo);
18214e400768SDavid Christensen 
18224e400768SDavid Christensen         ADD_64(afex_stats->tx_frames_dropped_hi,
18234e400768SDavid Christensen                qstats->total_transmitted_dropped_packets_error_hi,
18244e400768SDavid Christensen                afex_stats->tx_frames_dropped_lo,
18254e400768SDavid Christensen                qstats->total_transmitted_dropped_packets_error_lo);
18264e400768SDavid Christensen     }
18274e400768SDavid Christensen 
18284e400768SDavid Christensen     /*
18294e400768SDavid Christensen      * If port stats are requested, add them to the PMF
18304e400768SDavid Christensen      * stats, as anyway they will be accumulated by the
18314e400768SDavid Christensen      * MCP before sent to the switch
18324e400768SDavid Christensen      */
18334e400768SDavid Christensen     if ((sc->port.pmf) && (stats_type == VICSTATST_UIF_INDEX)) {
18344e400768SDavid Christensen         ADD_64(afex_stats->rx_frames_dropped_hi,
18354e400768SDavid Christensen                0,
18364e400768SDavid Christensen                afex_stats->rx_frames_dropped_lo,
18374e400768SDavid Christensen                estats->mac_filter_discard);
18384e400768SDavid Christensen         ADD_64(afex_stats->rx_frames_dropped_hi,
18394e400768SDavid Christensen                0,
18404e400768SDavid Christensen                afex_stats->rx_frames_dropped_lo,
18414e400768SDavid Christensen                estats->brb_truncate_discard);
18424e400768SDavid Christensen         ADD_64(afex_stats->rx_frames_discarded_hi,
18434e400768SDavid Christensen                0,
18444e400768SDavid Christensen                afex_stats->rx_frames_discarded_lo,
18454e400768SDavid Christensen                estats->mac_discard);
18464e400768SDavid Christensen     }
18474e400768SDavid Christensen }
18484e400768SDavid Christensen 
1849