/* * Probe and initialization for TDK/CONTEC PCMCIA Ethernet interface. * by MASUI Kenji <*****@*****.**> * * (Contec uses TDK Ethenet 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) { struct fe_softc *sc = device_get_softc(dev); static struct fe_simple_probe_struct probe_table [] = { { FE_DLCR2, 0x50, 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)"; /* Make sure we got a valid station address. */ if (!valid_Ether_p(sc->sc_enaddr, 0)) 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; }
static int fe_isa_attach(device_t dev) { struct fe_softc *sc = device_get_softc(dev); if (sc->port_used) fe_alloc_port(dev, sc->port_used); fe_alloc_irq(dev, 0); return fe_attach(dev); }
static int fe_probe_mbh(device_t dev) { 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; /* Ethernet MAC address should *NOT* have been given by pccardd, if this is a true MBH10302; i.e., Ethernet address must be "all-zero" upon entry. */ if (sc->sc_enaddr[0] || sc->sc_enaddr[1] || sc->sc_enaddr[2] || sc->sc_enaddr[3] || sc->sc_enaddr[4] || sc->sc_enaddr[5]) 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->sc_enaddr, ETHER_ADDR_LEN); /* Make sure we got a valid station address. */ if (!valid_Ether_p(sc->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; }
/* * 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; }
/* 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 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; }
static int fe_probe_jli(device_t dev) { struct fe_softc *sc = device_get_softc(dev); int i, n, error, xirq; u_long iobase, irq; u_char eeprom [JLI_EEPROM_SIZE]; u_short const * irqmap; static u_short const baseaddr [8] = { 0x260, 0x280, 0x2A0, 0x240, 0x340, 0x320, 0x380, 0x300 }; static struct fe_simple_probe_struct const probe_table [] = { { FE_DLCR1, 0x20, 0x00 }, { FE_DLCR2, 0x50, 0x00 }, { FE_DLCR4, 0x08, 0x00 }, { FE_DLCR5, 0x80, 0x00 }, #if 0 { FE_BMPR16, 0x1B, 0x00 }, { FE_BMPR17, 0x7F, 0x00 }, #endif { 0 } }; /* * See if the specified address is possible for MB86965A JLI mode. */ if (bus_get_resource(dev, SYS_RES_IOPORT, 0, &iobase, NULL) != 0) return ENXIO; for (i = 0; i < 8; i++) { if (baseaddr[i] == iobase) break; } if (i == 8) return ENXIO; /* 86965 JLI occupies 32 I/O addresses. */ if (fe_alloc_port(dev, 32)) return ENXIO; /* Fill the softc struct with reasonable default. */ fe_softc_defaults(sc); /* * We should test if MB86965A is on the base address now. * Unfortunately, it is very hard to probe it reliably, since * we have no way to reset the chip under software control. * On cold boot, we could check the "signature" bit patterns * described in the Fujitsu document. On warm boot, however, * we can predict almost nothing about register values. */ if (!fe_simple_probe(sc, probe_table)) return ENXIO; /* Check if our I/O address matches config info on 86965. */ n = (fe_inb(sc, FE_BMPR19) & FE_B19_ADDR) >> FE_B19_ADDR_SHIFT; if (baseaddr[n] != iobase) return ENXIO; /* * We are now almost sure we have an MB86965 at the given * address. So, read EEPROM through it. We have to write * into LSI registers to read from EEPROM. I want to avoid it * at this stage, but I cannot test the presence of the chip * any further without reading EEPROM. FIXME. */ fe_read_eeprom_jli(sc, eeprom); /* Make sure that config info in EEPROM and 86965 agree. */ if (eeprom[FE_EEPROM_CONF] != fe_inb(sc, FE_BMPR19)) return ENXIO; /* Use 86965 media selection scheme, unless othewise specified. It is "AUTO always" and "select with BMPR13." This behaviour covers most of the 86965 based board (as minimum requirements.) It is backward compatible with previous versions, also. */ sc->mbitmap = MB_HA; sc->defmedia = MB_HA; sc->msel = fe_msel_965; /* Perform board-specific probe, one by one. Note that the order of probe is important and should not be changed arbitrarily. */ if ((irqmap = fe_probe_jli_ati(sc, eeprom)) == NULL && (irqmap = fe_probe_jli_rex(sc, eeprom)) == NULL && (irqmap = fe_probe_jli_icl(sc, eeprom)) == NULL && (irqmap = fe_probe_jli_unk(sc, eeprom)) == NULL) return ENXIO; /* Find the IRQ read from EEPROM. */ n = (fe_inb(sc, FE_BMPR19) & FE_B19_IRQ) >> FE_B19_IRQ_SHIFT; xirq = irqmap[n]; /* Try to determine IRQ setting. */ error = bus_get_resource(dev, SYS_RES_IRQ, 0, &irq, NULL); if (error && xirq == NO_IRQ) { /* The device must be configured with an explicit IRQ. */ device_printf(dev, "IRQ auto-detection does not work\n"); return ENXIO; } else if (error && xirq != NO_IRQ) { /* Just use the probed IRQ value. */ bus_set_resource(dev, SYS_RES_IRQ, 0, xirq, 1); } else if (!error && xirq == NO_IRQ) { /* No problem. Go ahead. */ } else if (irq == xirq) { /* Good. Go ahead. */ } else { /* User must be warned in this case. */ sc->stability |= UNSTABLE_IRQ; } /* Setup a hook, which resets te 86965 when the driver is being initialized. This may solve a nasty bug. FIXME. */ sc->init = fe_init_jli; return 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; }