int bce_intr(void *xsc) { struct bce_softc *sc; struct ifnet *ifp; u_int32_t intstatus; int wantinit; int handled = 0; sc = xsc; ifp = &sc->bce_ac.ac_if; for (wantinit = 0; wantinit == 0;) { intstatus = bus_space_read_4(sc->bce_btag, sc->bce_bhandle, BCE_INT_STS); /* ignore if not ours, or unsolicited interrupts */ intstatus &= sc->bce_intmask; if (intstatus == 0) break; handled = 1; /* Ack interrupt */ bus_space_write_4(sc->bce_btag, sc->bce_bhandle, BCE_INT_STS, intstatus); /* Receive interrupts. */ if (intstatus & I_RI) bce_rxintr(sc); /* Transmit interrupts. */ if (intstatus & I_XI) bce_txintr(sc); /* Error interrupts */ if (intstatus & ~(I_RI | I_XI)) { if (intstatus & I_XU) printf("%s: transmit fifo underflow\n", sc->bce_dev.dv_xname); if (intstatus & I_RO) { printf("%s: receive fifo overflow\n", sc->bce_dev.dv_xname); ifp->if_ierrors++; } if (intstatus & I_RU) printf("%s: receive descriptor underflow\n", sc->bce_dev.dv_xname); if (intstatus & I_DE) printf("%s: descriptor protocol error\n", sc->bce_dev.dv_xname); if (intstatus & I_PD) printf("%s: data error\n", sc->bce_dev.dv_xname); if (intstatus & I_PC) printf("%s: descriptor error\n", sc->bce_dev.dv_xname); if (intstatus & I_TO) printf("%s: general purpose timeout\n", sc->bce_dev.dv_xname); wantinit = 1; } } if (handled) { if (wantinit) bce_init(ifp); /* Try to get more packets going. */ bce_start(ifp); } return (handled); }
int bce_intr(void *xsc) { struct bce_softc *sc; struct ifnet *ifp; uint32_t intstatus; int wantinit; int handled = 0; sc = xsc; ifp = &sc->ethercom.ec_if; for (wantinit = 0; wantinit == 0;) { intstatus = bus_space_read_4(sc->bce_btag, sc->bce_bhandle, BCE_INT_STS); /* ignore if not ours, or unsolicited interrupts */ intstatus &= sc->bce_intmask; if (intstatus == 0) break; handled = 1; /* Ack interrupt */ bus_space_write_4(sc->bce_btag, sc->bce_bhandle, BCE_INT_STS, intstatus); /* Receive interrupts. */ if (intstatus & I_RI) bce_rxintr(sc); /* Transmit interrupts. */ if (intstatus & I_XI) bce_txintr(sc); /* Error interrupts */ if (intstatus & ~(I_RI | I_XI)) { const char *msg = NULL; if (intstatus & I_XU) msg = "transmit fifo underflow"; if (intstatus & I_RO) { msg = "receive fifo overflow"; ifp->if_ierrors++; } if (intstatus & I_RU) msg = "receive descriptor underflow"; if (intstatus & I_DE) msg = "descriptor protocol error"; if (intstatus & I_PD) msg = "data error"; if (intstatus & I_PC) msg = "descriptor error"; if (intstatus & I_TO) msg = "general purpose timeout"; if (msg != NULL) aprint_error_dev(sc->bce_dev, "%s\n", msg); wantinit = 1; } } if (handled) { if (wantinit) bce_init(ifp); rnd_add_uint32(&sc->rnd_source, intstatus); /* Try to get more packets going. */ bce_start(ifp); } return (handled); }