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

📄 etherigbe.c

📁 这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易于我们学习和理解
💻 C
📖 第 1 页 / 共 4 页
字号:
/* * Intel 8254[340]NN Gigabit Ethernet Controller * as found on the Intel PRO/1000 series of adapters: *	82543GC	Intel PRO/1000 T *	82544EI Intel PRO/1000 XT *	82540EM Intel PRO/1000 MT *	82541[GP]I *	82547GI *	82546GB *	82546EB * To Do: *	finish autonegotiation code; *	integrate fiber stuff back in (this ONLY handles *		the CAT5 cards at the moment); *	add checksum-offload; *	add tuning control via ctl file; *	this driver is little-endian specific. */#ifdef FS#include "all.h"#include "io.h"#include "mem.h"#include "../ip/ip.h"#else#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"#endif			/* FS */#include "etherif.h"#include "ethermii.h"#include "compat.h"enum {	i82542     	= (0x1000<<16)|0x8086,	i82543gc   	= (0x1004<<16)|0x8086,	i82544ei   	= (0x1008<<16)|0x8086,	i82547ei   	= (0x1019<<16)|0x8086,	i82540em   	= (0x100E<<16)|0x8086,	i82540eplp 	= (0x101E<<16)|0x8086,	i82545gmc	= (0x1026<<16)|0x8086,	i82547gi   	= (0x1075<<16)|0x8086,	i82541gi   	= (0x1076<<16)|0x8086,	i82541gi2	= (0x1077<<16)|0x8086,	i82546gb   	= (0x1079<<16)|0x8086,	i82541pi	= (0x107c<<16)|0x8086,	i82546eb	= (0x1010<<16)|0x8086,};/* from pci.c */enum{					/* command register (pcidev->pcr) */	IOen		= (1<<0),	MEMen		= (1<<1),	MASen		= (1<<2),	MemWrInv	= (1<<4),	PErrEn		= (1<<6),	SErrEn		= (1<<8),};enum {	Ctrl		= 0x00000000,	/* Device Control */	Ctrldup		= 0x00000004,	/* Device Control Duplicate */	Status		= 0x00000008,	/* Device Status */	Eecd		= 0x00000010,	/* EEPROM/Flash Control/Data */	Ctrlext		= 0x00000018,	/* Extended Device Control */	Mdic		= 0x00000020,	/* MDI Control */	Fcal		= 0x00000028,	/* Flow Control Address Low */	Fcah		= 0x0000002C,	/* Flow Control Address High */	Fct		= 0x00000030,	/* Flow Control Type */	Icr		= 0x000000C0,	/* Interrupt Cause Read */	Ics		= 0x000000C8,	/* Interrupt Cause Set */	Ims		= 0x000000D0,	/* Interrupt Mask Set/Read */	Imc		= 0x000000D8,	/* Interrupt mask Clear */	Rctl		= 0x00000100,	/* Receive Control */	Fcttv		= 0x00000170,	/* Flow Control Transmit Timer Value */	Txcw		= 0x00000178,	/* Transmit Configuration Word */	Rxcw		= 0x00000180,	/* Receive Configuration Word */	Tctl		= 0x00000400,	/* Transmit Control */	Tipg		= 0x00000410,	/* Transmit IPG */	Tbt		= 0x00000448,	/* Transmit Burst Timer */	Ait		= 0x00000458,	/* Adaptive IFS Throttle */	Fcrtl		= 0x00002160,	/* Flow Control RX Threshold Low */	Fcrth		= 0x00002168,	/* Flow Control Rx Threshold High */	Rdfh		= 0x00002410,	/* Receive data fifo head */	Rdft		= 0x00002418,	/* Receive data fifo tail */	Rdfhs		= 0x00002420,	/* Receive data fifo head saved */	Rdfts		= 0x00002428,	/* Receive data fifo tail saved */	Rdfpc		= 0x00002430,	/* Receive data fifo packet count */	Rdbal		= 0x00002800,	/* Rd Base Address Low */	Rdbah		= 0x00002804,	/* Rd Base Address High */	Rdlen		= 0x00002808,	/* Receive Descriptor Length */	Rdh		= 0x00002810,	/* Receive Descriptor Head */	Rdt		= 0x00002818,	/* Receive Descriptor Tail */	Rdtr		= 0x00002820,	/* Receive Descriptor Timer Ring */	Rxdctl		= 0x00002828,	/* Receive Descriptor Control */	Radv		= 0x0000282C,	/* Receive Interrupt Absolute Delay Timer */	Txdmac		= 0x00003000,	/* Transfer DMA Control */	Ett		= 0x00003008,	/* Early Transmit Control */	Tdfh		= 0x00003410,	/* Transmit data fifo head */	Tdft		= 0x00003418,	/* Transmit data fifo tail */	Tdfhs		= 0x00003420,	/* Transmit data Fifo Head saved */	Tdfts		= 0x00003428,	/* Transmit data fifo tail saved */	Tdfpc		= 0x00003430,	/* Trasnmit data Fifo packet count */	Tdbal		= 0x00003800,	/* Td Base Address Low */	Tdbah		= 0x00003804,	/* Td Base Address High */	Tdlen		= 0x00003808,	/* Transmit Descriptor Length */	Tdh		= 0x00003810,	/* Transmit Descriptor Head */	Tdt		= 0x00003818,	/* Transmit Descriptor Tail */	Tidv		= 0x00003820,	/* Transmit Interrupt Delay Value */	Txdctl		= 0x00003828,	/* Transmit Descriptor Control */	Tadv		= 0x0000382C,	/* Transmit Interrupt Absolute Delay Timer */	Statistics	= 0x00004000,	/* Start of Statistics Area */	Gorcl		= 0x88/4,	/* Good Octets Received Count */	Gotcl		= 0x90/4,	/* Good Octets Transmitted Count */	Torl		= 0xC0/4,	/* Total Octets Received */	Totl		= 0xC8/4,	/* Total Octets Transmitted */	Nstatistics	= 64,	Rxcsum		= 0x00005000,	/* Receive Checksum Control */	Mta		= 0x00005200,	/* Multicast Table Array */	Ral		= 0x00005400,	/* Receive Address Low */	Rah		= 0x00005404,	/* Receive Address High */	Manc		= 0x00005820,	/* Management Control */};enum {					/* Ctrl */	Bem		= 0x00000002,	/* Big Endian Mode */	Prior		= 0x00000004,	/* Priority on the PCI bus */	Lrst		= 0x00000008,	/* Link Reset */	Asde		= 0x00000020,	/* Auto-Speed Detection Enable */	Slu		= 0x00000040,	/* Set Link Up */	Ilos		= 0x00000080,	/* Invert Loss of Signal (LOS) */	SspeedMASK	= 0x00000300,	/* Speed Selection */	SspeedSHIFT	= 8,	Sspeed10	= 0x00000000,	/* 10Mb/s */	Sspeed100	= 0x00000100,	/* 100Mb/s */	Sspeed1000	= 0x00000200,	/* 1000Mb/s */	Frcspd		= 0x00000800,	/* Force Speed */	Frcdplx		= 0x00001000,	/* Force Duplex */	SwdpinsloMASK	= 0x003C0000,	/* Software Defined Pins - lo nibble */	SwdpinsloSHIFT	= 18,	SwdpioloMASK	= 0x03C00000,	/* Software Defined Pins - I or O */	SwdpioloSHIFT	= 22,	Devrst		= 0x04000000,	/* Device Reset */	Rfce		= 0x08000000,	/* Receive Flow Control Enable */	Tfce		= 0x10000000,	/* Transmit Flow Control Enable */	Vme		= 0x40000000,	/* VLAN Mode Enable */};enum {					/* Status */	Lu		= 0x00000002,	/* Link Up */	Tckok		= 0x00000004,	/* Transmit clock is running */	Rbcok		= 0x00000008,	/* Receive clock is running */	Txoff		= 0x00000010,	/* Transmission Paused */	Tbimode		= 0x00000020,	/* TBI Mode Indication */	LspeedMASK	= 0x000000C0,	/* Link Speed Setting */	LspeedSHIFT	= 6,	Lspeed10	= 0x00000000,	/* 10Mb/s */	Lspeed100	= 0x00000040,	/* 100Mb/s */	Lspeed1000	= 0x00000080,	/* 1000Mb/s */	Mtxckok		= 0x00000400,	/* MTX clock is running */	Pci66		= 0x00000800,	/* PCI Bus speed indication */	Bus64		= 0x00001000,	/* PCI Bus width indication */	Pcixmode	= 0x00002000,	/* PCI-X mode */	PcixspeedMASK	= 0x0000C000,	/* PCI-X bus speed */	PcixspeedSHIFT	= 14,	Pcix66		= 0x00000000,	/* 50-66MHz */	Pcix100		= 0x00004000,	/* 66-100MHz */	Pcix133		= 0x00008000,	/* 100-133MHz */};enum {					/* Ctrl and Status */	Fd		= 0x00000001,	/* Full-Duplex */	AsdvMASK	= 0x00000300,	AsdvSHIFT	= 8,	Asdv10		= 0x00000000,	/* 10Mb/s */	Asdv100		= 0x00000100,	/* 100Mb/s */	Asdv1000	= 0x00000200,	/* 1000Mb/s */};enum {					/* Eecd */	Sk		= 0x00000001,	/* Clock input to the EEPROM */	Cs		= 0x00000002,	/* Chip Select */	Di		= 0x00000004,	/* Data Input to the EEPROM */	Do		= 0x00000008,	/* Data Output from the EEPROM */	Areq		= 0x00000040,	/* EEPROM Access Request */	Agnt		= 0x00000080,	/* EEPROM Access Grant */	Eepresent	= 0x00000100,	/* EEPROM Present */	Eesz256		= 0x00000200,	/* EEPROM is 256 words not 64 */	Eeszaddr	= 0x00000400,	/* EEPROM size for 8254[17] */	Spi		= 0x00002000,	/* EEPROM is SPI not Microwire */};enum {					/* Ctrlext */	Gpien		= 0x0000000F,	/* General Purpose Interrupt Enables */	SwdpinshiMASK	= 0x000000F0,	/* Software Defined Pins - hi nibble */	SwdpinshiSHIFT	= 4,	SwdpiohiMASK	= 0x00000F00,	/* Software Defined Pins - I or O */	SwdpiohiSHIFT	= 8,	Asdchk		= 0x00001000,	/* ASD Check */	Eerst		= 0x00002000,	/* EEPROM Reset */	Ips		= 0x00004000,	/* Invert Power State */	Spdbyps		= 0x00008000,	/* Speed Select Bypass */};enum {					/* EEPROM content offsets */	Ea		= 0x00,		/* Ethernet Address */	Cf		= 0x03,		/* Compatibility Field */	Pba		= 0x08,		/* Printed Board Assembly number */	/* in fs kernel, Icw1 is defined in io.h; changed it here */#define Icw1 Igbe_icw1	Icw1		= 0x0A,		/* Initialization Control Word 1 */	Sid		= 0x0B,		/* Subsystem ID */	Svid		= 0x0C,		/* Subsystem Vendor ID */	Did		= 0x0D,		/* Device ID */	Vid		= 0x0E,		/* Vendor ID */	Icw2		= 0x0F,		/* Initialization Control Word 2 */};enum {					/* Mdic */	MDIdMASK	= 0x0000FFFF,	/* Data */	MDIdSHIFT	= 0,	MDIrMASK	= 0x001F0000,	/* PHY Register Address */	MDIrSHIFT	= 16,	MDIpMASK	= 0x03E00000,	/* PHY Address */	MDIpSHIFT	= 21,	MDIwop		= 0x04000000,	/* Write Operation */	MDIrop		= 0x08000000,	/* Read Operation */	MDIready	= 0x10000000,	/* End of Transaction */	MDIie		= 0x20000000,	/* Interrupt Enable */	MDIe		= 0x40000000,	/* Error */};enum {					/* Icr, Ics, Ims, Imc */	Txdw		= 0x00000001,	/* Transmit Descriptor Written Back */	Txqe		= 0x00000002,	/* Transmit Queue Empty */	Lsc		= 0x00000004,	/* Link Status Change */	Rxseq		= 0x00000008,	/* Receive Sequence Error */	Rxdmt0		= 0x00000010,	/* Rd Minimum Threshold Reached */	Rxo		= 0x00000040,	/* Receiver Overrun */	Rxt0		= 0x00000080,	/* Receiver Timer Interrupt */	Mdac		= 0x00000200,	/* MDIO Access Completed */	Rxcfg		= 0x00000400,	/* Receiving /C/ ordered sets */	Gpi0		= 0x00000800,	/* General Purpose Interrupts */	Gpi1		= 0x00001000,	Gpi2		= 0x00002000,	Gpi3		= 0x00004000,};/* * The Mdic register isn't implemented on the 82543GC, * the software defined pins are used instead. * These definitions work for the Intel PRO/1000 T Server Adapter. * The direction pin bits are read from the EEPROM. */enum {	Mdd		= ((1<<2)<<SwdpinsloSHIFT),	/* data */	Mddo		= ((1<<2)<<SwdpioloSHIFT),	/* pin direction */	Mdc		= ((1<<3)<<SwdpinsloSHIFT),	/* clock */	Mdco		= ((1<<3)<<SwdpioloSHIFT),	/* pin direction */	Mdr		= ((1<<0)<<SwdpinshiSHIFT),	/* reset */	Mdro		= ((1<<0)<<SwdpiohiSHIFT),	/* pin direction */};enum {					/* Txcw */	TxcwFd		= 0x00000020,	/* Full Duplex */	TxcwHd		= 0x00000040,	/* Half Duplex */	TxcwPauseMASK	= 0x00000180,	/* Pause */	TxcwPauseSHIFT	= 7,	TxcwPs		= (1<<TxcwPauseSHIFT),	/* Pause Supported */	TxcwAs		= (2<<TxcwPauseSHIFT),	/* Asymmetric FC desired */	TxcwRfiMASK	= 0x00003000,	/* Remote Fault Indication */	TxcwRfiSHIFT	= 12,	TxcwNpr		= 0x00008000,	/* Next Page Request */	TxcwConfig	= 0x40000000,	/* Transmit COnfig Control */	TxcwAne		= 0x80000000,	/* Auto-Negotiation Enable */};enum {					/* Rxcw */	Rxword		= 0x0000FFFF,	/* Data from auto-negotiation process */	Rxnocarrier	= 0x04000000,	/* Carrier Sense indication */	Rxinvalid	= 0x08000000,	/* Invalid Symbol during configuration */	Rxchange	= 0x10000000,	/* Change to the Rxword indication */	Rxconfig	= 0x20000000,	/* /C/ order set reception indication */	Rxsync		= 0x40000000,	/* Lost bit synchronization indication */	Anc		= 0x80000000,	/* Auto Negotiation Complete */};enum {					/* Rctl */	Rrst		= 0x00000001,	/* Receiver Software Reset */	Ren		= 0x00000002,	/* Receiver Enable */	Sbp		= 0x00000004,	/* Store Bad Packets */	Upe		= 0x00000008,	/* Unicast Promiscuous Enable */	Mpe		= 0x00000010,	/* Multicast Promiscuous Enable */	Lpe		= 0x00000020,	/* Long Packet Reception Enable */	LbmMASK		= 0x000000C0,	/* Loopback Mode */	LbmOFF		= 0x00000000,	/* No Loopback */	LbmTBI		= 0x00000040,	/* TBI Loopback */	LbmMII		= 0x00000080,	/* GMII/MII Loopback */	LbmXCVR		= 0x000000C0,	/* Transceiver Loopback */	RdtmsMASK	= 0x00000300,	/* Rd Minimum Threshold Size */	RdtmsHALF	= 0x00000000,	/* Threshold is 1/2 Rdlen */	RdtmsQUARTER	= 0x00000100,	/* Threshold is 1/4 Rdlen */	RdtmsEIGHTH	= 0x00000200,	/* Threshold is 1/8 Rdlen */	MoMASK		= 0x00003000,	/* Multicast Offset */	Mo47b36		= 0x00000000,	/* bits [47:36] of received address */	Mo46b35		= 0x00001000,	/* bits [46:35] of received address */	Mo45b34		= 0x00002000,	/* bits [45:34] of received address */	Mo43b32		= 0x00003000,	/* bits [43:32] of received address */	Bam		= 0x00008000,	/* Broadcast Accept Mode */	BsizeMASK	= 0x00030000,	/* Receive Buffer Size */	Bsize2048	= 0x00000000,	/* Bsex = 0 */	Bsize1024	= 0x00010000,	/* Bsex = 0 */	Bsize512	= 0x00020000,	/* Bsex = 0 */	Bsize256	= 0x00030000,	/* Bsex = 0 */	Bsize16384	= 0x00010000,	/* Bsex = 1 */	Vfe		= 0x00040000,	/* VLAN Filter Enable */	Cfien		= 0x00080000,	/* Canonical Form Indicator Enable */	Cfi		= 0x00100000,	/* Canonical Form Indicator value */	Dpf		= 0x00400000,	/* Discard Pause Frames */	Pmcf		= 0x00800000,	/* Pass MAC Control Frames */	Bsex		= 0x02000000,	/* Buffer Size Extension */	Secrc		= 0x04000000,	/* Strip CRC from incoming packet */};enum {					/* Tctl */	Trst		= 0x00000001,	/* Transmitter Software Reset */	Ten		= 0x00000002,	/* Transmit Enable */	Psp		= 0x00000008,	/* Pad Short Packets */	CtMASK		= 0x00000FF0,	/* Collision Threshold */	CtSHIFT		= 4,	ColdMASK	= 0x003FF000,	/* Collision Distance */	ColdSHIFT	= 12,	Swxoff		= 0x00400000,	/* Sofware XOFF Transmission */	Pbe		= 0x00800000,	/* Packet Burst Enable */	Rtlc		= 0x01000000,	/* Re-transmit on Late Collision */	Nrtu		= 0x02000000,	/* No Re-transmit on Underrrun */};enum {					/* [RT]xdctl */	PthreshMASK	= 0x0000003F,	/* Prefetch Threshold */	PthreshSHIFT	= 0,	HthreshMASK	= 0x00003F00,	/* Host Threshold */	HthreshSHIFT	= 8,	WthreshMASK	= 0x003F0000,	/* Writeback Threshold */	WthreshSHIFT	= 16,	Gran		= 0x01000000,	/* Granularity */	LthreshMASK	= 0xFE000000,	/* Low Threshold */	LthreshSHIFT	= 25,};enum {					/* Rxcsum */	PcssMASK	= 0x000000FF,	/* Packet Checksum Start */	PcssSHIFT	= 0,	Ipofl		= 0x00000100,	/* IP Checksum Off-load Enable */	Tuofl		= 0x00000200,	/* TCP/UDP Checksum Off-load Enable */};enum {					/* Manc */	Arpen		= 0x00002000,	/* Enable ARP Request Filtering */};enum {					/* Receive Delay Timer Ring */	DelayMASK	= 0x0000FFFF,	/* delay timer in 1.024nS increments */	DelaySHIFT	= 0,	Fpd		= 0x80000000,	/* Flush partial Descriptor Block */};typedef struct Rd {			/* Receive Descriptor */	uint	addr[2];	ushort	length;	ushort	checksum;	uchar	status;	uchar	errors;	ushort	special;} Rd;enum {					/* Rd status */	Rdd		= 0x01,		/* Descriptor Done */	Reop		= 0x02,		/* End of Packet */	Ixsm		= 0x04,		/* Ignore Checksum Indication */	Vp		= 0x08,		/* Packet is 802.1Q (matched VET) */	Tcpcs		= 0x20,		/* TCP Checksum Calculated on Packet */	Ipcs		= 0x40,		/* IP Checksum Calculated on Packet */	Pif		= 0x80,		/* Passed in-exact filter */};enum {					/* Rd errors */	Ce		= 0x01,		/* CRC Error or Alignment Error */	Se		= 0x02,		/* Symbol Error */	Seq		= 0x04,		/* Sequence Error */	Cxe		= 0x10,		/* Carrier Extension Error */	Tcpe		= 0x20,		/* TCP/UDP Checksum Error */	Ipe		= 0x40,		/* IP Checksum Error */	Rxe		= 0x80,		/* RX Data Error */};typedef struct {			/* Transmit Descriptor */	union {		uint	addr[2];	/* Data */		struct {		/* Context */			uchar	ipcss;			uchar	ipcso;			ushort	ipcse;			uchar	tucss;			uchar	tucso;			ushort	tucse;		};	};	uint	control;	uint	status;} Td;enum {					/* Td control */	LenMASK		= 0x000FFFFF,	/* Data/Packet Length Field */	LenSHIFT	= 0,	DtypeCD		= 0x00000000,	/* Data Type 'Context Descriptor' */	DtypeDD		= 0x00100000,	/* Data Type 'Data Descriptor' */	PtypeTCP	= 0x01000000,	/* TCP/UDP Packet Type (CD) */	Teop		= 0x01000000,	/* End of Packet (DD) */	PtypeIP		= 0x02000000,	/* IP Packet Type (CD) */	Ifcs		= 0x02000000,	/* Insert FCS (DD) */	Tse		= 0x04000000,	/* TCP Segmentation Enable */	Rs		= 0x08000000,	/* Report Status */	Rps		= 0x10000000,	/* Report Status Sent */	Dext		= 0x20000000,	/* Descriptor Extension */	Vle		= 0x40000000,	/* VLAN Packet Enable */	Ide		= 0x80000000,	/* Interrupt Delay Enable */};enum {					/* Td status */	Tdd		= 0x00000001,	/* Descriptor Done */	Ec		= 0x00000002,	/* Excess Collisions */	Lc		= 0x00000004,	/* Late Collision */	Tu		= 0x00000008,	/* Transmit Underrun */	Iixsm		= 0x00000100,	/* Insert IP Checksum */	Itxsm		= 0x00000200,	/* Insert TCP/UDP Checksum */	HdrlenMASK	= 0x0000FF00,	/* Header Length (Tse) */	HdrlenSHIFT	= 8,	VlanMASK	= 0x0FFF0000,	/* VLAN Identifier */	VlanSHIFT	= 16,	Tcfi		= 0x10000000,	/* Canonical Form Indicator */	PriMASK		= 0xE0000000,	/* User Priority */	PriSHIFT	= 29,	MssMASK		= 0xFFFF0000,	/* Maximum Segment Size (Tse) */	MssSHIFT	= 16,};enum {	Nrd		= 256,		/* multiple of 8 */	/*	 * we require a power of 2. also must be a multiple of TDD_INTVL (64).	 * chip errata says max 256.	 */#ifdef FS	Ntd		= 256,		/* chip requires multiple of 8 */#else	Ntd		= 64,		/* chip requires multiple of 8 */#endif	Nrb		= 1024,		/* private receive buffers per Ctlr */	Rbsz		= 2048,};typedef struct Ctlr Ctlr;typedef struct Ctlr {	int	port;	Pcidev*	pcidev;	Ctlr*	next;	int	active;	int	started;	int	id;	int	cls;	ushort	eeprom[0x40];	QLock	alock;			/* attach */	void*	alloc;			/* receive/transmit descriptors */	int	nrd;	int	ntd;	int	nrb;			/* how many this Ctlr has in the pool */	int*	nic;	Lock	imlock;	int	im;			/* interrupt mask */	Mii*	mii;	Rendez	lrendez;	int	lim;	int	link;	QLock	slock;	uint	statistics[Nstatistics];	uint	lsleep;	uint	lintr;	uint	rsleep;	uint	rintr;	uint	txdw;	uint	tintr;	uint	ixsm;	uint	ipcs;	uint	tcpcs;	uchar	ra[Eaddrlen];		/* receive address */	ulong	mta[128];		/* multicast table array */	Rendez	rrendez;	int	rim;	int	rdfree;

⌨️ 快捷键说明

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