Пример #1
0
static int
rtwn_usb_attach(device_t self)
{
	struct usb_attach_arg *uaa = device_get_ivars(self);
	struct rtwn_usb_softc *uc = device_get_softc(self);
	struct rtwn_softc *sc = &uc->uc_sc;
	struct ieee80211com *ic = &sc->sc_ic;
	int error;

	device_set_usb_desc(self);
	uc->uc_udev = uaa->device;
	sc->sc_dev = self;
	ic->ic_name = device_get_nameunit(self);

	/* Need to be initialized early. */
	rtwn_sysctlattach(sc);
	rtwn_usb_sysctlattach(sc);
	mtx_init(&sc->sc_mtx, ic->ic_name, MTX_NETWORK_LOCK, MTX_DEF);

	rtwn_usb_attach_methods(sc);
	rtwn_usb_attach_private(uc, USB_GET_DRIVER_INFO(uaa));

	error = rtwn_usb_setup_endpoints(uc);
	if (error != 0)
		goto detach;

	/* Allocate Tx/Rx buffers. */
	error = rtwn_usb_alloc_rx_list(sc);
	if (error != 0)
		goto detach;

	error = rtwn_usb_alloc_tx_list(sc);
	if (error != 0)
		goto detach;

	/* Generic attach. */
	error = rtwn_attach(sc);
	if (error != 0)
		goto detach;

	return (0);

detach:
	rtwn_usb_detach(self);		/* failure */
	return (ENXIO);
}
Пример #2
0
static int
rtwn_pci_attach(device_t dev)
{
	const struct rtwn_pci_ident *ident;
	struct rtwn_pci_softc *pc = device_get_softc(dev);
	struct rtwn_softc *sc = &pc->pc_sc;
	struct ieee80211com *ic = &sc->sc_ic;
	uint32_t lcsr;
	int cap_off, i, error, rid;

	ident = rtwn_pci_probe_sub(dev);
	if (ident == NULL)
		return (ENXIO);

	/*
	 * Get the offset of the PCI Express Capability Structure in PCI
	 * Configuration Space.
	 */
	error = pci_find_cap(dev, PCIY_EXPRESS, &cap_off);
	if (error != 0) {
		device_printf(dev, "PCIe capability structure not found!\n");
		return (error);
	}

	/* Enable bus-mastering. */
	pci_enable_busmaster(dev);

	rid = PCIR_BAR(2);
	pc->mem = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
	    RF_ACTIVE);
	if (pc->mem == NULL) {
		device_printf(dev, "can't map mem space\n");
		return (ENOMEM);
	}
	pc->pc_st = rman_get_bustag(pc->mem);
	pc->pc_sh = rman_get_bushandle(pc->mem);

	/* Install interrupt handler. */
	rid = 1;
	if (pci_alloc_msi(dev, &rid) == 0)
		rid = 1;
	else
		rid = 0;
	pc->irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, RF_ACTIVE |
	    (rid != 0 ? 0 : RF_SHAREABLE));
	if (pc->irq == NULL) {
		device_printf(dev, "can't map interrupt\n");
		goto detach;
	}

	/* Disable PCIe Active State Power Management (ASPM). */
	lcsr = pci_read_config(dev, cap_off + PCIER_LINK_CTL, 4);
	lcsr &= ~PCIEM_LINK_CTL_ASPMC;
	pci_write_config(dev, cap_off + PCIER_LINK_CTL, lcsr, 4);

	sc->sc_dev = dev;
	ic->ic_name = device_get_nameunit(dev);

	/* Need to be initialized early. */
	rtwn_sysctlattach(sc);
	mtx_init(&sc->sc_mtx, ic->ic_name, MTX_NETWORK_LOCK, MTX_DEF);

	rtwn_pci_attach_methods(sc);
	rtwn_pci_attach_private(pc, ident->chip);

	/* Allocate Tx/Rx buffers. */
	error = rtwn_pci_alloc_rx_list(sc);
	if (error != 0) {
		device_printf(dev,
		    "could not allocate Rx buffers, error %d\n",
		    error);
		goto detach;
	}
	for (i = 0; i < RTWN_PCI_NTXQUEUES; i++) {
		error = rtwn_pci_alloc_tx_list(sc, i);
		if (error != 0) {
			device_printf(dev,
			    "could not allocate Tx buffers, error %d\n",
			    error);
			goto detach;
		}
	}

	/* Generic attach. */
	error = rtwn_attach(sc);
	if (error != 0)
		goto detach;

	/*
	 * Hook our interrupt after all initialization is complete.
	 */
	error = bus_setup_intr(dev, pc->irq, INTR_TYPE_NET | INTR_MPSAFE,
	    NULL, rtwn_pci_intr, sc, &pc->pc_ih);
	if (error != 0) {
		device_printf(dev, "can't establish interrupt, error %d\n",
		    error);
		goto detach;
	}

	return (0);

detach:
	rtwn_pci_detach(dev);		/* failure */
	return (ENXIO);
}