From nobody Sat Sep 12 01:44:26 2026 X-Original-To: dev-commits-src-branches@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 4hhZ2y1d9wz6rhhn for ; Sat, 12 Sep 2026 01:44:26 +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 4hhZ2y17ycz3LfC for ; Sat, 12 Sep 2026 01:44:26 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1789177466; 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=yAfZIT91wdCA75lecqTl59cbZSD3wG0mzC4NLI1RXR4=; b=udCJciuPhjeJS4efbeBTB5WifLGkumJbqK0BhRpB2+LmkYT58WvlRTlIK5Qf515n8CqagX c5z8c80XXy/CJoidpjl+DkDpCgVO7Ppu699e1vb61zafcMuC799JRCOgCz96yCecKSFpjm e/WlqwrGo3a+7rDvOd0zFSoukhnJ7/TOCV3W9LHhLlfOBYc4Lj1/lk7fu8XYfx56GdyBU+ 0cCxEvW0ZMQ10rPx4Bv60QA/WRXkZ3zqP4NUMmM4tUlRoF26cvjq00rcIJBwdiGZJAqR2Z HMWOlajaRnplIDDZ99ogUqwAB80vGJPZXKi50hfN5t+kMDi3R2ks5/DASPrvSQ== ARC-Seal: i=1; a=rsa-sha256; d=freebsd.org; s=dkim; cv=none; t=1789177466; b=RprwouzUMT28QLj0DvzsJ0lgBAdzeJBVA89TCRJwS1029zQwCU6/KcBwO8jpc48SKIIn8J Lfo9j+ErDITVSLUVS0131XsTG1NsfJYdxzdFzg7fWHzzELHISASo5csKOpOnQm2OyzdY2q 0gG6xIIE4EcTgA013aw/vd2QPoCf/j+c/u/S26SRAE9A01Rl7g16+akZHbeT971u75s+jM 3SsusM+0I07pHjEbPGhwfopUMVLqGQFZDkNXkhsrwKBCmhgo4bkx3tnP8lv9AIbZvbaezT FjPOOYFfOmbP5OgBrjwbowWQox6UfZjkL5kN8+5/V/poTTyweQUbNHA1CIPRsQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1789177466; 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=yAfZIT91wdCA75lecqTl59cbZSD3wG0mzC4NLI1RXR4=; b=dDcxHtt39u+X5A87+HhKFQYYN0f2LdM3iepbMr88lk6OwUnLUZhQxmj24pekxnEvhzV+oN YNtEpcfbiBo7mopiuHJcLftDK9+ngVfkOKvIIk+PWA+rd1YO4+dXGAk6UQXJlRFxtMvows Tjeb3cjTBWST0ZPnAkwn/em/2dU2GUG7xOmYbwYoc3tS37KWv3AsTtqC3uyGj3R8w0/LMl jJ+6duZScl6lDmiM5mwSGN5MxJw1GaQWKuQLZLq0KbWAKnTCVdsQEXj20o2HNJ8gb9WeBJ KFI1CVZuWUbt7VVIBYgN44ZLhFwoBM6PtDAMgxijhVu6n27dXm2ggplZWLqB3A== ARC-Authentication-Results: i=1; mx1.freebsd.org; none Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) by mxrelay.nyi.freebsd.org (Postfix) with ESMTP id 4hhZ2y0BG1zgcH for ; Sat, 12 Sep 2026 01:44:26 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from git (uid 1279) (envelope-from git@FreeBSD.org) id 205f4 by gitrepo.freebsd.org (DragonFly Mail Agent v0.13+ on gitrepo.freebsd.org); Sat, 12 Sep 2026 01:44:26 +0000 To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org From: Kevin Bowling Subject: git: f1275111f157 - stable/15 - e1000: Handle I354 internal memory errors List-Id: Commits to the stable branches of the FreeBSD src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-branches List-Help: List-Post: List-Subscribe: List-Unsubscribe: X-BeenThere: dev-commits-src-branches@freebsd.org Sender: owner-dev-commits-src-branches@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: f1275111f1570bbda46435882e3c9082cfb17a8b Auto-Submitted: auto-generated Date: Sat, 12 Sep 2026 01:44:26 +0000 Message-Id: <6aa4ae7a.205f4.68ca132a@gitrepo.freebsd.org> The branch stable/15 has been updated by kbowling: URL: https://cgit.FreeBSD.org/src/commit/?id=f1275111f1570bbda46435882e3c9082cfb17a8b commit f1275111f1570bbda46435882e3c9082cfb17a8b Author: Kevin Bowling AuthorDate: 2026-08-28 12:37:35 +0000 Commit: Kevin Bowling CommitDate: 2026-09-12 01:43:16 +0000 e1000: Handle I354 internal memory errors The Atom C2000 integrated GbE programming reference documents the I354 internal memory error architecture. It shares the I350 PEIND and ICR.FER routing, DMA and packet-buffer status, LAN parity status, and required reset recovery. Extend the existing I350 recovery and corrected error accounting paths to I354. Keep the PCIe corrected error mask family-specific. C2000 PCIEECCSTS ends at the transmit write-data indication in bit 4 and does not implement the I350 retry buffer indication in bit 5. Do not expose the corresponding retry counter on I354. The PRM overview says a PCIe region failure requires a system reboot, while the individual PCIEERRSTS fields prescribe CTRL.RST followed by port reinitialization. Use the register specific recovery, matching the existing I350 path; failed reinitialization still leaves the port down. This follows sections 5.6 and 6.21 of the Intel Atom Processor C2000 Product Family Integrated GbE Controller Programmer's Reference Manual, document 537426 revision 1.5. Sponsored by: BBOX.io (cherry picked from commit 5b4a7fd9378abba882a87330af31351c6353aea7) --- sys/dev/e1000/e1000_defines.h | 18 ++++++----- sys/dev/e1000/if_em.c | 75 +++++++++++++++++++++++-------------------- 2 files changed, 50 insertions(+), 43 deletions(-) diff --git a/sys/dev/e1000/e1000_defines.h b/sys/dev/e1000/e1000_defines.h index 371fee155dd0..21f54e15b9a7 100644 --- a/sys/dev/e1000/e1000_defines.h +++ b/sys/dev/e1000/e1000_defines.h @@ -535,7 +535,7 @@ #define E1000_ECC_82575_UNCORR_CNT_SHIFT 8 #define E1000_ECC_82575_ENABLE 0x00010000 -/* I350 and I210/I211 memory error status bits. */ +/* I350, I354, and I210/I211 memory error status bits. */ #define E1000_PEIND_LANPORT_PARITY_FATAL 0x00000001 #define E1000_PEIND_MNG_PARITY_FATAL 0x00000002 #define E1000_PEIND_PCIE_PARITY_FATAL 0x00000004 @@ -572,12 +572,14 @@ #define E1000_PBECCSTS_I210_CORR_ERR 0x00000004 #define E1000_PCIEERRSTS_I210_FATAL_MASK 0x00000078 -#define E1000_PCIEERRSTS_I350_FATAL_MASK 0x0000007C +#define E1000_PCIEERRSTS_I350_I354_FATAL_MASK 0x0000007C #define E1000_PCIEECCSTS_TX_WR_DATA 0x00000010 #define E1000_PCIEECCSTS_RETRY_BUF 0x00000020 #define E1000_PCIEECCSTS_I210_CORR_MASK 0x00000030 -#define E1000_PCIEECCSTS_I350_OTHER_MASK 0x0000000F +#define E1000_PCIEECCSTS_I350_I354_OTHER_MASK 0x0000000F #define E1000_PCIEECCSTS_I350_CORR_MASK 0x0000003F +/* I354 has no I350-style PCIe retry-buffer status bit. */ +#define E1000_PCIEECCSTS_I354_CORR_MASK 0x0000001F #define E1000_DTPARS_CORR_MASK 0x0000005B #define E1000_DTPARS_FATAL_MASK 0x00000020 @@ -585,13 +587,13 @@ #define E1000_DRPARS_FATAL_MASK 0x00000002 #define E1000_DDECCS_CORR_MASK 0x0000000F -#define E1000_PBECCSTS_I350_ENABLE_MASK 0x00030000 -#define E1000_PBECCSTS_I350_CORR_MASK 0x14000000 +#define E1000_PBECCSTS_I350_I354_ENABLE_MASK 0x00030000 +#define E1000_PBECCSTS_I350_I354_CORR_MASK 0x14000000 #define E1000_LANPERRSTS_RETX_BUF 0x00000200 -#define E1000_LANPERRSTS_I350_NO_RESET_MASK 0x00008400 -#define E1000_LANPERRSTS_I350_RESET_MASK 0x00007BFE -#define E1000_LANPERRSTS_I350_FATAL_MASK 0x0000FFFE +#define E1000_LANPERRSTS_I350_I354_NO_RESET_MASK 0x00008400 +#define E1000_LANPERRSTS_I350_I354_RESET_MASK 0x00007BFE +#define E1000_LANPERRSTS_I350_I354_FATAL_MASK 0x0000FFFE #define IFS_MAX 80 #define IFS_MIN 40 diff --git a/sys/dev/e1000/if_em.c b/sys/dev/e1000/if_em.c index f524d4d47572..014f8d6e8de6 100644 --- a/sys/dev/e1000/if_em.c +++ b/sys/dev/e1000/if_em.c @@ -2072,10 +2072,11 @@ em_has_i210_memory_errors(const struct e1000_hw *hw) } static bool -em_has_i350_memory_errors(const struct e1000_hw *hw) +em_has_i350_i354_memory_errors(const struct e1000_hw *hw) { - return (hw->mac.type == e1000_i350); + return (hw->mac.type == e1000_i350 || + hw->mac.type == e1000_i354); } static void @@ -2085,7 +2086,7 @@ em_configure_peind_memory_errors(struct e1000_softc *sc) u32 peindm; hw = &sc->hw; - if (!em_has_i350_memory_errors(hw) && + if (!em_has_i350_i354_memory_errors(hw) && !em_has_i210_memory_errors(hw)) return; @@ -2103,7 +2104,7 @@ em_has_peind_memory_errors(const struct e1000_hw *hw) { return (em_has_82580_memory_errors(hw) || - em_has_i350_memory_errors(hw) || + em_has_i350_i354_memory_errors(hw) || em_has_i210_memory_errors(hw)); } @@ -2113,8 +2114,8 @@ em_pcie_fatal_error_mask(const struct e1000_hw *hw) if (em_has_82580_memory_errors(hw)) return (~0U); - if (em_has_i350_memory_errors(hw)) - return (E1000_PCIEERRSTS_I350_FATAL_MASK); + if (em_has_i350_i354_memory_errors(hw)) + return (E1000_PCIEERRSTS_I350_I354_FATAL_MASK); if (em_has_i210_memory_errors(hw)) return (E1000_PCIEERRSTS_I210_FATAL_MASK); return (0); @@ -2301,10 +2302,10 @@ em_update_i210_ecc_stats(struct e1000_softc *sc) } static void -em_update_i350_ecc_stats(struct e1000_softc *sc) +em_update_i350_i354_ecc_stats(struct e1000_softc *sc) { struct e1000_hw *hw; - u32 pbeccsts, status; + u32 pbeccsts, pcieecc_mask, status; hw = &sc->hw; status = E1000_READ_REG(hw, E1000_DTPARS) & @@ -2327,31 +2328,33 @@ em_update_i350_ecc_stats(struct e1000_softc *sc) } pbeccsts = E1000_READ_REG(hw, E1000_RPBECCSTS); - status = pbeccsts & E1000_PBECCSTS_I350_CORR_MASK; + status = pbeccsts & E1000_PBECCSTS_I350_I354_CORR_MASK; if (status != 0) { sc->corrected_error_packet_buffer_count += bitcount32(status); /* Preserve the enable bits while clearing RW1C status. */ E1000_WRITE_REG(hw, E1000_RPBECCSTS, - pbeccsts & (E1000_PBECCSTS_I350_ENABLE_MASK | - E1000_PBECCSTS_I350_CORR_MASK)); + pbeccsts & (E1000_PBECCSTS_I350_I354_ENABLE_MASK | + E1000_PBECCSTS_I350_I354_CORR_MASK)); } pbeccsts = E1000_READ_REG(hw, E1000_TPBECCSTS); - status = pbeccsts & E1000_PBECCSTS_I350_CORR_MASK; + status = pbeccsts & E1000_PBECCSTS_I350_I354_CORR_MASK; if (status != 0) { sc->corrected_error_packet_buffer_count += bitcount32(status); E1000_WRITE_REG(hw, E1000_TPBECCSTS, - pbeccsts & (E1000_PBECCSTS_I350_ENABLE_MASK | - E1000_PBECCSTS_I350_CORR_MASK)); + pbeccsts & (E1000_PBECCSTS_I350_I354_ENABLE_MASK | + E1000_PBECCSTS_I350_I354_CORR_MASK)); } - status = E1000_READ_REG(hw, E1000_PCIEECCSTS) & + pcieecc_mask = hw->mac.type == e1000_i354 ? + E1000_PCIEECCSTS_I354_CORR_MASK : E1000_PCIEECCSTS_I350_CORR_MASK; + status = E1000_READ_REG(hw, E1000_PCIEECCSTS) & pcieecc_mask; if (status & E1000_PCIEECCSTS_TX_WR_DATA) sc->corrected_error_pcie_tx_data_count++; if (status & E1000_PCIEECCSTS_RETRY_BUF) sc->corrected_error_pcie_retry_count++; sc->corrected_error_pcie_other_count += bitcount32(status & - E1000_PCIEECCSTS_I350_OTHER_MASK); + E1000_PCIEECCSTS_I350_I354_OTHER_MASK); if (status != 0) E1000_WRITE_REG(hw, E1000_PCIEECCSTS, status); } @@ -2410,13 +2413,13 @@ em_handle_fatal_error_intr(struct e1000_softc *sc, u32 icr) E1000_DDPARS_82580); lanerr = E1000_READ_REG(hw, E1000_LANPERRSTS) & E1000_LANPERRSTS_82580_ERROR_MASK; - } else if (em_has_i350_memory_errors(hw)) { + } else if (em_has_i350_i354_memory_errors(hw)) { dma_tx = E1000_READ_REG(hw, E1000_DTPARS) & E1000_DTPARS_FATAL_MASK; dma_rx = E1000_READ_REG(hw, E1000_DRPARS) & E1000_DRPARS_FATAL_MASK; lanerr = E1000_READ_REG(hw, E1000_LANPERRSTS) & - E1000_LANPERRSTS_I350_FATAL_MASK; + E1000_LANPERRSTS_I350_I354_FATAL_MASK; } else { dma_tx = 0; dma_rx = 0; @@ -2548,19 +2551,19 @@ em_handle_fatal_error_admin(struct e1000_softc *sc) if (peind == 0) reset_required = true; if (peind & E1000_PEIND_LANPORT_PARITY_FATAL) { - if (!em_has_i350_memory_errors(&sc->hw) || + if (!em_has_i350_i354_memory_errors(&sc->hw) || sc->fatal_error_lan == 0 || (sc->fatal_error_lan & - E1000_LANPERRSTS_I350_RESET_MASK) != 0) + E1000_LANPERRSTS_I350_I354_RESET_MASK) != 0) reset_required = true; } /* Management-memory recovery belongs to management firmware. */ if (!reset_required) { - if (em_has_i350_memory_errors(&sc->hw) && + if (em_has_i350_i354_memory_errors(&sc->hw) && sc->fatal_error_lan != 0) E1000_WRITE_REG(&sc->hw, E1000_LANPERRSTS, sc->fatal_error_lan & - E1000_LANPERRSTS_I350_NO_RESET_MASK); + E1000_LANPERRSTS_I350_I354_NO_RESET_MASK); sc->fatal_error_peind = 0; sc->fatal_error_pcie = 0; sc->fatal_error_pcie_ecc = 0; @@ -2586,11 +2589,11 @@ em_handle_fatal_error_admin(struct e1000_softc *sc) } /* - * A PCIe-region parity failure stops PCIe and DMA traffic. I350, I210, and - * I211 require a port reset before master disable in this case. 82580 stops - * PCIe traffic for a fatal error in any host-owned region, so use the same - * order for every 82580 recovery. This differs from the normal reset path, - * which disables the bus master first. + * A PCIe-region parity failure stops PCIe and DMA traffic. I350, I354, + * I210, and I211 require a port reset before master disable in this case. + * 82580 stops PCIe traffic for a fatal error in any host-owned region, so use + * the same order for every 82580 recovery. This differs from the normal + * reset path, which disables the bus master first. * * Indications that relatch after admin accounting are discarded during * reset; sticky bits cannot distinguish them from the saved event. @@ -2716,7 +2719,7 @@ em_finish_fatal_error_reset(struct e1000_softc *sc) em_pcie_fatal_error_mask(hw)); if (pcieerr != 0) E1000_WRITE_REG(hw, E1000_PCIEERRSTS, pcieerr); - if (em_has_i350_memory_errors(hw)) { + if (em_has_i350_i354_memory_errors(hw)) { dma_tx = sc->fatal_error_dma_tx | (E1000_READ_REG(hw, E1000_DTPARS) & E1000_DTPARS_FATAL_MASK); @@ -2729,7 +2732,7 @@ em_finish_fatal_error_reset(struct e1000_softc *sc) E1000_WRITE_REG(hw, E1000_DRPARS, dma_rx); lanerr = sc->fatal_error_lan | (E1000_READ_REG(hw, E1000_LANPERRSTS) & - E1000_LANPERRSTS_I350_FATAL_MASK); + E1000_LANPERRSTS_I350_I354_FATAL_MASK); } else { lanerr = sc->fatal_error_lan | (E1000_READ_REG(hw, E1000_LANPERRSTS) & @@ -6079,8 +6082,8 @@ em_update_stats_counters(struct e1000_softc *sc) E1000_READ_REG(&sc->hw, E1000_RPBECCSTS), E1000_READ_REG(&sc->hw, E1000_TPBECCSTS), E1000_READ_REG(&sc->hw, E1000_PCIEECCSTS)); - else if (em_has_i350_memory_errors(&sc->hw)) - em_update_i350_ecc_stats(sc); + else if (em_has_i350_i354_memory_errors(&sc->hw)) + em_update_i350_i354_ecc_stats(sc); else if (em_has_i210_memory_errors(&sc->hw)) em_update_i210_ecc_stats(sc); } @@ -6519,10 +6522,12 @@ em_add_hw_stats(struct e1000_softc *sc) "corrected_pcie_tx_data", CTLFLAG_RD, &sc->corrected_error_pcie_tx_data_count, "Corrected PCIe transmit-data memory indications"); - SYSCTL_ADD_UQUAD(ctx, memerr_list, OID_AUTO, - "corrected_pcie_retry", CTLFLAG_RD, - &sc->corrected_error_pcie_retry_count, - "Corrected PCIe retry-buffer memory indications"); + if (sc->hw.mac.type == e1000_i350) + SYSCTL_ADD_UQUAD(ctx, memerr_list, OID_AUTO, + "corrected_pcie_retry", CTLFLAG_RD, + &sc->corrected_error_pcie_retry_count, + "Corrected PCIe retry-buffer memory " + "indications"); SYSCTL_ADD_UQUAD(ctx, memerr_list, OID_AUTO, "corrected_pcie_other", CTLFLAG_RD, &sc->corrected_error_pcie_other_count,