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,
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.