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

📄 ether2114x.c

📁 著名操作系统Plan 9的第三版的部分核心源代码。现在很难找到了。Plan 9是bell实验室开发的Unix后继者。
💻 C
📖 第 1 页 / 共 3 页
字号:
/* * Digital Semiconductor DECchip 2114x PCI Fast Ethernet LAN Controller. * To do: *	thresholds; *	ring sizing; *	handle more error conditions; *	tidy setup packet mess; *	push initialisation back to attach; *	full SROM decoding. */#include "u.h"#include "../port/lib.h"#include "mem.h"#include "dat.h"#include "fns.h"#include "io.h"#include "../port/error.h"#include "../port/netif.h"#include "etherif.h"#define DEBUG		0#define debug		if(DEBUG)printenum {	Nrde		= 64,	Ntde		= 64,};enum {					/* CRS0 - Bus Mode */	Swr		= 0x00000001,	/* Software Reset */	Bar		= 0x00000002,	/* Bus Arbitration */	Dsl		= 0x0000007C,	/* Descriptor Skip Length (field) */	Ble		= 0x00000080,	/* Big/Little Endian */	Pbl		= 0x00003F00,	/* Programmable Burst Length (field) */	Cal		= 0x0000C000,	/* Cache Alignment (field) */	Cal8		= 0x00004000,	/* 8 longword boundary alignment */	Cal16		= 0x00008000,	/* 16 longword boundary alignment */	Cal32		= 0x0000C000,	/* 32 longword boundary alignment */	Tap		= 0x000E0000,	/* Transmit Automatic Polling (field) */	Dbo		= 0x00100000,	/* Descriptor Byte Ordering Mode */	Rml		= 0x00200000,	/* Read Multiple */}; enum {					/* CSR[57] - Status and Interrupt Enable */	Ti		= 0x00000001,	/* Transmit Interrupt */	Tps		= 0x00000002,	/* Transmit Process Stopped */	Tu		= 0x00000004,	/* Transmit buffer Unavailable */	Tjt		= 0x00000008,	/* Transmit Jabber Timeout */	Unf		= 0x00000020,	/* transmit UNderFlow */	Ri		= 0x00000040,	/* Receive Interrupt */	Ru		= 0x00000080,	/* Receive buffer Unavailable */	Rps		= 0x00000100,	/* Receive Process Stopped */	Rwt		= 0x00000200,	/* Receive Watchdog Timeout */	Eti		= 0x00000400,	/* Early Transmit Interrupt */	Gte		= 0x00000800,	/* General purpose Timer Expired */	Fbe		= 0x00002000,	/* Fatal Bit Error */	Ais		= 0x00008000,	/* Abnormal Interrupt Summary */	Nis		= 0x00010000,	/* Normal Interrupt Summary */	Rs		= 0x000E0000,	/* Receive process State (field) */	Ts		= 0x00700000,	/* Transmit process State (field) */	Eb		= 0x03800000,	/* Error bits */};enum {					/* CSR6 - Operating Mode */	Hp		= 0x00000001,	/* Hash/Perfect receive filtering mode */	Sr		= 0x00000002,	/* Start/stop Receive */	Ho		= 0x00000004,	/* Hash-Only filtering mode */	Pb		= 0x00000008,	/* Pass Bad frames */	If		= 0x00000010,	/* Inverse Filtering */	Sb		= 0x00000020,	/* Start/stop Backoff counter */	Pr		= 0x00000040,	/* Promiscuous Mode */	Pm		= 0x00000080,	/* Pass all Multicast */	Fd		= 0x00000200,	/* Full Duplex mode */	Om		= 0x00000C00,	/* Operating Mode (field) */	Fc		= 0x00001000,	/* Force Collision */	St		= 0x00002000,	/* Start/stop Transmission Command */	Tr		= 0x0000C000,	/* ThReshold control bits (field) */	Tr128		= 0x00000000,	Tr256		= 0x00004000,	Tr512		= 0x00008000,	Tr1024		= 0x0000C000,	Ca		= 0x00020000,	/* CApture effect enable */	Ps		= 0x00040000,	/* Port Select */	Hbd		= 0x00080000,	/* HeartBeat Disable */	Imm		= 0x00100000,	/* IMMediate mode */	Sf		= 0x00200000,	/* Store and Forward */	Ttm		= 0x00400000,	/* Transmit Threshold Mode */	Pcs		= 0x00800000,	/* PCS function */	Scr		= 0x01000000,	/* SCRambler mode */	Mbo		= 0x02000000,	/* Must Be One */	Ra		= 0x40000000,	/* Receive All */	Sc		= 0x80000000,	/* Special Capture effect enable */	TrMODE		= Tr512,	/* default transmission threshold */};enum {					/* CSR9 - ROM and MII Management */	Scs		= 0x00000001,	/* serial ROM chip select */	Sclk		= 0x00000002,	/* serial ROM clock */	Sdi		= 0x00000004,	/* serial ROM data in */	Sdo		= 0x00000008,	/* serial ROM data out */	Ss		= 0x00000800,	/* serial ROM select */	Wr		= 0x00002000,	/* write */	Rd		= 0x00004000,	/* read */	Mdc		= 0x00010000,	/* MII management clock */	Mdo		= 0x00020000,	/* MII management write data */	Mii		= 0x00040000,	/* MII management operation mode (W) */	Mdi		= 0x00080000,	/* MII management data in */};enum {					/* CSR12 - General-Purpose Port */	Gpc		= 0x00000100,	/* General Purpose Control */};typedef struct Des {	int	status;	int	control;	ulong	addr;	Block*	bp;} Des;enum {					/* status */	Of		= 0x00000001,	/* Rx: OverFlow */	Ce		= 0x00000002,	/* Rx: CRC Error */	Db		= 0x00000004,	/* Rx: Dribbling Bit */	Re		= 0x00000008,	/* Rx: Report on MII Error */	Rw		= 0x00000010,	/* Rx: Receive Watchdog */	Ft		= 0x00000020,	/* Rx: Frame Type */	Cs		= 0x00000040,	/* Rx: Collision Seen */	Tl		= 0x00000080,	/* Rx: Frame too Long */	Ls		= 0x00000100,	/* Rx: Last deScriptor */	Fs		= 0x00000200,	/* Rx: First deScriptor */	Mf		= 0x00000400,	/* Rx: Multicast Frame */	Rf		= 0x00000800,	/* Rx: Runt Frame */	Dt		= 0x00003000,	/* Rx: Data Type (field) */	De		= 0x00004000,	/* Rx: Descriptor Error */	Fl		= 0x3FFF0000,	/* Rx: Frame Length (field) */	Ff		= 0x40000000,	/* Rx: Filtering Fail */	Def		= 0x00000001,	/* Tx: DEFerred */	Uf		= 0x00000002,	/* Tx: UnderFlow error */	Lf		= 0x00000004,	/* Tx: Link Fail report */	Cc		= 0x00000078,	/* Tx: Collision Count (field) */	Hf		= 0x00000080,	/* Tx: Heartbeat Fail */	Ec		= 0x00000100,	/* Tx: Excessive Collisions */	Lc		= 0x00000200,	/* Tx: Late Collision */	Nc		= 0x00000400,	/* Tx: No Carrier */	Lo		= 0x00000800,	/* Tx: LOss of carrier */	To		= 0x00004000,	/* Tx: Transmission jabber timeOut */	Es		= 0x00008000,	/* [RT]x: Error Summary */	Own		= 0x80000000,	/* [RT]x: OWN bit */};enum {					/* control */	Bs1		= 0x000007FF,	/* [RT]x: Buffer 1 Size */	Bs2		= 0x003FF800,	/* [RT]x: Buffer 2 Size */	Ch		= 0x01000000,	/* [RT]x: second address CHained */	Er		= 0x02000000,	/* [RT]x: End of Ring */	Ft0		= 0x00400000,	/* Tx: Filtering Type 0 */	Dpd		= 0x00800000,	/* Tx: Disabled PaDding */	Ac		= 0x04000000,	/* Tx: Add CRC disable */	Set		= 0x08000000,	/* Tx: SETup packet */	Ft1		= 0x10000000,	/* Tx: Filtering Type 1 */	Fseg		= 0x20000000,	/* Tx: First SEGment */	Lseg		= 0x40000000,	/* Tx: Last SEGment */	Ic		= 0x80000000,	/* Tx: Interrupt on Completion */};enum {					/* PHY registers */	Bmcr		= 0,		/* Basic Mode Control */	Bmsr		= 1,		/* Basic Mode Status */	Phyidr1		= 2,		/* PHY Identifier #1 */	Phyidr2		= 3,		/* PHY Identifier #2 */	Anar		= 4,		/* Auto-Negotiation Advertisment */	Anlpar		= 5,		/* Auto-Negotiation Link Partner Ability */	Aner		= 6,		/* Auto-Negotiation Expansion */};typedef struct Ctlr Ctlr;typedef struct Ctlr {	int	port;	Pcidev*	pcidev;	Ctlr*	next;	int	active;	uchar	srom[128];	uchar*	sromea;			/* MAC address */	uchar*	leaf;	int	sct;			/* selected connection type */	int	k;			/* info block count */	uchar*	infoblock[16];	int	sctk;			/* sct block index */	int	curk;			/* current block index */	uchar*	type5block;	int	phy[32];		/* logical to physical map */	int	phyreset;		/* reset bitmap */	int	curphyad;	int	fdx;	int	ttm;	uchar	fd;			/* option */	int	medium;			/* option */	int	csr6;			/* CSR6 - operating mode */	int	mask;			/* CSR[57] - interrupt mask */	int	mbps;	Lock	lock;	Des*	rdr;			/* receive descriptor ring */	int	nrdr;			/* size of rdr */	int	rdrx;			/* index into rdr */	Lock	tlock;	Des*	tdr;			/* transmit descriptor ring */	int	ntdr;			/* size of tdr */	int	tdrh;			/* host index into tdr */	int	tdri;			/* interface index into tdr */	int	ntq;			/* descriptors active */	int	ntqmax;	Block*	setupbp;	ulong	of;			/* receive statistics */	ulong	ce;	ulong	cs;	ulong	tl;	ulong	rf;	ulong	de;	ulong	ru;	ulong	rps;	ulong	rwt;	ulong	uf;			/* transmit statistics */	ulong	ec;	ulong	lc;	ulong	nc;	ulong	lo;	ulong	to;	ulong	tps;	ulong	tu;	ulong	tjt;	ulong	unf;} Ctlr;static Ctlr* ctlrhead;static Ctlr* ctlrtail;#define csr32r(c, r)	(inl((c)->port+((r)*8)))#define csr32w(c, r, l)	(outl((c)->port+((r)*8), (ulong)(l)))static voidpromiscuous(void* arg, int on){	Ctlr *ctlr;	ctlr = ((Ether*)arg)->ctlr;	ilock(&ctlr->lock);	if(on)		ctlr->csr6 |= Pr;	else		ctlr->csr6 &= ~Pr;	csr32w(ctlr, 6, ctlr->csr6);	iunlock(&ctlr->lock);}static voidattach(Ether* ether){	Ctlr *ctlr;	ctlr = ether->ctlr;	ilock(&ctlr->lock);	if(!(ctlr->csr6 & Sr)){		ctlr->csr6 |= Sr;		csr32w(ctlr, 6, ctlr->csr6);	}	iunlock(&ctlr->lock);}static longifstat(Ether* ether, void* a, long n, ulong offset){	Ctlr *ctlr;	char *buf, *p;	int i, l, len;	ctlr = ether->ctlr;	ether->crcs = ctlr->ce;	ether->frames = ctlr->rf+ctlr->cs;	ether->buffs = ctlr->de+ctlr->tl;	ether->overflows = ctlr->of;	if(n == 0)		return 0;	p = malloc(READSTR);	l = snprint(p, READSTR, "Overflow: %lud\n", ctlr->of);	l += snprint(p+l, READSTR-l, "Ru: %lud\n", ctlr->ru);	l += snprint(p+l, READSTR-l, "Rps: %lud\n", ctlr->rps);	l += snprint(p+l, READSTR-l, "Rwt: %lud\n", ctlr->rwt);	l += snprint(p+l, READSTR-l, "Tps: %lud\n", ctlr->tps);	l += snprint(p+l, READSTR-l, "Tu: %lud\n", ctlr->tu);	l += snprint(p+l, READSTR-l, "Tjt: %lud\n", ctlr->tjt);	l += snprint(p+l, READSTR-l, "Unf: %lud\n", ctlr->unf);	l += snprint(p+l, READSTR-l, "CRC Error: %lud\n", ctlr->ce);	l += snprint(p+l, READSTR-l, "Collision Seen: %lud\n", ctlr->cs);	l += snprint(p+l, READSTR-l, "Frame Too Long: %lud\n", ctlr->tl);	l += snprint(p+l, READSTR-l, "Runt Frame: %lud\n", ctlr->rf);	l += snprint(p+l, READSTR-l, "Descriptor Error: %lud\n", ctlr->de);	l += snprint(p+l, READSTR-l, "Underflow Error: %lud\n", ctlr->uf);	l += snprint(p+l, READSTR-l, "Excessive Collisions: %lud\n", ctlr->ec);	l += snprint(p+l, READSTR-l, "Late Collision: %lud\n", ctlr->lc);	l += snprint(p+l, READSTR-l, "No Carrier: %lud\n", ctlr->nc);	l += snprint(p+l, READSTR-l, "Loss of Carrier: %lud\n", ctlr->lo);	l += snprint(p+l, READSTR-l, "Transmit Jabber Timeout: %lud\n",		ctlr->to);	l += snprint(p+l, READSTR-l, "csr6: %luX %uX\n", csr32r(ctlr, 6),		ctlr->csr6);	snprint(p+l, READSTR-l, "ntqmax: %d\n", ctlr->ntqmax);	ctlr->ntqmax = 0;	buf = a;	len = readstr(offset, buf, n, p);	if(offset > l)		offset -= l;	else		offset = 0;	buf += len;	n -= len;	l = snprint(p, READSTR, "srom:");	for(i = 0; i < sizeof(ctlr->srom); i++){		if(i && ((i & 0x0F) == 0))			l += snprint(p+l, READSTR-l, "\n     ");		l += snprint(p+l, READSTR-l, " %2.2uX", ctlr->srom[i]);	}	snprint(p+l, READSTR-l, "\n");	len += readstr(offset, buf, n, p);	free(p);	return len;}static voidtxstart(Ether* ether){	Ctlr *ctlr;	Block *bp;	Des *des;	int control;	ctlr = ether->ctlr;	while(ctlr->ntq < (ctlr->ntdr-1)){		if(ctlr->setupbp){			bp = ctlr->setupbp;			ctlr->setupbp = 0;			control = Ic|Set|BLEN(bp);		}		else{			bp = qget(ether->oq);			if(bp == nil)				break;			control = Ic|Lseg|Fseg|BLEN(bp);		}		ctlr->tdr[PREV(ctlr->tdrh, ctlr->ntdr)].control &= ~Ic;		des = &ctlr->tdr[ctlr->tdrh];		des->bp = bp;		des->addr = PADDR(bp->rp);		des->control |= control;		ctlr->ntq++;		coherence();		des->status = Own;		csr32w(ctlr, 1, 0);		ctlr->tdrh = NEXT(ctlr->tdrh, ctlr->ntdr);	}	if(ctlr->ntq > ctlr->ntqmax)		ctlr->ntqmax = ctlr->ntq;}static voidtransmit(Ether* ether){	Ctlr *ctlr;	ctlr = ether->ctlr;	ilock(&ctlr->tlock);	txstart(ether);	iunlock(&ctlr->tlock);}static voidinterrupt(Ureg*, void* arg){	Ctlr *ctlr;	Ether *ether;	int len, status;	Des *des;	Block *bp;	ether = arg;	ctlr = ether->ctlr;	while((status = csr32r(ctlr, 5)) & (Nis|Ais)){		/*		 * Acknowledge the interrupts and mask-out		 * the ones that are implicitly handled.		 */		csr32w(ctlr, 5, status);		status &= (ctlr->mask & ~(Nis|Ti));		if(status & Ais){			if(status & Tps)				ctlr->tps++;			if(status & Tu)				ctlr->tu++;			if(status & Tjt)				ctlr->tjt++;			if(status & Ru)				ctlr->ru++;			if(status & Rps)				ctlr->rps++;			if(status & Rwt)				ctlr->rwt++;			status &= ~(Ais|Rwt|Rps|Ru|Tjt|Tu|Tps);		}		/*		 * Received packets.		 */		if(status & Ri){			des = &ctlr->rdr[ctlr->rdrx];			while(!(des->status & Own)){				if(des->status & Es){					if(des->status & Of)						ctlr->of++;					if(des->status & Ce)						ctlr->ce++;					if(des->status & Cs)						ctlr->cs++;					if(des->status & Tl)						ctlr->tl++;					if(des->status & Rf)						ctlr->rf++;					if(des->status & De)						ctlr->de++;				}				else if(bp = iallocb(sizeof(Etherpkt)+4)){					len = ((des->status & Fl)>>16)-4;					des->bp->wp = des->bp->rp+len;					etheriq(ether, des->bp, 1);					des->bp = bp;					des->addr = PADDR(bp->rp);				}				des->control &= Er;				des->control |= ROUNDUP(sizeof(Etherpkt)+4, 4);				coherence();				des->status = Own;				ctlr->rdrx = NEXT(ctlr->rdrx, ctlr->nrdr);				des = &ctlr->rdr[ctlr->rdrx];			}			status &= ~Ri;		}		/*		 * Check the transmit side:		 *	check for Transmit Underflow and Adjust

⌨️ 快捷键说明

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