⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ether82543gc.c

📁 这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易于我们学习和理解
💻 C
📖 第 1 页 / 共 3 页
字号:
	"Packets Received (65-127 Bytes)",	"Packets Received (128-255 Bytes)",	"Packets Received (256-511 Bytes)",	"Packets Received (512-1023 Bytes)",	"Packets Received (1024-1522 Bytes)",	"Good Packets Received",	"Broadcast Packets Received",	"Multicast Packets Received",	"Good Packets Transmitted",	nil,	"Good Octets Received",	nil,	"Good Octets Transmitted",	nil,	nil,	nil,	"Receive No Buffers",	"Receive Undersize",	"Receive Fragment",	"Receive Oversize",	"Receive Jabber",	nil,	nil,	nil,	"Total Octets Received",	nil,	"Total Octets Transmitted",	nil,	"Total Packets Received",	"Total Packets Transmitted",	"Packets Transmitted (64 Bytes)",	"Packets Transmitted (65-127 Bytes)",	"Packets Transmitted (128-255 Bytes)",	"Packets Transmitted (256-511 Bytes)",	"Packets Transmitted (512-1023 Bytes)",	"Packets Transmitted (1024-1522 Bytes)",	"Multicast Packets Transmitted",	"Broadcast Packets Transmitted",	"TCP Segmentation Context Transmitted",	"TCP Segmentation Context Fail",};static longgc82543ifstat(Ether* edev, void* a, long n, ulong offset){	Ctlr *ctlr;	char *p, *s;	int i, l, r;	uvlong tuvl, ruvl;	ctlr = edev->ctlr;	lock(&ctlr->slock);	p = malloc(2*READSTR);	l = 0;	for(i = 0; i < Nstatistics; i++){		r = csr32r(ctlr, Statistics+i*4);		if((s = statistics[i]) == nil)			continue;		switch(i){		case Gorcl:		case Gotcl:		case Torl:		case Totl:			ruvl = r;			ruvl += ((uvlong)csr32r(ctlr, Statistics+(i+1)*4))<<32;			tuvl = ruvl;			tuvl += ctlr->statistics[i];			tuvl += ((uvlong)ctlr->statistics[i+1])<<32;			if(tuvl == 0)				continue;			ctlr->statistics[i] = tuvl;			ctlr->statistics[i+1] = tuvl>>32;			l += snprint(p+l, 2*READSTR-l, "%s: %llud %llud\n",				s, tuvl, ruvl);			i++;			break;		default:			ctlr->statistics[i] += r;			if(ctlr->statistics[i] == 0)				continue;			l += snprint(p+l, 2*READSTR-l, "%s: %ud %ud\n",				s, ctlr->statistics[i], r);			break;		}	}	l += snprint(p+l, 2*READSTR-l, "eeprom:");	for(i = 0; i < 0x40; i++){		if(i && ((i & 0x07) == 0))			l += snprint(p+l, 2*READSTR-l, "\n       ");		l += snprint(p+l, 2*READSTR-l, " %4.4uX", ctlr->eeprom[i]);	}	snprint(p+l, 2*READSTR-l, "\ntxstalled %d\n", ctlr->txstalled);	n = readstr(offset, a, n, p);	free(p);	unlock(&ctlr->slock);	return n;}static voidgc82543promiscuous(void* arg, int on){	int rctl;	Ctlr *ctlr;	Ether *edev;	edev = arg;	ctlr = edev->ctlr;	rctl = csr32r(ctlr, Rctl);	rctl &= ~MoMASK;		/* make sure we're using bits 47:36 */	if(on)		rctl |= Upe|Mpe;	else		rctl &= ~(Upe|Mpe);	csr32w(ctlr, Rctl, rctl);}static voidgc82543multicast(void* arg, uchar* addr, int on){	int bit, x;	Ctlr *ctlr;	Ether *edev;	edev = arg;	ctlr = edev->ctlr;	x = addr[5]>>1;	bit = ((addr[5] & 1)<<4)|(addr[4]>>4);	if(on)		ctlr->multimask[x] |= 1<<bit;	else		ctlr->multimask[x] &= ~(1<<bit);		csr32w(ctlr, Mta+x*4, ctlr->multimask[x]);}static longgc82543ctl(Ether* edev, void* buf, long n){	Cmdbuf *cb;	Ctlr *ctlr;	int ctrl, i, r;	ctlr = edev->ctlr;	if(ctlr == nil)		error(Enonexist);	lock(&ctlr->slock);	r = 0;	cb = parsecmd(buf, n);	if(cb->nf < 2)		r = -1;	else if(cistrcmp(cb->f[0], "auto") == 0){		ctrl = csr32r(ctlr, Ctrl);		if(cistrcmp(cb->f[1], "off") == 0){			csr32w(ctlr, Txcw, ctlr->txcw & ~Ane);			ctrl |= (Slu|Fd);			if(ctlr->txcw & As)				ctrl |= Rfce;			if(ctlr->txcw & Ps)				ctrl |= Tfce;			csr32w(ctlr, Ctrl, ctrl);		}		else if(cistrcmp(cb->f[1], "on") == 0){			csr32w(ctlr, Txcw, ctlr->txcw);			ctrl &= ~(Slu|Fd);			csr32w(ctlr, Ctrl, ctrl);		}		else			r = -1;	}	else if(cistrcmp(cb->f[0], "clear") == 0){		if(cistrcmp(cb->f[1], "stats") == 0){			for(i = 0; i < Nstatistics; i++)				ctlr->statistics[i] = 0;		}		else			r = -1;	}	else		r = -1;	unlock(&ctlr->slock);	free(cb);	return (r == 0) ? n : r;}static voidgc82543txinit(Ctlr* ctlr){	int i;	int tdsize;	Block *bp, **bpp;	tdsize = ROUND(Ntdesc*sizeof(Tdesc), 4096);	if(ctlr->tdba == nil)		ctlr->tdba = xspanalloc(tdsize, 32, 0);	for(i = 0; i < Ntdesc; i++){		bpp = &ctlr->tb[i];		bp = *bpp;		if(bp != nil){			*bpp = nil;			freeb(bp);		}		memset(&ctlr->tdba[i], 0, sizeof(Tdesc));	}	csr32w(ctlr, Tdbal, PCIWADDR(ctlr->tdba));	csr32w(ctlr, Tdbah, 0);	csr32w(ctlr, Tdlen, Ntdesc*sizeof(Tdesc));	/*	 * set the ring head and tail pointers.	 */	ctlr->tdh = 0;	csr32w(ctlr, Tdh, ctlr->tdh);	ctlr->tdt = 0;	csr32w(ctlr, Tdt, ctlr->tdt);	csr32w(ctlr, Tipg, (6<<20)|(8<<10)|6);	csr32w(ctlr, Tidv, 128);	csr32w(ctlr, Ait, 0);	csr32w(ctlr, Txdmac, 0);	csr32w(ctlr, Txdctl, Gran|(4<<WthreshSHIFT)|(1<<HthreshSHIFT)|16);	csr32w(ctlr, Tctl, (0x0F<<CtSHIFT)|Psp|(6<<ColdSHIFT));	ctlr->im |= Txdw;}static voidgc82543transmit(Ether* edev){	Block *bp, **bpp;	Ctlr *ctlr;	Tdesc *tdesc;	int tdh, tdt, s;	ctlr = edev->ctlr;	ilock(&ctlr->tdlock);	tdh = ctlr->tdh;	for(;;){		/*		 * Free any completed packets		 */		tdesc = &ctlr->tdba[tdh];		if(!(tdesc->status & Tdd))			break;		memset(tdesc, 0, sizeof(Tdesc));		bpp = &ctlr->tb[tdh];		bp = *bpp;		if(bp != nil){			*bpp = nil;			freeb(bp);		}		tdh = NEXT(tdh, Ntdesc);	}	ctlr->tdh = tdh;	s = csr32r(ctlr, Status);	/*	 * Try to fill the ring back up	 * but only if link is up and transmission isn't paused.	 */	if((s & (Txoff|Lu)) == Lu){		tdt = ctlr->tdt;		while(NEXT(tdt, Ntdesc) != tdh){			if((bp = qget(edev->oq)) == nil)				break;			tdesc = &ctlr->tdba[tdt];			tdesc->addr[0] = PCIWADDR(bp->rp);			tdesc->control = Ide|Rs|Ifcs|Teop|BLEN(bp);			ctlr->tb[tdt] = bp;			tdt = NEXT(tdt, Ntdesc);		}		if(tdt != ctlr->tdt){			ctlr->tdt = tdt;			csr32w(ctlr, Tdt, tdt);		}	}	else		ctlr->txstalled++;	iunlock(&ctlr->tdlock);}static Block *gc82543allocb(Ctlr* ctlr){	Block *bp;	ilock(&freelistlock);	if((bp = *(ctlr->freehead)) != nil){		*(ctlr->freehead) = bp->next;		bp->next = nil;	}	iunlock(&freelistlock);	return bp;}static voidgc82543replenish(Ctlr* ctlr){	int rdt;	Block *bp;	Rdesc *rdesc;	ilock(&ctlr->rdlock);	rdt = ctlr->rdt;	while(NEXT(rdt, Nrdesc) != ctlr->rdh){		rdesc = &ctlr->rdba[rdt];		if(ctlr->rb[rdt] == nil){			bp = gc82543allocb(ctlr);			if(bp == nil){				iprint("no available buffers\n");				break;			}			ctlr->rb[rdt] = bp;			rdesc->addr[0] = PCIWADDR(bp->rp);			rdesc->addr[1] = 0;		}		coherence();		rdesc->status = 0;		rdt = NEXT(rdt, Nrdesc);	}	ctlr->rdt = rdt;	csr32w(ctlr, Rdt, rdt);	iunlock(&ctlr->rdlock);}static voidgc82543rxinit(Ctlr* ctlr){	int rdsize, i;	csr32w(ctlr, Rctl, Dpf|Bsize2048|Bam|RdtmsHALF);	/*	 * Allocate the descriptor ring and load its	 * address and length into the NIC.	 */	rdsize = ROUND(Nrdesc*sizeof(Rdesc), 4096);	if(ctlr->rdba == nil)		ctlr->rdba = xspanalloc(rdsize, 32, 0);	memset(ctlr->rdba, 0, rdsize);	ctlr->rdh = 0;	ctlr->rdt = 0;	csr32w(ctlr, Rdtr, Fpd|64);	csr32w(ctlr, Rdbal, PCIWADDR(ctlr->rdba));	csr32w(ctlr, Rdbah, 0);	csr32w(ctlr, Rdlen, Nrdesc*sizeof(Rdesc));	csr32w(ctlr, Rdh, 0);	csr32w(ctlr, Rdt, 0);	for(i = 0; i < Nrdesc; i++){		if(ctlr->rb[i] != nil){			freeb(ctlr->rb[i]);			ctlr->rb[i] = nil;		}	}	gc82543replenish(ctlr);	csr32w(ctlr, Rxdctl, RxGran|(8<<WthreshSHIFT)|(4<<HthreshSHIFT)|1);	ctlr->im |= Rxt0|Rxo|Rxdmt0|Rxseq;}static voidgc82543recv(Ether* edev, int icr){	Block *bp;	Ctlr *ctlr;	Rdesc *rdesc;	int rdh;	ctlr = edev->ctlr;	rdh = ctlr->rdh;	for(;;){		rdesc = &ctlr->rdba[rdh];		if(!(rdesc->status & Rdd))			break;		if((rdesc->status & Reop) && rdesc->errors == 0){			bp = ctlr->rb[rdh];			ctlr->rb[rdh] = nil;			bp->wp += rdesc->length;			bp->next = nil;			etheriq(edev, bp, 1);		}		if(ctlr->rb[rdh] != nil){			/* either non eop packet, or error */			freeb(ctlr->rb[rdh]);			ctlr->rb[rdh] = nil;		}		memset(rdesc, 0, sizeof(Rdesc));		coherence();		rdh = NEXT(rdh, Nrdesc);	}	ctlr->rdh = rdh;	if(icr & Rxdmt0)		gc82543replenish(ctlr);}static voidfreegc82543short(Block *bp){	ilock(&freelistlock);	/* reset read/write pointer to proper positions */	bp->rp = bp->lim - ROUND(SBLOCKSIZE, BLOCKALIGN);	bp->wp = bp->rp;	bp->next = freeShortHead;	freeShortHead = bp;	iunlock(&freelistlock);}static voidfreegc82532jumbo(Block *bp){	ilock(&freelistlock);	/* reset read/write pointer to proper positions */	bp->rp = bp->lim - ROUND(JBLOCKSIZE, BLOCKALIGN);	bp->wp = bp->rp;	bp->next = freeJumboHead;	freeJumboHead = bp;	iunlock(&freelistlock);}static voidlinkintr(Ctlr* ctlr){	int ctrl;	ctrl = csr32r(ctlr, Ctrl);	if((ctrl & Swdpin1) ||	  ((csr32r(ctlr, Rxcw) & Rxconfig) && !(csr32r(ctlr, Txcw) & Ane))){ 		csr32w(ctlr, Txcw, ctlr->txcw);		ctrl &= ~(Slu|Fd|Frcdplx);		csr32w(ctlr, Ctrl, ctrl);	}}static voidgc82543interrupt(Ureg*, void* arg)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -