plan 9 kernel history: overview | file list | diff list

1993/0212/pc/ether8003.c (diff list | history)

pc/ether8003.c on 1992/1222
1992/1222    
#include "u.h" 
#include "../port/lib.h" 
#include "mem.h" 
#include "dat.h" 
#include "fns.h" 
#include "../port/error.h" 
#include "io.h" 
#include "devtab.h" 
 
#include "ether.h" 
 
enum {					/* 83C584 Bus Interface Controller */ 
	Msr		= 0x00,		/* Memory Select Register */ 
	Icr		= 0x01,		/* Interface Configuration Register */ 
	Iar		= 0x02,		/* I/O Address Register */ 
	Bio		= 0x03,		/* BIOS ROM Address Register */ 
	Irr		= 0x04,		/* Interrupt Request Register */ 
	Laar		= 0x05,		/* LA Address Register */ 
	Ijr		= 0x06,		/* Initialisation Jumpers */ 
	Gp2		= 0x07,		/* General Purpose Data Register */ 
	Lar		= 0x08,		/* LAN Address Registers */ 
1993/0212    
	Id		= 0x0E,		/* Card ID byte */ 
1992/1222    
	Cksum		= 0x0F,		/* Checksum */ 
}; 
 
enum {					/* Msr */ 
	Rst		= 0x80,		/* software reset */ 
	Menb		= 0x40,		/* memory enable */ 
}; 
 
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 */ 
}; 
 
/* 
 * Mapping from configuration bits to interrupt level. 
 */ 
static int intrmap[] = { 
	9, 3, 5, 7, 10, 11, 15, 4, 
}; 
 
/* 
 * Get configuration parameters, enable memory. 
 */ 
static int 
reset(Ctlr *ctlr) 
{ 
	int i; 
	uchar msr, icr, laar, irr, sum; 
 
	/* 
	 * Look for the interface. We read the LAN address ROM 
	 * and validate the checksum - the sum of all 8 bytes 
	 * should be 0xFF. 
	 */ 
1993/0212    
	for(ctlr->card.io = 0x200; ctlr->card.io < 0x400; ctlr->card.io += 0x20){ 
1992/1222    
		sum = 0; 
		for(i = 0; i < sizeof(ctlr->ea); i++){ 
1993/0212    
			ctlr->ea[i] = inb(ctlr->card.io+Lar+i); 
1992/1222    
			sum += ctlr->ea[i]; 
		} 
1993/0212    
		sum += inb(ctlr->card.io+Id); 
		sum += inb(ctlr->card.io+Cksum); 
1992/1222    
		if(sum == 0xFF) 
			break; 
	} 
1993/0212    
	if(ctlr->card.io >= 0x400) 
1992/1222    
		return -1; 
 
	/* 
	 * Found it, reset it. 
	 * Be careful to preserve the Msr address bits, 
	 * they don't get reloaded from the EEPROM on reset. 
	 */ 
1993/0212    
	msr = inb(ctlr->card.io+Msr); 
	outb(ctlr->card.io+Msr, Rst|msr); 
1992/1222    
	delay(1); 
1993/0212    
	outb(ctlr->card.io+Msr, msr); 
1992/1222    
	delay(2); 
 
	/* 
	 * Check for old, dumb 8003E, which doesn't have an interface 
	 * chip. Only the msr exists out of the 1st eight registers, reads 
	 * of the others just alias the 2nd eight registers, the LAN 
	 * address ROM. We can check icr, irr and laar against the ethernet 
	 * address read above and if they match it's an 8003E (or an 
	 * 8003EBT, 8003S, 8003SH or 8003WT, we don't care), in which 
	 * case the default irq gets used. 
	 */ 
1993/0212    
	msr = inb(ctlr->card.io+Msr); 
	icr = inb(ctlr->card.io+Icr); 
	laar = inb(ctlr->card.io+Laar); 
	irr = inb(ctlr->card.io+Irr); 
1992/1222    
	if(icr != ctlr->ea[1] || irr != ctlr->ea[4] || laar != ctlr->ea[5]) 
1993/0212    
		ctlr->card.irq = intrmap[((irr>>5) & 0x3)|(icr & 0x4)]; 
1992/1222    
	else { 
1993/0212    
		msr = (((ulong)ctlr->card.ramstart)>>13) & 0x3F; 
1992/1222    
		icr = laar = 0; 
1993/0212    
		ctlr->card.watch = 0; 
1992/1222    
	} 
 
	/* 
	 * Set up the bus-size, RAM address and RAM size 
	 * from the info in the configuration registers. 
	 */ 
1993/0212    
	ctlr->card.bit16 = icr & 0x1; 
1992/1222    
 
1993/0212    
	ctlr->card.ram = 1; 
	ctlr->card.ramstart = KZERO|((msr & 0x3F)<<13); 
	if(ctlr->card.bit16) 
		ctlr->card.ramstart |= (laar & 0x1F)<<19; 
1992/1222    
	else 
1993/0212    
		ctlr->card.ramstart |= 0x80000; 
1992/1222    
 
	if(icr & (1<<3)) 
1993/0212    
		ctlr->card.ramstop = 32*1024; 
1992/1222    
	else 
1993/0212    
		ctlr->card.ramstop = 8*1024; 
	if(ctlr->card.bit16) 
		ctlr->card.ramstop <<= 1; 
	ctlr->card.ramstop += ctlr->card.ramstart; 
1992/1222    
 
	/* 
	 * Set the DP8390 ring addresses. 
	 */ 
1993/0212    
	ctlr->card.dp8390 = ctlr->card.io+0x10; 
	ctlr->card.pstart = HOWMANY(sizeof(Etherpkt), Dp8390BufSz); 
	ctlr->card.pstop = HOWMANY(ctlr->card.ramstop-ctlr->card.ramstart, Dp8390BufSz); 
	ctlr->card.tstart = 0; 
1992/1222    
 
	/* 
	 * Enable interface RAM, set interface width. 
	 */ 
1993/0212    
	outb(ctlr->card.io+Msr, Menb|msr); 
	if(ctlr->card.bit16) 
		outb(ctlr->card.io+Laar, laar|L16en|M16en|ZeroWS16); 
1992/1222    
 
	/* 
	 * Finally, init the 8390 and set the 
	 * ethernet address. 
	 */ 
	dp8390reset(ctlr); 
	dp8390setea(ctlr); 
 
	return 0; 
} 
 
1993/0212    
static void* 
read(Ctlr *ctlr, void *to, ulong from, ulong len) 
{ 
	/* 
	 * In this case, 'from' is an index into the shared memory. 
	 */ 
	memmove(to, (void*)(ctlr->card.ramstart+from), len); 
	return to; 
} 
 
static void* 
write(Ctlr *ctlr, ulong to, void *from, ulong len) 
{ 
	/* 
	 * In this case, 'to' is an index into the shared memory. 
	 */ 
	memmove((void*)(ctlr->card.ramstart+to), from, len); 
	return (void*)to; 
} 
 
1992/1222    
static void 
watch(Ctlr *ctlr) 
{ 
	uchar msr; 
	int s; 
 
	s = splhi(); 
1993/0212    
	msr = inb(ctlr->card.io+Msr); 
1992/1222    
	/* 
1993/0212    
	 * If the card has reset itself, 
1992/1222    
	 * start again. 
	 */ 
	if((msr & Menb) == 0){ 
		delay(100); 
 
		dp8390reset(ctlr); 
		etherinit(); 
 
		wakeup(&ctlr->tr); 
		wakeup(&ctlr->rr); 
	} 
	splx(s); 
} 
 
/* 
 * Defaults are set for the dumb 8003E 
 * which can't be autoconfigured. 
 */ 
1993/0212    
Card ether8003 = { 
	"WD8003",			/* ident */ 
1992/1222    
 
1993/0212    
	reset,				/* reset */ 
	0,				/* init */ 
	dp8390attach,			/* attach */ 
	dp8390mode,			/* mode */ 
1992/1222    
 
1993/0212    
	read,				/* read */ 
	write,				/* write */ 
 
	dp8390receive,			/* receive */ 
	dp8390transmit,			/* transmit */ 
	dp8390intr,			/* interrupt */ 
	watch,				/* watch */ 
	0,				/* overflow */ 
 
	0x280,				/* io */ 
	3,				/* irq */ 
	0,				/* bit16 */ 
 
	1,				/* ram */ 
	0xD0000,			/* ramstart */ 
	0xD0000+8*1024,			/* ramstop */ 
1992/1222    
}; 


source code copyright © 1990-2005 Lucent Technologies; see license
Plan 9 distribution
comments to russ cox (rsc@swtch.com)