Ejemplo n.º 1
0
static void
ex_probemedia(void)
{
	int i, j;
	struct mtabentry *m;

	/* test for presence of connectors */
	GO_WINDOW(3);
	i = CSR_READ_1(ELINK_W3_RESET_OPTIONS);
	j = (CSR_READ_2(ELINK_W3_INTERNAL_CONFIG + 2) & CONFIG_MEDIAMASK)
		>> CONFIG_MEDIAMASK_SHIFT;
	GO_WINDOW(0);

	for (ether_medium = 0, m = mediatab;
	     ether_medium < sizeof(mediatab) / sizeof(mediatab[0]);
	     ether_medium++, m++) {
		if (j == m->address_cfg) {
			if (!(i & m->config_bit)) {
				printf("%s not present\n", m->name);
				goto bad;
			}
			printf("using %s\n", m->name);
			return;
		}
	}
	printf("unknown connector\n");
bad:
	ether_medium = -1;
}
Ejemplo n.º 2
0
/*
 * Back-end attach and configure.
 */
void
epconfig(struct ep_softc *sc, u_short chipset, u_int8_t *enaddr)
{
	struct ifnet *ifp = &sc->sc_arpcom.ac_if;
	bus_space_tag_t iot = sc->sc_iot;
	bus_space_handle_t ioh = sc->sc_ioh;
	u_int16_t i;

	sc->ep_chipset = chipset;

	/*
	 * We could have been groveling around in other register
	 * windows in the front-end; make sure we're in window 0
	 * to read the EEPROM.
	 */
	GO_WINDOW(0);

	if (enaddr == NULL) {
		/*
		 * Read the station address from the eeprom.
		 */
		for (i = 0; i < 3; i++) {
			u_int16_t x = ep_read_eeprom(sc, i);

			sc->sc_arpcom.ac_enaddr[(i << 1)] = x >> 8;
			sc->sc_arpcom.ac_enaddr[(i << 1) + 1] = x;
		}
	} else {
Ejemplo n.º 3
0
void
ep_get_media(struct ep_softc *sc)
{
	u_int16_t		config;
	
        GO_WINDOW(0);
        config = inw(BASE + EP_W0_CONFIG_CTRL);
        if (config & IS_AUI)
                sc->ep_connectors |= AUI;
        if (config & IS_BNC)
                sc->ep_connectors |= BNC;
        if (config & IS_UTP)
                sc->ep_connectors |= UTP;

        if (!(sc->ep_connectors & 7)) {
		if (bootverbose)
                	if_printf(&sc->arpcom.ac_if, "no connectors!\n");
        }

	/*
	 * This works for most of the cards so we'll do it here.
	 * The cards that require something different can override
	 * this later on.
	 */
	sc->ep_connector = inw(BASE + EP_W0_ADDRESS_CFG) >> ACF_CONNECTOR_BITS;

	return;
}
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);
}
Ejemplo n.º 5
0
void
ex_set_media(void)
{
	int config0, config1;

	CSR_WRITE_2(ELINK_W3_MAC_CONTROL, 0);

	if (ether_medium == ETHERMEDIUM_MII)
		goto setcfg;

	GO_WINDOW(4);
	CSR_WRITE_2(ELINK_W4_MEDIA_TYPE, 0);
	CSR_WRITE_2(ELINK_COMMAND, STOP_TRANSCEIVER);
	delay(800);

	switch (ether_medium) {
	case ETHERMEDIUM_UTP:
		CSR_WRITE_2(ELINK_W4_MEDIA_TYPE,
			    JABBER_GUARD_ENABLE | LINKBEAT_ENABLE);
		break;
	case ETHERMEDIUM_BNC:
		CSR_WRITE_2(ELINK_COMMAND, START_TRANSCEIVER);
		delay(800);
		break;
	case ETHERMEDIUM_AUI:
		CSR_WRITE_2(ELINK_W4_MEDIA_TYPE, SQE_ENABLE);
		delay(800);
		break;
	case ETHERMEDIUM_100TX:
		CSR_WRITE_2(ELINK_W4_MEDIA_TYPE, LINKBEAT_ENABLE);
		break;
	}

setcfg:
	GO_WINDOW(3);

	config0 = CSR_READ_2(ELINK_W3_INTERNAL_CONFIG);
	config1 = CSR_READ_2(ELINK_W3_INTERNAL_CONFIG + 2);

	config1 = config1 & ~CONFIG_MEDIAMASK;
	config1 |= (mediatab[ether_medium].address_cfg
		    << CONFIG_MEDIAMASK_SHIFT);

	CSR_WRITE_2(ELINK_W3_INTERNAL_CONFIG, config0);
	CSR_WRITE_2(ELINK_W3_INTERNAL_CONFIG + 2, config1);
}
Ejemplo n.º 6
0
static int 
ep_ifmedia_upd(struct ifnet *ifp)
{
	struct ep_softc *	sc = ifp->if_softc;
	int			i = 0, j;

	GO_WINDOW(0);
	outw(BASE + EP_COMMAND, STOP_TRANSCEIVER);
	GO_WINDOW(4);
	outw(BASE + EP_W4_MEDIA_TYPE, DISABLE_UTP);
	GO_WINDOW(0);

	switch (IFM_SUBTYPE(sc->ifmedia.ifm_media)) {
		case IFM_10_T:
			if (sc->ep_connectors & UTP) {
				i = ACF_CONNECTOR_UTP;
				GO_WINDOW(4);
				outw(BASE + EP_W4_MEDIA_TYPE, ENABLE_UTP);
			}
			break;
		case IFM_10_2:
			if (sc->ep_connectors & BNC) {
				i = ACF_CONNECTOR_BNC;
				outw(BASE + EP_COMMAND, START_TRANSCEIVER);
				DELAY(DELAY_MULTIPLE * 1000);
			}
			break;
		case IFM_10_5:
			if (sc->ep_connectors & AUI)
				i = ACF_CONNECTOR_AUI;
			break;
		default:
			i = sc->ep_connector;
			if_printf(ifp, "strange connector type in EEPROM: "
				  "assuming AUI\n");
			break;
	}

	GO_WINDOW(0);
	j = inw(BASE + EP_W0_ADDRESS_CFG) & 0x3fff;
	outw(BASE + EP_W0_ADDRESS_CFG, j | (i << ACF_CONNECTOR_BITS));

	return (0);
}
Ejemplo n.º 7
0
/*
 * Bring device up.
 */
void
ex_init(void)
{
	int i;

	ex_waitcmd();
	EtherStop();

	/*
	 * Set the station address and clear the station mask. The latter
	 * is needed for 90x cards, 0 is the default for 90xB cards.
	 */
	GO_WINDOW(2);
	for (i = 0; i < 6; i++) {
		CSR_WRITE_1(ELINK_W2_ADDR_0 + i,
		    myethaddr[i]);
		CSR_WRITE_1(ELINK_W2_RECVMASK_0 + i, 0);
	}

	GO_WINDOW(3);

	CSR_WRITE_2(ELINK_COMMAND, RX_RESET);
	ex_waitcmd();
	CSR_WRITE_2(ELINK_COMMAND, TX_RESET);
	ex_waitcmd();

	CSR_WRITE_2(ELINK_COMMAND, SET_INTR_MASK | 0); /* disable */
	CSR_WRITE_2(ELINK_COMMAND, ACK_INTR | 0xff);

	ex_set_media();

	CSR_WRITE_2(ELINK_COMMAND, SET_RX_FILTER | FIL_INDIVIDUAL | FIL_BRDCST);

	CSR_WRITE_4(ELINK_DNLISTPTR, 0);
	CSR_WRITE_2(ELINK_COMMAND, TX_ENABLE);

	CSR_WRITE_4(ELINK_UPLISTPTR, RECVBUF_PHYS);
	CSR_WRITE_2(ELINK_COMMAND, RX_ENABLE);
	CSR_WRITE_2(ELINK_COMMAND, ELINK_UPUNSTALL);

	GO_WINDOW(1);
}
Ejemplo n.º 8
0
void
ep_get_macaddr(struct ep_softc *sc, uint8_t *addr)
{
	int			i;
	u_int16_t * 		macaddr = (u_int16_t *)addr;

	GO_WINDOW(0);
        for(i = EEPROM_NODE_ADDR_0; i <= EEPROM_NODE_ADDR_2; i++) {
		macaddr[i] = htons(get_e(sc, i));
        }

	return;
}
Ejemplo n.º 9
0
/*
 * Read EEPROM data.
 * XXX what to do if EEPROM doesn't unbusy?
 */
uint16_t
ex_read_eeprom(int offset)
{
	uint16_t data = 0;

	GO_WINDOW(0);
	if (ex_eeprom_busy())
		goto out;
	CSR_WRITE_1(ELINK_W0_EEPROM_COMMAND, READ_EEPROM | (offset & 0x3f));
	if (ex_eeprom_busy())
		goto out;
	data = CSR_READ_2(ELINK_W0_EEPROM_DATA);
out:
	return data;
}
Ejemplo n.º 10
0
int
ep_alloc(device_t dev)
{
	struct ep_softc	*	sc = device_get_softc(dev);
	int			rid;
	int			error = 0;

        rid = 0;
        sc->iobase = bus_alloc_resource_any(dev, SYS_RES_IOPORT, &rid,
	    RF_ACTIVE);
        if (!sc->iobase) {
                device_printf(dev, "No I/O space?!\n");
		error = ENXIO;
                goto bad;
        }

        rid = 0;
        sc->irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, RF_ACTIVE);
        if (!sc->irq) {
                device_printf(dev, "No irq?!\n");
		error = ENXIO;
                goto bad;
        }

	if_initname(&sc->arpcom.ac_if,
		    device_get_name(dev), device_get_unit(dev));
        sc->stat = 0;   /* 16 bit access */

        sc->ep_io_addr = rman_get_start(sc->iobase);

        sc->ep_btag = rman_get_bustag(sc->iobase);
        sc->ep_bhandle = rman_get_bushandle(sc->iobase);

	sc->ep_connectors = 0;
	sc->ep_connector = 0;

        GO_WINDOW(0);
	sc->epb.cmd_off = 0;
	sc->epb.prod_id = get_e(sc, EEPROM_PROD_ID);
	sc->epb.res_cfg = get_e(sc, EEPROM_RESOURCE_CFG);

bad:
	return (error);
}
Ejemplo n.º 11
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);
}
Ejemplo n.º 12
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);
}
Ejemplo n.º 13
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);
}
Ejemplo n.º 14
0
int
ep_attach(struct ep_softc *sc)
{
	struct ifnet *		ifp = NULL;
	struct ifmedia *	ifm = NULL;
	u_short *		p;
	uint8_t			ether_addr[ETHER_ADDR_LEN];
	int			i;

	sc->gone = 0;

	ep_get_macaddr(sc, ether_addr);

	/*
	 * Setup the station address
	 */
	p = (u_short*)ether_addr;
	GO_WINDOW(2);
	for (i = 0; i < 3; i++) {
		outw(BASE + EP_W2_ADDR_0 + (i * 2), ntohs(p[i]));
	}
  
	ifp = &sc->arpcom.ac_if;

	ifp->if_softc = sc;
	ifp->if_mtu = ETHERMTU;
	ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
	ifp->if_start = ep_if_start;
	ifp->if_ioctl = ep_if_ioctl;
	ifp->if_watchdog = ep_if_watchdog;
	ifp->if_init = ep_if_init;
	ifq_set_maxlen(&ifp->if_snd, IFQ_MAXLEN);
	ifq_set_ready(&ifp->if_snd);

	if (!sc->epb.mii_trans) {
		ifmedia_init(&sc->ifmedia, 0, ep_ifmedia_upd, ep_ifmedia_sts);

		if (sc->ep_connectors & AUI)
			ifmedia_add(&sc->ifmedia, IFM_ETHER|IFM_10_5, 0, NULL);
		if (sc->ep_connectors & UTP)
			ifmedia_add(&sc->ifmedia, IFM_ETHER|IFM_10_T, 0, NULL);
		if (sc->ep_connectors & BNC)
			ifmedia_add(&sc->ifmedia, IFM_ETHER|IFM_10_2, 0, NULL);
		if (!sc->ep_connectors)
			ifmedia_add(&sc->ifmedia, IFM_ETHER|IFM_NONE, 0, NULL);
	
		ifmedia_set(&sc->ifmedia, IFM_ETHER|ep_media2if_media[sc->ep_connector]);
	
		ifm = &sc->ifmedia;
		ifm->ifm_media = ifm->ifm_cur->ifm_media;
		ep_ifmedia_upd(ifp);
	}

	ether_ifattach(ifp, ether_addr, NULL);

#ifdef EP_LOCAL_STATS
	sc->rx_no_first = sc->rx_no_mbuf = sc->rx_bpf_disc =
		sc->rx_overrunf = sc->rx_overrunl = sc->tx_underrun = 0;
#endif
	EP_FSET(sc, F_RX_FIRST);
	sc->top = sc->mcur = 0;

	return 0;
}
Ejemplo n.º 15
0
static int 
vx_pci_attach(device_t dev)
{
    struct vx_softc *sc = device_get_softc(dev);
    struct ifnet *ifp = &sc->arpcom.ac_if;
    int rid;

    rid = PCIR_MAPS;
    sc->vx_res = bus_alloc_resource_any(dev, SYS_RES_IOPORT, &rid,
	RF_ACTIVE);

    if (sc->vx_res == NULL)
	goto bad;

    sc->vx_btag = rman_get_bustag(sc->vx_res);
    sc->vx_bhandle = rman_get_bushandle(sc->vx_res);

    rid = 0;
    sc->vx_irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
	RF_SHAREABLE | RF_ACTIVE);

    if (sc->vx_irq == NULL)
	goto bad;

    if (vxattach(dev) == 0) {
	goto bad;
    }

    /* defect check for 3C590 */
    if (pci_get_device(dev) == PCI_PRODUCT_3COM_3C590) {
	GO_WINDOW(0);
	if (vxbusyeeprom(sc))
	    goto bad;
	CSR_WRITE_2(sc, VX_W0_EEPROM_COMMAND,
	    EEPROM_CMD_RD | EEPROM_SOFT_INFO_2);
	if (vxbusyeeprom(sc))
	    goto bad;
	if (!(CSR_READ_2(sc, VX_W0_EEPROM_DATA) & NO_RX_OVN_ANOMALY)) {
	    kprintf("Warning! Defective early revision adapter!\n");
	}
    }

    ifq_set_cpuid(&ifp->if_snd, rman_get_cpuid(sc->vx_irq));

    if (bus_setup_intr(dev, sc->vx_irq, INTR_MPSAFE,
		       vxintr, sc, &sc->vx_intrhand, 
		       ifp->if_serializer)
    ) {
	ether_ifdetach(&sc->arpcom.ac_if);
	goto bad;
    }

    return(0);

bad:
    if (sc->vx_res != NULL)
	bus_release_resource(dev, SYS_RES_IOPORT, 0, sc->vx_res);
    if (sc->vx_irq != NULL)
	bus_release_resource(dev, SYS_RES_IRQ, 0, sc->vx_irq);
    return(ENXIO);
}
Ejemplo n.º 16
0
/**************************************************************************
ETH_RESET - Reset adapter
***************************************************************************/
static void t595_reset(struct nic *nic)
{
	int i;

	/***********************************************************
			Reset 3Com 595 card
	*************************************************************/

	/* stop card */
	outw(RX_DISABLE, BASE + VX_COMMAND);
	outw(RX_DISCARD_TOP_PACK, BASE + VX_COMMAND);
	VX_BUSY_WAIT;
	outw(TX_DISABLE, BASE + VX_COMMAND);
	outw(STOP_TRANSCEIVER, BASE + VX_COMMAND);
	udelay(8000);
	outw(RX_RESET, BASE + VX_COMMAND);
	VX_BUSY_WAIT;
	outw(TX_RESET, BASE + VX_COMMAND);
	VX_BUSY_WAIT;
	outw(C_INTR_LATCH, BASE + VX_COMMAND);
	outw(SET_RD_0_MASK, BASE + VX_COMMAND);
	outw(SET_INTR_MASK, BASE + VX_COMMAND);
	outw(SET_RX_FILTER, BASE + VX_COMMAND);

	/*
	* initialize card
	*/
	VX_BUSY_WAIT;

	GO_WINDOW(0);

	/* Disable the card */
/*	outw(0, BASE + VX_W0_CONFIG_CTRL); */

	/* Configure IRQ to none */
/*	outw(SET_IRQ(0), BASE + VX_W0_RESOURCE_CFG); */

	/* Enable the card */
/*	outw(ENABLE_DRQ_IRQ, BASE + VX_W0_CONFIG_CTRL); */

	GO_WINDOW(2);

	/* Reload the ether_addr. */
	for (i = 0; i < ETH_ALEN; i++)
		outb(nic->node_addr[i], BASE + VX_W2_ADDR_0 + i);

	outw(RX_RESET, BASE + VX_COMMAND);
	VX_BUSY_WAIT;
	outw(TX_RESET, BASE + VX_COMMAND);
	VX_BUSY_WAIT;

	/* Window 1 is operating window */
	GO_WINDOW(1);
	for (i = 0; i < 31; i++)
		inb(BASE + VX_W1_TX_STATUS);

	outw(SET_RD_0_MASK | S_CARD_FAILURE | S_RX_COMPLETE |
		S_TX_COMPLETE | S_TX_AVAIL, BASE + VX_COMMAND);
	outw(SET_INTR_MASK | S_CARD_FAILURE | S_RX_COMPLETE |
		S_TX_COMPLETE | S_TX_AVAIL, BASE + VX_COMMAND);

/*
 * Attempt to get rid of any stray interrupts that occured during
 * configuration.  On the i386 this isn't possible because one may
 * already be queued.  However, a single stray interrupt is
 * unimportant.
 */

	outw(ACK_INTR | 0xff, BASE + VX_COMMAND);

	outw(SET_RX_FILTER | FIL_INDIVIDUAL |
	    FIL_BRDCST|FIL_MULTICAST, BASE + VX_COMMAND);

	vxsetlink();
/*{
	int i,j;
	i = CONNECTOR_TX;
	GO_WINDOW(3);
	j = inl(BASE + VX_W3_INTERNAL_CFG) & ~INTERNAL_CONNECTOR_MASK;
	outl(BASE + VX_W3_INTERNAL_CFG, j | (i <<INTERNAL_CONNECTOR_BITS));
        GO_WINDOW(4);
        outw(LINKBEAT_ENABLE, BASE + VX_W4_MEDIA_TYPE);
        GO_WINDOW(1);
}*/

	/* start tranciever and receiver */
	outw(RX_ENABLE, BASE + VX_COMMAND);
	outw(TX_ENABLE, BASE + VX_COMMAND);

}
Ejemplo n.º 17
0
/**************************************************************************
ETH_RESET - Reset adapter
***************************************************************************/
void
epreset(void)
{
	int i;

	/***********************************************************
			Reset 3Com 509 card
	*************************************************************/

	epstop();

	/*
	 * initialize card
	*/
	while (inw(BASE + EP_STATUS) & S_COMMAND_IN_PROGRESS)
		continue;

	GO_WINDOW(0);

	/* Disable the card */
	outw(BASE + EP_W0_CONFIG_CTRL, 0);

	/* Configure IRQ to none */
	outw(BASE + EP_W0_RESOURCE_CFG, SET_IRQ(0));

	/* Enable the card */
	outw(BASE + EP_W0_CONFIG_CTRL, ENABLE_DRQ_IRQ);

	GO_WINDOW(2);

	/* Reload the ether_addr. */
	for (i = 0; i < 6; i++)
		outb(BASE + EP_W2_ADDR_0 + i, eth_myaddr[i]);

	outw(BASE + EP_COMMAND, RX_RESET);
	outw(BASE + EP_COMMAND, TX_RESET);

	/* Window 1 is operating window */
	GO_WINDOW(1);
	for (i = 0; i < 31; i++)
		inb(BASE + EP_W1_TX_STATUS);

	/* get rid of stray intr's */
	outw(BASE + EP_COMMAND, ACK_INTR | 0xff);

	outw(BASE + EP_COMMAND, SET_RD_0_MASK | S_5_INTS);

	outw(BASE + EP_COMMAND, SET_INTR_MASK);

	outw(BASE + EP_COMMAND, SET_RX_FILTER | FIL_INDIVIDUAL |
	    FIL_BRDCST);

	/* configure BNC */
	if (ether_medium == ETHERMEDIUM_BNC) {
		outw(BASE + EP_COMMAND, START_TRANSCEIVER);
		delay(1000);
	}
	/* configure UTP */
	if (ether_medium == ETHERMEDIUM_UTP) {
		GO_WINDOW(4);
		outw(BASE + EP_W4_MEDIA_TYPE, ENABLE_UTP);
		GO_WINDOW(1);
	}

	/* start tranciever and receiver */
	outw(BASE + EP_COMMAND, RX_ENABLE);
	outw(BASE + EP_COMMAND, TX_ENABLE);

	/* set early threshold for minimal packet length */
	outw(BASE + EP_COMMAND, SET_RX_EARLY_THRESH | 64);

	outw(BASE + EP_COMMAND, SET_TX_START_THRESH | 16);
}
Ejemplo n.º 18
0
/*
 * The order in here seems important. Otherwise we may not receive
 * interrupts. ?!
 */
static void
ep_if_init(void *xsc)
{
    struct ep_softc *sc = xsc;
    struct ifnet *ifp = &sc->arpcom.ac_if;
    int i;

    if (sc->gone)
	return;

    crit_enter();

    while (inw(BASE + EP_STATUS) & S_COMMAND_IN_PROGRESS);

    GO_WINDOW(0);
    outw(BASE + EP_COMMAND, STOP_TRANSCEIVER);
    GO_WINDOW(4);
    outw(BASE + EP_W4_MEDIA_TYPE, DISABLE_UTP);
    GO_WINDOW(0);

    /* Disable the card */
    outw(BASE + EP_W0_CONFIG_CTRL, 0);

    /* Enable the card */
    outw(BASE + EP_W0_CONFIG_CTRL, ENABLE_DRQ_IRQ);

    GO_WINDOW(2);

    /* Reload the ether_addr. */
    for (i = 0; i < 6; i++)
	outb(BASE + EP_W2_ADDR_0 + i, sc->arpcom.ac_enaddr[i]);

    outw(BASE + EP_COMMAND, RX_RESET);
    outw(BASE + EP_COMMAND, TX_RESET);
    while (inw(BASE + EP_STATUS) & S_COMMAND_IN_PROGRESS);

    /* Window 1 is operating window */
    GO_WINDOW(1);
    for (i = 0; i < 31; i++)
	inb(BASE + EP_W1_TX_STATUS);

    /* get rid of stray intr's */
    outw(BASE + EP_COMMAND, ACK_INTR | 0xff);

    outw(BASE + EP_COMMAND, SET_RD_0_MASK | S_5_INTS);

    outw(BASE + EP_COMMAND, SET_INTR_MASK | S_5_INTS);

    if (ifp->if_flags & IFF_PROMISC)
	outw(BASE + EP_COMMAND, SET_RX_FILTER | FIL_INDIVIDUAL |
	 FIL_GROUP | FIL_BRDCST | FIL_ALL);
    else
	outw(BASE + EP_COMMAND, SET_RX_FILTER | FIL_INDIVIDUAL |
	 FIL_GROUP | FIL_BRDCST);

    if (!sc->epb.mii_trans) {
	ep_ifmedia_upd(ifp);
    }

    outw(BASE + EP_COMMAND, RX_ENABLE);
    outw(BASE + EP_COMMAND, TX_ENABLE);

    ifp->if_flags |= IFF_RUNNING;
    ifq_clr_oactive(&ifp->if_snd);	/* just in case */

#ifdef EP_LOCAL_STATS
    sc->rx_no_first = sc->rx_no_mbuf =
	sc->rx_overrunf = sc->rx_overrunl = sc->tx_underrun = 0;
#endif
    EP_FSET(sc, F_RX_FIRST);
    if (sc->top) {
	m_freem(sc->top);
	sc->top = sc->mcur = 0;
    }
    outw(BASE + EP_COMMAND, SET_RX_EARLY_THRESH | RX_INIT_EARLY_THRESH);
    outw(BASE + EP_COMMAND, SET_TX_START_THRESH | 16);

    /*
     * Store up a bunch of mbuf's for use later. (MAX_MBS). First we free up
     * any that we had in case we're being called from intr or somewhere
     * else.
     */

    GO_WINDOW(1);

    if_devstart(ifp);

    crit_exit();
}
Ejemplo n.º 19
0
void
ep_intr(void *arg)
{
    struct ep_softc *sc = arg;
    struct ifnet *ifp = &sc->arpcom.ac_if;
    int status;

     /*
      * quick fix: Try to detect an interrupt when the card goes away.
      */
    if (sc->gone || inw(BASE + EP_STATUS) == 0xffff) {
	    return;
    }

    outw(BASE + EP_COMMAND, SET_INTR_MASK); /* disable all Ints */

rescan:

    while ((status = inw(BASE + EP_STATUS)) & S_5_INTS) {

	/* first acknowledge all interrupt sources */
	outw(BASE + EP_COMMAND, ACK_INTR | (status & S_MASK));

	if (status & (S_RX_COMPLETE | S_RX_EARLY))
	    epread(sc);
	if (status & S_TX_AVAIL) {
	    /* we need ACK */
	    ifp->if_timer = 0;
	    ifq_clr_oactive(&ifp->if_snd);
	    GO_WINDOW(1);
	    inw(BASE + EP_W1_FREE_TX);
	    if_devstart(ifp);
	}
	if (status & S_CARD_FAILURE) {
	    ifp->if_timer = 0;
#ifdef EP_LOCAL_STATS
	    kprintf("\n");
	    if_printf(ifp, "\n\tStatus: %x\n", status);
	    GO_WINDOW(4);
	    kprintf("\tFIFO Diagnostic: %x\n", inw(BASE + EP_W4_FIFO_DIAG));
	    kprintf("\tStat: %x\n", sc->stat);
	    kprintf("\tIpackets=%d, Opackets=%d\n",
		ifp->if_ipackets, ifp->if_opackets);
	    kprintf("\tNOF=%d, NOMB=%d, RXOF=%d, RXOL=%d, TXU=%d\n",
		   sc->rx_no_first, sc->rx_no_mbuf, sc->rx_overrunf,
		   sc->rx_overrunl, sc->tx_underrun);
#else

#ifdef DIAGNOSTIC
	    if_printf(ifp, "Status: %x (input buffer overflow)\n", status);
#else
	    IFNET_STAT_INC(ifp, ierrors, 1);
#endif

#endif
	    ep_if_init(sc);
	    return;
	}
	if (status & S_TX_COMPLETE) {
	    ifp->if_timer = 0;
	    /* we  need ACK. we do it at the end */
	    /*
	     * We need to read TX_STATUS until we get a 0 status in order to
	     * turn off the interrupt flag.
	     */
	    while ((status = inb(BASE + EP_W1_TX_STATUS)) & TXS_COMPLETE) {
		if (status & TXS_SUCCES_INTR_REQ);
		else if (status & (TXS_UNDERRUN | TXS_JABBER | TXS_MAX_COLLISION)) {
		    outw(BASE + EP_COMMAND, TX_RESET);
		    if (status & TXS_UNDERRUN) {
#ifdef EP_LOCAL_STATS
			sc->tx_underrun++;
#endif
		    } else {
			if (status & TXS_JABBER);
			else	/* TXS_MAX_COLLISION - we shouldn't get here */
			    IFNET_STAT_INC(ifp, collisions, 1);
		    }
		    IFNET_STAT_INC(ifp, oerrors, 1);
		    outw(BASE + EP_COMMAND, TX_ENABLE);
		    /*
		     * To have a tx_avail_int but giving the chance to the
		     * Reception
		     */
		    if (!ifq_is_empty(&ifp->if_snd))
			outw(BASE + EP_COMMAND, SET_TX_AVAIL_THRESH | 8);
		}
		outb(BASE + EP_W1_TX_STATUS, 0x0);	/* pops up the next
							 * status */
	    }			/* while */
	    ifq_clr_oactive(&ifp->if_snd);
	    GO_WINDOW(1);
	    inw(BASE + EP_W1_FREE_TX);
	    if_devstart(ifp);
	}			/* end TX_COMPLETE */
    }

    outw(BASE + EP_COMMAND, C_INTR_LATCH);	/* ACK int Latch */

    if ((status = inw(BASE + EP_STATUS)) & S_5_INTS)
	goto rescan;

    /* re-enable Ints */
    outw(BASE + EP_COMMAND, SET_INTR_MASK | S_5_INTS);
}