static int
ep_mca_attach(device_t dev)
{
	struct ep_softc *sc = device_get_softc(dev);
	int error = 0;

	if ((error = ep_alloc(dev)))
		goto bad;
	sc->stat = F_ACCESS_32_BITS;

	ep_get_media(sc);

	GO_WINDOW(sc, 0);
	SET_IRQ(sc, rman_get_start(sc->irq));

	if ((error = ep_attach(sc)))
		goto bad;
	if ((error = bus_setup_intr(dev, sc->irq, INTR_TYPE_NET | INTR_MPSAFE, NULL, ep_intr,
		    sc, &sc->ep_intrhand))) {
		device_printf(dev, "bus_setup_intr() failed! (%d)\n", error);
		goto bad;
	}
	return (0);
bad:
	ep_free(dev);
	return (error);
}
Пример #2
0
static int
ep_eisa_attach(device_t dev)
{
	struct ep_softc *sc = device_get_softc(dev);
	struct resource *eisa_io = NULL;
	uint32_t eisa_iobase;
	int irq;
	int error = 0;
	int rid;

	rid = 1;
	eisa_io = bus_alloc_resource_any(dev, SYS_RES_IOPORT, &rid, RF_ACTIVE);
	if (!eisa_io) {
		device_printf(dev, "No I/O space?!\n");
		error = ENXIO;
		goto bad;
	}
	eisa_iobase = rman_get_start(eisa_io);

	/* Reset and Enable the card */
	outb(eisa_iobase + EP_W0_CONFIG_CTRL, W0_P4_CMD_RESET_ADAPTER);
	DELAY(1000);		/* we must wait at least 1 ms */
	outb(eisa_iobase + EP_W0_CONFIG_CTRL, W0_P4_CMD_ENABLE_ADAPTER);
	/* Now the registers are availible through the lower ioport */

	if ((error = ep_alloc(dev))) {
		device_printf(dev, "ep_alloc() failed! (%d)\n", error);
		goto bad;
	}
	switch (eisa_get_id(dev)) {
	case EISA_DEVICE_ID_3COM_3C579_BNC:
	case EISA_DEVICE_ID_3COM_3C579_TP:
		sc->stat = F_ACCESS_32_BITS;
		break;
	}

	ep_get_media(sc);

	irq = rman_get_start(sc->irq);
	if (irq == 9)
		irq = 2;

	GO_WINDOW(sc, 0);
	SET_IRQ(sc, irq);

	if ((error = ep_attach(sc))) {
		device_printf(dev, "ep_attach() failed! (%d)\n", error);
		goto bad;
	}
	if ((error = bus_setup_intr(dev, sc->irq, INTR_TYPE_NET | INTR_MPSAFE, 
	    NULL, ep_intr, sc, &sc->ep_intrhand))) {
		device_printf(dev, "bus_setup_intr() failed! (%d)\n", error);
		goto bad;
	}
	return (0);

bad:
	if (eisa_io)
		bus_release_resource(dev, SYS_RES_IOPORT, 0, eisa_io);

	ep_free(dev);
	return (error);
}
Пример #3
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);
}
Пример #4
0
static int
ep_pccard_attach(device_t dev)
{
	struct ep_softc *sc = device_get_softc(dev);
	uint16_t result;
	int error = 0;
	const struct ep_pccard_product *pp;

	if ((pp = ep_pccard_lookup(dev)) == NULL)
		panic("ep_pccard_attach: can't find product in attach.");

	if (pp->chipset == EP_CHIP_574) {
		sc->epb.mii_trans = 1;
		sc->epb.cmd_off = 2;
	} else {
		sc->epb.mii_trans = 0;
		sc->epb.cmd_off = 0;
	}
	if ((error = ep_alloc(dev))) {
		device_printf(dev, "ep_alloc() failed! (%d)\n", error);
		goto bad;
	}

	if (pp->chipset == EP_CHIP_C1)
		sc->stat |= F_HAS_TX_PLL;
	
	/* ROM size = 0, ROM base = 0 */
	/* For now, ignore AUTO SELECT feature of 3C589B and later. */
	error = ep_get_e(sc, EEPROM_ADDR_CFG, &result);
	CSR_WRITE_2(sc, EP_W0_ADDRESS_CFG, result & 0xc000);

	/* 
	 * Fake IRQ must be 3 for 3C589 and 3C589B.  3C589D and newer
	 * ignore this value.  3C589C is unknown, as are the other
	 * cards supported by this driver, but it appears to never hurt
	 * and always helps.
	 */
	SET_IRQ(sc, 3);
	CSR_WRITE_2(sc, EP_W0_PRODUCT_ID, sc->epb.prod_id);

	if (sc->epb.mii_trans) {
		/*
		 * turn on the MII transciever
		 */
		GO_WINDOW(sc, 3);
		CSR_WRITE_2(sc, EP_W3_OPTIONS, 0x8040);
		DELAY(1000);
		CSR_WRITE_2(sc, EP_W3_OPTIONS, 0xc040);
		CSR_WRITE_2(sc, EP_COMMAND, RX_RESET);
		CSR_WRITE_2(sc, EP_COMMAND, TX_RESET);
		EP_BUSY_WAIT(sc);
		DELAY(1000);
		CSR_WRITE_2(sc, EP_W3_OPTIONS, 0x8040);
	} else
		ep_get_media(sc);

	/*
	 * The 3C562 (a-c revisions) stores the MAC in the CIS in a
	 * way that's unique to 3com.  If we have one of these cards,
	 * scan the CIS for that MAC address, and use it if we find
	 * it.  The NetBSD driver says that the ROADRUNNER chips also
	 * do this, which may be true, but none of the cards that I
	 * have include this TUPLE.  Always prefer the MAC addr in the
	 * CIS tuple to the one returned by the card, as it appears that
	 * only those cards that need it have this special tuple.
	 */
	if (pccard_cis_scan(dev, ep_pccard_mac, sc->eaddr))
		sc->stat |= F_ENADDR_SKIP;
	if ((error = ep_attach(sc))) {
		device_printf(dev, "ep_attach() failed! (%d)\n", error);
		goto bad;
	}
	if ((error = bus_setup_intr(dev, sc->irq, INTR_TYPE_NET | INTR_MPSAFE,
	    NULL, ep_intr, sc, &sc->ep_intrhand))) {
		device_printf(dev, "bus_setup_intr() failed! (%d)\n", error);
		goto bad;
	}
	return (0);
bad:
	ep_free(dev);
	return (error);
}