--- a/sys/dev/netif/age/if_age.c +++ b/sys/dev/netif/age/if_age.c @@ -1877,10 +1877,12 @@ age_intr(void *xsc) cmb = sc->age_rdata.age_cmb_block; bus_dmamap_sync(sc->age_cdata.age_cmb_block_tag, sc->age_cdata.age_cmb_block_map, BUS_DMASYNC_POSTREAD); status = le32toh(cmb->intr_status); if ((status & AGE_INTRS) == 0) goto done; again: - sc->age_tpd_cons = (le32toh(cmb->tpd_cons) & TPD_CONS_MASK) >> - TPD_CONS_SHIFT; - sc->age_rr_prod = (le32toh(cmb->rprod_cons) & RRD_PROD_MASK) >> - RRD_PROD_SHIFT; + /* ring indices are modulo the ring sizes, not the 16-bit field */ + sc->age_tpd_cons = ((le32toh(cmb->tpd_cons) & TPD_CONS_MASK) >> + TPD_CONS_SHIFT) % AGE_TX_RING_CNT; + sc->age_rr_prod = ((le32toh(cmb->rprod_cons) & RRD_PROD_MASK) >> + RRD_PROD_SHIFT) % AGE_RR_RING_CNT; @@ -2146,7 +2148,8 @@ age_rxintr(struct age_softc *sc, int rr_prod) bus_dmamap_sync(sc->age_cdata.age_rr_ring_tag, sc->age_cdata.age_rr_ring_map, BUS_DMASYNC_POSTREAD); - for (prog = 0; rr_cons != rr_prod; prog++) { + /* bound the work done per interrupt (AGE_PROC_DEFAULT was dead) */ + for (prog = 0; rr_cons != rr_prod && prog < AGE_PROC_DEFAULT; prog++) { rxrd = &sc->age_rdata.age_rr_ring[rr_cons]; nsegs = AGE_RX_NSEGS(le32toh(rxrd->index)); if (nsegs == 0)