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

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

1993/0212/sys/src/9/pc/ether8003.c:9,191993/0223/sys/src/9/pc/ether8003.c:9,24 (short | long | prev | next)
1992/1222    
 
#include "ether.h" 
 
1993/0223    
/* 
 * Western Digital/Standard Microsystems Corporation cards (WD80[01]3). 
 * Configuration code based on that provided by SMC. 
 */ 
1992/1222    
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 */ 
1993/0223    
	Ear		= 0x03,		/* EEROM Address Register (shared with Bio) */ 
1992/1222    
	Irr		= 0x04,		/* Interrupt Request Register */ 
	Laar		= 0x05,		/* LA Address Register */ 
	Ijr		= 0x06,		/* Initialisation Jumpers */ 
1993/0212/sys/src/9/pc/ether8003.c:28,331993/0223/sys/src/9/pc/ether8003.c:33,49
1992/1222    
	Menb		= 0x40,		/* memory enable */ 
}; 
 
1993/0223    
enum {					/* Icr */ 
	Bit16		= 0x01,		/* 16-bit bus */ 
	Other		= 0x02,		/* other register access */ 
	Ir2		= 0x04,		/* IR2 */ 
	Msz		= 0x08,		/* SRAM size */ 
	Rla		= 0x10,		/* recall LAN address */ 
	Rx7		= 0x20,		/* recall all but I/O and LAN address */ 
	Rio		= 0x40,		/* recall I/O address from EEROM */ 
	Sto		= 0x80,		/* non-volatile EEROM store */ 
}; 
 
1992/1222    
enum {					/* Laar */ 
	ZeroWS16	= (1<<5),	/* zero wait states for 16-bit ops */ 
	L16en		= (1<<6),	/* enable 16-bit LAN operation */ 
1993/0212/sys/src/9/pc/ether8003.c:43,591993/0223/sys/src/9/pc/ether8003.c:59,79
1992/1222    
 
/* 
 * Get configuration parameters, enable memory. 
1993/0223    
 * There are opportunities here for buckets of code. 
 * We'll try to resist. 
1992/1222    
 */ 
static int 
reset(Ctlr *ctlr) 
{ 
	int i; 
	uchar msr, icr, laar, irr, sum; 
1993/0223    
	uchar ic[8], sum; 
1992/1222    
 
	/* 
	 * Look for the interface. We read the LAN address ROM 
	 * and validate the checksum - the sum of all 8 bytes 
	 * should be 0xFF. 
1993/0223    
	 * While we're at it, get the (possible) interface chip 
	 * registers, we'll use them to check for aliasing later. 
1992/1222    
	 */ 
1993/0212    
	for(ctlr->card.io = 0x200; ctlr->card.io < 0x400; ctlr->card.io += 0x20){ 
1992/1222    
		sum = 0; 
1993/0212/sys/src/9/pc/ether8003.c:60,651993/0223/sys/src/9/pc/ether8003.c:80,86
1992/1222    
		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/0223    
			ic[i] = inb(ctlr->card.io+i); 
1992/1222    
		} 
1993/0212    
		sum += inb(ctlr->card.io+Id); 
		sum += inb(ctlr->card.io+Cksum); 
1993/0212/sys/src/9/pc/ether8003.c:70,861993/0223/sys/src/9/pc/ether8003.c:91,96
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 
1993/0212/sys/src/9/pc/ether8003.c:89,1201993/0223/sys/src/9/pc/ether8003.c:99,151
1992/1222    
	 * 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/0223    
	if(memcmp(&ctlr->ea[1], &ic[1], 5) == 0){ 
		memset(ic, 0, sizeof(ic)); 
		ic[Msr] = (((ulong)ctlr->card.ramstart)>>13) & 0x3F; 
1993/0212    
		ctlr->card.watch = 0; 
1992/1222    
	} 
1993/0223    
	else{ 
		/* 
		 * As a final sanity check for the 8013EBT, which doesn't have 
		 * the 83C584 interface chip, but has 2 real registers, write Gp2 and if 
		 * it reads back the same, it's not an 8013EBT. 
		 */ 
		outb(ctlr->card.io+Gp2, 0xAA); 
		inb(ctlr->card.io+Msr);				/* wiggle bus */ 
		if(inb(ctlr->card.io+Gp2) != 0xAA){ 
			memset(ic, 0, sizeof(ic)); 
			ic[Msr] = (((ulong)ctlr->card.ramstart)>>13) & 0x3F; 
			ctlr->card.watch = 0; 
			ctlr->card.irq = 2;			/* special */ 
		} 
		else 
			ctlr->card.irq = intrmap[((ic[Irr]>>5) & 0x3)|(ic[Icr] & 0x4)]; 
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; 
1993/0223    
		/* 
		 * Check if 16-bit card. 
		 * If Bit16 is read/write, then we have an 8-bit card. 
		 * If Bit16 is set, we're in a 16-bit slot. 
		 */ 
		outb(ctlr->card.io+Icr, ic[Icr]^Bit16); 
		inb(ctlr->card.io+Msr);				/* wiggle bus */ 
		if((inb(ctlr->card.io+Icr) & Bit16) == (ic[Icr] & Bit16)){ 
			ctlr->card.bit16 = 1; 
			ic[Icr] &= ~Bit16; 
		} 
		outb(ctlr->card.io+Icr, ic[Icr]); 
1992/1222    
 
1993/0212    
	ctlr->card.ram = 1; 
	ctlr->card.ramstart = KZERO|((msr & 0x3F)<<13); 
1993/0223    
		ic[Icr] = inb(ctlr->card.io+Icr); 
		if(ctlr->card.bit16 && (ic[Icr] & Bit16) == 0) 
			ctlr->card.bit16 = 0; 
	} 
 
	ctlr->card.ramstart = KZERO|((ic[Msr] & 0x3F)<<13); 
1993/0212    
	if(ctlr->card.bit16) 
		ctlr->card.ramstart |= (laar & 0x1F)<<19; 
1993/0223    
		ctlr->card.ramstart |= (ic[Laar] & 0x1F)<<19; 
1992/1222    
	else 
1993/0212    
		ctlr->card.ramstart |= 0x80000; 
1992/1222    
 
	if(icr & (1<<3)) 
1993/0223    
	if(ic[Icr] & (1<<3)) 
1993/0212    
		ctlr->card.ramstop = 32*1024; 
1992/1222    
	else 
1993/0212    
		ctlr->card.ramstop = 8*1024; 
1993/0212/sys/src/9/pc/ether8003.c:133,1411993/0223/sys/src/9/pc/ether8003.c:164,172
1992/1222    
	/* 
	 * Enable interface RAM, set interface width. 
	 */ 
1993/0212    
	outb(ctlr->card.io+Msr, Menb|msr); 
1993/0223    
	outb(ctlr->card.io+Msr, ic[Msr]|Menb); 
1993/0212    
	if(ctlr->card.bit16) 
		outb(ctlr->card.io+Laar, laar|L16en|M16en|ZeroWS16); 
1993/0223    
		outb(ctlr->card.io+Laar, ic[Laar]|L16en|M16en|ZeroWS16); 
1992/1222    
 
	/* 
	 * Finally, init the 8390 and set the 


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