From nobody Sun Oct 11 00:50:18 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 4j2MT61t5vz6w767 for ; Sun, 11 Oct 2026 00:50:18 +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 4j2MT61B9wz4vMX for ; Sun, 11 Oct 2026 00:50:18 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1791679818; 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=WgQYaTVxeKSFkmhmzKhMR+pOk3SzaKvBKLmQaNxkdMw=; b=Zm4x9BVLu6ec+i7YlNn2GgvvLb4GvLQs+idIArgrgu+1EsDO3Z3Si3EBXLo9qEu9hGJu1N vR83nqfNDPnR89pktiKwBUqYfGXAWYrLmN4r3ch3rOJ9x7PO1tdEcuSk0y/M4s8zE6kZ8D 6nSEJ19FLfYcpENM5jvoH4jj8FeVj7CKUDy0TqetY1L/2LwBQSo/ldqQo0ClLagNxf6jPx FJg4GhMth8tQWLoT0dvltuNUkhlWl/PAAs96Y1D39UvHVOafDXlxv1ZMcFDWlOiG5kKq9H 4WV+MQ0CmYLaeQ2Ak/EOYEzer3oWQr+PuXsgcIVj2zGTZQ5OSKvJilhAAvVl3A== ARC-Seal: i=1; a=rsa-sha256; d=freebsd.org; s=dkim; cv=none; t=1791679818; b=mR+b7JX+R7y5jK8DiXZajpETco6YSEzPNDofSeNEYskPhMh1B0XBbIb97fSTMcPD6wawUh sZ/9SaY1lXpVvr4A7LpHRnG1giGpWVHOHkMzkMn7iQin7RGWw6vTROwIdk4mmBOuOf2evI yXLGAKVXZC21RT1P783YyDpNBssoBco4WDwvoNFTI9k3XfSOmh/D7XKf+3ww0rkFsdIS3S M7ksW4auMhWLPpy+F87JeSVjVkfy8Jnen0eE3feABdVI8UgmxhniRXjAL+0yWAU5zv8nCB Hpxt9493znuzyZ6Ux0Zghl749wApffwA0kniegAsd0mOJQAIZFItjS9C01HOLQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1791679818; 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=WgQYaTVxeKSFkmhmzKhMR+pOk3SzaKvBKLmQaNxkdMw=; b=ZVoMUcPgYaNlhPuCLEQsDhZ4QDF+7lWJT0j8vbRMxJ+3onJM+qrvR1RKvpOgIzYGEhXh9z Ie0L94GHSoieTqvC18VABYAwSG0fjwPulUfye9RveknPESNzw3QvMWX1GLW4U1EQM4RG3D p4NZ5aoztBRVPNaaX9gkqEw92CQIJLAQR+OTljMYIm9KTNvve8JevZOKofApcDXxmvJt9Z 6vTdSDzuE6faeOtOzgLg+yXK+E6NBSaEij3ipTQpU1m10pdy+W2uBuZZAJm6TVLE+VZNex GUlONgl0uQ2n+L/lYdL65bUHqSpvDAj0DSrcB0j1y+eZlUtJ25jV8W1/tTh/pw== 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 4j2MT60GJxzHBP for ; Sun, 11 Oct 2026 00:50:18 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from git (uid 1279) (envelope-from git@FreeBSD.org) id 31dcf by gitrepo.freebsd.org (DragonFly Mail Agent v0.13+ on gitrepo.freebsd.org); Sun, 11 Oct 2026 00:50:18 +0000 To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org From: Kevin Bowling Subject: git: ea3fdee608a9 - stable/15 - e1000: Correct igb(4) DMA coalescing register programming List-Archive: https://lists.freebsd.org/archives/dev-commits-src-branches X-BeenThere: dev-commits-src-branches@freebsd.org Sender: owner-dev-commits-src-branches@FreeBSD.org List-Id: Commits to the stable branches of the FreeBSD src repository 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: ea3fdee608a9fb6f690e22392c9948d45d350e1b Auto-Submitted: auto-generated Date: Sun, 11 Oct 2026 00:50:18 +0000 Message-Id: <6acadd4a.31dcf.38bcae25@gitrepo.freebsd.org> The branch stable/15 has been updated by kbowling: URL: https://cgit.FreeBSD.org/src/commit/?id=ea3fdee608a9fb6f690e22392c9948d45d350e1b commit ea3fdee608a9fb6f690e22392c9948d45d350e1b Author: Kevin Bowling AuthorDate: 2026-08-29 02:38:43 +0000 Commit: Kevin Bowling CommitDate: 2026-10-11 00:49:57 +0000 e1000: Correct igb(4) DMA coalescing register programming The disabled path wrote the complement of DMAC_EN to DMACR. That set every other field, including reserved bits, the one-shot EXIT_DC command, watchdog enables, receive threshold, and PCIe Lx selection. When DMA coalescing was enabled, the requested watchdog and Lx-delay values were ORed into their reset values rather than replacing the fields. PCIEMISC.LX_DECISION was also cleared, preventing DMACR.DMAC_Lx from controlling PCIe low-power entry. Disable coalescing by clearing only DMAC_EN and retaining the documented DMAC_Lx policy and watchdog fields. On enable, replace the variable fields under their masks, select DMA requirements for PCIe low-power entry, and program the loopback and BMC watchdog policies independently of prior state. Apply this consistently to I350, I354, and I210 while preserving the I354-specific timer units. Leave I210 reserved fields at their required encodings and do not expose the ineffective control on I211. Validated on I210 and I350 hardware. Repeated I210 enable, disable, and reset cycles preserved the watchdog, Lx, TTLX, and LX_DECISION fields. On I350, dmac values of 250, 1000, and 10000 programmed DMACWT as 0x7, 0x1f, and 0x138, respectively, while retaining a four-tick TTLX and leaving the reserved and watchdog fields stable. A real reset initiated by a sibling function restored the enabled dmac=1000 tuple and a down interface path restored the disabled tuple. Sponsored by: BBOX.io (cherry picked from commit 245437113020582f3622c9bcc6d841b7d9dc8f96) --- sys/dev/e1000/e1000_defines.h | 2 ++ sys/dev/e1000/if_em.c | 70 +++++++++++++++++++++++++++++-------------- 2 files changed, 49 insertions(+), 23 deletions(-) diff --git a/sys/dev/e1000/e1000_defines.h b/sys/dev/e1000/e1000_defines.h index 18b311138032..acce4e7042e0 100644 --- a/sys/dev/e1000/e1000_defines.h +++ b/sys/dev/e1000/e1000_defines.h @@ -1546,6 +1546,8 @@ #define E1000_DMACR_DMAC_LX_MASK 0x30000000 #define E1000_DMACR_DMAC_LX_SHIFT 28 #define E1000_DMACR_DMAC_EN 0x80000000 /* Enable DMA Coalescing */ +/* DMA Coalescing VM-to-VM Loopback Watchdog Enable */ +#define E1000_DMACR_DC_LPBKW_EN 0x00004000 /* DMA Coalescing BMC-to-OS Watchdog Enable */ #define E1000_DMACR_DC_BMC2OSW_EN 0x00008000 diff --git a/sys/dev/e1000/if_em.c b/sys/dev/e1000/if_em.c index 10dfd7d9a05a..c482bdb0ccd4 100644 --- a/sys/dev/e1000/if_em.c +++ b/sys/dev/e1000/if_em.c @@ -1048,7 +1048,7 @@ em_if_attach_pre(if_ctx_t ctx) CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_NEEDGIANT, sc, 0, em_get_rs, "I", "Dump RS indexes"); - if (hw->mac.type >= e1000_i350) { + if (hw->mac.type >= e1000_i350 && hw->mac.type != e1000_i211) { SYSCTL_ADD_PROC(ctx_list, child, OID_AUTO, "dmac", CTLTYPE_INT | CTLFLAG_RW, sc, 0, igb_sysctl_dmac, "I", "DMA Coalesce"); @@ -3839,6 +3839,18 @@ lem_smartspeed(struct e1000_softc *sc) sc->smartspeed = 0; } +static void +igb_disable_dmac(struct e1000_hw *hw) +{ + u32 reg; + + reg = E1000_READ_REG(hw, E1000_DMACR); + reg &= ~E1000_DMACR_DMAC_EN; + /* Retain the documented Lx policy and I210 reserved encoding. */ + reg |= E1000_DMACR_DMAC_LX_MASK; + E1000_WRITE_REG(hw, E1000_DMACR, reg); +} + /********************************************************************* * * Initialize the DMA Coalescing feature @@ -3849,7 +3861,7 @@ igb_init_dmac(struct e1000_softc *sc, u32 pba) { device_t dev = sc->dev; struct e1000_hw *hw = &sc->hw; - u32 dmac, reg = ~E1000_DMACR_DMAC_EN; + u32 dmac, dmacwt, reg, ttlx; u16 hwm; u16 max_frame_size; @@ -3860,7 +3872,7 @@ igb_init_dmac(struct e1000_softc *sc, u32 pba) if (hw->mac.type > e1000_82580) { if (sc->dmac == 0) { /* Disabling it */ - E1000_WRITE_REG(hw, E1000_DMACR, reg); + igb_disable_dmac(hw); return; } else device_printf(dev, "DMA Coalescing enabled\n"); @@ -3882,52 +3894,64 @@ igb_init_dmac(struct e1000_softc *sc, u32 pba) if (dmac < pba - 10) dmac = pba - 10; reg = E1000_READ_REG(hw, E1000_DMACR); - reg &= ~E1000_DMACR_DMACTHR_MASK; + reg &= ~(E1000_DMACR_DMACWT_MASK | + E1000_DMACR_DMACTHR_MASK | E1000_DMACR_DMAC_LX_MASK | + E1000_DMACR_DMAC_EN | E1000_DMACR_DC_LPBKW_EN | + E1000_DMACR_DC_BMC2OSW_EN); reg |= ((dmac << E1000_DMACR_DMACTHR_SHIFT) & E1000_DMACR_DMACTHR_MASK); - /* transition to L0x or L1 if available..*/ + /* Transition to L0s or L1 if available. */ reg |= (E1000_DMACR_DMAC_EN | E1000_DMACR_DMAC_LX_MASK); - /* Check if status is 2.5Gb backplane connection - * before configuration of watchdog timer, which is - * in msec values in 12.8usec intervals - * watchdog timer= msec values in 32usec intervals - * for non 2.5Gb connection - */ + /* + * The watchdog uses 12.8 usec units on an I354 2.5 Gb/s + * backplane connection and 32 usec units otherwise. + */ if (hw->mac.type == e1000_i354) { int status = E1000_READ_REG(hw, E1000_STATUS); if ((status & E1000_STATUS_2P5_SKU) && (!(status & E1000_STATUS_2P5_SKU_OVER))) - reg |= ((sc->dmac * 5) >> 6); + dmacwt = (sc->dmac * 5) >> 6; else - reg |= (sc->dmac >> 5); + dmacwt = sc->dmac >> 5; } else { - reg |= (sc->dmac >> 5); + dmacwt = sc->dmac >> 5; } + reg |= dmacwt & E1000_DMACR_DMACWT_MASK; + if (hw->mac.type == e1000_i350 || + hw->mac.type == e1000_i354) + reg |= E1000_DMACR_DC_LPBKW_EN; + if (hw->mac.type == e1000_i354) + reg |= E1000_DMACR_DC_BMC2OSW_EN; E1000_WRITE_REG(hw, E1000_DMACR, reg); E1000_WRITE_REG(hw, E1000_DMCRTRH, 0); - /* Set the interval before transition */ + /* Set the interval before transition. */ reg = E1000_READ_REG(hw, E1000_DMCTLX); + reg &= ~E1000_DMCTLX_TTLX_MASK; if (hw->mac.type == e1000_i350) reg |= IGB_DMCTLX_DCFLUSH_DIS; /* - ** in 2.5Gb connection, TTLX unit is 0.4 usec - ** which is 0x4*2 = 0xA. But delay is still 4 usec - */ - if (hw->mac.type == e1000_i354) { + * I210 documents TTLX as reserved with a required value of 0x20. + * At 2.5 Gb/s the I354 unit is 0.4 usec, so ten ticks retain + * the four usec interval used at other speeds. + */ + if (hw->mac.type == e1000_i210) { + ttlx = 0x20; + } else if (hw->mac.type == e1000_i354) { int status = E1000_READ_REG(hw, E1000_STATUS); if ((status & E1000_STATUS_2P5_SKU) && (!(status & E1000_STATUS_2P5_SKU_OVER))) - reg |= 0xA; + ttlx = 0xA; else - reg |= 0x4; + ttlx = 0x4; } else { - reg |= 0x4; + ttlx = 0x4; } + reg |= ttlx & E1000_DMCTLX_TTLX_MASK; E1000_WRITE_REG(hw, E1000_DMCTLX, reg); @@ -3937,7 +3961,7 @@ igb_init_dmac(struct e1000_softc *sc, u32 pba) /* make low power state decision controlled by DMA coal */ reg = E1000_READ_REG(hw, E1000_PCIEMISC); - reg &= ~E1000_PCIEMISC_LX_DECISION; + reg |= E1000_PCIEMISC_LX_DECISION; E1000_WRITE_REG(hw, E1000_PCIEMISC, reg); } else if (hw->mac.type == e1000_82580) {