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

📄 eepro100.c

📁 Linux内核源代码 为压缩文件 是<<Linux内核>>一书中的源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
/* drivers/net/eepro100.c: An Intel i82557-559 Ethernet driver for Linux. *//*   NOTICE: For use with late 2.3 kernels only.   May not compile for kernels 2.3.43-47.	Written 1996-1999 by Donald Becker.	The driver also contains updates by different kernel developers	(see incomplete list below).	Current maintainer is Andrey V. Savochkin <saw@saw.sw.com.sg>.	Please use this email address and linux-kernel mailing list for bug reports.	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.	Version history:	1998 Apr - 2000 Feb  Andrey V. Savochkin <saw@saw.sw.com.sg>		Serious fixes for multicast filter list setting, TX timeout routine;		RX ring refilling logic;  other stuff	2000 Feb  Jeff Garzik <jgarzik@mandrakesoft.com>		Convert to new PCI driver interface	2000 Mar 24  Dragan Stancevic <visitor@valinux.com>		Disabled FC and ER, to avoid lockups when when we get FCP interrupts.	2000 Jul 17 Goutham Rao <goutham.rao@intel.com>		PCI DMA API fixes, adding pci_dma_sync_single calls where neccesary*/static 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.35 $ 2000/11/17 Modified by Andrey V. Savochkin <saw@saw.sw.com.sg> and others\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 = 8;		/* Tx FIFO threshold in 4 byte units, 0-15 */static int rxfifo = 8;		/* 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__)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 = 20;/* 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};static int debug = -1;			/* The debug level *//* A few values that may be tweaked. *//* The ring sizes should be a power of two for efficiency. */#define TX_RING_SIZE	32#define RX_RING_SIZE	32/* 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/config.h>#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/errno.h>#include <linux/ioport.h>#include <linux/malloc.h>#include <linux/interrupt.h>#include <linux/timer.h>#include <linux/pci.h>#include <linux/spinlock.h>#include <linux/init.h>#include <asm/bitops.h>#include <asm/io.h>#include <linux/netdevice.h>#include <linux/etherdevice.h>#include <linux/skbuff.h>#include <linux/delay.h>MODULE_AUTHOR("Maintainer: Andrey V. Savochkin <saw@saw.sw.com.sg>");MODULE_DESCRIPTION("Intel i82557/i82558/i82559 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");#define RUN_AT(x) (jiffies + (x))/* ACPI power states don't universally work (yet) */#ifndef CONFIG_EEPRO100_PM#undef pci_set_power_state#define pci_set_power_state null_set_power_statestatic inline int null_set_power_state(struct pci_dev *dev, int state){	return 0;}#endif /* CONFIG_EEPRO100_PM */#define netdevice_start(dev)#define netdevice_stop(dev)#define netif_set_tx_timeout(dev, tf, tm) \								do { \									(dev)->tx_timeout = (tf); \									(dev)->watchdog_timeo = (tm); \								} while(0)#define netif_device_attach(dev) netif_start_queue(dev)#define netif_device_detach(dev) netif_stop_queue(dev)#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#endifint 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!*/static int speedo_found1(struct pci_dev *pdev, long ioaddr, int fnd_cnt, int acpi_idle_state);enum 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,};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/* Currently alpha headers define in/out macros.   Undefine them.  2000/03/30  SAW */#undef inb#undef inw#undef inl#undef outb#undef outw#undef outl#define inb readb#define inw readw#define inl readl#define outb writeb#define outw writew#define outl writel#endif/* How to wait for the command unit to accept a command.   Typically this takes 0 ticks. */static inline void wait_for_cmd_done(long cmd_ioaddr){	int wait = 1000;	do   ;	while(inb(cmd_ioaddr) && --wait >= 0);#ifndef final_version	if (wait < 0)		printk(KERN_ALERT "eepro100: wait_for_cmd_done timeout!\n");#endif}/* Offsets to the various registers.   All accesses need not be longword aligned. */enum speedo_offsets {	SCBStatus = 0, SCBCmd = 2,	/* Rx/Command Unit command and status. */	SCBPointer = 4,				/* General purpose pointer. */	SCBPort = 8,				/* Misc. commands and operands.  */	SCBflash = 12, SCBeeprom = 14, /* EEPROM and flash memory control. */	SCBCtrlMDI = 16,			/* MDI interface control. */	SCBEarlyRx = 20,			/* Early receive byte count. */};/* Commands that can be put in a command list entry. */enum commands {	CmdNOp = 0, CmdIASetup = 0x10000, CmdConfigure = 0x20000,	CmdMulticastList = 0x30000, CmdTx = 0x40000, CmdTDR = 0x50000,	CmdDump = 0x60000, CmdDiagnose = 0x70000,	CmdSuspend = 0x40000000,	/* Suspend after completion. */	CmdIntr = 0x20000000,		/* Interrupt after completion. */	CmdTxFlex = 0x00080000,		/* Use "Flexible mode" for CmdTx command. */};/* Clear CmdSuspend (1<<30) avoiding interference with the card access to the   status bits.  Previous driver versions used separate 16 bit fields for   commands and statuses.  --SAW   FIXME: it may not work on non-IA32 architectures. */#if defined(__LITTLE_ENDIAN)#define clear_suspend(cmd)  ((__u16 *)&(cmd)->cmd_status)[1] &= ~0x4000#elif defined(__BIG_ENDIAN)#define clear_suspend(cmd)  ((__u16 *)&(cmd)->cmd_status)[1] &= ~0x0040#else#error Unsupported byteorder#endifenum SCBCmdBits {	SCBMaskCmdDone=0x8000, SCBMaskRxDone=0x4000, SCBMaskCmdIdle=0x2000,	SCBMaskRxSuspend=0x1000, SCBMaskEarlyRx=0x0800, SCBMaskFlowCtl=0x0400,	SCBTriggerIntr=0x0200, SCBMaskAll=0x0100,	/* The rest are Rx and Tx commands. */	CUStart=0x0010, CUResume=0x0020, CUStatsAddr=0x0040, CUShowStats=0x0050,	CUCmdBase=0x0060,	/* CU Base address (set to zero) . */	CUDumpStats=0x0070, /* Dump then reset stats counters. */	RxStart=0x0001, RxResume=0x0002, RxAbort=0x0004, RxAddrLoad=0x0006,	RxResumeNoResources=0x0007,};enum SCBPort_cmds {	PortReset=0, PortSelfTest=1, PortPartialReset=2, PortDump=3,};/* The Speedo3 Rx and Tx frame/buffer descriptors. */struct descriptor {			    /* A generic descriptor. */	s32 cmd_status;				/* All command and status fields. */	u32 link;				    /* struct descriptor *  */	unsigned char params[0];};/* The Speedo3 Rx and Tx buffer descriptors. */struct RxFD {					/* Receive frame descriptor. */	s32 status;	u32 link;					/* struct RxFD * */	u32 rx_buf_addr;			/* void * */	u32 count;};/* Selected elements of the Tx/RxFD.status word. */enum RxFD_bits {	RxComplete=0x8000, RxOK=0x2000,

⌨️ 快捷键说明

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