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

📄 e100.c

📁 网卡的驱动程序源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
/*******************************************************************************    Copyright(c) 1999 - 2006 Intel Corporation. All rights reserved.    This program is free software; you can redistribute it and/or modify it   under the terms of the GNU General Public License as published by the Free   Software Foundation; either version 2 of the License, or (at your option)   any later version.    This program is distributed in the hope that it will be useful, but WITHOUT   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or   FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for   more details.    You should have received a copy of the GNU General Public License along with  this program; if not, write to the Free Software Foundation, Inc., 59   Temple Place - Suite 330, Boston, MA  02111-1307, USA.    The full GNU General Public License is included in this distribution in the  file called LICENSE.    Contact Information:  Linux NICS <linux.nics@intel.com>  Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497*******************************************************************************//* *	e100.c: Intel(R) PRO/100 ethernet driver * *	(Re)written 2003 by scott.feldman@intel.com.  Based loosely on *	original e100 driver, but better described as a munging of *	e100, e1000, eepro100, tg3, 8139cp, and other drivers. * *	References: *		Intel 8255x 10/100 Mbps Ethernet Controller Family, *		Open Source Software Developers Manual, *		http://sourceforge.net/projects/e1000 * * *	                      Theory of Operation * *	I.   General * *	The driver supports Intel(R) 10/100 Mbps PCI Fast Ethernet *	controller family, which includes the 82557, 82558, 82559, 82550, *	82551, and 82562 devices.  82558 and greater controllers *	integrate the Intel 82555 PHY.  The controllers are used in *	server and client network interface cards, as well as in *	LAN-On-Motherboard (LOM), CardBus, MiniPCI, and ICHx *	configurations.  8255x supports a 32-bit linear addressing *	mode and operates at 33Mhz PCI clock rate. * *	II.  Driver Operation * *	Memory-mapped mode is used exclusively to access the device's *	shared-memory structure, the Control/Status Registers (CSR). All *	setup, configuration, and control of the device, including queuing *	of Tx, Rx, and configuration commands is through the CSR. *	cmd_lock serializes accesses to the CSR command register.  cb_lock *	protects the shared Command Block List (CBL). * *	8255x is highly MII-compliant and all access to the PHY go *	through the Management Data Interface (MDI).  Consequently, the *	driver leverages the mii.c library shared with other MII-compliant *	devices. * *	Big- and Little-Endian byte order as well as 32- and 64-bit *	archs are supported.  Weak-ordered memory and non-cache-coherent *	archs are supported. * *	III. Transmit * *	A Tx skb is mapped and hangs off of a TCB.  TCBs are linked *	together in a fixed-size ring (CBL) thus forming the flexible mode *	memory structure.  A TCB marked with the suspend-bit indicates *	the end of the ring.  The last TCB processed suspends the *	controller, and the controller can be restarted by issue a CU *	resume command to continue from the suspend point, or a CU start *	command to start at a given position in the ring. * *	Non-Tx commands (config, multicast setup, etc) are linked *	into the CBL ring along with Tx commands.  The common structure *	used for both Tx and non-Tx commands is the Command Block (CB). * *	cb_to_use is the next CB to use for queuing a command; cb_to_clean *	is the next CB to check for completion; cb_to_send is the first *	CB to start on in case of a previous failure to resume.  CB clean *	up happens in interrupt context in response to a CU interrupt. *	cbs_avail keeps track of number of free CB resources available. * * 	Hardware padding of short packets to minimum packet size is * 	enabled.  82557 pads with 7Eh, while the later controllers pad * 	with 00h. * *	IV.  Recieve * *	The Receive Frame Area (RFA) comprises a ring of Receive Frame *	Descriptors (RFD) + data buffer, thus forming the simplified mode *	memory structure.  Rx skbs are allocated to contain both the RFD *	and the data buffer, but the RFD is pulled off before the skb is *	indicated.  The data buffer is aligned such that encapsulated *	protocol headers are u32-aligned.  Since the RFD is part of the *	mapped shared memory, and completion status is contained within *	the RFD, the RFD must be dma_sync'ed to maintain a consistent *	view from software and hardware. * *	Under typical operation, the  receive unit (RU) is start once, *	and the controller happily fills RFDs as frames arrive.  If *	replacement RFDs cannot be allocated, or the RU goes non-active, *	the RU must be restarted.  Frame arrival generates an interrupt, *	and Rx indication and re-allocation happen in the same context, *	therefore no locking is required.  A software-generated interrupt *	is generated from the watchdog to recover from a failed allocation *	senario where all Rx resources have been indicated and none re- *	placed. * *	V.   Miscellaneous * * 	VLAN offloading of tagging, stripping and filtering is not * 	supported, but driver will accommodate the extra 4-byte VLAN tag * 	for processing by upper layers.  Tx/Rx Checksum offloading is not * 	supported.  Tx Scatter/Gather is not supported.  Jumbo Frames is * 	not supported (hardware limitation). * * 	MagicPacket(tm) WoL support is enabled/disabled via ethtool. * * 	Thanks to JC (jchapman@katalix.com) for helping with * 	testing/troubleshooting the development driver. * * 	TODO: * 	o several entry points race with dev->close * 	o check for tx-no-resources/stop Q races with tx clean/wake Q * *	FIXES: * 2005/12/02 - Michael O'Donnell <Michael.ODonnell at stratus dot com> *	- Stratus87247: protect MDI control register manipulations */#include <linux/config.h>#include <linux/module.h>#include <linux/kernel.h>#include <linux/types.h>#include <linux/slab.h>#include <linux/delay.h>#include <linux/init.h>#include <linux/pci.h>#include <linux/netdevice.h>#include <linux/etherdevice.h>#include <linux/mii.h>#ifdef NETIF_F_HW_VLAN_TX#include <linux/if_vlan.h>#endif#include <linux/skbuff.h>#include <linux/ethtool.h>#include <linux/string.h>#include <asm/unaligned.h>#include "kcompat.h"#ifdef ETHTOOL_OPS_COMPAT#include "ethtool.c"#endif#define DRV_NAME		"e100"#ifndef CONFIG_E100_NAPI#define DRV_EXT#else#define DRV_EXT		"-NAPI"#endif#define DRV_VERSION		"3.5.14"DRV_EXT#define DRV_DESCRIPTION		"Intel(R) PRO/100 Network Driver"#define DRV_COPYRIGHT		"Copyright(c) 1999-2006 Intel Corporation"#define PFX			DRV_NAME ": "#define E100_WATCHDOG_PERIOD	(2 * HZ)#define E100_NAPI_WEIGHT	16MODULE_DESCRIPTION(DRV_DESCRIPTION);MODULE_AUTHOR(DRV_COPYRIGHT);MODULE_LICENSE("GPL");MODULE_VERSION(DRV_VERSION);static int debug = 3;module_param(debug, int, 0);MODULE_PARM_DESC(debug, "Debug level (0=none,...,16=all)");#define DPRINTK(nlevel, klevel, fmt, args...) \	(void)((NETIF_MSG_##nlevel & nic->msg_enable) && \	printk(KERN_##klevel PFX "%s: %s: " fmt, nic->netdev->name, \		__FUNCTION__ , ## args))#define INTEL_8255X_ETHERNET_DEVICE(device_id, ich) {\	PCI_VENDOR_ID_INTEL, device_id, PCI_ANY_ID, PCI_ANY_ID, \	PCI_CLASS_NETWORK_ETHERNET << 8, 0xFFFF00, ich }static struct pci_device_id e100_id_table[] = {	INTEL_8255X_ETHERNET_DEVICE(0x1029, 0),	INTEL_8255X_ETHERNET_DEVICE(0x1030, 0),	INTEL_8255X_ETHERNET_DEVICE(0x1031, 3),	INTEL_8255X_ETHERNET_DEVICE(0x1032, 3),	INTEL_8255X_ETHERNET_DEVICE(0x1033, 3),	INTEL_8255X_ETHERNET_DEVICE(0x1034, 3),	INTEL_8255X_ETHERNET_DEVICE(0x1038, 3),	INTEL_8255X_ETHERNET_DEVICE(0x1039, 4),	INTEL_8255X_ETHERNET_DEVICE(0x103A, 4),	INTEL_8255X_ETHERNET_DEVICE(0x103B, 4),	INTEL_8255X_ETHERNET_DEVICE(0x103C, 4),	INTEL_8255X_ETHERNET_DEVICE(0x103D, 4),	INTEL_8255X_ETHERNET_DEVICE(0x103E, 4),	INTEL_8255X_ETHERNET_DEVICE(0x1050, 5),	INTEL_8255X_ETHERNET_DEVICE(0x1051, 5),	INTEL_8255X_ETHERNET_DEVICE(0x1052, 5),	INTEL_8255X_ETHERNET_DEVICE(0x1053, 5),	INTEL_8255X_ETHERNET_DEVICE(0x1054, 5),	INTEL_8255X_ETHERNET_DEVICE(0x1055, 5),	INTEL_8255X_ETHERNET_DEVICE(0x1056, 5),	INTEL_8255X_ETHERNET_DEVICE(0x1057, 5),	INTEL_8255X_ETHERNET_DEVICE(0x1059, 0),	INTEL_8255X_ETHERNET_DEVICE(0x1064, 6),	INTEL_8255X_ETHERNET_DEVICE(0x1065, 6),	INTEL_8255X_ETHERNET_DEVICE(0x1066, 6),	INTEL_8255X_ETHERNET_DEVICE(0x1067, 6),	INTEL_8255X_ETHERNET_DEVICE(0x1068, 6),	INTEL_8255X_ETHERNET_DEVICE(0x1069, 6),	INTEL_8255X_ETHERNET_DEVICE(0x106A, 6),	INTEL_8255X_ETHERNET_DEVICE(0x106B, 6),	INTEL_8255X_ETHERNET_DEVICE(0x1091, 7),	INTEL_8255X_ETHERNET_DEVICE(0x1092, 7),	INTEL_8255X_ETHERNET_DEVICE(0x1093, 7),	INTEL_8255X_ETHERNET_DEVICE(0x1094, 7),	INTEL_8255X_ETHERNET_DEVICE(0x1095, 7),	INTEL_8255X_ETHERNET_DEVICE(0x1209, 0),	INTEL_8255X_ETHERNET_DEVICE(0x1229, 0),	INTEL_8255X_ETHERNET_DEVICE(0x2449, 2),	INTEL_8255X_ETHERNET_DEVICE(0x2459, 2),	INTEL_8255X_ETHERNET_DEVICE(0x245D, 2),	INTEL_8255X_ETHERNET_DEVICE(0x27DC, 7),	{ 0, }};MODULE_DEVICE_TABLE(pci, e100_id_table);enum mac {	mac_82557_D100_A  = 0,	mac_82557_D100_B  = 1,	mac_82557_D100_C  = 2,	mac_82558_D101_A4 = 4,	mac_82558_D101_B0 = 5,	mac_82559_D101M   = 8,	mac_82559_D101S   = 9,	mac_82550_D102    = 12,	mac_82550_D102_C  = 13,	mac_82551_E       = 14,	mac_82551_F       = 15,	mac_82551_10      = 16,	mac_unknown       = 0xFF,};enum phy {	phy_100a     = 0x000003E0,	phy_100c     = 0x035002A8,	phy_82555_tx = 0x015002A8,	phy_nsc_tx   = 0x5C002000,	phy_82562_et = 0x033002A8,	phy_82562_em = 0x032002A8,	phy_82562_ek = 0x031002A8,	phy_82562_eh = 0x017002A8,	phy_unknown  = 0xFFFFFFFF,};/* CSR (Control/Status Registers) */struct csr {	struct {		u8 status;		u8 stat_ack;		u8 cmd_lo;		u8 cmd_hi;		u32 gen_ptr;	} scb;	u32 port;	u16 flash_ctrl;	u8 eeprom_ctrl_lo;	u8 eeprom_ctrl_hi;	u32 mdi_ctrl;	u32 rx_dma_count;};enum scb_status {	rus_ready        = 0x10,	rus_mask         = 0x3C,};enum ru_state  {	RU_SUSPENDED = 0,	RU_RUNNING	 = 1,	RU_UNINITIALIZED = -1,};enum scb_stat_ack {	stat_ack_not_ours    = 0x00,	stat_ack_sw_gen      = 0x04,	stat_ack_rnr         = 0x10,	stat_ack_cu_idle     = 0x20,	stat_ack_frame_rx    = 0x40,	stat_ack_cu_cmd_done = 0x80,	stat_ack_not_present = 0xFF,	stat_ack_rx = (stat_ack_sw_gen | stat_ack_rnr | stat_ack_frame_rx),	stat_ack_tx = (stat_ack_cu_idle | stat_ack_cu_cmd_done),};enum scb_cmd_hi {	irq_mask_none = 0x00,	irq_mask_all  = 0x01,	irq_sw_gen    = 0x02,};enum scb_cmd_lo {	cuc_nop        = 0x00,	ruc_start      = 0x01,	ruc_load_base  = 0x06,	cuc_start      = 0x10,	cuc_resume     = 0x20,	cuc_dump_addr  = 0x40,	cuc_dump_stats = 0x50,	cuc_load_base  = 0x60,	cuc_dump_reset = 0x70,};enum cuc_dump {	cuc_dump_complete       = 0x0000A005,	cuc_dump_reset_complete = 0x0000A007,};enum port {	software_reset  = 0x0000,	selftest        = 0x0001,	selective_reset = 0x0002,};enum eeprom_ctrl_lo {	eesk = 0x01,	eecs = 0x02,	eedi = 0x04,	eedo = 0x08,};enum mdi_ctrl {	mdi_write = 0x04000000,	mdi_read  = 0x08000000,	mdi_ready = 0x10000000,};enum eeprom_op {	op_write = 0x05,	op_read  = 0x06,	op_ewds  = 0x10,	op_ewen  = 0x13,};enum eeprom_offsets {	eeprom_cnfg_mdix  = 0x03,	eeprom_id         = 0x0A,	eeprom_config_asf = 0x0D,	eeprom_smbus_addr = 0x90,};enum eeprom_cnfg_mdix {	eeprom_mdix_enabled = 0x0080,};enum eeprom_id {	eeprom_id_wol = 0x0020,};enum eeprom_config_asf {	eeprom_asf = 0x8000,	eeprom_gcl = 0x4000,};enum cb_status {	cb_complete = 0x8000,	cb_ok       = 0x2000,};enum cb_command {	cb_nop    = 0x0000,	cb_iaaddr = 0x0001,	cb_config = 0x0002,	cb_multi  = 0x0003,	cb_tx     = 0x0004,	cb_ucode  = 0x0005,	cb_dump   = 0x0006,	cb_tx_sf  = 0x0008,	cb_cid    = 0x1f00,	cb_i      = 0x2000,	cb_s      = 0x4000,	cb_el     = 0x8000,};struct rfd {	u16 status;	u16 command;	u32 link;	u32 rbd;	u16 actual_size;	u16 size;};struct rx {	struct rx *next, *prev;	struct sk_buff *skb;	dma_addr_t dma_addr;};#if defined(__BIG_ENDIAN_BITFIELD)#define X(a,b)	b,a#else#define X(a,b)	a,b#endifstruct config {/*0*/	u8 X(byte_count:6, pad0:2);/*1*/	u8 X(X(rx_fifo_limit:4, tx_fifo_limit:3), pad1:1);/*2*/	u8 adaptive_ifs;/*3*/	u8 X(X(X(X(mwi_enable:1, type_enable:1), read_align_enable:1),	   term_write_cache_line:1), pad3:4);/*4*/	u8 X(rx_dma_max_count:7, pad4:1);/*5*/	u8 X(tx_dma_max_count:7, dma_max_count_enable:1);/*6*/	u8 X(X(X(X(X(X(X(late_scb_update:1, direct_rx_dma:1),	   tno_intr:1), cna_intr:1), standard_tcb:1), standard_stat_counter:1),	   rx_discard_overruns:1), rx_save_bad_frames:1);/*7*/	u8 X(X(X(X(X(rx_discard_short_frames:1, tx_underrun_retry:2),	   pad7:2), rx_extended_rfd:1), tx_two_frames_in_fifo:1),	   tx_dynamic_tbd:1);/*8*/	u8 X(X(mii_mode:1, pad8:6), csma_disabled:1);/*9*/	u8 X(X(X(X(X(rx_tcpudp_checksum:1, pad9:3), vlan_arp_tco:1),	   link_status_wake:1), arp_wake:1), mcmatch_wake:1);/*10*/	u8 X(X(X(pad10:3, no_source_addr_insertion:1), preamble_length:2),

⌨️ 快捷键说明

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