Latest if_bfe - I think it works!

Mike Silbersack <[email protected]>
Newsgroups gmane.os.freebsd.devel.mobile
Message-ID <[email protected]>
Ok, I got it working with an artificial 128MB limit.  I had to fix two 
major issues:

1.  It was requiring more bounce buffers than busdma was prepared to give 
it, so I reduced the size of the rings.
2.  It was leaking bounce buffers whenever you transmitted a 
multi-fragment buffer, which pretty much means any non-ping packet.

and scottl fixed #3 with rev 1.77 of busdma_machdep.c

3.  busdma wasn't telling us when we ran out of bounce buffers.

However, now that #1 and #2 are fixed, #3 shouldn't come into play ever, 
as far as I can tell.

I'm writing this e-mail via ssh into pine on the machine which has the 
artificial 128MB limit set, looking at hw.busdma sysctl I can see that 
it's bouncing pages all over the place, so I can say that it seems to be 
good to me.  Please test.

Thanks,

Mike "Silby" Silbersack

_______________________________________________
[email protected] mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-mobile
To unsubscribe, send any mail to "[email protected]"
if_bfe.c-wip2.patch (text/plain, 4.8 KB)
diff -u -r /usr/src/sys.old/dev/bfe/if_bfe.c /usr/src/sys/dev/bfe/if_bfe.c
--- /usr/src/sys.old/dev/bfe/if_bfe.c	Mon May  1 00:31:18 2006
+++ /usr/src/sys/dev/bfe/if_bfe.c	Wed May  3 02:24:35 2006
@@ -297,7 +298,7 @@
 	bzero(sc->bfe_rx_list, BFE_RX_LIST_SIZE);
 	error = bus_dmamap_load(sc->bfe_rx_tag, sc->bfe_rx_map,
 			sc->bfe_rx_list, sizeof(struct bfe_desc),
-			bfe_dma_map, &sc->bfe_rx_dma, 0);
+			bfe_dma_map, &sc->bfe_rx_dma, BUS_DMA_NOWAIT);
 
 	if(error)
 		return (ENOMEM);
@@ -312,7 +313,7 @@
 
 	error = bus_dmamap_load(sc->bfe_tx_tag, sc->bfe_tx_map,
 			sc->bfe_tx_list, sizeof(struct bfe_desc),
-			bfe_dma_map, &sc->bfe_tx_dma, 0);
+			bfe_dma_map, &sc->bfe_tx_dma, BUS_DMA_NOWAIT);
 	if(error)
 		return (ENOMEM);
 
@@ -574,6 +575,7 @@
 	struct bfe_desc *d;
 	struct bfe_data *r;
 	u_int32_t ctrl;
+	int error;
 
 	if ((c < 0) || (c >= BFE_RX_LIST_CNT))
 		return (EINVAL);
@@ -595,8 +597,10 @@
 	sc->bfe_rx_cnt = c;
 	d = &sc->bfe_rx_list[c];
 	r = &sc->bfe_rx_ring[c];
-	bus_dmamap_load(sc->bfe_tag, r->bfe_map, mtod(m, void *),
-			MCLBYTES, bfe_dma_map_desc, d, 0);
+	error = bus_dmamap_load(sc->bfe_tag, r->bfe_map, mtod(m, void *),
+			MCLBYTES, bfe_dma_map_desc, d, BUS_DMA_NOWAIT);
+	if (error)
+		printf("Error I can't handle!!!\n");
 	bus_dmamap_sync(sc->bfe_tag, r->bfe_map, BUS_DMASYNC_PREWRITE);
 
 	ctrl = ETHER_MAX_LEN + 32;
@@ -1102,8 +1106,8 @@
 			ifp->if_opackets++;
 			m_freem(r->bfe_mbuf);
 			r->bfe_mbuf = NULL;
-			bus_dmamap_unload(sc->bfe_tag, r->bfe_map);
 		}
+		bus_dmamap_unload(sc->bfe_tag, r->bfe_map);
 		sc->bfe_tx_cnt--;
 		BFE_INC(i, BFE_TX_LIST_CNT);
 	}
@@ -1241,13 +1245,14 @@
 }
 
 static int
-bfe_encap(struct bfe_softc *sc, struct mbuf *m_head, u_int32_t *txidx)
+bfe_encap(struct bfe_softc *sc, struct mbuf **m_head, u_int32_t *txidx)
 {
 	struct bfe_desc *d = NULL;
 	struct bfe_data *r = NULL;
 	struct mbuf	*m;
 	u_int32_t	   frag, cur, cnt = 0;
 	int chainlen = 0;
+	int error;
 
 	if(BFE_TX_LIST_CNT - sc->bfe_tx_cnt < 2)
 		return (ENOBUFS);
@@ -1258,16 +1263,16 @@
 	 * by all packets, we'll m_defrag long chains so that they
 	 * do not use up the entire list, even if they would fit.
 	 */
-	for(m = m_head; m != NULL; m = m->m_next)
+	for(m = *m_head; m != NULL; m = m->m_next) {
 		chainlen++;
-
+	}
 
 	if ((chainlen > BFE_TX_LIST_CNT / 4) ||
 			((BFE_TX_LIST_CNT - (chainlen + sc->bfe_tx_cnt)) < 2)) {
-		m = m_defrag(m_head, M_DONTWAIT);
+		m = m_defrag(*m_head, M_DONTWAIT);
 		if (m == NULL)
 			return (ENOBUFS);
-		m_head = m;
+		*m_head = m;
 	}
 
 	/*
@@ -1275,11 +1280,10 @@
 	 * the fragment pointers. Stop when we run out
 	 * of fragments or hit the end of the mbuf chain.
 	 */
-	m = m_head;
 	cur = frag = *txidx;
 	cnt = 0;
 
-	for(m = m_head; m != NULL; m = m->m_next) {
+	for(m = *m_head; m != NULL; m = m->m_next) {
 		if(m->m_len != 0) {
 			if((BFE_TX_LIST_CNT - (sc->bfe_tx_cnt + cnt)) < 2)
 				return (ENOBUFS);
@@ -1299,9 +1303,13 @@
 				 */
 				d->bfe_ctrl |= BFE_DESC_EOT;
 
-			bus_dmamap_load(sc->bfe_tag,
+			error = bus_dmamap_load(sc->bfe_tag,
 			    r->bfe_map, mtod(m, void*), m->m_len,
-			    bfe_dma_map_desc, d, 0);
+			    bfe_dma_map_desc, d, BUS_DMA_NOWAIT);
+			if (error) {
+				printf("dmamap_load error, ENOBUFS\n");
+				return (ENOBUFS);
+			}
 			bus_dmamap_sync(sc->bfe_tag, r->bfe_map,
 			    BUS_DMASYNC_PREWRITE);
 
@@ -1315,7 +1323,7 @@
 		return (ENOBUFS);
 
 	sc->bfe_tx_list[frag].bfe_ctrl |= BFE_DESC_EOF;
-	sc->bfe_tx_ring[frag].bfe_mbuf = m_head;
+	sc->bfe_tx_ring[frag].bfe_mbuf = *m_head;
 	bus_dmamap_sync(sc->bfe_tx_tag, sc->bfe_tx_map, BUS_DMASYNC_PREWRITE);
 
 	*txidx = cur;
@@ -1368,7 +1376,7 @@
 		 * Pack the data into the tx ring.  If we dont have
 		 * enough room, let the chip drain the ring.
 		 */
-		if(bfe_encap(sc, m_head, &idx)) {
+		if(bfe_encap(sc, &m_head, &idx)) {
 			IFQ_DRV_PREPEND(&ifp->if_snd, m_head);
 			ifp->if_drv_flags |= IFF_DRV_OACTIVE;
 			break;
Only in /usr/src/sys/dev/bfe: if_bfe.c.good
Only in /usr/src/sys/dev/bfe: if_bfe.c.orig
Only in /usr/src/sys/dev/bfe: if_bfe.c.wip
Only in /usr/src/sys/dev/bfe: if_bfe.c.wip2
diff -u -r /usr/src/sys.old/dev/bfe/if_bfereg.h /usr/src/sys/dev/bfe/if_bfereg.h
--- /usr/src/sys.old/dev/bfe/if_bfereg.h	Thu Apr 27 01:09:07 2006
+++ /usr/src/sys/dev/bfe/if_bfereg.h	Wed May  3 02:16:42 2006
@@ -427,8 +427,8 @@
 #define BFE_RX_RING_SIZE        512
 #define BFE_TX_RING_SIZE        512
 #define BFE_LINK_DOWN           5
-#define BFE_TX_LIST_CNT         511
-#define BFE_RX_LIST_CNT         511
+#define BFE_TX_LIST_CNT         128
+#define BFE_RX_LIST_CNT         128
 #define BFE_TX_LIST_SIZE        BFE_TX_LIST_CNT * sizeof(struct bfe_desc)
 #define BFE_RX_LIST_SIZE        BFE_RX_LIST_CNT * sizeof(struct bfe_desc)
 #define BFE_RX_OFFSET           30
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.