static int ed_pci_attach(device_t dev) { struct ed_softc *sc = device_get_softc(dev); int flags = 0; int error; error = ed_probe_Novell_generic(dev, PCIR_MAPS, flags); if (error) return (error); error = ed_alloc_irq(dev, 0, RF_SHAREABLE); if (error) { ed_release_resources(dev); return (error); } error = bus_setup_intr(dev, sc->irq_res, INTR_TYPE_NET, edintr, sc, &sc->irq_handle); if (error) { ed_release_resources(dev); return (error); } error = ed_attach(sc, device_get_unit(dev), flags); return (error); }
int ed_probe_Novell(device_t dev, int port_rid, int flags) { struct ed_softc *sc = device_get_softc(dev); int error; error = ed_alloc_port(dev, port_rid, ED_NOVELL_IO_PORTS); if (error) return (error); sc->asic_offset = ED_NOVELL_ASIC_OFFSET; sc->nic_offset = ED_NOVELL_NIC_OFFSET; return ed_probe_Novell_generic(dev, flags); }
/* * Special setup for TC5299J */ static int ed_pccard_tc5299j(device_t dev, const struct ed_product *pp) { int error, i, id; char *ts; struct ed_softc *sc = device_get_softc(dev); if (!(pp->flags & NE2000DVF_TC5299J)) return (ENXIO); if (bootverbose) device_printf(dev, "Checking Tc5299j\n"); error = ed_probe_Novell_generic(dev, device_get_flags(dev)); if (bootverbose) device_printf(dev, "Novell generic probe failed: %d\n", error); if (error != 0) return (error); /* * Check to see if we have a MII PHY ID at any address. All TC5299J * devices have MII and a PHY, so we use this to weed out chips that * would otherwise make it through the tests we have after this point. */ sc->mii_bitbang_ops = &ed_pccard_tc5299j_mii_bitbang_ops; for (i = 0; i < 32; i++) { id = ed_miibus_readreg(dev, i, MII_PHYIDR1); if (id != 0 && id != 0xffff) break; } if (i == 32) return (ENXIO); ts = "TC5299J"; if (ed_pccard_rom_mac(dev, sc->enaddr) == 0) return (ENXIO); sc->vendor = ED_VENDOR_NOVELL; sc->type = ED_TYPE_NE2000; sc->chip_type = ED_CHIP_TYPE_TC5299J; sc->type_str = ts; return (0); }
int ed_probe_RTL80x9(device_t dev, int port_rid, int flags) { struct ed_softc *sc = device_get_softc(dev); char *ts; int error; if ((error = ed_alloc_port(dev, port_rid, ED_NOVELL_IO_PORTS))) return (error); sc->asic_offset = ED_NOVELL_ASIC_OFFSET; sc->nic_offset = ED_NOVELL_NIC_OFFSET; if (ed_nic_inb(sc, ED_P0_CR) & (ED_CR_PS0 | ED_CR_PS1)) ed_nic_outb(sc, ED_P0_CR, ED_CR_RD2 | ED_CR_STP); if (ed_nic_inb(sc, ED_RTL80X9_80X9ID0) != ED_RTL80X9_ID0) return (ENXIO); switch (ed_nic_inb(sc, ED_RTL80X9_80X9ID1)) { case ED_RTL8019_ID1: sc->chip_type = ED_CHIP_TYPE_RTL8019; ts = "RTL8019"; break; case ED_RTL8029_ID1: sc->chip_type = ED_CHIP_TYPE_RTL8029; ts = "RTL8029"; break; default: return (ENXIO); } if ((error = ed_probe_Novell_generic(dev, flags))) return (error); sc->type_str = ts; sc->sc_media_ioctl = &ed_rtl80x9_media_ioctl; ifmedia_init(&sc->ifmedia, 0, ed_rtl_set_media, ed_rtl_get_media); ifmedia_add(&sc->ifmedia, IFM_ETHER | IFM_10_T | IFM_FDX, 0, 0); ifmedia_add(&sc->ifmedia, IFM_ETHER | IFM_10_T, 0, 0); ifmedia_add(&sc->ifmedia, IFM_ETHER | IFM_10_2, 0, 0); ifmedia_add(&sc->ifmedia, IFM_ETHER | IFM_10_5, 0, 0); ifmedia_add(&sc->ifmedia, IFM_ETHER | IFM_AUTO, 0, 0); ed_nic_barrier(sc, ED_P0_CR, 1, BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE); ed_nic_outb(sc, ED_P0_CR, ED_CR_RD2 | ED_CR_PAGE_3 | ED_CR_STP); ed_nic_barrier(sc, ED_P0_CR, 1, BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE); switch (ed_nic_inb(sc, ED_RTL80X9_CONFIG2) & ED_RTL80X9_CF2_MEDIA) { case ED_RTL80X9_CF2_AUTO: ifmedia_set(&sc->ifmedia, IFM_ETHER | IFM_AUTO); break; case ED_RTL80X9_CF2_10_5: ifmedia_set(&sc->ifmedia, IFM_ETHER | IFM_10_5); break; case ED_RTL80X9_CF2_10_2: ifmedia_set(&sc->ifmedia, IFM_ETHER | IFM_10_2); break; case ED_RTL80X9_CF2_10_T: ifmedia_set(&sc->ifmedia, IFM_ETHER | IFM_10_T | ((ed_nic_inb(sc, ED_RTL80X9_CONFIG3) & ED_RTL80X9_CF3_FUDUP) ? IFM_FDX : 0)); break; } return (0); }
/* * Probe the Ethernet MAC addrees for PCMCIA Linksys EtherFast 10/100 * and compatible cards (DL10019C Ethernet controller). */ static int ed_pccard_dl100xx(device_t dev, const struct ed_product *pp) { struct ed_softc *sc = device_get_softc(dev); u_char sum; uint8_t id; u_int memsize; int i, error; if (!(pp->flags & NE2000DVF_DL100XX)) return (ENXIO); if (bootverbose) device_printf(dev, "Trying DL100xx\n"); error = ed_probe_Novell_generic(dev, device_get_flags(dev)); if (bootverbose && error) device_printf(dev, "Novell generic probe failed: %d\n", error); if (error != 0) return (error); /* * Linksys registers(offset from ASIC base) * * 0x04-0x09 : Physical Address Register 0-5 (PAR0-PAR5) * 0x0A : Card ID Register (CIR) * 0x0B : Check Sum Register (SR) */ for (sum = 0, i = 0x04; i < 0x0c; i++) sum += ed_asic_inb(sc, i); if (sum != 0xff) { if (bootverbose) device_printf(dev, "Bad checksum %#x\n", sum); return (ENXIO); /* invalid DL10019C */ } if (bootverbose) device_printf(dev, "CIR is %d\n", ed_asic_inb(sc, 0xa)); for (i = 0; i < ETHER_ADDR_LEN; i++) sc->enaddr[i] = ed_asic_inb(sc, 0x04 + i); ed_nic_outb(sc, ED_P0_DCR, ED_DCR_WTS | ED_DCR_FT1 | ED_DCR_LS); id = ed_asic_inb(sc, 0xf); sc->isa16bit = 1; /* * Hard code values based on the datasheet. We're NE-2000 compatible * NIC with 24kb of packet memory starting at 24k offset. These * cards also work with 16k at 16k, but don't work with 24k at 16k * or 32k at 16k. */ sc->type = ED_TYPE_NE2000; sc->mem_start = 24 * 1024; memsize = sc->mem_size = 24 * 1024; sc->mem_end = sc->mem_start + memsize; sc->tx_page_start = memsize / ED_PAGE_SIZE; sc->txb_cnt = 3; sc->rec_page_start = sc->tx_page_start + sc->txb_cnt * ED_TXBUF_SIZE; sc->rec_page_stop = sc->tx_page_start + memsize / ED_PAGE_SIZE; sc->mem_ring = sc->mem_start + sc->txb_cnt * ED_PAGE_SIZE * ED_TXBUF_SIZE; ed_nic_outb(sc, ED_P0_PSTART, sc->mem_start / ED_PAGE_SIZE); ed_nic_outb(sc, ED_P0_PSTOP, sc->mem_end / ED_PAGE_SIZE); sc->vendor = ED_VENDOR_NOVELL; sc->chip_type = (id & 0x90) == 0x90 ? ED_CHIP_TYPE_DL10022 : ED_CHIP_TYPE_DL10019; sc->type_str = ((id & 0x90) == 0x90) ? "DL10022" : "DL10019"; sc->mii_bitbang_ops = &ed_pccard_dl100xx_mii_bitbang_ops; return (0); }
static int ed_pccard_attach(device_t dev) { u_char sum; u_char enaddr[ETHER_ADDR_LEN]; const struct ed_product *pp; int error, i, flags, port_rid, modem_rid; struct ed_softc *sc = device_get_softc(dev); u_long size; static uint16_t *intr_vals[] = {NULL, NULL}; sc->dev = dev; if ((pp = (const struct ed_product *) pccard_product_lookup(dev, (const struct pccard_product *) ed_pccard_products, sizeof(ed_pccard_products[0]), NULL)) == NULL) { printf("Can't find\n"); return (ENXIO); } modem_rid = port_rid = -1; if (pp->flags & NE2000DVF_MODEM) { for (i = 0; i < 4; i++) { size = bus_get_resource_count(dev, SYS_RES_IOPORT, i); if (size == ED_NOVELL_IO_PORTS) port_rid = i; else if (size == 8) modem_rid = i; } if (port_rid == -1) { device_printf(dev, "Cannot locate my ports!\n"); return (ENXIO); } } else { port_rid = 0; } /* Allocate the port resource during setup. */ error = ed_alloc_port(dev, port_rid, ED_NOVELL_IO_PORTS); if (error) { printf("alloc_port failed\n"); return (error); } if (rman_get_size(sc->port_res) == ED_NOVELL_IO_PORTS / 2) { port_rid++; sc->port_res2 = bus_alloc_resource(dev, SYS_RES_IOPORT, &port_rid, 0ul, ~0ul, 1, RF_ACTIVE); if (sc->port_res2 == NULL || rman_get_size(sc->port_res2) != ED_NOVELL_IO_PORTS / 2) { error = ENXIO; goto bad; } } error = ed_alloc_irq(dev, 0, 0); if (error) goto bad; /* * Determine which chipset we are. Almost all the PC Card chipsets * have the Novel ASIC and NIC offsets. There's 2 known cards that * follow the WD80x3 conventions, which are handled as a special case. */ sc->asic_offset = ED_NOVELL_ASIC_OFFSET; sc->nic_offset = ED_NOVELL_NIC_OFFSET; error = ENXIO; flags = device_get_flags(dev); if (error != 0) error = ed_pccard_dl100xx(dev, pp); if (error != 0) error = ed_pccard_ax88x90(dev, pp); if (error != 0) error = ed_pccard_tc5299j(dev, pp); if (error != 0) { error = ed_probe_Novell_generic(dev, flags); printf("Novell generic probe failed: %d\n", error); } if (error != 0 && (pp->flags & NE2000DVF_TOSHIBA)) { flags |= ED_FLAGS_TOSH_ETHER; flags |= ED_FLAGS_PCCARD; sc->asic_offset = ED_WD_ASIC_OFFSET; sc->nic_offset = ED_WD_NIC_OFFSET; error = ed_probe_WD80x3_generic(dev, flags, intr_vals); } if (error) goto bad; /* * There are several ways to get the MAC address for the card. * Some of the above probe routines can fill in the enaddr. If * not, we run through a number of 'well known' locations: * (1) From the PC Card FUNCE * (2) From offset 0 in the shared memory * (3) From a hinted offset in attribute memory * (4) From 0xff0 in attribute memory * If we can't get a non-zero MAC address from this list, we fail. */ for (i = 0, sum = 0; i < ETHER_ADDR_LEN; i++) sum |= sc->enaddr[i]; if (sum == 0) { pccard_get_ether(dev, enaddr); if (bootverbose) device_printf(dev, "CIS MAC %6D\n", enaddr, ":"); for (i = 0, sum = 0; i < ETHER_ADDR_LEN; i++) sum |= enaddr[i]; if (sum == 0 && ed_pccard_rom_mac(dev, enaddr)) { if (bootverbose) device_printf(dev, "ROM mac %6D\n", enaddr, ":"); sum++; } if (sum == 0 && pp->flags & NE2000DVF_ENADDR) { for (i = 0; i < ETHER_ADDR_LEN; i++) { pccard_attr_read_1(dev, pp->enoff + i * 2, enaddr + i); sum |= enaddr[i]; } if (bootverbose) device_printf(dev, "Hint %x MAC %6D\n", pp->enoff, enaddr, ":"); } if (sum == 0) { for (i = 0; i < ETHER_ADDR_LEN; i++) { pccard_attr_read_1(dev, ED_DEFAULT_MAC_OFFSET + i * 2, enaddr + i); sum |= enaddr[i]; } if (bootverbose) device_printf(dev, "Fallback MAC %6D\n", enaddr, ":"); } if (sum == 0) { device_printf(dev, "Cannot extract MAC address.\n"); ed_release_resources(dev); return (ENXIO); } bcopy(enaddr, sc->enaddr, ETHER_ADDR_LEN); } error = ed_attach(dev); if (error) goto bad; if (sc->chip_type == ED_CHIP_TYPE_DL10019 || sc->chip_type == ED_CHIP_TYPE_DL10022) { /* Try to attach an MII bus, but ignore errors. */ ed_pccard_dl100xx_mii_reset(sc); (void)mii_attach(dev, &sc->miibus, sc->ifp, ed_ifmedia_upd, ed_ifmedia_sts, BMSR_DEFCAPMASK, MII_PHY_ANY, MII_OFFSET_ANY, MIIF_FORCEANEG); } else if (sc->chip_type == ED_CHIP_TYPE_AX88190 || sc->chip_type == ED_CHIP_TYPE_AX88790 || sc->chip_type == ED_CHIP_TYPE_TC5299J) { error = mii_attach(dev, &sc->miibus, sc->ifp, ed_ifmedia_upd, ed_ifmedia_sts, BMSR_DEFCAPMASK, MII_PHY_ANY, MII_OFFSET_ANY, MIIF_FORCEANEG); if (error != 0) { device_printf(dev, "attaching PHYs failed\n"); goto bad; } } if (sc->miibus != NULL) { sc->sc_tick = ed_pccard_tick; sc->sc_mediachg = ed_pccard_mediachg; sc->sc_media_ioctl = ed_pccard_media_ioctl; ed_pccard_kick_phy(sc); } else { ed_gen_ifmedia_init(sc); } if (modem_rid != -1) ed_pccard_add_modem(dev); error = bus_setup_intr(dev, sc->irq_res, INTR_TYPE_NET | INTR_MPSAFE, NULL, edintr, sc, &sc->irq_handle); if (error) { device_printf(dev, "setup intr failed %d \n", error); goto bad; } return (0); bad: ed_detach(dev); return (error); }