xref: /f-stack/dpdk/drivers/net/bnx2x/bnx2x_stats.c (revision d30ea906)
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright (c) 2007-2013 Broadcom Corporation.
3  *
4  * Eric Davis        <[email protected]>
5  * David Christensen <[email protected]>
6  * Gary Zambrano     <[email protected]>
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
bnx2x_get_port_stats_dma_len(struct bnx2x_softc * sc)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
bnx2x_storm_stats_post(struct bnx2x_softc * sc)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
bnx2x_hw_stats_post(struct bnx2x_softc * sc)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
bnx2x_stats_comp(struct bnx2x_softc * sc)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
bnx2x_stats_pmf_update(struct bnx2x_softc * sc)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
bnx2x_port_stats_init(struct bnx2x_softc * sc)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
bnx2x_func_stats_init(struct bnx2x_softc * sc)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
bnx2x_stats_start(struct bnx2x_softc * sc)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
bnx2x_stats_pmf_start(struct bnx2x_softc * sc)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
bnx2x_stats_restart(struct bnx2x_softc * sc)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
bnx2x_bmac_stats_update(struct bnx2x_softc * sc)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
bnx2x_mstat_stats_update(struct bnx2x_softc * sc)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
bnx2x_emac_stats_update(struct bnx2x_softc * sc)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
bnx2x_hw_stats_update(struct bnx2x_softc * sc)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
bnx2x_storm_stats_validate_counters(struct bnx2x_softc * sc)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
bnx2x_storm_stats_update(struct bnx2x_softc * sc)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
bnx2x_drv_stats_update(struct bnx2x_softc * sc)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
bnx2x_edebug_stats_stopped(struct bnx2x_softc * sc)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
bnx2x_stats_update(struct bnx2x_softc * sc)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
bnx2x_port_stats_stop(struct bnx2x_softc * sc)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
bnx2x_stats_stop(struct bnx2x_softc * sc)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
bnx2x_stats_do_nothing(__rte_unused struct bnx2x_softc * sc)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 
bnx2x_stats_handle(struct bnx2x_softc * sc,enum bnx2x_stats_event event)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
bnx2x_port_stats_base_init(struct bnx2x_softc * sc)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
bnx2x_prep_fw_stats_req(struct bnx2x_softc * sc)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 
bnx2x_memset_stats(struct bnx2x_softc * sc)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
bnx2x_stats_init(struct bnx2x_softc * sc)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
bnx2x_save_statistics(struct bnx2x_softc * sc)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 }
1586