From nobody Sat Aug 8 00:38:12 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 4hH2Dj2Vq0z6mYNR for ; Sat, 08 Aug 2026 00:38:13 +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 "YR1" (not verified)) by mx1.freebsd.org (Postfix) with ESMTPS id 4hH2Dh6s5Kz3m8Z for ; Sat, 08 Aug 2026 00:38:12 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1786149493; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=UrYei/wbSffE81dgYSqTb2Dch+ZELGJqiU3d7AoCOpM=; b=vmsjERIrX2YVlm6PGLuWvDN8waKZPMYz5Kzc1XkVyzD3b7XTOkHwExKcZU2RYzNNSyMElT OXmChKzeQm96qKblIVzixsvdyZjpWHPecmeG7piEcbkdpHzJjP5qGuMcHfrH8uzy6goPWT uKt0qyZjtwDiSoYotmyti53wUM/roGOfhcfi4dn/aO7oUCkIvRknAWw/5km5/AVcPUTpTK xAE1dk1aYjH7JpQyMf6MGmF8dlCbd5st7ywLu/glv8qALuxsE6fmWhF6NDxd9foL+2zEHE MLni+J7B7TcSOHZLxEwJvp+2IcvrF6x16ZliHA/E1BBJsMyhCEbeUWY+jsTMrg== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1786149493; a=rsa-sha256; cv=none; b=wEvadQmutnQYpEw1aSjSnIWRlNMQM+E1tQj/NYriZNpVs8lWeiw77UgPhaGD9En8fLIzy1 Hj+SzmYhm4Sc+yIONUlOglkIO1A6o2u2cy5nRmgMP2uxVHnnwFBZIKtloAIrEfBK7OXl2z cWtzB08L6usAzpnofVx375EiKagoDe0cm01BJmYU0Eb6YELCLkch2QxS+bDJVr1y2bDrCG 9QJSozMXBv7zk2WwrJz3StJw/Z15VkSzcsvo/T4NF1M70g/cNK9n+oSV5RcGu2oQPTir3w fqqo2AzhL0+UfK4GH41fxpdBmCKWGIM8kzBVfq9TFwCSaRNOUyaNKoCIF1X36Q== 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=1786149493; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=UrYei/wbSffE81dgYSqTb2Dch+ZELGJqiU3d7AoCOpM=; b=V+wKyKKSNSg7Dtuvpl4926fQ0ajIyoKtiJaGaVzeJumtOttstjyoknffwbL9mmDRKIanhM 7NonmYZQrQX1XxczfVGW5N1U/JQ4rCJeqjFOe4tYuUb00ex6djpg6l2z0Y4dsAg8TuDZ2G fQ881ipNmpAmD4dDJzcBFah7W+U+zf6jU2M/yknFbIX8TVC8W3rczuAb44XWxOxEKftzSl +eQWWPbif0gvAFHLWYedq39Cql4vYIUZmT1BGDRETJ0XdQ44Mix+0znky8WMEzNo+WzyJa WKtuToP3kmnFry4+w61HOfM5APrjwAKHtxoDgt9RE9E3lWwxwdjvbbvwK7uq4g== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) by mxrelay.nyi.freebsd.org (Postfix) with ESMTP id 4hH2Dh5jq1zrm for ; Sat, 08 Aug 2026 00:38:12 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from git (uid 1279) (envelope-from git@FreeBSD.org) id 3fb07 by gitrepo.freebsd.org (DragonFly Mail Agent v0.13+ on gitrepo.freebsd.org); Sat, 08 Aug 2026 00:38:12 +0000 To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org Cc: Michael Adler From: Kevin Bowling Subject: git: a9d71b76c647 - stable/15 - igc: Disable ASPM L1.2 on I226 to prevent RX stalls 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: a9d71b76c647575c57d1e008b48f6b203ce184ac Auto-Submitted: auto-generated Date: Sat, 08 Aug 2026 00:38:12 +0000 Message-Id: <6a767a74.3fb07.2a9a8bcc@gitrepo.freebsd.org> The branch stable/15 has been updated by kbowling: URL: https://cgit.FreeBSD.org/src/commit/?id=a9d71b76c647575c57d1e008b48f6b203ce184ac commit a9d71b76c647575c57d1e008b48f6b203ce184ac Author: Michael Adler AuthorDate: 2026-07-09 17:02:37 +0000 Commit: Kevin Bowling CommitDate: 2026-08-08 00:33:39 +0000 igc: Disable ASPM L1.2 on I226 to prevent RX stalls I226 parts advertise support for the PCIe L1.2 link substate, but a hardware erratum makes the exit latency from that low-power state longer than the packet buffer can absorb under load. This stalls the inbound packet stream. Disabling ASPM system-wide (BIOS or OS ASPM policy) does not fix it. The L1.2 enable bit must be cleared directly in the device's own PCIe L1 PM extended capability. Add igc_is_device_id_i226() to identify affected parts and igc_disable_broken_aspm_l1_2() to clear the ASPM L1.2 enable bit on attach and after resume, since PCIe config space can be reset across a suspend/resume cycle. Adapted from the Linux igc driver: 0325143b59c6 igc: disable L1.2 PCI-E link substate to avoid performance issue 1468c1f97cf3 igc: fix disabling L1.2 PCI-E link substate on I226 on init Signed-off-by: Michael Adler PR: 279245 Reviewed by: Jim Thompson Pull-Request: https://github.com/freebsd/freebsd-src/pull/2318 (cherry picked from commit 9d30fd353dd3eacb095ce98cb9c91ec015b9af64) --- sys/dev/igc/if_igc.c | 44 ++++++++++++++++++++++++++++++++++++++++++++ sys/dev/igc/igc_base.c | 21 +++++++++++++++++++++ sys/dev/igc/igc_base.h | 1 + 3 files changed, 66 insertions(+) diff --git a/sys/dev/igc/if_igc.c b/sys/dev/igc/if_igc.c index df82d5a4e073..c015bf1f3c52 100644 --- a/sys/dev/igc/if_igc.c +++ b/sys/dev/igc/if_igc.c @@ -115,6 +115,7 @@ static bool igc_if_needs_restart(if_ctx_t, enum iflib_restart_event); static void igc_identify_hardware(if_ctx_t); static int igc_allocate_pci_resources(if_ctx_t); static void igc_free_pci_resources(if_ctx_t); +static void igc_disable_broken_aspm_l1_2(if_ctx_t); static void igc_reset(if_ctx_t); static int igc_setup_interface(if_ctx_t); static int igc_setup_msix(if_ctx_t); @@ -555,6 +556,14 @@ igc_if_attach_pre(if_ctx_t ctx) /* Determine hardware and mac info */ igc_identify_hardware(ctx); + /* + * I226 parts have an erratum where the PCIe ASPM L1.2 exit + * latency can exceed what the packet buffer can absorb under + * load, stalling the inbound packet stream. Disable ASPM L1.2 + * on the device to work around it. + */ + igc_disable_broken_aspm_l1_2(ctx); + scctx->isc_tx_nsegments = IGC_MAX_SCATTER; scctx->isc_nrxqsets_max = scctx->isc_ntxqsets_max = igc_set_num_queues(ctx); @@ -797,6 +806,12 @@ igc_if_suspend(if_ctx_t ctx) static int igc_if_resume(if_ctx_t ctx) { + /* + * PCIe config space, and with it ASPM L1.2, may have been reset + * across the suspend/resume cycle. + */ + igc_disable_broken_aspm_l1_2(ctx); + igc_if_init(ctx); return(0); @@ -1498,6 +1513,35 @@ igc_identify_hardware(if_ctx_t ctx) } } +/********************************************************************* + * + * I226 devices advertise support for the PCIe L1.2 link substate, but + * due to a hardware erratum the exit latency from that low-power state + * can exceed what the packet buffer can tolerate under load, which + * stalls the inbound packet stream. Disabling ASPM L1.2 on the device + * itself (as opposed to disabling ASPM/power management in the BIOS or + * at the OS level) works around the issue. + * + **********************************************************************/ +static void +igc_disable_broken_aspm_l1_2(if_ctx_t ctx) +{ + device_t dev = iflib_get_dev(ctx); + struct igc_softc *sc = iflib_get_softc(ctx); + int cap; + uint32_t ctl1; + + if (!igc_is_device_id_i226(&sc->hw)) + return; + + if (pci_find_extcap(dev, PCIZ_L1PM, &cap) != 0) + return; + + ctl1 = pci_read_config(dev, cap + PCIR_L1PM_CTL1, 4); + ctl1 &= ~PCIM_L1PM_CTL1_ASPM_L1_2; + pci_write_config(dev, cap + PCIR_L1PM_CTL1, ctl1, 4); +} + static int igc_allocate_pci_resources(if_ctx_t ctx) { diff --git a/sys/dev/igc/igc_base.c b/sys/dev/igc/igc_base.c index de48303a9c7c..181fd7025ba3 100644 --- a/sys/dev/igc/igc_base.c +++ b/sys/dev/igc/igc_base.c @@ -184,3 +184,24 @@ void igc_rx_fifo_flush_base(struct igc_hw *hw) IGC_READ_REG(hw, IGC_RNBC); IGC_READ_REG(hw, IGC_MPC); } + +/** + * igc_is_device_id_i226 - Check whether the device is I226 silicon + * @hw: pointer to the HW structure + * + * I225 and I226 share the same mac.type, so this checks the PCI + * device ID directly to distinguish I226 parts, e.g. for erratum + * workarounds that apply only to that silicon. + **/ +bool igc_is_device_id_i226(struct igc_hw *hw) +{ + switch (hw->device_id) { + case IGC_DEV_ID_I226_LM: + case IGC_DEV_ID_I226_V: + case IGC_DEV_ID_I226_K: + case IGC_DEV_ID_I226_IT: + return true; + default: + return false; + } +} diff --git a/sys/dev/igc/igc_base.h b/sys/dev/igc/igc_base.h index c986ecc840e3..91cb602f809d 100644 --- a/sys/dev/igc/igc_base.h +++ b/sys/dev/igc/igc_base.h @@ -13,6 +13,7 @@ void igc_power_down_phy_copper_base(struct igc_hw *hw); extern void igc_rx_fifo_flush_base(struct igc_hw *hw); s32 igc_acquire_phy_base(struct igc_hw *hw); void igc_release_phy_base(struct igc_hw *hw); +bool igc_is_device_id_i226(struct igc_hw *hw); /* Transmit Descriptor - Advanced */ union igc_adv_tx_desc {