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

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

1992/0425/sys/src/9/pc/devether.c:14,211992/0501/sys/src/9/pc/devether.c:14,24 (short | long | prev | next)
1992/0403    
 
1992/0424    
struct Hw { 
	int	addr;			/* interface address */ 
	void	*ram;			/* interface shared memory address */ 
	int	ramsz;			/* interface shared memory size */ 
1992/0501    
	uchar	*ram;			/* interface shared memory address */ 
	int	size; 
	uchar	tstart; 
	uchar	pstart; 
	uchar	pstop; 
1992/0424    
	void	(*reset)(Ctlr*); 
	void	(*init)(Ctlr*); 
	void	(*mode)(Ctlr*, int); 
1992/0425/sys/src/9/pc/devether.c:43,491992/0501/sys/src/9/pc/devether.c:46,52
1992/0424    
	uchar	owner; 
	uchar	busy; 
	ushort	len; 
	Etherpkt pkt; 
1992/0501    
	uchar	pkt[sizeof(Etherpkt)]; 
1992/0404    
}; 
1992/0403    
 
1992/0404    
enum { 
1992/0425/sys/src/9/pc/devether.c:250,2561992/0501/sys/src/9/pc/devether.c:253,258
1992/0424    
	sleep(&cp->tr, isobuf, cp); 
1992/0403    
 
1992/0424    
	tb = &cp->tb[cp->th]; 
	p = &tb->pkt; 
 
1992/0403    
	/* 
	 * copy message into buffer 
1992/0425/sys/src/9/pc/devether.c:258,2641992/0501/sys/src/9/pc/devether.c:260,266
1992/0403    
	len = 0; 
	for(nbp = bp; nbp; nbp = nbp->next){ 
		if(sizeof(Etherpkt) - len >= (n = BLEN(nbp))){ 
			memmove(((uchar *)p)+len, nbp->rptr, n); 
1992/0501    
			memmove(tb->pkt+len, nbp->rptr, n); 
1992/0403    
			len += n; 
		} else 
			print("no room damn it\n"); 
1992/0425/sys/src/9/pc/devether.c:270,2851992/0501/sys/src/9/pc/devether.c:272,282
1992/0407    
	 * pad the packet (zero the pad) 
1992/0403    
	 */ 
	if(len < ETHERMINTU){ 
		memset(((char*)p)+len, 0, ETHERMINTU-len); 
1992/0501    
		memset(tb->pkt+len, 0, ETHERMINTU-len); 
1992/0403    
		len = ETHERMINTU; 
	} 
 
	/* 
1992/0407    
	 * give packet a local address 
1992/0403    
	 */ 
1992/0407    
	memmove(p->s, cp->ea, sizeof(cp->ea)); 
1992/0403    
                 
	/* 
1992/0424    
	 * set up the transmit buffer and  
1992/0407    
	 * start the transmission 
1992/0403    
	 */ 
1992/0425/sys/src/9/pc/devether.c:392,4031992/0501/sys/src/9/pc/devether.c:389,402
1992/0403    
} 
 
static void 
1992/0424    
etherup(Ctlr *cp, Etherpkt *p, int len) 
1992/0501    
etherup(Ctlr *cp, void *data, int len) 
1992/0403    
{ 
1992/0404    
	Block *bp; 
1992/0410    
	Type *tp; 
1992/0501    
	Etherpkt *p; 
1992/0404    
	int t; 
1992/0501    
	Type *tp; 
	Block *bp; 
1992/0404    
 
1992/0501    
	p = data; 
1992/0410    
	t = (p->type[0]<<8)|p->type[1]; 
	for(tp = &cp->type[0]; tp < &cp->type[NType]; tp++){ 
1992/0404    
		/* 
1992/0425/sys/src/9/pc/devether.c:464,4701992/0501/sys/src/9/pc/devether.c:463,469
1992/0406    
		 */ 
1992/0424    
		while(bp = getq(&cp->lbq)){ 
1992/0404    
			cp->inpackets++; 
1992/0424    
			etherup(cp, (Etherpkt*)bp->rptr, BLEN(bp)); 
1992/0501    
			etherup(cp, bp->rptr, BLEN(bp)); 
1992/0404    
			freeb(bp); 
		} 
1992/0408    
 
1992/0425/sys/src/9/pc/devether.c:474,4801992/0501/sys/src/9/pc/devether.c:473,479
1992/0424    
		while(cp->rb[cp->rh].owner == Host){ 
1992/0406    
			cp->inpackets++; 
1992/0424    
			rb = &cp->rb[cp->rh]; 
			etherup(cp, &rb->pkt, rb->len); 
1992/0501    
			etherup(cp, rb->pkt, rb->len); 
1992/0424    
			rb->owner = Interface; 
			cp->rh = NEXT(cp->rh, Nrb); 
		} 
1992/0425/sys/src/9/pc/devether.c:528,5351992/0501/sys/src/9/pc/devether.c:527,533
1992/0403    
	/* 
	 * put the receiver online 
	 * and start the kproc 
	 */ 
1992/0424    
	                 
1992/0501    
	 */	 
1992/0424    
	(*cp->hw->online)(cp, 1); 
	if(cp->kproc == 0){ 
		sprint(cp->name, "ether%dkproc", ctlrno); 
1992/0425/sys/src/9/pc/devether.c:599,6041992/0501/sys/src/9/pc/devether.c:597,610
1992/0424    
#define IN(hw, m)	inb((hw)->addr+OFFSETOF(Wd8013, m)) 
#define OUT(hw, m, x)	outb((hw)->addr+OFFSETOF(Wd8013, m), (x)) 
 
1992/0501    
typedef struct { 
	uchar	status; 
	uchar	next; 
	uchar	len0; 
	uchar	len1; 
	uchar	data[256-4]; 
} Ring; 
 
1992/0424    
/* 
 */ 
static void 
1992/0425/sys/src/9/pc/devether.c:608,6311992/0501/sys/src/9/pc/devether.c:614,630
1992/0424    
	int i; 
	uchar msr; 
1992/0403    
 
1992/0424    
	cp->rb = ialloc(sizeof(Buffer)*Nrb, 0); 
	cp->nrb = Nrb; 
	cp->tb = ialloc(sizeof(Buffer)*Ntb, 0); 
1992/0501    
	cp->tb = ialloc(sizeof(Buffer)*Ntb, 1); 
1992/0424    
	cp->ntb = Ntb; 
1992/0501    
	cp->rb = ialloc(sizeof(Buffer)*Nrb, 1); 
	cp->nrb = Nrb; 
1992/0424    
 
	msr = IN(hw, msr); 
	OUT(hw, msr, 0x40|msr); 
1992/0403    
{ 
1992/0424    
int addr = hw->addr; 
 
for(i = 0; i < 16; i++){ 
    print("#%2.2ux ", inb(addr)); 
    addr++; 
1992/0403    
} 
1992/0424    
print("\n"); 
} 
	for(i = 0; i < sizeof(cp->ea); i++) 
		cp->ea[i] = IN(hw, lan[i]); 
1992/0501    
 
1992/0424    
	(*hw->init)(cp); 
	setvec(Ethervec, hw->intr); 
} 
1992/0425/sys/src/9/pc/devether.c:639,6471992/0501/sys/src/9/pc/devether.c:638,644
1992/0403    
{ 
1992/0424    
	Hw *hw = cp->hw; 
	int i; 
	uchar bnry; 
 
print("init %d %d\n", HOWMANY(sizeof(Etherpkt), 256), HOWMANY(hw->ramsz, 256)); 
	OUT(hw, w.cr, 0x21);			/* Page0|RD2|STP */ 
	OUT(hw, w.dcr, 0x48);			/* FT1|LS */ 
	OUT(hw, w.rbcr0, 0); 
1992/0425/sys/src/9/pc/devether.c:649,6581992/0501/sys/src/9/pc/devether.c:646,654
1992/0424    
	OUT(hw, w.rcr, 0x04);			/* AB */ 
	OUT(hw, w.tcr, 0x20);			/* LB0 */ 
 
	bnry = HOWMANY(sizeof(Etherpkt), 256); 
	OUT(hw, w.bnry, bnry); 
	OUT(hw, w.pstart, bnry); 
	OUT(hw, w.pstop, HOWMANY(hw->ramsz, 256)); 
1992/0501    
	OUT(hw, w.bnry, hw->pstart); 
	OUT(hw, w.pstart, hw->pstart); 
	OUT(hw, w.pstop, hw->pstop); 
1992/0424    
	OUT(hw, w.isr, 0xFF); 
	OUT(hw, w.imr, 0x1F);			/* OVWE|TXEE|RXEE|PTXE|PRXE */ 
 
1992/0425/sys/src/9/pc/devether.c:659,6651992/0501/sys/src/9/pc/devether.c:655,661
1992/0424    
	OUT(hw, w.cr, 0x61);			/* Page1|RD2|STP */ 
	for(i = 0; i < sizeof(cp->ea); i++) 
		OUT(hw, par[i], cp->ea[i]); 
	OUT(hw, curr, bnry+1); 
1992/0501    
	OUT(hw, curr, hw->pstart+1); 
1992/0424    
 
	OUT(hw, w.cr, 0x22);			/* Page0|RD2|STA */ 
	OUT(hw, w.tpsr, 0); 
1992/0425/sys/src/9/pc/devether.c:688,6931992/0501/sys/src/9/pc/devether.c:684,691
1992/0424    
	OUT(cp->hw, w.tcr, 0); 
1992/0403    
} 
 
1992/0501    
static ulong wraps; 
 
1992/0424    
static void 
wd8013receive(Ctlr *cp) 
1992/0403    
{ 
1992/0425/sys/src/9/pc/devether.c:694,7131992/0501/sys/src/9/pc/devether.c:692,704
1992/0424    
	Hw *hw = cp->hw; 
	Buffer *rb; 
	uchar bnry, curr, next; 
	typedef struct Ring { 
		uchar	status; 
		uchar	next; 
		uchar	len0; 
		uchar	len1; 
		uchar	data[256-4]; 
	} Ring; 
	Ring *p; 
1992/0425    
	int len0, len1; 
1992/0501    
	int len; 
1992/0424    
 
	bnry = IN(hw, r.bnry); 
	next = NEXT(bnry, HOWMANY(hw->ramsz, 256)); 
	if(next == 0) 
		next = HOWMANY(sizeof(Etherpkt), 256); 
1992/0501    
	next = bnry+1; 
	if(next >= hw->pstop) 
		next = hw->pstart; 
1992/0424    
	for(;;){ 
		OUT(hw, w.cr, 0x62);		/* Page1|RD2|STA */ 
		curr = IN(hw, curr); 
1992/0425/sys/src/9/pc/devether.c:716,7451992/0501/sys/src/9/pc/devether.c:707,737
1992/0424    
			break; 
		cp->inpackets++; 
		p = &((Ring*)hw->ram)[next]; 
1992/0425    
		len0 = (p->len1<<8)|p->len0-4; 
		len1 = 0; 
1992/0501    
		len = (p->len1<<8)|p->len0-4; 
if(len > sizeof(Etherpkt)) 
    print("!"); 
1992/0424    
 
		rb = &cp->rb[cp->ri]; 
		if(rb->owner == Interface){ 
1992/0425    
			rb->len = len0; 
1992/0501    
			rb->len = len; 
1992/0424    
			/*copy in packet*/ 
1992/0425    
			if(p->data+len0 >= (uchar*)hw->ram+hw->ramsz){ 
				len1 = p->data+len0 - (uchar*)hw->ram+hw->ramsz; 
				len0 = (uchar*)hw->ram+hw->ramsz - p->data; 
1992/0501    
			if(p->data+len >= hw->ram+hw->size){ 
wraps++; 
				len = hw->ram+hw->size - p->data; 
				memmove(rb->pkt+len, 
					&((Ring*)hw->ram)[hw->pstart], 
					p->data+rb->len - hw->ram+hw->size); 
1992/0425    
			} 
			memmove((uchar*)&rb->pkt, p->data, len0); 
			if(len1) 
				memmove((uchar*)&rb->pkt+len0, 
					(uchar*)hw->ram+ROUNDUP(sizeof(Etherpkt), 256), 
					len1); 
1992/0501    
			memmove(rb->pkt, p->data, len); 
1992/0424    
			rb->owner = Host; 
			cp->ri = NEXT(cp->ri, Nrb); 
		} 
 
1992/0501    
p->status = 0; 
1992/0424    
		next = p->next; 
		bnry = next-1; 
		if(bnry < HOWMANY(sizeof(Etherpkt), 256)) 
			bnry = HOWMANY(hw->ramsz, 256)-1; 
1992/0501    
		if(bnry < hw->pstart) 
			bnry = hw->pstop-1; 
1992/0424    
		OUT(hw, w.bnry, bnry); 
	} 
1992/0403    
} 
1992/0425/sys/src/9/pc/devether.c:751,7631992/0501/sys/src/9/pc/devether.c:743,754
1992/0424    
	Buffer *tb; 
	int s; 
 
print("transmit\n"); 
	s = splhi(); 
	tb = &cp->tb[cp->ti]; 
	if(tb->busy == 0 && tb->owner == Interface){ 
		hw = cp->hw; 
print("transmit memove %lux %lux, %d\n", hw->ram, &tb->pkt, tb->len); 
		memmove(hw->ram, &tb->pkt, tb->len); 
1992/0501    
tb->len = tb->len+1 & ~1; 
		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/0425/sys/src/9/pc/devether.c:764,7701992/0501/sys/src/9/pc/devether.c:755,760
1992/0424    
		tb->busy = 1; 
	} 
	splx(s); 
print("transmit done\n"); 
1992/0403    
} 
 
1992/0424    
static void 
1992/0425/sys/src/9/pc/devether.c:814,8201992/0501/sys/src/9/pc/devether.c:804,813
1992/0424    
static Hw wd8013 = { 
	0x360,					/* I/O base address */ 
	KZERO|0xC8000,				/* shared memory address */ 
	8*1024,					/* shared memory size */ 
1992/0501    
	8*1024, 
	0, 
	HOWMANY(sizeof(Etherpkt), 256), 
	HOWMANY(8*1024, 256), 
1992/0424    
	wd8013reset, 
	wd8013init, 
	wd8013mode, 
1992/0425/sys/src/9/pc/devether.c:827,8301992/0501/sys/src/9/pc/devether.c:820,841
1992/0409    
void 
1992/0411    
consdebug(void) 
1992/0409    
{ 
1992/0501    
	Ctlr *cp = &ctlr[0]; 
	Hw *hw = cp->hw; 
	Buffer *bp; 
	uchar bnry, curr; 
 
	print("th%d ti%d rh%d ri%d\n", 
		cp->th, cp->ti, cp->rh, cp->ri); 
	bp = &cp->tb[cp->ti]; 
	print("t: owner %d busy %d len %d\n", 
		bp->owner, bp->busy, bp->len); 
	bnry = IN(hw, r.bnry); 
	OUT(hw, w.cr, 0x62); 
	curr = IN(hw, curr); 
	OUT(hw, w.cr, 0x22); 
	print("bnry %d, curr %d\n", bnry, curr); 
	print("in %d out %d crcs %d oerrs %d frames %d overflows %d buffs %d wraps %d\n", 
		cp->inpackets, cp->outpackets, cp->crcs, cp->oerrs, cp->frames, 
		cp->overflows, cp->buffs, wraps); 
1992/0403    
} 


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