/*
 * Install interface into kernel networking data structures.
 */
void
ne_xsurf_attach(device_t parent, device_t self, void *aux)
{
	struct ne_xsurf_softc *zsc = device_private(self);
	struct ne2000_softc *nsc = &zsc->sc_ne2000;
	struct dp8390_softc *dsc = &nsc->sc_dp8390;

	struct xsurfbus_attach_args *xap = aux;

	bus_space_tag_t nict = &zsc->sc_bst;
	bus_space_handle_t nich;
	bus_space_tag_t asict = nict;
	bus_space_handle_t asich;

	dsc->sc_dev = self;
	dsc->sc_mediachange = rtl80x9_mediachange;
	dsc->sc_mediastatus = rtl80x9_mediastatus;
	dsc->init_card = rtl80x9_init_card;
	dsc->sc_media_init = rtl80x9_media_init;

	zsc->sc_bst.base = xap->xaa_base;

	zsc->sc_bst.absm = &amiga_bus_stride_2;

	aprint_normal("\n");

	/* Map i/o space. */
	if (bus_space_map(nict, NE_XSURF_NICBASE, 
	    NE_XSURF_NPORTS, 0, &nich)) {
		aprint_error_dev(self, "can't map nic i/o space\n");
		return;
	}

	if (bus_space_subregion(nict, nich, NE2000_ASIC_OFFSET, 
	    NE_XSURF_ASICSIZE, &asich)) {
		aprint_error_dev(self, "can't map asic i/o space\n");
		return;
	}

	dsc->sc_regt = nict;
	dsc->sc_regh = nich;

	nsc->sc_asict = asict;
	nsc->sc_asich = asich;

	/* This interface is always enabled. */
	dsc->sc_enabled = 1;

	/*
	 * Do generic NE2000 attach.  This will read the station address
	 * from the EEPROM.
	 */
	ne2000_attach(nsc, NULL);

	zsc->sc_isr.isr_intr = dp8390_intr;
	zsc->sc_isr.isr_arg = dsc;
	zsc->sc_isr.isr_ipl = 2;
	add_isr(&zsc->sc_isr);
}
예제 #2
0
파일: if_ne_obio.c 프로젝트: ryo/netbsd-src
void
ne_obio_attach(device_t parent, device_t self, void *aux )
{
    struct ne_obio_softc *sc = device_private(self);
    struct obio_attach_args *oba = aux;
    bus_space_tag_t iot = oba->oba_iot;
    bus_space_handle_t  nioh, aioh;
    uint8_t my_ea[ETHER_ADDR_LEN];
    int i;

    aprint_normal("\n");
    sc->nsc.sc_dp8390.sc_dev = self;

    /* Map i/o space. */
    if (bus_space_map(iot, oba->oba_addr, NE2000_NPORTS, 0, &nioh))
        return;

    if (bus_space_subregion(iot, nioh, NE2000_ASIC_OFFSET,
                            NE2000_ASIC_NPORTS, &aioh))
        goto out2;

    sc->nsc.sc_dp8390.sc_regt = iot;
    sc->nsc.sc_dp8390.sc_regh = nioh;

    sc->nsc.sc_asict = iot;
    sc->nsc.sc_asich = aioh;

    /*
     * XXX:
     * AX88796's reset register doesn't seem to work, and
     * ne2000_detect() fails.  We hardcord NIC type here.
     */
    sc->nsc.sc_type = NE2000_TYPE_NE2000; /* XXX _AX88796 ? */
    sc->nsc.sc_dp8390.sc_flags = DP8390_NO_REMOTE_DMA_COMPLETE;
    /* DP8390_NO_MULTI_BUFFERING; XXX */

    /* G4250EBX doesn't have EEPROM hooked to AX88796.  Read MAC
     * address set by Redboot and don't let ne2000_atthch() try to
     * read MAC from hardware.  (current ne2000 driver doesn't
     * support AX88796's EEPROM interface)
     */

    bus_space_write_1( iot, nioh, ED_P0_CR, ED_CR_RD2|ED_CR_PAGE_1 );

    for( i=0; i < ETHER_ADDR_LEN; ++i )
        my_ea[i] = bus_space_read_1( iot, nioh, ED_P1_PAR0+i );

    bus_space_write_1( iot, nioh, ED_P0_CR, ED_CR_RD2|ED_CR_PAGE_0 );

    /* disable all interrupts */
    bus_space_write_1(iot, nioh, ED_P0_IMR, 0);

#ifdef DEBUG_GPIO
    bus_space_write_4( pxa2x0_softc->saip.sc_iot,
                       pxa2x0_softc->saip.sc_gpioh,
                       GPIO_GPDR0, (0x01<<DEBUG_GPIO) | (0x01<<DEBUG_GPIO2) |
                       bus_space_read_4(pxa2x0_softc->saip.sc_iot, pxa2x0_softc->saip.sc_gpioh,
                                        GPIO_GPDR0));

#endif
    /* delay intr_establish until this IF is enabled
       to avoid spurious interrupts. */
    sc->nsc.sc_dp8390.sc_enabled = 0;
    sc->nsc.sc_dp8390.sc_enable = ne_obio_enable;
    sc->intr_no = oba->oba_intr;

    if( ne2000_attach( &sc->nsc, my_ea ) )
        goto out;

#ifndef ED_DCR_RDCR
#define ED_DCR_RDCR 0
#endif

    bus_space_write_1(iot, nioh, ED_P0_DCR, ED_DCR_RDCR|ED_DCR_WTS);

    return;

out:
    bus_space_unmap( iot, aioh, NE2000_ASIC_NPORTS );
out2:
    bus_space_unmap( iot, nioh, NE2000_NPORTS );
    return;
}
static void
ne_mainbus_attach(device_t parent, device_t self, void *aux)
{
	struct ne_mainbus_softc *msc = device_private(self);
	struct ne2000_softc *nsc = &msc->sc_ne2000;
	struct dp8390_softc *dsc = &nsc->sc_dp8390;
	bus_space_tag_t nict = &t_sh7706lan_bus_io;
	bus_space_handle_t nich;
	bus_space_tag_t asict = nict;
	bus_space_handle_t asich;
	const char *typestr;
	int netype;

	dsc->sc_dev = self;

	aprint_naive("\n");
	aprint_normal("\n");

	/* Map i/o space. */
	if (bus_space_map(nict, 0x10000300, NE2000_NPORTS, 0, &nich)){
		aprint_error_dev(self, "can't map i/o space\n");
		return;
	}

	if (bus_space_subregion(nict, nich, NE2000_ASIC_OFFSET,
	    NE2000_ASIC_NPORTS, &asich)) {
		aprint_error_dev(self, "can't subregion i/o space\n");
		bus_space_unmap(nict, nich, NE2000_NPORTS);
		return;
	}

	dsc->sc_regt = nict;
	dsc->sc_regh = nich;

	nsc->sc_asict = asict;
	nsc->sc_asich = asich;

	/*
	 * Detect it again, so we can print some information about the
	 * interface.
	 */
	netype = ne2000_detect(nict, nich, asict, asich);
	switch (netype) {
	case NE2000_TYPE_NE1000:
		typestr = "NE1000";
		break;

	case NE2000_TYPE_NE2000:
		typestr = "NE2000";
		break;

	case NE2000_TYPE_RTL8019:
		typestr = "NE2000 (RTL8019)";
 		break;

	default:
		aprint_error_dev(self, "where did the card go?!\n");
		bus_space_unmap(nict, nich, NE2000_NPORTS);
		return;
	}

	aprint_normal_dev(self, "%s Ethernet\n", typestr);

	/* This interface is always enabled. */
	dsc->sc_enabled = 1;

	/* force 8bit */
	nsc->sc_quirk |= NE2000_QUIRK_8BIT;

	/*
	 * Do generic NE2000 attach.  This will read the station address
	 * from the EEPROM.
	 */
	ne2000_attach(nsc, NULL);

	/* Establish the interrupt handler. */
	msc->sc_ih = intc_intr_establish(SH7709_INTEVT2_IRQ2, IST_LEVEL,
	    IPL_NET, dp8390_intr, dsc);
	if (msc->sc_ih == NULL)
		aprint_error_dev(self,
		    "couldn't establish interrupt handler\n");
}
예제 #4
0
static void
ne_isapnp_attach(struct device *parent, struct device *self, void *aux)
{
	struct ne_isapnp_softc * const isc = (struct ne_isapnp_softc *)self;
	struct ne2000_softc * const nsc = &isc->sc_ne2000;
	struct dp8390_softc * const dsc = &nsc->sc_dp8390;
	struct isa_attach_args * const ipa = aux;
	bus_space_tag_t nict;
	bus_space_handle_t nich;
	bus_space_tag_t asict;
	bus_space_handle_t asich;
	const char *typestr;
	int netype;

	nict = ipa->ia_iot;
	nich = ipa->ipa_io[0].h;

	asict = nict;

	if (bus_space_subregion(nict, nich, NE2000_ASIC_OFFSET,
	    NE2000_ASIC_NPORTS, &asich)) {
		printf("%s: can't subregion i/o space\n", dsc->sc_dev.dv_xname);
		return;
	}

	dsc->sc_regt = nict;
	dsc->sc_regh = nich;

	nsc->sc_asict = asict;
	nsc->sc_asich = asich;

	/*
	 * Detect it again, so we can print some information about the
	 * interface.
	 */
	netype = ne2000_detect(nsc);
	switch (netype) {
	case NE2000_TYPE_NE1000:
		typestr = "NE1000";
		break;

	case NE2000_TYPE_NE2000:
		typestr = "NE2000";
		/*
		 * Check for a RealTek 8019.
		 */
		bus_space_write_1(nict, nich, ED_P0_CR,
		    ED_CR_PAGE_0 | ED_CR_STP);
		if (bus_space_read_1(nict, nich, NERTL_RTL0_8019ID0) ==
								RTL0_8019ID0 &&
		    bus_space_read_1(nict, nich, NERTL_RTL0_8019ID1) ==
								RTL0_8019ID1) {
			typestr = "NE2000 (RTL8019)";
			dsc->sc_mediachange = rtl80x9_mediachange;
			dsc->sc_mediastatus = rtl80x9_mediastatus;
			dsc->init_card = rtl80x9_init_card;
			dsc->sc_media_init = rtl80x9_media_init;
		}
		break;

	default:
		printf(": where did the card go?!\n");
		return;
	}

	printf(": %s", typestr);

	/* This interface is always enabled. */
	dsc->sc_enabled = 1;

	/*
	 * Do generic NE2000 attach.  This will read the station address
	 * from the EEPROM.
	 */
	ne2000_attach(nsc, NULL);

	/* Establish the interrupt handler. */
	isc->sc_ih = isa_intr_establish(ipa->ia_ic, ipa->ipa_irq[0].num,
	    IST_EDGE, IPL_NET, dp8390_intr, dsc,
	    dsc->sc_dev.dv_xname);
	if (isc->sc_ih == NULL)
		printf(": couldn't establish interrupt handler\n");
}
예제 #5
0
void
ne_mca_attach(device_t parent, device_t self, void *aux)
{
	struct ne_mca_softc *psc = device_private(self);
	struct ne2000_softc *nsc = &psc->sc_ne2000;
	struct dp8390_softc *dsc = &nsc->sc_dp8390;
	struct mca_attach_args *ma = aux;
	bus_space_tag_t nict;
	bus_space_handle_t nich;
	bus_space_tag_t asict;
	bus_space_handle_t asich;
	int pos2, iobase, irq;
	const struct ne_mca_products *np;

	dsc->sc_dev = self;

	pos2 = mca_conf_read(ma->ma_mc, ma->ma_slot, 2);

	/*
	 * POS register 2: (adf pos0)
	 *
	 * 7 6 5 4 3 2 1 0
	 *   \_/ | \___/ \__ enable: 0=adapter disabled, 1=adapter enabled
	 *    |  |     \____ I/O, Mem: 001=0x1000-0x102f 010=0x2020-0x204f
	 *    |  |             011=0x8020-0x804f 100=0xa0a0-0xa0cf
	 *    |  |             101=0xb0b0-0xb0df 110=0xc0c0-0xc0ef
	 *     \  \            111=0xc3d0-0xc3ff
	 *      \  \________ Boot Rom: 1=disabled 0=enabled
	 *       \__________ Interrupt level: 00=3 01=4 10=5 11=9
	 */

	np = ne_mca_lookup(ma->ma_id);

	iobase = ne_mca_iobase[(pos2 & 0x0e) >> 1];
	irq = ne_mca_irq[(pos2 & 0x60) >> 5];

	aprint_normal(" slot %d irq %d: %s\n", ma->ma_slot + 1, irq,
	    np->ne_name);

	nict = ma->ma_iot;

	/* Map the device. */
	if (bus_space_map(nict, iobase, NE2_NPORTS, 0, &nich)) {
		aprint_error_dev(self, "can't map i/o space\n");
		return;
	}

	asict = nict;
	if (bus_space_subregion(nict, nich, NE2000_ASIC_OFFSET,
	    NE2000_ASIC_NPORTS, &asich)) {
		aprint_error_dev(self, "can't subregion i/o space\n");
		return;
	}

	dsc->sc_regt = nict;
	dsc->sc_regh = nich;

	nsc->sc_asict = asict;
	nsc->sc_asich = asich;

	/* This interface is always enabled. */
	dsc->sc_enabled = 1;

	dsc->sc_mediachange	= NULL;
	dsc->sc_mediastatus	= NULL;
	dsc->sc_media_init	= NULL;
	dsc->init_card		= NULL;

	/*
	 * This is necessary for NE/2. Hopefully the other clones also work
	 * this way.
	 */
	nsc->sc_type = NE2000_TYPE_AX88190;

	/*
	 * Do generic NE2000 attach.  This will read the station address
	 * from the EEPROM.
	 */
	if (ne2000_attach(nsc, NULL))
		return;

	/* establish interrupt handler */
	psc->sc_ih = mca_intr_establish(ma->ma_mc, irq, IPL_NET, dp8390_intr,
			dsc);
	if (psc->sc_ih == NULL) {
		aprint_error_dev(self,
		    "couldn't establish interrupt handler\n");
		return;
	}
}
예제 #6
0
void
ne_neptune_attach(device_t parent, device_t self, void *aux)
{
	struct ne_neptune_softc *nsc = device_private(self);
	struct dp8390_softc *dsc = &nsc->sc_dp8390;
	struct neptune_attach_args *na = aux;
	bus_space_tag_t nict = na->na_bst;
	bus_space_handle_t nich;
	bus_space_tag_t asict = nict;
	bus_space_handle_t asich;
	const char *typestr;
	int netype;

	dsc->sc_dev = self;
	aprint_normal("\n");

	/* Map i/o space. */
	if (bus_space_map(nict, na->na_addr, NE2000_NPORTS*2, 0, &nich)) {
		aprint_error_dev(self, "can't map i/o space\n");
		return;
	}

	if (bus_space_subregion(nict, nich, NE2000_ASIC_OFFSET,
	    NE2000_ASIC_NPORTS*2, &asich)) {
		aprint_error_dev(self, "can't subregion i/o space\n");
		return;
	}

	dsc->sc_regt = nict;
	dsc->sc_regh = nich;

	nsc->sc_asict = asict;
	nsc->sc_asich = asich;

	/*
	 * Detect it again, so we can print some information about the
	 * interface.
	 */
	netype = ne2000_detect(nict, nich, asict, asich);
	switch (netype) {
	case NE2000_TYPE_NE1000:
		typestr = "NE1000";
		break;

	case NE2000_TYPE_NE2000:
		typestr = "NE2000";
		break;

	case NE2000_TYPE_RTL8019:
		typestr = "NE2000 (RTL8019)";
		break;

	default:
		aprint_error_dev(self, "where did the card go?!\n");
		return;
	}

	aprint_normal_dev(self, "%s Ethernet\n", typestr);

	/* This interface is always enabled. */
	dsc->sc_enabled = 1;

	/*
	 * Do generic NE2000 attach.  This will read the station address
	 * from the EEPROM.
	 */
	ne2000_attach(nsc, NULL);

	/* Establish the interrupt handler. */
	if (neptune_intr_establish(na->na_intr, "ne", dp8390_intr, dsc))
		aprint_error_dev(self,
		    "couldn't establish interrupt handler\n");
}
예제 #7
0
static void
ne_intio_attach(device_t parent, device_t self, void *aux)
{
	struct ne_intio_softc *sc = device_private(self);
	struct dp8390_softc *dsc = &sc->sc_dp8390;
	struct intio_attach_args *ia = aux;
	bus_space_tag_t iot = ia->ia_bst;
	bus_space_handle_t ioh;
	bus_space_tag_t asict;
	bus_space_handle_t asich;
	const char *typestr;
	int netype;

	dsc->sc_dev = self;
	aprint_normal(": Nereid Ethernet\n");

	/* Map I/O space */
	if (bus_space_map(iot, ia->ia_addr, NE2000_NPORTS*2,
			BUS_SPACE_MAP_SHIFTED_EVEN, &ioh)){
		aprint_error_dev(self, "can't map I/O space\n");
		return;
	}

	asict = iot;
	if (bus_space_subregion(iot, ioh, NE2000_ASIC_OFFSET*2,
			NE2000_ASIC_NPORTS*2, &asich)) {
		aprint_error_dev(self, "can't subregion I/O space\n");
		return;
	}

	dsc->sc_regt = iot;
	dsc->sc_regh = ioh;

	sc->sc_asict = asict;
	sc->sc_asich = asich;

	/*
	 * detect it again, so we can print some information about
	 * the interface.
	 * XXX: Should I check NE1000 or NE2000 for Nereid?
	 */
	netype = ne2000_detect(iot, ioh, asict, asich);
	switch (netype) {
	case NE2000_TYPE_NE1000:
		typestr = "NE1000";
		break;

	case NE2000_TYPE_NE2000:
		typestr = "NE2000";
		break;

	case NE2000_TYPE_RTL8019:
		typestr = "NE2000 (RTL8019)";
		break;

	default:
		aprint_error_dev(self, "where did the card go?!\n");
		return;
	}

	aprint_normal_dev(self, "%s Ethernet\n", typestr);

	/* This interface is always enabled */
	dsc->sc_enabled = 1;

	/*
	 * Do generic NE2000 attach.
	 * This will read the mac address from the EEPROM.
	 */
	ne2000_attach(sc, NULL);

	/* Establish the interrupt handler */
	if (intio_intr_establish(ia->ia_intr, "ne", dp8390_intr, dsc))
		aprint_error_dev(self,
		    "couldn't establish interrupt handler\n");
}
void
ne_mainbus_attach(device_t parent, device_t self, void *aux)
{
	struct ne2000_softc *sc = device_private(self);
	struct dp8390_softc *dsc = &sc->sc_dp8390;
	struct mainbus_attach_args *ma = aux;
	bus_space_tag_t nict, asict;
	bus_space_handle_t nich, asich;
	int netype;
	const char *typestr;
	void *ih;

	dsc->sc_dev = self;
	aprint_normal("\n");

	/* Map i/o space. */
	nict = SH3_BUS_SPACE_PCMCIA_IO;
	if (bus_space_map(nict, ma->ma_addr1, NE2000_NPORTS, 0, &nich)) {
		aprint_error_dev(self, "can't map i/o space\n");
		return;
	}

	if (bus_space_subregion(nict, nich, NE2000_ASIC_OFFSET,
	    NE2000_ASIC_NPORTS, &asich)) {
		aprint_error_dev(self, "can't subregion i/o space\n");
		return;
	}
	asict = nict;

	dsc->sc_regt = nict;
	dsc->sc_regh = nich;

	sc->sc_asict = asict;
	sc->sc_asich = asich;

	/*
	 * Detect it again, so we can print some information about the
	 * interface.
	 */
	netype = ne2000_detect(nict, nich, asict, asich);
	switch (netype) {
	case NE2000_TYPE_RTL8019:
		typestr = "NE2000 (RTL8019)";
		break;

	case NE2000_TYPE_NE1000:
	case NE2000_TYPE_NE2000:
	default:
		aprint_error_dev(self, "where did the card go?!\n");
		return;
	}

	aprint_normal_dev(self, "%s Ethernet\n", typestr);

	/* This interface is always enabled. */
	dsc->sc_enabled = 1;

	/*
	 * Do generic NE2000 attach.  This will read the station address
	 * from the EEPROM.
	 */
	ne2000_attach(sc, NULL);

	/* Establish the interrupt handler. */
	ih = mmeye_intr_establish(ma->ma_irq1, IST_LEVEL, IPL_NET,
	    dp8390_intr, dsc);
	if (ih == NULL)
		aprint_error_dev(self,
		    "couldn't establish interrupt handler\n");
}
예제 #9
0
static void
ne_pci_attach(device_t parent, device_t self, void *aux)
{
	struct ne_pci_softc *psc = device_private(self);
	struct ne2000_softc *nsc = &psc->sc_ne2000;
	struct dp8390_softc *dsc = &nsc->sc_dp8390;
	struct pci_attach_args *pa = aux;
	pci_chipset_tag_t pc = pa->pa_pc;
	bus_space_tag_t nict;
	bus_space_handle_t nich;
	bus_space_tag_t asict;
	bus_space_handle_t asich;
	const char *intrstr;
	const struct ne_pci_product *npp;
	pci_intr_handle_t ih;
	pcireg_t csr;
	char intrbuf[PCI_INTRSTR_LEN];

	npp = ne_pci_lookup(pa);
	if (npp == NULL) {
		printf("\n");
		panic("ne_pci_attach: impossible");
	}

	dsc->sc_dev = self;

	printf(": %s Ethernet\n", npp->npp_name);

#ifdef IPKDB_NE_PCI
	if (ne_pci_isipkdb(pc, pa->pa_tag)) {
		nict = ipkdb_softc.sc_ne2000.sc_dp8390.sc_regt;
		nich = ipkdb_softc.sc_ne2000.sc_dp8390.sc_regh;
		ne_kip->port = nsc;
	} else
#endif
	if (pci_mapreg_map(pa, PCI_CBIO, PCI_MAPREG_TYPE_IO, 0,
	    &nict, &nich, NULL, NULL)) {
		aprint_error_dev(dsc->sc_dev, "can't map i/o space\n");
		return;
	}

	asict = nict;
	if (bus_space_subregion(nict, nich, NE2000_ASIC_OFFSET,
	    NE2000_ASIC_NPORTS, &asich)) {
		aprint_error_dev(dsc->sc_dev, "can't subregion i/o space\n");
		return;
	}

	dsc->sc_regt = nict;
	dsc->sc_regh = nich;

	nsc->sc_asict = asict;
	nsc->sc_asich = asich;

	/* Enable the card. */
	csr = pci_conf_read(pc, pa->pa_tag,
	    PCI_COMMAND_STATUS_REG);
	pci_conf_write(pc, pa->pa_tag, PCI_COMMAND_STATUS_REG,
	    csr | PCI_COMMAND_MASTER_ENABLE);

	/* This interface is always enabled. */
	dsc->sc_enabled = 1;

	dsc->sc_mediachange = npp->npp_mediachange;
	dsc->sc_mediastatus = npp->npp_mediastatus;
	dsc->sc_media_init = npp->npp_media_init;
	dsc->init_card = npp->npp_init_card;

	/*
	 * Do generic NE2000 attach.  This will read the station address
	 * from the EEPROM.
	 */
	ne2000_attach(nsc, NULL);

	/* Map and establish the interrupt. */
	if (pci_intr_map(pa, &ih)) {
		aprint_error_dev(dsc->sc_dev, "couldn't map interrupt\n");
		return;
	}
	intrstr = pci_intr_string(pc, ih, intrbuf, sizeof(intrbuf));
	psc->sc_ih = pci_intr_establish(pc, ih, IPL_NET, dp8390_intr, dsc);
	if (psc->sc_ih == NULL) {
		aprint_error_dev(dsc->sc_dev, "couldn't establish interrupt");
		if (intrstr != NULL)
			aprint_error(" at %s", intrstr);
		aprint_error("\n");
		return;
	}
	aprint_normal_dev(dsc->sc_dev, "interrupting at %s\n", intrstr);
}
/*
 * Install interface into kernel networking data structures.
 */
static void
ne_pbus_attach(device_t parent, device_t self, void *aux)
{
	struct podule_attach_args *pa = (void *)aux;
	struct ne_pbus_softc *npsc = device_private(self);
	struct ne2000_softc *nsc = &npsc->sc_ne2000;
	struct dp8390_softc *dsc = &nsc->sc_dp8390;
	struct ne_clone *ne = NULL;
	uint8_t buffer[6];
	uint8_t *myea;
	int loop;

	dsc->sc_dev = self;
	/* Check a few things about the attach args */

	if (pa->pa_podule_number == -1)
		panic("Podule has disappeared !");

	npsc->sc_podule_number = pa->pa_podule_number;
	npsc->sc_podule = pa->pa_podule;
	podules[npsc->sc_podule_number].attached = 1;		/* XXX */

	/* Scan the list of known interfaces for a match */
	for (loop = 0; loop < sizeof(ne_clones) / sizeof(struct ne_clone);
	    ++loop) {
		if (pa->pa_product == ne_clones[loop].product) {
			ne = &ne_clones[loop];
			break;
		}
	}

#ifdef	DIAGNOSTIC
	/* This should never fail as we must have matched at probe time */
	if (ne == NULL)
		panic("Podule has vanished");
#endif

	/* Update the nic and asic base addresses appropriately */
	switch (ne->nicspace) {
	case NE_SPACE_EASI:
		ne->nicbase += npsc->sc_podule->easi_base;
		break;
	case NE_SPACE_MOD:
		ne->nicbase += npsc->sc_podule->mod_base;
		break;
	case NE_SPACE_FAST:
	default:
		ne->nicbase += npsc->sc_podule->fast_base;
		break;
	}
	switch (ne->asicspace) {
	case NE_SPACE_EASI:
		ne->asicbase += npsc->sc_podule->easi_base;
		break;
	case NE_SPACE_MOD:
		ne->asicbase += npsc->sc_podule->mod_base;
		break;
	case NE_SPACE_FAST:
	default:
		ne->asicbase += npsc->sc_podule->fast_base;
		break;
	}

	switch (ne->extraspace) {
	case NE_SPACE_EASI:
		ne->extrabase += npsc->sc_podule->easi_base;
		break;
	case NE_SPACE_MOD:
		ne->extrabase += npsc->sc_podule->mod_base;
		break;
	case NE_SPACE_FAST:
	default:
		ne->extrabase += npsc->sc_podule->fast_base;
		break;
	}

	/* Report the interface name */
	aprint_normal(": %s ethernet\n", ne->name);

	/*
	 * Ok we need our own bus tag as the register spacing
	 * may not the default.
	 *
	 * For the podulebus, the bus tag cookie is the shift
	 * to apply to registers
	 * So duplicate the bus space tag and change the
	 * cookie.
	 */

	npsc->sc_tag = *pa->pa_iot;
	npsc->sc_tag.bs_cookie = (void *) ne->cookie;

	dsc->sc_regt = &npsc->sc_tag;
	nsc->sc_asict = dsc->sc_regt;

	/* Map all the I/O space for the NIC */
	if (bus_space_map(dsc->sc_regt, ne->nicbase, ne->nicsize,
	    0, &dsc->sc_regh)) {
		aprint_error_dev(self, "cannot map i/o space\n");
		return;
	}
	/* Map the I/O space for the ASIC */
	if (bus_space_map(nsc->sc_asict, ne->asicbase, ne->asicsize,
	    0, &nsc->sc_asich)) {
		aprint_error_dev(self, "cannot map i/o space\n");
		return;
	}
	/* Map any extra register space required by the card */
	if (ne->extrasize > 0) {
		if (bus_space_map(&npsc->sc_tag, ne->extrabase, ne->extrasize,
				  0, &npsc->sc_extrah)) {
			aprint_error_dev(self, "cannot map extra space\n");
			return;
		}
	}

	/* This interface is always enabled. */
	dsc->sc_enabled = 1;

	/*
	 * Now get the ethernet address in an interface specific manner if
	 * specified
	 */
	if (ne->getea)
		myea = ne->getea(npsc, buffer);
	else
		myea = NULL;

	/* Does the interface need a preattach call ? */
	if (ne->preattach)
		ne->preattach(npsc);

	/* if the interface has media support initialise it */
	if (ne->init_media) {
		dsc->sc_mediachange = ne->mediachange;
		dsc->sc_mediastatus = ne->mediastatus;
		dsc->init_card = ne->init_card;
		dsc->sc_media_init = ne->init_media;
#if 0
		int *media = NULL, nmedia = 0, defmedia = 0;
		ne->init_media(dsc, &media, &nmedia, &defmedia);
#endif
	}

	/*
	 * Do generic NE2000 attach.  This will read the station address
	 * from the EEPROM.
	 */
	ne2000_attach(nsc, myea);
	aprint_normal_dev(self, "");
	switch (nsc->sc_type) {
	case NE2000_TYPE_NE1000:
		aprint_normal("NE1000");
		break;
	case NE2000_TYPE_NE2000:
		aprint_normal("NE2000");
		break;
	case NE2000_TYPE_AX88190:
		aprint_normal("AX88190");
		break;
	case NE2000_TYPE_DL10019:
		aprint_normal("DL10019");
		break;
        case NE2000_TYPE_DL10022:
		aprint_normal("DL10022");
		break;
	default:
		printf("??");
	};
	aprint_normal(" chipset, %d Kb memory\n", dsc->mem_start/1024);

	/* Does the interface need a postattach call ? */
	if (ne->postattach)
		ne->postattach(npsc);

	/* Install an interrupt handler */
	evcnt_attach_dynamic(&npsc->sc_intrcnt, EVCNT_TYPE_INTR, NULL,
	    device_xname(self), "intr");
	npsc->sc_ih = podulebus_irq_establish(pa->pa_ih, IPL_NET, dp8390_intr,
	    dsc, &npsc->sc_intrcnt);
	if (npsc->sc_ih == NULL)
		panic("%s: Cannot install interrupt handler",
		   device_xname(self));
	/* this feels wrong to do this here */
	npsc->sc_ih->ih_maskaddr = npsc->sc_podule->irq_addr;
	npsc->sc_ih->ih_maskbits = npsc->sc_podule->irq_mask;
}