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

📄 ixgb_main.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 4 页
字号:
/*******************************************************************************    Copyright(c) 1999 - 2005 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*******************************************************************************/#include "ixgb.h"/* Change Log * 1.0.96 04/19/05 * - Make needlessly global code static -- bunk@stusta.de * - ethtool cleanup -- shemminger@osdl.org * - Support for MODULE_VERSION -- linville@tuxdriver.com * - add skb_header_cloned check to the tso path -- herbert@apana.org.au * 1.0.88 01/05/05 * - include fix to the condition that determines when to quit NAPI - Robert Olsson * - use netif_poll_{disable/enable} to synchronize between NAPI and i/f up/down * 1.0.84 10/26/04 * - reset buffer_info->dma in Tx resource cleanup logic * 1.0.83 10/12/04 * - sparse cleanup - shemminger@osdl.org * - fix tx resource cleanup logic */char ixgb_driver_name[] = "ixgb";static char ixgb_driver_string[] = "Intel(R) PRO/10GbE Network Driver";#ifndef CONFIG_IXGB_NAPI#define DRIVERNAPI#else#define DRIVERNAPI "-NAPI"#endif#define DRV_VERSION		"1.0.100-k2"DRIVERNAPIchar ixgb_driver_version[] = DRV_VERSION;static char ixgb_copyright[] = "Copyright (c) 1999-2005 Intel Corporation.";/* ixgb_pci_tbl - PCI Device ID Table * * Wildcard entries (PCI_ANY_ID) should come last * Last entry must be all 0s * * { Vendor ID, Device ID, SubVendor ID, SubDevice ID, *   Class, Class Mask, private data (not used) } */static struct pci_device_id ixgb_pci_tbl[] = {	{INTEL_VENDOR_ID, IXGB_DEVICE_ID_82597EX,	 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},	{INTEL_VENDOR_ID, IXGB_DEVICE_ID_82597EX_SR,	 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},	{INTEL_VENDOR_ID, IXGB_DEVICE_ID_82597EX_LR,  	 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},	/* required last entry */	{0,}};MODULE_DEVICE_TABLE(pci, ixgb_pci_tbl);/* Local Function Prototypes */int ixgb_up(struct ixgb_adapter *adapter);void ixgb_down(struct ixgb_adapter *adapter, boolean_t kill_watchdog);void ixgb_reset(struct ixgb_adapter *adapter);int ixgb_setup_tx_resources(struct ixgb_adapter *adapter);int ixgb_setup_rx_resources(struct ixgb_adapter *adapter);void ixgb_free_tx_resources(struct ixgb_adapter *adapter);void ixgb_free_rx_resources(struct ixgb_adapter *adapter);void ixgb_update_stats(struct ixgb_adapter *adapter);static int ixgb_init_module(void);static void ixgb_exit_module(void);static int ixgb_probe(struct pci_dev *pdev, const struct pci_device_id *ent);static void __devexit ixgb_remove(struct pci_dev *pdev);static int ixgb_sw_init(struct ixgb_adapter *adapter);static int ixgb_open(struct net_device *netdev);static int ixgb_close(struct net_device *netdev);static void ixgb_configure_tx(struct ixgb_adapter *adapter);static void ixgb_configure_rx(struct ixgb_adapter *adapter);static void ixgb_setup_rctl(struct ixgb_adapter *adapter);static void ixgb_clean_tx_ring(struct ixgb_adapter *adapter);static void ixgb_clean_rx_ring(struct ixgb_adapter *adapter);static void ixgb_set_multi(struct net_device *netdev);static void ixgb_watchdog(unsigned long data);static int ixgb_xmit_frame(struct sk_buff *skb, struct net_device *netdev);static struct net_device_stats *ixgb_get_stats(struct net_device *netdev);static int ixgb_change_mtu(struct net_device *netdev, int new_mtu);static int ixgb_set_mac(struct net_device *netdev, void *p);static irqreturn_t ixgb_intr(int irq, void *data, struct pt_regs *regs);static boolean_t ixgb_clean_tx_irq(struct ixgb_adapter *adapter);#ifdef CONFIG_IXGB_NAPIstatic int ixgb_clean(struct net_device *netdev, int *budget);static boolean_t ixgb_clean_rx_irq(struct ixgb_adapter *adapter,				   int *work_done, int work_to_do);#elsestatic boolean_t ixgb_clean_rx_irq(struct ixgb_adapter *adapter);#endifstatic void ixgb_alloc_rx_buffers(struct ixgb_adapter *adapter);void ixgb_set_ethtool_ops(struct net_device *netdev);static void ixgb_tx_timeout(struct net_device *dev);static void ixgb_tx_timeout_task(struct net_device *dev);static void ixgb_vlan_rx_register(struct net_device *netdev,				  struct vlan_group *grp);static void ixgb_vlan_rx_add_vid(struct net_device *netdev, uint16_t vid);static void ixgb_vlan_rx_kill_vid(struct net_device *netdev, uint16_t vid);static void ixgb_restore_vlan(struct ixgb_adapter *adapter);#ifdef CONFIG_NET_POLL_CONTROLLER/* for netdump / net console */static void ixgb_netpoll(struct net_device *dev);#endif/* Exported from other modules */extern void ixgb_check_options(struct ixgb_adapter *adapter);static struct pci_driver ixgb_driver = {	.name     = ixgb_driver_name,	.id_table = ixgb_pci_tbl,	.probe    = ixgb_probe,	.remove   = __devexit_p(ixgb_remove),};MODULE_AUTHOR("Intel Corporation, <linux.nics@intel.com>");MODULE_DESCRIPTION("Intel(R) PRO/10GbE Network Driver");MODULE_LICENSE("GPL");MODULE_VERSION(DRV_VERSION);/* some defines for controlling descriptor fetches in h/w */#define RXDCTL_WTHRESH_DEFAULT 16	/* chip writes back at this many or RXT0 */#define RXDCTL_PTHRESH_DEFAULT 0		/* chip considers prefech below						 * this */#define RXDCTL_HTHRESH_DEFAULT 0		/* chip will only prefetch if tail						 * is pushed this many descriptors						 * from head *//** * ixgb_init_module - Driver Registration Routine * * ixgb_init_module is the first routine called when the driver is * loaded. All it does is register with the PCI subsystem. **/static int __initixgb_init_module(void){	printk(KERN_INFO "%s - version %s\n",	       ixgb_driver_string, ixgb_driver_version);	printk(KERN_INFO "%s\n", ixgb_copyright);	return pci_module_init(&ixgb_driver);}module_init(ixgb_init_module);/** * ixgb_exit_module - Driver Exit Cleanup Routine * * ixgb_exit_module is called just before the driver is removed * from memory. **/static void __exitixgb_exit_module(void){	pci_unregister_driver(&ixgb_driver);}module_exit(ixgb_exit_module);/** * ixgb_irq_disable - Mask off interrupt generation on the NIC * @adapter: board private structure **/static inline voidixgb_irq_disable(struct ixgb_adapter *adapter){	atomic_inc(&adapter->irq_sem);	IXGB_WRITE_REG(&adapter->hw, IMC, ~0);	IXGB_WRITE_FLUSH(&adapter->hw);	synchronize_irq(adapter->pdev->irq);}/** * ixgb_irq_enable - Enable default interrupt generation settings * @adapter: board private structure **/static inline voidixgb_irq_enable(struct ixgb_adapter *adapter){	if(atomic_dec_and_test(&adapter->irq_sem)) {		IXGB_WRITE_REG(&adapter->hw, IMS,			       IXGB_INT_RXT0 | IXGB_INT_RXDMT0 | IXGB_INT_TXDW |			       IXGB_INT_LSC);		IXGB_WRITE_FLUSH(&adapter->hw);	}}intixgb_up(struct ixgb_adapter *adapter){	struct net_device *netdev = adapter->netdev;	int err;	int max_frame = netdev->mtu + ENET_HEADER_SIZE + ENET_FCS_LENGTH;	struct ixgb_hw *hw = &adapter->hw;	/* hardware has been reset, we need to reload some things */	ixgb_set_multi(netdev);	ixgb_restore_vlan(adapter);	ixgb_configure_tx(adapter);	ixgb_setup_rctl(adapter);	ixgb_configure_rx(adapter);	ixgb_alloc_rx_buffers(adapter);#ifdef CONFIG_PCI_MSI	{	boolean_t pcix = (IXGB_READ_REG(&adapter->hw, STATUS) & 						  IXGB_STATUS_PCIX_MODE) ? TRUE : FALSE;	adapter->have_msi = TRUE;	if (!pcix)	   adapter->have_msi = FALSE;	else if((err = pci_enable_msi(adapter->pdev))) {		printk (KERN_ERR		 "Unable to allocate MSI interrupt Error: %d\n", err);		adapter->have_msi = FALSE;		/* proceed to try to request regular interrupt */	}	}#endif	if((err = request_irq(adapter->pdev->irq, &ixgb_intr,				  SA_SHIRQ | SA_SAMPLE_RANDOM,				  netdev->name, netdev)))		return err;	/* disable interrupts and get the hardware into a known state */	IXGB_WRITE_REG(&adapter->hw, IMC, 0xffffffff);	if((hw->max_frame_size != max_frame) ||		(hw->max_frame_size !=		(IXGB_READ_REG(hw, MFS) >> IXGB_MFS_SHIFT))) {		hw->max_frame_size = max_frame;		IXGB_WRITE_REG(hw, MFS, hw->max_frame_size << IXGB_MFS_SHIFT);		if(hw->max_frame_size >		   IXGB_MAX_ENET_FRAME_SIZE_WITHOUT_FCS + ENET_FCS_LENGTH) {			uint32_t ctrl0 = IXGB_READ_REG(hw, CTRL0);			if(!(ctrl0 & IXGB_CTRL0_JFE)) {				ctrl0 |= IXGB_CTRL0_JFE;				IXGB_WRITE_REG(hw, CTRL0, ctrl0);			}		}	}	mod_timer(&adapter->watchdog_timer, jiffies);	ixgb_irq_enable(adapter);#ifdef CONFIG_IXGB_NAPI	netif_poll_enable(netdev);#endif	return 0;}voidixgb_down(struct ixgb_adapter *adapter, boolean_t kill_watchdog){	struct net_device *netdev = adapter->netdev;	ixgb_irq_disable(adapter);	free_irq(adapter->pdev->irq, netdev);#ifdef CONFIG_PCI_MSI	if(adapter->have_msi == TRUE)		pci_disable_msi(adapter->pdev);#endif	if(kill_watchdog)		del_timer_sync(&adapter->watchdog_timer);#ifdef CONFIG_IXGB_NAPI	netif_poll_disable(netdev);#endif	adapter->link_speed = 0;	adapter->link_duplex = 0;	netif_carrier_off(netdev);	netif_stop_queue(netdev);	ixgb_reset(adapter);	ixgb_clean_tx_ring(adapter);	ixgb_clean_rx_ring(adapter);}voidixgb_reset(struct ixgb_adapter *adapter){	ixgb_adapter_stop(&adapter->hw);	if(!ixgb_init_hw(&adapter->hw))		IXGB_DBG("ixgb_init_hw failed.\n");}/** * ixgb_probe - Device Initialization Routine * @pdev: PCI device information struct * @ent: entry in ixgb_pci_tbl * * Returns 0 on success, negative on failure * * ixgb_probe initializes an adapter identified by a pci_dev structure. * The OS initialization, configuring of the adapter private structure, * and a hardware reset occur. **/static int __devinitixgb_probe(struct pci_dev *pdev,		const struct pci_device_id *ent){	struct net_device *netdev = NULL;	struct ixgb_adapter *adapter;	static int cards_found = 0;	unsigned long mmio_start;	int mmio_len;	int pci_using_dac;	int i;	int err;	if((err = pci_enable_device(pdev)))		return err;	if(!(err = pci_set_dma_mask(pdev, DMA_64BIT_MASK))) {		pci_using_dac = 1;	} else {		if((err = pci_set_dma_mask(pdev, DMA_32BIT_MASK))) {			IXGB_ERR("No usable DMA configuration, aborting\n");			return err;		}		pci_using_dac = 0;	}	if((err = pci_request_regions(pdev, ixgb_driver_name)))		return err;	pci_set_master(pdev);	netdev = alloc_etherdev(sizeof(struct ixgb_adapter));	if(!netdev) {		err = -ENOMEM;		goto err_alloc_etherdev;	}	SET_MODULE_OWNER(netdev);	SET_NETDEV_DEV(netdev, &pdev->dev);	pci_set_drvdata(pdev, netdev);	adapter = netdev_priv(netdev);	adapter->netdev = netdev;	adapter->pdev = pdev;	adapter->hw.back = adapter;	mmio_start = pci_resource_start(pdev, BAR_0);	mmio_len = pci_resource_len(pdev, BAR_0);	adapter->hw.hw_addr = ioremap(mmio_start, mmio_len);	if(!adapter->hw.hw_addr) {		err = -EIO;		goto err_ioremap;	}	for(i = BAR_1; i <= BAR_5; i++) {		if(pci_resource_len(pdev, i) == 0)			continue;		if(pci_resource_flags(pdev, i) & IORESOURCE_IO) {			adapter->hw.io_base = pci_resource_start(pdev, i);			break;		}	}	netdev->open = &ixgb_open;	netdev->stop = &ixgb_close;	netdev->hard_start_xmit = &ixgb_xmit_frame;	netdev->get_stats = &ixgb_get_stats;	netdev->set_multicast_list = &ixgb_set_multi;	netdev->set_mac_address = &ixgb_set_mac;	netdev->change_mtu = &ixgb_change_mtu;	ixgb_set_ethtool_ops(netdev);	netdev->tx_timeout = &ixgb_tx_timeout;	netdev->watchdog_timeo = HZ;#ifdef CONFIG_IXGB_NAPI	netdev->poll = &ixgb_clean;	netdev->weight = 64;#endif	netdev->vlan_rx_register = ixgb_vlan_rx_register;	netdev->vlan_rx_add_vid = ixgb_vlan_rx_add_vid;	netdev->vlan_rx_kill_vid = ixgb_vlan_rx_kill_vid;#ifdef CONFIG_NET_POLL_CONTROLLER	netdev->poll_controller = ixgb_netpoll;#endif	netdev->mem_start = mmio_start;	netdev->mem_end = mmio_start + mmio_len;	netdev->base_addr = adapter->hw.io_base;	adapter->bd_number = cards_found;	adapter->link_speed = 0;	adapter->link_duplex = 0;	/* setup the private structure */	if((err = ixgb_sw_init(adapter)))		goto err_sw_init;	netdev->features = NETIF_F_SG |			   NETIF_F_HW_CSUM |			   NETIF_F_HW_VLAN_TX |			   NETIF_F_HW_VLAN_RX |			   NETIF_F_HW_VLAN_FILTER;#ifdef NETIF_F_TSO	netdev->features |= NETIF_F_TSO;#endif	if(pci_using_dac)		netdev->features |= NETIF_F_HIGHDMA;	/* make sure the EEPROM is good */	if(!ixgb_validate_eeprom_checksum(&adapter->hw)) {		printk(KERN_ERR "The EEPROM Checksum Is Not Valid\n");		err = -EIO;		goto err_eeprom;	}	ixgb_get_ee_mac_addr(&adapter->hw, netdev->dev_addr);	memcpy(netdev->perm_addr, netdev->dev_addr, netdev->addr_len);	if(!is_valid_ether_addr(netdev->perm_addr)) {		err = -EIO;		goto err_eeprom;	}	adapter->part_num = ixgb_get_ee_pba_number(&adapter->hw);	init_timer(&adapter->watchdog_timer);	adapter->watchdog_timer.function = &ixgb_watchdog;	adapter->watchdog_timer.data = (unsigned long)adapter;	INIT_WORK(&adapter->tx_timeout_task,		  (void (*)(void *))ixgb_tx_timeout_task, netdev);	if((err = register_netdev(netdev)))		goto err_register;	/* we're going to reset, so assume we have no link for now */	netif_carrier_off(netdev);	netif_stop_queue(netdev);	printk(KERN_INFO "%s: Intel(R) PRO/10GbE Network Connection\n",		   netdev->name);	ixgb_check_options(adapter);	/* reset the hardware with the new settings */	ixgb_reset(adapter);	cards_found++;	return 0;err_register:err_sw_init:err_eeprom:	iounmap(adapter->hw.hw_addr);err_ioremap:	free_netdev(netdev);err_alloc_etherdev:	pci_release_regions(pdev);	return err;}/** * ixgb_remove - Device Removal Routine * @pdev: PCI device information struct * * ixgb_remove is called by the PCI subsystem to alert the driver * that it should release a PCI device.  The could be caused by a * Hot-Plug event, or because the driver is going to be removed from * memory. **/static void __devexitixgb_remove(struct pci_dev *pdev){	struct net_device *netdev = pci_get_drvdata(pdev);	struct ixgb_adapter *adapter = netdev_priv(netdev);	unregister_netdev(netdev);	iounmap(adapter->hw.hw_addr);	pci_release_regions(pdev);	free_netdev(netdev);}/** * ixgb_sw_init - Initialize general software structures (struct ixgb_adapter)

⌨️ 快捷键说明

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