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

1995/0409/pc/ether8390.c (diff list | history)

1995/0408/sys/src/9/pc/ether8390.c:14,191995/0409/sys/src/9/pc/ether8390.c:14,22 (short | long | prev | next)
1992/1222    
 
1993/1116    
#include "etherif.h" 
1992/1222    
 
1995/0409    
extern int slowinb(ulong); 
extern void slowoutb(ulong, uchar); 
 
1992/1222    
enum { 
	Cr		= 0x00,		/* command register, all pages */ 
 
1995/0408/sys/src/9/pc/ether8390.c:146,1711995/0409/sys/src/9/pc/ether8390.c:149,154
1992/1222    
	uchar	len1; 
} Hdr; 
 
1995/0408    
/* 
 *  the 8390 register accesses must not be too close together 
 */ 
void 
dp8390outb(ulong port, uchar x) 
{ 
	outb(port, x); 
	microdelay(0); 
} 
                 
long 
dp8390inb(ulong port) 
{ 
	long x; 
                 
	x = inb(port); 
	microdelay(0); 
	return x; 
} 
                 
1992/1222    
static void 
1993/1117    
dp8390disable(Dp8390 *dp8390) 
1992/1222    
{ 
1995/0408/sys/src/9/pc/ether8390.c:180,1891995/0409/sys/src/9/pc/ether8390.c:163,172
1992/1222    
	 * chip there if this is called when probing for a device 
	 * at boot. 
	 */ 
1995/0408    
	dp8390outb(port+Cr, Page0|RDMAabort|Stp); 
	dp8390outb(port+Rbcr0, 0); 
	dp8390outb(port+Rbcr1, 0); 
	for(timo = 10000; (dp8390inb(port+Isr) & Rst) == 0 && timo; timo--) 
1995/0409    
	slowoutb(port+Cr, Page0|RDMAabort|Stp); 
	slowoutb(port+Rbcr0, 0); 
	slowoutb(port+Rbcr1, 0); 
	for(timo = 10000; (slowinb(port+Isr) & Rst) == 0 && timo; timo--) 
1992/1222    
			; 
} 
 
1995/0408/sys/src/9/pc/ether8390.c:192,2041995/0409/sys/src/9/pc/ether8390.c:175,187
1993/0212    
{ 
1993/1118    
	ulong port = dp8390->dp8390; 
1993/0212    
 
1995/0408    
	dp8390outb(port+Pstart, dp8390->pstart); 
	dp8390outb(port+Pstop, dp8390->pstop); 
	dp8390outb(port+Bnry, dp8390->pstop-1); 
1995/0409    
	slowoutb(port+Pstart, dp8390->pstart); 
	slowoutb(port+Pstop, dp8390->pstop); 
	slowoutb(port+Bnry, dp8390->pstop-1); 
1993/0212    
 
1995/0408    
	dp8390outb(port+Cr, Page1|RDMAabort|Stp); 
	dp8390outb(port+Curr, dp8390->pstart); 
	dp8390outb(port+Cr, Page0|RDMAabort|Stp); 
1995/0409    
	slowoutb(port+Cr, Page1|RDMAabort|Stp); 
	slowoutb(port+Curr, dp8390->pstart); 
	slowoutb(port+Cr, Page0|RDMAabort|Stp); 
1993/0915    
 
1993/1117    
	dp8390->nxtpkt = dp8390->pstart; 
1993/0212    
} 
1995/0408/sys/src/9/pc/ether8390.c:217,2271995/0409/sys/src/9/pc/ether8390.c:200,210
1992/1222    
	 * addresses as we never set the multicast 
	 * enable. 
	 */ 
1995/0408    
	cr = dp8390inb(port+Cr) & ~Txp; 
	dp8390outb(port+Cr, Page1|(~(Ps1|Ps0) & cr)); 
1995/0409    
	cr = slowinb(port+Cr) & ~Txp; 
	slowoutb(port+Cr, Page1|(~(Ps1|Ps0) & cr)); 
1993/1116    
	for(i = 0; i < sizeof(ether->ea); i++) 
1995/0408    
		dp8390outb(port+Par0+i, ether->ea[i]); 
	dp8390outb(port+Cr, cr); 
1995/0409    
		slowoutb(port+Par0+i, ether->ea[i]); 
	slowoutb(port+Cr, cr); 
1992/1222    
} 
 
1993/0915    
void 
1995/0408/sys/src/9/pc/ether8390.c:238,2481995/0409/sys/src/9/pc/ether8390.c:221,231
1993/0915    
	 * addresses as we never set the multicast 
	 * enable. 
	 */ 
1995/0408    
	cr = dp8390inb(port+Cr) & ~Txp; 
	dp8390outb(port+Cr, Page1|(~(Ps1|Ps0) & cr)); 
1995/0409    
	cr = slowinb(port+Cr) & ~Txp; 
	slowoutb(port+Cr, Page1|(~(Ps1|Ps0) & cr)); 
1993/1116    
	for(i = 0; i < sizeof(ether->ea); i++) 
1995/0408    
		ether->ea[i] = dp8390inb(port+Par0+i); 
	dp8390outb(port+Cr, cr); 
1995/0409    
		ether->ea[i] = slowinb(port+Par0+i); 
	slowoutb(port+Cr, cr); 
1993/0915    
} 
 
1994/0128    
void* 
1995/0408/sys/src/9/pc/ether8390.c:257,2651995/0409/sys/src/9/pc/ether8390.c:240,248
1992/1222    
	 * using the DP8390 remote DMA facility, and place it at 
	 * 'to' in main memory, via the I/O data port. 
	 */ 
1995/0408    
	cr = dp8390inb(port+Cr) & ~Txp; 
	dp8390outb(port+Cr, Page0|RDMAabort|Sta); 
	dp8390outb(port+Isr, Rdc); 
1995/0409    
	cr = slowinb(port+Cr) & ~Txp; 
	slowoutb(port+Cr, Page0|RDMAabort|Sta); 
	slowoutb(port+Isr, Rdc); 
1992/1222    
 
	/* 
	 * Set up the remote DMA address and count. 
1995/0408/sys/src/9/pc/ether8390.c:266,2811995/0409/sys/src/9/pc/ether8390.c:249,264
1992/1222    
	 */ 
1993/1117    
	if(dp8390->bit16) 
1992/1222    
		len = ROUNDUP(len, 2); 
1995/0408    
	dp8390outb(port+Rbcr0, len & 0xFF); 
	dp8390outb(port+Rbcr1, (len>>8) & 0xFF); 
	dp8390outb(port+Rsar0, from & 0xFF); 
	dp8390outb(port+Rsar1, (from>>8) & 0xFF); 
1995/0409    
	slowoutb(port+Rbcr0, len & 0xFF); 
	slowoutb(port+Rbcr1, (len>>8) & 0xFF); 
	slowoutb(port+Rsar0, from & 0xFF); 
	slowoutb(port+Rsar1, (from>>8) & 0xFF); 
1992/1222    
 
	/* 
	 * Start the remote DMA read and suck the data 
	 * out of the I/O port. 
	 */ 
1995/0408    
	dp8390outb(port+Cr, Page0|RDMAread|Sta); 
1995/0409    
	slowoutb(port+Cr, Page0|RDMAread|Sta); 
1993/1117    
	if(dp8390->bit16) 
		inss(dp8390->data, to, len/2); 
1992/1222    
	else 
1995/0408/sys/src/9/pc/ether8390.c:288,2981995/0409/sys/src/9/pc/ether8390.c:271,281
1992/1222    
	 * to the miracles of the bus, we could get this far 
	 * and still be talking to a slot full of nothing. 
	 */ 
1995/0408    
	for(timo = 10000; (dp8390inb(port+Isr) & Rdc) == 0 && timo; timo--) 
1995/0409    
	for(timo = 10000; (slowinb(port+Isr) & Rdc) == 0 && timo; timo--) 
1992/1222    
			; 
 
1995/0408    
	dp8390outb(port+Isr, Rdc); 
	dp8390outb(port+Cr, cr); 
1995/0409    
	slowoutb(port+Isr, Rdc); 
	slowoutb(port+Cr, cr); 
1992/1222    
	return to; 
} 
 
1995/0408/sys/src/9/pc/ether8390.c:315,3231995/0409/sys/src/9/pc/ether8390.c:298,306
1992/1222    
	 * using the DP8390 remote DMA facility, reading it at 
	 * 'from' in main memory, via the I/O data port. 
	 */ 
1995/0408    
	cr = dp8390inb(port+Cr) & ~Txp; 
	dp8390outb(port+Cr, Page0|RDMAabort|Sta); 
	dp8390outb(port+Isr, Rdc); 
1995/0409    
	cr = slowinb(port+Cr) & ~Txp; 
	slowoutb(port+Cr, Page0|RDMAabort|Sta); 
	slowoutb(port+Isr, Rdc); 
1992/1222    
 
1993/1118    
	if(dp8390->bit16) 
1993/0212    
		len = ROUNDUP(len, 2); 
1995/0408/sys/src/9/pc/ether8390.c:328,3511995/0409/sys/src/9/pc/ether8390.c:311,334
1993/0212    
	 * the initial set up for read. 
1992/1222    
	 */ 
1993/1118    
	crda = to-1-dp8390->bit16; 
1995/0408    
	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); 
1995/0409    
	slowoutb(port+Rbcr0, (len+1+dp8390->bit16) & 0xFF); 
	slowoutb(port+Rbcr1, ((len+1+dp8390->bit16)>>8) & 0xFF); 
	slowoutb(port+Rsar0, crda & 0xFF); 
	slowoutb(port+Rsar1, (crda>>8) & 0xFF); 
	slowoutb(port+Cr, Page0|RDMAread|Sta); 
1992/1222    
 
1993/0212    
	for(;;){ 
1995/0408    
		crda = dp8390inb(port+Crda0); 
		crda |= dp8390inb(port+Crda1)<<8; 
1995/0409    
		crda = slowinb(port+Crda0); 
		crda |= slowinb(port+Crda1)<<8; 
1993/0212    
		if(crda == to){ 
			/* 
			 * Start the remote DMA write and make sure 
			 * the registers are correct. 
			 */ 
1995/0408    
			dp8390outb(port+Cr, Page0|RDMAwrite|Sta); 
1995/0409    
			slowoutb(port+Cr, Page0|RDMAwrite|Sta); 
1992/1222    
 
1995/0408    
			crda = dp8390inb(port+Crda0); 
			crda |= dp8390inb(port+Crda1)<<8; 
1995/0409    
			crda = slowinb(port+Crda0); 
			crda |= slowinb(port+Crda1)<<8; 
1993/0212    
			if(crda != to) 
				panic("crda write %d to %d\n", crda, to); 
 
1995/0408/sys/src/9/pc/ether8390.c:366,3721995/0409/sys/src/9/pc/ether8390.c:349,355
1994/0202    
	 * be almost immediate. 
1992/1222    
	 */ 
1994/0201    
	tries = 0; 
1995/0408    
	while((dp8390inb(port+Isr) & Rdc) == 0){ 
1995/0409    
	while((slowinb(port+Isr) & Rdc) == 0){ 
1994/0202    
		if(tries++ >= 100000){ 
			print("dp8390write dma timed out\n"); 
1994/0201    
			break; 
1995/0408/sys/src/9/pc/ether8390.c:373,3801995/0409/sys/src/9/pc/ether8390.c:356,363
1994/0201    
		} 
1994/0202    
	} 
1992/1222    
 
1995/0408    
	dp8390outb(port+Isr, Rdc); 
	dp8390outb(port+Cr, cr); 
1995/0409    
	slowoutb(port+Isr, Rdc); 
	slowoutb(port+Cr, cr); 
1994/0202    
	splx(s); 
 
1992/1222    
	return (void*)to; 
1995/0408/sys/src/9/pc/ether8390.c:386,3951995/0409/sys/src/9/pc/ether8390.c:369,378
1993/1118    
	ulong port = dp8390->dp8390; 
1993/0212    
	uchar cr, curr; 
 
1995/0408    
	cr = dp8390inb(port+Cr) & ~Txp; 
	dp8390outb(port+Cr, Page1|(~(Ps1|Ps0) & cr)); 
	curr = dp8390inb(port+Curr); 
	dp8390outb(port+Cr, cr); 
1995/0409    
	cr = slowinb(port+Cr) & ~Txp; 
	slowoutb(port+Cr, Page1|(~(Ps1|Ps0) & cr)); 
	curr = slowinb(port+Curr); 
	slowoutb(port+Cr, cr); 
1993/0212    
	return curr; 
} 
 
1995/0408/sys/src/9/pc/ether8390.c:433,4411995/0409/sys/src/9/pc/ether8390.c:416,424
1993/0212    
		  || len < 60 || len > sizeof(Etherpkt)){ 
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); 
1995/0408    
			dp8390outb(port+Cr, Page0|RDMAabort|Stp); 
1995/0409    
			slowoutb(port+Cr, Page0|RDMAabort|Stp); 
1993/1118    
			dp8390ring(dp8390); 
1995/0408    
			dp8390outb(port+Cr, Page0|RDMAabort|Sta); 
1995/0409    
			slowoutb(port+Cr, Page0|RDMAabort|Sta); 
1992/1222    
			return; 
		} 
 
1995/0408/sys/src/9/pc/ether8390.c:484,4901995/0409/sys/src/9/pc/ether8390.c:467,473
1993/0212    
		hdr.next--; 
1993/1118    
		if(hdr.next < dp8390->pstart) 
			hdr.next = dp8390->pstop-1; 
1995/0408    
		dp8390outb(port+Bnry, hdr.next); 
1995/0409    
		slowoutb(port+Bnry, hdr.next); 
1992/1222    
	} 
} 
 
1995/0408/sys/src/9/pc/ether8390.c:536,5441995/0409/sys/src/9/pc/ether8390.c:519,527
1993/1120    
	if(dp8390->ram == 0) 
		dp8390write(dp8390, dp8390->tstart*Dp8390BufSz, pkt, len); 
 
1995/0408    
	dp8390outb(port+Tbcr0, len & 0xFF); 
	dp8390outb(port+Tbcr1, (len>>8) & 0xFF); 
	dp8390outb(port+Cr, Page0|RDMAabort|Txp|Sta); 
1995/0409    
	slowoutb(port+Tbcr0, len & 0xFF); 
	slowoutb(port+Tbcr1, (len>>8) & 0xFF); 
	slowoutb(port+Cr, Page0|RDMAabort|Txp|Sta); 
1993/1118    
 
1993/1120    
	return len; 
1993/0212    
} 
1995/0408/sys/src/9/pc/ether8390.c:558,5811995/0409/sys/src/9/pc/ether8390.c:541,564
1993/0212    
	 * The following procedure is taken from the DP8390[12D] datasheet, 
	 * it seems pretty adamant that this is what has to be done. 
	 */ 
1995/0408    
	txp = dp8390inb(port+Cr) & Txp; 
	dp8390outb(port+Cr, Page0|RDMAabort|Stp); 
1995/0409    
	txp = slowinb(port+Cr) & Txp; 
	slowoutb(port+Cr, Page0|RDMAabort|Stp); 
1993/0212    
	delay(2); 
1995/0408    
	dp8390outb(port+Rbcr0, 0); 
	dp8390outb(port+Rbcr1, 0); 
1995/0409    
	slowoutb(port+Rbcr0, 0); 
	slowoutb(port+Rbcr1, 0); 
1993/0212    
 
	resend = 0; 
1995/0408    
	if(txp && (dp8390inb(port+Isr) & (Txe|Ptx)) == 0) 
1995/0409    
	if(txp && (slowinb(port+Isr) & (Txe|Ptx)) == 0) 
1993/0212    
		resend = 1; 
 
1995/0408    
	dp8390outb(port+Tcr, Lb); 
	dp8390outb(port+Cr, Page0|RDMAabort|Sta); 
1995/0409    
	slowoutb(port+Tcr, Lb); 
	slowoutb(port+Cr, Page0|RDMAabort|Sta); 
1993/1118    
	receive(ether); 
1995/0408    
	dp8390outb(port+Isr, Ovw); 
	dp8390outb(port+Tcr, 0); 
1995/0409    
	slowoutb(port+Isr, Ovw); 
	slowoutb(port+Tcr, 0); 
1993/0212    
 
	if(resend) 
1995/0408    
		dp8390outb(port+Cr, Page0|RDMAabort|Txp|Sta); 
1995/0409    
		slowoutb(port+Cr, Page0|RDMAabort|Txp|Sta); 
1993/0212    
} 
 
1993/1116    
static void 
1995/0408/sys/src/9/pc/ether8390.c:596,6071995/0409/sys/src/9/pc/ether8390.c:579,590
1992/1222    
	 * While there is something of interest, 
	 * clear all the interrupts and process. 
	 */ 
1995/0408    
	dp8390outb(port+Imr, 0x00); 
	while(isr = dp8390inb(port+Isr)){ 
1995/0409    
	slowoutb(port+Imr, 0x00); 
	while(isr = slowinb(port+Isr)){ 
1992/1222    
 
		if(isr & Ovw){ 
1993/1116    
			overflow(ether); 
1995/0408    
			dp8390outb(port+Isr, Ovw); 
1995/0409    
			slowoutb(port+Isr, Ovw); 
1993/1116    
			ether->overflows++; 
1992/1222    
		} 
 
1995/0408/sys/src/9/pc/ether8390.c:611,6171995/0409/sys/src/9/pc/ether8390.c:594,600
1992/1222    
		 */ 
		if(isr & (Rxe|Prx)){ 
1993/1116    
			receive(ether); 
1995/0408    
			dp8390outb(port+Isr, Rxe|Prx); 
1995/0409    
			slowoutb(port+Isr, Rxe|Prx); 
1992/1222    
		} 
 
		/* 
1995/0408/sys/src/9/pc/ether8390.c:620,6261995/0409/sys/src/9/pc/ether8390.c:603,609
1992/1222    
		 * and wake the output routine. 
		 */ 
		if(isr & (Txe|Ptx)){ 
1995/0408    
			r = dp8390inb(port+Tsr); 
1995/0409    
			r = slowinb(port+Tsr); 
1993/0212    
			if(isr & Txe){ 
1993/1118    
				if((r & (Cdh|Fu|Crs|Abt))) 
					print("dp8390: Tsr#%2.2ux\n", r); 
1995/0408/sys/src/9/pc/ether8390.c:627,6331995/0409/sys/src/9/pc/ether8390.c:610,616
1993/1116    
				ether->oerrs++; 
1993/0212    
			} 
 
1995/0408    
			dp8390outb(port+Isr, Txe|Ptx); 
1995/0409    
			slowoutb(port+Isr, Txe|Ptx); 
1993/0212    
 
			if(isr & Ptx) 
1993/1116    
				ether->outpackets++; 
1995/0408/sys/src/9/pc/ether8390.c:636,6481995/0409/sys/src/9/pc/ether8390.c:619,631
1992/1222    
		} 
1993/0212    
 
		if(isr & Cnt){ 
1995/0408    
			ether->frames += dp8390inb(port+Cntr0); 
			ether->crcs += dp8390inb(port+Cntr1); 
			ether->buffs += dp8390inb(port+Cntr2); 
			dp8390outb(port+Isr, Cnt); 
1995/0409    
			ether->frames += slowinb(port+Cntr0); 
			ether->crcs += slowinb(port+Cntr1); 
			ether->buffs += slowinb(port+Cntr2); 
			slowoutb(port+Isr, Cnt); 
1993/0212    
		} 
1992/1222    
	} 
1995/0408    
	dp8390outb(port+Imr, Cnte|Ovwe|Txee|Rxee|Ptxe|Prxe); 
1995/0409    
	slowoutb(port+Imr, Cnte|Ovwe|Txee|Rxee|Ptxe|Prxe); 
1993/1116    
} 
 
static void 
1995/0408/sys/src/9/pc/ether8390.c:654,6621995/0409/sys/src/9/pc/ether8390.c:637,645
1993/1116    
	 * Set/reset promiscuous mode. 
	 */ 
	if(on) 
1995/0408    
		dp8390outb(dp8390->dp8390+Rcr, Pro|Ab); 
1995/0409    
		slowoutb(dp8390->dp8390+Rcr, Pro|Ab); 
1993/1116    
	else 
1995/0408    
		dp8390outb(dp8390->dp8390+Rcr, Ab); 
1995/0409    
		slowoutb(dp8390->dp8390+Rcr, Ab); 
1993/1116    
} 
 
1993/1118    
static void 
1995/0408/sys/src/9/pc/ether8390.c:670,6771995/0409/sys/src/9/pc/ether8390.c:653,660
1993/1116    
	 * mode. Clear the missed-packet counter, it 
	 * increments while in monitor mode. 
	 */ 
1995/0408    
	dp8390outb(dp8390->dp8390+Rcr, Ab); 
	dp8390inb(dp8390->dp8390+Cntr2); 
1995/0409    
	slowoutb(dp8390->dp8390+Rcr, Ab); 
	slowinb(dp8390->dp8390+Cntr2); 
1993/1116    
} 
 
1993/1118    
int 
1995/0408/sys/src/9/pc/ether8390.c:690,7041995/0409/sys/src/9/pc/ether8390.c:673,687
1993/1116    
	 */  
1993/1118    
	dp8390disable(dp8390); 
	if(dp8390->bit16) 
1995/0408    
		dp8390outb(port+Dcr, Ft4|Ls|Wts); 
1995/0409    
		slowoutb(port+Dcr, Ft4|Ls|Wts); 
1993/1116    
	else 
1995/0408    
		dp8390outb(port+Dcr, Ft4|Ls); 
1995/0409    
		slowoutb(port+Dcr, Ft4|Ls); 
1993/1116    
 
1995/0408    
	dp8390outb(port+Rbcr0, 0); 
	dp8390outb(port+Rbcr1, 0); 
1995/0409    
	slowoutb(port+Rbcr0, 0); 
	slowoutb(port+Rbcr1, 0); 
1993/1116    
 
1995/0408    
	dp8390outb(port+Tcr, 0); 
	dp8390outb(port+Rcr, Mon); 
1995/0409    
	slowoutb(port+Tcr, 0); 
	slowoutb(port+Rcr, Mon); 
1993/1116    
 
	/* 
	 * Init the ring hardware and software ring pointers. 
1995/0408/sys/src/9/pc/ether8390.c:706,7211995/0409/sys/src/9/pc/ether8390.c:689,704
1993/1116    
	 * it yet. 
	 */ 
1993/1118    
	dp8390ring(dp8390); 
1995/0408    
	dp8390outb(port+Tpsr, dp8390->tstart); 
1995/0409    
	slowoutb(port+Tpsr, dp8390->tstart); 
1993/1116    
 
1995/0408    
	dp8390outb(port+Isr, 0xFF); 
	dp8390outb(port+Imr, Cnte|Ovwe|Txee|Rxee|Ptxe|Prxe); 
1995/0409    
	slowoutb(port+Isr, 0xFF); 
	slowoutb(port+Imr, Cnte|Ovwe|Txee|Rxee|Ptxe|Prxe); 
1993/1116    
 
	/* 
	 * Leave the chip initialised, 
	 * but in monitor mode. 
	 */ 
1995/0408    
	dp8390outb(port+Cr, Page0|RDMAabort|Sta); 
1995/0409    
	slowoutb(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)