New upstream version 18.08
[deb_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,
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, "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, "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, "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, "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,
801               "stats updated by DMAE but no MAC active");
802         return -1;
803
804     default: /* unreached */
805         PMD_DRV_LOG(ERR, "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, "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,
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,
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,
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,
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,
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, "---------------"); */
938
939                 UPDATE_QSTAT(tclient->rcv_bcast_bytes,
940                                 total_broadcast_bytes_received);
941                 UPDATE_QSTAT(tclient->rcv_mcast_bytes,
942                                 total_multicast_bytes_received);
943                 UPDATE_QSTAT(tclient->rcv_ucast_bytes,
944                                 total_unicast_bytes_received);
945
946                 /*
947                  * sum to total_bytes_received all
948                  * unicast/multicast/broadcast
949                  */
950                 qstats->total_bytes_received_hi =
951                         qstats->total_broadcast_bytes_received_hi;
952                 qstats->total_bytes_received_lo =
953                         qstats->total_broadcast_bytes_received_lo;
954
955                 ADD_64(qstats->total_bytes_received_hi,
956                                 qstats->total_multicast_bytes_received_hi,
957                                 qstats->total_bytes_received_lo,
958                                 qstats->total_multicast_bytes_received_lo);
959
960                 ADD_64(qstats->total_bytes_received_hi,
961                                 qstats->total_unicast_bytes_received_hi,
962                                 qstats->total_bytes_received_lo,
963                                 qstats->total_unicast_bytes_received_lo);
964
965                 qstats->valid_bytes_received_hi = qstats->total_bytes_received_hi;
966                 qstats->valid_bytes_received_lo = qstats->total_bytes_received_lo;
967
968                 UPDATE_EXTEND_TSTAT(rcv_ucast_pkts, total_unicast_packets_received);
969                 UPDATE_EXTEND_TSTAT(rcv_mcast_pkts, total_multicast_packets_received);
970                 UPDATE_EXTEND_TSTAT(rcv_bcast_pkts, total_broadcast_packets_received);
971                 UPDATE_EXTEND_E_TSTAT(pkts_too_big_discard,
972                                 etherstatsoverrsizepkts, 32);
973                 UPDATE_EXTEND_E_TSTAT(no_buff_discard, no_buff_discard, 16);
974
975                 SUB_EXTEND_USTAT(ucast_no_buff_pkts, total_unicast_packets_received);
976                 SUB_EXTEND_USTAT(mcast_no_buff_pkts,
977                                 total_multicast_packets_received);
978                 SUB_EXTEND_USTAT(bcast_no_buff_pkts,
979                                 total_broadcast_packets_received);
980                 UPDATE_EXTEND_E_USTAT(ucast_no_buff_pkts, no_buff_discard);
981                 UPDATE_EXTEND_E_USTAT(mcast_no_buff_pkts, no_buff_discard);
982                 UPDATE_EXTEND_E_USTAT(bcast_no_buff_pkts, no_buff_discard);
983
984                 UPDATE_QSTAT(xclient->bcast_bytes_sent,
985                                 total_broadcast_bytes_transmitted);
986                 UPDATE_QSTAT(xclient->mcast_bytes_sent,
987                                 total_multicast_bytes_transmitted);
988                 UPDATE_QSTAT(xclient->ucast_bytes_sent,
989                                 total_unicast_bytes_transmitted);
990
991                 /*
992                  * sum to total_bytes_transmitted all
993                  * unicast/multicast/broadcast
994                  */
995                 qstats->total_bytes_transmitted_hi =
996                         qstats->total_unicast_bytes_transmitted_hi;
997                 qstats->total_bytes_transmitted_lo =
998                         qstats->total_unicast_bytes_transmitted_lo;
999
1000                 ADD_64(qstats->total_bytes_transmitted_hi,
1001                                 qstats->total_broadcast_bytes_transmitted_hi,
1002                                 qstats->total_bytes_transmitted_lo,
1003                                 qstats->total_broadcast_bytes_transmitted_lo);
1004
1005                 ADD_64(qstats->total_bytes_transmitted_hi,
1006                                 qstats->total_multicast_bytes_transmitted_hi,
1007                                 qstats->total_bytes_transmitted_lo,
1008                                 qstats->total_multicast_bytes_transmitted_lo);
1009
1010                 UPDATE_EXTEND_XSTAT(ucast_pkts_sent,
1011                                 total_unicast_packets_transmitted);
1012                 UPDATE_EXTEND_XSTAT(mcast_pkts_sent,
1013                                 total_multicast_packets_transmitted);
1014                 UPDATE_EXTEND_XSTAT(bcast_pkts_sent,
1015                                 total_broadcast_packets_transmitted);
1016
1017                 UPDATE_EXTEND_TSTAT(checksum_discard,
1018                                 total_packets_received_checksum_discarded);
1019                 UPDATE_EXTEND_TSTAT(ttl0_discard,
1020                                 total_packets_received_ttl0_discarded);
1021
1022                 UPDATE_EXTEND_XSTAT(error_drop_pkts,
1023                                 total_transmitted_dropped_packets_error);
1024
1025                 UPDATE_FSTAT_QSTAT(total_bytes_received);
1026                 UPDATE_FSTAT_QSTAT(total_bytes_transmitted);
1027                 UPDATE_FSTAT_QSTAT(total_unicast_packets_received);
1028                 UPDATE_FSTAT_QSTAT(total_multicast_packets_received);
1029                 UPDATE_FSTAT_QSTAT(total_broadcast_packets_received);
1030                 UPDATE_FSTAT_QSTAT(total_unicast_packets_transmitted);
1031                 UPDATE_FSTAT_QSTAT(total_multicast_packets_transmitted);
1032                 UPDATE_FSTAT_QSTAT(total_broadcast_packets_transmitted);
1033                 UPDATE_FSTAT_QSTAT(valid_bytes_received);
1034         }
1035
1036         ADD_64(estats->total_bytes_received_hi,
1037                         estats->rx_stat_ifhcinbadoctets_hi,
1038                         estats->total_bytes_received_lo,
1039                         estats->rx_stat_ifhcinbadoctets_lo);
1040
1041         ADD_64_LE(estats->total_bytes_received_hi,
1042                         tfunc->rcv_error_bytes.hi,
1043                         estats->total_bytes_received_lo,
1044                         tfunc->rcv_error_bytes.lo);
1045
1046         ADD_64_LE(estats->error_bytes_received_hi,
1047                         tfunc->rcv_error_bytes.hi,
1048                         estats->error_bytes_received_lo,
1049                         tfunc->rcv_error_bytes.lo);
1050
1051         UPDATE_ESTAT(etherstatsoverrsizepkts, rx_stat_dot3statsframestoolong);
1052
1053         ADD_64(estats->error_bytes_received_hi,
1054                         estats->rx_stat_ifhcinbadoctets_hi,
1055                         estats->error_bytes_received_lo,
1056                         estats->rx_stat_ifhcinbadoctets_lo);
1057
1058         if (sc->port.pmf) {
1059                 struct bnx2x_fw_port_stats_old *fwstats = &sc->fw_stats_old;
1060                 UPDATE_FW_STAT(mac_filter_discard);
1061                 UPDATE_FW_STAT(mf_tag_discard);
1062                 UPDATE_FW_STAT(brb_truncate_discard);
1063                 UPDATE_FW_STAT(mac_discard);
1064         }
1065
1066         fstats->host_func_stats_start = ++fstats->host_func_stats_end;
1067
1068         sc->stats_pending = 0;
1069
1070         return 0;
1071 }
1072
1073 static void
1074 bnx2x_drv_stats_update(struct bnx2x_softc *sc)
1075 {
1076     struct bnx2x_eth_stats *estats = &sc->eth_stats;
1077     int i;
1078
1079     for (i = 0; i < sc->num_queues; i++) {
1080         struct bnx2x_eth_q_stats *qstats = &sc->fp[i].eth_q_stats;
1081         struct bnx2x_eth_q_stats_old *qstats_old = &sc->fp[i].eth_q_stats_old;
1082
1083         UPDATE_ESTAT_QSTAT(rx_calls);
1084         UPDATE_ESTAT_QSTAT(rx_pkts);
1085         UPDATE_ESTAT_QSTAT(rx_soft_errors);
1086         UPDATE_ESTAT_QSTAT(rx_hw_csum_errors);
1087         UPDATE_ESTAT_QSTAT(rx_ofld_frames_csum_ip);
1088         UPDATE_ESTAT_QSTAT(rx_ofld_frames_csum_tcp_udp);
1089         UPDATE_ESTAT_QSTAT(rx_budget_reached);
1090         UPDATE_ESTAT_QSTAT(tx_pkts);
1091         UPDATE_ESTAT_QSTAT(tx_soft_errors);
1092         UPDATE_ESTAT_QSTAT(tx_ofld_frames_csum_ip);
1093         UPDATE_ESTAT_QSTAT(tx_ofld_frames_csum_tcp);
1094         UPDATE_ESTAT_QSTAT(tx_ofld_frames_csum_udp);
1095         UPDATE_ESTAT_QSTAT(tx_encap_failures);
1096         UPDATE_ESTAT_QSTAT(tx_hw_queue_full);
1097         UPDATE_ESTAT_QSTAT(tx_hw_max_queue_depth);
1098         UPDATE_ESTAT_QSTAT(tx_dma_mapping_failure);
1099         UPDATE_ESTAT_QSTAT(tx_max_drbr_queue_depth);
1100         UPDATE_ESTAT_QSTAT(tx_window_violation_std);
1101         UPDATE_ESTAT_QSTAT(tx_chain_lost_mbuf);
1102         UPDATE_ESTAT_QSTAT(tx_frames_deferred);
1103         UPDATE_ESTAT_QSTAT(tx_queue_xoff);
1104
1105         /* mbuf driver statistics */
1106         UPDATE_ESTAT_QSTAT(mbuf_defrag_attempts);
1107         UPDATE_ESTAT_QSTAT(mbuf_defrag_failures);
1108         UPDATE_ESTAT_QSTAT(mbuf_rx_bd_alloc_failed);
1109         UPDATE_ESTAT_QSTAT(mbuf_rx_bd_mapping_failed);
1110
1111         /* track the number of allocated mbufs */
1112         UPDATE_ESTAT_QSTAT(mbuf_alloc_tx);
1113         UPDATE_ESTAT_QSTAT(mbuf_alloc_rx);
1114     }
1115 }
1116
1117 static uint8_t
1118 bnx2x_edebug_stats_stopped(struct bnx2x_softc *sc)
1119 {
1120     uint32_t val;
1121
1122     if (SHMEM2_HAS(sc, edebug_driver_if[1])) {
1123         val = SHMEM2_RD(sc, edebug_driver_if[1]);
1124
1125         if (val == EDEBUG_DRIVER_IF_OP_CODE_DISABLE_STAT) {
1126             return TRUE;
1127         }
1128     }
1129
1130     return FALSE;
1131 }
1132
1133 static void
1134 bnx2x_stats_update(struct bnx2x_softc *sc)
1135 {
1136         uint32_t *stats_comp = BNX2X_SP(sc, stats_comp);
1137
1138         if (bnx2x_edebug_stats_stopped(sc)) {
1139                 return;
1140         }
1141
1142         if (IS_PF(sc)) {
1143
1144                 bnx2x_storm_stats_update(sc);
1145                 bnx2x_hw_stats_post(sc);
1146                 bnx2x_storm_stats_post(sc);
1147                 DELAY_MS(5);
1148
1149                 if (*stats_comp != DMAE_COMP_VAL) {
1150                         return;
1151                 }
1152
1153                 if (sc->port.pmf) {
1154                         bnx2x_hw_stats_update(sc);
1155                 }
1156
1157                 if (bnx2x_storm_stats_update(sc)) {
1158                         if (sc->stats_pending++ == 3) {
1159                                 rte_panic("storm stats not updated for 3 times");
1160                         }
1161                         return;
1162                 }
1163         } else {
1164                 /*
1165                  * VF doesn't collect HW statistics, and doesn't get completions,
1166                  * performs only update.
1167                  */
1168                 bnx2x_storm_stats_update(sc);
1169         }
1170
1171         bnx2x_drv_stats_update(sc);
1172 }
1173
1174 static void
1175 bnx2x_port_stats_stop(struct bnx2x_softc *sc)
1176 {
1177     struct dmae_command *dmae;
1178     uint32_t opcode;
1179     int loader_idx = PMF_DMAE_C(sc);
1180     uint32_t *stats_comp = BNX2X_SP(sc, stats_comp);
1181
1182     sc->executer_idx = 0;
1183
1184     opcode = bnx2x_dmae_opcode(sc, DMAE_SRC_PCI, DMAE_DST_GRC, FALSE, 0);
1185
1186     if (sc->port.port_stx) {
1187         dmae = BNX2X_SP(sc, dmae[sc->executer_idx++]);
1188
1189         if (sc->func_stx) {
1190             dmae->opcode = bnx2x_dmae_opcode_add_comp(opcode, DMAE_COMP_GRC);
1191         } else {
1192             dmae->opcode = bnx2x_dmae_opcode_add_comp(opcode, DMAE_COMP_PCI);
1193         }
1194
1195         dmae->src_addr_lo = U64_LO(BNX2X_SP_MAPPING(sc, port_stats));
1196         dmae->src_addr_hi = U64_HI(BNX2X_SP_MAPPING(sc, port_stats));
1197         dmae->dst_addr_lo = sc->port.port_stx >> 2;
1198         dmae->dst_addr_hi = 0;
1199         dmae->len = bnx2x_get_port_stats_dma_len(sc);
1200         if (sc->func_stx) {
1201             dmae->comp_addr_lo = (dmae_reg_go_c[loader_idx] >> 2);
1202             dmae->comp_addr_hi = 0;
1203             dmae->comp_val = 1;
1204         } else {
1205             dmae->comp_addr_lo = U64_LO(BNX2X_SP_MAPPING(sc, stats_comp));
1206             dmae->comp_addr_hi = U64_HI(BNX2X_SP_MAPPING(sc, stats_comp));
1207             dmae->comp_val = DMAE_COMP_VAL;
1208
1209             *stats_comp = 0;
1210         }
1211     }
1212
1213     if (sc->func_stx) {
1214         dmae = BNX2X_SP(sc, dmae[sc->executer_idx++]);
1215         dmae->opcode = bnx2x_dmae_opcode_add_comp(opcode, DMAE_COMP_PCI);
1216         dmae->src_addr_lo = U64_LO(BNX2X_SP_MAPPING(sc, func_stats));
1217         dmae->src_addr_hi = U64_HI(BNX2X_SP_MAPPING(sc, func_stats));
1218         dmae->dst_addr_lo = (sc->func_stx >> 2);
1219         dmae->dst_addr_hi = 0;
1220         dmae->len = (sizeof(struct host_func_stats) >> 2);
1221         dmae->comp_addr_lo = U64_LO(BNX2X_SP_MAPPING(sc, stats_comp));
1222         dmae->comp_addr_hi = U64_HI(BNX2X_SP_MAPPING(sc, stats_comp));
1223         dmae->comp_val = DMAE_COMP_VAL;
1224
1225         *stats_comp = 0;
1226     }
1227 }
1228
1229 static void
1230 bnx2x_stats_stop(struct bnx2x_softc *sc)
1231 {
1232     uint8_t update = FALSE;
1233
1234     bnx2x_stats_comp(sc);
1235
1236     if (sc->port.pmf) {
1237         update = bnx2x_hw_stats_update(sc) == 0;
1238     }
1239
1240     update |= bnx2x_storm_stats_update(sc) == 0;
1241
1242     if (update) {
1243
1244         if (sc->port.pmf) {
1245             bnx2x_port_stats_stop(sc);
1246         }
1247
1248         bnx2x_hw_stats_post(sc);
1249         bnx2x_stats_comp(sc);
1250     }
1251 }
1252
1253 static void
1254 bnx2x_stats_do_nothing(__rte_unused struct bnx2x_softc *sc)
1255 {
1256     return;
1257 }
1258
1259 static const struct {
1260     void (*action)(struct bnx2x_softc *sc);
1261     enum bnx2x_stats_state next_state;
1262 } bnx2x_stats_stm[STATS_STATE_MAX][STATS_EVENT_MAX] = {
1263     {
1264     /* DISABLED PMF */ { bnx2x_stats_pmf_update, STATS_STATE_DISABLED },
1265     /*      LINK_UP */ { bnx2x_stats_start,      STATS_STATE_ENABLED },
1266     /*      UPDATE  */ { bnx2x_stats_do_nothing, STATS_STATE_DISABLED },
1267     /*      STOP    */ { bnx2x_stats_do_nothing, STATS_STATE_DISABLED }
1268     },
1269     {
1270     /* ENABLED  PMF */ { bnx2x_stats_pmf_start,  STATS_STATE_ENABLED },
1271     /*      LINK_UP */ { bnx2x_stats_restart,    STATS_STATE_ENABLED },
1272     /*      UPDATE  */ { bnx2x_stats_update,     STATS_STATE_ENABLED },
1273     /*      STOP    */ { bnx2x_stats_stop,       STATS_STATE_DISABLED }
1274     }
1275 };
1276
1277 void bnx2x_stats_handle(struct bnx2x_softc *sc, enum bnx2x_stats_event event)
1278 {
1279         enum bnx2x_stats_state state;
1280
1281         if (unlikely(sc->panic)) {
1282                 return;
1283         }
1284
1285         state = sc->stats_state;
1286         sc->stats_state = bnx2x_stats_stm[state][event].next_state;
1287
1288         bnx2x_stats_stm[state][event].action(sc);
1289
1290         if (event != STATS_EVENT_UPDATE) {
1291                 PMD_DRV_LOG(DEBUG,
1292                                 "state %d -> event %d -> state %d",
1293                                 state, event, sc->stats_state);
1294         }
1295 }
1296
1297 static void
1298 bnx2x_port_stats_base_init(struct bnx2x_softc *sc)
1299 {
1300     struct dmae_command *dmae;
1301     uint32_t *stats_comp = BNX2X_SP(sc, stats_comp);
1302
1303     /* sanity */
1304     if (!sc->port.pmf || !sc->port.port_stx) {
1305         PMD_DRV_LOG(ERR, "BUG!");
1306         return;
1307     }
1308
1309     sc->executer_idx = 0;
1310
1311     dmae = BNX2X_SP(sc, dmae[sc->executer_idx++]);
1312     dmae->opcode = bnx2x_dmae_opcode(sc, DMAE_SRC_PCI, DMAE_DST_GRC,
1313                                    TRUE, DMAE_COMP_PCI);
1314     dmae->src_addr_lo = U64_LO(BNX2X_SP_MAPPING(sc, port_stats));
1315     dmae->src_addr_hi = U64_HI(BNX2X_SP_MAPPING(sc, port_stats));
1316     dmae->dst_addr_lo = (sc->port.port_stx >> 2);
1317     dmae->dst_addr_hi = 0;
1318     dmae->len = bnx2x_get_port_stats_dma_len(sc);
1319     dmae->comp_addr_lo = U64_LO(BNX2X_SP_MAPPING(sc, stats_comp));
1320     dmae->comp_addr_hi = U64_HI(BNX2X_SP_MAPPING(sc, stats_comp));
1321     dmae->comp_val = DMAE_COMP_VAL;
1322
1323     *stats_comp = 0;
1324     bnx2x_hw_stats_post(sc);
1325     bnx2x_stats_comp(sc);
1326 }
1327
1328 /*
1329  * This function will prepare the statistics ramrod data the way
1330  * we will only have to increment the statistics counter and
1331  * send the ramrod each time we have to.
1332  */
1333 static void
1334 bnx2x_prep_fw_stats_req(struct bnx2x_softc *sc)
1335 {
1336     int i;
1337     int first_queue_query_index;
1338     struct stats_query_header *stats_hdr = &sc->fw_stats_req->hdr;
1339     rte_iova_t cur_data_offset;
1340     struct stats_query_entry *cur_query_entry;
1341
1342     stats_hdr->cmd_num = sc->fw_stats_num;
1343     stats_hdr->drv_stats_counter = 0;
1344
1345     /*
1346      * The storm_counters struct contains the counters of completed
1347      * statistics requests per storm which are incremented by FW
1348      * each time it completes hadning a statistics ramrod. We will
1349      * check these counters in the timer handler and discard a
1350      * (statistics) ramrod completion.
1351      */
1352     cur_data_offset = (sc->fw_stats_data_mapping +
1353                        offsetof(struct bnx2x_fw_stats_data, storm_counters));
1354
1355     stats_hdr->stats_counters_addrs.hi = htole32(U64_HI(cur_data_offset));
1356     stats_hdr->stats_counters_addrs.lo = htole32(U64_LO(cur_data_offset));
1357
1358     /*
1359      * Prepare the first stats ramrod (will be completed with
1360      * the counters equal to zero) - init counters to somethig different.
1361      */
1362     memset(&sc->fw_stats_data->storm_counters, 0xff,
1363            sizeof(struct stats_counter));
1364
1365     /**** Port FW statistics data ****/
1366     cur_data_offset = (sc->fw_stats_data_mapping +
1367                        offsetof(struct bnx2x_fw_stats_data, port));
1368
1369     cur_query_entry = &sc->fw_stats_req->query[BNX2X_PORT_QUERY_IDX];
1370
1371     cur_query_entry->kind = STATS_TYPE_PORT;
1372     /* For port query index is a DON'T CARE */
1373     cur_query_entry->index = SC_PORT(sc);
1374     /* For port query funcID is a DON'T CARE */
1375     cur_query_entry->funcID = htole16(SC_FUNC(sc));
1376     cur_query_entry->address.hi = htole32(U64_HI(cur_data_offset));
1377     cur_query_entry->address.lo = htole32(U64_LO(cur_data_offset));
1378
1379     /**** PF FW statistics data ****/
1380     cur_data_offset = (sc->fw_stats_data_mapping +
1381                        offsetof(struct bnx2x_fw_stats_data, pf));
1382
1383     cur_query_entry = &sc->fw_stats_req->query[BNX2X_PF_QUERY_IDX];
1384
1385     cur_query_entry->kind = STATS_TYPE_PF;
1386     /* For PF query index is a DON'T CARE */
1387     cur_query_entry->index = SC_PORT(sc);
1388     cur_query_entry->funcID = htole16(SC_FUNC(sc));
1389     cur_query_entry->address.hi = htole32(U64_HI(cur_data_offset));
1390     cur_query_entry->address.lo = htole32(U64_LO(cur_data_offset));
1391
1392     /**** Clients' queries ****/
1393     cur_data_offset = (sc->fw_stats_data_mapping +
1394                        offsetof(struct bnx2x_fw_stats_data, queue_stats));
1395
1396     /*
1397      * First queue query index depends whether FCoE offloaded request will
1398      * be included in the ramrod
1399      */
1400         first_queue_query_index = (BNX2X_FIRST_QUEUE_QUERY_IDX - 1);
1401
1402     for (i = 0; i < sc->num_queues; i++) {
1403         cur_query_entry =
1404             &sc->fw_stats_req->query[first_queue_query_index + i];
1405
1406         cur_query_entry->kind = STATS_TYPE_QUEUE;
1407         cur_query_entry->index = bnx2x_stats_id(&sc->fp[i]);
1408         cur_query_entry->funcID = htole16(SC_FUNC(sc));
1409         cur_query_entry->address.hi = htole32(U64_HI(cur_data_offset));
1410         cur_query_entry->address.lo = htole32(U64_LO(cur_data_offset));
1411
1412         cur_data_offset += sizeof(struct per_queue_stats);
1413     }
1414 }
1415
1416 void bnx2x_memset_stats(struct bnx2x_softc *sc)
1417 {
1418         int i;
1419
1420         /* function stats */
1421         for (i = 0; i < sc->num_queues; i++) {
1422                 struct bnx2x_fastpath *fp = &sc->fp[i];
1423
1424                 memset(&fp->old_tclient, 0,
1425                                 sizeof(fp->old_tclient));
1426                 memset(&fp->old_uclient, 0,
1427                                 sizeof(fp->old_uclient));
1428                 memset(&fp->old_xclient, 0,
1429                                 sizeof(fp->old_xclient));
1430                 if (sc->stats_init) {
1431                         memset(&fp->eth_q_stats, 0,
1432                                         sizeof(fp->eth_q_stats));
1433                         memset(&fp->eth_q_stats_old, 0,
1434                                         sizeof(fp->eth_q_stats_old));
1435                 }
1436         }
1437
1438         if (sc->stats_init) {
1439                 memset(&sc->net_stats_old, 0, sizeof(sc->net_stats_old));
1440                 memset(&sc->fw_stats_old, 0, sizeof(sc->fw_stats_old));
1441                 memset(&sc->eth_stats_old, 0, sizeof(sc->eth_stats_old));
1442                 memset(&sc->eth_stats, 0, sizeof(sc->eth_stats));
1443                 memset(&sc->func_stats, 0, sizeof(sc->func_stats));
1444         }
1445
1446         sc->stats_state = STATS_STATE_DISABLED;
1447
1448         if (sc->port.pmf && sc->port.port_stx)
1449                 bnx2x_port_stats_base_init(sc);
1450
1451         /* mark the end of statistics initialization */
1452         sc->stats_init = false;
1453 }
1454
1455 void
1456 bnx2x_stats_init(struct bnx2x_softc *sc)
1457 {
1458         int /*abs*/port = SC_PORT(sc);
1459         int mb_idx = SC_FW_MB_IDX(sc);
1460         int i;
1461
1462         sc->stats_pending = 0;
1463         sc->executer_idx = 0;
1464         sc->stats_counter = 0;
1465
1466         sc->stats_init = TRUE;
1467
1468         /* port and func stats for management */
1469         if (!BNX2X_NOMCP(sc)) {
1470                 sc->port.port_stx = SHMEM_RD(sc, port_mb[port].port_stx);
1471                 sc->func_stx = SHMEM_RD(sc, func_mb[mb_idx].fw_mb_param);
1472         } else {
1473                 sc->port.port_stx = 0;
1474                 sc->func_stx = 0;
1475         }
1476
1477         PMD_DRV_LOG(DEBUG, "port_stx 0x%x func_stx 0x%x",
1478                         sc->port.port_stx, sc->func_stx);
1479
1480         /* pmf should retrieve port statistics from SP on a non-init*/
1481         if (!sc->stats_init && sc->port.pmf && sc->port.port_stx) {
1482                 bnx2x_stats_handle(sc, STATS_EVENT_PMF);
1483         }
1484
1485         port = SC_PORT(sc);
1486         /* port stats */
1487         memset(&(sc->port.old_nig_stats), 0, sizeof(struct nig_stats));
1488         sc->port.old_nig_stats.brb_discard =
1489                 REG_RD(sc, NIG_REG_STAT0_BRB_DISCARD + port*0x38);
1490         sc->port.old_nig_stats.brb_truncate =
1491                 REG_RD(sc, NIG_REG_STAT0_BRB_TRUNCATE + port*0x38);
1492         if (!CHIP_IS_E3(sc)) {
1493                 REG_RD_DMAE(sc, NIG_REG_STAT0_EGRESS_MAC_PKT0 + port*0x50,
1494                                 &(sc->port.old_nig_stats.egress_mac_pkt0_lo), 2);
1495                 REG_RD_DMAE(sc, NIG_REG_STAT0_EGRESS_MAC_PKT1 + port*0x50,
1496                                 &(sc->port.old_nig_stats.egress_mac_pkt1_lo), 2);
1497         }
1498
1499         /* function stats */
1500         for (i = 0; i < sc->num_queues; i++) {
1501                 memset(&sc->fp[i].old_tclient, 0, sizeof(sc->fp[i].old_tclient));
1502                 memset(&sc->fp[i].old_uclient, 0, sizeof(sc->fp[i].old_uclient));
1503                 memset(&sc->fp[i].old_xclient, 0, sizeof(sc->fp[i].old_xclient));
1504                 if (sc->stats_init) {
1505                         memset(&sc->fp[i].eth_q_stats, 0,
1506                                         sizeof(sc->fp[i].eth_q_stats));
1507                         memset(&sc->fp[i].eth_q_stats_old, 0,
1508                                         sizeof(sc->fp[i].eth_q_stats_old));
1509                 }
1510         }
1511
1512         /* prepare statistics ramrod data */
1513         bnx2x_prep_fw_stats_req(sc);
1514
1515         if (sc->stats_init) {
1516                 memset(&sc->net_stats_old, 0, sizeof(sc->net_stats_old));
1517                 memset(&sc->fw_stats_old, 0, sizeof(sc->fw_stats_old));
1518                 memset(&sc->eth_stats_old, 0, sizeof(sc->eth_stats_old));
1519                 memset(&sc->eth_stats, 0, sizeof(sc->eth_stats));
1520                 memset(&sc->func_stats, 0, sizeof(sc->func_stats));
1521
1522                 /* Clean SP from previous statistics */
1523                 if (sc->func_stx) {
1524                         memset(BNX2X_SP(sc, func_stats), 0, sizeof(struct host_func_stats));
1525                         bnx2x_func_stats_init(sc);
1526                         bnx2x_hw_stats_post(sc);
1527                         bnx2x_stats_comp(sc);
1528                 }
1529         }
1530
1531         sc->stats_state = STATS_STATE_DISABLED;
1532
1533         if (sc->port.pmf && sc->port.port_stx) {
1534                 bnx2x_port_stats_base_init(sc);
1535         }
1536
1537         /* mark the end of statistics initialization */
1538         sc->stats_init = FALSE;
1539 }
1540
1541 void
1542 bnx2x_save_statistics(struct bnx2x_softc *sc)
1543 {
1544         int i;
1545
1546         /* save queue statistics */
1547         for (i = 0; i < sc->num_queues; i++) {
1548                 struct bnx2x_fastpath *fp = &sc->fp[i];
1549                 struct bnx2x_eth_q_stats *qstats = &fp->eth_q_stats;
1550                 struct bnx2x_eth_q_stats_old *qstats_old = &fp->eth_q_stats_old;
1551
1552                 UPDATE_QSTAT_OLD(total_unicast_bytes_received_hi);
1553                 UPDATE_QSTAT_OLD(total_unicast_bytes_received_lo);
1554                 UPDATE_QSTAT_OLD(total_broadcast_bytes_received_hi);
1555                 UPDATE_QSTAT_OLD(total_broadcast_bytes_received_lo);
1556                 UPDATE_QSTAT_OLD(total_multicast_bytes_received_hi);
1557                 UPDATE_QSTAT_OLD(total_multicast_bytes_received_lo);
1558                 UPDATE_QSTAT_OLD(total_unicast_bytes_transmitted_hi);
1559                 UPDATE_QSTAT_OLD(total_unicast_bytes_transmitted_lo);
1560                 UPDATE_QSTAT_OLD(total_broadcast_bytes_transmitted_hi);
1561                 UPDATE_QSTAT_OLD(total_broadcast_bytes_transmitted_lo);
1562                 UPDATE_QSTAT_OLD(total_multicast_bytes_transmitted_hi);
1563                 UPDATE_QSTAT_OLD(total_multicast_bytes_transmitted_lo);
1564         }
1565
1566         /* store port firmware statistics */
1567         if (sc->port.pmf) {
1568                 struct bnx2x_eth_stats *estats = &sc->eth_stats;
1569                 struct bnx2x_fw_port_stats_old *fwstats = &sc->fw_stats_old;
1570                 struct host_port_stats *pstats = BNX2X_SP(sc, port_stats);
1571
1572                 fwstats->pfc_frames_rx_hi = pstats->pfc_frames_rx_hi;
1573                 fwstats->pfc_frames_rx_lo = pstats->pfc_frames_rx_lo;
1574                 fwstats->pfc_frames_tx_hi = pstats->pfc_frames_tx_hi;
1575                 fwstats->pfc_frames_tx_lo = pstats->pfc_frames_tx_lo;
1576
1577                 if (IS_MF(sc)) {
1578                         UPDATE_FW_STAT_OLD(mac_filter_discard);
1579                         UPDATE_FW_STAT_OLD(mf_tag_discard);
1580                         UPDATE_FW_STAT_OLD(brb_truncate_discard);
1581                         UPDATE_FW_STAT_OLD(mac_discard);
1582                 }
1583         }
1584 }