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