Module Name:    src
Committed By:   thorpej
Date:           Sun Mar  1 02:51:42 UTC 2020

Modified Files:
        src/sys/dev/pci: if_age.c

Log Message:
- Use the 64-bit PCI DMA tag if available.
- In age_dma_alloc(), ensure that all of the control data end up in the
  same 4GB segment, because the hardware requires this.


To generate a diff of this commit:
cvs rdiff -u -r1.68 -r1.69 src/sys/dev/pci/if_age.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/dev/pci/if_age.c
diff -u src/sys/dev/pci/if_age.c:1.68 src/sys/dev/pci/if_age.c:1.69
--- src/sys/dev/pci/if_age.c:1.68	Sun Mar  1 02:28:14 2020
+++ src/sys/dev/pci/if_age.c	Sun Mar  1 02:51:42 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: if_age.c,v 1.68 2020/03/01 02:28:14 thorpej Exp $ */
+/*	$NetBSD: if_age.c,v 1.69 2020/03/01 02:51:42 thorpej Exp $ */
 /*	$OpenBSD: if_age.c,v 1.1 2009/01/16 05:00:34 kevlo Exp $	*/
 
 /*-
@@ -31,7 +31,7 @@
 /* Driver for Attansic Technology Corp. L1 Gigabit Ethernet. */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_age.c,v 1.68 2020/03/01 02:28:14 thorpej Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_age.c,v 1.69 2020/03/01 02:51:42 thorpej Exp $");
 
 #include "vlan.h"
 
@@ -152,10 +152,14 @@ age_attach(device_t parent, device_t sel
 	aprint_normal(": Attansic/Atheros L1 Gigabit Ethernet\n");
 
 	sc->sc_dev = self;
-	sc->sc_dmat = pa->pa_dmat;
 	sc->sc_pct = pa->pa_pc;
 	sc->sc_pcitag = pa->pa_tag;
 
+	if (pci_dma64_available(pa))
+		sc->sc_dmat = pa->pa_dmat64;
+	else
+		sc->sc_dmat = pa->pa_dmat;
+
 	/*
 	 * Allocate IO memory
 	 */
@@ -901,6 +905,31 @@ age_dma_alloc(struct age_softc *sc)
 	sc->age_rdata.age_smb_block_paddr =
 	    sc->age_cdata.age_smb_block_map->dm_segs[0].ds_addr;
 
+	/*
+	 * All of the memory we allocated above needs to be within
+	 * the same 4GB segment.  Make sure this is so.
+	 *
+	 * XXX We don't care WHAT 4GB segment they're in, just that
+	 * XXX they're all in the same one.  Need some bus_dma API
+	 * XXX help to make this easier to enforce when we actually
+	 * XXX perform the allocation.
+	 */
+	if (! (AGE_ADDR_HI(sc->age_rdata.age_tx_ring_paddr) ==
+	       AGE_ADDR_HI(sc->age_rdata.age_rx_ring_paddr)
+
+	    && AGE_ADDR_HI(sc->age_rdata.age_tx_ring_paddr) ==
+	       AGE_ADDR_HI(sc->age_rdata.age_rr_ring_paddr)
+
+	    && AGE_ADDR_HI(sc->age_rdata.age_tx_ring_paddr) ==
+	       AGE_ADDR_HI(sc->age_rdata.age_cmb_block_paddr)
+
+	    && AGE_ADDR_HI(sc->age_rdata.age_tx_ring_paddr) ==
+	       AGE_ADDR_HI(sc->age_rdata.age_smb_block_paddr))) {
+		aprint_error_dev(sc->sc_dev,
+		    "control data allocation constraints failed\n");
+		return ENOBUFS;
+	}
+
 	/* Create DMA maps for Tx buffers. */
 	for (i = 0; i < AGE_TX_RING_CNT; i++) {
 		txd = &sc->age_cdata.age_txdesc[i];

Reply via email to