Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 16 May 2019 20:41:29 +0000 (UTC)
From:      Tycho Nightingale <tychon@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r347890 - in head/sys/dev: aac bge
Message-ID:  <201905162041.x4GKfTwb013353@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: tychon
Date: Thu May 16 20:41:28 2019
New Revision: 347890
URL: https://svnweb.freebsd.org/changeset/base/347890

Log:
  reinstate 4GB DMA boundary workarounds for bge and aac
  
  Reviewed by:	kib
  Sponsored by:	Dell EMC Isilon
  Differential Revision:	https://reviews.freebsd.org/D20277

Modified:
  head/sys/dev/aac/aac_pci.c
  head/sys/dev/bge/if_bge.c
  head/sys/dev/bge/if_bgereg.h

Modified: head/sys/dev/aac/aac_pci.c
==============================================================================
--- head/sys/dev/aac/aac_pci.c	Thu May 16 19:32:11 2019	(r347889)
+++ head/sys/dev/aac/aac_pci.c	Thu May 16 20:41:28 2019	(r347890)
@@ -443,7 +443,8 @@ aac_pci_attach(device_t dev)
 	 * Note that some of these controllers are 64-bit capable.
 	 */
 	if (bus_dma_tag_create(bus_get_dma_tag(dev),	/* parent */
-			       PAGE_SIZE, 0,		/* algnmnt, boundary */
+			       PAGE_SIZE,		/* algnmnt */
+			       ((bus_size_t)((uint64_t)1 << 32)), /* boundary*/
 			       BUS_SPACE_MAXADDR,	/* lowaddr */
 			       BUS_SPACE_MAXADDR, 	/* highaddr */
 			       NULL, NULL, 		/* filter, filterarg */

Modified: head/sys/dev/bge/if_bge.c
==============================================================================
--- head/sys/dev/bge/if_bge.c	Thu May 16 19:32:11 2019	(r347889)
+++ head/sys/dev/bge/if_bge.c	Thu May 16 20:41:28 2019	(r347890)
@@ -2927,10 +2927,14 @@ bge_dma_ring_alloc(struct bge_softc *sc, bus_size_t al
     bus_addr_t *paddr, const char *msg)
 {
 	struct bge_dmamap_arg ctx;
+	bus_addr_t lowaddr;
+	bus_size_t ring_end;
 	int error;
 
+	lowaddr = BUS_SPACE_MAXADDR;
+again:
 	error = bus_dma_tag_create(sc->bge_cdata.bge_parent_tag,
-	    alignment, 0, BUS_SPACE_MAXADDR, BUS_SPACE_MAXADDR, NULL,
+	    alignment, 0, lowaddr, BUS_SPACE_MAXADDR, NULL,
 	    NULL, maxsize, 1, maxsize, 0, NULL, NULL, tag);
 	if (error != 0) {
 		device_printf(sc->bge_dev,
@@ -2955,6 +2959,25 @@ bge_dma_ring_alloc(struct bge_softc *sc, bus_size_t al
 		return (ENOMEM);
 	}
 	*paddr = ctx.bge_busaddr;
+	ring_end = *paddr + maxsize;
+	if ((sc->bge_flags & BGE_FLAG_4G_BNDRY_BUG) != 0 &&
+	    BGE_ADDR_HI(*paddr) != BGE_ADDR_HI(ring_end)) {
+		/*
+		 * 4GB boundary crossed.  Limit maximum allowable DMA
+		 * address space to 32bit and try again.
+		 */
+		bus_dmamap_unload(*tag, *map);
+		bus_dmamem_free(*tag, *ring, *map);
+		bus_dma_tag_destroy(*tag);
+		if (bootverbose)
+			device_printf(sc->bge_dev, "4GB boundary crossed, "
+			    "limit DMA address space to 32bit for %s\n", msg);
+		*ring = NULL;
+		*tag = NULL;
+		*map = NULL;
+		lowaddr = BUS_SPACE_MAXADDR_32BIT;
+		goto again;
+	}
 	return (0);
 }
 
@@ -2962,7 +2985,7 @@ static int
 bge_dma_alloc(struct bge_softc *sc)
 {
 	bus_addr_t lowaddr;
-	bus_size_t rxmaxsegsz, sbsz, txsegsz, txmaxsegsz;
+	bus_size_t boundary, sbsz, rxmaxsegsz, txsegsz, txmaxsegsz;
 	int i, error;
 
 	lowaddr = BUS_SPACE_MAXADDR;
@@ -3049,7 +3072,9 @@ bge_dma_alloc(struct bge_softc *sc)
 	}
 
 	/* Create parent tag for buffers. */
+	boundary = 0;
 	if ((sc->bge_flags & BGE_FLAG_4G_BNDRY_BUG) != 0) {
+		boundary = BGE_DMA_BNDRY;
 		/*
 		 * XXX
 		 * watchdog timeout issue was observed on BCM5704 which
@@ -3060,10 +3085,10 @@ bge_dma_alloc(struct bge_softc *sc)
 		if (sc->bge_pcixcap != 0)
 			lowaddr = BUS_SPACE_MAXADDR_32BIT;
 	}
-	error = bus_dma_tag_create(bus_get_dma_tag(sc->bge_dev), 1, 0, lowaddr,
-	    BUS_SPACE_MAXADDR, NULL, NULL, BUS_SPACE_MAXSIZE_32BIT, 0,
-	    BUS_SPACE_MAXSIZE_32BIT, 0, NULL, NULL,
-	    &sc->bge_cdata.bge_buffer_tag);
+	error = bus_dma_tag_create(bus_get_dma_tag(sc->bge_dev),
+	    1, boundary, lowaddr, BUS_SPACE_MAXADDR, NULL,
+	    NULL, BUS_SPACE_MAXSIZE_32BIT, 0, BUS_SPACE_MAXSIZE_32BIT,
+	    0, NULL, NULL, &sc->bge_cdata.bge_buffer_tag);
 	if (error != 0) {
 		device_printf(sc->bge_dev,
 		    "could not allocate buffer dma tag\n");

Modified: head/sys/dev/bge/if_bgereg.h
==============================================================================
--- head/sys/dev/bge/if_bgereg.h	Thu May 16 19:32:11 2019	(r347889)
+++ head/sys/dev/bge/if_bgereg.h	Thu May 16 20:41:28 2019	(r347890)
@@ -2866,6 +2866,12 @@ struct bge_gib {
 #define	BGE_DMA_MAXADDR		0xFFFFFFFFFF
 #endif
 
+#if (BUS_SPACE_MAXADDR > 0xFFFFFFFF)
+#define	BGE_DMA_BNDRY		0x100000000
+#else
+#define	BGE_DMA_BNDRY		0
+#endif
+
 /*
  * Ring structures. Most of these reside in host memory and we tell
  * the NIC where they are via the ring control blocks. The exceptions



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201905162041.x4GKfTwb013353>