Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 24 Mar 2000 23:58:48 -0500 (EST)
From:      "Matthew N. Dodd" <winter@jurai.net>
To:        current@freebsd.org
Subject:   Testers Wanted! (EtherExpress 16 & 3C507 owners/users)
Message-ID:  <Pine.BSF.4.21.0003242350560.50194-300000@sasami.jurai.net>

index | next in thread | raw e-mail

[-- Attachment #1 --]
I'm working on converting the 'ie' driver to newbus.

I've rewritten the code that identifies the cards and am in need of wider
testing since I've only got a lone Intel EtherExpress 16.

I have a non-invasive test 'driver' that just looks for the cards and
figures out the resources they are using.

Please do the following if you own/use an Intel EtherExpress 16 or a 3Com
3C507 Etherlink 16 and are running -CURRENT:

	- save the attachment if_ie_isa.c to src/sys/dev/ie
	- save the attachment ie_test.patch to /tmp/
	- cd /sys && patch < /tmp/ie_test.patch
	- edit your kernel config file and add the following line:
	
		device	ie_test0

	- config and build your kernel
	- boot verbose and look for 'if_ie' in the messages.
	- compare the reported values with the values your card
	  actually uses.
	- report success or failure to me.

Thanks!

-- 
| Matthew N. Dodd  | '78 Datsun 280Z | '75 Volvo 164E | FreeBSD/NetBSD  |
| winter@jurai.net |       2 x '84 Volvo 245DL        | ix86,sparc,pmax |
| http://www.jurai.net/~winter | This Space For Rent  | ISO8802.5 4ever |

[-- Attachment #2 --]
Index: conf/files
===================================================================
RCS file: /cvs/src/sys/conf/files,v
retrieving revision 1.342
diff -u -r1.342 files
--- conf/files	2000/03/20 14:08:37	1.342
+++ conf/files	2000/03/25 03:29:40
@@ -168,6 +173,7 @@
 dev/hfa/fore_transmit.c	optional hfa
 dev/hfa/fore_vcm.c	optional hfa
 dev/ie/if_ie.c		optional ie isa
+dev/ie/if_ie_isa.c	optional ie_test isa
 dev/ida/ida.c		optional ida
 dev/ida/ida_disk.c	optional ida
 dev/ida/ida_eisa.c	optional ida eisa

[-- Attachment #3 --]
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kernel.h>
#include <sys/module.h>
#include <sys/bus.h>

#include <machine/bus_pio.h>
#include <machine/bus.h>
#include <machine/resource.h>
#include <sys/rman.h>

#include <machine/clock.h>

#include <isa/isavar.h>
#include <isa/pnpvar.h>

#include <i386/isa/elink.h>

#include <dev/ie/if_ie507.h>
#include <dev/ie/if_iee16.h>

static void		ie_isa_3C507_identify	(driver_t *, device_t);
static int		ie_3C507_port_check	(u_int32_t);

static void		ie_isa_ee16_identify	(driver_t *, device_t);
static u_int16_t	ie_ee16_hw_read_eeprom	(u_int32_t port, int loc);

#define IE_3C507_IOBASE_LOW	0x200
#define IE_3C507_IOBASE_HIGH	0x3e0
#define IE_3C507_IOSIZE		16

#define IE_3C507_IRQ_MASK	0x0f

#define IE_3C507_MADDR_HIGH	0x20
#define IE_3C507_MADDR_MASK	0x1c
#define IE_3C507_MADDR_BASE	0xc0000
#define IE_3C507_MADDR_SHIFT	12

#define IE_3C507_MSIZE_MASK	3
#define IE_3C507_MSIZE_SHIFT	14

/*
 * 3Com 3C507 Etherlink 16
 */
static void
ie_isa_3C507_identify (driver_t *driver, device_t parent)
{
	char *		desc = "3Com 3C507 Etherlink 16";
	u_int32_t	port;
	u_int32_t	maddr;
	u_int32_t	msize;
	u_int8_t	irq;
	u_int8_t	data;

	/* Reset and put card in CONFIG state without changing address. */
	elink_reset();
	outb(ELINK_ID_PORT, 0);
	elink_idseq(ELINK_507_POLY);
	elink_idseq(ELINK_507_POLY);
	outb(ELINK_ID_PORT, 0xff);

	for (port = IE_3C507_IOBASE_LOW;
	     port <= IE_3C507_IOBASE_HIGH;
	     port += IE_3C507_IOSIZE) {

		if (ie_3C507_port_check(port)) {
			if (bootverbose) {
#if 0
				device_printf(parent, "if_ie: (3C507) not found at port %#x\n",
					port);
#endif
			}
			continue;
		}

		outb(port + IE507_CTRL, EL_CTRL_NRST);

		data = inb(port + IE507_IRQ);
		irq = data & IE_3C507_IRQ_MASK;

		data = inb(port + IE507_MADDR);

		if (data & IE_3C507_MADDR_HIGH) {
			if (bootverbose) {
				device_printf(parent, "if_ef: can't map 3C507 RAM in high memory\n");
			}
			continue;
		}

		maddr = IE_3C507_MADDR_BASE +
			((data & IE_3C507_MADDR_MASK)
			<< IE_3C507_MADDR_SHIFT);
		msize = ((data & IE_3C507_MSIZE_MASK) + 1)
			<< IE_3C507_MSIZE_SHIFT;

		outb(port + IE507_CTRL, EL_CTRL_NORMAL);

		/* Clear the interrupt latch just in case. */
		outb(port + IE507_ICTRL, 1);

#if 0
		child = BUS_ADD_CHILD(parent, ISA_ORDER_SPECULATIVE, "ie", -1);
		device_set_desc_copy(child, desc);
		device_set_driver(child, driver);
		bus_set_resource(child, SYS_RES_IRQ, 0, irq, 1);
		bus_set_resource(child, SYS_RES_IOPORT, 0, port, IE_3C507_IOSIZE);
		bus_set_resource(child, SYS_RES_MEMORY, 0, maddr, msize);
#endif

		if (bootverbose) {
			device_printf(parent, "if_ie: <%s> at port %#x-%#x irq %d iomem %#lx-%#lx (%dKB)\n",
				desc, port, (port + IE_3C507_IOSIZE) - 1, irq,
				(u_long)maddr, (u_long)(maddr + msize) - 1,
				(msize / 1024));
		}
	}

	/* go to RUN state */
	outb(ELINK_ID_PORT, 0x00);
	elink_idseq(ELINK_507_POLY);
	outb(ELINK_ID_PORT, 0x00);

	return;
}

static int
ie_3C507_port_check (u_int32_t port)
{
	u_char *	signature = "*3COM*";
	int		i;

	for (i = 0; i < 6; i++)
		if (inb(port + i) != signature[i])
			return (ENXIO);

	return (0);
}

#define IE_EE16_ID_PORT			0x0f
#define IE_EE16_ID			0xbaba
#define IE_EE16_EEPROM_CONFIG1		0x00
#define IE_EE16_EEPROM_IRQ_MASK		0xe000
#define IE_EE16_EEPROM_IRQ_SHIFT	13
#define IE_EE16_EEPROM_MEMCFG		0x06
#define IE_EE16_IOSIZE			16

/*
 * Intel EtherExpress 16
 *
 * TODO:
 *		Test for 8/16 bit mode.
 *		Test for invalid mem sizes.
 */
static void
ie_isa_ee16_identify (driver_t *driver, device_t parent)
{
	char *		desc = "Intel EtherExpress 16";
	u_int16_t	ports[] = {
				0x300, 0x310, 0x320, 0x330,
				0x340, 0x350, 0x360, 0x370,
				0x200, 0x210, 0x220, 0x230,
				0x240, 0x250, 0x260, 0x270,
				0
			};
	u_int16_t	irqs[] = { 0, 0x09, 0x03, 0x04, 0x05, 0x0a, 0x0b, 0 };
	u_int32_t	port;
	u_int32_t	maddr;
	u_int32_t	msize;
	u_int8_t	irq;
	u_int8_t	data;
	u_int16_t	data1;
	int		i, j;

	for (i = 0; ports[i] != 0; i++) {
		u_int16_t	board_id;

		board_id = 0;
		port = ports[i];

		for (j = 0; j < 4; j++) {
			data = inb(port + IE_EE16_ID_PORT);
			board_id |= ((data >> 4) << ((data & 0x03) << 2));
		}

		if (board_id != IE_EE16_ID) {
#if 0
			device_printf(parent, "if_ie: (EE16) not found at port %#x\n",
				port);
#endif
			continue;
		}

		/* reset any ee16 at the current iobase */
		outb(port + IEE16_ECTRL, IEE16_RESET_ASIC);
		outb(port + IEE16_ECTRL, 0);
		DELAY(240);

		data1 = ie_ee16_hw_read_eeprom(port, IE_EE16_EEPROM_CONFIG1);
		irq = irqs[((data1 & IE_EE16_EEPROM_IRQ_MASK)
			   >> IE_EE16_EEPROM_IRQ_SHIFT)];

		data1 = ie_ee16_hw_read_eeprom(port, IE_EE16_EEPROM_MEMCFG);
		maddr = 0xc0000 + ((ffs(data1 & 0x00ff) - 1) * 0x4000);
		msize = (fls((data1 & 0x00ff) >> (ffs(data1 & 0x00ff) - 1)))
			* 0x4000;

#if 0
		child = BUS_ADD_CHILD(parent, ISA_ORDER_SPECULATIVE, "ie", -1);
		device_set_desc_copy(child, desc);
		device_set_driver(child, driver);
		bus_set_resource(child, SYS_RES_IRQ, 0, irq, 1);
		bus_set_resource(child, SYS_RES_IOPORT, 0, port, IE_EE16_IOSIZE);
		bus_set_resource(child, SYS_RES_MEMORY, 0, maddr, msize);
#endif
		if (bootverbose) {
			device_printf(parent, "if_ie: <%s> at port %#x-%#x irq %d iomem %#lx-%#lx (%dKB)\n",
				desc, port, (port + IE_EE16_IOSIZE) - 1, irq,
				(u_long)maddr, (u_long)(maddr + msize) - 1,
				(msize / 1024));
		}
	}

	return;
}

static void
ie_ee16_hw_eeprom_clock (u_int32_t port, int state)
{
	u_int8_t	ectrl;

	ectrl = inb(port + IEE16_ECTRL);
	ectrl &= ~(IEE16_RESET_ASIC | IEE16_ECTRL_EESK);

	if (state) {
		ectrl |= IEE16_ECTRL_EESK;
	}
	outb(port + IEE16_ECTRL, ectrl);
	DELAY(9);		/* EESK must be stable for 8.38 uSec */
}

static void
ie_ee16_hw_eeprom_out (u_int32_t port, u_int16_t edata, int count)
{
	u_int8_t	ectrl;
	int		i;

	ectrl = inb(port + IEE16_ECTRL);
	ectrl &= ~IEE16_RESET_ASIC;

	for (i = count - 1; i >= 0; i--) {
		ectrl &= ~IEE16_ECTRL_EEDI;
		if (edata & (1 << i)) {
			ectrl |= IEE16_ECTRL_EEDI;
		}
		outb(port + IEE16_ECTRL, ectrl);
		DELAY(1);       /* eeprom data must be setup for 0.4 uSec */
		ie_ee16_hw_eeprom_clock(port, 1);
		ie_ee16_hw_eeprom_clock(port, 0);
	}
	ectrl &= ~IEE16_ECTRL_EEDI;
	outb(port + IEE16_ECTRL, ectrl);
	DELAY(1);               /* eeprom data must be held for 0.4 uSec */

	return;
}

static u_int16_t
ie_ee16_hw_eeprom_in (u_int32_t port)
{
	u_int8_t	ectrl;
	u_int16_t	edata;
	int		i;

	ectrl = inb(port + IEE16_ECTRL);
	ectrl &= ~IEE16_RESET_ASIC;

	for (edata = 0, i = 0; i < 16; i++) {
		edata = edata << 1;
		ie_ee16_hw_eeprom_clock(port, 1);
		ectrl = inb(port + IEE16_ECTRL);
		if (ectrl & IEE16_ECTRL_EEDO) {
			edata |= 1;
		}
		ie_ee16_hw_eeprom_clock(port, 0);
	}
	return (edata);
}

static u_int16_t
ie_ee16_hw_read_eeprom (u_int32_t port, int loc)
{
	u_int8_t	ectrl;
	u_int16_t	edata;

	ectrl = inb(port + IEE16_ECTRL);
	ectrl &= IEE16_ECTRL_MASK;
	ectrl |= IEE16_ECTRL_EECS;
	outb(port + IEE16_ECTRL, ectrl);

	ie_ee16_hw_eeprom_out(port, IEE16_EEPROM_READ, IEE16_EEPROM_OPSIZE1);
	ie_ee16_hw_eeprom_out(port, loc, IEE16_EEPROM_ADDR_SIZE);
	edata = ie_ee16_hw_eeprom_in(port);

	ectrl = inb(port + IEE16_ECTRL);
	ectrl &= ~(IEE16_RESET_ASIC | IEE16_ECTRL_EEDI | IEE16_ECTRL_EECS);
	outb(port + IEE16_ECTRL, ectrl);

	ie_ee16_hw_eeprom_clock(port, 1);
	ie_ee16_hw_eeprom_clock(port, 0);

	return (edata);
}

static devclass_t ie_devclass;

static device_method_t ie_isa_3C507_methods[] = {
	DEVMETHOD(device_identify,	ie_isa_3C507_identify),
	{ 0, 0 }
};
static driver_t ie_isa_3C507_driver = {
	"ie",
	ie_isa_3C507_methods,
	1 /* sizeof(struct ie_softc) */, 
};
DRIVER_MODULE(ie_3C507, isa, ie_isa_3C507_driver, ie_devclass, 0, 0);

static device_method_t ie_isa_ee16_methods[] = {
	DEVMETHOD(device_identify,	ie_isa_ee16_identify),
	{ 0, 0 }
};
static driver_t ie_isa_ee16_driver = {
	"ie",
	ie_isa_ee16_methods,
	1 /* sizeof(struct ie_softc) */, 
};
DRIVER_MODULE(ie_ee16, isa, ie_isa_ee16_driver, ie_devclass, 0, 0);
help

Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?Pine.BSF.4.21.0003242350560.50194-300000>