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; }
/* * 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; }
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; }
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 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; }
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; }