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

📄 etherelnk3.c

📁 著名操作系统Plan 9的第三版的部分核心源代码。现在很难找到了。Plan 9是bell实验室开发的Unix后继者。
💻 C
📖 第 1 页 / 共 4 页
字号:
/* * Etherlink III, Fast EtherLink and Fast EtherLink XL adapters. * To do: *	check robustness in the face of errors (e.g. busmaster & rxUnderrun); *	RxEarly and busmaster; *	autoSelect; *	PCI latency timer and master enable; *	errata list; *	rewrite all initialisation; *	handle the cyclone adapter. * * Product ID: *	9150 ISA	3C509[B] *	9050 ISA	3C509[B]-TP *	9450 ISA	3C509[B]-COMBO *	9550 ISA	3C509[B]-TPO * *	9350 EISA	3C579 *	9250 EISA	3C579-TP * *	5920 EISA	3C592-[TP|COMBO|TPO] *	5970 EISA	3C597-TX	Fast Etherlink 10BASE-T/100BASE-TX *	5971 EISA	3C597-T4	Fast Etherlink 10BASE-T/100BASE-T4 *	5972 EISA	3C597-MII	Fast Etherlink 10BASE-T/MII * *	5900 PCI	3C590-[TP|COMBO|TPO] *	5950 PCI	3C595-TX	Fast Etherlink Shared 10BASE-T/100BASE-TX *	5951 PCI	3C595-T4	Fast Etherlink Shared 10BASE-T/100BASE-T4 *	5952 PCI	3C595-MII	Fast Etherlink 10BASE-T/MII * *	9000 PCI	3C900-TPO	Etherlink III XL PCI 10BASE-T *	9001 PCI	3C900-COMBO	Etherlink III XL PCI 10BASE-T/10BASE-2/AUI *	9005 PCI	3C900B-COMBO	Etherlink III XL PCI 10BASE-T/10BASE-2/AUI *	9050 PCI	3C905-TX	Fast Etherlink XL Shared 10BASE-T/100BASE-TX *	9051 PCI	3C905-T4	Fast Etherlink Shared 10BASE-T/100BASE-T4 *	9055 PCI	3C905B-TX	Fast Etherlink Shared 10BASE-T/100BASE-TX * *	9058 PCMCIA	3C589[B]-[TP|COMBO] * *	627C MCA	3C529 *	627D MCA	3C529-TP */#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 XCVRDEBUG		if(0)printenum {	IDport			= 0x0110,	/* anywhere between 0x0100 and 0x01F0 */};enum {						/* all windows */	CommandR		= 0x000E,	IntStatusR		= 0x000E,};enum {						/* Commands */	GlobalReset		= 0x0000,	SelectRegisterWindow	= 0x0001,	EnableDcConverter	= 0x0002,	RxDisable		= 0x0003,	RxEnable		= 0x0004,	RxReset			= 0x0005,	Stall			= 0x0006,	/* 3C90x */	TxDone			= 0x0007,	RxDiscard		= 0x0008,	TxEnable		= 0x0009,	TxDisable		= 0x000A,	TxReset			= 0x000B,	RequestInterrupt	= 0x000C,	AcknowledgeInterrupt	= 0x000D,	SetInterruptEnable	= 0x000E,	SetIndicationEnable	= 0x000F,	/* SetReadZeroMask */	SetRxFilter		= 0x0010,	SetRxEarlyThresh	= 0x0011,	SetTxAvailableThresh	= 0x0012,	SetTxStartThresh	= 0x0013,	StartDma		= 0x0014,	/* initiate busmaster operation */	StatisticsEnable	= 0x0015,	StatisticsDisable	= 0x0016,	DisableDcConverter	= 0x0017,	SetTxReclaimThresh	= 0x0018,	/* PIO-only adapters */	PowerUp			= 0x001B,	/* not all adapters */	PowerDownFull		= 0x001C,	/* not all adapters */	PowerAuto		= 0x001D,	/* not all adapters */};enum {						/* (Global|Rx|Tx)Reset command bits */	tpAuiReset		= 0x0001,	/* 10BaseT and AUI transceivers */	endecReset		= 0x0002,	/* internal Ethernet encoder/decoder */	networkReset		= 0x0004,	/* network interface logic */	fifoReset		= 0x0008,	/* FIFO control logic */	aismReset		= 0x0010,	/* autoinitialise state-machine logic */	hostReset		= 0x0020,	/* bus interface logic */	dmaReset		= 0x0040,	/* bus master logic */	vcoReset		= 0x0080,	/* on-board 10Mbps VCO */	updnReset		= 0x0100,	/* upload/download (Rx/TX) logic */	resetMask		= 0x01FF,};enum {						/* Stall command bits */	upStall			= 0x0000,	upUnStall		= 0x0001,	dnStall			= 0x0002,	dnUnStall		= 0x0003,};enum {						/* SetRxFilter command bits */	receiveIndividual	= 0x0001,	/* match station address */	receiveMulticast	= 0x0002,	receiveBroadcast	= 0x0004,	receiveAllFrames	= 0x0008,	/* promiscuous */};enum {						/* StartDma command bits */	Upload			= 0x0000,	/* transfer data from adapter to memory */	Download		= 0x0001,	/* transfer data from memory to adapter */};enum {						/* IntStatus bits */	interruptLatch		= 0x0001,	hostError		= 0x0002,	/* Adapter Failure */	txComplete		= 0x0004,	txAvailable		= 0x0008,	rxComplete		= 0x0010,	rxEarly			= 0x0020,	intRequested		= 0x0040,	updateStats		= 0x0080,	transferInt		= 0x0100,	/* Bus Master Transfer Complete */	dnComplete		= 0x0200,	upComplete		= 0x0400,	busMasterInProgress	= 0x0800,	commandInProgress	= 0x1000,	interruptMask		= 0x07FE,};#define COMMAND(port, cmd, a)	outs((port)+CommandR, ((cmd)<<11)|(a))#define STATUS(port)		ins((port)+IntStatusR)enum {						/* Window 0 - setup */	Wsetup			= 0x0000,						/* registers */	ManufacturerID		= 0x0000,	/* 3C5[08]*, 3C59[27] */	ProductID		= 0x0002,	/* 3C5[08]*, 3C59[27] */	ConfigControl		= 0x0004,	/* 3C5[08]*, 3C59[27] */	AddressConfig		= 0x0006,	/* 3C5[08]*, 3C59[27] */	ResourceConfig		= 0x0008,	/* 3C5[08]*, 3C59[27] */	EepromCommand		= 0x000A,	EepromData		= 0x000C,						/* AddressConfig Bits */	autoSelect9		= 0x0080,	xcvrMask9		= 0xC000,						/* ConfigControl bits */	Ena			= 0x0001,	base10TAvailable9	= 0x0200,	coaxAvailable9		= 0x1000,	auiAvailable9		= 0x2000,						/* EepromCommand bits */	EepromReadRegister	= 0x0080,	EepromBusy		= 0x8000,};#define EEPROMCMD(port, cmd, a)	outs((port)+EepromCommand, (cmd)|(a))#define EEPROMBUSY(port)	(ins((port)+EepromCommand) & EepromBusy)#define EEPROMDATA(port)	ins((port)+EepromData)enum {						/* Window 1 - operating set */	Wop			= 0x0001,						/* registers */	Fifo			= 0x0000,	RxError			= 0x0004,	/* 3C59[0257] only */	RxStatus		= 0x0008,	Timer			= 0x000A,	TxStatus		= 0x000B,	TxFree			= 0x000C,						/* RxError bits */	rxOverrun		= 0x0001,	runtFrame		= 0x0002,	alignmentError		= 0x0004,	/* Framing */	crcError		= 0x0008,	oversizedFrame		= 0x0010,	dribbleBits		= 0x0080,						/* RxStatus bits */	rxBytes			= 0x1FFF,	/* 3C59[0257] mask */	rxBytes9		= 0x07FF,	/* 3C5[078]9 mask */	rxError9		= 0x3800,	/* 3C5[078]9 error mask */	rxOverrun9		= 0x0000,	oversizedFrame9		= 0x0800,	dribbleBits9		= 0x1000,	runtFrame9		= 0x1800,	alignmentError9		= 0x2000,	/* Framing */	crcError9		= 0x2800,	rxError			= 0x4000,	rxIncomplete		= 0x8000,						/* TxStatus Bits */	txStatusOverflow	= 0x0004,	maxCollisions		= 0x0008,	txUnderrun		= 0x0010,	txJabber		= 0x0020,	interruptRequested	= 0x0040,	txStatusComplete	= 0x0080,};enum {						/* Window 2 - station address */	Wstation		= 0x0002,	ResetOp905B		= 0x000C,};enum {						/* Window 3 - FIFO management */	Wfifo			= 0x0003,						/* registers */	InternalConfig		= 0x0000,	/* 3C509B, 3C589, 3C59[0257] */	OtherInt		= 0x0004,	/* 3C59[0257] */	RomControl		= 0x0006,	/* 3C509B, 3C59[27] */	MacControl		= 0x0006,	/* 3C59[0257] */	ResetOptions		= 0x0008,	/* 3C59[0257] */	MediaOptions		= 0x0008,	/* 3C905B */	RxFree			= 0x000A,						/* InternalConfig bits */	disableBadSsdDetect	= 0x00000100,	ramLocation		= 0x00000200,	/* 0 external, 1 internal */	ramPartition5to3	= 0x00000000,	ramPartition3to1	= 0x00010000,	ramPartition1to1	= 0x00020000,	ramPartition3to5	= 0x00030000,	ramPartitionMask	= 0x00030000,	xcvr10BaseT		= 0x00000000,	xcvrAui			= 0x00100000,	/* 10BASE5 */	xcvr10Base2		= 0x00300000,	xcvr100BaseTX		= 0x00400000,	xcvr100BaseFX		= 0x00500000,	xcvrMii			= 0x00600000,	xcvrMask		= 0x00700000,	autoSelect		= 0x01000000,						/* MacControl bits */	deferExtendEnable	= 0x0001,	deferTimerSelect	= 0x001E,	/* mask */	fullDuplexEnable	= 0x0020,	allowLargePackets	= 0x0040,	extendAfterCollision	= 0x0080,	/* 3C90xB */	flowControlEnable	= 0x0100,	/* 3C90xB */	vltEnable		= 0x0200,	/* 3C90xB */						/* ResetOptions bits */	baseT4Available		= 0x0001,	baseTXAvailable		= 0x0002,	baseFXAvailable		= 0x0004,	base10TAvailable	= 0x0008,	coaxAvailable		= 0x0010,	auiAvailable		= 0x0020,	miiConnector		= 0x0040,};enum {						/* Window 4 - diagnostic */	Wdiagnostic		= 0x0004,						/* registers */	VcoDiagnostic		= 0x0002,	FifoDiagnostic		= 0x0004,	NetworkDiagnostic	= 0x0006,	PhysicalMgmt		= 0x0008,	MediaStatus		= 0x000A,	BadSSD			= 0x000C,	UpperBytesOk		= 0x000D,						/* FifoDiagnostic bits */	txOverrun		= 0x0400,	rxUnderrun		= 0x2000,	receiving		= 0x8000,						/* PhysicalMgmt bits */	mgmtClk			= 0x0001,	mgmtData		= 0x0002,	mgmtDir			= 0x0004,	cat5LinkTestDefeat	= 0x8000,						/* MediaStatus bits */	dataRate100		= 0x0002,	crcStripDisable		= 0x0004,	enableSqeStats		= 0x0008,	collisionDetect		= 0x0010,	carrierSense		= 0x0020,	jabberGuardEnable	= 0x0040,	linkBeatEnable		= 0x0080,	jabberDetect		= 0x0200,	polarityReversed	= 0x0400,	linkBeatDetect		= 0x0800,	txInProg		= 0x1000,	dcConverterEnabled	= 0x4000,	auiDisable		= 0x8000,	/* 10BaseT transceiver selected */};enum {						/* Window 5 - internal state */	Wstate			= 0x0005,						/* registers */	TxStartThresh		= 0x0000,	TxAvailableThresh	= 0x0002,	RxEarlyThresh		= 0x0006,	RxFilter		= 0x0008,	InterruptEnable		= 0x000A,	IndicationEnable	= 0x000C,};enum {						/* Window 6 - statistics */	Wstatistics		= 0x0006,						/* registers */	CarrierLost		= 0x0000,	SqeErrors		= 0x0001,	MultipleColls		= 0x0002,	SingleCollFrames	= 0x0003,	LateCollisions		= 0x0004,	RxOverruns		= 0x0005,	FramesXmittedOk		= 0x0006,	FramesRcvdOk		= 0x0007,	FramesDeferred		= 0x0008,	UpperFramesOk		= 0x0009,	BytesRcvdOk		= 0x000A,	BytesXmittedOk		= 0x000C,};enum {						/* Window 7 - bus master operations */	Wmaster			= 0x0007,						/* registers */	MasterAddress		= 0x0000,	MasterLen		= 0x0006,	MasterStatus		= 0x000C,						/* MasterStatus bits */	masterAbort		= 0x0001,	targetAbort		= 0x0002,	targetRetry		= 0x0004,	targetDisc		= 0x0008,	masterDownload		= 0x1000,	masterUpload		= 0x4000,	masterInProgress	= 0x8000,	masterMask		= 0xD00F,};enum {						/* 3C90x extended register set */	PktStatus		= 0x0020,	/* 32-bits */	DnListPtr		= 0x0024,	/* 32-bits, 8-byte aligned */	FragAddr		= 0x0028,	/* 32-bits */	FragLen			= 0x002C,	/* 16-bits */	ListOffset		= 0x002E,	/* 8-bits */	TxFreeThresh		= 0x002F,	/* 8-bits */	UpPktStatus		= 0x0030,	/* 32-bits */	FreeTimer		= 0x0034,	/* 16-bits */	UpListPtr		= 0x0038,	/* 32-bits, 8-byte aligned */						/* PktStatus bits */	fragLast		= 0x00000001,	dnCmplReq		= 0x00000002,	dnStalled		= 0x00000004,	upCompleteX		= 0x00000008,	dnCompleteX		= 0x00000010,	upRxEarlyEnable		= 0x00000020,	armCountdown		= 0x00000040,	dnInProg		= 0x00000080,	counterSpeed		= 0x00000010,	/* 0 3.2uS, 1 320nS */	countdownMode		= 0x00000020,						/* UpPktStatus bits (dpd->control) */	upPktLenMask		= 0x00001FFF,	upStalled		= 0x00002000,	upError			= 0x00004000,	upPktComplete		= 0x00008000,	upOverrun		= 0x00010000,	/* RxError<<16 */	upRuntFrame		= 0x00020000,	upAlignmentError	= 0x00040000,	upCRCError		= 0x00080000,	upOversizedFrame	= 0x00100000,	upDribbleBits		= 0x00800000,	upOverflow		= 0x01000000,	dnIndicate		= 0x80000000,	/* FrameStartHeader (dpd->control) */	updnLastFrag		= 0x80000000,	/* (dpd->len) */	Nup			= 32,	Ndn			= 64,};/* * Up/Dn Packet Descriptors. * The hardware info (np, control, addr, len) must be 8-byte aligned * and this structure size must be a multiple of 8. */typedef struct Pd Pd;typedef struct Pd {	ulong	np;				/* next pointer */	ulong	control;			/* FSH or UpPktStatus */	ulong	addr;	ulong	len;	Pd*	next;	Block*	bp;} Pd;typedef struct {	Lock	wlock;				/* window access */	int	attached;	int	busmaster;	Block*	rbp;				/* receive buffer */	Block*	txbp;				/* FIFO -based transmission */	int	txthreshold;	int	txbusy;	int	nup;				/* full-busmaster -based reception */	void*	upbase;	Pd*	upr;	Pd*	uphead;	int	ndn;				/* full-busmaster -based transmission */	void*	dnbase;	Pd*	dnr;	Pd*	dnhead;	Pd*	dntail;	int	dnq;	long	interrupts;			/* statistics */	long	timer;	long	stats[BytesRcvdOk+3];	int	upqmax;	int	upqmaxhw;	ulong	upinterrupts;	ulong	upqueued;	ulong	upstalls;	int	dnqmax;	int	dnqmaxhw;	ulong	dninterrupts;	ulong	dnqueued;	int	xcvr;				/* transceiver type */	int	rxstatus9;			/* old-style RxStatus register */	int	rxearly;			/* RxEarlyThreshold */	int	ts;				/* threshold shift */	int	upenabled;	int	dnenabled;} Ctlr;static voidinit905(Ctlr* ctlr){	Block *bp;	Pd *pd, *prev;	/*	 * Create rings for the receive and transmit sides.	 * Take care with alignment:	 *	make sure ring base is 8-byte aligned;	 *	make sure each entry is 8-byte aligned.	 */	ctlr->upbase = malloc((ctlr->nup+1)*sizeof(Pd));	ctlr->upr = (Pd*)ROUNDUP((ulong)ctlr->upbase, 8);	prev = ctlr->upr;	for(pd = &ctlr->upr[ctlr->nup-1]; pd >= ctlr->upr; pd--){		pd->np = PADDR(&prev->np);		pd->control = 0;		bp = allocb(sizeof(Etherpkt));		pd->addr = PADDR(bp->rp);		pd->len = updnLastFrag|sizeof(Etherpkt);		pd->next = prev;		prev = pd;		pd->bp = bp;	}	ctlr->uphead = ctlr->upr;	ctlr->dnbase = malloc((ctlr->ndn+1)*sizeof(Pd));	ctlr->dnr = (Pd*)ROUNDUP((ulong)ctlr->dnbase, 8);	prev = ctlr->dnr;	for(pd = &ctlr->dnr[ctlr->ndn-1]; pd >= ctlr->dnr; pd--){		pd->next = prev;		prev = pd;	}	ctlr->dnhead = ctlr->dnr;	ctlr->dntail = ctlr->dnr;	ctlr->dnq = 0;}static Block*rbpalloc(Block* (*f)(int)){	Block *bp;	ulong addr;	/*	 * The receive buffers must be on a 32-byte	 * boundary for EISA busmastering.	 */	if(bp = f(ROUNDUP(sizeof(Etherpkt), 4) + 31)){		addr = (ulong)bp->base;		addr = ROUNDUP(addr, 32);		bp->rp = (uchar*)addr;	}

⌨️ 快捷键说明

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