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

📄 etherdp83820.c

📁 这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易于我们学习和理解
💻 C
📖 第 1 页 / 共 3 页
字号:
	for(isr = csr32r(ctlr, Isr); isr & ctlr->imr; isr = csr32r(ctlr, Isr)){		if(isr & (Rxorn|Rxidle|Rxearly|Rxerr|Rxdesc|Rxok)){			x = ctlr->rdx;			desc = &ctlr->rd[x];			while((cmdsts = desc->cmdsts) & Own){				if((cmdsts & Ok) && desc->bp != nil){					/* unlink rcv. Block from Desc */					bp = desc->bp;					desc->bp = nil;					/* store its length, add to input q */					INCRPTR(bp, desc->cmdsts & SizeMASK);					ETHERIQ(edev, bp, 1);					rcvd++;				}				/* replace rcv. Block just detached from Desc */				if (dp83820rballoc(desc) == nil)					iprint(					  "dp83820interrupt: rballoc failed\n");				x = NEXT(x, ctlr->nrd);				desc = &ctlr->rd[x];			}			ctlr->rdx = x;			if (rcvd >= ctlr->nrd-1)				iprint("83820: rcv q full, Nrd=%d\n", Nrd);			if(isr & Rxidle){				/* resume reading packets */				r = csr32r(ctlr, Cr);				csr32w(ctlr, Cr, Rxe|r);				ctlr->rxidle++;			}			isr &= ~(Rxorn|Rxidle|Rxearly|Rxerr|Rxdesc|Rxok);		}		if(isr & Txurn){			x = (ctlr->txcfg & TxdrthMASK)>>TxdrthSHFT;			r = (ctlr->txcfg & FlthMASK)>>FlthSHFT;			if(x < ((TxdrthMASK)>>TxdrthSHFT)			&& x < (2048/32 - r)){				ctlr->txcfg &= ~TxdrthMASK;				x++;				ctlr->txcfg |= x<<TxdrthSHFT;				csr32w(ctlr, Txcfg, ctlr->txcfg);			}		}		if(isr & (Txurn|Txidle|Txdesc|Txok)){			/* toss completed packets, q new ones, fire */			dp83820transmit(edev);			isr &= ~(Txurn|Txidle|Txdesc|Txok);		}		if(isr & Mib){			for(i = 0; i < Nmibd; i++){				r = csr32r(ctlr, Mibd+(i*sizeof(int)));				ctlr->mibd[i] += r & 0xFFFF;			}			isr &= ~Mib;		}		if((isr & Phy) && ctlr->mii != nil){			ctlr->mii->mir(ctlr->mii, 1, Bmsr);			print("phy: cfg %8.8ux bmsr %4.4ux\n",				csr32r(ctlr, Cfg),				ctlr->mii->mir(ctlr->mii, 1, Bmsr));			dp83820cfg(ctlr);			isr &= ~Phy;		}		if(isr)			iprint("dp83820: isr %8.8ux\n", isr);	}}#ifndef FSstatic longdp83820ifstat(Ether* edev, void* a, long n, ulong offset){	char *p;	Ctlr *ctlr;	int i, l, r;	MiiPhy *phy;	ctlr = edev->ctlr;	edev->crcs = ctlr->mibd[1];	edev->frames = ctlr->mibd[3];	edev->buffs = ctlr->mibd[5];	edev->overflows = ctlr->mibd[2];	if(n == 0)		return 0;	p = malloc(READSTR);	l = 0;	for(i = 0; i < Nmibd; i++){		r = csr32r(ctlr, Mibd+(i*sizeof(int)));		ctlr->mibd[i] += r & 0xFFFF;		if(ctlr->mibd[i] != 0 && dp83820mibs[i] != nil)			l += snprint(p+l, READSTR-l, "%s: %ud %ud\n",				dp83820mibs[i], ctlr->mibd[i], r);	}	l += snprint(p+l, READSTR-l, "rxidle %d\n", ctlr->rxidle);	l += snprint(p+l, READSTR-l, "ec %d\n", ctlr->ec);	l += snprint(p+l, READSTR-l, "owc %d\n", ctlr->owc);	l += snprint(p+l, READSTR-l, "ed %d\n", ctlr->ed);	l += snprint(p+l, READSTR-l, "crs %d\n", ctlr->crs);	l += snprint(p+l, READSTR-l, "tfu %d\n", ctlr->tfu);	l += snprint(p+l, READSTR-l, "txa %d\n", ctlr->txa);	l += snprint(p+l, READSTR, "rom:");	for(i = 0; i < 0x10; i++){		if(i && ((i & 0x07) == 0))			l += snprint(p+l, READSTR-l, "\n    ");		l += snprint(p+l, READSTR-l, " %4.4uX", ctlr->eeprom[i]);	}	l += snprint(p+l, READSTR-l, "\n");	USED(l);	if(0 && ctlr->mii != nil && (phy = ctlr->mii->curphy) != nil){		l += snprint(p+l, READSTR, "phy:");		for(i = 0; i < NMiiPhyr; i++){			if(i && ((i & 0x07) == 0))				l += snprint(p+l, READSTR-l, "\n    ");			/* phy->r no longer exists */			// l += snprint(p+l, READSTR-l, " %4.4uX", phy->r[i]);		}		snprint(p+l, READSTR-l, "\n");	}	n = readstr(offset, a, n, p);	free(p);	return n;}#endif			/* FS */static voiddp83820promiscuous(void* arg, int on){	USED(arg, on);}static intatc93c46r(Ctlr* ctlr, int address){	int data, i, mear, r, size;	/*	 * Analog Technology, Inc. ATC93C46	 * or equivalent serial EEPROM.	 */	mear = csr32r(ctlr, Mear);	mear &= ~(Eesel|Eeclk|Eedo|Eedi);	r = Eesel|mear;reread:	csr32w(ctlr, Mear, r);	data = 0x06;	for(i = 3-1; i >= 0; i--){		if(data & (1<<i))			r |= Eedi;		else			r &= ~Eedi;		csr32w(ctlr, Mear, r);		csr32w(ctlr, Mear, Eeclk|r);		microdelay(1);		csr32w(ctlr, Mear, r);		microdelay(1);	}	/*	 * First time through must work out the EEPROM size.	 */	if((size = ctlr->eepromsz) == 0)		size = 8;	for(size = size-1; size >= 0; size--){		if(address & (1<<size))			r |= Eedi;		else			r &= ~Eedi;		csr32w(ctlr, Mear, r);		csr32w(ctlr, Mear, Eeclk|r);		microdelay(1);		csr32w(ctlr, Mear, r);		microdelay(1);		if(!(csr32r(ctlr, Mear) & Eedo))			break;	}	r &= ~Eedi;	data = 0;	for(i = 16-1; i >= 0; i--){		csr32w(ctlr, Mear, Eeclk|r);		microdelay(1);		if(csr32r(ctlr, Mear) & Eedo)			data |= (1<<i);		csr32w(ctlr, Mear, r);		microdelay(1);	}	csr32w(ctlr, Mear, mear);	if(ctlr->eepromsz == 0){		ctlr->eepromsz = 8-size;		ctlr->eeprom = malloc((1<<ctlr->eepromsz)*sizeof(ushort));		goto reread;	}	return data;}static voidresetctlr(Ctlr *ctlr){	csr32w(ctlr, Cr, Rst);	delay(1);	/* TODO: limit this; don't wait forever */	while(csr32r(ctlr, Cr) & Rst)		delay(1);	atc93c46r(ctlr, 0);}static voidshutdown(Ether* ether){	Ctlr *ctlr = ether->ctlr;print("ether83820 shutting down\n");	csr32w(ctlr, Cr, Txd|Rxd);	/* disable transceiver */	resetctlr(ctlr);}intdp83820reset(Ctlr* ctlr){	int i, r;	unsigned char sum;	/*	 * Soft reset the controller;	 * read the EEPROM to get the initial settings	 * of the Cfg and Gpior bits which should be cleared by	 * the reset.	 */	resetctlr(ctlr);	sum = 0;	for(i = 0; i < 0x0E; i++){		r = atc93c46r(ctlr, i);		ctlr->eeprom[i] = r;		sum += r;		sum += r>>8;	}	if(sum != 0){		print("dp83820reset: bad EEPROM checksum\n");		return -1;	}#ifdef notdef	csr32w(ctlr, Gpior, ctlr->eeprom[4]);	cfg = Extstsen|Exd;	r = csr32r(ctlr, Cfg);	if(ctlr->eeprom[5] & 0x0001)		cfg |= Ext125;	if(ctlr->eeprom[5] & 0x0002)		cfg |= M64addren;	if((ctlr->eeprom[5] & 0x0004) && (r & Pci64det))		cfg |= Data64en;	if(ctlr->eeprom[5] & 0x0008)		cfg |= T64addren;	if(!(pcicfgr16(ctlr->pcidev, PciPCR) & 0x10))		cfg |= Mwidis;	if(ctlr->eeprom[5] & 0x0020)		cfg |= Mrmdis;	if(ctlr->eeprom[5] & 0x0080)		cfg |= Mode1000;	if(ctlr->eeprom[5] & 0x0200)		cfg |= Tbien|Mode1000;	/*	 * What about RO bits we might have destroyed with Rst?	 * What about Exd, Tmrtest, Extstsen, Pintctl?	 * Why does it think it has detected a 64-bit bus when	 * it hasn't?	 */#else	//r = csr32r(ctlr, Cfg);	//r &= ~(Mode1000|T64addren|Data64en|M64addren);	//csr32w(ctlr, Cfg, r);	//csr32w(ctlr, Cfg, 0x2000);#endif /* notdef */	ctlr->cfg = csr32r(ctlr, Cfg);print("cfg %8.8ux pcicfg %8.8ux\n", ctlr->cfg, pcicfgr32(ctlr->pcidev, PciPCR));	ctlr->cfg &= ~(T64addren|Data64en|M64addren);	csr32w(ctlr, Cfg, ctlr->cfg);	csr32w(ctlr, Mibc, Aclr|Frz);	return 0;}// from pci.cenum {	Pcinetctlr = 0x02,		/* network controller *///	PciCCRp	= 0x09,			/* programming interface class code *///	PciCCRu	= 0x0A,			/* sub-class code *///	PciCCRb	= 0x0B,			/* base class code */};static voiddp83820pci(void){	void *mem;	Pcidev *p;	Ctlr *ctlr;	p = nil;	while(p = pcimatch(p, 0, 0)){		/* ccru is a short in the FS kernel, thus the cast to uchar */		if(p->ccrb != Pcinetctlr || (uchar)p->ccru != 0)			continue;		switch((p->did<<16)|p->vid){		default:			continue;		case (0x0022<<16)|0x100B:	/* NS DP83820 (Gig-NIC) *//*		case (0x1032<<16)|0x1737:	/* linksys eg1032 */			break;		}		/* cast for FS */		mem = (void *)vmap(p->mem[1].bar & ~0x0F, p->mem[1].size);		if(mem == 0){			print("DP83820: can't map %8.8lux\n", p->mem[1].bar);			continue;		}		/* malloc only zeroes storage if Npadlong!=0, so use mallocz */		ctlr = mallocz(sizeof(Ctlr), 1);		ctlr->port = p->mem[1].bar & ~0x0F;		ctlr->pcidev = p;		ctlr->id = (p->did<<16)|p->vid;#ifdef notdef		/*		 * bar[0] is the I/O port register address and		 * bar[1] is the memory-mapped register address.		 */		if (ioalloc(p->mem[0].bar & ~0x0F, p->mem[0].size, 0, "dp83820")		    < 0) {			print("dp83820: port 0x%uX in use\n", ctlr->port);			free(ctlr);			continue;		}#endif		ctlr->nic = mem;		if(dp83820reset(ctlr)){			free(ctlr);			continue;		}		pcisetbme(p);		if(dp83820ctlrhead != nil)			dp83820ctlrtail->next = ctlr;		else			dp83820ctlrhead = ctlr;		dp83820ctlrtail = ctlr;	}}intdp83820pnp(Ether* edev){	int i;	Ctlr *ctlr;	uchar ea[Eaddrlen];	if(dp83820ctlrhead == nil)		dp83820pci();	/*	 * Any adapter matches if no edev->port is supplied,	 * otherwise the ports must match.	 */	for(ctlr = dp83820ctlrhead; ctlr != nil; ctlr = ctlr->next){		if(ctlr->active)			continue;		if(edev->port == 0 || edev->port == ctlr->port){			ctlr->active = 1;			break;		}	}	if(ctlr == nil)		return -1;	edev->ctlr = ctlr;	edev->port = ctlr->port;	edev->irq = ctlr->pcidev->intl;	edev->tbdf = ctlr->pcidev->tbdf;	edev->mbps = 1000;	/*	 * Check if the adapter's station address is to be overridden.	 * If not, read it from the EEPROM and set in ether->ea prior to	 * loading the station address in the hardware.	 */	memset(ea, 0, Eaddrlen);	if(memcmp(ea, edev->ea, Eaddrlen) == 0){		for(i = 0; i < Eaddrlen/2; i++){			edev->ea[2*i] = ctlr->eeprom[0x0C-i];			edev->ea[2*i+1] = ctlr->eeprom[0x0C-i]>>8;		}	}	edev->attach = dp83820attach;	edev->transmit = dp83820transmit;	edev->interrupt = dp83820interrupt;#ifndef FS	edev->ifstat = dp83820ifstat;	edev->arg = edev;	edev->shutdown = shutdown;	edev->multicast = multicast;	edev->promiscuous = dp83820promiscuous;#endif	return 0;}#ifndef FSvoidetherdp83820link(void){	addethercard("DP83820", dp83820pnp);}voidetherdp83820bothlink(void){	etherdp83820link();}#endif

⌨️ 快捷键说明

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