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

📄 e100_main.c

📁 linux intel 网卡驱动,利用他可以让inel的pro 100 网卡进行网络配置和实用
💻 C
📖 第 1 页 / 共 5 页
字号:
/*******************************************************************************    Copyright(c) 1999 - 2002 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*******************************************************************************//***********************************************************************                                                                     ** INTEL CORPORATION                                                   **                                                                     ** This software is supplied under the terms of the license included   ** above.  All use of this driver must be in accordance with the terms ** of that license.                                                    **                                                                     ** Module Name:  e100_main.c                                           **                                                                     ** Abstract:     Functions for the driver entry points like load,      **               unload, open and close. All board specific calls made **               by the network interface section of the driver.       **                                                                     ** Environment:  This file is intended to be specific to the Linux     **               operating system.                                     **                                                                     ***********************************************************************//* Change Log * * 2.1.12       8/2/02 *   o Feature: ethtool register dump *   o Bug fix: Driver passes wrong name to /proc/interrupts *   o Bug fix: Ethernet bridging not working  *   o Bug fix: Promiscuous mode is not working *   o Bug fix: Checked return value from copy_from_user (William Stinson, wstinson@infonie.fr) *   o Bug fix: ARP wake on LAN fails *   o Bug fix: mii-diag does not update driver level's speed, duplex and re-configure flow control *   o Bug fix: Ethtool shows wrong speed/duplex when not connected *   o Bug fix: Ethtool shows wrong speed/duplex when reconnected if forced speed/duplex *   o Bug fix: PHY loopback diagnostic fails * * 2.1.6        7/5/02 *   o Added device ID support for Dell LOM. *   o Added device ID support for 82511QM mobile nics. *   o Bug fix: ethtool get/set EEPROM routines modified to use byte *     addressing rather than word addressing. *   o Feature: added MDIX mode support for 82550 and up. *   o Bug fix: added reboot notifer to setup WOL settings when *     shutting system down. *   o Cleanup: removed yield() redefinition (Andrew Morton,  *     akpm@zip.com.au). *   o Bug fix: flow control now working when link partner is  *     autoneg capable but not flow control capable. *   o Bug fix: added check for corrupted EEPROM *   o Bug fix: don't report checksum offloading for the older *     controllers that don't support the feature. *   o Bug fix: calculate cable diagnostics when link goes down *     rather than when queuering /proc file. *   o Cleanup: move mdi_access_lock to local get/set mdi routines. * * 2.0.30       5/30/02 */ #ifdef IANS#define _IANS_MAIN_MODULE_C_#endif#undef __NO_VERSION__#include <linux/config.h>#include <net/checksum.h>#include <linux/tcp.h>#include <linux/udp.h>#include "e100.h"#include "e100_ucode.h"#include "e100_config.h"#include "e100_phy.h"#include "e100_vendor.h"#ifdef E100_IA64_DMA_FIX#if !(defined __ia64__)#undef E100_IA64_DMA_FIX#endif#endif#ifdef CONFIG_PROC_FSextern int e100_create_proc_subdir(struct e100_private *);extern void e100_remove_proc_subdir(struct e100_private *);#else#define e100_create_proc_subdir(X) 0#define e100_remove_proc_subdir(X) do {} while(0)#endif#ifdef E100_IDIAG_PRO_SUPPORTextern enum idiag_pro_stat e100_run_idiag(struct net_device *,					 struct idiag_pro_data *);#endifstatic unsigned char e100_setup_filter(struct e100_private *bdp);static void e100_do_wol(struct pci_dev *pcid, struct e100_private *bdp);#ifdef ETHTOOL_SWOLstatic u16 e100_get_ip_lbytes(struct net_device *dev);#endifextern void e100_config_wol(struct e100_private *bdp);#ifdef SIOCETHTOOLstatic int e100_do_ethtool_ioctl(struct net_device *, struct ifreq *);static void e100_get_speed_duplex_caps(struct e100_private *);static int e100_ethtool_get_settings(struct net_device *, struct ifreq *);static int e100_ethtool_set_settings(struct net_device *, struct ifreq *);#ifdef ETHTOOL_GDRVINFOstatic int e100_ethtool_get_drvinfo(struct net_device *, struct ifreq *);#endif#ifdef ETHTOOL_GEEPROMstatic int e100_ethtool_eeprom(struct net_device *, struct ifreq *);#define E100_EEPROM_MAGIC 0x1234#endif#ifdef ETHTOOL_GLINKstatic int e100_ethtool_glink(struct net_device *, struct ifreq *);#endif#ifdef  ETHTOOL_GEEPROM  /* GREGS broken in earlier ethtool.h */#ifdef ETHTOOL_GREGSstatic int e100_ethtool_gregs(struct net_device *, struct ifreq *);#endif#endif#ifdef ETHTOOL_NWAY_RSTstatic int e100_ethtool_nway_rst(struct net_device *, struct ifreq *);#endif#ifdef ETHTOOL_GWOLstatic int e100_ethtool_wol(struct net_device *, struct ifreq *);#endif#ifdef ETHTOOL_TESTextern u32 e100_run_diag(struct net_device *dev, u64 *test_info, u32 flags);static int e100_ethtool_test(struct net_device *, struct ifreq *);#endif#ifdef ETHTOOL_GSTRINGSstatic int e100_ethtool_gstrings(struct net_device *, struct ifreq *);static char *test_strings[] = {	"E100_EEPROM_TEST_FAIL",	"E100_CHIP_TIMEOUT",	"E100_ROM_TEST_FAIL",	"E100_REG_TEST_FAIL",	"E100_MAC_TEST_FAIL",	"E100_LPBK_MAC_FAIL",	"E100_LPBK_PHY_FAIL"};#endif#ifdef	ETHTOOL_PHYS_IDstatic int e100_ethtool_led_blink(struct net_device *, struct ifreq *);#endif#endif /*SIOCETHTOOL */#ifdef SIOCGMIIPHY#include <linux/mii.h>static int e100_mii_ioctl(struct net_device *, struct ifreq *, int);#endifstatic unsigned char e100_delayed_exec_non_cu_cmd(struct e100_private *,						  nxmit_cb_entry_t *);static void e100_free_nontx_list(struct e100_private *);static void e100_non_tx_background(unsigned long);/* Global Data structures and variables */char e100_copyright[] __devinitdata = "Copyright (c) 2002 Intel Corporation";char e100_driver_version[]="2.1.15";const char *e100_full_driver_name = "Intel(R) PRO/100 Network Driver";char e100_short_driver_name[] = "e100";static int e100nics = 0;#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0)struct list_head e100_nic_list;#endifstatic int e100_notify_reboot(struct notifier_block *, unsigned long event, void *ptr);struct notifier_block e100_notifier = {	notifier_call:  e100_notify_reboot,	next:           NULL,	priority:       0};static int e100_suspend(struct pci_dev *pcid, u32 state);#ifdef CONFIG_PMstatic int e100_resume(struct pci_dev *pcid);#endifstatic void e100_get_mdix_status(struct e100_private *bdp);/*********************************************************************//*! This is a GCC extension to ANSI C. *  See the item "Labeled Elements in Initializers" in the section *  "Extensions to the C Language Family" of the GCC documentation. *********************************************************************/#define E100_PARAM_INIT { [0 ... E100_MAX_NIC] = -1 }/* All parameters are treated the same, as an integer array of values. * This macro just reduces the need to repeat the same declaration code * over and over (plus this helps to avoid typo bugs). */#define E100_PARAM(X, S)                                        \        static const int X[E100_MAX_NIC + 1] = E100_PARAM_INIT; \        MODULE_PARM(X, "1-" __MODULE_STRING(E100_MAX_NIC) "i"); \        MODULE_PARM_DESC(X, S);/* ====================================================================== */static u8 e100_D101M_checksum(struct e100_private *, struct sk_buff *);static u8 e100_D102_check_checksum(rfd_t *);static int e100_ioctl(struct net_device *, struct ifreq *, int);static int e100_open(struct net_device *);static int e100_close(struct net_device *);static int e100_change_mtu(struct net_device *, int);static int e100_xmit_frame(struct sk_buff *, struct net_device *);static unsigned char e100_init(struct e100_private *);static int e100_set_mac(struct net_device *, void *);struct net_device_stats *e100_get_stats(struct net_device *);static void e100intr(int, void *, struct pt_regs *);static void e100_print_brd_conf(struct e100_private *);static void e100_set_multi(struct net_device *);void e100_set_speed_duplex(struct e100_private *);char *e100_get_brand_msg(struct e100_private *);static u8 e100_pci_setup(struct pci_dev *, struct e100_private *);static u8 e100_sw_init(struct e100_private *);static unsigned char e100_alloc_space(struct e100_private *);static void e100_dealloc_space(struct e100_private *);static int e100_alloc_tcb_pool(struct e100_private *);static void e100_setup_tcb_pool(tcb_t *, unsigned int, struct e100_private *);static void e100_free_tcb_pool(struct e100_private *);static int e100_alloc_rfd_pool(struct e100_private *);static void e100_free_rfd_pool(struct e100_private *);static void e100_rd_eaddr(struct e100_private *);static void e100_rd_pwa_no(struct e100_private *);extern u16 e100_eeprom_read(struct e100_private *, u16);extern void e100_eeprom_write_block(struct e100_private *, u16, u16 *, u16);extern u16 e100_eeprom_size(struct e100_private *);u16 e100_eeprom_calculate_chksum(struct e100_private *adapter);static unsigned char e100_clr_cntrs(struct e100_private *);static unsigned char e100_load_microcode(struct e100_private *);static unsigned char e100_hw_init(struct e100_private *, u32);static unsigned char e100_setup_iaaddr(struct e100_private *, u8 *);static unsigned char e100_update_stats(struct e100_private *bdp);static void e100_start_ru(struct e100_private *);static void e100_dump_stats_cntrs(struct e100_private *);static void e100_check_options(int board, struct e100_private *bdp);static void e100_set_int_option(int *, int, int, int, int, char *);static void e100_set_bool_option(struct e100_private *bdp, int, u32, int,				 char *);unsigned char e100_wait_exec_cmplx(struct e100_private *, u32, u8);void e100_exec_cmplx(struct e100_private *, u32, u8);/** * e100_get_rx_struct - retrieve cell to hold skb buff from the pool * @bdp: atapter's private data struct * * Returns the new cell to hold sk_buff or %NULL. */static inline struct rx_list_elem *e100_get_rx_struct(struct e100_private *bdp){	struct rx_list_elem *rx_struct = NULL;	if (!list_empty(&(bdp->rx_struct_pool))) {		rx_struct = list_entry(bdp->rx_struct_pool.next,				       struct rx_list_elem, list_elem);		list_del(&(rx_struct->list_elem));	}	return rx_struct;}/** * e100_alloc_skb - allocate an skb for the adapter * @bdp: atapter's private data struct * * Allocates skb with enough room for rfd, and data, and reserve non-data space. * Returns the new cell with sk_buff or %NULL. */static inline struct rx_list_elem *e100_alloc_skb(struct e100_private *bdp){	struct sk_buff *new_skb;	u32 skb_size = sizeof (rfd_t);	struct rx_list_elem *rx_struct;#ifdef IANS	skb_size += BD_ANS_INFO_SIZE;#endif#ifdef E100_IA64_DMA_FIX	new_skb =		(struct sk_buff *) __dev_alloc_skb(skb_size,						   GFP_ATOMIC | GFP_DMA);	if (new_skb == NULL) {		new_skb = (struct sk_buff *) dev_alloc_skb(skb_size);	}#else	new_skb = (struct sk_buff *) dev_alloc_skb(skb_size);#endif	if (new_skb) {		/* The IP data should be 		   DWORD aligned. since the ethernet header is 14 bytes long, 		   we need to reserve 2 extra bytes so that the TCP/IP headers		   will be DWORD aligned. */		skb_reserve(new_skb, 2);#ifdef IANS		/* we need to allocate extra room for the ans stuff */		bd_ans_os_ReserveSpaceForANS(new_skb);#endif		if ((rx_struct = e100_get_rx_struct(bdp)) == NULL)			goto err;		rx_struct->skb = new_skb;		rx_struct->dma_addr = pci_map_single(bdp->pdev, new_skb->data,						     sizeof (rfd_t),						     PCI_DMA_FROMDEVICE);		if (!rx_struct->dma_addr)			goto err;		skb_reserve(new_skb, bdp->rfd_size);		return rx_struct;	} else {		return NULL;	}err:	dev_kfree_skb_irq(new_skb);	return NULL;}/** * e100_add_skb_to_end - add an skb to the end of our rfd list * @bdp: atapter's private data struct * @rx_struct: rx_list_elem with the new skb * * Adds a newly allocated skb to the end of our rfd list. */inline voide100_add_skb_to_end(struct e100_private *bdp, struct rx_list_elem *rx_struct){	rfd_t *rfdn;		/* The new rfd */	rfd_t *rfd;		/* The old rfd */	struct rx_list_elem *rx_struct_last;	(rx_struct->skb)->dev = bdp->device;	rfdn = RFD_POINTER(rx_struct->skb, bdp);	rfdn->rfd_header.cb_status = 0;	rfdn->rfd_header.cb_cmd = __constant_cpu_to_le16(RFD_EL_BIT);	rfdn->rfd_act_cnt = 0;	rfdn->rfd_sz = __constant_cpu_to_le16(RFD_DATA_SIZE);	pci_dma_sync_single(bdp->pdev, rx_struct->dma_addr, bdp->rfd_size,			    PCI_DMA_TODEVICE);	if (!list_empty(&(bdp->active_rx_list))) {		rx_struct_last = list_entry(bdp->active_rx_list.prev,					    struct rx_list_elem, list_elem);		rfd = RFD_POINTER(rx_struct_last->skb, bdp);		pci_dma_sync_single(bdp->pdev, rx_struct_last->dma_addr,				    4, PCI_DMA_FROMDEVICE);		put_unaligned(cpu_to_le32(rx_struct->dma_addr),			      ((u32 *) (&(rfd->rfd_header.cb_lnk_ptr))));		pci_dma_sync_single(bdp->pdev, rx_struct_last->dma_addr,				    8, PCI_DMA_TODEVICE);		rfd->rfd_header.cb_cmd &=			__constant_cpu_to_le16((u16) ~RFD_EL_BIT);		pci_dma_sync_single(bdp->pdev, rx_struct_last->dma_addr,				    4, PCI_DMA_TODEVICE);	}	list_add_tail(&(rx_struct->list_elem), &(bdp->active_rx_list));}static inline voide100_alloc_skbs(struct e100_private *bdp){	for (; bdp->skb_req > 0; bdp->skb_req--) {		struct rx_list_elem *rx_struct;		if ((rx_struct = e100_alloc_skb(bdp)) == NULL)			return;		e100_add_skb_to_end(bdp, rx_struct);	}}void e100_tx_srv(struct e100_private *);u32 e100_rx_srv(struct e100_private *, u32, int *);#ifdef E100_RX_CONGESTION_CONTROLvoid e100_polling_tasklet(unsigned long);#endifvoid e100_watchdog(struct net_device *);static void e100_do_hwi(struct net_device *);static void e100_hwi_restore(struct e100_private *);void e100_refresh_txthld(struct e100_private *);void e100_manage_adaptive_ifs(struct e100_private *);void e100_clear_pools(struct e100_private *);static void e100_clear_structs(struct net_device *);static inline tcb_t *e100_prepare_xmit_buff(struct e100_private *,					    struct sk_buff *);static void e100_set_multi_exec(struct net_device *dev);MODULE_AUTHOR("Intel Corporation, <linux.nics@intel.com>");MODULE_DESCRIPTION("Intel(R) PRO/100 Network Driver");MODULE_LICENSE("GPL");E100_PARAM(TxDescriptors, "Number of transmit descriptors");E100_PARAM(RxDescriptors, "Number of receive descriptors");E100_PARAM(XsumRX, "Disable or enable Receive Checksum offload");E100_PARAM(e100_speed_duplex, "Speed and Duplex settings");E100_PARAM(ucode, "Disable or enable microcode loading");E100_PARAM(ber, "Value for the BER correction algorithm");E100_PARAM(flow_control, "Disable or enable Ethernet PAUSE frames processing");E100_PARAM(IntDelay, "Value for CPU saver's interrupt delay");E100_PARAM(BundleSmallFr, "Disable or enable interrupt bundling of small frames");E100_PARAM(BundleMax, "Maximum number for CPU saver's packet bundling");E100_PARAM(IFS, "Disable or enable the adaptive IFS algorithm");#ifdef E100_RX_CONGESTION_CONTROLE100_PARAM(RxCongestionControl, "Disable or enable switch to polling mode");E100_PARAM(PollingMaxWork, "Max number of receive packets processed on single "	   "polling call");#endif/** * e100_exec_cmd - issue a comand * @bdp: atapter's private data struct * @scb_cmd_low: the command that is to be issued * * This general routine will issue a command to the e100. */static inline voide100_exec_cmd(struct e100_private *bdp, u8 cmd_low){	writeb(cmd_low, &(bdp->scb->scb_cmd_low));	readw(&(bdp->scb->scb_status));	/* flushes last write, read-safe */}/** * e100_wait_scb - wait for SCB to clear * @bdp: atapter's private data struct * * This routine checks to see if the e100 has accepted a command. * It does so by checking the command field in the SCB, which will * be zeroed by the e100 upon accepting a command.  The loop waits * for up to 1 millisecond for command acceptance. * * Returns: *      true if the SCB cleared within 1 millisecond. *      false if it didn't clear within 1 millisecond */unsigned char

⌨️ 快捷键说明

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