diff options
author | Yitchak Gertner <gertner@broadcom.com> | 2008-06-23 23:33:36 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2008-06-23 23:33:36 -0400 |
commit | bb2a0f7ae477740d947b442f640a5d10b51025c0 (patch) | |
tree | f12e40c057551dc645bfefd818523fec34b578db /drivers/net/bnx2x_main.c | |
parent | 34f80b04f325078ff21123579343d99756ad8d0e (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.c | 1455 |
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 | ||
575 | static void bnx2x_int_enable(struct bnx2x *bp) | 575 | static 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 | ||
1283 | static 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 | ||
2514 | static void bnx2x_init_mac_stats(struct bnx2x *bp) | 2555 | static 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 | |||
2586 | static 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 | |||
2607 | static 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 | |||
2640 | static 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 | |||
2686 | static 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 | |||
2707 | static 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 | |||
2762 | static 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 | ||
2686 | static void bnx2x_init_stats(struct bnx2x *bp) | 2970 | static 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); | 3006 | static 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 | |||
3018 | static 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 | |||
3025 | static void bnx2x_stats_restart(struct bnx2x *bp) | ||
3026 | { | ||
3027 | bnx2x_stats_comp(bp); | ||
3028 | bnx2x_stats_start(bp); | ||
3029 | } | ||
3030 | |||
3031 | static 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 | |||
3069 | static 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 | |||
3107 | static 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 | ||
2727 | static 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 | /* | 3145 | static int bnx2x_storm_stats_update(struct bnx2x *bp) |
2749 | * Statistics service functions | ||
2750 | */ | ||
2751 | |||
2752 | static 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 | |||
2809 | static 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 | |||
2874 | static 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 | ||
2988 | static void bnx2x_update_net_stats(struct bnx2x *bp) | 3265 | static 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 | ||
3047 | static void bnx2x_update_stats(struct bnx2x *bp) | 3331 | static 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 */ | 3400 | static 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 | |||
3464 | static 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 | ||
3486 | static void bnx2x_stats_do_nothing(struct bnx2x *bp) | ||
3487 | { | ||
3488 | } | ||
3489 | |||
3490 | static 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 | |||
3509 | static 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 | |||
3155 | static void bnx2x_timer(unsigned long data) | 3521 | static 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 | ||
3202 | timer_restart: | 3567 | timer_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 | ||
7346 | static struct { | 7720 | static 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" }, | |
7388 | static 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 | |||
7425 | static 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 | ||
7432 | static void bnx2x_get_strings(struct net_device *dev, u32 stringset, u8 *buf) | 7794 | static 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 | ||
7445 | static int bnx2x_get_stats_count(struct net_device *dev) | 7816 | static 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 | ||
7450 | static void bnx2x_get_ethtool_stats(struct net_device *dev, | 7829 | static 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 */ |
7910 | static int bnx2x_open(struct net_device *dev) | 8291 | static 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 */ |
7920 | static int bnx2x_close(struct net_device *dev) | 8301 | static 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 | } |