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

📄 eepro100.c

📁 GNU Mach 微内核源代码, 基于美国卡内基美隆大学的 Mach 研究项目
💻 C
📖 第 1 页 / 共 5 页
字号:
/* drivers/net/eepro100.c: An Intel i82557-559 Ethernet driver for Linux. *//*   NOTICE: this version of the driver is supposed to work with 2.2 kernels.	Written 1996-1999 by Donald Becker.	This software may be used and distributed according to the terms	of the GNU Public License, incorporated herein by reference.	This driver is for the Intel EtherExpress Pro100 (Speedo3) design.	It should work with all i82557/558/559 boards.	To use as a module, use the compile-command at the end of the file.	The author may be reached as becker@CESDIS.usra.edu, or C/O	Center of Excellence in Space Data and Information Sciences	   Code 930.5, NASA Goddard Space Flight Center, Greenbelt MD 20771	For updates see		http://cesdis.gsfc.nasa.gov/linux/drivers/eepro100.html	For installation instructions		http://cesdis.gsfc.nasa.gov/linux/misc/modules.html	There is a Majordomo mailing list based at		linux-eepro100@cesdis.gsfc.nasa.gov		The driver also contains updates by different kernel developers.	This driver clone is maintained by Andrey V. Savochkin <saw@saw.sw.com.sg>.	Please use this email address and linux-kernel mailing list for bug reports.		Modification history:	2000 Mar 24  Dragan Stancevic <visitor@valinux.com>		Disabled FC and ER, to avoid lockups when when we get FCP interrupts.	2000 May 27  Andrey Moruga <moruga@sw.com.sg>		Code duplication for 82559ER support was removed.		Accurate handling of all supported chips was implemented.		Some fixes in 2.3 clone of the driver were ported.	2000 May 30  Dragan Stancevic <visitor@valinux.com> and				 Andrey Moruga <moruga@sw.com.sg>		Honor PortReset timing specification.	2000 Jul 25  Dragan Stancevic <visitor@valinux.com>		Changed to MMIO, resized FIFOs, resized rings, changed ISR timeout		Problem reported by:		Marc MERLIN <merlin@valinux.com>	2000 Nov 15  Dragan Stancevic <visitor@valinux.com>		Changed command completion time and added debug info as to which		CMD timed out. Problem reported by:		"Ulrich Windl" <Ulrich.Windl@rz.uni-regensburg.de>*/#define USE_IOstatic const char *version ="eepro100.c:v1.09j-t 9/29/99 Donald Becker http://cesdis.gsfc.nasa.gov/linux/drivers/eepro100.html\n""eepro100.c: $Revision: 1.1 $ 2000/05/31 Modified by Andrey V. Savochkin <saw@saw.sw.com.sg> and others\n""eepro100.c: VA Linux custom, Dragan Stancevic <visitor@valinux.com> 2000/11/15\n";/* A few user-configurable values that apply to all boards.   First set is undocumented and spelled per Intel recommendations. */static int congenb = 0;		/* Enable congestion control in the DP83840. */static int txfifo = 0;		/* Tx FIFO threshold in 4 byte units, 0-15 */static int rxfifo = 0xF;		/* Rx FIFO threshold, default 32 bytes. *//* Tx/Rx DMA burst length, 0-127, 0 == no preemption, tx==128 -> disabled. */static int txdmacount = 128;static int rxdmacount = 0;/* Set the copy breakpoint for the copy-only-tiny-buffer Rx method.   Lower values use more memory, but are faster. */#if defined(__alpha__) || defined(__sparc__)/* force copying of all packets to avoid unaligned accesses on Alpha */static int rx_copybreak = 1518;#elsestatic int rx_copybreak = 200;#endif/* Maximum events (Rx packets, etc.) to handle at each interrupt. */static int max_interrupt_work = 200;/* Maximum number of multicast addresses to filter (vs. rx-all-multicast) */static int multicast_filter_limit = 64;/* 'options' is used to pass a transceiver override or full-duplex flag   e.g. "options=16" for FD, "options=32" for 100mbps-only. */static int full_duplex[] = {-1, -1, -1, -1, -1, -1, -1, -1};static int options[] = {-1, -1, -1, -1, -1, -1, -1, -1};#ifdef MODULEstatic int debug = -1;			/* The debug level */#endif/* A few values that may be tweaked. *//* The ring sizes should be a power of two for efficiency. */#define TX_RING_SIZE	64#define RX_RING_SIZE	64/* How much slots multicast filter setup may take.   Do not descrease without changing set_rx_mode() implementaion. */#define TX_MULTICAST_SIZE   2#define TX_MULTICAST_RESERV (TX_MULTICAST_SIZE*2)/* Actual number of TX packets queued, must be   <= TX_RING_SIZE-TX_MULTICAST_RESERV. */#define TX_QUEUE_LIMIT  (TX_RING_SIZE-TX_MULTICAST_RESERV)/* Hysteresis marking queue as no longer full. */#define TX_QUEUE_UNFULL (TX_QUEUE_LIMIT-4)/* Operational parameters that usually are not changed. *//* Time in jiffies before concluding the transmitter is hung. */#define TX_TIMEOUT		(2*HZ)/* Size of an pre-allocated Rx buffer: <Ethernet MTU> + slack.*/#define PKT_BUF_SZ		1536#if !defined(__OPTIMIZE__)  ||  !defined(__KERNEL__)#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/version.h>#include <linux/module.h>#if defined(MODVERSIONS)#include <linux/modversions.h>#endif#include <linux/kernel.h>#include <linux/string.h>#include <linux/timer.h>#include <linux/errno.h>#include <linux/ioport.h>#include <linux/malloc.h>#include <linux/interrupt.h>#include <linux/pci.h>#include <linux/compatmac.h>#include <asm/spinlock.h>#include <asm/processor.h>#include <asm/bitops.h>#include <asm/io.h>/* #include <asm/unaligned.h> *//* #include <asm/byteorder.h> */#define __LITTLE_ENDIAN#include <asm/hardirq.h>#include <linux/netdevice.h>#include <linux/etherdevice.h>#include <linux/skbuff.h>#include <linux/delay.h>#if defined(MODULE) && (LINUX_VERSION_CODE > 0x20115)MODULE_AUTHOR("Maintainer: Andrey V. Savochkin <saw@saw.sw.com.sg>");MODULE_DESCRIPTION("Intel i82557/i82558 PCI EtherExpressPro driver");MODULE_PARM(debug, "i");MODULE_PARM(options, "1-" __MODULE_STRING(8) "i");MODULE_PARM(full_duplex, "1-" __MODULE_STRING(8) "i");MODULE_PARM(congenb, "i");MODULE_PARM(txfifo, "i");MODULE_PARM(rxfifo, "i");MODULE_PARM(txdmacount, "i");MODULE_PARM(rxdmacount, "i");MODULE_PARM(rx_copybreak, "i");MODULE_PARM(max_interrupt_work, "i");MODULE_PARM(multicast_filter_limit, "i");#endif#if (LINUX_VERSION_CODE >= 0x20100)static char kernel_version[] = UTS_RELEASE;#endif#if LINUX_VERSION_CODE < 0x20123#define hard_smp_processor_id() smp_processor_id()#define test_and_set_bit(val, addr) set_bit(val, addr)#define le16_to_cpu(val) (val)#define le32_to_cpu(val) (val)#define cpu_to_le32(val) (val)#define cpu_to_le16(val) (val)#endif#if LINUX_VERSION_CODE <= 0x20139#define	net_device_stats enet_statistics#else#define NETSTATS_VER2#endif#if LINUX_VERSION_CODE < 0x20155/* Grrrr, the PCI code changed, but did not consider CardBus... */#include <linux/bios32.h>#define PCI_SUPPORT_VER1#else#define PCI_SUPPORT_VER2#endif#if LINUX_VERSION_CODE < 0x20159#define dev_free_skb(skb) dev_kfree_skb(skb, FREE_WRITE);#else#define dev_free_skb(skb) dev_kfree_skb(skb);#endif#if ! defined(CAP_NET_ADMIN)#define capable(CAP_XXX) (suser())#endif #define RUN_AT(x) (jiffies + (x))/* Condensed bus+endian portability operations. */#define virt_to_le32desc(addr)  cpu_to_le32(virt_to_bus(addr))#define le32desc_to_virt(addr)  bus_to_virt(le32_to_cpu(addr))#define net_device              device#define pci_base_address(p, n)  (p)->base_address[n]#define netif_wake_queue(dev)   do { \									clear_bit(0, (void*)&dev->tbusy); \									mark_bh(NET_BH); \								} while(0)#define netif_start_queue(dev)  clear_bit(0, (void*)&dev->tbusy)#define netif_stop_queue(dev)   set_bit(0, (void*)&dev->tbusy)#ifndef PCI_DEVICE_ID_INTEL_82559ER#define PCI_DEVICE_ID_INTEL_82559ER 0x1209#endif#ifndef PCI_DEVICE_ID_INTEL_ID1029#define PCI_DEVICE_ID_INTEL_ID1029 0x1029#endif#ifndef PCI_DEVICE_ID_INTEL_ID1030#define PCI_DEVICE_ID_INTEL_ID1030 0x1030#endif#ifndef PCI_DEVICE_ID_INTEL_ID2449#define PCI_DEVICE_ID_INTEL_ID2449 0x2449#endif/* The total I/O port extent of the board.   The registers beyond 0x18 only exist on the i82558. */#define SPEEDO3_TOTAL_SIZE 0x20int speedo_debug = 1;/*				Theory of OperationI. Board CompatibilityThis device driver is designed for the Intel i82557 "Speedo3" chip, Intel'ssingle-chip fast Ethernet controller for PCI, as used on the IntelEtherExpress Pro 100 adapter.II. Board-specific settingsPCI bus devices are configured by the system at boot time, so no jumpersneed to be set on the board.  The system BIOS should be set to assign thePCI INTA signal to an otherwise unused system IRQ line.  While it'spossible to share PCI interrupt lines, it negatively impacts performance andonly recent kernels support it.III. Driver operationIIIA. GeneralThe Speedo3 is very similar to other Intel network chips, that is to say"apparently designed on a different planet".  This chips retains the complexRx and Tx descriptors and multiple buffers pointers as previous chips, butalso has simplified Tx and Rx buffer modes.  This driver uses the "flexible"Tx mode, but in a simplified lower-overhead manner: it associates only asingle buffer descriptor with each frame descriptor.Despite the extra space overhead in each receive skbuff, the driver must usethe simplified Rx buffer mode to assure that only a single data buffer isassociated with each RxFD. The driver implements this by reserving spacefor the Rx descriptor at the head of each Rx skbuff.The Speedo-3 has receive and command unit base addresses that are added toalmost all descriptor pointers.  The driver sets these to zero, so that allpointer fields are absolute addresses.The System Control Block (SCB) of some previous Intel chips exists on thechip in both PCI I/O and memory space.  This driver uses the I/O spaceregisters, but might switch to memory mapped mode to better support non-x86processors.IIIB. Transmit structureThe driver must use the complex Tx command+descriptor mode in order tohave a indirect pointer to the skbuff data section.  Each Tx command block(TxCB) is associated with two immediately appended Tx Buffer Descriptor(TxBD).  A fixed ring of these TxCB+TxBD pairs are kept as part of thespeedo_private data structure for each adapter instance.The newer i82558 explicitly supports this structure, and can read the twoTxBDs in the same PCI burst as the TxCB.This ring structure is used for all normal transmit packets, but thetransmit packet descriptors aren't long enough for most non-Tx commands suchas CmdConfigure.  This is complicated by the possibility that the chip hasalready loaded the link address in the previous descriptor.  So for thesecommands we convert the next free descriptor on the ring to a NoOp, and pointthat descriptor's link to the complex command.An additional complexity of these non-transmit commands are that they may beadded asynchronous to the normal transmit queue, so we disable interruptswhenever the Tx descriptor ring is manipulated.A notable aspect of these special configure commands is that they dowork with the normal Tx ring entry scavenge method.  The Tx ring scavengeis done at interrupt time using the 'dirty_tx' index, and checking for thecommand-complete bit.  While the setup frames may have the NoOp command on theTx ring marked as complete, but not have completed the setup command, thisis not a problem.  The tx_ring entry can be still safely reused, as thetx_skbuff[] entry is always empty for config_cmd and mc_setup frames.Commands may have bits set e.g. CmdSuspend in the command word to eithersuspend or stop the transmit/command unit.  This driver always flags the lastcommand with CmdSuspend, erases the CmdSuspend in the previous command, andthen issues a CU_RESUME.Note: Watch out for the potential race condition here: imagine	erasing the previous suspend		the chip processes the previous command		the chip processes the final command, and suspends	doing the CU_RESUME		the chip processes the next-yet-valid post-final-command.So blindly sending a CU_RESUME is only safe if we do it immediately afterafter erasing the previous CmdSuspend, without the possibility of anintervening delay.  Thus the resume command is always within theinterrupts-disabled region.  This is a timing dependence, but handling thiscondition in a timing-independent way would considerably complicate the code.Note: In previous generation Intel chips, restarting the command unit was anotoriously slow process.  This is presumably no longer true.IIIC. Receive structureBecause of the bus-master support on the Speedo3 this driver uses the newSKBUFF_RX_COPYBREAK scheme, rather than a fixed intermediate receive buffer.This scheme allocates full-sized skbuffs as receive buffers.  The valueSKBUFF_RX_COPYBREAK is used as the copying breakpoint: it is chosen totrade-off the memory wasted by passing the full-sized skbuff to the queuelayer for all frames vs. the copying cost of copying a frame to acorrectly-sized skbuff.For small frames the copying cost is negligible (esp. considering that weare pre-loading the cache with immediately useful header information), so weallocate a new, minimally-sized skbuff.  For large frames the copying costis non-trivial, and the larger copy might flush the cache of useful data, sowe pass up the skbuff the packet was received into.IV. NotesThanks to Steve Williams of Intel for arranging the non-disclosure agreementthat stated that I could disclose the information.  But I still resenthaving to sign an Intel NDA when I'm helping Intel sell their own product!*//* This table drives the PCI probe routines. */static struct net_device *speedo_found1(struct pci_dev *pdev, int pci_bus, 										int pci_devfn, long ioaddr, 										int chip_idx, int card_idx);#ifdef USE_IO#define SPEEDO_IOTYPE   PCI_USES_MASTER|PCI_USES_IO|PCI_ADDR1#define SPEEDO_SIZE		32#else#define SPEEDO_IOTYPE   PCI_USES_MASTER|PCI_USES_MEM|PCI_ADDR0#define SPEEDO_SIZE		0x1000#endifenum pci_flags_bit {	PCI_USES_IO=1, PCI_USES_MEM=2, PCI_USES_MASTER=4,	PCI_ADDR0=0x10<<0, PCI_ADDR1=0x10<<1, PCI_ADDR2=0x10<<2, PCI_ADDR3=0x10<<3,};struct pci_id_info {	const char *name;	u16	vendor_id, device_id;	int pci_index;} static pci_tbl[] = {	{ "Intel PCI EtherExpress Pro100 82557",	  PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82557,	  0	},	{ "Intel PCI EtherExpress Pro100 82559ER",	  PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82559ER,	  0	},	{ "Intel PCI EtherExpress Pro100 ID1029",	  PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ID1029,	  0 	},	{ "Intel Corporation 82559 InBusiness 10/100",	  PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ID1030,	  0 	},	{ "Intel PCI EtherExpress Pro100 82562EM",	  PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ID2449,	  0	},	{0,}						/* 0 terminated list. */};static inline unsigned int io_inw(unsigned long port){	return inw(port);}static inline void io_outw(unsigned int val, unsigned long port){	outw(val, port);}#ifndef USE_IO#undef inb#undef inw

⌨️ 快捷键说明

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