From nobody Sun Aug 30 01:37:49 2026 X-Original-To: dev-commits-src-all@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4hXZWL2zcpz6ptGx for ; Sun, 30 Aug 2026 01:37:50 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "YR2" (not verified)) by mx1.freebsd.org (Postfix) with ESMTPS id 4hXZWL1t8Pz3sWh for ; Sun, 30 Aug 2026 01:37:50 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1788053870; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=WogwljrHpd48vic5kAgYU1aDcqXX7VTIg8NJIg9PXRY=; b=UI+dejo0CEEoxRDJPcYc1XA9gEfI83ClqRS8PRTq/GW25jAb7cKVlNLFapGd+/Swupnq2Q YCWGfg8gf1o9iBhIhaRZr8bl4+D4Etbv1PeQHJJSfWv8FIodd5Z7haOEihszfX0wJdYAgR GO8yn+aV6qTaZBCVRESEr0/1IWS5EevZLBqHBM81wwhXGaSETQh9xn6dLsfYQmC7B394RJ hsXMQW1h2wV03NRkSVhPAqAjWCC6+1pGRMI9/NL2uzas56IzZfMP/Cjk+jlxpae95YQVjs 46fK0Ma8DtpZRS/o2RF3mKMk+u59JwPk4OzmLxXuxUK5R/gAvtCiET3lqDVMbg== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1788053870; a=rsa-sha256; cv=none; b=v8u3VsaUHkxqX+Uq5pWPoRjoFqgUKW1wpUydrHWp+yS2SSQgEeU8XRsxt8ZBwEVjHZ1g/w lXzfym0LpOJEI5K7UlwKaFUiRNOeC/PKl6KNFu484GdZJrtOoEHfChSf5jh8zgSOMg82RT SlC663Ld0NE9XeDcWckwSBkdm3WwpwcB5pvd90pfuUK13P0QUxQFqmZr9oI9cUEb7MMYYI 3TeZVaYfZOSY8pawuwd3gzfz1JTkmda8bkOpvuWlLoaGZKsRMmIfIkFyUoud+mAvxJPFta SF9ei/2uTJJETIeEwayoN8YInwYcqTMTDFRFB44YBtumkKsn4Pn5XBrAeWHQlg== ARC-Authentication-Results: i=1; mx1.freebsd.org; none ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1788053870; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=WogwljrHpd48vic5kAgYU1aDcqXX7VTIg8NJIg9PXRY=; b=hreBn+vvfjgMTVa6XnT/tOb94Yco+6kjeEA8pMi+q7kUvwX5KJjsqW8HMFpfFxLaqhxzEJ QaVv2sr7HdQLC+PM/RgLeEeQPK1v+g8pccqx5YseV5F+XSsoQb/u12bbnbhG4r+YGzukPn sjyajgYmn6rlxt69TQyOFhfvw7c83r6Q9aDBlyzFz64PU1LT3mPQS+X9azOIysoMUhdgD1 K101gxIJ0iw38PQCl+w42b19Ex0LK+9PmAzaQt28CQxyD7Mkk4CId4gyEyg8UGpTR0EjsY kQp+F5shZEnNjJFwz/rjqy9tL9ZQnS94ciQLlDL5F84Wx0ovsun3SEb31cnGSQ== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) by mxrelay.nyi.freebsd.org (Postfix) with ESMTP id 4hXZWK6jMJz13fH for ; Sun, 30 Aug 2026 01:37:49 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from git (uid 1279) (envelope-from git@FreeBSD.org) id 3e0bf by gitrepo.freebsd.org (DragonFly Mail Agent v0.13+ on gitrepo.freebsd.org); Sun, 30 Aug 2026 01:37:49 +0000 To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org From: Kevin Bowling Subject: git: 0a3c4415a9b6 - stable/15 - e1000: Report 82576 memory ECC errors List-Id: Commit messages for all branches of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-all List-Help: List-Post: List-Subscribe: List-Unsubscribe: X-BeenThere: dev-commits-src-all@freebsd.org Sender: owner-dev-commits-src-all@FreeBSD.org List-Id: List-Post: List-Help: List-Subscribe: List-Unsubscribe: List-Owner: Precedence: list MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: kbowling X-Git-Repository: src X-Git-Refname: refs/heads/stable/15 X-Git-Reftype: branch X-Git-Commit: 0a3c4415a9b6e0c7c7039e84b69fcd95d1124984 Auto-Submitted: auto-generated Date: Sun, 30 Aug 2026 01:37:49 +0000 Message-Id: <6a93896d.3e0bf.6424b6a2@gitrepo.freebsd.org> The branch stable/15 has been updated by kbowling: URL: https://cgit.FreeBSD.org/src/commit/?id=0a3c4415a9b6e0c7c7039e84b69fcd95d1124984 commit 0a3c4415a9b6e0c7c7039e84b69fcd95d1124984 Author: Kevin Bowling AuthorDate: 2026-08-13 23:15:39 +0000 Commit: Kevin Bowling CommitDate: 2026-08-30 01:24:10 +0000 e1000: Report 82576 memory ECC errors 82576 exposes clear-on-read corrected error counters for RX, TX, switch, IPsec, descriptor-handler, PCIe retry, PCIe write, and MSI-X memories. The packet and descriptor memories also count uncorrectable errors. Sample each status register exactly once from the regular hardware statistics update and immediately before handling a memory-error interrupt. Group the counters by packet buffer, descriptor handler, and PCIe region. Skip the absent IPsec block on 82576NS. PRBESTS and PMSIXESTS are shared by both LAN ports. Attribute an indication to whichever attached port samples the clear-on-read register first so it is not counted twice. Hardware validation used an 82576EB revision 1. All nine implemented status registers reported their ECC-enable bit set. The sysctl counters remained clear across interface lifecycle, two-stream line-rate traffic, and NFER and FER cause injections. Each reset preserved the ECC enables while the driver restored PEINDM reactions. ICR cause injection does not corrupt SRAM, and the only documented data injector is specific to the IPsec packet buffer. Exact counter increments for the other memories were therefore validated against the register definitions rather than an injected ECC error. Sponsored by: BBOX.io (cherry picked from commit 17042fd31571c7ceb955570ef43c9921d4a80f21) --- sys/dev/e1000/e1000_defines.h | 5 +++ sys/dev/e1000/e1000_regs.h | 7 ++++ sys/dev/e1000/if_em.c | 83 +++++++++++++++++++++++++++++++++++++++++++ sys/dev/e1000/if_em.h | 1 + 4 files changed, 96 insertions(+) diff --git a/sys/dev/e1000/e1000_defines.h b/sys/dev/e1000/e1000_defines.h index cf23bbde846e..ab53546d5597 100644 --- a/sys/dev/e1000/e1000_defines.h +++ b/sys/dev/e1000/e1000_defines.h @@ -543,6 +543,11 @@ /* 82576NS omits the IPsec key, FIFO, and packet-buffer memories. */ #define E1000_PEIND_82576_IPSEC_MASK 0x40700600 +/* The 82576 clear-on-read ECC status registers share this count layout. */ +#define E1000_ECC_82576_CORR_CNT_MASK 0x000000FF +#define E1000_ECC_82576_UNCORR_CNT_MASK 0x0000FF00 +#define E1000_ECC_82576_UNCORR_CNT_SHIFT 8 + #define E1000_PBECCSTS_I210_ECC_ENABLE 0x00000001 #define E1000_PBECCSTS_I210_CORR_ERR 0x00000004 diff --git a/sys/dev/e1000/e1000_regs.h b/sys/dev/e1000/e1000_regs.h index 5b09183f836d..af5373c19aac 100644 --- a/sys/dev/e1000/e1000_regs.h +++ b/sys/dev/e1000/e1000_regs.h @@ -117,6 +117,13 @@ #define E1000_PEIND 0x01084 /* Parity and ECC Indication - RC */ #define E1000_PEINDM 0x01088 /* Parity and ECC Indication Mask - RW */ #define E1000_PBECCSTS_I210 0x0245C /* I210 Packet Buffer ECC Status */ +#define E1000_SWPBECCSTS_82576 0x0305C /* Switch Packet Buffer ECC Status */ +#define E1000_IPPBECCSTS_82576 0x0B470 /* IPsec Packet Buffer ECC Status */ +#define E1000_RDHESTS_82576 0x025C0 /* Rx Descriptor Handler ECC Status */ +#define E1000_TDHESTS_82576 0x035C0 /* Tx Descriptor Handler ECC Status */ +#define E1000_PRBESTS_82576 0x05BA0 /* PCIe Retry Buffer ECC Status */ +#define E1000_PMSIXESTS_82576 0x05BA8 /* PCIe MSI-X ECC Status */ +#define E1000_PWBESTS_82576 0x05BB0 /* PCIe Write Buffer ECC Status */ #define E1000_IOSFPC 0x00F28 /* TX corrupted data */ #define E1000_EEMNGCTL 0x01010 /* MNG EEprom Control */ #define E1000_EEMNGCTL_I210 0x01010 /* i210 MNG EEprom Mode Control */ diff --git a/sys/dev/e1000/if_em.c b/sys/dev/e1000/if_em.c index 5c5bc8253465..b158540071fd 100644 --- a/sys/dev/e1000/if_em.c +++ b/sys/dev/e1000/if_em.c @@ -1987,6 +1987,58 @@ em_fatal_error_intr_mask(struct e1000_softc *sc) return (mask); } +static void +em_update_82576_ecc_counter(struct e1000_softc *sc, u32 reg, + u64 *corrected, u64 *uncorrected) +{ + u32 status; + + status = E1000_READ_REG(&sc->hw, reg); + *corrected += status & E1000_ECC_82576_CORR_CNT_MASK; + if (uncorrected != NULL) + *uncorrected += + (status & E1000_ECC_82576_UNCORR_CNT_MASK) >> + E1000_ECC_82576_UNCORR_CNT_SHIFT; +} + +static void +em_update_82576_ecc_stats(struct e1000_softc *sc) +{ + + /* + * These counters are clear-on-read. PRBESTS and PMSIXESTS are + * controller-shared, so whichever LAN port samples them first owns + * the software count. + */ + em_update_82576_ecc_counter(sc, E1000_RPBECCSTS, + &sc->corrected_error_packet_buffer_count, + &sc->uncorrected_error_packet_buffer_count); + em_update_82576_ecc_counter(sc, E1000_TPBECCSTS, + &sc->corrected_error_packet_buffer_count, + &sc->uncorrected_error_packet_buffer_count); + em_update_82576_ecc_counter(sc, E1000_SWPBECCSTS_82576, + &sc->corrected_error_packet_buffer_count, + &sc->uncorrected_error_packet_buffer_count); + if (em_82576_has_ipsec(&sc->hw)) + em_update_82576_ecc_counter(sc, E1000_IPPBECCSTS_82576, + &sc->corrected_error_packet_buffer_count, + &sc->uncorrected_error_packet_buffer_count); + + em_update_82576_ecc_counter(sc, E1000_RDHESTS_82576, + &sc->corrected_error_dma_count, + &sc->uncorrected_error_dma_count); + em_update_82576_ecc_counter(sc, E1000_TDHESTS_82576, + &sc->corrected_error_dma_count, + &sc->uncorrected_error_dma_count); + + em_update_82576_ecc_counter(sc, E1000_PRBESTS_82576, + &sc->corrected_error_pcie_retry_count, NULL); + em_update_82576_ecc_counter(sc, E1000_PWBESTS_82576, + &sc->corrected_error_pcie_tx_data_count, NULL); + em_update_82576_ecc_counter(sc, E1000_PMSIXESTS_82576, + &sc->corrected_error_pcie_other_count, NULL); +} + static void em_update_pch_ecc_stats(struct e1000_softc *sc, u32 pbeccsts) { @@ -2165,6 +2217,7 @@ em_handle_fatal_error_admin(struct e1000_softc *sc) sc->fatal_error_pbeccsts); } else if (em_has_82576_memory_errors(&sc->hw)) { peind = sc->fatal_error_peind; + em_update_82576_ecc_stats(sc); reset_required = (sc->fatal_error_icr & E1000_ICR_FER) != 0 || (peind & (E1000_PEIND_82576_FATAL_MASK | @@ -5619,6 +5672,8 @@ em_update_stats_counters(struct e1000_softc *sc) if (em_has_pch_ecc(&sc->hw)) em_update_pch_ecc_stats(sc, E1000_READ_REG(&sc->hw, E1000_PBECCSTS)); + else if (em_has_82576_memory_errors(&sc->hw)) + em_update_82576_ecc_stats(sc); else if (em_has_i350_memory_errors(&sc->hw)) em_update_i350_ecc_stats(sc); else if (em_has_i210_memory_errors(&sc->hw)) @@ -5954,6 +6009,34 @@ em_add_hw_stats(struct e1000_softc *sc) "fatal_unknown", CTLFLAG_RD, &sc->fatal_error_unknown_count, "Fatal memory errors without a reported source"); + SYSCTL_ADD_UQUAD(ctx, memerr_list, OID_AUTO, + "corrected_packet_buffer", CTLFLAG_RD, + &sc->corrected_error_packet_buffer_count, + "Corrected packet and switch-buffer ECC errors"); + SYSCTL_ADD_UQUAD(ctx, memerr_list, OID_AUTO, + "uncorrected_packet_buffer", CTLFLAG_RD, + &sc->uncorrected_error_packet_buffer_count, + "Uncorrected packet and switch-buffer ECC errors"); + SYSCTL_ADD_UQUAD(ctx, memerr_list, OID_AUTO, + "corrected_descriptor_handler", CTLFLAG_RD, + &sc->corrected_error_dma_count, + "Corrected descriptor-handler ECC errors"); + SYSCTL_ADD_UQUAD(ctx, memerr_list, OID_AUTO, + "uncorrected_descriptor_handler", CTLFLAG_RD, + &sc->uncorrected_error_dma_count, + "Uncorrected descriptor-handler ECC errors"); + SYSCTL_ADD_UQUAD(ctx, memerr_list, OID_AUTO, + "corrected_pcie_write_buffer", CTLFLAG_RD, + &sc->corrected_error_pcie_tx_data_count, + "Corrected PCIe write-buffer ECC errors"); + SYSCTL_ADD_UQUAD(ctx, memerr_list, OID_AUTO, + "corrected_pcie_retry_buffer", CTLFLAG_RD, + &sc->corrected_error_pcie_retry_count, + "Corrected controller-shared PCIe retry-buffer errors"); + SYSCTL_ADD_UQUAD(ctx, memerr_list, OID_AUTO, + "corrected_pcie_msix", CTLFLAG_RD, + &sc->corrected_error_pcie_other_count, + "Corrected controller-shared PCIe MSI-X errors"); } else { SYSCTL_ADD_UQUAD(ctx, memerr_list, OID_AUTO, "fatal_lan", CTLFLAG_RD, diff --git a/sys/dev/e1000/if_em.h b/sys/dev/e1000/if_em.h index 219ebe7e7414..62e783307b59 100644 --- a/sys/dev/e1000/if_em.h +++ b/sys/dev/e1000/if_em.h @@ -638,6 +638,7 @@ struct e1000_softc { u64 corrected_error_pcie_other_count; u64 corrected_error_packet_buffer_count; u64 uncorrected_error_packet_buffer_count; + u64 uncorrected_error_dma_count; u64 que_mask;