git: aec0f1b85b54 - main - e1000: Report 82571 packet buffer ECC errors
Kevin Bowling <[email protected]>
| Newsgroups | gmane.os.freebsd.devel.cvs.src |
|---|---|
| Message-ID | <6a869220.3f3ac.3d352bc1__453.4831432224$1787204145$gmane$org@gitrepo.freebsd.org> |
The branch main has been updated by kbowling: URL: https://cgit.FreeBSD.org/src/commit/?id=aec0f1b85b54d14819747ed3364f366d21e76d88 commit aec0f1b85b54d14819747ed3364f366d21e76d88 Author: Kevin Bowling <[email protected]> AuthorDate: 2026-08-16 07:11:57 +0000 Commit: Kevin Bowling <[email protected]> CommitDate: 2026-08-20 05:33:54 +0000 e1000: Report 82571 packet buffer ECC errors The 82571 PBA_ECC register contains a 12-bit count of packet buffer ECC detections. The shared code enables single-bit correction, but neither FreeBSD nor the DPDK base driver consumes the counter. Sample it with the ordinary statistics timer, accumulate the value under dev.em.N.memory_errors.detected_packet_buffer, and clear the hardware counter while preserving correction and reserved register state. Do not enable its shared interrupt: the register does not distinguish corrected from uncorrectable events and does not provide a safe fatal recovery policy. Validated on a dual port 82571EB. Both functions reported zero after a clean boot, and a controlled link down/up cycle left the counter at zero while the management link recovered at 1 Gb/s without issue. MFC after: 2 weeks Sponsored by: BBOX.io --- sys/dev/e1000/if_em.c | 54 ++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 47 insertions(+), 7 deletions(-) diff --git a/sys/dev/e1000/if_em.c b/sys/dev/e1000/if_em.c index f07f75100650..7e312399b132 100644 --- a/sys/dev/e1000/if_em.c +++ b/sys/dev/e1000/if_em.c @@ -2189,6 +2189,13 @@ em_has_pch_ecc(const struct e1000_hw *hw) hw->mac.type < e1000_82575); } +static bool +em_has_82571_ecc_stats(const struct e1000_hw *hw) +{ + + return (hw->mac.type == e1000_82571); +} + static bool em_has_82575_memory_errors(const struct e1000_hw *hw) { @@ -2335,6 +2342,13 @@ em_has_memory_errors(const struct e1000_hw *hw) return (em_memory_error_intr_mask(hw) != 0); } +static bool +em_has_memory_error_stats(const struct e1000_hw *hw) +{ + + return (em_has_82571_ecc_stats(hw) || em_has_memory_errors(hw)); +} + static u32 em_fatal_error_intr_mask(struct e1000_softc *sc) { @@ -2429,6 +2443,24 @@ em_update_pch_ecc_stats(struct e1000_softc *sc, u32 pbeccsts) E1000_PBECCSTS_UNCORR_ERR_CNT_SHIFT; } +static void +em_update_82571_ecc_stats(struct e1000_softc *sc) +{ + struct e1000_hw *hw; + u32 count, pba_ecc; + + hw = &sc->hw; + pba_ecc = E1000_READ_REG(hw, E1000_PBA_ECC); + count = (pba_ecc & E1000_PBA_ECC_COUNTER_MASK) >> + E1000_PBA_ECC_COUNTER_SHIFT; + if (count == 0) + return; + sc->corrected_error_packet_buffer_count += count; + /* Preserve correction and reserved state while clearing statistics. */ + E1000_WRITE_REG(hw, E1000_PBA_ECC, + pba_ecc | E1000_PBA_ECC_STAT_CLR); +} + static void em_update_i210_ecc_stats(struct e1000_softc *sc) { @@ -6380,7 +6412,9 @@ em_update_stats_counters(struct e1000_softc *sc) E1000_READ_REG(&sc->hw, E1000_TSCTFC); } - if (em_has_pch_ecc(&sc->hw)) + if (em_has_82571_ecc_stats(&sc->hw)) + em_update_82571_ecc_stats(sc); + else if (em_has_pch_ecc(&sc->hw)) em_update_pch_ecc_stats(sc, E1000_READ_REG(&sc->hw, E1000_PBECCSTS)); else if (em_has_82575_memory_errors(&sc->hw)) @@ -6806,7 +6840,7 @@ em_add_hw_stats(struct e1000_softc *sc) SYSCTL_ADD_UQUAD(ctx, eee_list, OID_AUTO, "rx_lpi_count", CTLFLAG_RD, &stats->rlpic, "RX LPI event count"); } - if (em_has_memory_errors(&sc->hw)) { + if (em_has_memory_error_stats(&sc->hw)) { struct sysctl_oid *memerr_node; struct sysctl_oid_list *memerr_list; @@ -6814,11 +6848,17 @@ em_add_hw_stats(struct e1000_softc *sc) "memory_errors", CTLFLAG_RD | CTLFLAG_MPSAFE, NULL, "Internal memory error indications"); memerr_list = SYSCTL_CHILDREN(memerr_node); - SYSCTL_ADD_UQUAD(ctx, memerr_list, OID_AUTO, - "fatal_resets", CTLFLAG_RD, - &sc->fatal_error_reset_count, - "Resets requested for fatal internal memory errors"); - if (em_has_pch_ecc(&sc->hw)) { + if (em_has_memory_errors(&sc->hw)) + SYSCTL_ADD_UQUAD(ctx, memerr_list, OID_AUTO, + "fatal_resets", CTLFLAG_RD, + &sc->fatal_error_reset_count, + "Resets requested for fatal internal memory errors"); + if (em_has_82571_ecc_stats(&sc->hw)) { + SYSCTL_ADD_UQUAD(ctx, memerr_list, OID_AUTO, + "detected_packet_buffer", CTLFLAG_RD, + &sc->corrected_error_packet_buffer_count, + "Detected packet-buffer ECC errors"); + } else if (em_has_pch_ecc(&sc->hw)) { SYSCTL_ADD_UQUAD(ctx, memerr_list, OID_AUTO, "corrected_packet_buffer", CTLFLAG_RD, &sc->corrected_error_packet_buffer_count,