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

📄 etherigbe.c

📁 这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易于我们学习和理解
💻 C
📖 第 1 页 / 共 4 页
字号:
	Rd*	rdba;			/* receive descriptor base address */	Block**	rb;			/* receive buffers */	int	rdh;			/* receive descriptor head */	int	rdt;			/* receive descriptor tail */	int	rdtr;			/* receive delay timer ring value */	Lock	tlock;	int	tbusy;	int	tdfree;	Td*	tdba;			/* transmit descriptor base address */	Block**	tb;			/* transmit buffers */	int	tdh;			/* transmit descriptor head */	int	tdt;			/* transmit descriptor tail */	int	txcw;	int	fcrtl;	int	fcrth;} Ctlr;#define csr32r(c, r)	(*((c)->nic+((r)/4)))#define csr32w(c, r, v)	(*((c)->nic+((r)/4)) = (v))static Ctlr* igbectlrhead;static Ctlr* igbectlrtail;static Lock igberblock;		/* free receive Blocks */static Block* igberbpool;static char* statistics[Nstatistics] = {	"CRC Error",	"Alignment Error",	"Symbol Error",	"RX Error",	"Missed Packets",	"Single Collision",	"Excessive Collisions",	"Multiple Collision",	"Late Collisions",	nil,	"Collision",	"Transmit Underrun",	"Defer",	"Transmit - No CRS",	"Sequence Error",	"Carrier Extension Error",	"Receive Error Length",	nil,	"XON Received",	"XON Transmitted",	"XOFF Received",	"XOFF Transmitted",	"FC Received Unsupported",	"Packets Received (64 Bytes)",	"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",};#ifndef FSstatic longigbeifstat(Ether* edev, void* a, long n, ulong offset){	Ctlr *ctlr;	char *p, *s;	int i, l, r;	uvlong tuvl, ruvl;	ctlr = edev->ctlr;	qlock(&ctlr->slock);	p = malloc(2*READSTR);	if (p == nil)		panic("igbeifstat: no mem");	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, "lintr: %ud %ud\n",		ctlr->lintr, ctlr->lsleep);	l += snprint(p+l, 2*READSTR-l, "rintr: %ud %ud\n",		ctlr->rintr, ctlr->rsleep);	l += snprint(p+l, 2*READSTR-l, "tintr: %ud %ud\n",		ctlr->tintr, ctlr->txdw);	l += snprint(p+l, 2*READSTR-l, "ixcs: %ud %ud %ud\n",		ctlr->ixsm, ctlr->ipcs, ctlr->tcpcs);	l += snprint(p+l, 2*READSTR-l, "rdtr: %ud\n", ctlr->rdtr);	l += snprint(p+l, 2*READSTR-l, "Ctrlext: %08x\n", csr32r(ctlr, Ctrlext));	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]);	}	l += snprint(p+l, 2*READSTR-l, "\n");	if(ctlr->mii != nil && ctlr->mii->curphy != nil){		l += snprint(p+l, 2*READSTR, "phy:   ");		for(i = 0; i < NMiiPhyr; i++){			if(i && ((i & 0x07) == 0))				l += snprint(p+l, 2*READSTR-l, "\n       ");			r = miimir(ctlr->mii, i);			l += snprint(p+l, 2*READSTR-l, " %4.4uX", r);		}		snprint(p+l, 2*READSTR-l, "\n");	}	n = readstr(offset, a, n, p);	free(p);	qunlock(&ctlr->slock);	return n;}enum {	CMrdtr,};static Cmdtab igbectlmsg[] = {	CMrdtr,	"rdtr",	2,};static longigbectl(Ether* edev, void* buf, long n){	int v;	char *p;	Ctlr *ctlr;	Cmdbuf *cb;	Cmdtab *ct;	if((ctlr = edev->ctlr) == nil)		error(Enonexist);	cb = parsecmd(buf, n);	if(waserror()){		free(cb);		nexterror();	}	ct = lookupcmd(cb, igbectlmsg, nelem(igbectlmsg));	switch(ct->index){	case CMrdtr:		v = strtol(cb->f[1], &p, 0);		if(v < 0 || p == cb->f[1] || v > 0xFFFF)			error(Ebadarg);		ctlr->rdtr = v;;		csr32w(ctlr, Rdtr, Fpd|v);		break;	}	free(cb);	poperror();	return n;}#endif		/* FS */static voidigbepromiscuous(void* arg, int on){	int rctl;	Ctlr *ctlr;	Ether *edev;	edev = arg;	ctlr = edev->ctlr;	rctl = csr32r(ctlr, Rctl);	rctl &= ~MoMASK;	rctl |= Mo47b36;	if(on)		rctl |= Upe|Mpe;	else		rctl &= ~(Upe|Mpe);	csr32w(ctlr, Rctl, rctl);}static voidigbemulticast(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->mta[x] |= 1<<bit;	else		ctlr->mta[x] &= ~(1<<bit);	csr32w(ctlr, Mta+x*4, ctlr->mta[x]);}static Block*igberballoc(void){	Block *bp;	ilock(&igberblock);	if((bp = igberbpool) != nil){		igberbpool = bp->next;		bp->next = nil;	}	iunlock(&igberblock);	return bp;}static voidigberbfree(Block* bp){	BLKRESET(bp);	ilock(&igberblock);	bp->next = igberbpool;	igberbpool = bp;	iunlock(&igberblock);}static voidigbeim(Ctlr* ctlr, int im){	ilock(&ctlr->imlock);	ctlr->im |= im;	csr32w(ctlr, Ims, ctlr->im);	iunlock(&ctlr->imlock);}static intigbelim(void* ctlr){	return ((Ctlr*)ctlr)->lim != 0;}static voidigbelproc(PROCARG(void *arg)){	Ctlr *ctlr;	Ether *edev;	MiiPhy *phy;	int ctrl, r;	edev = GETARG(arg);	ctlr = edev->ctlr;	for(;;){		if(ctlr->mii == nil || ctlr->mii->curphy == nil)			continue;		/*		 * To do:		 *	logic to manage status change,		 *	this is incomplete but should work		 *	one time to set up the hardware.		 *		 *	MiiPhy.speed, etc. should be in Mii.		 */		if(miistatus(ctlr->mii) < 0)			//continue;			goto enable;		phy = ctlr->mii->curphy;		ctrl = csr32r(ctlr, Ctrl);		switch(ctlr->id){		case i82543gc:		case i82544ei:		default:			if(!(ctrl & Asde)){				ctrl &= ~(SspeedMASK|Ilos|Fd);				ctrl |= Frcdplx|Frcspd;				if(phy->speed == 1000)					ctrl |= Sspeed1000;				else if(phy->speed == 100)					ctrl |= Sspeed100;				if(phy->fd)					ctrl |= Fd;			}			break;		case i82540em:		case i82540eplp:		case i82547gi:		case i82541gi:		case i82541gi2:		case i82541pi:			break;		}		/*		 * Collision Distance.		 */		r = csr32r(ctlr, Tctl);		r &= ~ColdMASK;		if(phy->fd)			r |= 64<<ColdSHIFT;		else			r |= 512<<ColdSHIFT;		csr32w(ctlr, Tctl, r);		/*		 * Flow control.		 */		if(phy->rfc)			ctrl |= Rfce;		if(phy->tfc)			ctrl |= Tfce;		csr32w(ctlr, Ctrl, ctrl);enable:		ctlr->lim = 0;		igbeim(ctlr, Lsc);		ctlr->lsleep++;		sleep(&ctlr->lrendez, igbelim, ctlr);	}}static voidigbetxinit(Ctlr* ctlr){	int i, r;	Block *bp;	csr32w(ctlr, Tctl, (0x0F<<CtSHIFT)|Psp|(66<<ColdSHIFT));	switch(ctlr->id){	default:		r = 6;		break;	case i82543gc:	case i82544ei:	case i82547ei:	case i82540em:	case i82540eplp:	case i82541gi:	case i82541gi2:	case i82541pi:	case i82545gmc:	case i82546gb:	case i82546eb:	case i82547gi:		r = 8;		break;	}	csr32w(ctlr, Tipg, (6<<20)|(8<<10)|r);	csr32w(ctlr, Ait, 0);	csr32w(ctlr, Txdmac, 0);	csr32w(ctlr, Tdbal, PCIWADDR(ctlr->tdba));	csr32w(ctlr, Tdbah, 0);	csr32w(ctlr, Tdlen, ctlr->ntd*sizeof(Td));	ctlr->tdh = PREV(0, ctlr->ntd);	csr32w(ctlr, Tdh, 0);	ctlr->tdt = 0;	csr32w(ctlr, Tdt, 0);	for(i = 0; i < ctlr->ntd; i++){		if((bp = ctlr->tb[i]) != nil){			ctlr->tb[i] = nil;			freeb(bp);		}		memset(&ctlr->tdba[i], 0, sizeof(Td));	}	ctlr->tdfree = ctlr->ntd;	csr32w(ctlr, Tidv, 128);	r = (4<<WthreshSHIFT)|(4<<HthreshSHIFT)|(8<<PthreshSHIFT);	switch(ctlr->id){	default:		break;	case i82540em:	case i82540eplp:	case i82547gi:	case i82545gmc:	case i82546gb:	case i82546eb:	case i82541gi:	case i82541gi2:	case i82541pi:		r = csr32r(ctlr, Txdctl);		r &= ~WthreshMASK;		r |= Gran|(4<<WthreshSHIFT);		csr32w(ctlr, Tadv, 64);		break;	}	csr32w(ctlr, Txdctl, r);	r = csr32r(ctlr, Tctl);	r |= Ten;	csr32w(ctlr, Tctl, r);}static voidigbetransmit(Ether* edev){	Td *td;	Block *bp;	Ctlr *ctlr;	int tdh, tdt;	ctlr = edev->ctlr;	ilock(&ctlr->tlock);	/*	 * Free any completed packets	 */	tdh = ctlr->tdh;	while(NEXT(tdh, ctlr->ntd) != csr32r(ctlr, Tdh)){		if((bp = ctlr->tb[tdh]) != nil){			ctlr->tb[tdh] = nil;			freeb(bp);		}		memset(&ctlr->tdba[tdh], 0, sizeof(Td));		tdh = NEXT(tdh, ctlr->ntd);	}	ctlr->tdh = tdh;	/*	 * Try to fill the ring back up.	 */	tdt = ctlr->tdt;	while(NEXT(tdt, ctlr->ntd) != tdh){		if((bp = etheroq(edev)) == nil)			break;		td = &ctlr->tdba[tdt];		td->addr[0] = PCIWADDR(bp->rp);		td->control = ((BLEN(bp) & LenMASK)<<LenSHIFT);		td->control |= Dext|Ifcs|Teop|DtypeDD;		ctlr->tb[tdt] = bp;		tdt = NEXT(tdt, ctlr->ntd);		if(NEXT(tdt, ctlr->ntd) == tdh){			td->control |= Rs;			ctlr->txdw++;			ctlr->tdt = tdt;			csr32w(ctlr, Tdt, tdt);			igbeim(ctlr, Txdw);			break;		}		ctlr->tdt = tdt;		csr32w(ctlr, Tdt, tdt);	}	iunlock(&ctlr->tlock);}static void

⌨️ 快捷键说明

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