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

1992/0917/pc/devether.c (diff list | history)

1992/0916/sys/src/9/pc/devether.c:13,191992/0917/sys/src/9/pc/devether.c:13,19 (short | long | prev | next)
1992/0424    
typedef struct Ctlr Ctlr; 
1992/0403    
 
1992/0424    
struct Hw { 
1992/0909    
	void	(*reset)(Ctlr*); 
1992/0917    
	int	(*reset)(Ctlr*); 
1992/0909    
	void	(*init)(Ctlr*); 
	void	(*mode)(Ctlr*, int); 
	void	(*online)(Ctlr*, int); 
1992/0916/sys/src/9/pc/devether.c:77,821992/0917/sys/src/9/pc/devether.c:77,83
1992/0403    
	QLock; 
 
1992/0424    
	Hw	*hw; 
1992/0917    
	int	present; 
1992/0403    
 
1992/0424    
	ushort	nrb;		/* number of software receive buffers */ 
	ushort	ntb;		/* number of software transmit buffers */ 
1992/0916/sys/src/9/pc/devether.c:116,1211992/0917/sys/src/9/pc/devether.c:117,124
1992/0425    
Chan* 
etherattach(char *spec) 
1992/0424    
{ 
1992/0917    
	if(ctlr[0].present == 0) 
		error(Enodev); 
1992/0425    
	return devattach('l', spec); 
1992/0424    
} 
1992/0411    
 
1992/0916/sys/src/9/pc/devether.c:498,5041992/0917/sys/src/9/pc/devether.c:501,511
1992/0410    
 
1992/0625    
	cp = &ctlr[0]; 
1992/0424    
	cp->hw = &wd8013; 
	(*cp->hw->reset)(cp); 
1992/0917    
	if((*cp->hw->reset)(cp) < 0){ 
		cp->present = 0; 
		return; 
	} 
	cp->present = 1; 
1992/0410    
 
1992/0424    
	memset(cp->ba, 0xFF, sizeof(cp->ba)); 
1992/0410    
 
1992/0916/sys/src/9/pc/devether.c:524,5291992/0917/sys/src/9/pc/devether.c:531,539
1992/0424    
	Ctlr *cp = &ctlr[ctlrno]; 
	int i; 
1992/0403    
 
1992/0917    
	if(cp->present == 0) 
		return; 
 
1992/0424    
	cp->rh = 0; 
	cp->ri = 0; 
	for(i = 0; i < cp->nrb; i++) 
1992/0916/sys/src/9/pc/devether.c:601,6061992/0917/sys/src/9/pc/devether.c:611,640
1992/0424    
			uchar	curr; 
			uchar	mar[8]; 
		}; 
1992/0917    
		struct {			/* Page2, read */ 
			uchar	cr; 
			uchar	pstart; 
			uchar	pstop; 
			uchar	dummy1[1]; 
			uchar	tstart; 
			uchar	next; 
			uchar	block; 
			uchar	enh; 
			uchar	dummy2[4]; 
			uchar	rcon; 
			uchar	tcon; 
			uchar	dcon; 
			uchar	intmask; 
		} r2; 
		struct {			/* Page2, write */ 
			uchar	cr; 
			uchar	trincrl; 
			uchar	trincrh; 
			uchar	dummy1[2]; 
			uchar	next; 
			uchar	block; 
			uchar	enh; 
		} w2; 
1992/0424    
	}; 
} Wd8013; 
1992/0403    
 
1992/0916/sys/src/9/pc/devether.c:607,6141992/0917/sys/src/9/pc/devether.c:641,659
1992/0905    
enum { 
	MENB		= 0x40,			/* memory enable */ 
 
	L16EN		= 0x40,			/* enable 16-bit LAN operation */ 
	M16EN		= 0x80,			/* enable 16-bit memory access */ 
1992/0917    
	/* bit definitions for 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 */ 
 
	/* bit defintitions for DP8390/83C690 cr */ 
	Page0		= (0<<6), 
	Page1		= (1<<6), 
	Page2		= (2<<6), 
	RD2		= (4<<3), 
	TXP		= (1<<2), 
	STA		= (1<<1), 
	STP		= (1<<0), 
1992/0905    
}; 
 
1992/0424    
#define IN(hw, m)	inb((hw)->addr+OFFSETOF(Wd8013, m)) 
1992/0916/sys/src/9/pc/devether.c:648,6571992/0917/sys/src/9/pc/devether.c:693,703
1992/0906    
	9, 3, 5, 7, 10, 11, 15, 4, 
}; 
 
1992/0917    
 
1992/0424    
/* 
1992/0906    
 *  get configuration parameters, enable memory 
1992/0424    
 */ 
static void 
1992/0917    
static int 
1992/0424    
wd8013reset(Ctlr *cp) 
1992/0403    
{ 
1992/0424    
	Hw *hw = cp->hw; 
1992/0916/sys/src/9/pc/devether.c:662,6671992/0917/sys/src/9/pc/devether.c:708,721
1992/0906    
	uchar irr; 
1992/0905    
	ulong ram; 
1992/0403    
 
1992/0917    
	msr = IN(hw, msr); 
	icr = IN(hw, icr); 
	irr = IN(hw, irr); 
	laar = IN(hw, laar); 
 
	if(msr == 0xff || icr == 0xff || irr == 0xff || laar == 0xff) 
		return -1; 
 
1992/0915    
	if(cp->rb == 0){ 
		cp->rb = xspanalloc(sizeof(Buffer)*Nrb, BY2PG, 0); 
		cp->nrb = Nrb; 
1992/0916/sys/src/9/pc/devether.c:669,6791992/0917/sys/src/9/pc/devether.c:723,728
1992/0915    
		cp->ntb = Ntb; 
	} 
1992/0424    
 
	msr = IN(hw, msr); 
1992/0906    
	icr = IN(hw, icr); 
	irr = IN(hw, irr); 
	laar = IN(hw, laar); 
1992/0424    
                 
1992/0906    
	/* ethernet address */ 
1992/0424    
	for(i = 0; i < sizeof(cp->ea); i++) 
		cp->ea[i] = IN(hw, lan[i]); 
1992/0916/sys/src/9/pc/devether.c:708,7171992/0917/sys/src/9/pc/devether.c:757,767
1992/0906    
	/* enable interface RAM, set interface width */ 
	OUT(hw, msr, MENB|msr); 
	if(hw->bt16) 
1992/0915    
		OUT(hw, laar, laar|L16EN|M16EN); 
1992/0917    
		OUT(hw, laar, laar|L16EN|M16EN|ZeroWS16); 
1992/0906    
 
1992/0424    
	(*hw->init)(cp); 
1992/0906    
	setvec(Int0vec + hw->lvl, hw->intr); 
1992/0917    
	return 0; 
1992/0424    
} 
1992/0403    
 
1992/0505    
static void 
1992/0916/sys/src/9/pc/devether.c:719,7291992/0917/sys/src/9/pc/devether.c:769,779
1992/0505    
{ 
	Hw *hw = cp->hw; 
 
	OUT(hw, w.cr, 0x21);			/* Page0|RD2|STP */ 
1992/0917    
	OUT(hw, w.cr, Page0|RD2|STP); 
1992/0505    
	OUT(hw, w.bnry, hw->pstart); 
	OUT(hw, w.cr, 0x61);			/* Page1|RD2|STP */ 
1992/0917    
	OUT(hw, w.cr, Page1|RD2|STP); 
1992/0505    
	OUT(hw, curr, hw->pstart+1); 
	OUT(hw, w.cr, 0x22);			/* Page0|RD2|STA */ 
1992/0917    
	OUT(hw, w.cr, Page0|RD2|STA); 
1992/0505    
} 
 
1992/0424    
/* 
1992/0916/sys/src/9/pc/devether.c:736,7441992/0917/sys/src/9/pc/devether.c:786,794
1992/0424    
	Hw *hw = cp->hw; 
	int i; 
 
	OUT(hw, w.cr, 0x21);			/* Page0|RD2|STP */ 
1992/0917    
	OUT(hw, w.cr, Page0|RD2|STP); 
1992/0906    
	if(hw->bt16) 
1992/0916    
		OUT(hw, w.dcr, 0x01);		/* 16 bit interface */ 
1992/0917    
		OUT(hw, w.dcr, (1<<0)|(3<<5));	/* 16 bit interface, 12 byte DMA burst */ 
1992/0906    
	else 
		OUT(hw, w.dcr, 0x48);		/* FT1|LS */ 
1992/0424    
	OUT(hw, w.rbcr0, 0); 
1992/0916/sys/src/9/pc/devether.c:755,7661992/0917/sys/src/9/pc/devether.c:805,816
1992/0424    
	OUT(hw, w.isr, 0xFF); 
	OUT(hw, w.imr, 0x1F);			/* OVWE|TXEE|RXEE|PTXE|PRXE */ 
 
	OUT(hw, w.cr, 0x61);			/* Page1|RD2|STP */ 
1992/0917    
	OUT(hw, w.cr, Page1|RD2|STP); 
1992/0424    
	for(i = 0; i < sizeof(cp->ea); i++) 
		OUT(hw, par[i], cp->ea[i]); 
1992/0501    
	OUT(hw, curr, hw->pstart+1); 
1992/0424    
 
	OUT(hw, w.cr, 0x22);			/* Page0|RD2|STA */ 
1992/0917    
	OUT(hw, w.cr, Page0|RD2|STA); 
1992/0424    
	OUT(hw, w.tpsr, 0); 
1992/0403    
} 
 
1992/0916/sys/src/9/pc/devether.c:810,8151992/0917/sys/src/9/pc/devether.c:860,888
1992/0915    
	splx(s); 
} 
 
1992/0917    
/* 
 *  hack to keep away from the card's memory while it is receiving 
 *  a packet.  This is only a problem on the NCR 3170 safari. 
 * 
 *  we peek at the DMA registers and, if they are changing, wait. 
 */ 
void 
waitfordma(Hw *hw) 
{ 
	uchar a,b,c; 
 
	for(;;delay(10)){ 
		a = IN(hw, r.clda0); 
		b = IN(hw, r.clda0); 
		if(a != b) 
			continue; 
		c = IN(hw, r.clda0); 
		if(c != b) 
			continue; 
		break; 
	} 
} 
 
1992/0915    
static void 
1992/0424    
wd8013receive(Ctlr *cp) 
1992/0403    
{ 
1992/0916/sys/src/9/pc/devether.c:817,8451992/0917/sys/src/9/pc/devether.c:890,917
1992/0424    
	Buffer *rb; 
	uchar bnry, curr, next; 
	Ring *p; 
1992/0501    
	int len; 
1992/0917    
	int i, len; 
1992/0424    
 
	bnry = IN(hw, r.bnry); 
1992/0501    
	next = bnry+1; 
	if(next >= hw->pstop) 
		next = hw->pstart; 
1992/0424    
	for(;;){ 
		OUT(hw, w.cr, 0x62);		/* Page1|RD2|STA */ 
1992/0917    
	for(i = 0; ; i++){ 
		OUT(hw, w.cr, Page1|RD2|STA); 
1992/0424    
		curr = IN(hw, curr); 
		OUT(hw, w.cr, 0x22);		/* Page0|RD2|STA */ 
1992/0917    
		OUT(hw, w.cr, Page0|RD2|STA); 
1992/0424    
		if(next == curr) 
			break; 
1992/0917    
		waitfordma(hw); 
1992/0424    
		cp->inpackets++; 
		p = &((Ring*)hw->ram)[next]; 
1992/0505    
		len = ((p->len1<<8)|p->len0)-4; 
		if(p->next < hw->pstart || p->next >= hw->pstop || len < 60){ 
1992/0915    
/*			print("%d/%d : #%2.2ux #%2.2ux  #%2.2ux #%2.2ux\n", next, len, 
1992/0917    
			/*print("%d/%d : #%2.2ux #%2.2ux  #%2.2ux #%2.2ux\n", next, len, 
1992/0909    
				p->status, p->next, p->len0, p->len1);/**/ 
1992/0915    
			delay(100); 
1992/0505    
			dp8390rinit(cp); 
1992/0905    
			break; 
1992/0505    
		} 
1992/0424    
                 
		rb = &cp->rb[cp->ri]; 
		if(rb->owner == Interface){ 
1992/0501    
			rb->len = len; 
1992/0916/sys/src/9/pc/devether.c:853,8591992/0917/sys/src/9/pc/devether.c:925,930
1992/0424    
			rb->owner = Host; 
1992/0502    
			cp->ri = NEXT(cp->ri, cp->nrb); 
1992/0424    
		} 
                 
1992/0502    
		p->status = 0; 
1992/0424    
		next = p->next; 
		bnry = next-1; 
1992/0916/sys/src/9/pc/devether.c:860,8661992/0917/sys/src/9/pc/devether.c:931,936
1992/0501    
		if(bnry < hw->pstart) 
			bnry = hw->pstop-1; 
1992/0424    
		OUT(hw, w.bnry, bnry); 
1992/0915    
		break; 
1992/0424    
	} 
1992/0403    
} 
 
1992/0916/sys/src/9/pc/devether.c:878,8841992/0917/sys/src/9/pc/devether.c:948,954
1992/0906    
		memmove(hw->ram, tb->pkt, tb->len); 
1992/0424    
		OUT(hw, w.tbcr0, tb->len & 0xFF); 
		OUT(hw, w.tbcr1, (tb->len>>8) & 0xFF); 
		OUT(hw, w.cr, 0x26);		/* Page0|RD2|TXP|STA */ 
1992/0917    
		OUT(hw, w.cr, Page0|RD2|TXP|STA); 
1992/0424    
		tb->busy = 1; 
	} 
	splx(s); 
1992/0916/sys/src/9/pc/devether.c:895,9001992/0917/sys/src/9/pc/devether.c:965,979
1992/0711    
	USED(ur); 
1992/0424    
	while(isr = IN(hw, r.isr)){ 
		OUT(hw, w.isr, isr); 
1992/0917    
		/* 
		 * we have received packets. 
		 */ 
		if(isr & (0x04|0x01)){		/* Rxe|Prx - packet received */ 
			(*cp->hw->receive)(cp); 
			wakeup(&cp->rr); 
		} 
		if(isr & 0x10)			/* Ovw - overwrite warning */ 
			cp->overflows++; 
1992/0424    
		if(isr & 0x08)			/* Txe - transmit error */ 
			cp->oerrs++; 
		if(isr & 0x04){			/* Rxe - receive error */ 
1992/0916/sys/src/9/pc/devether.c:916,9301992/0917/sys/src/9/pc/devether.c:995,1000
1992/0502    
			cp->ti = NEXT(cp->ti, cp->ntb); 
1992/0424    
			(*cp->hw->transmit)(cp); 
			wakeup(&cp->tr); 
		} 
		if(isr & 0x10)			/* Ovw - overwrite warning */ 
			cp->overflows++; 
		/* 
		 * we have received packets. 
		 */ 
		if(isr & (0x04|0x01)){		/* Rxe|Prx - packet received */ 
			(*cp->hw->receive)(cp); 
			wakeup(&cp->rr); 
		} 
	} 
1992/0409    
} 


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