/* JLI sub-probe for RATOC REX-5586/5587. */ static u_short const * fe_probe_jli_rex(struct fe_softc * sc, u_char const * eeprom) { int i; static u_short const irqmap_rex [4] = { 3, 4, 5, NO_IRQ }; /* Make sure the EEPROM contains RATOC's config pattern. */ if (eeprom[1] != eeprom[0]) return NULL; for (i = 8; i < 32; i++) if (eeprom[i] != 0xFF) return NULL; /* Get our station address from EEPROM. Note that RATOC stores it "byte-swapped" in each word. (I don't know why.) So, we just can't use bcopy().*/ sc->enaddr[0] = eeprom[3]; sc->enaddr[1] = eeprom[2]; sc->enaddr[2] = eeprom[5]; sc->enaddr[3] = eeprom[4]; sc->enaddr[4] = eeprom[7]; sc->enaddr[5] = eeprom[6]; /* Make sure the EEPROM contains RATOC's station address. */ if (!fe_valid_Ether_p(sc->enaddr, 0x00C0D0)) return NULL; /* I don't know any sub-model identification. */ sc->type = FE_TYPE_JLI; sc->typestr = "REX-5586/5587"; /* Returns the IRQ for the RATOC board. */ return irqmap_rex; }
/* * Probe for Gateway Communications' old cards. * (both as Generic MB86960 probe routine) */ static int fe_probe_gwy(device_t dev) { struct fe_softc *sc = device_get_softc(dev); static struct fe_simple_probe_struct probe_table [] = { /* { FE_DLCR2, 0x70, 0x00 }, */ { FE_DLCR2, 0x58, 0x00 }, { FE_DLCR4, 0x08, 0x00 }, { 0 } }; /* * XXX * I'm not sure which address is possible, so accepts any. */ if (fe98_alloc_port(dev, FE_TYPE_GWY)) return ENXIO; /* Fill the softc struct with default values. */ fe_softc_defaults(sc); /* See if the card is on its address. */ if (!fe_simple_probe(sc, probe_table)) return ENXIO; /* Get our station address from EEPROM. */ fe_inblk(sc, 0x18, sc->enaddr, ETHER_ADDR_LEN); if (!fe_valid_Ether_p(sc->enaddr, 0x000000)) return ENXIO; /* Determine the card type. */ sc->typestr = "Generic MB86960 Ethernet"; if (fe_valid_Ether_p(sc->enaddr, 0x000061)) sc->typestr = "Gateway Ethernet (Fujitsu chipset)"; /* Gateway's board requires an explicit IRQ to work, since it is not possible to probe the setting of jumpers. */ if (bus_get_resource(dev, SYS_RES_IRQ, 0, NULL, NULL) != 0) { fe_irq_failure(sc->typestr, sc->sc_unit, NO_IRQ, NULL); return ENXIO; } return 0; }
/* Probe for TDK LAK-AX031, which is an SSi 78Q8377A based board. */ static int fe_probe_ssi(device_t dev) { struct fe_softc *sc = device_get_softc(dev); u_long iobase, irq; u_char eeprom [SSI_EEPROM_SIZE]; static struct fe_simple_probe_struct probe_table [] = { { FE_DLCR2, 0x08, 0x00 }, { FE_DLCR4, 0x08, 0x00 }, { 0 } }; /* See if the specified I/O address is possible for 78Q8377A. */ if (bus_get_resource(dev, SYS_RES_IOPORT, 0, &iobase, NULL) != 0) return ENXIO; if ((iobase & ~0x3F0) != 0x000) return ENXIO; /* We have 16 registers. */ if (fe_alloc_port(dev, 16)) return ENXIO; /* Fill the softc struct with default values. */ fe_softc_defaults(sc); /* See if the card is on its address. */ if (!fe_simple_probe(sc, probe_table)) return ENXIO; /* We now have to read the config EEPROM. We should be very careful, since doing so destroys a register. (Remember, we are not yet sure we have a LAK-AX031 board here.) Don't remember to select BMPRs bofore reading EEPROM, since other register bank may be selected before the probe() is called. */ fe_read_eeprom_ssi(sc, eeprom); /* Make sure the Ethernet (MAC) station address is of TDK's. */ if (!fe_valid_Ether_p(eeprom+FE_SSI_EEP_ADDR, 0x008098)) return ENXIO; bcopy(eeprom + FE_SSI_EEP_ADDR, sc->enaddr, ETHER_ADDR_LEN); /* This looks like a TDK-AX031 board. It requires an explicit IRQ setting in config, since we currently don't know how we can find the IRQ value assigned by ISA PnP manager. */ if (bus_get_resource(dev, SYS_RES_IRQ, 0, &irq, NULL) != 0) { fe_irq_failure("LAK-AX031", sc->sc_unit, NO_IRQ, NULL); return ENXIO; } /* Fill softc struct accordingly. */ sc->type = FE_TYPE_SSI; sc->typestr = "LAK-AX031"; sc->mbitmap = MB_HT; sc->defmedia = MB_HT; return 0; }
/* * Probe and initialization for TDK/CONTEC PCMCIA Ethernet interface. * by MASUI Kenji <*****@*****.**> * * (Contec uses TDK Ethernet chip -- hosokawa) * * This version of fe_probe_tdk has been rewrote to handle * *generic* PC Card implementation of Fujitsu MB8696x family. The * name _tdk is just for a historical reason. :-) */ static int fe_probe_tdk (device_t dev, const struct fe_pccard_product *pp) { struct fe_softc *sc = device_get_softc(dev); static struct fe_simple_probe_struct probe_table [] = { { FE_DLCR2, 0x10, 0x00 }, { FE_DLCR4, 0x08, 0x00 }, /* { FE_DLCR5, 0x80, 0x00 }, Does not work well. */ { 0 } }; /* C-NET(PC)C occupies 16 I/O addresses. */ if (fe_alloc_port(dev, 16)) return ENXIO; /* Fill the softc struct with default values. */ fe_softc_defaults(sc); /* * See if C-NET(PC)C is on its address. */ if (!fe_simple_probe(sc, probe_table)) return ENXIO; /* Determine the card type. */ sc->type = FE_TYPE_TDK; sc->typestr = "Generic MB8696x/78Q837x Ethernet (PCMCIA)"; pccard_get_ether(dev, sc->enaddr); /* Make sure we got a valid station address. */ if (!fe_valid_Ether_p(sc->enaddr, 0)) { pccard_cis_scan(dev, fe_pccard_xircom_mac, sc->enaddr); } /* Make sure we got a valid station address. */ if (!fe_valid_Ether_p(sc->enaddr, 0)) return ENXIO; return 0; }
/* * Probe and initialization for Gateway Communications' old cards. */ static int fe_probe_gwy(device_t dev) { struct fe_softc *sc = device_get_softc(dev); u_long iobase, irq; static struct fe_simple_probe_struct probe_table [] = { /* { FE_DLCR2, 0x70, 0x00 }, */ { FE_DLCR2, 0x58, 0x00 }, { FE_DLCR4, 0x08, 0x00 }, { 0 } }; /* See if the specified I/O address is possible for Gateway boards. */ if (bus_get_resource(dev, SYS_RES_IOPORT, 0, &iobase, NULL) != 0) return ENXIO; if ((iobase & ~0x1E0) != 0x200) return ENXIO; /* That's all. The card occupies 32 I/O addresses, as always. */ if (fe_alloc_port(dev, 32)) return ENXIO; /* Setup an I/O address mapping table and some others. */ fe_softc_defaults(sc); /* See if the card is on its address. */ if (!fe_simple_probe(sc, probe_table)) return ENXIO; /* Get our station address from EEPROM. */ fe_inblk(sc, 0x18, sc->enaddr, ETHER_ADDR_LEN); /* Make sure it is Gateway Communication's. */ if (!fe_valid_Ether_p(sc->enaddr, 0x000061)) return ENXIO; /* Gateway's board requires an explicit IRQ to work, since it is not possible to probe the setting of jumpers. */ if (bus_get_resource(dev, SYS_RES_IRQ, 0, &irq, NULL) != 0) { fe_irq_failure("Gateway Ethernet", sc->sc_unit, NO_IRQ, NULL); return ENXIO; } /* Fill softc struct accordingly. */ sc->type = FE_TYPE_GWY; sc->typestr = "Gateway Ethernet (Fujitsu chipset)"; return 0; }
static int fe_probe_mbh(device_t dev, const struct fe_pccard_product *pp) { struct fe_softc *sc = device_get_softc(dev); static struct fe_simple_probe_struct probe_table [] = { { FE_DLCR2, 0x58, 0x00 }, { FE_DLCR4, 0x08, 0x00 }, { FE_DLCR6, 0xFF, 0xB6 }, { 0 } }; /* MBH10302 occupies 32 I/O addresses. */ if (fe_alloc_port(dev, 32)) return ENXIO; /* Fill the softc struct with default values. */ fe_softc_defaults(sc); /* * See if MBH10302 is on its address. * I'm not sure the following probe code works. FIXME. */ if (!fe_simple_probe(sc, probe_table)) return ENXIO; /* Get our station address from EEPROM. */ fe_inblk(sc, FE_MBH10, sc->enaddr, ETHER_ADDR_LEN); /* Make sure we got a valid station address. */ if (!fe_valid_Ether_p(sc->enaddr, 0)) return ENXIO; /* Determine the card type. */ sc->type = FE_TYPE_MBH; sc->typestr = "MBH10302 (PCMCIA)"; /* We seems to need our own IDENT bits... FIXME. */ sc->proto_dlcr7 = FE_D7_BYTSWP_LH | FE_D7_IDENT_NICE; /* Setup hooks. We need a special initialization procedure. */ sc->init = fe_init_mbh; return 0; }
/* JLI sub-probe for Unknown board. */ static u_short const * fe_probe_jli_unk(struct fe_softc * sc, u_char const * eeprom) { int i, n, romsize; static u_short const irqmap [4] = { NO_IRQ, NO_IRQ, NO_IRQ, NO_IRQ }; /* The generic JLI probe considered this board has an 86965 in JLI mode, but any other board-specific routines could not find the matching implementation. So, we "guess" the location by looking for a bit pattern which looks like a MAC address. */ /* Determine how large the EEPROM is. */ for (romsize = JLI_EEPROM_SIZE/2; romsize > 16; romsize >>= 1) { for (i = 0; i < romsize; i++) { if (eeprom[i] != eeprom[i+romsize]) break; } if (i < romsize) break; } romsize <<= 1; /* Look for a bit pattern which looks like a MAC address. */ for (n = 2; n <= romsize - ETHER_ADDR_LEN; n += 2) { if (!fe_valid_Ether_p(eeprom + n, 0x000000)) continue; } /* If no reasonable address was found, we can't go further. */ if (n > romsize - ETHER_ADDR_LEN) return NULL; /* Extract our (guessed) station address. */ bcopy(eeprom+n, sc->enaddr, ETHER_ADDR_LEN); /* We are not sure what type of board it is... */ sc->type = FE_TYPE_JLI; sc->typestr = "(unknown JLI)"; sc->stability |= UNSTABLE_TYPE | UNSTABLE_MAC; /* Returns the totally unknown IRQ mapping table. */ return irqmap; }
/* JLI sub-probe for Allied-Telesis RE1000Plus/ME1500 series. */ static u_short const * fe_probe_jli_re1000p(struct fe_softc * sc, u_char const * eeprom) { int i; static u_short const irqmaps_re1000p [4] = { 3, 5, 6, 12 }; /* Make sure the EEPROM contains Allied-Telesis bit pattern. */ if (eeprom[1] != 0xFF) return NULL; for (i = 2; i < 8; i++) if (eeprom[i] != 0xFF) return NULL; for (i = 14; i < 24; i++) if (eeprom[i] != 0xFF) return NULL; /* Get our station address from EEPROM, and make sure the EEPROM contains Allied-Telesis's address. */ bcopy(eeprom + 8, sc->enaddr, ETHER_ADDR_LEN); if (!fe_valid_Ether_p(sc->enaddr, 0x0000F4)) return NULL; /* I don't know any sub-model identification. */ sc->typestr = "RE1000Plus/ME1500"; /* Returns the IRQ table for the RE1000Plus. */ return irqmaps_re1000p; }
static u_short const * fe_probe_jli_icl(struct fe_softc * sc, u_char const * eeprom) { int i; u_short defmedia; u_char d6; static u_short const irqmap_icl [4] = { 9, 10, 5, 15 }; /* Make sure the EEPROM contains ICL bit pattern. */ for (i = 24; i < 39; i++) { if (eeprom[i] != 0x20 && (eeprom[i] & 0xF0) != 0x30) return NULL; } for (i = 112; i < 122; i++) { if (eeprom[i] != 0x20 && (eeprom[i] & 0xF0) != 0x30) return NULL; } /* Make sure the EEPROM contains ICL's permanent station address. If it isn't, probably this board is not an ICL's. */ if (!fe_valid_Ether_p(eeprom+122, 0x00004B)) return NULL; /* Check if the "configured" Ethernet address in the EEPROM is valid. Use it if it is, or use the "permanent" address instead. */ if (fe_valid_Ether_p(eeprom+4, 0x020000)) { /* The configured address is valid. Use it. */ bcopy(eeprom+4, sc->enaddr, ETHER_ADDR_LEN); } else { /* The configured address is invalid. Use permanent. */ bcopy(eeprom+122, sc->enaddr, ETHER_ADDR_LEN); } /* Determine model and supported media. */ switch (eeprom[0x5E]) { case 0: sc->typestr = "EtherTeam16i/COMBO"; sc->mbitmap = MB_HA | MB_HT | MB_H5 | MB_H2; break; case 1: sc->typestr = "EtherTeam16i/TP"; sc->mbitmap = MB_HT; break; case 2: sc->typestr = "EtherTeam16i/ErgoPro"; sc->mbitmap = MB_HA | MB_HT | MB_H5; break; case 4: sc->typestr = "EtherTeam16i/DUO"; sc->mbitmap = MB_HA | MB_HT | MB_H2; break; default: sc->typestr = "EtherTeam16i"; sc->stability |= UNSTABLE_TYPE; if (bootverbose) { printf("fe%d: unknown model code %02x for EtherTeam16i\n", sc->sc_unit, eeprom[0x5E]); } break; } sc->type = FE_TYPE_JLI; /* I'm not sure the following msel hook is required by all models or COMBO only... FIXME. */ sc->msel = fe_msel_icl; /* Make the configured media selection the default media. */ switch (eeprom[0x28]) { case 0: defmedia = MB_HA; break; case 1: defmedia = MB_H5; break; case 2: defmedia = MB_HT; break; case 3: defmedia = MB_H2; break; default: if (bootverbose) { printf("fe%d: unknown default media: %02x\n", sc->sc_unit, eeprom[0x28]); } defmedia = MB_HA; break; } /* Make sure the default media is compatible with the supported media. */ if ((defmedia & sc->mbitmap) == 0) { if (bootverbose) { printf("fe%d: default media adjusted\n", sc->sc_unit); } defmedia = sc->mbitmap; } /* Keep the determined default media. */ sc->defmedia = defmedia; /* ICL has "fat" models. We have to program 86965 to properly reflect the hardware. */ d6 = sc->proto_dlcr6 & ~(FE_D6_BUFSIZ | FE_D6_BBW); switch ((eeprom[0x61] << 8) | eeprom[0x60]) { case 0x2008: d6 |= FE_D6_BUFSIZ_32KB | FE_D6_BBW_BYTE; break; case 0x4010: d6 |= FE_D6_BUFSIZ_64KB | FE_D6_BBW_WORD; break; default: /* We can't support it, since we don't know which bits to set in DLCR6. */ printf("fe%d: unknown SRAM config for ICL\n", sc->sc_unit); return NULL; } sc->proto_dlcr6 = d6; /* Returns the IRQ table for the ICL board. */ return irqmap_icl; }
/* JLI sub-probe for Allied-Telesyn/Allied-Telesis AT1700/RE2000 series. */ static u_short const * fe_probe_jli_ati(struct fe_softc * sc, u_char const * eeprom) { int i; static u_short const irqmaps_ati [4][4] = { { 3, 4, 5, 9 }, { 10, 11, 12, 15 }, { 3, 11, 5, 15 }, { 10, 11, 14, 15 }, }; /* Make sure the EEPROM contains Allied-Telesis/Allied-Telesyn bit pattern. */ if (eeprom[1] != 0x00) return NULL; for (i = 2; i < 8; i++) if (eeprom[i] != 0xFF) return NULL; for (i = 14; i < 24; i++) if (eeprom[i] != 0xFF) return NULL; /* Get our station address from EEPROM, and make sure the EEPROM contains ATI's address. */ bcopy(eeprom + 8, sc->enaddr, ETHER_ADDR_LEN); if (!fe_valid_Ether_p(sc->enaddr, 0x0000F4)) return NULL; /* * The following model identification codes are stolen * from the NetBSD port of the fe driver. My reviewers * suggested minor revision. */ /* Determine the card type. */ switch (eeprom[FE_ATI_EEP_MODEL]) { case FE_ATI_MODEL_AT1700T: sc->typestr = "AT-1700T/RE2001"; sc->mbitmap = MB_HT; sc->defmedia = MB_HT; break; case FE_ATI_MODEL_AT1700BT: sc->typestr = "AT-1700BT/RE2003"; sc->mbitmap = MB_HA | MB_HT | MB_H2; break; case FE_ATI_MODEL_AT1700FT: sc->typestr = "AT-1700FT/RE2009"; sc->mbitmap = MB_HA | MB_HT | MB_HF; break; case FE_ATI_MODEL_AT1700AT: sc->typestr = "AT-1700AT/RE2005"; sc->mbitmap = MB_HA | MB_HT | MB_H5; break; default: sc->typestr = "unknown AT-1700/RE2000"; sc->stability |= UNSTABLE_TYPE | UNSTABLE_IRQ; break; } sc->type = FE_TYPE_JLI; #if 0 /* Should we extract default media from eeprom? Linux driver for AT1700 does it, although previous releases of FreeBSD don't. FIXME. */ /* Determine the default media selection from the config EEPROM. The byte at offset EEP_MEDIA is believed to contain BMPR13 value to be set. We just ignore STP bit or squelch bit, since we don't support those. (It is intentional.) */ switch (eeprom[FE_ATI_EEP_MEDIA] & FE_B13_PORT) { case FE_B13_AUTO: sc->defmedia = MB_HA; break; case FE_B13_TP: sc->defmedia = MB_HT; break; case FE_B13_AUI: sc->defmedia = sc->mbitmap & (MB_H2|MB_H5|MB_H5); /*XXX*/ break; default: sc->defmedia = MB_HA; break; } /* Make sure the default media is compatible with the supported ones. */ if ((sc->defmedia & sc->mbitmap) == 0) { if (sc->defmedia == MB_HA) { sc->defmedia = MB_HT; } else { sc->defmedia = MB_HA; } } #endif /* * Try to determine IRQ settings. * Different models use different ranges of IRQs. */ switch ((eeprom[FE_ATI_EEP_REVISION] & 0xf0) |(eeprom[FE_ATI_EEP_MAGIC] & 0x04)) { case 0x30: case 0x34: return irqmaps_ati[3]; case 0x10: case 0x14: case 0x50: case 0x54: return irqmaps_ati[2]; case 0x44: case 0x64: return irqmaps_ati[1]; default: return irqmaps_ati[0]; } }
static int fe_probe_fmv(device_t dev) { struct fe_softc *sc = device_get_softc(dev); int n; u_long iobase, irq; static u_short const irqmap [ 4 ] = { 3, 7, 10, 15 }; static struct fe_simple_probe_struct const probe_table [] = { { FE_DLCR2, 0x71, 0x00 }, { FE_DLCR4, 0x08, 0x00 }, { FE_FMV0, 0x78, 0x50 }, /* ERRDY+PRRDY */ { FE_FMV1, 0xB0, 0x00 }, /* FMV-183/4 has 0x48 bits. */ { FE_FMV3, 0x7F, 0x00 }, { 0 } }; /* Board subtypes; it lists known FMV-180 variants. */ struct subtype { u_short mcode; u_short mbitmap; u_short defmedia; char const * str; }; static struct subtype const typelist [] = { { 0x0005, MB_HA|MB_HT|MB_H5, MB_HA, "FMV-181" }, { 0x0105, MB_HA|MB_HT|MB_H5, MB_HA, "FMV-181A" }, { 0x0003, MB_HM, MB_HM, "FMV-182" }, { 0x0103, MB_HM, MB_HM, "FMV-182A" }, { 0x0804, MB_HT, MB_HT, "FMV-183" }, { 0x0C04, MB_HT, MB_HT, "FMV-183 (on-board)" }, { 0x0803, MB_H2|MB_H5, MB_H2, "FMV-184" }, { 0, MB_HA, MB_HA, "unknown FMV-180 (?)" }, }; struct subtype const * type; /* Media indicator and "Hardware revision ID" */ u_short mcode; /* See if the specified address is possible for FMV-180 series. 220, 240, 260, 280, 2A0, 2C0, 300, and 340 are allowed for all boards, and 200, 2E0, 320, 360, 380, 3A0, 3C0, and 3E0 for PnP boards. */ if (bus_get_resource(dev, SYS_RES_IOPORT, 0, &iobase, NULL) != 0) return ENXIO; if ((iobase & ~0x1E0) != 0x200) return ENXIO; /* FMV-180 occupies 32 I/O addresses. */ if (fe_alloc_port(dev, 32)) return ENXIO; /* Setup an I/O address mapping table and some others. */ fe_softc_defaults(sc); /* Simple probe. */ if (!fe_simple_probe(sc, probe_table)) return ENXIO; /* Get our station address from EEPROM, and make sure it is Fujitsu's. */ fe_inblk(sc, FE_FMV4, sc->enaddr, ETHER_ADDR_LEN); if (!fe_valid_Ether_p(sc->enaddr, 0x00000E)) return ENXIO; /* Find the supported media and "hardware revision" to know the model identification. */ mcode = (fe_inb(sc, FE_FMV0) & FE_FMV0_MEDIA) | ((fe_inb(sc, FE_FMV1) & FE_FMV1_REV) << 8); /* Determine the card type. */ for (type = typelist; type->mcode != 0; type++) { if (type->mcode == mcode) break; } if (type->mcode == 0) { /* Unknown card type... Hope the driver works. */ sc->stability |= UNSTABLE_TYPE; if (bootverbose) { device_printf(dev, "unknown config: %x-%x-%x-%x\n", fe_inb(sc, FE_FMV0), fe_inb(sc, FE_FMV1), fe_inb(sc, FE_FMV2), fe_inb(sc, FE_FMV3)); } } /* Setup the board type and media information. */ sc->type = FE_TYPE_FMV; sc->typestr = type->str; sc->mbitmap = type->mbitmap; sc->defmedia = type->defmedia; sc->msel = fe_msel_965; if (type->mbitmap == (MB_H2 | MB_H5)) { /* FMV184 requires a special media selection procedure. */ sc->msel = fe_msel_fmv184; } /* * An FMV-180 has been probed. * Determine which IRQ to be used. * * In this version, we give a priority to the kernel config file. * If the EEPROM and config don't match, say it to the user for * an attention. */ n = (fe_inb(sc, FE_FMV2) & FE_FMV2_IRS) >> FE_FMV2_IRS_SHIFT; irq = 0; bus_get_resource(dev, SYS_RES_IRQ, 0, &irq, NULL); if (irq == NO_IRQ) { /* Just use the probed value. */ bus_set_resource(dev, SYS_RES_IRQ, 0, irqmap[n], 1); } else if (irq != irqmap[n]) { /* Don't match. */ sc->stability |= UNSTABLE_IRQ; } /* We need an init hook to initialize ASIC before we start. */ sc->init = fe_init_fmv; return 0; }
/* * Probe for TDK LAC-98012/013/025/9N011 - parhaps. */ static int fe_probe_lnx(device_t dev) { struct fe_softc *sc = device_get_softc(dev); rman_res_t iobase, irq; u_char eeprom [LNX_EEPROM_SIZE]; static struct fe_simple_probe_struct probe_table [] = { { FE_DLCR2, 0x58, 0x00 }, { FE_DLCR4, 0x08, 0x00 }, { 0 } }; /* See if the specified I/O address is possible for TDK/LANX boards. */ /* 0D0, 4D0, 8D0, and CD0 are allowed. */ if (bus_get_resource(dev, SYS_RES_IOPORT, 0, &iobase, NULL) != 0) return ENXIO; if ((iobase & ~0xC00) != 0xD0) return ENXIO; if (fe98_alloc_port(dev, FE_TYPE_LNX)) return ENXIO; /* Fill the softc struct with default values. */ fe_softc_defaults(sc); /* See if the card is on its address. */ if (!fe_simple_probe(sc, probe_table)) return ENXIO; /* We now have to read the config EEPROM. We should be very careful, since doing so destroys a register. (Remember, we are not yet sure we have a LAC-98012/98013 board here.) */ fe_read_eeprom_lnx(sc, eeprom); /* Make sure the Ethernet (MAC) station address is of TDK/LANX's. */ if (!fe_valid_Ether_p(eeprom, 0x008098)) return ENXIO; bcopy(eeprom, sc->enaddr, ETHER_ADDR_LEN); /* Setup the board type. */ sc->typestr = "LAC-98012/98013"; /* This looks like a TDK/LANX board. It requires an explicit IRQ setting in config. Make sure we have one, determining an appropriate value for the IRQ control register. */ irq = 0; if (bus_get_resource(dev, SYS_RES_IRQ, 0, &irq, NULL) != 0) return ENXIO; switch (irq) { case 3 : sc->priv_info = 0x10 | LNX_CLK_LO | LNX_SDA_HI; break; case 5 : sc->priv_info = 0x20 | LNX_CLK_LO | LNX_SDA_HI; break; case 6 : sc->priv_info = 0x40 | LNX_CLK_LO | LNX_SDA_HI; break; case 12: sc->priv_info = 0x80 | LNX_CLK_LO | LNX_SDA_HI; break; default: fe_irq_failure(sc->typestr, sc->sc_unit, irq, "3/5/6/12"); return ENXIO; } /* LAC-98's system bus width is 8-bit. */ sc->proto_dlcr6 = FE_D6_BUFSIZ_32KB | FE_D6_TXBSIZ_2x2KB | FE_D6_BBW_BYTE | FE_D6_SBW_BYTE | FE_D6_SRAM_150ns; /* Setup hooks. We need a special initialization procedure. */ sc->init = fe_init_lnx; return 0; }
/* * Probe for Contec C-NET(98)P2 series. * (Logitec LAN-98TP/LAN-98T25P - parhaps) */ static int fe_probe_ssi(device_t dev) { struct fe_softc *sc = device_get_softc(dev); rman_res_t iobase, irq; u_char eeprom [SSI_EEPROM_SIZE]; static struct fe_simple_probe_struct probe_table [] = { { FE_DLCR2, 0x08, 0x00 }, { FE_DLCR4, 0x08, 0x00 }, { 0 } }; static u_short const irqmap[] = { /* INT0 INT1 INT2 */ NO_IRQ, NO_IRQ, NO_IRQ, 3, NO_IRQ, 5, 6, NO_IRQ, NO_IRQ, 9, 10, NO_IRQ, 12, 13, NO_IRQ, NO_IRQ, /* INT3 INT41 INT5 INT6 */ }; /* See if the specified I/O address is possible for 78Q8377A. */ /* [0-D]3D0 are allowed. */ if (bus_get_resource(dev, SYS_RES_IOPORT, 0, &iobase, NULL) != 0) return ENXIO; if ((iobase & 0xFFF) != 0x3D0) return ENXIO; if (fe98_alloc_port(dev, FE_TYPE_SSI)) return ENXIO; /* Fill the softc struct with default values. */ fe_softc_defaults(sc); /* See if the card is on its address. */ if (!fe_simple_probe(sc, probe_table)) return ENXIO; /* We now have to read the config EEPROM. We should be very careful, since doing so destroys a register. (Remember, we are not yet sure we have a C-NET(98)P2 board here.) Don't remember to select BMPRs bofore reading EEPROM, since other register bank may be selected before the probe() is called. */ fe_read_eeprom_ssi(sc, eeprom); /* Make sure the Ethernet (MAC) station address is of Contec's. */ if (!fe_valid_Ether_p(eeprom + FE_SSI_EEP_ADDR, 0x00804C)) return ENXIO; bcopy(eeprom + FE_SSI_EEP_ADDR, sc->enaddr, ETHER_ADDR_LEN); /* Setup the board type. */ sc->typestr = "C-NET(98)P2"; /* Non-PnP mode, set static resource from eeprom. */ if (!isa_get_vendorid(dev)) { /* Get IRQ configuration from EEPROM. */ irq = irqmap[eeprom[FE_SSI_EEP_IRQ]]; if (irq == NO_IRQ) { fe_irq_failure(sc->typestr, sc->sc_unit, irq, "3/5/6/9/10/12/13"); return ENXIO; } bus_set_resource(dev, SYS_RES_IRQ, 0, irq, 1); } /* Get Duplex-mode configuration from EEPROM. */ sc->proto_dlcr4 |= (eeprom[FE_SSI_EEP_DUPLEX] & FE_D4_DSC); /* Fill softc struct accordingly. */ sc->mbitmap = MB_HT; sc->defmedia = MB_HT; return 0; }
static int fe_probe_cnet9ne (device_t dev) { struct fe_softc *sc = device_get_softc(dev); rman_res_t iobase, irq; static struct fe_simple_probe_struct probe_table [] = { { FE_DLCR2, 0x58, 0x00 }, { FE_DLCR4, 0x08, 0x00 }, { 0 } }; /* See if the specified I/O address is possible for C-NET(9N)E. */ if (bus_get_resource(dev, SYS_RES_IOPORT, 0, &iobase, NULL) != 0) return ENXIO; if (iobase != 0x73D0) return ENXIO; if (fe98_alloc_port(dev, FE_TYPE_CNET9NE)) return ENXIO; /* Fill the softc struct with default values. */ fe_softc_defaults(sc); /* See if the card is on its address. */ if (!fe_simple_probe(sc, probe_table)) return ENXIO; /* Get our station address from EEPROM. */ fe_inblk(sc, 0x18, sc->enaddr, ETHER_ADDR_LEN); /* Make sure it is Contec's. */ if (!fe_valid_Ether_p(sc->enaddr, 0x00804C)) return ENXIO; /* Determine the card type. */ if (sc->enaddr[3] == 0x06) { sc->typestr = "C-NET(9N)C"; /* We seems to need our own IDENT bits... FIXME. */ sc->proto_dlcr7 = FE_D7_BYTSWP_LH | FE_D7_IDENT_NICE; /* C-NET(9N)C requires an explicit IRQ to work. */ if (bus_get_resource(dev, SYS_RES_IRQ, 0, &irq, NULL) != 0) { fe_irq_failure(sc->typestr, sc->sc_unit, NO_IRQ, NULL); return ENXIO; } } else { sc->typestr = "C-NET(9N)E"; /* C-NET(9N)E works only IRQ5. */ if (bus_get_resource(dev, SYS_RES_IRQ, 0, &irq, NULL) != 0) return ENXIO; if (irq != 5) { fe_irq_failure(sc->typestr, sc->sc_unit, irq, "5"); return ENXIO; } /* We need an init hook to initialize ASIC before we start. */ sc->init = fe_init_cnet9ne; } /* C-NET(9N)E has 64KB SRAM. */ sc->proto_dlcr6 = FE_D6_BUFSIZ_64KB | FE_D6_TXBSIZ_2x4KB | FE_D6_BBW_WORD | FE_D6_SBW_WORD | FE_D6_SRAM; return 0; }
static int fe_probe_re1000(device_t dev) { struct fe_softc *sc = device_get_softc(dev); int i, n; rman_res_t iobase, irq; u_char sum; static struct fe_simple_probe_struct probe_table [] = { { FE_DLCR2, 0x58, 0x00 }, { FE_DLCR4, 0x08, 0x00 }, { 0 } }; /* See if the specified I/O address is possible for RE1000. */ /* [01]D[02468ACE] are allowed. */ if (bus_get_resource(dev, SYS_RES_IOPORT, 0, &iobase, NULL) != 0) return ENXIO; if ((iobase & ~0x10E) != 0xD0) return ENXIO; if (fe98_alloc_port(dev, FE_TYPE_RE1000)) return ENXIO; /* Fill the softc struct with default values. */ fe_softc_defaults(sc); /* See if the card is on its address. */ if (!fe_simple_probe(sc, probe_table)) return ENXIO; /* Get our station address from EEPROM. */ fe_inblk(sc, 0x18, sc->enaddr, ETHER_ADDR_LEN); /* Make sure it is Allied-Telesis's. */ if (!fe_valid_Ether_p(sc->enaddr, 0x0000F4)) return ENXIO; #if 1 /* Calculate checksum. */ sum = fe_inb(sc, 0x1e); for (i = 0; i < ETHER_ADDR_LEN; i++) sum ^= sc->enaddr[i]; if (sum != 0) return ENXIO; #endif /* Setup the board type. */ sc->typestr = "RE1000"; /* This looks like an RE1000 board. It requires an explicit IRQ setting in config. Make sure we have one, determining an appropriate value for the IRQ control register. */ irq = 0; bus_get_resource(dev, SYS_RES_IRQ, 0, &irq, NULL); switch (irq) { case 3: n = 0x10; break; case 5: n = 0x20; break; case 6: n = 0x40; break; case 12: n = 0x80; break; default: fe_irq_failure(sc->typestr, sc->sc_unit, irq, "3/5/6/12"); return ENXIO; } sc->priv_info = (fe_inb(sc, FE_RE1000_IRQCONF) & 0x0f) | n; /* Setup hooks. We need a special initialization procedure. */ sc->init = fe_init_re1000; return 0; }
/* * Probe and initialization for TDK/LANX LAC-AX012/013 boards. */ static int fe_probe_lnx(device_t dev) { struct fe_softc *sc = device_get_softc(dev); u_long iobase, irq; u_char eeprom [LNX_EEPROM_SIZE]; static struct fe_simple_probe_struct probe_table [] = { { FE_DLCR2, 0x58, 0x00 }, { FE_DLCR4, 0x08, 0x00 }, { 0 } }; /* See if the specified I/O address is possible for TDK/LANX boards. */ /* 300, 320, 340, and 360 are allowed. */ if (bus_get_resource(dev, SYS_RES_IOPORT, 0, &iobase, NULL) != 0) return ENXIO; if ((iobase & ~0x060) != 0x300) return ENXIO; /* We have 32 registers. */ if (fe_alloc_port(dev, 32)) return ENXIO; /* Fill the softc struct with default values. */ fe_softc_defaults(sc); /* See if the card is on its address. */ if (!fe_simple_probe(sc, probe_table)) return ENXIO; /* We now have to read the config EEPROM. We should be very careful, since doing so destroys a register. (Remember, we are not yet sure we have a LAC-AX012/AX013 board here.) */ fe_read_eeprom_lnx(sc, eeprom); /* Make sure the Ethernet (MAC) station address is of TDK/LANX's. */ if (!fe_valid_Ether_p(eeprom, 0x008098)) return ENXIO; bcopy(eeprom, sc->enaddr, ETHER_ADDR_LEN); /* This looks like a TDK/LANX board. It requires an explicit IRQ setting in config. Make sure we have one, determining an appropriate value for the IRQ control register. */ irq = 0; bus_get_resource(dev, SYS_RES_IRQ, 0, &irq, NULL); switch (irq) { case 3: sc->priv_info = 0x40 | LNX_CLK_LO | LNX_SDA_HI; break; case 4: sc->priv_info = 0x20 | LNX_CLK_LO | LNX_SDA_HI; break; case 5: sc->priv_info = 0x10 | LNX_CLK_LO | LNX_SDA_HI; break; case 9: sc->priv_info = 0x80 | LNX_CLK_LO | LNX_SDA_HI; break; default: fe_irq_failure("LAC-AX012/AX013", sc->sc_unit, irq, "3/4/5/9"); return ENXIO; } /* Fill softc struct accordingly. */ sc->type = FE_TYPE_LNX; sc->typestr = "LAC-AX012/AX013"; sc->init = fe_init_lnx; return 0; }
/* * Probe for Ungermann-Bass Access/PC N98C+(Model 85152). */ static int fe_probe_ubn(device_t dev) { struct fe_softc *sc = device_get_softc(dev); u_char sum, save7; rman_res_t iobase, irq; int i; static struct fe_simple_probe_struct const probe_table [] = { { FE_DLCR2, 0x58, 0x00 }, { FE_DLCR4, 0x08, 0x00 }, { 0 } }; /* See if the specified I/O address is possible for Access/PC. */ /* [01][048C]D0 are allowed. */ if (bus_get_resource(dev, SYS_RES_IOPORT, 0, &iobase, NULL) != 0) return ENXIO; if ((iobase & ~0x1C00) != 0xD0) return ENXIO; if (fe98_alloc_port(dev, FE_TYPE_UBN)) return ENXIO; /* Fill the softc struct with default values. */ fe_softc_defaults(sc); /* Simple probe. */ if (!fe_simple_probe(sc, probe_table)) return ENXIO; /* NOTE: Access/NOTE N98 sometimes freeze when reading station address. In case of using it togather with C-NET(9N)C, this problem usually happens. Writing DLCR7 prevents freezing, but I don't know why. FIXME. */ /* Save the current value for the DLCR7 register we are about to destroy. */ save7 = fe_inb(sc, FE_DLCR7); fe_outb(sc, FE_DLCR7, sc->proto_dlcr7 | FE_D7_RBS_BMPR | FE_D7_POWER_UP); /* Get our station address form ID ROM and make sure it is UBN's. */ fe_inblk(sc, 0x18, sc->enaddr, ETHER_ADDR_LEN); if (!fe_valid_Ether_p(sc->enaddr, 0x00DD01)) goto fail_ubn; #if 1 /* Calculate checksum. */ sum = fe_inb(sc, 0x1e); for (i = 0; i < ETHER_ADDR_LEN; i++) sum ^= sc->enaddr[i]; if (sum != 0) goto fail_ubn; #endif /* Setup the board type. */ sc->typestr = "Access/PC"; /* This looks like an AccessPC/N98C+ board. It requires an explicit IRQ setting in config. Make sure we have one, determining an appropriate value for the IRQ control register. */ irq = 0; bus_get_resource(dev, SYS_RES_IRQ, 0, &irq, NULL); switch (irq) { case 3: sc->priv_info = 0x01; break; case 5: sc->priv_info = 0x02; break; case 6: sc->priv_info = 0x04; break; case 12: sc->priv_info = 0x08; break; default: fe_irq_failure(sc->typestr, sc->sc_unit, irq, "3/5/6/12"); goto fail_ubn; } /* Setup hooks. We need a special initialization procedure. */ sc->init = fe_init_ubn; return 0; fail_ubn: fe_outb(sc, FE_DLCR7, save7); return ENXIO; }
/* Probe and initialization for Ungermann-Bass Network K.K. "Access/PC" boards. */ static int fe_probe_ubn(device_t dev) { struct fe_softc *sc = device_get_softc(dev); u_long iobase, irq; #if 0 u_char sum; #endif static struct fe_simple_probe_struct const probe_table [] = { { FE_DLCR2, 0x58, 0x00 }, { FE_DLCR4, 0x08, 0x00 }, { 0 } }; /* See if the specified I/O address is possible for AccessPC/ISA. */ if (bus_get_resource(dev, SYS_RES_IOPORT, 0, &iobase, NULL) != 0) return ENXIO; if ((iobase & ~0x0E0) != 0x300) return ENXIO; /* We have 32 registers. */ if (fe_alloc_port(dev, 32)) return ENXIO; /* Setup an I/O address mapping table and some others. */ fe_softc_defaults(sc); /* Simple probe. */ if (!fe_simple_probe(sc, probe_table)) return ENXIO; /* Get our station address form ID ROM and make sure it is UBN's. */ fe_inblk(sc, 0x18, sc->enaddr, ETHER_ADDR_LEN); if (!fe_valid_Ether_p(sc->enaddr, 0x00DD01)) return ENXIO; #if 0 /* Calculate checksum. */ sum = fe_inb(sc, 0x1e); for (i = 0; i < ETHER_ADDR_LEN; i++) { sum ^= sc->enaddr[i]; } if (sum != 0) return ENXIO; #endif /* This looks like an AccessPC/ISA board. It requires an explicit IRQ setting in config. Make sure we have one, determining an appropriate value for the IRQ control register. */ irq = 0; bus_get_resource(dev, SYS_RES_IRQ, 0, &irq, NULL); switch (irq) { case 3: sc->priv_info = 0x02; break; case 4: sc->priv_info = 0x04; break; case 5: sc->priv_info = 0x08; break; case 10: sc->priv_info = 0x10; break; default: fe_irq_failure("Access/PC", sc->sc_unit, irq, "3/4/5/10"); return ENXIO; } /* Fill softc struct accordingly. */ sc->type = FE_TYPE_UBN; sc->typestr = "Access/PC"; sc->init = fe_init_ubn; return 0; }
/* * Probe for RATOC REX-9880/81/82/83 series. */ static int fe_probe_rex(device_t dev) { struct fe_softc *sc = device_get_softc(dev); int i; rman_res_t iobase, irq; u_char eeprom [REX_EEPROM_SIZE]; static struct fe_simple_probe_struct probe_table [] = { { FE_DLCR2, 0x58, 0x00 }, { FE_DLCR4, 0x08, 0x00 }, { 0 } }; /* See if the specified I/O address is possible for REX-9880. */ /* 6[46CE]D0 are allowed. */ if (bus_get_resource(dev, SYS_RES_IOPORT, 0, &iobase, NULL) != 0) return ENXIO; if ((iobase & ~0xA00) != 0x64D0) return ENXIO; if (fe98_alloc_port(dev, FE_TYPE_REX)) return ENXIO; /* Fill the softc struct with default values. */ fe_softc_defaults(sc); /* See if the card is on its address. */ if (!fe_simple_probe(sc, probe_table)) return ENXIO; /* We now have to read the config EEPROM. We should be very careful, since doing so destroys a register. (Remember, we are not yet sure we have a REX-9880 board here.) */ fe_read_eeprom_rex(sc, eeprom); for (i = 0; i < ETHER_ADDR_LEN; i++) sc->enaddr[i] = eeprom[7 - i]; /* Make sure it is RATOC's. */ if (!fe_valid_Ether_p(sc->enaddr, 0x00C0D0) && !fe_valid_Ether_p(sc->enaddr, 0x00803D)) return 0; /* Setup the board type. */ sc->typestr = "REX-9880/9883"; /* This looks like a REX-9880 board. It requires an explicit IRQ setting in config. Make sure we have one, determining an appropriate value for the IRQ control register. */ irq = 0; bus_get_resource(dev, SYS_RES_IRQ, 0, &irq, NULL); switch (irq) { case 3: sc->priv_info = 0x10; break; case 5: sc->priv_info = 0x20; break; case 6: sc->priv_info = 0x40; break; case 12: sc->priv_info = 0x80; break; default: fe_irq_failure(sc->typestr, sc->sc_unit, irq, "3/5/6/12"); return ENXIO; } /* Setup hooks. We need a special initialization procedure. */ sc->init = fe_init_rex; /* REX-9880 has 64KB SRAM. */ sc->proto_dlcr6 = FE_D6_BUFSIZ_64KB | FE_D6_TXBSIZ_2x4KB | FE_D6_BBW_WORD | FE_D6_SBW_WORD | FE_D6_SRAM; #if 1 sc->proto_dlcr7 |= FE_D7_EOPPOL; /* XXX */ #endif return 0; }