コード例 #1
0
ファイル: if_fe_isa.c プロジェクト: AhmadTux/freebsd
static void
fe_init_fmv(struct fe_softc *sc)
{
	/* Initialize ASIC.  */
	fe_outb(sc, FE_FMV3, 0);
	fe_outb(sc, FE_FMV10, 0);

#if 0
	/* "Refresh" hardware configuration.  FIXME.  */
	fe_outb(sc, FE_FMV2, fe_inb(sc, FE_FMV2));
#endif

	/* Turn the "master interrupt control" flag of ASIC on.  */
	fe_outb(sc, FE_FMV3, FE_FMV3_IRQENB);
}
コード例 #2
0
ファイル: if_fe_cbus.c プロジェクト: 2asoft/freebsd
static void
fe_read_eeprom_rex(struct fe_softc *sc, u_char *data)
{
	int i;
	u_char bit, val;
	u_char save16;

	save16 = fe_inb(sc, 0x10);

	/* Issue a start condition.  */
	val = fe_inb(sc, 0x10) & 0xf0;
	fe_outb(sc, 0x10, val);

	(void) fe_inb(sc, 0x10);
	(void) fe_inb(sc, 0x10);
	(void) fe_inb(sc, 0x10);
	(void) fe_inb(sc, 0x10);

	/* Read bytes from EEPROM.  */
	for (i = 0; i < REX_EEPROM_SIZE; i++) {
		/* Read a byte and store it into the buffer.  */
		val = 0x00;
		for (bit = 0x01; bit != 0x00; bit <<= 1)
			if (fe_inb(sc, 0x10) & REX_DAT)
				val |= bit;
		*data++ = val;
	}

	fe_outb(sc, 0x10, save16);

#if 1
	/* Report what we got.  */
	if (bootverbose) {
		data -= REX_EEPROM_SIZE;
		for (i = 0; i < REX_EEPROM_SIZE; i += 16) {
			printf("fe%d: EEPROM(REX):%3x: %16D\n",
			       sc->sc_unit, i, data + i, " ");
		}
	}
#endif
}
コード例 #3
0
ファイル: if_fe_isa.c プロジェクト: AhmadTux/freebsd
/* 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;
}
コード例 #4
0
ファイル: if_fe_isa.c プロジェクト: AhmadTux/freebsd
static int
fe_probe_jli(device_t dev)
{
	struct fe_softc *sc = device_get_softc(dev);
	int i, n, error, xirq;
	u_long iobase, irq;
	u_char eeprom [JLI_EEPROM_SIZE];
	u_short const * irqmap;

	static u_short const baseaddr [8] =
		{ 0x260, 0x280, 0x2A0, 0x240, 0x340, 0x320, 0x380, 0x300 };
	static struct fe_simple_probe_struct const probe_table [] = {
		{ FE_DLCR1,  0x20, 0x00 },
		{ FE_DLCR2,  0x50, 0x00 },
		{ FE_DLCR4,  0x08, 0x00 },
		{ FE_DLCR5,  0x80, 0x00 },
#if 0
		{ FE_BMPR16, 0x1B, 0x00 },
		{ FE_BMPR17, 0x7F, 0x00 },
#endif
		{ 0 }
	};

	/*
	 * See if the specified address is possible for MB86965A JLI mode.
	 */
	if (bus_get_resource(dev, SYS_RES_IOPORT, 0, &iobase, NULL) != 0)
		return ENXIO;
	for (i = 0; i < 8; i++) {
		if (baseaddr[i] == iobase)
			break;
	}
	if (i == 8)
		return ENXIO;

	/* 86965 JLI occupies 32 I/O addresses. */
	if (fe_alloc_port(dev, 32))
		return ENXIO;

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

	/*
	 * We should test if MB86965A is on the base address now.
	 * Unfortunately, it is very hard to probe it reliably, since
	 * we have no way to reset the chip under software control.
	 * On cold boot, we could check the "signature" bit patterns
	 * described in the Fujitsu document.  On warm boot, however,
	 * we can predict almost nothing about register values.
	 */
	if (!fe_simple_probe(sc, probe_table))
		return ENXIO;

	/* Check if our I/O address matches config info on 86965.  */
	n = (fe_inb(sc, FE_BMPR19) & FE_B19_ADDR) >> FE_B19_ADDR_SHIFT;
	if (baseaddr[n] != iobase)
		return ENXIO;

	/*
	 * We are now almost sure we have an MB86965 at the given
	 * address.  So, read EEPROM through it.  We have to write
	 * into LSI registers to read from EEPROM.  I want to avoid it
	 * at this stage, but I cannot test the presence of the chip
	 * any further without reading EEPROM.  FIXME.
	 */
	fe_read_eeprom_jli(sc, eeprom);

	/* Make sure that config info in EEPROM and 86965 agree.  */
	if (eeprom[FE_EEPROM_CONF] != fe_inb(sc, FE_BMPR19))
		return ENXIO;

	/* Use 86965 media selection scheme, unless othewise
           specified.  It is "AUTO always" and "select with BMPR13."
           This behaviour covers most of the 86965 based board (as
           minimum requirements.)  It is backward compatible with
           previous versions, also.  */
	sc->mbitmap = MB_HA;
	sc->defmedia = MB_HA;
	sc->msel = fe_msel_965;

	/* Perform board-specific probe, one by one.  Note that the
           order of probe is important and should not be changed
           arbitrarily.  */
	if ((irqmap = fe_probe_jli_ati(sc, eeprom)) == NULL
	 && (irqmap = fe_probe_jli_rex(sc, eeprom)) == NULL
	 && (irqmap = fe_probe_jli_icl(sc, eeprom)) == NULL
	 && (irqmap = fe_probe_jli_unk(sc, eeprom)) == NULL)
		return ENXIO;

	/* Find the IRQ read from EEPROM.  */
	n = (fe_inb(sc, FE_BMPR19) & FE_B19_IRQ) >> FE_B19_IRQ_SHIFT;
	xirq = irqmap[n];

	/* Try to determine IRQ setting.  */
	error = bus_get_resource(dev, SYS_RES_IRQ, 0, &irq, NULL);
	if (error && xirq == NO_IRQ) {
		/* The device must be configured with an explicit IRQ.  */
		device_printf(dev, "IRQ auto-detection does not work\n");
		return ENXIO;
	} else if (error && xirq != NO_IRQ) {
		/* Just use the probed IRQ value.  */
		bus_set_resource(dev, SYS_RES_IRQ, 0, xirq, 1);
	} else if (!error && xirq == NO_IRQ) {
		/* No problem.  Go ahead.  */
	} else if (irq == xirq) {
		/* Good.  Go ahead.  */
	} else {
		/* User must be warned in this case.  */
		sc->stability |= UNSTABLE_IRQ;
	}

	/* Setup a hook, which resets te 86965 when the driver is being
           initialized.  This may solve a nasty bug.  FIXME.  */
	sc->init = fe_init_jli;

	return 0;
}
コード例 #5
0
ファイル: if_fe_isa.c プロジェクト: AhmadTux/freebsd
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;
}
コード例 #6
0
ファイル: if_fe_cbus.c プロジェクト: 2asoft/freebsd
/*
 * 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;
}
コード例 #7
0
ファイル: if_fe_cbus.c プロジェクト: 2asoft/freebsd
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;
}