Index: if_nfe.c
===================================================================
RCS file: /home/ncvs/src/sys/dev/nfe/if_nfe.c,v
retrieving revision 1.21.2.6
diff -u -r1.21.2.6 if_nfe.c
--- if_nfe.c	20 Aug 2008 05:12:30 -0000	1.21.2.6
+++ if_nfe.c	16 Sep 2008 12:19:26 -0000
@@ -1769,25 +1769,21 @@
 {
 	struct nfe_softc *sc = arg;
 	struct ifnet *ifp = sc->nfe_ifp;
-	uint32_t r;
-	int domore;
+	int domore = 0;	/* pending work from previous nfe_[j]rxeof() calls */
 
 	NFE_LOCK(sc);
-
-	if ((r = NFE_READ(sc, sc->nfe_irq_status)) == 0) {
-		nfe_enable_intr(sc);
-		NFE_UNLOCK(sc);
-		return;	/* not for us */
-	}
-	NFE_WRITE(sc, sc->nfe_irq_status, r);
+    for (;;) {
+	uint32_t r = NFE_READ(sc, sc->nfe_irq_status);
+	if (r == 0 && !domore)
+		break; /* not for us, or we are done */
+	if (r)
+		NFE_WRITE(sc, sc->nfe_irq_status, r);
 
 	DPRINTFN(sc, 5, "nfe_intr: interrupt register %x\n", r);
 
 #ifdef DEVICE_POLLING
-	if (ifp->if_capenable & IFCAP_POLLING) {
-		NFE_UNLOCK(sc);
-		return;
-	}
+	if (ifp->if_capenable & IFCAP_POLLING)
+		break;	/* in polling, we ignore interrupts */
 #endif
 
 	if (r & NFE_IRQ_LINK) {
@@ -1796,13 +1792,9 @@
 		DPRINTF(sc, "link state changed\n");
 	}
 
-	if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) {
-		NFE_UNLOCK(sc);
-		nfe_enable_intr(sc);
-		return;
-	}
+	if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0)
+		break;	/* not running, ignore interrupts */
 
-	domore = 0;
 	/* check Rx ring */
 	if (sc->nfe_framesize > MCLBYTES - ETHER_HDR_LEN)
 		domore = nfe_jrxeof(sc, sc->nfe_process_limit);
@@ -1813,16 +1805,10 @@
 
 	if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd))
 		taskqueue_enqueue_fast(sc->nfe_tq, &sc->nfe_tx_task);
-
-	NFE_UNLOCK(sc);
-
-	if (domore || (NFE_READ(sc, sc->nfe_irq_status) != 0)) {
-		taskqueue_enqueue_fast(sc->nfe_tq, &sc->nfe_int_task);
-		return;
-	}
-
+    }
 	/* Reenable interrupts. */
 	nfe_enable_intr(sc);
+	NFE_UNLOCK(sc);
 }
 
 
