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, "a);\} 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 + -
显示快捷键?