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

📄 ether83815.mii.c

📁 这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易于我们学习和理解
💻 C
📖 第 1 页 / 共 3 页
字号:
	data = mdior(ctlr, 18);	if(data & 0x10000)		return -1;	return data & 0xFFFF;}static intns83815miimiw(Mii* mii, int pa, int ra, int data){	Ctlr *ctlr;	ctlr = mii->ctlr;	/*	 * MII Management Interface Write.	 *	 * Preamble;	 * ST+OP+PA+RA+LT + 16 data bits;	 * Z.	 */	mdiow(ctlr, 0xFFFFFFFF, 32);	data &= 0xFFFF;	data |= (0x05<<(5+5+2+16))|(pa<<(5+2+16))|(ra<<(2+16))|(0x02<<16);	mdiow(ctlr, data, 32);	return data & 0xFFFF;	/* TODO: what's the caller expect here? */}// TODO: finish thisstatic intsismiimir(Mii* mii, int pa, int ra){	int data;	Ctlr *ctlr;	ctlr = mii->ctlr;	/*	 * MII Management Interface Read.	 *	 * Preamble;	 * ST+OP+PA+RA;	 * LT + 16 data bits.	 */	mdiow(ctlr, 0xFFFFFFFF, 32);	mdiow(ctlr, 0x1800|(pa<<5)|ra, 14);	data = mdior(ctlr, 18);	if(data & 0x10000)		return -1;	return data & 0xFFFF;}// TODO: finish thisstatic intsismiimiw(Mii* mii, int pa, int ra, int data){	Ctlr *ctlr;	ctlr = mii->ctlr;	/*	 * MII Management Interface Write.	 *	 * Preamble;	 * ST+OP+PA+RA+LT + 16 data bits;	 * Z.	 */	mdiow(ctlr, 0xFFFFFFFF, 32);	data &= 0xFFFF;	data |= (0x05<<(5+5+2+16))|(pa<<(5+2+16))|(ra<<(2+16))|(0x02<<16);	mdiow(ctlr, data, 32);	return data & 0xFFFF;	/* TODO: what's the caller expect here? */}// MII// TODO: finish thisstatic intmedia(Ether* ether){	Ctlr* ctlr;	ulong cfg;	ctlr = ether->ctlr;	cfg = csr32r(ctlr, Rcfg);	if(waserror()){err:		if(ctlr->mii != nil){			free(ctlr->mii);			ctlr->mii = nil;		}#ifdef FS		return 10;#else		nexterror();#endif	}	switch (ctlr->id) {	case SiS900:	case SiS7016:		if (1){			if((ctlr->mii = malloc(sizeof(Mii))) == nil)				error(Enomem);			ctlr->mii->ctlr = ctlr;			ctlr->mii->mir = sismiimir;			ctlr->mii->miw = sismiimiw;			if(mii(ctlr->mii, ~0) == 0)				error("no PHY");			// ctlr->cfg |= Dupstsien|Lnkstsien|Spdstsien;			// ctlr->imr |= Phy;		}		break;	case Nat83815:		if (1){			if((ctlr->mii = malloc(sizeof(Mii))) == nil)				error(Enomem);			ctlr->mii->ctlr = ctlr;			ctlr->mii->mir = ns83815miimir;			ctlr->mii->miw = ns83815miimiw;			if(mii(ctlr->mii, ~0) == 0)				error("no PHY");			// ctlr->cfg |= Dupstsien|Lnkstsien|Spdstsien;			// ctlr->imr |= Phy;		}		break;	}	ctlr->fd = (cfg & Fdup) != 0;	if(cfg & Speed100)		return 100;	if((cfg & Lnksts) == 0)		return 100;	/* no link: use 100 to ensure larger queues */	return 10;}static char* mediatable[9] = {	"10BASE-T",				/* TP */	"10BASE-2",				/* BNC */	"10BASE-5",				/* AUI */	"100BASE-TX",	"10BASE-TFD",	"100BASE-TXFD",	"100BASE-T4",	"100BASE-FX",	"100BASE-FXFD",};enum {	MagicReg = 0x48,	MagicRegSz = 1,	Magicrden = 0x40,	/* read enable, apparently */	Paddr=		0x70,	/* address port */	Pdata=		0x71,	/* data port */};/* rcmos() originally from LANL's SiS 900 driver's rcmos() */static intsisrdcmos(Ctlr *ctlr){	int i;	unsigned reg;	ulong port;	Pcidev *p;	p = pcimatch(nil, SiS, SiS630bridge);	if (p == nil) {		print("ns83815: no SiS 630 rev. %ux bridge for mac addr\n",			ctlr->pcidev->rid);		return 0;	}	port = p->mem[0].bar & ~0x01;	print("ns83815: SiS 630 rev. %ux reading mac addr from cmos via bridge at port 0x%lux\n",		ctlr->pcidev->rid, port);	reg = pcicfgr8(p, MagicReg);	pcicfgw8(p, MagicReg, reg|Magicrden);	for (i = 0; i < Eaddrlen; i++) {		outb(port+Paddr, SiS630eenodeaddr + i);		ctlr->sromea[i] = inb(port+Pdata);	}	pcicfgw8(p, MagicReg, reg & ~Magicrden);	return 1;}static intis630(ulong id, Pcidev *p){	if (id == SiS900)		switch (p->rid) {		case SiSrev630s:		case SiSrev630e:	  	case SiSrev630ea1:			return 1;		}	return 0;}/* * If this is a SiS 630E chipset with an embedded SiS 900 controller, * we have to read the MAC address from the APC CMOS RAM. - sez freebsd. * However, CMOS *is* NVRAM normally.  See devrtc.c:440, memory.c:88. */static voidsissrom(Ctlr *ctlr){	union {		uchar	eaddr[Eaddrlen];		ushort	alignment;	} ee;	int i, off = SiSeenodeaddr, cnt = sizeof ee.eaddr / sizeof(short);	ushort *shp = (ushort *)ee.eaddr;	if (!is630(ctlr->id, ctlr->pcidev) || !sisrdcmos(ctlr)) {		print("ns83815: reading SiS mac address from eeprom\n");		for (i = 0; i < cnt; i++)			*shp++ = eegetw(ctlr, off++);		memmove(ctlr->sromea, ee.eaddr, sizeof ctlr->sromea);	}}static voidnssrom(Ctlr *ctlr){	int i, j;	debug("ns83815: fa311: reading mac address from eeprom & swizzling\n");	for(i = 0; i < nelem(ctlr->srom); i++)		ctlr->srom[i] = eegetw(ctlr, i);	/*	 * the MAC address is reversed, straddling word boundaries	 */	j = Nseenodeaddr*16 + 15;		// bit offset to read	for (i=0; i<48; i++, j++)		ctlr->sromea[i>>3] |=			((ctlr->srom[j>>4] >> (15-(j&0xF))) & 1) << (i&7);}static voidsrom(Ctlr* ctlr){	memset(ctlr->sromea, 0, sizeof(ctlr->sromea));	switch (ctlr->id) {	case SiS900:	case SiS7016:		sissrom(ctlr);		break;	case Nat83815:		nssrom(ctlr);		break;	default:		print("ns83815: srom: unknown id 0x%ux\n", ctlr->id);		break;	}}// from pci.cenum {	Pcinetctlr = 0x02,		/* network controller *///	PciCCRp	= 0x09,			/* programming interface class code *///	PciCCRu	= 0x0A,			/* sub-class code *///	PciCCRb	= 0x0B,			/* base class code */};static voidscanpci83815(void){	typedef struct {		ulong	bar;		/* base address */		int	size;	} Bar;	int port;	ulong id;	Bar *portbarp;	Ctlr *ctlr;	Pcidev *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;		// not a nic		id = (p->did<<16)|p->vid;		// print("ns83815: id 0x%lux on pci bus\n", id);		switch(id){		case Nat83815:			print("ns83815: FA31[12] found\n");			break;		case SiS900:			print("ns83815: SiS900");			if (is630(id, p))				print(" (within SiS630)");			print(" found\n");			break;		case SiS7016:			print("ns83815: SiS7016 found\n");			break;		default:			continue;		// unrecognised		}		portbarp = &p->mem[0];		port = portbarp->bar & ~1;		/*		 * bar[0] is the I/O port register address and		 * bar[1] is the memory-mapped register address.		 */		ctlr = mallocz(sizeof(Ctlr), 1);		ctlr->port = port;		ctlr->pcidev = p;		ctlr->id = id;		if(ioalloc(ctlr->port, portbarp->size, 0, "ns83815") < 0){			print("ns83815: port 0x%ux in use\n", ctlr->port);			free(ctlr);			continue;		}		softreset(ctlr, 0);		srom(ctlr);		if(ctlrhead != nil)			ctlrtail->next = ctlr;		else			ctlrhead = ctlr;		ctlrtail = ctlr;	}}intdp83815reset(Ether* ether){	Ctlr *ctlr;	int i, x;	ulong ctladdr;	uchar ea[Eaddrlen];	static int scandone;	if(scandone == 0){		scanpci83815();		scandone = 1;	}	/*	 * Any adapter matches if no ether->port is supplied,	 * otherwise the ports must match.	 */	for(ctlr = ctlrhead; ctlr != nil; ctlr = ctlr->next){		if(ctlr->active)			continue;		if(ether->port == 0 || ether->port == ctlr->port){			ctlr->active = 1;			break;		}	}	if(ctlr == nil)		return -1;	ether->ctlr = ctlr;	ether->port = ctlr->port;	ether->irq = ctlr->pcidev->intl;	ether->tbdf = ctlr->pcidev->tbdf;	/*	 * 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, ether->ea, Eaddrlen) == 0)		memmove(ether->ea, ctlr->sromea, Eaddrlen);	print("ns83815: setting mac addr\n");		/* DEBUG */	for(i=0; i<Eaddrlen; i+=2){		x = ether->ea[i] | (ether->ea[i+1]<<8);		ctladdr = (ctlr->id == Nat83815? i: i<<15);		csr32w(ctlr, Rrfcr, ctladdr);		csr32w(ctlr, Rrfdr, x);	}	csr32w(ctlr, Rrfcr, Rfen|Apm|Aab|Aam);	ether->mbps = media(ether);	/*	 * Look for a medium override in case there's no autonegotiation	 * or the autonegotiation fails.	 */	for(i = 0; i < ether->nopt; i++){		if(cistrcmp(ether->opt[i], "FD") == 0){			ctlr->fd = 1;			continue;		}		for(x = 0; x < nelem(mediatable); x++){			debug("compare <%s> <%s>\n", mediatable[x],				ether->opt[i]);			if(cistrcmp(mediatable[x], ether->opt[i]) == 0){				if(x != 4 && x >= 3)					ether->mbps = 100;				else					ether->mbps = 10;				switch(x){				default:					ctlr->fd = 0;					break;				case 0x04:		/* 10BASE-TFD */				case 0x05:		/* 100BASE-TXFD */				case 0x08:		/* 100BASE-FXFD */					ctlr->fd = 1;					break;				}				break;			}		}	}	/*	 * Initialise descriptor rings, ethernet address.	 */	ctlr->nrdr = Nrde;	ctlr->ntdr = Ntde;	pcisetbme(ctlr->pcidev);	ctlrinit(ether);	/*	 * Linkage to the generic ethernet driver.	 */	ether->attach = attach;	ether->transmit = transmit;	ether->interrupt = interrupt;#ifndef FS	ether->ifstat = ifstat;	ether->arg = ether;	ether->promiscuous = promiscuous;#endif	debug("ns83815: dp83815reset: done\n");	return 0;}#ifndef FSvoidether83815link(void){	addethercard("83815",  dp83815reset);}#endif

⌨️ 快捷键说明

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