/* * Reset interface. */ void qereset(struct qe_softc *sc) { int s; s = splnet(); qestop(sc); qeinit(sc); splx(s); }
/* * Check for dead transmit logic. Not uncommon. */ void qetimeout(struct ifnet *ifp) { struct qe_softc *sc = ifp->if_softc; if (sc->sc_inq == 0) return; printf("%s: xmit logic died, resetting...\n", sc->sc_dev.dv_xname); /* * Do a reset of interface, to get it going again. * Will it work by just restart the transmit logic? */ qeinit(sc); }
/* * Process an ioctl request. */ int qeioctl(struct ifnet *ifp, u_long cmd, caddr_t data) { struct qe_softc *sc = ifp->if_softc; struct ifaddr *ifa = (struct ifaddr *)data; int s, error = 0; s = splnet(); switch (cmd) { case SIOCSIFADDR: ifp->if_flags |= IFF_UP; switch(ifa->ifa_addr->sa_family) { #ifdef INET case AF_INET: qeinit(sc); arp_ifinit(&sc->sc_ac, ifa); break; #endif } break; case SIOCSIFFLAGS: if ((ifp->if_flags & IFF_UP) == 0 && (ifp->if_flags & IFF_RUNNING) != 0) { /* * If interface is marked down and it is running, * stop it. (by disabling receive mechanism). */ QE_WCSR(QE_CSR_CSR, QE_RCSR(QE_CSR_CSR) & ~QE_RCV_ENABLE); ifp->if_flags &= ~IFF_RUNNING; } else if ((ifp->if_flags & IFF_UP) != 0 && (ifp->if_flags & IFF_RUNNING) == 0) { /* * If interface it marked up and it is stopped, then * start it. */ qeinit(sc); } else if ((ifp->if_flags & IFF_UP) != 0) { /* * Send a new setup packet to match any new changes. * (Like IFF_PROMISC etc) */ qe_setup(sc); } break; default: error = ether_ioctl(ifp, &sc->sc_ac, cmd, data); } if (error == ENETRESET) { if (ifp->if_flags & IFF_RUNNING) qe_setup(sc); error = 0; } splx(s); return (error); }
int qeioctl(struct ifnet *ifp, u_long cmd, void *data) { struct qe_softc *sc = ifp->if_softc; struct ifaddr *ifa = data; struct ifreq *ifr = data; int s, error = 0; s = splnet(); switch (cmd) { case SIOCINITIFADDR: ifp->if_flags |= IFF_UP; qeinit(sc); switch (ifa->ifa_addr->sa_family) { #ifdef INET case AF_INET: arp_ifinit(ifp, ifa); break; #endif /* INET */ default: break; } break; case SIOCSIFFLAGS: if ((error = ifioctl_common(ifp, cmd, data)) != 0) break; /* XXX re-use ether_ioctl() */ switch (ifp->if_flags & (IFF_UP|IFF_RUNNING)) { case IFF_RUNNING: /* * If interface is marked down and it is running, then * stop it. */ qestop(sc); ifp->if_flags &= ~IFF_RUNNING; break; case IFF_UP: /* * If interface is marked up and it is stopped, then * start it. */ qeinit(sc); break; default: /* * Reset the interface to pick up changes in any other * flags that affect hardware registers. */ qestop(sc); qeinit(sc); break; } #ifdef QEDEBUG sc->sc_debug = (ifp->if_flags & IFF_DEBUG) != 0 ? 1 : 0; #endif break; case SIOCADDMULTI: case SIOCDELMULTI: if ((error = ether_ioctl(ifp, cmd, data)) == ENETRESET) { /* * Multicast list has changed; set the hardware filter * accordingly. */ if (ifp->if_flags & IFF_RUNNING) qe_mcreset(sc); error = 0; } break; case SIOCGIFMEDIA: case SIOCSIFMEDIA: error = ifmedia_ioctl(ifp, ifr, &sc->sc_ifmedia, cmd); break; default: error = ether_ioctl(ifp, cmd, data); break; } splx(s); return (error); }