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); }