/* Watchdog timer handler. */ void bce_watchdog(struct ifnet *ifp) { struct bce_softc *sc = ifp->if_softc; printf("%s: device timeout\n", sc->bce_dev.dv_xname); ifp->if_oerrors++; (void) bce_init(ifp); /* Try to get more packets going. */ bce_start(ifp); }
/* Watchdog timer handler. */ static void bce_watchdog(struct ifnet *ifp) { struct bce_softc *sc = ifp->if_softc; aprint_error_dev(sc->bce_dev, "device timeout\n"); ifp->if_oerrors++; (void) bce_init(ifp); /* Try to get more packets going. */ bce_start(ifp); }
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); }
/* handle media, and ethernet requests */ int bce_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) { struct bce_softc *sc = ifp->if_softc; struct ifreq *ifr = (struct ifreq *) data; struct ifaddr *ifa = (struct ifaddr *)data; int s, error = 0; s = splnet(); if ((error = ether_ioctl(ifp, &sc->bce_ac, cmd, data)) > 0) { splx(s); return (error); } switch (cmd) { case SIOCSIFADDR: ifp->if_flags |= IFF_UP; switch (ifa->ifa_addr->sa_family) { #ifdef INET case AF_INET: bce_init(ifp); arp_ifinit(&sc->bce_ac, ifa); break; #endif /* INET */ default: bce_init(ifp); break; } break; case SIOCSIFMTU: if (ifr->ifr_mtu < ETHERMIN || ifr->ifr_mtu > ETHERMTU) error = EINVAL; else if (ifp->if_mtu != ifr->ifr_mtu) ifp->if_mtu = ifr->ifr_mtu; break; case SIOCSIFFLAGS: if(ifp->if_flags & IFF_UP) if(ifp->if_flags & IFF_RUNNING) bce_set_filter(ifp); else bce_init(ifp); else if(ifp->if_flags & IFF_RUNNING) bce_stop(ifp, 0); break; case SIOCADDMULTI: case SIOCDELMULTI: error = (cmd == SIOCADDMULTI) ? ether_addmulti(ifr, &sc->bce_ac) : ether_delmulti(ifr, &sc->bce_ac); if (error == ENETRESET) { /* * Multicast list has changed; set the hardware * filter accordingly. */ if (ifp->if_flags & IFF_RUNNING) bce_set_filter(ifp); error = 0; } break; case SIOCSIFMEDIA: case SIOCGIFMEDIA: error = ifmedia_ioctl(ifp, ifr, &sc->bce_mii.mii_media, cmd); break; default: error = ENOTTY; break; } if (error == 0) { /* Try to get more packets going. */ bce_start(ifp); } splx(s); return error; }
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); }