Module Name:    src
Committed By:   matt
Date:           Tue Dec 25 21:17:41 UTC 2012

Modified Files:
        src/sys/arch/arm/broadcom: bcm53xx_eth.c

Log Message:
Change the way rx are consumed.  Only consume a 1/4 of the receive buffers
before refilling with new buffers.  Don't stop until there are no packets
left to receive.


To generate a diff of this commit:
cvs rdiff -u -r1.19 -r1.20 src/sys/arch/arm/broadcom/bcm53xx_eth.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/arch/arm/broadcom/bcm53xx_eth.c
diff -u src/sys/arch/arm/broadcom/bcm53xx_eth.c:1.19 src/sys/arch/arm/broadcom/bcm53xx_eth.c:1.20
--- src/sys/arch/arm/broadcom/bcm53xx_eth.c:1.19	Wed Dec 19 02:44:39 2012
+++ src/sys/arch/arm/broadcom/bcm53xx_eth.c	Tue Dec 25 21:17:40 2012
@@ -35,7 +35,7 @@
 
 #include <sys/cdefs.h>
 
-__KERNEL_RCSID(1, "$NetBSD: bcm53xx_eth.c,v 1.19 2012/12/19 02:44:39 matt Exp $");
+__KERNEL_RCSID(1, "$NetBSD: bcm53xx_eth.c,v 1.20 2012/12/25 21:17:40 matt Exp $");
 
 #include <sys/param.h>
 #include <sys/atomic.h>
@@ -1009,29 +1009,27 @@ bcmeth_rx_input(
 #endif
 }
 
-static void
+static bool
 bcmeth_rxq_consume(
 	struct bcmeth_softc *sc,
-	struct bcmeth_rxqueue *rxq)
+	struct bcmeth_rxqueue *rxq,
+	size_t atmost)
 {
 	struct ifnet * const ifp = &sc->sc_if;
 	struct gmac_rxdb *consumer = rxq->rxq_consumer;
 	size_t rxconsumed = 0;
+	bool didconsume = false;
 
-	for (;;) {
+	while (atmost-- > 0) {
 		if (consumer == rxq->rxq_producer) {
-			rxq->rxq_consumer = consumer;
-			rxq->rxq_inuse -= rxconsumed;
 			KASSERT(rxq->rxq_inuse == 0);
-			return;
+			break;
 		}
 		
 		uint32_t rcvsts0 = bcmeth_read_4(sc, rxq->rxq_reg_rcvsts0);
 		uint32_t currdscr = __SHIFTOUT(rcvsts0, RCV_CURRDSCR);
 		if (consumer == rxq->rxq_first + currdscr) {
-			rxq->rxq_consumer = consumer;
-			rxq->rxq_inuse -= rxconsumed;
-			return;
+			break;
 		}
 		bcmeth_rxq_desc_postsync(sc, rxq, consumer, 1);
 
@@ -1039,6 +1037,7 @@ bcmeth_rxq_consume(
 		 * We own this packet again.  Copy the rxsts word from it.
 		 */
 		rxconsumed++;
+		didconsume = true;
 		uint32_t rxsts;
 		KASSERT(rxq->rxq_mhead != NULL);
 		bus_dmamap_t map = M_GETCTX(rxq->rxq_mhead, bus_dmamap_t);
@@ -1152,6 +1151,17 @@ bcmeth_rxq_consume(
 			consumer = rxq->rxq_first;
 		}
 	}
+
+	/*
+	 * Update queue info.
+	 */
+	rxq->rxq_consumer = consumer;
+	rxq->rxq_inuse -= rxconsumed;
+
+	/*
+	 * Did we consume anything?
+	 */
+	return didconsume;
 }
 
 static void
@@ -1896,7 +1906,14 @@ bcmeth_soft_intr(void *arg)
 		/*
 		 * Let's consume 
 		 */
-		bcmeth_rxq_consume(sc, &sc->sc_rxq);
+		while (bcmeth_rxq_consume(sc, &sc->sc_rxq,
+		    sc->sc_rxq.rxq_threshold / 4)) {
+			/*
+			 * We've consumed a quarter of the ring and still have
+			 * more to do.  Refill the ring.
+			 */
+			bcmeth_rxq_produce(sc, &sc->sc_rxq);
+		}
 		intmask |= RCVINT;
 	}
 
@@ -1949,7 +1966,14 @@ bcmeth_worker(struct work *wk, void *arg
 		/*
 		 * Let's consume 
 		 */
-		bcmeth_rxq_consume(sc, &sc->sc_rxq);
+		while (bcmeth_rxq_consume(sc, &sc->sc_rxq,
+		    sc->sc_rxq.rxq_threshold / 4)) {
+			/*
+			 * We've consumed a quarter of the ring and still have
+			 * more to do.  Refill the ring.
+			 */
+			bcmeth_rxq_produce(sc, &sc->sc_rxq);
+		}
 		intmask |= RCVINT;
 	}
 

Reply via email to