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

1993/1118/pc/ether8390.c (diff list | history)

1993/1117/sys/src/9/pc/ether8390.c:14,191993/1118/sys/src/9/pc/ether8390.c:14,22 (short | long | prev | next)
1992/1222    
 
1993/1116    
#include "etherif.h" 
1992/1222    
 
1993/1118    
extern int dp8390inb(ulong); 
extern void dp8390outb(ulong, uchar); 
 
1992/1222    
enum { 
	Cr		= 0x00,		/* command register, all pages */ 
 
1993/1117/sys/src/9/pc/ether8390.c:149,1581993/1118/sys/src/9/pc/ether8390.c:152,160
1992/1222    
static void 
1993/1117    
dp8390disable(Dp8390 *dp8390) 
1992/1222    
{ 
1993/1117    
	ulong port; 
1993/1118    
	ulong port = dp8390->dp8390; 
1992/1222    
	int timo; 
 
1993/1117    
	port = dp8390->dp8390; 
1992/1222    
	/* 
	 * Stop the chip. Set the Stp bit and wait for the chip 
	 * to finish whatever was on its tiny mind before it sets 
1993/1117/sys/src/9/pc/ether8390.c:171,1791993/1118/sys/src/9/pc/ether8390.c:173,180
1993/0212    
static void 
1993/1117    
dp8390ring(Dp8390 *dp8390) 
1993/0212    
{ 
1993/1117    
	ulong port; 
1993/1118    
	ulong port = dp8390->dp8390; 
1993/0212    
 
1993/1117    
	port = dp8390->dp8390; 
	dp8390outb(port+Pstart, dp8390->pstart); 
	dp8390outb(port+Pstop, dp8390->pstop); 
	dp8390outb(port+Bnry, dp8390->pstop-1); 
1993/1117/sys/src/9/pc/ether8390.c:188,1981993/1118/sys/src/9/pc/ether8390.c:189,198
1992/1222    
void 
1993/1116    
dp8390setea(Ether *ether) 
1992/1222    
{ 
1993/1117    
	ulong port; 
1993/1118    
	ulong port = ((Dp8390*)ether->private)->dp8390; 
1992/1222    
	uchar cr; 
	int i; 
 
1993/1117    
	port = ((Dp8390*)ether->private)->dp8390; 
1992/1222    
	/* 
	 * Set the ethernet address into the chip. 
	 * Take care to restore the command register 
1993/1117/sys/src/9/pc/ether8390.c:210,2201993/1118/sys/src/9/pc/ether8390.c:210,219
1993/0915    
void 
1993/1116    
dp8390getea(Ether *ether) 
1993/0915    
{ 
1993/1117    
	ulong port; 
1993/1118    
	ulong port = ((Dp8390*)ether->private)->dp8390; 
1993/0915    
	uchar cr; 
	int i; 
 
1993/1117    
	port = ((Dp8390*)ether->private)->dp8390; 
1993/0915    
	/* 
1993/1116    
	 * Get the ethernet address from the chip. 
1993/0915    
	 * Take care to restore the command register 
1993/1117/sys/src/9/pc/ether8390.c:232,2421993/1118/sys/src/9/pc/ether8390.c:231,240
1993/1116    
static void* 
1993/1117    
dp8390read(Dp8390 *dp8390, void *to, ulong from, ulong len) 
1992/1222    
{ 
1993/1117    
	ulong port; 
1993/1118    
	ulong port = dp8390->dp8390; 
1992/1222    
	uchar cr; 
	int timo; 
 
1993/1117    
	port = dp8390->dp8390; 
1992/1222    
	/* 
1993/0212    
	 * Read some data at offset 'from' in the card's memory 
1992/1222    
	 * using the DP8390 remote DMA facility, and place it at 
1993/1117/sys/src/9/pc/ether8390.c:282,3031993/1118/sys/src/9/pc/ether8390.c:280,301
1992/1222    
} 
 
1993/1116    
static void* 
dp8390write(Ether *ether, ulong to, void *from, ulong len) 
1993/1118    
dp8390write(Dp8390 *dp8390, ulong to, void *from, ulong len) 
1992/1222    
{ 
1993/0915    
	ulong dp8390, crda; 
1993/1118    
	ulong port = dp8390->dp8390; 
	ulong crda; 
1992/1222    
	uchar cr; 
 
1993/1117    
	dp8390 = ((Dp8390*)ether->private)->dp8390; 
1992/1222    
	/* 
1993/0212    
	 * Write some data to offset 'to' in the card's memory 
1992/1222    
	 * using the DP8390 remote DMA facility, reading it at 
	 * 'from' in main memory, via the I/O data port. 
	 */ 
1993/0915    
	cr = dp8390inb(dp8390+Cr) & ~Txp; 
	dp8390outb(dp8390+Cr, Page0|RDMAabort|Sta); 
	dp8390outb(dp8390+Isr, Rdc); 
1993/1118    
	cr = dp8390inb(port+Cr) & ~Txp; 
	dp8390outb(port+Cr, Page0|RDMAabort|Sta); 
	dp8390outb(port+Isr, Rdc); 
1992/1222    
 
1993/1116    
	if(ether->bit16) 
1993/1118    
	if(dp8390->bit16) 
1993/0212    
		len = ROUNDUP(len, 2); 
 
1992/1222    
	/* 
1993/1117/sys/src/9/pc/ether8390.c:305,3291993/1118/sys/src/9/pc/ether8390.c:303,327
1993/0212    
	 * This is straight from the DP8390[12D] datasheet, hence 
	 * the initial set up for read. 
1992/1222    
	 */ 
1993/1116    
	crda = to-1-ether->bit16; 
	dp8390outb(dp8390+Rbcr0, (len+1+ether->bit16) & 0xFF); 
	dp8390outb(dp8390+Rbcr1, ((len+1+ether->bit16)>>8) & 0xFF); 
1993/0915    
	dp8390outb(dp8390+Rsar0, crda & 0xFF); 
	dp8390outb(dp8390+Rsar1, (crda>>8) & 0xFF); 
	dp8390outb(dp8390+Cr, Page0|RDMAread|Sta); 
1993/1118    
	crda = to-1-dp8390->bit16; 
	dp8390outb(port+Rbcr0, (len+1+dp8390->bit16) & 0xFF); 
	dp8390outb(port+Rbcr1, ((len+1+dp8390->bit16)>>8) & 0xFF); 
	dp8390outb(port+Rsar0, crda & 0xFF); 
	dp8390outb(port+Rsar1, (crda>>8) & 0xFF); 
	dp8390outb(port+Cr, Page0|RDMAread|Sta); 
1992/1222    
 
1993/0212    
	for(;;){ 
1993/0915    
		crda = dp8390inb(dp8390+Crda0); 
		crda |= dp8390inb(dp8390+Crda1)<<8; 
1993/1118    
		crda = dp8390inb(port+Crda0); 
		crda |= dp8390inb(port+Crda1)<<8; 
1993/0212    
		if(crda == to){ 
			/* 
			 * Start the remote DMA write and make sure 
			 * the registers are correct. 
			 */ 
1993/0915    
			dp8390outb(dp8390+Cr, Page0|RDMAwrite|Sta); 
1993/1118    
			dp8390outb(port+Cr, Page0|RDMAwrite|Sta); 
1992/1222    
 
1993/0915    
			crda = dp8390inb(dp8390+Crda0); 
			crda |= dp8390inb(dp8390+Crda1)<<8; 
1993/1118    
			crda = dp8390inb(port+Crda0); 
			crda |= dp8390inb(port+Crda1)<<8; 
1993/0212    
			if(crda != to) 
				panic("crda write %d to %d\n", crda, to); 
 
1993/1117/sys/src/9/pc/ether8390.c:334,3431993/1118/sys/src/9/pc/ether8390.c:332,341
1992/1222    
	/* 
1993/0212    
	 * Pump the data into the I/O port. 
1992/1222    
	 */ 
1993/1116    
	if(ether->bit16) 
		outss(ether->data, from, len/2); 
1993/1118    
	if(dp8390->bit16) 
		outss(dp8390->data, from, len/2); 
1992/1222    
	else 
1993/1116    
		outsb(ether->data, from, len); 
1993/1118    
		outsb(dp8390->data, from, len); 
1992/1222    
 
	/* 
	 * Wait for the remote DMA to finish. We'll need 
1993/1117/sys/src/9/pc/ether8390.c:344,3661993/1118/sys/src/9/pc/ether8390.c:342,365
1992/1222    
	 * a timeout here if this ever gets called before 
	 * we know there really is a chip there. 
	 */ 
1993/0915    
	while((dp8390inb(dp8390+Isr) & Rdc) == 0) 
1993/1118    
	while((dp8390inb(port+Isr) & Rdc) == 0) 
1992/1222    
			; 
 
1993/0915    
	dp8390outb(dp8390+Isr, Rdc); 
	dp8390outb(dp8390+Cr, cr); 
1993/1118    
	dp8390outb(port+Isr, Rdc); 
	dp8390outb(port+Cr, cr); 
1992/1222    
	return (void*)to; 
} 
 
1993/0212    
static uchar 
1993/0915    
getcurr(ulong dp8390) 
1993/1118    
getcurr(Dp8390 *dp8390) 
1993/0212    
{ 
1993/1118    
	ulong port = dp8390->dp8390; 
1993/0212    
	uchar cr, curr; 
 
1993/0915    
	cr = dp8390inb(dp8390+Cr) & ~Txp; 
	dp8390outb(dp8390+Cr, Page1|(~(Ps1|Ps0) & cr)); 
	curr = dp8390inb(dp8390+Curr); 
	dp8390outb(dp8390+Cr, cr); 
1993/1118    
	cr = dp8390inb(port+Cr) & ~Txp; 
	dp8390outb(port+Cr, Page1|(~(Ps1|Ps0) & cr)); 
	curr = dp8390inb(port+Curr); 
	dp8390outb(port+Cr, cr); 
1993/0212    
	return curr; 
} 
 
1993/1117/sys/src/9/pc/ether8390.c:367,3841993/1118/sys/src/9/pc/ether8390.c:366,388
1993/0213    
static void 
1993/1116    
receive(Ether *ether) 
1993/0213    
{ 
1993/0212    
	uchar curr, len1, *pkt; 
1993/1118    
	Dp8390 *dp8390; 
	uchar curr, *pkt; 
1992/1222    
	Hdr hdr; 
1993/0915    
	ulong dp8390, data, len; 
1993/1118    
	ulong port, data, len, len1; 
1993/1116    
	ushort type; 
	Netfile *f, **fp, **ep; 
1992/1222    
 
1993/1117    
	dp8390 = ((Dp8390*)ether->private)->dp8390; 
1993/1116    
	for(curr = getcurr(dp8390); ether->nxtpkt != curr; curr = getcurr(dp8390)){ 
1993/1118    
	dp8390 = ether->private; 
	port = dp8390->dp8390; 
	for(curr = getcurr(dp8390); dp8390->nxtpkt != curr; curr = getcurr(dp8390)){ 
1993/1116    
		ether->inpackets++; 
1992/1222    
 
1993/1116    
		data = ether->nxtpkt*Dp8390BufSz; 
		(*ether->read)(ctlr, &hdr, data, sizeof(Hdr)); 
1993/1118    
		data = dp8390->nxtpkt*Dp8390BufSz; 
		if(dp8390->ram) 
			memmove(&hdr, (void*)(ether->mem+data), sizeof(Hdr)); 
		else 
			dp8390read(dp8390, &hdr, data, sizeof(Hdr)); 
1992/1222    
 
		/* 
1993/0212    
		 * Don't believe the upper byte count, work it 
1993/1117/sys/src/9/pc/ether8390.c:385,3941993/1118/sys/src/9/pc/ether8390.c:389,398
1993/0212    
		 * out from the software next-page pointer and 
		 * the current next-page pointer. 
1992/1222    
		 */ 
1993/1116    
		if(hdr.next > ether->nxtpkt) 
			len1 = hdr.next - ether->nxtpkt - 1; 
1993/1118    
		if(hdr.next > dp8390->nxtpkt) 
			len1 = hdr.next - dp8390->nxtpkt - 1; 
1993/0212    
		else 
1993/1116    
			len1 = (ether->pstop-ether->nxtpkt) + (hdr.next-ether->pstart) - 1; 
1993/1118    
			len1 = (dp8390->pstop-dp8390->nxtpkt) + (hdr.next-dp8390->pstart) - 1; 
1993/0212    
		if(hdr.len0 > (Dp8390BufSz-sizeof(Hdr))) 
			len1--; 
 
1993/1117/sys/src/9/pc/ether8390.c:397,4091993/1118/sys/src/9/pc/ether8390.c:401,413
1993/0212    
		/* 
		 * Chip is badly scrogged, reinitialise the ring. 
		 */ 
1993/1116    
		if(hdr.next < ether->pstart || hdr.next >= ether->pstop 
1993/1118    
		if(hdr.next < dp8390->pstart || hdr.next >= dp8390->pstop 
1993/0212    
		  || len < 60 || len > sizeof(Etherpkt)){ 
			print("H#%2.2ux#%2.2ux#%2.2ux#%2.2ux,%d|", 
1993/1118    
			print("dp8390: H#%2.2ux#%2.2ux#%2.2ux#%2.2ux,%d\n", 
1993/0212    
				hdr.status, hdr.next, hdr.len0, hdr.len1, len); 
1993/0915    
			dp8390outb(dp8390+Cr, Page0|RDMAabort|Stp); 
1993/1116    
			dp8390ring(ether); 
1993/0915    
			dp8390outb(dp8390+Cr, Page0|RDMAabort|Sta); 
1993/1118    
			dp8390outb(port+Cr, Page0|RDMAabort|Stp); 
			dp8390ring(dp8390); 
			dp8390outb(port+Cr, Page0|RDMAabort|Sta); 
1992/1222    
			return; 
		} 
 
1993/1117/sys/src/9/pc/ether8390.c:412,4311993/1118/sys/src/9/pc/ether8390.c:416,442
1993/1116    
		 * If the packet wraps round the hardware ring, read it in two pieces. 
1993/0212    
		 */ 
1993/1116    
		if((hdr.status & (Fo|Fae|Crce|Prxok)) == Prxok){ 
			pkt = ether->rpkt; 
1993/1118    
			pkt = (uchar*)ðer->rpkt; 
1992/1222    
			data += sizeof(Hdr); 
1993/0212    
			ring->len = len; 
1993/1118    
			len1 = len; 
1993/0212    
 
1993/1116    
			if((data+len) >= ether->pstop*Dp8390BufSz){ 
				ulong count = ether->pstop*Dp8390BufSz - data; 
1993/1118    
			if((data+len1) >= dp8390->pstop*Dp8390BufSz){ 
				ulong count = dp8390->pstop*Dp8390BufSz - data; 
1993/0212    
 
1993/1116    
				(*ether->read)(ctlr, pkt, data, count); 
1993/1118    
				if(dp8390->ram) 
					memmove(pkt, (void*)(ether->mem+data), count); 
				else 
					dp8390read(dp8390, pkt, data, count); 
1993/0212    
				pkt += count; 
1993/1116    
				data = ether->pstart*Dp8390BufSz; 
1993/0212    
				len -= count; 
1993/1118    
				data = dp8390->pstart*Dp8390BufSz; 
				len1 -= count; 
1992/1222    
			} 
1993/0212    
			if(len) 
1993/1116    
				(*ether->read)(ctlr, pkt, data, len); 
1993/1118    
			if(len1){ 
				if(dp8390->ram) 
					memmove(pkt, (void*)(ether->mem+data), len1); 
				else 
					dp8390read(dp8390, pkt, data, len1); 
			} 
1993/0212    
 
1993/1116    
			/* 
			 * Copy the packet to whoever wants it. 
1993/1117/sys/src/9/pc/ether8390.c:440,5301993/1118/sys/src/9/pc/ether8390.c:451,564
1992/1222    
		} 
 
1993/0212    
		/* 
		 * Finished woth this packet, update the 
1993/1118    
		 * Finished with this packet, update the 
1993/0212    
		 * hardware and software ring pointers. 
		 */ 
1993/1116    
		ether->nxtpkt = hdr.next; 
1993/1118    
		dp8390->nxtpkt = hdr.next; 
1993/0212    
 
		hdr.next--; 
1993/1116    
		if(hdr.next < ether->pstart) 
			hdr.next = ether->pstop-1; 
1993/0915    
		dp8390outb(dp8390+Bnry, hdr.next); 
1993/1118    
		if(hdr.next < dp8390->pstart) 
			hdr.next = dp8390->pstop-1; 
		dp8390outb(port+Bnry, hdr.next); 
1992/1222    
	} 
} 
 
1993/0212    
/* 
 * Initiate a transmission. Must be called splhi(). 
 */ 
1992/1222    
void 
1993/1116    
dp8390transmit(Ether *ether) 
1993/1118    
static int 
istxbusy(void *arg) 
1992/1222    
{ 
1993/0915    
	ulong dp8390; 
1992/1222    
	RingBuf *ring; 
1993/1118    
	return ((Dp8390*)arg)->busy == 0; 
} 
1993/0212    
 
1993/1117    
	dp8390 = ((Dp8390*)ether->private)->dp8390; 
1993/1116    
	ring = ðer->tb[ether->ti]; 
	if(ether->tbusy == 0 && ring->owner == Interface){ 
1993/1118    
static long 
write(Ether *ether, void *buf, long n) 
{ 
	Dp8390 *dp8390; 
	ulong port; 
1993/0213    
 
1993/1116    
		ether->tbusy = 1; 
1993/1118    
	dp8390 = ether->private; 
	port = dp8390->dp8390; 
1993/0213    
 
1993/1116    
		(*ether->write)(ctlr, ether->tstart*Dp8390BufSz, ring->pkt, ring->len); 
1993/0213    
                 
1993/0915    
		dp8390outb(dp8390+Tbcr0, ring->len & 0xFF); 
		dp8390outb(dp8390+Tbcr1, (ring->len>>8) & 0xFF); 
		dp8390outb(dp8390+Cr, Page0|RDMAabort|Txp|Sta); 
1993/1118    
	qlock(ðer->tlock); 
	if(waserror()) { 
		qunlock(ðer->tlock); 
		nexterror(); 
1993/0212    
	} 
1993/1118    
 
	tsleep(ðer->tr, istxbusy, dp8390, 10000); 
	if(dp8390->busy) 
		print("dp8390: transmitter jammed\n"); 
	dp8390->busy = 1; 
 
	if(dp8390->ram) 
		memmove((void*)(ether->mem+dp8390->tstart*Dp8390BufSz), buf, n); 
	else 
		dp8390write(dp8390, dp8390->tstart*Dp8390BufSz, buf, n); 
 
	dp8390outb(port+Tbcr0, n & 0xFF); 
	dp8390outb(port+Tbcr1, (n>>8) & 0xFF); 
	dp8390outb(port+Cr, Page0|RDMAabort|Txp|Sta); 
 
	poperror(); 
	qunlock(ðer->tlock); 
 
	return n; 
1993/0212    
} 
 
1993/1116    
static void 
overflow(Ether *ether) 
1993/0212    
{ 
1993/0915    
	ulong dp8390; 
1993/1118    
	Dp8390 *dp8390; 
	ulong port; 
1993/0212    
	uchar txp; 
	int resend; 
 
1993/1117    
	dp8390 = ((Dp8390*)ether->private)->dp8390; 
1993/1118    
	dp8390 = ether->private; 
	port = dp8390->dp8390; 
 
1993/0212    
	/* 
	 * The following procedure is taken from the DP8390[12D] datasheet, 
	 * it seems pretty adamant that this is what has to be done. 
	 */ 
1993/0915    
	txp = dp8390inb(dp8390+Cr) & Txp; 
	dp8390outb(dp8390+Cr, Page0|RDMAabort|Stp); 
1993/1118    
	txp = dp8390inb(port+Cr) & Txp; 
	dp8390outb(port+Cr, Page0|RDMAabort|Stp); 
1993/0212    
	delay(2); 
1993/0915    
	dp8390outb(dp8390+Rbcr0, 0); 
	dp8390outb(dp8390+Rbcr1, 0); 
1993/1118    
	dp8390outb(port+Rbcr0, 0); 
	dp8390outb(port+Rbcr1, 0); 
1993/0212    
 
	resend = 0; 
1993/0915    
	if(txp && (dp8390inb(dp8390+Isr) & (Txe|Ptx)) == 0) 
1993/1118    
	if(txp && (dp8390inb(port+Isr) & (Txe|Ptx)) == 0) 
1993/0212    
		resend = 1; 
 
1993/0915    
	dp8390outb(dp8390+Tcr, Lb); 
	dp8390outb(dp8390+Cr, Page0|RDMAabort|Sta); 
1993/1116    
	(*ether->receive)(ether); 
1993/0915    
	dp8390outb(dp8390+Isr, Ovw); 
1993/1116    
	wakeup(ðer->rr); 
1993/0915    
	dp8390outb(dp8390+Tcr, 0); 
1993/1118    
	dp8390outb(port+Tcr, Lb); 
	dp8390outb(port+Cr, Page0|RDMAabort|Sta); 
	receive(ether); 
	dp8390outb(port+Isr, Ovw); 
	dp8390outb(port+Tcr, 0); 
1993/0212    
 
	if(resend) 
1993/0915    
		dp8390outb(dp8390+Cr, Page0|RDMAabort|Txp|Sta); 
1993/1118    
		dp8390outb(port+Cr, Page0|RDMAabort|Txp|Sta); 
1993/0212    
} 
 
1993/1116    
static void 
interrupt(Ether *ether) 
1993/0212    
{ 
1993/0915    
	ulong dp8390; 
1993/1118    
	Dp8390 *dp8390; 
	ulong port; 
1993/0212    
	uchar isr, r; 
1992/1222    
 
1993/1117    
	dp8390 = ((Dp8390*)ether->private)->dp8390; 
1993/1118    
	dp8390 = ether->private; 
	port = dp8390->dp8390; 
 
1992/1222    
	/* 
	 * While there is something of interest, 
	 * clear all the interrupts and process. 
	 */ 
1993/0915    
	dp8390outb(dp8390+Imr, 0x00); 
	while(isr = dp8390inb(dp8390+Isr)){ 
1993/1118    
	dp8390outb(port+Imr, 0x00); 
	while(isr = dp8390inb(port+Isr)){ 
1992/1222    
 
		if(isr & Ovw){ 
1993/1116    
			overflow(ether); 
1993/0915    
			dp8390outb(dp8390+Isr, Ovw); 
1993/1118    
			dp8390outb(port+Isr, Ovw); 
1993/1116    
			ether->overflows++; 
1992/1222    
		} 
 
1993/1117/sys/src/9/pc/ether8390.c:534,5401993/1118/sys/src/9/pc/ether8390.c:568,574
1992/1222    
		 */ 
		if(isr & (Rxe|Prx)){ 
1993/1116    
			receive(ether); 
1993/0915    
			dp8390outb(dp8390+Isr, Rxe|Prx); 
1993/1118    
			dp8390outb(port+Isr, Rxe|Prx); 
1992/1222    
		} 
 
		/* 
1993/1117/sys/src/9/pc/ether8390.c:543,5931993/1118/sys/src/9/pc/ether8390.c:577,626
1992/1222    
		 * and wake the output routine. 
		 */ 
		if(isr & (Txe|Ptx)){ 
1993/0915    
			r = dp8390inb(dp8390+Tsr); 
1993/1118    
			r = dp8390inb(port+Tsr); 
1993/0212    
			if(isr & Txe){ 
1993/1116    
				if((r & (Cdh|Fu|Crs|Abt)) && ether->debug) 
1993/0212    
					print("Tsr#%2.2ux|", r); 
1993/1118    
				if((r & (Cdh|Fu|Crs|Abt))) 
					print("dp8390: Tsr#%2.2ux\n", r); 
1993/1116    
				ether->oerrs++; 
1993/0212    
			} 
 
1993/0915    
			dp8390outb(dp8390+Isr, Txe|Ptx); 
1993/1118    
			dp8390outb(port+Isr, Txe|Ptx); 
1993/0212    
 
			if(isr & Ptx) 
1993/1116    
				ether->outpackets++; 
1993/1118    
			dp8390->busy = 0; 
1993/1116    
			wakeup(ðer->tr); 
1992/1222    
		} 
1993/0212    
 
		if(isr & Cnt){ 
1993/1116    
			ether->frames += dp8390inb(dp8390+Cntr0); 
			ether->crcs += dp8390inb(dp8390+Cntr1); 
			ether->buffs += dp8390inb(dp8390+Cntr2); 
1993/0915    
			dp8390outb(dp8390+Isr, Cnt); 
1993/1118    
			ether->frames += dp8390inb(port+Cntr0); 
			ether->crcs += dp8390inb(port+Cntr1); 
			ether->buffs += dp8390inb(port+Cntr2); 
			dp8390outb(port+Isr, Cnt); 
1993/0212    
		} 
1992/1222    
	} 
1993/0915    
	dp8390outb(dp8390+Imr, Cnte|Ovwe|Txee|Rxee|Ptxe|Prxe); 
1993/1118    
	dp8390outb(port+Imr, Cnte|Ovwe|Txee|Rxee|Ptxe|Prxe); 
1993/1116    
} 
 
static void 
promiscuous(Ether *ether, int on) 
1993/1118    
promiscuous(void *arg, int on) 
1993/1116    
{ 
1993/1117    
	ulong dp8390; 
1993/1118    
	Dp8390 *dp8390 = ((Ether*)arg)->private; 
1993/1117    
 
	dp8390 = ((Dp8390*)ether->private)->dp8390; 
1993/1116    
	/* 
	 * Set/reset promiscuous mode. 
	 */ 
	if(on) 
		dp8390outb(ether->dp8390+Rcr, Pro|Ab); 
1993/1118    
		dp8390outb(dp8390->dp8390+Rcr, Pro|Ab); 
1993/1116    
	else 
		dp8390outb(ether->dp8390+Rcr, Ab); 
1993/1118    
		dp8390outb(dp8390->dp8390+Rcr, Ab); 
1993/1116    
} 
 
void 
dp8390attach(Ether *ether) 
1993/1118    
static void 
attach(Ether *ether) 
1993/1116    
{ 
1993/1117    
	ulong dp8390; 
1993/1118    
	Dp8390 *dp8390 = ether->private; 
1993/1117    
 
	dp8390 = ((Dp8390*)ether->private)->dp8390; 
1993/1116    
	/* 
	 * Enable the chip for transmit/receive. 
	 * The init routine leaves the chip in monitor 
1993/1117/sys/src/9/pc/ether8390.c:594,6251993/1118/sys/src/9/pc/ether8390.c:627,661
1993/1116    
	 * mode. Clear the missed-packet counter, it 
	 * increments while in monitor mode. 
	 */ 
	dp8390outb(ether->dp8390+Rcr, Ab); 
	dp8390inb(ether->dp8390+Cntr2); 
1993/1118    
	dp8390outb(dp8390->dp8390+Rcr, Ab); 
	dp8390inb(dp8390->dp8390+Cntr2); 
1993/1116    
} 
 
static int 
1993/1118    
int 
1993/1116    
dp8390reset(Ether *ether) 
{ 
	ulong dp8390; 
1993/1118    
	Dp8390 *dp8390; 
	ulong port; 
1993/1116    
 
1993/1117    
	dp8390 = ((Dp8390*)ether->private)->dp8390; 
1993/1118    
	dp8390 = ether->private; 
	port = dp8390->dp8390; 
 
1993/1116    
	/* 
	 * This is the initialisation procedure described 
	 * as 'mandatory' in the datasheet, with references 
	 * to the 3Com503 technical reference manual. 
	 */  
	dp8390disable(ether); 
	if(ether->bit16) 
		dp8390outb(dp8390+Dcr, Ft4|Ls|Wts); 
1993/1118    
	dp8390disable(dp8390); 
	if(dp8390->bit16) 
		dp8390outb(port+Dcr, Ft4|Ls|Wts); 
1993/1116    
	else 
		dp8390outb(dp8390+Dcr, Ft4|Ls); 
1993/1118    
		dp8390outb(port+Dcr, Ft4|Ls); 
1993/1116    
 
	dp8390outb(dp8390+Rbcr0, 0); 
	dp8390outb(dp8390+Rbcr1, 0); 
1993/1118    
	dp8390outb(port+Rbcr0, 0); 
	dp8390outb(port+Rbcr1, 0); 
1993/1116    
 
	dp8390outb(dp8390+Tcr, 0); 
	dp8390outb(dp8390+Rcr, Mon); 
1993/1118    
	dp8390outb(port+Tcr, 0); 
	dp8390outb(port+Rcr, Mon); 
1993/1116    
 
	/* 
	 * Init the ring hardware and software ring pointers. 
1993/1117/sys/src/9/pc/ether8390.c:626,6421993/1118/sys/src/9/pc/ether8390.c:662,678
1993/1116    
	 * Can't initialise ethernet address as we may not know 
	 * it yet. 
	 */ 
	dp8390ring(ether); 
	dp8390outb(dp8390+Tpsr, ether->tstart); 
1993/1118    
	dp8390ring(dp8390); 
	dp8390outb(port+Tpsr, dp8390->tstart); 
1993/1116    
 
	dp8390outb(dp8390+Isr, 0xFF); 
	dp8390outb(dp8390+Imr, Cnte|Ovwe|Txee|Rxee|Ptxe|Prxe); 
1993/1118    
	dp8390outb(port+Isr, 0xFF); 
	dp8390outb(port+Imr, Cnte|Ovwe|Txee|Rxee|Ptxe|Prxe); 
1993/1116    
 
	/* 
	 * Leave the chip initialised, 
	 * but in monitor mode. 
	 */ 
	dp8390outb(dp8390+Cr, Page0|RDMAabort|Sta); 
1993/1118    
	dp8390outb(port+Cr, Page0|RDMAabort|Sta); 
1993/1116    
 
	/* 
	 * Set up the software configuration. 


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