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

📄 natsemi.c

📁 linux和2410结合开发 用他可以生成2410所需的zImage文件
💻 C
📖 第 1 页 / 共 5 页
字号:
/* natsemi.c: A Linux PCI Ethernet driver for the NatSemi DP8381x series. *//*	Written/copyright 1999-2001 by Donald Becker.	Portions copyright (c) 2001 Sun Microsystems (thockin@sun.com)	This software may be used and distributed according to the terms of	the GNU General Public License (GPL), incorporated herein by reference.	Drivers based on or derived from this code fall under the GPL and must	retain the authorship, copyright and license notice.  This file is not	a complete program and may only be used when the entire operating	system is licensed under the GPL.  License for under other terms may be	available.  Contact the original author for details.	The original author may be reached as becker@scyld.com, or at	Scyld Computing Corporation	410 Severn Ave., Suite 210	Annapolis MD 21403	Support information and updates available at	http://www.scyld.com/network/netsemi.html	Linux kernel modifications:	Version 1.0.1:		- Spinlock fixes		- Bug fixes and better intr performance (Tjeerd)	Version 1.0.2:		- Now reads correct MAC address from eeprom	Version 1.0.3:		- Eliminate redundant priv->tx_full flag		- Call netif_start_queue from dev->tx_timeout		- wmb() in start_tx() to flush data		- Update Tx locking		- Clean up PCI enable (davej)	Version 1.0.4:		- Merge Donald Becker's natsemi.c version 1.07	Version 1.0.5:		- { fill me in }	Version 1.0.6:		* ethtool support (jgarzik)		* Proper initialization of the card (which sometimes		fails to occur and leaves the card in a non-functional		state). (uzi)		* Some documented register settings to optimize some		of the 100Mbit autodetection circuitry in rev C cards. (uzi)		* Polling of the PHY intr for stuff like link state		change and auto- negotiation to finally work properly. (uzi)		* One-liner removal of a duplicate declaration of		netdev_error(). (uzi)	Version 1.0.7: (Manfred Spraul)		* pci dma		* SMP locking update		* full reset added into tx_timeout		* correct multicast hash generation (both big and little endian)			[copied from a natsemi driver version			 from Myrio Corporation, Greg Smith]		* suspend/resume	version 1.0.8 (Tim Hockin <thockin@sun.com>)		* ETHTOOL_* support		* Wake on lan support (Erik Gilling)		* MXDMA fixes for serverworks		* EEPROM reload	version 1.0.9 (Manfred Spraul)		* Main change: fix lack of synchronize		netif_close/netif_suspend against a last interrupt		or packet.		* do not enable superflous interrupts (e.g. the		drivers relies on TxDone - TxIntr not needed)		* wait that the hardware has really stopped in close		and suspend.		* workaround for the (at least) gcc-2.95.1 compiler		problem. Also simplifies the code a bit.		* disable_irq() in tx_timeout - needed to protect		against rx interrupts.		* stop the nic before switching into silent rx mode		for wol (required according to docu).	version 1.0.10:		* use long for ee_addr (various)		* print pointers properly (DaveM)		* include asm/irq.h (?)		version 1.0.11:		* check and reset if PHY errors appear (Adrian Sun)		* WoL cleanup (Tim Hockin)		* Magic number cleanup (Tim Hockin)		* Don't reload EEPROM on every reset (Tim Hockin)		* Save and restore EEPROM state across reset (Tim Hockin)		* MDIO Cleanup (Tim Hockin)		* Reformat register offsets/bits (jgarzik)	version 1.0.12:		* ETHTOOL_* further support (Tim Hockin)	version 1.0.13:		* ETHTOOL_GEEPROM support (Tim Hockin)	version 1.0.14:		* Cleanup some messages and autoneg in ethtool (Tim Hockin)	TODO:	* big endian support with CFG:BEM instead of cpu_to_le32	* support for an external PHY	* flow control*/#if !defined(__OPTIMIZE__)#warning  You must compile this file with the correct options!#warning  See the last lines of the source file.#error You must compile this driver with "-O".#endif#include <linux/config.h>#include <linux/module.h>#include <linux/kernel.h>#include <linux/string.h>#include <linux/timer.h>#include <linux/errno.h>#include <linux/ioport.h>#include <linux/slab.h>#include <linux/interrupt.h>#include <linux/pci.h>#include <linux/netdevice.h>#include <linux/etherdevice.h>#include <linux/skbuff.h>#include <linux/init.h>#include <linux/spinlock.h>#include <linux/ethtool.h>#include <linux/delay.h>#include <linux/rtnetlink.h>#include <linux/mii.h>#include <asm/processor.h>	/* Processor type for cache alignment. */#include <asm/bitops.h>#include <asm/io.h>#include <asm/irq.h>#include <asm/uaccess.h>#define DRV_NAME	"natsemi"#define DRV_VERSION	"1.07+LK1.0.14"#define DRV_RELDATE	"Nov 27, 2001"/* Updated to recommendations in pci-skeleton v2.03. *//* Automatically extracted configuration info:probe-func: natsemi_probeconfig-in: tristate 'National Semiconductor DP8381x series PCI Ethernet support' CONFIG_NATSEMIc-help-name: National Semiconductor DP8381x series PCI Ethernet supportc-help-symbol: CONFIG_NATSEMIc-help: This driver is for the National Semiconductor DP8381x series,c-help: including the 8381[56] chips.c-help: More specific information and updates are available from c-help: http://www.scyld.com/network/natsemi.html*//* The user-configurable values.   These may be modified when a driver module is loaded.*/#define NATSEMI_DEF_MSG		(NETIF_MSG_DRV		| \				 NETIF_MSG_LINK		| \				 NETIF_MSG_WOL		| \				 NETIF_MSG_RX_ERR	| \				 NETIF_MSG_TX_ERR)static int debug = NATSEMI_DEF_MSG;/* Maximum events (Rx packets, etc.) to handle at each interrupt. */static int max_interrupt_work = 20;static int mtu;/* Maximum number of multicast addresses to filter (vs. rx-all-multicast).   This chip uses a 512 element hash table based on the Ethernet CRC.  */static int multicast_filter_limit = 100;/* Set the copy breakpoint for the copy-only-tiny-frames scheme.   Setting to > 1518 effectively disables this feature. */static int rx_copybreak;/* Used to pass the media type, etc.   Both 'options[]' and 'full_duplex[]' should exist for driver   interoperability.   The media type is usually passed in 'options[]'.*/#define MAX_UNITS 8		/* More are supported, limit only on options */static int options[MAX_UNITS] = {-1, -1, -1, -1, -1, -1, -1, -1};static int full_duplex[MAX_UNITS] = {-1, -1, -1, -1, -1, -1, -1, -1};/* Operational parameters that are set at compile time. *//* Keep the ring sizes a power of two for compile efficiency.   The compiler will convert <unsigned>'%'<2^N> into a bit mask.   Making the Tx ring too large decreases the effectiveness of channel   bonding and packet priority.   There are no ill effects from too-large receive rings. */#define TX_RING_SIZE	16#define TX_QUEUE_LEN	10 /* Limit ring entries actually used, min 4. */#define RX_RING_SIZE	64/* Operational parameters that usually are not changed. *//* Time in jiffies before concluding the transmitter is hung. */#define TX_TIMEOUT  (2*HZ)#define NATSEMI_HW_TIMEOUT	400#define NATSEMI_TIMER_FREQ	3*HZ#define NATSEMI_PG0_NREGS	64#define NATSEMI_RFDR_NREGS	8#define NATSEMI_PG1_NREGS	4#define NATSEMI_NREGS		(NATSEMI_PG0_NREGS + NATSEMI_RFDR_NREGS + \				 NATSEMI_PG1_NREGS)#define NATSEMI_REGS_VER	1 /* v1 added RFDR registers */#define NATSEMI_REGS_SIZE	(NATSEMI_NREGS * sizeof(u32))#define NATSEMI_EEPROM_SIZE	24 /* 12 16-bit values */#define PKT_BUF_SZ		1536 /* Size of each temporary Rx buffer. *//* These identify the driver base version and may not be removed. */static char version[] __devinitdata =KERN_INFO DRV_NAME ".c:v1.07 1/9/2001  Written by Donald Becker <becker@scyld.com>\n"KERN_INFO "  http://www.scyld.com/network/natsemi.html\n"KERN_INFO "  (unofficial 2.4.x kernel port, version " DRV_VERSION ", " DRV_RELDATE "  Jeff Garzik, Tjeerd Mulder)\n";MODULE_AUTHOR("Donald Becker <becker@scyld.com>");MODULE_DESCRIPTION("National Semiconductor DP8381x series PCI Ethernet driver");MODULE_LICENSE("GPL");MODULE_PARM(max_interrupt_work, "i");MODULE_PARM(mtu, "i");MODULE_PARM(debug, "i");MODULE_PARM(rx_copybreak, "i");MODULE_PARM(options, "1-" __MODULE_STRING(MAX_UNITS) "i");MODULE_PARM(full_duplex, "1-" __MODULE_STRING(MAX_UNITS) "i");MODULE_PARM_DESC(max_interrupt_work, "DP8381x maximum events handled per interrupt");MODULE_PARM_DESC(mtu, "DP8381x MTU (all boards)");MODULE_PARM_DESC(debug, "DP8381x debug bitmask");MODULE_PARM_DESC(rx_copybreak, "DP8381x copy breakpoint for copy-only-tiny-frames");MODULE_PARM_DESC(options, "DP8381x: Bits 0-3: media type, bit 17: full duplex");MODULE_PARM_DESC(full_duplex, "DP8381x full duplex setting(s) (1)");/*				Theory of OperationI. Board CompatibilityThis driver is designed for National Semiconductor DP83815 PCI Ethernet NIC.It also works with other chips in in the DP83810 series.II. Board-specific settingsThis driver requires the PCI interrupt line to be valid.It honors the EEPROM-set values. III. Driver operationIIIa. Ring buffersThis driver uses two statically allocated fixed-size descriptor listsformed into rings by a branch from the final descriptor to the beginning ofthe list.  The ring sizes are set at compile time by RX/TX_RING_SIZE.The NatSemi design uses a 'next descriptor' pointer that the driver formsinto a list. IIIb/c. Transmit/Receive StructureThis driver uses a zero-copy receive and transmit scheme.The driver allocates full frame size skbuffs for the Rx ring buffers atopen() time and passes the skb->data field to the chip as receive databuffers.  When an incoming frame is less than RX_COPYBREAK bytes long,a fresh skbuff is allocated and the frame is copied to the new skbuff.When the incoming frame is larger, the skbuff is passed directly up theprotocol stack.  Buffers consumed this way are replaced by newly allocatedskbuffs in a later phase of receives.The RX_COPYBREAK value is chosen to trade-off the memory wasted byusing a full-sized skbuff for small frames vs. the copying costs of largerframes.  New boards are typically used in generously configured machinesand the underfilled buffers have negligible impact compared to the benefit ofa single allocation size, so the default value of zero results in nevercopying packets.  When copying is done, the cost is usually mitigated by usinga combined copy/checksum routine.  Copying also preloads the cache, which ismost useful with small frames.A subtle aspect of the operation is that unaligned buffers are not permittedby the hardware.  Thus the IP header at offset 14 in an ethernet frame isn'tlongword aligned for further processing.  On copies frames are put into theskbuff at an offset of "+2", 16-byte aligning the IP header.IIId. SynchronizationThe driver runs as two independent, single-threaded flows of control.  Oneis the send-packet routine, which enforces single-threaded use by thedev->tbusy flag.  The other thread is the interrupt handler, which is singlethreaded by the hardware and interrupt handling software.The send packet thread has partial control over the Tx ring and 'dev->tbusy'flag.  It sets the tbusy flag whenever it's queuing a Tx packet. If the nextqueue slot is empty, it clears the tbusy flag when finished otherwise it setsthe 'lp->tx_full' flag.The interrupt handler has exclusive control over the Rx ring and records statsfrom the Tx ring.  After reaping the stats, it marks the Tx queue entry asempty by incrementing the dirty_tx mark. Iff the 'lp->tx_full' flag is set, itclears both the tx_full and tbusy flags.IV. NotesNatSemi PCI network controllers are very uncommon.IVb. Referenceshttp://www.scyld.com/expert/100mbps.htmlhttp://www.scyld.com/expert/NWay.htmlDatasheet is available from:http://www.national.com/pf/DP/DP83815.htmlIVc. ErrataNone characterised.*/enum pcistuff {	PCI_USES_IO = 0x01,	PCI_USES_MEM = 0x02,	PCI_USES_MASTER = 0x04,	PCI_ADDR0 = 0x08,	PCI_ADDR1 = 0x10,};/* MMIO operations required */#define PCI_IOTYPE (PCI_USES_MASTER | PCI_USES_MEM | PCI_ADDR1)/* array of board data directly indexed by pci_tbl[x].driver_data */static struct {	const char *name;	unsigned long flags;} natsemi_pci_info[] __devinitdata = {	{ "NatSemi DP8381[56]", PCI_IOTYPE },};static struct pci_device_id natsemi_pci_tbl[] __devinitdata = {	{ PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_83815, PCI_ANY_ID, PCI_ANY_ID, },	{ 0, },};MODULE_DEVICE_TABLE(pci, natsemi_pci_tbl);/* Offsets to the device registers.   Unlike software-only systems, device drivers interact with complex hardware.   It's not useful to define symbolic names for every register bit in the   device.*/enum register_offsets {	ChipCmd			= 0x00,	ChipConfig		= 0x04,	EECtrl			= 0x08,	PCIBusCfg		= 0x0C,	IntrStatus		= 0x10,	IntrMask		= 0x14,	IntrEnable		= 0x18,	TxRingPtr		= 0x20,	TxConfig		= 0x24,	RxRingPtr		= 0x30,	RxConfig		= 0x34,	ClkRun			= 0x3C,	WOLCmd			= 0x40,	PauseCmd		= 0x44,	RxFilterAddr		= 0x48,	RxFilterData		= 0x4C,	BootRomAddr		= 0x50,	BootRomData		= 0x54,	SiliconRev		= 0x58,	StatsCtrl		= 0x5C,	StatsData		= 0x60,	RxPktErrs		= 0x60,	RxMissed		= 0x68,	RxCRCErrs		= 0x64,	BasicControl		= 0x80,	BasicStatus		= 0x84,	AnegAdv			= 0x90,	AnegPeer		= 0x94,	PhyStatus		= 0xC0,	MIntrCtrl		= 0xC4,	MIntrStatus		= 0xC8,	PhyCtrl			= 0xE4,	/* These are from the spec, around page 78... on a separate table.	 * The meaning of these registers depend on the value of PGSEL. */	PGSEL			= 0xCC,	PMDCSR			= 0xE4,	TSTDAT			= 0xFC,	DSPCFG			= 0xF4,	SDCFG			= 0xF8};/* the values for the 'magic' registers above (PGSEL=1) */#ifdef CONFIG_NATSEMI_CABLE_MAGIC#define PMDCSR_VAL	0x1898#else#define PMDCSR_VAL	0x189C#endif#define TSTDAT_VAL	0x0#define DSPCFG_VAL	0x5040#define SDCFG_VAL	0x008c/* misc PCI space registers */enum pci_register_offsets {	PCIPM			= 0x44,};enum ChipCmd_bits {	ChipReset		= 0x100,	RxReset			= 0x20,	TxReset			= 0x10,	RxOff			= 0x08,	RxOn			= 0x04,	TxOff			= 0x02,	TxOn			= 0x01,};enum ChipConfig_bits {	CfgPhyDis		= 0x200,	CfgPhyRst		= 0x400,	CfgExtPhy		= 0x1000,	CfgAnegEnable		= 0x2000,	CfgAneg100		= 0x4000,	CfgAnegFull		= 0x8000,	CfgAnegDone		= 0x8000000,	CfgFullDuplex		= 0x20000000,	CfgSpeed100		= 0x40000000,	CfgLink			= 0x80000000,};enum EECtrl_bits {	EE_ShiftClk		= 0x04,	EE_DataIn		= 0x01,	EE_ChipSelect		= 0x08,	EE_DataOut		= 0x02,};enum PCIBusCfg_bits {	EepromReload		= 0x4,};/* Bits in the interrupt status/mask registers. */enum IntrStatus_bits {	IntrRxDone		= 0x0001,	IntrRxIntr		= 0x0002,	IntrRxErr		= 0x0004,

⌨️ 快捷键说明

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