net/i40e: fix Rx packet statistics
[dpdk.git] / drivers / net / bnx2x / bnx2x_stats.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright (c) 2007-2013 Broadcom Corporation.
3  *
4  * Eric Davis        <edavis@broadcom.com>
5  * David Christensen <davidch@broadcom.com>
6  * Gary Zambrano     <zambrano@broadcom.com>
7  *
8  * Copyright (c) 2013-2015 Brocade Communications Systems, Inc.
9  * Copyright (c) 2015-2018 Cavium Inc.
10  * All rights reserved.
11  * www.cavium.com
12  */
13
14 #include "bnx2x.h"
15 #include "bnx2x_stats.h"
16
17 #ifdef __i386__
18 #define BITS_PER_LONG 32
19 #else
20 #define BITS_PER_LONG 64
21 #endif
22
23 static inline uint16_t
24 bnx2x_get_port_stats_dma_len(struct bnx2x_softc *sc)
25 {
26         uint16_t res = 0;
27         uint32_t size;
28
29         /* 'newest' convention - shmem2 contains the size of the port stats */
30         if (SHMEM2_HAS(sc, sizeof_port_stats)) {
31                 size = SHMEM2_RD(sc, sizeof_port_stats);
32                 if (size) {
33                         res = size;
34                 }
35
36                 /* prevent newer BC from causing buffer overflow */
37                 if (res > sizeof(struct host_port_stats)) {
38                         res = sizeof(struct host_port_stats);
39                 }
40         }
41
42         /*
43          * Older convention - all BCs support the port stats fields up until
44          * the 'not_used' field
45          */
46         if (!res) {
47                 res = (offsetof(struct host_port_stats, not_used) + 4);
48
49                 /* if PFC stats are supported by the MFW, DMA them as well */
50                 if (sc->devinfo.bc_ver >= REQ_BC_VER_4_PFC_STATS_SUPPORTED) {
51                         res += (offsetof(struct host_port_stats, pfc_frames_rx_lo) -
52                                 offsetof(struct host_port_stats, pfc_frames_tx_hi) + 4);
53                 }
54         }
55
56         res >>= 2;
57
58         return res;
59 }
60
61 /*
62  * Init service functions
63  */
64
65 /*
66  * Post the next statistics ramrod. Protect it with the lock in
67  * order to ensure the strict order between statistics ramrods
68  * (each ramrod has a sequence number passed in a
69  * sc->fw_stats_req->hdr.drv_stats_counter and ramrods must be
70  * sent in order).
71  */
72 static void
73 bnx2x_storm_stats_post(struct bnx2x_softc *sc)
74 {
75         int rc;
76
77         if (!sc->stats_pending) {
78                 if (sc->stats_pending) {
79                         return;
80                 }
81
82                 sc->fw_stats_req->hdr.drv_stats_counter =
83                         htole16(sc->stats_counter++);
84
85                 PMD_DEBUG_PERIODIC_LOG(DEBUG, sc,
86                                 "sending statistics ramrod %d",
87                                 le16toh(sc->fw_stats_req->hdr.drv_stats_counter));
88
89                 /* adjust the ramrod to include VF queues statistics */
90
91                 /* send FW stats ramrod */
92                 rc = bnx2x_sp_post(sc, RAMROD_CMD_ID_COMMON_STAT_QUERY, 0,
93                                 U64_HI(sc->fw_stats_req_mapping),
94                                 U64_LO(sc->fw_stats_req_mapping),
95                                 NONE_CONNECTION_TYPE);
96                 if (rc == 0) {
97                         sc->stats_pending = 1;
98                 }
99         }
100 }
101
102 static void
103 bnx2x_hw_stats_post(struct bnx2x_softc *sc)
104 {
105         struct dmae_command *dmae = &sc->stats_dmae;
106         uint32_t *stats_comp = BNX2X_SP(sc, stats_comp);
107         int loader_idx;
108         uint32_t opcode;
109
110         *stats_comp = DMAE_COMP_VAL;
111         if (CHIP_REV_IS_SLOW(sc)) {
112                 return;
113         }
114
115         /* Update MCP's statistics if possible */
116         if (sc->func_stx) {
117                 rte_memcpy(BNX2X_SP(sc, func_stats), &sc->func_stats,
118                                 sizeof(sc->func_stats));
119         }
120
121         /* loader */
122         if (sc->executer_idx) {
123                 loader_idx = PMF_DMAE_C(sc);
124                 opcode =  bnx2x_dmae_opcode(sc, DMAE_SRC_PCI, DMAE_DST_GRC,
125                                 TRUE, DMAE_COMP_GRC);
126                 opcode = bnx2x_dmae_opcode_clr_src_reset(opcode);
127
128                 memset(dmae, 0, sizeof(struct dmae_command));
129                 dmae->opcode = opcode;
130                 dmae->src_addr_lo = U64_LO(BNX2X_SP_MAPPING(sc, dmae[0]));
131                 dmae->src_addr_hi = U64_HI(BNX2X_SP_MAPPING(sc, dmae[0]));
132                 dmae->dst_addr_lo = ((DMAE_REG_CMD_MEM +
133                                         sizeof(struct dmae_command) *
134                                         (loader_idx + 1)) >> 2);
135                 dmae->dst_addr_hi = 0;
136                 dmae->len = sizeof(struct dmae_command) >> 2;
137                 dmae->comp_addr_lo = (dmae_reg_go_c[loader_idx + 1] >> 2);
138                 dmae->comp_addr_hi = 0;
139                 dmae->comp_val = 1;
140
141                 *stats_comp = 0;
142                 bnx2x_post_dmae(sc, dmae, loader_idx);
143         } else if (sc->func_stx) {
144                 *stats_comp = 0;
145                 bnx2x_post_dmae(sc, dmae, INIT_DMAE_C(sc));
146         }
147 }
148
149 static int
150 bnx2x_stats_comp(struct bnx2x_softc *sc)
151 {
152         uint32_t *stats_comp = BNX2X_SP(sc, stats_comp);
153         int cnt = 10;
154
155         while (*stats_comp != DMAE_COMP_VAL) {
156                 if (!cnt) {
157                         PMD_DRV_LOG(ERR, sc, "Timeout waiting for stats finished");
158                         break;
159                 }
160
161                 cnt--;
162                 DELAY(1000);
163         }
164
165         return 1;
166 }
167
168 /*
169  * Statistics service functions
170  */
171
172 static void
173 bnx2x_stats_pmf_update(struct bnx2x_softc *sc)
174 {
175         struct dmae_command *dmae;
176         uint32_t opcode;
177         int loader_idx = PMF_DMAE_C(sc);
178         uint32_t *stats_comp = BNX2X_SP(sc, stats_comp);
179
180         if (sc->devinfo.bc_ver <= 0x06001400) {
181                 /*
182                  * Bootcode v6.0.21 fixed a GRC timeout that occurs when accessing
183                  * BRB registers while the BRB block is in reset. The DMA transfer
184                  * below triggers this issue resulting in the DMAE to stop
185                  * functioning. Skip this initial stats transfer for old bootcode
186                  * versions <= 6.0.20.
187                  */
188                 return;
189         }
190         /* sanity */
191         if (!sc->port.pmf || !sc->port.port_stx) {
192                 PMD_DRV_LOG(ERR, sc, "BUG!");
193                 return;
194         }
195
196         sc->executer_idx = 0;
197
198         opcode = bnx2x_dmae_opcode(sc, DMAE_SRC_GRC, DMAE_DST_PCI, FALSE, 0);
199
200         dmae = BNX2X_SP(sc, dmae[sc->executer_idx++]);
201         dmae->opcode = bnx2x_dmae_opcode_add_comp(opcode, DMAE_COMP_GRC);
202         dmae->src_addr_lo = (sc->port.port_stx >> 2);
203         dmae->src_addr_hi = 0;
204         dmae->dst_addr_lo = U64_LO(BNX2X_SP_MAPPING(sc, port_stats));
205         dmae->dst_addr_hi = U64_HI(BNX2X_SP_MAPPING(sc, port_stats));
206         dmae->len = DMAE_LEN32_RD_MAX;
207         dmae->comp_addr_lo = (dmae_reg_go_c[loader_idx] >> 2);
208         dmae->comp_addr_hi = 0;
209         dmae->comp_val = 1;
210
211         dmae = BNX2X_SP(sc, dmae[sc->executer_idx++]);
212         dmae->opcode = bnx2x_dmae_opcode_add_comp(opcode, DMAE_COMP_PCI);
213         dmae->src_addr_lo = ((sc->port.port_stx >> 2) + DMAE_LEN32_RD_MAX);
214         dmae->src_addr_hi = 0;
215         dmae->dst_addr_lo = U64_LO(BNX2X_SP_MAPPING(sc, port_stats) +
216                         DMAE_LEN32_RD_MAX * 4);
217         dmae->dst_addr_hi = U64_HI(BNX2X_SP_MAPPING(sc, port_stats) +
218                         DMAE_LEN32_RD_MAX * 4);
219         dmae->len = (bnx2x_get_port_stats_dma_len(sc) - DMAE_LEN32_RD_MAX);
220
221         dmae->comp_addr_lo = U64_LO(BNX2X_SP_MAPPING(sc, stats_comp));
222         dmae->comp_addr_hi = U64_HI(BNX2X_SP_MAPPING(sc, stats_comp));
223         dmae->comp_val = DMAE_COMP_VAL;
224
225         *stats_comp = 0;
226         bnx2x_hw_stats_post(sc);
227         bnx2x_stats_comp(sc);
228 }
229
230 static void
231 bnx2x_port_stats_init(struct bnx2x_softc *sc)
232 {
233     struct dmae_command *dmae;
234     int port = SC_PORT(sc);
235     uint32_t opcode;
236     int loader_idx = PMF_DMAE_C(sc);
237     uint32_t mac_addr;
238     uint32_t *stats_comp = BNX2X_SP(sc, stats_comp);
239
240     /* sanity */
241     if (!sc->link_vars.link_up || !sc->port.pmf) {
242         PMD_DRV_LOG(ERR, sc, "BUG!");
243         return;
244     }
245
246     sc->executer_idx = 0;
247
248     /* MCP */
249     opcode = bnx2x_dmae_opcode(sc, DMAE_SRC_PCI, DMAE_DST_GRC,
250                              TRUE, DMAE_COMP_GRC);
251
252     if (sc->port.port_stx) {
253         dmae = BNX2X_SP(sc, dmae[sc->executer_idx++]);
254         dmae->opcode = opcode;
255         dmae->src_addr_lo = U64_LO(BNX2X_SP_MAPPING(sc, port_stats));
256         dmae->src_addr_hi = U64_HI(BNX2X_SP_MAPPING(sc, port_stats));
257         dmae->dst_addr_lo = sc->port.port_stx >> 2;
258         dmae->dst_addr_hi = 0;
259         dmae->len = bnx2x_get_port_stats_dma_len(sc);
260         dmae->comp_addr_lo = dmae_reg_go_c[loader_idx] >> 2;
261         dmae->comp_addr_hi = 0;
262         dmae->comp_val = 1;
263     }
264
265     if (sc->func_stx) {
266         dmae = BNX2X_SP(sc, dmae[sc->executer_idx++]);
267         dmae->opcode = opcode;
268         dmae->src_addr_lo = U64_LO(BNX2X_SP_MAPPING(sc, func_stats));
269         dmae->src_addr_hi = U64_HI(BNX2X_SP_MAPPING(sc, func_stats));
270         dmae->dst_addr_lo = (sc->func_stx >> 2);
271         dmae->dst_addr_hi = 0;
272         dmae->len = (sizeof(struct host_func_stats) >> 2);
273         dmae->comp_addr_lo = (dmae_reg_go_c[loader_idx] >> 2);
274         dmae->comp_addr_hi = 0;
275         dmae->comp_val = 1;
276     }
277
278     /* MAC */
279     opcode = bnx2x_dmae_opcode(sc, DMAE_SRC_GRC, DMAE_DST_PCI,
280                              TRUE, DMAE_COMP_GRC);
281
282     /* EMAC is special */
283     if (sc->link_vars.mac_type == ELINK_MAC_TYPE_EMAC) {
284         mac_addr = (port ? GRCBASE_EMAC1 : GRCBASE_EMAC0);
285
286         /* EMAC_REG_EMAC_RX_STAT_AC (EMAC_REG_EMAC_RX_STAT_AC_COUNT)*/
287         dmae = BNX2X_SP(sc, dmae[sc->executer_idx++]);
288         dmae->opcode = opcode;
289         dmae->src_addr_lo = (mac_addr + EMAC_REG_EMAC_RX_STAT_AC) >> 2;
290         dmae->src_addr_hi = 0;
291         dmae->dst_addr_lo = U64_LO(BNX2X_SP_MAPPING(sc, mac_stats));
292         dmae->dst_addr_hi = U64_HI(BNX2X_SP_MAPPING(sc, mac_stats));
293         dmae->len = EMAC_REG_EMAC_RX_STAT_AC_COUNT;
294         dmae->comp_addr_lo = (dmae_reg_go_c[loader_idx] >> 2);
295         dmae->comp_addr_hi = 0;
296         dmae->comp_val = 1;
297
298         /* EMAC_REG_EMAC_RX_STAT_AC_28 */
299         dmae = BNX2X_SP(sc, dmae[sc->executer_idx++]);
300         dmae->opcode = opcode;
301         dmae->src_addr_lo = ((mac_addr + EMAC_REG_EMAC_RX_STAT_AC_28) >> 2);
302         dmae->src_addr_hi = 0;
303         dmae->dst_addr_lo = U64_LO(BNX2X_SP_MAPPING(sc, mac_stats) +
304                                    offsetof(struct emac_stats,
305                                             rx_stat_falsecarriererrors));
306         dmae->dst_addr_hi = U64_HI(BNX2X_SP_MAPPING(sc, mac_stats) +
307                                    offsetof(struct emac_stats,
308                                             rx_stat_falsecarriererrors));
309         dmae->len = 1;
310         dmae->comp_addr_lo = (dmae_reg_go_c[loader_idx] >> 2);
311         dmae->comp_addr_hi = 0;
312         dmae->comp_val = 1;
313
314         /* EMAC_REG_EMAC_TX_STAT_AC (EMAC_REG_EMAC_TX_STAT_AC_COUNT)*/
315         dmae = BNX2X_SP(sc, dmae[sc->executer_idx++]);
316         dmae->opcode = opcode;
317         dmae->src_addr_lo = ((mac_addr + EMAC_REG_EMAC_TX_STAT_AC) >> 2);
318         dmae->src_addr_hi = 0;
319         dmae->dst_addr_lo = U64_LO(BNX2X_SP_MAPPING(sc, mac_stats) +
320                                    offsetof(struct emac_stats,
321                                             tx_stat_ifhcoutoctets));
322         dmae->dst_addr_hi = U64_HI(BNX2X_SP_MAPPING(sc, mac_stats) +
323                                    offsetof(struct emac_stats,
324                                             tx_stat_ifhcoutoctets));
325         dmae->len = EMAC_REG_EMAC_TX_STAT_AC_COUNT;
326         dmae->comp_addr_lo = (dmae_reg_go_c[loader_idx] >> 2);
327         dmae->comp_addr_hi = 0;
328         dmae->comp_val = 1;
329     } else {
330         uint32_t tx_src_addr_lo, rx_src_addr_lo;
331         uint16_t rx_len, tx_len;
332
333         /* configure the params according to MAC type */
334         switch (sc->link_vars.mac_type) {
335         case ELINK_MAC_TYPE_BMAC:
336             mac_addr = (port) ? NIG_REG_INGRESS_BMAC1_MEM :
337                                 NIG_REG_INGRESS_BMAC0_MEM;
338
339             /* BIGMAC_REGISTER_TX_STAT_GTPKT ..
340                BIGMAC_REGISTER_TX_STAT_GTBYT */
341             if (CHIP_IS_E1x(sc)) {
342                 tx_src_addr_lo =
343                     ((mac_addr + BIGMAC_REGISTER_TX_STAT_GTPKT) >> 2);
344                 tx_len = ((8 + BIGMAC_REGISTER_TX_STAT_GTBYT -
345                            BIGMAC_REGISTER_TX_STAT_GTPKT) >> 2);
346                 rx_src_addr_lo =
347                     ((mac_addr + BIGMAC_REGISTER_RX_STAT_GR64) >> 2);
348                 rx_len = ((8 + BIGMAC_REGISTER_RX_STAT_GRIPJ -
349                            BIGMAC_REGISTER_RX_STAT_GR64) >> 2);
350             } else {
351                 tx_src_addr_lo =
352                     ((mac_addr + BIGMAC2_REGISTER_TX_STAT_GTPOK) >> 2);
353                 tx_len = ((8 + BIGMAC2_REGISTER_TX_STAT_GTBYT -
354                            BIGMAC2_REGISTER_TX_STAT_GTPOK) >> 2);
355                 rx_src_addr_lo =
356                     ((mac_addr + BIGMAC2_REGISTER_RX_STAT_GR64) >> 2);
357                 rx_len = ((8 + BIGMAC2_REGISTER_RX_STAT_GRIPJ -
358                            BIGMAC2_REGISTER_RX_STAT_GR64) >> 2);
359             }
360
361             break;
362
363         case ELINK_MAC_TYPE_UMAC: /* handled by MSTAT */
364         case ELINK_MAC_TYPE_XMAC: /* handled by MSTAT */
365         default:
366             mac_addr = (port) ? GRCBASE_MSTAT1 : GRCBASE_MSTAT0;
367             tx_src_addr_lo = ((mac_addr + MSTAT_REG_TX_STAT_GTXPOK_LO) >> 2);
368             rx_src_addr_lo = ((mac_addr + MSTAT_REG_RX_STAT_GR64_LO) >> 2);
369             tx_len =
370                 (sizeof(sc->sp->mac_stats.mstat_stats.stats_tx) >> 2);
371             rx_len =
372                 (sizeof(sc->sp->mac_stats.mstat_stats.stats_rx) >> 2);
373             break;
374         }
375
376         /* TX stats */
377         dmae = BNX2X_SP(sc, dmae[sc->executer_idx++]);
378         dmae->opcode = opcode;
379         dmae->src_addr_lo = tx_src_addr_lo;
380         dmae->src_addr_hi = 0;
381         dmae->len = tx_len;
382         dmae->dst_addr_lo = U64_LO(BNX2X_SP_MAPPING(sc, mac_stats));
383         dmae->dst_addr_hi = U64_HI(BNX2X_SP_MAPPING(sc, mac_stats));
384         dmae->comp_addr_lo = dmae_reg_go_c[loader_idx] >> 2;
385         dmae->comp_addr_hi = 0;
386         dmae->comp_val = 1;
387
388         /* RX stats */
389         dmae = BNX2X_SP(sc, dmae[sc->executer_idx++]);
390         dmae->opcode = opcode;
391         dmae->src_addr_hi = 0;
392         dmae->src_addr_lo = rx_src_addr_lo;
393         dmae->dst_addr_lo =
394             U64_LO(BNX2X_SP_MAPPING(sc, mac_stats) + (tx_len << 2));
395         dmae->dst_addr_hi =
396             U64_HI(BNX2X_SP_MAPPING(sc, mac_stats) + (tx_len << 2));
397         dmae->len = rx_len;
398         dmae->comp_addr_lo = dmae_reg_go_c[loader_idx] >> 2;
399         dmae->comp_addr_hi = 0;
400         dmae->comp_val = 1;
401     }
402
403     /* NIG */
404     if (!CHIP_IS_E3(sc)) {
405         dmae = BNX2X_SP(sc, dmae[sc->executer_idx++]);
406         dmae->opcode = opcode;
407         dmae->src_addr_lo =
408             (port ? NIG_REG_STAT1_EGRESS_MAC_PKT0 :
409                     NIG_REG_STAT0_EGRESS_MAC_PKT0) >> 2;
410         dmae->src_addr_hi = 0;
411         dmae->dst_addr_lo = U64_LO(BNX2X_SP_MAPPING(sc, nig_stats) +
412                                    offsetof(struct nig_stats,
413                                             egress_mac_pkt0_lo));
414         dmae->dst_addr_hi = U64_HI(BNX2X_SP_MAPPING(sc, nig_stats) +
415                                    offsetof(struct nig_stats,
416                                             egress_mac_pkt0_lo));
417         dmae->len = ((2 * sizeof(uint32_t)) >> 2);
418         dmae->comp_addr_lo = (dmae_reg_go_c[loader_idx] >> 2);
419         dmae->comp_addr_hi = 0;
420         dmae->comp_val = 1;
421
422         dmae = BNX2X_SP(sc, dmae[sc->executer_idx++]);
423         dmae->opcode = opcode;
424         dmae->src_addr_lo =
425             (port ? NIG_REG_STAT1_EGRESS_MAC_PKT1 :
426                     NIG_REG_STAT0_EGRESS_MAC_PKT1) >> 2;
427         dmae->src_addr_hi = 0;
428         dmae->dst_addr_lo = U64_LO(BNX2X_SP_MAPPING(sc, nig_stats) +
429                                    offsetof(struct nig_stats,
430                                             egress_mac_pkt1_lo));
431         dmae->dst_addr_hi = U64_HI(BNX2X_SP_MAPPING(sc, nig_stats) +
432                                    offsetof(struct nig_stats,
433                                             egress_mac_pkt1_lo));
434         dmae->len = ((2 * sizeof(uint32_t)) >> 2);
435         dmae->comp_addr_lo = (dmae_reg_go_c[loader_idx] >> 2);
436         dmae->comp_addr_hi = 0;
437         dmae->comp_val = 1;
438     }
439
440     dmae = BNX2X_SP(sc, dmae[sc->executer_idx++]);
441     dmae->opcode = bnx2x_dmae_opcode(sc, DMAE_SRC_GRC, DMAE_DST_PCI,
442                                    TRUE, DMAE_COMP_PCI);
443     dmae->src_addr_lo =
444         (port ? NIG_REG_STAT1_BRB_DISCARD :
445                 NIG_REG_STAT0_BRB_DISCARD) >> 2;
446     dmae->src_addr_hi = 0;
447     dmae->dst_addr_lo = U64_LO(BNX2X_SP_MAPPING(sc, nig_stats));
448     dmae->dst_addr_hi = U64_HI(BNX2X_SP_MAPPING(sc, nig_stats));
449     dmae->len = (sizeof(struct nig_stats) - 4*sizeof(uint32_t)) >> 2;
450
451     dmae->comp_addr_lo = U64_LO(BNX2X_SP_MAPPING(sc, stats_comp));
452     dmae->comp_addr_hi = U64_HI(BNX2X_SP_MAPPING(sc, stats_comp));
453     dmae->comp_val = DMAE_COMP_VAL;
454
455     *stats_comp = 0;
456 }
457
458 static void
459 bnx2x_func_stats_init(struct bnx2x_softc *sc)
460 {
461     struct dmae_command *dmae = &sc->stats_dmae;
462     uint32_t *stats_comp = BNX2X_SP(sc, stats_comp);
463
464     /* sanity */
465     if (!sc->func_stx) {
466         PMD_DRV_LOG(ERR, sc, "BUG!");
467         return;
468     }
469
470     sc->executer_idx = 0;
471     memset(dmae, 0, sizeof(struct dmae_command));
472
473     dmae->opcode = bnx2x_dmae_opcode(sc, DMAE_SRC_PCI, DMAE_DST_GRC,
474                                    TRUE, DMAE_COMP_PCI);
475     dmae->src_addr_lo = U64_LO(BNX2X_SP_MAPPING(sc, func_stats));
476     dmae->src_addr_hi = U64_HI(BNX2X_SP_MAPPING(sc, func_stats));
477     dmae->dst_addr_lo = (sc->func_stx >> 2);
478     dmae->dst_addr_hi = 0;
479     dmae->len = (sizeof(struct host_func_stats) >> 2);
480     dmae->comp_addr_lo = U64_LO(BNX2X_SP_MAPPING(sc, stats_comp));
481     dmae->comp_addr_hi = U64_HI(BNX2X_SP_MAPPING(sc, stats_comp));
482     dmae->comp_val = DMAE_COMP_VAL;
483
484     *stats_comp = 0;
485 }
486
487 static void
488 bnx2x_stats_start(struct bnx2x_softc *sc)
489 {
490     /*
491      * VFs travel through here as part of the statistics FSM, but no action
492      * is required
493      */
494     if (IS_VF(sc)) {
495         return;
496     }
497
498     if (sc->port.pmf) {
499         bnx2x_port_stats_init(sc);
500     }
501
502     else if (sc->func_stx) {
503         bnx2x_func_stats_init(sc);
504     }
505
506     bnx2x_hw_stats_post(sc);
507     bnx2x_storm_stats_post(sc);
508 }
509
510 static void
511 bnx2x_stats_pmf_start(struct bnx2x_softc *sc)
512 {
513     bnx2x_stats_comp(sc);
514     bnx2x_stats_pmf_update(sc);
515     bnx2x_stats_start(sc);
516 }
517
518 static void
519 bnx2x_stats_restart(struct bnx2x_softc *sc)
520 {
521     /*
522      * VFs travel through here as part of the statistics FSM, but no action
523      * is required
524      */
525     if (IS_VF(sc)) {
526         return;
527     }
528
529     bnx2x_stats_comp(sc);
530     bnx2x_stats_start(sc);
531 }
532
533 static void
534 bnx2x_bmac_stats_update(struct bnx2x_softc *sc)
535 {
536     struct host_port_stats *pstats = BNX2X_SP(sc, port_stats);
537     struct bnx2x_eth_stats *estats = &sc->eth_stats;
538     struct {
539         uint32_t lo;
540         uint32_t hi;
541     } diff;
542
543     if (CHIP_IS_E1x(sc)) {
544         struct bmac1_stats *new = BNX2X_SP(sc, mac_stats.bmac1_stats);
545
546         /* the macros below will use "bmac1_stats" type */
547         UPDATE_STAT64(rx_stat_grerb, rx_stat_ifhcinbadoctets);
548         UPDATE_STAT64(rx_stat_grfcs, rx_stat_dot3statsfcserrors);
549         UPDATE_STAT64(rx_stat_grund, rx_stat_etherstatsundersizepkts);
550         UPDATE_STAT64(rx_stat_grovr, rx_stat_dot3statsframestoolong);
551         UPDATE_STAT64(rx_stat_grfrg, rx_stat_etherstatsfragments);
552         UPDATE_STAT64(rx_stat_grjbr, rx_stat_etherstatsjabbers);
553         UPDATE_STAT64(rx_stat_grxcf, rx_stat_maccontrolframesreceived);
554         UPDATE_STAT64(rx_stat_grxpf, rx_stat_xoffstateentered);
555         UPDATE_STAT64(rx_stat_grxpf, rx_stat_mac_xpf);
556
557         UPDATE_STAT64(tx_stat_gtxpf, tx_stat_outxoffsent);
558         UPDATE_STAT64(tx_stat_gtxpf, tx_stat_flowcontroldone);
559         UPDATE_STAT64(tx_stat_gt64, tx_stat_etherstatspkts64octets);
560         UPDATE_STAT64(tx_stat_gt127,
561                       tx_stat_etherstatspkts65octetsto127octets);
562         UPDATE_STAT64(tx_stat_gt255,
563                       tx_stat_etherstatspkts128octetsto255octets);
564         UPDATE_STAT64(tx_stat_gt511,
565                       tx_stat_etherstatspkts256octetsto511octets);
566         UPDATE_STAT64(tx_stat_gt1023,
567                       tx_stat_etherstatspkts512octetsto1023octets);
568         UPDATE_STAT64(tx_stat_gt1518,
569                       tx_stat_etherstatspkts1024octetsto1522octets);
570         UPDATE_STAT64(tx_stat_gt2047, tx_stat_mac_2047);
571         UPDATE_STAT64(tx_stat_gt4095, tx_stat_mac_4095);
572         UPDATE_STAT64(tx_stat_gt9216, tx_stat_mac_9216);
573         UPDATE_STAT64(tx_stat_gt16383, tx_stat_mac_16383);
574         UPDATE_STAT64(tx_stat_gterr,
575                       tx_stat_dot3statsinternalmactransmiterrors);
576         UPDATE_STAT64(tx_stat_gtufl, tx_stat_mac_ufl);
577     } else {
578         struct bmac2_stats *new = BNX2X_SP(sc, mac_stats.bmac2_stats);
579         struct bnx2x_fw_port_stats_old *fwstats = &sc->fw_stats_old;
580
581         /* the macros below will use "bmac2_stats" type */
582         UPDATE_STAT64(rx_stat_grerb, rx_stat_ifhcinbadoctets);
583         UPDATE_STAT64(rx_stat_grfcs, rx_stat_dot3statsfcserrors);
584         UPDATE_STAT64(rx_stat_grund, rx_stat_etherstatsundersizepkts);
585         UPDATE_STAT64(rx_stat_grovr, rx_stat_dot3statsframestoolong);
586         UPDATE_STAT64(rx_stat_grfrg, rx_stat_etherstatsfragments);
587         UPDATE_STAT64(rx_stat_grjbr, rx_stat_etherstatsjabbers);
588         UPDATE_STAT64(rx_stat_grxcf, rx_stat_maccontrolframesreceived);
589         UPDATE_STAT64(rx_stat_grxpf, rx_stat_xoffstateentered);
590         UPDATE_STAT64(rx_stat_grxpf, rx_stat_mac_xpf);
591         UPDATE_STAT64(tx_stat_gtxpf, tx_stat_outxoffsent);
592         UPDATE_STAT64(tx_stat_gtxpf, tx_stat_flowcontroldone);
593         UPDATE_STAT64(tx_stat_gt64, tx_stat_etherstatspkts64octets);
594         UPDATE_STAT64(tx_stat_gt127,
595                       tx_stat_etherstatspkts65octetsto127octets);
596         UPDATE_STAT64(tx_stat_gt255,
597                       tx_stat_etherstatspkts128octetsto255octets);
598         UPDATE_STAT64(tx_stat_gt511,
599                       tx_stat_etherstatspkts256octetsto511octets);
600         UPDATE_STAT64(tx_stat_gt1023,
601                       tx_stat_etherstatspkts512octetsto1023octets);
602         UPDATE_STAT64(tx_stat_gt1518,
603                       tx_stat_etherstatspkts1024octetsto1522octets);
604         UPDATE_STAT64(tx_stat_gt2047, tx_stat_mac_2047);
605         UPDATE_STAT64(tx_stat_gt4095, tx_stat_mac_4095);
606         UPDATE_STAT64(tx_stat_gt9216, tx_stat_mac_9216);
607         UPDATE_STAT64(tx_stat_gt16383, tx_stat_mac_16383);
608         UPDATE_STAT64(tx_stat_gterr,
609                       tx_stat_dot3statsinternalmactransmiterrors);
610         UPDATE_STAT64(tx_stat_gtufl, tx_stat_mac_ufl);
611
612         /* collect PFC stats */
613         pstats->pfc_frames_tx_hi = new->tx_stat_gtpp_hi;
614         pstats->pfc_frames_tx_lo = new->tx_stat_gtpp_lo;
615         ADD_64(pstats->pfc_frames_tx_hi, fwstats->pfc_frames_tx_hi,
616                pstats->pfc_frames_tx_lo, fwstats->pfc_frames_tx_lo);
617
618         pstats->pfc_frames_rx_hi = new->rx_stat_grpp_hi;
619         pstats->pfc_frames_rx_lo = new->rx_stat_grpp_lo;
620         ADD_64(pstats->pfc_frames_rx_hi, fwstats->pfc_frames_rx_hi,
621                pstats->pfc_frames_rx_lo, fwstats->pfc_frames_rx_lo);
622     }
623
624     estats->pause_frames_received_hi = pstats->mac_stx[1].rx_stat_mac_xpf_hi;
625     estats->pause_frames_received_lo = pstats->mac_stx[1].rx_stat_mac_xpf_lo;
626
627     estats->pause_frames_sent_hi = pstats->mac_stx[1].tx_stat_outxoffsent_hi;
628     estats->pause_frames_sent_lo = pstats->mac_stx[1].tx_stat_outxoffsent_lo;
629
630     estats->pfc_frames_received_hi = pstats->pfc_frames_rx_hi;
631     estats->pfc_frames_received_lo = pstats->pfc_frames_rx_lo;
632     estats->pfc_frames_sent_hi = pstats->pfc_frames_tx_hi;
633     estats->pfc_frames_sent_lo = pstats->pfc_frames_tx_lo;
634 }
635
636 static void
637 bnx2x_mstat_stats_update(struct bnx2x_softc *sc)
638 {
639     struct host_port_stats *pstats = BNX2X_SP(sc, port_stats);
640     struct bnx2x_eth_stats *estats = &sc->eth_stats;
641     struct mstat_stats *new = BNX2X_SP(sc, mac_stats.mstat_stats);
642
643     ADD_STAT64(stats_rx.rx_grerb, rx_stat_ifhcinbadoctets);
644     ADD_STAT64(stats_rx.rx_grfcs, rx_stat_dot3statsfcserrors);
645     ADD_STAT64(stats_rx.rx_grund, rx_stat_etherstatsundersizepkts);
646     ADD_STAT64(stats_rx.rx_grovr, rx_stat_dot3statsframestoolong);
647     ADD_STAT64(stats_rx.rx_grfrg, rx_stat_etherstatsfragments);
648     ADD_STAT64(stats_rx.rx_grxcf, rx_stat_maccontrolframesreceived);
649     ADD_STAT64(stats_rx.rx_grxpf, rx_stat_xoffstateentered);
650     ADD_STAT64(stats_rx.rx_grxpf, rx_stat_mac_xpf);
651     ADD_STAT64(stats_tx.tx_gtxpf, tx_stat_outxoffsent);
652     ADD_STAT64(stats_tx.tx_gtxpf, tx_stat_flowcontroldone);
653
654     /* collect pfc stats */
655     ADD_64(pstats->pfc_frames_tx_hi, new->stats_tx.tx_gtxpp_hi,
656            pstats->pfc_frames_tx_lo, new->stats_tx.tx_gtxpp_lo);
657     ADD_64(pstats->pfc_frames_rx_hi, new->stats_rx.rx_grxpp_hi,
658            pstats->pfc_frames_rx_lo, new->stats_rx.rx_grxpp_lo);
659
660     ADD_STAT64(stats_tx.tx_gt64, tx_stat_etherstatspkts64octets);
661     ADD_STAT64(stats_tx.tx_gt127, tx_stat_etherstatspkts65octetsto127octets);
662     ADD_STAT64(stats_tx.tx_gt255, tx_stat_etherstatspkts128octetsto255octets);
663     ADD_STAT64(stats_tx.tx_gt511, tx_stat_etherstatspkts256octetsto511octets);
664     ADD_STAT64(stats_tx.tx_gt1023,
665                tx_stat_etherstatspkts512octetsto1023octets);
666     ADD_STAT64(stats_tx.tx_gt1518,
667                tx_stat_etherstatspkts1024octetsto1522octets);
668     ADD_STAT64(stats_tx.tx_gt2047, tx_stat_mac_2047);
669
670     ADD_STAT64(stats_tx.tx_gt4095, tx_stat_mac_4095);
671     ADD_STAT64(stats_tx.tx_gt9216, tx_stat_mac_9216);
672     ADD_STAT64(stats_tx.tx_gt16383, tx_stat_mac_16383);
673
674     ADD_STAT64(stats_tx.tx_gterr, tx_stat_dot3statsinternalmactransmiterrors);
675     ADD_STAT64(stats_tx.tx_gtufl, tx_stat_mac_ufl);
676
677     estats->etherstatspkts1024octetsto1522octets_hi =
678         pstats->mac_stx[1].tx_stat_etherstatspkts1024octetsto1522octets_hi;
679     estats->etherstatspkts1024octetsto1522octets_lo =
680         pstats->mac_stx[1].tx_stat_etherstatspkts1024octetsto1522octets_lo;
681
682     estats->etherstatspktsover1522octets_hi =
683         pstats->mac_stx[1].tx_stat_mac_2047_hi;
684     estats->etherstatspktsover1522octets_lo =
685         pstats->mac_stx[1].tx_stat_mac_2047_lo;
686
687     ADD_64(estats->etherstatspktsover1522octets_hi,
688            pstats->mac_stx[1].tx_stat_mac_4095_hi,
689            estats->etherstatspktsover1522octets_lo,
690            pstats->mac_stx[1].tx_stat_mac_4095_lo);
691
692     ADD_64(estats->etherstatspktsover1522octets_hi,
693            pstats->mac_stx[1].tx_stat_mac_9216_hi,
694            estats->etherstatspktsover1522octets_lo,
695            pstats->mac_stx[1].tx_stat_mac_9216_lo);
696
697     ADD_64(estats->etherstatspktsover1522octets_hi,
698            pstats->mac_stx[1].tx_stat_mac_16383_hi,
699            estats->etherstatspktsover1522octets_lo,
700            pstats->mac_stx[1].tx_stat_mac_16383_lo);
701
702     estats->pause_frames_received_hi = pstats->mac_stx[1].rx_stat_mac_xpf_hi;
703     estats->pause_frames_received_lo = pstats->mac_stx[1].rx_stat_mac_xpf_lo;
704
705     estats->pause_frames_sent_hi = pstats->mac_stx[1].tx_stat_outxoffsent_hi;
706     estats->pause_frames_sent_lo = pstats->mac_stx[1].tx_stat_outxoffsent_lo;
707
708     estats->pfc_frames_received_hi = pstats->pfc_frames_rx_hi;
709     estats->pfc_frames_received_lo = pstats->pfc_frames_rx_lo;
710     estats->pfc_frames_sent_hi = pstats->pfc_frames_tx_hi;
711     estats->pfc_frames_sent_lo = pstats->pfc_frames_tx_lo;
712 }
713
714 static void
715 bnx2x_emac_stats_update(struct bnx2x_softc *sc)
716 {
717     struct emac_stats *new = BNX2X_SP(sc, mac_stats.emac_stats);
718     struct host_port_stats *pstats = BNX2X_SP(sc, port_stats);
719     struct bnx2x_eth_stats *estats = &sc->eth_stats;
720
721     UPDATE_EXTEND_STAT(rx_stat_ifhcinbadoctets);
722     UPDATE_EXTEND_STAT(tx_stat_ifhcoutbadoctets);
723     UPDATE_EXTEND_STAT(rx_stat_dot3statsfcserrors);
724     UPDATE_EXTEND_STAT(rx_stat_dot3statsalignmenterrors);
725     UPDATE_EXTEND_STAT(rx_stat_dot3statscarriersenseerrors);
726     UPDATE_EXTEND_STAT(rx_stat_falsecarriererrors);
727     UPDATE_EXTEND_STAT(rx_stat_etherstatsundersizepkts);
728     UPDATE_EXTEND_STAT(rx_stat_dot3statsframestoolong);
729     UPDATE_EXTEND_STAT(rx_stat_etherstatsfragments);
730     UPDATE_EXTEND_STAT(rx_stat_etherstatsjabbers);
731     UPDATE_EXTEND_STAT(rx_stat_maccontrolframesreceived);
732     UPDATE_EXTEND_STAT(rx_stat_xoffstateentered);
733     UPDATE_EXTEND_STAT(rx_stat_xonpauseframesreceived);
734     UPDATE_EXTEND_STAT(rx_stat_xoffpauseframesreceived);
735     UPDATE_EXTEND_STAT(tx_stat_outxonsent);
736     UPDATE_EXTEND_STAT(tx_stat_outxoffsent);
737     UPDATE_EXTEND_STAT(tx_stat_flowcontroldone);
738     UPDATE_EXTEND_STAT(tx_stat_etherstatscollisions);
739     UPDATE_EXTEND_STAT(tx_stat_dot3statssinglecollisionframes);
740     UPDATE_EXTEND_STAT(tx_stat_dot3statsmultiplecollisionframes);
741     UPDATE_EXTEND_STAT(tx_stat_dot3statsdeferredtransmissions);
742     UPDATE_EXTEND_STAT(tx_stat_dot3statsexcessivecollisions);
743     UPDATE_EXTEND_STAT(tx_stat_dot3statslatecollisions);
744     UPDATE_EXTEND_STAT(tx_stat_etherstatspkts64octets);
745     UPDATE_EXTEND_STAT(tx_stat_etherstatspkts65octetsto127octets);
746     UPDATE_EXTEND_STAT(tx_stat_etherstatspkts128octetsto255octets);
747     UPDATE_EXTEND_STAT(tx_stat_etherstatspkts256octetsto511octets);
748     UPDATE_EXTEND_STAT(tx_stat_etherstatspkts512octetsto1023octets);
749     UPDATE_EXTEND_STAT(tx_stat_etherstatspkts1024octetsto1522octets);
750     UPDATE_EXTEND_STAT(tx_stat_etherstatspktsover1522octets);
751     UPDATE_EXTEND_STAT(tx_stat_dot3statsinternalmactransmiterrors);
752
753     estats->pause_frames_received_hi =
754         pstats->mac_stx[1].rx_stat_xonpauseframesreceived_hi;
755     estats->pause_frames_received_lo =
756         pstats->mac_stx[1].rx_stat_xonpauseframesreceived_lo;
757     ADD_64(estats->pause_frames_received_hi,
758            pstats->mac_stx[1].rx_stat_xoffpauseframesreceived_hi,
759            estats->pause_frames_received_lo,
760            pstats->mac_stx[1].rx_stat_xoffpauseframesreceived_lo);
761
762     estats->pause_frames_sent_hi =
763         pstats->mac_stx[1].tx_stat_outxonsent_hi;
764     estats->pause_frames_sent_lo =
765         pstats->mac_stx[1].tx_stat_outxonsent_lo;
766     ADD_64(estats->pause_frames_sent_hi,
767            pstats->mac_stx[1].tx_stat_outxoffsent_hi,
768            estats->pause_frames_sent_lo,
769            pstats->mac_stx[1].tx_stat_outxoffsent_lo);
770 }
771
772 static int
773 bnx2x_hw_stats_update(struct bnx2x_softc *sc)
774 {
775     struct nig_stats *new = BNX2X_SP(sc, nig_stats);
776     struct nig_stats *old = &(sc->port.old_nig_stats);
777     struct host_port_stats *pstats = BNX2X_SP(sc, port_stats);
778     struct bnx2x_eth_stats *estats = &sc->eth_stats;
779     uint32_t lpi_reg, nig_timer_max;
780     struct {
781         uint32_t lo;
782         uint32_t hi;
783     } diff;
784
785     switch (sc->link_vars.mac_type) {
786     case ELINK_MAC_TYPE_BMAC:
787         bnx2x_bmac_stats_update(sc);
788         break;
789
790     case ELINK_MAC_TYPE_EMAC:
791         bnx2x_emac_stats_update(sc);
792         break;
793
794     case ELINK_MAC_TYPE_UMAC:
795     case ELINK_MAC_TYPE_XMAC:
796         bnx2x_mstat_stats_update(sc);
797         break;
798
799     case ELINK_MAC_TYPE_NONE: /* unreached */
800         PMD_DRV_LOG(DEBUG, sc,
801               "stats updated by DMAE but no MAC active");
802         return -1;
803
804     default: /* unreached */
805         PMD_DRV_LOG(ERR, sc, "stats update failed, unknown MAC type");
806     }
807
808     ADD_EXTEND_64(pstats->brb_drop_hi, pstats->brb_drop_lo,
809                   new->brb_discard - old->brb_discard);
810     ADD_EXTEND_64(estats->brb_truncate_hi, estats->brb_truncate_lo,
811                   new->brb_truncate - old->brb_truncate);
812
813     if (!CHIP_IS_E3(sc)) {
814         UPDATE_STAT64_NIG(egress_mac_pkt0,
815                           etherstatspkts1024octetsto1522octets);
816         UPDATE_STAT64_NIG(egress_mac_pkt1,
817                           etherstatspktsover1522octets);
818     }
819
820     rte_memcpy(old, new, sizeof(struct nig_stats));
821
822     rte_memcpy(&(estats->rx_stat_ifhcinbadoctets_hi), &(pstats->mac_stx[1]),
823            sizeof(struct mac_stx));
824     estats->brb_drop_hi = pstats->brb_drop_hi;
825     estats->brb_drop_lo = pstats->brb_drop_lo;
826
827     pstats->host_port_stats_counter++;
828
829     if (CHIP_IS_E3(sc)) {
830         lpi_reg = (SC_PORT(sc)) ?
831                       MISC_REG_CPMU_LP_SM_ENT_CNT_P1 :
832                       MISC_REG_CPMU_LP_SM_ENT_CNT_P0;
833         estats->eee_tx_lpi += REG_RD(sc, lpi_reg);
834     }
835
836     if (!BNX2X_NOMCP(sc)) {
837         nig_timer_max = SHMEM_RD(sc, port_mb[SC_PORT(sc)].stat_nig_timer);
838         if (nig_timer_max != estats->nig_timer_max) {
839             estats->nig_timer_max = nig_timer_max;
840             PMD_DRV_LOG(ERR, sc, "invalid NIG timer max (%u)",
841                   estats->nig_timer_max);
842         }
843     }
844
845     return 0;
846 }
847
848 static int
849 bnx2x_storm_stats_validate_counters(struct bnx2x_softc *sc)
850 {
851     struct stats_counter *counters = &sc->fw_stats_data->storm_counters;
852     uint16_t cur_stats_counter;
853
854     /*
855      * Make sure we use the value of the counter
856      * used for sending the last stats ramrod.
857      */
858     cur_stats_counter = (sc->stats_counter - 1);
859
860     /* are storm stats valid? */
861     if (le16toh(counters->xstats_counter) != cur_stats_counter) {
862         PMD_DRV_LOG(DEBUG, sc,
863               "stats not updated by xstorm, "
864               "counter 0x%x != stats_counter 0x%x",
865               le16toh(counters->xstats_counter), sc->stats_counter);
866         return -EAGAIN;
867     }
868
869     if (le16toh(counters->ustats_counter) != cur_stats_counter) {
870         PMD_DRV_LOG(DEBUG, sc,
871               "stats not updated by ustorm, "
872               "counter 0x%x != stats_counter 0x%x",
873               le16toh(counters->ustats_counter), sc->stats_counter);
874         return -EAGAIN;
875     }
876
877     if (le16toh(counters->cstats_counter) != cur_stats_counter) {
878         PMD_DRV_LOG(DEBUG, sc,
879               "stats not updated by cstorm, "
880               "counter 0x%x != stats_counter 0x%x",
881               le16toh(counters->cstats_counter), sc->stats_counter);
882         return -EAGAIN;
883     }
884
885     if (le16toh(counters->tstats_counter) != cur_stats_counter) {
886         PMD_DRV_LOG(DEBUG, sc,
887               "stats not updated by tstorm, "
888               "counter 0x%x != stats_counter 0x%x",
889               le16toh(counters->tstats_counter), sc->stats_counter);
890         return -EAGAIN;
891     }
892
893     return 0;
894 }
895
896 static int
897 bnx2x_storm_stats_update(struct bnx2x_softc *sc)
898 {
899         struct tstorm_per_port_stats *tport =
900                 &sc->fw_stats_data->port.tstorm_port_statistics;
901         struct tstorm_per_pf_stats *tfunc =
902                 &sc->fw_stats_data->pf.tstorm_pf_statistics;
903         struct host_func_stats *fstats = &sc->func_stats;
904         struct bnx2x_eth_stats *estats = &sc->eth_stats;
905         struct bnx2x_eth_stats_old *estats_old = &sc->eth_stats_old;
906         int i;
907
908         /* vfs stat counter is managed by pf */
909         if (IS_PF(sc) && bnx2x_storm_stats_validate_counters(sc)) {
910                 return -EAGAIN;
911         }
912
913         estats->error_bytes_received_hi = 0;
914         estats->error_bytes_received_lo = 0;
915
916         for (i = 0; i < sc->num_queues; i++) {
917                 struct bnx2x_fastpath *fp = &sc->fp[i];
918                 struct tstorm_per_queue_stats *tclient =
919                         &sc->fw_stats_data->queue_stats[i].tstorm_queue_statistics;
920                 struct tstorm_per_queue_stats *old_tclient = &fp->old_tclient;
921                 struct ustorm_per_queue_stats *uclient =
922                         &sc->fw_stats_data->queue_stats[i].ustorm_queue_statistics;
923                 struct ustorm_per_queue_stats *old_uclient = &fp->old_uclient;
924                 struct xstorm_per_queue_stats *xclient =
925                         &sc->fw_stats_data->queue_stats[i].xstorm_queue_statistics;
926                 struct xstorm_per_queue_stats *old_xclient = &fp->old_xclient;
927                 struct bnx2x_eth_q_stats *qstats = &fp->eth_q_stats;
928                 struct bnx2x_eth_q_stats_old *qstats_old = &fp->eth_q_stats_old;
929
930                 uint32_t diff;
931
932                 /* PMD_DRV_LOG(DEBUG, sc,
933                                 "queue[%d]: ucast_sent 0x%x bcast_sent 0x%x mcast_sent 0x%x",
934                                 i, xclient->ucast_pkts_sent, xclient->bcast_pkts_sent,
935                                 xclient->mcast_pkts_sent);
936
937                 PMD_DRV_LOG(DEBUG, sc, "---------------");
938                  */
939
940                 UPDATE_QSTAT(tclient->rcv_bcast_bytes,
941                                 total_broadcast_bytes_received);
942                 UPDATE_QSTAT(tclient->rcv_mcast_bytes,
943                                 total_multicast_bytes_received);
944                 UPDATE_QSTAT(tclient->rcv_ucast_bytes,
945                                 total_unicast_bytes_received);
946
947                 /*
948                  * sum to total_bytes_received all
949                  * unicast/multicast/broadcast
950                  */
951                 qstats->total_bytes_received_hi =
952                         qstats->total_broadcast_bytes_received_hi;
953                 qstats->total_bytes_received_lo =
954                         qstats->total_broadcast_bytes_received_lo;
955
956                 ADD_64(qstats->total_bytes_received_hi,
957                                 qstats->total_multicast_bytes_received_hi,
958                                 qstats->total_bytes_received_lo,
959                                 qstats->total_multicast_bytes_received_lo);
960
961                 ADD_64(qstats->total_bytes_received_hi,
962                                 qstats->total_unicast_bytes_received_hi,
963                                 qstats->total_bytes_received_lo,
964                                 qstats->total_unicast_bytes_received_lo);
965
966                 qstats->valid_bytes_received_hi = qstats->total_bytes_received_hi;
967                 qstats->valid_bytes_received_lo = qstats->total_bytes_received_lo;
968
969                 UPDATE_EXTEND_TSTAT(rcv_ucast_pkts, total_unicast_packets_received);
970                 UPDATE_EXTEND_TSTAT(rcv_mcast_pkts, total_multicast_packets_received);
971                 UPDATE_EXTEND_TSTAT(rcv_bcast_pkts, total_broadcast_packets_received);
972                 UPDATE_EXTEND_E_TSTAT(pkts_too_big_discard,
973                                 etherstatsoverrsizepkts, 32);
974                 UPDATE_EXTEND_E_TSTAT(no_buff_discard, no_buff_discard, 16);
975
976                 SUB_EXTEND_USTAT(ucast_no_buff_pkts, total_unicast_packets_received);
977                 SUB_EXTEND_USTAT(mcast_no_buff_pkts,
978                                 total_multicast_packets_received);
979                 SUB_EXTEND_USTAT(bcast_no_buff_pkts,
980                                 total_broadcast_packets_received);
981                 UPDATE_EXTEND_E_USTAT(ucast_no_buff_pkts, no_buff_discard);
982                 UPDATE_EXTEND_E_USTAT(mcast_no_buff_pkts, no_buff_discard);
983                 UPDATE_EXTEND_E_USTAT(bcast_no_buff_pkts, no_buff_discard);
984
985                 UPDATE_QSTAT(xclient->bcast_bytes_sent,
986                                 total_broadcast_bytes_transmitted);
987                 UPDATE_QSTAT(xclient->mcast_bytes_sent,
988                                 total_multicast_bytes_transmitted);
989                 UPDATE_QSTAT(xclient->ucast_bytes_sent,
990                                 total_unicast_bytes_transmitted);
991
992                 /*
993                  * sum to total_bytes_transmitted all
994                  * unicast/multicast/broadcast
995                  */
996                 qstats->total_bytes_transmitted_hi =
997                         qstats->total_unicast_bytes_transmitted_hi;
998                 qstats->total_bytes_transmitted_lo =
999                         qstats->total_unicast_bytes_transmitted_lo;
1000
1001                 ADD_64(qstats->total_bytes_transmitted_hi,
1002                                 qstats->total_broadcast_bytes_transmitted_hi,
1003                                 qstats->total_bytes_transmitted_lo,
1004                                 qstats->total_broadcast_bytes_transmitted_lo);
1005
1006                 ADD_64(qstats->total_bytes_transmitted_hi,
1007                                 qstats->total_multicast_bytes_transmitted_hi,
1008                                 qstats->total_bytes_transmitted_lo,
1009                                 qstats->total_multicast_bytes_transmitted_lo);
1010
1011                 UPDATE_EXTEND_XSTAT(ucast_pkts_sent,
1012                                 total_unicast_packets_transmitted);
1013                 UPDATE_EXTEND_XSTAT(mcast_pkts_sent,
1014                                 total_multicast_packets_transmitted);
1015                 UPDATE_EXTEND_XSTAT(bcast_pkts_sent,
1016                                 total_broadcast_packets_transmitted);
1017
1018                 UPDATE_EXTEND_TSTAT(checksum_discard,
1019                                 total_packets_received_checksum_discarded);
1020                 UPDATE_EXTEND_TSTAT(ttl0_discard,
1021                                 total_packets_received_ttl0_discarded);
1022
1023                 UPDATE_EXTEND_XSTAT(error_drop_pkts,
1024                                 total_transmitted_dropped_packets_error);
1025
1026                 UPDATE_FSTAT_QSTAT(total_bytes_received);
1027                 UPDATE_FSTAT_QSTAT(total_bytes_transmitted);
1028                 UPDATE_FSTAT_QSTAT(total_unicast_packets_received);
1029                 UPDATE_FSTAT_QSTAT(total_multicast_packets_received);
1030                 UPDATE_FSTAT_QSTAT(total_broadcast_packets_received);
1031                 UPDATE_FSTAT_QSTAT(total_unicast_packets_transmitted);
1032                 UPDATE_FSTAT_QSTAT(total_multicast_packets_transmitted);
1033                 UPDATE_FSTAT_QSTAT(total_broadcast_packets_transmitted);
1034                 UPDATE_FSTAT_QSTAT(valid_bytes_received);
1035         }
1036
1037         ADD_64(estats->total_bytes_received_hi,
1038                         estats->rx_stat_ifhcinbadoctets_hi,
1039                         estats->total_bytes_received_lo,
1040                         estats->rx_stat_ifhcinbadoctets_lo);
1041
1042         ADD_64_LE(estats->total_bytes_received_hi,
1043                         tfunc->rcv_error_bytes.hi,
1044                         estats->total_bytes_received_lo,
1045                         tfunc->rcv_error_bytes.lo);
1046
1047         ADD_64_LE(estats->error_bytes_received_hi,
1048                         tfunc->rcv_error_bytes.hi,
1049                         estats->error_bytes_received_lo,
1050                         tfunc->rcv_error_bytes.lo);
1051
1052         UPDATE_ESTAT(etherstatsoverrsizepkts, rx_stat_dot3statsframestoolong);
1053
1054         ADD_64(estats->error_bytes_received_hi,
1055                         estats->rx_stat_ifhcinbadoctets_hi,
1056                         estats->error_bytes_received_lo,
1057                         estats->rx_stat_ifhcinbadoctets_lo);
1058
1059         if (sc->port.pmf) {
1060                 struct bnx2x_fw_port_stats_old *fwstats = &sc->fw_stats_old;
1061                 UPDATE_FW_STAT(mac_filter_discard);
1062                 UPDATE_FW_STAT(mf_tag_discard);
1063                 UPDATE_FW_STAT(brb_truncate_discard);
1064                 UPDATE_FW_STAT(mac_discard);
1065         }
1066
1067         fstats->host_func_stats_start = ++fstats->host_func_stats_end;
1068
1069         sc->stats_pending = 0;
1070
1071         return 0;
1072 }
1073
1074 static void
1075 bnx2x_drv_stats_update(struct bnx2x_softc *sc)
1076 {
1077     struct bnx2x_eth_stats *estats = &sc->eth_stats;
1078     int i;
1079
1080     for (i = 0; i < sc->num_queues; i++) {
1081         struct bnx2x_eth_q_stats *qstats = &sc->fp[i].eth_q_stats;
1082         struct bnx2x_eth_q_stats_old *qstats_old = &sc->fp[i].eth_q_stats_old;
1083
1084         UPDATE_ESTAT_QSTAT(rx_calls);
1085         UPDATE_ESTAT_QSTAT(rx_pkts);
1086         UPDATE_ESTAT_QSTAT(rx_soft_errors);
1087         UPDATE_ESTAT_QSTAT(rx_hw_csum_errors);
1088         UPDATE_ESTAT_QSTAT(rx_ofld_frames_csum_ip);
1089         UPDATE_ESTAT_QSTAT(rx_ofld_frames_csum_tcp_udp);
1090         UPDATE_ESTAT_QSTAT(rx_budget_reached);
1091         UPDATE_ESTAT_QSTAT(tx_pkts);
1092         UPDATE_ESTAT_QSTAT(tx_soft_errors);
1093         UPDATE_ESTAT_QSTAT(tx_ofld_frames_csum_ip);
1094         UPDATE_ESTAT_QSTAT(tx_ofld_frames_csum_tcp);
1095         UPDATE_ESTAT_QSTAT(tx_ofld_frames_csum_udp);
1096         UPDATE_ESTAT_QSTAT(tx_encap_failures);
1097         UPDATE_ESTAT_QSTAT(tx_hw_queue_full);
1098         UPDATE_ESTAT_QSTAT(tx_hw_max_queue_depth);
1099         UPDATE_ESTAT_QSTAT(tx_dma_mapping_failure);
1100         UPDATE_ESTAT_QSTAT(tx_max_drbr_queue_depth);
1101         UPDATE_ESTAT_QSTAT(tx_window_violation_std);
1102         UPDATE_ESTAT_QSTAT(tx_chain_lost_mbuf);
1103         UPDATE_ESTAT_QSTAT(tx_frames_deferred);
1104         UPDATE_ESTAT_QSTAT(tx_queue_xoff);
1105
1106         /* mbuf driver statistics */
1107         UPDATE_ESTAT_QSTAT(mbuf_defrag_attempts);
1108         UPDATE_ESTAT_QSTAT(mbuf_defrag_failures);
1109         UPDATE_ESTAT_QSTAT(mbuf_rx_bd_alloc_failed);
1110         UPDATE_ESTAT_QSTAT(mbuf_rx_bd_mapping_failed);
1111
1112         /* track the number of allocated mbufs */
1113         UPDATE_ESTAT_QSTAT(mbuf_alloc_tx);
1114         UPDATE_ESTAT_QSTAT(mbuf_alloc_rx);
1115     }
1116 }
1117
1118 static uint8_t
1119 bnx2x_edebug_stats_stopped(struct bnx2x_softc *sc)
1120 {
1121     uint32_t val;
1122
1123     if (SHMEM2_HAS(sc, edebug_driver_if[1])) {
1124         val = SHMEM2_RD(sc, edebug_driver_if[1]);
1125
1126         if (val == EDEBUG_DRIVER_IF_OP_CODE_DISABLE_STAT) {
1127             return TRUE;
1128         }
1129     }
1130
1131     return FALSE;
1132 }
1133
1134 static void
1135 bnx2x_stats_update(struct bnx2x_softc *sc)
1136 {
1137         uint32_t *stats_comp = BNX2X_SP(sc, stats_comp);
1138
1139         if (bnx2x_edebug_stats_stopped(sc)) {
1140                 return;
1141         }
1142
1143         if (IS_PF(sc)) {
1144
1145                 bnx2x_storm_stats_update(sc);
1146                 bnx2x_hw_stats_post(sc);
1147                 bnx2x_storm_stats_post(sc);
1148                 DELAY_MS(5);
1149
1150                 if (*stats_comp != DMAE_COMP_VAL) {
1151                         return;
1152                 }
1153
1154                 if (sc->port.pmf) {
1155                         bnx2x_hw_stats_update(sc);
1156                 }
1157
1158                 if (bnx2x_storm_stats_update(sc)) {
1159                         if (sc->stats_pending++ == 3) {
1160                                 rte_panic("storm stats not updated for 3 times");
1161                         }
1162                         return;
1163                 }
1164         } else {
1165                 /*
1166                  * VF doesn't collect HW statistics, and doesn't get completions,
1167                  * performs only update.
1168                  */
1169                 bnx2x_storm_stats_update(sc);
1170         }
1171
1172         bnx2x_drv_stats_update(sc);
1173 }
1174
1175 static void
1176 bnx2x_port_stats_stop(struct bnx2x_softc *sc)
1177 {
1178     struct dmae_command *dmae;
1179     uint32_t opcode;
1180     int loader_idx = PMF_DMAE_C(sc);
1181     uint32_t *stats_comp = BNX2X_SP(sc, stats_comp);
1182
1183     sc->executer_idx = 0;
1184
1185     opcode = bnx2x_dmae_opcode(sc, DMAE_SRC_PCI, DMAE_DST_GRC, FALSE, 0);
1186
1187     if (sc->port.port_stx) {
1188         dmae = BNX2X_SP(sc, dmae[sc->executer_idx++]);
1189
1190         if (sc->func_stx) {
1191             dmae->opcode = bnx2x_dmae_opcode_add_comp(opcode, DMAE_COMP_GRC);
1192         } else {
1193             dmae->opcode = bnx2x_dmae_opcode_add_comp(opcode, DMAE_COMP_PCI);
1194         }
1195
1196         dmae->src_addr_lo = U64_LO(BNX2X_SP_MAPPING(sc, port_stats));
1197         dmae->src_addr_hi = U64_HI(BNX2X_SP_MAPPING(sc, port_stats));
1198         dmae->dst_addr_lo = sc->port.port_stx >> 2;
1199         dmae->dst_addr_hi = 0;
1200         dmae->len = bnx2x_get_port_stats_dma_len(sc);
1201         if (sc->func_stx) {
1202             dmae->comp_addr_lo = (dmae_reg_go_c[loader_idx] >> 2);
1203             dmae->comp_addr_hi = 0;
1204             dmae->comp_val = 1;
1205         } else {
1206             dmae->comp_addr_lo = U64_LO(BNX2X_SP_MAPPING(sc, stats_comp));
1207             dmae->comp_addr_hi = U64_HI(BNX2X_SP_MAPPING(sc, stats_comp));
1208             dmae->comp_val = DMAE_COMP_VAL;
1209
1210             *stats_comp = 0;
1211         }
1212     }
1213
1214     if (sc->func_stx) {
1215         dmae = BNX2X_SP(sc, dmae[sc->executer_idx++]);
1216         dmae->opcode = bnx2x_dmae_opcode_add_comp(opcode, DMAE_COMP_PCI);
1217         dmae->src_addr_lo = U64_LO(BNX2X_SP_MAPPING(sc, func_stats));
1218         dmae->src_addr_hi = U64_HI(BNX2X_SP_MAPPING(sc, func_stats));
1219         dmae->dst_addr_lo = (sc->func_stx >> 2);
1220         dmae->dst_addr_hi = 0;
1221         dmae->len = (sizeof(struct host_func_stats) >> 2);
1222         dmae->comp_addr_lo = U64_LO(BNX2X_SP_MAPPING(sc, stats_comp));
1223         dmae->comp_addr_hi = U64_HI(BNX2X_SP_MAPPING(sc, stats_comp));
1224         dmae->comp_val = DMAE_COMP_VAL;
1225
1226         *stats_comp = 0;
1227     }
1228 }
1229
1230 static void
1231 bnx2x_stats_stop(struct bnx2x_softc *sc)
1232 {
1233     uint8_t update = FALSE;
1234
1235     bnx2x_stats_comp(sc);
1236
1237     if (sc->port.pmf) {
1238         update = bnx2x_hw_stats_update(sc) == 0;
1239     }
1240
1241     update |= bnx2x_storm_stats_update(sc) == 0;
1242
1243     if (update) {
1244
1245         if (sc->port.pmf) {
1246             bnx2x_port_stats_stop(sc);
1247         }
1248
1249         bnx2x_hw_stats_post(sc);
1250         bnx2x_stats_comp(sc);
1251     }
1252 }
1253
1254 static void
1255 bnx2x_stats_do_nothing(__rte_unused struct bnx2x_softc *sc)
1256 {
1257     return;
1258 }
1259
1260 static const struct {
1261     void (*action)(struct bnx2x_softc *sc);
1262     enum bnx2x_stats_state next_state;
1263 } bnx2x_stats_stm[STATS_STATE_MAX][STATS_EVENT_MAX] = {
1264     {
1265     /* DISABLED PMF */ { bnx2x_stats_pmf_update, STATS_STATE_DISABLED },
1266     /*      LINK_UP */ { bnx2x_stats_start,      STATS_STATE_ENABLED },
1267     /*      UPDATE  */ { bnx2x_stats_do_nothing, STATS_STATE_DISABLED },
1268     /*      STOP    */ { bnx2x_stats_do_nothing, STATS_STATE_DISABLED }
1269     },
1270     {
1271     /* ENABLED  PMF */ { bnx2x_stats_pmf_start,  STATS_STATE_ENABLED },
1272     /*      LINK_UP */ { bnx2x_stats_restart,    STATS_STATE_ENABLED },
1273     /*      UPDATE  */ { bnx2x_stats_update,     STATS_STATE_ENABLED },
1274     /*      STOP    */ { bnx2x_stats_stop,       STATS_STATE_DISABLED }
1275     }
1276 };
1277
1278 void bnx2x_stats_handle(struct bnx2x_softc *sc, enum bnx2x_stats_event event)
1279 {
1280         enum bnx2x_stats_state state;
1281
1282         if (unlikely(sc->panic)) {
1283                 return;
1284         }
1285
1286         state = sc->stats_state;
1287         sc->stats_state = bnx2x_stats_stm[state][event].next_state;
1288
1289         bnx2x_stats_stm[state][event].action(sc);
1290
1291         if (event != STATS_EVENT_UPDATE) {
1292                 PMD_DRV_LOG(DEBUG, sc,
1293                                 "state %d -> event %d -> state %d",
1294                                 state, event, sc->stats_state);
1295         }
1296 }
1297
1298 static void
1299 bnx2x_port_stats_base_init(struct bnx2x_softc *sc)
1300 {
1301     struct dmae_command *dmae;
1302     uint32_t *stats_comp = BNX2X_SP(sc, stats_comp);
1303
1304     /* sanity */
1305     if (!sc->port.pmf || !sc->port.port_stx) {
1306         PMD_DRV_LOG(ERR, sc, "BUG!");
1307         return;
1308     }
1309
1310     sc->executer_idx = 0;
1311
1312     dmae = BNX2X_SP(sc, dmae[sc->executer_idx++]);
1313     dmae->opcode = bnx2x_dmae_opcode(sc, DMAE_SRC_PCI, DMAE_DST_GRC,
1314                                    TRUE, DMAE_COMP_PCI);
1315     dmae->src_addr_lo = U64_LO(BNX2X_SP_MAPPING(sc, port_stats));
1316     dmae->src_addr_hi = U64_HI(BNX2X_SP_MAPPING(sc, port_stats));
1317     dmae->dst_addr_lo = (sc->port.port_stx >> 2);
1318     dmae->dst_addr_hi = 0;
1319     dmae->len = bnx2x_get_port_stats_dma_len(sc);
1320     dmae->comp_addr_lo = U64_LO(BNX2X_SP_MAPPING(sc, stats_comp));
1321     dmae->comp_addr_hi = U64_HI(BNX2X_SP_MAPPING(sc, stats_comp));
1322     dmae->comp_val = DMAE_COMP_VAL;
1323
1324     *stats_comp = 0;
1325     bnx2x_hw_stats_post(sc);
1326     bnx2x_stats_comp(sc);
1327 }
1328
1329 /*
1330  * This function will prepare the statistics ramrod data the way
1331  * we will only have to increment the statistics counter and
1332  * send the ramrod each time we have to.
1333  */
1334 static void
1335 bnx2x_prep_fw_stats_req(struct bnx2x_softc *sc)
1336 {
1337     int i;
1338     int first_queue_query_index;
1339     struct stats_query_header *stats_hdr = &sc->fw_stats_req->hdr;
1340     rte_iova_t cur_data_offset;
1341     struct stats_query_entry *cur_query_entry;
1342
1343     stats_hdr->cmd_num = sc->fw_stats_num;
1344     stats_hdr->drv_stats_counter = 0;
1345
1346     /*
1347      * The storm_counters struct contains the counters of completed
1348      * statistics requests per storm which are incremented by FW
1349      * each time it completes hadning a statistics ramrod. We will
1350      * check these counters in the timer handler and discard a
1351      * (statistics) ramrod completion.
1352      */
1353     cur_data_offset = (sc->fw_stats_data_mapping +
1354                        offsetof(struct bnx2x_fw_stats_data, storm_counters));
1355
1356     stats_hdr->stats_counters_addrs.hi = htole32(U64_HI(cur_data_offset));
1357     stats_hdr->stats_counters_addrs.lo = htole32(U64_LO(cur_data_offset));
1358
1359     /*
1360      * Prepare the first stats ramrod (will be completed with
1361      * the counters equal to zero) - init counters to somethig different.
1362      */
1363     memset(&sc->fw_stats_data->storm_counters, 0xff,
1364            sizeof(struct stats_counter));
1365
1366     /**** Port FW statistics data ****/
1367     cur_data_offset = (sc->fw_stats_data_mapping +
1368                        offsetof(struct bnx2x_fw_stats_data, port));
1369
1370     cur_query_entry = &sc->fw_stats_req->query[BNX2X_PORT_QUERY_IDX];
1371
1372     cur_query_entry->kind = STATS_TYPE_PORT;
1373     /* For port query index is a DON'T CARE */
1374     cur_query_entry->index = SC_PORT(sc);
1375     /* For port query funcID is a DON'T CARE */
1376     cur_query_entry->funcID = htole16(SC_FUNC(sc));
1377     cur_query_entry->address.hi = htole32(U64_HI(cur_data_offset));
1378     cur_query_entry->address.lo = htole32(U64_LO(cur_data_offset));
1379
1380     /**** PF FW statistics data ****/
1381     cur_data_offset = (sc->fw_stats_data_mapping +
1382                        offsetof(struct bnx2x_fw_stats_data, pf));
1383
1384     cur_query_entry = &sc->fw_stats_req->query[BNX2X_PF_QUERY_IDX];
1385
1386     cur_query_entry->kind = STATS_TYPE_PF;
1387     /* For PF query index is a DON'T CARE */
1388     cur_query_entry->index = SC_PORT(sc);
1389     cur_query_entry->funcID = htole16(SC_FUNC(sc));
1390     cur_query_entry->address.hi = htole32(U64_HI(cur_data_offset));
1391     cur_query_entry->address.lo = htole32(U64_LO(cur_data_offset));
1392
1393     /**** Clients' queries ****/
1394     cur_data_offset = (sc->fw_stats_data_mapping +
1395                        offsetof(struct bnx2x_fw_stats_data, queue_stats));
1396
1397     /*
1398      * First queue query index depends whether FCoE offloaded request will
1399      * be included in the ramrod
1400      */
1401         first_queue_query_index = (BNX2X_FIRST_QUEUE_QUERY_IDX - 1);
1402
1403     for (i = 0; i < sc->num_queues; i++) {
1404         cur_query_entry =
1405             &sc->fw_stats_req->query[first_queue_query_index + i];
1406
1407         cur_query_entry->kind = STATS_TYPE_QUEUE;
1408         cur_query_entry->index = bnx2x_stats_id(&sc->fp[i]);
1409         cur_query_entry->funcID = htole16(SC_FUNC(sc));
1410         cur_query_entry->address.hi = htole32(U64_HI(cur_data_offset));
1411         cur_query_entry->address.lo = htole32(U64_LO(cur_data_offset));
1412
1413         cur_data_offset += sizeof(struct per_queue_stats);
1414     }
1415 }
1416
1417 void bnx2x_memset_stats(struct bnx2x_softc *sc)
1418 {
1419         int i;
1420
1421         /* function stats */
1422         for (i = 0; i < sc->num_queues; i++) {
1423                 struct bnx2x_fastpath *fp = &sc->fp[i];
1424
1425                 memset(&fp->old_tclient, 0,
1426                                 sizeof(fp->old_tclient));
1427                 memset(&fp->old_uclient, 0,
1428                                 sizeof(fp->old_uclient));
1429                 memset(&fp->old_xclient, 0,
1430                                 sizeof(fp->old_xclient));
1431                 if (sc->stats_init) {
1432                         memset(&fp->eth_q_stats, 0,
1433                                         sizeof(fp->eth_q_stats));
1434                         memset(&fp->eth_q_stats_old, 0,
1435                                         sizeof(fp->eth_q_stats_old));
1436                 }
1437         }
1438
1439         if (sc->stats_init) {
1440                 memset(&sc->net_stats_old, 0, sizeof(sc->net_stats_old));
1441                 memset(&sc->fw_stats_old, 0, sizeof(sc->fw_stats_old));
1442                 memset(&sc->eth_stats_old, 0, sizeof(sc->eth_stats_old));
1443                 memset(&sc->eth_stats, 0, sizeof(sc->eth_stats));
1444                 memset(&sc->func_stats, 0, sizeof(sc->func_stats));
1445         }
1446
1447         sc->stats_state = STATS_STATE_DISABLED;
1448
1449         if (sc->port.pmf && sc->port.port_stx)
1450                 bnx2x_port_stats_base_init(sc);
1451
1452         /* mark the end of statistics initialization */
1453         sc->stats_init = false;
1454 }
1455
1456 void
1457 bnx2x_stats_init(struct bnx2x_softc *sc)
1458 {
1459         int /*abs*/port = SC_PORT(sc);
1460         int mb_idx = SC_FW_MB_IDX(sc);
1461         int i;
1462
1463         sc->stats_pending = 0;
1464         sc->executer_idx = 0;
1465         sc->stats_counter = 0;
1466
1467         sc->stats_init = TRUE;
1468
1469         /* port and func stats for management */
1470         if (!BNX2X_NOMCP(sc)) {
1471                 sc->port.port_stx = SHMEM_RD(sc, port_mb[port].port_stx);
1472                 sc->func_stx = SHMEM_RD(sc, func_mb[mb_idx].fw_mb_param);
1473         } else {
1474                 sc->port.port_stx = 0;
1475                 sc->func_stx = 0;
1476         }
1477
1478         PMD_DRV_LOG(DEBUG, sc, "port_stx 0x%x func_stx 0x%x",
1479                         sc->port.port_stx, sc->func_stx);
1480
1481         /* pmf should retrieve port statistics from SP on a non-init*/
1482         if (!sc->stats_init && sc->port.pmf && sc->port.port_stx) {
1483                 bnx2x_stats_handle(sc, STATS_EVENT_PMF);
1484         }
1485
1486         port = SC_PORT(sc);
1487         /* port stats */
1488         memset(&(sc->port.old_nig_stats), 0, sizeof(struct nig_stats));
1489         sc->port.old_nig_stats.brb_discard =
1490                 REG_RD(sc, NIG_REG_STAT0_BRB_DISCARD + port*0x38);
1491         sc->port.old_nig_stats.brb_truncate =
1492                 REG_RD(sc, NIG_REG_STAT0_BRB_TRUNCATE + port*0x38);
1493         if (!CHIP_IS_E3(sc)) {
1494                 REG_RD_DMAE(sc, NIG_REG_STAT0_EGRESS_MAC_PKT0 + port*0x50,
1495                                 &(sc->port.old_nig_stats.egress_mac_pkt0_lo), 2);
1496                 REG_RD_DMAE(sc, NIG_REG_STAT0_EGRESS_MAC_PKT1 + port*0x50,
1497                                 &(sc->port.old_nig_stats.egress_mac_pkt1_lo), 2);
1498         }
1499
1500         /* function stats */
1501         for (i = 0; i < sc->num_queues; i++) {
1502                 memset(&sc->fp[i].old_tclient, 0, sizeof(sc->fp[i].old_tclient));
1503                 memset(&sc->fp[i].old_uclient, 0, sizeof(sc->fp[i].old_uclient));
1504                 memset(&sc->fp[i].old_xclient, 0, sizeof(sc->fp[i].old_xclient));
1505                 if (sc->stats_init) {
1506                         memset(&sc->fp[i].eth_q_stats, 0,
1507                                         sizeof(sc->fp[i].eth_q_stats));
1508                         memset(&sc->fp[i].eth_q_stats_old, 0,
1509                                         sizeof(sc->fp[i].eth_q_stats_old));
1510                 }
1511         }
1512
1513         /* prepare statistics ramrod data */
1514         bnx2x_prep_fw_stats_req(sc);
1515
1516         if (sc->stats_init) {
1517                 memset(&sc->net_stats_old, 0, sizeof(sc->net_stats_old));
1518                 memset(&sc->fw_stats_old, 0, sizeof(sc->fw_stats_old));
1519                 memset(&sc->eth_stats_old, 0, sizeof(sc->eth_stats_old));
1520                 memset(&sc->eth_stats, 0, sizeof(sc->eth_stats));
1521                 memset(&sc->func_stats, 0, sizeof(sc->func_stats));
1522
1523                 /* Clean SP from previous statistics */
1524                 if (sc->func_stx) {
1525                         memset(BNX2X_SP(sc, func_stats), 0, sizeof(struct host_func_stats));
1526                         bnx2x_func_stats_init(sc);
1527                         bnx2x_hw_stats_post(sc);
1528                         bnx2x_stats_comp(sc);
1529                 }
1530         }
1531
1532         sc->stats_state = STATS_STATE_DISABLED;
1533
1534         if (sc->port.pmf && sc->port.port_stx) {
1535                 bnx2x_port_stats_base_init(sc);
1536         }
1537
1538         /* mark the end of statistics initialization */
1539         sc->stats_init = FALSE;
1540 }
1541
1542 void
1543 bnx2x_save_statistics(struct bnx2x_softc *sc)
1544 {
1545         int i;
1546
1547         /* save queue statistics */
1548         for (i = 0; i < sc->num_queues; i++) {
1549                 struct bnx2x_fastpath *fp = &sc->fp[i];
1550                 struct bnx2x_eth_q_stats *qstats = &fp->eth_q_stats;
1551                 struct bnx2x_eth_q_stats_old *qstats_old = &fp->eth_q_stats_old;
1552
1553                 UPDATE_QSTAT_OLD(total_unicast_bytes_received_hi);
1554                 UPDATE_QSTAT_OLD(total_unicast_bytes_received_lo);
1555                 UPDATE_QSTAT_OLD(total_broadcast_bytes_received_hi);
1556                 UPDATE_QSTAT_OLD(total_broadcast_bytes_received_lo);
1557                 UPDATE_QSTAT_OLD(total_multicast_bytes_received_hi);
1558                 UPDATE_QSTAT_OLD(total_multicast_bytes_received_lo);
1559                 UPDATE_QSTAT_OLD(total_unicast_bytes_transmitted_hi);
1560                 UPDATE_QSTAT_OLD(total_unicast_bytes_transmitted_lo);
1561                 UPDATE_QSTAT_OLD(total_broadcast_bytes_transmitted_hi);
1562                 UPDATE_QSTAT_OLD(total_broadcast_bytes_transmitted_lo);
1563                 UPDATE_QSTAT_OLD(total_multicast_bytes_transmitted_hi);
1564                 UPDATE_QSTAT_OLD(total_multicast_bytes_transmitted_lo);
1565         }
1566
1567         /* store port firmware statistics */
1568         if (sc->port.pmf) {
1569                 struct bnx2x_eth_stats *estats = &sc->eth_stats;
1570                 struct bnx2x_fw_port_stats_old *fwstats = &sc->fw_stats_old;
1571                 struct host_port_stats *pstats = BNX2X_SP(sc, port_stats);
1572
1573                 fwstats->pfc_frames_rx_hi = pstats->pfc_frames_rx_hi;
1574                 fwstats->pfc_frames_rx_lo = pstats->pfc_frames_rx_lo;
1575                 fwstats->pfc_frames_tx_hi = pstats->pfc_frames_tx_hi;
1576                 fwstats->pfc_frames_tx_lo = pstats->pfc_frames_tx_lo;
1577
1578                 if (IS_MF(sc)) {
1579                         UPDATE_FW_STAT_OLD(mac_filter_discard);
1580                         UPDATE_FW_STAT_OLD(mf_tag_discard);
1581                         UPDATE_FW_STAT_OLD(brb_truncate_discard);
1582                         UPDATE_FW_STAT_OLD(mac_discard);
1583                 }
1584         }
1585 }