Beispiel #1
0
static int
an_pccard_attach(device_t dev)
{
	struct an_softc *sc = device_get_softc(dev);
	struct ifnet *ifp = &sc->arpcom.ac_if;
	int flags = device_get_flags(dev);
	int error;

	an_alloc_port(dev, sc->port_rid, AN_IOSIZ);
	an_alloc_irq(dev, sc->irq_rid, 0);

	sc->an_bhandle = rman_get_bushandle(sc->port_res);
	sc->an_btag = rman_get_bustag(sc->port_res);

	error = an_attach(sc, dev, flags);
	if (error)
		goto fail;

	/*
	 * Must setup the interrupt after the an_attach to prevent racing.
	 */
	error = bus_setup_intr(dev, sc->irq_res, INTR_MPSAFE,
			       an_intr, sc, &sc->irq_handle,
			       sc->arpcom.ac_if.if_serializer);
	if (error) {
		ether_ifdetach(&sc->arpcom.ac_if);
		ifmedia_removeall(&sc->an_ifmedia);
		goto fail;
	}

	ifp->if_cpuid = ithread_cpuid(rman_get_start(sc->irq_res));
	KKASSERT(ifp->if_cpuid >= 0 && ifp->if_cpuid < ncpus);

	return 0;

fail:
	an_release_resources(dev);
	return (error);
}
Beispiel #2
0
static int
ep_pccard_attach(device_t dev)
{
	struct ep_softc *	sc = device_get_softc(dev);
	struct ifnet *		ifp = &sc->arpcom.ac_if;
	int			error = 0;

	if ((error = ep_alloc(dev))) {
		device_printf(dev, "ep_alloc() failed! (%d)\n", error);
		goto bad;
	}

	sc->epb.cmd_off = 0;
	sc->epb.prod_id = get_e(sc, EEPROM_PROD_ID);
	if (!ep_pccard_card_attach(&sc->epb)) {
		sc->epb.cmd_off = 2;
		sc->epb.prod_id = get_e(sc, EEPROM_PROD_ID);
		sc->epb.res_cfg = get_e(sc, EEPROM_RESOURCE_CFG);
		if (!ep_pccard_card_attach(&sc->epb)) {
			device_printf(dev,
			    "Probe found ID, attach failed so ignore card!\n");
			error = ENXIO;
			goto bad;
		}
	}

	/* ROM size = 0, ROM base = 0 */
	/* For now, ignore AUTO SELECT feature of 3C589B and later. */
	outw(BASE + EP_W0_ADDRESS_CFG, get_e(sc, EEPROM_ADDR_CFG) & 0xc000);

	/* Fake IRQ must be 3 */
	outw(BASE + EP_W0_RESOURCE_CFG, (sc->epb.res_cfg & 0x0fff) | 0x3000);

	outw(BASE + EP_W0_PRODUCT_ID, sc->epb.prod_id);

	if (sc->epb.mii_trans) {
		/*
		 * turn on the MII transciever
		 */
		GO_WINDOW(3);
		outw(BASE + EP_W3_OPTIONS, 0x8040);
		DELAY(1000);
		outw(BASE + EP_W3_OPTIONS, 0xc040);
		outw(BASE + EP_COMMAND, RX_RESET);
		outw(BASE + EP_COMMAND, TX_RESET);
		while (inw(BASE + EP_STATUS) & S_COMMAND_IN_PROGRESS);
		DELAY(1000);
		outw(BASE + EP_W3_OPTIONS, 0x8040);
	} else {
		ep_get_media(sc);
	}

	if ((error = ep_attach(sc))) {
		device_printf(dev, "ep_attach() failed! (%d)\n", error);
		goto bad;
	}

	error = bus_setup_intr(dev, sc->irq, INTR_MPSAFE, ep_intr,
				    sc, &sc->ep_intrhand, 
				    sc->arpcom.ac_if.if_serializer);
	if (error) {
		device_printf(dev, "bus_setup_intr() failed! (%d)\n", error);
		goto bad;
	}

	ifp->if_cpuid = ithread_cpuid(rman_get_start(sc->irq));
	KKASSERT(ifp->if_cpuid >= 0 && ifp->if_cpuid < ncpus);

	return (0);
bad:
	ep_free(dev);
	return (error);
}
Beispiel #3
0
static int
txp_attach(device_t dev)
{
	struct txp_softc *sc;
	struct ifnet *ifp;
	uint16_t p1;
	uint32_t p2;
	uint8_t enaddr[ETHER_ADDR_LEN];
	int error = 0, rid;

	sc = device_get_softc(dev);
	callout_init(&sc->txp_stat_timer);

	ifp = &sc->sc_arpcom.ac_if;
	if_initname(ifp, device_get_name(dev), device_get_unit(dev));

	pci_enable_busmaster(dev);

	rid = TXP_RID;
	sc->sc_res = bus_alloc_resource_any(dev, TXP_RES, &rid, RF_ACTIVE);

	if (sc->sc_res == NULL) {
		device_printf(dev, "couldn't map ports/memory\n");
		return(ENXIO);
	}

	sc->sc_bt = rman_get_bustag(sc->sc_res);
	sc->sc_bh = rman_get_bushandle(sc->sc_res);

	/* Allocate interrupt */
	rid = 0;
	sc->sc_irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
	    RF_SHAREABLE | RF_ACTIVE);

	if (sc->sc_irq == NULL) {
		device_printf(dev, "couldn't map interrupt\n");
		error = ENXIO;
		goto fail;
	}

	if (txp_chip_init(sc)) {
		error = ENXIO;
		goto fail;
	}

	sc->sc_fwbuf = contigmalloc(32768, M_DEVBUF,
	    M_WAITOK, 0, 0xffffffff, PAGE_SIZE, 0);
	error = txp_download_fw(sc);
	contigfree(sc->sc_fwbuf, 32768, M_DEVBUF);
	sc->sc_fwbuf = NULL;

	if (error)
		goto fail;

	sc->sc_ldata = contigmalloc(sizeof(struct txp_ldata), M_DEVBUF,
	    M_WAITOK | M_ZERO, 0, 0xffffffff, PAGE_SIZE, 0);

	if (txp_alloc_rings(sc)) {
		error = ENXIO;
		goto fail;
	}

	if (txp_command(sc, TXP_CMD_MAX_PKT_SIZE_WRITE, TXP_MAX_PKTLEN, 0, 0,
	    NULL, NULL, NULL, 1)) {
		error = ENXIO;
		goto fail;
	}

	if (txp_command(sc, TXP_CMD_STATION_ADDRESS_READ, 0, 0, 0,
	    &p1, &p2, NULL, 1)) {
		error = ENXIO;
		goto fail;
	}

	txp_set_filter(sc);

	enaddr[0] = ((uint8_t *)&p1)[1];
	enaddr[1] = ((uint8_t *)&p1)[0];
	enaddr[2] = ((uint8_t *)&p2)[3];
	enaddr[3] = ((uint8_t *)&p2)[2];
	enaddr[4] = ((uint8_t *)&p2)[1];
	enaddr[5] = ((uint8_t *)&p2)[0];

	ifmedia_init(&sc->sc_ifmedia, 0, txp_ifmedia_upd, txp_ifmedia_sts);
	ifmedia_add(&sc->sc_ifmedia, IFM_ETHER|IFM_10_T, 0, NULL);
	ifmedia_add(&sc->sc_ifmedia, IFM_ETHER|IFM_10_T|IFM_HDX, 0, NULL);
	ifmedia_add(&sc->sc_ifmedia, IFM_ETHER|IFM_10_T|IFM_FDX, 0, NULL);
	ifmedia_add(&sc->sc_ifmedia, IFM_ETHER|IFM_100_TX, 0, NULL);
	ifmedia_add(&sc->sc_ifmedia, IFM_ETHER|IFM_100_TX|IFM_HDX, 0, NULL);
	ifmedia_add(&sc->sc_ifmedia, IFM_ETHER|IFM_100_TX|IFM_FDX, 0, NULL);
	ifmedia_add(&sc->sc_ifmedia, IFM_ETHER|IFM_AUTO, 0, NULL);

	sc->sc_xcvr = TXP_XCVR_AUTO;
	txp_command(sc, TXP_CMD_XCVR_SELECT, TXP_XCVR_AUTO, 0, 0,
	    NULL, NULL, NULL, 0);
	ifmedia_set(&sc->sc_ifmedia, IFM_ETHER|IFM_AUTO);

	ifp->if_softc = sc;
	ifp->if_mtu = ETHERMTU;
	ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
	ifp->if_ioctl = txp_ioctl;
	ifp->if_start = txp_start;
	ifp->if_watchdog = txp_watchdog;
	ifp->if_init = txp_init;
	ifp->if_baudrate = 100000000;
	ifq_set_maxlen(&ifp->if_snd, TX_ENTRIES);
	ifq_set_ready(&ifp->if_snd);
	ifp->if_hwassist = 0;
	txp_capabilities(sc);

	ether_ifattach(ifp, enaddr, NULL);

	error = bus_setup_intr(dev, sc->sc_irq, INTR_MPSAFE,
			       txp_intr, sc, &sc->sc_intrhand, 
			       ifp->if_serializer);
	if (error) {
		device_printf(dev, "couldn't set up irq\n");
		ether_ifdetach(ifp);
		goto fail;
	}

	ifp->if_cpuid = ithread_cpuid(rman_get_start(sc->sc_irq));
	KKASSERT(ifp->if_cpuid >= 0 && ifp->if_cpuid < ncpus);

	return(0);

fail:
	txp_release_resources(dev);
	return(error);
}
Beispiel #4
0
static int
le_pci_attach(device_t dev)
{
    struct le_pci_softc *lesc;
    struct lance_softc *sc;
    int error, i;

    lesc = device_get_softc(dev);
    sc = &lesc->sc_am79900.lsc;

    pci_enable_busmaster(dev);
    pci_enable_io(dev, PCIM_CMD_PORTEN);

    lesc->sc_rrid = PCIR_BAR(0);
    lesc->sc_rres = bus_alloc_resource_any(dev, SYS_RES_IOPORT,
                                           &lesc->sc_rrid, RF_ACTIVE);
    if (lesc->sc_rres == NULL) {
        device_printf(dev, "cannot allocate registers\n");
        error = ENXIO;
        goto fail_mtx;
    }
    lesc->sc_regt = rman_get_bustag(lesc->sc_rres);
    lesc->sc_regh = rman_get_bushandle(lesc->sc_rres);

    lesc->sc_irid = 0;
    if ((lesc->sc_ires = bus_alloc_resource_any(dev, SYS_RES_IRQ,
                         &lesc->sc_irid, RF_SHAREABLE | RF_ACTIVE)) == NULL) {
        device_printf(dev, "cannot allocate interrupt\n");
        error = ENXIO;
        goto fail_rres;
    }

    error = bus_dma_tag_create(
                NULL,			/* parent */
                1, 0,			/* alignment, boundary */
                BUS_SPACE_MAXADDR_32BIT,	/* lowaddr */
                BUS_SPACE_MAXADDR,		/* highaddr */
                NULL, NULL,			/* filter, filterarg */
                BUS_SPACE_MAXSIZE_32BIT,	/* maxsize */
                0,				/* nsegments */
                BUS_SPACE_MAXSIZE_32BIT,	/* maxsegsize */
                BUS_DMA_WAITOK,		/* flags */
                &lesc->sc_pdmat);
    if (error != 0) {
        device_printf(dev, "cannot allocate parent DMA tag\n");
        goto fail_ires;
    }

    sc->sc_memsize = PCNET_MEMSIZE;
    /*
     * For Am79C970A, Am79C971 and Am79C978 the init block must be 2-byte
     * aligned and the ring descriptors must be 16-byte aligned when using
     * a 32-bit software style.
     */
    error = bus_dma_tag_create(
                lesc->sc_pdmat,		/* parent */
                16, 0,			/* alignment, boundary */
                BUS_SPACE_MAXADDR_32BIT,	/* lowaddr */
                BUS_SPACE_MAXADDR,		/* highaddr */
                NULL, NULL,			/* filter, filterarg */
                sc->sc_memsize,		/* maxsize */
                1,				/* nsegments */
                sc->sc_memsize,		/* maxsegsize */
                BUS_DMA_WAITOK,		/* flags */
                &lesc->sc_dmat);
    if (error != 0) {
        device_printf(dev, "cannot allocate buffer DMA tag\n");
        goto fail_pdtag;
    }

    error = bus_dmamem_alloc(lesc->sc_dmat, (void **)&sc->sc_mem,
                             BUS_DMA_WAITOK | BUS_DMA_COHERENT, &lesc->sc_dmam);
    if (error != 0) {
        device_printf(dev, "cannot allocate DMA buffer memory\n");
        goto fail_dtag;
    }

    sc->sc_addr = 0;
    error = bus_dmamap_load(lesc->sc_dmat, lesc->sc_dmam, sc->sc_mem,
                            sc->sc_memsize, le_pci_dma_callback, sc, 0);
    if (error != 0 || sc->sc_addr == 0) {
        device_printf(dev, "cannot load DMA buffer map\n");
        goto fail_dmem;
    }

    sc->sc_flags = LE_BSWAP;
    sc->sc_conf3 = 0;

    sc->sc_mediastatus = NULL;
    switch (pci_get_device(dev)) {
    case AMD_PCNET_HOME:
        sc->sc_mediachange = le_pci_mediachange;
        sc->sc_supmedia = le_home_supmedia;
        sc->sc_nsupmedia = sizeof(le_home_supmedia) / sizeof(int);
        sc->sc_defaultmedia = le_home_supmedia[0];
        break;
    default:
        sc->sc_mediachange = le_pci_mediachange;
        sc->sc_supmedia = le_pci_supmedia;
        sc->sc_nsupmedia = sizeof(le_pci_supmedia) / sizeof(int);
        sc->sc_defaultmedia = le_pci_supmedia[0];
    }

    /*
     * Extract the physical MAC address from the ROM.
     */
    for (i = 0; i < sizeof(sc->sc_enaddr); i++)
        sc->sc_enaddr[i] =
            bus_space_read_1(lesc->sc_regt, lesc->sc_regh, i);

    sc->sc_copytodesc = lance_copytobuf_contig;
    sc->sc_copyfromdesc = lance_copyfrombuf_contig;
    sc->sc_copytobuf = lance_copytobuf_contig;
    sc->sc_copyfrombuf = lance_copyfrombuf_contig;
    sc->sc_zerobuf = lance_zerobuf_contig;

    sc->sc_rdcsr = le_pci_rdcsr;
    sc->sc_wrcsr = le_pci_wrcsr;
    sc->sc_hwreset = le_pci_hwreset;
    sc->sc_hwinit = NULL;
    sc->sc_hwintr = NULL;
    sc->sc_nocarrier = NULL;

    error = am79900_config(&lesc->sc_am79900, device_get_name(dev),
                           device_get_unit(dev));
    if (error != 0) {
        device_printf(dev, "cannot attach Am79900\n");
        goto fail_dmap;
    }

    error = bus_setup_intr(dev, lesc->sc_ires, INTR_MPSAFE,
                           am79900_intr, sc, &lesc->sc_ih, sc->ifp->if_serializer);
    if (error != 0) {
        device_printf(dev, "cannot set up interrupt\n");
        goto fail_am79900;
    }

    sc->ifp->if_cpuid = ithread_cpuid(rman_get_start(lesc->sc_ires));
    KKASSERT(sc->ifp->if_cpuid >= 0 && sc->ifp->if_cpuid < ncpus);

    return (0);

fail_am79900:
    am79900_detach(&lesc->sc_am79900);
fail_dmap:
    bus_dmamap_unload(lesc->sc_dmat, lesc->sc_dmam);
fail_dmem:
    bus_dmamem_free(lesc->sc_dmat, sc->sc_mem, lesc->sc_dmam);
fail_dtag:
    bus_dma_tag_destroy(lesc->sc_dmat);
fail_pdtag:
    bus_dma_tag_destroy(lesc->sc_pdmat);
fail_ires:
    bus_release_resource(dev, SYS_RES_IRQ, lesc->sc_irid, lesc->sc_ires);
fail_rres:
    bus_release_resource(dev, SYS_RES_IOPORT, lesc->sc_rrid, lesc->sc_rres);
fail_mtx:
    return (error);
}
Beispiel #5
0
static int
le_isa_attach(device_t dev)
{
	struct le_isa_softc *lesc;
	struct lance_softc *sc;
	bus_size_t macstart, rap, rdp;
	int error, i, macstride;

	lesc = device_get_softc(dev);
	sc = &lesc->sc_am7990.lsc;

	lesc->sc_rrid = 0;
	switch (ISA_PNP_PROBE(device_get_parent(dev), dev, le_isa_ids)) {
	case 0:
		lesc->sc_rres = bus_alloc_resource_any(dev, SYS_RES_IOPORT,
		    &lesc->sc_rrid, RF_ACTIVE);
		rap = PCNET_RAP;
		rdp = PCNET_RDP;
		macstart = 0;
		macstride = 1;
		break;
	case ENOENT:
		for (i = 0; i < sizeof(le_isa_params) /
		    sizeof(le_isa_params[0]); i++) {
			if (le_isa_probe_legacy(dev, &le_isa_params[i]) == 0) {
				lesc->sc_rres = bus_alloc_resource(dev,
				    SYS_RES_IOPORT, &lesc->sc_rrid, 0, ~0,
				    le_isa_params[i].iosize, RF_ACTIVE);
				rap = le_isa_params[i].rap;
				rdp = le_isa_params[i].rdp;
				macstart = le_isa_params[i].macstart;
				macstride = le_isa_params[i].macstride;
				goto found;
			}
		}
		/* FALLTHROUGH */
	case ENXIO:
	default:
		device_printf(dev, "cannot determine chip\n");
		error = ENXIO;
		goto fail_mtx;
	}

 found:
	if (lesc->sc_rres == NULL) {
		device_printf(dev, "cannot allocate registers\n");
		error = ENXIO;
		goto fail_mtx;
	}
	lesc->sc_regt = rman_get_bustag(lesc->sc_rres);
	lesc->sc_regh = rman_get_bushandle(lesc->sc_rres);
	lesc->sc_rap = rap;
	lesc->sc_rdp = rdp;

	lesc->sc_drid = 0;
	if ((lesc->sc_dres = bus_alloc_resource_any(dev, SYS_RES_DRQ,
	    &lesc->sc_drid, RF_ACTIVE)) == NULL) {
		device_printf(dev, "cannot allocate DMA channel\n");
		error = ENXIO;
		goto fail_rres;
	}

	lesc->sc_irid = 0;
	if ((lesc->sc_ires = bus_alloc_resource_any(dev, SYS_RES_IRQ,
	    &lesc->sc_irid, RF_SHAREABLE | RF_ACTIVE)) == NULL) {
		device_printf(dev, "cannot allocate interrupt\n");
		error = ENXIO;
		goto fail_dres;
	}

	error = bus_dma_tag_create(
	    NULL,			/* parent */
	    1, 0,			/* alignment, boundary */
	    BUS_SPACE_MAXADDR_24BIT,	/* lowaddr */
	    BUS_SPACE_MAXADDR,		/* highaddr */
	    NULL, NULL,			/* filter, filterarg */
	    BUS_SPACE_MAXSIZE_32BIT,	/* maxsize */
	    0,				/* nsegments */
	    BUS_SPACE_MAXSIZE_32BIT,	/* maxsegsize */
	    BUS_DMA_WAITOK,		/* flags */
	    &lesc->sc_pdmat);
	if (error != 0) {
		device_printf(dev, "cannot allocate parent DMA tag\n");
		goto fail_ires;
	}

	sc->sc_memsize = LE_ISA_MEMSIZE;
	/*
	 * For Am79C90, Am79C961 and Am79C961A the init block must be 2-byte
	 * aligned and the ring descriptors must be 8-byte aligned.
	 */
	error = bus_dma_tag_create(
	    lesc->sc_pdmat,		/* parent */
	    8, 0,			/* alignment, boundary */
	    BUS_SPACE_MAXADDR_24BIT,	/* lowaddr */
	    BUS_SPACE_MAXADDR,		/* highaddr */
	    NULL, NULL,			/* filter, filterarg */
	    sc->sc_memsize,		/* maxsize */
	    1,				/* nsegments */
	    sc->sc_memsize,		/* maxsegsize */
	    BUS_DMA_WAITOK,		/* flags */
	    &lesc->sc_dmat);
	if (error != 0) {
		device_printf(dev, "cannot allocate buffer DMA tag\n");
		goto fail_pdtag;
	}

	error = bus_dmamem_alloc(lesc->sc_dmat, (void **)&sc->sc_mem,
	    BUS_DMA_WAITOK | BUS_DMA_COHERENT, &lesc->sc_dmam);
	if (error != 0) {
		device_printf(dev, "cannot allocate DMA buffer memory\n");
		goto fail_dtag;
	}

	sc->sc_addr = 0;
	error = bus_dmamap_load(lesc->sc_dmat, lesc->sc_dmam, sc->sc_mem,
	    sc->sc_memsize, le_isa_dma_callback, sc, 0);
	if (error != 0 || sc->sc_addr == 0) {
                device_printf(dev, "cannot load DMA buffer map\n");
		goto fail_dmem;
	}

	isa_dmacascade(rman_get_start(lesc->sc_dres));

	sc->sc_flags = 0;
	sc->sc_conf3 = 0;

	/*
	 * Extract the physical MAC address from the ROM.
	 */
	for (i = 0; i < sizeof(sc->sc_enaddr); i++)
		sc->sc_enaddr[i] =  bus_space_read_1(lesc->sc_regt,
		    lesc->sc_regh, macstart + i * macstride);

	sc->sc_copytodesc = lance_copytobuf_contig;
	sc->sc_copyfromdesc = lance_copyfrombuf_contig;
	sc->sc_copytobuf = lance_copytobuf_contig;
	sc->sc_copyfrombuf = lance_copyfrombuf_contig;
	sc->sc_zerobuf = lance_zerobuf_contig;

	sc->sc_rdcsr = le_isa_rdcsr;
	sc->sc_wrcsr = le_isa_wrcsr;
	sc->sc_hwreset = NULL;
	sc->sc_hwinit = NULL;
	sc->sc_hwintr = NULL;
	sc->sc_nocarrier = NULL;
	sc->sc_mediachange = NULL;
	sc->sc_mediastatus = NULL;
	sc->sc_supmedia = NULL;

	error = am7990_config(&lesc->sc_am7990, device_get_name(dev),
	    device_get_unit(dev));
	if (error != 0) {
		device_printf(dev, "cannot attach Am7990\n");
		goto fail_dmap;
	}

	error = bus_setup_intr(dev, lesc->sc_ires, INTR_MPSAFE,
	    am7990_intr, sc, &lesc->sc_ih, sc->ifp->if_serializer);
	if (error != 0) {
		device_printf(dev, "cannot set up interrupt\n");
		goto fail_am7990;
	}

	sc->ifp->if_cpuid = ithread_cpuid(rman_get_start(lesc->sc_ires));
	KKASSERT(sc->ifp->if_cpuid >= 0 && sc->ifp->if_cpuid < ncpus);

	return (0);

 fail_am7990:
	am7990_detach(&lesc->sc_am7990);
 fail_dmap:
	bus_dmamap_unload(lesc->sc_dmat, lesc->sc_dmam);
 fail_dmem:
	bus_dmamem_free(lesc->sc_dmat, sc->sc_mem, lesc->sc_dmam);
 fail_dtag:
	bus_dma_tag_destroy(lesc->sc_dmat);
 fail_pdtag:
	bus_dma_tag_destroy(lesc->sc_pdmat);
 fail_ires:
	bus_release_resource(dev, SYS_RES_IRQ, lesc->sc_irid, lesc->sc_ires);
 fail_dres:
	bus_release_resource(dev, SYS_RES_DRQ, lesc->sc_drid, lesc->sc_dres);
 fail_rres:
	bus_release_resource(dev, SYS_RES_IOPORT, lesc->sc_rrid, lesc->sc_rres);
 fail_mtx:
	return (error);
}