Skip to content
Snippets Groups Projects
igb_main.c 205 KiB
Newer Older
  • Learn to ignore specific revisions
  • /*******************************************************************************
    
      Intel(R) Gigabit Ethernet Linux driver
    
      Copyright(c) 2007-2012 Intel Corporation.
    
    
      This program is free software; you can redistribute it and/or modify it
      under the terms and conditions of the GNU General Public License,
      version 2, as published by the Free Software Foundation.
    
      This program is distributed in the hope 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.,
      51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
    
      The full GNU General Public License is included in this distribution in
      the file called "COPYING".
    
      Contact Information:
      e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
      Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
    
    *******************************************************************************/
    
    
    #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
    
    
    #include <linux/module.h>
    #include <linux/types.h>
    #include <linux/init.h>
    
    Jiri Pirko's avatar
    Jiri Pirko committed
    #include <linux/bitops.h>
    
    #include <linux/vmalloc.h>
    #include <linux/pagemap.h>
    #include <linux/netdevice.h>
    #include <linux/ipv6.h>
    
    #include <net/checksum.h>
    #include <net/ip6_checksum.h>
    
    #include <linux/net_tstamp.h>
    
    #include <linux/mii.h>
    #include <linux/ethtool.h>
    
    #include <linux/if.h>
    
    #include <linux/if_vlan.h>
    #include <linux/pci.h>
    
    #include <linux/pci-aspm.h>
    
    #include <linux/delay.h>
    #include <linux/interrupt.h>
    
    #include <linux/ip.h>
    #include <linux/tcp.h>
    #include <linux/sctp.h>
    
    #include <linux/if_ether.h>
    
    #include <linux/aer.h>
    
    #include <linux/prefetch.h>
    
    #include <linux/pm_runtime.h>
    
    #ifdef CONFIG_IGB_DCA
    
    Jeb Cramer's avatar
    Jeb Cramer committed
    #include <linux/dca.h>
    #endif
    
    #include <linux/i2c.h>
    
    Carolyn Wyborny's avatar
    Carolyn Wyborny committed
    #define MAJ 4
    
    #define MIN 1
    #define BUILD 2
    
    #define DRV_VERSION __stringify(MAJ) "." __stringify(MIN) "." \
    
    char igb_driver_name[] = "igb";
    char igb_driver_version[] = DRV_VERSION;
    static const char igb_driver_string[] =
    				"Intel(R) Gigabit Ethernet Network Driver";
    
    static const char igb_copyright[] = "Copyright (c) 2007-2012 Intel Corporation.";
    
    
    static const struct e1000_info *igb_info_tbl[] = {
    	[board_82575] = &e1000_82575_info,
    };
    
    
    static DEFINE_PCI_DEVICE_TABLE(igb_pci_tbl) = {
    
    	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_I211_COPPER), board_82575 },
    	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_I210_COPPER), board_82575 },
    	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_I210_FIBER), board_82575 },
    	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_I210_SERDES), board_82575 },
    	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_I210_SGMII), board_82575 },
    
    	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_I350_COPPER), board_82575 },
    	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_I350_FIBER), board_82575 },
    	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_I350_SERDES), board_82575 },
    	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_I350_SGMII), board_82575 },
    
    	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82580_COPPER), board_82575 },
    	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82580_FIBER), board_82575 },
    
    	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82580_QUAD_FIBER), board_82575 },
    
    	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82580_SERDES), board_82575 },
    	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82580_SGMII), board_82575 },
    	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82580_COPPER_DUAL), board_82575 },
    
    	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_DH89XXCC_SGMII), board_82575 },
    	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_DH89XXCC_SERDES), board_82575 },
    
    	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_DH89XXCC_BACKPLANE), board_82575 },
    	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_DH89XXCC_SFP), board_82575 },
    
    	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82576), board_82575 },
    
    	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82576_NS), board_82575 },
    
    	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82576_NS_SERDES), board_82575 },
    
    	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82576_FIBER), board_82575 },
    	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82576_SERDES), board_82575 },
    
    	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82576_SERDES_QUAD), board_82575 },
    
    	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82576_QUAD_COPPER_ET2), board_82575 },
    
    	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82576_QUAD_COPPER), board_82575 },
    
    	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82575EB_COPPER), board_82575 },
    	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82575EB_FIBER_SERDES), board_82575 },
    	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82575GB_QUAD_COPPER), board_82575 },
    	/* required last entry */
    	{0, }
    };
    
    MODULE_DEVICE_TABLE(pci, igb_pci_tbl);
    
    void igb_reset(struct igb_adapter *);
    static int igb_setup_all_tx_resources(struct igb_adapter *);
    static int igb_setup_all_rx_resources(struct igb_adapter *);
    static void igb_free_all_tx_resources(struct igb_adapter *);
    static void igb_free_all_rx_resources(struct igb_adapter *);
    
    static void igb_setup_mrqc(struct igb_adapter *);
    
    static int igb_probe(struct pci_dev *, const struct pci_device_id *);
    
    static void igb_remove(struct pci_dev *pdev);
    
    static int igb_sw_init(struct igb_adapter *);
    static int igb_open(struct net_device *);
    static int igb_close(struct net_device *);
    
    static void igb_configure(struct igb_adapter *);
    
    static void igb_configure_tx(struct igb_adapter *);
    static void igb_configure_rx(struct igb_adapter *);
    static void igb_clean_all_tx_rings(struct igb_adapter *);
    static void igb_clean_all_rx_rings(struct igb_adapter *);
    
    static void igb_clean_tx_ring(struct igb_ring *);
    static void igb_clean_rx_ring(struct igb_ring *);
    
    static void igb_set_rx_mode(struct net_device *);
    
    static void igb_update_phy_info(unsigned long);
    static void igb_watchdog(unsigned long);
    static void igb_watchdog_task(struct work_struct *);
    
    static netdev_tx_t igb_xmit_frame(struct sk_buff *skb, struct net_device *);
    
    Eric Dumazet's avatar
    Eric Dumazet committed
    static struct rtnl_link_stats64 *igb_get_stats64(struct net_device *dev,
    						 struct rtnl_link_stats64 *stats);
    
    static int igb_change_mtu(struct net_device *, int);
    static int igb_set_mac(struct net_device *, void *);
    
    static void igb_set_uta(struct igb_adapter *adapter);
    
    static irqreturn_t igb_intr(int irq, void *);
    static irqreturn_t igb_intr_msi(int irq, void *);
    static irqreturn_t igb_msix_other(int irq, void *);
    
    static irqreturn_t igb_msix_ring(int irq, void *);
    
    #ifdef CONFIG_IGB_DCA
    
    static void igb_update_dca(struct igb_q_vector *);
    
    Jeb Cramer's avatar
    Jeb Cramer committed
    static void igb_setup_dca(struct igb_adapter *);
    
    #endif /* CONFIG_IGB_DCA */
    
    static int igb_poll(struct napi_struct *, int);
    
    static bool igb_clean_tx_irq(struct igb_q_vector *);
    
    static bool igb_clean_rx_irq(struct igb_q_vector *, int);
    
    static int igb_ioctl(struct net_device *, struct ifreq *, int cmd);
    static void igb_tx_timeout(struct net_device *);
    static void igb_reset_task(struct work_struct *);
    
    static void igb_vlan_mode(struct net_device *netdev, netdev_features_t features);
    
    static int igb_vlan_rx_add_vid(struct net_device *, u16);
    static int igb_vlan_rx_kill_vid(struct net_device *, u16);
    
    static void igb_restore_vlan(struct igb_adapter *);
    
    static void igb_rar_set_qsel(struct igb_adapter *, u8 *, u32 , u8);
    
    static void igb_ping_all_vfs(struct igb_adapter *);
    static void igb_msg_task(struct igb_adapter *);
    static void igb_vmm_control(struct igb_adapter *);
    
    static int igb_set_vf_mac(struct igb_adapter *, int, unsigned char *);
    
    static void igb_restore_vf_multicasts(struct igb_adapter *adapter);
    
    static int igb_ndo_set_vf_mac(struct net_device *netdev, int vf, u8 *mac);
    static int igb_ndo_set_vf_vlan(struct net_device *netdev,
    			       int vf, u16 vlan, u8 qos);
    static int igb_ndo_set_vf_bw(struct net_device *netdev, int vf, int tx_rate);
    static int igb_ndo_get_vf_config(struct net_device *netdev, int vf,
    				 struct ifla_vf_info *ivi);
    
    static void igb_check_vf_rate_limit(struct igb_adapter *);
    
    RongQing Li's avatar
    RongQing Li committed
    
    #ifdef CONFIG_PCI_IOV
    
    static int igb_vf_configure(struct igb_adapter *adapter, int vf);
    
    static bool igb_vfs_are_assigned(struct igb_adapter *adapter);
    
    RongQing Li's avatar
    RongQing Li committed
    #endif
    
    #ifdef CONFIG_PM_SLEEP
    
    static int igb_suspend(struct device *);
    
    static int igb_resume(struct device *);
    #ifdef CONFIG_PM_RUNTIME
    static int igb_runtime_suspend(struct device *dev);
    static int igb_runtime_resume(struct device *dev);
    static int igb_runtime_idle(struct device *dev);
    #endif
    static const struct dev_pm_ops igb_pm_ops = {
    	SET_SYSTEM_SLEEP_PM_OPS(igb_suspend, igb_resume)
    	SET_RUNTIME_PM_OPS(igb_runtime_suspend, igb_runtime_resume,
    			igb_runtime_idle)
    };
    
    #endif
    static void igb_shutdown(struct pci_dev *);
    
    static int igb_pci_sriov_configure(struct pci_dev *dev, int num_vfs);
    
    #ifdef CONFIG_IGB_DCA
    
    Jeb Cramer's avatar
    Jeb Cramer committed
    static int igb_notify_dca(struct notifier_block *, unsigned long, void *);
    static struct notifier_block dca_notifier = {
    	.notifier_call	= igb_notify_dca,
    	.next		= NULL,
    	.priority	= 0
    };
    #endif
    
    #ifdef CONFIG_NET_POLL_CONTROLLER
    /* for netdump / net console */
    static void igb_netpoll(struct net_device *);
    #endif
    
    static unsigned int max_vfs = 0;
    module_param(max_vfs, uint, 0);
    MODULE_PARM_DESC(max_vfs, "Maximum number of virtual functions to allocate "
                     "per physical function");
    #endif /* CONFIG_PCI_IOV */
    
    
    static pci_ers_result_t igb_io_error_detected(struct pci_dev *,
    		     pci_channel_state_t);
    static pci_ers_result_t igb_io_slot_reset(struct pci_dev *);
    static void igb_io_resume(struct pci_dev *);
    
    
    static const struct pci_error_handlers igb_err_handler = {
    
    	.error_detected = igb_io_error_detected,
    	.slot_reset = igb_io_slot_reset,
    	.resume = igb_io_resume,
    };
    
    
    static void igb_init_dmac(struct igb_adapter *adapter, u32 pba);
    
    
    static struct pci_driver igb_driver = {
    	.name     = igb_driver_name,
    	.id_table = igb_pci_tbl,
    	.probe    = igb_probe,
    
    	.remove   = igb_remove,
    
    #ifdef CONFIG_PM
    
    	.driver.pm = &igb_pm_ops,
    
    #endif
    	.shutdown = igb_shutdown,
    
    	.sriov_configure = igb_pci_sriov_configure,
    
    	.err_handler = &igb_err_handler
    };
    
    MODULE_AUTHOR("Intel Corporation, <e1000-devel@lists.sourceforge.net>");
    MODULE_DESCRIPTION("Intel(R) Gigabit Ethernet Network Driver");
    MODULE_LICENSE("GPL");
    MODULE_VERSION(DRV_VERSION);
    
    
    #define DEFAULT_MSG_ENABLE (NETIF_MSG_DRV|NETIF_MSG_PROBE|NETIF_MSG_LINK)
    static int debug = -1;
    module_param(debug, int, 0);
    MODULE_PARM_DESC(debug, "Debug level (0=none,...,16=all)");
    
    
    struct igb_reg_info {
    	u32 ofs;
    	char *name;
    };
    
    static const struct igb_reg_info igb_reg_info_tbl[] = {
    
    	/* General Registers */
    	{E1000_CTRL, "CTRL"},
    	{E1000_STATUS, "STATUS"},
    	{E1000_CTRL_EXT, "CTRL_EXT"},
    
    	/* Interrupt Registers */
    	{E1000_ICR, "ICR"},
    
    	/* RX Registers */
    	{E1000_RCTL, "RCTL"},
    	{E1000_RDLEN(0), "RDLEN"},
    	{E1000_RDH(0), "RDH"},
    	{E1000_RDT(0), "RDT"},
    	{E1000_RXDCTL(0), "RXDCTL"},
    	{E1000_RDBAL(0), "RDBAL"},
    	{E1000_RDBAH(0), "RDBAH"},
    
    	/* TX Registers */
    	{E1000_TCTL, "TCTL"},
    	{E1000_TDBAL(0), "TDBAL"},
    	{E1000_TDBAH(0), "TDBAH"},
    	{E1000_TDLEN(0), "TDLEN"},
    	{E1000_TDH(0), "TDH"},
    	{E1000_TDT(0), "TDT"},
    	{E1000_TXDCTL(0), "TXDCTL"},
    	{E1000_TDFH, "TDFH"},
    	{E1000_TDFT, "TDFT"},
    	{E1000_TDFHS, "TDFHS"},
    	{E1000_TDFPC, "TDFPC"},
    
    	/* List Terminator */
    	{}
    };
    
    /*
     * igb_regdump - register printout routine
     */
    static void igb_regdump(struct e1000_hw *hw, struct igb_reg_info *reginfo)
    {
    	int n = 0;
    	char rname[16];
    	u32 regs[8];
    
    	switch (reginfo->ofs) {
    	case E1000_RDLEN(0):
    		for (n = 0; n < 4; n++)
    			regs[n] = rd32(E1000_RDLEN(n));
    		break;
    	case E1000_RDH(0):
    		for (n = 0; n < 4; n++)
    			regs[n] = rd32(E1000_RDH(n));
    		break;
    	case E1000_RDT(0):
    		for (n = 0; n < 4; n++)
    			regs[n] = rd32(E1000_RDT(n));
    		break;
    	case E1000_RXDCTL(0):
    		for (n = 0; n < 4; n++)
    			regs[n] = rd32(E1000_RXDCTL(n));
    		break;
    	case E1000_RDBAL(0):
    		for (n = 0; n < 4; n++)
    			regs[n] = rd32(E1000_RDBAL(n));
    		break;
    	case E1000_RDBAH(0):
    		for (n = 0; n < 4; n++)
    			regs[n] = rd32(E1000_RDBAH(n));
    		break;
    	case E1000_TDBAL(0):
    		for (n = 0; n < 4; n++)
    			regs[n] = rd32(E1000_RDBAL(n));
    		break;
    	case E1000_TDBAH(0):
    		for (n = 0; n < 4; n++)
    			regs[n] = rd32(E1000_TDBAH(n));
    		break;
    	case E1000_TDLEN(0):
    		for (n = 0; n < 4; n++)
    			regs[n] = rd32(E1000_TDLEN(n));
    		break;
    	case E1000_TDH(0):
    		for (n = 0; n < 4; n++)
    			regs[n] = rd32(E1000_TDH(n));
    		break;
    	case E1000_TDT(0):
    		for (n = 0; n < 4; n++)
    			regs[n] = rd32(E1000_TDT(n));
    		break;
    	case E1000_TXDCTL(0):
    		for (n = 0; n < 4; n++)
    			regs[n] = rd32(E1000_TXDCTL(n));
    		break;
    	default:
    
    		pr_info("%-15s %08x\n", reginfo->name, rd32(reginfo->ofs));
    
    		return;
    	}
    
    	snprintf(rname, 16, "%s%s", reginfo->name, "[0-3]");
    
    	pr_info("%-15s %08x %08x %08x %08x\n", rname, regs[0], regs[1],
    		regs[2], regs[3]);
    
    }
    
    /*
     * igb_dump - Print registers, tx-rings and rx-rings
     */
    static void igb_dump(struct igb_adapter *adapter)
    {
    	struct net_device *netdev = adapter->netdev;
    	struct e1000_hw *hw = &adapter->hw;
    	struct igb_reg_info *reginfo;
    	struct igb_ring *tx_ring;
    	union e1000_adv_tx_desc *tx_desc;
    	struct my_u0 { u64 a; u64 b; } *u0;
    	struct igb_ring *rx_ring;
    	union e1000_adv_rx_desc *rx_desc;
    	u32 staterr;
    
    
    	if (!netif_msg_hw(adapter))
    		return;
    
    	/* Print netdevice Info */
    	if (netdev) {
    		dev_info(&adapter->pdev->dev, "Net device Info\n");
    
    		pr_info("Device Name     state            trans_start      "
    			"last_rx\n");
    		pr_info("%-15s %016lX %016lX %016lX\n", netdev->name,
    			netdev->state, netdev->trans_start, netdev->last_rx);
    
    	}
    
    	/* Print Registers */
    	dev_info(&adapter->pdev->dev, "Register Dump\n");
    
    	pr_info(" Register Name   Value\n");
    
    	for (reginfo = (struct igb_reg_info *)igb_reg_info_tbl;
    	     reginfo->name; reginfo++) {
    		igb_regdump(hw, reginfo);
    	}
    
    	/* Print TX Ring Summary */
    	if (!netdev || !netif_running(netdev))
    		goto exit;
    
    	dev_info(&adapter->pdev->dev, "TX Rings Summary\n");
    
    	pr_info("Queue [NTU] [NTC] [bi(ntc)->dma  ] leng ntw timestamp\n");
    
    	for (n = 0; n < adapter->num_tx_queues; n++) {
    
    		struct igb_tx_buffer *buffer_info;
    
    		tx_ring = adapter->tx_ring[n];
    
    		buffer_info = &tx_ring->tx_buffer_info[tx_ring->next_to_clean];
    
    		pr_info(" %5d %5X %5X %016llX %04X %p %016llX\n",
    			n, tx_ring->next_to_use, tx_ring->next_to_clean,
    
    			(u64)dma_unmap_addr(buffer_info, dma),
    			dma_unmap_len(buffer_info, len),
    
    			buffer_info->next_to_watch,
    			(u64)buffer_info->time_stamp);
    
    	}
    
    	/* Print TX Rings */
    	if (!netif_msg_tx_done(adapter))
    		goto rx_ring_summary;
    
    	dev_info(&adapter->pdev->dev, "TX Rings Dump\n");
    
    	/* Transmit Descriptor Formats
    	 *
    	 * Advanced Transmit Descriptor
    	 *   +--------------------------------------------------------------+
    	 * 0 |         Buffer Address [63:0]                                |
    	 *   +--------------------------------------------------------------+
    	 * 8 | PAYLEN  | PORTS  |CC|IDX | STA | DCMD  |DTYP|MAC|RSV| DTALEN |
    	 *   +--------------------------------------------------------------+
    	 *   63      46 45    40 39 38 36 35 32 31   24             15       0
    	 */
    
    	for (n = 0; n < adapter->num_tx_queues; n++) {
    		tx_ring = adapter->tx_ring[n];
    
    		pr_info("------------------------------------\n");
    		pr_info("TX QUEUE INDEX = %d\n", tx_ring->queue_index);
    		pr_info("------------------------------------\n");
    		pr_info("T [desc]     [address 63:0  ] [PlPOCIStDDM Ln] "
    			"[bi->dma       ] leng  ntw timestamp        "
    			"bi->skb\n");
    
    
    		for (i = 0; tx_ring->desc && (i < tx_ring->count); i++) {
    
    			const char *next_desc;
    
    			struct igb_tx_buffer *buffer_info;
    
    			tx_desc = IGB_TX_DESC(tx_ring, i);
    
    			buffer_info = &tx_ring->tx_buffer_info[i];
    
    			if (i == tx_ring->next_to_use &&
    			    i == tx_ring->next_to_clean)
    				next_desc = " NTC/U";
    			else if (i == tx_ring->next_to_use)
    				next_desc = " NTU";
    			else if (i == tx_ring->next_to_clean)
    				next_desc = " NTC";
    			else
    				next_desc = "";
    
    			pr_info("T [0x%03X]    %016llX %016llX %016llX"
    				" %04X  %p %016llX %p%s\n", i,
    
    				le64_to_cpu(u0->a),
    				le64_to_cpu(u0->b),
    
    				(u64)dma_unmap_addr(buffer_info, dma),
    				dma_unmap_len(buffer_info, len),
    
    				buffer_info->next_to_watch,
    				(u64)buffer_info->time_stamp,
    
    				buffer_info->skb, next_desc);
    
    			if (netif_msg_pktdata(adapter) && buffer_info->skb)
    
    				print_hex_dump(KERN_INFO, "",
    					DUMP_PREFIX_ADDRESS,
    
    					16, 1, buffer_info->skb->data,
    
    					dma_unmap_len(buffer_info, len),
    					true);
    
    		}
    	}
    
    	/* Print RX Rings Summary */
    rx_ring_summary:
    	dev_info(&adapter->pdev->dev, "RX Rings Summary\n");
    
    	pr_info("Queue [NTU] [NTC]\n");
    
    	for (n = 0; n < adapter->num_rx_queues; n++) {
    		rx_ring = adapter->rx_ring[n];
    
    		pr_info(" %5d %5X %5X\n",
    			n, rx_ring->next_to_use, rx_ring->next_to_clean);
    
    	}
    
    	/* Print RX Rings */
    	if (!netif_msg_rx_status(adapter))
    		goto exit;
    
    	dev_info(&adapter->pdev->dev, "RX Rings Dump\n");
    
    	/* Advanced Receive Descriptor (Read) Format
    	 *    63                                           1        0
    	 *    +-----------------------------------------------------+
    	 *  0 |       Packet Buffer Address [63:1]           |A0/NSE|
    	 *    +----------------------------------------------+------+
    	 *  8 |       Header Buffer Address [63:1]           |  DD  |
    	 *    +-----------------------------------------------------+
    	 *
    	 *
    	 * Advanced Receive Descriptor (Write-Back) Format
    	 *
    	 *   63       48 47    32 31  30      21 20 17 16   4 3     0
    	 *   +------------------------------------------------------+
    	 * 0 | Packet     IP     |SPH| HDR_LEN   | RSV|Packet|  RSS |
    	 *   | Checksum   Ident  |   |           |    | Type | Type |
    	 *   +------------------------------------------------------+
    	 * 8 | VLAN Tag | Length | Extended Error | Extended Status |
    	 *   +------------------------------------------------------+
    	 *   63       48 47    32 31            20 19               0
    	 */
    
    	for (n = 0; n < adapter->num_rx_queues; n++) {
    		rx_ring = adapter->rx_ring[n];
    
    		pr_info("------------------------------------\n");
    		pr_info("RX QUEUE INDEX = %d\n", rx_ring->queue_index);
    		pr_info("------------------------------------\n");
    		pr_info("R  [desc]      [ PktBuf     A0] [  HeadBuf   DD] "
    			"[bi->dma       ] [bi->skb] <-- Adv Rx Read format\n");
    		pr_info("RWB[desc]      [PcsmIpSHl PtRs] [vl er S cks ln] -----"
    			"----------- [bi->skb] <-- Adv Rx Write-Back format\n");
    
    
    		for (i = 0; i < rx_ring->count; i++) {
    
    			const char *next_desc;
    
    			struct igb_rx_buffer *buffer_info;
    			buffer_info = &rx_ring->rx_buffer_info[i];
    
    			rx_desc = IGB_RX_DESC(rx_ring, i);
    
    			u0 = (struct my_u0 *)rx_desc;
    			staterr = le32_to_cpu(rx_desc->wb.upper.status_error);
    
    
    			if (i == rx_ring->next_to_use)
    				next_desc = " NTU";
    			else if (i == rx_ring->next_to_clean)
    				next_desc = " NTC";
    			else
    				next_desc = "";
    
    
    			if (staterr & E1000_RXD_STAT_DD) {
    				/* Descriptor Done */
    
    				pr_info("%s[0x%03X]     %016llX %016llX ---------------- %s\n",
    					"RWB", i,
    
    					le64_to_cpu(u0->a),
    					le64_to_cpu(u0->b),
    
    				pr_info("%s[0x%03X]     %016llX %016llX %016llX %s\n",
    					"R  ", i,
    
    					le64_to_cpu(u0->a),
    					le64_to_cpu(u0->b),
    					(u64)buffer_info->dma,
    
    				if (netif_msg_pktdata(adapter) &&
    
    				    buffer_info->dma && buffer_info->page) {
    
    					print_hex_dump(KERN_INFO, "",
    					  DUMP_PREFIX_ADDRESS,
    					  16, 1,
    
    					  page_address(buffer_info->page) +
    						      buffer_info->page_offset,
    
    /*  igb_get_i2c_data - Reads the I2C SDA data bit
     *  @hw: pointer to hardware structure
     *  @i2cctl: Current value of I2CCTL register
     *
     *  Returns the I2C data bit value
     */
    static int igb_get_i2c_data(void *data)
    {
    	struct igb_adapter *adapter = (struct igb_adapter *)data;
    	struct e1000_hw *hw = &adapter->hw;
    	s32 i2cctl = rd32(E1000_I2CPARAMS);
    
    	return ((i2cctl & E1000_I2C_DATA_IN) != 0);
    }
    
    /* igb_set_i2c_data - Sets the I2C data bit
     *  @data: pointer to hardware structure
     *  @state: I2C data value (0 or 1) to set
     *
     *  Sets the I2C data bit
     */
    static void igb_set_i2c_data(void *data, int state)
    {
    	struct igb_adapter *adapter = (struct igb_adapter *)data;
    	struct e1000_hw *hw = &adapter->hw;
    	s32 i2cctl = rd32(E1000_I2CPARAMS);
    
    	if (state)
    		i2cctl |= E1000_I2C_DATA_OUT;
    	else
    		i2cctl &= ~E1000_I2C_DATA_OUT;
    
    	i2cctl &= ~E1000_I2C_DATA_OE_N;
    	i2cctl |= E1000_I2C_CLK_OE_N;
    	wr32(E1000_I2CPARAMS, i2cctl);
    	wrfl();
    
    }
    
    /* igb_set_i2c_clk - Sets the I2C SCL clock
     *  @data: pointer to hardware structure
     *  @state: state to set clock
     *
     *  Sets the I2C clock line to state
     */
    static void igb_set_i2c_clk(void *data, int state)
    {
    	struct igb_adapter *adapter = (struct igb_adapter *)data;
    	struct e1000_hw *hw = &adapter->hw;
    	s32 i2cctl = rd32(E1000_I2CPARAMS);
    
    	if (state) {
    		i2cctl |= E1000_I2C_CLK_OUT;
    		i2cctl &= ~E1000_I2C_CLK_OE_N;
    	} else {
    		i2cctl &= ~E1000_I2C_CLK_OUT;
    		i2cctl &= ~E1000_I2C_CLK_OE_N;
    	}
    	wr32(E1000_I2CPARAMS, i2cctl);
    	wrfl();
    }
    
    /* igb_get_i2c_clk - Gets the I2C SCL clock state
     *  @data: pointer to hardware structure
     *
     *  Gets the I2C clock state
     */
    static int igb_get_i2c_clk(void *data)
    {
    	struct igb_adapter *adapter = (struct igb_adapter *)data;
    	struct e1000_hw *hw = &adapter->hw;
    	s32 i2cctl = rd32(E1000_I2CPARAMS);
    
    	return ((i2cctl & E1000_I2C_CLK_IN) != 0);
    }
    
    static const struct i2c_algo_bit_data igb_i2c_algo = {
    	.setsda		= igb_set_i2c_data,
    	.setscl		= igb_set_i2c_clk,
    	.getsda		= igb_get_i2c_data,
    	.getscl		= igb_get_i2c_clk,
    	.udelay		= 5,
    	.timeout	= 20,
    };
    
    
     * igb_get_hw_dev - return device
    
     * used by hardware layer to print debugging information
     **/
    
    struct net_device *igb_get_hw_dev(struct e1000_hw *hw)
    
    {
    	struct igb_adapter *adapter = hw->back;
    
    /**
     * igb_init_module - Driver Registration Routine
     *
     * igb_init_module is the first routine called when the driver is
     * loaded. All it does is register with the PCI subsystem.
     **/
    static int __init igb_init_module(void)
    {
    	int ret;
    
    	pr_info("%s - version %s\n",
    
    	       igb_driver_string, igb_driver_version);
    
    
    	pr_info("%s\n", igb_copyright);
    
    #ifdef CONFIG_IGB_DCA
    
    Jeb Cramer's avatar
    Jeb Cramer committed
    	dca_register_notify(&dca_notifier);
    #endif
    
    	ret = pci_register_driver(&igb_driver);
    
    	return ret;
    }
    
    module_init(igb_init_module);
    
    /**
     * igb_exit_module - Driver Exit Cleanup Routine
     *
     * igb_exit_module is called just before the driver is removed
     * from memory.
     **/
    static void __exit igb_exit_module(void)
    {
    
    #ifdef CONFIG_IGB_DCA
    
    Jeb Cramer's avatar
    Jeb Cramer committed
    	dca_unregister_notify(&dca_notifier);
    #endif
    
    	pci_unregister_driver(&igb_driver);
    }
    
    module_exit(igb_exit_module);
    
    
    #define Q_IDX_82576(i) (((i & 0x1) << 3) + (i >> 1))
    /**
     * igb_cache_ring_register - Descriptor ring to register mapping
     * @adapter: board private structure to initialize
     *
     * Once we know the feature-set enabled for the device, we'll cache
     * the register offset the descriptor ring is assigned to.
     **/
    static void igb_cache_ring_register(struct igb_adapter *adapter)
    {
    
    	u32 rbase_offset = adapter->vfs_allocated_count;
    
    
    	switch (adapter->hw.mac.type) {
    	case e1000_82576:
    		/* The queues are allocated for virtualization such that VF 0
    		 * is allocated queues 0 and 8, VF 1 queues 1 and 9, etc.
    		 * In order to avoid collision we start at the first free queue
    		 * and continue consuming queues in the same sequence
    		 */
    
    		if (adapter->vfs_allocated_count) {
    
    			for (; i < adapter->rss_queues; i++)
    
    				adapter->rx_ring[i]->reg_idx = rbase_offset +
    				                               Q_IDX_82576(i);
    
    	case e1000_82580:
    
    	case e1000_i210:
    	case e1000_i211:
    
    		for (; i < adapter->num_rx_queues; i++)
    
    			adapter->rx_ring[i]->reg_idx = rbase_offset + i;
    
    		for (; j < adapter->num_tx_queues; j++)
    
    			adapter->tx_ring[j]->reg_idx = rbase_offset + j;
    
    /**
     *  igb_write_ivar - configure ivar for given MSI-X vector
     *  @hw: pointer to the HW structure
     *  @msix_vector: vector number we are allocating to a given ring
     *  @index: row index of IVAR register to write within IVAR table
     *  @offset: column offset of in IVAR, should be multiple of 8
     *
     *  This function is intended to handle the writing of the IVAR register
     *  for adapters 82576 and newer.  The IVAR table consists of 2 columns,
     *  each containing an cause allocation for an Rx and Tx ring, and a
     *  variable number of rows depending on the number of queues supported.
     **/
    static void igb_write_ivar(struct e1000_hw *hw, int msix_vector,
    			   int index, int offset)
    {
    	u32 ivar = array_rd32(E1000_IVAR0, index);
    
    	/* clear any bits that are currently set */
    	ivar &= ~((u32)0xFF << offset);
    
    	/* write vector and valid bit */
    	ivar |= (msix_vector | E1000_IVAR_VALID) << offset;
    
    	array_wr32(E1000_IVAR0, index, ivar);
    }
    
    
    #define IGB_N0_QUEUE -1
    
    static void igb_assign_vector(struct igb_q_vector *q_vector, int msix_vector)
    
    	struct igb_adapter *adapter = q_vector->adapter;
    
    	struct e1000_hw *hw = &adapter->hw;
    
    	int rx_queue = IGB_N0_QUEUE;
    	int tx_queue = IGB_N0_QUEUE;
    
    	u32 msixbm = 0;
    
    	if (q_vector->rx.ring)
    		rx_queue = q_vector->rx.ring->reg_idx;
    	if (q_vector->tx.ring)
    		tx_queue = q_vector->tx.ring->reg_idx;
    
    
    	switch (hw->mac.type) {
    	case e1000_82575:
    
    		/* The 82575 assigns vectors using a bitmask, which matches the
    		   bitmask for the EICR/EIMS/EIMC registers.  To assign one
    		   or more queues to a vector, we write the appropriate bits
    		   into the MSIXBM register for that vector. */
    
    		if (rx_queue > IGB_N0_QUEUE)
    
    			msixbm = E1000_EICR_RX_QUEUE0 << rx_queue;
    
    		if (tx_queue > IGB_N0_QUEUE)
    
    			msixbm |= E1000_EICR_TX_QUEUE0 << tx_queue;
    
    		if (!adapter->msix_entries && msix_vector == 0)
    			msixbm |= E1000_EIMS_OTHER;
    
    		array_wr32(E1000_MSIXBM(0), msix_vector, msixbm);
    
    		q_vector->eims_value = msixbm;
    
    		break;
    	case e1000_82576:
    
    		/*
    		 * 82576 uses a table that essentially consists of 2 columns
    		 * with 8 rows.  The ordering is column-major so we use the
    		 * lower 3 bits as the row index, and the 4th bit as the
    		 * column offset.
    		 */
    		if (rx_queue > IGB_N0_QUEUE)
    			igb_write_ivar(hw, msix_vector,
    				       rx_queue & 0x7,
    				       (rx_queue & 0x8) << 1);
    		if (tx_queue > IGB_N0_QUEUE)
    			igb_write_ivar(hw, msix_vector,
    				       tx_queue & 0x7,
    				       ((tx_queue & 0x8) << 1) + 8);
    
    		q_vector->eims_value = 1 << msix_vector;
    
    		break;
    
    	case e1000_82580:
    
    	case e1000_i210:
    	case e1000_i211:
    
    		/*
    		 * On 82580 and newer adapters the scheme is similar to 82576
    		 * however instead of ordering column-major we have things
    		 * ordered row-major.  So we traverse the table by using
    		 * bit 0 as the column offset, and the remaining bits as the
    		 * row index.
    		 */
    		if (rx_queue > IGB_N0_QUEUE)
    			igb_write_ivar(hw, msix_vector,
    				       rx_queue >> 1,
    				       (rx_queue & 0x1) << 4);
    		if (tx_queue > IGB_N0_QUEUE)
    			igb_write_ivar(hw, msix_vector,
    				       tx_queue >> 1,
    				       ((tx_queue & 0x1) << 4) + 8);
    
    		q_vector->eims_value = 1 << msix_vector;
    		break;
    
    	default:
    		BUG();
    		break;
    	}
    
    
    	/* add q_vector eims value to global eims_enable_mask */
    	adapter->eims_enable_mask |= q_vector->eims_value;
    
    	/* configure q_vector to set itr on first interrupt */
    	q_vector->set_itr = 1;
    
    }
    
    /**
     * igb_configure_msix - Configure MSI-X hardware
     *
     * igb_configure_msix sets up the hardware to properly
     * generate MSI-X interrupts.
     **/
    static void igb_configure_msix(struct igb_adapter *adapter)
    {
    	u32 tmp;
    	int i, vector = 0;
    	struct e1000_hw *hw = &adapter->hw;
    
    	adapter->eims_enable_mask = 0;
    
    	/* set vector for other causes, i.e. link changes */
    
    	switch (hw->mac.type) {
    	case e1000_82575:
    
    		tmp = rd32(E1000_CTRL_EXT);
    		/* enable MSI-X PBA support*/
    		tmp |= E1000_CTRL_EXT_PBA_CLR;
    
    		/* Auto-Mask interrupts upon ICR read. */
    		tmp |= E1000_CTRL_EXT_EIAME;
    		tmp |= E1000_CTRL_EXT_IRCA;
    
    		wr32(E1000_CTRL_EXT, tmp);
    
    
    		/* enable msix_other interrupt */
    		array_wr32(E1000_MSIXBM(0), vector++,
    		                      E1000_EIMS_OTHER);
    
    		adapter->eims_other = E1000_EIMS_OTHER;
    
    		break;
    
    	case e1000_82576:
    
    	case e1000_82580:
    
    	case e1000_i210:
    	case e1000_i211:
    
    		/* Turn on MSI-X capability first, or our settings
    		 * won't stick.  And it will take days to debug. */
    		wr32(E1000_GPIE, E1000_GPIE_MSIX_MODE |
    		                E1000_GPIE_PBA | E1000_GPIE_EIAME |
    		                E1000_GPIE_NSICR);
    
    		/* enable msix_other interrupt */
    		adapter->eims_other = 1 << vector;
    
    		tmp = (vector++ | E1000_IVAR_VALID) << 8;
    
    
    		break;
    	default:
    		/* do nothing, since nothing else supports MSI-X */
    		break;
    	} /* switch (hw->mac.type) */
    
    
    	adapter->eims_enable_mask |= adapter->eims_other;
    
    
    	for (i = 0; i < adapter->num_q_vectors; i++)
    		igb_assign_vector(adapter->q_vector[i], vector++);
    
    	wrfl();
    }
    
    /**
     * igb_request_msix - Initialize MSI-X interrupts
     *
     * igb_request_msix allocates MSI-X vectors and requests interrupts from the
     * kernel.
     **/
    static int igb_request_msix(struct igb_adapter *adapter)
    {
    	struct net_device *netdev = adapter->netdev;
    
    	struct e1000_hw *hw = &adapter->hw;
    
    	int i, err = 0, vector = 0, free_vector = 0;
    
    	err = request_irq(adapter->msix_entries[vector].vector,
    
    	                  igb_msix_other, 0, netdev->name, adapter);
    
    
    	for (i = 0; i < adapter->num_q_vectors; i++) {
    		struct igb_q_vector *q_vector = adapter->q_vector[i];
    
    
    		q_vector->itr_register = hw->hw_addr + E1000_EITR(vector);
    
    
    		if (q_vector->rx.ring && q_vector->tx.ring)
    
    			sprintf(q_vector->name, "%s-TxRx-%u", netdev->name,
    
    				q_vector->rx.ring->queue_index);
    		else if (q_vector->tx.ring)
    
    			sprintf(q_vector->name, "%s-tx-%u", netdev->name,
    
    				q_vector->tx.ring->queue_index);
    		else if (q_vector->rx.ring)
    
    			sprintf(q_vector->name, "%s-rx-%u", netdev->name,
    
    				q_vector->rx.ring->queue_index);
    
    			sprintf(q_vector->name, "%s-unused", netdev->name);
    
    
    		err = request_irq(adapter->msix_entries[vector].vector,
    
    		                  igb_msix_ring, 0, q_vector->name,
    
    	}
    
    	igb_configure_msix(adapter);
    	return 0;
    
    
    err_free:
    	/* free already assigned IRQs */
    	free_irq(adapter->msix_entries[free_vector++].vector, adapter);
    
    	vector--;
    	for (i = 0; i < vector; i++) {
    		free_irq(adapter->msix_entries[free_vector++].vector,
    			 adapter->q_vector[i]);
    	}
    err_out:
    
    	return err;
    }
    
    static void igb_reset_interrupt_capability(struct igb_adapter *adapter)
    {
    	if (adapter->msix_entries) {
    		pci_disable_msix(adapter->pdev);
    		kfree(adapter->msix_entries);
    		adapter->msix_entries = NULL;
    
    	} else if (adapter->flags & IGB_FLAG_HAS_MSI) {
    
    		pci_disable_msi(adapter->pdev);
    
    /**
     * igb_free_q_vector - Free memory allocated for specific interrupt vector
     * @adapter: board private structure to initialize
     * @v_idx: Index of vector to be freed
     *
     * This function frees the memory allocated to the q_vector.  In addition if
     * NAPI is enabled it will delete any references to the NAPI struct prior
     * to freeing the q_vector.
     **/
    static void igb_free_q_vector(struct igb_adapter *adapter, int v_idx)
    {
    	struct igb_q_vector *q_vector = adapter->q_vector[v_idx];
    
    	if (q_vector->tx.ring)
    		adapter->tx_ring[q_vector->tx.ring->queue_index] = NULL;
    
    	if (q_vector->rx.ring)
    		adapter->tx_ring[q_vector->rx.ring->queue_index] = NULL;