void pdq_ifinit( pdq_softc_t *sc) { if (sc->sc_if.if_flags & IFF_UP) { sc->sc_if.if_flags |= IFF_RUNNING; if (sc->sc_if.if_flags & IFF_PROMISC) { sc->sc_pdq->pdq_flags |= PDQ_PROMISC; } else { sc->sc_pdq->pdq_flags &= ~PDQ_PROMISC; } if (sc->sc_if.if_flags & IFF_ALLMULTI) { sc->sc_pdq->pdq_flags |= PDQ_ALLMULTI; } else { sc->sc_pdq->pdq_flags &= ~PDQ_ALLMULTI; } if (sc->sc_if.if_flags & IFF_LINK1) { sc->sc_pdq->pdq_flags |= PDQ_PASS_SMT; } else { sc->sc_pdq->pdq_flags &= ~PDQ_PASS_SMT; } sc->sc_pdq->pdq_flags |= PDQ_RUNNING; pdq_run(sc->sc_pdq); } else { sc->sc_if.if_flags &= ~IFF_RUNNING; sc->sc_pdq->pdq_flags &= ~PDQ_RUNNING; pdq_stop(sc->sc_pdq); } }
static int pdq_ifmedia_change( struct ifnet *ifp) { pdq_softc_t * const sc = PDQ_OS_IFP_TO_SOFTC(ifp); PDQ_LOCK(sc); if (sc->sc_ifmedia.ifm_media & IFM_FDX) { if ((sc->sc_pdq->pdq_flags & PDQ_WANT_FDX) == 0) { sc->sc_pdq->pdq_flags |= PDQ_WANT_FDX; if (sc->sc_pdq->pdq_flags & PDQ_RUNNING) pdq_run(sc->sc_pdq); } } else if (sc->sc_pdq->pdq_flags & PDQ_WANT_FDX) { sc->sc_pdq->pdq_flags &= ~PDQ_WANT_FDX; if (sc->sc_pdq->pdq_flags & PDQ_RUNNING) pdq_run(sc->sc_pdq); } PDQ_UNLOCK(sc); return 0; }
static int pdq_ifioctl( struct ifnet *ifp, u_long cmd, caddr_t data) { pdq_softc_t *sc = PDQ_OS_IFP_TO_SOFTC(ifp); int error = 0; switch (cmd) { case SIOCSIFFLAGS: { pdq_ifinit(sc); break; } case SIOCADDMULTI: case SIOCDELMULTI: { PDQ_LOCK(sc); if (PDQ_IFNET(sc)->if_drv_flags & IFF_DRV_RUNNING) { pdq_run(sc->sc_pdq); error = 0; } PDQ_UNLOCK(sc); break; } #if defined(IFM_FDDI) && defined(SIOCSIFMEDIA) case SIOCSIFMEDIA: case SIOCGIFMEDIA: { struct ifreq *ifr = (struct ifreq *)data; error = ifmedia_ioctl(ifp, ifr, &sc->sc_ifmedia, cmd); break; } #endif default: { error = fddi_ioctl(ifp, cmd, data); break; } } return error; }
static void pdq_ifinit_locked(pdq_softc_t *sc) { PDQ_LOCK_ASSERT(sc); if (PDQ_IFNET(sc)->if_flags & IFF_UP) { PDQ_IFNET(sc)->if_drv_flags |= IFF_DRV_RUNNING; if (PDQ_IFNET(sc)->if_flags & IFF_PROMISC) { sc->sc_pdq->pdq_flags |= PDQ_PROMISC; } else { sc->sc_pdq->pdq_flags &= ~PDQ_PROMISC; } if (PDQ_IFNET(sc)->if_flags & IFF_LINK1) { sc->sc_pdq->pdq_flags |= PDQ_PASS_SMT; } else { sc->sc_pdq->pdq_flags &= ~PDQ_PASS_SMT; } sc->sc_pdq->pdq_flags |= PDQ_RUNNING; pdq_run(sc->sc_pdq); callout_reset(&sc->watchdog, hz, pdq_watchdog, sc); } else pdq_ifstop(sc); }
int pdq_ifioctl( struct ifnet *ifp, ioctl_cmd_t cmd, caddr_t data) { pdq_softc_t *sc = (pdq_softc_t *) ((caddr_t) ifp - offsetof(pdq_softc_t, sc_arpcom.ac_if)); int s, error = 0; s = splnet(); switch (cmd) { case SIOCSIFADDR: { struct ifaddr *ifa = (struct ifaddr *)data; ifp->if_flags |= IFF_UP; switch(ifa->ifa_addr->sa_family) { #if defined(INET) case AF_INET: { pdq_ifinit(sc); arp_ifinit(&sc->sc_arpcom, ifa); break; } #endif /* INET */ #if defined(NS) /* This magic copied from if_is.c; I don't use XNS, * so I have no way of telling if this actually * works or not. */ case AF_NS: { struct ns_addr *ina = &(IA_SNS(ifa)->sns_addr); if (ns_nullhost(*ina)) { ina->x_host = *(union ns_host *)(sc->sc_arpcom.ac_enaddr); } else { ifp->if_flags &= ~IFF_RUNNING; bcopy((caddr_t)ina->x_host.c_host, (caddr_t)sc->sc_arpcom.ac_enaddr, sizeof sc->sc_arpcom.ac_enaddr); } pdq_ifinit(sc); break; } #endif /* NS */ default: { pdq_ifinit(sc); break; } } break; } case SIOCSIFFLAGS: { pdq_ifinit(sc); break; } case SIOCADDMULTI: case SIOCDELMULTI: { /* * Update multicast listeners */ if (cmd == SIOCADDMULTI) error = ether_addmulti((struct ifreq *)data, &sc->sc_arpcom); else error = ether_delmulti((struct ifreq *)data, &sc->sc_arpcom); if (error == ENETRESET) { if (sc->sc_if.if_flags & IFF_RUNNING) pdq_run(sc->sc_pdq); error = 0; } break; } default: { error = EINVAL; break; } } splx(s); return error; }