Index | Thread | Search

From:
Vitaliy Makkoveev <mvs@openbsd.org>
Subject:
Re: em 64 bit dma
To:
Alexander Bluhm <bluhm@openbsd.org>
Cc:
Brad Smith <brad@comstyle.com>, tech@openbsd.org
Date:
Mon, 2 Mar 2026 08:22:31 +0000

Download raw body.

Thread
On Fri, Feb 27, 2026 at 07:41:08PM +0100, Alexander Bluhm wrote:
> On Fri, Feb 27, 2026 at 12:58:15PM -0500, Brad Smith wrote:
> > On 2026-02-27 12:36 p.m., Alexander Bluhm wrote:
> > > Hi,
> > >
> > > I have tested 64 bit dma for em(4) with
> > >
> > > em0 at pci0 dev 25 function 0 "Intel 82579LM" rev 0x04: msi, address 3c:97:0e:a7:09:b2
> > > em0 at pci2 dev 0 function 0 "Intel 82571EB" rev 0x06: apic 2 int 8, address 00:1b:21:7b:d1:10
> > > em2 at pci3 dev 0 function 0 "Intel 82580" rev 0x01: msi, address 90:e2:ba:78:7c:f0
> > > em6 at pci4 dev 0 function 0 "Intel 82576" rev 0x01: msi, address 00:1b:21:da:f6:ec
> > > em8 at pci5 dev 0 function 0 "Intel I350" rev 0x01: msi, address 00:25:90:e7:ec:7c
> > > em14 at pci11 dev 0 function 0 "Intel 82576" rev 0x01: msi, address 00:1b:21:60:58:28
> > >
> > > I only enable BUS_DMA_64BIT for PCIe.
> > >
> > > ok?
> > >
> > > bluhm
> > >
> > > Index: dev/pci/if_em.c
> > > ===================================================================
> > > RCS file: /data/mirror/openbsd/cvs/src/sys/dev/pci/if_em.c,v
> > > diff -u -p -r1.379 if_em.c
> > > --- dev/pci/if_em.c	14 Jul 2025 11:52:43 -0000	1.379
> > > +++ dev/pci/if_em.c	27 Feb 2026 17:30:06 -0000
> > > @@ -534,6 +534,23 @@ em_attach(struct device *parent, struct
> > >   	sc->hw.min_frame_size =
> > >   	    ETHER_MIN_LEN + ETHER_CRC_LEN;
> > >   
> > > +	em_get_bus_info(&sc->hw);
> > > +	switch (sc->hw.bus_type) {
> > > +	case em_bus_type_pcix:
> > > +		/* Identify 82544 on PCI-X */
> > > +		if (sc->hw.mac_type == em_82544)
> > > +			sc->pcix_82544 = TRUE;
> > > +		else
> > > +			sc->pcix_82544 = FALSE;
> > > +		break;
> > > +	case em_bus_type_pci_express:
> > > +		/* Only PCI-X and PCIe support 64 bit DMA */
> > 
> > The comment doesn't match what the code does.
> 
> Sorry, that was a last minute change.  Before there was a FALLTHROUGH
> instead of break above.  It seems that we want to be on the safe
> side and disable 64 bit DMA for PCI-X.
> 

ok mvs@

Works for me with

em0 at pci4 dev 0 function 0 "Intel 82574L" rev 0x00: msi, address 00:1b:21:39:12:ca

> Index: dev/pci/if_em.c
> ===================================================================
> RCS file: /data/mirror/openbsd/cvs/src/sys/dev/pci/if_em.c,v
> diff -u -p -r1.379 if_em.c
> --- dev/pci/if_em.c	14 Jul 2025 11:52:43 -0000	1.379
> +++ dev/pci/if_em.c	27 Feb 2026 18:38:37 -0000
> @@ -534,6 +534,23 @@ em_attach(struct device *parent, struct 
>  	sc->hw.min_frame_size = 
>  	    ETHER_MIN_LEN + ETHER_CRC_LEN;
>  
> +	em_get_bus_info(&sc->hw);
> +	switch (sc->hw.bus_type) {
> +	case em_bus_type_pcix:
> +		/* Identify 82544 on PCI-X */
> +		if (sc->hw.mac_type == em_82544)
> +			sc->pcix_82544 = TRUE;
> +		else
> +			sc->pcix_82544 = FALSE;
> +		break;
> +	case em_bus_type_pci_express:
> +		/* Only PCIe support 64 bit DMA */
> +		sc->sc_dmaflags |= BUS_DMA_64BIT;
> +		break;
> +	default:
> +		break;
> +	}
> +
>  	if (em_allocate_desc_rings(sc) != 0) {
>  		printf("%s: Unable to allocate descriptor ring memory\n",
>  		    DEVNAME(sc));
> @@ -609,14 +626,6 @@ em_attach(struct device *parent, struct 
>  		printf("%s: PHY reset is blocked due to SOL/IDER session.\n",
>  		    DEVNAME(sc));
>  
> -	/* Identify 82544 on PCI-X */
> -	em_get_bus_info(&sc->hw);
> -	if (sc->hw.bus_type == em_bus_type_pcix &&
> -	    sc->hw.mac_type == em_82544)
> -		sc->pcix_82544 = TRUE;
> -        else
> -		sc->pcix_82544 = FALSE;
> -
>  	sc->hw.icp_xxxx_is_link_up = FALSE;
>  
>  	INIT_DEBUGOUT("em_attach: end");
> @@ -2158,12 +2167,13 @@ em_dma_malloc(struct em_softc *sc, bus_s
>  	int r;
>  
>  	r = bus_dmamap_create(sc->sc_dmat, size, 1,
> -	    size, 0, BUS_DMA_WAITOK | BUS_DMA_ALLOCNOW, &dma->dma_map);
> +	    size, 0, BUS_DMA_WAITOK | BUS_DMA_ALLOCNOW | sc->sc_dmaflags,
> +	    &dma->dma_map);
>  	if (r != 0)
>  		return (r);
>  
>  	r = bus_dmamem_alloc(sc->sc_dmat, size, PAGE_SIZE, 0, &dma->dma_seg,
> -	    1, &dma->dma_nseg, BUS_DMA_WAITOK | BUS_DMA_ZERO);
> +	    1, &dma->dma_nseg, BUS_DMA_WAITOK | BUS_DMA_ZERO | sc->sc_dmaflags);
>  	if (r != 0)
>  		goto destroy;
>  
> @@ -2250,10 +2260,12 @@ em_setup_transmit_structures(struct em_s
>  			pkt = &que->tx.sc_tx_pkts_ring[i];
>  			error = bus_dmamap_create(sc->sc_dmat, EM_TSO_SIZE,
>  			    EM_MAX_SCATTER / (sc->pcix_82544 ? 2 : 1),
> -			    EM_TSO_SEG_SIZE, 0, BUS_DMA_NOWAIT, &pkt->pkt_map);
> +			    EM_TSO_SEG_SIZE, 0,
> +			    BUS_DMA_NOWAIT | sc->sc_dmaflags,
> +			    &pkt->pkt_map);
>  			if (error != 0) {
> -				printf("%s: Unable to create TX DMA map\n",
> -				    DEVNAME(sc));
> +				printf("%s: Unable to create TX DMA map, "
> +				    "error %d\n", DEVNAME(sc), error);
>  				goto fail;
>  			}
>  		}
> @@ -2772,11 +2784,11 @@ em_allocate_receive_structures(struct em
>  			pkt = &que->rx.sc_rx_pkts_ring[i];
>  
>  			error = bus_dmamap_create(sc->sc_dmat, EM_MCLBYTES, 1,
> -			    EM_MCLBYTES, 0, BUS_DMA_NOWAIT, &pkt->pkt_map);
> +			    EM_MCLBYTES, 0, BUS_DMA_NOWAIT | sc->sc_dmaflags,
> +			    &pkt->pkt_map);
>  			if (error != 0) {
> -				printf("%s: em_allocate_receive_structures: "
> -				    "bus_dmamap_create failed; error %u\n",
> -				    DEVNAME(sc), error);
> +				printf("%s: Unable to create RX DMA map, "
> +				    "error %d\n", DEVNAME(sc), error);
>  				goto fail;
>  			}
>  
> Index: dev/pci/if_em.h
> ===================================================================
> RCS file: /data/mirror/openbsd/cvs/src/sys/dev/pci/if_em.h,v
> diff -u -p -r1.83 if_em.h
> --- dev/pci/if_em.h	16 Feb 2024 22:30:54 -0000	1.83
> +++ dev/pci/if_em.h	27 Feb 2026 17:01:30 -0000
> @@ -385,6 +385,7 @@ struct em_softc {
>  	struct arpcom	sc_ac;
>  
>  	bus_dma_tag_t	sc_dmat;
> +	int		sc_dmaflags;
>  
>  	struct em_hw	hw;
>  
>