~kris/9p

9hist

c72c7bfb5ed0e041df271cb3ebdbbfa79383ebf3 — David du Colombier 31 years ago bfc6e60
Plan 9 from Bell Labs 1995-08-29
2 files changed, 124 insertions(+), 64 deletions(-)

M pc/ether8003.c
M pc/ether8390.c
M pc/ether8003.c => pc/ether8003.c +121 -59
@@ 11,6 11,7 @@

/*
 * Western Digital/Standard Microsystems Corporation cards (WD80[01]3).
 * Also handles 8216 cards (Elite Ultra).
 * Configuration code based on that provided by SMC.
 */
enum {					/* 83C584 Bus Interface Controller */


@@ 20,6 21,7 @@ enum {					/* 83C584 Bus Interface Controller */
	Bio		= 0x03,		/* BIOS ROM Address Register */
	Ear		= 0x03,		/* EEROM Address Register (shared with Bio) */
	Irr		= 0x04,		/* Interrupt Request Register */
	Hcr		= 0x04,		/* 8216 hardware control */
	Laar		= 0x05,		/* LA Address Register */
	Ijr		= 0x06,		/* Initialisation Jumpers */
	Gp2		= 0x07,		/* General Purpose Data Register */


@@ 45,68 47,34 @@ enum {					/* Icr */
};

enum {					/* Laar */
	ZeroWS16	= (1<<5),	/* zero wait states for 16-bit ops */
	L16en		= (1<<6),	/* enable 16-bit LAN operation */
	M16en		= (1<<7),	/* enable 16-bit memory access */
	ZeroWS16	= 0x20,		/* zero wait states for 16-bit ops */
	L16en		= 0x40,		/* enable 16-bit LAN operation */
	M16en		= 0x80,		/* enable 16-bit memory access */
};

enum {					/* Ijr */
	Ienable		= 0x01,		/* 8216 interrupt enable */
};

/*
 * Mapping from configuration bits to interrupt level.
 */
static int intrmap[] = {
static int irq8003[8] = {
	9, 3, 5, 7, 10, 11, 15, 4,
};

/*
 * Get configuration parameters, enable memory.
 * There are opportunities here for buckets of code.
 * We'll try to resist.
 */
static int
reset(Ether *ether)
static int irq8216[8] = {
	0, 9, 3, 5, 7, 10, 11, 15,
};

static void
reset8003(Ether *ether, uchar ea[Eaddrlen], uchar ic[8])
{
	int i;
	uchar ea[Eaddrlen], ic[8], sum;
	ulong port;
	Dp8390 *dp8390;
	ulong port;

	/*
	 * Set up the software configuration.
	 * Use defaults for port, irq, mem and size if not specified.
	 * Defaults are set for the dumb 8003E which can't be
	 * autoconfigured.
	 */
	if(ether->port == 0)
		ether->port = 0x280;
	if(ether->irq == 0)
		ether->irq = 3;
	if(ether->mem == 0)
		ether->mem = 0xD0000;
	if(ether->size == 0)
		ether->size = 8*1024;

	/*
	 * Look for the interface. We read the LAN address ROM
	 * and validate the checksum - the sum of all 8 bytes
	 * should be 0xFF.
	 * While we're at it, get the (possible) interface chip
	 * registers, we'll use them to check for aliasing later.
	 */
	port = ether->port;
	sum = 0;
	for(i = 0; i < sizeof(ea); i++){
		ea[i] = inb(port+Lar+i);
		sum += ea[i];
		ic[i] = inb(port+i);
	}
	sum += inb(port+Id);
	sum += inb(port+Cksum);
	if(sum != 0xFF)
		return -1;

	ether->ctlr = malloc(sizeof(Dp8390));
	dp8390 = ether->ctlr;
	dp8390->ram = 1;
	port = ether->port;

	/*
	 * Check for old, dumb 8003E, which doesn't have an interface


@@ 117,7 85,7 @@ reset(Ether *ether)
	 * 8003EBT, 8003S, 8003SH or 8003WT, we don't care), in which
	 * case the default irq gets used.
	 */
	if(memcmp(&ether->ea[1], &ic[1], 5) == 0){
	if(memcmp(&ea[1], &ic[1], 5) == 0){
		memset(ic, 0, sizeof(ic));
		ic[Msr] = (((ulong)ether->mem)>>13) & 0x3F;
	}


@@ 134,7 102,7 @@ reset(Ether *ether)
			ic[Msr] = (((ulong)ether->mem)>>13) & 0x3F;
		}
		else
			ether->irq = intrmap[((ic[Irr]>>5) & 0x3)|(ic[Icr] & 0x4)];
			ether->irq = irq8003[((ic[Irr]>>5) & 0x3)|(ic[Icr] & 0x4)];

		/*
		 * Check if 16-bit card.


@@ 165,6 133,107 @@ reset(Ether *ether)
		ether->size <<= 1;

	/*
	 * Enable interface RAM, set interface width.
	 */
	outb(port+Msr, ic[Msr]|Menb);
	if(dp8390->bit16)
		outb(port+Laar, ic[Laar]|L16en|M16en|ZeroWS16);
}

static void
reset8216(Ether *ether, uchar[8])
{
	uchar hcr, irq, x;
	ulong addr, port;
	Dp8390 *dp8390;

	dp8390 = ether->ctlr;
	dp8390->bit16 = 1;
	port = ether->port;

	/*
	 * Switch to the alternate register set and retrieve the memory
	 * and irq information.
	 */
	hcr = inb(port+Hcr);
	outb(port+Hcr, 0x80|hcr);
	addr = inb(port+0x0B) & 0xFF;
	irq = inb(port+0x0D);
	outb(port+Hcr, hcr);

	ether->mem = KZERO|(0xC0000+((((addr>>2) & 0x30)|(addr & 0x0F))<<13));
	ether->size = 8192*(1<<((addr>>4) & 0x03));
	ether->irq = irq8216[((irq>>4) & 0x04)|((irq>>2) & 0x03)];

	/*
	 * Enable interface RAM, set interface width,
	 * and enable interrupts.
	 */
	x = inb(port+Msr) & ~Rst;
	outb(port+Msr, Menb|x);
	x = inb(port+Laar);
	outb(port+Laar, M16en|x);
	outb(port+Ijr, Ienable);
}

/*
 * Get configuration parameters, enable memory.
 * There are opportunities here for buckets of code.
 * We'll try to resist.
 */
static int
reset(Ether *ether)
{
	int i;
	uchar ea[Eaddrlen], ic[8], id, sum;
	ulong port;
	Dp8390 *dp8390;

	/*
	 * Set up the software configuration.
	 * Use defaults for port, irq, mem and size if not specified.
	 * Defaults are set for the dumb 8003E which can't be
	 * autoconfigured.
	 */
	if(ether->port == 0)
		ether->port = 0x280;
	if(ether->irq == 0)
		ether->irq = 3;
	if(ether->mem == 0)
		ether->mem = 0xD0000;
	if(ether->size == 0)
		ether->size = 8*1024;

	/*
	 * Look for the interface. We read the LAN address ROM
	 * and validate the checksum - the sum of all 8 bytes
	 * should be 0xFF.
	 * While we're at it, get the (possible) interface chip
	 * registers, we'll use them to check for aliasing later.
	 */
	port = ether->port;
	sum = 0;
	for(i = 0; i < sizeof(ea); i++){
		ea[i] = inb(port+Lar+i);
		sum += ea[i];
		ic[i] = inb(port+i);
	}
	id = inb(port+Id);
	sum += id;
	sum += inb(port+Cksum);
	if(sum != 0xFF)
		return -1;

	ether->ctlr = malloc(sizeof(Dp8390));
	dp8390 = ether->ctlr;
	dp8390->ram = 1;

	if((id & 0xFE) == 0x2A)
		reset8216(ether, ic);
	else
		reset8003(ether, ea, ic);

	/*
	 * Set the DP8390 ring addresses.
	 */
	dp8390->dp8390 = port+0x10;


@@ 173,13 242,6 @@ reset(Ether *ether)
	dp8390->pstop = HOWMANY(ether->size, Dp8390BufSz);

	/*
	 * Enable interface RAM, set interface width.
	 */
	outb(port+Msr, ic[Msr]|Menb);
	if(dp8390->bit16)
		outb(port+Laar, ic[Laar]|L16en|M16en|ZeroWS16);

	/*
	 * Finally, init the 8390 and set the
	 * ethernet address.
	 */

M pc/ether8390.c => pc/ether8390.c +3 -5
@@ 562,15 562,13 @@ overflow(Ether *ether)
}

static void
interrupt(Ureg *ur, void *arg)
interrupt(Ureg*, void *arg)
{
	Ether *ether;
	Dp8390 *dp8390;
	ulong port;
	uchar isr, r;

	USED(ur);

	ether = arg;
	dp8390 = ether->ctlr;
	port = dp8390->dp8390;


@@ 580,7 578,7 @@ interrupt(Ureg *ur, void *arg)
	 * clear all the interrupts and process.
	 */
	slowoutb(port+Imr, 0x00);
	while(isr = slowinb(port+Isr)){
	while(isr = (slowinb(port+Isr) & (Cnte|Ovwe|Txee|Rxee|Ptxe|Prxe))){

		if(isr & Ovw){
			overflow(ether);


@@ 657,7 655,7 @@ attach(Ether *ether)
	x = Ab;
	if(ether->prom)
		x |= Pro;
	slowoutb(dp8390->dp8390+Rcr, Ab);
	slowoutb(dp8390->dp8390+Rcr, x);
	slowinb(dp8390->dp8390+Cntr2);
}