1139749Simp/*- 265832Snyan * All Rights Reserved, Copyright (C) Fujitsu Limited 1995 365832Snyan * 465832Snyan * This software may be used, modified, copied, distributed, and sold, in 565832Snyan * both source and binary form provided that the above copyright, these 665832Snyan * terms and the following disclaimer are retained. The name of the author 765832Snyan * and/or the contributor may not be used to endorse or promote products 865832Snyan * derived from this software without specific prior written permission. 965832Snyan * 1065832Snyan * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND THE CONTRIBUTOR ``AS IS'' AND 1165832Snyan * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1265832Snyan * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 1365832Snyan * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR THE CONTRIBUTOR BE LIABLE 1465832Snyan * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 1565832Snyan * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 1665832Snyan * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION. 1765832Snyan * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 1865832Snyan * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 1965832Snyan * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2065832Snyan * SUCH DAMAGE. 2165832Snyan * 2265832Snyan */ 2365832Snyan 24119418Sobrien#include <sys/cdefs.h> 25119418Sobrien__FBSDID("$FreeBSD$"); 26119418Sobrien 2765832Snyan#include <sys/param.h> 2865832Snyan#include <sys/systm.h> 2965832Snyan#include <sys/kernel.h> 3065832Snyan#include <sys/socket.h> 3165832Snyan#include <sys/module.h> 3265832Snyan 3365832Snyan#include <sys/bus.h> 3465832Snyan#include <machine/bus.h> 35179959Sjhb#include <sys/rman.h> 3665832Snyan 3765832Snyan#include <net/ethernet.h> 3865832Snyan#include <net/if.h> 3965832Snyan#include <net/if_mib.h> 4065832Snyan#include <net/if_media.h> 4165832Snyan 4265832Snyan#include <netinet/in.h> 4365832Snyan#include <netinet/if_ether.h> 4465832Snyan 45142135Simp#include <dev/fe/mb86960.h> 4665832Snyan#include <dev/fe/if_fereg.h> 4765832Snyan#include <dev/fe/if_fevar.h> 4865832Snyan 4965832Snyan#include <isa/isavar.h> 5065832Snyan 5165832Snyan/* 5265832Snyan * ISA specific code. 5365832Snyan */ 5465832Snyanstatic int fe_isa_probe(device_t); 5565832Snyanstatic int fe_isa_attach(device_t); 5665832Snyan 5765832Snyanstatic device_method_t fe_isa_methods[] = { 5865832Snyan /* Device interface */ 5965832Snyan DEVMETHOD(device_probe, fe_isa_probe), 6065832Snyan DEVMETHOD(device_attach, fe_isa_attach), 6165832Snyan 6265832Snyan { 0, 0 } 6365832Snyan}; 6465832Snyan 6565832Snyanstatic driver_t fe_isa_driver = { 6665832Snyan "fe", 6765832Snyan fe_isa_methods, 6865832Snyan sizeof (struct fe_softc) 6965832Snyan}; 7065832Snyan 7165832SnyanDRIVER_MODULE(fe, isa, fe_isa_driver, fe_devclass, 0, 0); 7265832Snyan 7365832Snyan 7465832Snyanstatic int fe_probe_ssi(device_t); 7565832Snyanstatic int fe_probe_jli(device_t); 7665832Snyanstatic int fe_probe_fmv(device_t); 7765832Snyanstatic int fe_probe_lnx(device_t); 7865832Snyanstatic int fe_probe_gwy(device_t); 7965832Snyanstatic int fe_probe_ubn(device_t); 8065832Snyan 8165832Snyan/* 8265832Snyan * Determine if the device is present at a specified I/O address. The 8365832Snyan * main entry to the driver. 8465832Snyan */ 8565832Snyanstatic int 8665832Snyanfe_isa_probe(device_t dev) 8765832Snyan{ 8865832Snyan struct fe_softc *sc; 8965832Snyan int error; 9065832Snyan 9165832Snyan /* Check isapnp ids */ 9265832Snyan if (isa_get_vendorid(dev)) 9365832Snyan return (ENXIO); 9465832Snyan 9565832Snyan /* Prepare for the softc struct. */ 9665832Snyan sc = device_get_softc(dev); 9765832Snyan sc->sc_unit = device_get_unit(dev); 9865832Snyan 9965832Snyan /* Probe for supported boards. */ 10065832Snyan if ((error = fe_probe_ssi(dev)) == 0) 10165832Snyan goto end; 10265832Snyan fe_release_resource(dev); 10365832Snyan 10465832Snyan if ((error = fe_probe_jli(dev)) == 0) 10565832Snyan goto end; 10665832Snyan fe_release_resource(dev); 10765832Snyan 10865832Snyan if ((error = fe_probe_fmv(dev)) == 0) 10965832Snyan goto end; 11065832Snyan fe_release_resource(dev); 11165832Snyan 11265832Snyan if ((error = fe_probe_lnx(dev)) == 0) 11365832Snyan goto end; 11465832Snyan fe_release_resource(dev); 11565832Snyan 11665832Snyan if ((error = fe_probe_ubn(dev)) == 0) 11765832Snyan goto end; 11865832Snyan fe_release_resource(dev); 11965832Snyan 12065832Snyan if ((error = fe_probe_gwy(dev)) == 0) 12165832Snyan goto end; 12265832Snyan fe_release_resource(dev); 12365832Snyan 12465832Snyanend: 12565832Snyan if (error == 0) 12665832Snyan error = fe_alloc_irq(dev, 0); 12765832Snyan 12865832Snyan fe_release_resource(dev); 12965832Snyan return (error); 13065832Snyan} 13165832Snyan 13265832Snyanstatic int 13365832Snyanfe_isa_attach(device_t dev) 13465832Snyan{ 13565832Snyan struct fe_softc *sc = device_get_softc(dev); 13665832Snyan 13765832Snyan if (sc->port_used) 13865832Snyan fe_alloc_port(dev, sc->port_used); 13965832Snyan fe_alloc_irq(dev, 0); 14065832Snyan 14165832Snyan return fe_attach(dev); 14265832Snyan} 14365832Snyan 14465832Snyan 14565832Snyan/* 14665832Snyan * Probe and initialization for Fujitsu FMV-180 series boards 14765832Snyan */ 14865832Snyan 14965832Snyanstatic void 15065832Snyanfe_init_fmv(struct fe_softc *sc) 15165832Snyan{ 15265832Snyan /* Initialize ASIC. */ 15365832Snyan fe_outb(sc, FE_FMV3, 0); 15465832Snyan fe_outb(sc, FE_FMV10, 0); 15565832Snyan 15665832Snyan#if 0 15765832Snyan /* "Refresh" hardware configuration. FIXME. */ 15865832Snyan fe_outb(sc, FE_FMV2, fe_inb(sc, FE_FMV2)); 15965832Snyan#endif 16065832Snyan 16165832Snyan /* Turn the "master interrupt control" flag of ASIC on. */ 16265832Snyan fe_outb(sc, FE_FMV3, FE_FMV3_IRQENB); 16365832Snyan} 16465832Snyan 16565832Snyanstatic void 16665832Snyanfe_msel_fmv184(struct fe_softc *sc) 16765832Snyan{ 16865832Snyan u_char port; 16965832Snyan 17065832Snyan /* FMV-184 has a special "register" to switch between AUI/BNC. 17165832Snyan Determine the value to write into the register, based on the 17265832Snyan user-specified media selection. */ 17365832Snyan port = (IFM_SUBTYPE(sc->media.ifm_media) == IFM_10_2) ? 0x00 : 0x01; 17465832Snyan 17565832Snyan /* The register is #5 on exntesion register bank... 17665832Snyan (Details of the register layout is not yet discovered.) */ 17765832Snyan fe_outb(sc, 0x1B, 0x46); /* ??? */ 17865832Snyan fe_outb(sc, 0x1E, 0x04); /* select ex-reg #4. */ 17965832Snyan fe_outb(sc, 0x1F, 0xC8); /* ??? */ 18065832Snyan fe_outb(sc, 0x1E, 0x05); /* select ex-reg #5. */ 18165832Snyan fe_outb(sc, 0x1F, port); /* Switch the media. */ 18265832Snyan fe_outb(sc, 0x1E, 0x04); /* select ex-reg #4. */ 18365832Snyan fe_outb(sc, 0x1F, 0x00); /* ??? */ 18465832Snyan fe_outb(sc, 0x1B, 0x00); /* ??? */ 18565832Snyan 18665832Snyan /* Make sure to select "external tranceiver" on MB86964. */ 18765832Snyan fe_outb(sc, FE_BMPR13, sc->proto_bmpr13 | FE_B13_PORT_AUI); 18865832Snyan} 18965832Snyan 19065832Snyanstatic int 19165832Snyanfe_probe_fmv(device_t dev) 19265832Snyan{ 19365832Snyan struct fe_softc *sc = device_get_softc(dev); 19465832Snyan int n; 19565832Snyan u_long iobase, irq; 19665832Snyan 19765832Snyan static u_short const irqmap [ 4 ] = { 3, 7, 10, 15 }; 19865832Snyan 19965832Snyan static struct fe_simple_probe_struct const probe_table [] = { 20065832Snyan { FE_DLCR2, 0x71, 0x00 }, 20165832Snyan { FE_DLCR4, 0x08, 0x00 }, 20265832Snyan 20365832Snyan { FE_FMV0, 0x78, 0x50 }, /* ERRDY+PRRDY */ 20465832Snyan { FE_FMV1, 0xB0, 0x00 }, /* FMV-183/4 has 0x48 bits. */ 20565832Snyan { FE_FMV3, 0x7F, 0x00 }, 20665832Snyan 20765832Snyan { 0 } 20865832Snyan }; 20965832Snyan 21065832Snyan /* Board subtypes; it lists known FMV-180 variants. */ 21165832Snyan struct subtype { 21265832Snyan u_short mcode; 21365832Snyan u_short mbitmap; 21465832Snyan u_short defmedia; 21565832Snyan char const * str; 21665832Snyan }; 21765832Snyan static struct subtype const typelist [] = { 21865832Snyan { 0x0005, MB_HA|MB_HT|MB_H5, MB_HA, "FMV-181" }, 21965832Snyan { 0x0105, MB_HA|MB_HT|MB_H5, MB_HA, "FMV-181A" }, 22065832Snyan { 0x0003, MB_HM, MB_HM, "FMV-182" }, 22165832Snyan { 0x0103, MB_HM, MB_HM, "FMV-182A" }, 22265832Snyan { 0x0804, MB_HT, MB_HT, "FMV-183" }, 22365832Snyan { 0x0C04, MB_HT, MB_HT, "FMV-183 (on-board)" }, 22465832Snyan { 0x0803, MB_H2|MB_H5, MB_H2, "FMV-184" }, 22565832Snyan { 0, MB_HA, MB_HA, "unknown FMV-180 (?)" }, 22665832Snyan }; 22765832Snyan struct subtype const * type; 22865832Snyan 22965832Snyan /* Media indicator and "Hardware revision ID" */ 23065832Snyan u_short mcode; 23165832Snyan 23265832Snyan /* See if the specified address is possible for FMV-180 23365832Snyan series. 220, 240, 260, 280, 2A0, 2C0, 300, and 340 are 23465832Snyan allowed for all boards, and 200, 2E0, 320, 360, 380, 3A0, 23565832Snyan 3C0, and 3E0 for PnP boards. */ 23665832Snyan if (bus_get_resource(dev, SYS_RES_IOPORT, 0, &iobase, NULL) != 0) 23765832Snyan return ENXIO; 23865832Snyan if ((iobase & ~0x1E0) != 0x200) 23965832Snyan return ENXIO; 24065832Snyan 24165832Snyan /* FMV-180 occupies 32 I/O addresses. */ 24265832Snyan if (fe_alloc_port(dev, 32)) 24365832Snyan return ENXIO; 24465832Snyan 24565832Snyan /* Setup an I/O address mapping table and some others. */ 24665832Snyan fe_softc_defaults(sc); 24765832Snyan 24865832Snyan /* Simple probe. */ 24965832Snyan if (!fe_simple_probe(sc, probe_table)) 25065832Snyan return ENXIO; 25165832Snyan 25265832Snyan /* Get our station address from EEPROM, and make sure it is 25365832Snyan Fujitsu's. */ 254147256Sbrooks fe_inblk(sc, FE_FMV4, sc->enaddr, ETHER_ADDR_LEN); 255147256Sbrooks if (!fe_valid_Ether_p(sc->enaddr, 0x00000E)) 25665832Snyan return ENXIO; 25765832Snyan 25865832Snyan /* Find the supported media and "hardware revision" to know 25965832Snyan the model identification. */ 26065832Snyan mcode = (fe_inb(sc, FE_FMV0) & FE_FMV0_MEDIA) 26165832Snyan | ((fe_inb(sc, FE_FMV1) & FE_FMV1_REV) << 8); 26265832Snyan 26365832Snyan /* Determine the card type. */ 26465832Snyan for (type = typelist; type->mcode != 0; type++) { 26565832Snyan if (type->mcode == mcode) 26665832Snyan break; 26765832Snyan } 26865832Snyan if (type->mcode == 0) { 26965832Snyan /* Unknown card type... Hope the driver works. */ 27065832Snyan sc->stability |= UNSTABLE_TYPE; 27165832Snyan if (bootverbose) { 27265832Snyan device_printf(dev, "unknown config: %x-%x-%x-%x\n", 27365832Snyan fe_inb(sc, FE_FMV0), 27465832Snyan fe_inb(sc, FE_FMV1), 27565832Snyan fe_inb(sc, FE_FMV2), 27665832Snyan fe_inb(sc, FE_FMV3)); 27765832Snyan } 27865832Snyan } 27965832Snyan 28065832Snyan /* Setup the board type and media information. */ 28165832Snyan sc->type = FE_TYPE_FMV; 28265832Snyan sc->typestr = type->str; 28365832Snyan sc->mbitmap = type->mbitmap; 28465832Snyan sc->defmedia = type->defmedia; 28565832Snyan sc->msel = fe_msel_965; 28665832Snyan 28765832Snyan if (type->mbitmap == (MB_H2 | MB_H5)) { 28865832Snyan /* FMV184 requires a special media selection procedure. */ 28965832Snyan sc->msel = fe_msel_fmv184; 29065832Snyan } 29165832Snyan 29265832Snyan /* 29365832Snyan * An FMV-180 has been probed. 29465832Snyan * Determine which IRQ to be used. 29565832Snyan * 29665832Snyan * In this version, we give a priority to the kernel config file. 29765832Snyan * If the EEPROM and config don't match, say it to the user for 29865832Snyan * an attention. 29965832Snyan */ 30065832Snyan n = (fe_inb(sc, FE_FMV2) & FE_FMV2_IRS) >> FE_FMV2_IRS_SHIFT; 30165832Snyan 30265832Snyan irq = 0; 30365832Snyan bus_get_resource(dev, SYS_RES_IRQ, 0, &irq, NULL); 30465832Snyan if (irq == NO_IRQ) { 30565832Snyan /* Just use the probed value. */ 30665832Snyan bus_set_resource(dev, SYS_RES_IRQ, 0, irqmap[n], 1); 30765832Snyan } else if (irq != irqmap[n]) { 30865832Snyan /* Don't match. */ 30965832Snyan sc->stability |= UNSTABLE_IRQ; 31065832Snyan } 31165832Snyan 31265832Snyan /* We need an init hook to initialize ASIC before we start. */ 31365832Snyan sc->init = fe_init_fmv; 31465832Snyan 31565832Snyan return 0; 31665832Snyan} 31765832Snyan 31865832Snyan/* 31965832Snyan * Fujitsu MB86965 JLI mode probe routines. 32065832Snyan * 32165832Snyan * 86965 has a special operating mode called JLI (mode 0), under which 32265832Snyan * the chip interfaces with ISA bus with a software-programmable 32365832Snyan * configuration. (The Fujitsu document calls the feature "Plug and 32465832Snyan * play," but it is not compatible with the ISA-PnP spec. designed by 32565832Snyan * Intel and Microsoft.) Ethernet cards designed to use JLI are 32665832Snyan * almost same, but there are two things which require board-specific 32765832Snyan * probe routines: EEPROM layout and IRQ pin connection. 32865832Snyan * 32965832Snyan * JLI provides a handy way to access EEPROM which should contains the 33065832Snyan * chip configuration information (such as I/O port address) as well 33165832Snyan * as Ethernet station (MAC) address. The chip configuration info. is 33265832Snyan * stored on a fixed location. However, the station address can be 33365832Snyan * located anywhere in the EEPROM; it is up to the board designer to 33465832Snyan * determine the location. (The manual just says "somewhere in the 33565832Snyan * EEPROM.") The fe driver must somehow find out the correct 33665832Snyan * location. 33765832Snyan * 33865832Snyan * Another problem resides in the IRQ pin connection. JLI provides a 33965832Snyan * user to choose an IRQ from up to four predefined IRQs. The 86965 34065832Snyan * chip has a register to select one out of the four possibilities. 34165832Snyan * However, the selection is against the four IRQ pins on the chip. 34265832Snyan * (So-called IRQ-A, -B, -C and -D.) It is (again) up to the board 34365832Snyan * designer to determine which pin to connect which IRQ line on the 34465832Snyan * ISA bus. We need a vendor (or model, for some vendor) specific IRQ 34565832Snyan * mapping table. 34665832Snyan * 34765832Snyan * The routine fe_probe_jli() provides all probe and initialization 34865832Snyan * processes which are common to all JLI implementation, and sub-probe 34965832Snyan * routines supply board-specific actions. 35065832Snyan * 35165832Snyan * JLI sub-probe routine has the following template: 35265832Snyan * 35365832Snyan * u_short const * func (struct fe_softc * sc, u_char const * eeprom); 35465832Snyan * 35565832Snyan * where eeprom is a pointer to an array of 32 byte data read from the 35665832Snyan * config EEPROM on the board. It retuns an IRQ mapping table for the 35765832Snyan * board, when the corresponding implementation is detected. It 35865832Snyan * returns a NULL otherwise. 35965832Snyan * 36065832Snyan * Primary purpose of the functin is to analize the config EEPROM, 36165832Snyan * determine if it matches with the pattern of that of supported card, 36265832Snyan * and extract necessary information from it. One of the information 36365832Snyan * expected to be extracted from EEPROM is the Ethernet station (MAC) 36465832Snyan * address, which must be set to the softc table of the interface by 36565832Snyan * the board-specific routine. 36665832Snyan */ 36765832Snyan 36865832Snyan/* JLI sub-probe for Allied-Telesyn/Allied-Telesis AT1700/RE2000 series. */ 36965832Snyanstatic u_short const * 37065832Snyanfe_probe_jli_ati(struct fe_softc * sc, u_char const * eeprom) 37165832Snyan{ 37265832Snyan int i; 37365832Snyan static u_short const irqmaps_ati [4][4] = 37465832Snyan { 37565832Snyan { 3, 4, 5, 9 }, 37665832Snyan { 10, 11, 12, 15 }, 37765832Snyan { 3, 11, 5, 15 }, 37865832Snyan { 10, 11, 14, 15 }, 37965832Snyan }; 38065832Snyan 38165832Snyan /* Make sure the EEPROM contains Allied-Telesis/Allied-Telesyn 38265832Snyan bit pattern. */ 38365832Snyan if (eeprom[1] != 0x00) return NULL; 38465832Snyan for (i = 2; i < 8; i++) if (eeprom[i] != 0xFF) return NULL; 38565832Snyan for (i = 14; i < 24; i++) if (eeprom[i] != 0xFF) return NULL; 38665832Snyan 38765832Snyan /* Get our station address from EEPROM, and make sure the 38865832Snyan EEPROM contains ATI's address. */ 389147256Sbrooks bcopy(eeprom + 8, sc->enaddr, ETHER_ADDR_LEN); 390147256Sbrooks if (!fe_valid_Ether_p(sc->enaddr, 0x0000F4)) 39165832Snyan return NULL; 39265832Snyan 39365832Snyan /* 39465832Snyan * The following model identification codes are stolen 39565832Snyan * from the NetBSD port of the fe driver. My reviewers 39665832Snyan * suggested minor revision. 39765832Snyan */ 39865832Snyan 39965832Snyan /* Determine the card type. */ 40065832Snyan switch (eeprom[FE_ATI_EEP_MODEL]) { 40165832Snyan case FE_ATI_MODEL_AT1700T: 40265832Snyan sc->typestr = "AT-1700T/RE2001"; 40365832Snyan sc->mbitmap = MB_HT; 40465832Snyan sc->defmedia = MB_HT; 40565832Snyan break; 40665832Snyan case FE_ATI_MODEL_AT1700BT: 40765832Snyan sc->typestr = "AT-1700BT/RE2003"; 40865832Snyan sc->mbitmap = MB_HA | MB_HT | MB_H2; 40965832Snyan break; 41065832Snyan case FE_ATI_MODEL_AT1700FT: 41165832Snyan sc->typestr = "AT-1700FT/RE2009"; 41265832Snyan sc->mbitmap = MB_HA | MB_HT | MB_HF; 41365832Snyan break; 41465832Snyan case FE_ATI_MODEL_AT1700AT: 41565832Snyan sc->typestr = "AT-1700AT/RE2005"; 41665832Snyan sc->mbitmap = MB_HA | MB_HT | MB_H5; 41765832Snyan break; 41865832Snyan default: 41965832Snyan sc->typestr = "unknown AT-1700/RE2000"; 42065832Snyan sc->stability |= UNSTABLE_TYPE | UNSTABLE_IRQ; 42165832Snyan break; 42265832Snyan } 42365832Snyan sc->type = FE_TYPE_JLI; 42465832Snyan 42565832Snyan#if 0 42665832Snyan /* Should we extract default media from eeprom? Linux driver 42765832Snyan for AT1700 does it, although previous releases of FreeBSD 42865832Snyan don't. FIXME. */ 42965832Snyan /* Determine the default media selection from the config 43065832Snyan EEPROM. The byte at offset EEP_MEDIA is believed to 43165832Snyan contain BMPR13 value to be set. We just ignore STP bit or 43265832Snyan squelch bit, since we don't support those. (It is 43365832Snyan intentional.) */ 43465832Snyan switch (eeprom[FE_ATI_EEP_MEDIA] & FE_B13_PORT) { 43565832Snyan case FE_B13_AUTO: 43665832Snyan sc->defmedia = MB_HA; 43765832Snyan break; 43865832Snyan case FE_B13_TP: 43965832Snyan sc->defmedia = MB_HT; 44065832Snyan break; 44165832Snyan case FE_B13_AUI: 44265832Snyan sc->defmedia = sc->mbitmap & (MB_H2|MB_H5|MB_H5); /*XXX*/ 44365832Snyan break; 44465832Snyan default: 44565832Snyan sc->defmedia = MB_HA; 44665832Snyan break; 44765832Snyan } 44865832Snyan 44965832Snyan /* Make sure the default media is compatible with the supported 45065832Snyan ones. */ 45165832Snyan if ((sc->defmedia & sc->mbitmap) == 0) { 45265832Snyan if (sc->defmedia == MB_HA) { 45365832Snyan sc->defmedia = MB_HT; 45465832Snyan } else { 45565832Snyan sc->defmedia = MB_HA; 45665832Snyan } 45765832Snyan } 45865832Snyan#endif 45965832Snyan 46065832Snyan /* 46165832Snyan * Try to determine IRQ settings. 46265832Snyan * Different models use different ranges of IRQs. 46365832Snyan */ 46465832Snyan switch ((eeprom[FE_ATI_EEP_REVISION] & 0xf0) 46565832Snyan |(eeprom[FE_ATI_EEP_MAGIC] & 0x04)) { 46665832Snyan case 0x30: case 0x34: return irqmaps_ati[3]; 46765832Snyan case 0x10: case 0x14: 46865832Snyan case 0x50: case 0x54: return irqmaps_ati[2]; 46965832Snyan case 0x44: case 0x64: return irqmaps_ati[1]; 47065832Snyan default: return irqmaps_ati[0]; 47165832Snyan } 47265832Snyan} 47365832Snyan 47465832Snyan/* JLI sub-probe and msel hook for ICL Ethernet. */ 47565832Snyanstatic void 47665832Snyanfe_msel_icl(struct fe_softc *sc) 47765832Snyan{ 47865832Snyan u_char d4; 47965832Snyan 48065832Snyan /* Switch between UTP and "external tranceiver" as always. */ 48165832Snyan fe_msel_965(sc); 48265832Snyan 48365832Snyan /* The board needs one more bit (on DLCR4) be set appropriately. */ 48465832Snyan if (IFM_SUBTYPE(sc->media.ifm_media) == IFM_10_5) { 48565832Snyan d4 = sc->proto_dlcr4 | FE_D4_CNTRL; 48665832Snyan } else { 48765832Snyan d4 = sc->proto_dlcr4 & ~FE_D4_CNTRL; 48865832Snyan } 48965832Snyan fe_outb(sc, FE_DLCR4, d4); 49065832Snyan} 49165832Snyan 49265832Snyanstatic u_short const * 49365832Snyanfe_probe_jli_icl(struct fe_softc * sc, u_char const * eeprom) 49465832Snyan{ 49565832Snyan int i; 49665832Snyan u_short defmedia; 49765832Snyan u_char d6; 49865832Snyan static u_short const irqmap_icl [4] = { 9, 10, 5, 15 }; 49965832Snyan 50065832Snyan /* Make sure the EEPROM contains ICL bit pattern. */ 50165832Snyan for (i = 24; i < 39; i++) { 50265832Snyan if (eeprom[i] != 0x20 && (eeprom[i] & 0xF0) != 0x30) return NULL; 50365832Snyan } 50465832Snyan for (i = 112; i < 122; i++) { 50565832Snyan if (eeprom[i] != 0x20 && (eeprom[i] & 0xF0) != 0x30) return NULL; 50665832Snyan } 50765832Snyan 50865832Snyan /* Make sure the EEPROM contains ICL's permanent station 50965832Snyan address. If it isn't, probably this board is not an 51065832Snyan ICL's. */ 511139972Simp if (!fe_valid_Ether_p(eeprom+122, 0x00004B)) 51265832Snyan return NULL; 51365832Snyan 51465832Snyan /* Check if the "configured" Ethernet address in the EEPROM is 51565832Snyan valid. Use it if it is, or use the "permanent" address instead. */ 516139972Simp if (fe_valid_Ether_p(eeprom+4, 0x020000)) { 51765832Snyan /* The configured address is valid. Use it. */ 518147256Sbrooks bcopy(eeprom+4, sc->enaddr, ETHER_ADDR_LEN); 51965832Snyan } else { 52065832Snyan /* The configured address is invalid. Use permanent. */ 521147256Sbrooks bcopy(eeprom+122, sc->enaddr, ETHER_ADDR_LEN); 52265832Snyan } 52365832Snyan 52465832Snyan /* Determine model and supported media. */ 52565832Snyan switch (eeprom[0x5E]) { 52665832Snyan case 0: 52765832Snyan sc->typestr = "EtherTeam16i/COMBO"; 52865832Snyan sc->mbitmap = MB_HA | MB_HT | MB_H5 | MB_H2; 52965832Snyan break; 53065832Snyan case 1: 53165832Snyan sc->typestr = "EtherTeam16i/TP"; 53265832Snyan sc->mbitmap = MB_HT; 53365832Snyan break; 53465832Snyan case 2: 53565832Snyan sc->typestr = "EtherTeam16i/ErgoPro"; 53665832Snyan sc->mbitmap = MB_HA | MB_HT | MB_H5; 53765832Snyan break; 53865832Snyan case 4: 53965832Snyan sc->typestr = "EtherTeam16i/DUO"; 54065832Snyan sc->mbitmap = MB_HA | MB_HT | MB_H2; 54165832Snyan break; 54265832Snyan default: 54365832Snyan sc->typestr = "EtherTeam16i"; 54465832Snyan sc->stability |= UNSTABLE_TYPE; 54565832Snyan if (bootverbose) { 54665832Snyan printf("fe%d: unknown model code %02x for EtherTeam16i\n", 54765832Snyan sc->sc_unit, eeprom[0x5E]); 54865832Snyan } 54965832Snyan break; 55065832Snyan } 55165832Snyan sc->type = FE_TYPE_JLI; 55265832Snyan 55365832Snyan /* I'm not sure the following msel hook is required by all 55465832Snyan models or COMBO only... FIXME. */ 55565832Snyan sc->msel = fe_msel_icl; 55665832Snyan 55765832Snyan /* Make the configured media selection the default media. */ 55865832Snyan switch (eeprom[0x28]) { 55965832Snyan case 0: defmedia = MB_HA; break; 56065832Snyan case 1: defmedia = MB_H5; break; 56165832Snyan case 2: defmedia = MB_HT; break; 56265832Snyan case 3: defmedia = MB_H2; break; 56365832Snyan default: 56465832Snyan if (bootverbose) { 56565832Snyan printf("fe%d: unknown default media: %02x\n", 56665832Snyan sc->sc_unit, eeprom[0x28]); 56765832Snyan } 56865832Snyan defmedia = MB_HA; 56965832Snyan break; 57065832Snyan } 57165832Snyan 57265832Snyan /* Make sure the default media is compatible with the 57365832Snyan supported media. */ 57465832Snyan if ((defmedia & sc->mbitmap) == 0) { 57565832Snyan if (bootverbose) { 57665832Snyan printf("fe%d: default media adjusted\n", sc->sc_unit); 57765832Snyan } 57865832Snyan defmedia = sc->mbitmap; 57965832Snyan } 58065832Snyan 58165832Snyan /* Keep the determined default media. */ 58265832Snyan sc->defmedia = defmedia; 58365832Snyan 58465832Snyan /* ICL has "fat" models. We have to program 86965 to properly 58565832Snyan reflect the hardware. */ 58665832Snyan d6 = sc->proto_dlcr6 & ~(FE_D6_BUFSIZ | FE_D6_BBW); 58765832Snyan switch ((eeprom[0x61] << 8) | eeprom[0x60]) { 58865832Snyan case 0x2008: d6 |= FE_D6_BUFSIZ_32KB | FE_D6_BBW_BYTE; break; 58965832Snyan case 0x4010: d6 |= FE_D6_BUFSIZ_64KB | FE_D6_BBW_WORD; break; 59065832Snyan default: 59165832Snyan /* We can't support it, since we don't know which bits 59265832Snyan to set in DLCR6. */ 59365832Snyan printf("fe%d: unknown SRAM config for ICL\n", sc->sc_unit); 59465832Snyan return NULL; 59565832Snyan } 59665832Snyan sc->proto_dlcr6 = d6; 59765832Snyan 59865832Snyan /* Returns the IRQ table for the ICL board. */ 59965832Snyan return irqmap_icl; 60065832Snyan} 60165832Snyan 60265832Snyan/* JLI sub-probe for RATOC REX-5586/5587. */ 60365832Snyanstatic u_short const * 60465832Snyanfe_probe_jli_rex(struct fe_softc * sc, u_char const * eeprom) 60565832Snyan{ 60665832Snyan int i; 60765832Snyan static u_short const irqmap_rex [4] = { 3, 4, 5, NO_IRQ }; 60865832Snyan 60965832Snyan /* Make sure the EEPROM contains RATOC's config pattern. */ 61065832Snyan if (eeprom[1] != eeprom[0]) return NULL; 61165832Snyan for (i = 8; i < 32; i++) if (eeprom[i] != 0xFF) return NULL; 61265832Snyan 61365832Snyan /* Get our station address from EEPROM. Note that RATOC 61465832Snyan stores it "byte-swapped" in each word. (I don't know why.) 61565832Snyan So, we just can't use bcopy().*/ 616147256Sbrooks sc->enaddr[0] = eeprom[3]; 617147256Sbrooks sc->enaddr[1] = eeprom[2]; 618147256Sbrooks sc->enaddr[2] = eeprom[5]; 619147256Sbrooks sc->enaddr[3] = eeprom[4]; 620147256Sbrooks sc->enaddr[4] = eeprom[7]; 621147256Sbrooks sc->enaddr[5] = eeprom[6]; 62265832Snyan 62365832Snyan /* Make sure the EEPROM contains RATOC's station address. */ 624147256Sbrooks if (!fe_valid_Ether_p(sc->enaddr, 0x00C0D0)) 62565832Snyan return NULL; 62665832Snyan 62765832Snyan /* I don't know any sub-model identification. */ 62865832Snyan sc->type = FE_TYPE_JLI; 62965832Snyan sc->typestr = "REX-5586/5587"; 63065832Snyan 63165832Snyan /* Returns the IRQ for the RATOC board. */ 63265832Snyan return irqmap_rex; 63365832Snyan} 63465832Snyan 63565832Snyan/* JLI sub-probe for Unknown board. */ 63665832Snyanstatic u_short const * 63765832Snyanfe_probe_jli_unk(struct fe_softc * sc, u_char const * eeprom) 63865832Snyan{ 63965832Snyan int i, n, romsize; 64065832Snyan static u_short const irqmap [4] = { NO_IRQ, NO_IRQ, NO_IRQ, NO_IRQ }; 64165832Snyan 64265832Snyan /* The generic JLI probe considered this board has an 86965 64365832Snyan in JLI mode, but any other board-specific routines could 64465832Snyan not find the matching implementation. So, we "guess" the 64565832Snyan location by looking for a bit pattern which looks like a 64665832Snyan MAC address. */ 64765832Snyan 64865832Snyan /* Determine how large the EEPROM is. */ 64965832Snyan for (romsize = JLI_EEPROM_SIZE/2; romsize > 16; romsize >>= 1) { 65065832Snyan for (i = 0; i < romsize; i++) { 65165832Snyan if (eeprom[i] != eeprom[i+romsize]) 65265832Snyan break; 65365832Snyan } 65465832Snyan if (i < romsize) 65565832Snyan break; 65665832Snyan } 65765832Snyan romsize <<= 1; 65865832Snyan 65965832Snyan /* Look for a bit pattern which looks like a MAC address. */ 66065832Snyan for (n = 2; n <= romsize - ETHER_ADDR_LEN; n += 2) { 661139972Simp if (!fe_valid_Ether_p(eeprom + n, 0x000000)) 66265832Snyan continue; 66365832Snyan } 66465832Snyan 66565832Snyan /* If no reasonable address was found, we can't go further. */ 66665832Snyan if (n > romsize - ETHER_ADDR_LEN) 66765832Snyan return NULL; 66865832Snyan 66965832Snyan /* Extract our (guessed) station address. */ 670147256Sbrooks bcopy(eeprom+n, sc->enaddr, ETHER_ADDR_LEN); 67165832Snyan 67265832Snyan /* We are not sure what type of board it is... */ 67365832Snyan sc->type = FE_TYPE_JLI; 67465832Snyan sc->typestr = "(unknown JLI)"; 67565832Snyan sc->stability |= UNSTABLE_TYPE | UNSTABLE_MAC; 67665832Snyan 67765832Snyan /* Returns the totally unknown IRQ mapping table. */ 67865832Snyan return irqmap; 67965832Snyan} 68065832Snyan 68165832Snyan/* 68265832Snyan * Probe and initialization for all JLI implementations. 68365832Snyan */ 68465832Snyan 68565832Snyanstatic int 68665832Snyanfe_probe_jli(device_t dev) 68765832Snyan{ 68865832Snyan struct fe_softc *sc = device_get_softc(dev); 68965832Snyan int i, n, error, xirq; 69065832Snyan u_long iobase, irq; 69165832Snyan u_char eeprom [JLI_EEPROM_SIZE]; 69265832Snyan u_short const * irqmap; 69365832Snyan 69465832Snyan static u_short const baseaddr [8] = 69565832Snyan { 0x260, 0x280, 0x2A0, 0x240, 0x340, 0x320, 0x380, 0x300 }; 69665832Snyan static struct fe_simple_probe_struct const probe_table [] = { 69765832Snyan { FE_DLCR1, 0x20, 0x00 }, 69865832Snyan { FE_DLCR2, 0x50, 0x00 }, 69965832Snyan { FE_DLCR4, 0x08, 0x00 }, 70065832Snyan { FE_DLCR5, 0x80, 0x00 }, 70165832Snyan#if 0 70265832Snyan { FE_BMPR16, 0x1B, 0x00 }, 70365832Snyan { FE_BMPR17, 0x7F, 0x00 }, 70465832Snyan#endif 70565832Snyan { 0 } 70665832Snyan }; 70765832Snyan 70865832Snyan /* 70965832Snyan * See if the specified address is possible for MB86965A JLI mode. 71065832Snyan */ 71165832Snyan if (bus_get_resource(dev, SYS_RES_IOPORT, 0, &iobase, NULL) != 0) 71265832Snyan return ENXIO; 71365832Snyan for (i = 0; i < 8; i++) { 71465832Snyan if (baseaddr[i] == iobase) 71565832Snyan break; 71665832Snyan } 71765832Snyan if (i == 8) 71865832Snyan return ENXIO; 71965832Snyan 72065832Snyan /* 86965 JLI occupies 32 I/O addresses. */ 72165832Snyan if (fe_alloc_port(dev, 32)) 72265832Snyan return ENXIO; 72365832Snyan 72465832Snyan /* Fill the softc struct with reasonable default. */ 72565832Snyan fe_softc_defaults(sc); 72665832Snyan 72765832Snyan /* 72865832Snyan * We should test if MB86965A is on the base address now. 72965832Snyan * Unfortunately, it is very hard to probe it reliably, since 73065832Snyan * we have no way to reset the chip under software control. 73165832Snyan * On cold boot, we could check the "signature" bit patterns 73265832Snyan * described in the Fujitsu document. On warm boot, however, 73365832Snyan * we can predict almost nothing about register values. 73465832Snyan */ 73565832Snyan if (!fe_simple_probe(sc, probe_table)) 73665832Snyan return ENXIO; 73765832Snyan 73865832Snyan /* Check if our I/O address matches config info on 86965. */ 73965832Snyan n = (fe_inb(sc, FE_BMPR19) & FE_B19_ADDR) >> FE_B19_ADDR_SHIFT; 74065832Snyan if (baseaddr[n] != iobase) 74165832Snyan return ENXIO; 74265832Snyan 74365832Snyan /* 74465832Snyan * We are now almost sure we have an MB86965 at the given 74565832Snyan * address. So, read EEPROM through it. We have to write 74665832Snyan * into LSI registers to read from EEPROM. I want to avoid it 74765832Snyan * at this stage, but I cannot test the presence of the chip 74865832Snyan * any further without reading EEPROM. FIXME. 74965832Snyan */ 75065832Snyan fe_read_eeprom_jli(sc, eeprom); 75165832Snyan 75265832Snyan /* Make sure that config info in EEPROM and 86965 agree. */ 75365832Snyan if (eeprom[FE_EEPROM_CONF] != fe_inb(sc, FE_BMPR19)) 75465832Snyan return ENXIO; 75565832Snyan 75665832Snyan /* Use 86965 media selection scheme, unless othewise 75765832Snyan specified. It is "AUTO always" and "select with BMPR13." 75865832Snyan This behaviour covers most of the 86965 based board (as 75965832Snyan minimum requirements.) It is backward compatible with 76065832Snyan previous versions, also. */ 76165832Snyan sc->mbitmap = MB_HA; 76265832Snyan sc->defmedia = MB_HA; 76365832Snyan sc->msel = fe_msel_965; 76465832Snyan 76565832Snyan /* Perform board-specific probe, one by one. Note that the 76665832Snyan order of probe is important and should not be changed 76765832Snyan arbitrarily. */ 76865832Snyan if ((irqmap = fe_probe_jli_ati(sc, eeprom)) == NULL 76965832Snyan && (irqmap = fe_probe_jli_rex(sc, eeprom)) == NULL 77065832Snyan && (irqmap = fe_probe_jli_icl(sc, eeprom)) == NULL 77165832Snyan && (irqmap = fe_probe_jli_unk(sc, eeprom)) == NULL) 77265832Snyan return ENXIO; 77365832Snyan 77465832Snyan /* Find the IRQ read from EEPROM. */ 77565832Snyan n = (fe_inb(sc, FE_BMPR19) & FE_B19_IRQ) >> FE_B19_IRQ_SHIFT; 77665832Snyan xirq = irqmap[n]; 77765832Snyan 77865832Snyan /* Try to determine IRQ setting. */ 77965832Snyan error = bus_get_resource(dev, SYS_RES_IRQ, 0, &irq, NULL); 78065832Snyan if (error && xirq == NO_IRQ) { 78165832Snyan /* The device must be configured with an explicit IRQ. */ 78265832Snyan device_printf(dev, "IRQ auto-detection does not work\n"); 78365832Snyan return ENXIO; 78465832Snyan } else if (error && xirq != NO_IRQ) { 78565832Snyan /* Just use the probed IRQ value. */ 78665832Snyan bus_set_resource(dev, SYS_RES_IRQ, 0, xirq, 1); 78765832Snyan } else if (!error && xirq == NO_IRQ) { 78865832Snyan /* No problem. Go ahead. */ 78965832Snyan } else if (irq == xirq) { 79065832Snyan /* Good. Go ahead. */ 79165832Snyan } else { 79265832Snyan /* User must be warned in this case. */ 79365832Snyan sc->stability |= UNSTABLE_IRQ; 79465832Snyan } 79565832Snyan 79665832Snyan /* Setup a hook, which resets te 86965 when the driver is being 79765832Snyan initialized. This may solve a nasty bug. FIXME. */ 79865832Snyan sc->init = fe_init_jli; 79965832Snyan 80065832Snyan return 0; 80165832Snyan} 80265832Snyan 80365832Snyan/* Probe for TDK LAK-AX031, which is an SSi 78Q8377A based board. */ 80465832Snyanstatic int 80565832Snyanfe_probe_ssi(device_t dev) 80665832Snyan{ 80765832Snyan struct fe_softc *sc = device_get_softc(dev); 80865832Snyan u_long iobase, irq; 80965832Snyan 81065832Snyan u_char eeprom [SSI_EEPROM_SIZE]; 81165832Snyan static struct fe_simple_probe_struct probe_table [] = { 81265832Snyan { FE_DLCR2, 0x08, 0x00 }, 81365832Snyan { FE_DLCR4, 0x08, 0x00 }, 81465832Snyan { 0 } 81565832Snyan }; 81665832Snyan 81765832Snyan /* See if the specified I/O address is possible for 78Q8377A. */ 81865832Snyan if (bus_get_resource(dev, SYS_RES_IOPORT, 0, &iobase, NULL) != 0) 81965832Snyan return ENXIO; 82065832Snyan if ((iobase & ~0x3F0) != 0x000) 82165832Snyan return ENXIO; 82265832Snyan 82365832Snyan /* We have 16 registers. */ 82465832Snyan if (fe_alloc_port(dev, 16)) 82565832Snyan return ENXIO; 82665832Snyan 82765832Snyan /* Fill the softc struct with default values. */ 82865832Snyan fe_softc_defaults(sc); 82965832Snyan 83065832Snyan /* See if the card is on its address. */ 83165832Snyan if (!fe_simple_probe(sc, probe_table)) 83265832Snyan return ENXIO; 83365832Snyan 83465832Snyan /* We now have to read the config EEPROM. We should be very 83565832Snyan careful, since doing so destroys a register. (Remember, we 83665832Snyan are not yet sure we have a LAK-AX031 board here.) Don't 83765832Snyan remember to select BMPRs bofore reading EEPROM, since other 83865832Snyan register bank may be selected before the probe() is called. */ 83965832Snyan fe_read_eeprom_ssi(sc, eeprom); 84065832Snyan 84165832Snyan /* Make sure the Ethernet (MAC) station address is of TDK's. */ 842139972Simp if (!fe_valid_Ether_p(eeprom+FE_SSI_EEP_ADDR, 0x008098)) 84365832Snyan return ENXIO; 844147256Sbrooks bcopy(eeprom + FE_SSI_EEP_ADDR, sc->enaddr, ETHER_ADDR_LEN); 84565832Snyan 84665832Snyan /* This looks like a TDK-AX031 board. It requires an explicit 84765832Snyan IRQ setting in config, since we currently don't know how we 84865832Snyan can find the IRQ value assigned by ISA PnP manager. */ 84965832Snyan if (bus_get_resource(dev, SYS_RES_IRQ, 0, &irq, NULL) != 0) { 85065832Snyan fe_irq_failure("LAK-AX031", sc->sc_unit, NO_IRQ, NULL); 85165832Snyan return ENXIO; 85265832Snyan } 85365832Snyan 85465832Snyan /* Fill softc struct accordingly. */ 85565832Snyan sc->type = FE_TYPE_SSI; 85665832Snyan sc->typestr = "LAK-AX031"; 85765832Snyan sc->mbitmap = MB_HT; 85865832Snyan sc->defmedia = MB_HT; 85965832Snyan 86065832Snyan return 0; 86165832Snyan} 86265832Snyan 86365832Snyan/* 86465832Snyan * Probe and initialization for TDK/LANX LAC-AX012/013 boards. 86565832Snyan */ 86665832Snyanstatic int 86765832Snyanfe_probe_lnx(device_t dev) 86865832Snyan{ 86965832Snyan struct fe_softc *sc = device_get_softc(dev); 87065832Snyan u_long iobase, irq; 87165832Snyan 87265832Snyan u_char eeprom [LNX_EEPROM_SIZE]; 87365832Snyan static struct fe_simple_probe_struct probe_table [] = { 87465832Snyan { FE_DLCR2, 0x58, 0x00 }, 87565832Snyan { FE_DLCR4, 0x08, 0x00 }, 87665832Snyan { 0 } 87765832Snyan }; 87865832Snyan 87965832Snyan /* See if the specified I/O address is possible for TDK/LANX boards. */ 88065832Snyan /* 300, 320, 340, and 360 are allowed. */ 88165832Snyan if (bus_get_resource(dev, SYS_RES_IOPORT, 0, &iobase, NULL) != 0) 88265832Snyan return ENXIO; 88365832Snyan if ((iobase & ~0x060) != 0x300) 88465832Snyan return ENXIO; 88565832Snyan 88665832Snyan /* We have 32 registers. */ 88765832Snyan if (fe_alloc_port(dev, 32)) 88865832Snyan return ENXIO; 88965832Snyan 89065832Snyan /* Fill the softc struct with default values. */ 89165832Snyan fe_softc_defaults(sc); 89265832Snyan 89365832Snyan /* See if the card is on its address. */ 89465832Snyan if (!fe_simple_probe(sc, probe_table)) 89565832Snyan return ENXIO; 89665832Snyan 89765832Snyan /* We now have to read the config EEPROM. We should be very 89865832Snyan careful, since doing so destroys a register. (Remember, we 89965832Snyan are not yet sure we have a LAC-AX012/AX013 board here.) */ 90065832Snyan fe_read_eeprom_lnx(sc, eeprom); 90165832Snyan 90265832Snyan /* Make sure the Ethernet (MAC) station address is of TDK/LANX's. */ 903139972Simp if (!fe_valid_Ether_p(eeprom, 0x008098)) 90465832Snyan return ENXIO; 905147256Sbrooks bcopy(eeprom, sc->enaddr, ETHER_ADDR_LEN); 90665832Snyan 90765832Snyan /* This looks like a TDK/LANX board. It requires an 90865832Snyan explicit IRQ setting in config. Make sure we have one, 90965832Snyan determining an appropriate value for the IRQ control 91065832Snyan register. */ 91165832Snyan irq = 0; 91265832Snyan bus_get_resource(dev, SYS_RES_IRQ, 0, &irq, NULL); 91365832Snyan switch (irq) { 91465832Snyan case 3: sc->priv_info = 0x40 | LNX_CLK_LO | LNX_SDA_HI; break; 91565832Snyan case 4: sc->priv_info = 0x20 | LNX_CLK_LO | LNX_SDA_HI; break; 91665832Snyan case 5: sc->priv_info = 0x10 | LNX_CLK_LO | LNX_SDA_HI; break; 91765832Snyan case 9: sc->priv_info = 0x80 | LNX_CLK_LO | LNX_SDA_HI; break; 91865832Snyan default: 91965832Snyan fe_irq_failure("LAC-AX012/AX013", sc->sc_unit, irq, "3/4/5/9"); 92065832Snyan return ENXIO; 92165832Snyan } 92265832Snyan 92365832Snyan /* Fill softc struct accordingly. */ 92465832Snyan sc->type = FE_TYPE_LNX; 92565832Snyan sc->typestr = "LAC-AX012/AX013"; 92665832Snyan sc->init = fe_init_lnx; 92765832Snyan 92865832Snyan return 0; 92965832Snyan} 93065832Snyan 93165832Snyan/* 93265832Snyan * Probe and initialization for Gateway Communications' old cards. 93365832Snyan */ 93465832Snyanstatic int 93565832Snyanfe_probe_gwy(device_t dev) 93665832Snyan{ 93765832Snyan struct fe_softc *sc = device_get_softc(dev); 93865832Snyan u_long iobase, irq; 93965832Snyan 94065832Snyan static struct fe_simple_probe_struct probe_table [] = { 94165832Snyan /* { FE_DLCR2, 0x70, 0x00 }, */ 94265832Snyan { FE_DLCR2, 0x58, 0x00 }, 94365832Snyan { FE_DLCR4, 0x08, 0x00 }, 94465832Snyan { 0 } 94565832Snyan }; 94665832Snyan 94765832Snyan /* See if the specified I/O address is possible for Gateway boards. */ 94865832Snyan if (bus_get_resource(dev, SYS_RES_IOPORT, 0, &iobase, NULL) != 0) 94965832Snyan return ENXIO; 95065832Snyan if ((iobase & ~0x1E0) != 0x200) 95165832Snyan return ENXIO; 95265832Snyan 95365832Snyan /* That's all. The card occupies 32 I/O addresses, as always. */ 95465832Snyan if (fe_alloc_port(dev, 32)) 95565832Snyan return ENXIO; 95665832Snyan 95765832Snyan /* Setup an I/O address mapping table and some others. */ 95865832Snyan fe_softc_defaults(sc); 95965832Snyan 96065832Snyan /* See if the card is on its address. */ 96165832Snyan if (!fe_simple_probe(sc, probe_table)) 96265832Snyan return ENXIO; 96365832Snyan 96465832Snyan /* Get our station address from EEPROM. */ 965147256Sbrooks fe_inblk(sc, 0x18, sc->enaddr, ETHER_ADDR_LEN); 96665832Snyan 96765832Snyan /* Make sure it is Gateway Communication's. */ 968147256Sbrooks if (!fe_valid_Ether_p(sc->enaddr, 0x000061)) 96965832Snyan return ENXIO; 97065832Snyan 97165832Snyan /* Gateway's board requires an explicit IRQ to work, since it 97265832Snyan is not possible to probe the setting of jumpers. */ 97365832Snyan if (bus_get_resource(dev, SYS_RES_IRQ, 0, &irq, NULL) != 0) { 97465832Snyan fe_irq_failure("Gateway Ethernet", sc->sc_unit, NO_IRQ, NULL); 97565832Snyan return ENXIO; 97665832Snyan } 97765832Snyan 97865832Snyan /* Fill softc struct accordingly. */ 97965832Snyan sc->type = FE_TYPE_GWY; 98065832Snyan sc->typestr = "Gateway Ethernet (Fujitsu chipset)"; 98165832Snyan 98265832Snyan return 0; 98365832Snyan} 98465832Snyan 98565832Snyan/* Probe and initialization for Ungermann-Bass Network 98665832Snyan K.K. "Access/PC" boards. */ 98765832Snyanstatic int 98865832Snyanfe_probe_ubn(device_t dev) 98965832Snyan{ 99065832Snyan struct fe_softc *sc = device_get_softc(dev); 99165832Snyan u_long iobase, irq; 99265832Snyan#if 0 99365832Snyan u_char sum; 99465832Snyan#endif 99565832Snyan static struct fe_simple_probe_struct const probe_table [] = { 99665832Snyan { FE_DLCR2, 0x58, 0x00 }, 99765832Snyan { FE_DLCR4, 0x08, 0x00 }, 99865832Snyan { 0 } 99965832Snyan }; 100065832Snyan 100165832Snyan /* See if the specified I/O address is possible for AccessPC/ISA. */ 100265832Snyan if (bus_get_resource(dev, SYS_RES_IOPORT, 0, &iobase, NULL) != 0) 100365832Snyan return ENXIO; 100465832Snyan if ((iobase & ~0x0E0) != 0x300) 100565832Snyan return ENXIO; 100665832Snyan 100765832Snyan /* We have 32 registers. */ 100865832Snyan if (fe_alloc_port(dev, 32)) 100965832Snyan return ENXIO; 101065832Snyan 101165832Snyan /* Setup an I/O address mapping table and some others. */ 101265832Snyan fe_softc_defaults(sc); 101365832Snyan 101465832Snyan /* Simple probe. */ 101565832Snyan if (!fe_simple_probe(sc, probe_table)) 101665832Snyan return ENXIO; 101765832Snyan 101865832Snyan /* Get our station address form ID ROM and make sure it is UBN's. */ 1019147256Sbrooks fe_inblk(sc, 0x18, sc->enaddr, ETHER_ADDR_LEN); 1020147256Sbrooks if (!fe_valid_Ether_p(sc->enaddr, 0x00DD01)) 102165832Snyan return ENXIO; 102265832Snyan#if 0 102365832Snyan /* Calculate checksum. */ 102465832Snyan sum = fe_inb(sc, 0x1e); 102565832Snyan for (i = 0; i < ETHER_ADDR_LEN; i++) { 1026147256Sbrooks sum ^= sc->enaddr[i]; 102765832Snyan } 102865832Snyan if (sum != 0) 102965832Snyan return ENXIO; 103065832Snyan#endif 103165832Snyan /* This looks like an AccessPC/ISA board. It requires an 103265832Snyan explicit IRQ setting in config. Make sure we have one, 103365832Snyan determining an appropriate value for the IRQ control 103465832Snyan register. */ 103565832Snyan irq = 0; 103665832Snyan bus_get_resource(dev, SYS_RES_IRQ, 0, &irq, NULL); 103765832Snyan switch (irq) { 103865832Snyan case 3: sc->priv_info = 0x02; break; 103965832Snyan case 4: sc->priv_info = 0x04; break; 104065832Snyan case 5: sc->priv_info = 0x08; break; 104165832Snyan case 10: sc->priv_info = 0x10; break; 104265832Snyan default: 104365832Snyan fe_irq_failure("Access/PC", sc->sc_unit, irq, "3/4/5/10"); 104465832Snyan return ENXIO; 104565832Snyan } 104665832Snyan 104765832Snyan /* Fill softc struct accordingly. */ 104865832Snyan sc->type = FE_TYPE_UBN; 104965832Snyan sc->typestr = "Access/PC"; 105065832Snyan sc->init = fe_init_ubn; 105165832Snyan 105265832Snyan return 0; 105365832Snyan} 1054