int
wanpipe_generic_register(sdla_t *card, struct ifnet *ifp, char *ifname)
{
	wanpipe_common_t*	common = WAN_IFP_TO_COMMON(ifp);

	if (ifname == NULL || strlen(ifname) > IFNAMSIZ)
		return (EINVAL);
	else
		bcopy(ifname, ifp->if_xname, strlen(ifname));

	IFQ_SET_MAXLEN(&ifp->if_snd, IFQ_MAXLEN);
	IFQ_SET_READY(&ifp->if_snd);
	ifp->if_mtu = PP_MTU;
	ifp->if_flags = IFF_POINTOPOINT | IFF_MULTICAST;
	common->protocol = IF_PROTO_CISCO;

	((struct sppp *)ifp)->pp_flags |= PP_CISCO;
	((struct sppp *)ifp)->pp_flags |= PP_KEEPALIVE;
	((struct sppp *)ifp)->pp_framebytes = 3;

	ifp->if_ioctl = wanpipe_generic_ioctl;	/* Will set from new_if() */
	ifp->if_start = wanpipe_generic_start;
	ifp->if_watchdog = wanpipe_generic_watchdog;

	if_attach(ifp);
	if_alloc_sadl(ifp);
	sppp_attach(ifp);

#if NBPFILTER > 0
	bpfattach(&ifp->if_bpf, ifp, DLT_PPP, PPP_HEADER_LEN);
#endif /* NBPFILTER > 0 */

	return (0);
}
Exemple #2
0
int
gif_clone_create(struct if_clone *ifc, int unit)
{
	struct gif_softc *sc;
	int s;

	sc = malloc(sizeof(*sc), M_DEVBUF, M_NOWAIT|M_ZERO);
	if (!sc)
		return (ENOMEM);

	snprintf(sc->gif_if.if_xname, sizeof sc->gif_if.if_xname,
	     "%s%d", ifc->ifc_name, unit);
	sc->gif_if.if_mtu    = GIF_MTU;
	sc->gif_if.if_flags  = IFF_POINTOPOINT | IFF_MULTICAST;
	sc->gif_if.if_ioctl  = gif_ioctl;
	sc->gif_if.if_start  = gif_start;
	sc->gif_if.if_output = gif_output;
	sc->gif_if.if_type   = IFT_GIF;
	IFQ_SET_MAXLEN(&sc->gif_if.if_snd, ifqmaxlen);
	IFQ_SET_READY(&sc->gif_if.if_snd);
	sc->gif_if.if_softc = sc;
	if_attach(&sc->gif_if);
	if_alloc_sadl(&sc->gif_if);

#if NBPFILTER > 0
	bpfattach(&sc->gif_if.if_bpf, &sc->gif_if, DLT_LOOP, sizeof(u_int32_t));
#endif
	s = splnet();
	LIST_INSERT_HEAD(&gif_softc_list, sc, gif_list);
	splx(s);

	return (0);
}
Exemple #3
0
static int
virtif_create(struct ifnet *ifp)
{
	uint8_t enaddr[ETHER_ADDR_LEN];
	char enaddrstr[3*ETHER_ADDR_LEN];
	struct virtif_sc *sc = ifp->if_softc;
	int error;

	if (sc->sc_viu)
		panic("%s: already created", ifp->if_xname);

	/* XXX generalize */
	virt_hwaddr(ifp->if_xname, enaddr);

	if ((error = VIFHYPER_CREATE(sc->sc_linkstr,
	    sc, enaddr, &sc->sc_viu)) != 0) {
		printf("VIFHYPER_CREATE failed: %d\n", error);
		return error;
	}

	ether_ifattach(ifp, enaddr);
	ether_snprintf(enaddrstr, sizeof(enaddrstr), enaddr);
	aprint_normal_ifnet(ifp, "Ethernet address %s\n", enaddrstr);

	IFQ_SET_READY(&ifp->if_snd);

	return 0;
}
Exemple #4
0
static int
virtif_create(struct ifnet *ifp)
{
	uint8_t enaddr[ETHER_ADDR_LEN] = { 0xb2, 0x0a, 0x00, 0x0b, 0x0e, 0x01 };
	char enaddrstr[3*ETHER_ADDR_LEN];
	struct virtif_sc *sc = ifp->if_softc;
	int error;

	if (sc->sc_viu)
		panic("%s: already created", ifp->if_xname);

	enaddr[2] = cprng_fast32() & 0xff;
	enaddr[5] = sc->sc_num & 0xff;

	if ((error = VIFHYPER_CREATE(sc->sc_linkstr,
	    sc, enaddr, &sc->sc_viu)) != 0) {
		printf("VIFHYPER_CREATE failed: %d\n", error);
		return error;
	}

	ether_ifattach(ifp, enaddr);
	ether_snprintf(enaddrstr, sizeof(enaddrstr), enaddr);
	aprint_normal_ifnet(ifp, "Ethernet address %s\n", enaddrstr);

	IFQ_SET_READY(&ifp->if_snd);

	return 0;
}
Exemple #5
0
/*
 * Interface exists: make available by filling in network interface
 * record.  System will initialize the interface when it is ready
 * to accept packets.
 */
void
dmcattach(device_t parent, device_t self, void *aux)
{
	struct uba_attach_args *ua = aux;
	struct dmc_softc *sc = device_private(self);

	sc->sc_dev = self;
	sc->sc_iot = ua->ua_iot;
	sc->sc_ioh = ua->ua_ioh;
	sc->sc_dmat = ua->ua_dmat;

	strlcpy(sc->sc_if.if_xname, device_xname(sc->sc_dev), IFNAMSIZ);
	sc->sc_if.if_mtu = DMCMTU;
	sc->sc_if.if_init = dmcinit;
	sc->sc_if.if_output = dmcoutput;
	sc->sc_if.if_ioctl = dmcioctl;
	sc->sc_if.if_watchdog = dmctimeout;
	sc->sc_if.if_flags = IFF_POINTOPOINT;
	sc->sc_if.if_softc = sc;
	IFQ_SET_READY(&sc->sc_if.if_snd);

	uba_intr_establish(ua->ua_icookie, ua->ua_cvec, dmcrint, sc,
	    &sc->sc_rintrcnt);
	uba_intr_establish(ua->ua_icookie, ua->ua_cvec+4, dmcxint, sc,
	    &sc->sc_tintrcnt);
	uba_reset_establish(dmcreset, sc->sc_dev);
	evcnt_attach_dynamic(&sc->sc_rintrcnt, EVCNT_TYPE_INTR, ua->ua_evcnt,
	    device_xname(sc->sc_dev), "intr");
	evcnt_attach_dynamic(&sc->sc_tintrcnt, EVCNT_TYPE_INTR, ua->ua_evcnt,
	    device_xname(sc->sc_dev), "intr");

	if_attach(&sc->sc_if);
}
static void
tunattach0(struct tun_softc *tp)
{
	struct ifnet *ifp;

	ifp = &tp->tun_if;
	ifp->if_softc = tp;
	ifp->if_mtu = TUNMTU;
	ifp->if_ioctl = tun_ioctl;
	ifp->if_output = tun_output;
#ifdef ALTQ
	ifp->if_start = tunstart;
#endif
	ifp->if_flags = IFF_POINTOPOINT;
	ifp->if_type = IFT_TUNNEL;
	ifp->if_snd.ifq_maxlen = ifqmaxlen;
	ifp->if_collisions = 0;
	ifp->if_ierrors = 0;
	ifp->if_oerrors = 0;
	ifp->if_ipackets = 0;
	ifp->if_opackets = 0;
	ifp->if_ibytes   = 0;
	ifp->if_obytes   = 0;
	ifp->if_dlt = DLT_NULL;
	IFQ_SET_READY(&ifp->if_snd);
	if_attach(ifp);
	if_alloc_sadl(ifp);
	bpf_attach(ifp, DLT_NULL, sizeof(uint32_t));
}
void
pdq_ifattach(
    pdq_softc_t *sc,
    ifnet_ret_t (*ifwatchdog)(int unit))
{
    struct ifnet *ifp = &sc->sc_if;

    ifp->if_flags = IFF_BROADCAST|IFF_SIMPLEX|IFF_NOTRAILERS|IFF_MULTICAST;

#if (defined(__FreeBSD__) && BSD >= 199506) || defined(__NetBSD__) || \
	defined(__OpenBSD__)
    ifp->if_watchdog = pdq_ifwatchdog;
#else
    ifp->if_watchdog = ifwatchdog;
#endif

    ifp->if_ioctl = pdq_ifioctl;
    ifp->if_start = pdq_ifstart;
    IFQ_SET_READY(&ifp->if_snd);

    if_attach(ifp);
    fddi_ifattach(ifp);
#if NBPFILTER > 0
    PDQ_BPFATTACH(sc, DLT_FDDI, sizeof(struct fddi_header));
#endif
}
Exemple #8
0
int
loop_clone_create(struct if_clone *ifc, int unit)
{
	struct ifnet *ifp;

	ifp = malloc(sizeof(*ifp), M_DEVBUF, M_NOWAIT|M_ZERO);
	if (ifp == NULL)
		return (ENOMEM);

	snprintf(ifp->if_xname, sizeof ifp->if_xname, "lo%d", unit);
	ifp->if_softc = NULL;
	ifp->if_mtu = LOMTU;
	ifp->if_flags = IFF_LOOPBACK | IFF_MULTICAST;
	ifp->if_rtrequest = lortrequest;
	ifp->if_ioctl = loioctl;
	ifp->if_output = looutput;
	ifp->if_type = IFT_LOOP;
	ifp->if_hdrlen = sizeof(u_int32_t);
	ifp->if_addrlen = 0;
	IFQ_SET_READY(&ifp->if_snd);
	if (unit == 0) {
		if_attachhead(ifp);
		if_addgroup(ifp, ifc->ifc_name);
		lo0ifidx = ifp->if_index;
	} else
		if_attach(ifp);
	if_alloc_sadl(ifp);
#if NBPFILTER > 0
	bpfattach(&ifp->if_bpf, ifp, DLT_LOOP, sizeof(u_int32_t));
#endif
	return (0);
}
Exemple #9
0
/*
 * Called from boot code to establish sl interfaces.
 */
void
slattach()
{
    struct sl_softc *sc;
    int i = 0;

    for (sc = sl_softc; i < NSL; sc++) {
        sc->sc_unit = i;		/* XXX */
        sprintf(sc->sc_if.if_xname, "sl%d", i++);
        sc->sc_if.if_softc = sc;
        sc->sc_if.if_mtu = SLMTU;
        sc->sc_if.if_flags =
            IFF_POINTOPOINT | SC_AUTOCOMP | IFF_MULTICAST;
        sc->sc_if.if_type = IFT_SLIP;
        sc->sc_if.if_ioctl = slioctl;
        sc->sc_if.if_output = sloutput;
        sc->sc_if.if_dlt = DLT_SLIP;
        sc->sc_fastq.ifq_maxlen = 32;
        IFQ_SET_READY(&sc->sc_if.if_snd);
        if_attach(&sc->sc_if);
        if_alloc_sadl(&sc->sc_if);
#if NBPFILTER > 0
        bpfattach(&sc->sc_if, DLT_SLIP, SLIP_HDRLEN);
#endif
    }
}
Exemple #10
0
static void
tuncreate(struct cdev *dev)
{
	struct tun_softc *sc;
	struct ifnet *ifp;

	dev->si_flags &= ~SI_CHEAPCLONE;

	MALLOC(sc, struct tun_softc *, sizeof(*sc), M_TUN, M_WAITOK | M_ZERO);
	mtx_init(&sc->tun_mtx, "tun_mtx", NULL, MTX_DEF);
	sc->tun_flags = TUN_INITED;
	sc->tun_dev = dev;
	mtx_lock(&tunmtx);
	TAILQ_INSERT_TAIL(&tunhead, sc, tun_list);
	mtx_unlock(&tunmtx);

	ifp = &sc->tun_if;
	if_initname(ifp, TUNNAME, dev2unit(dev));
	ifp->if_mtu = TUNMTU;
	ifp->if_ioctl = tunifioctl;
	ifp->if_output = tunoutput;
	ifp->if_start = tunstart;
	ifp->if_flags = IFF_POINTOPOINT | IFF_MULTICAST;
	ifp->if_type = IFT_PPP;
	ifp->if_softc = sc;
	IFQ_SET_MAXLEN(&ifp->if_snd, ifqmaxlen);
	ifp->if_snd.ifq_drv_maxlen = 0;
	IFQ_SET_READY(&ifp->if_snd);

	if_attach(ifp);
	bpfattach(ifp, DLT_NULL, sizeof(u_int));
	dev->si_drv1 = sc;
}
Exemple #11
0
/*
 * Interface exists: make available by filling in network interface
 * record.  System will initialize the interface when it is ready
 * to accept packets.  A STATUS command is done to get the ethernet
 * address and other interesting data.
 */
void
ilattach(device_t parent, device_t self, void *aux)
{
	struct uba_attach_args *ua = aux;
	struct il_softc *sc = device_private(self);
	struct ifnet *ifp = &sc->sc_if;
	int error;

	sc->sc_dev = self;
	sc->sc_iot = ua->ua_iot;
	sc->sc_ioh = ua->ua_ioh;
	sc->sc_dmat = ua->ua_dmat;

	/*
	 * Map interrupt vectors and reset function.
	 */
	uba_intr_establish(ua->ua_icookie, ua->ua_cvec, ilcint,
	    sc, &sc->sc_cintrcnt);
	evcnt_attach_dynamic(&sc->sc_cintrcnt, EVCNT_TYPE_INTR, ua->ua_evcnt,
	    device_xname(sc->sc_dev), "intr");
	uba_intr_establish(ua->ua_icookie, ua->ua_cvec-4, ilrint,
	    sc, &sc->sc_rintrcnt);
	evcnt_attach_dynamic(&sc->sc_rintrcnt, EVCNT_TYPE_INTR, ua->ua_evcnt,
	    device_xname(sc->sc_dev), "intr");
	uba_reset_establish(ilreset, sc->sc_dev);

	/*
	 * Reset the board and map the statistics
	 * buffer onto the Unibus.
	 */
	IL_WCSR(IL_CSR, ILC_RESET);
	(void)ilwait(sc, "reset");
	sc->sc_ui.ui_size = sizeof(struct il_stats);
	sc->sc_ui.ui_vaddr = (void *)&sc->sc_stats;
	if ((error = uballoc(device_private(parent), &sc->sc_ui, 0)))
		return printf(": failed uballoc, error = %d\n", error);

	IL_WCSR(IL_BAR, LOWORD(sc->sc_ui.ui_baddr));
	IL_WCSR(IL_BCR, sizeof(struct il_stats));
	IL_WCSR(IL_CSR, ((sc->sc_ui.ui_baddr >> 2) & IL_EUA)|ILC_STAT);
	(void)ilwait(sc, "status");
	ubfree(device_private(parent), &sc->sc_ui);
	printf("%s: module=%s firmware=%s\n", device_xname(sc->sc_dev),
		sc->sc_stats.ils_module, sc->sc_stats.ils_firmware);
	printf("%s: hardware address %s\n", device_xname(sc->sc_dev),
		ether_sprintf(sc->sc_stats.ils_addr));

	strlcpy(ifp->if_xname, device_xname(sc->sc_dev), IFNAMSIZ);
	ifp->if_softc = sc;
	ifp->if_flags = IFF_BROADCAST;
	ifp->if_init = ilinit;
	ifp->if_stop = ilstop;
	ifp->if_ioctl = ether_ioctl;
	ifp->if_start = ilstart;
	ifp->if_watchdog = ilwatch;
	IFQ_SET_READY(&ifp->if_snd);

	if_attach(ifp);
	ether_ifattach(ifp, sc->sc_stats.ils_addr);
}
Exemple #12
0
static int
uhso_attach_ifnet(struct uhso_softc *sc, struct usb_interface *iface, int type)
{
	struct ifnet *ifp;
	usb_error_t uerr;
	struct sysctl_ctx_list *sctx;
	struct sysctl_oid *soid;
	unsigned int devunit;

	uerr = usbd_transfer_setup(sc->sc_udev,
	    &iface->idesc->bInterfaceNumber, sc->sc_if_xfer,
	    uhso_ifnet_config, UHSO_IFNET_MAX, sc, &sc->sc_mtx);
	if (uerr) {
		UHSO_DPRINTF(0, "usbd_transfer_setup failed: %s\n",
		    usbd_errstr(uerr));
		return (-1);
	}

	sc->sc_ifp = ifp = if_alloc(IFT_OTHER);
	if (sc->sc_ifp == NULL) {
		device_printf(sc->sc_dev, "if_alloc() failed\n");
		return (-1);
	}

	callout_init_mtx(&sc->sc_c, &sc->sc_mtx, 0);
	mtx_lock(&sc->sc_mtx);
	callout_reset(&sc->sc_c, 1, uhso_if_rxflush, sc);
	mtx_unlock(&sc->sc_mtx);

	/*
	 * We create our own unit numbers for ifnet devices because the
	 * USB interface unit numbers can be at arbitrary positions yielding
	 * odd looking device names.
	 */
	devunit = alloc_unr(uhso_ifnet_unit);

	if_initname(ifp, device_get_name(sc->sc_dev), devunit);
	ifp->if_mtu = UHSO_MAX_MTU;
	ifp->if_ioctl = uhso_if_ioctl;
	ifp->if_init = uhso_if_init;
	ifp->if_start = uhso_if_start;
	ifp->if_output = uhso_if_output;
	ifp->if_flags = IFF_BROADCAST | IFF_MULTICAST | IFF_NOARP;
	ifp->if_softc = sc;
	IFQ_SET_MAXLEN(&ifp->if_snd, ifqmaxlen);
	ifp->if_snd.ifq_drv_maxlen = ifqmaxlen;
	IFQ_SET_READY(&ifp->if_snd);

	if_attach(ifp);
	bpfattach(ifp, DLT_RAW, 0);

	sctx = device_get_sysctl_ctx(sc->sc_dev);
	soid = device_get_sysctl_tree(sc->sc_dev);
	/* Unlocked read... */
	SYSCTL_ADD_STRING(sctx, SYSCTL_CHILDREN(soid), OID_AUTO, "netif",
	    CTLFLAG_RD, ifp->if_xname, 0, "Attached network interface");

	return (0);
}
Exemple #13
0
static int
ntb_setup_interface(void)
{
	struct ifnet *ifp;
	struct ntb_queue_handlers handlers = { ntb_net_rx_handler,
	    ntb_net_tx_handler, ntb_net_event_handler };
	int rc;

	net_softc.ntb = devclass_get_softc(devclass_find("ntb_hw"), 0);
	if (net_softc.ntb == NULL) {
		printf("ntb: Cannot find devclass\n");
		return (ENXIO);
	}

	ifp = net_softc.ifp = if_alloc(IFT_ETHER);
	if (ifp == NULL) {
		ntb_transport_free(&net_softc);
		printf("ntb: Cannot allocate ifnet structure\n");
		return (ENOMEM);
	}
	if_initname(ifp, "ntb", 0);

	rc = ntb_transport_probe(net_softc.ntb);
	if (rc != 0) {
		printf("ntb: Cannot init transport: %d\n", rc);
		if_free(net_softc.ifp);
		return (rc);
	}

	net_softc.qp = ntb_transport_create_queue(ifp, net_softc.ntb,
	    &handlers);
	ifp->if_init = ntb_net_init;
	ifp->if_softc = &net_softc;
	ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX;
	ifp->if_ioctl = ntb_ioctl;
	ifp->if_start = ntb_start;
	IFQ_SET_MAXLEN(&ifp->if_snd, IFQ_MAXLEN);
	ifp->if_snd.ifq_drv_maxlen = IFQ_MAXLEN;
	IFQ_SET_READY(&ifp->if_snd);
	create_random_local_eui48(net_softc.eaddr);
	ether_ifattach(ifp, net_softc.eaddr);
	ifp->if_capabilities = IFCAP_HWCSUM | IFCAP_JUMBO_MTU;
	ifp->if_capenable = ifp->if_capabilities;
	ifp->if_mtu = ntb_transport_max_size(net_softc.qp) - ETHER_HDR_LEN -
	    ETHER_CRC_LEN;

	ntb_transport_link_up(net_softc.qp);
	net_softc.bufsize = ntb_transport_max_size(net_softc.qp) +
	    sizeof(struct ether_header);
	return (0);
}
Exemple #14
0
void
che_attach(struct device *parent, struct device *self, void *aux)
{
	struct cheg_softc *gsc = (struct cheg_softc *)parent;
	struct che_softc *sc = (struct che_softc *)self;
	struct che_attach_args *caa = aux;
	struct ifnet *ifp;

	sc->sc_cheg = gsc;

	sc->sc_port = caa->caa_port;
	bcopy(caa->caa_lladdr, sc->sc_ac.ac_enaddr, ETHER_ADDR_LEN);

	printf(": address %s\n", ether_sprintf(sc->sc_ac.ac_enaddr));

	ifp = &sc->sc_ac.ac_if;
	ifp->if_softc = sc;
	ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
	ifp->if_ioctl = che_ioctl;
	ifp->if_start = che_start;
	ifp->if_watchdog = che_watchdog;
	ifp->if_hardmtu = MCLBYTES - ETHER_HDR_LEN - ETHER_CRC_LEN; /* XXX */
	strlcpy(ifp->if_xname, DEVNAME(sc), IFNAMSIZ);
	IFQ_SET_MAXLEN(&ifp->if_snd, 400);
	IFQ_SET_READY(&ifp->if_snd);

	ifmedia_init(&sc->sc_mii.mii_media, 0,
	    che_ifmedia_upd, che_ifmedia_sts);

	sc->sc_mii.mii_ifp = ifp;
	sc->sc_mii.mii_readreg = che_miibus_ind_readreg;
	sc->sc_mii.mii_writereg = che_miibus_ind_writereg;
	sc->sc_mii.mii_statchg = che_miibus_statchg;

	mii_attach(self, &sc->sc_mii, 0xffffffff, MII_PHY_ANY,
	    MII_OFFSET_ANY, MIIF_DOPAUSE | MIIF_HAVEFIBER);

	if (LIST_FIRST(&sc->sc_mii.mii_phys) == NULL) {
		printf("%s: no PHY found!\n", sc->sc_dev.dv_xname);
		ifmedia_add(&sc->sc_mii.mii_media, IFM_ETHER|IFM_MANUAL,
		    0, NULL);
		ifmedia_set(&sc->sc_mii.mii_media, IFM_ETHER|IFM_MANUAL);
	} else
		ifmedia_set(&sc->sc_mii.mii_media, IFM_ETHER|IFM_AUTO);

	if_attach(ifp);
	ether_ifattach(ifp);

	return;
}
Exemple #15
0
int
mpw_clone_create(struct if_clone *ifc, int unit)
{
	struct mpw_softc *sc;
	struct ifnet *ifp;
	struct ifih *ifih;

	sc = malloc(sizeof(*sc), M_DEVBUF, M_NOWAIT | M_ZERO);
	if (sc == NULL)
		return (ENOMEM);

	ifih = malloc(sizeof(*ifih), M_DEVBUF, M_NOWAIT | M_ZERO);
	if (ifih == NULL) {
		free(sc, M_DEVBUF, sizeof(*sc));
		return (ENOMEM);
	}

	ifp = &sc->sc_if;
	snprintf(ifp->if_xname, sizeof(ifp->if_xname), "mpw%d", unit);
	ifp->if_softc = sc;
	ifp->if_mtu = ETHERMTU;
	ifp->if_flags = IFF_POINTOPOINT;
	ifp->if_ioctl = mpw_ioctl;
	ifp->if_output = mpw_output;
	ifp->if_start = mpw_start;
	ifp->if_type = IFT_MPLSTUNNEL;
	ifp->if_hdrlen = ETHER_HDR_LEN;
	IFQ_SET_MAXLEN(&ifp->if_snd, IFQ_MAXLEN);
	IFQ_SET_READY(&ifp->if_snd);

	if_attach(ifp);
	if_alloc_sadl(ifp);

	sc->sc_ifa.ifa_ifp = ifp;
	sc->sc_ifa.ifa_rtrequest = link_rtrequest;
	sc->sc_ifa.ifa_addr = (struct sockaddr *) ifp->if_sadl;
	sc->sc_smpls.smpls_len = sizeof(sc->sc_smpls);
	sc->sc_smpls.smpls_family = AF_MPLS;

	ifih->ifih_input = mpw_input;
	SLIST_INSERT_HEAD(&ifp->if_inputs, ifih, ifih_next);

#if NBPFILTER > 0
	bpfattach(&ifp->if_bpf, ifp, DLT_EN10MB, ETHER_HDR_LEN);
#endif /* NBFILTER */

	return (0);
}
Exemple #16
0
static int
if_netmap_setup_interface(struct if_netmap_softc *sc)
{
	struct ifnet *ifp;

	ifp = sc->ifp = if_alloc(IFT_ETHER);

	ifp->if_init =  if_netmap_init;
	ifp->if_softc = sc;

	if_initname(ifp, sc->cfg->name, IF_DUNIT_NONE);
	ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
	ifp->if_ioctl = if_netmap_ioctl;
	ifp->if_start = if_netmap_start;

	/* XXX what values? */
	IFQ_SET_MAXLEN(&ifp->if_snd, if_netmap_txslots(sc->nm_host_ctx));
	ifp->if_snd.ifq_drv_maxlen = if_netmap_txslots(sc->nm_host_ctx);

	IFQ_SET_READY(&ifp->if_snd);

	ifp->if_fib = sc->cfg->cdom;

	ether_ifattach(ifp, sc->addr);
	ifp->if_capabilities = ifp->if_capenable = IFCAP_HWSTATS;


	mtx_init(&sc->tx_lock, "txlk", NULL, MTX_DEF);
	cv_init(&sc->tx_cv, "txcv");

	if (kthread_add(if_netmap_send, sc, NULL, &sc->tx_thread.thr, 0, 0, "nm_tx: %s", ifp->if_xname)) {
		printf("Could not start transmit thread for %s (%s)\n", ifp->if_xname, sc->host_ifname);
		ether_ifdetach(ifp);
		if_free(ifp);
		return (1);
	}


	if (kthread_add(if_netmap_receive, sc, NULL, &sc->rx_thread.thr, 0, 0, "nm_rx: %s", ifp->if_xname)) {
		printf("Could not start receive thread for %s (%s)\n", ifp->if_xname, sc->host_ifname);
		ether_ifdetach(ifp);
		if_free(ifp);
		return (1);
	}

	return (0);
}
Exemple #17
0
static int 
sfxge_ifnet_init(struct ifnet *ifp, struct sfxge_softc *sc)
{
	const efx_nic_cfg_t *encp = efx_nic_cfg_get(sc->enp);
	device_t dev;
	int rc;

	dev = sc->dev;
	sc->ifnet = ifp;

	if_initname(ifp, device_get_name(dev), device_get_unit(dev));
	ifp->if_init = sfxge_if_init;
	ifp->if_softc = sc;
	ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
	ifp->if_ioctl = sfxge_if_ioctl;

	ifp->if_capabilities = SFXGE_CAP;
	ifp->if_capenable = SFXGE_CAP_ENABLE;
	ifp->if_hwassist = CSUM_TCP | CSUM_UDP | CSUM_IP | CSUM_TSO;

	ether_ifattach(ifp, encp->enc_mac_addr);

#ifdef SFXGE_HAVE_MQ
	ifp->if_transmit = sfxge_if_transmit;
	ifp->if_qflush = sfxge_if_qflush;
#else
	ifp->if_start = sfxge_if_start;
	IFQ_SET_MAXLEN(&ifp->if_snd, SFXGE_NDESCS - 1);
	ifp->if_snd.ifq_drv_maxlen = SFXGE_NDESCS - 1;
	IFQ_SET_READY(&ifp->if_snd);

	mtx_init(&sc->tx_lock, "txq", NULL, MTX_DEF);
#endif

	if ((rc = sfxge_port_ifmedia_init(sc)) != 0)
		goto fail;

	return 0;

fail:
	ether_ifdetach(sc->ifnet);
	return rc;
}
Exemple #18
0
void
gifattach0(struct gif_softc *sc)
{

	sc->encap_cookie4 = sc->encap_cookie6 = NULL;

	sc->gif_if.if_addrlen = 0;
	sc->gif_if.if_mtu    = GIF_MTU;
	sc->gif_if.if_flags  = IFF_POINTOPOINT | IFF_MULTICAST;
	sc->gif_if.if_ioctl  = gif_ioctl;
	sc->gif_if.if_output = gif_output;
	sc->gif_if.if_type   = IFT_GIF;
	sc->gif_if.if_dlt    = DLT_NULL;
	sc->gif_if.if_softc  = sc;
	IFQ_SET_READY(&sc->gif_if.if_snd);
	if_attach(&sc->gif_if);
	if_alloc_sadl(&sc->gif_if);
	bpf_attach(&sc->gif_if, DLT_NULL, sizeof(u_int));
}
Exemple #19
0
static void
ofnet_attach(struct device *parent, struct device *self, void *aux)
{
	struct ofnet_softc *of = device_private(self);
	struct ifnet *ifp = &of->sc_ethercom.ec_if;
	struct ofbus_attach_args *oba = aux;
	char path[256];
	int l;
	u_int8_t myaddr[ETHER_ADDR_LEN];

	of->sc_phandle = oba->oba_phandle;
#if NIPKDB_OFN > 0
	if (kifp &&
	    kifp->unit - 1 == device_unit(&of->sc_dev) &&
	    OF_instance_to_package(kifp->port) == oba->oba_phandle)  {
		ipkdb_of = of;
		of->sc_ihandle = kifp->port;
	} else
#endif
	if ((l = OF_package_to_path(oba->oba_phandle, path,
	    sizeof path - 1)) < 0 ||
	    l >= sizeof path ||
	    (path[l] = 0, !(of->sc_ihandle = OF_open(path))))
		panic("ofnet_attach: unable to open");
	if (OF_getprop(oba->oba_phandle, "mac-address", myaddr,
	    sizeof myaddr) < 0)
		panic("ofnet_attach: no mac-address");
	printf(": address %s\n", ether_sprintf(myaddr));

	callout_init(&of->sc_callout, 0);

	strlcpy(ifp->if_xname, device_xname(&of->sc_dev), IFNAMSIZ);
	ifp->if_softc = of;
	ifp->if_start = ofnet_start;
	ifp->if_ioctl = ofnet_ioctl;
	ifp->if_watchdog = ofnet_watchdog;
	ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_NOTRAILERS;
	IFQ_SET_READY(&ifp->if_snd);

	if_attach(ifp);
	ether_ifattach(ifp, myaddr);
}
Exemple #20
0
int
mpw_clone_create(struct if_clone *ifc, int unit)
{
	struct mpw_softc *sc;
	struct ifnet *ifp;

	sc = malloc(sizeof(*sc), M_DEVBUF, M_NOWAIT | M_ZERO);
	if (sc == NULL)
		return (ENOMEM);

	ifp = &sc->sc_if;
	snprintf(ifp->if_xname, sizeof(ifp->if_xname), "mpw%d", unit);
	ifp->if_softc = sc;
	ifp->if_mtu = ETHERMTU;
	ifp->if_flags = IFF_POINTOPOINT;
	ifp->if_ioctl = mpw_ioctl;
	ifp->if_output = mpw_output;
	ifp->if_start = mpw_start;
	ifp->if_type = IFT_MPLSTUNNEL;
	ifp->if_hdrlen = ETHER_HDR_LEN;
	IFQ_SET_MAXLEN(&ifp->if_snd, IFQ_MAXLEN);
	IFQ_SET_READY(&ifp->if_snd);

	if_attach(ifp);
	if_alloc_sadl(ifp);

	sc->sc_ifa.ifa_ifp = ifp;
	sc->sc_ifa.ifa_addr = sdltosa(ifp->if_sadl);
	sc->sc_smpls.smpls_len = sizeof(sc->sc_smpls);
	sc->sc_smpls.smpls_family = AF_MPLS;

	if_ih_insert(ifp, mpw_input, NULL);

#if NBPFILTER > 0
	bpfattach(&ifp->if_bpf, ifp, DLT_EN10MB, ETHER_HDR_LEN);
#endif /* NBFILTER */

	return (0);
}
Exemple #21
0
int
ppp_clone_create(struct if_clone *ifc, int unit)
{
    struct ppp_softc *sc;
    int s;

    sc = malloc(sizeof(*sc), M_DEVBUF, M_NOWAIT|M_ZERO);
    if (!sc)
	return (ENOMEM);

    sc->sc_unit = unit;
    snprintf(sc->sc_if.if_xname, sizeof sc->sc_if.if_xname, "%s%d",
	ifc->ifc_name, unit);
    sc->sc_if.if_softc = sc;
    sc->sc_if.if_mtu = PPP_MTU;
    sc->sc_if.if_flags = IFF_POINTOPOINT | IFF_MULTICAST;
    sc->sc_if.if_type = IFT_PPP;
    sc->sc_if.if_hdrlen = PPP_HDRLEN;
    sc->sc_if.if_ioctl = pppsioctl;
    sc->sc_if.if_output = pppoutput;
    sc->sc_if.if_start = ppp_ifstart;
    IFQ_SET_MAXLEN(&sc->sc_if.if_snd, IFQ_MAXLEN);
    IFQ_SET_MAXLEN(&sc->sc_inq, IFQ_MAXLEN);
    IFQ_SET_MAXLEN(&sc->sc_fastq, IFQ_MAXLEN);
    IFQ_SET_MAXLEN(&sc->sc_rawq, IFQ_MAXLEN);
    IFQ_SET_READY(&sc->sc_if.if_snd);
    if_attach(&sc->sc_if);
    if_alloc_sadl(&sc->sc_if);
#if NBPFILTER > 0
    bpfattach(&sc->sc_bpf, &sc->sc_if, DLT_PPP, PPP_HDRLEN);
#endif
    s = splnet();
    LIST_INSERT_HEAD(&ppp_softc_list, sc, sc_list);
    splx(s);

    return (0);
}
Exemple #22
0
static int
loop_clone_create(struct if_clone *ifc, int unit)
{
	struct ifnet *ifp;

	ifp = if_alloc(IFT_LOOP);

	if_initname(ifp, ifc->ifc_name, unit);

	ifp->if_mtu = LOMTU;
	ifp->if_flags = IFF_LOOPBACK | IFF_MULTICAST | IFF_RUNNING;
//	ifp->if_ioctl = loioctl;
	ifp->if_output = looutput;
#ifdef ALTQ
	ifp->if_start = lostart;
#endif
	ifp->if_type = IFT_LOOP;
	ifp->if_hdrlen = 0;
	ifp->if_addrlen = 0;
	ifp->if_dlt = DLT_NULL;
	IFQ_SET_READY(&ifp->if_snd);
	if (unit == 0)
		lo0ifp = ifp;
	if_attach(ifp);
	if_alloc_sadl(ifp);
#if NBPFILTER > 0
	bpfattach(ifp, DLT_NULL, sizeof(u_int));
#endif
#ifdef MBUFTRACE
	ifp->if_mowner = malloc(sizeof(struct mowner));
	strlcpy(ifp->if_mowner->mo_name, ifp->if_xname,
	    sizeof(ifp->if_mowner->mo_name));
	MOWNER_ATTACH(ifp->if_mowner);
#endif

	return (0);
}
Exemple #23
0
int
mpe_clone_create(struct if_clone *ifc, int unit)
{
	struct ifnet 		*ifp;
	struct mpe_softc	*mpeif;
	int 			 s;

	if ((mpeif = malloc(sizeof(*mpeif),
	    M_DEVBUF, M_NOWAIT|M_ZERO)) == NULL)
		return (ENOMEM);

	mpeif->sc_shim.shim_label = 0;
	mpeif->sc_unit = unit;
	ifp = &mpeif->sc_if;
	snprintf(ifp->if_xname, sizeof ifp->if_xname, "mpe%d", unit);
	ifp->if_flags = IFF_POINTOPOINT;
	ifp->if_softc = mpeif;
	ifp->if_mtu = MPE_MTU;
	ifp->if_ioctl = mpeioctl;
	ifp->if_output = mpeoutput;
	ifp->if_start = mpestart;
	ifp->if_type = IFT_MPLS;
	ifp->if_hdrlen = MPE_HDRLEN;
	IFQ_SET_MAXLEN(&ifp->if_snd, IFQ_MAXLEN);
	IFQ_SET_READY(&ifp->if_snd);
	if_attach(ifp);
	if_alloc_sadl(ifp);
#if NBPFILTER > 0
	bpfattach(&ifp->if_bpf, ifp, DLT_LOOP, sizeof(u_int32_t));
#endif

	s = splnet();
	LIST_INSERT_HEAD(&mpeif_list, mpeif, sc_list);
	splx(s);

	return (0);
}
Exemple #24
0
int
pair_clone_create(struct if_clone *ifc, int unit)
{
	struct ifnet		*ifp;
	struct pair_softc	*sc;

	if ((sc = malloc(sizeof(*sc),
	    M_DEVBUF, M_NOWAIT|M_ZERO)) == NULL)
		return (ENOMEM);

	ifp = &sc->sc_ac.ac_if;
	snprintf(ifp->if_xname, sizeof ifp->if_xname, "pair%d", unit);
	ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
	ether_fakeaddr(ifp);

	ifp->if_softc = sc;
	ifp->if_ioctl = pairioctl;
	ifp->if_start = pairstart;
	IFQ_SET_MAXLEN(&ifp->if_snd, IFQ_MAXLEN);
	IFQ_SET_READY(&ifp->if_snd);

	ifp->if_hardmtu = 0xffff;
	ifp->if_capabilities = IFCAP_VLAN_MTU;

	ifmedia_init(&sc->sc_media, 0, pair_media_change,
	    pair_media_status);
	ifmedia_add(&sc->sc_media, IFM_ETHER | IFM_AUTO, 0, NULL);
	ifmedia_set(&sc->sc_media, IFM_ETHER | IFM_AUTO);

	if_attach(ifp);
	ether_ifattach(ifp);

	pair_link_state(ifp);

	return (0);
}
Exemple #25
0
void
nfe_attach(struct device *parent, struct device *self, void *aux)
{
	struct nfe_softc *sc = (struct nfe_softc *)self;
	struct pci_attach_args *pa = aux;
	pci_chipset_tag_t pc = pa->pa_pc;
	pci_intr_handle_t ih;
	const char *intrstr;
	struct ifnet *ifp;
	bus_size_t memsize;
	pcireg_t memtype;

	memtype = pci_mapreg_type(pa->pa_pc, pa->pa_tag, NFE_PCI_BA);
	if (pci_mapreg_map(pa, NFE_PCI_BA, memtype, 0, &sc->sc_memt,
	    &sc->sc_memh, NULL, &memsize, 0)) {
		printf(": can't map mem space\n");
		return;
	}

	if (pci_intr_map(pa, &ih) != 0) {
		printf(": can't map interrupt\n");
		return;
	}

	intrstr = pci_intr_string(pc, ih);
	sc->sc_ih = pci_intr_establish(pc, ih, IPL_NET, nfe_intr, sc,
	    sc->sc_dev.dv_xname);
	if (sc->sc_ih == NULL) {
		printf(": could not establish interrupt");
		if (intrstr != NULL)
			printf(" at %s", intrstr);
		printf("\n");
		return;
	}
	printf(": %s", intrstr);

	sc->sc_dmat = pa->pa_dmat;
	sc->sc_flags = 0;

	switch (PCI_PRODUCT(pa->pa_id)) {
	case PCI_PRODUCT_NVIDIA_NFORCE3_LAN2:
	case PCI_PRODUCT_NVIDIA_NFORCE3_LAN3:
	case PCI_PRODUCT_NVIDIA_NFORCE3_LAN4:
	case PCI_PRODUCT_NVIDIA_NFORCE3_LAN5:
		sc->sc_flags |= NFE_JUMBO_SUP | NFE_HW_CSUM;
		break;
	case PCI_PRODUCT_NVIDIA_MCP51_LAN1:
	case PCI_PRODUCT_NVIDIA_MCP51_LAN2:
		sc->sc_flags |= NFE_40BIT_ADDR | NFE_PWR_MGMT;
		break;
	case PCI_PRODUCT_NVIDIA_MCP61_LAN1:
	case PCI_PRODUCT_NVIDIA_MCP61_LAN2:
	case PCI_PRODUCT_NVIDIA_MCP61_LAN3:
	case PCI_PRODUCT_NVIDIA_MCP61_LAN4:
	case PCI_PRODUCT_NVIDIA_MCP67_LAN1:
	case PCI_PRODUCT_NVIDIA_MCP67_LAN2:
	case PCI_PRODUCT_NVIDIA_MCP67_LAN3:
	case PCI_PRODUCT_NVIDIA_MCP67_LAN4:
	case PCI_PRODUCT_NVIDIA_MCP73_LAN1:
	case PCI_PRODUCT_NVIDIA_MCP73_LAN2:
	case PCI_PRODUCT_NVIDIA_MCP73_LAN3:
	case PCI_PRODUCT_NVIDIA_MCP73_LAN4:
		sc->sc_flags |= NFE_40BIT_ADDR | NFE_CORRECT_MACADDR |
		    NFE_PWR_MGMT;
		break;
	case PCI_PRODUCT_NVIDIA_MCP77_LAN1:
	case PCI_PRODUCT_NVIDIA_MCP77_LAN2:
	case PCI_PRODUCT_NVIDIA_MCP77_LAN3:
	case PCI_PRODUCT_NVIDIA_MCP77_LAN4:
		sc->sc_flags |= NFE_40BIT_ADDR | NFE_HW_CSUM |
		    NFE_CORRECT_MACADDR | NFE_PWR_MGMT;
		break;
	case PCI_PRODUCT_NVIDIA_MCP79_LAN1:
	case PCI_PRODUCT_NVIDIA_MCP79_LAN2:
	case PCI_PRODUCT_NVIDIA_MCP79_LAN3:
	case PCI_PRODUCT_NVIDIA_MCP79_LAN4:
	case PCI_PRODUCT_NVIDIA_MCP89_LAN:
		sc->sc_flags |= NFE_JUMBO_SUP | NFE_40BIT_ADDR | NFE_HW_CSUM |
		    NFE_CORRECT_MACADDR | NFE_PWR_MGMT;
		break;
	case PCI_PRODUCT_NVIDIA_CK804_LAN1:
	case PCI_PRODUCT_NVIDIA_CK804_LAN2:
	case PCI_PRODUCT_NVIDIA_MCP04_LAN1:
	case PCI_PRODUCT_NVIDIA_MCP04_LAN2:
		sc->sc_flags |= NFE_JUMBO_SUP | NFE_40BIT_ADDR | NFE_HW_CSUM;
		break;
	case PCI_PRODUCT_NVIDIA_MCP65_LAN1:
	case PCI_PRODUCT_NVIDIA_MCP65_LAN2:
	case PCI_PRODUCT_NVIDIA_MCP65_LAN3:
	case PCI_PRODUCT_NVIDIA_MCP65_LAN4:
		sc->sc_flags |= NFE_JUMBO_SUP | NFE_40BIT_ADDR |
		    NFE_CORRECT_MACADDR | NFE_PWR_MGMT;
		break;
	case PCI_PRODUCT_NVIDIA_MCP55_LAN1:
	case PCI_PRODUCT_NVIDIA_MCP55_LAN2:
		sc->sc_flags |= NFE_JUMBO_SUP | NFE_40BIT_ADDR | NFE_HW_CSUM |
		    NFE_HW_VLAN | NFE_PWR_MGMT;
		break;
	}

	if (sc->sc_flags & NFE_PWR_MGMT) {
		NFE_WRITE(sc, NFE_RXTX_CTL, NFE_RXTX_RESET | NFE_RXTX_BIT2);
		NFE_WRITE(sc, NFE_MAC_RESET, NFE_MAC_RESET_MAGIC);
		DELAY(100);
		NFE_WRITE(sc, NFE_MAC_RESET, 0);
		DELAY(100);
		NFE_WRITE(sc, NFE_RXTX_CTL, NFE_RXTX_BIT2);
		NFE_WRITE(sc, NFE_PWR2_CTL,
		    NFE_READ(sc, NFE_PWR2_CTL) & ~NFE_PWR2_WAKEUP_MASK);
	}

	nfe_get_macaddr(sc, sc->sc_arpcom.ac_enaddr);
	printf(", address %s\n", ether_sprintf(sc->sc_arpcom.ac_enaddr));

	/*
	 * Allocate Tx and Rx rings.
	 */
	if (nfe_alloc_tx_ring(sc, &sc->txq) != 0) {
		printf("%s: could not allocate Tx ring\n",
		    sc->sc_dev.dv_xname);
		return;
	}

	if (nfe_alloc_rx_ring(sc, &sc->rxq) != 0) {
		printf("%s: could not allocate Rx ring\n",
		    sc->sc_dev.dv_xname);
		nfe_free_tx_ring(sc, &sc->txq);
		return;
	}

	ifp = &sc->sc_arpcom.ac_if;
	ifp->if_softc = sc;
	ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
	ifp->if_ioctl = nfe_ioctl;
	ifp->if_start = nfe_start;
	ifp->if_watchdog = nfe_watchdog;
	IFQ_SET_MAXLEN(&ifp->if_snd, NFE_IFQ_MAXLEN);
	IFQ_SET_READY(&ifp->if_snd);
	strlcpy(ifp->if_xname, sc->sc_dev.dv_xname, IFNAMSIZ);

	ifp->if_capabilities = IFCAP_VLAN_MTU;

#ifndef SMALL_KERNEL
	ifp->if_capabilities |= IFCAP_WOL;
	ifp->if_wol = nfe_wol;
	nfe_wol(ifp, 0);
#endif

#if NVLAN > 0
	if (sc->sc_flags & NFE_HW_VLAN)
		ifp->if_capabilities |= IFCAP_VLAN_HWTAGGING;
#endif

	if (sc->sc_flags & NFE_HW_CSUM) {
		ifp->if_capabilities |= IFCAP_CSUM_IPv4 | IFCAP_CSUM_TCPv4 |
		    IFCAP_CSUM_UDPv4;
	}

	sc->sc_mii.mii_ifp = ifp;
	sc->sc_mii.mii_readreg = nfe_miibus_readreg;
	sc->sc_mii.mii_writereg = nfe_miibus_writereg;
	sc->sc_mii.mii_statchg = nfe_miibus_statchg;

	ifmedia_init(&sc->sc_mii.mii_media, 0, nfe_ifmedia_upd,
	    nfe_ifmedia_sts);
	mii_attach(self, &sc->sc_mii, 0xffffffff, MII_PHY_ANY, 0, 0);
	if (LIST_FIRST(&sc->sc_mii.mii_phys) == NULL) {
		printf("%s: no PHY found!\n", sc->sc_dev.dv_xname);
		ifmedia_add(&sc->sc_mii.mii_media, IFM_ETHER | IFM_MANUAL,
		    0, NULL);
		ifmedia_set(&sc->sc_mii.mii_media, IFM_ETHER | IFM_MANUAL);
	} else
		ifmedia_set(&sc->sc_mii.mii_media, IFM_ETHER | IFM_AUTO);

	if_attach(ifp);
	ether_ifattach(ifp);

	timeout_set(&sc->sc_tick_ch, nfe_tick, sc);
}
Exemple #26
0
/*
 * cas_config:
 *
 *	Attach a Cassini interface to the system.
 */
void
cas_config(struct cas_softc *sc)
{
	struct ifnet *ifp = &sc->sc_arpcom.ac_if;
	struct mii_data *mii = &sc->sc_mii;
	struct mii_softc *child;
	int i, error;

	/* Make sure the chip is stopped. */
	ifp->if_softc = sc;
	cas_reset(sc);

	/*
	 * Allocate the control data structures, and create and load the
	 * DMA map for it.
	 */
	if ((error = bus_dmamem_alloc(sc->sc_dmatag,
	    sizeof(struct cas_control_data), CAS_PAGE_SIZE, 0, &sc->sc_cdseg,
	    1, &sc->sc_cdnseg, 0)) != 0) {
		printf("\n%s: unable to allocate control data, error = %d\n",
		    sc->sc_dev.dv_xname, error);
		goto fail_0;
	}

	/* XXX should map this in with correct endianness */
	if ((error = bus_dmamem_map(sc->sc_dmatag, &sc->sc_cdseg, sc->sc_cdnseg,
	    sizeof(struct cas_control_data), (caddr_t *)&sc->sc_control_data,
	    BUS_DMA_COHERENT)) != 0) {
		printf("\n%s: unable to map control data, error = %d\n",
		    sc->sc_dev.dv_xname, error);
		goto fail_1;
	}

	if ((error = bus_dmamap_create(sc->sc_dmatag,
	    sizeof(struct cas_control_data), 1,
	    sizeof(struct cas_control_data), 0, 0, &sc->sc_cddmamap)) != 0) {
		printf("\n%s: unable to create control data DMA map, "
		    "error = %d\n", sc->sc_dev.dv_xname, error);
		goto fail_2;
	}

	if ((error = bus_dmamap_load(sc->sc_dmatag, sc->sc_cddmamap,
	    sc->sc_control_data, sizeof(struct cas_control_data), NULL,
	    0)) != 0) {
		printf("\n%s: unable to load control data DMA map, error = %d\n",
		    sc->sc_dev.dv_xname, error);
		goto fail_3;
	}

	bzero(sc->sc_control_data, sizeof(struct cas_control_data));

	/*
	 * Create the receive buffer DMA maps.
	 */
	for (i = 0; i < CAS_NRXDESC; i++) {
		bus_dma_segment_t seg;
		caddr_t kva;
		int rseg;

		if ((error = bus_dmamem_alloc(sc->sc_dmatag, CAS_PAGE_SIZE,
		    CAS_PAGE_SIZE, 0, &seg, 1, &rseg, BUS_DMA_NOWAIT)) != 0) {
			printf("\n%s: unable to alloc rx DMA mem %d, "
			    "error = %d\n", sc->sc_dev.dv_xname, i, error);
			goto fail_5;
		}
		sc->sc_rxsoft[i].rxs_dmaseg = seg;

		if ((error = bus_dmamem_map(sc->sc_dmatag, &seg, rseg,
		    CAS_PAGE_SIZE, &kva, BUS_DMA_NOWAIT)) != 0) {
			printf("\n%s: unable to alloc rx DMA mem %d, "
			    "error = %d\n", sc->sc_dev.dv_xname, i, error);
			goto fail_5;
		}
		sc->sc_rxsoft[i].rxs_kva = kva;

		if ((error = bus_dmamap_create(sc->sc_dmatag, CAS_PAGE_SIZE, 1,
		    CAS_PAGE_SIZE, 0, 0, &sc->sc_rxsoft[i].rxs_dmamap)) != 0) {
			printf("\n%s: unable to create rx DMA map %d, "
			    "error = %d\n", sc->sc_dev.dv_xname, i, error);
			goto fail_5;
		}

		if ((error = bus_dmamap_load(sc->sc_dmatag,
		   sc->sc_rxsoft[i].rxs_dmamap, kva, CAS_PAGE_SIZE, NULL,
		   BUS_DMA_NOWAIT)) != 0) {
			printf("\n%s: unable to load rx DMA map %d, "
			    "error = %d\n", sc->sc_dev.dv_xname, i, error);
			goto fail_5;
		}
	}

	/*
	 * Create the transmit buffer DMA maps.
	 */
	for (i = 0; i < CAS_NTXDESC; i++) {
		if ((error = bus_dmamap_create(sc->sc_dmatag, MCLBYTES,
		    CAS_NTXSEGS, MCLBYTES, 0, BUS_DMA_NOWAIT,
		    &sc->sc_txd[i].sd_map)) != 0) {
			printf("\n%s: unable to create tx DMA map %d, "
			    "error = %d\n", sc->sc_dev.dv_xname, i, error);
			goto fail_6;
		}
		sc->sc_txd[i].sd_mbuf = NULL;
	}

	/*
	 * From this point forward, the attachment cannot fail.  A failure
	 * before this point releases all resources that may have been
	 * allocated.
	 */

	/* Announce ourselves. */
	printf(", address %s\n", ether_sprintf(sc->sc_arpcom.ac_enaddr));

	/* Get RX FIFO size */
	sc->sc_rxfifosize = 16 * 1024;

	/* Initialize ifnet structure. */
	strlcpy(ifp->if_xname, sc->sc_dev.dv_xname, sizeof ifp->if_xname);
	ifp->if_softc = sc;
	ifp->if_flags =
	    IFF_BROADCAST | IFF_SIMPLEX | IFF_NOTRAILERS | IFF_MULTICAST;
	ifp->if_start = cas_start;
	ifp->if_ioctl = cas_ioctl;
	ifp->if_watchdog = cas_watchdog;
	IFQ_SET_MAXLEN(&ifp->if_snd, CAS_NTXDESC - 1);
	IFQ_SET_READY(&ifp->if_snd);

	ifp->if_capabilities = IFCAP_VLAN_MTU;

	/* Initialize ifmedia structures and MII info */
	mii->mii_ifp = ifp;
	mii->mii_readreg = cas_mii_readreg;
	mii->mii_writereg = cas_mii_writereg;
	mii->mii_statchg = cas_mii_statchg;

	ifmedia_init(&mii->mii_media, 0, cas_mediachange, cas_mediastatus);

	bus_space_write_4(sc->sc_memt, sc->sc_memh, CAS_MII_DATAPATH_MODE, 0);

	cas_mifinit(sc);

	if (sc->sc_mif_config & CAS_MIF_CONFIG_MDI1) {
		sc->sc_mif_config |= CAS_MIF_CONFIG_PHY_SEL;
		bus_space_write_4(sc->sc_memt, sc->sc_memh,
	            CAS_MIF_CONFIG, sc->sc_mif_config);
	}

	mii_attach(&sc->sc_dev, mii, 0xffffffff, MII_PHY_ANY,
	    MII_OFFSET_ANY, 0);

	child = LIST_FIRST(&mii->mii_phys);
	if (child == NULL &&
	    sc->sc_mif_config & (CAS_MIF_CONFIG_MDI0|CAS_MIF_CONFIG_MDI1)) {
		/* 
		 * Try the external PCS SERDES if we didn't find any
		 * MII devices.
		 */
		bus_space_write_4(sc->sc_memt, sc->sc_memh,
		    CAS_MII_DATAPATH_MODE, CAS_MII_DATAPATH_SERDES);

		bus_space_write_4(sc->sc_memt, sc->sc_memh,
		     CAS_MII_CONFIG, CAS_MII_CONFIG_ENABLE);

		mii->mii_readreg = cas_pcs_readreg;
		mii->mii_writereg = cas_pcs_writereg;

		mii_attach(&sc->sc_dev, mii, 0xffffffff, MII_PHY_ANY,
		    MII_OFFSET_ANY, MIIF_NOISOLATE);
	}

	child = LIST_FIRST(&mii->mii_phys);
	if (child == NULL) {
		/* No PHY attached */
		ifmedia_add(&sc->sc_media, IFM_ETHER|IFM_MANUAL, 0, NULL);
		ifmedia_set(&sc->sc_media, IFM_ETHER|IFM_MANUAL);
	} else {
		/*
		 * Walk along the list of attached MII devices and
		 * establish an `MII instance' to `phy number'
		 * mapping. We'll use this mapping in media change
		 * requests to determine which phy to use to program
		 * the MIF configuration register.
		 */
		for (; child != NULL; child = LIST_NEXT(child, mii_list)) {
			/*
			 * Note: we support just two PHYs: the built-in
			 * internal device and an external on the MII
			 * connector.
			 */
			if (child->mii_phy > 1 || child->mii_inst > 1) {
				printf("%s: cannot accommodate MII device %s"
				       " at phy %d, instance %d\n",
				       sc->sc_dev.dv_xname,
				       child->mii_dev.dv_xname,
				       child->mii_phy, child->mii_inst);
				continue;
			}

			sc->sc_phys[child->mii_inst] = child->mii_phy;
		}

		/*
		 * XXX - we can really do the following ONLY if the
		 * phy indeed has the auto negotiation capability!!
		 */
		ifmedia_set(&sc->sc_media, IFM_ETHER|IFM_AUTO);
	}

	/* Attach the interface. */
	if_attach(ifp);
	ether_ifattach(ifp);

	sc->sc_sh = shutdownhook_establish(cas_shutdown, sc);
	if (sc->sc_sh == NULL)
		panic("cas_config: can't establish shutdownhook");

	timeout_set(&sc->sc_tick_ch, cas_tick, sc);
	return;

	/*
	 * Free any resources we've allocated during the failed attach
	 * attempt.  Do this in reverse order and fall through.
	 */
 fail_6:
	for (i = 0; i < CAS_NTXDESC; i++) {
		if (sc->sc_txd[i].sd_map != NULL)
			bus_dmamap_destroy(sc->sc_dmatag,
			    sc->sc_txd[i].sd_map);
	}
 fail_5:
	for (i = 0; i < CAS_NRXDESC; i++) {
		if (sc->sc_rxsoft[i].rxs_dmamap != NULL)
			bus_dmamap_destroy(sc->sc_dmatag,
			    sc->sc_rxsoft[i].rxs_dmamap);
	}
	bus_dmamap_unload(sc->sc_dmatag, sc->sc_cddmamap);
 fail_3:
	bus_dmamap_destroy(sc->sc_dmatag, sc->sc_cddmamap);
 fail_2:
	bus_dmamem_unmap(sc->sc_dmatag, (caddr_t)sc->sc_control_data,
	    sizeof(struct cas_control_data));
 fail_1:
	bus_dmamem_free(sc->sc_dmatag, &sc->sc_cdseg, sc->sc_cdnseg);
 fail_0:
	return;
}
Exemple #27
0
static int
admsw_attach(device_t dev)
{
	uint8_t enaddr[ETHER_ADDR_LEN];
	struct admsw_softc *sc = (struct admsw_softc *) device_get_softc(dev);
	struct ifnet *ifp;
	int error, i, rid;

	sc->sc_dev = dev;
	device_printf(dev, "ADM5120 Switch Engine, %d ports\n", SW_DEVS);
	sc->ndevs = 0;

	/* XXXMIPS: fix it */
	enaddr[0] = 0x00;
	enaddr[1] = 0x0C;
	enaddr[2] = 0x42;
	enaddr[3] = 0x07;
	enaddr[4] = 0xB2;
	enaddr[5] = 0x4E;

	memcpy(sc->sc_enaddr, enaddr, sizeof(sc->sc_enaddr));

	device_printf(sc->sc_dev, "base Ethernet address %s\n",
	    ether_sprintf(enaddr));
	callout_init(&sc->sc_watchdog, 1);

	rid = 0;
	if ((sc->mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, 
	    RF_ACTIVE)) == NULL) {
                device_printf(dev, "unable to allocate memory resource\n");
                return (ENXIO);
        }

	/* Hook up the interrupt handler. */
	rid = 0;
	if ((sc->irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, 
	    RF_SHAREABLE | RF_ACTIVE)) == NULL) {
                device_printf(dev, "unable to allocate IRQ resource\n");
                return (ENXIO);
        }

	if ((error = bus_setup_intr(dev, sc->irq_res, INTR_TYPE_NET, 
	    admsw_intr, NULL, sc, &sc->sc_ih)) != 0) {
                device_printf(dev, 
                    "WARNING: unable to register interrupt handler\n");
                return (error);
        }

	/*
	 * Allocate the control data structures, and create and load the
	 * DMA map for it.
	 */
	if ((error = bus_dma_tag_create(NULL, 4, 0, 
	    BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR,
	    NULL, NULL, sizeof(struct admsw_control_data), 1,
	    sizeof(struct admsw_control_data), 0, NULL, NULL, 
	    &sc->sc_control_dmat)) != 0) {
		device_printf(sc->sc_dev, 
		    "unable to create control data DMA map, error = %d\n", 
		    error);
		return (error);
	}

	if ((error = bus_dmamem_alloc(sc->sc_control_dmat,
	    (void **)&sc->sc_control_data, BUS_DMA_NOWAIT, 
	    &sc->sc_cddmamap)) != 0) {
		device_printf(sc->sc_dev, 
		    "unable to allocate control data, error = %d\n", error);
		return (error);
	}

	if ((error = bus_dmamap_load(sc->sc_control_dmat, sc->sc_cddmamap,
	    sc->sc_control_data, sizeof(struct admsw_control_data), 
	    admsw_dma_map_addr, &sc->sc_cddma, 0)) != 0) {
		device_printf(sc->sc_dev, 
		    "unable to load control data DMA map, error = %d\n", error);
		return (error);
	}

	/*
	 * Create the transmit buffer DMA maps.
	 */
	if ((error = bus_dma_tag_create(NULL, 1, 0, 
	    BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR,
	    NULL, NULL, MCLBYTES, 1, MCLBYTES, 0, NULL, NULL, 
	    &sc->sc_bufs_dmat)) != 0) {
		device_printf(sc->sc_dev, 
		    "unable to create control data DMA map, error = %d\n", 
		    error);
		return (error);
	}

	for (i = 0; i < ADMSW_NTXHDESC; i++) {
		if ((error = bus_dmamap_create(sc->sc_bufs_dmat, 0,
		    &sc->sc_txhsoft[i].ds_dmamap)) != 0) {
			device_printf(sc->sc_dev, 
			    "unable to create txh DMA map %d, error = %d\n", 
			    i, error);
			return (error);
		}
		sc->sc_txhsoft[i].ds_mbuf = NULL;
	}

	for (i = 0; i < ADMSW_NTXLDESC; i++) {
		if ((error = bus_dmamap_create(sc->sc_bufs_dmat, 0,
		    &sc->sc_txlsoft[i].ds_dmamap)) != 0) {
			device_printf(sc->sc_dev, 
			    "unable to create txl DMA map %d, error = %d\n", 
			    i, error);
			return (error);
		}
		sc->sc_txlsoft[i].ds_mbuf = NULL;
	}

	/*
	 * Create the receive buffer DMA maps.
	 */
	for (i = 0; i < ADMSW_NRXHDESC; i++) {
		if ((error = bus_dmamap_create(sc->sc_bufs_dmat, 0, 
		     &sc->sc_rxhsoft[i].ds_dmamap)) != 0) {
			device_printf(sc->sc_dev, 
			    "unable to create rxh DMA map %d, error = %d\n", 
			    i, error);
			return (error);
		}
		sc->sc_rxhsoft[i].ds_mbuf = NULL;
	}

	for (i = 0; i < ADMSW_NRXLDESC; i++) {
		if ((error = bus_dmamap_create(sc->sc_bufs_dmat, 0,
		    &sc->sc_rxlsoft[i].ds_dmamap)) != 0) {
			device_printf(sc->sc_dev, 
			    "unable to create rxl DMA map %d, error = %d\n",
			    i, error);
			return (error);
		}
		sc->sc_rxlsoft[i].ds_mbuf = NULL;
	}

	admsw_init_bufs(sc);
	admsw_reset(sc);

	for (i = 0; i < SW_DEVS; i++) {
		ifmedia_init(&sc->sc_ifmedia[i], 0, admsw_mediachange, 
		    admsw_mediastatus);
		ifmedia_add(&sc->sc_ifmedia[i], IFM_ETHER|IFM_10_T, 0, NULL);
		ifmedia_add(&sc->sc_ifmedia[i], 
		    IFM_ETHER|IFM_10_T|IFM_FDX, 0, NULL);
		ifmedia_add(&sc->sc_ifmedia[i], IFM_ETHER|IFM_100_TX, 0, NULL);
		ifmedia_add(&sc->sc_ifmedia[i], 
		    IFM_ETHER|IFM_100_TX|IFM_FDX, 0, NULL);
		ifmedia_add(&sc->sc_ifmedia[i], IFM_ETHER|IFM_AUTO, 0, NULL);
		ifmedia_set(&sc->sc_ifmedia[i], IFM_ETHER|IFM_AUTO);

		ifp = sc->sc_ifnet[i] = if_alloc(IFT_ETHER);

		/* Setup interface parameters */
		ifp->if_softc = sc;
		if_initname(ifp, device_get_name(dev), i);
		ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
		ifp->if_ioctl = admsw_ioctl;
		ifp->if_output = ether_output;
		ifp->if_start = admsw_start;
		ifp->if_init = admsw_init;
		ifp->if_mtu = ETHERMTU;
		ifp->if_baudrate = IF_Mbps(100);
		IFQ_SET_MAXLEN(&ifp->if_snd, max(ADMSW_NTXLDESC, ifqmaxlen));
		ifp->if_snd.ifq_drv_maxlen = max(ADMSW_NTXLDESC, ifqmaxlen);
		IFQ_SET_READY(&ifp->if_snd);
		ifp->if_capabilities |= IFCAP_VLAN_MTU;

		/* Attach the interface. */
		ether_ifattach(ifp, enaddr);
		enaddr[5]++;
	}

	/* XXX: admwdog_attach(sc); */

	/* leave interrupts and cpu port disabled */
	return (0);
}
Exemple #28
0
int
smc_attach(device_t dev)
{
	int			type, error;
	uint16_t		val;
	u_char			eaddr[ETHER_ADDR_LEN];
	struct smc_softc	*sc;
	struct ifnet		*ifp;

	sc = device_get_softc(dev);
	error = 0;

	sc->smc_dev = dev;

	ifp = sc->smc_ifp = if_alloc(IFT_ETHER);
	if (ifp == NULL) {
		error = ENOSPC;
		goto done;
	}

	mtx_init(&sc->smc_mtx, device_get_nameunit(dev), NULL, MTX_DEF);

	/* Set up watchdog callout. */
	callout_init_mtx(&sc->smc_watchdog, &sc->smc_mtx, 0);

	type = SYS_RES_IOPORT;
	if (sc->smc_usemem)
		type = SYS_RES_MEMORY;

	sc->smc_reg_rid = 0;
	sc->smc_reg = bus_alloc_resource(dev, type, &sc->smc_reg_rid, 0, ~0,
	    16, RF_ACTIVE);
	if (sc->smc_reg == NULL) {
		error = ENXIO;
		goto done;
	}

	sc->smc_irq = bus_alloc_resource(dev, SYS_RES_IRQ, &sc->smc_irq_rid, 0,
	    ~0, 1, RF_ACTIVE | RF_SHAREABLE);
	if (sc->smc_irq == NULL) {
		error = ENXIO;
		goto done;
	}

	SMC_LOCK(sc);
	smc_reset(sc);
	SMC_UNLOCK(sc);

	smc_select_bank(sc, 3);
	val = smc_read_2(sc, REV);
	sc->smc_chip = (val & REV_CHIP_MASK) >> REV_CHIP_SHIFT;
	sc->smc_rev = (val * REV_REV_MASK) >> REV_REV_SHIFT;
	if (bootverbose)
		device_printf(dev, "revision %x\n", sc->smc_rev);

	callout_init_mtx(&sc->smc_mii_tick_ch, &sc->smc_mtx,
	    CALLOUT_RETURNUNLOCKED);
	if (sc->smc_chip >= REV_CHIP_91110FD) {
		(void)mii_attach(dev, &sc->smc_miibus, ifp,
		    smc_mii_ifmedia_upd, smc_mii_ifmedia_sts, BMSR_DEFCAPMASK,
		    MII_PHY_ANY, MII_OFFSET_ANY, 0);
		if (sc->smc_miibus != NULL) {
			sc->smc_mii_tick = smc_mii_tick;
			sc->smc_mii_mediachg = smc_mii_mediachg;
			sc->smc_mii_mediaioctl = smc_mii_mediaioctl;
		}
	}

	smc_select_bank(sc, 1);
	eaddr[0] = smc_read_1(sc, IAR0);
	eaddr[1] = smc_read_1(sc, IAR1);
	eaddr[2] = smc_read_1(sc, IAR2);
	eaddr[3] = smc_read_1(sc, IAR3);
	eaddr[4] = smc_read_1(sc, IAR4);
	eaddr[5] = smc_read_1(sc, IAR5);

	if_initname(ifp, device_get_name(dev), device_get_unit(dev));
	ifp->if_softc = sc;
	ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
	ifp->if_init = smc_init;
	ifp->if_ioctl = smc_ioctl;
	ifp->if_start = smc_start;
	IFQ_SET_MAXLEN(&ifp->if_snd, ifqmaxlen);
	IFQ_SET_READY(&ifp->if_snd);

	ifp->if_capabilities = ifp->if_capenable = 0;

#ifdef DEVICE_POLLING
	ifp->if_capabilities |= IFCAP_POLLING;
#endif

	ether_ifattach(ifp, eaddr);

	/* Set up taskqueue */
	TASK_INIT(&sc->smc_intr, SMC_INTR_PRIORITY, smc_task_intr, ifp);
	TASK_INIT(&sc->smc_rx, SMC_RX_PRIORITY, smc_task_rx, ifp);
	TASK_INIT(&sc->smc_tx, SMC_TX_PRIORITY, smc_task_tx, ifp);
	sc->smc_tq = taskqueue_create_fast("smc_taskq", M_NOWAIT,
	    taskqueue_thread_enqueue, &sc->smc_tq);
	taskqueue_start_threads(&sc->smc_tq, 1, PI_NET, "%s taskq",
	    device_get_nameunit(sc->smc_dev));

	/* Mask all interrupts. */
	sc->smc_mask = 0;
	smc_write_1(sc, MSK, 0);

	/* Wire up interrupt */
	error = bus_setup_intr(dev, sc->smc_irq,
	    INTR_TYPE_NET|INTR_MPSAFE, smc_intr, NULL, sc, &sc->smc_ih);
	if (error != 0)
		goto done;

done:
	if (error != 0)
		smc_detach(dev);
	return (error);
}
Exemple #29
0
void
kue_attachhook(void *xsc)
{
	struct kue_softc *sc = xsc;
	int			s;
	struct ifnet		*ifp;
	usbd_device_handle	dev = sc->kue_udev;
	usbd_interface_handle	iface;
	usbd_status		err;
	usb_interface_descriptor_t	*id;
	usb_endpoint_descriptor_t	*ed;
	int			i;

	/* Load the firmware into the NIC. */
	if (kue_load_fw(sc)) {
		printf("%s: loading firmware failed\n",
		    sc->kue_dev.dv_xname);
		return;
	}

	err = usbd_device2interface_handle(dev, KUE_IFACE_IDX, &iface);
	if (err) {
		printf("%s: getting interface handle failed\n",
		    sc->kue_dev.dv_xname);
		return;
	}

	sc->kue_iface = iface;
	id = usbd_get_interface_descriptor(iface);

	/* Find endpoints. */
	for (i = 0; i < id->bNumEndpoints; i++) {
		ed = usbd_interface2endpoint_descriptor(iface, i);
		if (ed == NULL) {
			printf("%s: couldn't get ep %d\n",
			    sc->kue_dev.dv_xname, i);
			return;
		}
		if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN &&
		    UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) {
			sc->kue_ed[KUE_ENDPT_RX] = ed->bEndpointAddress;
		} else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT &&
			   UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) {
			sc->kue_ed[KUE_ENDPT_TX] = ed->bEndpointAddress;
		} else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN &&
			   UE_GET_XFERTYPE(ed->bmAttributes) == UE_INTERRUPT) {
			sc->kue_ed[KUE_ENDPT_INTR] = ed->bEndpointAddress;
		}
	}

	if (sc->kue_ed[KUE_ENDPT_RX] == 0 || sc->kue_ed[KUE_ENDPT_TX] == 0) {
		printf("%s: missing endpoint\n", sc->kue_dev.dv_xname);
		return;
	}

	/* Read ethernet descriptor */
	err = kue_ctl(sc, KUE_CTL_READ, KUE_CMD_GET_ETHER_DESCRIPTOR,
	    0, &sc->kue_desc, sizeof(sc->kue_desc));
	if (err) {
		printf("%s: could not read Ethernet descriptor\n",
		    sc->kue_dev.dv_xname);
		return;
	}

	sc->kue_mcfilters = malloc(KUE_MCFILTCNT(sc) * ETHER_ADDR_LEN,
	    M_USBDEV, M_NOWAIT);
	if (sc->kue_mcfilters == NULL) {
		printf("%s: no memory for multicast filter buffer\n",
		    sc->kue_dev.dv_xname);
		return;
	}

	s = splnet();

	/*
	 * A KLSI chip was detected. Inform the world.
	 */
	printf("%s: address %s\n", sc->kue_dev.dv_xname,
	    ether_sprintf(sc->kue_desc.kue_macaddr));

	bcopy(sc->kue_desc.kue_macaddr,
	    (char *)&sc->arpcom.ac_enaddr, ETHER_ADDR_LEN);

	/* Initialize interface info.*/
	ifp = GET_IFP(sc);
	ifp->if_softc = sc;
	ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
	ifp->if_ioctl = kue_ioctl;
	ifp->if_start = kue_start;
	ifp->if_watchdog = kue_watchdog;
	strlcpy(ifp->if_xname, sc->kue_dev.dv_xname, IFNAMSIZ);

	IFQ_SET_READY(&ifp->if_snd);

	/* Attach the interface. */
	if_attach(ifp);
	ether_ifattach(ifp);

	sc->kue_attached = 1;
	splx(s);

}
Exemple #30
0
static int
usie_attach(device_t self)
{
	struct usie_softc *sc = device_get_softc(self);
	struct usb_attach_arg *uaa = device_get_ivars(self);
	struct ifnet *ifp;
	struct usb_interface *iface;
	struct usb_interface_descriptor *id;
	struct usb_device_request req;
	int err;
	uint16_t fwattr;
	uint8_t iface_index;
	uint8_t ifidx;
	uint8_t start;

	device_set_usb_desc(self);
	sc->sc_udev = uaa->device;
	sc->sc_dev = self;

	mtx_init(&sc->sc_mtx, "usie", MTX_NETWORK_LOCK, MTX_DEF);

	TASK_INIT(&sc->sc_if_status_task, 0, usie_if_status_cb, sc);
	TASK_INIT(&sc->sc_if_sync_task, 0, usie_if_sync_cb, sc);

	usb_callout_init_mtx(&sc->sc_if_sync_ch, &sc->sc_mtx, 0);

	mtx_lock(&sc->sc_mtx);

	/* set power mode to D0 */
	req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
	req.bRequest = USIE_POWER;
	USETW(req.wValue, 0);
	USETW(req.wIndex, 0);
	USETW(req.wLength, 0);
	if (usie_do_request(sc, &req, NULL)) {
		mtx_unlock(&sc->sc_mtx);
		goto detach;
	}
	/* read fw attr */
	fwattr = 0;
	req.bmRequestType = UT_READ_VENDOR_DEVICE;
	req.bRequest = USIE_FW_ATTR;
	USETW(req.wValue, 0);
	USETW(req.wIndex, 0);
	USETW(req.wLength, sizeof(fwattr));
	if (usie_do_request(sc, &req, &fwattr)) {
		mtx_unlock(&sc->sc_mtx);
		goto detach;
	}
	mtx_unlock(&sc->sc_mtx);

	/* check DHCP supports */
	DPRINTF("fwattr=%x\n", fwattr);
	if (!(fwattr & USIE_FW_DHCP)) {
		device_printf(self, "DHCP is not supported. A firmware upgrade might be needed.\n");
	}

	/* find available interfaces */
	sc->sc_nucom = 0;
	for (ifidx = 0; ifidx < USIE_IFACE_MAX; ifidx++) {
		iface = usbd_get_iface(uaa->device, ifidx);
		if (iface == NULL)
			break;

		id = usbd_get_interface_descriptor(iface);
		if ((id == NULL) || (id->bInterfaceClass != UICLASS_VENDOR))
			continue;

		/* setup Direct IP transfer */
		if (id->bInterfaceNumber >= 7 && id->bNumEndpoints == 3) {
			sc->sc_if_ifnum = id->bInterfaceNumber;
			iface_index = ifidx;

			DPRINTF("ifnum=%d, ifidx=%d\n",
			    sc->sc_if_ifnum, ifidx);

			err = usbd_transfer_setup(uaa->device,
			    &iface_index, sc->sc_if_xfer, usie_if_config,
			    USIE_IF_N_XFER, sc, &sc->sc_mtx);

			if (err == 0)
				continue;

			device_printf(self,
			    "could not allocate USB transfers on "
			    "iface_index=%d, err=%s\n",
			    iface_index, usbd_errstr(err));
			goto detach;
		}

		/* setup ucom */
		if (sc->sc_nucom >= USIE_UCOM_MAX)
			continue;

		usbd_set_parent_iface(uaa->device, ifidx,
		    uaa->info.bIfaceIndex);

		DPRINTF("NumEndpoints=%d bInterfaceNumber=%d\n",
		    id->bNumEndpoints, id->bInterfaceNumber);

		if (id->bNumEndpoints == 2) {
			sc->sc_uc_xfer[sc->sc_nucom][0] = NULL;
			start = 1;
		} else
			start = 0;

		err = usbd_transfer_setup(uaa->device, &ifidx,
		    sc->sc_uc_xfer[sc->sc_nucom] + start,
		    usie_uc_config + start, USIE_UC_N_XFER - start,
		    &sc->sc_ucom[sc->sc_nucom], &sc->sc_mtx);

		if (err != 0) {
			DPRINTF("usbd_transfer_setup error=%s\n", usbd_errstr(err));
			continue;
		}

		mtx_lock(&sc->sc_mtx);
		for (; start < USIE_UC_N_XFER; start++)
			usbd_xfer_set_stall(sc->sc_uc_xfer[sc->sc_nucom][start]);
		mtx_unlock(&sc->sc_mtx);

		sc->sc_uc_ifnum[sc->sc_nucom] = id->bInterfaceNumber;

		sc->sc_nucom++;		/* found a port */
	}

	if (sc->sc_nucom == 0) {
		device_printf(self, "no comports found\n");
		goto detach;
	}

	err = ucom_attach(&sc->sc_super_ucom, sc->sc_ucom,
	    sc->sc_nucom, sc, &usie_uc_callback, &sc->sc_mtx);

	if (err != 0) {
		DPRINTF("ucom_attach failed\n");
		goto detach;
	}
	DPRINTF("Found %d interfaces.\n", sc->sc_nucom);

	/* setup ifnet (Direct IP) */
	sc->sc_ifp = ifp = if_alloc(IFT_OTHER);

	if (ifp == NULL) {
		device_printf(self, "Could not allocate a network interface\n");
		goto detach;
	}
	if_initname(ifp, "usie", device_get_unit(self));

	ifp->if_softc = sc;
	ifp->if_mtu = USIE_MTU_MAX;
	ifp->if_flags |= IFF_NOARP;
	ifp->if_init = usie_if_init;
	ifp->if_ioctl = usie_if_ioctl;
	ifp->if_start = usie_if_start;
	ifp->if_output = usie_if_output;
	IFQ_SET_MAXLEN(&ifp->if_snd, ifqmaxlen);
	ifp->if_snd.ifq_drv_maxlen = ifqmaxlen;
	IFQ_SET_READY(&ifp->if_snd);

	if_attach(ifp);
	bpfattach(ifp, DLT_RAW, 0);

	if (fwattr & USIE_PM_AUTO) {
		usbd_set_power_mode(uaa->device, USB_POWER_MODE_SAVE);
		DPRINTF("enabling automatic suspend and resume\n");
	} else {
		usbd_set_power_mode(uaa->device, USB_POWER_MODE_ON);
		DPRINTF("USB power is always ON\n");
	}

	DPRINTF("device attached\n");
	return (0);

detach:
	usie_detach(self);
	return (ENOMEM);
}