diff options
author | Dmitry Kravkov <dmitry@broadcom.com> | 2010-07-27 08:36:15 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2010-07-27 23:35:42 -0400 |
commit | 6c719d00bd99113a4af417620d891aeba98b8d03 (patch) | |
tree | 37ea9444a060e0fae54219d890d980aca0fdba86 | |
parent | de0c62dba71389bcf3d9249d6e6edbc5a032c5ce (diff) |
bnx2x: Move statistics handling code to bnx2x_stats.*
Signed-off-by: Dmitry Kravkov <dmitry@broadcom.com>
Signed-off-by: Eilon Greenstein <eilong@broadcom.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | drivers/net/bnx2x/Makefile | 2 | ||||
-rw-r--r-- | drivers/net/bnx2x/bnx2x.h | 212 | ||||
-rw-r--r-- | drivers/net/bnx2x/bnx2x_main.c | 1388 | ||||
-rw-r--r-- | drivers/net/bnx2x/bnx2x_stats.c | 1400 | ||||
-rw-r--r-- | drivers/net/bnx2x/bnx2x_stats.h | 239 |
5 files changed, 1647 insertions, 1594 deletions
diff --git a/drivers/net/bnx2x/Makefile b/drivers/net/bnx2x/Makefile index 1cdd1e9e4c52..084afce89ae9 100644 --- a/drivers/net/bnx2x/Makefile +++ b/drivers/net/bnx2x/Makefile | |||
@@ -4,4 +4,4 @@ | |||
4 | 4 | ||
5 | obj-$(CONFIG_BNX2X) += bnx2x.o | 5 | obj-$(CONFIG_BNX2X) += bnx2x.o |
6 | 6 | ||
7 | bnx2x-objs := bnx2x_main.o bnx2x_link.o bnx2x_cmn.o bnx2x_ethtool.o | 7 | bnx2x-objs := bnx2x_main.o bnx2x_link.o bnx2x_cmn.o bnx2x_ethtool.o bnx2x_stats.o |
diff --git a/drivers/net/bnx2x/bnx2x.h b/drivers/net/bnx2x/bnx2x.h index ed7058fe94cd..383e13ee1dbb 100644 --- a/drivers/net/bnx2x/bnx2x.h +++ b/drivers/net/bnx2x/bnx2x.h | |||
@@ -54,6 +54,7 @@ | |||
54 | #include "bnx2x_fw_defs.h" | 54 | #include "bnx2x_fw_defs.h" |
55 | #include "bnx2x_hsi.h" | 55 | #include "bnx2x_hsi.h" |
56 | #include "bnx2x_link.h" | 56 | #include "bnx2x_link.h" |
57 | #include "bnx2x_stats.h" | ||
57 | 58 | ||
58 | /* error/debug prints */ | 59 | /* error/debug prints */ |
59 | 60 | ||
@@ -111,6 +112,7 @@ do { \ | |||
111 | dev_info(&bp->pdev->dev, __fmt, ##__args); \ | 112 | dev_info(&bp->pdev->dev, __fmt, ##__args); \ |
112 | } while (0) | 113 | } while (0) |
113 | 114 | ||
115 | void bnx2x_panic_dump(struct bnx2x *bp); | ||
114 | 116 | ||
115 | #ifdef BNX2X_STOP_ON_ERROR | 117 | #ifdef BNX2X_STOP_ON_ERROR |
116 | #define bnx2x_panic() do { \ | 118 | #define bnx2x_panic() do { \ |
@@ -253,43 +255,6 @@ union db_prod { | |||
253 | #define NEXT_SGE_MASK_ELEM(el) (((el) + 1) & RX_SGE_MASK_LEN_MASK) | 255 | #define NEXT_SGE_MASK_ELEM(el) (((el) + 1) & RX_SGE_MASK_LEN_MASK) |
254 | 256 | ||
255 | 257 | ||
256 | struct bnx2x_eth_q_stats { | ||
257 | u32 total_bytes_received_hi; | ||
258 | u32 total_bytes_received_lo; | ||
259 | u32 total_bytes_transmitted_hi; | ||
260 | u32 total_bytes_transmitted_lo; | ||
261 | u32 total_unicast_packets_received_hi; | ||
262 | u32 total_unicast_packets_received_lo; | ||
263 | u32 total_multicast_packets_received_hi; | ||
264 | u32 total_multicast_packets_received_lo; | ||
265 | u32 total_broadcast_packets_received_hi; | ||
266 | u32 total_broadcast_packets_received_lo; | ||
267 | u32 total_unicast_packets_transmitted_hi; | ||
268 | u32 total_unicast_packets_transmitted_lo; | ||
269 | u32 total_multicast_packets_transmitted_hi; | ||
270 | u32 total_multicast_packets_transmitted_lo; | ||
271 | u32 total_broadcast_packets_transmitted_hi; | ||
272 | u32 total_broadcast_packets_transmitted_lo; | ||
273 | u32 valid_bytes_received_hi; | ||
274 | u32 valid_bytes_received_lo; | ||
275 | |||
276 | u32 error_bytes_received_hi; | ||
277 | u32 error_bytes_received_lo; | ||
278 | u32 etherstatsoverrsizepkts_hi; | ||
279 | u32 etherstatsoverrsizepkts_lo; | ||
280 | u32 no_buff_discard_hi; | ||
281 | u32 no_buff_discard_lo; | ||
282 | |||
283 | u32 driver_xoff; | ||
284 | u32 rx_err_discard_pkt; | ||
285 | u32 rx_skb_alloc_failed; | ||
286 | u32 hw_csum_err; | ||
287 | }; | ||
288 | |||
289 | #define BNX2X_NUM_Q_STATS 13 | ||
290 | #define Q_STATS_OFFSET32(stat_name) \ | ||
291 | (offsetof(struct bnx2x_eth_q_stats, stat_name) / 4) | ||
292 | |||
293 | struct bnx2x_fastpath { | 258 | struct bnx2x_fastpath { |
294 | 259 | ||
295 | struct napi_struct napi; | 260 | struct napi_struct napi; |
@@ -598,27 +563,6 @@ struct bnx2x_common { | |||
598 | 563 | ||
599 | /* port */ | 564 | /* port */ |
600 | 565 | ||
601 | struct nig_stats { | ||
602 | u32 brb_discard; | ||
603 | u32 brb_packet; | ||
604 | u32 brb_truncate; | ||
605 | u32 flow_ctrl_discard; | ||
606 | u32 flow_ctrl_octets; | ||
607 | u32 flow_ctrl_packet; | ||
608 | u32 mng_discard; | ||
609 | u32 mng_octet_inp; | ||
610 | u32 mng_octet_out; | ||
611 | u32 mng_packet_inp; | ||
612 | u32 mng_packet_out; | ||
613 | u32 pbf_octets; | ||
614 | u32 pbf_packet; | ||
615 | u32 safc_inp; | ||
616 | u32 egress_mac_pkt0_lo; | ||
617 | u32 egress_mac_pkt0_hi; | ||
618 | u32 egress_mac_pkt1_lo; | ||
619 | u32 egress_mac_pkt1_hi; | ||
620 | }; | ||
621 | |||
622 | struct bnx2x_port { | 566 | struct bnx2x_port { |
623 | u32 pmf; | 567 | u32 pmf; |
624 | 568 | ||
@@ -646,156 +590,6 @@ struct bnx2x_port { | |||
646 | /* end of port */ | 590 | /* end of port */ |
647 | 591 | ||
648 | 592 | ||
649 | enum bnx2x_stats_event { | ||
650 | STATS_EVENT_PMF = 0, | ||
651 | STATS_EVENT_LINK_UP, | ||
652 | STATS_EVENT_UPDATE, | ||
653 | STATS_EVENT_STOP, | ||
654 | STATS_EVENT_MAX | ||
655 | }; | ||
656 | |||
657 | enum bnx2x_stats_state { | ||
658 | STATS_STATE_DISABLED = 0, | ||
659 | STATS_STATE_ENABLED, | ||
660 | STATS_STATE_MAX | ||
661 | }; | ||
662 | |||
663 | struct bnx2x_eth_stats { | ||
664 | u32 total_bytes_received_hi; | ||
665 | u32 total_bytes_received_lo; | ||
666 | u32 total_bytes_transmitted_hi; | ||
667 | u32 total_bytes_transmitted_lo; | ||
668 | u32 total_unicast_packets_received_hi; | ||
669 | u32 total_unicast_packets_received_lo; | ||
670 | u32 total_multicast_packets_received_hi; | ||
671 | u32 total_multicast_packets_received_lo; | ||
672 | u32 total_broadcast_packets_received_hi; | ||
673 | u32 total_broadcast_packets_received_lo; | ||
674 | u32 total_unicast_packets_transmitted_hi; | ||
675 | u32 total_unicast_packets_transmitted_lo; | ||
676 | u32 total_multicast_packets_transmitted_hi; | ||
677 | u32 total_multicast_packets_transmitted_lo; | ||
678 | u32 total_broadcast_packets_transmitted_hi; | ||
679 | u32 total_broadcast_packets_transmitted_lo; | ||
680 | u32 valid_bytes_received_hi; | ||
681 | u32 valid_bytes_received_lo; | ||
682 | |||
683 | u32 error_bytes_received_hi; | ||
684 | u32 error_bytes_received_lo; | ||
685 | u32 etherstatsoverrsizepkts_hi; | ||
686 | u32 etherstatsoverrsizepkts_lo; | ||
687 | u32 no_buff_discard_hi; | ||
688 | u32 no_buff_discard_lo; | ||
689 | |||
690 | u32 rx_stat_ifhcinbadoctets_hi; | ||
691 | u32 rx_stat_ifhcinbadoctets_lo; | ||
692 | u32 tx_stat_ifhcoutbadoctets_hi; | ||
693 | u32 tx_stat_ifhcoutbadoctets_lo; | ||
694 | u32 rx_stat_dot3statsfcserrors_hi; | ||
695 | u32 rx_stat_dot3statsfcserrors_lo; | ||
696 | u32 rx_stat_dot3statsalignmenterrors_hi; | ||
697 | u32 rx_stat_dot3statsalignmenterrors_lo; | ||
698 | u32 rx_stat_dot3statscarriersenseerrors_hi; | ||
699 | u32 rx_stat_dot3statscarriersenseerrors_lo; | ||
700 | u32 rx_stat_falsecarriererrors_hi; | ||
701 | u32 rx_stat_falsecarriererrors_lo; | ||
702 | u32 rx_stat_etherstatsundersizepkts_hi; | ||
703 | u32 rx_stat_etherstatsundersizepkts_lo; | ||
704 | u32 rx_stat_dot3statsframestoolong_hi; | ||
705 | u32 rx_stat_dot3statsframestoolong_lo; | ||
706 | u32 rx_stat_etherstatsfragments_hi; | ||
707 | u32 rx_stat_etherstatsfragments_lo; | ||
708 | u32 rx_stat_etherstatsjabbers_hi; | ||
709 | u32 rx_stat_etherstatsjabbers_lo; | ||
710 | u32 rx_stat_maccontrolframesreceived_hi; | ||
711 | u32 rx_stat_maccontrolframesreceived_lo; | ||
712 | u32 rx_stat_bmac_xpf_hi; | ||
713 | u32 rx_stat_bmac_xpf_lo; | ||
714 | u32 rx_stat_bmac_xcf_hi; | ||
715 | u32 rx_stat_bmac_xcf_lo; | ||
716 | u32 rx_stat_xoffstateentered_hi; | ||
717 | u32 rx_stat_xoffstateentered_lo; | ||
718 | u32 rx_stat_xonpauseframesreceived_hi; | ||
719 | u32 rx_stat_xonpauseframesreceived_lo; | ||
720 | u32 rx_stat_xoffpauseframesreceived_hi; | ||
721 | u32 rx_stat_xoffpauseframesreceived_lo; | ||
722 | u32 tx_stat_outxonsent_hi; | ||
723 | u32 tx_stat_outxonsent_lo; | ||
724 | u32 tx_stat_outxoffsent_hi; | ||
725 | u32 tx_stat_outxoffsent_lo; | ||
726 | u32 tx_stat_flowcontroldone_hi; | ||
727 | u32 tx_stat_flowcontroldone_lo; | ||
728 | u32 tx_stat_etherstatscollisions_hi; | ||
729 | u32 tx_stat_etherstatscollisions_lo; | ||
730 | u32 tx_stat_dot3statssinglecollisionframes_hi; | ||
731 | u32 tx_stat_dot3statssinglecollisionframes_lo; | ||
732 | u32 tx_stat_dot3statsmultiplecollisionframes_hi; | ||
733 | u32 tx_stat_dot3statsmultiplecollisionframes_lo; | ||
734 | u32 tx_stat_dot3statsdeferredtransmissions_hi; | ||
735 | u32 tx_stat_dot3statsdeferredtransmissions_lo; | ||
736 | u32 tx_stat_dot3statsexcessivecollisions_hi; | ||
737 | u32 tx_stat_dot3statsexcessivecollisions_lo; | ||
738 | u32 tx_stat_dot3statslatecollisions_hi; | ||
739 | u32 tx_stat_dot3statslatecollisions_lo; | ||
740 | u32 tx_stat_etherstatspkts64octets_hi; | ||
741 | u32 tx_stat_etherstatspkts64octets_lo; | ||
742 | u32 tx_stat_etherstatspkts65octetsto127octets_hi; | ||
743 | u32 tx_stat_etherstatspkts65octetsto127octets_lo; | ||
744 | u32 tx_stat_etherstatspkts128octetsto255octets_hi; | ||
745 | u32 tx_stat_etherstatspkts128octetsto255octets_lo; | ||
746 | u32 tx_stat_etherstatspkts256octetsto511octets_hi; | ||
747 | u32 tx_stat_etherstatspkts256octetsto511octets_lo; | ||
748 | u32 tx_stat_etherstatspkts512octetsto1023octets_hi; | ||
749 | u32 tx_stat_etherstatspkts512octetsto1023octets_lo; | ||
750 | u32 tx_stat_etherstatspkts1024octetsto1522octets_hi; | ||
751 | u32 tx_stat_etherstatspkts1024octetsto1522octets_lo; | ||
752 | u32 tx_stat_etherstatspktsover1522octets_hi; | ||
753 | u32 tx_stat_etherstatspktsover1522octets_lo; | ||
754 | u32 tx_stat_bmac_2047_hi; | ||
755 | u32 tx_stat_bmac_2047_lo; | ||
756 | u32 tx_stat_bmac_4095_hi; | ||
757 | u32 tx_stat_bmac_4095_lo; | ||
758 | u32 tx_stat_bmac_9216_hi; | ||
759 | u32 tx_stat_bmac_9216_lo; | ||
760 | u32 tx_stat_bmac_16383_hi; | ||
761 | u32 tx_stat_bmac_16383_lo; | ||
762 | u32 tx_stat_dot3statsinternalmactransmiterrors_hi; | ||
763 | u32 tx_stat_dot3statsinternalmactransmiterrors_lo; | ||
764 | u32 tx_stat_bmac_ufl_hi; | ||
765 | u32 tx_stat_bmac_ufl_lo; | ||
766 | |||
767 | u32 pause_frames_received_hi; | ||
768 | u32 pause_frames_received_lo; | ||
769 | u32 pause_frames_sent_hi; | ||
770 | u32 pause_frames_sent_lo; | ||
771 | |||
772 | u32 etherstatspkts1024octetsto1522octets_hi; | ||
773 | u32 etherstatspkts1024octetsto1522octets_lo; | ||
774 | u32 etherstatspktsover1522octets_hi; | ||
775 | u32 etherstatspktsover1522octets_lo; | ||
776 | |||
777 | u32 brb_drop_hi; | ||
778 | u32 brb_drop_lo; | ||
779 | u32 brb_truncate_hi; | ||
780 | u32 brb_truncate_lo; | ||
781 | |||
782 | u32 mac_filter_discard; | ||
783 | u32 xxoverflow_discard; | ||
784 | u32 brb_truncate_discard; | ||
785 | u32 mac_discard; | ||
786 | |||
787 | u32 driver_xoff; | ||
788 | u32 rx_err_discard_pkt; | ||
789 | u32 rx_skb_alloc_failed; | ||
790 | u32 hw_csum_err; | ||
791 | |||
792 | u32 nig_timer_max; | ||
793 | }; | ||
794 | |||
795 | #define BNX2X_NUM_STATS 43 | ||
796 | #define STATS_OFFSET32(stat_name) \ | ||
797 | (offsetof(struct bnx2x_eth_stats, stat_name) / 4) | ||
798 | |||
799 | 593 | ||
800 | #ifdef BCM_CNIC | 594 | #ifdef BCM_CNIC |
801 | #define MAX_CONTEXT 15 | 595 | #define MAX_CONTEXT 15 |
@@ -1394,4 +1188,6 @@ BNX2X_EXTERN int load_count[3]; /* 0-common, 1-port0, 2-port1 */ | |||
1394 | 1188 | ||
1395 | extern void bnx2x_set_ethtool_ops(struct net_device *netdev); | 1189 | extern void bnx2x_set_ethtool_ops(struct net_device *netdev); |
1396 | 1190 | ||
1191 | void bnx2x_post_dmae(struct bnx2x *bp, struct dmae_command *dmae, int idx); | ||
1192 | |||
1397 | #endif /* bnx2x.h */ | 1193 | #endif /* bnx2x.h */ |
diff --git a/drivers/net/bnx2x/bnx2x_main.c b/drivers/net/bnx2x/bnx2x_main.c index 3abfce2d467e..75568f111754 100644 --- a/drivers/net/bnx2x/bnx2x_main.c +++ b/drivers/net/bnx2x/bnx2x_main.c | |||
@@ -172,7 +172,7 @@ static u32 bnx2x_reg_rd_ind(struct bnx2x *bp, u32 addr) | |||
172 | return val; | 172 | return val; |
173 | } | 173 | } |
174 | 174 | ||
175 | static const u32 dmae_reg_go_c[] = { | 175 | const u32 dmae_reg_go_c[] = { |
176 | DMAE_REG_GO_C0, DMAE_REG_GO_C1, DMAE_REG_GO_C2, DMAE_REG_GO_C3, | 176 | DMAE_REG_GO_C0, DMAE_REG_GO_C1, DMAE_REG_GO_C2, DMAE_REG_GO_C3, |
177 | DMAE_REG_GO_C4, DMAE_REG_GO_C5, DMAE_REG_GO_C6, DMAE_REG_GO_C7, | 177 | DMAE_REG_GO_C4, DMAE_REG_GO_C5, DMAE_REG_GO_C6, DMAE_REG_GO_C7, |
178 | DMAE_REG_GO_C8, DMAE_REG_GO_C9, DMAE_REG_GO_C10, DMAE_REG_GO_C11, | 178 | DMAE_REG_GO_C8, DMAE_REG_GO_C9, DMAE_REG_GO_C10, DMAE_REG_GO_C11, |
@@ -180,8 +180,7 @@ static const u32 dmae_reg_go_c[] = { | |||
180 | }; | 180 | }; |
181 | 181 | ||
182 | /* copy command into DMAE command memory and set DMAE command go */ | 182 | /* copy command into DMAE command memory and set DMAE command go */ |
183 | static void bnx2x_post_dmae(struct bnx2x *bp, struct dmae_command *dmae, | 183 | void bnx2x_post_dmae(struct bnx2x *bp, struct dmae_command *dmae, int idx) |
184 | int idx) | ||
185 | { | 184 | { |
186 | u32 cmd_offset; | 185 | u32 cmd_offset; |
187 | int i; | 186 | int i; |
@@ -536,7 +535,7 @@ static void bnx2x_fw_dump(struct bnx2x *bp) | |||
536 | pr_err("end of fw dump\n"); | 535 | pr_err("end of fw dump\n"); |
537 | } | 536 | } |
538 | 537 | ||
539 | static void bnx2x_panic_dump(struct bnx2x *bp) | 538 | void bnx2x_panic_dump(struct bnx2x *bp) |
540 | { | 539 | { |
541 | int i; | 540 | int i; |
542 | u16 j, start, end; | 541 | u16 j, start, end; |
@@ -2653,1387 +2652,6 @@ irqreturn_t bnx2x_msix_sp_int(int irq, void *dev_instance) | |||
2653 | 2652 | ||
2654 | /* end of slow path */ | 2653 | /* end of slow path */ |
2655 | 2654 | ||
2656 | /* Statistics */ | ||
2657 | |||
2658 | /**************************************************************************** | ||
2659 | * Macros | ||
2660 | ****************************************************************************/ | ||
2661 | |||
2662 | /* sum[hi:lo] += add[hi:lo] */ | ||
2663 | #define ADD_64(s_hi, a_hi, s_lo, a_lo) \ | ||
2664 | do { \ | ||
2665 | s_lo += a_lo; \ | ||
2666 | s_hi += a_hi + ((s_lo < a_lo) ? 1 : 0); \ | ||
2667 | } while (0) | ||
2668 | |||
2669 | /* difference = minuend - subtrahend */ | ||
2670 | #define DIFF_64(d_hi, m_hi, s_hi, d_lo, m_lo, s_lo) \ | ||
2671 | do { \ | ||
2672 | if (m_lo < s_lo) { \ | ||
2673 | /* underflow */ \ | ||
2674 | d_hi = m_hi - s_hi; \ | ||
2675 | if (d_hi > 0) { \ | ||
2676 | /* we can 'loan' 1 */ \ | ||
2677 | d_hi--; \ | ||
2678 | d_lo = m_lo + (UINT_MAX - s_lo) + 1; \ | ||
2679 | } else { \ | ||
2680 | /* m_hi <= s_hi */ \ | ||
2681 | d_hi = 0; \ | ||
2682 | d_lo = 0; \ | ||
2683 | } \ | ||
2684 | } else { \ | ||
2685 | /* m_lo >= s_lo */ \ | ||
2686 | if (m_hi < s_hi) { \ | ||
2687 | d_hi = 0; \ | ||
2688 | d_lo = 0; \ | ||
2689 | } else { \ | ||
2690 | /* m_hi >= s_hi */ \ | ||
2691 | d_hi = m_hi - s_hi; \ | ||
2692 | d_lo = m_lo - s_lo; \ | ||
2693 | } \ | ||
2694 | } \ | ||
2695 | } while (0) | ||
2696 | |||
2697 | #define UPDATE_STAT64(s, t) \ | ||
2698 | do { \ | ||
2699 | DIFF_64(diff.hi, new->s##_hi, pstats->mac_stx[0].t##_hi, \ | ||
2700 | diff.lo, new->s##_lo, pstats->mac_stx[0].t##_lo); \ | ||
2701 | pstats->mac_stx[0].t##_hi = new->s##_hi; \ | ||
2702 | pstats->mac_stx[0].t##_lo = new->s##_lo; \ | ||
2703 | ADD_64(pstats->mac_stx[1].t##_hi, diff.hi, \ | ||
2704 | pstats->mac_stx[1].t##_lo, diff.lo); \ | ||
2705 | } while (0) | ||
2706 | |||
2707 | #define UPDATE_STAT64_NIG(s, t) \ | ||
2708 | do { \ | ||
2709 | DIFF_64(diff.hi, new->s##_hi, old->s##_hi, \ | ||
2710 | diff.lo, new->s##_lo, old->s##_lo); \ | ||
2711 | ADD_64(estats->t##_hi, diff.hi, \ | ||
2712 | estats->t##_lo, diff.lo); \ | ||
2713 | } while (0) | ||
2714 | |||
2715 | /* sum[hi:lo] += add */ | ||
2716 | #define ADD_EXTEND_64(s_hi, s_lo, a) \ | ||
2717 | do { \ | ||
2718 | s_lo += a; \ | ||
2719 | s_hi += (s_lo < a) ? 1 : 0; \ | ||
2720 | } while (0) | ||
2721 | |||
2722 | #define UPDATE_EXTEND_STAT(s) \ | ||
2723 | do { \ | ||
2724 | ADD_EXTEND_64(pstats->mac_stx[1].s##_hi, \ | ||
2725 | pstats->mac_stx[1].s##_lo, \ | ||
2726 | new->s); \ | ||
2727 | } while (0) | ||
2728 | |||
2729 | #define UPDATE_EXTEND_TSTAT(s, t) \ | ||
2730 | do { \ | ||
2731 | diff = le32_to_cpu(tclient->s) - le32_to_cpu(old_tclient->s); \ | ||
2732 | old_tclient->s = tclient->s; \ | ||
2733 | ADD_EXTEND_64(qstats->t##_hi, qstats->t##_lo, diff); \ | ||
2734 | } while (0) | ||
2735 | |||
2736 | #define UPDATE_EXTEND_USTAT(s, t) \ | ||
2737 | do { \ | ||
2738 | diff = le32_to_cpu(uclient->s) - le32_to_cpu(old_uclient->s); \ | ||
2739 | old_uclient->s = uclient->s; \ | ||
2740 | ADD_EXTEND_64(qstats->t##_hi, qstats->t##_lo, diff); \ | ||
2741 | } while (0) | ||
2742 | |||
2743 | #define UPDATE_EXTEND_XSTAT(s, t) \ | ||
2744 | do { \ | ||
2745 | diff = le32_to_cpu(xclient->s) - le32_to_cpu(old_xclient->s); \ | ||
2746 | old_xclient->s = xclient->s; \ | ||
2747 | ADD_EXTEND_64(qstats->t##_hi, qstats->t##_lo, diff); \ | ||
2748 | } while (0) | ||
2749 | |||
2750 | /* minuend -= subtrahend */ | ||
2751 | #define SUB_64(m_hi, s_hi, m_lo, s_lo) \ | ||
2752 | do { \ | ||
2753 | DIFF_64(m_hi, m_hi, s_hi, m_lo, m_lo, s_lo); \ | ||
2754 | } while (0) | ||
2755 | |||
2756 | /* minuend[hi:lo] -= subtrahend */ | ||
2757 | #define SUB_EXTEND_64(m_hi, m_lo, s) \ | ||
2758 | do { \ | ||
2759 | SUB_64(m_hi, 0, m_lo, s); \ | ||
2760 | } while (0) | ||
2761 | |||
2762 | #define SUB_EXTEND_USTAT(s, t) \ | ||
2763 | do { \ | ||
2764 | diff = le32_to_cpu(uclient->s) - le32_to_cpu(old_uclient->s); \ | ||
2765 | SUB_EXTEND_64(qstats->t##_hi, qstats->t##_lo, diff); \ | ||
2766 | } while (0) | ||
2767 | |||
2768 | /* | ||
2769 | * General service functions | ||
2770 | */ | ||
2771 | |||
2772 | static inline long bnx2x_hilo(u32 *hiref) | ||
2773 | { | ||
2774 | u32 lo = *(hiref + 1); | ||
2775 | #if (BITS_PER_LONG == 64) | ||
2776 | u32 hi = *hiref; | ||
2777 | |||
2778 | return HILO_U64(hi, lo); | ||
2779 | #else | ||
2780 | return lo; | ||
2781 | #endif | ||
2782 | } | ||
2783 | |||
2784 | /* | ||
2785 | * Init service functions | ||
2786 | */ | ||
2787 | |||
2788 | static void bnx2x_storm_stats_post(struct bnx2x *bp) | ||
2789 | { | ||
2790 | if (!bp->stats_pending) { | ||
2791 | struct eth_query_ramrod_data ramrod_data = {0}; | ||
2792 | int i, rc; | ||
2793 | |||
2794 | ramrod_data.drv_counter = bp->stats_counter++; | ||
2795 | ramrod_data.collect_port = bp->port.pmf ? 1 : 0; | ||
2796 | for_each_queue(bp, i) | ||
2797 | ramrod_data.ctr_id_vector |= (1 << bp->fp[i].cl_id); | ||
2798 | |||
2799 | rc = bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_STAT_QUERY, 0, | ||
2800 | ((u32 *)&ramrod_data)[1], | ||
2801 | ((u32 *)&ramrod_data)[0], 0); | ||
2802 | if (rc == 0) { | ||
2803 | /* stats ramrod has it's own slot on the spq */ | ||
2804 | bp->spq_left++; | ||
2805 | bp->stats_pending = 1; | ||
2806 | } | ||
2807 | } | ||
2808 | } | ||
2809 | |||
2810 | static void bnx2x_hw_stats_post(struct bnx2x *bp) | ||
2811 | { | ||
2812 | struct dmae_command *dmae = &bp->stats_dmae; | ||
2813 | u32 *stats_comp = bnx2x_sp(bp, stats_comp); | ||
2814 | |||
2815 | *stats_comp = DMAE_COMP_VAL; | ||
2816 | if (CHIP_REV_IS_SLOW(bp)) | ||
2817 | return; | ||
2818 | |||
2819 | /* loader */ | ||
2820 | if (bp->executer_idx) { | ||
2821 | int loader_idx = PMF_DMAE_C(bp); | ||
2822 | |||
2823 | memset(dmae, 0, sizeof(struct dmae_command)); | ||
2824 | |||
2825 | dmae->opcode = (DMAE_CMD_SRC_PCI | DMAE_CMD_DST_GRC | | ||
2826 | DMAE_CMD_C_DST_GRC | DMAE_CMD_C_ENABLE | | ||
2827 | DMAE_CMD_DST_RESET | | ||
2828 | #ifdef __BIG_ENDIAN | ||
2829 | DMAE_CMD_ENDIANITY_B_DW_SWAP | | ||
2830 | #else | ||
2831 | DMAE_CMD_ENDIANITY_DW_SWAP | | ||
2832 | #endif | ||
2833 | (BP_PORT(bp) ? DMAE_CMD_PORT_1 : | ||
2834 | DMAE_CMD_PORT_0) | | ||
2835 | (BP_E1HVN(bp) << DMAE_CMD_E1HVN_SHIFT)); | ||
2836 | dmae->src_addr_lo = U64_LO(bnx2x_sp_mapping(bp, dmae[0])); | ||
2837 | dmae->src_addr_hi = U64_HI(bnx2x_sp_mapping(bp, dmae[0])); | ||
2838 | dmae->dst_addr_lo = (DMAE_REG_CMD_MEM + | ||
2839 | sizeof(struct dmae_command) * | ||
2840 | (loader_idx + 1)) >> 2; | ||
2841 | dmae->dst_addr_hi = 0; | ||
2842 | dmae->len = sizeof(struct dmae_command) >> 2; | ||
2843 | if (CHIP_IS_E1(bp)) | ||
2844 | dmae->len--; | ||
2845 | dmae->comp_addr_lo = dmae_reg_go_c[loader_idx + 1] >> 2; | ||
2846 | dmae->comp_addr_hi = 0; | ||
2847 | dmae->comp_val = 1; | ||
2848 | |||
2849 | *stats_comp = 0; | ||
2850 | bnx2x_post_dmae(bp, dmae, loader_idx); | ||
2851 | |||
2852 | } else if (bp->func_stx) { | ||
2853 | *stats_comp = 0; | ||
2854 | bnx2x_post_dmae(bp, dmae, INIT_DMAE_C(bp)); | ||
2855 | } | ||
2856 | } | ||
2857 | |||
2858 | static int bnx2x_stats_comp(struct bnx2x *bp) | ||
2859 | { | ||
2860 | u32 *stats_comp = bnx2x_sp(bp, stats_comp); | ||
2861 | int cnt = 10; | ||
2862 | |||
2863 | might_sleep(); | ||
2864 | while (*stats_comp != DMAE_COMP_VAL) { | ||
2865 | if (!cnt) { | ||
2866 | BNX2X_ERR("timeout waiting for stats finished\n"); | ||
2867 | break; | ||
2868 | } | ||
2869 | cnt--; | ||
2870 | msleep(1); | ||
2871 | } | ||
2872 | return 1; | ||
2873 | } | ||
2874 | |||
2875 | /* | ||
2876 | * Statistics service functions | ||
2877 | */ | ||
2878 | |||
2879 | static void bnx2x_stats_pmf_update(struct bnx2x *bp) | ||
2880 | { | ||
2881 | struct dmae_command *dmae; | ||
2882 | u32 opcode; | ||
2883 | int loader_idx = PMF_DMAE_C(bp); | ||
2884 | u32 *stats_comp = bnx2x_sp(bp, stats_comp); | ||
2885 | |||
2886 | /* sanity */ | ||
2887 | if (!IS_E1HMF(bp) || !bp->port.pmf || !bp->port.port_stx) { | ||
2888 | BNX2X_ERR("BUG!\n"); | ||
2889 | return; | ||
2890 | } | ||
2891 | |||
2892 | bp->executer_idx = 0; | ||
2893 | |||
2894 | opcode = (DMAE_CMD_SRC_GRC | DMAE_CMD_DST_PCI | | ||
2895 | DMAE_CMD_C_ENABLE | | ||
2896 | DMAE_CMD_SRC_RESET | DMAE_CMD_DST_RESET | | ||
2897 | #ifdef __BIG_ENDIAN | ||
2898 | DMAE_CMD_ENDIANITY_B_DW_SWAP | | ||
2899 | #else | ||
2900 | DMAE_CMD_ENDIANITY_DW_SWAP | | ||
2901 | #endif | ||
2902 | (BP_PORT(bp) ? DMAE_CMD_PORT_1 : DMAE_CMD_PORT_0) | | ||
2903 | (BP_E1HVN(bp) << DMAE_CMD_E1HVN_SHIFT)); | ||
2904 | |||
2905 | dmae = bnx2x_sp(bp, dmae[bp->executer_idx++]); | ||
2906 | dmae->opcode = (opcode | DMAE_CMD_C_DST_GRC); | ||
2907 | dmae->src_addr_lo = bp->port.port_stx >> 2; | ||
2908 | dmae->src_addr_hi = 0; | ||
2909 | dmae->dst_addr_lo = U64_LO(bnx2x_sp_mapping(bp, port_stats)); | ||
2910 | dmae->dst_addr_hi = U64_HI(bnx2x_sp_mapping(bp, port_stats)); | ||
2911 | dmae->len = DMAE_LEN32_RD_MAX; | ||
2912 | dmae->comp_addr_lo = dmae_reg_go_c[loader_idx] >> 2; | ||
2913 | dmae->comp_addr_hi = 0; | ||
2914 | dmae->comp_val = 1; | ||
2915 | |||
2916 | dmae = bnx2x_sp(bp, dmae[bp->executer_idx++]); | ||
2917 | dmae->opcode = (opcode | DMAE_CMD_C_DST_PCI); | ||
2918 | dmae->src_addr_lo = (bp->port.port_stx >> 2) + DMAE_LEN32_RD_MAX; | ||
2919 | dmae->src_addr_hi = 0; | ||
2920 | dmae->dst_addr_lo = U64_LO(bnx2x_sp_mapping(bp, port_stats) + | ||
2921 | DMAE_LEN32_RD_MAX * 4); | ||
2922 | dmae->dst_addr_hi = U64_HI(bnx2x_sp_mapping(bp, port_stats) + | ||
2923 | DMAE_LEN32_RD_MAX * 4); | ||
2924 | dmae->len = (sizeof(struct host_port_stats) >> 2) - DMAE_LEN32_RD_MAX; | ||
2925 | dmae->comp_addr_lo = U64_LO(bnx2x_sp_mapping(bp, stats_comp)); | ||
2926 | dmae->comp_addr_hi = U64_HI(bnx2x_sp_mapping(bp, stats_comp)); | ||
2927 | dmae->comp_val = DMAE_COMP_VAL; | ||
2928 | |||
2929 | *stats_comp = 0; | ||
2930 | bnx2x_hw_stats_post(bp); | ||
2931 | bnx2x_stats_comp(bp); | ||
2932 | } | ||
2933 | |||
2934 | static void bnx2x_port_stats_init(struct bnx2x *bp) | ||
2935 | { | ||
2936 | struct dmae_command *dmae; | ||
2937 | int port = BP_PORT(bp); | ||
2938 | int vn = BP_E1HVN(bp); | ||
2939 | u32 opcode; | ||
2940 | int loader_idx = PMF_DMAE_C(bp); | ||
2941 | u32 mac_addr; | ||
2942 | u32 *stats_comp = bnx2x_sp(bp, stats_comp); | ||
2943 | |||
2944 | /* sanity */ | ||
2945 | if (!bp->link_vars.link_up || !bp->port.pmf) { | ||
2946 | BNX2X_ERR("BUG!\n"); | ||
2947 | return; | ||
2948 | } | ||
2949 | |||
2950 | bp->executer_idx = 0; | ||
2951 | |||
2952 | /* MCP */ | ||
2953 | opcode = (DMAE_CMD_SRC_PCI | DMAE_CMD_DST_GRC | | ||
2954 | DMAE_CMD_C_DST_GRC | DMAE_CMD_C_ENABLE | | ||
2955 | DMAE_CMD_SRC_RESET | DMAE_CMD_DST_RESET | | ||
2956 | #ifdef __BIG_ENDIAN | ||
2957 | DMAE_CMD_ENDIANITY_B_DW_SWAP | | ||
2958 | #else | ||
2959 | DMAE_CMD_ENDIANITY_DW_SWAP | | ||
2960 | #endif | ||
2961 | (port ? DMAE_CMD_PORT_1 : DMAE_CMD_PORT_0) | | ||
2962 | (vn << DMAE_CMD_E1HVN_SHIFT)); | ||
2963 | |||
2964 | if (bp->port.port_stx) { | ||
2965 | |||
2966 | dmae = bnx2x_sp(bp, dmae[bp->executer_idx++]); | ||
2967 | dmae->opcode = opcode; | ||
2968 | dmae->src_addr_lo = U64_LO(bnx2x_sp_mapping(bp, port_stats)); | ||
2969 | dmae->src_addr_hi = U64_HI(bnx2x_sp_mapping(bp, port_stats)); | ||
2970 | dmae->dst_addr_lo = bp->port.port_stx >> 2; | ||
2971 | dmae->dst_addr_hi = 0; | ||
2972 | dmae->len = sizeof(struct host_port_stats) >> 2; | ||
2973 | dmae->comp_addr_lo = dmae_reg_go_c[loader_idx] >> 2; | ||
2974 | dmae->comp_addr_hi = 0; | ||
2975 | dmae->comp_val = 1; | ||
2976 | } | ||
2977 | |||
2978 | if (bp->func_stx) { | ||
2979 | |||
2980 | dmae = bnx2x_sp(bp, dmae[bp->executer_idx++]); | ||
2981 | dmae->opcode = opcode; | ||
2982 | dmae->src_addr_lo = U64_LO(bnx2x_sp_mapping(bp, func_stats)); | ||
2983 | dmae->src_addr_hi = U64_HI(bnx2x_sp_mapping(bp, func_stats)); | ||
2984 | dmae->dst_addr_lo = bp->func_stx >> 2; | ||
2985 | dmae->dst_addr_hi = 0; | ||
2986 | dmae->len = sizeof(struct host_func_stats) >> 2; | ||
2987 | dmae->comp_addr_lo = dmae_reg_go_c[loader_idx] >> 2; | ||
2988 | dmae->comp_addr_hi = 0; | ||
2989 | dmae->comp_val = 1; | ||
2990 | } | ||
2991 | |||
2992 | /* MAC */ | ||
2993 | opcode = (DMAE_CMD_SRC_GRC | DMAE_CMD_DST_PCI | | ||
2994 | DMAE_CMD_C_DST_GRC | DMAE_CMD_C_ENABLE | | ||
2995 | DMAE_CMD_SRC_RESET | DMAE_CMD_DST_RESET | | ||
2996 | #ifdef __BIG_ENDIAN | ||
2997 | DMAE_CMD_ENDIANITY_B_DW_SWAP | | ||
2998 | #else | ||
2999 | DMAE_CMD_ENDIANITY_DW_SWAP | | ||
3000 | #endif | ||
3001 | (port ? DMAE_CMD_PORT_1 : DMAE_CMD_PORT_0) | | ||
3002 | (vn << DMAE_CMD_E1HVN_SHIFT)); | ||
3003 | |||
3004 | if (bp->link_vars.mac_type == MAC_TYPE_BMAC) { | ||
3005 | |||
3006 | mac_addr = (port ? NIG_REG_INGRESS_BMAC1_MEM : | ||
3007 | NIG_REG_INGRESS_BMAC0_MEM); | ||
3008 | |||
3009 | /* BIGMAC_REGISTER_TX_STAT_GTPKT .. | ||
3010 | BIGMAC_REGISTER_TX_STAT_GTBYT */ | ||
3011 | dmae = bnx2x_sp(bp, dmae[bp->executer_idx++]); | ||
3012 | dmae->opcode = opcode; | ||
3013 | dmae->src_addr_lo = (mac_addr + | ||
3014 | BIGMAC_REGISTER_TX_STAT_GTPKT) >> 2; | ||
3015 | dmae->src_addr_hi = 0; | ||
3016 | dmae->dst_addr_lo = U64_LO(bnx2x_sp_mapping(bp, mac_stats)); | ||
3017 | dmae->dst_addr_hi = U64_HI(bnx2x_sp_mapping(bp, mac_stats)); | ||
3018 | dmae->len = (8 + BIGMAC_REGISTER_TX_STAT_GTBYT - | ||
3019 | BIGMAC_REGISTER_TX_STAT_GTPKT) >> 2; | ||
3020 | dmae->comp_addr_lo = dmae_reg_go_c[loader_idx] >> 2; | ||
3021 | dmae->comp_addr_hi = 0; | ||
3022 | dmae->comp_val = 1; | ||
3023 | |||
3024 | /* BIGMAC_REGISTER_RX_STAT_GR64 .. | ||
3025 | BIGMAC_REGISTER_RX_STAT_GRIPJ */ | ||
3026 | dmae = bnx2x_sp(bp, dmae[bp->executer_idx++]); | ||
3027 | dmae->opcode = opcode; | ||
3028 | dmae->src_addr_lo = (mac_addr + | ||
3029 | BIGMAC_REGISTER_RX_STAT_GR64) >> 2; | ||
3030 | dmae->src_addr_hi = 0; | ||
3031 | dmae->dst_addr_lo = U64_LO(bnx2x_sp_mapping(bp, mac_stats) + | ||
3032 | offsetof(struct bmac_stats, rx_stat_gr64_lo)); | ||
3033 | dmae->dst_addr_hi = U64_HI(bnx2x_sp_mapping(bp, mac_stats) + | ||
3034 | offsetof(struct bmac_stats, rx_stat_gr64_lo)); | ||
3035 | dmae->len = (8 + BIGMAC_REGISTER_RX_STAT_GRIPJ - | ||
3036 | BIGMAC_REGISTER_RX_STAT_GR64) >> 2; | ||
3037 | dmae->comp_addr_lo = dmae_reg_go_c[loader_idx] >> 2; | ||
3038 | dmae->comp_addr_hi = 0; | ||
3039 | dmae->comp_val = 1; | ||
3040 | |||
3041 | } else if (bp->link_vars.mac_type == MAC_TYPE_EMAC) { | ||
3042 | |||
3043 | mac_addr = (port ? GRCBASE_EMAC1 : GRCBASE_EMAC0); | ||
3044 | |||
3045 | /* EMAC_REG_EMAC_RX_STAT_AC (EMAC_REG_EMAC_RX_STAT_AC_COUNT)*/ | ||
3046 | dmae = bnx2x_sp(bp, dmae[bp->executer_idx++]); | ||
3047 | dmae->opcode = opcode; | ||
3048 | dmae->src_addr_lo = (mac_addr + | ||
3049 | EMAC_REG_EMAC_RX_STAT_AC) >> 2; | ||
3050 | dmae->src_addr_hi = 0; | ||
3051 | dmae->dst_addr_lo = U64_LO(bnx2x_sp_mapping(bp, mac_stats)); | ||
3052 | dmae->dst_addr_hi = U64_HI(bnx2x_sp_mapping(bp, mac_stats)); | ||
3053 | dmae->len = EMAC_REG_EMAC_RX_STAT_AC_COUNT; | ||
3054 | dmae->comp_addr_lo = dmae_reg_go_c[loader_idx] >> 2; | ||
3055 | dmae->comp_addr_hi = 0; | ||
3056 | dmae->comp_val = 1; | ||
3057 | |||
3058 | /* EMAC_REG_EMAC_RX_STAT_AC_28 */ | ||
3059 | dmae = bnx2x_sp(bp, dmae[bp->executer_idx++]); | ||
3060 | dmae->opcode = opcode; | ||
3061 | dmae->src_addr_lo = (mac_addr + | ||
3062 | EMAC_REG_EMAC_RX_STAT_AC_28) >> 2; | ||
3063 | dmae->src_addr_hi = 0; | ||
3064 | dmae->dst_addr_lo = U64_LO(bnx2x_sp_mapping(bp, mac_stats) + | ||
3065 | offsetof(struct emac_stats, rx_stat_falsecarriererrors)); | ||
3066 | dmae->dst_addr_hi = U64_HI(bnx2x_sp_mapping(bp, mac_stats) + | ||
3067 | offsetof(struct emac_stats, rx_stat_falsecarriererrors)); | ||
3068 | dmae->len = 1; | ||
3069 | dmae->comp_addr_lo = dmae_reg_go_c[loader_idx] >> 2; | ||
3070 | dmae->comp_addr_hi = 0; | ||
3071 | dmae->comp_val = 1; | ||
3072 | |||
3073 | /* EMAC_REG_EMAC_TX_STAT_AC (EMAC_REG_EMAC_TX_STAT_AC_COUNT)*/ | ||
3074 | dmae = bnx2x_sp(bp, dmae[bp->executer_idx++]); | ||
3075 | dmae->opcode = opcode; | ||
3076 | dmae->src_addr_lo = (mac_addr + | ||
3077 | EMAC_REG_EMAC_TX_STAT_AC) >> 2; | ||
3078 | dmae->src_addr_hi = 0; | ||
3079 | dmae->dst_addr_lo = U64_LO(bnx2x_sp_mapping(bp, mac_stats) + | ||
3080 | offsetof(struct emac_stats, tx_stat_ifhcoutoctets)); | ||
3081 | dmae->dst_addr_hi = U64_HI(bnx2x_sp_mapping(bp, mac_stats) + | ||
3082 | offsetof(struct emac_stats, tx_stat_ifhcoutoctets)); | ||
3083 | dmae->len = EMAC_REG_EMAC_TX_STAT_AC_COUNT; | ||
3084 | dmae->comp_addr_lo = dmae_reg_go_c[loader_idx] >> 2; | ||
3085 | dmae->comp_addr_hi = 0; | ||
3086 | dmae->comp_val = 1; | ||
3087 | } | ||
3088 | |||
3089 | /* NIG */ | ||
3090 | dmae = bnx2x_sp(bp, dmae[bp->executer_idx++]); | ||
3091 | dmae->opcode = opcode; | ||
3092 | dmae->src_addr_lo = (port ? NIG_REG_STAT1_BRB_DISCARD : | ||
3093 | NIG_REG_STAT0_BRB_DISCARD) >> 2; | ||
3094 | dmae->src_addr_hi = 0; | ||
3095 | dmae->dst_addr_lo = U64_LO(bnx2x_sp_mapping(bp, nig_stats)); | ||
3096 | dmae->dst_addr_hi = U64_HI(bnx2x_sp_mapping(bp, nig_stats)); | ||
3097 | dmae->len = (sizeof(struct nig_stats) - 4*sizeof(u32)) >> 2; | ||
3098 | dmae->comp_addr_lo = dmae_reg_go_c[loader_idx] >> 2; | ||
3099 | dmae->comp_addr_hi = 0; | ||
3100 | dmae->comp_val = 1; | ||
3101 | |||
3102 | dmae = bnx2x_sp(bp, dmae[bp->executer_idx++]); | ||
3103 | dmae->opcode = opcode; | ||
3104 | dmae->src_addr_lo = (port ? NIG_REG_STAT1_EGRESS_MAC_PKT0 : | ||
3105 | NIG_REG_STAT0_EGRESS_MAC_PKT0) >> 2; | ||
3106 | dmae->src_addr_hi = 0; | ||
3107 | dmae->dst_addr_lo = U64_LO(bnx2x_sp_mapping(bp, nig_stats) + | ||
3108 | offsetof(struct nig_stats, egress_mac_pkt0_lo)); | ||
3109 | dmae->dst_addr_hi = U64_HI(bnx2x_sp_mapping(bp, nig_stats) + | ||
3110 | offsetof(struct nig_stats, egress_mac_pkt0_lo)); | ||
3111 | dmae->len = (2*sizeof(u32)) >> 2; | ||
3112 | dmae->comp_addr_lo = dmae_reg_go_c[loader_idx] >> 2; | ||
3113 | dmae->comp_addr_hi = 0; | ||
3114 | dmae->comp_val = 1; | ||
3115 | |||
3116 | dmae = bnx2x_sp(bp, dmae[bp->executer_idx++]); | ||
3117 | dmae->opcode = (DMAE_CMD_SRC_GRC | DMAE_CMD_DST_PCI | | ||
3118 | DMAE_CMD_C_DST_PCI | DMAE_CMD_C_ENABLE | | ||
3119 | DMAE_CMD_SRC_RESET | DMAE_CMD_DST_RESET | | ||
3120 | #ifdef __BIG_ENDIAN | ||
3121 | DMAE_CMD_ENDIANITY_B_DW_SWAP | | ||
3122 | #else | ||
3123 | DMAE_CMD_ENDIANITY_DW_SWAP | | ||
3124 | #endif | ||
3125 | (port ? DMAE_CMD_PORT_1 : DMAE_CMD_PORT_0) | | ||
3126 | (vn << DMAE_CMD_E1HVN_SHIFT)); | ||
3127 | dmae->src_addr_lo = (port ? NIG_REG_STAT1_EGRESS_MAC_PKT1 : | ||
3128 | NIG_REG_STAT0_EGRESS_MAC_PKT1) >> 2; | ||
3129 | dmae->src_addr_hi = 0; | ||
3130 | dmae->dst_addr_lo = U64_LO(bnx2x_sp_mapping(bp, nig_stats) + | ||
3131 | offsetof(struct nig_stats, egress_mac_pkt1_lo)); | ||
3132 | dmae->dst_addr_hi = U64_HI(bnx2x_sp_mapping(bp, nig_stats) + | ||
3133 | offsetof(struct nig_stats, egress_mac_pkt1_lo)); | ||
3134 | dmae->len = (2*sizeof(u32)) >> 2; | ||
3135 | dmae->comp_addr_lo = U64_LO(bnx2x_sp_mapping(bp, stats_comp)); | ||
3136 | dmae->comp_addr_hi = U64_HI(bnx2x_sp_mapping(bp, stats_comp)); | ||
3137 | dmae->comp_val = DMAE_COMP_VAL; | ||
3138 | |||
3139 | *stats_comp = 0; | ||
3140 | } | ||
3141 | |||
3142 | static void bnx2x_func_stats_init(struct bnx2x *bp) | ||
3143 | { | ||
3144 | struct dmae_command *dmae = &bp->stats_dmae; | ||
3145 | u32 *stats_comp = bnx2x_sp(bp, stats_comp); | ||
3146 | |||
3147 | /* sanity */ | ||
3148 | if (!bp->func_stx) { | ||
3149 | BNX2X_ERR("BUG!\n"); | ||
3150 | return; | ||
3151 | } | ||
3152 | |||
3153 | bp->executer_idx = 0; | ||
3154 | memset(dmae, 0, sizeof(struct dmae_command)); | ||
3155 | |||
3156 | dmae->opcode = (DMAE_CMD_SRC_PCI | DMAE_CMD_DST_GRC | | ||
3157 | DMAE_CMD_C_DST_PCI | DMAE_CMD_C_ENABLE | | ||
3158 | DMAE_CMD_SRC_RESET | DMAE_CMD_DST_RESET | | ||
3159 | #ifdef __BIG_ENDIAN | ||
3160 | DMAE_CMD_ENDIANITY_B_DW_SWAP | | ||
3161 | #else | ||
3162 | DMAE_CMD_ENDIANITY_DW_SWAP | | ||
3163 | #endif | ||
3164 | (BP_PORT(bp) ? DMAE_CMD_PORT_1 : DMAE_CMD_PORT_0) | | ||
3165 | (BP_E1HVN(bp) << DMAE_CMD_E1HVN_SHIFT)); | ||
3166 | dmae->src_addr_lo = U64_LO(bnx2x_sp_mapping(bp, func_stats)); | ||
3167 | dmae->src_addr_hi = U64_HI(bnx2x_sp_mapping(bp, func_stats)); | ||
3168 | dmae->dst_addr_lo = bp->func_stx >> 2; | ||
3169 | dmae->dst_addr_hi = 0; | ||
3170 | dmae->len = sizeof(struct host_func_stats) >> 2; | ||
3171 | dmae->comp_addr_lo = U64_LO(bnx2x_sp_mapping(bp, stats_comp)); | ||
3172 | dmae->comp_addr_hi = U64_HI(bnx2x_sp_mapping(bp, stats_comp)); | ||
3173 | dmae->comp_val = DMAE_COMP_VAL; | ||
3174 | |||
3175 | *stats_comp = 0; | ||
3176 | } | ||
3177 | |||
3178 | static void bnx2x_stats_start(struct bnx2x *bp) | ||
3179 | { | ||
3180 | if (bp->port.pmf) | ||
3181 | bnx2x_port_stats_init(bp); | ||
3182 | |||
3183 | else if (bp->func_stx) | ||
3184 | bnx2x_func_stats_init(bp); | ||
3185 | |||
3186 | bnx2x_hw_stats_post(bp); | ||
3187 | bnx2x_storm_stats_post(bp); | ||
3188 | } | ||
3189 | |||
3190 | static void bnx2x_stats_pmf_start(struct bnx2x *bp) | ||
3191 | { | ||
3192 | bnx2x_stats_comp(bp); | ||
3193 | bnx2x_stats_pmf_update(bp); | ||
3194 | bnx2x_stats_start(bp); | ||
3195 | } | ||
3196 | |||
3197 | static void bnx2x_stats_restart(struct bnx2x *bp) | ||
3198 | { | ||
3199 | bnx2x_stats_comp(bp); | ||
3200 | bnx2x_stats_start(bp); | ||
3201 | } | ||
3202 | |||
3203 | static void bnx2x_bmac_stats_update(struct bnx2x *bp) | ||
3204 | { | ||
3205 | struct bmac_stats *new = bnx2x_sp(bp, mac_stats.bmac_stats); | ||
3206 | struct host_port_stats *pstats = bnx2x_sp(bp, port_stats); | ||
3207 | struct bnx2x_eth_stats *estats = &bp->eth_stats; | ||
3208 | struct { | ||
3209 | u32 lo; | ||
3210 | u32 hi; | ||
3211 | } diff; | ||
3212 | |||
3213 | UPDATE_STAT64(rx_stat_grerb, rx_stat_ifhcinbadoctets); | ||
3214 | UPDATE_STAT64(rx_stat_grfcs, rx_stat_dot3statsfcserrors); | ||
3215 | UPDATE_STAT64(rx_stat_grund, rx_stat_etherstatsundersizepkts); | ||
3216 | UPDATE_STAT64(rx_stat_grovr, rx_stat_dot3statsframestoolong); | ||
3217 | UPDATE_STAT64(rx_stat_grfrg, rx_stat_etherstatsfragments); | ||
3218 | UPDATE_STAT64(rx_stat_grjbr, rx_stat_etherstatsjabbers); | ||
3219 | UPDATE_STAT64(rx_stat_grxcf, rx_stat_maccontrolframesreceived); | ||
3220 | UPDATE_STAT64(rx_stat_grxpf, rx_stat_xoffstateentered); | ||
3221 | UPDATE_STAT64(rx_stat_grxpf, rx_stat_bmac_xpf); | ||
3222 | UPDATE_STAT64(tx_stat_gtxpf, tx_stat_outxoffsent); | ||
3223 | UPDATE_STAT64(tx_stat_gtxpf, tx_stat_flowcontroldone); | ||
3224 | UPDATE_STAT64(tx_stat_gt64, tx_stat_etherstatspkts64octets); | ||
3225 | UPDATE_STAT64(tx_stat_gt127, | ||
3226 | tx_stat_etherstatspkts65octetsto127octets); | ||
3227 | UPDATE_STAT64(tx_stat_gt255, | ||
3228 | tx_stat_etherstatspkts128octetsto255octets); | ||
3229 | UPDATE_STAT64(tx_stat_gt511, | ||
3230 | tx_stat_etherstatspkts256octetsto511octets); | ||
3231 | UPDATE_STAT64(tx_stat_gt1023, | ||
3232 | tx_stat_etherstatspkts512octetsto1023octets); | ||
3233 | UPDATE_STAT64(tx_stat_gt1518, | ||
3234 | tx_stat_etherstatspkts1024octetsto1522octets); | ||
3235 | UPDATE_STAT64(tx_stat_gt2047, tx_stat_bmac_2047); | ||
3236 | UPDATE_STAT64(tx_stat_gt4095, tx_stat_bmac_4095); | ||
3237 | UPDATE_STAT64(tx_stat_gt9216, tx_stat_bmac_9216); | ||
3238 | UPDATE_STAT64(tx_stat_gt16383, tx_stat_bmac_16383); | ||
3239 | UPDATE_STAT64(tx_stat_gterr, | ||
3240 | tx_stat_dot3statsinternalmactransmiterrors); | ||
3241 | UPDATE_STAT64(tx_stat_gtufl, tx_stat_bmac_ufl); | ||
3242 | |||
3243 | estats->pause_frames_received_hi = | ||
3244 | pstats->mac_stx[1].rx_stat_bmac_xpf_hi; | ||
3245 | estats->pause_frames_received_lo = | ||
3246 | pstats->mac_stx[1].rx_stat_bmac_xpf_lo; | ||
3247 | |||
3248 | estats->pause_frames_sent_hi = | ||
3249 | pstats->mac_stx[1].tx_stat_outxoffsent_hi; | ||
3250 | estats->pause_frames_sent_lo = | ||
3251 | pstats->mac_stx[1].tx_stat_outxoffsent_lo; | ||
3252 | } | ||
3253 | |||
3254 | static void bnx2x_emac_stats_update(struct bnx2x *bp) | ||
3255 | { | ||
3256 | struct emac_stats *new = bnx2x_sp(bp, mac_stats.emac_stats); | ||
3257 | struct host_port_stats *pstats = bnx2x_sp(bp, port_stats); | ||
3258 | struct bnx2x_eth_stats *estats = &bp->eth_stats; | ||
3259 | |||
3260 | UPDATE_EXTEND_STAT(rx_stat_ifhcinbadoctets); | ||
3261 | UPDATE_EXTEND_STAT(tx_stat_ifhcoutbadoctets); | ||
3262 | UPDATE_EXTEND_STAT(rx_stat_dot3statsfcserrors); | ||
3263 | UPDATE_EXTEND_STAT(rx_stat_dot3statsalignmenterrors); | ||
3264 | UPDATE_EXTEND_STAT(rx_stat_dot3statscarriersenseerrors); | ||
3265 | UPDATE_EXTEND_STAT(rx_stat_falsecarriererrors); | ||
3266 | UPDATE_EXTEND_STAT(rx_stat_etherstatsundersizepkts); | ||
3267 | UPDATE_EXTEND_STAT(rx_stat_dot3statsframestoolong); | ||
3268 | UPDATE_EXTEND_STAT(rx_stat_etherstatsfragments); | ||
3269 | UPDATE_EXTEND_STAT(rx_stat_etherstatsjabbers); | ||
3270 | UPDATE_EXTEND_STAT(rx_stat_maccontrolframesreceived); | ||
3271 | UPDATE_EXTEND_STAT(rx_stat_xoffstateentered); | ||
3272 | UPDATE_EXTEND_STAT(rx_stat_xonpauseframesreceived); | ||
3273 | UPDATE_EXTEND_STAT(rx_stat_xoffpauseframesreceived); | ||
3274 | UPDATE_EXTEND_STAT(tx_stat_outxonsent); | ||
3275 | UPDATE_EXTEND_STAT(tx_stat_outxoffsent); | ||
3276 | UPDATE_EXTEND_STAT(tx_stat_flowcontroldone); | ||
3277 | UPDATE_EXTEND_STAT(tx_stat_etherstatscollisions); | ||
3278 | UPDATE_EXTEND_STAT(tx_stat_dot3statssinglecollisionframes); | ||
3279 | UPDATE_EXTEND_STAT(tx_stat_dot3statsmultiplecollisionframes); | ||
3280 | UPDATE_EXTEND_STAT(tx_stat_dot3statsdeferredtransmissions); | ||
3281 | UPDATE_EXTEND_STAT(tx_stat_dot3statsexcessivecollisions); | ||
3282 | UPDATE_EXTEND_STAT(tx_stat_dot3statslatecollisions); | ||
3283 | UPDATE_EXTEND_STAT(tx_stat_etherstatspkts64octets); | ||
3284 | UPDATE_EXTEND_STAT(tx_stat_etherstatspkts65octetsto127octets); | ||
3285 | UPDATE_EXTEND_STAT(tx_stat_etherstatspkts128octetsto255octets); | ||
3286 | UPDATE_EXTEND_STAT(tx_stat_etherstatspkts256octetsto511octets); | ||
3287 | UPDATE_EXTEND_STAT(tx_stat_etherstatspkts512octetsto1023octets); | ||
3288 | UPDATE_EXTEND_STAT(tx_stat_etherstatspkts1024octetsto1522octets); | ||
3289 | UPDATE_EXTEND_STAT(tx_stat_etherstatspktsover1522octets); | ||
3290 | UPDATE_EXTEND_STAT(tx_stat_dot3statsinternalmactransmiterrors); | ||
3291 | |||
3292 | estats->pause_frames_received_hi = | ||
3293 | pstats->mac_stx[1].rx_stat_xonpauseframesreceived_hi; | ||
3294 | estats->pause_frames_received_lo = | ||
3295 | pstats->mac_stx[1].rx_stat_xonpauseframesreceived_lo; | ||
3296 | ADD_64(estats->pause_frames_received_hi, | ||
3297 | pstats->mac_stx[1].rx_stat_xoffpauseframesreceived_hi, | ||
3298 | estats->pause_frames_received_lo, | ||
3299 | pstats->mac_stx[1].rx_stat_xoffpauseframesreceived_lo); | ||
3300 | |||
3301 | estats->pause_frames_sent_hi = | ||
3302 | pstats->mac_stx[1].tx_stat_outxonsent_hi; | ||
3303 | estats->pause_frames_sent_lo = | ||
3304 | pstats->mac_stx[1].tx_stat_outxonsent_lo; | ||
3305 | ADD_64(estats->pause_frames_sent_hi, | ||
3306 | pstats->mac_stx[1].tx_stat_outxoffsent_hi, | ||
3307 | estats->pause_frames_sent_lo, | ||
3308 | pstats->mac_stx[1].tx_stat_outxoffsent_lo); | ||
3309 | } | ||
3310 | |||
3311 | static int bnx2x_hw_stats_update(struct bnx2x *bp) | ||
3312 | { | ||
3313 | struct nig_stats *new = bnx2x_sp(bp, nig_stats); | ||
3314 | struct nig_stats *old = &(bp->port.old_nig_stats); | ||
3315 | struct host_port_stats *pstats = bnx2x_sp(bp, port_stats); | ||
3316 | struct bnx2x_eth_stats *estats = &bp->eth_stats; | ||
3317 | struct { | ||
3318 | u32 lo; | ||
3319 | u32 hi; | ||
3320 | } diff; | ||
3321 | |||
3322 | if (bp->link_vars.mac_type == MAC_TYPE_BMAC) | ||
3323 | bnx2x_bmac_stats_update(bp); | ||
3324 | |||
3325 | else if (bp->link_vars.mac_type == MAC_TYPE_EMAC) | ||
3326 | bnx2x_emac_stats_update(bp); | ||
3327 | |||
3328 | else { /* unreached */ | ||
3329 | BNX2X_ERR("stats updated by DMAE but no MAC active\n"); | ||
3330 | return -1; | ||
3331 | } | ||
3332 | |||
3333 | ADD_EXTEND_64(pstats->brb_drop_hi, pstats->brb_drop_lo, | ||
3334 | new->brb_discard - old->brb_discard); | ||
3335 | ADD_EXTEND_64(estats->brb_truncate_hi, estats->brb_truncate_lo, | ||
3336 | new->brb_truncate - old->brb_truncate); | ||
3337 | |||
3338 | UPDATE_STAT64_NIG(egress_mac_pkt0, | ||
3339 | etherstatspkts1024octetsto1522octets); | ||
3340 | UPDATE_STAT64_NIG(egress_mac_pkt1, etherstatspktsover1522octets); | ||
3341 | |||
3342 | memcpy(old, new, sizeof(struct nig_stats)); | ||
3343 | |||
3344 | memcpy(&(estats->rx_stat_ifhcinbadoctets_hi), &(pstats->mac_stx[1]), | ||
3345 | sizeof(struct mac_stx)); | ||
3346 | estats->brb_drop_hi = pstats->brb_drop_hi; | ||
3347 | estats->brb_drop_lo = pstats->brb_drop_lo; | ||
3348 | |||
3349 | pstats->host_port_stats_start = ++pstats->host_port_stats_end; | ||
3350 | |||
3351 | if (!BP_NOMCP(bp)) { | ||
3352 | u32 nig_timer_max = | ||
3353 | SHMEM_RD(bp, port_mb[BP_PORT(bp)].stat_nig_timer); | ||
3354 | if (nig_timer_max != estats->nig_timer_max) { | ||
3355 | estats->nig_timer_max = nig_timer_max; | ||
3356 | BNX2X_ERR("NIG timer max (%u)\n", | ||
3357 | estats->nig_timer_max); | ||
3358 | } | ||
3359 | } | ||
3360 | |||
3361 | return 0; | ||
3362 | } | ||
3363 | |||
3364 | static int bnx2x_storm_stats_update(struct bnx2x *bp) | ||
3365 | { | ||
3366 | struct eth_stats_query *stats = bnx2x_sp(bp, fw_stats); | ||
3367 | struct tstorm_per_port_stats *tport = | ||
3368 | &stats->tstorm_common.port_statistics; | ||
3369 | struct host_func_stats *fstats = bnx2x_sp(bp, func_stats); | ||
3370 | struct bnx2x_eth_stats *estats = &bp->eth_stats; | ||
3371 | int i; | ||
3372 | |||
3373 | memcpy(&(fstats->total_bytes_received_hi), | ||
3374 | &(bnx2x_sp(bp, func_stats_base)->total_bytes_received_hi), | ||
3375 | sizeof(struct host_func_stats) - 2*sizeof(u32)); | ||
3376 | estats->error_bytes_received_hi = 0; | ||
3377 | estats->error_bytes_received_lo = 0; | ||
3378 | estats->etherstatsoverrsizepkts_hi = 0; | ||
3379 | estats->etherstatsoverrsizepkts_lo = 0; | ||
3380 | estats->no_buff_discard_hi = 0; | ||
3381 | estats->no_buff_discard_lo = 0; | ||
3382 | |||
3383 | for_each_queue(bp, i) { | ||
3384 | struct bnx2x_fastpath *fp = &bp->fp[i]; | ||
3385 | int cl_id = fp->cl_id; | ||
3386 | struct tstorm_per_client_stats *tclient = | ||
3387 | &stats->tstorm_common.client_statistics[cl_id]; | ||
3388 | struct tstorm_per_client_stats *old_tclient = &fp->old_tclient; | ||
3389 | struct ustorm_per_client_stats *uclient = | ||
3390 | &stats->ustorm_common.client_statistics[cl_id]; | ||
3391 | struct ustorm_per_client_stats *old_uclient = &fp->old_uclient; | ||
3392 | struct xstorm_per_client_stats *xclient = | ||
3393 | &stats->xstorm_common.client_statistics[cl_id]; | ||
3394 | struct xstorm_per_client_stats *old_xclient = &fp->old_xclient; | ||
3395 | struct bnx2x_eth_q_stats *qstats = &fp->eth_q_stats; | ||
3396 | u32 diff; | ||
3397 | |||
3398 | /* are storm stats valid? */ | ||
3399 | if ((u16)(le16_to_cpu(xclient->stats_counter) + 1) != | ||
3400 | bp->stats_counter) { | ||
3401 | DP(BNX2X_MSG_STATS, "[%d] stats not updated by xstorm" | ||
3402 | " xstorm counter (0x%x) != stats_counter (0x%x)\n", | ||
3403 | i, xclient->stats_counter, bp->stats_counter); | ||
3404 | return -1; | ||
3405 | } | ||
3406 | if ((u16)(le16_to_cpu(tclient->stats_counter) + 1) != | ||
3407 | bp->stats_counter) { | ||
3408 | DP(BNX2X_MSG_STATS, "[%d] stats not updated by tstorm" | ||
3409 | " tstorm counter (0x%x) != stats_counter (0x%x)\n", | ||
3410 | i, tclient->stats_counter, bp->stats_counter); | ||
3411 | return -2; | ||
3412 | } | ||
3413 | if ((u16)(le16_to_cpu(uclient->stats_counter) + 1) != | ||
3414 | bp->stats_counter) { | ||
3415 | DP(BNX2X_MSG_STATS, "[%d] stats not updated by ustorm" | ||
3416 | " ustorm counter (0x%x) != stats_counter (0x%x)\n", | ||
3417 | i, uclient->stats_counter, bp->stats_counter); | ||
3418 | return -4; | ||
3419 | } | ||
3420 | |||
3421 | qstats->total_bytes_received_hi = | ||
3422 | le32_to_cpu(tclient->rcv_broadcast_bytes.hi); | ||
3423 | qstats->total_bytes_received_lo = | ||
3424 | le32_to_cpu(tclient->rcv_broadcast_bytes.lo); | ||
3425 | |||
3426 | ADD_64(qstats->total_bytes_received_hi, | ||
3427 | le32_to_cpu(tclient->rcv_multicast_bytes.hi), | ||
3428 | qstats->total_bytes_received_lo, | ||
3429 | le32_to_cpu(tclient->rcv_multicast_bytes.lo)); | ||
3430 | |||
3431 | ADD_64(qstats->total_bytes_received_hi, | ||
3432 | le32_to_cpu(tclient->rcv_unicast_bytes.hi), | ||
3433 | qstats->total_bytes_received_lo, | ||
3434 | le32_to_cpu(tclient->rcv_unicast_bytes.lo)); | ||
3435 | |||
3436 | SUB_64(qstats->total_bytes_received_hi, | ||
3437 | le32_to_cpu(uclient->bcast_no_buff_bytes.hi), | ||
3438 | qstats->total_bytes_received_lo, | ||
3439 | le32_to_cpu(uclient->bcast_no_buff_bytes.lo)); | ||
3440 | |||
3441 | SUB_64(qstats->total_bytes_received_hi, | ||
3442 | le32_to_cpu(uclient->mcast_no_buff_bytes.hi), | ||
3443 | qstats->total_bytes_received_lo, | ||
3444 | le32_to_cpu(uclient->mcast_no_buff_bytes.lo)); | ||
3445 | |||
3446 | SUB_64(qstats->total_bytes_received_hi, | ||
3447 | le32_to_cpu(uclient->ucast_no_buff_bytes.hi), | ||
3448 | qstats->total_bytes_received_lo, | ||
3449 | le32_to_cpu(uclient->ucast_no_buff_bytes.lo)); | ||
3450 | |||
3451 | qstats->valid_bytes_received_hi = | ||
3452 | qstats->total_bytes_received_hi; | ||
3453 | qstats->valid_bytes_received_lo = | ||
3454 | qstats->total_bytes_received_lo; | ||
3455 | |||
3456 | qstats->error_bytes_received_hi = | ||
3457 | le32_to_cpu(tclient->rcv_error_bytes.hi); | ||
3458 | qstats->error_bytes_received_lo = | ||
3459 | le32_to_cpu(tclient->rcv_error_bytes.lo); | ||
3460 | |||
3461 | ADD_64(qstats->total_bytes_received_hi, | ||
3462 | qstats->error_bytes_received_hi, | ||
3463 | qstats->total_bytes_received_lo, | ||
3464 | qstats->error_bytes_received_lo); | ||
3465 | |||
3466 | UPDATE_EXTEND_TSTAT(rcv_unicast_pkts, | ||
3467 | total_unicast_packets_received); | ||
3468 | UPDATE_EXTEND_TSTAT(rcv_multicast_pkts, | ||
3469 | total_multicast_packets_received); | ||
3470 | UPDATE_EXTEND_TSTAT(rcv_broadcast_pkts, | ||
3471 | total_broadcast_packets_received); | ||
3472 | UPDATE_EXTEND_TSTAT(packets_too_big_discard, | ||
3473 | etherstatsoverrsizepkts); | ||
3474 | UPDATE_EXTEND_TSTAT(no_buff_discard, no_buff_discard); | ||
3475 | |||
3476 | SUB_EXTEND_USTAT(ucast_no_buff_pkts, | ||
3477 | total_unicast_packets_received); | ||
3478 | SUB_EXTEND_USTAT(mcast_no_buff_pkts, | ||
3479 | total_multicast_packets_received); | ||
3480 | SUB_EXTEND_USTAT(bcast_no_buff_pkts, | ||
3481 | total_broadcast_packets_received); | ||
3482 | UPDATE_EXTEND_USTAT(ucast_no_buff_pkts, no_buff_discard); | ||
3483 | UPDATE_EXTEND_USTAT(mcast_no_buff_pkts, no_buff_discard); | ||
3484 | UPDATE_EXTEND_USTAT(bcast_no_buff_pkts, no_buff_discard); | ||
3485 | |||
3486 | qstats->total_bytes_transmitted_hi = | ||
3487 | le32_to_cpu(xclient->unicast_bytes_sent.hi); | ||
3488 | qstats->total_bytes_transmitted_lo = | ||
3489 | le32_to_cpu(xclient->unicast_bytes_sent.lo); | ||
3490 | |||
3491 | ADD_64(qstats->total_bytes_transmitted_hi, | ||
3492 | le32_to_cpu(xclient->multicast_bytes_sent.hi), | ||
3493 | qstats->total_bytes_transmitted_lo, | ||
3494 | le32_to_cpu(xclient->multicast_bytes_sent.lo)); | ||
3495 | |||
3496 | ADD_64(qstats->total_bytes_transmitted_hi, | ||
3497 | le32_to_cpu(xclient->broadcast_bytes_sent.hi), | ||
3498 | qstats->total_bytes_transmitted_lo, | ||
3499 | le32_to_cpu(xclient->broadcast_bytes_sent.lo)); | ||
3500 | |||
3501 | UPDATE_EXTEND_XSTAT(unicast_pkts_sent, | ||
3502 | total_unicast_packets_transmitted); | ||
3503 | UPDATE_EXTEND_XSTAT(multicast_pkts_sent, | ||
3504 | total_multicast_packets_transmitted); | ||
3505 | UPDATE_EXTEND_XSTAT(broadcast_pkts_sent, | ||
3506 | total_broadcast_packets_transmitted); | ||
3507 | |||
3508 | old_tclient->checksum_discard = tclient->checksum_discard; | ||
3509 | old_tclient->ttl0_discard = tclient->ttl0_discard; | ||
3510 | |||
3511 | ADD_64(fstats->total_bytes_received_hi, | ||
3512 | qstats->total_bytes_received_hi, | ||
3513 | fstats->total_bytes_received_lo, | ||
3514 | qstats->total_bytes_received_lo); | ||
3515 | ADD_64(fstats->total_bytes_transmitted_hi, | ||
3516 | qstats->total_bytes_transmitted_hi, | ||
3517 | fstats->total_bytes_transmitted_lo, | ||
3518 | qstats->total_bytes_transmitted_lo); | ||
3519 | ADD_64(fstats->total_unicast_packets_received_hi, | ||
3520 | qstats->total_unicast_packets_received_hi, | ||
3521 | fstats->total_unicast_packets_received_lo, | ||
3522 | qstats->total_unicast_packets_received_lo); | ||
3523 | ADD_64(fstats->total_multicast_packets_received_hi, | ||
3524 | qstats->total_multicast_packets_received_hi, | ||
3525 | fstats->total_multicast_packets_received_lo, | ||
3526 | qstats->total_multicast_packets_received_lo); | ||
3527 | ADD_64(fstats->total_broadcast_packets_received_hi, | ||
3528 | qstats->total_broadcast_packets_received_hi, | ||
3529 | fstats->total_broadcast_packets_received_lo, | ||
3530 | qstats->total_broadcast_packets_received_lo); | ||
3531 | ADD_64(fstats->total_unicast_packets_transmitted_hi, | ||
3532 | qstats->total_unicast_packets_transmitted_hi, | ||
3533 | fstats->total_unicast_packets_transmitted_lo, | ||
3534 | qstats->total_unicast_packets_transmitted_lo); | ||
3535 | ADD_64(fstats->total_multicast_packets_transmitted_hi, | ||
3536 | qstats->total_multicast_packets_transmitted_hi, | ||
3537 | fstats->total_multicast_packets_transmitted_lo, | ||
3538 | qstats->total_multicast_packets_transmitted_lo); | ||
3539 | ADD_64(fstats->total_broadcast_packets_transmitted_hi, | ||
3540 | qstats->total_broadcast_packets_transmitted_hi, | ||
3541 | fstats->total_broadcast_packets_transmitted_lo, | ||
3542 | qstats->total_broadcast_packets_transmitted_lo); | ||
3543 | ADD_64(fstats->valid_bytes_received_hi, | ||
3544 | qstats->valid_bytes_received_hi, | ||
3545 | fstats->valid_bytes_received_lo, | ||
3546 | qstats->valid_bytes_received_lo); | ||
3547 | |||
3548 | ADD_64(estats->error_bytes_received_hi, | ||
3549 | qstats->error_bytes_received_hi, | ||
3550 | estats->error_bytes_received_lo, | ||
3551 | qstats->error_bytes_received_lo); | ||
3552 | ADD_64(estats->etherstatsoverrsizepkts_hi, | ||
3553 | qstats->etherstatsoverrsizepkts_hi, | ||
3554 | estats->etherstatsoverrsizepkts_lo, | ||
3555 | qstats->etherstatsoverrsizepkts_lo); | ||
3556 | ADD_64(estats->no_buff_discard_hi, qstats->no_buff_discard_hi, | ||
3557 | estats->no_buff_discard_lo, qstats->no_buff_discard_lo); | ||
3558 | } | ||
3559 | |||
3560 | ADD_64(fstats->total_bytes_received_hi, | ||
3561 | estats->rx_stat_ifhcinbadoctets_hi, | ||
3562 | fstats->total_bytes_received_lo, | ||
3563 | estats->rx_stat_ifhcinbadoctets_lo); | ||
3564 | |||
3565 | memcpy(estats, &(fstats->total_bytes_received_hi), | ||
3566 | sizeof(struct host_func_stats) - 2*sizeof(u32)); | ||
3567 | |||
3568 | ADD_64(estats->etherstatsoverrsizepkts_hi, | ||
3569 | estats->rx_stat_dot3statsframestoolong_hi, | ||
3570 | estats->etherstatsoverrsizepkts_lo, | ||
3571 | estats->rx_stat_dot3statsframestoolong_lo); | ||
3572 | ADD_64(estats->error_bytes_received_hi, | ||
3573 | estats->rx_stat_ifhcinbadoctets_hi, | ||
3574 | estats->error_bytes_received_lo, | ||
3575 | estats->rx_stat_ifhcinbadoctets_lo); | ||
3576 | |||
3577 | if (bp->port.pmf) { | ||
3578 | estats->mac_filter_discard = | ||
3579 | le32_to_cpu(tport->mac_filter_discard); | ||
3580 | estats->xxoverflow_discard = | ||
3581 | le32_to_cpu(tport->xxoverflow_discard); | ||
3582 | estats->brb_truncate_discard = | ||
3583 | le32_to_cpu(tport->brb_truncate_discard); | ||
3584 | estats->mac_discard = le32_to_cpu(tport->mac_discard); | ||
3585 | } | ||
3586 | |||
3587 | fstats->host_func_stats_start = ++fstats->host_func_stats_end; | ||
3588 | |||
3589 | bp->stats_pending = 0; | ||
3590 | |||
3591 | return 0; | ||
3592 | } | ||
3593 | |||
3594 | static void bnx2x_net_stats_update(struct bnx2x *bp) | ||
3595 | { | ||
3596 | struct bnx2x_eth_stats *estats = &bp->eth_stats; | ||
3597 | struct net_device_stats *nstats = &bp->dev->stats; | ||
3598 | int i; | ||
3599 | |||
3600 | nstats->rx_packets = | ||
3601 | bnx2x_hilo(&estats->total_unicast_packets_received_hi) + | ||
3602 | bnx2x_hilo(&estats->total_multicast_packets_received_hi) + | ||
3603 | bnx2x_hilo(&estats->total_broadcast_packets_received_hi); | ||
3604 | |||
3605 | nstats->tx_packets = | ||
3606 | bnx2x_hilo(&estats->total_unicast_packets_transmitted_hi) + | ||
3607 | bnx2x_hilo(&estats->total_multicast_packets_transmitted_hi) + | ||
3608 | bnx2x_hilo(&estats->total_broadcast_packets_transmitted_hi); | ||
3609 | |||
3610 | nstats->rx_bytes = bnx2x_hilo(&estats->total_bytes_received_hi); | ||
3611 | |||
3612 | nstats->tx_bytes = bnx2x_hilo(&estats->total_bytes_transmitted_hi); | ||
3613 | |||
3614 | nstats->rx_dropped = estats->mac_discard; | ||
3615 | for_each_queue(bp, i) | ||
3616 | nstats->rx_dropped += | ||
3617 | le32_to_cpu(bp->fp[i].old_tclient.checksum_discard); | ||
3618 | |||
3619 | nstats->tx_dropped = 0; | ||
3620 | |||
3621 | nstats->multicast = | ||
3622 | bnx2x_hilo(&estats->total_multicast_packets_received_hi); | ||
3623 | |||
3624 | nstats->collisions = | ||
3625 | bnx2x_hilo(&estats->tx_stat_etherstatscollisions_hi); | ||
3626 | |||
3627 | nstats->rx_length_errors = | ||
3628 | bnx2x_hilo(&estats->rx_stat_etherstatsundersizepkts_hi) + | ||
3629 | bnx2x_hilo(&estats->etherstatsoverrsizepkts_hi); | ||
3630 | nstats->rx_over_errors = bnx2x_hilo(&estats->brb_drop_hi) + | ||
3631 | bnx2x_hilo(&estats->brb_truncate_hi); | ||
3632 | nstats->rx_crc_errors = | ||
3633 | bnx2x_hilo(&estats->rx_stat_dot3statsfcserrors_hi); | ||
3634 | nstats->rx_frame_errors = | ||
3635 | bnx2x_hilo(&estats->rx_stat_dot3statsalignmenterrors_hi); | ||
3636 | nstats->rx_fifo_errors = bnx2x_hilo(&estats->no_buff_discard_hi); | ||
3637 | nstats->rx_missed_errors = estats->xxoverflow_discard; | ||
3638 | |||
3639 | nstats->rx_errors = nstats->rx_length_errors + | ||
3640 | nstats->rx_over_errors + | ||
3641 | nstats->rx_crc_errors + | ||
3642 | nstats->rx_frame_errors + | ||
3643 | nstats->rx_fifo_errors + | ||
3644 | nstats->rx_missed_errors; | ||
3645 | |||
3646 | nstats->tx_aborted_errors = | ||
3647 | bnx2x_hilo(&estats->tx_stat_dot3statslatecollisions_hi) + | ||
3648 | bnx2x_hilo(&estats->tx_stat_dot3statsexcessivecollisions_hi); | ||
3649 | nstats->tx_carrier_errors = | ||
3650 | bnx2x_hilo(&estats->rx_stat_dot3statscarriersenseerrors_hi); | ||
3651 | nstats->tx_fifo_errors = 0; | ||
3652 | nstats->tx_heartbeat_errors = 0; | ||
3653 | nstats->tx_window_errors = 0; | ||
3654 | |||
3655 | nstats->tx_errors = nstats->tx_aborted_errors + | ||
3656 | nstats->tx_carrier_errors + | ||
3657 | bnx2x_hilo(&estats->tx_stat_dot3statsinternalmactransmiterrors_hi); | ||
3658 | } | ||
3659 | |||
3660 | static void bnx2x_drv_stats_update(struct bnx2x *bp) | ||
3661 | { | ||
3662 | struct bnx2x_eth_stats *estats = &bp->eth_stats; | ||
3663 | int i; | ||
3664 | |||
3665 | estats->driver_xoff = 0; | ||
3666 | estats->rx_err_discard_pkt = 0; | ||
3667 | estats->rx_skb_alloc_failed = 0; | ||
3668 | estats->hw_csum_err = 0; | ||
3669 | for_each_queue(bp, i) { | ||
3670 | struct bnx2x_eth_q_stats *qstats = &bp->fp[i].eth_q_stats; | ||
3671 | |||
3672 | estats->driver_xoff += qstats->driver_xoff; | ||
3673 | estats->rx_err_discard_pkt += qstats->rx_err_discard_pkt; | ||
3674 | estats->rx_skb_alloc_failed += qstats->rx_skb_alloc_failed; | ||
3675 | estats->hw_csum_err += qstats->hw_csum_err; | ||
3676 | } | ||
3677 | } | ||
3678 | |||
3679 | static void bnx2x_stats_update(struct bnx2x *bp) | ||
3680 | { | ||
3681 | u32 *stats_comp = bnx2x_sp(bp, stats_comp); | ||
3682 | |||
3683 | if (*stats_comp != DMAE_COMP_VAL) | ||
3684 | return; | ||
3685 | |||
3686 | if (bp->port.pmf) | ||
3687 | bnx2x_hw_stats_update(bp); | ||
3688 | |||
3689 | if (bnx2x_storm_stats_update(bp) && (bp->stats_pending++ == 3)) { | ||
3690 | BNX2X_ERR("storm stats were not updated for 3 times\n"); | ||
3691 | bnx2x_panic(); | ||
3692 | return; | ||
3693 | } | ||
3694 | |||
3695 | bnx2x_net_stats_update(bp); | ||
3696 | bnx2x_drv_stats_update(bp); | ||
3697 | |||
3698 | if (netif_msg_timer(bp)) { | ||
3699 | struct bnx2x_eth_stats *estats = &bp->eth_stats; | ||
3700 | int i; | ||
3701 | |||
3702 | printk(KERN_DEBUG "%s: brb drops %u brb truncate %u\n", | ||
3703 | bp->dev->name, | ||
3704 | estats->brb_drop_lo, estats->brb_truncate_lo); | ||
3705 | |||
3706 | for_each_queue(bp, i) { | ||
3707 | struct bnx2x_fastpath *fp = &bp->fp[i]; | ||
3708 | struct bnx2x_eth_q_stats *qstats = &fp->eth_q_stats; | ||
3709 | |||
3710 | printk(KERN_DEBUG "%s: rx usage(%4u) *rx_cons_sb(%u)" | ||
3711 | " rx pkt(%lu) rx calls(%lu %lu)\n", | ||
3712 | fp->name, (le16_to_cpu(*fp->rx_cons_sb) - | ||
3713 | fp->rx_comp_cons), | ||
3714 | le16_to_cpu(*fp->rx_cons_sb), | ||
3715 | bnx2x_hilo(&qstats-> | ||
3716 | total_unicast_packets_received_hi), | ||
3717 | fp->rx_calls, fp->rx_pkt); | ||
3718 | } | ||
3719 | |||
3720 | for_each_queue(bp, i) { | ||
3721 | struct bnx2x_fastpath *fp = &bp->fp[i]; | ||
3722 | struct bnx2x_eth_q_stats *qstats = &fp->eth_q_stats; | ||
3723 | struct netdev_queue *txq = | ||
3724 | netdev_get_tx_queue(bp->dev, i); | ||
3725 | |||
3726 | printk(KERN_DEBUG "%s: tx avail(%4u) *tx_cons_sb(%u)" | ||
3727 | " tx pkt(%lu) tx calls (%lu)" | ||
3728 | " %s (Xoff events %u)\n", | ||
3729 | fp->name, bnx2x_tx_avail(fp), | ||
3730 | le16_to_cpu(*fp->tx_cons_sb), | ||
3731 | bnx2x_hilo(&qstats-> | ||
3732 | total_unicast_packets_transmitted_hi), | ||
3733 | fp->tx_pkt, | ||
3734 | (netif_tx_queue_stopped(txq) ? "Xoff" : "Xon"), | ||
3735 | qstats->driver_xoff); | ||
3736 | } | ||
3737 | } | ||
3738 | |||
3739 | bnx2x_hw_stats_post(bp); | ||
3740 | bnx2x_storm_stats_post(bp); | ||
3741 | } | ||
3742 | |||
3743 | static void bnx2x_port_stats_stop(struct bnx2x *bp) | ||
3744 | { | ||
3745 | struct dmae_command *dmae; | ||
3746 | u32 opcode; | ||
3747 | int loader_idx = PMF_DMAE_C(bp); | ||
3748 | u32 *stats_comp = bnx2x_sp(bp, stats_comp); | ||
3749 | |||
3750 | bp->executer_idx = 0; | ||
3751 | |||
3752 | opcode = (DMAE_CMD_SRC_PCI | DMAE_CMD_DST_GRC | | ||
3753 | DMAE_CMD_C_ENABLE | | ||
3754 | DMAE_CMD_SRC_RESET | DMAE_CMD_DST_RESET | | ||
3755 | #ifdef __BIG_ENDIAN | ||
3756 | DMAE_CMD_ENDIANITY_B_DW_SWAP | | ||
3757 | #else | ||
3758 | DMAE_CMD_ENDIANITY_DW_SWAP | | ||
3759 | #endif | ||
3760 | (BP_PORT(bp) ? DMAE_CMD_PORT_1 : DMAE_CMD_PORT_0) | | ||
3761 | (BP_E1HVN(bp) << DMAE_CMD_E1HVN_SHIFT)); | ||
3762 | |||
3763 | if (bp->port.port_stx) { | ||
3764 | |||
3765 | dmae = bnx2x_sp(bp, dmae[bp->executer_idx++]); | ||
3766 | if (bp->func_stx) | ||
3767 | dmae->opcode = (opcode | DMAE_CMD_C_DST_GRC); | ||
3768 | else | ||
3769 | dmae->opcode = (opcode | DMAE_CMD_C_DST_PCI); | ||
3770 | dmae->src_addr_lo = U64_LO(bnx2x_sp_mapping(bp, port_stats)); | ||
3771 | dmae->src_addr_hi = U64_HI(bnx2x_sp_mapping(bp, port_stats)); | ||
3772 | dmae->dst_addr_lo = bp->port.port_stx >> 2; | ||
3773 | dmae->dst_addr_hi = 0; | ||
3774 | dmae->len = sizeof(struct host_port_stats) >> 2; | ||
3775 | if (bp->func_stx) { | ||
3776 | dmae->comp_addr_lo = dmae_reg_go_c[loader_idx] >> 2; | ||
3777 | dmae->comp_addr_hi = 0; | ||
3778 | dmae->comp_val = 1; | ||
3779 | } else { | ||
3780 | dmae->comp_addr_lo = | ||
3781 | U64_LO(bnx2x_sp_mapping(bp, stats_comp)); | ||
3782 | dmae->comp_addr_hi = | ||
3783 | U64_HI(bnx2x_sp_mapping(bp, stats_comp)); | ||
3784 | dmae->comp_val = DMAE_COMP_VAL; | ||
3785 | |||
3786 | *stats_comp = 0; | ||
3787 | } | ||
3788 | } | ||
3789 | |||
3790 | if (bp->func_stx) { | ||
3791 | |||
3792 | dmae = bnx2x_sp(bp, dmae[bp->executer_idx++]); | ||
3793 | dmae->opcode = (opcode | DMAE_CMD_C_DST_PCI); | ||
3794 | dmae->src_addr_lo = U64_LO(bnx2x_sp_mapping(bp, func_stats)); | ||
3795 | dmae->src_addr_hi = U64_HI(bnx2x_sp_mapping(bp, func_stats)); | ||
3796 | dmae->dst_addr_lo = bp->func_stx >> 2; | ||
3797 | dmae->dst_addr_hi = 0; | ||
3798 | dmae->len = sizeof(struct host_func_stats) >> 2; | ||
3799 | dmae->comp_addr_lo = U64_LO(bnx2x_sp_mapping(bp, stats_comp)); | ||
3800 | dmae->comp_addr_hi = U64_HI(bnx2x_sp_mapping(bp, stats_comp)); | ||
3801 | dmae->comp_val = DMAE_COMP_VAL; | ||
3802 | |||
3803 | *stats_comp = 0; | ||
3804 | } | ||
3805 | } | ||
3806 | |||
3807 | static void bnx2x_stats_stop(struct bnx2x *bp) | ||
3808 | { | ||
3809 | int update = 0; | ||
3810 | |||
3811 | bnx2x_stats_comp(bp); | ||
3812 | |||
3813 | if (bp->port.pmf) | ||
3814 | update = (bnx2x_hw_stats_update(bp) == 0); | ||
3815 | |||
3816 | update |= (bnx2x_storm_stats_update(bp) == 0); | ||
3817 | |||
3818 | if (update) { | ||
3819 | bnx2x_net_stats_update(bp); | ||
3820 | |||
3821 | if (bp->port.pmf) | ||
3822 | bnx2x_port_stats_stop(bp); | ||
3823 | |||
3824 | bnx2x_hw_stats_post(bp); | ||
3825 | bnx2x_stats_comp(bp); | ||
3826 | } | ||
3827 | } | ||
3828 | |||
3829 | static void bnx2x_stats_do_nothing(struct bnx2x *bp) | ||
3830 | { | ||
3831 | } | ||
3832 | |||
3833 | static const struct { | ||
3834 | void (*action)(struct bnx2x *bp); | ||
3835 | enum bnx2x_stats_state next_state; | ||
3836 | } bnx2x_stats_stm[STATS_STATE_MAX][STATS_EVENT_MAX] = { | ||
3837 | /* state event */ | ||
3838 | { | ||
3839 | /* DISABLED PMF */ {bnx2x_stats_pmf_update, STATS_STATE_DISABLED}, | ||
3840 | /* LINK_UP */ {bnx2x_stats_start, STATS_STATE_ENABLED}, | ||
3841 | /* UPDATE */ {bnx2x_stats_do_nothing, STATS_STATE_DISABLED}, | ||
3842 | /* STOP */ {bnx2x_stats_do_nothing, STATS_STATE_DISABLED} | ||
3843 | }, | ||
3844 | { | ||
3845 | /* ENABLED PMF */ {bnx2x_stats_pmf_start, STATS_STATE_ENABLED}, | ||
3846 | /* LINK_UP */ {bnx2x_stats_restart, STATS_STATE_ENABLED}, | ||
3847 | /* UPDATE */ {bnx2x_stats_update, STATS_STATE_ENABLED}, | ||
3848 | /* STOP */ {bnx2x_stats_stop, STATS_STATE_DISABLED} | ||
3849 | } | ||
3850 | }; | ||
3851 | |||
3852 | void bnx2x_stats_handle(struct bnx2x *bp, enum bnx2x_stats_event event) | ||
3853 | { | ||
3854 | enum bnx2x_stats_state state = bp->stats_state; | ||
3855 | |||
3856 | if (unlikely(bp->panic)) | ||
3857 | return; | ||
3858 | |||
3859 | bnx2x_stats_stm[state][event].action(bp); | ||
3860 | bp->stats_state = bnx2x_stats_stm[state][event].next_state; | ||
3861 | |||
3862 | /* Make sure the state has been "changed" */ | ||
3863 | smp_wmb(); | ||
3864 | |||
3865 | if ((event != STATS_EVENT_UPDATE) || netif_msg_timer(bp)) | ||
3866 | DP(BNX2X_MSG_STATS, "state %d -> event %d -> state %d\n", | ||
3867 | state, event, bp->stats_state); | ||
3868 | } | ||
3869 | |||
3870 | static void bnx2x_port_stats_base_init(struct bnx2x *bp) | ||
3871 | { | ||
3872 | struct dmae_command *dmae; | ||
3873 | u32 *stats_comp = bnx2x_sp(bp, stats_comp); | ||
3874 | |||
3875 | /* sanity */ | ||
3876 | if (!bp->port.pmf || !bp->port.port_stx) { | ||
3877 | BNX2X_ERR("BUG!\n"); | ||
3878 | return; | ||
3879 | } | ||
3880 | |||
3881 | bp->executer_idx = 0; | ||
3882 | |||
3883 | dmae = bnx2x_sp(bp, dmae[bp->executer_idx++]); | ||
3884 | dmae->opcode = (DMAE_CMD_SRC_PCI | DMAE_CMD_DST_GRC | | ||
3885 | DMAE_CMD_C_DST_PCI | DMAE_CMD_C_ENABLE | | ||
3886 | DMAE_CMD_SRC_RESET | DMAE_CMD_DST_RESET | | ||
3887 | #ifdef __BIG_ENDIAN | ||
3888 | DMAE_CMD_ENDIANITY_B_DW_SWAP | | ||
3889 | #else | ||
3890 | DMAE_CMD_ENDIANITY_DW_SWAP | | ||
3891 | #endif | ||
3892 | (BP_PORT(bp) ? DMAE_CMD_PORT_1 : DMAE_CMD_PORT_0) | | ||
3893 | (BP_E1HVN(bp) << DMAE_CMD_E1HVN_SHIFT)); | ||
3894 | dmae->src_addr_lo = U64_LO(bnx2x_sp_mapping(bp, port_stats)); | ||
3895 | dmae->src_addr_hi = U64_HI(bnx2x_sp_mapping(bp, port_stats)); | ||
3896 | dmae->dst_addr_lo = bp->port.port_stx >> 2; | ||
3897 | dmae->dst_addr_hi = 0; | ||
3898 | dmae->len = sizeof(struct host_port_stats) >> 2; | ||
3899 | dmae->comp_addr_lo = U64_LO(bnx2x_sp_mapping(bp, stats_comp)); | ||
3900 | dmae->comp_addr_hi = U64_HI(bnx2x_sp_mapping(bp, stats_comp)); | ||
3901 | dmae->comp_val = DMAE_COMP_VAL; | ||
3902 | |||
3903 | *stats_comp = 0; | ||
3904 | bnx2x_hw_stats_post(bp); | ||
3905 | bnx2x_stats_comp(bp); | ||
3906 | } | ||
3907 | |||
3908 | static void bnx2x_func_stats_base_init(struct bnx2x *bp) | ||
3909 | { | ||
3910 | int vn, vn_max = IS_E1HMF(bp) ? E1HVN_MAX : E1VN_MAX; | ||
3911 | int port = BP_PORT(bp); | ||
3912 | int func; | ||
3913 | u32 func_stx; | ||
3914 | |||
3915 | /* sanity */ | ||
3916 | if (!bp->port.pmf || !bp->func_stx) { | ||
3917 | BNX2X_ERR("BUG!\n"); | ||
3918 | return; | ||
3919 | } | ||
3920 | |||
3921 | /* save our func_stx */ | ||
3922 | func_stx = bp->func_stx; | ||
3923 | |||
3924 | for (vn = VN_0; vn < vn_max; vn++) { | ||
3925 | func = 2*vn + port; | ||
3926 | |||
3927 | bp->func_stx = SHMEM_RD(bp, func_mb[func].fw_mb_param); | ||
3928 | bnx2x_func_stats_init(bp); | ||
3929 | bnx2x_hw_stats_post(bp); | ||
3930 | bnx2x_stats_comp(bp); | ||
3931 | } | ||
3932 | |||
3933 | /* restore our func_stx */ | ||
3934 | bp->func_stx = func_stx; | ||
3935 | } | ||
3936 | |||
3937 | static void bnx2x_func_stats_base_update(struct bnx2x *bp) | ||
3938 | { | ||
3939 | struct dmae_command *dmae = &bp->stats_dmae; | ||
3940 | u32 *stats_comp = bnx2x_sp(bp, stats_comp); | ||
3941 | |||
3942 | /* sanity */ | ||
3943 | if (!bp->func_stx) { | ||
3944 | BNX2X_ERR("BUG!\n"); | ||
3945 | return; | ||
3946 | } | ||
3947 | |||
3948 | bp->executer_idx = 0; | ||
3949 | memset(dmae, 0, sizeof(struct dmae_command)); | ||
3950 | |||
3951 | dmae->opcode = (DMAE_CMD_SRC_GRC | DMAE_CMD_DST_PCI | | ||
3952 | DMAE_CMD_C_DST_PCI | DMAE_CMD_C_ENABLE | | ||
3953 | DMAE_CMD_SRC_RESET | DMAE_CMD_DST_RESET | | ||
3954 | #ifdef __BIG_ENDIAN | ||
3955 | DMAE_CMD_ENDIANITY_B_DW_SWAP | | ||
3956 | #else | ||
3957 | DMAE_CMD_ENDIANITY_DW_SWAP | | ||
3958 | #endif | ||
3959 | (BP_PORT(bp) ? DMAE_CMD_PORT_1 : DMAE_CMD_PORT_0) | | ||
3960 | (BP_E1HVN(bp) << DMAE_CMD_E1HVN_SHIFT)); | ||
3961 | dmae->src_addr_lo = bp->func_stx >> 2; | ||
3962 | dmae->src_addr_hi = 0; | ||
3963 | dmae->dst_addr_lo = U64_LO(bnx2x_sp_mapping(bp, func_stats_base)); | ||
3964 | dmae->dst_addr_hi = U64_HI(bnx2x_sp_mapping(bp, func_stats_base)); | ||
3965 | dmae->len = sizeof(struct host_func_stats) >> 2; | ||
3966 | dmae->comp_addr_lo = U64_LO(bnx2x_sp_mapping(bp, stats_comp)); | ||
3967 | dmae->comp_addr_hi = U64_HI(bnx2x_sp_mapping(bp, stats_comp)); | ||
3968 | dmae->comp_val = DMAE_COMP_VAL; | ||
3969 | |||
3970 | *stats_comp = 0; | ||
3971 | bnx2x_hw_stats_post(bp); | ||
3972 | bnx2x_stats_comp(bp); | ||
3973 | } | ||
3974 | |||
3975 | static void bnx2x_stats_init(struct bnx2x *bp) | ||
3976 | { | ||
3977 | int port = BP_PORT(bp); | ||
3978 | int func = BP_FUNC(bp); | ||
3979 | int i; | ||
3980 | |||
3981 | bp->stats_pending = 0; | ||
3982 | bp->executer_idx = 0; | ||
3983 | bp->stats_counter = 0; | ||
3984 | |||
3985 | /* port and func stats for management */ | ||
3986 | if (!BP_NOMCP(bp)) { | ||
3987 | bp->port.port_stx = SHMEM_RD(bp, port_mb[port].port_stx); | ||
3988 | bp->func_stx = SHMEM_RD(bp, func_mb[func].fw_mb_param); | ||
3989 | |||
3990 | } else { | ||
3991 | bp->port.port_stx = 0; | ||
3992 | bp->func_stx = 0; | ||
3993 | } | ||
3994 | DP(BNX2X_MSG_STATS, "port_stx 0x%x func_stx 0x%x\n", | ||
3995 | bp->port.port_stx, bp->func_stx); | ||
3996 | |||
3997 | /* port stats */ | ||
3998 | memset(&(bp->port.old_nig_stats), 0, sizeof(struct nig_stats)); | ||
3999 | bp->port.old_nig_stats.brb_discard = | ||
4000 | REG_RD(bp, NIG_REG_STAT0_BRB_DISCARD + port*0x38); | ||
4001 | bp->port.old_nig_stats.brb_truncate = | ||
4002 | REG_RD(bp, NIG_REG_STAT0_BRB_TRUNCATE + port*0x38); | ||
4003 | REG_RD_DMAE(bp, NIG_REG_STAT0_EGRESS_MAC_PKT0 + port*0x50, | ||
4004 | &(bp->port.old_nig_stats.egress_mac_pkt0_lo), 2); | ||
4005 | REG_RD_DMAE(bp, NIG_REG_STAT0_EGRESS_MAC_PKT1 + port*0x50, | ||
4006 | &(bp->port.old_nig_stats.egress_mac_pkt1_lo), 2); | ||
4007 | |||
4008 | /* function stats */ | ||
4009 | for_each_queue(bp, i) { | ||
4010 | struct bnx2x_fastpath *fp = &bp->fp[i]; | ||
4011 | |||
4012 | memset(&fp->old_tclient, 0, | ||
4013 | sizeof(struct tstorm_per_client_stats)); | ||
4014 | memset(&fp->old_uclient, 0, | ||
4015 | sizeof(struct ustorm_per_client_stats)); | ||
4016 | memset(&fp->old_xclient, 0, | ||
4017 | sizeof(struct xstorm_per_client_stats)); | ||
4018 | memset(&fp->eth_q_stats, 0, sizeof(struct bnx2x_eth_q_stats)); | ||
4019 | } | ||
4020 | |||
4021 | memset(&bp->dev->stats, 0, sizeof(struct net_device_stats)); | ||
4022 | memset(&bp->eth_stats, 0, sizeof(struct bnx2x_eth_stats)); | ||
4023 | |||
4024 | bp->stats_state = STATS_STATE_DISABLED; | ||
4025 | |||
4026 | if (bp->port.pmf) { | ||
4027 | if (bp->port.port_stx) | ||
4028 | bnx2x_port_stats_base_init(bp); | ||
4029 | |||
4030 | if (bp->func_stx) | ||
4031 | bnx2x_func_stats_base_init(bp); | ||
4032 | |||
4033 | } else if (bp->func_stx) | ||
4034 | bnx2x_func_stats_base_update(bp); | ||
4035 | } | ||
4036 | |||
4037 | static void bnx2x_timer(unsigned long data) | 2655 | static void bnx2x_timer(unsigned long data) |
4038 | { | 2656 | { |
4039 | struct bnx2x *bp = (struct bnx2x *) data; | 2657 | struct bnx2x *bp = (struct bnx2x *) data; |
diff --git a/drivers/net/bnx2x/bnx2x_stats.c b/drivers/net/bnx2x/bnx2x_stats.c new file mode 100644 index 000000000000..3f5127720423 --- /dev/null +++ b/drivers/net/bnx2x/bnx2x_stats.c | |||
@@ -0,0 +1,1400 @@ | |||
1 | /* bnx2x_stats.c: Broadcom Everest network driver. | ||
2 | * | ||
3 | * Copyright (c) 2007-2010 Broadcom Corporation | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify | ||
6 | * it under the terms of the GNU General Public License as published by | ||
7 | * the Free Software Foundation. | ||
8 | * | ||
9 | * Maintained by: Eilon Greenstein <eilong@broadcom.com> | ||
10 | * Written by: Eliezer Tamir | ||
11 | * Based on code from Michael Chan's bnx2 driver | ||
12 | * UDP CSUM errata workaround by Arik Gendelman | ||
13 | * Slowpath and fastpath rework by Vladislav Zolotarov | ||
14 | * Statistics and Link management by Yitchak Gertner | ||
15 | * | ||
16 | */ | ||
17 | #include "bnx2x_cmn.h" | ||
18 | #include "bnx2x_stats.h" | ||
19 | |||
20 | /* Statistics */ | ||
21 | |||
22 | /**************************************************************************** | ||
23 | * Macros | ||
24 | ****************************************************************************/ | ||
25 | |||
26 | /* sum[hi:lo] += add[hi:lo] */ | ||
27 | #define ADD_64(s_hi, a_hi, s_lo, a_lo) \ | ||
28 | do { \ | ||
29 | s_lo += a_lo; \ | ||
30 | s_hi += a_hi + ((s_lo < a_lo) ? 1 : 0); \ | ||
31 | } while (0) | ||
32 | |||
33 | /* difference = minuend - subtrahend */ | ||
34 | #define DIFF_64(d_hi, m_hi, s_hi, d_lo, m_lo, s_lo) \ | ||
35 | do { \ | ||
36 | if (m_lo < s_lo) { \ | ||
37 | /* underflow */ \ | ||
38 | d_hi = m_hi - s_hi; \ | ||
39 | if (d_hi > 0) { \ | ||
40 | /* we can 'loan' 1 */ \ | ||
41 | d_hi--; \ | ||
42 | d_lo = m_lo + (UINT_MAX - s_lo) + 1; \ | ||
43 | } else { \ | ||
44 | /* m_hi <= s_hi */ \ | ||
45 | d_hi = 0; \ | ||
46 | d_lo = 0; \ | ||
47 | } \ | ||
48 | } else { \ | ||
49 | /* m_lo >= s_lo */ \ | ||
50 | if (m_hi < s_hi) { \ | ||
51 | d_hi = 0; \ | ||
52 | d_lo = 0; \ | ||
53 | } else { \ | ||
54 | /* m_hi >= s_hi */ \ | ||
55 | d_hi = m_hi - s_hi; \ | ||
56 | d_lo = m_lo - s_lo; \ | ||
57 | } \ | ||
58 | } \ | ||
59 | } while (0) | ||
60 | |||
61 | #define UPDATE_STAT64(s, t) \ | ||
62 | do { \ | ||
63 | DIFF_64(diff.hi, new->s##_hi, pstats->mac_stx[0].t##_hi, \ | ||
64 | diff.lo, new->s##_lo, pstats->mac_stx[0].t##_lo); \ | ||
65 | pstats->mac_stx[0].t##_hi = new->s##_hi; \ | ||
66 | pstats->mac_stx[0].t##_lo = new->s##_lo; \ | ||
67 | ADD_64(pstats->mac_stx[1].t##_hi, diff.hi, \ | ||
68 | pstats->mac_stx[1].t##_lo, diff.lo); \ | ||
69 | } while (0) | ||
70 | |||
71 | #define UPDATE_STAT64_NIG(s, t) \ | ||
72 | do { \ | ||
73 | DIFF_64(diff.hi, new->s##_hi, old->s##_hi, \ | ||
74 | diff.lo, new->s##_lo, old->s##_lo); \ | ||
75 | ADD_64(estats->t##_hi, diff.hi, \ | ||
76 | estats->t##_lo, diff.lo); \ | ||
77 | } while (0) | ||
78 | |||
79 | /* sum[hi:lo] += add */ | ||
80 | #define ADD_EXTEND_64(s_hi, s_lo, a) \ | ||
81 | do { \ | ||
82 | s_lo += a; \ | ||
83 | s_hi += (s_lo < a) ? 1 : 0; \ | ||
84 | } while (0) | ||
85 | |||
86 | #define UPDATE_EXTEND_STAT(s) \ | ||
87 | do { \ | ||
88 | ADD_EXTEND_64(pstats->mac_stx[1].s##_hi, \ | ||
89 | pstats->mac_stx[1].s##_lo, \ | ||
90 | new->s); \ | ||
91 | } while (0) | ||
92 | |||
93 | #define UPDATE_EXTEND_TSTAT(s, t) \ | ||
94 | do { \ | ||
95 | diff = le32_to_cpu(tclient->s) - le32_to_cpu(old_tclient->s); \ | ||
96 | old_tclient->s = tclient->s; \ | ||
97 | ADD_EXTEND_64(qstats->t##_hi, qstats->t##_lo, diff); \ | ||
98 | } while (0) | ||
99 | |||
100 | #define UPDATE_EXTEND_USTAT(s, t) \ | ||
101 | do { \ | ||
102 | diff = le32_to_cpu(uclient->s) - le32_to_cpu(old_uclient->s); \ | ||
103 | old_uclient->s = uclient->s; \ | ||
104 | ADD_EXTEND_64(qstats->t##_hi, qstats->t##_lo, diff); \ | ||
105 | } while (0) | ||
106 | |||
107 | #define UPDATE_EXTEND_XSTAT(s, t) \ | ||
108 | do { \ | ||
109 | diff = le32_to_cpu(xclient->s) - le32_to_cpu(old_xclient->s); \ | ||
110 | old_xclient->s = xclient->s; \ | ||
111 | ADD_EXTEND_64(qstats->t##_hi, qstats->t##_lo, diff); \ | ||
112 | } while (0) | ||
113 | |||
114 | /* minuend -= subtrahend */ | ||
115 | #define SUB_64(m_hi, s_hi, m_lo, s_lo) \ | ||
116 | do { \ | ||
117 | DIFF_64(m_hi, m_hi, s_hi, m_lo, m_lo, s_lo); \ | ||
118 | } while (0) | ||
119 | |||
120 | /* minuend[hi:lo] -= subtrahend */ | ||
121 | #define SUB_EXTEND_64(m_hi, m_lo, s) \ | ||
122 | do { \ | ||
123 | SUB_64(m_hi, 0, m_lo, s); \ | ||
124 | } while (0) | ||
125 | |||
126 | #define SUB_EXTEND_USTAT(s, t) \ | ||
127 | do { \ | ||
128 | diff = le32_to_cpu(uclient->s) - le32_to_cpu(old_uclient->s); \ | ||
129 | SUB_EXTEND_64(qstats->t##_hi, qstats->t##_lo, diff); \ | ||
130 | } while (0) | ||
131 | |||
132 | /* | ||
133 | * General service functions | ||
134 | */ | ||
135 | |||
136 | static inline long bnx2x_hilo(u32 *hiref) | ||
137 | { | ||
138 | u32 lo = *(hiref + 1); | ||
139 | #if (BITS_PER_LONG == 64) | ||
140 | u32 hi = *hiref; | ||
141 | |||
142 | return HILO_U64(hi, lo); | ||
143 | #else | ||
144 | return lo; | ||
145 | #endif | ||
146 | } | ||
147 | |||
148 | /* | ||
149 | * Init service functions | ||
150 | */ | ||
151 | |||
152 | |||
153 | static void bnx2x_storm_stats_post(struct bnx2x *bp) | ||
154 | { | ||
155 | if (!bp->stats_pending) { | ||
156 | struct eth_query_ramrod_data ramrod_data = {0}; | ||
157 | int i, rc; | ||
158 | |||
159 | ramrod_data.drv_counter = bp->stats_counter++; | ||
160 | ramrod_data.collect_port = bp->port.pmf ? 1 : 0; | ||
161 | for_each_queue(bp, i) | ||
162 | ramrod_data.ctr_id_vector |= (1 << bp->fp[i].cl_id); | ||
163 | |||
164 | rc = bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_STAT_QUERY, 0, | ||
165 | ((u32 *)&ramrod_data)[1], | ||
166 | ((u32 *)&ramrod_data)[0], 0); | ||
167 | if (rc == 0) { | ||
168 | /* stats ramrod has it's own slot on the spq */ | ||
169 | bp->spq_left++; | ||
170 | bp->stats_pending = 1; | ||
171 | } | ||
172 | } | ||
173 | } | ||
174 | |||
175 | static void bnx2x_hw_stats_post(struct bnx2x *bp) | ||
176 | { | ||
177 | struct dmae_command *dmae = &bp->stats_dmae; | ||
178 | u32 *stats_comp = bnx2x_sp(bp, stats_comp); | ||
179 | |||
180 | *stats_comp = DMAE_COMP_VAL; | ||
181 | if (CHIP_REV_IS_SLOW(bp)) | ||
182 | return; | ||
183 | |||
184 | /* loader */ | ||
185 | if (bp->executer_idx) { | ||
186 | int loader_idx = PMF_DMAE_C(bp); | ||
187 | |||
188 | memset(dmae, 0, sizeof(struct dmae_command)); | ||
189 | |||
190 | dmae->opcode = (DMAE_CMD_SRC_PCI | DMAE_CMD_DST_GRC | | ||
191 | DMAE_CMD_C_DST_GRC | DMAE_CMD_C_ENABLE | | ||
192 | DMAE_CMD_DST_RESET | | ||
193 | #ifdef __BIG_ENDIAN | ||
194 | DMAE_CMD_ENDIANITY_B_DW_SWAP | | ||
195 | #else | ||
196 | DMAE_CMD_ENDIANITY_DW_SWAP | | ||
197 | #endif | ||
198 | (BP_PORT(bp) ? DMAE_CMD_PORT_1 : | ||
199 | DMAE_CMD_PORT_0) | | ||
200 | (BP_E1HVN(bp) << DMAE_CMD_E1HVN_SHIFT)); | ||
201 | dmae->src_addr_lo = U64_LO(bnx2x_sp_mapping(bp, dmae[0])); | ||
202 | dmae->src_addr_hi = U64_HI(bnx2x_sp_mapping(bp, dmae[0])); | ||
203 | dmae->dst_addr_lo = (DMAE_REG_CMD_MEM + | ||
204 | sizeof(struct dmae_command) * | ||
205 | (loader_idx + 1)) >> 2; | ||
206 | dmae->dst_addr_hi = 0; | ||
207 | dmae->len = sizeof(struct dmae_command) >> 2; | ||
208 | if (CHIP_IS_E1(bp)) | ||
209 | dmae->len--; | ||
210 | dmae->comp_addr_lo = dmae_reg_go_c[loader_idx + 1] >> 2; | ||
211 | dmae->comp_addr_hi = 0; | ||
212 | dmae->comp_val = 1; | ||
213 | |||
214 | *stats_comp = 0; | ||
215 | bnx2x_post_dmae(bp, dmae, loader_idx); | ||
216 | |||
217 | } else if (bp->func_stx) { | ||
218 | *stats_comp = 0; | ||
219 | bnx2x_post_dmae(bp, dmae, INIT_DMAE_C(bp)); | ||
220 | } | ||
221 | } | ||
222 | |||
223 | static int bnx2x_stats_comp(struct bnx2x *bp) | ||
224 | { | ||
225 | u32 *stats_comp = bnx2x_sp(bp, stats_comp); | ||
226 | int cnt = 10; | ||
227 | |||
228 | might_sleep(); | ||
229 | while (*stats_comp != DMAE_COMP_VAL) { | ||
230 | if (!cnt) { | ||
231 | BNX2X_ERR("timeout waiting for stats finished\n"); | ||
232 | break; | ||
233 | } | ||
234 | cnt--; | ||
235 | msleep(1); | ||
236 | } | ||
237 | return 1; | ||
238 | } | ||
239 | |||
240 | /* | ||
241 | * Statistics service functions | ||
242 | */ | ||
243 | |||
244 | static void bnx2x_stats_pmf_update(struct bnx2x *bp) | ||
245 | { | ||
246 | struct dmae_command *dmae; | ||
247 | u32 opcode; | ||
248 | int loader_idx = PMF_DMAE_C(bp); | ||
249 | u32 *stats_comp = bnx2x_sp(bp, stats_comp); | ||
250 | |||
251 | /* sanity */ | ||
252 | if (!IS_E1HMF(bp) || !bp->port.pmf || !bp->port.port_stx) { | ||
253 | BNX2X_ERR("BUG!\n"); | ||
254 | return; | ||
255 | } | ||
256 | |||
257 | bp->executer_idx = 0; | ||
258 | |||
259 | opcode = (DMAE_CMD_SRC_GRC | DMAE_CMD_DST_PCI | | ||
260 | DMAE_CMD_C_ENABLE | | ||
261 | DMAE_CMD_SRC_RESET | DMAE_CMD_DST_RESET | | ||
262 | #ifdef __BIG_ENDIAN | ||
263 | DMAE_CMD_ENDIANITY_B_DW_SWAP | | ||
264 | #else | ||
265 | DMAE_CMD_ENDIANITY_DW_SWAP | | ||
266 | #endif | ||
267 | (BP_PORT(bp) ? DMAE_CMD_PORT_1 : DMAE_CMD_PORT_0) | | ||
268 | (BP_E1HVN(bp) << DMAE_CMD_E1HVN_SHIFT)); | ||
269 | |||
270 | dmae = bnx2x_sp(bp, dmae[bp->executer_idx++]); | ||
271 | dmae->opcode = (opcode | DMAE_CMD_C_DST_GRC); | ||
272 | dmae->src_addr_lo = bp->port.port_stx >> 2; | ||
273 | dmae->src_addr_hi = 0; | ||
274 | dmae->dst_addr_lo = U64_LO(bnx2x_sp_mapping(bp, port_stats)); | ||
275 | dmae->dst_addr_hi = U64_HI(bnx2x_sp_mapping(bp, port_stats)); | ||
276 | dmae->len = DMAE_LEN32_RD_MAX; | ||
277 | dmae->comp_addr_lo = dmae_reg_go_c[loader_idx] >> 2; | ||
278 | dmae->comp_addr_hi = 0; | ||
279 | dmae->comp_val = 1; | ||
280 | |||
281 | dmae = bnx2x_sp(bp, dmae[bp->executer_idx++]); | ||
282 | dmae->opcode = (opcode | DMAE_CMD_C_DST_PCI); | ||
283 | dmae->src_addr_lo = (bp->port.port_stx >> 2) + DMAE_LEN32_RD_MAX; | ||
284 | dmae->src_addr_hi = 0; | ||
285 | dmae->dst_addr_lo = U64_LO(bnx2x_sp_mapping(bp, port_stats) + | ||
286 | DMAE_LEN32_RD_MAX * 4); | ||
287 | dmae->dst_addr_hi = U64_HI(bnx2x_sp_mapping(bp, port_stats) + | ||
288 | DMAE_LEN32_RD_MAX * 4); | ||
289 | dmae->len = (sizeof(struct host_port_stats) >> 2) - DMAE_LEN32_RD_MAX; | ||
290 | dmae->comp_addr_lo = U64_LO(bnx2x_sp_mapping(bp, stats_comp)); | ||
291 | dmae->comp_addr_hi = U64_HI(bnx2x_sp_mapping(bp, stats_comp)); | ||
292 | dmae->comp_val = DMAE_COMP_VAL; | ||
293 | |||
294 | *stats_comp = 0; | ||
295 | bnx2x_hw_stats_post(bp); | ||
296 | bnx2x_stats_comp(bp); | ||
297 | } | ||
298 | |||
299 | static void bnx2x_port_stats_init(struct bnx2x *bp) | ||
300 | { | ||
301 | struct dmae_command *dmae; | ||
302 | int port = BP_PORT(bp); | ||
303 | int vn = BP_E1HVN(bp); | ||
304 | u32 opcode; | ||
305 | int loader_idx = PMF_DMAE_C(bp); | ||
306 | u32 mac_addr; | ||
307 | u32 *stats_comp = bnx2x_sp(bp, stats_comp); | ||
308 | |||
309 | /* sanity */ | ||
310 | if (!bp->link_vars.link_up || !bp->port.pmf) { | ||
311 | BNX2X_ERR("BUG!\n"); | ||
312 | return; | ||
313 | } | ||
314 | |||
315 | bp->executer_idx = 0; | ||
316 | |||
317 | /* MCP */ | ||
318 | opcode = (DMAE_CMD_SRC_PCI | DMAE_CMD_DST_GRC | | ||
319 | DMAE_CMD_C_DST_GRC | DMAE_CMD_C_ENABLE | | ||
320 | DMAE_CMD_SRC_RESET | DMAE_CMD_DST_RESET | | ||
321 | #ifdef __BIG_ENDIAN | ||
322 | DMAE_CMD_ENDIANITY_B_DW_SWAP | | ||
323 | #else | ||
324 | DMAE_CMD_ENDIANITY_DW_SWAP | | ||
325 | #endif | ||
326 | (port ? DMAE_CMD_PORT_1 : DMAE_CMD_PORT_0) | | ||
327 | (vn << DMAE_CMD_E1HVN_SHIFT)); | ||
328 | |||
329 | if (bp->port.port_stx) { | ||
330 | |||
331 | dmae = bnx2x_sp(bp, dmae[bp->executer_idx++]); | ||
332 | dmae->opcode = opcode; | ||
333 | dmae->src_addr_lo = U64_LO(bnx2x_sp_mapping(bp, port_stats)); | ||
334 | dmae->src_addr_hi = U64_HI(bnx2x_sp_mapping(bp, port_stats)); | ||
335 | dmae->dst_addr_lo = bp->port.port_stx >> 2; | ||
336 | dmae->dst_addr_hi = 0; | ||
337 | dmae->len = sizeof(struct host_port_stats) >> 2; | ||
338 | dmae->comp_addr_lo = dmae_reg_go_c[loader_idx] >> 2; | ||
339 | dmae->comp_addr_hi = 0; | ||
340 | dmae->comp_val = 1; | ||
341 | } | ||
342 | |||
343 | if (bp->func_stx) { | ||
344 | |||
345 | dmae = bnx2x_sp(bp, dmae[bp->executer_idx++]); | ||
346 | dmae->opcode = opcode; | ||
347 | dmae->src_addr_lo = U64_LO(bnx2x_sp_mapping(bp, func_stats)); | ||
348 | dmae->src_addr_hi = U64_HI(bnx2x_sp_mapping(bp, func_stats)); | ||
349 | dmae->dst_addr_lo = bp->func_stx >> 2; | ||
350 | dmae->dst_addr_hi = 0; | ||
351 | dmae->len = sizeof(struct host_func_stats) >> 2; | ||
352 | dmae->comp_addr_lo = dmae_reg_go_c[loader_idx] >> 2; | ||
353 | dmae->comp_addr_hi = 0; | ||
354 | dmae->comp_val = 1; | ||
355 | } | ||
356 | |||
357 | /* MAC */ | ||
358 | opcode = (DMAE_CMD_SRC_GRC | DMAE_CMD_DST_PCI | | ||
359 | DMAE_CMD_C_DST_GRC | DMAE_CMD_C_ENABLE | | ||
360 | DMAE_CMD_SRC_RESET | DMAE_CMD_DST_RESET | | ||
361 | #ifdef __BIG_ENDIAN | ||
362 | DMAE_CMD_ENDIANITY_B_DW_SWAP | | ||
363 | #else | ||
364 | DMAE_CMD_ENDIANITY_DW_SWAP | | ||
365 | #endif | ||
366 | (port ? DMAE_CMD_PORT_1 : DMAE_CMD_PORT_0) | | ||
367 | (vn << DMAE_CMD_E1HVN_SHIFT)); | ||
368 | |||
369 | if (bp->link_vars.mac_type == MAC_TYPE_BMAC) { | ||
370 | |||
371 | mac_addr = (port ? NIG_REG_INGRESS_BMAC1_MEM : | ||
372 | NIG_REG_INGRESS_BMAC0_MEM); | ||
373 | |||
374 | /* BIGMAC_REGISTER_TX_STAT_GTPKT .. | ||
375 | BIGMAC_REGISTER_TX_STAT_GTBYT */ | ||
376 | dmae = bnx2x_sp(bp, dmae[bp->executer_idx++]); | ||
377 | dmae->opcode = opcode; | ||
378 | dmae->src_addr_lo = (mac_addr + | ||
379 | BIGMAC_REGISTER_TX_STAT_GTPKT) >> 2; | ||
380 | dmae->src_addr_hi = 0; | ||
381 | dmae->dst_addr_lo = U64_LO(bnx2x_sp_mapping(bp, mac_stats)); | ||
382 | dmae->dst_addr_hi = U64_HI(bnx2x_sp_mapping(bp, mac_stats)); | ||
383 | dmae->len = (8 + BIGMAC_REGISTER_TX_STAT_GTBYT - | ||
384 | BIGMAC_REGISTER_TX_STAT_GTPKT) >> 2; | ||
385 | dmae->comp_addr_lo = dmae_reg_go_c[loader_idx] >> 2; | ||
386 | dmae->comp_addr_hi = 0; | ||
387 | dmae->comp_val = 1; | ||
388 | |||
389 | /* BIGMAC_REGISTER_RX_STAT_GR64 .. | ||
390 | BIGMAC_REGISTER_RX_STAT_GRIPJ */ | ||
391 | dmae = bnx2x_sp(bp, dmae[bp->executer_idx++]); | ||
392 | dmae->opcode = opcode; | ||
393 | dmae->src_addr_lo = (mac_addr + | ||
394 | BIGMAC_REGISTER_RX_STAT_GR64) >> 2; | ||
395 | dmae->src_addr_hi = 0; | ||
396 | dmae->dst_addr_lo = U64_LO(bnx2x_sp_mapping(bp, mac_stats) + | ||
397 | offsetof(struct bmac_stats, rx_stat_gr64_lo)); | ||
398 | dmae->dst_addr_hi = U64_HI(bnx2x_sp_mapping(bp, mac_stats) + | ||
399 | offsetof(struct bmac_stats, rx_stat_gr64_lo)); | ||
400 | dmae->len = (8 + BIGMAC_REGISTER_RX_STAT_GRIPJ - | ||
401 | BIGMAC_REGISTER_RX_STAT_GR64) >> 2; | ||
402 | dmae->comp_addr_lo = dmae_reg_go_c[loader_idx] >> 2; | ||
403 | dmae->comp_addr_hi = 0; | ||
404 | dmae->comp_val = 1; | ||
405 | |||
406 | } else if (bp->link_vars.mac_type == MAC_TYPE_EMAC) { | ||
407 | |||
408 | mac_addr = (port ? GRCBASE_EMAC1 : GRCBASE_EMAC0); | ||
409 | |||
410 | /* EMAC_REG_EMAC_RX_STAT_AC (EMAC_REG_EMAC_RX_STAT_AC_COUNT)*/ | ||
411 | dmae = bnx2x_sp(bp, dmae[bp->executer_idx++]); | ||
412 | dmae->opcode = opcode; | ||
413 | dmae->src_addr_lo = (mac_addr + | ||
414 | EMAC_REG_EMAC_RX_STAT_AC) >> 2; | ||
415 | dmae->src_addr_hi = 0; | ||
416 | dmae->dst_addr_lo = U64_LO(bnx2x_sp_mapping(bp, mac_stats)); | ||
417 | dmae->dst_addr_hi = U64_HI(bnx2x_sp_mapping(bp, mac_stats)); | ||
418 | dmae->len = EMAC_REG_EMAC_RX_STAT_AC_COUNT; | ||
419 | dmae->comp_addr_lo = dmae_reg_go_c[loader_idx] >> 2; | ||
420 | dmae->comp_addr_hi = 0; | ||
421 | dmae->comp_val = 1; | ||
422 | |||
423 | /* EMAC_REG_EMAC_RX_STAT_AC_28 */ | ||
424 | dmae = bnx2x_sp(bp, dmae[bp->executer_idx++]); | ||
425 | dmae->opcode = opcode; | ||
426 | dmae->src_addr_lo = (mac_addr + | ||
427 | EMAC_REG_EMAC_RX_STAT_AC_28) >> 2; | ||
428 | dmae->src_addr_hi = 0; | ||
429 | dmae->dst_addr_lo = U64_LO(bnx2x_sp_mapping(bp, mac_stats) + | ||
430 | offsetof(struct emac_stats, rx_stat_falsecarriererrors)); | ||
431 | dmae->dst_addr_hi = U64_HI(bnx2x_sp_mapping(bp, mac_stats) + | ||
432 | offsetof(struct emac_stats, rx_stat_falsecarriererrors)); | ||
433 | dmae->len = 1; | ||
434 | dmae->comp_addr_lo = dmae_reg_go_c[loader_idx] >> 2; | ||
435 | dmae->comp_addr_hi = 0; | ||
436 | dmae->comp_val = 1; | ||
437 | |||
438 | /* EMAC_REG_EMAC_TX_STAT_AC (EMAC_REG_EMAC_TX_STAT_AC_COUNT)*/ | ||
439 | dmae = bnx2x_sp(bp, dmae[bp->executer_idx++]); | ||
440 | dmae->opcode = opcode; | ||
441 | dmae->src_addr_lo = (mac_addr + | ||
442 | EMAC_REG_EMAC_TX_STAT_AC) >> 2; | ||
443 | dmae->src_addr_hi = 0; | ||
444 | dmae->dst_addr_lo = U64_LO(bnx2x_sp_mapping(bp, mac_stats) + | ||
445 | offsetof(struct emac_stats, tx_stat_ifhcoutoctets)); | ||
446 | dmae->dst_addr_hi = U64_HI(bnx2x_sp_mapping(bp, mac_stats) + | ||
447 | offsetof(struct emac_stats, tx_stat_ifhcoutoctets)); | ||
448 | dmae->len = EMAC_REG_EMAC_TX_STAT_AC_COUNT; | ||
449 | dmae->comp_addr_lo = dmae_reg_go_c[loader_idx] >> 2; | ||
450 | dmae->comp_addr_hi = 0; | ||
451 | dmae->comp_val = 1; | ||
452 | } | ||
453 | |||
454 | /* NIG */ | ||
455 | dmae = bnx2x_sp(bp, dmae[bp->executer_idx++]); | ||
456 | dmae->opcode = opcode; | ||
457 | dmae->src_addr_lo = (port ? NIG_REG_STAT1_BRB_DISCARD : | ||
458 | NIG_REG_STAT0_BRB_DISCARD) >> 2; | ||
459 | dmae->src_addr_hi = 0; | ||
460 | dmae->dst_addr_lo = U64_LO(bnx2x_sp_mapping(bp, nig_stats)); | ||
461 | dmae->dst_addr_hi = U64_HI(bnx2x_sp_mapping(bp, nig_stats)); | ||
462 | dmae->len = (sizeof(struct nig_stats) - 4*sizeof(u32)) >> 2; | ||
463 | dmae->comp_addr_lo = dmae_reg_go_c[loader_idx] >> 2; | ||
464 | dmae->comp_addr_hi = 0; | ||
465 | dmae->comp_val = 1; | ||
466 | |||
467 | dmae = bnx2x_sp(bp, dmae[bp->executer_idx++]); | ||
468 | dmae->opcode = opcode; | ||
469 | dmae->src_addr_lo = (port ? NIG_REG_STAT1_EGRESS_MAC_PKT0 : | ||
470 | NIG_REG_STAT0_EGRESS_MAC_PKT0) >> 2; | ||
471 | dmae->src_addr_hi = 0; | ||
472 | dmae->dst_addr_lo = U64_LO(bnx2x_sp_mapping(bp, nig_stats) + | ||
473 | offsetof(struct nig_stats, egress_mac_pkt0_lo)); | ||
474 | dmae->dst_addr_hi = U64_HI(bnx2x_sp_mapping(bp, nig_stats) + | ||
475 | offsetof(struct nig_stats, egress_mac_pkt0_lo)); | ||
476 | dmae->len = (2*sizeof(u32)) >> 2; | ||
477 | dmae->comp_addr_lo = dmae_reg_go_c[loader_idx] >> 2; | ||
478 | dmae->comp_addr_hi = 0; | ||
479 | dmae->comp_val = 1; | ||
480 | |||
481 | dmae = bnx2x_sp(bp, dmae[bp->executer_idx++]); | ||
482 | dmae->opcode = (DMAE_CMD_SRC_GRC | DMAE_CMD_DST_PCI | | ||
483 | DMAE_CMD_C_DST_PCI | DMAE_CMD_C_ENABLE | | ||
484 | DMAE_CMD_SRC_RESET | DMAE_CMD_DST_RESET | | ||
485 | #ifdef __BIG_ENDIAN | ||
486 | DMAE_CMD_ENDIANITY_B_DW_SWAP | | ||
487 | #else | ||
488 | DMAE_CMD_ENDIANITY_DW_SWAP | | ||
489 | #endif | ||
490 | (port ? DMAE_CMD_PORT_1 : DMAE_CMD_PORT_0) | | ||
491 | (vn << DMAE_CMD_E1HVN_SHIFT)); | ||
492 | dmae->src_addr_lo = (port ? NIG_REG_STAT1_EGRESS_MAC_PKT1 : | ||
493 | NIG_REG_STAT0_EGRESS_MAC_PKT1) >> 2; | ||
494 | dmae->src_addr_hi = 0; | ||
495 | dmae->dst_addr_lo = U64_LO(bnx2x_sp_mapping(bp, nig_stats) + | ||
496 | offsetof(struct nig_stats, egress_mac_pkt1_lo)); | ||
497 | dmae->dst_addr_hi = U64_HI(bnx2x_sp_mapping(bp, nig_stats) + | ||
498 | offsetof(struct nig_stats, egress_mac_pkt1_lo)); | ||
499 | dmae->len = (2*sizeof(u32)) >> 2; | ||
500 | dmae->comp_addr_lo = U64_LO(bnx2x_sp_mapping(bp, stats_comp)); | ||
501 | dmae->comp_addr_hi = U64_HI(bnx2x_sp_mapping(bp, stats_comp)); | ||
502 | dmae->comp_val = DMAE_COMP_VAL; | ||
503 | |||
504 | *stats_comp = 0; | ||
505 | } | ||
506 | |||
507 | static void bnx2x_func_stats_init(struct bnx2x *bp) | ||
508 | { | ||
509 | struct dmae_command *dmae = &bp->stats_dmae; | ||
510 | u32 *stats_comp = bnx2x_sp(bp, stats_comp); | ||
511 | |||
512 | /* sanity */ | ||
513 | if (!bp->func_stx) { | ||
514 | BNX2X_ERR("BUG!\n"); | ||
515 | return; | ||
516 | } | ||
517 | |||
518 | bp->executer_idx = 0; | ||
519 | memset(dmae, 0, sizeof(struct dmae_command)); | ||
520 | |||
521 | dmae->opcode = (DMAE_CMD_SRC_PCI | DMAE_CMD_DST_GRC | | ||
522 | DMAE_CMD_C_DST_PCI | DMAE_CMD_C_ENABLE | | ||
523 | DMAE_CMD_SRC_RESET | DMAE_CMD_DST_RESET | | ||
524 | #ifdef __BIG_ENDIAN | ||
525 | DMAE_CMD_ENDIANITY_B_DW_SWAP | | ||
526 | #else | ||
527 | DMAE_CMD_ENDIANITY_DW_SWAP | | ||
528 | #endif | ||
529 | (BP_PORT(bp) ? DMAE_CMD_PORT_1 : DMAE_CMD_PORT_0) | | ||
530 | (BP_E1HVN(bp) << DMAE_CMD_E1HVN_SHIFT)); | ||
531 | dmae->src_addr_lo = U64_LO(bnx2x_sp_mapping(bp, func_stats)); | ||
532 | dmae->src_addr_hi = U64_HI(bnx2x_sp_mapping(bp, func_stats)); | ||
533 | dmae->dst_addr_lo = bp->func_stx >> 2; | ||
534 | dmae->dst_addr_hi = 0; | ||
535 | dmae->len = sizeof(struct host_func_stats) >> 2; | ||
536 | dmae->comp_addr_lo = U64_LO(bnx2x_sp_mapping(bp, stats_comp)); | ||
537 | dmae->comp_addr_hi = U64_HI(bnx2x_sp_mapping(bp, stats_comp)); | ||
538 | dmae->comp_val = DMAE_COMP_VAL; | ||
539 | |||
540 | *stats_comp = 0; | ||
541 | } | ||
542 | |||
543 | static void bnx2x_stats_start(struct bnx2x *bp) | ||
544 | { | ||
545 | if (bp->port.pmf) | ||
546 | bnx2x_port_stats_init(bp); | ||
547 | |||
548 | else if (bp->func_stx) | ||
549 | bnx2x_func_stats_init(bp); | ||
550 | |||
551 | bnx2x_hw_stats_post(bp); | ||
552 | bnx2x_storm_stats_post(bp); | ||
553 | } | ||
554 | |||
555 | static void bnx2x_stats_pmf_start(struct bnx2x *bp) | ||
556 | { | ||
557 | bnx2x_stats_comp(bp); | ||
558 | bnx2x_stats_pmf_update(bp); | ||
559 | bnx2x_stats_start(bp); | ||
560 | } | ||
561 | |||
562 | static void bnx2x_stats_restart(struct bnx2x *bp) | ||
563 | { | ||
564 | bnx2x_stats_comp(bp); | ||
565 | bnx2x_stats_start(bp); | ||
566 | } | ||
567 | |||
568 | static void bnx2x_bmac_stats_update(struct bnx2x *bp) | ||
569 | { | ||
570 | struct bmac_stats *new = bnx2x_sp(bp, mac_stats.bmac_stats); | ||
571 | struct host_port_stats *pstats = bnx2x_sp(bp, port_stats); | ||
572 | struct bnx2x_eth_stats *estats = &bp->eth_stats; | ||
573 | struct { | ||
574 | u32 lo; | ||
575 | u32 hi; | ||
576 | } diff; | ||
577 | |||
578 | UPDATE_STAT64(rx_stat_grerb, rx_stat_ifhcinbadoctets); | ||
579 | UPDATE_STAT64(rx_stat_grfcs, rx_stat_dot3statsfcserrors); | ||
580 | UPDATE_STAT64(rx_stat_grund, rx_stat_etherstatsundersizepkts); | ||
581 | UPDATE_STAT64(rx_stat_grovr, rx_stat_dot3statsframestoolong); | ||
582 | UPDATE_STAT64(rx_stat_grfrg, rx_stat_etherstatsfragments); | ||
583 | UPDATE_STAT64(rx_stat_grjbr, rx_stat_etherstatsjabbers); | ||
584 | UPDATE_STAT64(rx_stat_grxcf, rx_stat_maccontrolframesreceived); | ||
585 | UPDATE_STAT64(rx_stat_grxpf, rx_stat_xoffstateentered); | ||
586 | UPDATE_STAT64(rx_stat_grxpf, rx_stat_bmac_xpf); | ||
587 | UPDATE_STAT64(tx_stat_gtxpf, tx_stat_outxoffsent); | ||
588 | UPDATE_STAT64(tx_stat_gtxpf, tx_stat_flowcontroldone); | ||
589 | UPDATE_STAT64(tx_stat_gt64, tx_stat_etherstatspkts64octets); | ||
590 | UPDATE_STAT64(tx_stat_gt127, | ||
591 | tx_stat_etherstatspkts65octetsto127octets); | ||
592 | UPDATE_STAT64(tx_stat_gt255, | ||
593 | tx_stat_etherstatspkts128octetsto255octets); | ||
594 | UPDATE_STAT64(tx_stat_gt511, | ||
595 | tx_stat_etherstatspkts256octetsto511octets); | ||
596 | UPDATE_STAT64(tx_stat_gt1023, | ||
597 | tx_stat_etherstatspkts512octetsto1023octets); | ||
598 | UPDATE_STAT64(tx_stat_gt1518, | ||
599 | tx_stat_etherstatspkts1024octetsto1522octets); | ||
600 | UPDATE_STAT64(tx_stat_gt2047, tx_stat_bmac_2047); | ||
601 | UPDATE_STAT64(tx_stat_gt4095, tx_stat_bmac_4095); | ||
602 | UPDATE_STAT64(tx_stat_gt9216, tx_stat_bmac_9216); | ||
603 | UPDATE_STAT64(tx_stat_gt16383, tx_stat_bmac_16383); | ||
604 | UPDATE_STAT64(tx_stat_gterr, | ||
605 | tx_stat_dot3statsinternalmactransmiterrors); | ||
606 | UPDATE_STAT64(tx_stat_gtufl, tx_stat_bmac_ufl); | ||
607 | |||
608 | estats->pause_frames_received_hi = | ||
609 | pstats->mac_stx[1].rx_stat_bmac_xpf_hi; | ||
610 | estats->pause_frames_received_lo = | ||
611 | pstats->mac_stx[1].rx_stat_bmac_xpf_lo; | ||
612 | |||
613 | estats->pause_frames_sent_hi = | ||
614 | pstats->mac_stx[1].tx_stat_outxoffsent_hi; | ||
615 | estats->pause_frames_sent_lo = | ||
616 | pstats->mac_stx[1].tx_stat_outxoffsent_lo; | ||
617 | } | ||
618 | |||
619 | static void bnx2x_emac_stats_update(struct bnx2x *bp) | ||
620 | { | ||
621 | struct emac_stats *new = bnx2x_sp(bp, mac_stats.emac_stats); | ||
622 | struct host_port_stats *pstats = bnx2x_sp(bp, port_stats); | ||
623 | struct bnx2x_eth_stats *estats = &bp->eth_stats; | ||
624 | |||
625 | UPDATE_EXTEND_STAT(rx_stat_ifhcinbadoctets); | ||
626 | UPDATE_EXTEND_STAT(tx_stat_ifhcoutbadoctets); | ||
627 | UPDATE_EXTEND_STAT(rx_stat_dot3statsfcserrors); | ||
628 | UPDATE_EXTEND_STAT(rx_stat_dot3statsalignmenterrors); | ||
629 | UPDATE_EXTEND_STAT(rx_stat_dot3statscarriersenseerrors); | ||
630 | UPDATE_EXTEND_STAT(rx_stat_falsecarriererrors); | ||
631 | UPDATE_EXTEND_STAT(rx_stat_etherstatsundersizepkts); | ||
632 | UPDATE_EXTEND_STAT(rx_stat_dot3statsframestoolong); | ||
633 | UPDATE_EXTEND_STAT(rx_stat_etherstatsfragments); | ||
634 | UPDATE_EXTEND_STAT(rx_stat_etherstatsjabbers); | ||
635 | UPDATE_EXTEND_STAT(rx_stat_maccontrolframesreceived); | ||
636 | UPDATE_EXTEND_STAT(rx_stat_xoffstateentered); | ||
637 | UPDATE_EXTEND_STAT(rx_stat_xonpauseframesreceived); | ||
638 | UPDATE_EXTEND_STAT(rx_stat_xoffpauseframesreceived); | ||
639 | UPDATE_EXTEND_STAT(tx_stat_outxonsent); | ||
640 | UPDATE_EXTEND_STAT(tx_stat_outxoffsent); | ||
641 | UPDATE_EXTEND_STAT(tx_stat_flowcontroldone); | ||
642 | UPDATE_EXTEND_STAT(tx_stat_etherstatscollisions); | ||
643 | UPDATE_EXTEND_STAT(tx_stat_dot3statssinglecollisionframes); | ||
644 | UPDATE_EXTEND_STAT(tx_stat_dot3statsmultiplecollisionframes); | ||
645 | UPDATE_EXTEND_STAT(tx_stat_dot3statsdeferredtransmissions); | ||
646 | UPDATE_EXTEND_STAT(tx_stat_dot3statsexcessivecollisions); | ||
647 | UPDATE_EXTEND_STAT(tx_stat_dot3statslatecollisions); | ||
648 | UPDATE_EXTEND_STAT(tx_stat_etherstatspkts64octets); | ||
649 | UPDATE_EXTEND_STAT(tx_stat_etherstatspkts65octetsto127octets); | ||
650 | UPDATE_EXTEND_STAT(tx_stat_etherstatspkts128octetsto255octets); | ||
651 | UPDATE_EXTEND_STAT(tx_stat_etherstatspkts256octetsto511octets); | ||
652 | UPDATE_EXTEND_STAT(tx_stat_etherstatspkts512octetsto1023octets); | ||
653 | UPDATE_EXTEND_STAT(tx_stat_etherstatspkts1024octetsto1522octets); | ||
654 | UPDATE_EXTEND_STAT(tx_stat_etherstatspktsover1522octets); | ||
655 | UPDATE_EXTEND_STAT(tx_stat_dot3statsinternalmactransmiterrors); | ||
656 | |||
657 | estats->pause_frames_received_hi = | ||
658 | pstats->mac_stx[1].rx_stat_xonpauseframesreceived_hi; | ||
659 | estats->pause_frames_received_lo = | ||
660 | pstats->mac_stx[1].rx_stat_xonpauseframesreceived_lo; | ||
661 | ADD_64(estats->pause_frames_received_hi, | ||
662 | pstats->mac_stx[1].rx_stat_xoffpauseframesreceived_hi, | ||
663 | estats->pause_frames_received_lo, | ||
664 | pstats->mac_stx[1].rx_stat_xoffpauseframesreceived_lo); | ||
665 | |||
666 | estats->pause_frames_sent_hi = | ||
667 | pstats->mac_stx[1].tx_stat_outxonsent_hi; | ||
668 | estats->pause_frames_sent_lo = | ||
669 | pstats->mac_stx[1].tx_stat_outxonsent_lo; | ||
670 | ADD_64(estats->pause_frames_sent_hi, | ||
671 | pstats->mac_stx[1].tx_stat_outxoffsent_hi, | ||
672 | estats->pause_frames_sent_lo, | ||
673 | pstats->mac_stx[1].tx_stat_outxoffsent_lo); | ||
674 | } | ||
675 | |||
676 | static int bnx2x_hw_stats_update(struct bnx2x *bp) | ||
677 | { | ||
678 | struct nig_stats *new = bnx2x_sp(bp, nig_stats); | ||
679 | struct nig_stats *old = &(bp->port.old_nig_stats); | ||
680 | struct host_port_stats *pstats = bnx2x_sp(bp, port_stats); | ||
681 | struct bnx2x_eth_stats *estats = &bp->eth_stats; | ||
682 | struct { | ||
683 | u32 lo; | ||
684 | u32 hi; | ||
685 | } diff; | ||
686 | |||
687 | if (bp->link_vars.mac_type == MAC_TYPE_BMAC) | ||
688 | bnx2x_bmac_stats_update(bp); | ||
689 | |||
690 | else if (bp->link_vars.mac_type == MAC_TYPE_EMAC) | ||
691 | bnx2x_emac_stats_update(bp); | ||
692 | |||
693 | else { /* unreached */ | ||
694 | BNX2X_ERR("stats updated by DMAE but no MAC active\n"); | ||
695 | return -1; | ||
696 | } | ||
697 | |||
698 | ADD_EXTEND_64(pstats->brb_drop_hi, pstats->brb_drop_lo, | ||
699 | new->brb_discard - old->brb_discard); | ||
700 | ADD_EXTEND_64(estats->brb_truncate_hi, estats->brb_truncate_lo, | ||
701 | new->brb_truncate - old->brb_truncate); | ||
702 | |||
703 | UPDATE_STAT64_NIG(egress_mac_pkt0, | ||
704 | etherstatspkts1024octetsto1522octets); | ||
705 | UPDATE_STAT64_NIG(egress_mac_pkt1, etherstatspktsover1522octets); | ||
706 | |||
707 | memcpy(old, new, sizeof(struct nig_stats)); | ||
708 | |||
709 | memcpy(&(estats->rx_stat_ifhcinbadoctets_hi), &(pstats->mac_stx[1]), | ||
710 | sizeof(struct mac_stx)); | ||
711 | estats->brb_drop_hi = pstats->brb_drop_hi; | ||
712 | estats->brb_drop_lo = pstats->brb_drop_lo; | ||
713 | |||
714 | pstats->host_port_stats_start = ++pstats->host_port_stats_end; | ||
715 | |||
716 | if (!BP_NOMCP(bp)) { | ||
717 | u32 nig_timer_max = | ||
718 | SHMEM_RD(bp, port_mb[BP_PORT(bp)].stat_nig_timer); | ||
719 | if (nig_timer_max != estats->nig_timer_max) { | ||
720 | estats->nig_timer_max = nig_timer_max; | ||
721 | BNX2X_ERR("NIG timer max (%u)\n", | ||
722 | estats->nig_timer_max); | ||
723 | } | ||
724 | } | ||
725 | |||
726 | return 0; | ||
727 | } | ||
728 | |||
729 | static int bnx2x_storm_stats_update(struct bnx2x *bp) | ||
730 | { | ||
731 | struct eth_stats_query *stats = bnx2x_sp(bp, fw_stats); | ||
732 | struct tstorm_per_port_stats *tport = | ||
733 | &stats->tstorm_common.port_statistics; | ||
734 | struct host_func_stats *fstats = bnx2x_sp(bp, func_stats); | ||
735 | struct bnx2x_eth_stats *estats = &bp->eth_stats; | ||
736 | int i; | ||
737 | |||
738 | memcpy(&(fstats->total_bytes_received_hi), | ||
739 | &(bnx2x_sp(bp, func_stats_base)->total_bytes_received_hi), | ||
740 | sizeof(struct host_func_stats) - 2*sizeof(u32)); | ||
741 | estats->error_bytes_received_hi = 0; | ||
742 | estats->error_bytes_received_lo = 0; | ||
743 | estats->etherstatsoverrsizepkts_hi = 0; | ||
744 | estats->etherstatsoverrsizepkts_lo = 0; | ||
745 | estats->no_buff_discard_hi = 0; | ||
746 | estats->no_buff_discard_lo = 0; | ||
747 | |||
748 | for_each_queue(bp, i) { | ||
749 | struct bnx2x_fastpath *fp = &bp->fp[i]; | ||
750 | int cl_id = fp->cl_id; | ||
751 | struct tstorm_per_client_stats *tclient = | ||
752 | &stats->tstorm_common.client_statistics[cl_id]; | ||
753 | struct tstorm_per_client_stats *old_tclient = &fp->old_tclient; | ||
754 | struct ustorm_per_client_stats *uclient = | ||
755 | &stats->ustorm_common.client_statistics[cl_id]; | ||
756 | struct ustorm_per_client_stats *old_uclient = &fp->old_uclient; | ||
757 | struct xstorm_per_client_stats *xclient = | ||
758 | &stats->xstorm_common.client_statistics[cl_id]; | ||
759 | struct xstorm_per_client_stats *old_xclient = &fp->old_xclient; | ||
760 | struct bnx2x_eth_q_stats *qstats = &fp->eth_q_stats; | ||
761 | u32 diff; | ||
762 | |||
763 | /* are storm stats valid? */ | ||
764 | if ((u16)(le16_to_cpu(xclient->stats_counter) + 1) != | ||
765 | bp->stats_counter) { | ||
766 | DP(BNX2X_MSG_STATS, "[%d] stats not updated by xstorm" | ||
767 | " xstorm counter (0x%x) != stats_counter (0x%x)\n", | ||
768 | i, xclient->stats_counter, bp->stats_counter); | ||
769 | return -1; | ||
770 | } | ||
771 | if ((u16)(le16_to_cpu(tclient->stats_counter) + 1) != | ||
772 | bp->stats_counter) { | ||
773 | DP(BNX2X_MSG_STATS, "[%d] stats not updated by tstorm" | ||
774 | " tstorm counter (0x%x) != stats_counter (0x%x)\n", | ||
775 | i, tclient->stats_counter, bp->stats_counter); | ||
776 | return -2; | ||
777 | } | ||
778 | if ((u16)(le16_to_cpu(uclient->stats_counter) + 1) != | ||
779 | bp->stats_counter) { | ||
780 | DP(BNX2X_MSG_STATS, "[%d] stats not updated by ustorm" | ||
781 | " ustorm counter (0x%x) != stats_counter (0x%x)\n", | ||
782 | i, uclient->stats_counter, bp->stats_counter); | ||
783 | return -4; | ||
784 | } | ||
785 | |||
786 | qstats->total_bytes_received_hi = | ||
787 | le32_to_cpu(tclient->rcv_broadcast_bytes.hi); | ||
788 | qstats->total_bytes_received_lo = | ||
789 | le32_to_cpu(tclient->rcv_broadcast_bytes.lo); | ||
790 | |||
791 | ADD_64(qstats->total_bytes_received_hi, | ||
792 | le32_to_cpu(tclient->rcv_multicast_bytes.hi), | ||
793 | qstats->total_bytes_received_lo, | ||
794 | le32_to_cpu(tclient->rcv_multicast_bytes.lo)); | ||
795 | |||
796 | ADD_64(qstats->total_bytes_received_hi, | ||
797 | le32_to_cpu(tclient->rcv_unicast_bytes.hi), | ||
798 | qstats->total_bytes_received_lo, | ||
799 | le32_to_cpu(tclient->rcv_unicast_bytes.lo)); | ||
800 | |||
801 | SUB_64(qstats->total_bytes_received_hi, | ||
802 | le32_to_cpu(uclient->bcast_no_buff_bytes.hi), | ||
803 | qstats->total_bytes_received_lo, | ||
804 | le32_to_cpu(uclient->bcast_no_buff_bytes.lo)); | ||
805 | |||
806 | SUB_64(qstats->total_bytes_received_hi, | ||
807 | le32_to_cpu(uclient->mcast_no_buff_bytes.hi), | ||
808 | qstats->total_bytes_received_lo, | ||
809 | le32_to_cpu(uclient->mcast_no_buff_bytes.lo)); | ||
810 | |||
811 | SUB_64(qstats->total_bytes_received_hi, | ||
812 | le32_to_cpu(uclient->ucast_no_buff_bytes.hi), | ||
813 | qstats->total_bytes_received_lo, | ||
814 | le32_to_cpu(uclient->ucast_no_buff_bytes.lo)); | ||
815 | |||
816 | qstats->valid_bytes_received_hi = | ||
817 | qstats->total_bytes_received_hi; | ||
818 | qstats->valid_bytes_received_lo = | ||
819 | qstats->total_bytes_received_lo; | ||
820 | |||
821 | qstats->error_bytes_received_hi = | ||
822 | le32_to_cpu(tclient->rcv_error_bytes.hi); | ||
823 | qstats->error_bytes_received_lo = | ||
824 | le32_to_cpu(tclient->rcv_error_bytes.lo); | ||
825 | |||
826 | ADD_64(qstats->total_bytes_received_hi, | ||
827 | qstats->error_bytes_received_hi, | ||
828 | qstats->total_bytes_received_lo, | ||
829 | qstats->error_bytes_received_lo); | ||
830 | |||
831 | UPDATE_EXTEND_TSTAT(rcv_unicast_pkts, | ||
832 | total_unicast_packets_received); | ||
833 | UPDATE_EXTEND_TSTAT(rcv_multicast_pkts, | ||
834 | total_multicast_packets_received); | ||
835 | UPDATE_EXTEND_TSTAT(rcv_broadcast_pkts, | ||
836 | total_broadcast_packets_received); | ||
837 | UPDATE_EXTEND_TSTAT(packets_too_big_discard, | ||
838 | etherstatsoverrsizepkts); | ||
839 | UPDATE_EXTEND_TSTAT(no_buff_discard, no_buff_discard); | ||
840 | |||
841 | SUB_EXTEND_USTAT(ucast_no_buff_pkts, | ||
842 | total_unicast_packets_received); | ||
843 | SUB_EXTEND_USTAT(mcast_no_buff_pkts, | ||
844 | total_multicast_packets_received); | ||
845 | SUB_EXTEND_USTAT(bcast_no_buff_pkts, | ||
846 | total_broadcast_packets_received); | ||
847 | UPDATE_EXTEND_USTAT(ucast_no_buff_pkts, no_buff_discard); | ||
848 | UPDATE_EXTEND_USTAT(mcast_no_buff_pkts, no_buff_discard); | ||
849 | UPDATE_EXTEND_USTAT(bcast_no_buff_pkts, no_buff_discard); | ||
850 | |||
851 | qstats->total_bytes_transmitted_hi = | ||
852 | le32_to_cpu(xclient->unicast_bytes_sent.hi); | ||
853 | qstats->total_bytes_transmitted_lo = | ||
854 | le32_to_cpu(xclient->unicast_bytes_sent.lo); | ||
855 | |||
856 | ADD_64(qstats->total_bytes_transmitted_hi, | ||
857 | le32_to_cpu(xclient->multicast_bytes_sent.hi), | ||
858 | qstats->total_bytes_transmitted_lo, | ||
859 | le32_to_cpu(xclient->multicast_bytes_sent.lo)); | ||
860 | |||
861 | ADD_64(qstats->total_bytes_transmitted_hi, | ||
862 | le32_to_cpu(xclient->broadcast_bytes_sent.hi), | ||
863 | qstats->total_bytes_transmitted_lo, | ||
864 | le32_to_cpu(xclient->broadcast_bytes_sent.lo)); | ||
865 | |||
866 | UPDATE_EXTEND_XSTAT(unicast_pkts_sent, | ||
867 | total_unicast_packets_transmitted); | ||
868 | UPDATE_EXTEND_XSTAT(multicast_pkts_sent, | ||
869 | total_multicast_packets_transmitted); | ||
870 | UPDATE_EXTEND_XSTAT(broadcast_pkts_sent, | ||
871 | total_broadcast_packets_transmitted); | ||
872 | |||
873 | old_tclient->checksum_discard = tclient->checksum_discard; | ||
874 | old_tclient->ttl0_discard = tclient->ttl0_discard; | ||
875 | |||
876 | ADD_64(fstats->total_bytes_received_hi, | ||
877 | qstats->total_bytes_received_hi, | ||
878 | fstats->total_bytes_received_lo, | ||
879 | qstats->total_bytes_received_lo); | ||
880 | ADD_64(fstats->total_bytes_transmitted_hi, | ||
881 | qstats->total_bytes_transmitted_hi, | ||
882 | fstats->total_bytes_transmitted_lo, | ||
883 | qstats->total_bytes_transmitted_lo); | ||
884 | ADD_64(fstats->total_unicast_packets_received_hi, | ||
885 | qstats->total_unicast_packets_received_hi, | ||
886 | fstats->total_unicast_packets_received_lo, | ||
887 | qstats->total_unicast_packets_received_lo); | ||
888 | ADD_64(fstats->total_multicast_packets_received_hi, | ||
889 | qstats->total_multicast_packets_received_hi, | ||
890 | fstats->total_multicast_packets_received_lo, | ||
891 | qstats->total_multicast_packets_received_lo); | ||
892 | ADD_64(fstats->total_broadcast_packets_received_hi, | ||
893 | qstats->total_broadcast_packets_received_hi, | ||
894 | fstats->total_broadcast_packets_received_lo, | ||
895 | qstats->total_broadcast_packets_received_lo); | ||
896 | ADD_64(fstats->total_unicast_packets_transmitted_hi, | ||
897 | qstats->total_unicast_packets_transmitted_hi, | ||
898 | fstats->total_unicast_packets_transmitted_lo, | ||
899 | qstats->total_unicast_packets_transmitted_lo); | ||
900 | ADD_64(fstats->total_multicast_packets_transmitted_hi, | ||
901 | qstats->total_multicast_packets_transmitted_hi, | ||
902 | fstats->total_multicast_packets_transmitted_lo, | ||
903 | qstats->total_multicast_packets_transmitted_lo); | ||
904 | ADD_64(fstats->total_broadcast_packets_transmitted_hi, | ||
905 | qstats->total_broadcast_packets_transmitted_hi, | ||
906 | fstats->total_broadcast_packets_transmitted_lo, | ||
907 | qstats->total_broadcast_packets_transmitted_lo); | ||
908 | ADD_64(fstats->valid_bytes_received_hi, | ||
909 | qstats->valid_bytes_received_hi, | ||
910 | fstats->valid_bytes_received_lo, | ||
911 | qstats->valid_bytes_received_lo); | ||
912 | |||
913 | ADD_64(estats->error_bytes_received_hi, | ||
914 | qstats->error_bytes_received_hi, | ||
915 | estats->error_bytes_received_lo, | ||
916 | qstats->error_bytes_received_lo); | ||
917 | ADD_64(estats->etherstatsoverrsizepkts_hi, | ||
918 | qstats->etherstatsoverrsizepkts_hi, | ||
919 | estats->etherstatsoverrsizepkts_lo, | ||
920 | qstats->etherstatsoverrsizepkts_lo); | ||
921 | ADD_64(estats->no_buff_discard_hi, qstats->no_buff_discard_hi, | ||
922 | estats->no_buff_discard_lo, qstats->no_buff_discard_lo); | ||
923 | } | ||
924 | |||
925 | ADD_64(fstats->total_bytes_received_hi, | ||
926 | estats->rx_stat_ifhcinbadoctets_hi, | ||
927 | fstats->total_bytes_received_lo, | ||
928 | estats->rx_stat_ifhcinbadoctets_lo); | ||
929 | |||
930 | memcpy(estats, &(fstats->total_bytes_received_hi), | ||
931 | sizeof(struct host_func_stats) - 2*sizeof(u32)); | ||
932 | |||
933 | ADD_64(estats->etherstatsoverrsizepkts_hi, | ||
934 | estats->rx_stat_dot3statsframestoolong_hi, | ||
935 | estats->etherstatsoverrsizepkts_lo, | ||
936 | estats->rx_stat_dot3statsframestoolong_lo); | ||
937 | ADD_64(estats->error_bytes_received_hi, | ||
938 | estats->rx_stat_ifhcinbadoctets_hi, | ||
939 | estats->error_bytes_received_lo, | ||
940 | estats->rx_stat_ifhcinbadoctets_lo); | ||
941 | |||
942 | if (bp->port.pmf) { | ||
943 | estats->mac_filter_discard = | ||
944 | le32_to_cpu(tport->mac_filter_discard); | ||
945 | estats->xxoverflow_discard = | ||
946 | le32_to_cpu(tport->xxoverflow_discard); | ||
947 | estats->brb_truncate_discard = | ||
948 | le32_to_cpu(tport->brb_truncate_discard); | ||
949 | estats->mac_discard = le32_to_cpu(tport->mac_discard); | ||
950 | } | ||
951 | |||
952 | fstats->host_func_stats_start = ++fstats->host_func_stats_end; | ||
953 | |||
954 | bp->stats_pending = 0; | ||
955 | |||
956 | return 0; | ||
957 | } | ||
958 | |||
959 | static void bnx2x_net_stats_update(struct bnx2x *bp) | ||
960 | { | ||
961 | struct bnx2x_eth_stats *estats = &bp->eth_stats; | ||
962 | struct net_device_stats *nstats = &bp->dev->stats; | ||
963 | int i; | ||
964 | |||
965 | nstats->rx_packets = | ||
966 | bnx2x_hilo(&estats->total_unicast_packets_received_hi) + | ||
967 | bnx2x_hilo(&estats->total_multicast_packets_received_hi) + | ||
968 | bnx2x_hilo(&estats->total_broadcast_packets_received_hi); | ||
969 | |||
970 | nstats->tx_packets = | ||
971 | bnx2x_hilo(&estats->total_unicast_packets_transmitted_hi) + | ||
972 | bnx2x_hilo(&estats->total_multicast_packets_transmitted_hi) + | ||
973 | bnx2x_hilo(&estats->total_broadcast_packets_transmitted_hi); | ||
974 | |||
975 | nstats->rx_bytes = bnx2x_hilo(&estats->total_bytes_received_hi); | ||
976 | |||
977 | nstats->tx_bytes = bnx2x_hilo(&estats->total_bytes_transmitted_hi); | ||
978 | |||
979 | nstats->rx_dropped = estats->mac_discard; | ||
980 | for_each_queue(bp, i) | ||
981 | nstats->rx_dropped += | ||
982 | le32_to_cpu(bp->fp[i].old_tclient.checksum_discard); | ||
983 | |||
984 | nstats->tx_dropped = 0; | ||
985 | |||
986 | nstats->multicast = | ||
987 | bnx2x_hilo(&estats->total_multicast_packets_received_hi); | ||
988 | |||
989 | nstats->collisions = | ||
990 | bnx2x_hilo(&estats->tx_stat_etherstatscollisions_hi); | ||
991 | |||
992 | nstats->rx_length_errors = | ||
993 | bnx2x_hilo(&estats->rx_stat_etherstatsundersizepkts_hi) + | ||
994 | bnx2x_hilo(&estats->etherstatsoverrsizepkts_hi); | ||
995 | nstats->rx_over_errors = bnx2x_hilo(&estats->brb_drop_hi) + | ||
996 | bnx2x_hilo(&estats->brb_truncate_hi); | ||
997 | nstats->rx_crc_errors = | ||
998 | bnx2x_hilo(&estats->rx_stat_dot3statsfcserrors_hi); | ||
999 | nstats->rx_frame_errors = | ||
1000 | bnx2x_hilo(&estats->rx_stat_dot3statsalignmenterrors_hi); | ||
1001 | nstats->rx_fifo_errors = bnx2x_hilo(&estats->no_buff_discard_hi); | ||
1002 | nstats->rx_missed_errors = estats->xxoverflow_discard; | ||
1003 | |||
1004 | nstats->rx_errors = nstats->rx_length_errors + | ||
1005 | nstats->rx_over_errors + | ||
1006 | nstats->rx_crc_errors + | ||
1007 | nstats->rx_frame_errors + | ||
1008 | nstats->rx_fifo_errors + | ||
1009 | nstats->rx_missed_errors; | ||
1010 | |||
1011 | nstats->tx_aborted_errors = | ||
1012 | bnx2x_hilo(&estats->tx_stat_dot3statslatecollisions_hi) + | ||
1013 | bnx2x_hilo(&estats->tx_stat_dot3statsexcessivecollisions_hi); | ||
1014 | nstats->tx_carrier_errors = | ||
1015 | bnx2x_hilo(&estats->rx_stat_dot3statscarriersenseerrors_hi); | ||
1016 | nstats->tx_fifo_errors = 0; | ||
1017 | nstats->tx_heartbeat_errors = 0; | ||
1018 | nstats->tx_window_errors = 0; | ||
1019 | |||
1020 | nstats->tx_errors = nstats->tx_aborted_errors + | ||
1021 | nstats->tx_carrier_errors + | ||
1022 | bnx2x_hilo(&estats->tx_stat_dot3statsinternalmactransmiterrors_hi); | ||
1023 | } | ||
1024 | |||
1025 | static void bnx2x_drv_stats_update(struct bnx2x *bp) | ||
1026 | { | ||
1027 | struct bnx2x_eth_stats *estats = &bp->eth_stats; | ||
1028 | int i; | ||
1029 | |||
1030 | estats->driver_xoff = 0; | ||
1031 | estats->rx_err_discard_pkt = 0; | ||
1032 | estats->rx_skb_alloc_failed = 0; | ||
1033 | estats->hw_csum_err = 0; | ||
1034 | for_each_queue(bp, i) { | ||
1035 | struct bnx2x_eth_q_stats *qstats = &bp->fp[i].eth_q_stats; | ||
1036 | |||
1037 | estats->driver_xoff += qstats->driver_xoff; | ||
1038 | estats->rx_err_discard_pkt += qstats->rx_err_discard_pkt; | ||
1039 | estats->rx_skb_alloc_failed += qstats->rx_skb_alloc_failed; | ||
1040 | estats->hw_csum_err += qstats->hw_csum_err; | ||
1041 | } | ||
1042 | } | ||
1043 | |||
1044 | static void bnx2x_stats_update(struct bnx2x *bp) | ||
1045 | { | ||
1046 | u32 *stats_comp = bnx2x_sp(bp, stats_comp); | ||
1047 | |||
1048 | if (*stats_comp != DMAE_COMP_VAL) | ||
1049 | return; | ||
1050 | |||
1051 | if (bp->port.pmf) | ||
1052 | bnx2x_hw_stats_update(bp); | ||
1053 | |||
1054 | if (bnx2x_storm_stats_update(bp) && (bp->stats_pending++ == 3)) { | ||
1055 | BNX2X_ERR("storm stats were not updated for 3 times\n"); | ||
1056 | bnx2x_panic(); | ||
1057 | return; | ||
1058 | } | ||
1059 | |||
1060 | bnx2x_net_stats_update(bp); | ||
1061 | bnx2x_drv_stats_update(bp); | ||
1062 | |||
1063 | if (netif_msg_timer(bp)) { | ||
1064 | struct bnx2x_eth_stats *estats = &bp->eth_stats; | ||
1065 | int i; | ||
1066 | |||
1067 | printk(KERN_DEBUG "%s: brb drops %u brb truncate %u\n", | ||
1068 | bp->dev->name, | ||
1069 | estats->brb_drop_lo, estats->brb_truncate_lo); | ||
1070 | |||
1071 | for_each_queue(bp, i) { | ||
1072 | struct bnx2x_fastpath *fp = &bp->fp[i]; | ||
1073 | struct bnx2x_eth_q_stats *qstats = &fp->eth_q_stats; | ||
1074 | |||
1075 | printk(KERN_DEBUG "%s: rx usage(%4u) *rx_cons_sb(%u)" | ||
1076 | " rx pkt(%lu) rx calls(%lu %lu)\n", | ||
1077 | fp->name, (le16_to_cpu(*fp->rx_cons_sb) - | ||
1078 | fp->rx_comp_cons), | ||
1079 | le16_to_cpu(*fp->rx_cons_sb), | ||
1080 | bnx2x_hilo(&qstats-> | ||
1081 | total_unicast_packets_received_hi), | ||
1082 | fp->rx_calls, fp->rx_pkt); | ||
1083 | } | ||
1084 | |||
1085 | for_each_queue(bp, i) { | ||
1086 | struct bnx2x_fastpath *fp = &bp->fp[i]; | ||
1087 | struct bnx2x_eth_q_stats *qstats = &fp->eth_q_stats; | ||
1088 | struct netdev_queue *txq = | ||
1089 | netdev_get_tx_queue(bp->dev, i); | ||
1090 | |||
1091 | printk(KERN_DEBUG "%s: tx avail(%4u) *tx_cons_sb(%u)" | ||
1092 | " tx pkt(%lu) tx calls (%lu)" | ||
1093 | " %s (Xoff events %u)\n", | ||
1094 | fp->name, bnx2x_tx_avail(fp), | ||
1095 | le16_to_cpu(*fp->tx_cons_sb), | ||
1096 | bnx2x_hilo(&qstats-> | ||
1097 | total_unicast_packets_transmitted_hi), | ||
1098 | fp->tx_pkt, | ||
1099 | (netif_tx_queue_stopped(txq) ? "Xoff" : "Xon"), | ||
1100 | qstats->driver_xoff); | ||
1101 | } | ||
1102 | } | ||
1103 | |||
1104 | bnx2x_hw_stats_post(bp); | ||
1105 | bnx2x_storm_stats_post(bp); | ||
1106 | } | ||
1107 | |||
1108 | static void bnx2x_port_stats_stop(struct bnx2x *bp) | ||
1109 | { | ||
1110 | struct dmae_command *dmae; | ||
1111 | u32 opcode; | ||
1112 | int loader_idx = PMF_DMAE_C(bp); | ||
1113 | u32 *stats_comp = bnx2x_sp(bp, stats_comp); | ||
1114 | |||
1115 | bp->executer_idx = 0; | ||
1116 | |||
1117 | opcode = (DMAE_CMD_SRC_PCI | DMAE_CMD_DST_GRC | | ||
1118 | DMAE_CMD_C_ENABLE | | ||
1119 | DMAE_CMD_SRC_RESET | DMAE_CMD_DST_RESET | | ||
1120 | #ifdef __BIG_ENDIAN | ||
1121 | DMAE_CMD_ENDIANITY_B_DW_SWAP | | ||
1122 | #else | ||
1123 | DMAE_CMD_ENDIANITY_DW_SWAP | | ||
1124 | #endif | ||
1125 | (BP_PORT(bp) ? DMAE_CMD_PORT_1 : DMAE_CMD_PORT_0) | | ||
1126 | (BP_E1HVN(bp) << DMAE_CMD_E1HVN_SHIFT)); | ||
1127 | |||
1128 | if (bp->port.port_stx) { | ||
1129 | |||
1130 | dmae = bnx2x_sp(bp, dmae[bp->executer_idx++]); | ||
1131 | if (bp->func_stx) | ||
1132 | dmae->opcode = (opcode | DMAE_CMD_C_DST_GRC); | ||
1133 | else | ||
1134 | dmae->opcode = (opcode | DMAE_CMD_C_DST_PCI); | ||
1135 | dmae->src_addr_lo = U64_LO(bnx2x_sp_mapping(bp, port_stats)); | ||
1136 | dmae->src_addr_hi = U64_HI(bnx2x_sp_mapping(bp, port_stats)); | ||
1137 | dmae->dst_addr_lo = bp->port.port_stx >> 2; | ||
1138 | dmae->dst_addr_hi = 0; | ||
1139 | dmae->len = sizeof(struct host_port_stats) >> 2; | ||
1140 | if (bp->func_stx) { | ||
1141 | dmae->comp_addr_lo = dmae_reg_go_c[loader_idx] >> 2; | ||
1142 | dmae->comp_addr_hi = 0; | ||
1143 | dmae->comp_val = 1; | ||
1144 | } else { | ||
1145 | dmae->comp_addr_lo = | ||
1146 | U64_LO(bnx2x_sp_mapping(bp, stats_comp)); | ||
1147 | dmae->comp_addr_hi = | ||
1148 | U64_HI(bnx2x_sp_mapping(bp, stats_comp)); | ||
1149 | dmae->comp_val = DMAE_COMP_VAL; | ||
1150 | |||
1151 | *stats_comp = 0; | ||
1152 | } | ||
1153 | } | ||
1154 | |||
1155 | if (bp->func_stx) { | ||
1156 | |||
1157 | dmae = bnx2x_sp(bp, dmae[bp->executer_idx++]); | ||
1158 | dmae->opcode = (opcode | DMAE_CMD_C_DST_PCI); | ||
1159 | dmae->src_addr_lo = U64_LO(bnx2x_sp_mapping(bp, func_stats)); | ||
1160 | dmae->src_addr_hi = U64_HI(bnx2x_sp_mapping(bp, func_stats)); | ||
1161 | dmae->dst_addr_lo = bp->func_stx >> 2; | ||
1162 | dmae->dst_addr_hi = 0; | ||
1163 | dmae->len = sizeof(struct host_func_stats) >> 2; | ||
1164 | dmae->comp_addr_lo = U64_LO(bnx2x_sp_mapping(bp, stats_comp)); | ||
1165 | dmae->comp_addr_hi = U64_HI(bnx2x_sp_mapping(bp, stats_comp)); | ||
1166 | dmae->comp_val = DMAE_COMP_VAL; | ||
1167 | |||
1168 | *stats_comp = 0; | ||
1169 | } | ||
1170 | } | ||
1171 | |||
1172 | static void bnx2x_stats_stop(struct bnx2x *bp) | ||
1173 | { | ||
1174 | int update = 0; | ||
1175 | |||
1176 | bnx2x_stats_comp(bp); | ||
1177 | |||
1178 | if (bp->port.pmf) | ||
1179 | update = (bnx2x_hw_stats_update(bp) == 0); | ||
1180 | |||
1181 | update |= (bnx2x_storm_stats_update(bp) == 0); | ||
1182 | |||
1183 | if (update) { | ||
1184 | bnx2x_net_stats_update(bp); | ||
1185 | |||
1186 | if (bp->port.pmf) | ||
1187 | bnx2x_port_stats_stop(bp); | ||
1188 | |||
1189 | bnx2x_hw_stats_post(bp); | ||
1190 | bnx2x_stats_comp(bp); | ||
1191 | } | ||
1192 | } | ||
1193 | |||
1194 | static void bnx2x_stats_do_nothing(struct bnx2x *bp) | ||
1195 | { | ||
1196 | } | ||
1197 | |||
1198 | static const struct { | ||
1199 | void (*action)(struct bnx2x *bp); | ||
1200 | enum bnx2x_stats_state next_state; | ||
1201 | } bnx2x_stats_stm[STATS_STATE_MAX][STATS_EVENT_MAX] = { | ||
1202 | /* state event */ | ||
1203 | { | ||
1204 | /* DISABLED PMF */ {bnx2x_stats_pmf_update, STATS_STATE_DISABLED}, | ||
1205 | /* LINK_UP */ {bnx2x_stats_start, STATS_STATE_ENABLED}, | ||
1206 | /* UPDATE */ {bnx2x_stats_do_nothing, STATS_STATE_DISABLED}, | ||
1207 | /* STOP */ {bnx2x_stats_do_nothing, STATS_STATE_DISABLED} | ||
1208 | }, | ||
1209 | { | ||
1210 | /* ENABLED PMF */ {bnx2x_stats_pmf_start, STATS_STATE_ENABLED}, | ||
1211 | /* LINK_UP */ {bnx2x_stats_restart, STATS_STATE_ENABLED}, | ||
1212 | /* UPDATE */ {bnx2x_stats_update, STATS_STATE_ENABLED}, | ||
1213 | /* STOP */ {bnx2x_stats_stop, STATS_STATE_DISABLED} | ||
1214 | } | ||
1215 | }; | ||
1216 | |||
1217 | void bnx2x_stats_handle(struct bnx2x *bp, enum bnx2x_stats_event event) | ||
1218 | { | ||
1219 | enum bnx2x_stats_state state = bp->stats_state; | ||
1220 | |||
1221 | if (unlikely(bp->panic)) | ||
1222 | return; | ||
1223 | |||
1224 | bnx2x_stats_stm[state][event].action(bp); | ||
1225 | bp->stats_state = bnx2x_stats_stm[state][event].next_state; | ||
1226 | |||
1227 | /* Make sure the state has been "changed" */ | ||
1228 | smp_wmb(); | ||
1229 | |||
1230 | if ((event != STATS_EVENT_UPDATE) || netif_msg_timer(bp)) | ||
1231 | DP(BNX2X_MSG_STATS, "state %d -> event %d -> state %d\n", | ||
1232 | state, event, bp->stats_state); | ||
1233 | } | ||
1234 | |||
1235 | static void bnx2x_port_stats_base_init(struct bnx2x *bp) | ||
1236 | { | ||
1237 | struct dmae_command *dmae; | ||
1238 | u32 *stats_comp = bnx2x_sp(bp, stats_comp); | ||
1239 | |||
1240 | /* sanity */ | ||
1241 | if (!bp->port.pmf || !bp->port.port_stx) { | ||
1242 | BNX2X_ERR("BUG!\n"); | ||
1243 | return; | ||
1244 | } | ||
1245 | |||
1246 | bp->executer_idx = 0; | ||
1247 | |||
1248 | dmae = bnx2x_sp(bp, dmae[bp->executer_idx++]); | ||
1249 | dmae->opcode = (DMAE_CMD_SRC_PCI | DMAE_CMD_DST_GRC | | ||
1250 | DMAE_CMD_C_DST_PCI | DMAE_CMD_C_ENABLE | | ||
1251 | DMAE_CMD_SRC_RESET | DMAE_CMD_DST_RESET | | ||
1252 | #ifdef __BIG_ENDIAN | ||
1253 | DMAE_CMD_ENDIANITY_B_DW_SWAP | | ||
1254 | #else | ||
1255 | DMAE_CMD_ENDIANITY_DW_SWAP | | ||
1256 | #endif | ||
1257 | (BP_PORT(bp) ? DMAE_CMD_PORT_1 : DMAE_CMD_PORT_0) | | ||
1258 | (BP_E1HVN(bp) << DMAE_CMD_E1HVN_SHIFT)); | ||
1259 | dmae->src_addr_lo = U64_LO(bnx2x_sp_mapping(bp, port_stats)); | ||
1260 | dmae->src_addr_hi = U64_HI(bnx2x_sp_mapping(bp, port_stats)); | ||
1261 | dmae->dst_addr_lo = bp->port.port_stx >> 2; | ||
1262 | dmae->dst_addr_hi = 0; | ||
1263 | dmae->len = sizeof(struct host_port_stats) >> 2; | ||
1264 | dmae->comp_addr_lo = U64_LO(bnx2x_sp_mapping(bp, stats_comp)); | ||
1265 | dmae->comp_addr_hi = U64_HI(bnx2x_sp_mapping(bp, stats_comp)); | ||
1266 | dmae->comp_val = DMAE_COMP_VAL; | ||
1267 | |||
1268 | *stats_comp = 0; | ||
1269 | bnx2x_hw_stats_post(bp); | ||
1270 | bnx2x_stats_comp(bp); | ||
1271 | } | ||
1272 | |||
1273 | static void bnx2x_func_stats_base_init(struct bnx2x *bp) | ||
1274 | { | ||
1275 | int vn, vn_max = IS_E1HMF(bp) ? E1HVN_MAX : E1VN_MAX; | ||
1276 | int port = BP_PORT(bp); | ||
1277 | int func; | ||
1278 | u32 func_stx; | ||
1279 | |||
1280 | /* sanity */ | ||
1281 | if (!bp->port.pmf || !bp->func_stx) { | ||
1282 | BNX2X_ERR("BUG!\n"); | ||
1283 | return; | ||
1284 | } | ||
1285 | |||
1286 | /* save our func_stx */ | ||
1287 | func_stx = bp->func_stx; | ||
1288 | |||
1289 | for (vn = VN_0; vn < vn_max; vn++) { | ||
1290 | func = 2*vn + port; | ||
1291 | |||
1292 | bp->func_stx = SHMEM_RD(bp, func_mb[func].fw_mb_param); | ||
1293 | bnx2x_func_stats_init(bp); | ||
1294 | bnx2x_hw_stats_post(bp); | ||
1295 | bnx2x_stats_comp(bp); | ||
1296 | } | ||
1297 | |||
1298 | /* restore our func_stx */ | ||
1299 | bp->func_stx = func_stx; | ||
1300 | } | ||
1301 | |||
1302 | static void bnx2x_func_stats_base_update(struct bnx2x *bp) | ||
1303 | { | ||
1304 | struct dmae_command *dmae = &bp->stats_dmae; | ||
1305 | u32 *stats_comp = bnx2x_sp(bp, stats_comp); | ||
1306 | |||
1307 | /* sanity */ | ||
1308 | if (!bp->func_stx) { | ||
1309 | BNX2X_ERR("BUG!\n"); | ||
1310 | return; | ||
1311 | } | ||
1312 | |||
1313 | bp->executer_idx = 0; | ||
1314 | memset(dmae, 0, sizeof(struct dmae_command)); | ||
1315 | |||
1316 | dmae->opcode = (DMAE_CMD_SRC_GRC | DMAE_CMD_DST_PCI | | ||
1317 | DMAE_CMD_C_DST_PCI | DMAE_CMD_C_ENABLE | | ||
1318 | DMAE_CMD_SRC_RESET | DMAE_CMD_DST_RESET | | ||
1319 | #ifdef __BIG_ENDIAN | ||
1320 | DMAE_CMD_ENDIANITY_B_DW_SWAP | | ||
1321 | #else | ||
1322 | DMAE_CMD_ENDIANITY_DW_SWAP | | ||
1323 | #endif | ||
1324 | (BP_PORT(bp) ? DMAE_CMD_PORT_1 : DMAE_CMD_PORT_0) | | ||
1325 | (BP_E1HVN(bp) << DMAE_CMD_E1HVN_SHIFT)); | ||
1326 | dmae->src_addr_lo = bp->func_stx >> 2; | ||
1327 | dmae->src_addr_hi = 0; | ||
1328 | dmae->dst_addr_lo = U64_LO(bnx2x_sp_mapping(bp, func_stats_base)); | ||
1329 | dmae->dst_addr_hi = U64_HI(bnx2x_sp_mapping(bp, func_stats_base)); | ||
1330 | dmae->len = sizeof(struct host_func_stats) >> 2; | ||
1331 | dmae->comp_addr_lo = U64_LO(bnx2x_sp_mapping(bp, stats_comp)); | ||
1332 | dmae->comp_addr_hi = U64_HI(bnx2x_sp_mapping(bp, stats_comp)); | ||
1333 | dmae->comp_val = DMAE_COMP_VAL; | ||
1334 | |||
1335 | *stats_comp = 0; | ||
1336 | bnx2x_hw_stats_post(bp); | ||
1337 | bnx2x_stats_comp(bp); | ||
1338 | } | ||
1339 | |||
1340 | void bnx2x_stats_init(struct bnx2x *bp) | ||
1341 | { | ||
1342 | int port = BP_PORT(bp); | ||
1343 | int func = BP_FUNC(bp); | ||
1344 | int i; | ||
1345 | |||
1346 | bp->stats_pending = 0; | ||
1347 | bp->executer_idx = 0; | ||
1348 | bp->stats_counter = 0; | ||
1349 | |||
1350 | /* port and func stats for management */ | ||
1351 | if (!BP_NOMCP(bp)) { | ||
1352 | bp->port.port_stx = SHMEM_RD(bp, port_mb[port].port_stx); | ||
1353 | bp->func_stx = SHMEM_RD(bp, func_mb[func].fw_mb_param); | ||
1354 | |||
1355 | } else { | ||
1356 | bp->port.port_stx = 0; | ||
1357 | bp->func_stx = 0; | ||
1358 | } | ||
1359 | DP(BNX2X_MSG_STATS, "port_stx 0x%x func_stx 0x%x\n", | ||
1360 | bp->port.port_stx, bp->func_stx); | ||
1361 | |||
1362 | /* port stats */ | ||
1363 | memset(&(bp->port.old_nig_stats), 0, sizeof(struct nig_stats)); | ||
1364 | bp->port.old_nig_stats.brb_discard = | ||
1365 | REG_RD(bp, NIG_REG_STAT0_BRB_DISCARD + port*0x38); | ||
1366 | bp->port.old_nig_stats.brb_truncate = | ||
1367 | REG_RD(bp, NIG_REG_STAT0_BRB_TRUNCATE + port*0x38); | ||
1368 | REG_RD_DMAE(bp, NIG_REG_STAT0_EGRESS_MAC_PKT0 + port*0x50, | ||
1369 | &(bp->port.old_nig_stats.egress_mac_pkt0_lo), 2); | ||
1370 | REG_RD_DMAE(bp, NIG_REG_STAT0_EGRESS_MAC_PKT1 + port*0x50, | ||
1371 | &(bp->port.old_nig_stats.egress_mac_pkt1_lo), 2); | ||
1372 | |||
1373 | /* function stats */ | ||
1374 | for_each_queue(bp, i) { | ||
1375 | struct bnx2x_fastpath *fp = &bp->fp[i]; | ||
1376 | |||
1377 | memset(&fp->old_tclient, 0, | ||
1378 | sizeof(struct tstorm_per_client_stats)); | ||
1379 | memset(&fp->old_uclient, 0, | ||
1380 | sizeof(struct ustorm_per_client_stats)); | ||
1381 | memset(&fp->old_xclient, 0, | ||
1382 | sizeof(struct xstorm_per_client_stats)); | ||
1383 | memset(&fp->eth_q_stats, 0, sizeof(struct bnx2x_eth_q_stats)); | ||
1384 | } | ||
1385 | |||
1386 | memset(&bp->dev->stats, 0, sizeof(struct net_device_stats)); | ||
1387 | memset(&bp->eth_stats, 0, sizeof(struct bnx2x_eth_stats)); | ||
1388 | |||
1389 | bp->stats_state = STATS_STATE_DISABLED; | ||
1390 | |||
1391 | if (bp->port.pmf) { | ||
1392 | if (bp->port.port_stx) | ||
1393 | bnx2x_port_stats_base_init(bp); | ||
1394 | |||
1395 | if (bp->func_stx) | ||
1396 | bnx2x_func_stats_base_init(bp); | ||
1397 | |||
1398 | } else if (bp->func_stx) | ||
1399 | bnx2x_func_stats_base_update(bp); | ||
1400 | } | ||
diff --git a/drivers/net/bnx2x/bnx2x_stats.h b/drivers/net/bnx2x/bnx2x_stats.h new file mode 100644 index 000000000000..38a4e908f4fb --- /dev/null +++ b/drivers/net/bnx2x/bnx2x_stats.h | |||
@@ -0,0 +1,239 @@ | |||
1 | /* bnx2x_stats.h: Broadcom Everest network driver. | ||
2 | * | ||
3 | * Copyright (c) 2007-2010 Broadcom Corporation | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify | ||
6 | * it under the terms of the GNU General Public License as published by | ||
7 | * the Free Software Foundation. | ||
8 | * | ||
9 | * Maintained by: Eilon Greenstein <eilong@broadcom.com> | ||
10 | * Written by: Eliezer Tamir | ||
11 | * Based on code from Michael Chan's bnx2 driver | ||
12 | */ | ||
13 | |||
14 | #ifndef BNX2X_STATS_H | ||
15 | #define BNX2X_STATS_H | ||
16 | |||
17 | #include <linux/types.h> | ||
18 | |||
19 | struct bnx2x_eth_q_stats { | ||
20 | u32 total_bytes_received_hi; | ||
21 | u32 total_bytes_received_lo; | ||
22 | u32 total_bytes_transmitted_hi; | ||
23 | u32 total_bytes_transmitted_lo; | ||
24 | u32 total_unicast_packets_received_hi; | ||
25 | u32 total_unicast_packets_received_lo; | ||
26 | u32 total_multicast_packets_received_hi; | ||
27 | u32 total_multicast_packets_received_lo; | ||
28 | u32 total_broadcast_packets_received_hi; | ||
29 | u32 total_broadcast_packets_received_lo; | ||
30 | u32 total_unicast_packets_transmitted_hi; | ||
31 | u32 total_unicast_packets_transmitted_lo; | ||
32 | u32 total_multicast_packets_transmitted_hi; | ||
33 | u32 total_multicast_packets_transmitted_lo; | ||
34 | u32 total_broadcast_packets_transmitted_hi; | ||
35 | u32 total_broadcast_packets_transmitted_lo; | ||
36 | u32 valid_bytes_received_hi; | ||
37 | u32 valid_bytes_received_lo; | ||
38 | |||
39 | u32 error_bytes_received_hi; | ||
40 | u32 error_bytes_received_lo; | ||
41 | u32 etherstatsoverrsizepkts_hi; | ||
42 | u32 etherstatsoverrsizepkts_lo; | ||
43 | u32 no_buff_discard_hi; | ||
44 | u32 no_buff_discard_lo; | ||
45 | |||
46 | u32 driver_xoff; | ||
47 | u32 rx_err_discard_pkt; | ||
48 | u32 rx_skb_alloc_failed; | ||
49 | u32 hw_csum_err; | ||
50 | }; | ||
51 | |||
52 | #define BNX2X_NUM_Q_STATS 13 | ||
53 | #define Q_STATS_OFFSET32(stat_name) \ | ||
54 | (offsetof(struct bnx2x_eth_q_stats, stat_name) / 4) | ||
55 | |||
56 | struct nig_stats { | ||
57 | u32 brb_discard; | ||
58 | u32 brb_packet; | ||
59 | u32 brb_truncate; | ||
60 | u32 flow_ctrl_discard; | ||
61 | u32 flow_ctrl_octets; | ||
62 | u32 flow_ctrl_packet; | ||
63 | u32 mng_discard; | ||
64 | u32 mng_octet_inp; | ||
65 | u32 mng_octet_out; | ||
66 | u32 mng_packet_inp; | ||
67 | u32 mng_packet_out; | ||
68 | u32 pbf_octets; | ||
69 | u32 pbf_packet; | ||
70 | u32 safc_inp; | ||
71 | u32 egress_mac_pkt0_lo; | ||
72 | u32 egress_mac_pkt0_hi; | ||
73 | u32 egress_mac_pkt1_lo; | ||
74 | u32 egress_mac_pkt1_hi; | ||
75 | }; | ||
76 | |||
77 | |||
78 | enum bnx2x_stats_event { | ||
79 | STATS_EVENT_PMF = 0, | ||
80 | STATS_EVENT_LINK_UP, | ||
81 | STATS_EVENT_UPDATE, | ||
82 | STATS_EVENT_STOP, | ||
83 | STATS_EVENT_MAX | ||
84 | }; | ||
85 | |||
86 | enum bnx2x_stats_state { | ||
87 | STATS_STATE_DISABLED = 0, | ||
88 | STATS_STATE_ENABLED, | ||
89 | STATS_STATE_MAX | ||
90 | }; | ||
91 | |||
92 | struct bnx2x_eth_stats { | ||
93 | u32 total_bytes_received_hi; | ||
94 | u32 total_bytes_received_lo; | ||
95 | u32 total_bytes_transmitted_hi; | ||
96 | u32 total_bytes_transmitted_lo; | ||
97 | u32 total_unicast_packets_received_hi; | ||
98 | u32 total_unicast_packets_received_lo; | ||
99 | u32 total_multicast_packets_received_hi; | ||
100 | u32 total_multicast_packets_received_lo; | ||
101 | u32 total_broadcast_packets_received_hi; | ||
102 | u32 total_broadcast_packets_received_lo; | ||
103 | u32 total_unicast_packets_transmitted_hi; | ||
104 | u32 total_unicast_packets_transmitted_lo; | ||
105 | u32 total_multicast_packets_transmitted_hi; | ||
106 | u32 total_multicast_packets_transmitted_lo; | ||
107 | u32 total_broadcast_packets_transmitted_hi; | ||
108 | u32 total_broadcast_packets_transmitted_lo; | ||
109 | u32 valid_bytes_received_hi; | ||
110 | u32 valid_bytes_received_lo; | ||
111 | |||
112 | u32 error_bytes_received_hi; | ||
113 | u32 error_bytes_received_lo; | ||
114 | u32 etherstatsoverrsizepkts_hi; | ||
115 | u32 etherstatsoverrsizepkts_lo; | ||
116 | u32 no_buff_discard_hi; | ||
117 | u32 no_buff_discard_lo; | ||
118 | |||
119 | u32 rx_stat_ifhcinbadoctets_hi; | ||
120 | u32 rx_stat_ifhcinbadoctets_lo; | ||
121 | u32 tx_stat_ifhcoutbadoctets_hi; | ||
122 | u32 tx_stat_ifhcoutbadoctets_lo; | ||
123 | u32 rx_stat_dot3statsfcserrors_hi; | ||
124 | u32 rx_stat_dot3statsfcserrors_lo; | ||
125 | u32 rx_stat_dot3statsalignmenterrors_hi; | ||
126 | u32 rx_stat_dot3statsalignmenterrors_lo; | ||
127 | u32 rx_stat_dot3statscarriersenseerrors_hi; | ||
128 | u32 rx_stat_dot3statscarriersenseerrors_lo; | ||
129 | u32 rx_stat_falsecarriererrors_hi; | ||
130 | u32 rx_stat_falsecarriererrors_lo; | ||
131 | u32 rx_stat_etherstatsundersizepkts_hi; | ||
132 | u32 rx_stat_etherstatsundersizepkts_lo; | ||
133 | u32 rx_stat_dot3statsframestoolong_hi; | ||
134 | u32 rx_stat_dot3statsframestoolong_lo; | ||
135 | u32 rx_stat_etherstatsfragments_hi; | ||
136 | u32 rx_stat_etherstatsfragments_lo; | ||
137 | u32 rx_stat_etherstatsjabbers_hi; | ||
138 | u32 rx_stat_etherstatsjabbers_lo; | ||
139 | u32 rx_stat_maccontrolframesreceived_hi; | ||
140 | u32 rx_stat_maccontrolframesreceived_lo; | ||
141 | u32 rx_stat_bmac_xpf_hi; | ||
142 | u32 rx_stat_bmac_xpf_lo; | ||
143 | u32 rx_stat_bmac_xcf_hi; | ||
144 | u32 rx_stat_bmac_xcf_lo; | ||
145 | u32 rx_stat_xoffstateentered_hi; | ||
146 | u32 rx_stat_xoffstateentered_lo; | ||
147 | u32 rx_stat_xonpauseframesreceived_hi; | ||
148 | u32 rx_stat_xonpauseframesreceived_lo; | ||
149 | u32 rx_stat_xoffpauseframesreceived_hi; | ||
150 | u32 rx_stat_xoffpauseframesreceived_lo; | ||
151 | u32 tx_stat_outxonsent_hi; | ||
152 | u32 tx_stat_outxonsent_lo; | ||
153 | u32 tx_stat_outxoffsent_hi; | ||
154 | u32 tx_stat_outxoffsent_lo; | ||
155 | u32 tx_stat_flowcontroldone_hi; | ||
156 | u32 tx_stat_flowcontroldone_lo; | ||
157 | u32 tx_stat_etherstatscollisions_hi; | ||
158 | u32 tx_stat_etherstatscollisions_lo; | ||
159 | u32 tx_stat_dot3statssinglecollisionframes_hi; | ||
160 | u32 tx_stat_dot3statssinglecollisionframes_lo; | ||
161 | u32 tx_stat_dot3statsmultiplecollisionframes_hi; | ||
162 | u32 tx_stat_dot3statsmultiplecollisionframes_lo; | ||
163 | u32 tx_stat_dot3statsdeferredtransmissions_hi; | ||
164 | u32 tx_stat_dot3statsdeferredtransmissions_lo; | ||
165 | u32 tx_stat_dot3statsexcessivecollisions_hi; | ||
166 | u32 tx_stat_dot3statsexcessivecollisions_lo; | ||
167 | u32 tx_stat_dot3statslatecollisions_hi; | ||
168 | u32 tx_stat_dot3statslatecollisions_lo; | ||
169 | u32 tx_stat_etherstatspkts64octets_hi; | ||
170 | u32 tx_stat_etherstatspkts64octets_lo; | ||
171 | u32 tx_stat_etherstatspkts65octetsto127octets_hi; | ||
172 | u32 tx_stat_etherstatspkts65octetsto127octets_lo; | ||
173 | u32 tx_stat_etherstatspkts128octetsto255octets_hi; | ||
174 | u32 tx_stat_etherstatspkts128octetsto255octets_lo; | ||
175 | u32 tx_stat_etherstatspkts256octetsto511octets_hi; | ||
176 | u32 tx_stat_etherstatspkts256octetsto511octets_lo; | ||
177 | u32 tx_stat_etherstatspkts512octetsto1023octets_hi; | ||
178 | u32 tx_stat_etherstatspkts512octetsto1023octets_lo; | ||
179 | u32 tx_stat_etherstatspkts1024octetsto1522octets_hi; | ||
180 | u32 tx_stat_etherstatspkts1024octetsto1522octets_lo; | ||
181 | u32 tx_stat_etherstatspktsover1522octets_hi; | ||
182 | u32 tx_stat_etherstatspktsover1522octets_lo; | ||
183 | u32 tx_stat_bmac_2047_hi; | ||
184 | u32 tx_stat_bmac_2047_lo; | ||
185 | u32 tx_stat_bmac_4095_hi; | ||
186 | u32 tx_stat_bmac_4095_lo; | ||
187 | u32 tx_stat_bmac_9216_hi; | ||
188 | u32 tx_stat_bmac_9216_lo; | ||
189 | u32 tx_stat_bmac_16383_hi; | ||
190 | u32 tx_stat_bmac_16383_lo; | ||
191 | u32 tx_stat_dot3statsinternalmactransmiterrors_hi; | ||
192 | u32 tx_stat_dot3statsinternalmactransmiterrors_lo; | ||
193 | u32 tx_stat_bmac_ufl_hi; | ||
194 | u32 tx_stat_bmac_ufl_lo; | ||
195 | |||
196 | u32 pause_frames_received_hi; | ||
197 | u32 pause_frames_received_lo; | ||
198 | u32 pause_frames_sent_hi; | ||
199 | u32 pause_frames_sent_lo; | ||
200 | |||
201 | u32 etherstatspkts1024octetsto1522octets_hi; | ||
202 | u32 etherstatspkts1024octetsto1522octets_lo; | ||
203 | u32 etherstatspktsover1522octets_hi; | ||
204 | u32 etherstatspktsover1522octets_lo; | ||
205 | |||
206 | u32 brb_drop_hi; | ||
207 | u32 brb_drop_lo; | ||
208 | u32 brb_truncate_hi; | ||
209 | u32 brb_truncate_lo; | ||
210 | |||
211 | u32 mac_filter_discard; | ||
212 | u32 xxoverflow_discard; | ||
213 | u32 brb_truncate_discard; | ||
214 | u32 mac_discard; | ||
215 | |||
216 | u32 driver_xoff; | ||
217 | u32 rx_err_discard_pkt; | ||
218 | u32 rx_skb_alloc_failed; | ||
219 | u32 hw_csum_err; | ||
220 | |||
221 | u32 nig_timer_max; | ||
222 | }; | ||
223 | |||
224 | #define BNX2X_NUM_STATS 43 | ||
225 | #define STATS_OFFSET32(stat_name) \ | ||
226 | (offsetof(struct bnx2x_eth_stats, stat_name) / 4) | ||
227 | |||
228 | /* Forward declaration */ | ||
229 | struct bnx2x; | ||
230 | |||
231 | |||
232 | void bnx2x_stats_init(struct bnx2x *bp); | ||
233 | |||
234 | extern const u32 dmae_reg_go_c[]; | ||
235 | extern int bnx2x_sp_post(struct bnx2x *bp, int command, int cid, | ||
236 | u32 data_hi, u32 data_lo, int common); | ||
237 | |||
238 | |||
239 | #endif /* BNX2X_STATS_H */ | ||