Module Name: src Committed By: martin Date: Tue Jun 27 18:32:46 UTC 2023
Modified Files: src/sys/dev/pci [netbsd-9]: if_wm.c if_wmreg.h if_wmvar.h Log Message: Pull up the following revisions, requested by msaitoh in #1656: sys/dev/pci/if_wm.c 1.768-1.782 via patch sys/dev/pci/if_wmreg.h 1.129-1.130 sys/dev/pci/if_wmvar.h 1.49 wm(4): - Rework for event counters: - Fix calculation of GORC, GOTC, TOR and TOT counters correctly. - Rearrange the order of the registers so that they are roughly in ascending order. - Reorder evcnt_attach_dynamic(), WM_EVCNT_ADD() and evcnt_detach() to match. - IC{TX,RX}*C registers are for older than 82575. - Fix a bug that the transmit underrun counter is incorrectly counted. - Don't add "Count" for event counter's description. - Some statistics registers were replaced with new counters on newer chips. Treat 0x403c(CEXTERR->HTDPMC), 0x40fc(TSCTFC->CBRMPC), 0x4124(ICRXOC->HTCBDPC) and from 0x4104 to 0x4124. - Add some new counters: - Circuit Breaker TX Manageability Packet - Circuit Breaker RX Dropped Packet - Host Good Octets RX - Host Good Octets TX - Length Errors - SerDes/SGMII Code Violation Packet - Header Redirection Missed Packet - EEE TX LPI - EEE RX LPI - Fix prc511's comment and description. - Add SOICZIFDATA (ifconfig -z) support for evcnt(9). - Use WM_IS_ICHPCH(). No functional change. - Fix typo. s/ictxact/ictxatc/. No functional change. - Add comment. To generate a diff of this commit: cvs rdiff -u -r1.645.2.15 -r1.645.2.16 src/sys/dev/pci/if_wm.c cvs rdiff -u -r1.115.2.7 -r1.115.2.8 src/sys/dev/pci/if_wmreg.h cvs rdiff -u -r1.44.4.4 -r1.44.4.5 src/sys/dev/pci/if_wmvar.h Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/dev/pci/if_wm.c diff -u src/sys/dev/pci/if_wm.c:1.645.2.15 src/sys/dev/pci/if_wm.c:1.645.2.16 --- src/sys/dev/pci/if_wm.c:1.645.2.15 Mon Jan 23 13:59:04 2023 +++ src/sys/dev/pci/if_wm.c Tue Jun 27 18:32:46 2023 @@ -1,4 +1,4 @@ -/* $NetBSD: if_wm.c,v 1.645.2.15 2023/01/23 13:59:04 martin Exp $ */ +/* $NetBSD: if_wm.c,v 1.645.2.16 2023/06/27 18:32:46 martin Exp $ */ /* * Copyright (c) 2001, 2002, 2003, 2004 Wasabi Systems, Inc. @@ -82,7 +82,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: if_wm.c,v 1.645.2.15 2023/01/23 13:59:04 martin Exp $"); +__KERNEL_RCSID(0, "$NetBSD: if_wm.c,v 1.645.2.16 2023/06/27 18:32:46 martin Exp $"); #ifdef _KERNEL_OPT #include "opt_net_mpsafe.h" @@ -598,10 +598,10 @@ struct wm_softc { struct evcnt sc_ev_linkintr; /* Link interrupts */ /* >= WM_T_82542_2_1 */ - struct evcnt sc_ev_tx_xoff; /* Tx PAUSE(!0) frames */ + struct evcnt sc_ev_rx_xon; /* Rx PAUSE(0) frames */ struct evcnt sc_ev_tx_xon; /* Tx PAUSE(0) frames */ struct evcnt sc_ev_rx_xoff; /* Rx PAUSE(!0) frames */ - struct evcnt sc_ev_rx_xon; /* Rx PAUSE(0) frames */ + struct evcnt sc_ev_tx_xoff; /* Tx PAUSE(!0) frames */ struct evcnt sc_ev_rx_macctl; /* Rx Unsupported */ struct evcnt sc_ev_crcerrs; /* CRC Error */ @@ -609,15 +609,29 @@ struct wm_softc { struct evcnt sc_ev_symerrc; /* Symbol Error */ struct evcnt sc_ev_rxerrc; /* Receive Error */ struct evcnt sc_ev_mpc; /* Missed Packets */ - struct evcnt sc_ev_colc; /* Collision */ - struct evcnt sc_ev_sec; /* Sequence Error */ - struct evcnt sc_ev_cexterr; /* Carrier Extension Error */ - struct evcnt sc_ev_rlec; /* Receive Length Error */ struct evcnt sc_ev_scc; /* Single Collision */ struct evcnt sc_ev_ecol; /* Excessive Collision */ struct evcnt sc_ev_mcc; /* Multiple Collision */ struct evcnt sc_ev_latecol; /* Late Collision */ + struct evcnt sc_ev_colc; /* Collision */ + struct evcnt sc_ev_cbtmpc; /* Circuit Breaker Tx Mng. Packet */ struct evcnt sc_ev_dc; /* Defer */ + struct evcnt sc_ev_tncrs; /* Tx-No CRS */ + struct evcnt sc_ev_sec; /* Sequence Error */ + + /* Old */ + struct evcnt sc_ev_cexterr; /* Carrier Extension Error */ + /* New */ + struct evcnt sc_ev_htdpmc; /* Host Tx Discarded Pkts by MAC */ + + struct evcnt sc_ev_rlec; /* Receive Length Error */ + struct evcnt sc_ev_cbrdpc; /* Circuit Breaker Rx Dropped Packet */ + struct evcnt sc_ev_prc64; /* Packets Rx (64 bytes) */ + struct evcnt sc_ev_prc127; /* Packets Rx (65-127 bytes) */ + struct evcnt sc_ev_prc255; /* Packets Rx (128-255 bytes) */ + struct evcnt sc_ev_prc511; /* Packets Rx (256-511 bytes) */ + struct evcnt sc_ev_prc1023; /* Packets Rx (512-1023 bytes) */ + struct evcnt sc_ev_prc1522; /* Packets Rx (1024-1522 bytes) */ struct evcnt sc_ev_gprc; /* Good Packets Rx */ struct evcnt sc_ev_bprc; /* Broadcast Packets Rx */ struct evcnt sc_ev_mprc; /* Multicast Packets Rx */ @@ -629,44 +643,62 @@ struct wm_softc { struct evcnt sc_ev_rfc; /* Rx Fragment */ struct evcnt sc_ev_roc; /* Rx Oversize */ struct evcnt sc_ev_rjc; /* Rx Jabber */ + struct evcnt sc_ev_mgtprc; /* Management Packets RX */ + struct evcnt sc_ev_mgtpdc; /* Management Packets Dropped */ + struct evcnt sc_ev_mgtptc; /* Management Packets TX */ struct evcnt sc_ev_tor; /* Total Octets Rx */ struct evcnt sc_ev_tot; /* Total Octets Tx */ struct evcnt sc_ev_tpr; /* Total Packets Rx */ struct evcnt sc_ev_tpt; /* Total Packets Tx */ - struct evcnt sc_ev_mptc; /* Multicast Packets Tx */ - struct evcnt sc_ev_bptc; /* Broadcast Packets Tx Count */ - struct evcnt sc_ev_prc64; /* Packets Rx (64 bytes) */ - struct evcnt sc_ev_prc127; /* Packets Rx (65-127 bytes) */ - struct evcnt sc_ev_prc255; /* Packets Rx (128-255 bytes) */ - struct evcnt sc_ev_prc511; /* Packets Rx (255-511 bytes) */ - struct evcnt sc_ev_prc1023; /* Packets Rx (512-1023 bytes) */ - struct evcnt sc_ev_prc1522; /* Packets Rx (1024-1522 bytes) */ struct evcnt sc_ev_ptc64; /* Packets Tx (64 bytes) */ struct evcnt sc_ev_ptc127; /* Packets Tx (65-127 bytes) */ struct evcnt sc_ev_ptc255; /* Packets Tx (128-255 bytes) */ struct evcnt sc_ev_ptc511; /* Packets Tx (256-511 bytes) */ struct evcnt sc_ev_ptc1023; /* Packets Tx (512-1023 bytes) */ struct evcnt sc_ev_ptc1522; /* Packets Tx (1024-1522 Bytes) */ + struct evcnt sc_ev_mptc; /* Multicast Packets Tx */ + struct evcnt sc_ev_bptc; /* Broadcast Packets Tx */ + struct evcnt sc_ev_tsctc; /* TCP Segmentation Context Tx */ + + /* Old */ + struct evcnt sc_ev_tsctfc; /* TCP Segmentation Context Tx Fail */ + /* New */ + struct evcnt sc_ev_cbrmpc; /* Circuit Breaker Rx Mng. Packet */ + struct evcnt sc_ev_iac; /* Interrupt Assertion */ + + /* Old */ struct evcnt sc_ev_icrxptc; /* Intr. Cause Rx Pkt Timer Expire */ struct evcnt sc_ev_icrxatc; /* Intr. Cause Rx Abs Timer Expire */ struct evcnt sc_ev_ictxptc; /* Intr. Cause Tx Pkt Timer Expire */ - struct evcnt sc_ev_ictxact; /* Intr. Cause Tx Abs Timer Expire */ + struct evcnt sc_ev_ictxatc; /* Intr. Cause Tx Abs Timer Expire */ struct evcnt sc_ev_ictxqec; /* Intr. Cause Tx Queue Empty */ struct evcnt sc_ev_ictxqmtc; /* Intr. Cause Tx Queue Min Thresh */ - struct evcnt sc_ev_icrxdmtc; /* Intr. Cause Rx Desc Min Thresh */ + /* + * sc_ev_rxdmtc is shared with both "Intr. cause" and + * non "Intr. cause" register. + */ + struct evcnt sc_ev_rxdmtc; /* (Intr. Cause) Rx Desc Min Thresh */ struct evcnt sc_ev_icrxoc; /* Intr. Cause Receiver Overrun */ - struct evcnt sc_ev_tncrs; /* Tx-No CRS */ - struct evcnt sc_ev_tsctc; /* TCP Segmentation Context Tx */ - struct evcnt sc_ev_tsctfc; /* TCP Segmentation Context Tx Fail */ - struct evcnt sc_ev_mgtprc; /* Management Packets RX */ - struct evcnt sc_ev_mgtpdc; /* Management Packets Dropped */ - struct evcnt sc_ev_mgtptc; /* Management Packets TX */ + /* New */ + struct evcnt sc_ev_rpthc; /* Rx Packets To Host */ + struct evcnt sc_ev_debug1; /* Debug Counter 1 */ + struct evcnt sc_ev_debug2; /* Debug Counter 2 */ + struct evcnt sc_ev_debug3; /* Debug Counter 3 */ + struct evcnt sc_ev_hgptc; /* Host Good Packets TX */ + struct evcnt sc_ev_debug4; /* Debug Counter 4 */ + struct evcnt sc_ev_htcbdpc; /* Host Tx Circuit Breaker Drp. Pkts */ + struct evcnt sc_ev_hgorc; /* Host Good Octets Rx */ + struct evcnt sc_ev_hgotc; /* Host Good Octets Tx */ + struct evcnt sc_ev_lenerrs; /* Length Error */ + struct evcnt sc_ev_tlpic; /* EEE Tx LPI */ + struct evcnt sc_ev_rlpic; /* EEE Rx LPI */ struct evcnt sc_ev_b2ogprc; /* BMC2OS pkts received by host */ struct evcnt sc_ev_o2bspc; /* OS2BMC pkts transmitted by host */ struct evcnt sc_ev_b2ospc; /* BMC2OS pkts sent by BMC */ struct evcnt sc_ev_o2bgptc; /* OS2BMC pkts received by BMC */ - + struct evcnt sc_ev_scvpc; /* SerDes/SGMII Code Violation Pkt. */ + struct evcnt sc_ev_hrmpc; /* Header Redirection Missed Packet */ #endif /* WM_EVENT_COUNTERS */ struct sysctllog *sc_sysctllog; @@ -735,25 +767,33 @@ do { \ #define WM_EVCNT_INCR(ev) \ atomic_store_relaxed(&((ev)->ev_count), \ atomic_load_relaxed(&(ev)->ev_count) + 1) +#define WM_EVCNT_STORE(ev, val) \ + atomic_store_relaxed(&((ev)->ev_count), (val)) #define WM_EVCNT_ADD(ev, val) \ atomic_store_relaxed(&((ev)->ev_count), \ atomic_load_relaxed(&(ev)->ev_count) + (val)) #else #define WM_EVCNT_INCR(ev) \ ((ev)->ev_count)++ +#define WM_EVCNT_STORE(ev, val) \ + ((ev)->ev_count = (val)) #define WM_EVCNT_ADD(ev, val) \ (ev)->ev_count += (val) #endif #define WM_Q_EVCNT_INCR(qname, evname) \ WM_EVCNT_INCR(&(qname)->qname##_ev_##evname) +#define WM_Q_EVCNT_STORE(qname, evname, val) \ + WM_EVCNT_STORE(&(qname)->qname##_ev_##evname, (val)) #define WM_Q_EVCNT_ADD(qname, evname, val) \ WM_EVCNT_ADD(&(qname)->qname##_ev_##evname, (val)) #else /* !WM_EVENT_COUNTERS */ #define WM_EVCNT_INCR(ev) /* nothing */ +#define WM_EVCNT_STORE(ev, val) /* nothing */ #define WM_EVCNT_ADD(ev, val) /* nothing */ #define WM_Q_EVCNT_INCR(qname, evname) /* nothing */ +#define WM_Q_EVCNT_STORE(qname, evname, val) /* nothing */ #define WM_Q_EVCNT_ADD(qname, evname, val) /* nothing */ #endif /* !WM_EVENT_COUNTERS */ @@ -862,6 +902,8 @@ static int wm_setup_msix(struct wm_softc static int wm_init(struct ifnet *); static int wm_init_locked(struct ifnet *); static void wm_init_sysctls(struct wm_softc *); +static void wm_update_stats(struct wm_softc *); +static void wm_clear_evcnt(struct wm_softc *); static void wm_unset_stopping_flags(struct wm_softc *); static void wm_set_stopping_flags(struct wm_softc *); static void wm_stop(struct ifnet *, int); @@ -3208,6 +3250,53 @@ alloc_retry: evcnt_attach_dynamic(&sc->sc_ev_linkintr, EVCNT_TYPE_INTR, NULL, xname, "linkintr"); + evcnt_attach_dynamic(&sc->sc_ev_crcerrs, EVCNT_TYPE_MISC, + NULL, xname, "CRC Error"); + evcnt_attach_dynamic(&sc->sc_ev_symerrc, EVCNT_TYPE_MISC, + NULL, xname, "Symbol Error"); + evcnt_attach_dynamic(&sc->sc_ev_mpc, EVCNT_TYPE_MISC, + NULL, xname, "Missed Packets"); + evcnt_attach_dynamic(&sc->sc_ev_colc, EVCNT_TYPE_MISC, + NULL, xname, "Collision"); + evcnt_attach_dynamic(&sc->sc_ev_sec, EVCNT_TYPE_MISC, + NULL, xname, "Sequence Error"); + evcnt_attach_dynamic(&sc->sc_ev_rlec, EVCNT_TYPE_MISC, + NULL, xname, "Receive Length Error"); + + if (sc->sc_type >= WM_T_82543) { + evcnt_attach_dynamic(&sc->sc_ev_algnerrc, EVCNT_TYPE_MISC, + NULL, xname, "Alignment Error"); + evcnt_attach_dynamic(&sc->sc_ev_rxerrc, EVCNT_TYPE_MISC, + NULL, xname, "Receive Error"); + /* XXX Does 82575 have HTDPMC? */ + if ((sc->sc_type < WM_T_82575) || WM_IS_ICHPCH(sc)) + evcnt_attach_dynamic(&sc->sc_ev_cexterr, + EVCNT_TYPE_MISC, NULL, xname, + "Carrier Extension Error"); + else + evcnt_attach_dynamic(&sc->sc_ev_htdpmc, + EVCNT_TYPE_MISC, NULL, xname, + "Host Transmit Discarded Packets by MAC"); + + evcnt_attach_dynamic(&sc->sc_ev_tncrs, EVCNT_TYPE_MISC, + NULL, xname, "Tx with No CRS"); + evcnt_attach_dynamic(&sc->sc_ev_tsctc, EVCNT_TYPE_MISC, + NULL, xname, "TCP Segmentation Context Tx"); + if ((sc->sc_type < WM_T_82575) || WM_IS_ICHPCH(sc)) + evcnt_attach_dynamic(&sc->sc_ev_tsctfc, + EVCNT_TYPE_MISC, NULL, xname, + "TCP Segmentation Context Tx Fail"); + else { + /* XXX Is the circuit breaker only for 82576? */ + evcnt_attach_dynamic(&sc->sc_ev_cbrdpc, + EVCNT_TYPE_MISC, NULL, xname, + "Circuit Breaker Rx Dropped Packet"); + evcnt_attach_dynamic(&sc->sc_ev_cbrmpc, + EVCNT_TYPE_MISC, NULL, xname, + "Circuit Breaker Rx Manageability Packet"); + } + } + if (sc->sc_type >= WM_T_82542_2_1) { evcnt_attach_dynamic(&sc->sc_ev_tx_xoff, EVCNT_TYPE_MISC, NULL, xname, "tx_xoff"); @@ -3221,28 +3310,6 @@ alloc_retry: NULL, xname, "rx_macctl"); } - evcnt_attach_dynamic(&sc->sc_ev_crcerrs, EVCNT_TYPE_MISC, - NULL, xname, "CRC Error"); - evcnt_attach_dynamic(&sc->sc_ev_symerrc, EVCNT_TYPE_MISC, - NULL, xname, "Symbol Error"); - - if (sc->sc_type >= WM_T_82543) { - evcnt_attach_dynamic(&sc->sc_ev_algnerrc, EVCNT_TYPE_MISC, - NULL, xname, "Alignment Error"); - evcnt_attach_dynamic(&sc->sc_ev_rxerrc, EVCNT_TYPE_MISC, - NULL, xname, "Receive Error"); - evcnt_attach_dynamic(&sc->sc_ev_cexterr, EVCNT_TYPE_MISC, - NULL, xname, "Carrier Extension Error"); - } - - evcnt_attach_dynamic(&sc->sc_ev_mpc, EVCNT_TYPE_MISC, - NULL, xname, "Missed Packets"); - evcnt_attach_dynamic(&sc->sc_ev_colc, EVCNT_TYPE_MISC, - NULL, xname, "Collision"); - evcnt_attach_dynamic(&sc->sc_ev_sec, EVCNT_TYPE_MISC, - NULL, xname, "Sequence Error"); - evcnt_attach_dynamic(&sc->sc_ev_rlec, EVCNT_TYPE_MISC, - NULL, xname, "Receive Length Error"); evcnt_attach_dynamic(&sc->sc_ev_scc, EVCNT_TYPE_MISC, NULL, xname, "Single Collision"); evcnt_attach_dynamic(&sc->sc_ev_ecol, EVCNT_TYPE_MISC, @@ -3251,8 +3318,25 @@ alloc_retry: NULL, xname, "Multiple Collision"); evcnt_attach_dynamic(&sc->sc_ev_latecol, EVCNT_TYPE_MISC, NULL, xname, "Late Collisions"); + + if ((sc->sc_type >= WM_T_I350) && !WM_IS_ICHPCH(sc)) + evcnt_attach_dynamic(&sc->sc_ev_cbtmpc, EVCNT_TYPE_MISC, + NULL, xname, "Circuit Breaker Tx Manageability Packet"); + evcnt_attach_dynamic(&sc->sc_ev_dc, EVCNT_TYPE_MISC, NULL, xname, "Defer"); + evcnt_attach_dynamic(&sc->sc_ev_prc64, EVCNT_TYPE_MISC, + NULL, xname, "Packets Rx (64 bytes)"); + evcnt_attach_dynamic(&sc->sc_ev_prc127, EVCNT_TYPE_MISC, + NULL, xname, "Packets Rx (65-127 bytes)"); + evcnt_attach_dynamic(&sc->sc_ev_prc255, EVCNT_TYPE_MISC, + NULL, xname, "Packets Rx (128-255 bytes)"); + evcnt_attach_dynamic(&sc->sc_ev_prc511, EVCNT_TYPE_MISC, + NULL, xname, "Packets Rx (256-511 bytes)"); + evcnt_attach_dynamic(&sc->sc_ev_prc1023, EVCNT_TYPE_MISC, + NULL, xname, "Packets Rx (512-1023 bytes)"); + evcnt_attach_dynamic(&sc->sc_ev_prc1522, EVCNT_TYPE_MISC, + NULL, xname, "Packets Rx (1024-1522 bytes)"); evcnt_attach_dynamic(&sc->sc_ev_gprc, EVCNT_TYPE_MISC, NULL, xname, "Good Packets Rx"); evcnt_attach_dynamic(&sc->sc_ev_bprc, EVCNT_TYPE_MISC, @@ -3275,6 +3359,14 @@ alloc_retry: NULL, xname, "Rx Oversize"); evcnt_attach_dynamic(&sc->sc_ev_rjc, EVCNT_TYPE_MISC, NULL, xname, "Rx Jabber"); + if (sc->sc_type >= WM_T_82540) { + evcnt_attach_dynamic(&sc->sc_ev_mgtprc, EVCNT_TYPE_MISC, + NULL, xname, "Management Packets RX"); + evcnt_attach_dynamic(&sc->sc_ev_mgtpdc, EVCNT_TYPE_MISC, + NULL, xname, "Management Packets Dropped"); + evcnt_attach_dynamic(&sc->sc_ev_mgtptc, EVCNT_TYPE_MISC, + NULL, xname, "Management Packets TX"); + } evcnt_attach_dynamic(&sc->sc_ev_tor, EVCNT_TYPE_MISC, NULL, xname, "Total Octets Rx"); evcnt_attach_dynamic(&sc->sc_ev_tot, EVCNT_TYPE_MISC, @@ -3283,22 +3375,6 @@ alloc_retry: NULL, xname, "Total Packets Rx"); evcnt_attach_dynamic(&sc->sc_ev_tpt, EVCNT_TYPE_MISC, NULL, xname, "Total Packets Tx"); - evcnt_attach_dynamic(&sc->sc_ev_mptc, EVCNT_TYPE_MISC, - NULL, xname, "Multicast Packets Tx"); - evcnt_attach_dynamic(&sc->sc_ev_bptc, EVCNT_TYPE_MISC, - NULL, xname, "Broadcast Packets Tx Count"); - evcnt_attach_dynamic(&sc->sc_ev_prc64, EVCNT_TYPE_MISC, - NULL, xname, "Packets Rx (64 bytes)"); - evcnt_attach_dynamic(&sc->sc_ev_prc127, EVCNT_TYPE_MISC, - NULL, xname, "Packets Rx (65-127 bytes)"); - evcnt_attach_dynamic(&sc->sc_ev_prc255, EVCNT_TYPE_MISC, - NULL, xname, "Packets Rx (128-255 bytes)"); - evcnt_attach_dynamic(&sc->sc_ev_prc511, EVCNT_TYPE_MISC, - NULL, xname, "Packets Rx (255-511 bytes)"); - evcnt_attach_dynamic(&sc->sc_ev_prc1023, EVCNT_TYPE_MISC, - NULL, xname, "Packets Rx (512-1023 bytes)"); - evcnt_attach_dynamic(&sc->sc_ev_prc1522, EVCNT_TYPE_MISC, - NULL, xname, "Packets Rx (1024-1522 bytes)"); evcnt_attach_dynamic(&sc->sc_ev_ptc64, EVCNT_TYPE_MISC, NULL, xname, "Packets Tx (64 bytes)"); evcnt_attach_dynamic(&sc->sc_ev_ptc127, EVCNT_TYPE_MISC, @@ -3311,41 +3387,77 @@ alloc_retry: NULL, xname, "Packets Tx (512-1023 bytes)"); evcnt_attach_dynamic(&sc->sc_ev_ptc1522, EVCNT_TYPE_MISC, NULL, xname, "Packets Tx (1024-1522 Bytes)"); + evcnt_attach_dynamic(&sc->sc_ev_mptc, EVCNT_TYPE_MISC, + NULL, xname, "Multicast Packets Tx"); + evcnt_attach_dynamic(&sc->sc_ev_bptc, EVCNT_TYPE_MISC, + NULL, xname, "Broadcast Packets Tx"); evcnt_attach_dynamic(&sc->sc_ev_iac, EVCNT_TYPE_MISC, NULL, xname, "Interrupt Assertion"); - evcnt_attach_dynamic(&sc->sc_ev_icrxptc, EVCNT_TYPE_MISC, - NULL, xname, "Intr. Cause Rx Pkt Timer Expire"); - evcnt_attach_dynamic(&sc->sc_ev_icrxatc, EVCNT_TYPE_MISC, - NULL, xname, "Intr. Cause Rx Abs Timer Expire"); - evcnt_attach_dynamic(&sc->sc_ev_ictxptc, EVCNT_TYPE_MISC, - NULL, xname, "Intr. Cause Tx Pkt Timer Expire"); - evcnt_attach_dynamic(&sc->sc_ev_ictxact, EVCNT_TYPE_MISC, - NULL, xname, "Intr. Cause Tx Abs Timer Expire"); - evcnt_attach_dynamic(&sc->sc_ev_ictxqec, EVCNT_TYPE_MISC, - NULL, xname, "Intr. Cause Tx Queue Empty"); - evcnt_attach_dynamic(&sc->sc_ev_ictxqmtc, EVCNT_TYPE_MISC, - NULL, xname, "Intr. Cause Tx Queue Min Thresh"); - evcnt_attach_dynamic(&sc->sc_ev_icrxdmtc, EVCNT_TYPE_MISC, - NULL, xname, "Intr. Cause Rx Desc Min Thresh"); - evcnt_attach_dynamic(&sc->sc_ev_icrxoc, EVCNT_TYPE_MISC, - NULL, xname, "Interrupt Cause Receiver Overrun"); - if (sc->sc_type >= WM_T_82543) { - evcnt_attach_dynamic(&sc->sc_ev_tncrs, EVCNT_TYPE_MISC, - NULL, xname, "Tx with No CRS"); - evcnt_attach_dynamic(&sc->sc_ev_tsctc, EVCNT_TYPE_MISC, - NULL, xname, "TCP Segmentation Context Tx"); - evcnt_attach_dynamic(&sc->sc_ev_tsctfc, EVCNT_TYPE_MISC, - NULL, xname, "TCP Segmentation Context Tx Fail"); - } - if (sc->sc_type >= WM_T_82540) { - evcnt_attach_dynamic(&sc->sc_ev_mgtprc, EVCNT_TYPE_MISC, - NULL, xname, "Management Packets RX"); - evcnt_attach_dynamic(&sc->sc_ev_mgtpdc, EVCNT_TYPE_MISC, - NULL, xname, "Management Packets Dropped"); - evcnt_attach_dynamic(&sc->sc_ev_mgtptc, EVCNT_TYPE_MISC, - NULL, xname, "Management Packets TX"); - } - if ((sc->sc_type >= WM_T_I350) && (sc->sc_type < WM_T_80003)) { + if (sc->sc_type < WM_T_82575) { + evcnt_attach_dynamic(&sc->sc_ev_icrxptc, EVCNT_TYPE_MISC, + NULL, xname, "Intr. Cause Rx Pkt Timer Expire"); + evcnt_attach_dynamic(&sc->sc_ev_icrxatc, EVCNT_TYPE_MISC, + NULL, xname, "Intr. Cause Rx Abs Timer Expire"); + evcnt_attach_dynamic(&sc->sc_ev_ictxptc, EVCNT_TYPE_MISC, + NULL, xname, "Intr. Cause Tx Pkt Timer Expire"); + evcnt_attach_dynamic(&sc->sc_ev_ictxatc, EVCNT_TYPE_MISC, + NULL, xname, "Intr. Cause Tx Abs Timer Expire"); + evcnt_attach_dynamic(&sc->sc_ev_ictxqec, EVCNT_TYPE_MISC, + NULL, xname, "Intr. Cause Tx Queue Empty"); + evcnt_attach_dynamic(&sc->sc_ev_ictxqmtc, EVCNT_TYPE_MISC, + NULL, xname, "Intr. Cause Tx Queue Min Thresh"); + evcnt_attach_dynamic(&sc->sc_ev_rxdmtc, EVCNT_TYPE_MISC, + NULL, xname, "Intr. Cause Rx Desc Min Thresh"); + + /* XXX 82575 document says it has ICRXOC. Is that right? */ + evcnt_attach_dynamic(&sc->sc_ev_icrxoc, EVCNT_TYPE_MISC, + NULL, xname, "Interrupt Cause Receiver Overrun"); + } else if (!WM_IS_ICHPCH(sc)) { + /* + * For 82575 and newer. + * + * On 80003, ICHs and PCHs, it seems all of the following + * registers are zero. + */ + evcnt_attach_dynamic(&sc->sc_ev_rpthc, EVCNT_TYPE_MISC, + NULL, xname, "Rx Packets To Host"); + evcnt_attach_dynamic(&sc->sc_ev_debug1, EVCNT_TYPE_MISC, + NULL, xname, "Debug Counter 1"); + evcnt_attach_dynamic(&sc->sc_ev_debug2, EVCNT_TYPE_MISC, + NULL, xname, "Debug Counter 2"); + evcnt_attach_dynamic(&sc->sc_ev_debug3, EVCNT_TYPE_MISC, + NULL, xname, "Debug Counter 3"); + + /* + * 82575 datasheet says 0x4118 is for TXQEC(Tx Queue Empty). + * I think it's wrong. The real count I observed is the same + * as GPTC(Good Packets Tx) and TPT(Total Packets Tx). + * It's HGPTC(Host Good Packets Tx) which is described in + * 82576's datasheet. + */ + evcnt_attach_dynamic(&sc->sc_ev_hgptc, EVCNT_TYPE_MISC, + NULL, xname, "Host Good Packets TX"); + + evcnt_attach_dynamic(&sc->sc_ev_debug4, EVCNT_TYPE_MISC, + NULL, xname, "Debug Counter 4"); + evcnt_attach_dynamic(&sc->sc_ev_rxdmtc, EVCNT_TYPE_MISC, + NULL, xname, "Rx Desc Min Thresh"); + /* XXX Is the circuit breaker only for 82576? */ + evcnt_attach_dynamic(&sc->sc_ev_htcbdpc, EVCNT_TYPE_MISC, + NULL, xname, "Host Tx Circuit Breaker Dropped Packets"); + + evcnt_attach_dynamic(&sc->sc_ev_hgorc, EVCNT_TYPE_MISC, + NULL, xname, "Host Good Octets Rx"); + evcnt_attach_dynamic(&sc->sc_ev_hgotc, EVCNT_TYPE_MISC, + NULL, xname, "Host Good Octets Tx"); + evcnt_attach_dynamic(&sc->sc_ev_lenerrs, EVCNT_TYPE_MISC, + NULL, xname, "Length Errors"); + } + if ((sc->sc_type >= WM_T_I350) && !WM_IS_ICHPCH(sc)) { + evcnt_attach_dynamic(&sc->sc_ev_tlpic, EVCNT_TYPE_MISC, + NULL, xname, "EEE Tx LPI"); + evcnt_attach_dynamic(&sc->sc_ev_rlpic, EVCNT_TYPE_MISC, + NULL, xname, "EEE Rx LPI"); evcnt_attach_dynamic(&sc->sc_ev_b2ogprc, EVCNT_TYPE_MISC, NULL, xname, "BMC2OS Packets received by host"); evcnt_attach_dynamic(&sc->sc_ev_o2bspc, EVCNT_TYPE_MISC, @@ -3354,6 +3466,10 @@ alloc_retry: NULL, xname, "BMC2OS Packets sent by BMC"); evcnt_attach_dynamic(&sc->sc_ev_o2bgptc, EVCNT_TYPE_MISC, NULL, xname, "OS2BMC Packets received by BMC"); + evcnt_attach_dynamic(&sc->sc_ev_scvpc, EVCNT_TYPE_MISC, + NULL, xname, "SerDes/SGMII Code Violation Packet"); + evcnt_attach_dynamic(&sc->sc_ev_hrmpc, EVCNT_TYPE_MISC, + NULL, xname, "Header Redirection Missed Packet"); } #endif /* WM_EVENT_COUNTERS */ @@ -3399,6 +3515,31 @@ wm_detach(device_t self, int flags __unu #ifdef WM_EVENT_COUNTERS evcnt_detach(&sc->sc_ev_linkintr); + evcnt_detach(&sc->sc_ev_crcerrs); + evcnt_detach(&sc->sc_ev_symerrc); + evcnt_detach(&sc->sc_ev_mpc); + evcnt_detach(&sc->sc_ev_colc); + evcnt_detach(&sc->sc_ev_sec); + evcnt_detach(&sc->sc_ev_rlec); + + if (sc->sc_type >= WM_T_82543) { + evcnt_detach(&sc->sc_ev_algnerrc); + evcnt_detach(&sc->sc_ev_rxerrc); + if ((sc->sc_type < WM_T_82575) || WM_IS_ICHPCH(sc)) + evcnt_detach(&sc->sc_ev_cexterr); + else + evcnt_detach(&sc->sc_ev_htdpmc); + + evcnt_detach(&sc->sc_ev_tncrs); + evcnt_detach(&sc->sc_ev_tsctc); + if ((sc->sc_type < WM_T_82575) || WM_IS_ICHPCH(sc)) + evcnt_detach(&sc->sc_ev_tsctfc); + else { + evcnt_detach(&sc->sc_ev_cbrdpc); + evcnt_detach(&sc->sc_ev_cbrmpc); + } + } + if (sc->sc_type >= WM_T_82542_2_1) { evcnt_detach(&sc->sc_ev_tx_xoff); evcnt_detach(&sc->sc_ev_tx_xon); @@ -3407,23 +3548,21 @@ wm_detach(device_t self, int flags __unu evcnt_detach(&sc->sc_ev_rx_macctl); } - evcnt_detach(&sc->sc_ev_crcerrs); - evcnt_detach(&sc->sc_ev_symerrc); - - if (sc->sc_type >= WM_T_82543) { - evcnt_detach(&sc->sc_ev_algnerrc); - evcnt_detach(&sc->sc_ev_rxerrc); - evcnt_detach(&sc->sc_ev_cexterr); - } - evcnt_detach(&sc->sc_ev_mpc); - evcnt_detach(&sc->sc_ev_colc); - evcnt_detach(&sc->sc_ev_sec); - evcnt_detach(&sc->sc_ev_rlec); evcnt_detach(&sc->sc_ev_scc); evcnt_detach(&sc->sc_ev_ecol); evcnt_detach(&sc->sc_ev_mcc); evcnt_detach(&sc->sc_ev_latecol); + + if ((sc->sc_type >= WM_T_I350) && !WM_IS_ICHPCH(sc)) + evcnt_detach(&sc->sc_ev_cbtmpc); + evcnt_detach(&sc->sc_ev_dc); + evcnt_detach(&sc->sc_ev_prc64); + evcnt_detach(&sc->sc_ev_prc127); + evcnt_detach(&sc->sc_ev_prc255); + evcnt_detach(&sc->sc_ev_prc511); + evcnt_detach(&sc->sc_ev_prc1023); + evcnt_detach(&sc->sc_ev_prc1522); evcnt_detach(&sc->sc_ev_gprc); evcnt_detach(&sc->sc_ev_bprc); evcnt_detach(&sc->sc_ev_mprc); @@ -3435,48 +3574,56 @@ wm_detach(device_t self, int flags __unu evcnt_detach(&sc->sc_ev_rfc); evcnt_detach(&sc->sc_ev_roc); evcnt_detach(&sc->sc_ev_rjc); + if (sc->sc_type >= WM_T_82540) { + evcnt_detach(&sc->sc_ev_mgtprc); + evcnt_detach(&sc->sc_ev_mgtpdc); + evcnt_detach(&sc->sc_ev_mgtptc); + } evcnt_detach(&sc->sc_ev_tor); evcnt_detach(&sc->sc_ev_tot); evcnt_detach(&sc->sc_ev_tpr); evcnt_detach(&sc->sc_ev_tpt); - evcnt_detach(&sc->sc_ev_mptc); - evcnt_detach(&sc->sc_ev_bptc); - evcnt_detach(&sc->sc_ev_prc64); - evcnt_detach(&sc->sc_ev_prc127); - evcnt_detach(&sc->sc_ev_prc255); - evcnt_detach(&sc->sc_ev_prc511); - evcnt_detach(&sc->sc_ev_prc1023); - evcnt_detach(&sc->sc_ev_prc1522); evcnt_detach(&sc->sc_ev_ptc64); evcnt_detach(&sc->sc_ev_ptc127); evcnt_detach(&sc->sc_ev_ptc255); evcnt_detach(&sc->sc_ev_ptc511); evcnt_detach(&sc->sc_ev_ptc1023); evcnt_detach(&sc->sc_ev_ptc1522); + evcnt_detach(&sc->sc_ev_mptc); + evcnt_detach(&sc->sc_ev_bptc); evcnt_detach(&sc->sc_ev_iac); - evcnt_detach(&sc->sc_ev_icrxptc); - evcnt_detach(&sc->sc_ev_icrxatc); - evcnt_detach(&sc->sc_ev_ictxptc); - evcnt_detach(&sc->sc_ev_ictxact); - evcnt_detach(&sc->sc_ev_ictxqec); - evcnt_detach(&sc->sc_ev_ictxqmtc); - evcnt_detach(&sc->sc_ev_icrxdmtc); - evcnt_detach(&sc->sc_ev_icrxoc); - if (sc->sc_type >= WM_T_82543) { - evcnt_detach(&sc->sc_ev_tncrs); - evcnt_detach(&sc->sc_ev_tsctc); - evcnt_detach(&sc->sc_ev_tsctfc); - } - if (sc->sc_type >= WM_T_82540) { - evcnt_detach(&sc->sc_ev_mgtprc); - evcnt_detach(&sc->sc_ev_mgtpdc); - evcnt_detach(&sc->sc_ev_mgtptc); - } - if ((sc->sc_type >= WM_T_I350) && (sc->sc_type < WM_T_80003)) { + if (sc->sc_type < WM_T_82575) { + evcnt_detach(&sc->sc_ev_icrxptc); + evcnt_detach(&sc->sc_ev_icrxatc); + evcnt_detach(&sc->sc_ev_ictxptc); + evcnt_detach(&sc->sc_ev_ictxatc); + evcnt_detach(&sc->sc_ev_ictxqec); + evcnt_detach(&sc->sc_ev_ictxqmtc); + evcnt_detach(&sc->sc_ev_rxdmtc); + evcnt_detach(&sc->sc_ev_icrxoc); + } else if (!WM_IS_ICHPCH(sc)) { + evcnt_detach(&sc->sc_ev_rpthc); + evcnt_detach(&sc->sc_ev_debug1); + evcnt_detach(&sc->sc_ev_debug2); + evcnt_detach(&sc->sc_ev_debug3); + evcnt_detach(&sc->sc_ev_hgptc); + evcnt_detach(&sc->sc_ev_debug4); + evcnt_detach(&sc->sc_ev_rxdmtc); + evcnt_detach(&sc->sc_ev_htcbdpc); + + evcnt_detach(&sc->sc_ev_hgorc); + evcnt_detach(&sc->sc_ev_hgotc); + evcnt_detach(&sc->sc_ev_lenerrs); + } + if ((sc->sc_type >= WM_T_I350) && !WM_IS_ICHPCH(sc)) { + evcnt_detach(&sc->sc_ev_tlpic); + evcnt_detach(&sc->sc_ev_rlpic); evcnt_detach(&sc->sc_ev_b2ogprc); evcnt_detach(&sc->sc_ev_o2bspc); evcnt_detach(&sc->sc_ev_b2ospc); evcnt_detach(&sc->sc_ev_o2bgptc); + evcnt_detach(&sc->sc_ev_scvpc); + evcnt_detach(&sc->sc_ev_hrmpc); } #endif /* WM_EVENT_COUNTERS */ @@ -3714,8 +3861,6 @@ wm_tick(void *arg) { struct wm_softc *sc = arg; struct ifnet *ifp = &sc->sc_ethercom.ec_if; - uint64_t crcerrs, algnerrc, symerrc, mpc, colc, sec, rlec, rxerrc, - cexterr; #ifndef WM_MPSAFE int s = splnet(); #endif @@ -3730,120 +3875,7 @@ wm_tick(void *arg) return; } - crcerrs = CSR_READ(sc, WMREG_CRCERRS); - symerrc = CSR_READ(sc, WMREG_SYMERRC); - mpc = CSR_READ(sc, WMREG_MPC); - colc = CSR_READ(sc, WMREG_COLC); - sec = CSR_READ(sc, WMREG_SEC); - rlec = CSR_READ(sc, WMREG_RLEC); - - WM_EVCNT_ADD(&sc->sc_ev_crcerrs, crcerrs); - WM_EVCNT_ADD(&sc->sc_ev_symerrc, symerrc); - WM_EVCNT_ADD(&sc->sc_ev_mpc, mpc); - WM_EVCNT_ADD(&sc->sc_ev_colc, colc); - WM_EVCNT_ADD(&sc->sc_ev_sec, sec); - WM_EVCNT_ADD(&sc->sc_ev_rlec, rlec); - - if (sc->sc_type >= WM_T_82542_2_1) { - WM_EVCNT_ADD(&sc->sc_ev_rx_xon, CSR_READ(sc, WMREG_XONRXC)); - WM_EVCNT_ADD(&sc->sc_ev_tx_xon, CSR_READ(sc, WMREG_XONTXC)); - WM_EVCNT_ADD(&sc->sc_ev_rx_xoff, CSR_READ(sc, WMREG_XOFFRXC)); - WM_EVCNT_ADD(&sc->sc_ev_tx_xoff, CSR_READ(sc, WMREG_XOFFTXC)); - WM_EVCNT_ADD(&sc->sc_ev_rx_macctl, CSR_READ(sc, WMREG_FCRUC)); - } - - WM_EVCNT_ADD(&sc->sc_ev_scc, CSR_READ(sc, WMREG_SCC)); - WM_EVCNT_ADD(&sc->sc_ev_ecol, CSR_READ(sc, WMREG_ECOL)); - WM_EVCNT_ADD(&sc->sc_ev_mcc, CSR_READ(sc, WMREG_MCC)); - WM_EVCNT_ADD(&sc->sc_ev_latecol, CSR_READ(sc, WMREG_LATECOL)); - WM_EVCNT_ADD(&sc->sc_ev_dc, CSR_READ(sc, WMREG_DC)); - WM_EVCNT_ADD(&sc->sc_ev_gprc, CSR_READ(sc, WMREG_GPRC)); - WM_EVCNT_ADD(&sc->sc_ev_bprc, CSR_READ(sc, WMREG_BPRC)); - WM_EVCNT_ADD(&sc->sc_ev_mprc, CSR_READ(sc, WMREG_MPRC)); - WM_EVCNT_ADD(&sc->sc_ev_gptc, CSR_READ(sc, WMREG_GPTC)); - - WM_EVCNT_ADD(&sc->sc_ev_gorc, - CSR_READ(sc, WMREG_GORCL) + CSR_READ(sc, WMREG_GORCH)); - WM_EVCNT_ADD(&sc->sc_ev_gotc, - CSR_READ(sc, WMREG_GOTCL) + CSR_READ(sc, WMREG_GOTCH)); - - WM_EVCNT_ADD(&sc->sc_ev_rnbc, CSR_READ(sc, WMREG_RNBC)); - WM_EVCNT_ADD(&sc->sc_ev_ruc, CSR_READ(sc, WMREG_RUC)); - WM_EVCNT_ADD(&sc->sc_ev_rfc, CSR_READ(sc, WMREG_RFC)); - WM_EVCNT_ADD(&sc->sc_ev_roc, CSR_READ(sc, WMREG_ROC)); - WM_EVCNT_ADD(&sc->sc_ev_rjc, CSR_READ(sc, WMREG_RJC)); - - WM_EVCNT_ADD(&sc->sc_ev_tor, - CSR_READ(sc, WMREG_TORL) + CSR_READ(sc, WMREG_TORH)); - WM_EVCNT_ADD(&sc->sc_ev_tot, - CSR_READ(sc, WMREG_TOTL) + CSR_READ(sc, WMREG_TOTH)); - - WM_EVCNT_ADD(&sc->sc_ev_tpr, CSR_READ(sc, WMREG_TPR)); - WM_EVCNT_ADD(&sc->sc_ev_tpt, CSR_READ(sc, WMREG_TPT)); - WM_EVCNT_ADD(&sc->sc_ev_mptc, CSR_READ(sc, WMREG_MPTC)); - WM_EVCNT_ADD(&sc->sc_ev_bptc, CSR_READ(sc, WMREG_BPTC)); - WM_EVCNT_ADD(&sc->sc_ev_prc64, CSR_READ(sc, WMREG_PRC64)); - WM_EVCNT_ADD(&sc->sc_ev_prc127, CSR_READ(sc, WMREG_PRC127)); - WM_EVCNT_ADD(&sc->sc_ev_prc255, CSR_READ(sc, WMREG_PRC255)); - WM_EVCNT_ADD(&sc->sc_ev_prc511, CSR_READ(sc, WMREG_PRC511)); - WM_EVCNT_ADD(&sc->sc_ev_prc1023, CSR_READ(sc, WMREG_PRC1023)); - WM_EVCNT_ADD(&sc->sc_ev_prc1522, CSR_READ(sc, WMREG_PRC1522)); - WM_EVCNT_ADD(&sc->sc_ev_ptc64, CSR_READ(sc, WMREG_PTC64)); - WM_EVCNT_ADD(&sc->sc_ev_ptc127, CSR_READ(sc, WMREG_PTC127)); - WM_EVCNT_ADD(&sc->sc_ev_ptc255, CSR_READ(sc, WMREG_PTC255)); - WM_EVCNT_ADD(&sc->sc_ev_ptc511, CSR_READ(sc, WMREG_PTC511)); - WM_EVCNT_ADD(&sc->sc_ev_ptc1023, CSR_READ(sc, WMREG_PTC1023)); - WM_EVCNT_ADD(&sc->sc_ev_ptc1522, CSR_READ(sc, WMREG_PTC1522)); - WM_EVCNT_ADD(&sc->sc_ev_iac, CSR_READ(sc, WMREG_IAC)); - WM_EVCNT_ADD(&sc->sc_ev_icrxptc, CSR_READ(sc, WMREG_ICRXPTC)); - WM_EVCNT_ADD(&sc->sc_ev_icrxatc, CSR_READ(sc, WMREG_ICRXATC)); - WM_EVCNT_ADD(&sc->sc_ev_ictxptc, CSR_READ(sc, WMREG_ICTXPTC)); - WM_EVCNT_ADD(&sc->sc_ev_ictxact, CSR_READ(sc, WMREG_ICTXATC)); - WM_EVCNT_ADD(&sc->sc_ev_ictxqec, CSR_READ(sc, WMREG_ICTXQEC)); - WM_EVCNT_ADD(&sc->sc_ev_ictxqmtc, CSR_READ(sc, WMREG_ICTXQMTC)); - WM_EVCNT_ADD(&sc->sc_ev_icrxdmtc, CSR_READ(sc, WMREG_ICRXDMTC)); - WM_EVCNT_ADD(&sc->sc_ev_icrxoc, CSR_READ(sc, WMREG_ICRXOC)); - - if (sc->sc_type >= WM_T_82543) { - algnerrc = CSR_READ(sc, WMREG_ALGNERRC); - rxerrc = CSR_READ(sc, WMREG_RXERRC); - cexterr = CSR_READ(sc, WMREG_CEXTERR); - WM_EVCNT_ADD(&sc->sc_ev_algnerrc, algnerrc); - WM_EVCNT_ADD(&sc->sc_ev_rxerrc, rxerrc); - WM_EVCNT_ADD(&sc->sc_ev_cexterr, cexterr); - - WM_EVCNT_ADD(&sc->sc_ev_tncrs, CSR_READ(sc, WMREG_TNCRS)); - WM_EVCNT_ADD(&sc->sc_ev_tsctc, CSR_READ(sc, WMREG_TSCTC)); - WM_EVCNT_ADD(&sc->sc_ev_tsctfc, CSR_READ(sc, WMREG_TSCTFC)); - } else - algnerrc = rxerrc = cexterr = 0; - - if (sc->sc_type >= WM_T_82540) { - WM_EVCNT_ADD(&sc->sc_ev_mgtprc, CSR_READ(sc, WMREG_MGTPRC)); - WM_EVCNT_ADD(&sc->sc_ev_mgtpdc, CSR_READ(sc, WMREG_MGTPDC)); - WM_EVCNT_ADD(&sc->sc_ev_mgtptc, CSR_READ(sc, WMREG_MGTPTC)); - } - if (((sc->sc_type >= WM_T_I350) && (sc->sc_type < WM_T_80003)) - && ((CSR_READ(sc, WMREG_MANC) & MANC_EN_BMC2OS) != 0)) { - WM_EVCNT_ADD(&sc->sc_ev_b2ogprc, CSR_READ(sc, WMREG_B2OGPRC)); - WM_EVCNT_ADD(&sc->sc_ev_o2bspc, CSR_READ(sc, WMREG_O2BSPC)); - WM_EVCNT_ADD(&sc->sc_ev_b2ospc, CSR_READ(sc, WMREG_B2OSPC)); - WM_EVCNT_ADD(&sc->sc_ev_o2bgptc, CSR_READ(sc, WMREG_O2BGPTC)); - } - ifp->if_collisions += colc; - ifp->if_ierrors += - crcerrs + algnerrc + symerrc + rxerrc + sec + cexterr + rlec; - - /* - * WMREG_RNBC is incremented when there are no available buffers in - * host memory. It does not mean the number of dropped packets, because - * an Ethernet controller can receive packets in such case if there is - * space in the phy's FIFO. - * - * If you want to know the nubmer of WMREG_RMBC, you should use such as - * own EVCNT instead of if_iqdrops. - */ - ifp->if_iqdrops += mpc; + wm_update_stats(sc); if (sc->sc_flags & WM_F_HAS_MII) mii_tick(&sc->sc_mii); @@ -3977,6 +4009,19 @@ wm_ioctl(struct ifnet *ifp, u_long cmd, #ifndef WM_MPSAFE s = splnet(); #endif + + if (cmd == SIOCZIFDATA) { + /* + * Special handling for SIOCZIFDATA. + * Copying and clearing the if_data structure is done with + * ether_ioctl() below. + */ + WM_CORE_LOCK(sc); + wm_update_stats(sc); + wm_clear_evcnt(sc); + WM_CORE_UNLOCK(sc); + } + switch (cmd) { case SIOCSIFMEDIA: WM_CORE_LOCK(sc); @@ -4954,7 +4999,7 @@ wm_initialize_hardware_bits(struct wm_so /* For 82571 variant, 80003 and ICHs */ if (((sc->sc_type >= WM_T_82571) && (sc->sc_type <= WM_T_82583)) - || (sc->sc_type >= WM_T_80003)) { + || WM_IS_ICHPCH(sc)) { /* Transmit Descriptor Control 0 */ reg = CSR_READ(sc, WMREG_TXDCTL(0)); @@ -6484,6 +6529,351 @@ err: __func__, rv); } +static void +wm_update_stats(struct wm_softc *sc) +{ + struct ifnet *ifp = &sc->sc_ethercom.ec_if; + uint64_t crcerrs, algnerrc, symerrc, mpc, colc, sec, rlec, rxerrc, + cexterr; + + crcerrs = CSR_READ(sc, WMREG_CRCERRS); + symerrc = CSR_READ(sc, WMREG_SYMERRC); + mpc = CSR_READ(sc, WMREG_MPC); + colc = CSR_READ(sc, WMREG_COLC); + sec = CSR_READ(sc, WMREG_SEC); + rlec = CSR_READ(sc, WMREG_RLEC); + + WM_EVCNT_ADD(&sc->sc_ev_crcerrs, crcerrs); + WM_EVCNT_ADD(&sc->sc_ev_symerrc, symerrc); + WM_EVCNT_ADD(&sc->sc_ev_mpc, mpc); + WM_EVCNT_ADD(&sc->sc_ev_colc, colc); + WM_EVCNT_ADD(&sc->sc_ev_sec, sec); + WM_EVCNT_ADD(&sc->sc_ev_rlec, rlec); + + if (sc->sc_type >= WM_T_82543) { + algnerrc = CSR_READ(sc, WMREG_ALGNERRC); + rxerrc = CSR_READ(sc, WMREG_RXERRC); + WM_EVCNT_ADD(&sc->sc_ev_algnerrc, algnerrc); + WM_EVCNT_ADD(&sc->sc_ev_rxerrc, rxerrc); + if ((sc->sc_type < WM_T_82575) || WM_IS_ICHPCH(sc)) { + cexterr = CSR_READ(sc, WMREG_CEXTERR); + WM_EVCNT_ADD(&sc->sc_ev_cexterr, cexterr); + } else { + cexterr = 0; + /* Excessive collision + Link down */ + WM_EVCNT_ADD(&sc->sc_ev_htdpmc, + CSR_READ(sc, WMREG_HTDPMC)); + } + + WM_EVCNT_ADD(&sc->sc_ev_tncrs, CSR_READ(sc, WMREG_TNCRS)); + WM_EVCNT_ADD(&sc->sc_ev_tsctc, CSR_READ(sc, WMREG_TSCTC)); + if ((sc->sc_type < WM_T_82575) || WM_IS_ICHPCH(sc)) + WM_EVCNT_ADD(&sc->sc_ev_tsctfc, + CSR_READ(sc, WMREG_TSCTFC)); + else { + WM_EVCNT_ADD(&sc->sc_ev_cbrdpc, + CSR_READ(sc, WMREG_CBRDPC)); + WM_EVCNT_ADD(&sc->sc_ev_cbrmpc, + CSR_READ(sc, WMREG_CBRMPC)); + } + } else + algnerrc = rxerrc = cexterr = 0; + + if (sc->sc_type >= WM_T_82542_2_1) { + WM_EVCNT_ADD(&sc->sc_ev_rx_xon, CSR_READ(sc, WMREG_XONRXC)); + WM_EVCNT_ADD(&sc->sc_ev_tx_xon, CSR_READ(sc, WMREG_XONTXC)); + WM_EVCNT_ADD(&sc->sc_ev_rx_xoff, CSR_READ(sc, WMREG_XOFFRXC)); + WM_EVCNT_ADD(&sc->sc_ev_tx_xoff, CSR_READ(sc, WMREG_XOFFTXC)); + WM_EVCNT_ADD(&sc->sc_ev_rx_macctl, CSR_READ(sc, WMREG_FCRUC)); + } + + WM_EVCNT_ADD(&sc->sc_ev_scc, CSR_READ(sc, WMREG_SCC)); + WM_EVCNT_ADD(&sc->sc_ev_ecol, CSR_READ(sc, WMREG_ECOL)); + WM_EVCNT_ADD(&sc->sc_ev_mcc, CSR_READ(sc, WMREG_MCC)); + WM_EVCNT_ADD(&sc->sc_ev_latecol, CSR_READ(sc, WMREG_LATECOL)); + + if ((sc->sc_type >= WM_T_I350) && !WM_IS_ICHPCH(sc)) { + WM_EVCNT_ADD(&sc->sc_ev_cbtmpc, CSR_READ(sc, WMREG_CBTMPC)); + } + + WM_EVCNT_ADD(&sc->sc_ev_dc, CSR_READ(sc, WMREG_DC)); + WM_EVCNT_ADD(&sc->sc_ev_prc64, CSR_READ(sc, WMREG_PRC64)); + WM_EVCNT_ADD(&sc->sc_ev_prc127, CSR_READ(sc, WMREG_PRC127)); + WM_EVCNT_ADD(&sc->sc_ev_prc255, CSR_READ(sc, WMREG_PRC255)); + WM_EVCNT_ADD(&sc->sc_ev_prc511, CSR_READ(sc, WMREG_PRC511)); + WM_EVCNT_ADD(&sc->sc_ev_prc1023, CSR_READ(sc, WMREG_PRC1023)); + WM_EVCNT_ADD(&sc->sc_ev_prc1522, CSR_READ(sc, WMREG_PRC1522)); + WM_EVCNT_ADD(&sc->sc_ev_gprc, CSR_READ(sc, WMREG_GPRC)); + WM_EVCNT_ADD(&sc->sc_ev_bprc, CSR_READ(sc, WMREG_BPRC)); + WM_EVCNT_ADD(&sc->sc_ev_mprc, CSR_READ(sc, WMREG_MPRC)); + WM_EVCNT_ADD(&sc->sc_ev_gptc, CSR_READ(sc, WMREG_GPTC)); + + WM_EVCNT_ADD(&sc->sc_ev_gorc, + CSR_READ(sc, WMREG_GORCL) + + ((uint64_t)CSR_READ(sc, WMREG_GORCH) << 32)); + WM_EVCNT_ADD(&sc->sc_ev_gotc, + CSR_READ(sc, WMREG_GOTCL) + + ((uint64_t)CSR_READ(sc, WMREG_GOTCH) << 32)); + + WM_EVCNT_ADD(&sc->sc_ev_rnbc, CSR_READ(sc, WMREG_RNBC)); + WM_EVCNT_ADD(&sc->sc_ev_ruc, CSR_READ(sc, WMREG_RUC)); + WM_EVCNT_ADD(&sc->sc_ev_rfc, CSR_READ(sc, WMREG_RFC)); + WM_EVCNT_ADD(&sc->sc_ev_roc, CSR_READ(sc, WMREG_ROC)); + WM_EVCNT_ADD(&sc->sc_ev_rjc, CSR_READ(sc, WMREG_RJC)); + + if (sc->sc_type >= WM_T_82540) { + WM_EVCNT_ADD(&sc->sc_ev_mgtprc, CSR_READ(sc, WMREG_MGTPRC)); + WM_EVCNT_ADD(&sc->sc_ev_mgtpdc, CSR_READ(sc, WMREG_MGTPDC)); + WM_EVCNT_ADD(&sc->sc_ev_mgtptc, CSR_READ(sc, WMREG_MGTPTC)); + } + + /* + * The TOR(L) register includes: + * - Error + * - Flow control + * - Broadcast rejected (This note is described in 82574 and newer + * datasheets. What does "broadcast rejected" mean?) + */ + WM_EVCNT_ADD(&sc->sc_ev_tor, + CSR_READ(sc, WMREG_TORL) + + ((uint64_t)CSR_READ(sc, WMREG_TORH) << 32)); + WM_EVCNT_ADD(&sc->sc_ev_tot, + CSR_READ(sc, WMREG_TOTL) + + ((uint64_t)CSR_READ(sc, WMREG_TOTH) << 32)); + + WM_EVCNT_ADD(&sc->sc_ev_tpr, CSR_READ(sc, WMREG_TPR)); + WM_EVCNT_ADD(&sc->sc_ev_tpt, CSR_READ(sc, WMREG_TPT)); + WM_EVCNT_ADD(&sc->sc_ev_ptc64, CSR_READ(sc, WMREG_PTC64)); + WM_EVCNT_ADD(&sc->sc_ev_ptc127, CSR_READ(sc, WMREG_PTC127)); + WM_EVCNT_ADD(&sc->sc_ev_ptc255, CSR_READ(sc, WMREG_PTC255)); + WM_EVCNT_ADD(&sc->sc_ev_ptc511, CSR_READ(sc, WMREG_PTC511)); + WM_EVCNT_ADD(&sc->sc_ev_ptc1023, CSR_READ(sc, WMREG_PTC1023)); + WM_EVCNT_ADD(&sc->sc_ev_ptc1522, CSR_READ(sc, WMREG_PTC1522)); + WM_EVCNT_ADD(&sc->sc_ev_mptc, CSR_READ(sc, WMREG_MPTC)); + WM_EVCNT_ADD(&sc->sc_ev_bptc, CSR_READ(sc, WMREG_BPTC)); + WM_EVCNT_ADD(&sc->sc_ev_iac, CSR_READ(sc, WMREG_IAC)); + if (sc->sc_type < WM_T_82575) { + WM_EVCNT_ADD(&sc->sc_ev_icrxptc, CSR_READ(sc, WMREG_ICRXPTC)); + WM_EVCNT_ADD(&sc->sc_ev_icrxatc, CSR_READ(sc, WMREG_ICRXATC)); + WM_EVCNT_ADD(&sc->sc_ev_ictxptc, CSR_READ(sc, WMREG_ICTXPTC)); + WM_EVCNT_ADD(&sc->sc_ev_ictxatc, CSR_READ(sc, WMREG_ICTXATC)); + WM_EVCNT_ADD(&sc->sc_ev_ictxqec, CSR_READ(sc, WMREG_ICTXQEC)); + WM_EVCNT_ADD(&sc->sc_ev_ictxqmtc, + CSR_READ(sc, WMREG_ICTXQMTC)); + WM_EVCNT_ADD(&sc->sc_ev_rxdmtc, + CSR_READ(sc, WMREG_ICRXDMTC)); + WM_EVCNT_ADD(&sc->sc_ev_icrxoc, CSR_READ(sc, WMREG_ICRXOC)); + } else if (!WM_IS_ICHPCH(sc)) { + WM_EVCNT_ADD(&sc->sc_ev_rpthc, CSR_READ(sc, WMREG_RPTHC)); + WM_EVCNT_ADD(&sc->sc_ev_debug1, CSR_READ(sc, WMREG_DEBUG1)); + WM_EVCNT_ADD(&sc->sc_ev_debug2, CSR_READ(sc, WMREG_DEBUG2)); + WM_EVCNT_ADD(&sc->sc_ev_debug3, CSR_READ(sc, WMREG_DEBUG3)); + WM_EVCNT_ADD(&sc->sc_ev_hgptc, CSR_READ(sc, WMREG_HGPTC)); + WM_EVCNT_ADD(&sc->sc_ev_debug4, CSR_READ(sc, WMREG_DEBUG4)); + WM_EVCNT_ADD(&sc->sc_ev_rxdmtc, CSR_READ(sc, WMREG_RXDMTC)); + WM_EVCNT_ADD(&sc->sc_ev_htcbdpc, CSR_READ(sc, WMREG_HTCBDPC)); + + WM_EVCNT_ADD(&sc->sc_ev_hgorc, + CSR_READ(sc, WMREG_HGORCL) + + ((uint64_t)CSR_READ(sc, WMREG_HGORCH) << 32)); + WM_EVCNT_ADD(&sc->sc_ev_hgotc, + CSR_READ(sc, WMREG_HGOTCL) + + ((uint64_t)CSR_READ(sc, WMREG_HGOTCH) << 32)); + WM_EVCNT_ADD(&sc->sc_ev_lenerrs, CSR_READ(sc, WMREG_LENERRS)); + } + if ((sc->sc_type >= WM_T_I350) && !WM_IS_ICHPCH(sc)) { + WM_EVCNT_ADD(&sc->sc_ev_tlpic, CSR_READ(sc, WMREG_TLPIC)); + WM_EVCNT_ADD(&sc->sc_ev_rlpic, CSR_READ(sc, WMREG_RLPIC)); + if ((CSR_READ(sc, WMREG_MANC) & MANC_EN_BMC2OS) != 0) { + WM_EVCNT_ADD(&sc->sc_ev_b2ogprc, + CSR_READ(sc, WMREG_B2OGPRC)); + WM_EVCNT_ADD(&sc->sc_ev_o2bspc, + CSR_READ(sc, WMREG_O2BSPC)); + WM_EVCNT_ADD(&sc->sc_ev_b2ospc, + CSR_READ(sc, WMREG_B2OSPC)); + WM_EVCNT_ADD(&sc->sc_ev_o2bgptc, + CSR_READ(sc, WMREG_O2BGPTC)); + } + WM_EVCNT_ADD(&sc->sc_ev_scvpc, CSR_READ(sc, WMREG_SCVPC)); + WM_EVCNT_ADD(&sc->sc_ev_hrmpc, CSR_READ(sc, WMREG_HRMPC)); + } + ifp->if_collisions += colc; + ifp->if_ierrors += + crcerrs + algnerrc + symerrc + rxerrc + sec + cexterr + rlec; + + /* + * WMREG_RNBC is incremented when there are no available buffers in + * host memory. It does not mean the number of dropped packets, because + * an Ethernet controller can receive packets in such case if there is + * space in the phy's FIFO. + * + * If you want to know the nubmer of WMREG_RMBC, you should use such as + * own EVCNT instead of if_iqdrops. + */ + ifp->if_iqdrops += mpc; +} + +void +wm_clear_evcnt(struct wm_softc *sc) +{ +#ifdef WM_EVENT_COUNTERS + int i; + + /* RX queues */ + for (i = 0; i < sc->sc_nqueues; i++) { + struct wm_rxqueue *rxq = &sc->sc_queue[i].wmq_rxq; + + WM_Q_EVCNT_STORE(rxq, intr, 0); + WM_Q_EVCNT_STORE(rxq, defer, 0); + WM_Q_EVCNT_STORE(rxq, ipsum, 0); + WM_Q_EVCNT_STORE(rxq, tusum, 0); + } + + /* TX queues */ + for (i = 0; i < sc->sc_nqueues; i++) { + struct wm_txqueue *txq = &sc->sc_queue[i].wmq_txq; + int j; + + WM_Q_EVCNT_STORE(txq, txsstall, 0); + WM_Q_EVCNT_STORE(txq, txdstall, 0); + WM_Q_EVCNT_STORE(txq, fifo_stall, 0); + WM_Q_EVCNT_STORE(txq, txdw, 0); + WM_Q_EVCNT_STORE(txq, txqe, 0); + WM_Q_EVCNT_STORE(txq, ipsum, 0); + WM_Q_EVCNT_STORE(txq, tusum, 0); + WM_Q_EVCNT_STORE(txq, tusum6, 0); + WM_Q_EVCNT_STORE(txq, tso, 0); + WM_Q_EVCNT_STORE(txq, tso6, 0); + WM_Q_EVCNT_STORE(txq, tsopain, 0); + + for (j = 0; j < WM_NTXSEGS; j++) + WM_EVCNT_STORE(&txq->txq_ev_txseg[j], 0); + + WM_Q_EVCNT_STORE(txq, pcqdrop, 0); + WM_Q_EVCNT_STORE(txq, descdrop, 0); + WM_Q_EVCNT_STORE(txq, toomanyseg, 0); + WM_Q_EVCNT_STORE(txq, defrag, 0); + if (sc->sc_type <= WM_T_82544) + WM_Q_EVCNT_STORE(txq, underrun, 0); + WM_Q_EVCNT_STORE(txq, skipcontext, 0); + } + + /* Miscs */ + WM_EVCNT_STORE(&sc->sc_ev_linkintr, 0); + + WM_EVCNT_STORE(&sc->sc_ev_crcerrs, 0); + WM_EVCNT_STORE(&sc->sc_ev_symerrc, 0); + WM_EVCNT_STORE(&sc->sc_ev_mpc, 0); + WM_EVCNT_STORE(&sc->sc_ev_colc, 0); + WM_EVCNT_STORE(&sc->sc_ev_sec, 0); + WM_EVCNT_STORE(&sc->sc_ev_rlec, 0); + + if (sc->sc_type >= WM_T_82543) { + WM_EVCNT_STORE(&sc->sc_ev_algnerrc, 0); + WM_EVCNT_STORE(&sc->sc_ev_rxerrc, 0); + if ((sc->sc_type < WM_T_82575) || WM_IS_ICHPCH(sc)) + WM_EVCNT_STORE(&sc->sc_ev_cexterr, 0); + else + WM_EVCNT_STORE(&sc->sc_ev_htdpmc, 0); + + WM_EVCNT_STORE(&sc->sc_ev_tncrs, 0); + WM_EVCNT_STORE(&sc->sc_ev_tsctc, 0); + if ((sc->sc_type < WM_T_82575) || WM_IS_ICHPCH(sc)) + WM_EVCNT_STORE(&sc->sc_ev_tsctfc, 0); + else { + WM_EVCNT_STORE(&sc->sc_ev_cbrdpc, 0); + WM_EVCNT_STORE(&sc->sc_ev_cbrmpc, 0); + } + } + + if (sc->sc_type >= WM_T_82542_2_1) { + WM_EVCNT_STORE(&sc->sc_ev_tx_xoff, 0); + WM_EVCNT_STORE(&sc->sc_ev_tx_xon, 0); + WM_EVCNT_STORE(&sc->sc_ev_rx_xoff, 0); + WM_EVCNT_STORE(&sc->sc_ev_rx_xon, 0); + WM_EVCNT_STORE(&sc->sc_ev_rx_macctl, 0); + } + + WM_EVCNT_STORE(&sc->sc_ev_scc, 0); + WM_EVCNT_STORE(&sc->sc_ev_ecol, 0); + WM_EVCNT_STORE(&sc->sc_ev_mcc, 0); + WM_EVCNT_STORE(&sc->sc_ev_latecol, 0); + + if ((sc->sc_type >= WM_T_I350) && !WM_IS_ICHPCH(sc)) + WM_EVCNT_STORE(&sc->sc_ev_cbtmpc, 0); + + WM_EVCNT_STORE(&sc->sc_ev_dc, 0); + WM_EVCNT_STORE(&sc->sc_ev_prc64, 0); + WM_EVCNT_STORE(&sc->sc_ev_prc127, 0); + WM_EVCNT_STORE(&sc->sc_ev_prc255, 0); + WM_EVCNT_STORE(&sc->sc_ev_prc511, 0); + WM_EVCNT_STORE(&sc->sc_ev_prc1023, 0); + WM_EVCNT_STORE(&sc->sc_ev_prc1522, 0); + WM_EVCNT_STORE(&sc->sc_ev_gprc, 0); + WM_EVCNT_STORE(&sc->sc_ev_bprc, 0); + WM_EVCNT_STORE(&sc->sc_ev_mprc, 0); + WM_EVCNT_STORE(&sc->sc_ev_gptc, 0); + WM_EVCNT_STORE(&sc->sc_ev_gorc, 0); + WM_EVCNT_STORE(&sc->sc_ev_gotc, 0); + WM_EVCNT_STORE(&sc->sc_ev_rnbc, 0); + WM_EVCNT_STORE(&sc->sc_ev_ruc, 0); + WM_EVCNT_STORE(&sc->sc_ev_rfc, 0); + WM_EVCNT_STORE(&sc->sc_ev_roc, 0); + WM_EVCNT_STORE(&sc->sc_ev_rjc, 0); + if (sc->sc_type >= WM_T_82540) { + WM_EVCNT_STORE(&sc->sc_ev_mgtprc, 0); + WM_EVCNT_STORE(&sc->sc_ev_mgtpdc, 0); + WM_EVCNT_STORE(&sc->sc_ev_mgtptc, 0); + } + WM_EVCNT_STORE(&sc->sc_ev_tor, 0); + WM_EVCNT_STORE(&sc->sc_ev_tot, 0); + WM_EVCNT_STORE(&sc->sc_ev_tpr, 0); + WM_EVCNT_STORE(&sc->sc_ev_tpt, 0); + WM_EVCNT_STORE(&sc->sc_ev_ptc64, 0); + WM_EVCNT_STORE(&sc->sc_ev_ptc127, 0); + WM_EVCNT_STORE(&sc->sc_ev_ptc255, 0); + WM_EVCNT_STORE(&sc->sc_ev_ptc511, 0); + WM_EVCNT_STORE(&sc->sc_ev_ptc1023, 0); + WM_EVCNT_STORE(&sc->sc_ev_ptc1522, 0); + WM_EVCNT_STORE(&sc->sc_ev_mptc, 0); + WM_EVCNT_STORE(&sc->sc_ev_bptc, 0); + WM_EVCNT_STORE(&sc->sc_ev_iac, 0); + if (sc->sc_type < WM_T_82575) { + WM_EVCNT_STORE(&sc->sc_ev_icrxptc, 0); + WM_EVCNT_STORE(&sc->sc_ev_icrxatc, 0); + WM_EVCNT_STORE(&sc->sc_ev_ictxptc, 0); + WM_EVCNT_STORE(&sc->sc_ev_ictxatc, 0); + WM_EVCNT_STORE(&sc->sc_ev_ictxqec, 0); + WM_EVCNT_STORE(&sc->sc_ev_ictxqmtc, 0); + WM_EVCNT_STORE(&sc->sc_ev_rxdmtc, 0); + WM_EVCNT_STORE(&sc->sc_ev_icrxoc, 0); + } else if (!WM_IS_ICHPCH(sc)) { + WM_EVCNT_STORE(&sc->sc_ev_rpthc, 0); + WM_EVCNT_STORE(&sc->sc_ev_debug1, 0); + WM_EVCNT_STORE(&sc->sc_ev_debug2, 0); + WM_EVCNT_STORE(&sc->sc_ev_debug3, 0); + WM_EVCNT_STORE(&sc->sc_ev_hgptc, 0); + WM_EVCNT_STORE(&sc->sc_ev_debug4, 0); + WM_EVCNT_STORE(&sc->sc_ev_rxdmtc, 0); + WM_EVCNT_STORE(&sc->sc_ev_htcbdpc, 0); + + WM_EVCNT_STORE(&sc->sc_ev_hgorc, 0); + WM_EVCNT_STORE(&sc->sc_ev_hgotc, 0); + WM_EVCNT_STORE(&sc->sc_ev_lenerrs, 0); + } + if ((sc->sc_type >= WM_T_I350) && !WM_IS_ICHPCH(sc)) { + WM_EVCNT_STORE(&sc->sc_ev_tlpic, 0); + WM_EVCNT_STORE(&sc->sc_ev_rlpic, 0); + WM_EVCNT_STORE(&sc->sc_ev_b2ogprc, 0); + WM_EVCNT_STORE(&sc->sc_ev_o2bspc, 0); + WM_EVCNT_STORE(&sc->sc_ev_b2ospc, 0); + WM_EVCNT_STORE(&sc->sc_ev_o2bgptc, 0); + WM_EVCNT_STORE(&sc->sc_ev_scvpc, 0); + WM_EVCNT_STORE(&sc->sc_ev_hrmpc, 0); + } +#endif +} + /* * wm_init: [ifnet interface function] * @@ -7625,7 +8015,9 @@ wm_alloc_txrx_queues(struct wm_softc *sc WM_Q_MISC_EVCNT_ATTACH(txq, descdrop, txq, i, xname); WM_Q_MISC_EVCNT_ATTACH(txq, toomanyseg, txq, i, xname); WM_Q_MISC_EVCNT_ATTACH(txq, defrag, txq, i, xname); - WM_Q_MISC_EVCNT_ATTACH(txq, underrun, txq, i, xname); + /* Only for 82544 (and earlier?) */ + if (sc->sc_type <= WM_T_82544) + WM_Q_MISC_EVCNT_ATTACH(txq, underrun, txq, i, xname); WM_Q_MISC_EVCNT_ATTACH(txq, skipcontext, txq, i, xname); #endif /* WM_EVENT_COUNTERS */ @@ -7758,7 +8150,8 @@ wm_free_txrx_queues(struct wm_softc *sc) WM_Q_EVCNT_DETACH(txq, descdrop, txq, i); WM_Q_EVCNT_DETACH(txq, toomanyseg, txq, i); WM_Q_EVCNT_DETACH(txq, defrag, txq, i); - WM_Q_EVCNT_DETACH(txq, underrun, txq, i); + if (sc->sc_type <= WM_T_82544) + WM_Q_EVCNT_DETACH(txq, underrun, txq, i); WM_Q_EVCNT_DETACH(txq, skipcontext, txq, i); #endif /* WM_EVENT_COUNTERS */ @@ -9406,14 +9799,8 @@ wm_txeof(struct wm_txqueue *txq, u_int l device_xname(sc->sc_dev), i, txs->txs_firstdesc, txs->txs_lastdesc)); - /* - * XXX We should probably be using the statistics - * XXX registers, but I don't know if they exist - * XXX on chips before the i82544. - */ - #ifdef WM_EVENT_COUNTERS - if (status & WTX_ST_TU) + if ((status & WTX_ST_TU) && (sc->sc_type <= WM_T_82544)) WM_Q_EVCNT_INCR(txq, underrun); #endif /* WM_EVENT_COUNTERS */ Index: src/sys/dev/pci/if_wmreg.h diff -u src/sys/dev/pci/if_wmreg.h:1.115.2.7 src/sys/dev/pci/if_wmreg.h:1.115.2.8 --- src/sys/dev/pci/if_wmreg.h:1.115.2.7 Mon Jan 23 13:59:04 2023 +++ src/sys/dev/pci/if_wmreg.h Tue Jun 27 18:32:46 2023 @@ -1,4 +1,4 @@ -/* $NetBSD: if_wmreg.h,v 1.115.2.7 2023/01/23 13:59:04 martin Exp $ */ +/* $NetBSD: if_wmreg.h,v 1.115.2.8 2023/06/27 18:32:46 martin Exp $ */ /* * Copyright (c) 2001 Wasabi Systems, Inc. @@ -1152,11 +1152,18 @@ struct livengood_tcpip_ctxdesc { #define WMREG_MCC 0x401c /* Multiple Collision Count - R/clr */ #define WMREG_LATECOL 0x4020 /* Late Collisions Count - R/clr */ #define WMREG_COLC 0x4028 /* Collision Count - R/clr */ +#define WMREG_CBTMPC 0x402c /* Circuit Breaker Tx Manageability Packet */ #define WMREG_DC 0x4030 /* Defer Count - R/clr */ #define WMREG_TNCRS 0x4034 /* Tx with No CRS - R/clr */ #define WMREG_SEC 0x4038 /* Sequence Error Count */ + +/* Old */ #define WMREG_CEXTERR 0x403c /* Carrier Extension Error Count */ +/* New */ +#define WMREG_HTDPMC 0x403c /* Host Tx Discarded Packets by MAC Count */ + #define WMREG_RLEC 0x4040 /* Receive Length Error Count */ +#define WMREG_CBRDPC 0x4044 /* Circuit Breaker Rx Dropped Packet Count */ #define WMREG_XONRXC 0x4048 /* XON Rx Count - R/clr */ #define WMREG_XONTXC 0x404c /* XON Tx Count - R/clr */ #define WMREG_XOFFRXC 0x4050 /* XOFF Rx Count - R/clr */ @@ -1199,8 +1206,15 @@ struct livengood_tcpip_ctxdesc { #define WMREG_MPTC 0x40f0 /* Multicast Packets Tx Count - R/clr */ #define WMREG_BPTC 0x40f4 /* Broadcast Packets Tx Count */ #define WMREG_TSCTC 0x40f8 /* TCP Segmentation Context Tx */ + +/* Old */ #define WMREG_TSCTFC 0x40fc /* TCP Segmentation Context Tx Fail */ +/* New */ +#define WMREG_CBRMPC 0x40fc /* Circuit Breaker Rx Manageability Packet */ + #define WMREG_IAC 0x4100 /* Interrupt Assertion Count */ + +/* Old */ #define WMREG_ICRXPTC 0x4104 /* Interrupt Cause Rx Pkt Timer Expire Count */ #define WMREG_ICRXATC 0x4108 /* Interrupt Cause Rx Abs Timer Expire Count */ #define WMREG_ICTXPTC 0x410c /* Interrupt Cause Tx Pkt Timer Expire Count */ @@ -1209,6 +1223,21 @@ struct livengood_tcpip_ctxdesc { #define WMREG_ICTXQMTC 0x411c /* Interrupt Cause Tx Queue Min Thresh Count */ #define WMREG_ICRXDMTC 0x4120 /* Interrupt Cause Rx Desc Min Thresh Count */ #define WMREG_ICRXOC 0x4124 /* Interrupt Cause Receiver Overrun Count */ +/* New */ +#define WMREG_RPTHC 0x4104 /* Rx Pkt To Host Count */ +#define WMREG_DEBUG1 0x4108 /* Debug Counter 1 */ +#define WMREG_DEBUG2 0x410c /* Debug Counter 2 */ +#define WMREG_DEBUG3 0x4110 /* Debug Counter 3 */ +#define WMREG_HGPTC 0x4118 /* Host Good Packets Tx Count (>=82576?) */ +#define WMREG_DEBUG4 0x411c /* Debug Counter 4 */ +#define WMREG_RXDMTC 0x4120 /* Rx Desc Min Thresh Count */ +#define WMREG_HTCBDPC 0x4124 /* Host Tx Circuit Breaker Dropped Pkt. Cnt. */ +#define WMREG_HGORCL 0x4128 /* Host Good Octets Rx Count Low (>=82576?) */ +#define WMREG_HGORCH 0x412c /* Host Good Octets Rx Count High (>=82576?) */ +#define WMREG_HGOTCL 0x4130 /* Host Good Octets Tx Count Low (>=82576?) */ +#define WMREG_HGOTCH 0x4134 /* Host Good Octets Tx Count High (>=82576?) */ +#define WMREG_LENERRS 0x4138 /* Length Errors Count (>=82576?) */ + #define WMREG_TLPIC 0x4148 /* EEE Tx LPI Count */ #define WMREG_RLPIC 0x414c /* EEE Rx LPI Count */ #define WMREG_B2OGPRC 0x4158 /* BMC2OS packets received by host */ @@ -1248,6 +1277,7 @@ struct livengood_tcpip_ctxdesc { #define WMREG_PCS_ANADV 0x4218 /* AN Advertsement */ #define WMREG_PCS_LPAB 0x421c /* Link Partnet Ability */ #define WMREG_PCS_NPTX 0x4220 /* Next Page Transmit */ +#define WMREG_SCVPC 0x4228 /* SerDes/SGMII Code Violation Packet Count */ #define WMREG_RXCSUM 0x5000 /* Receive Checksum register */ #define RXCSUM_PCSS 0x000000ff /* Packet Checksum Start */ @@ -1445,6 +1475,8 @@ struct livengood_tcpip_ctxdesc { #define WMREG_B2OSPC 0x8fe0 /* BMC2OS packets sent by BMC */ #define WMREG_O2BGPTC 0x8fe4 /* OS2BMC packets received by BMC */ +#define WMREG_HRMPC 0xa018 /* Header Redirection Missed Packet Count */ + #define WMREG_EEC 0x12010 #define EEC_FLASH_DETECTED __BIT(19) /* FLASH */ #define EEC_FLUPD __BIT(23) /* Update FLASH */ Index: src/sys/dev/pci/if_wmvar.h diff -u src/sys/dev/pci/if_wmvar.h:1.44.4.4 src/sys/dev/pci/if_wmvar.h:1.44.4.5 --- src/sys/dev/pci/if_wmvar.h:1.44.4.4 Mon Jul 11 14:10:18 2022 +++ src/sys/dev/pci/if_wmvar.h Tue Jun 27 18:32:46 2023 @@ -1,4 +1,4 @@ -/* $NetBSD: if_wmvar.h,v 1.44.4.4 2022/07/11 14:10:18 martin Exp $ */ +/* $NetBSD: if_wmvar.h,v 1.44.4.5 2023/06/27 18:32:46 martin Exp $ */ /* * Copyright (c) 2001, 2002, 2003, 2004 Wasabi Systems, Inc. @@ -213,4 +213,7 @@ typedef enum { #define WM_MDIO_OWNERSHIP_TIMEOUT 10 #define WM_MAX_PLL_TRIES 5 +/* For 80003, ICHs and PCHs */ +#define WM_IS_ICHPCH(x) ((x)->sc_type >= WM_T_80003) + #endif /* _DEV_PCI_IF_WMVAR_H_ */