Module Name: src Committed By: martin Date: Thu Jun 22 08:14:35 UTC 2023
Modified Files: src/sys/dev/pci [netbsd-10]: if_wm.c if_wmreg.h if_wmvar.h Log Message: Pull up following revision(s) (requested by msaitoh in ticket #213): sys/dev/pci/if_wm.c: revision 1.770 sys/dev/pci/if_wm.c: revision 1.771 sys/dev/pci/if_wm.c: revision 1.772 sys/dev/pci/if_wm.c: revision 1.773 sys/dev/pci/if_wm.c: revision 1.774 sys/dev/pci/if_wm.c: revision 1.775 sys/dev/pci/if_wm.c: revision 1.776 sys/dev/pci/if_wmreg.h: revision 1.129 sys/dev/pci/if_wm.c: revision 1.777 sys/dev/pci/if_wm.c: revision 1.778 sys/dev/pci/if_wmvar.h: revision 1.49 sys/dev/pci/if_wm.c: revision 1.779 sys/dev/pci/if_wm.c: revision 1.768 sys/dev/pci/if_wm.c: revision 1.769 sys/dev/pci/if_wmreg.h: revision 1.130 sys/dev/pci/if_wm.c: revision 1.780 sys/dev/pci/if_wm.c: revision 1.781 Count some 64bit counters correctly. - Fix calculation of GORC, GOTC, TOR and TOT counters correctly. - Found by knakahara. Add note for the TORL register. The TOR register includes error, flow control and broadcast rejected. Sort lines. No functional change. Rearrange the order of the registers so that they are roughly in ascending order. Sort lines. No functional change. 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. The transmit underrun bit in the transmit status filed is only for 82544 (and older?), so don't use the counter for newer chips. The bit is reserved for newer chips, but the bit sometimes set on 82575 at least. Don't add "Count" for event counter's description. Some statistics registers were replaced with new counters. - 0x403c was CEXTERR(Carrier Extension Error). 82575 and newer except 80003, ICHs and PCHs have HTDPMC(Host Tx Discarded Packets by MAC). I don't really know for 82575. The 82575 datasheet say nothing about it. - The following two are changed for circuit breaker. Only 82576's datasheet describes abut it, so the registers might be only for 82576. Use those registers for 82575 and newer except 80003, ICHs and PCHs just in case. - 0x40fc was TSCTFC(TCP Segmentation Context Tx Fail). It was replaced by the CBRMPC(Circuit Breaker Rx Manageability Packet) register. - 0x4124 was ICRXOC(Interrupt Cause Receiver Overrun). It was replaced by the HTCBDPC(Host Tx Circuit Breaker Dropped Packet) register. - From 0x4104 to 0x4124: - For 0x4124, 82575's datasheet says it's not changed(ICRXOC). I don't know if it's correct. We use new HTCBDPC register for 82575. - 82576 and newer changed the meaning. - I don't know for 80003, ICHs and PCHs. Don't count those registers. At least, those registers in PCH2 and PCH_CNP are all zero. Add some new event counters. Add the following counters for 82575 and newer except 80003, ICHs and PCHs: - Only 82576 document describes about the circuit breaker, so the following two might be only for 82575: - Circuit Breaker TX Manageability Packet - Circuit Breaker RX Dropped Packet - 82575's document doesn't describe the following two, but we can see the same value as GO{T,R}C have: - Host Good Octets RX - Host Good Octets TX - 82575's document doesn't describe the LENERRS (Length Errors) counter. I don't know if it has. - Perhaps Non-SerDes/SGMII devices don't have SCVPC (SerDes/SGMII Code Violation Packet) register. We don't care if it's SerDes/SGMII or not for now. - HRMPC (Header Redirection Missed Packet) appears only once in 8257[56]'s datasheet. FreeBSD's igb counts it, so we do, too. - Count the following two for I350 and newer. I don't know if PCHs have: - EEE TX LPI - EEE RX LPI Move statistics updating code from wm_tick() to new wm_update_stats(). - To reuse. - No functional change. Add SOICZIFDATA (ifconfig -z) support for evcnt(9). First update the statistics data, then clear the event counters, and finally copy and clear if_data via ether_ioctl(). Fix prc511's comment and description. Use WM_IS_ICHPCH(). No functional change. Fix typo. s/ictxact/ictxatc/. No functional change. To generate a diff of this commit: cvs rdiff -u -r1.767 -r1.767.2.1 src/sys/dev/pci/if_wm.c cvs rdiff -u -r1.128 -r1.128.2.1 src/sys/dev/pci/if_wmreg.h cvs rdiff -u -r1.48 -r1.48.4.1 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.767 src/sys/dev/pci/if_wm.c:1.767.2.1 --- src/sys/dev/pci/if_wm.c:1.767 Thu Dec 8 08:14:28 2022 +++ src/sys/dev/pci/if_wm.c Thu Jun 22 08:14:35 2023 @@ -1,4 +1,4 @@ -/* $NetBSD: if_wm.c,v 1.767 2022/12/08 08:14:28 knakahara Exp $ */ +/* $NetBSD: if_wm.c,v 1.767.2.1 2023/06/22 08:14:35 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.767 2022/12/08 08:14:28 knakahara Exp $"); +__KERNEL_RCSID(0, "$NetBSD: if_wm.c,v 1.767.2.1 2023/06/22 08:14:35 martin Exp $"); #ifdef _KERNEL_OPT #include "opt_if_wm.h" @@ -585,10 +585,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 */ @@ -596,15 +596,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 */ @@ -616,44 +630,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; @@ -725,25 +757,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 */ @@ -852,6 +892,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); @@ -3199,6 +3241,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"); @@ -3212,28 +3301,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, @@ -3242,8 +3309,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, @@ -3266,6 +3350,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, @@ -3274,22 +3366,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, @@ -3302,41 +3378,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, @@ -3345,6 +3457,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 */ @@ -3393,6 +3509,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); @@ -3401,23 +3542,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); @@ -3429,48 +3568,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 */ @@ -3744,8 +3891,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; mutex_enter(sc->sc_core_lock); @@ -3754,120 +3899,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)); - } - net_stat_ref_t nsr = IF_STAT_GETREF(ifp); - if_statadd_ref(nsr, if_collisions, colc); - if_statadd_ref(nsr, 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. - */ - if_statadd_ref(nsr, if_iqdrops, mpc); - IF_STAT_PUTREF(ifp); + wm_update_stats(sc); if (sc->sc_flags & WM_F_HAS_MII) mii_tick(&sc->sc_mii); @@ -4005,6 +4037,18 @@ wm_ioctl(struct ifnet *ifp, u_long cmd, KASSERT(IFNET_LOCKED(ifp)); } + if (cmd == SIOCZIFDATA) { + /* + * Special handling for SIOCZIFDATA. + * Copying and clearing the if_data structure is done with + * ether_ioctl() below. + */ + mutex_enter(sc->sc_core_lock); + wm_update_stats(sc); + wm_clear_evcnt(sc); + mutex_exit(sc->sc_core_lock); + } + switch (cmd) { case SIOCSIFMEDIA: mutex_enter(sc->sc_core_lock); @@ -4970,7 +5014,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)); @@ -6502,6 +6546,350 @@ 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_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)); + } + net_stat_ref_t nsr = IF_STAT_GETREF(ifp); + if_statadd_ref(nsr, if_collisions, colc); + if_statadd_ref(nsr, 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. + */ + if_statadd_ref(nsr, if_iqdrops, mpc); + IF_STAT_PUTREF(ifp); +} + +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] * @@ -7669,7 +8057,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 */ @@ -7790,7 +8180,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 */ @@ -9412,14 +9803,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.128 src/sys/dev/pci/if_wmreg.h:1.128.2.1 --- src/sys/dev/pci/if_wmreg.h:1.128 Wed Oct 19 06:37:25 2022 +++ src/sys/dev/pci/if_wmreg.h Thu Jun 22 08:14:35 2023 @@ -1,4 +1,4 @@ -/* $NetBSD: if_wmreg.h,v 1.128 2022/10/19 06:37:25 msaitoh Exp $ */ +/* $NetBSD: if_wmreg.h,v 1.128.2.1 2023/06/22 08:14:35 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.48 src/sys/dev/pci/if_wmvar.h:1.48.4.1 --- src/sys/dev/pci/if_wmvar.h:1.48 Mon Dec 20 12:50:35 2021 +++ src/sys/dev/pci/if_wmvar.h Thu Jun 22 08:14:35 2023 @@ -1,4 +1,4 @@ -/* $NetBSD: if_wmvar.h,v 1.48 2021/12/20 12:50:35 skrll Exp $ */ +/* $NetBSD: if_wmvar.h,v 1.48.4.1 2023/06/22 08:14:35 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_ */