Esempio n. 1
0
/* JLI sub-probe for RATOC REX-5586/5587.  */
static u_short const *
fe_probe_jli_rex(struct fe_softc * sc, u_char const * eeprom)
{
	int i;
	static u_short const irqmap_rex [4] = { 3, 4, 5, NO_IRQ };

	/* Make sure the EEPROM contains RATOC's config pattern.  */
	if (eeprom[1] != eeprom[0]) return NULL;
	for (i = 8; i < 32; i++) if (eeprom[i] != 0xFF) return NULL;

	/* Get our station address from EEPROM.  Note that RATOC
	   stores it "byte-swapped" in each word.  (I don't know why.)
	   So, we just can't use bcopy().*/
	sc->enaddr[0] = eeprom[3];
	sc->enaddr[1] = eeprom[2];
	sc->enaddr[2] = eeprom[5];
	sc->enaddr[3] = eeprom[4];
	sc->enaddr[4] = eeprom[7];
	sc->enaddr[5] = eeprom[6];

	/* Make sure the EEPROM contains RATOC's station address.  */
	if (!fe_valid_Ether_p(sc->enaddr, 0x00C0D0))
		return NULL;

	/* I don't know any sub-model identification.  */
	sc->type = FE_TYPE_JLI;
	sc->typestr = "REX-5586/5587";

	/* Returns the IRQ for the RATOC board.  */
	return irqmap_rex;
}
Esempio n. 2
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;
}
Esempio n. 3
0
/* Probe for TDK LAK-AX031, which is an SSi 78Q8377A based board.  */
static int
fe_probe_ssi(device_t dev)
{
	struct fe_softc *sc = device_get_softc(dev);
	u_long iobase, irq;

	u_char eeprom [SSI_EEPROM_SIZE];
	static struct fe_simple_probe_struct probe_table [] = {
		{ FE_DLCR2, 0x08, 0x00 },
		{ FE_DLCR4, 0x08, 0x00 },
		{ 0 }
	};

	/* See if the specified I/O address is possible for 78Q8377A.  */
	if (bus_get_resource(dev, SYS_RES_IOPORT, 0, &iobase, NULL) != 0)
		return ENXIO;
	if ((iobase & ~0x3F0) != 0x000)
                return ENXIO;

	/* We have 16 registers.  */
	if (fe_alloc_port(dev, 16))
		return ENXIO;

	/* Fill the softc struct with default values.  */
	fe_softc_defaults(sc);

	/* See if the card is on its address.  */
	if (!fe_simple_probe(sc, probe_table))
		return ENXIO;

	/* We now have to read the config EEPROM.  We should be very
           careful, since doing so destroys a register.  (Remember, we
           are not yet sure we have a LAK-AX031 board here.)  Don't
           remember to select BMPRs bofore reading EEPROM, since other
           register bank may be selected before the probe() is called.  */
	fe_read_eeprom_ssi(sc, eeprom);

	/* Make sure the Ethernet (MAC) station address is of TDK's.  */
	if (!fe_valid_Ether_p(eeprom+FE_SSI_EEP_ADDR, 0x008098))
		return ENXIO;
	bcopy(eeprom + FE_SSI_EEP_ADDR, sc->enaddr, ETHER_ADDR_LEN);

	/* This looks like a TDK-AX031 board.  It requires an explicit
	   IRQ setting in config, since we currently don't know how we
	   can find the IRQ value assigned by ISA PnP manager.  */
	if (bus_get_resource(dev, SYS_RES_IRQ, 0, &irq, NULL) != 0) {
		fe_irq_failure("LAK-AX031", sc->sc_unit, NO_IRQ, NULL);
		return ENXIO;
	}

	/* Fill softc struct accordingly.  */
	sc->type = FE_TYPE_SSI;
	sc->typestr = "LAK-AX031";
	sc->mbitmap = MB_HT;
	sc->defmedia = MB_HT;

	return 0;
}
Esempio n. 4
0
/*
 * Probe and initialization for TDK/CONTEC PCMCIA Ethernet interface.
 * by MASUI Kenji <*****@*****.**>
 *
 * (Contec uses TDK Ethernet chip -- hosokawa)
 *
 * This version of fe_probe_tdk has been rewrote to handle
 * *generic* PC Card implementation of Fujitsu MB8696x family.  The
 * name _tdk is just for a historical reason. :-)
 */
static int
fe_probe_tdk (device_t dev, const struct fe_pccard_product *pp)
{
    struct fe_softc *sc = device_get_softc(dev);

    static struct fe_simple_probe_struct probe_table [] = {
        { FE_DLCR2, 0x10, 0x00 },
        { FE_DLCR4, 0x08, 0x00 },
        /*		{ FE_DLCR5, 0x80, 0x00 },	Does not work well.  */
        { 0 }
    };


    /* C-NET(PC)C occupies 16 I/O addresses. */
    if (fe_alloc_port(dev, 16))
        return ENXIO;

    /* Fill the softc struct with default values.  */
    fe_softc_defaults(sc);

    /*
     * See if C-NET(PC)C is on its address.
     */
    if (!fe_simple_probe(sc, probe_table))
        return ENXIO;

    /* Determine the card type.  */
    sc->type = FE_TYPE_TDK;
    sc->typestr = "Generic MB8696x/78Q837x Ethernet (PCMCIA)";

    pccard_get_ether(dev, sc->enaddr);

    /* Make sure we got a valid station address.  */
    if (!fe_valid_Ether_p(sc->enaddr, 0)) {
        pccard_cis_scan(dev, fe_pccard_xircom_mac, sc->enaddr);
    }

    /* Make sure we got a valid station address.  */
    if (!fe_valid_Ether_p(sc->enaddr, 0))
        return ENXIO;

    return 0;
}
Esempio n. 5
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;
}
Esempio n. 6
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;
}
Esempio n. 7
0
/* JLI sub-probe for Unknown board.  */
static u_short const *
fe_probe_jli_unk(struct fe_softc * sc, u_char const * eeprom)
{
	int i, n, romsize;
	static u_short const irqmap [4] = { NO_IRQ, NO_IRQ, NO_IRQ, NO_IRQ };

	/* The generic JLI probe considered this board has an 86965
	   in JLI mode, but any other board-specific routines could
	   not find the matching implementation.  So, we "guess" the
	   location by looking for a bit pattern which looks like a
	   MAC address.  */

	/* Determine how large the EEPROM is.  */
	for (romsize = JLI_EEPROM_SIZE/2; romsize > 16; romsize >>= 1) {
		for (i = 0; i < romsize; i++) {
			if (eeprom[i] != eeprom[i+romsize])
				break;
		}
		if (i < romsize)
			break;
	}
	romsize <<= 1;

	/* Look for a bit pattern which looks like a MAC address.  */
	for (n = 2; n <= romsize - ETHER_ADDR_LEN; n += 2) {
		if (!fe_valid_Ether_p(eeprom + n, 0x000000))
			continue;
	}

	/* If no reasonable address was found, we can't go further.  */
	if (n > romsize - ETHER_ADDR_LEN)
		return NULL;

	/* Extract our (guessed) station address.  */
	bcopy(eeprom+n, sc->enaddr, ETHER_ADDR_LEN);

	/* We are not sure what type of board it is... */
	sc->type = FE_TYPE_JLI;
	sc->typestr = "(unknown JLI)";
	sc->stability |= UNSTABLE_TYPE | UNSTABLE_MAC;

	/* Returns the totally unknown IRQ mapping table.  */
	return irqmap;
}
Esempio n. 8
0
/* JLI sub-probe for Allied-Telesis RE1000Plus/ME1500 series.  */
static u_short const *
fe_probe_jli_re1000p(struct fe_softc * sc, u_char const * eeprom)
{
	int i;
	static u_short const irqmaps_re1000p [4] = { 3, 5, 6, 12 };

	/* Make sure the EEPROM contains Allied-Telesis bit pattern.  */
	if (eeprom[1] != 0xFF) return NULL;
	for (i =  2; i <  8; i++) if (eeprom[i] != 0xFF) return NULL;
	for (i = 14; i < 24; i++) if (eeprom[i] != 0xFF) return NULL;

	/* Get our station address from EEPROM, and make sure the
           EEPROM contains Allied-Telesis's address.  */
	bcopy(eeprom + 8, sc->enaddr, ETHER_ADDR_LEN);
	if (!fe_valid_Ether_p(sc->enaddr, 0x0000F4))
		return NULL;

	/* I don't know any sub-model identification.  */
	sc->typestr = "RE1000Plus/ME1500";

	/* Returns the IRQ table for the RE1000Plus.  */
	return irqmaps_re1000p;
}
Esempio n. 9
0
static u_short const *
fe_probe_jli_icl(struct fe_softc * sc, u_char const * eeprom)
{
	int i;
	u_short defmedia;
	u_char d6;
	static u_short const irqmap_icl [4] = { 9, 10, 5, 15 };

	/* Make sure the EEPROM contains ICL bit pattern.  */
	for (i = 24; i < 39; i++) {
	    if (eeprom[i] != 0x20 && (eeprom[i] & 0xF0) != 0x30) return NULL;
	}
	for (i = 112; i < 122; i++) {
	    if (eeprom[i] != 0x20 && (eeprom[i] & 0xF0) != 0x30) return NULL;
	}

	/* Make sure the EEPROM contains ICL's permanent station
           address.  If it isn't, probably this board is not an
           ICL's.  */
	if (!fe_valid_Ether_p(eeprom+122, 0x00004B))
		return NULL;

	/* Check if the "configured" Ethernet address in the EEPROM is
	   valid.  Use it if it is, or use the "permanent" address instead.  */
	if (fe_valid_Ether_p(eeprom+4, 0x020000)) {
		/* The configured address is valid.  Use it.  */
		bcopy(eeprom+4, sc->enaddr, ETHER_ADDR_LEN);
	} else {
		/* The configured address is invalid.  Use permanent.  */
		bcopy(eeprom+122, sc->enaddr, ETHER_ADDR_LEN);
	}

	/* Determine model and supported media.  */
	switch (eeprom[0x5E]) {
	    case 0:
	        sc->typestr = "EtherTeam16i/COMBO";
	        sc->mbitmap = MB_HA | MB_HT | MB_H5 | MB_H2;
		break;
	    case 1:
		sc->typestr = "EtherTeam16i/TP";
	        sc->mbitmap = MB_HT;
		break;
	    case 2:
		sc->typestr = "EtherTeam16i/ErgoPro";
		sc->mbitmap = MB_HA | MB_HT | MB_H5;
		break;
	    case 4:
		sc->typestr = "EtherTeam16i/DUO";
		sc->mbitmap = MB_HA | MB_HT | MB_H2;
		break;
	    default:
		sc->typestr = "EtherTeam16i";
		sc->stability |= UNSTABLE_TYPE;
		if (bootverbose) {
		    printf("fe%d: unknown model code %02x for EtherTeam16i\n",
			   sc->sc_unit, eeprom[0x5E]);
		}
		break;
	}
	sc->type = FE_TYPE_JLI;

	/* I'm not sure the following msel hook is required by all
           models or COMBO only...  FIXME.  */
	sc->msel = fe_msel_icl;

	/* Make the configured media selection the default media.  */
	switch (eeprom[0x28]) {
	    case 0: defmedia = MB_HA; break;
	    case 1: defmedia = MB_H5; break;
	    case 2: defmedia = MB_HT; break;
	    case 3: defmedia = MB_H2; break;
	    default: 
		if (bootverbose) {
			printf("fe%d: unknown default media: %02x\n",
			       sc->sc_unit, eeprom[0x28]);
		}
		defmedia = MB_HA;
		break;
	}

	/* Make sure the default media is compatible with the
	   supported media.  */
	if ((defmedia & sc->mbitmap) == 0) {
		if (bootverbose) {
			printf("fe%d: default media adjusted\n", sc->sc_unit);
		}
		defmedia = sc->mbitmap;
	}

	/* Keep the determined default media.  */
	sc->defmedia = defmedia;

	/* ICL has "fat" models.  We have to program 86965 to properly
	   reflect the hardware.  */
	d6 = sc->proto_dlcr6 & ~(FE_D6_BUFSIZ | FE_D6_BBW);
	switch ((eeprom[0x61] << 8) | eeprom[0x60]) {
	    case 0x2008: d6 |= FE_D6_BUFSIZ_32KB | FE_D6_BBW_BYTE; break;
	    case 0x4010: d6 |= FE_D6_BUFSIZ_64KB | FE_D6_BBW_WORD; break;
	    default:
		/* We can't support it, since we don't know which bits
		   to set in DLCR6.  */
		printf("fe%d: unknown SRAM config for ICL\n", sc->sc_unit);
		return NULL;
	}
	sc->proto_dlcr6 = d6;

	/* Returns the IRQ table for the ICL board.  */
	return irqmap_icl;
}
Esempio n. 10
0
/* JLI sub-probe for Allied-Telesyn/Allied-Telesis AT1700/RE2000 series.  */
static u_short const *
fe_probe_jli_ati(struct fe_softc * sc, u_char const * eeprom)
{
	int i;
	static u_short const irqmaps_ati [4][4] =
	{
		{  3,  4,  5,  9 },
		{ 10, 11, 12, 15 },
		{  3, 11,  5, 15 },
		{ 10, 11, 14, 15 },
	};

	/* Make sure the EEPROM contains Allied-Telesis/Allied-Telesyn
	   bit pattern.  */
	if (eeprom[1] != 0x00) return NULL;
	for (i =  2; i <  8; i++) if (eeprom[i] != 0xFF) return NULL;
	for (i = 14; i < 24; i++) if (eeprom[i] != 0xFF) return NULL;

	/* Get our station address from EEPROM, and make sure the
           EEPROM contains ATI's address.  */
	bcopy(eeprom + 8, sc->enaddr, ETHER_ADDR_LEN);
	if (!fe_valid_Ether_p(sc->enaddr, 0x0000F4))
		return NULL;

	/*
	 * The following model identification codes are stolen
	 * from the NetBSD port of the fe driver.  My reviewers
	 * suggested minor revision.
	 */

	/* Determine the card type.  */
	switch (eeprom[FE_ATI_EEP_MODEL]) {
	  case FE_ATI_MODEL_AT1700T:
		sc->typestr = "AT-1700T/RE2001";
		sc->mbitmap = MB_HT;
		sc->defmedia = MB_HT;
		break;
	  case FE_ATI_MODEL_AT1700BT:
		sc->typestr = "AT-1700BT/RE2003";
		sc->mbitmap = MB_HA | MB_HT | MB_H2;
		break;
	  case FE_ATI_MODEL_AT1700FT:
		sc->typestr = "AT-1700FT/RE2009";
		sc->mbitmap = MB_HA | MB_HT | MB_HF;
		break;
	  case FE_ATI_MODEL_AT1700AT:
		sc->typestr = "AT-1700AT/RE2005";
		sc->mbitmap = MB_HA | MB_HT | MB_H5;
		break;
	  default:
		sc->typestr = "unknown AT-1700/RE2000";
		sc->stability |= UNSTABLE_TYPE | UNSTABLE_IRQ;
		break;
	}
	sc->type = FE_TYPE_JLI;

#if 0
	/* Should we extract default media from eeprom?  Linux driver
	   for AT1700 does it, although previous releases of FreeBSD
	   don't.  FIXME.  */
	/* Determine the default media selection from the config
           EEPROM.  The byte at offset EEP_MEDIA is believed to
           contain BMPR13 value to be set.  We just ignore STP bit or
           squelch bit, since we don't support those.  (It is
           intentional.)  */
	switch (eeprom[FE_ATI_EEP_MEDIA] & FE_B13_PORT) {
	    case FE_B13_AUTO:
		sc->defmedia = MB_HA;
		break;
	    case FE_B13_TP:
		sc->defmedia = MB_HT;
		break;
	    case FE_B13_AUI:
		sc->defmedia = sc->mbitmap & (MB_H2|MB_H5|MB_H5); /*XXX*/
		break;
	    default:	    
		sc->defmedia = MB_HA;
		break;
	}

	/* Make sure the default media is compatible with the supported
	   ones.  */
	if ((sc->defmedia & sc->mbitmap) == 0) {
		if (sc->defmedia == MB_HA) {
			sc->defmedia = MB_HT;
		} else {
			sc->defmedia = MB_HA;
		}
	}
#endif	

	/*
	 * Try to determine IRQ settings.
	 * Different models use different ranges of IRQs.
	 */
	switch ((eeprom[FE_ATI_EEP_REVISION] & 0xf0)
	       |(eeprom[FE_ATI_EEP_MAGIC]    & 0x04)) {
	    case 0x30: case 0x34: return irqmaps_ati[3];
	    case 0x10: case 0x14:
	    case 0x50: case 0x54: return irqmaps_ati[2];
	    case 0x44: case 0x64: return irqmaps_ati[1];
	    default:		  return irqmaps_ati[0];
	}
}
Esempio n. 11
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;
}
Esempio n. 12
0
/*
 * Probe for TDK LAC-98012/013/025/9N011 - parhaps.
 */
static int
fe_probe_lnx(device_t dev)
{
	struct fe_softc *sc = device_get_softc(dev);

	rman_res_t iobase, irq;
	u_char eeprom [LNX_EEPROM_SIZE];

	static struct fe_simple_probe_struct probe_table [] = {
		{ FE_DLCR2, 0x58, 0x00 },
		{ FE_DLCR4, 0x08, 0x00 },
		{ 0 }
	};

	/* See if the specified I/O address is possible for TDK/LANX boards. */
	/* 0D0, 4D0, 8D0, and CD0 are allowed.  */
	if (bus_get_resource(dev, SYS_RES_IOPORT, 0, &iobase, NULL) != 0)
		return ENXIO;
	if ((iobase & ~0xC00) != 0xD0)
		return ENXIO;

	if (fe98_alloc_port(dev, FE_TYPE_LNX))
		return ENXIO;

	/* Fill the softc struct with default values.  */
	fe_softc_defaults(sc);

	/* See if the card is on its address.  */
	if (!fe_simple_probe(sc, probe_table))
		return ENXIO;

	/* We now have to read the config EEPROM.  We should be very
           careful, since doing so destroys a register.  (Remember, we
           are not yet sure we have a LAC-98012/98013 board here.)  */
	fe_read_eeprom_lnx(sc, eeprom);

	/* Make sure the Ethernet (MAC) station address is of TDK/LANX's.  */
	if (!fe_valid_Ether_p(eeprom, 0x008098))
		return ENXIO;
	bcopy(eeprom, sc->enaddr, ETHER_ADDR_LEN);

	/* Setup the board type.  */
	sc->typestr = "LAC-98012/98013";

	/* This looks like a TDK/LANX board.  It requires an
	   explicit IRQ setting in config.  Make sure we have one,
	   determining an appropriate value for the IRQ control
	   register.  */
	irq = 0;
	if (bus_get_resource(dev, SYS_RES_IRQ, 0, &irq, NULL) != 0)
		return ENXIO;
	switch (irq) {
	case 3 : sc->priv_info = 0x10 | LNX_CLK_LO | LNX_SDA_HI; break;
	case 5 : sc->priv_info = 0x20 | LNX_CLK_LO | LNX_SDA_HI; break;
	case 6 : sc->priv_info = 0x40 | LNX_CLK_LO | LNX_SDA_HI; break;
	case 12: sc->priv_info = 0x80 | LNX_CLK_LO | LNX_SDA_HI; break;
	default:
		fe_irq_failure(sc->typestr, sc->sc_unit, irq, "3/5/6/12");
		return ENXIO;
	}

	/* LAC-98's system bus width is 8-bit.  */ 
	sc->proto_dlcr6 = FE_D6_BUFSIZ_32KB | FE_D6_TXBSIZ_2x2KB
			| FE_D6_BBW_BYTE | FE_D6_SBW_BYTE | FE_D6_SRAM_150ns;

	/* Setup hooks.  We need a special initialization procedure.  */
	sc->init = fe_init_lnx;

	return 0;
}
Esempio n. 13
0
/*
 * Probe for Contec C-NET(98)P2 series.
 * (Logitec LAN-98TP/LAN-98T25P - parhaps)
 */
static int
fe_probe_ssi(device_t dev)
{
	struct fe_softc *sc = device_get_softc(dev);
	rman_res_t iobase, irq;

	u_char eeprom [SSI_EEPROM_SIZE];
	static struct fe_simple_probe_struct probe_table [] = {
		{ FE_DLCR2, 0x08, 0x00 },
		{ FE_DLCR4, 0x08, 0x00 },
		{ 0 }
	};
	static u_short const irqmap[] = {
		/*                        INT0          INT1    INT2       */
		NO_IRQ, NO_IRQ, NO_IRQ,      3, NO_IRQ,    5,      6, NO_IRQ,
		NO_IRQ,      9,     10, NO_IRQ,     12,   13, NO_IRQ, NO_IRQ,
		/*        INT3   INT41            INT5  INT6               */
	};

	/* See if the specified I/O address is possible for 78Q8377A.  */
	/* [0-D]3D0 are allowed.  */
	if (bus_get_resource(dev, SYS_RES_IOPORT, 0, &iobase, NULL) != 0)
		return ENXIO;
	if ((iobase & 0xFFF) != 0x3D0)
		return ENXIO;
		
	if (fe98_alloc_port(dev, FE_TYPE_SSI))
		return ENXIO;

	/* Fill the softc struct with default values.  */
	fe_softc_defaults(sc);

	/* See if the card is on its address.  */
	if (!fe_simple_probe(sc, probe_table))
		return ENXIO;

	/* We now have to read the config EEPROM.  We should be very
           careful, since doing so destroys a register.  (Remember, we
           are not yet sure we have a C-NET(98)P2 board here.)  Don't
           remember to select BMPRs bofore reading EEPROM, since other
           register bank may be selected before the probe() is called.  */
	fe_read_eeprom_ssi(sc, eeprom);

	/* Make sure the Ethernet (MAC) station address is of Contec's.  */
	if (!fe_valid_Ether_p(eeprom + FE_SSI_EEP_ADDR, 0x00804C))
		return ENXIO;
	bcopy(eeprom + FE_SSI_EEP_ADDR, sc->enaddr, ETHER_ADDR_LEN);

	/* Setup the board type.  */
        sc->typestr = "C-NET(98)P2";

	/* Non-PnP mode, set static resource from eeprom. */
	if (!isa_get_vendorid(dev)) {
		/* Get IRQ configuration from EEPROM.  */
		irq = irqmap[eeprom[FE_SSI_EEP_IRQ]];
		if (irq == NO_IRQ) {
			fe_irq_failure(sc->typestr, sc->sc_unit, irq,
				       "3/5/6/9/10/12/13");
			return ENXIO;
		}
		bus_set_resource(dev, SYS_RES_IRQ, 0, irq, 1);
	}

	/* Get Duplex-mode configuration from EEPROM.  */
	sc->proto_dlcr4 |= (eeprom[FE_SSI_EEP_DUPLEX] & FE_D4_DSC);

	/* Fill softc struct accordingly.  */
	sc->mbitmap = MB_HT;
	sc->defmedia = MB_HT;

	return 0;
}
Esempio n. 14
0
static int
fe_probe_cnet9ne (device_t dev)
{
	struct fe_softc *sc = device_get_softc(dev);
	rman_res_t iobase, irq;

	static struct fe_simple_probe_struct probe_table [] = {
		{ FE_DLCR2, 0x58, 0x00 },
		{ FE_DLCR4, 0x08, 0x00 },
		{ 0 }
	};

	/* See if the specified I/O address is possible for C-NET(9N)E.  */
	if (bus_get_resource(dev, SYS_RES_IOPORT, 0, &iobase, NULL) != 0)
		return ENXIO;
	if (iobase != 0x73D0)
		return ENXIO;

	if (fe98_alloc_port(dev, FE_TYPE_CNET9NE))
		return ENXIO;

	/* Fill the softc struct with default values.  */
	fe_softc_defaults(sc);

	/* See if the card is on its address.  */
	if (!fe_simple_probe(sc, probe_table))
		return ENXIO;

	/* Get our station address from EEPROM.  */
	fe_inblk(sc, 0x18, sc->enaddr, ETHER_ADDR_LEN);

	/* Make sure it is Contec's.  */
	if (!fe_valid_Ether_p(sc->enaddr, 0x00804C))
		return ENXIO;

	/* Determine the card type.  */
	if (sc->enaddr[3] == 0x06) {
		sc->typestr = "C-NET(9N)C";

		/* We seems to need our own IDENT bits...  FIXME.  */
		sc->proto_dlcr7 = FE_D7_BYTSWP_LH | FE_D7_IDENT_NICE;

		/* C-NET(9N)C requires an explicit IRQ to work.  */
		if (bus_get_resource(dev, SYS_RES_IRQ, 0, &irq, NULL) != 0) {
			fe_irq_failure(sc->typestr, sc->sc_unit, NO_IRQ, NULL);
			return ENXIO;
		}
	} else {
		sc->typestr = "C-NET(9N)E";

		/* C-NET(9N)E works only IRQ5.  */
		if (bus_get_resource(dev, SYS_RES_IRQ, 0, &irq, NULL) != 0)
			return ENXIO;
		if (irq != 5) {
			fe_irq_failure(sc->typestr, sc->sc_unit, irq, "5");
			return ENXIO;
		}

		/* We need an init hook to initialize ASIC before we start.  */
		sc->init = fe_init_cnet9ne;
	}

	/* C-NET(9N)E has 64KB SRAM.  */
	sc->proto_dlcr6 = FE_D6_BUFSIZ_64KB | FE_D6_TXBSIZ_2x4KB
			| FE_D6_BBW_WORD | FE_D6_SBW_WORD | FE_D6_SRAM;

	return 0;
}
Esempio n. 15
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;
}
Esempio n. 16
0
/*
 * Probe and initialization for TDK/LANX LAC-AX012/013 boards.
 */
static int
fe_probe_lnx(device_t dev)
{
	struct fe_softc *sc = device_get_softc(dev);
	u_long iobase, irq;

	u_char eeprom [LNX_EEPROM_SIZE];
	static struct fe_simple_probe_struct probe_table [] = {
		{ FE_DLCR2, 0x58, 0x00 },
		{ FE_DLCR4, 0x08, 0x00 },
		{ 0 }
	};

	/* See if the specified I/O address is possible for TDK/LANX boards. */
	/* 300, 320, 340, and 360 are allowed.  */
	if (bus_get_resource(dev, SYS_RES_IOPORT, 0, &iobase, NULL) != 0)
		return ENXIO;
	if ((iobase & ~0x060) != 0x300)
                return ENXIO;

	/* We have 32 registers.  */
	if (fe_alloc_port(dev, 32))
		return ENXIO;

	/* Fill the softc struct with default values.  */
	fe_softc_defaults(sc);

	/* See if the card is on its address.  */
	if (!fe_simple_probe(sc, probe_table))
		return ENXIO;

	/* We now have to read the config EEPROM.  We should be very
           careful, since doing so destroys a register.  (Remember, we
           are not yet sure we have a LAC-AX012/AX013 board here.)  */
	fe_read_eeprom_lnx(sc, eeprom);

	/* Make sure the Ethernet (MAC) station address is of TDK/LANX's.  */
	if (!fe_valid_Ether_p(eeprom, 0x008098))
		return ENXIO;
	bcopy(eeprom, sc->enaddr, ETHER_ADDR_LEN);

	/* This looks like a TDK/LANX board.  It requires an
	   explicit IRQ setting in config.  Make sure we have one,
	   determining an appropriate value for the IRQ control
	   register.  */
	irq = 0;
	bus_get_resource(dev, SYS_RES_IRQ, 0, &irq, NULL);
	switch (irq) {
	case 3: sc->priv_info = 0x40 | LNX_CLK_LO | LNX_SDA_HI; break;
	case 4: sc->priv_info = 0x20 | LNX_CLK_LO | LNX_SDA_HI; break;
	case 5: sc->priv_info = 0x10 | LNX_CLK_LO | LNX_SDA_HI; break;
	case 9: sc->priv_info = 0x80 | LNX_CLK_LO | LNX_SDA_HI; break;
	default:
		fe_irq_failure("LAC-AX012/AX013", sc->sc_unit, irq, "3/4/5/9");
		return ENXIO;
	}

	/* Fill softc struct accordingly.  */
	sc->type = FE_TYPE_LNX;
	sc->typestr = "LAC-AX012/AX013";
	sc->init = fe_init_lnx;

	return 0;
}
Esempio n. 17
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;
}
Esempio n. 18
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;
}
Esempio n. 19
0
/*
 * Probe for RATOC REX-9880/81/82/83 series.
 */
static int
fe_probe_rex(device_t dev)
{
	struct fe_softc *sc = device_get_softc(dev);

	int i;
	rman_res_t iobase, irq;
	u_char eeprom [REX_EEPROM_SIZE];

	static struct fe_simple_probe_struct probe_table [] = {
		{ FE_DLCR2, 0x58, 0x00 },
		{ FE_DLCR4, 0x08, 0x00 },
		{ 0 }
	};

	/* See if the specified I/O address is possible for REX-9880.  */
	/* 6[46CE]D0 are allowed.  */ 
	if (bus_get_resource(dev, SYS_RES_IOPORT, 0, &iobase, NULL) != 0)
		return ENXIO;
	if ((iobase & ~0xA00) != 0x64D0)
		return ENXIO;

	if (fe98_alloc_port(dev, FE_TYPE_REX))
		return ENXIO;

	/* Fill the softc struct with default values.  */
	fe_softc_defaults(sc);

	/* See if the card is on its address.  */
	if (!fe_simple_probe(sc, probe_table))
		return ENXIO;

	/* We now have to read the config EEPROM.  We should be very
           careful, since doing so destroys a register.  (Remember, we
           are not yet sure we have a REX-9880 board here.)  */
	fe_read_eeprom_rex(sc, eeprom);
	for (i = 0; i < ETHER_ADDR_LEN; i++)
		sc->enaddr[i] = eeprom[7 - i];

	/* Make sure it is RATOC's.  */
	if (!fe_valid_Ether_p(sc->enaddr, 0x00C0D0) &&
	    !fe_valid_Ether_p(sc->enaddr, 0x00803D))
		return 0;

	/* Setup the board type.  */
	sc->typestr = "REX-9880/9883";

	/* This looks like a REX-9880 board.  It requires an
	   explicit IRQ setting in config.  Make sure we have one,
	   determining an appropriate value for the IRQ control
	   register.  */
	irq = 0;
	bus_get_resource(dev, SYS_RES_IRQ, 0, &irq, NULL);
	switch (irq) {
	case 3:  sc->priv_info = 0x10; break;
	case 5:  sc->priv_info = 0x20; break;
	case 6:  sc->priv_info = 0x40; break;
	case 12: sc->priv_info = 0x80; break;
	default:
		fe_irq_failure(sc->typestr, sc->sc_unit, irq, "3/5/6/12");
		return ENXIO;
	}

	/* Setup hooks.  We need a special initialization procedure.  */
	sc->init = fe_init_rex;

	/* REX-9880 has 64KB SRAM.  */
	sc->proto_dlcr6 = FE_D6_BUFSIZ_64KB | FE_D6_TXBSIZ_2x4KB
			| FE_D6_BBW_WORD | FE_D6_SBW_WORD | FE_D6_SRAM;
#if 1
	sc->proto_dlcr7 |= FE_D7_EOPPOL;	/* XXX */
#endif

	return 0;
}