Static int url_ioctl(struct ifnet *ifp, u_long cmd, void *data) { struct url_softc *sc = ifp->if_softc; int s, error = 0; DPRINTF(("%s: %s: enter\n", device_xname(sc->sc_dev), __func__)); if (sc->sc_dying) return (EIO); s = splnet(); error = ether_ioctl(ifp, cmd, data); if (error == ENETRESET) { if (ifp->if_flags & IFF_RUNNING) url_setmulti(sc); error = 0; } splx(s); return (error); }
Static int url_init(struct ifnet *ifp) { struct url_softc *sc = ifp->if_softc; struct mii_data *mii = GET_MII(sc); u_char *eaddr; int i, s; DPRINTF(("%s: %s: enter\n", USBDEVNAME(sc->sc_dev), __func__)); if (sc->sc_dying) return (EIO); s = splnet(); /* Cancel pending I/O and free all TX/RX buffers */ url_stop(ifp, 1); #if defined(__OpenBSD__) eaddr = sc->sc_ac.ac_enaddr; #elif defined(__NetBSD__) eaddr = LLADDR(ifp->if_sadl); #endif for (i = 0; i < ETHER_ADDR_LEN; i++) url_csr_write_1(sc, URL_IDR0 + i, eaddr[i]); /* Init transmission control register */ URL_CLRBIT(sc, URL_TCR, URL_TCR_TXRR1 | URL_TCR_TXRR0 | URL_TCR_IFG1 | URL_TCR_IFG0 | URL_TCR_NOCRC); /* Init receive control register */ URL_SETBIT2(sc, URL_RCR, URL_RCR_TAIL | URL_RCR_AD); if (ifp->if_flags & IFF_BROADCAST) URL_SETBIT2(sc, URL_RCR, URL_RCR_AB); else URL_CLRBIT2(sc, URL_RCR, URL_RCR_AB); /* If we want promiscuous mode, accept all physical frames. */ if (ifp->if_flags & IFF_PROMISC) URL_SETBIT2(sc, URL_RCR, URL_RCR_AAM|URL_RCR_AAP); else URL_CLRBIT2(sc, URL_RCR, URL_RCR_AAM|URL_RCR_AAP); /* Initialize transmit ring */ if (url_tx_list_init(sc) == ENOBUFS) { printf("%s: tx list init failed\n", USBDEVNAME(sc->sc_dev)); splx(s); return (EIO); } /* Initialize receive ring */ if (url_rx_list_init(sc) == ENOBUFS) { printf("%s: rx list init failed\n", USBDEVNAME(sc->sc_dev)); splx(s); return (EIO); } /* Load the multicast filter */ url_setmulti(sc); /* Enable RX and TX */ URL_SETBIT(sc, URL_CR, URL_CR_TE | URL_CR_RE); mii_mediachg(mii); if (sc->sc_pipe_tx == NULL || sc->sc_pipe_rx == NULL) { if (url_openpipes(sc)) { splx(s); return (EIO); } } ifp->if_flags |= IFF_RUNNING; ifp->if_flags &= ~IFF_OACTIVE; splx(s); usb_callout(sc->sc_stat_ch, hz, url_tick, sc); return (0); }
Static int url_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) { struct url_softc *sc = ifp->if_softc; struct ifaddr *ifa = (struct ifaddr *)data; struct ifreq *ifr = (struct ifreq *)data; struct mii_data *mii; int s, error = 0; DPRINTF(("%s: %s: enter\n", USBDEVNAME(sc->sc_dev), __func__)); if (sc->sc_dying) return (EIO); s = splnet(); switch (cmd) { case SIOCSIFADDR: ifp->if_flags |= IFF_UP; url_init(ifp); switch (ifa->ifa_addr->sa_family) { #ifdef INET case AF_INET: arp_ifinit(&sc->sc_ac, ifa); break; #endif /* INET */ } break; case SIOCSIFMTU: if (ifr->ifr_mtu > ETHERMTU) error = EINVAL; else ifp->if_mtu = ifr->ifr_mtu; break; case SIOCSIFFLAGS: if (ifp->if_flags & IFF_UP) { if (ifp->if_flags & IFF_RUNNING && ifp->if_flags & IFF_PROMISC) { URL_SETBIT2(sc, URL_RCR, URL_RCR_AAM|URL_RCR_AAP); } else if (ifp->if_flags & IFF_RUNNING && !(ifp->if_flags & IFF_PROMISC)) { URL_CLRBIT2(sc, URL_RCR, URL_RCR_AAM|URL_RCR_AAP); } else if (!(ifp->if_flags & IFF_RUNNING)) url_init(ifp); } else { if (ifp->if_flags & IFF_RUNNING) url_stop(ifp, 1); } error = 0; break; case SIOCADDMULTI: case SIOCDELMULTI: error = (cmd == SIOCADDMULTI) ? ether_addmulti(ifr, &sc->sc_ac) : ether_delmulti(ifr, &sc->sc_ac); if (error == ENETRESET) { if (ifp->if_flags & IFF_RUNNING) url_setmulti(sc); error = 0; } break; case SIOCGIFMEDIA: case SIOCSIFMEDIA: mii = GET_MII(sc); error = ifmedia_ioctl(ifp, ifr, &mii->mii_media, cmd); break; default: error = EINVAL; break; } splx(s); return (error); }