Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 31 Jul 2026 08:55:46 +0000
From:      Kevin Bowling <kbowling@FreeBSD.org>
To:        src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org
Subject:   git: 41759495769d - main - e1000: restrict conventional PCI DMA to 32 bits
Message-ID:  <6a6c6312.2423e.2e7b8491@gitrepo.freebsd.org>

index | next in thread | raw e-mail

The branch main has been updated by kbowling:

URL: https://cgit.FreeBSD.org/src/commit/?id=41759495769dff87cd4ebbb257d4054128ea5b42

commit 41759495769dff87cd4ebbb257d4054128ea5b42
Author:     Kevin Bowling <kbowling@FreeBSD.org>
AuthorDate: 2026-07-31 07:02:22 +0000
Commit:     Kevin Bowling <kbowling@FreeBSD.org>
CommitDate: 2026-07-31 08:55:07 +0000

    e1000: restrict conventional PCI DMA to 32 bits
    
    Some conventional PCI e1000 configurations hang when given DMA
    addresses above 4 GB, particularly on systems using AMD
    HyperTransport-to-PCI bridges.  Linux has restricted e1000 to DMA32 in
    PCI mode since 2011 for the same failure class in commit
    e508be174ad36b0cf9b324cd04978c2b13c21502.
    
    Set iflib's DMA width after determining the negotiated bus type.  This
    covers descriptor and packet-buffer mappings while preserving 64-bit
    DMA for PCI-X and PCIe devices and providing a conditional tunable.
    
    PR:             297064
    Reported by:    Alexander Leidinger <netchild@FreeBSD.org>
    Tested by:      Alexander Leidinger <netchild@FreeBSD.org>
    MFC after:      1 week
---
 sys/dev/e1000/if_em.c | 21 +++++++++++++++++++++
 sys/dev/e1000/if_em.h |  1 +
 2 files changed, 22 insertions(+)

diff --git a/sys/dev/e1000/if_em.c b/sys/dev/e1000/if_em.c
index 43519dd72d25..bfb5595be199 100644
--- a/sys/dev/e1000/if_em.c
+++ b/sys/dev/e1000/if_em.c
@@ -1446,6 +1446,27 @@ em_if_attach_pre(if_ctx_t ctx)
 	em_setup_msix(ctx);
 	e1000_get_bus_info(hw);
 
+	/*
+	 * Some conventional PCI systems hang when e1000 devices use
+	 * DMA addresses above 4 GB.  Keep PCI-mode DMA below that boundary
+	 * by default; PCI-X and PCIe retain 64-bit DMA.
+	 */
+	if (hw->bus.type == e1000_bus_type_pci) {
+		SYSCTL_ADD_BOOL(ctx_list, child, OID_AUTO, "allow_64bit_dma",
+		    CTLFLAG_RDTUN, &sc->allow_64bit_dma, 0,
+		    "Allow 64-bit DMA in conventional PCI mode");
+		if (sc->allow_64bit_dma)
+			device_printf(dev, "64-bit DMA in conventional PCI mode.  "
+			    "Some chipsets are unstable.\n");
+		else {
+			scctx->isc_dma_width = 32;
+			device_printf(dev, "32-bit DMA in conventional PCI mode.  "
+			    "Set dev.%s.%d.allow_64bit_dma=1 at boot to enable "
+			    "64-bit DMA if the chipset is stable with it.\n",
+			    device_get_name(dev), device_get_unit(dev));
+		}
+	}
+
 	/* Set up some sysctls for the tunable interrupt delays */
 	if (hw->mac.type < igb_mac_min) {
 		em_add_int_delay_sysctl(sc, "rx_int_delay",
diff --git a/sys/dev/e1000/if_em.h b/sys/dev/e1000/if_em.h
index 6e9d17c7b7a0..4676cffc5033 100644
--- a/sys/dev/e1000/if_em.h
+++ b/sys/dev/e1000/if_em.h
@@ -556,6 +556,7 @@ struct e1000_softc {
 	int			if_flags;
 	int			em_insert_vlan_header;
 	u32			ims;
+	bool			allow_64bit_dma;
 	bool			in_detach;
 
 	u32			flags;


home | help

Want to link to this message? Use this
URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?6a6c6312.2423e.2e7b8491>