From nobody Sat Aug 29 02:02:53 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 4hWz6q12ctz6q2SZ for ; Sat, 29 Aug 2026 02:02:59 +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 4hWz6p69S2z3pRW for ; Sat, 29 Aug 2026 02:02:58 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1787968978; 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=tkHHX7n/r9fFmv8FYfH8qf4FKdOufS5LEt5GYAKvb/0=; b=f8xwJJu3APYWDQ0o7Eu25hzOcMnb7K/51pacd15dKeUJspeGHotlxjcX5sJ8KRvFw077H0 8mrEQH00O3XlLdA7zgOqmAsefFJsERqGtq7+DWqmLExLUpIhgyq1zQI+xnwfM/tNIhj7Ta vJwR23DMhp76gTV7eALOWIZGfiOut2NsYtDk+M19JGrzjTR4biiNK3kXWvjP8nQL7DLCIG Z9GbuCtDN2Y1cLAFKWfsE3QtUJnTLh5T6enkKNlfEuruJj1musbyBCBbBeX+VlKnK2KCpx INqJpNFBbnVZ+h2nAZ5Gkp3d/1t6IGAaEiQJVd6jAwJqByVix7uFCiYUaYktfg== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1787968978; a=rsa-sha256; cv=none; b=lSFxDk2fHJWEGH54l+CH/icPb3A9gPNciSCjEGCdgH7/LBwX6FUlzPm6nc9bjQcHjDY2wb EO7p1DidS+OW7d9t2+35Xdav8rPaSxUhT6Fe23sBc1bbWum2uiDlJ3v+39NadnBUEsZmxP hY5c73/1eZE0cZ1OylUNIxhzXYRmq7xpvrI0JxqUyHmrNc65dQ/agmJkvXJXkoID9Ulewx E0mQiNcPTxUip996IW49tE5nSU32lq3810nFM31JD39WRkJHBQt77PqqANl76Dvgx+VbuV RPmQQxQbtXHNNdq6Nse5i2pUo/gGRyjMMKcr6CygZ5d1a6Y3MLpYuHTI5iA5tA== 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=1787968978; 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=tkHHX7n/r9fFmv8FYfH8qf4FKdOufS5LEt5GYAKvb/0=; b=Qe1+Lw/YcTrMjkJO153kohcSi79zzNfq7h8IpJZHeM+NAeUmc5sJoETxeWC9SELBiSwQ3U QkUE5qLQNXsNGLLhQGcaJ66GkCn3/QfkaFLhq21yXKtOxdGNA+sp3XTCc2qW27zdmmHdj+ Va3Mbvq9OyOsFFcY3ouQIsjX2x2TrlngwkPuoKR6XhX4COmd4w6j1/MiUeRQZ6M7Am+VSJ N9QHKi732oE8NqJjE1S64V99QrUdkazXERBVmkmIrz4n2Dm8y46/DfuwqoUtFe4T+8Jnod Qnd9krSYpjKVGg6Ocac1pLS8z0QEVTBtqzJrNdW+HSllVuz9Rz0xaz0pHvrazQ== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) by mxrelay.nyi.freebsd.org (Postfix) with ESMTP id 4hWz6p2BL7z4tH for ; Sat, 29 Aug 2026 02:02:58 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from git (uid 1279) (envelope-from git@FreeBSD.org) id 37524 by gitrepo.freebsd.org (DragonFly Mail Agent v0.13+ on gitrepo.freebsd.org); Sat, 29 Aug 2026 02:02:53 +0000 To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: Kevin Bowling Subject: git: 5b4a7fd9378a - main - e1000: Handle I354 internal memory 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/main X-Git-Reftype: branch X-Git-Commit: 5b4a7fd9378abba882a87330af31351c6353aea7 Auto-Submitted: auto-generated Date: Sat, 29 Aug 2026 02:02:53 +0000 Message-Id: <6a923dcd.37524.6db584b3@gitrepo.freebsd.org> The branch main has been updated by kbowling: URL: https://cgit.FreeBSD.org/src/commit/?id=5b4a7fd9378abba882a87330af31351c6353aea7 commit 5b4a7fd9378abba882a87330af31351c6353aea7 Author: Kevin Bowling AuthorDate: 2026-08-28 12:37:35 +0000 Commit: Kevin Bowling CommitDate: 2026-08-29 02:01:59 +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. MFC after: 2 weeks Sponsored by: BBOX.io --- 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 082549767315..de1b513f1040 100644 --- a/sys/dev/e1000/if_em.c +++ b/sys/dev/e1000/if_em.c @@ -2360,10 +2360,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 @@ -2373,7 +2374,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; @@ -2391,7 +2392,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)); } @@ -2401,8 +2402,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); @@ -2589,10 +2590,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) & @@ -2615,31 +2616,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); } @@ -2698,13 +2701,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; @@ -2836,19 +2839,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; @@ -2874,11 +2877,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. @@ -3004,7 +3007,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); @@ -3017,7 +3020,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) & @@ -6631,8 +6634,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); } @@ -7180,10 +7183,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,