Ejemplo n.º 1
0
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);
    }
}
Ejemplo n.º 2
0
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;
}
Ejemplo n.º 3
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;
}
Ejemplo n.º 4
0
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);
}
Ejemplo n.º 5
0
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;
}