RT-AC56 3.0.0.4.374.37 core
[tomato.git] / release / src-rt-6.x.4708 / linux / linux-2.6.36 / drivers / net / bnx2x / bnx2x_stats.c
blob0888c03fc89cb324faf4961aa91af80cd171602c
2 #include "bnx2x_cmn.h"
3 #include "bnx2x_stats.h"
5 /* Statistics */
7 /****************************************************************************
8 * Macros
9 ****************************************************************************/
11 /* sum[hi:lo] += add[hi:lo] */
12 #define ADD_64(s_hi, a_hi, s_lo, a_lo) \
13 do { \
14 s_lo += a_lo; \
15 s_hi += a_hi + ((s_lo < a_lo) ? 1 : 0); \
16 } while (0)
18 /* difference = minuend - subtrahend */
19 #define DIFF_64(d_hi, m_hi, s_hi, d_lo, m_lo, s_lo) \
20 do { \
21 if (m_lo < s_lo) { \
22 /* underflow */ \
23 d_hi = m_hi - s_hi; \
24 if (d_hi > 0) { \
25 /* we can 'loan' 1 */ \
26 d_hi--; \
27 d_lo = m_lo + (UINT_MAX - s_lo) + 1; \
28 } else { \
29 /* m_hi <= s_hi */ \
30 d_hi = 0; \
31 d_lo = 0; \
32 } \
33 } else { \
34 /* m_lo >= s_lo */ \
35 if (m_hi < s_hi) { \
36 d_hi = 0; \
37 d_lo = 0; \
38 } else { \
39 /* m_hi >= s_hi */ \
40 d_hi = m_hi - s_hi; \
41 d_lo = m_lo - s_lo; \
42 } \
43 } \
44 } while (0)
46 #define UPDATE_STAT64(s, t) \
47 do { \
48 DIFF_64(diff.hi, new->s##_hi, pstats->mac_stx[0].t##_hi, \
49 diff.lo, new->s##_lo, pstats->mac_stx[0].t##_lo); \
50 pstats->mac_stx[0].t##_hi = new->s##_hi; \
51 pstats->mac_stx[0].t##_lo = new->s##_lo; \
52 ADD_64(pstats->mac_stx[1].t##_hi, diff.hi, \
53 pstats->mac_stx[1].t##_lo, diff.lo); \
54 } while (0)
56 #define UPDATE_STAT64_NIG(s, t) \
57 do { \
58 DIFF_64(diff.hi, new->s##_hi, old->s##_hi, \
59 diff.lo, new->s##_lo, old->s##_lo); \
60 ADD_64(estats->t##_hi, diff.hi, \
61 estats->t##_lo, diff.lo); \
62 } while (0)
64 /* sum[hi:lo] += add */
65 #define ADD_EXTEND_64(s_hi, s_lo, a) \
66 do { \
67 s_lo += a; \
68 s_hi += (s_lo < a) ? 1 : 0; \
69 } while (0)
71 #define UPDATE_EXTEND_STAT(s) \
72 do { \
73 ADD_EXTEND_64(pstats->mac_stx[1].s##_hi, \
74 pstats->mac_stx[1].s##_lo, \
75 new->s); \
76 } while (0)
78 #define UPDATE_EXTEND_TSTAT(s, t) \
79 do { \
80 diff = le32_to_cpu(tclient->s) - le32_to_cpu(old_tclient->s); \
81 old_tclient->s = tclient->s; \
82 ADD_EXTEND_64(qstats->t##_hi, qstats->t##_lo, diff); \
83 } while (0)
85 #define UPDATE_EXTEND_USTAT(s, t) \
86 do { \
87 diff = le32_to_cpu(uclient->s) - le32_to_cpu(old_uclient->s); \
88 old_uclient->s = uclient->s; \
89 ADD_EXTEND_64(qstats->t##_hi, qstats->t##_lo, diff); \
90 } while (0)
92 #define UPDATE_EXTEND_XSTAT(s, t) \
93 do { \
94 diff = le32_to_cpu(xclient->s) - le32_to_cpu(old_xclient->s); \
95 old_xclient->s = xclient->s; \
96 ADD_EXTEND_64(qstats->t##_hi, qstats->t##_lo, diff); \
97 } while (0)
99 /* minuend -= subtrahend */
100 #define SUB_64(m_hi, s_hi, m_lo, s_lo) \
101 do { \
102 DIFF_64(m_hi, m_hi, s_hi, m_lo, m_lo, s_lo); \
103 } while (0)
105 /* minuend[hi:lo] -= subtrahend */
106 #define SUB_EXTEND_64(m_hi, m_lo, s) \
107 do { \
108 SUB_64(m_hi, 0, m_lo, s); \
109 } while (0)
111 #define SUB_EXTEND_USTAT(s, t) \
112 do { \
113 diff = le32_to_cpu(uclient->s) - le32_to_cpu(old_uclient->s); \
114 SUB_EXTEND_64(qstats->t##_hi, qstats->t##_lo, diff); \
115 } while (0)
118 * General service functions
121 static inline long bnx2x_hilo(u32 *hiref)
123 u32 lo = *(hiref + 1);
124 #if (BITS_PER_LONG == 64)
125 u32 hi = *hiref;
127 return HILO_U64(hi, lo);
128 #else
129 return lo;
130 #endif
134 * Init service functions
138 static void bnx2x_storm_stats_post(struct bnx2x *bp)
140 if (!bp->stats_pending) {
141 struct eth_query_ramrod_data ramrod_data = {0};
142 int i, rc;
144 spin_lock_bh(&bp->stats_lock);
146 ramrod_data.drv_counter = bp->stats_counter++;
147 ramrod_data.collect_port = bp->port.pmf ? 1 : 0;
148 for_each_queue(bp, i)
149 ramrod_data.ctr_id_vector |= (1 << bp->fp[i].cl_id);
151 rc = bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_STAT_QUERY, 0,
152 ((u32 *)&ramrod_data)[1],
153 ((u32 *)&ramrod_data)[0], 0);
154 if (rc == 0) {
155 /* stats ramrod has it's own slot on the spq */
156 bp->spq_left++;
157 bp->stats_pending = 1;
160 spin_unlock_bh(&bp->stats_lock);
164 static void bnx2x_hw_stats_post(struct bnx2x *bp)
166 struct dmae_command *dmae = &bp->stats_dmae;
167 u32 *stats_comp = bnx2x_sp(bp, stats_comp);
169 *stats_comp = DMAE_COMP_VAL;
170 if (CHIP_REV_IS_SLOW(bp))
171 return;
173 /* loader */
174 if (bp->executer_idx) {
175 int loader_idx = PMF_DMAE_C(bp);
177 memset(dmae, 0, sizeof(struct dmae_command));
179 dmae->opcode = (DMAE_CMD_SRC_PCI | DMAE_CMD_DST_GRC |
180 DMAE_CMD_C_DST_GRC | DMAE_CMD_C_ENABLE |
181 DMAE_CMD_DST_RESET |
182 #ifdef __BIG_ENDIAN
183 DMAE_CMD_ENDIANITY_B_DW_SWAP |
184 #else
185 DMAE_CMD_ENDIANITY_DW_SWAP |
186 #endif
187 (BP_PORT(bp) ? DMAE_CMD_PORT_1 :
188 DMAE_CMD_PORT_0) |
189 (BP_E1HVN(bp) << DMAE_CMD_E1HVN_SHIFT));
190 dmae->src_addr_lo = U64_LO(bnx2x_sp_mapping(bp, dmae[0]));
191 dmae->src_addr_hi = U64_HI(bnx2x_sp_mapping(bp, dmae[0]));
192 dmae->dst_addr_lo = (DMAE_REG_CMD_MEM +
193 sizeof(struct dmae_command) *
194 (loader_idx + 1)) >> 2;
195 dmae->dst_addr_hi = 0;
196 dmae->len = sizeof(struct dmae_command) >> 2;
197 if (CHIP_IS_E1(bp))
198 dmae->len--;
199 dmae->comp_addr_lo = dmae_reg_go_c[loader_idx + 1] >> 2;
200 dmae->comp_addr_hi = 0;
201 dmae->comp_val = 1;
203 *stats_comp = 0;
204 bnx2x_post_dmae(bp, dmae, loader_idx);
206 } else if (bp->func_stx) {
207 *stats_comp = 0;
208 bnx2x_post_dmae(bp, dmae, INIT_DMAE_C(bp));
212 static int bnx2x_stats_comp(struct bnx2x *bp)
214 u32 *stats_comp = bnx2x_sp(bp, stats_comp);
215 int cnt = 10;
217 might_sleep();
218 while (*stats_comp != DMAE_COMP_VAL) {
219 if (!cnt) {
220 BNX2X_ERR("timeout waiting for stats finished\n");
221 break;
223 cnt--;
224 msleep(1);
226 return 1;
230 * Statistics service functions
233 static void bnx2x_stats_pmf_update(struct bnx2x *bp)
235 struct dmae_command *dmae;
236 u32 opcode;
237 int loader_idx = PMF_DMAE_C(bp);
238 u32 *stats_comp = bnx2x_sp(bp, stats_comp);
240 /* sanity */
241 if (!IS_E1HMF(bp) || !bp->port.pmf || !bp->port.port_stx) {
242 BNX2X_ERR("BUG!\n");
243 return;
246 bp->executer_idx = 0;
248 opcode = (DMAE_CMD_SRC_GRC | DMAE_CMD_DST_PCI |
249 DMAE_CMD_C_ENABLE |
250 DMAE_CMD_SRC_RESET | DMAE_CMD_DST_RESET |
251 #ifdef __BIG_ENDIAN
252 DMAE_CMD_ENDIANITY_B_DW_SWAP |
253 #else
254 DMAE_CMD_ENDIANITY_DW_SWAP |
255 #endif
256 (BP_PORT(bp) ? DMAE_CMD_PORT_1 : DMAE_CMD_PORT_0) |
257 (BP_E1HVN(bp) << DMAE_CMD_E1HVN_SHIFT));
259 dmae = bnx2x_sp(bp, dmae[bp->executer_idx++]);
260 dmae->opcode = (opcode | DMAE_CMD_C_DST_GRC);
261 dmae->src_addr_lo = bp->port.port_stx >> 2;
262 dmae->src_addr_hi = 0;
263 dmae->dst_addr_lo = U64_LO(bnx2x_sp_mapping(bp, port_stats));
264 dmae->dst_addr_hi = U64_HI(bnx2x_sp_mapping(bp, port_stats));
265 dmae->len = DMAE_LEN32_RD_MAX;
266 dmae->comp_addr_lo = dmae_reg_go_c[loader_idx] >> 2;
267 dmae->comp_addr_hi = 0;
268 dmae->comp_val = 1;
270 dmae = bnx2x_sp(bp, dmae[bp->executer_idx++]);
271 dmae->opcode = (opcode | DMAE_CMD_C_DST_PCI);
272 dmae->src_addr_lo = (bp->port.port_stx >> 2) + DMAE_LEN32_RD_MAX;
273 dmae->src_addr_hi = 0;
274 dmae->dst_addr_lo = U64_LO(bnx2x_sp_mapping(bp, port_stats) +
275 DMAE_LEN32_RD_MAX * 4);
276 dmae->dst_addr_hi = U64_HI(bnx2x_sp_mapping(bp, port_stats) +
277 DMAE_LEN32_RD_MAX * 4);
278 dmae->len = (sizeof(struct host_port_stats) >> 2) - DMAE_LEN32_RD_MAX;
279 dmae->comp_addr_lo = U64_LO(bnx2x_sp_mapping(bp, stats_comp));
280 dmae->comp_addr_hi = U64_HI(bnx2x_sp_mapping(bp, stats_comp));
281 dmae->comp_val = DMAE_COMP_VAL;
283 *stats_comp = 0;
284 bnx2x_hw_stats_post(bp);
285 bnx2x_stats_comp(bp);
288 static void bnx2x_port_stats_init(struct bnx2x *bp)
290 struct dmae_command *dmae;
291 int port = BP_PORT(bp);
292 int vn = BP_E1HVN(bp);
293 u32 opcode;
294 int loader_idx = PMF_DMAE_C(bp);
295 u32 mac_addr;
296 u32 *stats_comp = bnx2x_sp(bp, stats_comp);
298 /* sanity */
299 if (!bp->link_vars.link_up || !bp->port.pmf) {
300 BNX2X_ERR("BUG!\n");
301 return;
304 bp->executer_idx = 0;
306 /* MCP */
307 opcode = (DMAE_CMD_SRC_PCI | DMAE_CMD_DST_GRC |
308 DMAE_CMD_C_DST_GRC | DMAE_CMD_C_ENABLE |
309 DMAE_CMD_SRC_RESET | DMAE_CMD_DST_RESET |
310 #ifdef __BIG_ENDIAN
311 DMAE_CMD_ENDIANITY_B_DW_SWAP |
312 #else
313 DMAE_CMD_ENDIANITY_DW_SWAP |
314 #endif
315 (port ? DMAE_CMD_PORT_1 : DMAE_CMD_PORT_0) |
316 (vn << DMAE_CMD_E1HVN_SHIFT));
318 if (bp->port.port_stx) {
320 dmae = bnx2x_sp(bp, dmae[bp->executer_idx++]);
321 dmae->opcode = opcode;
322 dmae->src_addr_lo = U64_LO(bnx2x_sp_mapping(bp, port_stats));
323 dmae->src_addr_hi = U64_HI(bnx2x_sp_mapping(bp, port_stats));
324 dmae->dst_addr_lo = bp->port.port_stx >> 2;
325 dmae->dst_addr_hi = 0;
326 dmae->len = sizeof(struct host_port_stats) >> 2;
327 dmae->comp_addr_lo = dmae_reg_go_c[loader_idx] >> 2;
328 dmae->comp_addr_hi = 0;
329 dmae->comp_val = 1;
332 if (bp->func_stx) {
334 dmae = bnx2x_sp(bp, dmae[bp->executer_idx++]);
335 dmae->opcode = opcode;
336 dmae->src_addr_lo = U64_LO(bnx2x_sp_mapping(bp, func_stats));
337 dmae->src_addr_hi = U64_HI(bnx2x_sp_mapping(bp, func_stats));
338 dmae->dst_addr_lo = bp->func_stx >> 2;
339 dmae->dst_addr_hi = 0;
340 dmae->len = sizeof(struct host_func_stats) >> 2;
341 dmae->comp_addr_lo = dmae_reg_go_c[loader_idx] >> 2;
342 dmae->comp_addr_hi = 0;
343 dmae->comp_val = 1;
346 /* MAC */
347 opcode = (DMAE_CMD_SRC_GRC | DMAE_CMD_DST_PCI |
348 DMAE_CMD_C_DST_GRC | DMAE_CMD_C_ENABLE |
349 DMAE_CMD_SRC_RESET | DMAE_CMD_DST_RESET |
350 #ifdef __BIG_ENDIAN
351 DMAE_CMD_ENDIANITY_B_DW_SWAP |
352 #else
353 DMAE_CMD_ENDIANITY_DW_SWAP |
354 #endif
355 (port ? DMAE_CMD_PORT_1 : DMAE_CMD_PORT_0) |
356 (vn << DMAE_CMD_E1HVN_SHIFT));
358 if (bp->link_vars.mac_type == MAC_TYPE_BMAC) {
360 mac_addr = (port ? NIG_REG_INGRESS_BMAC1_MEM :
361 NIG_REG_INGRESS_BMAC0_MEM);
363 /* BIGMAC_REGISTER_TX_STAT_GTPKT ..
364 BIGMAC_REGISTER_TX_STAT_GTBYT */
365 dmae = bnx2x_sp(bp, dmae[bp->executer_idx++]);
366 dmae->opcode = opcode;
367 dmae->src_addr_lo = (mac_addr +
368 BIGMAC_REGISTER_TX_STAT_GTPKT) >> 2;
369 dmae->src_addr_hi = 0;
370 dmae->dst_addr_lo = U64_LO(bnx2x_sp_mapping(bp, mac_stats));
371 dmae->dst_addr_hi = U64_HI(bnx2x_sp_mapping(bp, mac_stats));
372 dmae->len = (8 + BIGMAC_REGISTER_TX_STAT_GTBYT -
373 BIGMAC_REGISTER_TX_STAT_GTPKT) >> 2;
374 dmae->comp_addr_lo = dmae_reg_go_c[loader_idx] >> 2;
375 dmae->comp_addr_hi = 0;
376 dmae->comp_val = 1;
378 /* BIGMAC_REGISTER_RX_STAT_GR64 ..
379 BIGMAC_REGISTER_RX_STAT_GRIPJ */
380 dmae = bnx2x_sp(bp, dmae[bp->executer_idx++]);
381 dmae->opcode = opcode;
382 dmae->src_addr_lo = (mac_addr +
383 BIGMAC_REGISTER_RX_STAT_GR64) >> 2;
384 dmae->src_addr_hi = 0;
385 dmae->dst_addr_lo = U64_LO(bnx2x_sp_mapping(bp, mac_stats) +
386 offsetof(struct bmac_stats, rx_stat_gr64_lo));
387 dmae->dst_addr_hi = U64_HI(bnx2x_sp_mapping(bp, mac_stats) +
388 offsetof(struct bmac_stats, rx_stat_gr64_lo));
389 dmae->len = (8 + BIGMAC_REGISTER_RX_STAT_GRIPJ -
390 BIGMAC_REGISTER_RX_STAT_GR64) >> 2;
391 dmae->comp_addr_lo = dmae_reg_go_c[loader_idx] >> 2;
392 dmae->comp_addr_hi = 0;
393 dmae->comp_val = 1;
395 } else if (bp->link_vars.mac_type == MAC_TYPE_EMAC) {
397 mac_addr = (port ? GRCBASE_EMAC1 : GRCBASE_EMAC0);
399 /* EMAC_REG_EMAC_RX_STAT_AC (EMAC_REG_EMAC_RX_STAT_AC_COUNT)*/
400 dmae = bnx2x_sp(bp, dmae[bp->executer_idx++]);
401 dmae->opcode = opcode;
402 dmae->src_addr_lo = (mac_addr +
403 EMAC_REG_EMAC_RX_STAT_AC) >> 2;
404 dmae->src_addr_hi = 0;
405 dmae->dst_addr_lo = U64_LO(bnx2x_sp_mapping(bp, mac_stats));
406 dmae->dst_addr_hi = U64_HI(bnx2x_sp_mapping(bp, mac_stats));
407 dmae->len = EMAC_REG_EMAC_RX_STAT_AC_COUNT;
408 dmae->comp_addr_lo = dmae_reg_go_c[loader_idx] >> 2;
409 dmae->comp_addr_hi = 0;
410 dmae->comp_val = 1;
412 /* EMAC_REG_EMAC_RX_STAT_AC_28 */
413 dmae = bnx2x_sp(bp, dmae[bp->executer_idx++]);
414 dmae->opcode = opcode;
415 dmae->src_addr_lo = (mac_addr +
416 EMAC_REG_EMAC_RX_STAT_AC_28) >> 2;
417 dmae->src_addr_hi = 0;
418 dmae->dst_addr_lo = U64_LO(bnx2x_sp_mapping(bp, mac_stats) +
419 offsetof(struct emac_stats, rx_stat_falsecarriererrors));
420 dmae->dst_addr_hi = U64_HI(bnx2x_sp_mapping(bp, mac_stats) +
421 offsetof(struct emac_stats, rx_stat_falsecarriererrors));
422 dmae->len = 1;
423 dmae->comp_addr_lo = dmae_reg_go_c[loader_idx] >> 2;
424 dmae->comp_addr_hi = 0;
425 dmae->comp_val = 1;
427 /* EMAC_REG_EMAC_TX_STAT_AC (EMAC_REG_EMAC_TX_STAT_AC_COUNT)*/
428 dmae = bnx2x_sp(bp, dmae[bp->executer_idx++]);
429 dmae->opcode = opcode;
430 dmae->src_addr_lo = (mac_addr +
431 EMAC_REG_EMAC_TX_STAT_AC) >> 2;
432 dmae->src_addr_hi = 0;
433 dmae->dst_addr_lo = U64_LO(bnx2x_sp_mapping(bp, mac_stats) +
434 offsetof(struct emac_stats, tx_stat_ifhcoutoctets));
435 dmae->dst_addr_hi = U64_HI(bnx2x_sp_mapping(bp, mac_stats) +
436 offsetof(struct emac_stats, tx_stat_ifhcoutoctets));
437 dmae->len = EMAC_REG_EMAC_TX_STAT_AC_COUNT;
438 dmae->comp_addr_lo = dmae_reg_go_c[loader_idx] >> 2;
439 dmae->comp_addr_hi = 0;
440 dmae->comp_val = 1;
443 /* NIG */
444 dmae = bnx2x_sp(bp, dmae[bp->executer_idx++]);
445 dmae->opcode = opcode;
446 dmae->src_addr_lo = (port ? NIG_REG_STAT1_BRB_DISCARD :
447 NIG_REG_STAT0_BRB_DISCARD) >> 2;
448 dmae->src_addr_hi = 0;
449 dmae->dst_addr_lo = U64_LO(bnx2x_sp_mapping(bp, nig_stats));
450 dmae->dst_addr_hi = U64_HI(bnx2x_sp_mapping(bp, nig_stats));
451 dmae->len = (sizeof(struct nig_stats) - 4*sizeof(u32)) >> 2;
452 dmae->comp_addr_lo = dmae_reg_go_c[loader_idx] >> 2;
453 dmae->comp_addr_hi = 0;
454 dmae->comp_val = 1;
456 dmae = bnx2x_sp(bp, dmae[bp->executer_idx++]);
457 dmae->opcode = opcode;
458 dmae->src_addr_lo = (port ? NIG_REG_STAT1_EGRESS_MAC_PKT0 :
459 NIG_REG_STAT0_EGRESS_MAC_PKT0) >> 2;
460 dmae->src_addr_hi = 0;
461 dmae->dst_addr_lo = U64_LO(bnx2x_sp_mapping(bp, nig_stats) +
462 offsetof(struct nig_stats, egress_mac_pkt0_lo));
463 dmae->dst_addr_hi = U64_HI(bnx2x_sp_mapping(bp, nig_stats) +
464 offsetof(struct nig_stats, egress_mac_pkt0_lo));
465 dmae->len = (2*sizeof(u32)) >> 2;
466 dmae->comp_addr_lo = dmae_reg_go_c[loader_idx] >> 2;
467 dmae->comp_addr_hi = 0;
468 dmae->comp_val = 1;
470 dmae = bnx2x_sp(bp, dmae[bp->executer_idx++]);
471 dmae->opcode = (DMAE_CMD_SRC_GRC | DMAE_CMD_DST_PCI |
472 DMAE_CMD_C_DST_PCI | DMAE_CMD_C_ENABLE |
473 DMAE_CMD_SRC_RESET | DMAE_CMD_DST_RESET |
474 #ifdef __BIG_ENDIAN
475 DMAE_CMD_ENDIANITY_B_DW_SWAP |
476 #else
477 DMAE_CMD_ENDIANITY_DW_SWAP |
478 #endif
479 (port ? DMAE_CMD_PORT_1 : DMAE_CMD_PORT_0) |
480 (vn << DMAE_CMD_E1HVN_SHIFT));
481 dmae->src_addr_lo = (port ? NIG_REG_STAT1_EGRESS_MAC_PKT1 :
482 NIG_REG_STAT0_EGRESS_MAC_PKT1) >> 2;
483 dmae->src_addr_hi = 0;
484 dmae->dst_addr_lo = U64_LO(bnx2x_sp_mapping(bp, nig_stats) +
485 offsetof(struct nig_stats, egress_mac_pkt1_lo));
486 dmae->dst_addr_hi = U64_HI(bnx2x_sp_mapping(bp, nig_stats) +
487 offsetof(struct nig_stats, egress_mac_pkt1_lo));
488 dmae->len = (2*sizeof(u32)) >> 2;
489 dmae->comp_addr_lo = U64_LO(bnx2x_sp_mapping(bp, stats_comp));
490 dmae->comp_addr_hi = U64_HI(bnx2x_sp_mapping(bp, stats_comp));
491 dmae->comp_val = DMAE_COMP_VAL;
493 *stats_comp = 0;
496 static void bnx2x_func_stats_init(struct bnx2x *bp)
498 struct dmae_command *dmae = &bp->stats_dmae;
499 u32 *stats_comp = bnx2x_sp(bp, stats_comp);
501 /* sanity */
502 if (!bp->func_stx) {
503 BNX2X_ERR("BUG!\n");
504 return;
507 bp->executer_idx = 0;
508 memset(dmae, 0, sizeof(struct dmae_command));
510 dmae->opcode = (DMAE_CMD_SRC_PCI | DMAE_CMD_DST_GRC |
511 DMAE_CMD_C_DST_PCI | DMAE_CMD_C_ENABLE |
512 DMAE_CMD_SRC_RESET | DMAE_CMD_DST_RESET |
513 #ifdef __BIG_ENDIAN
514 DMAE_CMD_ENDIANITY_B_DW_SWAP |
515 #else
516 DMAE_CMD_ENDIANITY_DW_SWAP |
517 #endif
518 (BP_PORT(bp) ? DMAE_CMD_PORT_1 : DMAE_CMD_PORT_0) |
519 (BP_E1HVN(bp) << DMAE_CMD_E1HVN_SHIFT));
520 dmae->src_addr_lo = U64_LO(bnx2x_sp_mapping(bp, func_stats));
521 dmae->src_addr_hi = U64_HI(bnx2x_sp_mapping(bp, func_stats));
522 dmae->dst_addr_lo = bp->func_stx >> 2;
523 dmae->dst_addr_hi = 0;
524 dmae->len = sizeof(struct host_func_stats) >> 2;
525 dmae->comp_addr_lo = U64_LO(bnx2x_sp_mapping(bp, stats_comp));
526 dmae->comp_addr_hi = U64_HI(bnx2x_sp_mapping(bp, stats_comp));
527 dmae->comp_val = DMAE_COMP_VAL;
529 *stats_comp = 0;
532 static void bnx2x_stats_start(struct bnx2x *bp)
534 if (bp->port.pmf)
535 bnx2x_port_stats_init(bp);
537 else if (bp->func_stx)
538 bnx2x_func_stats_init(bp);
540 bnx2x_hw_stats_post(bp);
541 bnx2x_storm_stats_post(bp);
544 static void bnx2x_stats_pmf_start(struct bnx2x *bp)
546 bnx2x_stats_comp(bp);
547 bnx2x_stats_pmf_update(bp);
548 bnx2x_stats_start(bp);
551 static void bnx2x_stats_restart(struct bnx2x *bp)
553 bnx2x_stats_comp(bp);
554 bnx2x_stats_start(bp);
557 static void bnx2x_bmac_stats_update(struct bnx2x *bp)
559 struct bmac_stats *new = bnx2x_sp(bp, mac_stats.bmac_stats);
560 struct host_port_stats *pstats = bnx2x_sp(bp, port_stats);
561 struct bnx2x_eth_stats *estats = &bp->eth_stats;
562 struct {
563 u32 lo;
564 u32 hi;
565 } diff;
567 UPDATE_STAT64(rx_stat_grerb, rx_stat_ifhcinbadoctets);
568 UPDATE_STAT64(rx_stat_grfcs, rx_stat_dot3statsfcserrors);
569 UPDATE_STAT64(rx_stat_grund, rx_stat_etherstatsundersizepkts);
570 UPDATE_STAT64(rx_stat_grovr, rx_stat_dot3statsframestoolong);
571 UPDATE_STAT64(rx_stat_grfrg, rx_stat_etherstatsfragments);
572 UPDATE_STAT64(rx_stat_grjbr, rx_stat_etherstatsjabbers);
573 UPDATE_STAT64(rx_stat_grxcf, rx_stat_maccontrolframesreceived);
574 UPDATE_STAT64(rx_stat_grxpf, rx_stat_xoffstateentered);
575 UPDATE_STAT64(rx_stat_grxpf, rx_stat_bmac_xpf);
576 UPDATE_STAT64(tx_stat_gtxpf, tx_stat_outxoffsent);
577 UPDATE_STAT64(tx_stat_gtxpf, tx_stat_flowcontroldone);
578 UPDATE_STAT64(tx_stat_gt64, tx_stat_etherstatspkts64octets);
579 UPDATE_STAT64(tx_stat_gt127,
580 tx_stat_etherstatspkts65octetsto127octets);
581 UPDATE_STAT64(tx_stat_gt255,
582 tx_stat_etherstatspkts128octetsto255octets);
583 UPDATE_STAT64(tx_stat_gt511,
584 tx_stat_etherstatspkts256octetsto511octets);
585 UPDATE_STAT64(tx_stat_gt1023,
586 tx_stat_etherstatspkts512octetsto1023octets);
587 UPDATE_STAT64(tx_stat_gt1518,
588 tx_stat_etherstatspkts1024octetsto1522octets);
589 UPDATE_STAT64(tx_stat_gt2047, tx_stat_bmac_2047);
590 UPDATE_STAT64(tx_stat_gt4095, tx_stat_bmac_4095);
591 UPDATE_STAT64(tx_stat_gt9216, tx_stat_bmac_9216);
592 UPDATE_STAT64(tx_stat_gt16383, tx_stat_bmac_16383);
593 UPDATE_STAT64(tx_stat_gterr,
594 tx_stat_dot3statsinternalmactransmiterrors);
595 UPDATE_STAT64(tx_stat_gtufl, tx_stat_bmac_ufl);
597 estats->pause_frames_received_hi =
598 pstats->mac_stx[1].rx_stat_bmac_xpf_hi;
599 estats->pause_frames_received_lo =
600 pstats->mac_stx[1].rx_stat_bmac_xpf_lo;
602 estats->pause_frames_sent_hi =
603 pstats->mac_stx[1].tx_stat_outxoffsent_hi;
604 estats->pause_frames_sent_lo =
605 pstats->mac_stx[1].tx_stat_outxoffsent_lo;
608 static void bnx2x_emac_stats_update(struct bnx2x *bp)
610 struct emac_stats *new = bnx2x_sp(bp, mac_stats.emac_stats);
611 struct host_port_stats *pstats = bnx2x_sp(bp, port_stats);
612 struct bnx2x_eth_stats *estats = &bp->eth_stats;
614 UPDATE_EXTEND_STAT(rx_stat_ifhcinbadoctets);
615 UPDATE_EXTEND_STAT(tx_stat_ifhcoutbadoctets);
616 UPDATE_EXTEND_STAT(rx_stat_dot3statsfcserrors);
617 UPDATE_EXTEND_STAT(rx_stat_dot3statsalignmenterrors);
618 UPDATE_EXTEND_STAT(rx_stat_dot3statscarriersenseerrors);
619 UPDATE_EXTEND_STAT(rx_stat_falsecarriererrors);
620 UPDATE_EXTEND_STAT(rx_stat_etherstatsundersizepkts);
621 UPDATE_EXTEND_STAT(rx_stat_dot3statsframestoolong);
622 UPDATE_EXTEND_STAT(rx_stat_etherstatsfragments);
623 UPDATE_EXTEND_STAT(rx_stat_etherstatsjabbers);
624 UPDATE_EXTEND_STAT(rx_stat_maccontrolframesreceived);
625 UPDATE_EXTEND_STAT(rx_stat_xoffstateentered);
626 UPDATE_EXTEND_STAT(rx_stat_xonpauseframesreceived);
627 UPDATE_EXTEND_STAT(rx_stat_xoffpauseframesreceived);
628 UPDATE_EXTEND_STAT(tx_stat_outxonsent);
629 UPDATE_EXTEND_STAT(tx_stat_outxoffsent);
630 UPDATE_EXTEND_STAT(tx_stat_flowcontroldone);
631 UPDATE_EXTEND_STAT(tx_stat_etherstatscollisions);
632 UPDATE_EXTEND_STAT(tx_stat_dot3statssinglecollisionframes);
633 UPDATE_EXTEND_STAT(tx_stat_dot3statsmultiplecollisionframes);
634 UPDATE_EXTEND_STAT(tx_stat_dot3statsdeferredtransmissions);
635 UPDATE_EXTEND_STAT(tx_stat_dot3statsexcessivecollisions);
636 UPDATE_EXTEND_STAT(tx_stat_dot3statslatecollisions);
637 UPDATE_EXTEND_STAT(tx_stat_etherstatspkts64octets);
638 UPDATE_EXTEND_STAT(tx_stat_etherstatspkts65octetsto127octets);
639 UPDATE_EXTEND_STAT(tx_stat_etherstatspkts128octetsto255octets);
640 UPDATE_EXTEND_STAT(tx_stat_etherstatspkts256octetsto511octets);
641 UPDATE_EXTEND_STAT(tx_stat_etherstatspkts512octetsto1023octets);
642 UPDATE_EXTEND_STAT(tx_stat_etherstatspkts1024octetsto1522octets);
643 UPDATE_EXTEND_STAT(tx_stat_etherstatspktsover1522octets);
644 UPDATE_EXTEND_STAT(tx_stat_dot3statsinternalmactransmiterrors);
646 estats->pause_frames_received_hi =
647 pstats->mac_stx[1].rx_stat_xonpauseframesreceived_hi;
648 estats->pause_frames_received_lo =
649 pstats->mac_stx[1].rx_stat_xonpauseframesreceived_lo;
650 ADD_64(estats->pause_frames_received_hi,
651 pstats->mac_stx[1].rx_stat_xoffpauseframesreceived_hi,
652 estats->pause_frames_received_lo,
653 pstats->mac_stx[1].rx_stat_xoffpauseframesreceived_lo);
655 estats->pause_frames_sent_hi =
656 pstats->mac_stx[1].tx_stat_outxonsent_hi;
657 estats->pause_frames_sent_lo =
658 pstats->mac_stx[1].tx_stat_outxonsent_lo;
659 ADD_64(estats->pause_frames_sent_hi,
660 pstats->mac_stx[1].tx_stat_outxoffsent_hi,
661 estats->pause_frames_sent_lo,
662 pstats->mac_stx[1].tx_stat_outxoffsent_lo);
665 static int bnx2x_hw_stats_update(struct bnx2x *bp)
667 struct nig_stats *new = bnx2x_sp(bp, nig_stats);
668 struct nig_stats *old = &(bp->port.old_nig_stats);
669 struct host_port_stats *pstats = bnx2x_sp(bp, port_stats);
670 struct bnx2x_eth_stats *estats = &bp->eth_stats;
671 struct {
672 u32 lo;
673 u32 hi;
674 } diff;
676 if (bp->link_vars.mac_type == MAC_TYPE_BMAC)
677 bnx2x_bmac_stats_update(bp);
679 else if (bp->link_vars.mac_type == MAC_TYPE_EMAC)
680 bnx2x_emac_stats_update(bp);
682 else { /* unreached */
683 BNX2X_ERR("stats updated by DMAE but no MAC active\n");
684 return -1;
687 ADD_EXTEND_64(pstats->brb_drop_hi, pstats->brb_drop_lo,
688 new->brb_discard - old->brb_discard);
689 ADD_EXTEND_64(estats->brb_truncate_hi, estats->brb_truncate_lo,
690 new->brb_truncate - old->brb_truncate);
692 UPDATE_STAT64_NIG(egress_mac_pkt0,
693 etherstatspkts1024octetsto1522octets);
694 UPDATE_STAT64_NIG(egress_mac_pkt1, etherstatspktsover1522octets);
696 memcpy(old, new, sizeof(struct nig_stats));
698 memcpy(&(estats->rx_stat_ifhcinbadoctets_hi), &(pstats->mac_stx[1]),
699 sizeof(struct mac_stx));
700 estats->brb_drop_hi = pstats->brb_drop_hi;
701 estats->brb_drop_lo = pstats->brb_drop_lo;
703 pstats->host_port_stats_start = ++pstats->host_port_stats_end;
705 if (!BP_NOMCP(bp)) {
706 u32 nig_timer_max =
707 SHMEM_RD(bp, port_mb[BP_PORT(bp)].stat_nig_timer);
708 if (nig_timer_max != estats->nig_timer_max) {
709 estats->nig_timer_max = nig_timer_max;
710 BNX2X_ERR("NIG timer max (%u)\n",
711 estats->nig_timer_max);
715 return 0;
718 static int bnx2x_storm_stats_update(struct bnx2x *bp)
720 struct eth_stats_query *stats = bnx2x_sp(bp, fw_stats);
721 struct tstorm_per_port_stats *tport =
722 &stats->tstorm_common.port_statistics;
723 struct host_func_stats *fstats = bnx2x_sp(bp, func_stats);
724 struct bnx2x_eth_stats *estats = &bp->eth_stats;
725 int i;
726 u16 cur_stats_counter;
728 /* Make sure we use the value of the counter
729 * used for sending the last stats ramrod.
731 spin_lock_bh(&bp->stats_lock);
732 cur_stats_counter = bp->stats_counter - 1;
733 spin_unlock_bh(&bp->stats_lock);
735 memcpy(&(fstats->total_bytes_received_hi),
736 &(bnx2x_sp(bp, func_stats_base)->total_bytes_received_hi),
737 sizeof(struct host_func_stats) - 2*sizeof(u32));
738 estats->error_bytes_received_hi = 0;
739 estats->error_bytes_received_lo = 0;
740 estats->etherstatsoverrsizepkts_hi = 0;
741 estats->etherstatsoverrsizepkts_lo = 0;
742 estats->no_buff_discard_hi = 0;
743 estats->no_buff_discard_lo = 0;
745 for_each_queue(bp, i) {
746 struct bnx2x_fastpath *fp = &bp->fp[i];
747 int cl_id = fp->cl_id;
748 struct tstorm_per_client_stats *tclient =
749 &stats->tstorm_common.client_statistics[cl_id];
750 struct tstorm_per_client_stats *old_tclient = &fp->old_tclient;
751 struct ustorm_per_client_stats *uclient =
752 &stats->ustorm_common.client_statistics[cl_id];
753 struct ustorm_per_client_stats *old_uclient = &fp->old_uclient;
754 struct xstorm_per_client_stats *xclient =
755 &stats->xstorm_common.client_statistics[cl_id];
756 struct xstorm_per_client_stats *old_xclient = &fp->old_xclient;
757 struct bnx2x_eth_q_stats *qstats = &fp->eth_q_stats;
758 u32 diff;
760 /* are storm stats valid? */
761 if (le16_to_cpu(xclient->stats_counter) != cur_stats_counter) {
762 DP(BNX2X_MSG_STATS, "[%d] stats not updated by xstorm"
763 " xstorm counter (0x%x) != stats_counter (0x%x)\n",
764 i, xclient->stats_counter, cur_stats_counter + 1);
765 return -1;
767 if (le16_to_cpu(tclient->stats_counter) != cur_stats_counter) {
768 DP(BNX2X_MSG_STATS, "[%d] stats not updated by tstorm"
769 " tstorm counter (0x%x) != stats_counter (0x%x)\n",
770 i, tclient->stats_counter, cur_stats_counter + 1);
771 return -2;
773 if (le16_to_cpu(uclient->stats_counter) != cur_stats_counter) {
774 DP(BNX2X_MSG_STATS, "[%d] stats not updated by ustorm"
775 " ustorm counter (0x%x) != stats_counter (0x%x)\n",
776 i, uclient->stats_counter, cur_stats_counter + 1);
777 return -4;
780 qstats->total_bytes_received_hi =
781 le32_to_cpu(tclient->rcv_broadcast_bytes.hi);
782 qstats->total_bytes_received_lo =
783 le32_to_cpu(tclient->rcv_broadcast_bytes.lo);
785 ADD_64(qstats->total_bytes_received_hi,
786 le32_to_cpu(tclient->rcv_multicast_bytes.hi),
787 qstats->total_bytes_received_lo,
788 le32_to_cpu(tclient->rcv_multicast_bytes.lo));
790 ADD_64(qstats->total_bytes_received_hi,
791 le32_to_cpu(tclient->rcv_unicast_bytes.hi),
792 qstats->total_bytes_received_lo,
793 le32_to_cpu(tclient->rcv_unicast_bytes.lo));
795 SUB_64(qstats->total_bytes_received_hi,
796 le32_to_cpu(uclient->bcast_no_buff_bytes.hi),
797 qstats->total_bytes_received_lo,
798 le32_to_cpu(uclient->bcast_no_buff_bytes.lo));
800 SUB_64(qstats->total_bytes_received_hi,
801 le32_to_cpu(uclient->mcast_no_buff_bytes.hi),
802 qstats->total_bytes_received_lo,
803 le32_to_cpu(uclient->mcast_no_buff_bytes.lo));
805 SUB_64(qstats->total_bytes_received_hi,
806 le32_to_cpu(uclient->ucast_no_buff_bytes.hi),
807 qstats->total_bytes_received_lo,
808 le32_to_cpu(uclient->ucast_no_buff_bytes.lo));
810 qstats->valid_bytes_received_hi =
811 qstats->total_bytes_received_hi;
812 qstats->valid_bytes_received_lo =
813 qstats->total_bytes_received_lo;
815 qstats->error_bytes_received_hi =
816 le32_to_cpu(tclient->rcv_error_bytes.hi);
817 qstats->error_bytes_received_lo =
818 le32_to_cpu(tclient->rcv_error_bytes.lo);
820 ADD_64(qstats->total_bytes_received_hi,
821 qstats->error_bytes_received_hi,
822 qstats->total_bytes_received_lo,
823 qstats->error_bytes_received_lo);
825 UPDATE_EXTEND_TSTAT(rcv_unicast_pkts,
826 total_unicast_packets_received);
827 UPDATE_EXTEND_TSTAT(rcv_multicast_pkts,
828 total_multicast_packets_received);
829 UPDATE_EXTEND_TSTAT(rcv_broadcast_pkts,
830 total_broadcast_packets_received);
831 UPDATE_EXTEND_TSTAT(packets_too_big_discard,
832 etherstatsoverrsizepkts);
833 UPDATE_EXTEND_TSTAT(no_buff_discard, no_buff_discard);
835 SUB_EXTEND_USTAT(ucast_no_buff_pkts,
836 total_unicast_packets_received);
837 SUB_EXTEND_USTAT(mcast_no_buff_pkts,
838 total_multicast_packets_received);
839 SUB_EXTEND_USTAT(bcast_no_buff_pkts,
840 total_broadcast_packets_received);
841 UPDATE_EXTEND_USTAT(ucast_no_buff_pkts, no_buff_discard);
842 UPDATE_EXTEND_USTAT(mcast_no_buff_pkts, no_buff_discard);
843 UPDATE_EXTEND_USTAT(bcast_no_buff_pkts, no_buff_discard);
845 qstats->total_bytes_transmitted_hi =
846 le32_to_cpu(xclient->unicast_bytes_sent.hi);
847 qstats->total_bytes_transmitted_lo =
848 le32_to_cpu(xclient->unicast_bytes_sent.lo);
850 ADD_64(qstats->total_bytes_transmitted_hi,
851 le32_to_cpu(xclient->multicast_bytes_sent.hi),
852 qstats->total_bytes_transmitted_lo,
853 le32_to_cpu(xclient->multicast_bytes_sent.lo));
855 ADD_64(qstats->total_bytes_transmitted_hi,
856 le32_to_cpu(xclient->broadcast_bytes_sent.hi),
857 qstats->total_bytes_transmitted_lo,
858 le32_to_cpu(xclient->broadcast_bytes_sent.lo));
860 UPDATE_EXTEND_XSTAT(unicast_pkts_sent,
861 total_unicast_packets_transmitted);
862 UPDATE_EXTEND_XSTAT(multicast_pkts_sent,
863 total_multicast_packets_transmitted);
864 UPDATE_EXTEND_XSTAT(broadcast_pkts_sent,
865 total_broadcast_packets_transmitted);
867 old_tclient->checksum_discard = tclient->checksum_discard;
868 old_tclient->ttl0_discard = tclient->ttl0_discard;
870 ADD_64(fstats->total_bytes_received_hi,
871 qstats->total_bytes_received_hi,
872 fstats->total_bytes_received_lo,
873 qstats->total_bytes_received_lo);
874 ADD_64(fstats->total_bytes_transmitted_hi,
875 qstats->total_bytes_transmitted_hi,
876 fstats->total_bytes_transmitted_lo,
877 qstats->total_bytes_transmitted_lo);
878 ADD_64(fstats->total_unicast_packets_received_hi,
879 qstats->total_unicast_packets_received_hi,
880 fstats->total_unicast_packets_received_lo,
881 qstats->total_unicast_packets_received_lo);
882 ADD_64(fstats->total_multicast_packets_received_hi,
883 qstats->total_multicast_packets_received_hi,
884 fstats->total_multicast_packets_received_lo,
885 qstats->total_multicast_packets_received_lo);
886 ADD_64(fstats->total_broadcast_packets_received_hi,
887 qstats->total_broadcast_packets_received_hi,
888 fstats->total_broadcast_packets_received_lo,
889 qstats->total_broadcast_packets_received_lo);
890 ADD_64(fstats->total_unicast_packets_transmitted_hi,
891 qstats->total_unicast_packets_transmitted_hi,
892 fstats->total_unicast_packets_transmitted_lo,
893 qstats->total_unicast_packets_transmitted_lo);
894 ADD_64(fstats->total_multicast_packets_transmitted_hi,
895 qstats->total_multicast_packets_transmitted_hi,
896 fstats->total_multicast_packets_transmitted_lo,
897 qstats->total_multicast_packets_transmitted_lo);
898 ADD_64(fstats->total_broadcast_packets_transmitted_hi,
899 qstats->total_broadcast_packets_transmitted_hi,
900 fstats->total_broadcast_packets_transmitted_lo,
901 qstats->total_broadcast_packets_transmitted_lo);
902 ADD_64(fstats->valid_bytes_received_hi,
903 qstats->valid_bytes_received_hi,
904 fstats->valid_bytes_received_lo,
905 qstats->valid_bytes_received_lo);
907 ADD_64(estats->error_bytes_received_hi,
908 qstats->error_bytes_received_hi,
909 estats->error_bytes_received_lo,
910 qstats->error_bytes_received_lo);
911 ADD_64(estats->etherstatsoverrsizepkts_hi,
912 qstats->etherstatsoverrsizepkts_hi,
913 estats->etherstatsoverrsizepkts_lo,
914 qstats->etherstatsoverrsizepkts_lo);
915 ADD_64(estats->no_buff_discard_hi, qstats->no_buff_discard_hi,
916 estats->no_buff_discard_lo, qstats->no_buff_discard_lo);
919 ADD_64(fstats->total_bytes_received_hi,
920 estats->rx_stat_ifhcinbadoctets_hi,
921 fstats->total_bytes_received_lo,
922 estats->rx_stat_ifhcinbadoctets_lo);
924 memcpy(estats, &(fstats->total_bytes_received_hi),
925 sizeof(struct host_func_stats) - 2*sizeof(u32));
927 ADD_64(estats->etherstatsoverrsizepkts_hi,
928 estats->rx_stat_dot3statsframestoolong_hi,
929 estats->etherstatsoverrsizepkts_lo,
930 estats->rx_stat_dot3statsframestoolong_lo);
931 ADD_64(estats->error_bytes_received_hi,
932 estats->rx_stat_ifhcinbadoctets_hi,
933 estats->error_bytes_received_lo,
934 estats->rx_stat_ifhcinbadoctets_lo);
936 if (bp->port.pmf) {
937 estats->mac_filter_discard =
938 le32_to_cpu(tport->mac_filter_discard);
939 estats->xxoverflow_discard =
940 le32_to_cpu(tport->xxoverflow_discard);
941 estats->brb_truncate_discard =
942 le32_to_cpu(tport->brb_truncate_discard);
943 estats->mac_discard = le32_to_cpu(tport->mac_discard);
946 fstats->host_func_stats_start = ++fstats->host_func_stats_end;
948 bp->stats_pending = 0;
950 return 0;
953 static void bnx2x_net_stats_update(struct bnx2x *bp)
955 struct bnx2x_eth_stats *estats = &bp->eth_stats;
956 struct net_device_stats *nstats = &bp->dev->stats;
957 int i;
959 nstats->rx_packets =
960 bnx2x_hilo(&estats->total_unicast_packets_received_hi) +
961 bnx2x_hilo(&estats->total_multicast_packets_received_hi) +
962 bnx2x_hilo(&estats->total_broadcast_packets_received_hi);
964 nstats->tx_packets =
965 bnx2x_hilo(&estats->total_unicast_packets_transmitted_hi) +
966 bnx2x_hilo(&estats->total_multicast_packets_transmitted_hi) +
967 bnx2x_hilo(&estats->total_broadcast_packets_transmitted_hi);
969 nstats->rx_bytes = bnx2x_hilo(&estats->total_bytes_received_hi);
971 nstats->tx_bytes = bnx2x_hilo(&estats->total_bytes_transmitted_hi);
973 nstats->rx_dropped = estats->mac_discard;
974 for_each_queue(bp, i)
975 nstats->rx_dropped +=
976 le32_to_cpu(bp->fp[i].old_tclient.checksum_discard);
978 nstats->tx_dropped = 0;
980 nstats->multicast =
981 bnx2x_hilo(&estats->total_multicast_packets_received_hi);
983 nstats->collisions =
984 bnx2x_hilo(&estats->tx_stat_etherstatscollisions_hi);
986 nstats->rx_length_errors =
987 bnx2x_hilo(&estats->rx_stat_etherstatsundersizepkts_hi) +
988 bnx2x_hilo(&estats->etherstatsoverrsizepkts_hi);
989 nstats->rx_over_errors = bnx2x_hilo(&estats->brb_drop_hi) +
990 bnx2x_hilo(&estats->brb_truncate_hi);
991 nstats->rx_crc_errors =
992 bnx2x_hilo(&estats->rx_stat_dot3statsfcserrors_hi);
993 nstats->rx_frame_errors =
994 bnx2x_hilo(&estats->rx_stat_dot3statsalignmenterrors_hi);
995 nstats->rx_fifo_errors = bnx2x_hilo(&estats->no_buff_discard_hi);
996 nstats->rx_missed_errors = estats->xxoverflow_discard;
998 nstats->rx_errors = nstats->rx_length_errors +
999 nstats->rx_over_errors +
1000 nstats->rx_crc_errors +
1001 nstats->rx_frame_errors +
1002 nstats->rx_fifo_errors +
1003 nstats->rx_missed_errors;
1005 nstats->tx_aborted_errors =
1006 bnx2x_hilo(&estats->tx_stat_dot3statslatecollisions_hi) +
1007 bnx2x_hilo(&estats->tx_stat_dot3statsexcessivecollisions_hi);
1008 nstats->tx_carrier_errors =
1009 bnx2x_hilo(&estats->rx_stat_dot3statscarriersenseerrors_hi);
1010 nstats->tx_fifo_errors = 0;
1011 nstats->tx_heartbeat_errors = 0;
1012 nstats->tx_window_errors = 0;
1014 nstats->tx_errors = nstats->tx_aborted_errors +
1015 nstats->tx_carrier_errors +
1016 bnx2x_hilo(&estats->tx_stat_dot3statsinternalmactransmiterrors_hi);
1019 static void bnx2x_drv_stats_update(struct bnx2x *bp)
1021 struct bnx2x_eth_stats *estats = &bp->eth_stats;
1022 int i;
1024 estats->driver_xoff = 0;
1025 estats->rx_err_discard_pkt = 0;
1026 estats->rx_skb_alloc_failed = 0;
1027 estats->hw_csum_err = 0;
1028 for_each_queue(bp, i) {
1029 struct bnx2x_eth_q_stats *qstats = &bp->fp[i].eth_q_stats;
1031 estats->driver_xoff += qstats->driver_xoff;
1032 estats->rx_err_discard_pkt += qstats->rx_err_discard_pkt;
1033 estats->rx_skb_alloc_failed += qstats->rx_skb_alloc_failed;
1034 estats->hw_csum_err += qstats->hw_csum_err;
1038 static void bnx2x_stats_update(struct bnx2x *bp)
1040 u32 *stats_comp = bnx2x_sp(bp, stats_comp);
1042 if (*stats_comp != DMAE_COMP_VAL)
1043 return;
1045 if (bp->port.pmf)
1046 bnx2x_hw_stats_update(bp);
1048 if (bnx2x_storm_stats_update(bp) && (bp->stats_pending++ == 3)) {
1049 BNX2X_ERR("storm stats were not updated for 3 times\n");
1050 bnx2x_panic();
1051 return;
1054 bnx2x_net_stats_update(bp);
1055 bnx2x_drv_stats_update(bp);
1057 if (netif_msg_timer(bp)) {
1058 struct bnx2x_eth_stats *estats = &bp->eth_stats;
1059 int i;
1061 printk(KERN_DEBUG "%s: brb drops %u brb truncate %u\n",
1062 bp->dev->name,
1063 estats->brb_drop_lo, estats->brb_truncate_lo);
1065 for_each_queue(bp, i) {
1066 struct bnx2x_fastpath *fp = &bp->fp[i];
1067 struct bnx2x_eth_q_stats *qstats = &fp->eth_q_stats;
1069 printk(KERN_DEBUG "%s: rx usage(%4u) *rx_cons_sb(%u)"
1070 " rx pkt(%lu) rx calls(%lu %lu)\n",
1071 fp->name, (le16_to_cpu(*fp->rx_cons_sb) -
1072 fp->rx_comp_cons),
1073 le16_to_cpu(*fp->rx_cons_sb),
1074 bnx2x_hilo(&qstats->
1075 total_unicast_packets_received_hi),
1076 fp->rx_calls, fp->rx_pkt);
1079 for_each_queue(bp, i) {
1080 struct bnx2x_fastpath *fp = &bp->fp[i];
1081 struct bnx2x_eth_q_stats *qstats = &fp->eth_q_stats;
1082 struct netdev_queue *txq =
1083 netdev_get_tx_queue(bp->dev, i);
1085 printk(KERN_DEBUG "%s: tx avail(%4u) *tx_cons_sb(%u)"
1086 " tx pkt(%lu) tx calls (%lu)"
1087 " %s (Xoff events %u)\n",
1088 fp->name, bnx2x_tx_avail(fp),
1089 le16_to_cpu(*fp->tx_cons_sb),
1090 bnx2x_hilo(&qstats->
1091 total_unicast_packets_transmitted_hi),
1092 fp->tx_pkt,
1093 (netif_tx_queue_stopped(txq) ? "Xoff" : "Xon"),
1094 qstats->driver_xoff);
1098 bnx2x_hw_stats_post(bp);
1099 bnx2x_storm_stats_post(bp);
1102 static void bnx2x_port_stats_stop(struct bnx2x *bp)
1104 struct dmae_command *dmae;
1105 u32 opcode;
1106 int loader_idx = PMF_DMAE_C(bp);
1107 u32 *stats_comp = bnx2x_sp(bp, stats_comp);
1109 bp->executer_idx = 0;
1111 opcode = (DMAE_CMD_SRC_PCI | DMAE_CMD_DST_GRC |
1112 DMAE_CMD_C_ENABLE |
1113 DMAE_CMD_SRC_RESET | DMAE_CMD_DST_RESET |
1114 #ifdef __BIG_ENDIAN
1115 DMAE_CMD_ENDIANITY_B_DW_SWAP |
1116 #else
1117 DMAE_CMD_ENDIANITY_DW_SWAP |
1118 #endif
1119 (BP_PORT(bp) ? DMAE_CMD_PORT_1 : DMAE_CMD_PORT_0) |
1120 (BP_E1HVN(bp) << DMAE_CMD_E1HVN_SHIFT));
1122 if (bp->port.port_stx) {
1124 dmae = bnx2x_sp(bp, dmae[bp->executer_idx++]);
1125 if (bp->func_stx)
1126 dmae->opcode = (opcode | DMAE_CMD_C_DST_GRC);
1127 else
1128 dmae->opcode = (opcode | DMAE_CMD_C_DST_PCI);
1129 dmae->src_addr_lo = U64_LO(bnx2x_sp_mapping(bp, port_stats));
1130 dmae->src_addr_hi = U64_HI(bnx2x_sp_mapping(bp, port_stats));
1131 dmae->dst_addr_lo = bp->port.port_stx >> 2;
1132 dmae->dst_addr_hi = 0;
1133 dmae->len = sizeof(struct host_port_stats) >> 2;
1134 if (bp->func_stx) {
1135 dmae->comp_addr_lo = dmae_reg_go_c[loader_idx] >> 2;
1136 dmae->comp_addr_hi = 0;
1137 dmae->comp_val = 1;
1138 } else {
1139 dmae->comp_addr_lo =
1140 U64_LO(bnx2x_sp_mapping(bp, stats_comp));
1141 dmae->comp_addr_hi =
1142 U64_HI(bnx2x_sp_mapping(bp, stats_comp));
1143 dmae->comp_val = DMAE_COMP_VAL;
1145 *stats_comp = 0;
1149 if (bp->func_stx) {
1151 dmae = bnx2x_sp(bp, dmae[bp->executer_idx++]);
1152 dmae->opcode = (opcode | DMAE_CMD_C_DST_PCI);
1153 dmae->src_addr_lo = U64_LO(bnx2x_sp_mapping(bp, func_stats));
1154 dmae->src_addr_hi = U64_HI(bnx2x_sp_mapping(bp, func_stats));
1155 dmae->dst_addr_lo = bp->func_stx >> 2;
1156 dmae->dst_addr_hi = 0;
1157 dmae->len = sizeof(struct host_func_stats) >> 2;
1158 dmae->comp_addr_lo = U64_LO(bnx2x_sp_mapping(bp, stats_comp));
1159 dmae->comp_addr_hi = U64_HI(bnx2x_sp_mapping(bp, stats_comp));
1160 dmae->comp_val = DMAE_COMP_VAL;
1162 *stats_comp = 0;
1166 static void bnx2x_stats_stop(struct bnx2x *bp)
1168 int update = 0;
1170 bnx2x_stats_comp(bp);
1172 if (bp->port.pmf)
1173 update = (bnx2x_hw_stats_update(bp) == 0);
1175 update |= (bnx2x_storm_stats_update(bp) == 0);
1177 if (update) {
1178 bnx2x_net_stats_update(bp);
1180 if (bp->port.pmf)
1181 bnx2x_port_stats_stop(bp);
1183 bnx2x_hw_stats_post(bp);
1184 bnx2x_stats_comp(bp);
1188 static void bnx2x_stats_do_nothing(struct bnx2x *bp)
1192 static const struct {
1193 void (*action)(struct bnx2x *bp);
1194 enum bnx2x_stats_state next_state;
1195 } bnx2x_stats_stm[STATS_STATE_MAX][STATS_EVENT_MAX] = {
1196 /* state event */
1198 /* DISABLED PMF */ {bnx2x_stats_pmf_update, STATS_STATE_DISABLED},
1199 /* LINK_UP */ {bnx2x_stats_start, STATS_STATE_ENABLED},
1200 /* UPDATE */ {bnx2x_stats_do_nothing, STATS_STATE_DISABLED},
1201 /* STOP */ {bnx2x_stats_do_nothing, STATS_STATE_DISABLED}
1204 /* ENABLED PMF */ {bnx2x_stats_pmf_start, STATS_STATE_ENABLED},
1205 /* LINK_UP */ {bnx2x_stats_restart, STATS_STATE_ENABLED},
1206 /* UPDATE */ {bnx2x_stats_update, STATS_STATE_ENABLED},
1207 /* STOP */ {bnx2x_stats_stop, STATS_STATE_DISABLED}
1211 void bnx2x_stats_handle(struct bnx2x *bp, enum bnx2x_stats_event event)
1213 enum bnx2x_stats_state state;
1215 if (unlikely(bp->panic))
1216 return;
1218 /* Protect a state change flow */
1219 spin_lock_bh(&bp->stats_lock);
1220 state = bp->stats_state;
1221 bp->stats_state = bnx2x_stats_stm[state][event].next_state;
1222 spin_unlock_bh(&bp->stats_lock);
1224 bnx2x_stats_stm[state][event].action(bp);
1226 if ((event != STATS_EVENT_UPDATE) || netif_msg_timer(bp))
1227 DP(BNX2X_MSG_STATS, "state %d -> event %d -> state %d\n",
1228 state, event, bp->stats_state);
1231 static void bnx2x_port_stats_base_init(struct bnx2x *bp)
1233 struct dmae_command *dmae;
1234 u32 *stats_comp = bnx2x_sp(bp, stats_comp);
1236 /* sanity */
1237 if (!bp->port.pmf || !bp->port.port_stx) {
1238 BNX2X_ERR("BUG!\n");
1239 return;
1242 bp->executer_idx = 0;
1244 dmae = bnx2x_sp(bp, dmae[bp->executer_idx++]);
1245 dmae->opcode = (DMAE_CMD_SRC_PCI | DMAE_CMD_DST_GRC |
1246 DMAE_CMD_C_DST_PCI | DMAE_CMD_C_ENABLE |
1247 DMAE_CMD_SRC_RESET | DMAE_CMD_DST_RESET |
1248 #ifdef __BIG_ENDIAN
1249 DMAE_CMD_ENDIANITY_B_DW_SWAP |
1250 #else
1251 DMAE_CMD_ENDIANITY_DW_SWAP |
1252 #endif
1253 (BP_PORT(bp) ? DMAE_CMD_PORT_1 : DMAE_CMD_PORT_0) |
1254 (BP_E1HVN(bp) << DMAE_CMD_E1HVN_SHIFT));
1255 dmae->src_addr_lo = U64_LO(bnx2x_sp_mapping(bp, port_stats));
1256 dmae->src_addr_hi = U64_HI(bnx2x_sp_mapping(bp, port_stats));
1257 dmae->dst_addr_lo = bp->port.port_stx >> 2;
1258 dmae->dst_addr_hi = 0;
1259 dmae->len = sizeof(struct host_port_stats) >> 2;
1260 dmae->comp_addr_lo = U64_LO(bnx2x_sp_mapping(bp, stats_comp));
1261 dmae->comp_addr_hi = U64_HI(bnx2x_sp_mapping(bp, stats_comp));
1262 dmae->comp_val = DMAE_COMP_VAL;
1264 *stats_comp = 0;
1265 bnx2x_hw_stats_post(bp);
1266 bnx2x_stats_comp(bp);
1269 static void bnx2x_func_stats_base_init(struct bnx2x *bp)
1271 int vn, vn_max = IS_E1HMF(bp) ? E1HVN_MAX : E1VN_MAX;
1272 int port = BP_PORT(bp);
1273 int func;
1274 u32 func_stx;
1276 /* sanity */
1277 if (!bp->port.pmf || !bp->func_stx) {
1278 BNX2X_ERR("BUG!\n");
1279 return;
1282 /* save our func_stx */
1283 func_stx = bp->func_stx;
1285 for (vn = VN_0; vn < vn_max; vn++) {
1286 func = 2*vn + port;
1288 bp->func_stx = SHMEM_RD(bp, func_mb[func].fw_mb_param);
1289 bnx2x_func_stats_init(bp);
1290 bnx2x_hw_stats_post(bp);
1291 bnx2x_stats_comp(bp);
1294 /* restore our func_stx */
1295 bp->func_stx = func_stx;
1298 static void bnx2x_func_stats_base_update(struct bnx2x *bp)
1300 struct dmae_command *dmae = &bp->stats_dmae;
1301 u32 *stats_comp = bnx2x_sp(bp, stats_comp);
1303 /* sanity */
1304 if (!bp->func_stx) {
1305 BNX2X_ERR("BUG!\n");
1306 return;
1309 bp->executer_idx = 0;
1310 memset(dmae, 0, sizeof(struct dmae_command));
1312 dmae->opcode = (DMAE_CMD_SRC_GRC | DMAE_CMD_DST_PCI |
1313 DMAE_CMD_C_DST_PCI | DMAE_CMD_C_ENABLE |
1314 DMAE_CMD_SRC_RESET | DMAE_CMD_DST_RESET |
1315 #ifdef __BIG_ENDIAN
1316 DMAE_CMD_ENDIANITY_B_DW_SWAP |
1317 #else
1318 DMAE_CMD_ENDIANITY_DW_SWAP |
1319 #endif
1320 (BP_PORT(bp) ? DMAE_CMD_PORT_1 : DMAE_CMD_PORT_0) |
1321 (BP_E1HVN(bp) << DMAE_CMD_E1HVN_SHIFT));
1322 dmae->src_addr_lo = bp->func_stx >> 2;
1323 dmae->src_addr_hi = 0;
1324 dmae->dst_addr_lo = U64_LO(bnx2x_sp_mapping(bp, func_stats_base));
1325 dmae->dst_addr_hi = U64_HI(bnx2x_sp_mapping(bp, func_stats_base));
1326 dmae->len = sizeof(struct host_func_stats) >> 2;
1327 dmae->comp_addr_lo = U64_LO(bnx2x_sp_mapping(bp, stats_comp));
1328 dmae->comp_addr_hi = U64_HI(bnx2x_sp_mapping(bp, stats_comp));
1329 dmae->comp_val = DMAE_COMP_VAL;
1331 *stats_comp = 0;
1332 bnx2x_hw_stats_post(bp);
1333 bnx2x_stats_comp(bp);
1336 void bnx2x_stats_init(struct bnx2x *bp)
1338 int port = BP_PORT(bp);
1339 int func = BP_FUNC(bp);
1340 int i;
1342 bp->stats_pending = 0;
1343 bp->executer_idx = 0;
1344 bp->stats_counter = 0;
1346 /* port and func stats for management */
1347 if (!BP_NOMCP(bp)) {
1348 bp->port.port_stx = SHMEM_RD(bp, port_mb[port].port_stx);
1349 bp->func_stx = SHMEM_RD(bp, func_mb[func].fw_mb_param);
1351 } else {
1352 bp->port.port_stx = 0;
1353 bp->func_stx = 0;
1355 DP(BNX2X_MSG_STATS, "port_stx 0x%x func_stx 0x%x\n",
1356 bp->port.port_stx, bp->func_stx);
1358 /* port stats */
1359 memset(&(bp->port.old_nig_stats), 0, sizeof(struct nig_stats));
1360 bp->port.old_nig_stats.brb_discard =
1361 REG_RD(bp, NIG_REG_STAT0_BRB_DISCARD + port*0x38);
1362 bp->port.old_nig_stats.brb_truncate =
1363 REG_RD(bp, NIG_REG_STAT0_BRB_TRUNCATE + port*0x38);
1364 REG_RD_DMAE(bp, NIG_REG_STAT0_EGRESS_MAC_PKT0 + port*0x50,
1365 &(bp->port.old_nig_stats.egress_mac_pkt0_lo), 2);
1366 REG_RD_DMAE(bp, NIG_REG_STAT0_EGRESS_MAC_PKT1 + port*0x50,
1367 &(bp->port.old_nig_stats.egress_mac_pkt1_lo), 2);
1369 /* function stats */
1370 for_each_queue(bp, i) {
1371 struct bnx2x_fastpath *fp = &bp->fp[i];
1373 memset(&fp->old_tclient, 0,
1374 sizeof(struct tstorm_per_client_stats));
1375 memset(&fp->old_uclient, 0,
1376 sizeof(struct ustorm_per_client_stats));
1377 memset(&fp->old_xclient, 0,
1378 sizeof(struct xstorm_per_client_stats));
1379 memset(&fp->eth_q_stats, 0, sizeof(struct bnx2x_eth_q_stats));
1382 memset(&bp->dev->stats, 0, sizeof(struct net_device_stats));
1383 memset(&bp->eth_stats, 0, sizeof(struct bnx2x_eth_stats));
1385 bp->stats_state = STATS_STATE_DISABLED;
1387 if (bp->port.pmf) {
1388 if (bp->port.port_stx)
1389 bnx2x_port_stats_base_init(bp);
1391 if (bp->func_stx)
1392 bnx2x_func_stats_base_init(bp);
1394 } else if (bp->func_stx)
1395 bnx2x_func_stats_base_update(bp);