starfire.c

来自「Linux Kernel 2.6.9 for OMAP1710」· C语言 代码 · 共 2,115 行 · 第 1/5 页

C
2,115
字号
/* starfire.c: Linux device driver for the Adaptec Starfire network adapter. *//*	Written 1998-2000 by Donald Becker.	Current maintainer is Ion Badulescu <ionut@cs.columbia.edu>. Please	send all bug reports to me, and not to Donald Becker, as this code	has been heavily modified from Donald's original version.	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.	The information below comes from Donald Becker's original driver:	The author may be reached as becker@scyld.com, or C/O	Scyld Computing Corporation	410 Severn Ave., Suite 210	Annapolis MD 21403	Support and updates available at	http://www.scyld.com/network/starfire.html	-----------------------------------------------------------	Linux kernel-specific changes:	LK1.1.1 (jgarzik):	- Use PCI driver interface	- Fix MOD_xxx races	- softnet fixups	LK1.1.2 (jgarzik):	- Merge Becker version 0.15	LK1.1.3 (Andrew Morton)	- Timer cleanups	LK1.1.4 (jgarzik):	- Merge Becker version 1.03	LK1.2.1 (Ion Badulescu <ionut@cs.columbia.edu>)	- Support hardware Rx/Tx checksumming	- Use the GFP firmware taken from Adaptec's Netware driver	LK1.2.2 (Ion Badulescu)	- Backported to 2.2.x	LK1.2.3 (Ion Badulescu)	- Fix the flaky mdio interface	- More compat clean-ups	LK1.2.4 (Ion Badulescu)	- More 2.2.x initialization fixes	LK1.2.5 (Ion Badulescu)	- Several fixes from Manfred Spraul	LK1.2.6 (Ion Badulescu)	- Fixed ifup/ifdown/ifup problem in 2.4.x	LK1.2.7 (Ion Badulescu)	- Removed unused code	- Made more functions static and __init	LK1.2.8 (Ion Badulescu)	- Quell bogus error messages, inform about the Tx threshold	- Removed #ifdef CONFIG_PCI, this driver is PCI only	LK1.2.9 (Ion Badulescu)	- Merged Jeff Garzik's changes from 2.4.4-pre5	- Added 2.2.x compatibility stuff required by the above changes	LK1.2.9a (Ion Badulescu)	- More updates from Jeff Garzik	LK1.3.0 (Ion Badulescu)	- Merged zerocopy support	LK1.3.1 (Ion Badulescu)	- Added ethtool support	- Added GPIO (media change) interrupt support	LK1.3.2 (Ion Badulescu)	- Fixed 2.2.x compatibility issues introduced in 1.3.1	- Fixed ethtool ioctl returning uninitialized memory	LK1.3.3 (Ion Badulescu)	- Initialize the TxMode register properly	- Don't dereference dev->priv after freeing it	LK1.3.4 (Ion Badulescu)	- Fixed initialization timing problems	- Fixed interrupt mask definitions	LK1.3.5 (jgarzik)	- ethtool NWAY_RST, GLINK, [GS]MSGLVL support	LK1.3.6:	- Sparc64 support and fixes (Ion Badulescu)	- Better stats and error handling (Ion Badulescu)	- Use new pci_set_mwi() PCI API function (jgarzik)	LK1.3.7 (Ion Badulescu)	- minimal implementation of tx_timeout()	- correctly shutdown the Rx/Tx engines in netdev_close()	- added calls to netif_carrier_on/off	(patch from Stefan Rompf <srompf@isg.de>)	- VLAN support	LK1.3.8 (Ion Badulescu)	- adjust DMA burst size on sparc64	- 64-bit support	- reworked zerocopy support for 64-bit buffers	- working and usable interrupt mitigation/latency	- reduced Tx interrupt frequency for lower interrupt overhead	LK1.3.9 (Ion Badulescu)	- bugfix for mcast filter	- enable the right kind of Tx interrupts (TxDMADone, not TxDone)	LK1.4.0 (Ion Badulescu)	- NAPI support	LK1.4.1 (Ion Badulescu)	- flush PCI posting buffers after disabling Rx interrupts	- put the chip to a D3 slumber on driver unload	- added config option to enable/disable NAPITODO:	bugfixes (no bugs known as of right now)*/#define DRV_NAME	"starfire"#define DRV_VERSION	"1.03+LK1.4.1"#define DRV_RELDATE	"February 10, 2002"#include <linux/config.h>#include <linux/version.h>#include <linux/module.h>#include <linux/kernel.h>#include <linux/pci.h>#include <linux/netdevice.h>#include <linux/etherdevice.h>#include <linux/init.h>#include <linux/delay.h>#include <asm/processor.h>		/* Processor type for cache alignment. */#include <asm/uaccess.h>#include <asm/io.h>/* * Adaptec's license for their drivers (which is where I got the * firmware files) does not allow one to redistribute them. Thus, we can't * include the firmware with this driver. * * However, should a legal-to-distribute firmware become available, * the driver developer would need only to obtain the firmware in the * form of a C header file. * Once that's done, the #undef below must be changed into a #define * for this driver to really use the firmware. Note that Rx/Tx * hardware TCP checksumming is not possible without the firmware. * * WANTED: legal firmware to include with this GPL'd driver. */#undef HAS_FIRMWARE/* * The current frame processor firmware fails to checksum a fragment * of length 1. If and when this is fixed, the #define below can be removed. */#define HAS_BROKEN_FIRMWARE/* * Define this if using the driver with the zero-copy patch */#if defined(HAS_FIRMWARE) && defined(MAX_SKB_FRAGS)#define ZEROCOPY#endif#ifdef HAS_FIRMWARE#include "starfire_firmware.h"#endif /* HAS_FIRMWARE */#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE)#define VLAN_SUPPORT#endif#ifndef CONFIG_ADAPTEC_STARFIRE_NAPI#undef HAVE_NETDEV_POLL#endif/* The user-configurable values.   These may be modified when a driver module is loaded.*//* Used for tuning interrupt latency vs. overhead. */static int intr_latency;static int small_frames;static int debug = 1;			/* 1 normal messages, 0 quiet .. 7 verbose. */static int max_interrupt_work = 20;static int mtu;/* Maximum number of multicast addresses to filter (vs. rx-all-multicast).   The Starfire has a 512 element hash table based on the Ethernet CRC. */static int multicast_filter_limit = 512;/* Whether to do TCP/UDP checksums in hardware */#ifdef HAS_FIRMWAREstatic int enable_hw_cksum = 1;#elsestatic int enable_hw_cksum = 0;#endif#define PKT_BUF_SZ	1536		/* Size of each temporary Rx buffer.*//* * Set the copy breakpoint for the copy-only-tiny-frames scheme. * Setting to > 1518 effectively disables this feature. * * NOTE: * The ia64 doesn't allow for unaligned loads even of integers being * misaligned on a 2 byte boundary. Thus always force copying of * packets as the starfire doesn't allow for misaligned DMAs ;-( * 23/10/2000 - Jes * * The Alpha and the Sparc don't like unaligned loads, either. On Sparc64, * at least, having unaligned frames leads to a rather serious performance * penalty. -Ion */#if defined(__ia64__) || defined(__alpha__) || defined(__sparc__)static int rx_copybreak = PKT_BUF_SZ;#elsestatic int rx_copybreak /* = 0 */;#endif/* PCI DMA burst size -- on sparc64 we want to force it to 64 bytes, on the others the default of 128 is fine. */#ifdef __sparc__#define DMA_BURST_SIZE 64#else#define DMA_BURST_SIZE 128#endif/* Used to pass the media type, etc.   Both 'options[]' and 'full_duplex[]' exist for driver interoperability.   The media type is usually passed in 'options[]'.   These variables are deprecated, use ethtool instead. -Ion*/#define MAX_UNITS 8		/* More are supported, limit only on options */static int options[MAX_UNITS] = {0, };static int full_duplex[MAX_UNITS] = {0, };/* Operational parameters that are set at compile time. *//* The "native" ring sizes are either 256 or 2048.   However in some modes a descriptor may be marked to wrap the ring earlier.*/#define RX_RING_SIZE	256#define TX_RING_SIZE	32/* The completion queues are fixed at 1024 entries i.e. 4K or 8KB. */#define DONE_Q_SIZE	1024/* All queues must be aligned on a 256-byte boundary */#define QUEUE_ALIGN	256#if RX_RING_SIZE > 256#define RX_Q_ENTRIES Rx2048QEntries#else#define RX_Q_ENTRIES Rx256QEntries#endif/* Operational parameters that usually are not changed. *//* Time in jiffies before concluding the transmitter is hung. */#define TX_TIMEOUT	(2 * HZ)/* * This SUCKS. * We need a much better method to determine if dma_addr_t is 64-bit. */#if (defined(__i386__) && defined(CONFIG_HIGHMEM) && (LINUX_VERSION_CODE > 0x20500 || defined(CONFIG_HIGHMEM64G))) || defined(__x86_64__) || defined (__ia64__) || defined(__mips64__) || (defined(__mips__) && defined(CONFIG_HIGHMEM) && defined(CONFIG_64BIT_PHYS_ADDR))/* 64-bit dma_addr_t */#define ADDR_64BITS	/* This chip uses 64 bit addresses. */#define cpu_to_dma(x) cpu_to_le64(x)#define dma_to_cpu(x) le64_to_cpu(x)#define RX_DESC_Q_ADDR_SIZE RxDescQAddr64bit#define TX_DESC_Q_ADDR_SIZE TxDescQAddr64bit#define RX_COMPL_Q_ADDR_SIZE RxComplQAddr64bit#define TX_COMPL_Q_ADDR_SIZE TxComplQAddr64bit#define RX_DESC_ADDR_SIZE RxDescAddr64bit#else  /* 32-bit dma_addr_t */#define cpu_to_dma(x) cpu_to_le32(x)#define dma_to_cpu(x) le32_to_cpu(x)#define RX_DESC_Q_ADDR_SIZE RxDescQAddr32bit#define TX_DESC_Q_ADDR_SIZE TxDescQAddr32bit#define RX_COMPL_Q_ADDR_SIZE RxComplQAddr32bit#define TX_COMPL_Q_ADDR_SIZE TxComplQAddr32bit#define RX_DESC_ADDR_SIZE RxDescAddr32bit#endif#ifdef MAX_SKB_FRAGS#define skb_first_frag_len(skb)	skb_headlen(skb)#define skb_num_frags(skb) (skb_shinfo(skb)->nr_frags + 1)#else  /* not MAX_SKB_FRAGS */#define skb_first_frag_len(skb)	(skb->len)#define skb_num_frags(skb) 1#endif /* not MAX_SKB_FRAGS *//* 2.2.x compatibility code */#if LINUX_VERSION_CODE < 0x20300#include "starfire-kcomp22.h"#else  /* LINUX_VERSION_CODE > 0x20300 */#include <linux/crc32.h>#include <linux/ethtool.h>#include <linux/mii.h>#include <linux/if_vlan.h>#define COMPAT_MOD_INC_USE_COUNT#define COMPAT_MOD_DEC_USE_COUNT#define init_tx_timer(dev, func, timeout) \	dev->tx_timeout = func; \	dev->watchdog_timeo = timeout;#define kick_tx_timer(dev, func, timeout)#define netif_start_if(dev)#define netif_stop_if(dev)#define PCI_SLOT_NAME(pci_dev)	pci_name(pci_dev)#endif /* LINUX_VERSION_CODE > 0x20300 */#ifdef HAVE_NETDEV_POLL#define init_poll(dev) \	dev->poll = &netdev_poll; \	dev->weight = max_interrupt_work;#define netdev_rx(dev, ioaddr) \do { \	u32 intr_enable; \	if (netif_rx_schedule_prep(dev)) { \		__netif_rx_schedule(dev); \		intr_enable = readl(ioaddr + IntrEnable); \		intr_enable &= ~(IntrRxDone | IntrRxEmpty); \		writel(intr_enable, ioaddr + IntrEnable); \		readl(ioaddr + IntrEnable); /* flush PCI posting buffers */ \	} else { \		/* Paranoia check */ \		intr_enable = readl(ioaddr + IntrEnable); \		if (intr_enable & (IntrRxDone | IntrRxEmpty)) { \			printk("%s: interrupt while in polling mode!\n", dev->name); \			intr_enable &= ~(IntrRxDone | IntrRxEmpty); \			writel(intr_enable, ioaddr + IntrEnable); \		} \	} \} while (0)#define netdev_receive_skb(skb) netif_receive_skb(skb)#define vlan_netdev_receive_skb(skb, vlgrp, vlid) vlan_hwaccel_receive_skb(skb, vlgrp, vlid)static int	netdev_poll(struct net_device *dev, int *budget);#else  /* not HAVE_NETDEV_POLL */#define init_poll(dev)#define netdev_receive_skb(skb) netif_rx(skb)#define vlan_netdev_receive_skb(skb, vlgrp, vlid) vlan_hwaccel_rx(skb, vlgrp, vlid)#define netdev_rx(dev, ioaddr) \do { \	int quota = np->dirty_rx + RX_RING_SIZE - np->cur_rx; \	__netdev_rx(dev, &quota);\} while (0)#endif /* not HAVE_NETDEV_POLL *//* end of compatibility code *//* These identify the driver base version and may not be removed. */static char version[] __devinitdata =KERN_INFO "starfire.c:v1.03 7/26/2000  Written by Donald Becker <becker@scyld.com>\n"KERN_INFO " (unofficial 2.2/2.4 kernel port, version " DRV_VERSION ", " DRV_RELDATE ")\n";MODULE_AUTHOR("Donald Becker <becker@scyld.com>");MODULE_DESCRIPTION("Adaptec Starfire 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(intr_latency, "i");MODULE_PARM(small_frames, "i");MODULE_PARM(options, "1-" __MODULE_STRING(MAX_UNITS) "i");MODULE_PARM(full_duplex, "1-" __MODULE_STRING(MAX_UNITS) "i");MODULE_PARM(enable_hw_cksum, "i");MODULE_PARM_DESC(max_interrupt_work, "Maximum events handled per interrupt");MODULE_PARM_DESC(mtu, "MTU (all boards)");MODULE_PARM_DESC(debug, "Debug level (0-6)");MODULE_PARM_DESC(rx_copybreak, "Copy breakpoint for copy-only-tiny-frames");MODULE_PARM_DESC(intr_latency, "Maximum interrupt latency, in microseconds");MODULE_PARM_DESC(small_frames, "Maximum size of receive frames that bypass interrupt latency (0,64,128,256,512)");MODULE_PARM_DESC(options, "Deprecated: Bits 0-3: media type, bit 17: full duplex");MODULE_PARM_DESC(full_duplex, "Deprecated: Forced full-duplex setting (0/1)");MODULE_PARM_DESC(enable_hw_cksum, "Enable/disable hardware cksum support (0/1)");/*				Theory of OperationI. Board CompatibilityThis driver is for the Adaptec 6915 "Starfire" 64 bit PCI Ethernet adapter.II. Board-specific settingsIII. Driver operationIIIa. Ring buffersThe Starfire hardware uses multiple fixed-size descriptor queues/rings.  Thering sizes are set fixed by the hardware, but may optionally be wrappedearlier by the END bit in the descriptor.This driver uses that hardware queue size for the Rx ring, where a largenumber of entries has no ill effect beyond increases the potential backlog.The Tx ring is wrapped with the END bit, since a large hardware Tx queuedisables the queue layer priority ordering and we have no mechanism toutilize the hardware two-level priority queue.  When modifying theRX/TX_RING_SIZE pay close attention to page sizes and the ring-empty warninglevels.IIIb/c. Transmit/Receive StructureSee the Adaptec manual for the many possible structures, and options for

⌨️ 快捷键说明

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