aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/bnx2x_main.c
diff options
context:
space:
mode:
authorYitchak Gertner <gertner@broadcom.com>2008-06-23 23:33:36 -0400
committerDavid S. Miller <davem@davemloft.net>2008-06-23 23:33:36 -0400
commitbb2a0f7ae477740d947b442f640a5d10b51025c0 (patch)
treef12e40c057551dc645bfefd818523fec34b578db /drivers/net/bnx2x_main.c
parent34f80b04f325078ff21123579343d99756ad8d0e (diff)
bnx2x: New statistics code
To avoid race conditions with link up/down and driver up/down - the statistics handling was re-written in a form of state machine. Also supporting statistics for 57711 Signed-off-by: Yitchak Gertner <gertner@broadcom.com> Signed-off-by: Eilon Greenstein <eilong@broadcom.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/bnx2x_main.c')
-rw-r--r--drivers/net/bnx2x_main.c1455
1 files changed, 918 insertions, 537 deletions
diff --git a/drivers/net/bnx2x_main.c b/drivers/net/bnx2x_main.c
index 90b54e4c5c3b..ccfe33c110b4 100644
--- a/drivers/net/bnx2x_main.c
+++ b/drivers/net/bnx2x_main.c
@@ -568,8 +568,8 @@ static void bnx2x_panic_dump(struct bnx2x *bp)
568 bnx2x_mc_assert(bp); 568 bnx2x_mc_assert(bp);
569 BNX2X_ERR("end crash dump -----------------\n"); 569 BNX2X_ERR("end crash dump -----------------\n");
570 570
571 bp->stats_state = STATS_STATE_DISABLE; 571 bp->stats_state = STATS_STATE_DISABLED;
572 DP(BNX2X_MSG_STATS, "stats_state - DISABLE\n"); 572 DP(BNX2X_MSG_STATS, "stats_state - DISABLED\n");
573} 573}
574 574
575static void bnx2x_int_enable(struct bnx2x *bp) 575static void bnx2x_int_enable(struct bnx2x *bp)
@@ -948,6 +948,7 @@ static void bnx2x_sp_event(struct bnx2x_fastpath *fp,
948 case (RAMROD_CMD_ID_ETH_SET_MAC | BNX2X_STATE_OPEN): 948 case (RAMROD_CMD_ID_ETH_SET_MAC | BNX2X_STATE_OPEN):
949 case (RAMROD_CMD_ID_ETH_SET_MAC | BNX2X_STATE_DIAG): 949 case (RAMROD_CMD_ID_ETH_SET_MAC | BNX2X_STATE_DIAG):
950 DP(NETIF_MSG_IFUP, "got set mac ramrod\n"); 950 DP(NETIF_MSG_IFUP, "got set mac ramrod\n");
951 bp->set_mac_pending = 0;
951 break; 952 break;
952 953
953 case (RAMROD_CMD_ID_ETH_SET_MAC | BNX2X_STATE_CLOSING_WAIT4_HALT): 954 case (RAMROD_CMD_ID_ETH_SET_MAC | BNX2X_STATE_CLOSING_WAIT4_HALT):
@@ -1279,6 +1280,7 @@ static irqreturn_t bnx2x_interrupt(int irq, void *dev_instance)
1279 1280
1280/* end of fast path */ 1281/* end of fast path */
1281 1282
1283static void bnx2x_stats_handle(struct bnx2x *bp, enum bnx2x_stats_event event);
1282 1284
1283/* Link */ 1285/* Link */
1284 1286
@@ -1787,10 +1789,28 @@ static void bnx2x_link_attn(struct bnx2x *bp)
1787{ 1789{
1788 int vn; 1790 int vn;
1789 1791
1792 /* Make sure that we are synced with the current statistics */
1793 bnx2x_stats_handle(bp, STATS_EVENT_STOP);
1794
1790 bnx2x_phy_hw_lock(bp); 1795 bnx2x_phy_hw_lock(bp);
1791 bnx2x_link_update(&bp->link_params, &bp->link_vars); 1796 bnx2x_link_update(&bp->link_params, &bp->link_vars);
1792 bnx2x_phy_hw_unlock(bp); 1797 bnx2x_phy_hw_unlock(bp);
1793 1798
1799 if (bp->link_vars.link_up) {
1800
1801 if (bp->link_vars.mac_type == MAC_TYPE_BMAC) {
1802 struct host_port_stats *pstats;
1803
1804 pstats = bnx2x_sp(bp, port_stats);
1805 /* reset old bmac stats */
1806 memset(&(pstats->mac_stx[0]), 0,
1807 sizeof(struct mac_stx));
1808 }
1809 if ((bp->state == BNX2X_STATE_OPEN) ||
1810 (bp->state == BNX2X_STATE_DISABLED))
1811 bnx2x_stats_handle(bp, STATS_EVENT_LINK_UP);
1812 }
1813
1794 /* indicate link status */ 1814 /* indicate link status */
1795 bnx2x_link_report(bp); 1815 bnx2x_link_report(bp);
1796 1816
@@ -1835,6 +1855,11 @@ static void bnx2x__link_status_update(struct bnx2x *bp)
1835 1855
1836 bnx2x_link_status_update(&bp->link_params, &bp->link_vars); 1856 bnx2x_link_status_update(&bp->link_params, &bp->link_vars);
1837 1857
1858 if (bp->link_vars.link_up)
1859 bnx2x_stats_handle(bp, STATS_EVENT_LINK_UP);
1860 else
1861 bnx2x_stats_handle(bp, STATS_EVENT_STOP);
1862
1838 /* indicate link status */ 1863 /* indicate link status */
1839 bnx2x_link_report(bp); 1864 bnx2x_link_report(bp);
1840} 1865}
@@ -1851,6 +1876,8 @@ static void bnx2x_pmf_update(struct bnx2x *bp)
1851 val = (0xff0f | (1 << (BP_E1HVN(bp) + 4))); 1876 val = (0xff0f | (1 << (BP_E1HVN(bp) + 4)));
1852 REG_WR(bp, HC_REG_TRAILING_EDGE_0 + port*8, val); 1877 REG_WR(bp, HC_REG_TRAILING_EDGE_0 + port*8, val);
1853 REG_WR(bp, HC_REG_LEADING_EDGE_0 + port*8, val); 1878 REG_WR(bp, HC_REG_LEADING_EDGE_0 + port*8, val);
1879
1880 bnx2x_stats_handle(bp, STATS_EVENT_PMF);
1854} 1881}
1855 1882
1856/* end of Link */ 1883/* end of Link */
@@ -2376,6 +2403,10 @@ static void bnx2x_sp_task(struct work_struct *work)
2376 if (status & 0x1) 2403 if (status & 0x1)
2377 bnx2x_attn_int(bp); 2404 bnx2x_attn_int(bp);
2378 2405
2406 /* CStorm events: query_stats, port delete ramrod */
2407 if (status & 0x2)
2408 bp->stats_pending = 0;
2409
2379 bnx2x_ack_sb(bp, DEF_SB_ID, ATTENTION_ID, bp->def_att_idx, 2410 bnx2x_ack_sb(bp, DEF_SB_ID, ATTENTION_ID, bp->def_att_idx,
2380 IGU_INT_NOP, 1); 2411 IGU_INT_NOP, 1);
2381 bnx2x_ack_sb(bp, DEF_SB_ID, USTORM_ID, le16_to_cpu(bp->def_u_idx), 2412 bnx2x_ack_sb(bp, DEF_SB_ID, USTORM_ID, le16_to_cpu(bp->def_u_idx),
@@ -2420,12 +2451,6 @@ static irqreturn_t bnx2x_msix_sp_int(int irq, void *dev_instance)
2420* Macros 2451* Macros
2421****************************************************************************/ 2452****************************************************************************/
2422 2453
2423#define UPDATE_STAT(s, t) \
2424 do { \
2425 estats->t += new->s - old->s; \
2426 old->s = new->s; \
2427 } while (0)
2428
2429/* sum[hi:lo] += add[hi:lo] */ 2454/* sum[hi:lo] += add[hi:lo] */
2430#define ADD_64(s_hi, a_hi, s_lo, a_lo) \ 2455#define ADD_64(s_hi, a_hi, s_lo, a_lo) \
2431 do { \ 2456 do { \
@@ -2436,40 +2461,47 @@ static irqreturn_t bnx2x_msix_sp_int(int irq, void *dev_instance)
2436/* difference = minuend - subtrahend */ 2461/* difference = minuend - subtrahend */
2437#define DIFF_64(d_hi, m_hi, s_hi, d_lo, m_lo, s_lo) \ 2462#define DIFF_64(d_hi, m_hi, s_hi, d_lo, m_lo, s_lo) \
2438 do { \ 2463 do { \
2439 if (m_lo < s_lo) { /* underflow */ \ 2464 if (m_lo < s_lo) { \
2465 /* underflow */ \
2440 d_hi = m_hi - s_hi; \ 2466 d_hi = m_hi - s_hi; \
2441 if (d_hi > 0) { /* we can 'loan' 1 */ \ 2467 if (d_hi > 0) { \
2468 /* we can 'loan' 1 */ \
2442 d_hi--; \ 2469 d_hi--; \
2443 d_lo = m_lo + (UINT_MAX - s_lo) + 1; \ 2470 d_lo = m_lo + (UINT_MAX - s_lo) + 1; \
2444 } else { /* m_hi <= s_hi */ \ 2471 } else { \
2472 /* m_hi <= s_hi */ \
2445 d_hi = 0; \ 2473 d_hi = 0; \
2446 d_lo = 0; \ 2474 d_lo = 0; \
2447 } \ 2475 } \
2448 } else { /* m_lo >= s_lo */ \ 2476 } else { \
2477 /* m_lo >= s_lo */ \
2449 if (m_hi < s_hi) { \ 2478 if (m_hi < s_hi) { \
2450 d_hi = 0; \ 2479 d_hi = 0; \
2451 d_lo = 0; \ 2480 d_lo = 0; \
2452 } else { /* m_hi >= s_hi */ \ 2481 } else { \
2453 d_hi = m_hi - s_hi; \ 2482 /* m_hi >= s_hi */ \
2454 d_lo = m_lo - s_lo; \ 2483 d_hi = m_hi - s_hi; \
2484 d_lo = m_lo - s_lo; \
2455 } \ 2485 } \
2456 } \ 2486 } \
2457 } while (0) 2487 } while (0)
2458 2488
2459/* minuend -= subtrahend */ 2489#define UPDATE_STAT64(s, t) \
2460#define SUB_64(m_hi, s_hi, m_lo, s_lo) \
2461 do { \ 2490 do { \
2462 DIFF_64(m_hi, m_hi, s_hi, m_lo, m_lo, s_lo); \ 2491 DIFF_64(diff.hi, new->s##_hi, pstats->mac_stx[0].t##_hi, \
2492 diff.lo, new->s##_lo, pstats->mac_stx[0].t##_lo); \
2493 pstats->mac_stx[0].t##_hi = new->s##_hi; \
2494 pstats->mac_stx[0].t##_lo = new->s##_lo; \
2495 ADD_64(pstats->mac_stx[1].t##_hi, diff.hi, \
2496 pstats->mac_stx[1].t##_lo, diff.lo); \
2463 } while (0) 2497 } while (0)
2464 2498
2465#define UPDATE_STAT64(s_hi, t_hi, s_lo, t_lo) \ 2499#define UPDATE_STAT64_NIG(s, t) \
2466 do { \ 2500 do { \
2467 DIFF_64(diff.hi, new->s_hi, old->s_hi, \ 2501 DIFF_64(diff.hi, new->s##_hi, old->s##_hi, \
2468 diff.lo, new->s_lo, old->s_lo); \ 2502 diff.lo, new->s##_lo, old->s##_lo); \
2469 old->s_hi = new->s_hi; \ 2503 ADD_64(estats->t##_hi, diff.hi, \
2470 old->s_lo = new->s_lo; \ 2504 estats->t##_lo, diff.lo); \
2471 ADD_64(estats->t_hi, diff.hi, \
2472 estats->t_lo, diff.lo); \
2473 } while (0) 2505 } while (0)
2474 2506
2475/* sum[hi:lo] += add */ 2507/* sum[hi:lo] += add */
@@ -2479,16 +2511,25 @@ static irqreturn_t bnx2x_msix_sp_int(int irq, void *dev_instance)
2479 s_hi += (s_lo < a) ? 1 : 0; \ 2511 s_hi += (s_lo < a) ? 1 : 0; \
2480 } while (0) 2512 } while (0)
2481 2513
2482#define UPDATE_EXTEND_STAT(s, t_hi, t_lo) \ 2514#define UPDATE_EXTEND_STAT(s) \
2483 do { \ 2515 do { \
2484 ADD_EXTEND_64(estats->t_hi, estats->t_lo, new->s); \ 2516 ADD_EXTEND_64(pstats->mac_stx[1].s##_hi, \
2517 pstats->mac_stx[1].s##_lo, \
2518 new->s); \
2485 } while (0) 2519 } while (0)
2486 2520
2487#define UPDATE_EXTEND_TSTAT(s, t_hi, t_lo) \ 2521#define UPDATE_EXTEND_TSTAT(s, t) \
2488 do { \ 2522 do { \
2489 diff = le32_to_cpu(tclient->s) - old_tclient->s; \ 2523 diff = le32_to_cpu(tclient->s) - old_tclient->s; \
2490 old_tclient->s = le32_to_cpu(tclient->s); \ 2524 old_tclient->s = le32_to_cpu(tclient->s); \
2491 ADD_EXTEND_64(estats->t_hi, estats->t_lo, diff); \ 2525 ADD_EXTEND_64(fstats->t##_hi, fstats->t##_lo, diff); \
2526 } while (0)
2527
2528#define UPDATE_EXTEND_XSTAT(s, t) \
2529 do { \
2530 diff = le32_to_cpu(xclient->s) - old_xclient->s; \
2531 old_xclient->s = le32_to_cpu(xclient->s); \
2532 ADD_EXTEND_64(fstats->t##_hi, fstats->t##_lo, diff); \
2492 } while (0) 2533 } while (0)
2493 2534
2494/* 2535/*
@@ -2511,55 +2552,272 @@ static inline long bnx2x_hilo(u32 *hiref)
2511 * Init service functions 2552 * Init service functions
2512 */ 2553 */
2513 2554
2514static void bnx2x_init_mac_stats(struct bnx2x *bp) 2555static void bnx2x_storm_stats_init(struct bnx2x *bp)
2556{
2557 int func = BP_FUNC(bp);
2558
2559 REG_WR(bp, BAR_XSTRORM_INTMEM + XSTORM_STATS_FLAGS_OFFSET(func), 1);
2560 REG_WR(bp, BAR_XSTRORM_INTMEM +
2561 XSTORM_STATS_FLAGS_OFFSET(func) + 4, 0);
2562
2563 REG_WR(bp, BAR_TSTRORM_INTMEM + TSTORM_STATS_FLAGS_OFFSET(func), 1);
2564 REG_WR(bp, BAR_TSTRORM_INTMEM +
2565 TSTORM_STATS_FLAGS_OFFSET(func) + 4, 0);
2566
2567 REG_WR(bp, BAR_CSTRORM_INTMEM + CSTORM_STATS_FLAGS_OFFSET(func), 0);
2568 REG_WR(bp, BAR_CSTRORM_INTMEM +
2569 CSTORM_STATS_FLAGS_OFFSET(func) + 4, 0);
2570
2571 REG_WR(bp, BAR_XSTRORM_INTMEM +
2572 XSTORM_ETH_STATS_QUERY_ADDR_OFFSET(func),
2573 U64_LO(bnx2x_sp_mapping(bp, fw_stats)));
2574 REG_WR(bp, BAR_XSTRORM_INTMEM +
2575 XSTORM_ETH_STATS_QUERY_ADDR_OFFSET(func) + 4,
2576 U64_HI(bnx2x_sp_mapping(bp, fw_stats)));
2577
2578 REG_WR(bp, BAR_TSTRORM_INTMEM +
2579 TSTORM_ETH_STATS_QUERY_ADDR_OFFSET(func),
2580 U64_LO(bnx2x_sp_mapping(bp, fw_stats)));
2581 REG_WR(bp, BAR_TSTRORM_INTMEM +
2582 TSTORM_ETH_STATS_QUERY_ADDR_OFFSET(func) + 4,
2583 U64_HI(bnx2x_sp_mapping(bp, fw_stats)));
2584}
2585
2586static void bnx2x_storm_stats_post(struct bnx2x *bp)
2587{
2588 if (!bp->stats_pending) {
2589 struct eth_query_ramrod_data ramrod_data = {0};
2590 int rc;
2591
2592 ramrod_data.drv_counter = bp->stats_counter++;
2593 ramrod_data.collect_port_1b = bp->port.pmf ? 1 : 0;
2594 ramrod_data.ctr_id_vector = (1 << BP_CL_ID(bp));
2595
2596 rc = bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_STAT_QUERY, 0,
2597 ((u32 *)&ramrod_data)[1],
2598 ((u32 *)&ramrod_data)[0], 0);
2599 if (rc == 0) {
2600 /* stats ramrod has it's own slot on the spq */
2601 bp->spq_left++;
2602 bp->stats_pending = 1;
2603 }
2604 }
2605}
2606
2607static void bnx2x_stats_init(struct bnx2x *bp)
2608{
2609 int port = BP_PORT(bp);
2610
2611 bp->executer_idx = 0;
2612 bp->stats_counter = 0;
2613
2614 /* port stats */
2615 if (!BP_NOMCP(bp))
2616 bp->port.port_stx = SHMEM_RD(bp, port_mb[port].port_stx);
2617 else
2618 bp->port.port_stx = 0;
2619 DP(BNX2X_MSG_STATS, "port_stx 0x%x\n", bp->port.port_stx);
2620
2621 memset(&(bp->port.old_nig_stats), 0, sizeof(struct nig_stats));
2622 bp->port.old_nig_stats.brb_discard =
2623 REG_RD(bp, NIG_REG_STAT0_BRB_DISCARD + port*0x38);
2624 REG_RD_DMAE(bp, NIG_REG_STAT0_EGRESS_MAC_PKT0 + port*0x50,
2625 &(bp->port.old_nig_stats.egress_mac_pkt0_lo), 2);
2626 REG_RD_DMAE(bp, NIG_REG_STAT0_EGRESS_MAC_PKT1 + port*0x50,
2627 &(bp->port.old_nig_stats.egress_mac_pkt1_lo), 2);
2628
2629 /* function stats */
2630 memset(&bp->dev->stats, 0, sizeof(struct net_device_stats));
2631 memset(&bp->old_tclient, 0, sizeof(struct tstorm_per_client_stats));
2632 memset(&bp->old_xclient, 0, sizeof(struct xstorm_per_client_stats));
2633 memset(&bp->eth_stats, 0, sizeof(struct bnx2x_eth_stats));
2634
2635 bp->stats_state = STATS_STATE_DISABLED;
2636 if (IS_E1HMF(bp) && bp->port.pmf && bp->port.port_stx)
2637 bnx2x_stats_handle(bp, STATS_EVENT_PMF);
2638}
2639
2640static void bnx2x_hw_stats_post(struct bnx2x *bp)
2641{
2642 struct dmae_command *dmae = &bp->stats_dmae;
2643 u32 *stats_comp = bnx2x_sp(bp, stats_comp);
2644
2645 *stats_comp = DMAE_COMP_VAL;
2646
2647 /* loader */
2648 if (bp->executer_idx) {
2649 int loader_idx = PMF_DMAE_C(bp);
2650
2651 memset(dmae, 0, sizeof(struct dmae_command));
2652
2653 dmae->opcode = (DMAE_CMD_SRC_PCI | DMAE_CMD_DST_GRC |
2654 DMAE_CMD_C_DST_GRC | DMAE_CMD_C_ENABLE |
2655 DMAE_CMD_DST_RESET |
2656#ifdef __BIG_ENDIAN
2657 DMAE_CMD_ENDIANITY_B_DW_SWAP |
2658#else
2659 DMAE_CMD_ENDIANITY_DW_SWAP |
2660#endif
2661 (BP_PORT(bp) ? DMAE_CMD_PORT_1 :
2662 DMAE_CMD_PORT_0) |
2663 (BP_E1HVN(bp) << DMAE_CMD_E1HVN_SHIFT));
2664 dmae->src_addr_lo = U64_LO(bnx2x_sp_mapping(bp, dmae[0]));
2665 dmae->src_addr_hi = U64_HI(bnx2x_sp_mapping(bp, dmae[0]));
2666 dmae->dst_addr_lo = (DMAE_REG_CMD_MEM +
2667 sizeof(struct dmae_command) *
2668 (loader_idx + 1)) >> 2;
2669 dmae->dst_addr_hi = 0;
2670 dmae->len = sizeof(struct dmae_command) >> 2;
2671 if (CHIP_IS_E1(bp))
2672 dmae->len--;
2673 dmae->comp_addr_lo = dmae_reg_go_c[loader_idx + 1] >> 2;
2674 dmae->comp_addr_hi = 0;
2675 dmae->comp_val = 1;
2676
2677 *stats_comp = 0;
2678 bnx2x_post_dmae(bp, dmae, loader_idx);
2679
2680 } else if (bp->func_stx) {
2681 *stats_comp = 0;
2682 bnx2x_post_dmae(bp, dmae, INIT_DMAE_C(bp));
2683 }
2684}
2685
2686static int bnx2x_stats_comp(struct bnx2x *bp)
2687{
2688 u32 *stats_comp = bnx2x_sp(bp, stats_comp);
2689 int cnt = 10;
2690
2691 might_sleep();
2692 while (*stats_comp != DMAE_COMP_VAL) {
2693 msleep(1);
2694 if (!cnt) {
2695 BNX2X_ERR("timeout waiting for stats finished\n");
2696 break;
2697 }
2698 cnt--;
2699 }
2700 return 1;
2701}
2702
2703/*
2704 * Statistics service functions
2705 */
2706
2707static void bnx2x_stats_pmf_update(struct bnx2x *bp)
2708{
2709 struct dmae_command *dmae;
2710 u32 opcode;
2711 int loader_idx = PMF_DMAE_C(bp);
2712 u32 *stats_comp = bnx2x_sp(bp, stats_comp);
2713
2714 /* sanity */
2715 if (!IS_E1HMF(bp) || !bp->port.pmf || !bp->port.port_stx) {
2716 BNX2X_ERR("BUG!\n");
2717 return;
2718 }
2719
2720 bp->executer_idx = 0;
2721
2722 opcode = (DMAE_CMD_SRC_GRC | DMAE_CMD_DST_PCI |
2723 DMAE_CMD_C_ENABLE |
2724 DMAE_CMD_SRC_RESET | DMAE_CMD_DST_RESET |
2725#ifdef __BIG_ENDIAN
2726 DMAE_CMD_ENDIANITY_B_DW_SWAP |
2727#else
2728 DMAE_CMD_ENDIANITY_DW_SWAP |
2729#endif
2730 (BP_PORT(bp) ? DMAE_CMD_PORT_1 : DMAE_CMD_PORT_0) |
2731 (BP_E1HVN(bp) << DMAE_CMD_E1HVN_SHIFT));
2732
2733 dmae = bnx2x_sp(bp, dmae[bp->executer_idx++]);
2734 dmae->opcode = (opcode | DMAE_CMD_C_DST_GRC);
2735 dmae->src_addr_lo = bp->port.port_stx >> 2;
2736 dmae->src_addr_hi = 0;
2737 dmae->dst_addr_lo = U64_LO(bnx2x_sp_mapping(bp, port_stats));
2738 dmae->dst_addr_hi = U64_HI(bnx2x_sp_mapping(bp, port_stats));
2739 dmae->len = DMAE_LEN32_RD_MAX;
2740 dmae->comp_addr_lo = dmae_reg_go_c[loader_idx] >> 2;
2741 dmae->comp_addr_hi = 0;
2742 dmae->comp_val = 1;
2743
2744 dmae = bnx2x_sp(bp, dmae[bp->executer_idx++]);
2745 dmae->opcode = (opcode | DMAE_CMD_C_DST_PCI);
2746 dmae->src_addr_lo = (bp->port.port_stx >> 2) + DMAE_LEN32_RD_MAX;
2747 dmae->src_addr_hi = 0;
2748 dmae->dst_addr_lo = U64_LO(bnx2x_sp_mapping(bp, port_stats)
2749 + DMAE_LEN32_RD_MAX * 4);
2750 dmae->dst_addr_hi = U64_HI(bnx2x_sp_mapping(bp, port_stats)
2751 + DMAE_LEN32_RD_MAX * 4);
2752 dmae->len = (sizeof(struct host_port_stats) >> 2) - DMAE_LEN32_RD_MAX;
2753 dmae->comp_addr_lo = U64_LO(bnx2x_sp_mapping(bp, stats_comp));
2754 dmae->comp_addr_hi = U64_HI(bnx2x_sp_mapping(bp, stats_comp));
2755 dmae->comp_val = DMAE_COMP_VAL;
2756
2757 *stats_comp = 0;
2758 bnx2x_hw_stats_post(bp);
2759 bnx2x_stats_comp(bp);
2760}
2761
2762static void bnx2x_port_stats_init(struct bnx2x *bp)
2515{ 2763{
2516 struct dmae_command *dmae; 2764 struct dmae_command *dmae;
2517 int port = BP_PORT(bp); 2765 int port = BP_PORT(bp);
2518 int loader_idx = port * 8; 2766 int vn = BP_E1HVN(bp);
2519 u32 opcode; 2767 u32 opcode;
2768 int loader_idx = PMF_DMAE_C(bp);
2520 u32 mac_addr; 2769 u32 mac_addr;
2770 u32 *stats_comp = bnx2x_sp(bp, stats_comp);
2771
2772 /* sanity */
2773 if (!bp->link_vars.link_up || !bp->port.pmf) {
2774 BNX2X_ERR("BUG!\n");
2775 return;
2776 }
2521 2777
2522 bp->executer_idx = 0; 2778 bp->executer_idx = 0;
2523 if (bp->func_stx) { 2779
2524 /* MCP */ 2780 /* MCP */
2525 opcode = (DMAE_CMD_SRC_PCI | DMAE_CMD_DST_GRC | 2781 opcode = (DMAE_CMD_SRC_PCI | DMAE_CMD_DST_GRC |
2526 DMAE_CMD_SRC_RESET | DMAE_CMD_DST_RESET | 2782 DMAE_CMD_C_DST_GRC | DMAE_CMD_C_ENABLE |
2783 DMAE_CMD_SRC_RESET | DMAE_CMD_DST_RESET |
2527#ifdef __BIG_ENDIAN 2784#ifdef __BIG_ENDIAN
2528 DMAE_CMD_ENDIANITY_B_DW_SWAP | 2785 DMAE_CMD_ENDIANITY_B_DW_SWAP |
2529#else 2786#else
2530 DMAE_CMD_ENDIANITY_DW_SWAP | 2787 DMAE_CMD_ENDIANITY_DW_SWAP |
2531#endif 2788#endif
2532 (port ? DMAE_CMD_PORT_1 : DMAE_CMD_PORT_0)); 2789 (port ? DMAE_CMD_PORT_1 : DMAE_CMD_PORT_0) |
2790 (vn << DMAE_CMD_E1HVN_SHIFT));
2533 2791
2534 if (bp->link_vars.link_up) 2792 if (bp->port.port_stx) {
2535 opcode |= (DMAE_CMD_C_DST_GRC | DMAE_CMD_C_ENABLE);
2536 2793
2537 dmae = bnx2x_sp(bp, dmae[bp->executer_idx++]); 2794 dmae = bnx2x_sp(bp, dmae[bp->executer_idx++]);
2538 dmae->opcode = opcode; 2795 dmae->opcode = opcode;
2539 dmae->src_addr_lo = U64_LO(bnx2x_sp_mapping(bp, eth_stats) + 2796 dmae->src_addr_lo = U64_LO(bnx2x_sp_mapping(bp, port_stats));
2540 sizeof(u32)); 2797 dmae->src_addr_hi = U64_HI(bnx2x_sp_mapping(bp, port_stats));
2541 dmae->src_addr_hi = U64_HI(bnx2x_sp_mapping(bp, eth_stats) + 2798 dmae->dst_addr_lo = bp->port.port_stx >> 2;
2542 sizeof(u32));
2543 dmae->dst_addr_lo = bp->func_stx >> 2;
2544 dmae->dst_addr_hi = 0; 2799 dmae->dst_addr_hi = 0;
2545 dmae->len = (offsetof(struct bnx2x_eth_stats, mac_stx_end) - 2800 dmae->len = sizeof(struct host_port_stats) >> 2;
2546 sizeof(u32)) >> 2; 2801 dmae->comp_addr_lo = dmae_reg_go_c[loader_idx] >> 2;
2547 if (bp->link_vars.link_up) { 2802 dmae->comp_addr_hi = 0;
2548 dmae->comp_addr_lo = dmae_reg_go_c[loader_idx] >> 2; 2803 dmae->comp_val = 1;
2549 dmae->comp_addr_hi = 0;
2550 dmae->comp_val = 1;
2551 } else {
2552 dmae->comp_addr_lo = 0;
2553 dmae->comp_addr_hi = 0;
2554 dmae->comp_val = 0;
2555 }
2556 } 2804 }
2557 2805
2558 if (!bp->link_vars.link_up) { 2806 if (bp->func_stx) {
2559 /* no need to collect statistics in link down */ 2807
2560 return; 2808 dmae = bnx2x_sp(bp, dmae[bp->executer_idx++]);
2809 dmae->opcode = opcode;
2810 dmae->src_addr_lo = U64_LO(bnx2x_sp_mapping(bp, func_stats));
2811 dmae->src_addr_hi = U64_HI(bnx2x_sp_mapping(bp, func_stats));
2812 dmae->dst_addr_lo = bp->func_stx >> 2;
2813 dmae->dst_addr_hi = 0;
2814 dmae->len = sizeof(struct host_func_stats) >> 2;
2815 dmae->comp_addr_lo = dmae_reg_go_c[loader_idx] >> 2;
2816 dmae->comp_addr_hi = 0;
2817 dmae->comp_val = 1;
2561 } 2818 }
2562 2819
2820 /* MAC */
2563 opcode = (DMAE_CMD_SRC_GRC | DMAE_CMD_DST_PCI | 2821 opcode = (DMAE_CMD_SRC_GRC | DMAE_CMD_DST_PCI |
2564 DMAE_CMD_C_DST_GRC | DMAE_CMD_C_ENABLE | 2822 DMAE_CMD_C_DST_GRC | DMAE_CMD_C_ENABLE |
2565 DMAE_CMD_SRC_RESET | DMAE_CMD_DST_RESET | 2823 DMAE_CMD_SRC_RESET | DMAE_CMD_DST_RESET |
@@ -2568,7 +2826,8 @@ static void bnx2x_init_mac_stats(struct bnx2x *bp)
2568#else 2826#else
2569 DMAE_CMD_ENDIANITY_DW_SWAP | 2827 DMAE_CMD_ENDIANITY_DW_SWAP |
2570#endif 2828#endif
2571 (port ? DMAE_CMD_PORT_1 : DMAE_CMD_PORT_0)); 2829 (port ? DMAE_CMD_PORT_1 : DMAE_CMD_PORT_0) |
2830 (vn << DMAE_CMD_E1HVN_SHIFT));
2572 2831
2573 if (bp->link_vars.mac_type == MAC_TYPE_BMAC) { 2832 if (bp->link_vars.mac_type == MAC_TYPE_BMAC) {
2574 2833
@@ -2598,9 +2857,9 @@ static void bnx2x_init_mac_stats(struct bnx2x *bp)
2598 BIGMAC_REGISTER_RX_STAT_GR64) >> 2; 2857 BIGMAC_REGISTER_RX_STAT_GR64) >> 2;
2599 dmae->src_addr_hi = 0; 2858 dmae->src_addr_hi = 0;
2600 dmae->dst_addr_lo = U64_LO(bnx2x_sp_mapping(bp, mac_stats) + 2859 dmae->dst_addr_lo = U64_LO(bnx2x_sp_mapping(bp, mac_stats) +
2601 offsetof(struct bmac_stats, rx_gr64)); 2860 offsetof(struct bmac_stats, rx_stat_gr64_lo));
2602 dmae->dst_addr_hi = U64_HI(bnx2x_sp_mapping(bp, mac_stats) + 2861 dmae->dst_addr_hi = U64_HI(bnx2x_sp_mapping(bp, mac_stats) +
2603 offsetof(struct bmac_stats, rx_gr64)); 2862 offsetof(struct bmac_stats, rx_stat_gr64_lo));
2604 dmae->len = (8 + BIGMAC_REGISTER_RX_STAT_GRIPJ - 2863 dmae->len = (8 + BIGMAC_REGISTER_RX_STAT_GRIPJ -
2605 BIGMAC_REGISTER_RX_STAT_GR64) >> 2; 2864 BIGMAC_REGISTER_RX_STAT_GR64) >> 2;
2606 dmae->comp_addr_lo = dmae_reg_go_c[loader_idx] >> 2; 2865 dmae->comp_addr_lo = dmae_reg_go_c[loader_idx] >> 2;
@@ -2631,11 +2890,9 @@ static void bnx2x_init_mac_stats(struct bnx2x *bp)
2631 EMAC_REG_EMAC_RX_STAT_AC_28) >> 2; 2890 EMAC_REG_EMAC_RX_STAT_AC_28) >> 2;
2632 dmae->src_addr_hi = 0; 2891 dmae->src_addr_hi = 0;
2633 dmae->dst_addr_lo = U64_LO(bnx2x_sp_mapping(bp, mac_stats) + 2892 dmae->dst_addr_lo = U64_LO(bnx2x_sp_mapping(bp, mac_stats) +
2634 offsetof(struct emac_stats, 2893 offsetof(struct emac_stats, rx_stat_falsecarriererrors));
2635 rx_falsecarriererrors));
2636 dmae->dst_addr_hi = U64_HI(bnx2x_sp_mapping(bp, mac_stats) + 2894 dmae->dst_addr_hi = U64_HI(bnx2x_sp_mapping(bp, mac_stats) +
2637 offsetof(struct emac_stats, 2895 offsetof(struct emac_stats, rx_stat_falsecarriererrors));
2638 rx_falsecarriererrors));
2639 dmae->len = 1; 2896 dmae->len = 1;
2640 dmae->comp_addr_lo = dmae_reg_go_c[loader_idx] >> 2; 2897 dmae->comp_addr_lo = dmae_reg_go_c[loader_idx] >> 2;
2641 dmae->comp_addr_hi = 0; 2898 dmae->comp_addr_hi = 0;
@@ -2648,11 +2905,9 @@ static void bnx2x_init_mac_stats(struct bnx2x *bp)
2648 EMAC_REG_EMAC_TX_STAT_AC) >> 2; 2905 EMAC_REG_EMAC_TX_STAT_AC) >> 2;
2649 dmae->src_addr_hi = 0; 2906 dmae->src_addr_hi = 0;
2650 dmae->dst_addr_lo = U64_LO(bnx2x_sp_mapping(bp, mac_stats) + 2907 dmae->dst_addr_lo = U64_LO(bnx2x_sp_mapping(bp, mac_stats) +
2651 offsetof(struct emac_stats, 2908 offsetof(struct emac_stats, tx_stat_ifhcoutoctets));
2652 tx_ifhcoutoctets));
2653 dmae->dst_addr_hi = U64_HI(bnx2x_sp_mapping(bp, mac_stats) + 2909 dmae->dst_addr_hi = U64_HI(bnx2x_sp_mapping(bp, mac_stats) +
2654 offsetof(struct emac_stats, 2910 offsetof(struct emac_stats, tx_stat_ifhcoutoctets));
2655 tx_ifhcoutoctets));
2656 dmae->len = EMAC_REG_EMAC_TX_STAT_AC_COUNT; 2911 dmae->len = EMAC_REG_EMAC_TX_STAT_AC_COUNT;
2657 dmae->comp_addr_lo = dmae_reg_go_c[loader_idx] >> 2; 2912 dmae->comp_addr_lo = dmae_reg_go_c[loader_idx] >> 2;
2658 dmae->comp_addr_hi = 0; 2913 dmae->comp_addr_hi = 0;
@@ -2661,6 +2916,32 @@ static void bnx2x_init_mac_stats(struct bnx2x *bp)
2661 2916
2662 /* NIG */ 2917 /* NIG */
2663 dmae = bnx2x_sp(bp, dmae[bp->executer_idx++]); 2918 dmae = bnx2x_sp(bp, dmae[bp->executer_idx++]);
2919 dmae->opcode = opcode;
2920 dmae->src_addr_lo = (port ? NIG_REG_STAT1_BRB_DISCARD :
2921 NIG_REG_STAT0_BRB_DISCARD) >> 2;
2922 dmae->src_addr_hi = 0;
2923 dmae->dst_addr_lo = U64_LO(bnx2x_sp_mapping(bp, nig_stats));
2924 dmae->dst_addr_hi = U64_HI(bnx2x_sp_mapping(bp, nig_stats));
2925 dmae->len = (sizeof(struct nig_stats) - 4*sizeof(u32)) >> 2;
2926 dmae->comp_addr_lo = dmae_reg_go_c[loader_idx] >> 2;
2927 dmae->comp_addr_hi = 0;
2928 dmae->comp_val = 1;
2929
2930 dmae = bnx2x_sp(bp, dmae[bp->executer_idx++]);
2931 dmae->opcode = opcode;
2932 dmae->src_addr_lo = (port ? NIG_REG_STAT1_EGRESS_MAC_PKT0 :
2933 NIG_REG_STAT0_EGRESS_MAC_PKT0) >> 2;
2934 dmae->src_addr_hi = 0;
2935 dmae->dst_addr_lo = U64_LO(bnx2x_sp_mapping(bp, nig_stats) +
2936 offsetof(struct nig_stats, egress_mac_pkt0_lo));
2937 dmae->dst_addr_hi = U64_HI(bnx2x_sp_mapping(bp, nig_stats) +
2938 offsetof(struct nig_stats, egress_mac_pkt0_lo));
2939 dmae->len = (2*sizeof(u32)) >> 2;
2940 dmae->comp_addr_lo = dmae_reg_go_c[loader_idx] >> 2;
2941 dmae->comp_addr_hi = 0;
2942 dmae->comp_val = 1;
2943
2944 dmae = bnx2x_sp(bp, dmae[bp->executer_idx++]);
2664 dmae->opcode = (DMAE_CMD_SRC_GRC | DMAE_CMD_DST_PCI | 2945 dmae->opcode = (DMAE_CMD_SRC_GRC | DMAE_CMD_DST_PCI |
2665 DMAE_CMD_C_DST_PCI | DMAE_CMD_C_ENABLE | 2946 DMAE_CMD_C_DST_PCI | DMAE_CMD_C_ENABLE |
2666 DMAE_CMD_SRC_RESET | DMAE_CMD_DST_RESET | 2947 DMAE_CMD_SRC_RESET | DMAE_CMD_DST_RESET |
@@ -2669,325 +2950,322 @@ static void bnx2x_init_mac_stats(struct bnx2x *bp)
2669#else 2950#else
2670 DMAE_CMD_ENDIANITY_DW_SWAP | 2951 DMAE_CMD_ENDIANITY_DW_SWAP |
2671#endif 2952#endif
2672 (port ? DMAE_CMD_PORT_1 : DMAE_CMD_PORT_0)); 2953 (port ? DMAE_CMD_PORT_1 : DMAE_CMD_PORT_0) |
2673 dmae->src_addr_lo = (port ? NIG_REG_STAT1_BRB_DISCARD : 2954 (vn << DMAE_CMD_E1HVN_SHIFT));
2674 NIG_REG_STAT0_BRB_DISCARD) >> 2; 2955 dmae->src_addr_lo = (port ? NIG_REG_STAT1_EGRESS_MAC_PKT1 :
2956 NIG_REG_STAT0_EGRESS_MAC_PKT1) >> 2;
2675 dmae->src_addr_hi = 0; 2957 dmae->src_addr_hi = 0;
2676 dmae->dst_addr_lo = U64_LO(bnx2x_sp_mapping(bp, nig)); 2958 dmae->dst_addr_lo = U64_LO(bnx2x_sp_mapping(bp, nig_stats) +
2677 dmae->dst_addr_hi = U64_HI(bnx2x_sp_mapping(bp, nig)); 2959 offsetof(struct nig_stats, egress_mac_pkt1_lo));
2678 dmae->len = (sizeof(struct nig_stats) - 2*sizeof(u32)) >> 2; 2960 dmae->dst_addr_hi = U64_HI(bnx2x_sp_mapping(bp, nig_stats) +
2679 dmae->comp_addr_lo = U64_LO(bnx2x_sp_mapping(bp, nig) + 2961 offsetof(struct nig_stats, egress_mac_pkt1_lo));
2680 offsetof(struct nig_stats, done)); 2962 dmae->len = (2*sizeof(u32)) >> 2;
2681 dmae->comp_addr_hi = U64_HI(bnx2x_sp_mapping(bp, nig) + 2963 dmae->comp_addr_lo = U64_LO(bnx2x_sp_mapping(bp, stats_comp));
2682 offsetof(struct nig_stats, done)); 2964 dmae->comp_addr_hi = U64_HI(bnx2x_sp_mapping(bp, stats_comp));
2683 dmae->comp_val = 0xffffffff; 2965 dmae->comp_val = DMAE_COMP_VAL;
2966
2967 *stats_comp = 0;
2684} 2968}
2685 2969
2686static void bnx2x_init_stats(struct bnx2x *bp) 2970static void bnx2x_func_stats_init(struct bnx2x *bp)
2687{ 2971{
2688 int port = BP_PORT(bp); 2972 struct dmae_command *dmae = &bp->stats_dmae;
2973 u32 *stats_comp = bnx2x_sp(bp, stats_comp);
2689 2974
2690 bp->stats_state = STATS_STATE_DISABLE; 2975 /* sanity */
2691 bp->executer_idx = 0; 2976 if (!bp->func_stx) {
2977 BNX2X_ERR("BUG!\n");
2978 return;
2979 }
2692 2980
2693 bp->old_brb_discard = REG_RD(bp, 2981 bp->executer_idx = 0;
2694 NIG_REG_STAT0_BRB_DISCARD + port*0x38); 2982 memset(dmae, 0, sizeof(struct dmae_command));
2695 2983
2696 memset(&bp->old_bmac, 0, sizeof(struct bmac_stats)); 2984 dmae->opcode = (DMAE_CMD_SRC_PCI | DMAE_CMD_DST_GRC |
2697 memset(&bp->old_tclient, 0, sizeof(struct tstorm_per_client_stats)); 2985 DMAE_CMD_C_DST_PCI | DMAE_CMD_C_ENABLE |
2698 memset(&bp->dev->stats, 0, sizeof(struct net_device_stats)); 2986 DMAE_CMD_SRC_RESET | DMAE_CMD_DST_RESET |
2987#ifdef __BIG_ENDIAN
2988 DMAE_CMD_ENDIANITY_B_DW_SWAP |
2989#else
2990 DMAE_CMD_ENDIANITY_DW_SWAP |
2991#endif
2992 (BP_PORT(bp) ? DMAE_CMD_PORT_1 : DMAE_CMD_PORT_0) |
2993 (BP_E1HVN(bp) << DMAE_CMD_E1HVN_SHIFT));
2994 dmae->src_addr_lo = U64_LO(bnx2x_sp_mapping(bp, func_stats));
2995 dmae->src_addr_hi = U64_HI(bnx2x_sp_mapping(bp, func_stats));
2996 dmae->dst_addr_lo = bp->func_stx >> 2;
2997 dmae->dst_addr_hi = 0;
2998 dmae->len = sizeof(struct host_func_stats) >> 2;
2999 dmae->comp_addr_lo = U64_LO(bnx2x_sp_mapping(bp, stats_comp));
3000 dmae->comp_addr_hi = U64_HI(bnx2x_sp_mapping(bp, stats_comp));
3001 dmae->comp_val = DMAE_COMP_VAL;
2699 3002
2700 REG_WR(bp, BAR_XSTRORM_INTMEM + XSTORM_STATS_FLAGS_OFFSET(port), 1); 3003 *stats_comp = 0;
2701 REG_WR(bp, BAR_XSTRORM_INTMEM + 3004}
2702 XSTORM_STATS_FLAGS_OFFSET(port) + 4, 0);
2703 3005
2704 REG_WR(bp, BAR_TSTRORM_INTMEM + TSTORM_STATS_FLAGS_OFFSET(port), 1); 3006static void bnx2x_stats_start(struct bnx2x *bp)
2705 REG_WR(bp, BAR_TSTRORM_INTMEM + 3007{
2706 TSTORM_STATS_FLAGS_OFFSET(port) + 4, 0); 3008 if (bp->port.pmf)
3009 bnx2x_port_stats_init(bp);
3010
3011 else if (bp->func_stx)
3012 bnx2x_func_stats_init(bp);
3013
3014 bnx2x_hw_stats_post(bp);
3015 bnx2x_storm_stats_post(bp);
3016}
3017
3018static void bnx2x_stats_pmf_start(struct bnx2x *bp)
3019{
3020 bnx2x_stats_comp(bp);
3021 bnx2x_stats_pmf_update(bp);
3022 bnx2x_stats_start(bp);
3023}
3024
3025static void bnx2x_stats_restart(struct bnx2x *bp)
3026{
3027 bnx2x_stats_comp(bp);
3028 bnx2x_stats_start(bp);
3029}
3030
3031static void bnx2x_bmac_stats_update(struct bnx2x *bp)
3032{
3033 struct bmac_stats *new = bnx2x_sp(bp, mac_stats.bmac_stats);
3034 struct host_port_stats *pstats = bnx2x_sp(bp, port_stats);
3035 struct regpair diff;
3036
3037 UPDATE_STAT64(rx_stat_grerb, rx_stat_ifhcinbadoctets);
3038 UPDATE_STAT64(rx_stat_grfcs, rx_stat_dot3statsfcserrors);
3039 UPDATE_STAT64(rx_stat_grund, rx_stat_etherstatsundersizepkts);
3040 UPDATE_STAT64(rx_stat_grovr, rx_stat_dot3statsframestoolong);
3041 UPDATE_STAT64(rx_stat_grfrg, rx_stat_etherstatsfragments);
3042 UPDATE_STAT64(rx_stat_grjbr, rx_stat_etherstatsjabbers);
3043 UPDATE_STAT64(rx_stat_grxpf, rx_stat_bmac_xpf);
3044 UPDATE_STAT64(rx_stat_grxcf, rx_stat_bmac_xcf);
3045 UPDATE_STAT64(rx_stat_grxpf, rx_stat_xoffstateentered);
3046 UPDATE_STAT64(rx_stat_grxpf, rx_stat_xoffpauseframesreceived);
3047 UPDATE_STAT64(tx_stat_gtxpf, tx_stat_outxoffsent);
3048 UPDATE_STAT64(tx_stat_gtxpf, tx_stat_flowcontroldone);
3049 UPDATE_STAT64(tx_stat_gt64, tx_stat_etherstatspkts64octets);
3050 UPDATE_STAT64(tx_stat_gt127,
3051 tx_stat_etherstatspkts65octetsto127octets);
3052 UPDATE_STAT64(tx_stat_gt255,
3053 tx_stat_etherstatspkts128octetsto255octets);
3054 UPDATE_STAT64(tx_stat_gt511,
3055 tx_stat_etherstatspkts256octetsto511octets);
3056 UPDATE_STAT64(tx_stat_gt1023,
3057 tx_stat_etherstatspkts512octetsto1023octets);
3058 UPDATE_STAT64(tx_stat_gt1518,
3059 tx_stat_etherstatspkts1024octetsto1522octets);
3060 UPDATE_STAT64(tx_stat_gt2047, tx_stat_bmac_2047);
3061 UPDATE_STAT64(tx_stat_gt4095, tx_stat_bmac_4095);
3062 UPDATE_STAT64(tx_stat_gt9216, tx_stat_bmac_9216);
3063 UPDATE_STAT64(tx_stat_gt16383, tx_stat_bmac_16383);
3064 UPDATE_STAT64(tx_stat_gterr,
3065 tx_stat_dot3statsinternalmactransmiterrors);
3066 UPDATE_STAT64(tx_stat_gtufl, tx_stat_bmac_ufl);
3067}
3068
3069static void bnx2x_emac_stats_update(struct bnx2x *bp)
3070{
3071 struct emac_stats *new = bnx2x_sp(bp, mac_stats.emac_stats);
3072 struct host_port_stats *pstats = bnx2x_sp(bp, port_stats);
3073
3074 UPDATE_EXTEND_STAT(rx_stat_ifhcinbadoctets);
3075 UPDATE_EXTEND_STAT(tx_stat_ifhcoutbadoctets);
3076 UPDATE_EXTEND_STAT(rx_stat_dot3statsfcserrors);
3077 UPDATE_EXTEND_STAT(rx_stat_dot3statsalignmenterrors);
3078 UPDATE_EXTEND_STAT(rx_stat_dot3statscarriersenseerrors);
3079 UPDATE_EXTEND_STAT(rx_stat_falsecarriererrors);
3080 UPDATE_EXTEND_STAT(rx_stat_etherstatsundersizepkts);
3081 UPDATE_EXTEND_STAT(rx_stat_dot3statsframestoolong);
3082 UPDATE_EXTEND_STAT(rx_stat_etherstatsfragments);
3083 UPDATE_EXTEND_STAT(rx_stat_etherstatsjabbers);
3084 UPDATE_EXTEND_STAT(rx_stat_maccontrolframesreceived);
3085 UPDATE_EXTEND_STAT(rx_stat_xoffstateentered);
3086 UPDATE_EXTEND_STAT(rx_stat_xonpauseframesreceived);
3087 UPDATE_EXTEND_STAT(rx_stat_xoffpauseframesreceived);
3088 UPDATE_EXTEND_STAT(tx_stat_outxonsent);
3089 UPDATE_EXTEND_STAT(tx_stat_outxoffsent);
3090 UPDATE_EXTEND_STAT(tx_stat_flowcontroldone);
3091 UPDATE_EXTEND_STAT(tx_stat_etherstatscollisions);
3092 UPDATE_EXTEND_STAT(tx_stat_dot3statssinglecollisionframes);
3093 UPDATE_EXTEND_STAT(tx_stat_dot3statsmultiplecollisionframes);
3094 UPDATE_EXTEND_STAT(tx_stat_dot3statsdeferredtransmissions);
3095 UPDATE_EXTEND_STAT(tx_stat_dot3statsexcessivecollisions);
3096 UPDATE_EXTEND_STAT(tx_stat_dot3statslatecollisions);
3097 UPDATE_EXTEND_STAT(tx_stat_etherstatspkts64octets);
3098 UPDATE_EXTEND_STAT(tx_stat_etherstatspkts65octetsto127octets);
3099 UPDATE_EXTEND_STAT(tx_stat_etherstatspkts128octetsto255octets);
3100 UPDATE_EXTEND_STAT(tx_stat_etherstatspkts256octetsto511octets);
3101 UPDATE_EXTEND_STAT(tx_stat_etherstatspkts512octetsto1023octets);
3102 UPDATE_EXTEND_STAT(tx_stat_etherstatspkts1024octetsto1522octets);
3103 UPDATE_EXTEND_STAT(tx_stat_etherstatspktsover1522octets);
3104 UPDATE_EXTEND_STAT(tx_stat_dot3statsinternalmactransmiterrors);
3105}
3106
3107static int bnx2x_hw_stats_update(struct bnx2x *bp)
3108{
3109 struct nig_stats *new = bnx2x_sp(bp, nig_stats);
3110 struct nig_stats *old = &(bp->port.old_nig_stats);
3111 struct host_port_stats *pstats = bnx2x_sp(bp, port_stats);
3112 struct bnx2x_eth_stats *estats = &bp->eth_stats;
3113 struct regpair diff;
3114
3115 if (bp->link_vars.mac_type == MAC_TYPE_BMAC)
3116 bnx2x_bmac_stats_update(bp);
3117
3118 else if (bp->link_vars.mac_type == MAC_TYPE_EMAC)
3119 bnx2x_emac_stats_update(bp);
3120
3121 else { /* unreached */
3122 BNX2X_ERR("stats updated by dmae but no MAC active\n");
3123 return -1;
3124 }
2707 3125
2708 REG_WR(bp, BAR_CSTRORM_INTMEM + CSTORM_STATS_FLAGS_OFFSET(port), 0); 3126 ADD_EXTEND_64(pstats->brb_drop_hi, pstats->brb_drop_lo,
2709 REG_WR(bp, BAR_CSTRORM_INTMEM + 3127 new->brb_discard - old->brb_discard);
2710 CSTORM_STATS_FLAGS_OFFSET(port) + 4, 0);
2711 3128
2712 REG_WR(bp, BAR_XSTRORM_INTMEM + 3129 UPDATE_STAT64_NIG(egress_mac_pkt0,
2713 XSTORM_ETH_STATS_QUERY_ADDR_OFFSET(port), 3130 etherstatspkts1024octetsto1522octets);
2714 U64_LO(bnx2x_sp_mapping(bp, fw_stats))); 3131 UPDATE_STAT64_NIG(egress_mac_pkt1, etherstatspktsover1522octets);
2715 REG_WR(bp, BAR_XSTRORM_INTMEM +
2716 XSTORM_ETH_STATS_QUERY_ADDR_OFFSET(port) + 4,
2717 U64_HI(bnx2x_sp_mapping(bp, fw_stats)));
2718 3132
2719 REG_WR(bp, BAR_TSTRORM_INTMEM + 3133 memcpy(old, new, sizeof(struct nig_stats));
2720 TSTORM_ETH_STATS_QUERY_ADDR_OFFSET(port),
2721 U64_LO(bnx2x_sp_mapping(bp, fw_stats)));
2722 REG_WR(bp, BAR_TSTRORM_INTMEM +
2723 TSTORM_ETH_STATS_QUERY_ADDR_OFFSET(port) + 4,
2724 U64_HI(bnx2x_sp_mapping(bp, fw_stats)));
2725}
2726 3134
2727static void bnx2x_stop_stats(struct bnx2x *bp) 3135 memcpy(&(estats->rx_stat_ifhcinbadoctets_hi), &(pstats->mac_stx[1]),
2728{ 3136 sizeof(struct mac_stx));
2729 might_sleep(); 3137 estats->brb_drop_hi = pstats->brb_drop_hi;
2730 if (bp->stats_state != STATS_STATE_DISABLE) { 3138 estats->brb_drop_lo = pstats->brb_drop_lo;
2731 int timeout = 10;
2732 3139
2733 bp->stats_state = STATS_STATE_STOP; 3140 pstats->host_port_stats_start = ++pstats->host_port_stats_end;
2734 DP(BNX2X_MSG_STATS, "stats_state - STOP\n");
2735 3141
2736 while (bp->stats_state != STATS_STATE_DISABLE) { 3142 return 0;
2737 if (!timeout) {
2738 BNX2X_ERR("timeout waiting for stats stop\n");
2739 break;
2740 }
2741 timeout--;
2742 msleep(100);
2743 }
2744 }
2745 DP(BNX2X_MSG_STATS, "stats_state - DISABLE\n");
2746} 3143}
2747 3144
2748/* 3145static int bnx2x_storm_stats_update(struct bnx2x *bp)
2749 * Statistics service functions
2750 */
2751
2752static void bnx2x_update_bmac_stats(struct bnx2x *bp)
2753{
2754 struct regp diff;
2755 struct regp sum;
2756 struct bmac_stats *new = bnx2x_sp(bp, mac_stats.bmac);
2757 struct bmac_stats *old = &bp->old_bmac;
2758 struct bnx2x_eth_stats *estats = bnx2x_sp(bp, eth_stats);
2759
2760 sum.hi = 0;
2761 sum.lo = 0;
2762
2763 UPDATE_STAT64(tx_gtbyt.hi, total_bytes_transmitted_hi,
2764 tx_gtbyt.lo, total_bytes_transmitted_lo);
2765
2766 UPDATE_STAT64(tx_gtmca.hi, total_multicast_packets_transmitted_hi,
2767 tx_gtmca.lo, total_multicast_packets_transmitted_lo);
2768 ADD_64(sum.hi, diff.hi, sum.lo, diff.lo);
2769
2770 UPDATE_STAT64(tx_gtgca.hi, total_broadcast_packets_transmitted_hi,
2771 tx_gtgca.lo, total_broadcast_packets_transmitted_lo);
2772 ADD_64(sum.hi, diff.hi, sum.lo, diff.lo);
2773
2774 UPDATE_STAT64(tx_gtpkt.hi, total_unicast_packets_transmitted_hi,
2775 tx_gtpkt.lo, total_unicast_packets_transmitted_lo);
2776 SUB_64(estats->total_unicast_packets_transmitted_hi, sum.hi,
2777 estats->total_unicast_packets_transmitted_lo, sum.lo);
2778
2779 UPDATE_STAT(tx_gtxpf.lo, pause_xoff_frames_transmitted);
2780 UPDATE_STAT(tx_gt64.lo, frames_transmitted_64_bytes);
2781 UPDATE_STAT(tx_gt127.lo, frames_transmitted_65_127_bytes);
2782 UPDATE_STAT(tx_gt255.lo, frames_transmitted_128_255_bytes);
2783 UPDATE_STAT(tx_gt511.lo, frames_transmitted_256_511_bytes);
2784 UPDATE_STAT(tx_gt1023.lo, frames_transmitted_512_1023_bytes);
2785 UPDATE_STAT(tx_gt1518.lo, frames_transmitted_1024_1522_bytes);
2786 UPDATE_STAT(tx_gt2047.lo, frames_transmitted_1523_9022_bytes);
2787 UPDATE_STAT(tx_gt4095.lo, frames_transmitted_1523_9022_bytes);
2788 UPDATE_STAT(tx_gt9216.lo, frames_transmitted_1523_9022_bytes);
2789 UPDATE_STAT(tx_gt16383.lo, frames_transmitted_1523_9022_bytes);
2790
2791 UPDATE_STAT(rx_grfcs.lo, crc_receive_errors);
2792 UPDATE_STAT(rx_grund.lo, runt_packets_received);
2793 UPDATE_STAT(rx_grovr.lo, stat_Dot3statsFramesTooLong);
2794 UPDATE_STAT(rx_grxpf.lo, pause_xoff_frames_received);
2795 UPDATE_STAT(rx_grxcf.lo, control_frames_received);
2796 /* UPDATE_STAT(rx_grxpf.lo, control_frames_received); */
2797 UPDATE_STAT(rx_grfrg.lo, error_runt_packets_received);
2798 UPDATE_STAT(rx_grjbr.lo, error_jabber_packets_received);
2799
2800 UPDATE_STAT64(rx_grerb.hi, stat_IfHCInBadOctets_hi,
2801 rx_grerb.lo, stat_IfHCInBadOctets_lo);
2802 UPDATE_STAT64(tx_gtufl.hi, stat_IfHCOutBadOctets_hi,
2803 tx_gtufl.lo, stat_IfHCOutBadOctets_lo);
2804 UPDATE_STAT(tx_gterr.lo, stat_Dot3statsInternalMacTransmitErrors);
2805 /* UPDATE_STAT(rx_grxpf.lo, stat_XoffStateEntered); */
2806 estats->stat_XoffStateEntered = estats->pause_xoff_frames_received;
2807}
2808
2809static void bnx2x_update_emac_stats(struct bnx2x *bp)
2810{
2811 struct emac_stats *new = bnx2x_sp(bp, mac_stats.emac);
2812 struct bnx2x_eth_stats *estats = bnx2x_sp(bp, eth_stats);
2813
2814 UPDATE_EXTEND_STAT(tx_ifhcoutoctets, total_bytes_transmitted_hi,
2815 total_bytes_transmitted_lo);
2816 UPDATE_EXTEND_STAT(tx_ifhcoutucastpkts,
2817 total_unicast_packets_transmitted_hi,
2818 total_unicast_packets_transmitted_lo);
2819 UPDATE_EXTEND_STAT(tx_ifhcoutmulticastpkts,
2820 total_multicast_packets_transmitted_hi,
2821 total_multicast_packets_transmitted_lo);
2822 UPDATE_EXTEND_STAT(tx_ifhcoutbroadcastpkts,
2823 total_broadcast_packets_transmitted_hi,
2824 total_broadcast_packets_transmitted_lo);
2825
2826 estats->pause_xon_frames_transmitted += new->tx_outxonsent;
2827 estats->pause_xoff_frames_transmitted += new->tx_outxoffsent;
2828 estats->single_collision_transmit_frames +=
2829 new->tx_dot3statssinglecollisionframes;
2830 estats->multiple_collision_transmit_frames +=
2831 new->tx_dot3statsmultiplecollisionframes;
2832 estats->late_collision_frames += new->tx_dot3statslatecollisions;
2833 estats->excessive_collision_frames +=
2834 new->tx_dot3statsexcessivecollisions;
2835 estats->frames_transmitted_64_bytes += new->tx_etherstatspkts64octets;
2836 estats->frames_transmitted_65_127_bytes +=
2837 new->tx_etherstatspkts65octetsto127octets;
2838 estats->frames_transmitted_128_255_bytes +=
2839 new->tx_etherstatspkts128octetsto255octets;
2840 estats->frames_transmitted_256_511_bytes +=
2841 new->tx_etherstatspkts256octetsto511octets;
2842 estats->frames_transmitted_512_1023_bytes +=
2843 new->tx_etherstatspkts512octetsto1023octets;
2844 estats->frames_transmitted_1024_1522_bytes +=
2845 new->tx_etherstatspkts1024octetsto1522octet;
2846 estats->frames_transmitted_1523_9022_bytes +=
2847 new->tx_etherstatspktsover1522octets;
2848
2849 estats->crc_receive_errors += new->rx_dot3statsfcserrors;
2850 estats->alignment_errors += new->rx_dot3statsalignmenterrors;
2851 estats->false_carrier_detections += new->rx_falsecarriererrors;
2852 estats->runt_packets_received += new->rx_etherstatsundersizepkts;
2853 estats->stat_Dot3statsFramesTooLong += new->rx_dot3statsframestoolong;
2854 estats->pause_xon_frames_received += new->rx_xonpauseframesreceived;
2855 estats->pause_xoff_frames_received += new->rx_xoffpauseframesreceived;
2856 estats->control_frames_received += new->rx_maccontrolframesreceived;
2857 estats->error_runt_packets_received += new->rx_etherstatsfragments;
2858 estats->error_jabber_packets_received += new->rx_etherstatsjabbers;
2859
2860 UPDATE_EXTEND_STAT(rx_ifhcinbadoctets, stat_IfHCInBadOctets_hi,
2861 stat_IfHCInBadOctets_lo);
2862 UPDATE_EXTEND_STAT(tx_ifhcoutbadoctets, stat_IfHCOutBadOctets_hi,
2863 stat_IfHCOutBadOctets_lo);
2864 estats->stat_Dot3statsInternalMacTransmitErrors +=
2865 new->tx_dot3statsinternalmactransmiterrors;
2866 estats->stat_Dot3StatsCarrierSenseErrors +=
2867 new->rx_dot3statscarriersenseerrors;
2868 estats->stat_Dot3StatsDeferredTransmissions +=
2869 new->tx_dot3statsdeferredtransmissions;
2870 estats->stat_FlowControlDone += new->tx_flowcontroldone;
2871 estats->stat_XoffStateEntered += new->rx_xoffstateentered;
2872}
2873
2874static int bnx2x_update_storm_stats(struct bnx2x *bp)
2875{ 3146{
2876 struct eth_stats_query *stats = bnx2x_sp(bp, fw_stats); 3147 struct eth_stats_query *stats = bnx2x_sp(bp, fw_stats);
2877 struct tstorm_common_stats *tstats = &stats->tstorm_common; 3148 int cl_id = BP_CL_ID(bp);
3149 struct tstorm_per_port_stats *tport =
3150 &stats->tstorm_common.port_statistics;
2878 struct tstorm_per_client_stats *tclient = 3151 struct tstorm_per_client_stats *tclient =
2879 &tstats->client_statistics[0]; 3152 &stats->tstorm_common.client_statistics[cl_id];
2880 struct tstorm_per_client_stats *old_tclient = &bp->old_tclient; 3153 struct tstorm_per_client_stats *old_tclient = &bp->old_tclient;
2881 struct xstorm_common_stats *xstats = &stats->xstorm_common; 3154 struct xstorm_per_client_stats *xclient =
2882 struct nig_stats *nstats = bnx2x_sp(bp, nig); 3155 &stats->xstorm_common.client_statistics[cl_id];
2883 struct bnx2x_eth_stats *estats = bnx2x_sp(bp, eth_stats); 3156 struct xstorm_per_client_stats *old_xclient = &bp->old_xclient;
3157 struct host_func_stats *fstats = bnx2x_sp(bp, func_stats);
3158 struct bnx2x_eth_stats *estats = &bp->eth_stats;
2884 u32 diff; 3159 u32 diff;
2885 3160
2886 /* are DMAE stats valid? */ 3161 /* are storm stats valid? */
2887 if (nstats->done != 0xffffffff) { 3162 if ((u16)(le16_to_cpu(tclient->stats_counter) + 1) !=
2888 DP(BNX2X_MSG_STATS, "stats not updated by dmae\n"); 3163 bp->stats_counter) {
3164 DP(BNX2X_MSG_STATS, "stats not updated by tstorm"
3165 " tstorm counter (%d) != stats_counter (%d)\n",
3166 tclient->stats_counter, bp->stats_counter);
2889 return -1; 3167 return -1;
2890 } 3168 }
2891 3169 if ((u16)(le16_to_cpu(xclient->stats_counter) + 1) !=
2892 /* are storm stats valid? */ 3170 bp->stats_counter) {
2893 if (tstats->done.hi != 0xffffffff) { 3171 DP(BNX2X_MSG_STATS, "stats not updated by xstorm"
2894 DP(BNX2X_MSG_STATS, "stats not updated by tstorm\n"); 3172 " xstorm counter (%d) != stats_counter (%d)\n",
3173 xclient->stats_counter, bp->stats_counter);
2895 return -2; 3174 return -2;
2896 } 3175 }
2897 if (xstats->done.hi != 0xffffffff) {
2898 DP(BNX2X_MSG_STATS, "stats not updated by xstorm\n");
2899 return -3;
2900 }
2901 3176
2902 estats->total_bytes_received_hi = 3177 fstats->total_bytes_received_hi =
2903 estats->valid_bytes_received_hi = 3178 fstats->valid_bytes_received_hi =
2904 le32_to_cpu(tclient->total_rcv_bytes.hi); 3179 le32_to_cpu(tclient->total_rcv_bytes.hi);
2905 estats->total_bytes_received_lo = 3180 fstats->total_bytes_received_lo =
2906 estats->valid_bytes_received_lo = 3181 fstats->valid_bytes_received_lo =
2907 le32_to_cpu(tclient->total_rcv_bytes.lo); 3182 le32_to_cpu(tclient->total_rcv_bytes.lo);
2908 ADD_64(estats->total_bytes_received_hi, 3183
2909 le32_to_cpu(tclient->rcv_error_bytes.hi), 3184 estats->error_bytes_received_hi =
2910 estats->total_bytes_received_lo, 3185 le32_to_cpu(tclient->rcv_error_bytes.hi);
2911 le32_to_cpu(tclient->rcv_error_bytes.lo)); 3186 estats->error_bytes_received_lo =
2912 3187 le32_to_cpu(tclient->rcv_error_bytes.lo);
2913 UPDATE_EXTEND_TSTAT(rcv_unicast_pkts, 3188 ADD_64(estats->error_bytes_received_hi,
2914 total_unicast_packets_received_hi, 3189 estats->rx_stat_ifhcinbadoctets_hi,
2915 total_unicast_packets_received_lo); 3190 estats->error_bytes_received_lo,
3191 estats->rx_stat_ifhcinbadoctets_lo);
3192
3193 ADD_64(fstats->total_bytes_received_hi,
3194 estats->error_bytes_received_hi,
3195 fstats->total_bytes_received_lo,
3196 estats->error_bytes_received_lo);
3197
3198 UPDATE_EXTEND_TSTAT(rcv_unicast_pkts, total_unicast_packets_received);
2916 UPDATE_EXTEND_TSTAT(rcv_multicast_pkts, 3199 UPDATE_EXTEND_TSTAT(rcv_multicast_pkts,
2917 total_multicast_packets_received_hi, 3200 total_multicast_packets_received);
2918 total_multicast_packets_received_lo);
2919 UPDATE_EXTEND_TSTAT(rcv_broadcast_pkts, 3201 UPDATE_EXTEND_TSTAT(rcv_broadcast_pkts,
2920 total_broadcast_packets_received_hi, 3202 total_broadcast_packets_received);
2921 total_broadcast_packets_received_lo); 3203
2922 3204 fstats->total_bytes_transmitted_hi =
2923 estats->frames_received_64_bytes = MAC_STX_NA; 3205 le32_to_cpu(xclient->total_sent_bytes.hi);
2924 estats->frames_received_65_127_bytes = MAC_STX_NA; 3206 fstats->total_bytes_transmitted_lo =
2925 estats->frames_received_128_255_bytes = MAC_STX_NA; 3207 le32_to_cpu(xclient->total_sent_bytes.lo);
2926 estats->frames_received_256_511_bytes = MAC_STX_NA; 3208
2927 estats->frames_received_512_1023_bytes = MAC_STX_NA; 3209 UPDATE_EXTEND_XSTAT(unicast_pkts_sent,
2928 estats->frames_received_1024_1522_bytes = MAC_STX_NA; 3210 total_unicast_packets_transmitted);
2929 estats->frames_received_1523_9022_bytes = MAC_STX_NA; 3211 UPDATE_EXTEND_XSTAT(multicast_pkts_sent,
2930 3212 total_multicast_packets_transmitted);
2931 estats->x_total_sent_bytes_hi = 3213 UPDATE_EXTEND_XSTAT(broadcast_pkts_sent,
2932 le32_to_cpu(xstats->total_sent_bytes.hi); 3214 total_broadcast_packets_transmitted);
2933 estats->x_total_sent_bytes_lo = 3215
2934 le32_to_cpu(xstats->total_sent_bytes.lo); 3216 memcpy(estats, &(fstats->total_bytes_received_hi),
2935 estats->x_total_sent_pkts = le32_to_cpu(xstats->total_sent_pkts); 3217 sizeof(struct host_func_stats) - 2*sizeof(u32));
2936 3218
2937 estats->t_rcv_unicast_bytes_hi = 3219 estats->mac_filter_discard = le32_to_cpu(tport->mac_filter_discard);
3220 estats->xxoverflow_discard = le32_to_cpu(tport->xxoverflow_discard);
3221 estats->brb_truncate_discard =
3222 le32_to_cpu(tport->brb_truncate_discard);
3223 estats->mac_discard = le32_to_cpu(tport->mac_discard);
3224
3225 old_tclient->rcv_unicast_bytes.hi =
2938 le32_to_cpu(tclient->rcv_unicast_bytes.hi); 3226 le32_to_cpu(tclient->rcv_unicast_bytes.hi);
2939 estats->t_rcv_unicast_bytes_lo = 3227 old_tclient->rcv_unicast_bytes.lo =
2940 le32_to_cpu(tclient->rcv_unicast_bytes.lo); 3228 le32_to_cpu(tclient->rcv_unicast_bytes.lo);
2941 estats->t_rcv_broadcast_bytes_hi = 3229 old_tclient->rcv_broadcast_bytes.hi =
2942 le32_to_cpu(tclient->rcv_broadcast_bytes.hi); 3230 le32_to_cpu(tclient->rcv_broadcast_bytes.hi);
2943 estats->t_rcv_broadcast_bytes_lo = 3231 old_tclient->rcv_broadcast_bytes.lo =
2944 le32_to_cpu(tclient->rcv_broadcast_bytes.lo); 3232 le32_to_cpu(tclient->rcv_broadcast_bytes.lo);
2945 estats->t_rcv_multicast_bytes_hi = 3233 old_tclient->rcv_multicast_bytes.hi =
2946 le32_to_cpu(tclient->rcv_multicast_bytes.hi); 3234 le32_to_cpu(tclient->rcv_multicast_bytes.hi);
2947 estats->t_rcv_multicast_bytes_lo = 3235 old_tclient->rcv_multicast_bytes.lo =
2948 le32_to_cpu(tclient->rcv_multicast_bytes.lo); 3236 le32_to_cpu(tclient->rcv_multicast_bytes.lo);
2949 estats->t_total_rcv_pkt = le32_to_cpu(tclient->total_rcv_pkts); 3237 old_tclient->total_rcv_pkts = le32_to_cpu(tclient->total_rcv_pkts);
2950 3238
2951 estats->checksum_discard = le32_to_cpu(tclient->checksum_discard); 3239 old_tclient->checksum_discard = le32_to_cpu(tclient->checksum_discard);
2952 estats->packets_too_big_discard = 3240 old_tclient->packets_too_big_discard =
2953 le32_to_cpu(tclient->packets_too_big_discard); 3241 le32_to_cpu(tclient->packets_too_big_discard);
2954 estats->jabber_packets_received = estats->packets_too_big_discard + 3242 estats->no_buff_discard =
2955 estats->stat_Dot3statsFramesTooLong; 3243 old_tclient->no_buff_discard = le32_to_cpu(tclient->no_buff_discard);
2956 estats->no_buff_discard = le32_to_cpu(tclient->no_buff_discard); 3244 old_tclient->ttl0_discard = le32_to_cpu(tclient->ttl0_discard);
2957 estats->ttl0_discard = le32_to_cpu(tclient->ttl0_discard); 3245
2958 estats->mac_discard = le32_to_cpu(tclient->mac_discard); 3246 old_xclient->total_sent_pkts = le32_to_cpu(xclient->total_sent_pkts);
2959 estats->mac_filter_discard = le32_to_cpu(tstats->mac_filter_discard); 3247 old_xclient->unicast_bytes_sent.hi =
2960 estats->xxoverflow_discard = le32_to_cpu(tstats->xxoverflow_discard); 3248 le32_to_cpu(xclient->unicast_bytes_sent.hi);
2961 estats->brb_truncate_discard = 3249 old_xclient->unicast_bytes_sent.lo =
2962 le32_to_cpu(tstats->brb_truncate_discard); 3250 le32_to_cpu(xclient->unicast_bytes_sent.lo);
2963 3251 old_xclient->multicast_bytes_sent.hi =
2964 estats->brb_discard += nstats->brb_discard - bp->old_brb_discard; 3252 le32_to_cpu(xclient->multicast_bytes_sent.hi);
2965 bp->old_brb_discard = nstats->brb_discard; 3253 old_xclient->multicast_bytes_sent.lo =
2966 3254 le32_to_cpu(xclient->multicast_bytes_sent.lo);
2967 estats->brb_packet = nstats->brb_packet; 3255 old_xclient->broadcast_bytes_sent.hi =
2968 estats->brb_truncate = nstats->brb_truncate; 3256 le32_to_cpu(xclient->broadcast_bytes_sent.hi);
2969 estats->flow_ctrl_discard = nstats->flow_ctrl_discard; 3257 old_xclient->broadcast_bytes_sent.lo =
2970 estats->flow_ctrl_octets = nstats->flow_ctrl_octets; 3258 le32_to_cpu(xclient->broadcast_bytes_sent.lo);
2971 estats->flow_ctrl_packet = nstats->flow_ctrl_packet; 3259
2972 estats->mng_discard = nstats->mng_discard; 3260 fstats->host_func_stats_start = ++fstats->host_func_stats_end;
2973 estats->mng_octet_inp = nstats->mng_octet_inp;
2974 estats->mng_octet_out = nstats->mng_octet_out;
2975 estats->mng_packet_inp = nstats->mng_packet_inp;
2976 estats->mng_packet_out = nstats->mng_packet_out;
2977 estats->pbf_octets = nstats->pbf_octets;
2978 estats->pbf_packet = nstats->pbf_packet;
2979 estats->safc_inp = nstats->safc_inp;
2980
2981 xstats->done.hi = 0;
2982 tstats->done.hi = 0;
2983 nstats->done = 0;
2984 3261
2985 return 0; 3262 return 0;
2986} 3263}
2987 3264
2988static void bnx2x_update_net_stats(struct bnx2x *bp) 3265static void bnx2x_net_stats_update(struct bnx2x *bp)
2989{ 3266{
2990 struct bnx2x_eth_stats *estats = bnx2x_sp(bp, eth_stats); 3267 struct tstorm_per_client_stats *old_tclient = &bp->old_tclient;
3268 struct bnx2x_eth_stats *estats = &bp->eth_stats;
2991 struct net_device_stats *nstats = &bp->dev->stats; 3269 struct net_device_stats *nstats = &bp->dev->stats;
2992 3270
2993 nstats->rx_packets = 3271 nstats->rx_packets =
@@ -3000,28 +3278,35 @@ static void bnx2x_update_net_stats(struct bnx2x *bp)
3000 bnx2x_hilo(&estats->total_multicast_packets_transmitted_hi) + 3278 bnx2x_hilo(&estats->total_multicast_packets_transmitted_hi) +
3001 bnx2x_hilo(&estats->total_broadcast_packets_transmitted_hi); 3279 bnx2x_hilo(&estats->total_broadcast_packets_transmitted_hi);
3002 3280
3003 nstats->rx_bytes = bnx2x_hilo(&estats->total_bytes_received_hi); 3281 nstats->rx_bytes = bnx2x_hilo(&estats->valid_bytes_received_hi);
3004 3282
3005 nstats->tx_bytes = bnx2x_hilo(&estats->total_bytes_transmitted_hi); 3283 nstats->tx_bytes = bnx2x_hilo(&estats->total_bytes_transmitted_hi);
3006 3284
3007 nstats->rx_dropped = estats->checksum_discard + estats->mac_discard; 3285 nstats->rx_dropped = old_tclient->checksum_discard +
3286 estats->mac_discard;
3008 nstats->tx_dropped = 0; 3287 nstats->tx_dropped = 0;
3009 3288
3010 nstats->multicast = 3289 nstats->multicast =
3011 bnx2x_hilo(&estats->total_multicast_packets_transmitted_hi); 3290 bnx2x_hilo(&estats->total_multicast_packets_transmitted_hi);
3012 3291
3013 nstats->collisions = estats->single_collision_transmit_frames + 3292 nstats->collisions =
3014 estats->multiple_collision_transmit_frames + 3293 estats->tx_stat_dot3statssinglecollisionframes_lo +
3015 estats->late_collision_frames + 3294 estats->tx_stat_dot3statsmultiplecollisionframes_lo +
3016 estats->excessive_collision_frames; 3295 estats->tx_stat_dot3statslatecollisions_lo +
3296 estats->tx_stat_dot3statsexcessivecollisions_lo;
3297
3298 estats->jabber_packets_received =
3299 old_tclient->packets_too_big_discard +
3300 estats->rx_stat_dot3statsframestoolong_lo;
3017 3301
3018 nstats->rx_length_errors = estats->runt_packets_received + 3302 nstats->rx_length_errors =
3019 estats->jabber_packets_received; 3303 estats->rx_stat_etherstatsundersizepkts_lo +
3020 nstats->rx_over_errors = estats->brb_discard + 3304 estats->jabber_packets_received;
3305 nstats->rx_over_errors = estats->brb_drop_lo +
3021 estats->brb_truncate_discard; 3306 estats->brb_truncate_discard;
3022 nstats->rx_crc_errors = estats->crc_receive_errors; 3307 nstats->rx_crc_errors = estats->rx_stat_dot3statsfcserrors_lo;
3023 nstats->rx_frame_errors = estats->alignment_errors; 3308 nstats->rx_frame_errors = estats->rx_stat_dot3statsalignmenterrors_lo;
3024 nstats->rx_fifo_errors = estats->no_buff_discard; 3309 nstats->rx_fifo_errors = old_tclient->no_buff_discard;
3025 nstats->rx_missed_errors = estats->xxoverflow_discard; 3310 nstats->rx_missed_errors = estats->xxoverflow_discard;
3026 3311
3027 nstats->rx_errors = nstats->rx_length_errors + 3312 nstats->rx_errors = nstats->rx_length_errors +
@@ -3031,39 +3316,48 @@ static void bnx2x_update_net_stats(struct bnx2x *bp)
3031 nstats->rx_fifo_errors + 3316 nstats->rx_fifo_errors +
3032 nstats->rx_missed_errors; 3317 nstats->rx_missed_errors;
3033 3318
3034 nstats->tx_aborted_errors = estats->late_collision_frames + 3319 nstats->tx_aborted_errors =
3035 estats->excessive_collision_frames; 3320 estats->tx_stat_dot3statslatecollisions_lo +
3036 nstats->tx_carrier_errors = estats->false_carrier_detections; 3321 estats->tx_stat_dot3statsexcessivecollisions_lo;
3322 nstats->tx_carrier_errors = estats->rx_stat_falsecarriererrors_lo;
3037 nstats->tx_fifo_errors = 0; 3323 nstats->tx_fifo_errors = 0;
3038 nstats->tx_heartbeat_errors = 0; 3324 nstats->tx_heartbeat_errors = 0;
3039 nstats->tx_window_errors = 0; 3325 nstats->tx_window_errors = 0;
3040 3326
3041 nstats->tx_errors = nstats->tx_aborted_errors + 3327 nstats->tx_errors = nstats->tx_aborted_errors +
3042 nstats->tx_carrier_errors; 3328 nstats->tx_carrier_errors;
3043
3044 estats->mac_stx_start = ++estats->mac_stx_end;
3045} 3329}
3046 3330
3047static void bnx2x_update_stats(struct bnx2x *bp) 3331static void bnx2x_stats_update(struct bnx2x *bp)
3048{ 3332{
3049 if (!bnx2x_update_storm_stats(bp)) { 3333 u32 *stats_comp = bnx2x_sp(bp, stats_comp);
3334 int update = 0;
3050 3335
3051 if (bp->link_vars.mac_type == MAC_TYPE_BMAC) { 3336 if (*stats_comp != DMAE_COMP_VAL)
3052 bnx2x_update_bmac_stats(bp); 3337 return;
3053 3338
3054 } else if (bp->link_vars.mac_type == MAC_TYPE_EMAC) { 3339 if (bp->port.pmf)
3055 bnx2x_update_emac_stats(bp); 3340 update = (bnx2x_hw_stats_update(bp) == 0);
3056 3341
3057 } else { /* unreached */ 3342 update |= (bnx2x_storm_stats_update(bp) == 0);
3058 BNX2X_ERR("no MAC active\n"); 3343
3059 return; 3344 if (update)
3060 } 3345 bnx2x_net_stats_update(bp);
3061 3346
3062 bnx2x_update_net_stats(bp); 3347 else {
3348 if (bp->stats_pending) {
3349 bp->stats_pending++;
3350 if (bp->stats_pending == 3) {
3351 BNX2X_ERR("stats not updated for 3 times\n");
3352 bnx2x_panic();
3353 return;
3354 }
3355 }
3063 } 3356 }
3064 3357
3065 if (bp->msglevel & NETIF_MSG_TIMER) { 3358 if (bp->msglevel & NETIF_MSG_TIMER) {
3066 struct bnx2x_eth_stats *estats = bnx2x_sp(bp, eth_stats); 3359 struct tstorm_per_client_stats *old_tclient = &bp->old_tclient;
3360 struct bnx2x_eth_stats *estats = &bp->eth_stats;
3067 struct net_device_stats *nstats = &bp->dev->stats; 3361 struct net_device_stats *nstats = &bp->dev->stats;
3068 int i; 3362 int i;
3069 3363
@@ -3078,17 +3372,18 @@ static void bnx2x_update_stats(struct bnx2x *bp)
3078 *bp->fp->rx_cons_sb, nstats->rx_packets); 3372 *bp->fp->rx_cons_sb, nstats->rx_packets);
3079 printk(KERN_DEBUG " %s (Xoff events %u) brb drops %u\n", 3373 printk(KERN_DEBUG " %s (Xoff events %u) brb drops %u\n",
3080 netif_queue_stopped(bp->dev)? "Xoff" : "Xon", 3374 netif_queue_stopped(bp->dev)? "Xoff" : "Xon",
3081 estats->driver_xoff, estats->brb_discard); 3375 estats->driver_xoff, estats->brb_drop_lo);
3082 printk(KERN_DEBUG "tstats: checksum_discard %u " 3376 printk(KERN_DEBUG "tstats: checksum_discard %u "
3083 "packets_too_big_discard %u no_buff_discard %u " 3377 "packets_too_big_discard %u no_buff_discard %u "
3084 "mac_discard %u mac_filter_discard %u " 3378 "mac_discard %u mac_filter_discard %u "
3085 "xxovrflow_discard %u brb_truncate_discard %u " 3379 "xxovrflow_discard %u brb_truncate_discard %u "
3086 "ttl0_discard %u\n", 3380 "ttl0_discard %u\n",
3087 estats->checksum_discard, 3381 old_tclient->checksum_discard,
3088 estats->packets_too_big_discard, 3382 old_tclient->packets_too_big_discard,
3089 estats->no_buff_discard, estats->mac_discard, 3383 old_tclient->no_buff_discard, estats->mac_discard,
3090 estats->mac_filter_discard, estats->xxoverflow_discard, 3384 estats->mac_filter_discard, estats->xxoverflow_discard,
3091 estats->brb_truncate_discard, estats->ttl0_discard); 3385 estats->brb_truncate_discard,
3386 old_tclient->ttl0_discard);
3092 3387
3093 for_each_queue(bp, i) { 3388 for_each_queue(bp, i) {
3094 printk(KERN_DEBUG "[%d]: %lu\t%lu\t%lu\n", i, 3389 printk(KERN_DEBUG "[%d]: %lu\t%lu\t%lu\n", i,
@@ -3098,60 +3393,131 @@ static void bnx2x_update_stats(struct bnx2x *bp)
3098 } 3393 }
3099 } 3394 }
3100 3395
3101 if (bp->state != BNX2X_STATE_OPEN) { 3396 bnx2x_hw_stats_post(bp);
3102 DP(BNX2X_MSG_STATS, "state is %x, returning\n", bp->state); 3397 bnx2x_storm_stats_post(bp);
3103 return; 3398}
3104 }
3105
3106#ifdef BNX2X_STOP_ON_ERROR
3107 if (unlikely(bp->panic))
3108 return;
3109#endif
3110 3399
3111 /* loader */ 3400static void bnx2x_port_stats_stop(struct bnx2x *bp)
3112 if (bp->executer_idx) { 3401{
3113 struct dmae_command *dmae = &bp->dmae; 3402 struct dmae_command *dmae;
3114 int port = BP_PORT(bp); 3403 u32 opcode;
3115 int loader_idx = port * 8; 3404 int loader_idx = PMF_DMAE_C(bp);
3405 u32 *stats_comp = bnx2x_sp(bp, stats_comp);
3116 3406
3117 memset(dmae, 0, sizeof(struct dmae_command)); 3407 bp->executer_idx = 0;
3118 3408
3119 dmae->opcode = (DMAE_CMD_SRC_PCI | DMAE_CMD_DST_GRC | 3409 opcode = (DMAE_CMD_SRC_PCI | DMAE_CMD_DST_GRC |
3120 DMAE_CMD_C_DST_GRC | DMAE_CMD_C_ENABLE | 3410 DMAE_CMD_C_ENABLE |
3121 DMAE_CMD_DST_RESET | 3411 DMAE_CMD_SRC_RESET | DMAE_CMD_DST_RESET |
3122#ifdef __BIG_ENDIAN 3412#ifdef __BIG_ENDIAN
3123 DMAE_CMD_ENDIANITY_B_DW_SWAP | 3413 DMAE_CMD_ENDIANITY_B_DW_SWAP |
3124#else 3414#else
3125 DMAE_CMD_ENDIANITY_DW_SWAP | 3415 DMAE_CMD_ENDIANITY_DW_SWAP |
3126#endif 3416#endif
3127 (port ? DMAE_CMD_PORT_1 : DMAE_CMD_PORT_0)); 3417 (BP_PORT(bp) ? DMAE_CMD_PORT_1 : DMAE_CMD_PORT_0) |
3128 dmae->src_addr_lo = U64_LO(bnx2x_sp_mapping(bp, dmae[0])); 3418 (BP_E1HVN(bp) << DMAE_CMD_E1HVN_SHIFT));
3129 dmae->src_addr_hi = U64_HI(bnx2x_sp_mapping(bp, dmae[0])); 3419
3130 dmae->dst_addr_lo = (DMAE_REG_CMD_MEM + 3420 if (bp->port.port_stx) {
3131 sizeof(struct dmae_command) * 3421
3132 (loader_idx + 1)) >> 2; 3422 dmae = bnx2x_sp(bp, dmae[bp->executer_idx++]);
3423 if (bp->func_stx)
3424 dmae->opcode = (opcode | DMAE_CMD_C_DST_GRC);
3425 else
3426 dmae->opcode = (opcode | DMAE_CMD_C_DST_PCI);
3427 dmae->src_addr_lo = U64_LO(bnx2x_sp_mapping(bp, port_stats));
3428 dmae->src_addr_hi = U64_HI(bnx2x_sp_mapping(bp, port_stats));
3429 dmae->dst_addr_lo = bp->port.port_stx >> 2;
3133 dmae->dst_addr_hi = 0; 3430 dmae->dst_addr_hi = 0;
3134 dmae->len = sizeof(struct dmae_command) >> 2; 3431 dmae->len = sizeof(struct host_port_stats) >> 2;
3135 dmae->len--; /* !!! for A0/1 only */ 3432 if (bp->func_stx) {
3136 dmae->comp_addr_lo = dmae_reg_go_c[loader_idx + 1] >> 2; 3433 dmae->comp_addr_lo = dmae_reg_go_c[loader_idx] >> 2;
3137 dmae->comp_addr_hi = 0; 3434 dmae->comp_addr_hi = 0;
3138 dmae->comp_val = 1; 3435 dmae->comp_val = 1;
3436 } else {
3437 dmae->comp_addr_lo =
3438 U64_LO(bnx2x_sp_mapping(bp, stats_comp));
3439 dmae->comp_addr_hi =
3440 U64_HI(bnx2x_sp_mapping(bp, stats_comp));
3441 dmae->comp_val = DMAE_COMP_VAL;
3139 3442
3140 bnx2x_post_dmae(bp, dmae, loader_idx); 3443 *stats_comp = 0;
3444 }
3141 } 3445 }
3142 3446
3143 if (bp->stats_state != STATS_STATE_ENABLE) { 3447 if (bp->func_stx) {
3144 bp->stats_state = STATS_STATE_DISABLE; 3448
3145 return; 3449 dmae = bnx2x_sp(bp, dmae[bp->executer_idx++]);
3450 dmae->opcode = (opcode | DMAE_CMD_C_DST_PCI);
3451 dmae->src_addr_lo = U64_LO(bnx2x_sp_mapping(bp, func_stats));
3452 dmae->src_addr_hi = U64_HI(bnx2x_sp_mapping(bp, func_stats));
3453 dmae->dst_addr_lo = bp->func_stx >> 2;
3454 dmae->dst_addr_hi = 0;
3455 dmae->len = sizeof(struct host_func_stats) >> 2;
3456 dmae->comp_addr_lo = U64_LO(bnx2x_sp_mapping(bp, stats_comp));
3457 dmae->comp_addr_hi = U64_HI(bnx2x_sp_mapping(bp, stats_comp));
3458 dmae->comp_val = DMAE_COMP_VAL;
3459
3460 *stats_comp = 0;
3146 } 3461 }
3462}
3463
3464static void bnx2x_stats_stop(struct bnx2x *bp)
3465{
3466 int update = 0;
3467
3468 bnx2x_stats_comp(bp);
3469
3470 if (bp->port.pmf)
3471 update = (bnx2x_hw_stats_update(bp) == 0);
3472
3473 update |= (bnx2x_storm_stats_update(bp) == 0);
3474
3475 if (update) {
3476 bnx2x_net_stats_update(bp);
3477
3478 if (bp->port.pmf)
3479 bnx2x_port_stats_stop(bp);
3147 3480
3148 if (bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_STAT_QUERY, 0, 0, 0, 0) == 0) { 3481 bnx2x_hw_stats_post(bp);
3149 /* stats ramrod has it's own slot on the spe */ 3482 bnx2x_stats_comp(bp);
3150 bp->spq_left++;
3151 bp->stat_pending = 1;
3152 } 3483 }
3153} 3484}
3154 3485
3486static void bnx2x_stats_do_nothing(struct bnx2x *bp)
3487{
3488}
3489
3490static const struct {
3491 void (*action)(struct bnx2x *bp);
3492 enum bnx2x_stats_state next_state;
3493} bnx2x_stats_stm[STATS_STATE_MAX][STATS_EVENT_MAX] = {
3494/* state event */
3495{
3496/* DISABLED PMF */ {bnx2x_stats_pmf_update, STATS_STATE_DISABLED},
3497/* LINK_UP */ {bnx2x_stats_start, STATS_STATE_ENABLED},
3498/* UPDATE */ {bnx2x_stats_do_nothing, STATS_STATE_DISABLED},
3499/* STOP */ {bnx2x_stats_do_nothing, STATS_STATE_DISABLED}
3500},
3501{
3502/* ENABLED PMF */ {bnx2x_stats_pmf_start, STATS_STATE_ENABLED},
3503/* LINK_UP */ {bnx2x_stats_restart, STATS_STATE_ENABLED},
3504/* UPDATE */ {bnx2x_stats_update, STATS_STATE_ENABLED},
3505/* STOP */ {bnx2x_stats_stop, STATS_STATE_DISABLED}
3506}
3507};
3508
3509static void bnx2x_stats_handle(struct bnx2x *bp, enum bnx2x_stats_event event)
3510{
3511 enum bnx2x_stats_state state = bp->stats_state;
3512
3513 bnx2x_stats_stm[state][event].action(bp);
3514 bp->stats_state = bnx2x_stats_stm[state][event].next_state;
3515
3516 if ((event != STATS_EVENT_UPDATE) || (bp->msglevel & NETIF_MSG_TIMER))
3517 DP(BNX2X_MSG_STATS, "state %d -> event %d -> state %d\n",
3518 state, event, bp->stats_state);
3519}
3520
3155static void bnx2x_timer(unsigned long data) 3521static void bnx2x_timer(unsigned long data)
3156{ 3522{
3157 struct bnx2x *bp = (struct bnx2x *) data; 3523 struct bnx2x *bp = (struct bnx2x *) data;
@@ -3194,10 +3560,9 @@ static void bnx2x_timer(unsigned long data)
3194 } 3560 }
3195 } 3561 }
3196 3562
3197 if (bp->stats_state == STATS_STATE_DISABLE) 3563 if ((bp->state == BNX2X_STATE_OPEN) ||
3198 goto timer_restart; 3564 (bp->state == BNX2X_STATE_DISABLED))
3199 3565 bnx2x_stats_handle(bp, STATS_EVENT_UPDATE);
3200 bnx2x_update_stats(bp);
3201 3566
3202timer_restart: 3567timer_restart:
3203 mod_timer(&bp->timer, jiffies + bp->current_interval); 3568 mod_timer(&bp->timer, jiffies + bp->current_interval);
@@ -3227,6 +3592,7 @@ static void bnx2x_init_sb(struct bnx2x *bp, int sb_id,
3227 struct host_status_block *sb, dma_addr_t mapping) 3592 struct host_status_block *sb, dma_addr_t mapping)
3228{ 3593{
3229 int port = BP_PORT(bp); 3594 int port = BP_PORT(bp);
3595 int func = BP_FUNC(bp);
3230 int index; 3596 int index;
3231 u64 section; 3597 u64 section;
3232 3598
@@ -3240,6 +3606,8 @@ static void bnx2x_init_sb(struct bnx2x *bp, int sb_id,
3240 REG_WR(bp, BAR_USTRORM_INTMEM + 3606 REG_WR(bp, BAR_USTRORM_INTMEM +
3241 ((USTORM_SB_HOST_SB_ADDR_OFFSET(port, sb_id)) + 4), 3607 ((USTORM_SB_HOST_SB_ADDR_OFFSET(port, sb_id)) + 4),
3242 U64_HI(section)); 3608 U64_HI(section));
3609 REG_WR8(bp, BAR_USTRORM_INTMEM + FP_USB_FUNC_OFF +
3610 USTORM_SB_HOST_STATUS_BLOCK_OFFSET(port, sb_id), func);
3243 3611
3244 for (index = 0; index < HC_USTORM_SB_NUM_INDICES; index++) 3612 for (index = 0; index < HC_USTORM_SB_NUM_INDICES; index++)
3245 REG_WR16(bp, BAR_USTRORM_INTMEM + 3613 REG_WR16(bp, BAR_USTRORM_INTMEM +
@@ -3411,6 +3779,8 @@ static void bnx2x_init_def_sb(struct bnx2x *bp,
3411 REG_WR16(bp, BAR_XSTRORM_INTMEM + 3779 REG_WR16(bp, BAR_XSTRORM_INTMEM +
3412 XSTORM_DEF_SB_HC_DISABLE_OFFSET(func, index), 1); 3780 XSTORM_DEF_SB_HC_DISABLE_OFFSET(func, index), 1);
3413 3781
3782 bp->stats_pending = 0;
3783
3414 bnx2x_ack_sb(bp, sb_id, CSTORM_ID, 0, IGU_INT_ENABLE, 0); 3784 bnx2x_ack_sb(bp, sb_id, CSTORM_ID, 0, IGU_INT_ENABLE, 0);
3415} 3785}
3416 3786
@@ -3804,7 +4174,7 @@ static void bnx2x_nic_init(struct bnx2x *bp)
3804 bnx2x_init_sp_ring(bp); 4174 bnx2x_init_sp_ring(bp);
3805 bnx2x_init_context(bp); 4175 bnx2x_init_context(bp);
3806 bnx2x_init_internal(bp); 4176 bnx2x_init_internal(bp);
3807 bnx2x_init_stats(bp); 4177 bnx2x_storm_stats_init(bp);
3808 bnx2x_init_ind_table(bp); 4178 bnx2x_init_ind_table(bp);
3809 bnx2x_int_enable(bp); 4179 bnx2x_int_enable(bp);
3810} 4180}
@@ -5339,6 +5709,8 @@ static int bnx2x_nic_load(struct bnx2x *bp, int load_mode)
5339 } 5709 }
5340 } 5710 }
5341 5711
5712 bnx2x_stats_init(bp);
5713
5342 bp->state = BNX2X_STATE_OPENING_WAIT4_PORT; 5714 bp->state = BNX2X_STATE_OPENING_WAIT4_PORT;
5343 5715
5344 /* Enable Rx interrupt handling before sending the ramrod 5716 /* Enable Rx interrupt handling before sending the ramrod
@@ -5595,6 +5967,7 @@ static int bnx2x_nic_unload(struct bnx2x *bp, int unload_mode)
5595 del_timer_sync(&bp->timer); 5967 del_timer_sync(&bp->timer);
5596 SHMEM_WR(bp, func_mb[BP_FUNC(bp)].drv_pulse_mb, 5968 SHMEM_WR(bp, func_mb[BP_FUNC(bp)].drv_pulse_mb,
5597 (DRV_PULSE_ALWAYS_ALIVE | bp->fw_drv_pulse_wr_seq)); 5969 (DRV_PULSE_ALWAYS_ALIVE | bp->fw_drv_pulse_wr_seq));
5970 bnx2x_stats_handle(bp, STATS_EVENT_STOP);
5598 5971
5599 /* Wait until all fast path tasks complete */ 5972 /* Wait until all fast path tasks complete */
5600 for_each_queue(bp, i) { 5973 for_each_queue(bp, i) {
@@ -6641,7 +7014,7 @@ static int bnx2x_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
6641 bp->port.advertising); 7014 bp->port.advertising);
6642 7015
6643 if (netif_running(dev)) { 7016 if (netif_running(dev)) {
6644 bnx2x_stop_stats(bp); 7017 bnx2x_stats_handle(bp, STATS_EVENT_STOP);
6645 bnx2x_link_set(bp); 7018 bnx2x_link_set(bp);
6646 } 7019 }
6647 7020
@@ -6738,7 +7111,7 @@ static int bnx2x_nway_reset(struct net_device *dev)
6738 return 0; 7111 return 0;
6739 7112
6740 if (netif_running(dev)) { 7113 if (netif_running(dev)) {
6741 bnx2x_stop_stats(bp); 7114 bnx2x_stats_handle(bp, STATS_EVENT_STOP);
6742 bnx2x_link_set(bp); 7115 bnx2x_link_set(bp);
6743 } 7116 }
6744 7117
@@ -7128,10 +7501,13 @@ static int bnx2x_set_eeprom(struct net_device *dev,
7128 bp->link_params.ext_phy_config, 7501 bp->link_params.ext_phy_config,
7129 (bp->state != BNX2X_STATE_CLOSED), 7502 (bp->state != BNX2X_STATE_CLOSED),
7130 eebuf, eeprom->len); 7503 eebuf, eeprom->len);
7504 if ((bp->state == BNX2X_STATE_OPEN) ||
7505 (bp->state == BNX2X_STATE_DISABLED)) {
7131 rc |= bnx2x_link_reset(&bp->link_params, 7506 rc |= bnx2x_link_reset(&bp->link_params,
7132 &bp->link_vars); 7507 &bp->link_vars);
7133 rc |= bnx2x_phy_init(&bp->link_params, 7508 rc |= bnx2x_phy_init(&bp->link_params,
7134 &bp->link_vars); 7509 &bp->link_vars);
7510 }
7135 bnx2x_phy_hw_unlock(bp); 7511 bnx2x_phy_hw_unlock(bp);
7136 7512
7137 } else /* Only the PMF can access the PHY */ 7513 } else /* Only the PMF can access the PHY */
@@ -7274,7 +7650,7 @@ static int bnx2x_set_pauseparam(struct net_device *dev,
7274 "req_flow_ctrl 0x%x\n", bp->link_params.req_flow_ctrl); 7650 "req_flow_ctrl 0x%x\n", bp->link_params.req_flow_ctrl);
7275 7651
7276 if (netif_running(dev)) { 7652 if (netif_running(dev)) {
7277 bnx2x_stop_stats(bp); 7653 bnx2x_stats_handle(bp, STATS_EVENT_STOP);
7278 bnx2x_link_set(bp); 7654 bnx2x_link_set(bp);
7279 } 7655 }
7280 7656
@@ -7330,7 +7706,6 @@ static void bnx2x_self_test(struct net_device *dev,
7330 } 7706 }
7331 7707
7332 stats_state = bp->stats_state; 7708 stats_state = bp->stats_state;
7333 bnx2x_stop_stats(bp);
7334 7709
7335 if (bnx2x_mc_assert(bp) != 0) { 7710 if (bnx2x_mc_assert(bp) != 0) {
7336 buf[0] = 1; 7711 buf[0] = 1;
@@ -7340,100 +7715,96 @@ static void bnx2x_self_test(struct net_device *dev,
7340#ifdef BNX2X_EXTRA_DEBUG 7715#ifdef BNX2X_EXTRA_DEBUG
7341 bnx2x_panic_dump(bp); 7716 bnx2x_panic_dump(bp);
7342#endif 7717#endif
7343 bp->stats_state = stats_state;
7344} 7718}
7345 7719
7346static struct { 7720static const struct {
7721 long offset;
7722 int size;
7723 u32 flags;
7347 char string[ETH_GSTRING_LEN]; 7724 char string[ETH_GSTRING_LEN];
7348} bnx2x_stats_str_arr[BNX2X_NUM_STATS] = { 7725} bnx2x_stats_arr[BNX2X_NUM_STATS] = {
7349 { "rx_bytes"}, 7726/* 1 */ { STATS_OFFSET32(valid_bytes_received_hi), 8, 1, "rx_bytes" },
7350 { "rx_error_bytes"}, 7727 { STATS_OFFSET32(error_bytes_received_hi), 8, 1, "rx_error_bytes" },
7351 { "tx_bytes"}, 7728 { STATS_OFFSET32(total_bytes_transmitted_hi), 8, 1, "tx_bytes" },
7352 { "tx_error_bytes"}, 7729 { STATS_OFFSET32(tx_stat_ifhcoutbadoctets_hi), 8, 0, "tx_error_bytes" },
7353 { "rx_ucast_packets"}, 7730 { STATS_OFFSET32(total_unicast_packets_received_hi),
7354 { "rx_mcast_packets"}, 7731 8, 1, "rx_ucast_packets" },
7355 { "rx_bcast_packets"}, 7732 { STATS_OFFSET32(total_multicast_packets_received_hi),
7356 { "tx_ucast_packets"}, 7733 8, 1, "rx_mcast_packets" },
7357 { "tx_mcast_packets"}, 7734 { STATS_OFFSET32(total_broadcast_packets_received_hi),
7358 { "tx_bcast_packets"}, 7735 8, 1, "rx_bcast_packets" },
7359 { "tx_mac_errors"}, /* 10 */ 7736 { STATS_OFFSET32(total_unicast_packets_transmitted_hi),
7360 { "tx_carrier_errors"}, 7737 8, 1, "tx_packets" },
7361 { "rx_crc_errors"}, 7738 { STATS_OFFSET32(tx_stat_dot3statsinternalmactransmiterrors_hi),
7362 { "rx_align_errors"}, 7739 8, 0, "tx_mac_errors" },
7363 { "tx_single_collisions"}, 7740/* 10 */{ STATS_OFFSET32(rx_stat_dot3statscarriersenseerrors_hi),
7364 { "tx_multi_collisions"}, 7741 8, 0, "tx_carrier_errors" },
7365 { "tx_deferred"}, 7742 { STATS_OFFSET32(rx_stat_dot3statsfcserrors_hi),
7366 { "tx_excess_collisions"}, 7743 8, 0, "rx_crc_errors" },
7367 { "tx_late_collisions"}, 7744 { STATS_OFFSET32(rx_stat_dot3statsalignmenterrors_hi),
7368 { "tx_total_collisions"}, 7745 8, 0, "rx_align_errors" },
7369 { "rx_fragments"}, /* 20 */ 7746 { STATS_OFFSET32(tx_stat_dot3statssinglecollisionframes_hi),
7370 { "rx_jabbers"}, 7747 8, 0, "tx_single_collisions" },
7371 { "rx_undersize_packets"}, 7748 { STATS_OFFSET32(tx_stat_dot3statsmultiplecollisionframes_hi),
7372 { "rx_oversize_packets"}, 7749 8, 0, "tx_multi_collisions" },
7373 { "rx_xon_frames"}, 7750 { STATS_OFFSET32(tx_stat_dot3statsdeferredtransmissions_hi),
7374 { "rx_xoff_frames"}, 7751 8, 0, "tx_deferred" },
7375 { "tx_xon_frames"}, 7752 { STATS_OFFSET32(tx_stat_dot3statsexcessivecollisions_hi),
7376 { "tx_xoff_frames"}, 7753 8, 0, "tx_excess_collisions" },
7377 { "rx_mac_ctrl_frames"}, 7754 { STATS_OFFSET32(tx_stat_dot3statslatecollisions_hi),
7378 { "rx_filtered_packets"}, 7755 8, 0, "tx_late_collisions" },
7379 { "rx_discards"}, /* 30 */ 7756 { STATS_OFFSET32(tx_stat_etherstatscollisions_hi),
7380 { "brb_discard"}, 7757 8, 0, "tx_total_collisions" },
7381 { "brb_truncate"}, 7758 { STATS_OFFSET32(rx_stat_etherstatsfragments_hi),
7382 { "xxoverflow"} 7759 8, 0, "rx_fragments" },
7383}; 7760/* 20 */{ STATS_OFFSET32(rx_stat_etherstatsjabbers_hi), 8, 0, "rx_jabbers" },
7384 7761 { STATS_OFFSET32(rx_stat_etherstatsundersizepkts_hi),
7385#define STATS_OFFSET32(offset_name) \ 7762 8, 0, "rx_undersize_packets" },
7386 (offsetof(struct bnx2x_eth_stats, offset_name) / 4) 7763 { STATS_OFFSET32(jabber_packets_received),
7387 7764 4, 1, "rx_oversize_packets" },
7388static unsigned long bnx2x_stats_offset_arr[BNX2X_NUM_STATS] = { 7765 { STATS_OFFSET32(tx_stat_etherstatspkts64octets_hi),
7389 STATS_OFFSET32(total_bytes_received_hi), 7766 8, 0, "tx_64_byte_packets" },
7390 STATS_OFFSET32(stat_IfHCInBadOctets_hi), 7767 { STATS_OFFSET32(tx_stat_etherstatspkts65octetsto127octets_hi),
7391 STATS_OFFSET32(total_bytes_transmitted_hi), 7768 8, 0, "tx_65_to_127_byte_packets" },
7392 STATS_OFFSET32(stat_IfHCOutBadOctets_hi), 7769 { STATS_OFFSET32(tx_stat_etherstatspkts128octetsto255octets_hi),
7393 STATS_OFFSET32(total_unicast_packets_received_hi), 7770 8, 0, "tx_128_to_255_byte_packets" },
7394 STATS_OFFSET32(total_multicast_packets_received_hi), 7771 { STATS_OFFSET32(tx_stat_etherstatspkts256octetsto511octets_hi),
7395 STATS_OFFSET32(total_broadcast_packets_received_hi), 7772 8, 0, "tx_256_to_511_byte_packets" },
7396 STATS_OFFSET32(total_unicast_packets_transmitted_hi), 7773 { STATS_OFFSET32(tx_stat_etherstatspkts512octetsto1023octets_hi),
7397 STATS_OFFSET32(total_multicast_packets_transmitted_hi), 7774 8, 0, "tx_512_to_1023_byte_packets" },
7398 STATS_OFFSET32(total_broadcast_packets_transmitted_hi), 7775 { STATS_OFFSET32(etherstatspkts1024octetsto1522octets_hi),
7399 STATS_OFFSET32(stat_Dot3statsInternalMacTransmitErrors), /* 10 */ 7776 8, 0, "tx_1024_to_1522_byte_packets" },
7400 STATS_OFFSET32(stat_Dot3StatsCarrierSenseErrors), 7777 { STATS_OFFSET32(etherstatspktsover1522octets_hi),
7401 STATS_OFFSET32(crc_receive_errors), 7778 8, 0, "tx_1523_to_9022_byte_packets" },
7402 STATS_OFFSET32(alignment_errors), 7779/* 30 */{ STATS_OFFSET32(rx_stat_xonpauseframesreceived_hi),
7403 STATS_OFFSET32(single_collision_transmit_frames), 7780 8, 0, "rx_xon_frames" },
7404 STATS_OFFSET32(multiple_collision_transmit_frames), 7781 { STATS_OFFSET32(rx_stat_xoffpauseframesreceived_hi),
7405 STATS_OFFSET32(stat_Dot3StatsDeferredTransmissions), 7782 8, 0, "rx_xoff_frames" },
7406 STATS_OFFSET32(excessive_collision_frames), 7783 { STATS_OFFSET32(tx_stat_outxonsent_hi), 8, 0, "tx_xon_frames" },
7407 STATS_OFFSET32(late_collision_frames), 7784 { STATS_OFFSET32(tx_stat_outxoffsent_hi), 8, 0, "tx_xoff_frames" },
7408 STATS_OFFSET32(number_of_bugs_found_in_stats_spec), 7785 { STATS_OFFSET32(rx_stat_maccontrolframesreceived_hi),
7409 STATS_OFFSET32(runt_packets_received), /* 20 */ 7786 8, 0, "rx_mac_ctrl_frames" },
7410 STATS_OFFSET32(jabber_packets_received), 7787 { STATS_OFFSET32(mac_filter_discard), 4, 1, "rx_filtered_packets" },
7411 STATS_OFFSET32(error_runt_packets_received), 7788 { STATS_OFFSET32(no_buff_discard), 4, 1, "rx_discards" },
7412 STATS_OFFSET32(error_jabber_packets_received), 7789 { STATS_OFFSET32(xxoverflow_discard), 4, 1, "rx_fw_discards" },
7413 STATS_OFFSET32(pause_xon_frames_received), 7790 { STATS_OFFSET32(brb_drop_hi), 8, 1, "brb_discard" },
7414 STATS_OFFSET32(pause_xoff_frames_received), 7791/* 39 */{ STATS_OFFSET32(brb_truncate_discard), 8, 1, "brb_truncate" }
7415 STATS_OFFSET32(pause_xon_frames_transmitted),
7416 STATS_OFFSET32(pause_xoff_frames_transmitted),
7417 STATS_OFFSET32(control_frames_received),
7418 STATS_OFFSET32(mac_filter_discard),
7419 STATS_OFFSET32(no_buff_discard), /* 30 */
7420 STATS_OFFSET32(brb_discard),
7421 STATS_OFFSET32(brb_truncate_discard),
7422 STATS_OFFSET32(xxoverflow_discard)
7423};
7424
7425static u8 bnx2x_stats_len_arr[BNX2X_NUM_STATS] = {
7426 8, 0, 8, 0, 8, 8, 8, 8, 8, 8,
7427 4, 0, 4, 4, 4, 4, 4, 4, 4, 4,
7428 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
7429 4, 4, 4, 4
7430}; 7792};
7431 7793
7432static void bnx2x_get_strings(struct net_device *dev, u32 stringset, u8 *buf) 7794static void bnx2x_get_strings(struct net_device *dev, u32 stringset, u8 *buf)
7433{ 7795{
7796 struct bnx2x *bp = netdev_priv(dev);
7797 int i, j;
7798
7434 switch (stringset) { 7799 switch (stringset) {
7435 case ETH_SS_STATS: 7800 case ETH_SS_STATS:
7436 memcpy(buf, bnx2x_stats_str_arr, sizeof(bnx2x_stats_str_arr)); 7801 for (i = 0, j = 0; i < BNX2X_NUM_STATS; i++) {
7802 if (IS_E1HMF(bp) && (!bnx2x_stats_arr[i].flags))
7803 continue;
7804 strcpy(buf + j*ETH_GSTRING_LEN,
7805 bnx2x_stats_arr[i].string);
7806 j++;
7807 }
7437 break; 7808 break;
7438 7809
7439 case ETH_SS_TEST: 7810 case ETH_SS_TEST:
@@ -7444,34 +7815,44 @@ static void bnx2x_get_strings(struct net_device *dev, u32 stringset, u8 *buf)
7444 7815
7445static int bnx2x_get_stats_count(struct net_device *dev) 7816static int bnx2x_get_stats_count(struct net_device *dev)
7446{ 7817{
7447 return BNX2X_NUM_STATS; 7818 struct bnx2x *bp = netdev_priv(dev);
7819 int i, num_stats = 0;
7820
7821 for (i = 0; i < BNX2X_NUM_STATS; i++) {
7822 if (IS_E1HMF(bp) && (!bnx2x_stats_arr[i].flags))
7823 continue;
7824 num_stats++;
7825 }
7826 return num_stats;
7448} 7827}
7449 7828
7450static void bnx2x_get_ethtool_stats(struct net_device *dev, 7829static void bnx2x_get_ethtool_stats(struct net_device *dev,
7451 struct ethtool_stats *stats, u64 *buf) 7830 struct ethtool_stats *stats, u64 *buf)
7452{ 7831{
7453 struct bnx2x *bp = netdev_priv(dev); 7832 struct bnx2x *bp = netdev_priv(dev);
7454 u32 *hw_stats = (u32 *)bnx2x_sp_check(bp, eth_stats); 7833 u32 *hw_stats = (u32 *)&bp->eth_stats;
7455 int i; 7834 int i, j;
7456 7835
7457 for (i = 0; i < BNX2X_NUM_STATS; i++) { 7836 for (i = 0, j = 0; i < BNX2X_NUM_STATS; i++) {
7458 if (bnx2x_stats_len_arr[i] == 0) { 7837 if (IS_E1HMF(bp) && (!bnx2x_stats_arr[i].flags))
7459 /* skip this counter */
7460 buf[i] = 0;
7461 continue; 7838 continue;
7462 } 7839
7463 if (!hw_stats) { 7840 if (bnx2x_stats_arr[i].size == 0) {
7464 buf[i] = 0; 7841 /* skip this counter */
7842 buf[j] = 0;
7843 j++;
7465 continue; 7844 continue;
7466 } 7845 }
7467 if (bnx2x_stats_len_arr[i] == 4) { 7846 if (bnx2x_stats_arr[i].size == 4) {
7468 /* 4-byte counter */ 7847 /* 4-byte counter */
7469 buf[i] = (u64) *(hw_stats + bnx2x_stats_offset_arr[i]); 7848 buf[j] = (u64) *(hw_stats + bnx2x_stats_arr[i].offset);
7849 j++;
7470 continue; 7850 continue;
7471 } 7851 }
7472 /* 8-byte counter */ 7852 /* 8-byte counter */
7473 buf[i] = HILO_U64(*(hw_stats + bnx2x_stats_offset_arr[i]), 7853 buf[j] = HILO_U64(*(hw_stats + bnx2x_stats_arr[i].offset),
7474 *(hw_stats + bnx2x_stats_offset_arr[i] + 1)); 7854 *(hw_stats + bnx2x_stats_arr[i].offset + 1));
7855 j++;
7475 } 7856 }
7476} 7857}
7477 7858
@@ -7546,7 +7927,7 @@ static struct ethtool_ops bnx2x_ethtool_ops = {
7546 .get_strings = bnx2x_get_strings, 7927 .get_strings = bnx2x_get_strings,
7547 .phys_id = bnx2x_phys_id, 7928 .phys_id = bnx2x_phys_id,
7548 .get_stats_count = bnx2x_get_stats_count, 7929 .get_stats_count = bnx2x_get_stats_count,
7549 .get_ethtool_stats = bnx2x_get_ethtool_stats 7930 .get_ethtool_stats = bnx2x_get_ethtool_stats,
7550}; 7931};
7551 7932
7552/* end of ethtool_ops */ 7933/* end of ethtool_ops */
@@ -7665,7 +8046,7 @@ static int bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev)
7665 fp = &bp->fp[fp_index]; 8046 fp = &bp->fp[fp_index];
7666 if (unlikely(bnx2x_tx_avail(bp->fp) < 8047 if (unlikely(bnx2x_tx_avail(bp->fp) <
7667 (skb_shinfo(skb)->nr_frags + 3))) { 8048 (skb_shinfo(skb)->nr_frags + 3))) {
7668 bp->slowpath->eth_stats.driver_xoff++, 8049 bp->eth_stats.driver_xoff++,
7669 netif_stop_queue(dev); 8050 netif_stop_queue(dev);
7670 BNX2X_ERR("BUG! Tx ring full when queue awake!\n"); 8051 BNX2X_ERR("BUG! Tx ring full when queue awake!\n");
7671 return NETDEV_TX_BUSY; 8052 return NETDEV_TX_BUSY;
@@ -7897,7 +8278,7 @@ static int bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev)
7897 8278
7898 if (unlikely(bnx2x_tx_avail(fp) < MAX_SKB_FRAGS + 3)) { 8279 if (unlikely(bnx2x_tx_avail(fp) < MAX_SKB_FRAGS + 3)) {
7899 netif_stop_queue(dev); 8280 netif_stop_queue(dev);
7900 bp->slowpath->eth_stats.driver_xoff++; 8281 bp->eth_stats.driver_xoff++;
7901 if (bnx2x_tx_avail(fp) >= MAX_SKB_FRAGS + 3) 8282 if (bnx2x_tx_avail(fp) >= MAX_SKB_FRAGS + 3)
7902 netif_wake_queue(dev); 8283 netif_wake_queue(dev);
7903 } 8284 }
@@ -7906,26 +8287,26 @@ static int bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev)
7906 return NETDEV_TX_OK; 8287 return NETDEV_TX_OK;
7907} 8288}
7908 8289
7909/* Called with rtnl_lock */ 8290/* called with rtnl_lock */
7910static int bnx2x_open(struct net_device *dev) 8291static int bnx2x_open(struct net_device *dev)
7911{ 8292{
7912 struct bnx2x *bp = netdev_priv(dev); 8293 struct bnx2x *bp = netdev_priv(dev);
7913 8294
7914 bnx2x_set_power_state(bp, PCI_D0); 8295 bnx2x_set_power_state(bp, PCI_D0);
7915 8296
7916 return bnx2x_nic_load(bp, 1); 8297 return bnx2x_nic_load(bp, LOAD_OPEN);
7917} 8298}
7918 8299
7919/* Called with rtnl_lock */ 8300/* called with rtnl_lock */
7920static int bnx2x_close(struct net_device *dev) 8301static int bnx2x_close(struct net_device *dev)
7921{ 8302{
7922 struct bnx2x *bp = netdev_priv(dev); 8303 struct bnx2x *bp = netdev_priv(dev);
7923 8304
7924 /* Unload the driver, release IRQs */ 8305 /* Unload the driver, release IRQs */
7925 bnx2x_nic_unload(bp, 1); 8306 bnx2x_nic_unload(bp, UNLOAD_CLOSE);
7926 8307 if (atomic_read(&bp->pdev->enable_cnt) == 1)
7927 if (!CHIP_REV_IS_SLOW(bp)) 8308 if (!CHIP_REV_IS_SLOW(bp))
7928 bnx2x_set_power_state(bp, PCI_D3hot); 8309 bnx2x_set_power_state(bp, PCI_D3hot);
7929 8310
7930 return 0; 8311 return 0;
7931} 8312}