igb: re-order queues to support cleaner use of ivar on 82576
[safe/jmp/linux-2.6] / drivers / net / igb / igb_main.c
index 6f1ad53..9331e52 100644 (file)
 #include <linux/ethtool.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/if_ether.h>
-
+#include <linux/aer.h>
+#ifdef CONFIG_IGB_DCA
+#include <linux/dca.h>
+#endif
 #include "igb.h"
 
-#define DRV_VERSION "1.0.8-k2"
+#define DRV_VERSION "1.2.45-k2"
 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 Intel Corporation.";
-
+static const char igb_copyright[] = "Copyright (c) 2008 Intel Corporation.";
 
 static const struct e1000_info *igb_info_tbl[] = {
        [board_82575] = &e1000_82575_info,
 };
 
 static struct pci_device_id igb_pci_tbl[] = {
+       { PCI_VDEVICE(INTEL, E1000_DEV_ID_82576), 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_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 },
@@ -71,8 +77,6 @@ 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_free_tx_resources(struct igb_adapter *, struct igb_ring *);
-static void igb_free_rx_resources(struct igb_adapter *, struct igb_ring *);
 void igb_update_stats(struct igb_adapter *);
 static int igb_probe(struct pci_dev *, const struct pci_device_id *);
 static void __devexit igb_remove(struct pci_dev *pdev);
@@ -84,8 +88,8 @@ static void igb_configure_rx(struct igb_adapter *);
 static void igb_setup_rctl(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_adapter *, struct igb_ring *);
-static void igb_clean_rx_ring(struct igb_adapter *, struct igb_ring *);
+static void igb_clean_tx_ring(struct igb_ring *);
+static void igb_clean_rx_ring(struct igb_ring *);
 static void igb_set_multi(struct net_device *);
 static void igb_update_phy_info(unsigned long);
 static void igb_watchdog(unsigned long);
@@ -102,12 +106,18 @@ static irqreturn_t igb_msix_other(int irq, void *);
 static irqreturn_t igb_msix_rx(int irq, void *);
 static irqreturn_t igb_msix_tx(int irq, void *);
 static int igb_clean_rx_ring_msix(struct napi_struct *, int);
-static bool igb_clean_tx_irq(struct igb_adapter *, struct igb_ring *);
-static int igb_clean(struct napi_struct *, int);
-static bool igb_clean_rx_irq_adv(struct igb_adapter *,
-                                struct igb_ring *, int *, int);
-static void igb_alloc_rx_buffers_adv(struct igb_adapter *,
-                                    struct igb_ring *, int);
+#ifdef CONFIG_IGB_DCA
+static void igb_update_rx_dca(struct igb_ring *);
+static void igb_update_tx_dca(struct igb_ring *);
+static void igb_setup_dca(struct igb_adapter *);
+#endif /* CONFIG_IGB_DCA */
+static bool igb_clean_tx_irq(struct igb_ring *);
+static int igb_poll(struct napi_struct *, int);
+static bool igb_clean_rx_irq_adv(struct igb_ring *, int *, int);
+static void igb_alloc_rx_buffers_adv(struct igb_ring *, int);
+#ifdef CONFIG_IGB_LRO
+static int igb_get_skb_hdr(struct sk_buff *skb, void **, void **, u64 *, void *);
+#endif
 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 *);
@@ -121,6 +131,14 @@ static int igb_suspend(struct pci_dev *, pm_message_t);
 static int igb_resume(struct pci_dev *);
 #endif
 static void igb_shutdown(struct pci_dev *);
+#ifdef CONFIG_IGB_DCA
+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 */
@@ -153,6 +171,8 @@ static struct pci_driver igb_driver = {
        .err_handler = &igb_err_handler
 };
 
+static int global_quad_port_a; /* global quad port a indication */
+
 MODULE_AUTHOR("Intel Corporation, <e1000-devel@lists.sourceforge.net>");
 MODULE_DESCRIPTION("Intel(R) Gigabit Ethernet Network Driver");
 MODULE_LICENSE("GPL");
@@ -184,7 +204,12 @@ static int __init igb_init_module(void)
 
        printk(KERN_INFO "%s\n", igb_copyright);
 
+       global_quad_port_a = 0;
+
        ret = pci_register_driver(&igb_driver);
+#ifdef CONFIG_IGB_DCA
+       dca_register_notify(&dca_notifier);
+#endif
        return ret;
 }
 
@@ -198,11 +223,48 @@ module_init(igb_init_module);
  **/
 static void __exit igb_exit_module(void)
 {
+#ifdef CONFIG_IGB_DCA
+       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)
+{
+       int i;
+
+       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
+                */
+               for (i = 0; i < adapter->num_rx_queues; i++)
+                       adapter->rx_ring[i].reg_idx = Q_IDX_82576(i);
+               for (i = 0; i < adapter->num_tx_queues; i++)
+                       adapter->tx_ring[i].reg_idx = Q_IDX_82576(i);
+               break;
+       case e1000_82575:
+       default:
+               for (i = 0; i < adapter->num_rx_queues; i++)
+                       adapter->rx_ring[i].reg_idx = i;
+               for (i = 0; i < adapter->num_tx_queues; i++)
+                       adapter->tx_ring[i].reg_idx = i;
+               break;
+       }
+}
+
 /**
  * igb_alloc_queues - Allocate memory for all rings
  * @adapter: board private structure to initialize
@@ -226,25 +288,50 @@ static int igb_alloc_queues(struct igb_adapter *adapter)
                return -ENOMEM;
        }
 
+       adapter->rx_ring->buddy = adapter->tx_ring;
+
+       for (i = 0; i < adapter->num_tx_queues; i++) {
+               struct igb_ring *ring = &(adapter->tx_ring[i]);
+               ring->count = adapter->tx_ring_count;
+               ring->adapter = adapter;
+               ring->queue_index = i;
+       }
        for (i = 0; i < adapter->num_rx_queues; i++) {
                struct igb_ring *ring = &(adapter->rx_ring[i]);
+               ring->count = adapter->rx_ring_count;
                ring->adapter = adapter;
+               ring->queue_index = i;
                ring->itr_register = E1000_ITR;
 
-               if (!ring->napi.poll)
-                       netif_napi_add(adapter->netdev, &ring->napi, igb_clean,
-                                      adapter->napi.weight /
-                                      adapter->num_rx_queues);
+               /* set a default napi handler for each rx_ring */
+               netif_napi_add(adapter->netdev, &ring->napi, igb_poll, 64);
        }
+
+       igb_cache_ring_register(adapter);
        return 0;
 }
 
+static void igb_free_queues(struct igb_adapter *adapter)
+{
+       int i;
+
+       for (i = 0; i < adapter->num_rx_queues; i++)
+               netif_napi_del(&adapter->rx_ring[i].napi);
+
+       kfree(adapter->tx_ring);
+       kfree(adapter->rx_ring);
+}
+
 #define IGB_N0_QUEUE -1
 static void igb_assign_vector(struct igb_adapter *adapter, int rx_queue,
                              int tx_queue, int msix_vector)
 {
        u32 msixbm = 0;
        struct e1000_hw *hw = &adapter->hw;
+       u32 ivar, index;
+
+       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
@@ -259,6 +346,47 @@ static void igb_assign_vector(struct igb_adapter *adapter, int rx_queue,
                                  E1000_EICR_TX_QUEUE0 << tx_queue;
                }
                array_wr32(E1000_MSIXBM(0), msix_vector, msixbm);
+               break;
+       case e1000_82576:
+               /* 82576 uses a table-based method for assigning vectors.
+                  Each queue has a single entry in the table to which we write
+                  a vector number along with a "valid" bit.  Sadly, the layout
+                  of the table is somewhat counterintuitive. */
+               if (rx_queue > IGB_N0_QUEUE) {
+                       index = (rx_queue >> 1);
+                       ivar = array_rd32(E1000_IVAR0, index);
+                       if (rx_queue & 0x1) {
+                               /* vector goes into third byte of register */
+                               ivar = ivar & 0xFF00FFFF;
+                               ivar |= (msix_vector | E1000_IVAR_VALID) << 16;
+                       } else {
+                               /* vector goes into low byte of register */
+                               ivar = ivar & 0xFFFFFF00;
+                               ivar |= msix_vector | E1000_IVAR_VALID;
+                       }
+                       adapter->rx_ring[rx_queue].eims_value= 1 << msix_vector;
+                       array_wr32(E1000_IVAR0, index, ivar);
+               }
+               if (tx_queue > IGB_N0_QUEUE) {
+                       index = (tx_queue >> 1);
+                       ivar = array_rd32(E1000_IVAR0, index);
+                       if (tx_queue & 0x1) {
+                               /* vector goes into high byte of register */
+                               ivar = ivar & 0x00FFFFFF;
+                               ivar |= (msix_vector | E1000_IVAR_VALID) << 24;
+                       } else {
+                               /* vector goes into second byte of register */
+                               ivar = ivar & 0xFFFF00FF;
+                               ivar |= (msix_vector | E1000_IVAR_VALID) << 8;
+                       }
+                       adapter->tx_ring[tx_queue].eims_value= 1 << msix_vector;
+                       array_wr32(E1000_IVAR0, index, ivar);
+               }
+               break;
+       default:
+               BUG();
+               break;
+       }
 }
 
 /**
@@ -274,13 +402,19 @@ static void igb_configure_msix(struct igb_adapter *adapter)
        struct e1000_hw *hw = &adapter->hw;
 
        adapter->eims_enable_mask = 0;
+       if (hw->mac.type == e1000_82576)
+               /* 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);
 
        for (i = 0; i < adapter->num_tx_queues; i++) {
                struct igb_ring *tx_ring = &adapter->tx_ring[i];
                igb_assign_vector(adapter, IGB_N0_QUEUE, i, vector++);
                adapter->eims_enable_mask |= tx_ring->eims_value;
                if (tx_ring->itr_val)
-                       writel(1000000000 / (tx_ring->itr_val * 256),
+                       writel(tx_ring->itr_val,
                               hw->hw_addr + tx_ring->itr_register);
                else
                        writel(1, hw->hw_addr + tx_ring->itr_register);
@@ -288,10 +422,11 @@ static void igb_configure_msix(struct igb_adapter *adapter)
 
        for (i = 0; i < adapter->num_rx_queues; i++) {
                struct igb_ring *rx_ring = &adapter->rx_ring[i];
+               rx_ring->buddy = NULL;
                igb_assign_vector(adapter, i, IGB_N0_QUEUE, vector++);
                adapter->eims_enable_mask |= rx_ring->eims_value;
                if (rx_ring->itr_val)
-                       writel(1000000000 / (rx_ring->itr_val * 256),
+                       writel(rx_ring->itr_val,
                               hw->hw_addr + rx_ring->itr_register);
                else
                        writel(1, hw->hw_addr + rx_ring->itr_register);
@@ -299,12 +434,11 @@ static void igb_configure_msix(struct igb_adapter *adapter)
 
 
        /* set vector for other causes, i.e. link changes */
+       switch (hw->mac.type) {
+       case e1000_82575:
                array_wr32(E1000_MSIXBM(0), vector++,
                                      E1000_EIMS_OTHER);
 
-               /* disable IAM for ICR interrupt bits */
-               wr32(E1000_IAM, 0);
-
                tmp = rd32(E1000_CTRL_EXT);
                /* enable MSI-X PBA support*/
                tmp |= E1000_CTRL_EXT_PBA_CLR;
@@ -315,7 +449,21 @@ static void igb_configure_msix(struct igb_adapter *adapter)
 
                wr32(E1000_CTRL_EXT, tmp);
                adapter->eims_enable_mask |= E1000_EIMS_OTHER;
+               adapter->eims_other = E1000_EIMS_OTHER;
 
+               break;
+
+       case e1000_82576:
+               tmp = (vector++ | E1000_IVAR_VALID) << 8;
+               wr32(E1000_IVAR_MISC, tmp);
+
+               adapter->eims_enable_mask = (1 << (vector)) - 1;
+               adapter->eims_other = 1 << (vector - 1);
+               break;
+       default:
+               /* do nothing, since nothing else supports MSI-X */
+               break;
+       } /* switch (hw->mac.type) */
        wrfl();
 }
 
@@ -334,20 +482,20 @@ static int igb_request_msix(struct igb_adapter *adapter)
 
        for (i = 0; i < adapter->num_tx_queues; i++) {
                struct igb_ring *ring = &(adapter->tx_ring[i]);
-               sprintf(ring->name, "%s-tx%d", netdev->name, i);
+               sprintf(ring->name, "%s-tx-%d", netdev->name, i);
                err = request_irq(adapter->msix_entries[vector].vector,
                                  &igb_msix_tx, 0, ring->name,
                                  &(adapter->tx_ring[i]));
                if (err)
                        goto out;
                ring->itr_register = E1000_EITR(0) + (vector << 2);
-               ring->itr_val = adapter->itr;
+               ring->itr_val = 976; /* ~4000 ints/sec */
                vector++;
        }
        for (i = 0; i < adapter->num_rx_queues; i++) {
                struct igb_ring *ring = &(adapter->rx_ring[i]);
                if (strlen(netdev->name) < (IFNAMSIZ - 5))
-                       sprintf(ring->name, "%s-rx%d", netdev->name, i);
+                       sprintf(ring->name, "%s-rx-%d", netdev->name, i);
                else
                        memcpy(ring->name, netdev->name, IFNAMSIZ);
                err = request_irq(adapter->msix_entries[vector].vector,
@@ -357,6 +505,9 @@ static int igb_request_msix(struct igb_adapter *adapter)
                        goto out;
                ring->itr_register = E1000_EITR(0) + (vector << 2);
                ring->itr_val = adapter->itr;
+               /* overwrite the poll routine for MSIX, we've already done
+                * netif_napi_add */
+               ring->napi.poll = &igb_clean_rx_ring_msix;
                vector++;
        }
 
@@ -365,9 +516,6 @@ static int igb_request_msix(struct igb_adapter *adapter)
        if (err)
                goto out;
 
-       adapter->napi.poll = igb_clean_rx_ring_msix;
-       for (i = 0; i < adapter->num_rx_queues; i++)
-               adapter->rx_ring[i].napi.poll = adapter->napi.poll;
        igb_configure_msix(adapter);
        return 0;
 out:
@@ -380,7 +528,7 @@ static void igb_reset_interrupt_capability(struct igb_adapter *adapter)
                pci_disable_msix(adapter->pdev);
                kfree(adapter->msix_entries);
                adapter->msix_entries = NULL;
-       } else if (adapter->msi_enabled)
+       } else if (adapter->flags & IGB_FLAG_HAS_MSI)
                pci_disable_msi(adapter->pdev);
        return;
 }
@@ -410,15 +558,19 @@ static void igb_set_interrupt_capability(struct igb_adapter *adapter)
                              adapter->msix_entries,
                              numvecs);
        if (err == 0)
-               return;
+               goto out;
 
        igb_reset_interrupt_capability(adapter);
 
        /* If we can't do MSI-X, try MSI */
 msi_only:
        adapter->num_rx_queues = 1;
+       adapter->num_tx_queues = 1;
        if (!pci_enable_msi(adapter->pdev))
-               adapter->msi_enabled = 1;
+               adapter->flags |= IGB_FLAG_HAS_MSI;
+out:
+       /* Notify the stack of the (possibly) reduced Tx Queue count. */
+       adapter->netdev->real_num_tx_queues = adapter->num_tx_queues;
        return;
 }
 
@@ -436,29 +588,38 @@ static int igb_request_irq(struct igb_adapter *adapter)
 
        if (adapter->msix_entries) {
                err = igb_request_msix(adapter);
-               if (!err) {
-                       /* enable IAM, auto-mask,
-                        * DO NOT USE EIAM or IAM in legacy mode */
-                       wr32(E1000_IAM, IMS_ENABLE_MASK);
+               if (!err)
                        goto request_done;
-               }
                /* fall back to MSI */
                igb_reset_interrupt_capability(adapter);
                if (!pci_enable_msi(adapter->pdev))
-                       adapter->msi_enabled = 1;
+                       adapter->flags |= IGB_FLAG_HAS_MSI;
                igb_free_all_tx_resources(adapter);
                igb_free_all_rx_resources(adapter);
                adapter->num_rx_queues = 1;
                igb_alloc_queues(adapter);
+       } else {
+               switch (hw->mac.type) {
+               case e1000_82575:
+                       wr32(E1000_MSIXBM(0),
+                            (E1000_EICR_RX_QUEUE0 | E1000_EIMS_OTHER));
+                       break;
+               case e1000_82576:
+                       wr32(E1000_IVAR0, E1000_IVAR_VALID);
+                       break;
+               default:
+                       break;
+               }
        }
-       if (adapter->msi_enabled) {
+
+       if (adapter->flags & IGB_FLAG_HAS_MSI) {
                err = request_irq(adapter->pdev->irq, &igb_intr_msi, 0,
                                  netdev->name, netdev);
                if (!err)
                        goto request_done;
                /* fall back to legacy interrupts */
                igb_reset_interrupt_capability(adapter);
-               adapter->msi_enabled = 0;
+               adapter->flags &= ~IGB_FLAG_HAS_MSI;
        }
 
        err = request_irq(adapter->pdev->irq, &igb_intr, IRQF_SHARED,
@@ -502,9 +663,12 @@ static void igb_irq_disable(struct igb_adapter *adapter)
        struct e1000_hw *hw = &adapter->hw;
 
        if (adapter->msix_entries) {
+               wr32(E1000_EIAM, 0);
                wr32(E1000_EIMC, ~0);
                wr32(E1000_EIAC, 0);
        }
+
+       wr32(E1000_IAM, 0);
        wr32(E1000_IMC, ~0);
        wrfl();
        synchronize_irq(adapter->pdev->irq);
@@ -519,13 +683,14 @@ static void igb_irq_enable(struct igb_adapter *adapter)
        struct e1000_hw *hw = &adapter->hw;
 
        if (adapter->msix_entries) {
-               wr32(E1000_EIMS,
-                               adapter->eims_enable_mask);
-               wr32(E1000_EIAC,
-                               adapter->eims_enable_mask);
+               wr32(E1000_EIAC, adapter->eims_enable_mask);
+               wr32(E1000_EIAM, adapter->eims_enable_mask);
+               wr32(E1000_EIMS, adapter->eims_enable_mask);
                wr32(E1000_IMS, E1000_IMS_LSC);
-       } else
-       wr32(E1000_IMS, IMS_ENABLE_MASK);
+       } else {
+               wr32(E1000_IMS, IMS_ENABLE_MASK);
+               wr32(E1000_IAM, IMS_ENABLE_MASK);
+       }
 }
 
 static void igb_update_mng_vlan(struct igb_adapter *adapter)
@@ -592,28 +757,6 @@ static void igb_get_hw_control(struct igb_adapter *adapter)
                        ctrl_ext | E1000_CTRL_EXT_DRV_LOAD);
 }
 
-static void igb_init_manageability(struct igb_adapter *adapter)
-{
-       struct e1000_hw *hw = &adapter->hw;
-
-       if (adapter->en_mng_pt) {
-               u32 manc2h = rd32(E1000_MANC2H);
-               u32 manc = rd32(E1000_MANC);
-
-               /* enable receiving management packets to the host */
-               /* this will probably generate destination unreachable messages
-                * from the host OS, but the packets will be handled on SMBUS */
-               manc |= E1000_MANC_EN_MNG2HOST;
-#define E1000_MNG2HOST_PORT_623 (1 << 5)
-#define E1000_MNG2HOST_PORT_664 (1 << 6)
-               manc2h |= E1000_MNG2HOST_PORT_623;
-               manc2h |= E1000_MNG2HOST_PORT_664;
-               wr32(E1000_MANC2H, manc2h);
-
-               wr32(E1000_MANC, manc);
-       }
-}
-
 /**
  * igb_configure - configure the hardware for RX and TX
  * @adapter: private board structure
@@ -627,17 +770,19 @@ static void igb_configure(struct igb_adapter *adapter)
        igb_set_multi(netdev);
 
        igb_restore_vlan(adapter);
-       igb_init_manageability(adapter);
 
        igb_configure_tx(adapter);
        igb_setup_rctl(adapter);
        igb_configure_rx(adapter);
+
+       igb_rx_fifo_flush_82575(&adapter->hw);
+
        /* call IGB_DESC_UNUSED which always leaves
         * at least 1 descriptor unused to make sure
         * next_to_use != next_to_clean */
        for (i = 0; i < adapter->num_rx_queues; i++) {
                struct igb_ring *ring = &adapter->rx_ring[i];
-               igb_alloc_rx_buffers_adv(adapter, ring, IGB_DESC_UNUSED(ring));
+               igb_alloc_rx_buffers_adv(ring, IGB_DESC_UNUSED(ring));
        }
 
 
@@ -660,13 +805,10 @@ int igb_up(struct igb_adapter *adapter)
 
        clear_bit(__IGB_DOWN, &adapter->state);
 
-       napi_enable(&adapter->napi);
-
-       if (adapter->msix_entries) {
-               for (i = 0; i < adapter->num_rx_queues; i++)
-                       napi_enable(&adapter->rx_ring[i].napi);
+       for (i = 0; i < adapter->num_rx_queues; i++)
+               napi_enable(&adapter->rx_ring[i].napi);
+       if (adapter->msix_entries)
                igb_configure_msix(adapter);
-       }
 
        /* Clear any pending interrupts. */
        rd32(E1000_ICR);
@@ -693,7 +835,7 @@ void igb_down(struct igb_adapter *adapter)
        wr32(E1000_RCTL, rctl & ~E1000_RCTL_EN);
        /* flush and sleep below */
 
-       netif_stop_queue(netdev);
+       netif_tx_stop_all_queues(netdev);
 
        /* disable transmits in the hardware */
        tctl = rd32(E1000_TCTL);
@@ -703,11 +845,9 @@ void igb_down(struct igb_adapter *adapter)
        wrfl();
        msleep(10);
 
-       napi_disable(&adapter->napi);
+       for (i = 0; i < adapter->num_rx_queues; i++)
+               napi_disable(&adapter->rx_ring[i].napi);
 
-       if (adapter->msix_entries)
-               for (i = 0; i < adapter->num_rx_queues; i++)
-                       napi_disable(&adapter->rx_ring[i].napi);
        igb_irq_disable(adapter);
 
        del_timer_sync(&adapter->watchdog_timer);
@@ -737,16 +877,23 @@ void igb_reinit_locked(struct igb_adapter *adapter)
 void igb_reset(struct igb_adapter *adapter)
 {
        struct e1000_hw *hw = &adapter->hw;
-       struct e1000_fc_info *fc = &adapter->hw.fc;
+       struct e1000_mac_info *mac = &hw->mac;
+       struct e1000_fc_info *fc = &hw->fc;
        u32 pba = 0, tx_space, min_tx_space, min_rx_space;
        u16 hwm;
 
        /* Repartition Pba for greater than 9k mtu
         * To take effect CTRL.RST is required.
         */
+       if (mac->type != e1000_82576) {
        pba = E1000_PBA_34K;
+       }
+       else {
+               pba = E1000_PBA_64K;
+       }
 
-       if (adapter->max_frame_size > ETH_FRAME_LEN + ETH_FCS_LEN) {
+       if ((adapter->max_frame_size > ETH_FRAME_LEN + ETH_FCS_LEN) &&
+           (mac->type < e1000_82576)) {
                /* adjust PBA for jumbo frames */
                wr32(E1000_PBA, pba);
 
@@ -785,8 +932,8 @@ void igb_reset(struct igb_adapter *adapter)
                        if (pba < min_rx_space)
                                pba = min_rx_space;
                }
+               wr32(E1000_PBA, pba);
        }
-       wr32(E1000_PBA, pba);
 
        /* flow control settings */
        /* The high water mark must be low enough to fit one full frame
@@ -795,10 +942,15 @@ void igb_reset(struct igb_adapter *adapter)
         * - 90% of the Rx FIFO size, or
         * - the full Rx FIFO size minus one full frame */
        hwm = min(((pba << 10) * 9 / 10),
-                 ((pba << 10) - adapter->max_frame_size));
+                       ((pba << 10) - 2 * adapter->max_frame_size));
 
-       fc->high_water = hwm & 0xFFF8;  /* 8-byte granularity */
-       fc->low_water = fc->high_water - 8;
+       if (mac->type < e1000_82576) {
+               fc->high_water = hwm & 0xFFF8;  /* 8-byte granularity */
+               fc->low_water = fc->high_water - 8;
+       } else {
+               fc->high_water = hwm & 0xFFF0;  /* 16-byte granularity */
+               fc->low_water = fc->high_water - 16;
+       }
        fc->pause_time = 0xFFFF;
        fc->send_xon = 1;
        fc->type = fc->original_type;
@@ -816,11 +968,44 @@ void igb_reset(struct igb_adapter *adapter)
        wr32(E1000_VET, ETHERNET_IEEE_VLAN_TYPE);
 
        igb_reset_adaptive(&adapter->hw);
-       if (adapter->hw.phy.ops.get_phy_info)
-               adapter->hw.phy.ops.get_phy_info(&adapter->hw);
+       igb_get_phy_info(&adapter->hw);
 }
 
 /**
+ * igb_is_need_ioport - determine if an adapter needs ioport resources or not
+ * @pdev: PCI device information struct
+ *
+ * Returns true if an adapter needs ioport resources
+ **/
+static int igb_is_need_ioport(struct pci_dev *pdev)
+{
+       switch (pdev->device) {
+       /* Currently there are no adapters that need ioport resources */
+       default:
+               return false;
+       }
+}
+
+static const struct net_device_ops igb_netdev_ops = {
+       .ndo_open               = igb_open,
+       .ndo_stop               = igb_close,
+       .ndo_start_xmit         = igb_xmit_frame_adv,
+       .ndo_get_stats          = igb_get_stats,
+       .ndo_set_multicast_list = igb_set_multi,
+       .ndo_set_mac_address    = igb_set_mac,
+       .ndo_change_mtu         = igb_change_mtu,
+       .ndo_do_ioctl           = igb_ioctl,
+       .ndo_tx_timeout         = igb_tx_timeout,
+       .ndo_validate_addr      = eth_validate_addr,
+       .ndo_vlan_rx_register   = igb_vlan_rx_register,
+       .ndo_vlan_rx_add_vid    = igb_vlan_rx_add_vid,
+       .ndo_vlan_rx_kill_vid   = igb_vlan_rx_kill_vid,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+       .ndo_poll_controller    = igb_netpoll,
+#endif
+};
+
+/**
  * igb_probe - Device Initialization Routine
  * @pdev: PCI device information struct
  * @ent: entry in igb_pci_tbl
@@ -837,15 +1022,24 @@ static int __devinit igb_probe(struct pci_dev *pdev,
        struct net_device *netdev;
        struct igb_adapter *adapter;
        struct e1000_hw *hw;
+       struct pci_dev *us_dev;
        const struct e1000_info *ei = igb_info_tbl[ent->driver_data];
        unsigned long mmio_start, mmio_len;
-       static int cards_found;
-       int i, err, pci_using_dac;
-       u16 eeprom_data = 0;
+       int i, err, pci_using_dac, pos;
+       u16 eeprom_data = 0, state = 0;
        u16 eeprom_apme_mask = IGB_EEPROM_APME;
        u32 part_num;
+       int bars, need_ioport;
 
-       err = pci_enable_device(pdev);
+       /* do not allocate ioport bars when not needed */
+       need_ioport = igb_is_need_ioport(pdev);
+       if (need_ioport) {
+               bars = pci_select_bars(pdev, IORESOURCE_MEM | IORESOURCE_IO);
+               err = pci_enable_device(pdev);
+       } else {
+               bars = pci_select_bars(pdev, IORESOURCE_MEM);
+               err = pci_enable_device_mem(pdev);
+       }
        if (err)
                return err;
 
@@ -867,15 +1061,43 @@ static int __devinit igb_probe(struct pci_dev *pdev,
                }
        }
 
-       err = pci_request_regions(pdev, igb_driver_name);
+       /* 82575 requires that the pci-e link partner disable the L0s state */
+       switch (pdev->device) {
+       case E1000_DEV_ID_82575EB_COPPER:
+       case E1000_DEV_ID_82575EB_FIBER_SERDES:
+       case E1000_DEV_ID_82575GB_QUAD_COPPER:
+               us_dev = pdev->bus->self;
+               pos = pci_find_capability(us_dev, PCI_CAP_ID_EXP);
+               if (pos) {
+                       pci_read_config_word(us_dev, pos + PCI_EXP_LNKCTL,
+                                            &state);
+                       state &= ~PCIE_LINK_STATE_L0S;
+                       pci_write_config_word(us_dev, pos + PCI_EXP_LNKCTL,
+                                             state);
+                       dev_info(&pdev->dev,
+                                "Disabling ASPM L0s upstream switch port %s\n",
+                                pci_name(us_dev));
+               }
+       default:
+               break;
+       }
+
+       err = pci_request_selected_regions(pdev, bars, igb_driver_name);
        if (err)
                goto err_pci_reg;
 
+       err = pci_enable_pcie_error_reporting(pdev);
+       if (err) {
+               dev_err(&pdev->dev, "pci_enable_pcie_error_reporting failed "
+                       "0x%x\n", err);
+               /* non-fatal, continue */
+       }
+
        pci_set_master(pdev);
        pci_save_state(pdev);
 
        err = -ENOMEM;
-       netdev = alloc_etherdev(sizeof(struct igb_adapter));
+       netdev = alloc_etherdev_mq(sizeof(struct igb_adapter), IGB_MAX_TX_QUEUES);
        if (!netdev)
                goto err_alloc_etherdev;
 
@@ -888,6 +1110,8 @@ static int __devinit igb_probe(struct pci_dev *pdev,
        hw = &adapter->hw;
        hw->back = adapter;
        adapter->msg_enable = NETIF_MSG_DRV | NETIF_MSG_PROBE;
+       adapter->bars = bars;
+       adapter->need_ioport = need_ioport;
 
        mmio_start = pci_resource_start(pdev, 0);
        mmio_len = pci_resource_len(pdev, 0);
@@ -897,32 +1121,15 @@ static int __devinit igb_probe(struct pci_dev *pdev,
        if (!adapter->hw.hw_addr)
                goto err_ioremap;
 
-       netdev->open = &igb_open;
-       netdev->stop = &igb_close;
-       netdev->get_stats = &igb_get_stats;
-       netdev->set_multicast_list = &igb_set_multi;
-       netdev->set_mac_address = &igb_set_mac;
-       netdev->change_mtu = &igb_change_mtu;
-       netdev->do_ioctl = &igb_ioctl;
+       netdev->netdev_ops = &igb_netdev_ops;
        igb_set_ethtool_ops(netdev);
-       netdev->tx_timeout = &igb_tx_timeout;
        netdev->watchdog_timeo = 5 * HZ;
-       netif_napi_add(netdev, &adapter->napi, igb_clean, 64);
-       netdev->vlan_rx_register = igb_vlan_rx_register;
-       netdev->vlan_rx_add_vid = igb_vlan_rx_add_vid;
-       netdev->vlan_rx_kill_vid = igb_vlan_rx_kill_vid;
-#ifdef CONFIG_NET_POLL_CONTROLLER
-       netdev->poll_controller = igb_netpoll;
-#endif
-       netdev->hard_start_xmit = &igb_xmit_frame_adv;
 
        strncpy(netdev->name, pci_name(pdev), sizeof(netdev->name) - 1);
 
        netdev->mem_start = mmio_start;
        netdev->mem_end = mmio_start + mmio_len;
 
-       adapter->bd_number = cards_found;
-
        /* PCI config space info */
        hw->vendor_id = pdev->vendor;
        hw->device_id = pdev->device;
@@ -947,6 +1154,17 @@ static int __devinit igb_probe(struct pci_dev *pdev,
 
        igb_get_bus_info_pcie(hw);
 
+       /* set flags */
+       switch (hw->mac.type) {
+       case e1000_82576:
+       case e1000_82575:
+               adapter->flags |= IGB_FLAG_HAS_DCA;
+               adapter->flags |= IGB_FLAG_NEED_CTX_IDX;
+               break;
+       default:
+               break;
+       }
+
        hw->phy.autoneg_wait_to_complete = false;
        hw->mac.adaptive_ifs = true;
 
@@ -970,6 +1188,10 @@ static int __devinit igb_probe(struct pci_dev *pdev,
        netdev->features |= NETIF_F_TSO;
        netdev->features |= NETIF_F_TSO6;
 
+#ifdef CONFIG_IGB_LRO
+       netdev->features |= NETIF_F_LRO;
+#endif
+
        netdev->vlan_features |= NETIF_F_TSO;
        netdev->vlan_features |= NETIF_F_TSO6;
        netdev->vlan_features |= NETIF_F_HW_CSUM;
@@ -1058,6 +1280,8 @@ static int __devinit igb_probe(struct pci_dev *pdev,
                adapter->eeprom_wol = 0;
                break;
        case E1000_DEV_ID_82575EB_FIBER_SERDES:
+       case E1000_DEV_ID_82576_FIBER:
+       case E1000_DEV_ID_82576_SERDES:
                /* Wake events only supported on port A for dual fiber
                 * regardless of eeprom setting */
                if (rd32(E1000_STATUS) & E1000_STATUS_FUNC_1)
@@ -1067,6 +1291,7 @@ static int __devinit igb_probe(struct pci_dev *pdev,
 
        /* initialize the wol settings based on the eeprom settings */
        adapter->wol = adapter->eeprom_wol;
+       device_set_wakeup_enable(&adapter->pdev->dev, adapter->wol);
 
        /* reset the hardware with the new settings */
        igb_reset(adapter);
@@ -1077,25 +1302,35 @@ static int __devinit igb_probe(struct pci_dev *pdev,
 
        /* tell the stack to leave us alone until igb_open() is called */
        netif_carrier_off(netdev);
-       netif_stop_queue(netdev);
+       netif_tx_stop_all_queues(netdev);
 
        strcpy(netdev->name, "eth%d");
        err = register_netdev(netdev);
        if (err)
                goto err_register;
 
+#ifdef CONFIG_IGB_DCA
+       if ((adapter->flags & IGB_FLAG_HAS_DCA) &&
+           (dca_add_requester(&pdev->dev) == 0)) {
+               adapter->flags |= IGB_FLAG_DCA_ENABLED;
+               dev_info(&pdev->dev, "DCA enabled\n");
+               /* Always use CB2 mode, difference is masked
+                * in the CB driver. */
+               wr32(E1000_DCA_CTRL, 2);
+               igb_setup_dca(adapter);
+       }
+#endif
+
        dev_info(&pdev->dev, "Intel(R) Gigabit Ethernet Network Connection\n");
        /* print bus type/speed/width info */
-       dev_info(&pdev->dev,
-                "%s: (PCIe:%s:%s) %02x:%02x:%02x:%02x:%02x:%02x\n",
+       dev_info(&pdev->dev, "%s: (PCIe:%s:%s) %pM\n",
                 netdev->name,
                 ((hw->bus.speed == e1000_bus_speed_2500)
                  ? "2.5Gb/s" : "unknown"),
                 ((hw->bus.width == e1000_bus_width_pcie_x4)
                  ? "Width x4" : (hw->bus.width == e1000_bus_width_pcie_x1)
                  ? "Width x1" : "unknown"),
-                netdev->dev_addr[0], netdev->dev_addr[1], netdev->dev_addr[2],
-                netdev->dev_addr[3], netdev->dev_addr[4], netdev->dev_addr[5]);
+                netdev->dev_addr);
 
        igb_read_part_num(hw, &part_num);
        dev_info(&pdev->dev, "%s: PBA No: %06x-%03x\n", netdev->name,
@@ -1104,31 +1339,29 @@ static int __devinit igb_probe(struct pci_dev *pdev,
        dev_info(&pdev->dev,
                "Using %s interrupts. %d rx queue(s), %d tx queue(s)\n",
                adapter->msix_entries ? "MSI-X" :
-               adapter->msi_enabled ? "MSI" : "legacy",
+               (adapter->flags & IGB_FLAG_HAS_MSI) ? "MSI" : "legacy",
                adapter->num_rx_queues, adapter->num_tx_queues);
 
-       cards_found++;
        return 0;
 
 err_register:
        igb_release_hw_control(adapter);
 err_eeprom:
        if (!igb_check_reset_block(hw))
-               hw->phy.ops.reset_phy(hw);
+               igb_reset_phy(hw);
 
        if (hw->flash_address)
                iounmap(hw->flash_address);
 
        igb_remove_device(hw);
-       kfree(adapter->tx_ring);
-       kfree(adapter->rx_ring);
+       igb_free_queues(adapter);
 err_sw_init:
 err_hw_init:
        iounmap(hw->hw_addr);
 err_ioremap:
        free_netdev(netdev);
 err_alloc_etherdev:
-       pci_release_regions(pdev);
+       pci_release_selected_regions(pdev, bars);
 err_pci_reg:
 err_dma:
        pci_disable_device(pdev);
@@ -1148,6 +1381,10 @@ static void __devexit igb_remove(struct pci_dev *pdev)
 {
        struct net_device *netdev = pci_get_drvdata(pdev);
        struct igb_adapter *adapter = netdev_priv(netdev);
+#ifdef CONFIG_IGB_DCA
+       struct e1000_hw *hw = &adapter->hw;
+#endif
+       int err;
 
        /* flush_scheduled work may reschedule our watchdog task, so
         * explicitly disable watchdog tasks from being rescheduled  */
@@ -1157,6 +1394,15 @@ static void __devexit igb_remove(struct pci_dev *pdev)
 
        flush_scheduled_work();
 
+#ifdef CONFIG_IGB_DCA
+       if (adapter->flags & IGB_FLAG_DCA_ENABLED) {
+               dev_info(&pdev->dev, "DCA disabled\n");
+               dca_remove_requester(&pdev->dev);
+               adapter->flags &= ~IGB_FLAG_DCA_ENABLED;
+               wr32(E1000_DCA_CTRL, 1);
+       }
+#endif
+
        /* Release control of h/w to f/w.  If f/w is AMT enabled, this
         * would have already happened in close and is redundant. */
        igb_release_hw_control(adapter);
@@ -1164,21 +1410,25 @@ static void __devexit igb_remove(struct pci_dev *pdev)
        unregister_netdev(netdev);
 
        if (!igb_check_reset_block(&adapter->hw))
-               adapter->hw.phy.ops.reset_phy(&adapter->hw);
+               igb_reset_phy(&adapter->hw);
 
        igb_remove_device(&adapter->hw);
        igb_reset_interrupt_capability(adapter);
 
-       kfree(adapter->tx_ring);
-       kfree(adapter->rx_ring);
+       igb_free_queues(adapter);
 
        iounmap(adapter->hw.hw_addr);
        if (adapter->hw.flash_address)
                iounmap(adapter->hw.flash_address);
-       pci_release_regions(pdev);
+       pci_release_selected_regions(pdev, adapter->bars);
 
        free_netdev(netdev);
 
+       err = pci_disable_pcie_error_reporting(pdev);
+       if (err)
+               dev_err(&pdev->dev,
+                       "pci_disable_pcie_error_reporting failed 0x%x\n", err);
+
        pci_disable_device(pdev);
 }
 
@@ -1198,6 +1448,8 @@ static int __devinit igb_sw_init(struct igb_adapter *adapter)
 
        pci_read_config_word(pdev, PCI_COMMAND, &hw->bus.pci_cmd_word);
 
+       adapter->tx_ring_count = IGB_DEFAULT_TXD;
+       adapter->rx_ring_count = IGB_DEFAULT_RXD;
        adapter->rx_buffer_len = MAXIMUM_ETHERNET_VLAN_SIZE;
        adapter->rx_ps_hdr_size = 0; /* disable packet split */
        adapter->max_frame_size = netdev->mtu + ETH_HLEN + ETH_FCS_LEN;
@@ -1205,9 +1457,11 @@ static int __devinit igb_sw_init(struct igb_adapter *adapter)
 
        /* Number of supported queues. */
        /* Having more queues than CPUs doesn't make sense. */
-       adapter->num_tx_queues = 1;
-       adapter->num_rx_queues = min(IGB_MAX_RX_QUEUES, num_online_cpus());
+       adapter->num_rx_queues = min((u32)IGB_MAX_RX_QUEUES, (u32)num_online_cpus());
+       adapter->num_tx_queues = min(IGB_MAX_TX_QUEUES, num_online_cpus());
 
+       /* This call may decrease the number of queues depending on
+        * interrupt mode. */
        igb_set_interrupt_capability(adapter);
 
        if (igb_alloc_queues(adapter)) {
@@ -1275,15 +1529,16 @@ static int igb_open(struct net_device *netdev)
        /* From here on the code is the same as igb_up() */
        clear_bit(__IGB_DOWN, &adapter->state);
 
-       napi_enable(&adapter->napi);
-       if (adapter->msix_entries)
-               for (i = 0; i < adapter->num_rx_queues; i++)
-                       napi_enable(&adapter->rx_ring[i].napi);
-
-       igb_irq_enable(adapter);
+       for (i = 0; i < adapter->num_rx_queues; i++)
+               napi_enable(&adapter->rx_ring[i].napi);
 
        /* Clear any pending interrupts. */
        rd32(E1000_ICR);
+
+       igb_irq_enable(adapter);
+
+       netif_tx_start_all_queues(netdev);
+
        /* Fire a link status change interrupt to start the watchdog. */
        wr32(E1000_ICS, E1000_ICS_LSC);
 
@@ -1356,8 +1611,7 @@ int igb_setup_tx_resources(struct igb_adapter *adapter,
        memset(tx_ring->buffer_info, 0, size);
 
        /* round up to nearest 4K */
-       tx_ring->size = tx_ring->count * sizeof(struct e1000_tx_desc)
-                       + sizeof(u32);
+       tx_ring->size = tx_ring->count * sizeof(struct e1000_tx_desc);
        tx_ring->size = ALIGN(tx_ring->size, 4096);
 
        tx_ring->desc = pci_alloc_consistent(pdev, tx_ring->size,
@@ -1369,8 +1623,6 @@ int igb_setup_tx_resources(struct igb_adapter *adapter,
        tx_ring->adapter = adapter;
        tx_ring->next_to_use = 0;
        tx_ring->next_to_clean = 0;
-       spin_lock_init(&tx_ring->tx_clean_lock);
-       spin_lock_init(&tx_ring->tx_lock);
        return 0;
 
 err:
@@ -1390,6 +1642,7 @@ err:
 static int igb_setup_all_tx_resources(struct igb_adapter *adapter)
 {
        int i, err = 0;
+       int r_idx;
 
        for (i = 0; i < adapter->num_tx_queues; i++) {
                err = igb_setup_tx_resources(adapter, &adapter->tx_ring[i]);
@@ -1397,12 +1650,15 @@ static int igb_setup_all_tx_resources(struct igb_adapter *adapter)
                        dev_err(&adapter->pdev->dev,
                                "Allocation for Tx Queue %u failed\n", i);
                        for (i--; i >= 0; i--)
-                               igb_free_tx_resources(adapter,
-                                                       &adapter->tx_ring[i]);
+                               igb_free_tx_resources(&adapter->tx_ring[i]);
                        break;
                }
        }
 
+       for (i = 0; i < IGB_MAX_TX_QUEUES; i++) {
+               r_idx = i % adapter->num_tx_queues;
+               adapter->multi_tx_table[i] = &adapter->tx_ring[r_idx];
+       }       
        return err;
 }
 
@@ -1414,43 +1670,37 @@ static int igb_setup_all_tx_resources(struct igb_adapter *adapter)
  **/
 static void igb_configure_tx(struct igb_adapter *adapter)
 {
-       u64 tdba, tdwba;
+       u64 tdba;
        struct e1000_hw *hw = &adapter->hw;
        u32 tctl;
        u32 txdctl, txctrl;
-       int i;
+       int i, j;
 
        for (i = 0; i < adapter->num_tx_queues; i++) {
                struct igb_ring *ring = &(adapter->tx_ring[i]);
-
-               wr32(E1000_TDLEN(i),
+               j = ring->reg_idx;
+               wr32(E1000_TDLEN(j),
                                ring->count * sizeof(struct e1000_tx_desc));
                tdba = ring->dma;
-               wr32(E1000_TDBAL(i),
+               wr32(E1000_TDBAL(j),
                                tdba & 0x00000000ffffffffULL);
-               wr32(E1000_TDBAH(i), tdba >> 32);
+               wr32(E1000_TDBAH(j), tdba >> 32);
 
-               tdwba = ring->dma + ring->count * sizeof(struct e1000_tx_desc);
-               tdwba |= 1; /* enable head wb */
-               wr32(E1000_TDWBAL(i),
-                               tdwba & 0x00000000ffffffffULL);
-               wr32(E1000_TDWBAH(i), tdwba >> 32);
-
-               ring->head = E1000_TDH(i);
-               ring->tail = E1000_TDT(i);
+               ring->head = E1000_TDH(j);
+               ring->tail = E1000_TDT(j);
                writel(0, hw->hw_addr + ring->tail);
                writel(0, hw->hw_addr + ring->head);
-               txdctl = rd32(E1000_TXDCTL(i));
+               txdctl = rd32(E1000_TXDCTL(j));
                txdctl |= E1000_TXDCTL_QUEUE_ENABLE;
-               wr32(E1000_TXDCTL(i), txdctl);
+               wr32(E1000_TXDCTL(j), txdctl);
 
                /* Turn off Relaxed Ordering on head write-backs.  The
                 * writebacks MUST be delivered in order or it will
                 * completely screw up our bookeeping.
                 */
-               txctrl = rd32(E1000_DCA_TXCTRL(i));
+               txctrl = rd32(E1000_DCA_TXCTRL(j));
                txctrl &= ~E1000_DCA_TXCTRL_TX_WB_RO_EN;
-               wr32(E1000_DCA_TXCTRL(i), txctrl);
+               wr32(E1000_DCA_TXCTRL(j), txctrl);
        }
 
 
@@ -1489,6 +1739,14 @@ int igb_setup_rx_resources(struct igb_adapter *adapter,
        struct pci_dev *pdev = adapter->pdev;
        int size, desc_len;
 
+#ifdef CONFIG_IGB_LRO
+       size = sizeof(struct net_lro_desc) * MAX_LRO_DESCRIPTORS;
+       rx_ring->lro_mgr.lro_arr = vmalloc(size);
+       if (!rx_ring->lro_mgr.lro_arr)
+               goto err;
+       memset(rx_ring->lro_mgr.lro_arr, 0, size);
+#endif
+
        size = sizeof(struct igb_buffer) * rx_ring->count;
        rx_ring->buffer_info = vmalloc(size);
        if (!rx_ring->buffer_info)
@@ -1509,15 +1767,16 @@ int igb_setup_rx_resources(struct igb_adapter *adapter,
 
        rx_ring->next_to_clean = 0;
        rx_ring->next_to_use = 0;
-       rx_ring->pending_skb = NULL;
 
        rx_ring->adapter = adapter;
-       /* FIXME: do we want to setup ring->napi->poll here? */
-       rx_ring->napi.poll = adapter->napi.poll;
 
        return 0;
 
 err:
+#ifdef CONFIG_IGB_LRO
+       vfree(rx_ring->lro_mgr.lro_arr);
+       rx_ring->lro_mgr.lro_arr = NULL;
+#endif
        vfree(rx_ring->buffer_info);
        dev_err(&adapter->pdev->dev, "Unable to allocate memory for "
                "the receive descriptor ring\n");
@@ -1541,8 +1800,7 @@ static int igb_setup_all_rx_resources(struct igb_adapter *adapter)
                        dev_err(&adapter->pdev->dev,
                                "Allocation for Rx Queue %u failed\n", i);
                        for (i--; i >= 0; i--)
-                               igb_free_rx_resources(adapter,
-                                                       &adapter->rx_ring[i]);
+                               igb_free_rx_resources(&adapter->rx_ring[i]);
                        break;
                }
        }
@@ -1559,62 +1817,43 @@ static void igb_setup_rctl(struct igb_adapter *adapter)
        struct e1000_hw *hw = &adapter->hw;
        u32 rctl;
        u32 srrctl = 0;
-       int i;
+       int i, j;
 
        rctl = rd32(E1000_RCTL);
 
        rctl &= ~(3 << E1000_RCTL_MO_SHIFT);
+       rctl &= ~(E1000_RCTL_LBM_TCVR | E1000_RCTL_LBM_MAC);
 
-       rctl |= E1000_RCTL_EN | E1000_RCTL_BAM |
-               E1000_RCTL_LBM_NO | E1000_RCTL_RDMTS_HALF |
+       rctl |= E1000_RCTL_EN | E1000_RCTL_BAM | E1000_RCTL_RDMTS_HALF |
                (adapter->hw.mac.mc_filter_type << E1000_RCTL_MO_SHIFT);
 
-       /* disable the stripping of CRC because it breaks
-        * BMC firmware connected over SMBUS
-       rctl |= E1000_RCTL_SECRC;
+       /*
+        * enable stripping of CRC. It's unlikely this will break BMC
+        * redirection as it did with e1000. Newer features require
+        * that the HW strips the CRC.
        */
+       rctl |= E1000_RCTL_SECRC;
 
-       rctl &= ~E1000_RCTL_SBP;
+       /*
+        * disable store bad packets, long packet enable, and clear size bits.
+        */
+       rctl &= ~(E1000_RCTL_SBP | E1000_RCTL_LPE | E1000_RCTL_SZ_256);
 
-       if (adapter->netdev->mtu <= ETH_DATA_LEN)
-               rctl &= ~E1000_RCTL_LPE;
-       else
+       if (adapter->netdev->mtu > ETH_DATA_LEN)
                rctl |= E1000_RCTL_LPE;
-       if (adapter->rx_buffer_len <= IGB_RXBUFFER_2048) {
-               /* Setup buffer sizes */
-               rctl &= ~E1000_RCTL_SZ_4096;
-               rctl |= E1000_RCTL_BSEX;
-               switch (adapter->rx_buffer_len) {
-               case IGB_RXBUFFER_256:
-                       rctl |= E1000_RCTL_SZ_256;
-                       rctl &= ~E1000_RCTL_BSEX;
-                       break;
-               case IGB_RXBUFFER_512:
-                       rctl |= E1000_RCTL_SZ_512;
-                       rctl &= ~E1000_RCTL_BSEX;
-                       break;
-               case IGB_RXBUFFER_1024:
-                       rctl |= E1000_RCTL_SZ_1024;
-                       rctl &= ~E1000_RCTL_BSEX;
-                       break;
-               case IGB_RXBUFFER_2048:
-               default:
-                       rctl |= E1000_RCTL_SZ_2048;
-                       rctl &= ~E1000_RCTL_BSEX;
-                       break;
-               case IGB_RXBUFFER_4096:
-                       rctl |= E1000_RCTL_SZ_4096;
-                       break;
-               case IGB_RXBUFFER_8192:
-                       rctl |= E1000_RCTL_SZ_8192;
-                       break;
-               case IGB_RXBUFFER_16384:
-                       rctl |= E1000_RCTL_SZ_16384;
-                       break;
-               }
-       } else {
-               rctl &= ~E1000_RCTL_BSEX;
-               srrctl = adapter->rx_buffer_len >> E1000_SRRCTL_BSIZEPKT_SHIFT;
+
+       /* Setup buffer sizes */
+       switch (adapter->rx_buffer_len) {
+       case IGB_RXBUFFER_256:
+               rctl |= E1000_RCTL_SZ_256;
+               break;
+       case IGB_RXBUFFER_512:
+               rctl |= E1000_RCTL_SZ_512;
+               break;
+       default:
+               srrctl = ALIGN(adapter->rx_buffer_len, 1024)
+                        >> E1000_SRRCTL_BSIZEPKT_SHIFT;
+               break;
        }
 
        /* 82575 and greater support packet-split where the protocol
@@ -1628,18 +1867,18 @@ static void igb_setup_rctl(struct igb_adapter *adapter)
         * so only enable packet split for jumbo frames */
        if (rctl & E1000_RCTL_LPE) {
                adapter->rx_ps_hdr_size = IGB_RXBUFFER_128;
-               srrctl = adapter->rx_ps_hdr_size <<
+               srrctl |= adapter->rx_ps_hdr_size <<
                         E1000_SRRCTL_BSIZEHDRSIZE_SHIFT;
-               /* buffer size is ALWAYS one page */
-               srrctl |= PAGE_SIZE >> E1000_SRRCTL_BSIZEPKT_SHIFT;
                srrctl |= E1000_SRRCTL_DESCTYPE_HDR_SPLIT_ALWAYS;
        } else {
                adapter->rx_ps_hdr_size = 0;
                srrctl |= E1000_SRRCTL_DESCTYPE_ADV_ONEBUF;
        }
 
-       for (i = 0; i < adapter->num_rx_queues; i++)
-               wr32(E1000_SRRCTL(i), srrctl);
+       for (i = 0; i < adapter->num_rx_queues; i++) {
+               j = adapter->rx_ring[i].reg_idx;
+               wr32(E1000_SRRCTL(j), srrctl);
+       }
 
        wr32(E1000_RCTL, rctl);
 }
@@ -1656,7 +1895,7 @@ static void igb_configure_rx(struct igb_adapter *adapter)
        struct e1000_hw *hw = &adapter->hw;
        u32 rctl, rxcsum;
        u32 rxdctl;
-       int i;
+       int i, j;
 
        /* disable receives while setting up the descriptors */
        rctl = rd32(E1000_RCTL);
@@ -1665,32 +1904,42 @@ static void igb_configure_rx(struct igb_adapter *adapter)
        mdelay(10);
 
        if (adapter->itr_setting > 3)
-               wr32(E1000_ITR,
-                               1000000000 / (adapter->itr * 256));
+               wr32(E1000_ITR, adapter->itr);
 
        /* Setup the HW Rx Head and Tail Descriptor Pointers and
         * the Base and Length of the Rx Descriptor Ring */
        for (i = 0; i < adapter->num_rx_queues; i++) {
                struct igb_ring *ring = &(adapter->rx_ring[i]);
+               j = ring->reg_idx;
                rdba = ring->dma;
-               wr32(E1000_RDBAL(i),
+               wr32(E1000_RDBAL(j),
                                rdba & 0x00000000ffffffffULL);
-               wr32(E1000_RDBAH(i), rdba >> 32);
-               wr32(E1000_RDLEN(i),
+               wr32(E1000_RDBAH(j), rdba >> 32);
+               wr32(E1000_RDLEN(j),
                               ring->count * sizeof(union e1000_adv_rx_desc));
 
-               ring->head = E1000_RDH(i);
-               ring->tail = E1000_RDT(i);
+               ring->head = E1000_RDH(j);
+               ring->tail = E1000_RDT(j);
                writel(0, hw->hw_addr + ring->tail);
                writel(0, hw->hw_addr + ring->head);
 
-               rxdctl = rd32(E1000_RXDCTL(i));
+               rxdctl = rd32(E1000_RXDCTL(j));
                rxdctl |= E1000_RXDCTL_QUEUE_ENABLE;
                rxdctl &= 0xFFF00000;
                rxdctl |= IGB_RX_PTHRESH;
                rxdctl |= IGB_RX_HTHRESH << 8;
                rxdctl |= IGB_RX_WTHRESH << 16;
-               wr32(E1000_RXDCTL(i), rxdctl);
+               wr32(E1000_RXDCTL(j), rxdctl);
+#ifdef CONFIG_IGB_LRO
+               /* Intitial LRO Settings */
+               ring->lro_mgr.max_aggr = MAX_LRO_AGGR;
+               ring->lro_mgr.max_desc = MAX_LRO_DESCRIPTORS;
+               ring->lro_mgr.get_skb_header = igb_get_skb_hdr;
+               ring->lro_mgr.features = LRO_F_NAPI | LRO_F_EXTRACT_VLAN_ID;
+               ring->lro_mgr.dev = adapter->netdev;
+               ring->lro_mgr.ip_summed = CHECKSUM_UNNECESSARY;
+               ring->lro_mgr.ip_summed_aggr = CHECKSUM_UNNECESSARY;
+#endif
        }
 
        if (adapter->num_rx_queues > 1) {
@@ -1704,10 +1953,13 @@ static void igb_configure_rx(struct igb_adapter *adapter)
 
                get_random_bytes(&random[0], 40);
 
-               shift = 6;
+               if (hw->mac.type >= e1000_82576)
+                       shift = 0;
+               else
+                       shift = 6;
                for (j = 0; j < (32 * 4); j++) {
                        reta.bytes[j & 3] =
-                               (j % adapter->num_rx_queues) << shift;
+                               adapter->rx_ring[(j % adapter->num_rx_queues)].reg_idx << shift;
                        if ((j & 3) == 3)
                                writel(reta.dword,
                                       hw->hw_addr + E1000_RETA(0) + (j & ~3));
@@ -1765,17 +2017,15 @@ static void igb_configure_rx(struct igb_adapter *adapter)
 
 /**
  * igb_free_tx_resources - Free Tx Resources per Queue
- * @adapter: board private structure
  * @tx_ring: Tx descriptor ring for a specific queue
  *
  * Free all transmit software resources
  **/
-static void igb_free_tx_resources(struct igb_adapter *adapter,
-                                 struct igb_ring *tx_ring)
+void igb_free_tx_resources(struct igb_ring *tx_ring)
 {
-       struct pci_dev *pdev = adapter->pdev;
+       struct pci_dev *pdev = tx_ring->adapter->pdev;
 
-       igb_clean_tx_ring(adapter, tx_ring);
+       igb_clean_tx_ring(tx_ring);
 
        vfree(tx_ring->buffer_info);
        tx_ring->buffer_info = NULL;
@@ -1796,7 +2046,7 @@ static void igb_free_all_tx_resources(struct igb_adapter *adapter)
        int i;
 
        for (i = 0; i < adapter->num_tx_queues; i++)
-               igb_free_tx_resources(adapter, &adapter->tx_ring[i]);
+               igb_free_tx_resources(&adapter->tx_ring[i]);
 }
 
 static void igb_unmap_and_free_tx_resource(struct igb_adapter *adapter,
@@ -1819,12 +2069,11 @@ static void igb_unmap_and_free_tx_resource(struct igb_adapter *adapter,
 
 /**
  * igb_clean_tx_ring - Free Tx Buffers
- * @adapter: board private structure
  * @tx_ring: ring to be cleaned
  **/
-static void igb_clean_tx_ring(struct igb_adapter *adapter,
-                             struct igb_ring *tx_ring)
+static void igb_clean_tx_ring(struct igb_ring *tx_ring)
 {
+       struct igb_adapter *adapter = tx_ring->adapter;
        struct igb_buffer *buffer_info;
        unsigned long size;
        unsigned int i;
@@ -1861,26 +2110,29 @@ static void igb_clean_all_tx_rings(struct igb_adapter *adapter)
        int i;
 
        for (i = 0; i < adapter->num_tx_queues; i++)
-               igb_clean_tx_ring(adapter, &adapter->tx_ring[i]);
+               igb_clean_tx_ring(&adapter->tx_ring[i]);
 }
 
 /**
  * igb_free_rx_resources - Free Rx Resources
- * @adapter: board private structure
  * @rx_ring: ring to clean the resources from
  *
  * Free all receive software resources
  **/
-static void igb_free_rx_resources(struct igb_adapter *adapter,
-                                 struct igb_ring *rx_ring)
+void igb_free_rx_resources(struct igb_ring *rx_ring)
 {
-       struct pci_dev *pdev = adapter->pdev;
+       struct pci_dev *pdev = rx_ring->adapter->pdev;
 
-       igb_clean_rx_ring(adapter, rx_ring);
+       igb_clean_rx_ring(rx_ring);
 
        vfree(rx_ring->buffer_info);
        rx_ring->buffer_info = NULL;
 
+#ifdef CONFIG_IGB_LRO
+       vfree(rx_ring->lro_mgr.lro_arr);
+       rx_ring->lro_mgr.lro_arr = NULL;
+#endif 
+
        pci_free_consistent(pdev, rx_ring->size, rx_ring->desc, rx_ring->dma);
 
        rx_ring->desc = NULL;
@@ -1897,17 +2149,16 @@ static void igb_free_all_rx_resources(struct igb_adapter *adapter)
        int i;
 
        for (i = 0; i < adapter->num_rx_queues; i++)
-               igb_free_rx_resources(adapter, &adapter->rx_ring[i]);
+               igb_free_rx_resources(&adapter->rx_ring[i]);
 }
 
 /**
  * igb_clean_rx_ring - Free Rx Buffers per Queue
- * @adapter: board private structure
  * @rx_ring: ring to free buffers from
  **/
-static void igb_clean_rx_ring(struct igb_adapter *adapter,
-                             struct igb_ring *rx_ring)
+static void igb_clean_rx_ring(struct igb_ring *rx_ring)
 {
+       struct igb_adapter *adapter = rx_ring->adapter;
        struct igb_buffer *buffer_info;
        struct pci_dev *pdev = adapter->pdev;
        unsigned long size;
@@ -1935,20 +2186,17 @@ static void igb_clean_rx_ring(struct igb_adapter *adapter,
                        buffer_info->skb = NULL;
                }
                if (buffer_info->page) {
-                       pci_unmap_page(pdev, buffer_info->page_dma,
-                                      PAGE_SIZE, PCI_DMA_FROMDEVICE);
+                       if (buffer_info->page_dma)
+                               pci_unmap_page(pdev, buffer_info->page_dma,
+                                              PAGE_SIZE / 2,
+                                              PCI_DMA_FROMDEVICE);
                        put_page(buffer_info->page);
                        buffer_info->page = NULL;
                        buffer_info->page_dma = 0;
+                       buffer_info->page_offset = 0;
                }
        }
 
-       /* there also may be some cached data from a chained receive */
-       if (rx_ring->pending_skb) {
-               dev_kfree_skb(rx_ring->pending_skb);
-               rx_ring->pending_skb = NULL;
-       }
-
        size = sizeof(struct igb_buffer) * rx_ring->count;
        memset(rx_ring->buffer_info, 0, size);
 
@@ -1971,7 +2219,7 @@ static void igb_clean_all_rx_rings(struct igb_adapter *adapter)
        int i;
 
        for (i = 0; i < adapter->num_rx_queues; i++)
-               igb_clean_rx_ring(adapter, &adapter->rx_ring[i]);
+               igb_clean_rx_ring(&adapter->rx_ring[i]);
 }
 
 /**
@@ -2020,19 +2268,22 @@ static void igb_set_multi(struct net_device *netdev)
 
        rctl = rd32(E1000_RCTL);
 
-       if (netdev->flags & IFF_PROMISC)
+       if (netdev->flags & IFF_PROMISC) {
                rctl |= (E1000_RCTL_UPE | E1000_RCTL_MPE);
-       else if (netdev->flags & IFF_ALLMULTI) {
-               rctl |= E1000_RCTL_MPE;
-               rctl &= ~E1000_RCTL_UPE;
-       } else
-               rctl &= ~(E1000_RCTL_UPE | E1000_RCTL_MPE);
-
+               rctl &= ~E1000_RCTL_VFE;
+       } else {
+               if (netdev->flags & IFF_ALLMULTI) {
+                       rctl |= E1000_RCTL_MPE;
+                       rctl &= ~E1000_RCTL_UPE;
+               } else
+                       rctl &= ~(E1000_RCTL_UPE | E1000_RCTL_MPE);
+               rctl |= E1000_RCTL_VFE;
+       }
        wr32(E1000_RCTL, rctl);
 
        if (!netdev->mc_count) {
                /* nothing to program, so clear mc list */
-               igb_update_mc_addr_list(hw, NULL, 0, 1,
+               igb_update_mc_addr_list_82575(hw, NULL, 0, 1,
                                          mac->rar_entry_count);
                return;
        }
@@ -2050,7 +2301,8 @@ static void igb_set_multi(struct net_device *netdev)
                memcpy(mta_list + (i*ETH_ALEN), mc_ptr->dmi_addr, ETH_ALEN);
                mc_ptr = mc_ptr->next;
        }
-       igb_update_mc_addr_list(hw, mta_list, i, 1, mac->rar_entry_count);
+       igb_update_mc_addr_list_82575(hw, mta_list, i, 1,
+                                     mac->rar_entry_count);
        kfree(mta_list);
 }
 
@@ -2059,8 +2311,7 @@ static void igb_set_multi(struct net_device *netdev)
 static void igb_update_phy_info(unsigned long data)
 {
        struct igb_adapter *adapter = (struct igb_adapter *) data;
-       if (adapter->hw.phy.ops.get_phy_info)
-               adapter->hw.phy.ops.get_phy_info(&adapter->hw);
+       igb_get_phy_info(&adapter->hw);
 }
 
 /**
@@ -2084,7 +2335,9 @@ static void igb_watchdog_task(struct work_struct *work)
        struct igb_ring *tx_ring = adapter->tx_ring;
        struct e1000_mac_info *mac = &adapter->hw.mac;
        u32 link;
+       u32 eics = 0;
        s32 ret_val;
+       int i;
 
        if ((netif_carrier_ok(netdev)) &&
            (rd32(E1000_STATUS) & E1000_STATUS_LU))
@@ -2113,9 +2366,10 @@ static void igb_watchdog_task(struct work_struct *work)
                                                   &adapter->link_duplex);
 
                        ctrl = rd32(E1000_CTRL);
-                       dev_info(&adapter->pdev->dev,
-                                "NIC Link is Up %d Mbps %s, "
+                       /* Links status message must follow this format */
+                       printk(KERN_INFO "igb: %s NIC Link is Up %d Mbps %s, "
                                 "Flow Control: %s\n",
+                                netdev->name,
                                 adapter->link_speed,
                                 adapter->link_duplex == FULL_DUPLEX ?
                                 "Full Duplex" : "Half Duplex",
@@ -2140,7 +2394,7 @@ static void igb_watchdog_task(struct work_struct *work)
                        }
 
                        netif_carrier_on(netdev);
-                       netif_wake_queue(netdev);
+                       netif_tx_wake_all_queues(netdev);
 
                        if (!test_bit(__IGB_DOWN, &adapter->state))
                                mod_timer(&adapter->phy_info_timer,
@@ -2150,9 +2404,11 @@ static void igb_watchdog_task(struct work_struct *work)
                if (netif_carrier_ok(netdev)) {
                        adapter->link_speed = 0;
                        adapter->link_duplex = 0;
-                       dev_info(&adapter->pdev->dev, "NIC Link is Down\n");
+                       /* Links status message must follow this format */
+                       printk(KERN_INFO "igb: %s NIC Link is Down\n",
+                              netdev->name);
                        netif_carrier_off(netdev);
-                       netif_stop_queue(netdev);
+                       netif_tx_stop_all_queues(netdev);
                        if (!test_bit(__IGB_DOWN, &adapter->state))
                                mod_timer(&adapter->phy_info_timer,
                                          round_jiffies(jiffies + 2 * HZ));
@@ -2186,7 +2442,13 @@ link_up:
        }
 
        /* Cause software interrupt to ensure rx ring is cleaned */
-       wr32(E1000_ICS, E1000_ICS_RXDMT0);
+       if (adapter->msix_entries) {
+               for (i = 0; i < adapter->num_rx_queues; i++)
+                       eics |= adapter->rx_ring[i].eims_value;
+               wr32(E1000_EICS, eics);
+       } else {
+               wr32(E1000_ICS, E1000_ICS_RXDMT0);
+       }
 
        /* Force detection of hung controller every watchdog period */
        tx_ring->detect_tx_hung = true;
@@ -2205,38 +2467,60 @@ enum latency_range {
 };
 
 
-static void igb_lower_rx_eitr(struct igb_adapter *adapter,
-                             struct igb_ring *rx_ring)
+/**
+ * igb_update_ring_itr - update the dynamic ITR value based on packet size
+ *
+ *      Stores a new ITR value based on strictly on packet size.  This
+ *      algorithm is less sophisticated than that used in igb_update_itr,
+ *      due to the difficulty of synchronizing statistics across multiple
+ *      receive rings.  The divisors and thresholds used by this fuction
+ *      were determined based on theoretical maximum wire speed and testing
+ *      data, in order to minimize response time while increasing bulk
+ *      throughput.
+ *      This functionality is controlled by the InterruptThrottleRate module
+ *      parameter (see igb_param.c)
+ *      NOTE:  This function is called only when operating in a multiqueue
+ *             receive environment.
+ * @rx_ring: pointer to ring
+ **/
+static void igb_update_ring_itr(struct igb_ring *rx_ring)
 {
-       struct e1000_hw *hw = &adapter->hw;
-       int new_val;
+       int new_val = rx_ring->itr_val;
+       int avg_wire_size = 0;
+       struct igb_adapter *adapter = rx_ring->adapter;
 
-       new_val = rx_ring->itr_val / 2;
-       if (new_val < IGB_MIN_DYN_ITR)
-               new_val = IGB_MIN_DYN_ITR;
+       if (!rx_ring->total_packets)
+               goto clear_counts; /* no packets, so don't do anything */
 
-       if (new_val != rx_ring->itr_val) {
-               rx_ring->itr_val = new_val;
-               wr32(rx_ring->itr_register,
-                               1000000000 / (new_val * 256));
+       /* For non-gigabit speeds, just fix the interrupt rate at 4000
+        * ints/sec - ITR timer value of 120 ticks.
+        */
+       if (adapter->link_speed != SPEED_1000) {
+               new_val = 120;
+               goto set_itr_val;
        }
-}
+       avg_wire_size = rx_ring->total_bytes / rx_ring->total_packets;
 
-static void igb_raise_rx_eitr(struct igb_adapter *adapter,
-                             struct igb_ring *rx_ring)
-{
-       struct e1000_hw *hw = &adapter->hw;
-       int new_val;
+       /* Add 24 bytes to size to account for CRC, preamble, and gap */
+       avg_wire_size += 24;
+
+       /* Don't starve jumbo frames */
+       avg_wire_size = min(avg_wire_size, 3000);
 
-       new_val = rx_ring->itr_val * 2;
-       if (new_val > IGB_MAX_DYN_ITR)
-               new_val = IGB_MAX_DYN_ITR;
+       /* Give a little boost to mid-size frames */
+       if ((avg_wire_size > 300) && (avg_wire_size < 1200))
+               new_val = avg_wire_size / 3;
+       else
+               new_val = avg_wire_size / 2;
 
+set_itr_val:
        if (new_val != rx_ring->itr_val) {
                rx_ring->itr_val = new_val;
-               wr32(rx_ring->itr_register,
-                               1000000000 / (new_val * 256));
+               rx_ring->set_itr = 1;
        }
+clear_counts:
+       rx_ring->total_bytes = 0;
+       rx_ring->total_packets = 0;
 }
 
 /**
@@ -2303,8 +2587,7 @@ update_itr_done:
        return retval;
 }
 
-static void igb_set_itr(struct igb_adapter *adapter, u16 itr_register,
-                       int rx_only)
+static void igb_set_itr(struct igb_adapter *adapter)
 {
        u16 current_itr;
        u32 new_itr = adapter->itr;
@@ -2320,26 +2603,23 @@ static void igb_set_itr(struct igb_adapter *adapter, u16 itr_register,
                                    adapter->rx_itr,
                                    adapter->rx_ring->total_packets,
                                    adapter->rx_ring->total_bytes);
-       /* conservative mode (itr 3) eliminates the lowest_latency setting */
-       if (adapter->itr_setting == 3 && adapter->rx_itr == lowest_latency)
-               adapter->rx_itr = low_latency;
 
-       if (!rx_only) {
+       if (adapter->rx_ring->buddy) {
                adapter->tx_itr = igb_update_itr(adapter,
                                            adapter->tx_itr,
                                            adapter->tx_ring->total_packets,
                                            adapter->tx_ring->total_bytes);
-               /* conservative mode (itr 3) eliminates the
-                * lowest_latency setting */
-               if (adapter->itr_setting == 3 &&
-                   adapter->tx_itr == lowest_latency)
-                       adapter->tx_itr = low_latency;
 
                current_itr = max(adapter->rx_itr, adapter->tx_itr);
        } else {
                current_itr = adapter->rx_itr;
        }
 
+       /* conservative mode (itr 3) eliminates the lowest_latency setting */
+       if (adapter->itr_setting == 3 &&
+           current_itr == lowest_latency)
+               current_itr = low_latency;
+
        switch (current_itr) {
        /* counts and packets in update_itr are dependent on these numbers */
        case lowest_latency:
@@ -2356,6 +2636,13 @@ static void igb_set_itr(struct igb_adapter *adapter, u16 itr_register,
        }
 
 set_itr_now:
+       adapter->rx_ring->total_bytes = 0;
+       adapter->rx_ring->total_packets = 0;
+       if (adapter->rx_ring->buddy) {
+               adapter->rx_ring->buddy->total_bytes = 0;
+               adapter->rx_ring->buddy->total_packets = 0;
+       }
+
        if (new_itr != adapter->itr) {
                /* this attempts to bias the interrupt rate towards Bulk
                 * by adding intermediate steps when interrupt rate is
@@ -2370,7 +2657,8 @@ set_itr_now:
                 * ends up being correct.
                 */
                adapter->itr = new_itr;
-               adapter->set_itr = 1;
+               adapter->rx_ring->itr_val = 1000000000 / (new_itr * 256);
+               adapter->rx_ring->set_itr = 1;
        }
 
        return;
@@ -2446,14 +2734,15 @@ static inline int igb_tso_adv(struct igb_adapter *adapter,
        mss_l4len_idx = (skb_shinfo(skb)->gso_size << E1000_ADVTXD_MSS_SHIFT);
        mss_l4len_idx |= (l4len << E1000_ADVTXD_L4LEN_SHIFT);
 
-       /* Context index must be unique per ring.  Luckily, so is the interrupt
-        * mask value. */
-       mss_l4len_idx |= tx_ring->eims_value >> 4;
+       /* Context index must be unique per ring. */
+       if (adapter->flags & IGB_FLAG_NEED_CTX_IDX)
+               mss_l4len_idx |= tx_ring->queue_index << 4;
 
        context_desc->mss_l4len_idx = cpu_to_le32(mss_l4len_idx);
        context_desc->seqnum_seed = 0;
 
        buffer_info->time_stamp = jiffies;
+       buffer_info->next_to_watch = i;
        buffer_info->dma = 0;
        i++;
        if (i == tx_ring->count)
@@ -2512,10 +2801,12 @@ static inline bool igb_tx_csum_adv(struct igb_adapter *adapter,
 
                context_desc->type_tucmd_mlhl = cpu_to_le32(tu_cmd);
                context_desc->seqnum_seed = 0;
-               context_desc->mss_l4len_idx =
-                                         cpu_to_le32(tx_ring->eims_value >> 4);
+               if (adapter->flags & IGB_FLAG_NEED_CTX_IDX)
+                       context_desc->mss_l4len_idx =
+                               cpu_to_le32(tx_ring->queue_index << 4);
 
                buffer_info->time_stamp = jiffies;
+               buffer_info->next_to_watch = i;
                buffer_info->dma = 0;
 
                i++;
@@ -2534,8 +2825,8 @@ static inline bool igb_tx_csum_adv(struct igb_adapter *adapter,
 #define IGB_MAX_DATA_PER_TXD   (1<<IGB_MAX_TXD_PWR)
 
 static inline int igb_tx_map_adv(struct igb_adapter *adapter,
-                                struct igb_ring *tx_ring,
-                                struct sk_buff *skb)
+                                struct igb_ring *tx_ring, struct sk_buff *skb,
+                                unsigned int first)
 {
        struct igb_buffer *buffer_info;
        unsigned int len = skb_headlen(skb);
@@ -2549,6 +2840,7 @@ static inline int igb_tx_map_adv(struct igb_adapter *adapter,
        buffer_info->length = len;
        /* set time_stamp *before* dma to help avoid a possible race */
        buffer_info->time_stamp = jiffies;
+       buffer_info->next_to_watch = i;
        buffer_info->dma = pci_map_single(adapter->pdev, skb->data, len,
                                          PCI_DMA_TODEVICE);
        count++;
@@ -2566,6 +2858,7 @@ static inline int igb_tx_map_adv(struct igb_adapter *adapter,
                BUG_ON(len >= IGB_MAX_DATA_PER_TXD);
                buffer_info->length = len;
                buffer_info->time_stamp = jiffies;
+               buffer_info->next_to_watch = i;
                buffer_info->dma = pci_map_page(adapter->pdev,
                                                frag->page,
                                                frag->page_offset,
@@ -2578,8 +2871,9 @@ static inline int igb_tx_map_adv(struct igb_adapter *adapter,
                        i = 0;
        }
 
-       i = (i == 0) ? tx_ring->count - 1 : i - 1;
+       i = ((i == 0) ? tx_ring->count - 1 : i - 1);
        tx_ring->buffer_info[i].skb = skb;
+       tx_ring->buffer_info[first].next_to_watch = i;
 
        return count;
 }
@@ -2614,9 +2908,10 @@ static inline void igb_tx_queue_adv(struct igb_adapter *adapter,
                olinfo_status |= E1000_TXD_POPTS_TXSM << 8;
        }
 
-       if (tx_flags & (IGB_TX_FLAGS_CSUM | IGB_TX_FLAGS_TSO |
-                       IGB_TX_FLAGS_VLAN))
-               olinfo_status |= tx_ring->eims_value >> 4;
+       if ((adapter->flags & IGB_FLAG_NEED_CTX_IDX) &&
+           (tx_flags & (IGB_TX_FLAGS_CSUM | IGB_TX_FLAGS_TSO |
+                        IGB_TX_FLAGS_VLAN)))
+               olinfo_status |= tx_ring->queue_index << 4;
 
        olinfo_status |= ((paylen - hdr_len) << E1000_ADVTXD_PAYLEN_SHIFT);
 
@@ -2652,7 +2947,8 @@ static int __igb_maybe_stop_tx(struct net_device *netdev,
 {
        struct igb_adapter *adapter = netdev_priv(netdev);
 
-       netif_stop_queue(netdev);
+       netif_stop_subqueue(netdev, tx_ring->queue_index);
+
        /* Herbert's original patch had:
         *  smp_mb__after_netif_stop_queue();
         * but since that doesn't exist yet, just open code it. */
@@ -2664,7 +2960,7 @@ static int __igb_maybe_stop_tx(struct net_device *netdev,
                return -EBUSY;
 
        /* A reprieve! */
-       netif_start_queue(netdev);
+       netif_wake_subqueue(netdev, tx_ring->queue_index);
        ++adapter->restart_queue;
        return 0;
 }
@@ -2684,9 +2980,9 @@ static int igb_xmit_frame_ring_adv(struct sk_buff *skb,
                                   struct igb_ring *tx_ring)
 {
        struct igb_adapter *adapter = netdev_priv(netdev);
+       unsigned int first;
        unsigned int tx_flags = 0;
        unsigned int len;
-       unsigned long irq_flags;
        u8 hdr_len = 0;
        int tso = 0;
 
@@ -2702,10 +2998,6 @@ static int igb_xmit_frame_ring_adv(struct sk_buff *skb,
                return NETDEV_TX_OK;
        }
 
-       if (!spin_trylock_irqsave(&tx_ring->tx_lock, irq_flags))
-               /* Collision - tell upper layer to requeue */
-               return NETDEV_TX_LOCKED;
-
        /* need: 1 descriptor per page,
         *       + 2 desc gap to keep tail from touching head,
         *       + 1 desc for skb->data,
@@ -2713,21 +3005,25 @@ static int igb_xmit_frame_ring_adv(struct sk_buff *skb,
         * otherwise try next time */
        if (igb_maybe_stop_tx(netdev, tx_ring, skb_shinfo(skb)->nr_frags + 4)) {
                /* this is a hard error */
-               spin_unlock_irqrestore(&tx_ring->tx_lock, irq_flags);
                return NETDEV_TX_BUSY;
        }
+       skb_orphan(skb);
 
        if (adapter->vlgrp && vlan_tx_tag_present(skb)) {
                tx_flags |= IGB_TX_FLAGS_VLAN;
                tx_flags |= (vlan_tx_tag_get(skb) << IGB_TX_FLAGS_VLAN_SHIFT);
        }
 
+       if (skb->protocol == htons(ETH_P_IP))
+               tx_flags |= IGB_TX_FLAGS_IPV4;
+
+       first = tx_ring->next_to_use;
+
        tso = skb_is_gso(skb) ? igb_tso_adv(adapter, tx_ring, skb, tx_flags,
                                              &hdr_len) : 0;
 
        if (tso < 0) {
                dev_kfree_skb_any(skb);
-               spin_unlock_irqrestore(&tx_ring->tx_lock, irq_flags);
                return NETDEV_TX_OK;
        }
 
@@ -2737,11 +3033,8 @@ static int igb_xmit_frame_ring_adv(struct sk_buff *skb,
                        if (skb->ip_summed == CHECKSUM_PARTIAL)
                                tx_flags |= IGB_TX_FLAGS_CSUM;
 
-       if (skb->protocol == htons(ETH_P_IP))
-               tx_flags |= IGB_TX_FLAGS_IPV4;
-
        igb_tx_queue_adv(adapter, tx_ring, tx_flags,
-                        igb_tx_map_adv(adapter, tx_ring, skb),
+                        igb_tx_map_adv(adapter, tx_ring, skb, first),
                         skb->len, hdr_len);
 
        netdev->trans_start = jiffies;
@@ -2749,14 +3042,17 @@ static int igb_xmit_frame_ring_adv(struct sk_buff *skb,
        /* Make sure there is space in the ring for the next send. */
        igb_maybe_stop_tx(netdev, tx_ring, MAX_SKB_FRAGS + 4);
 
-       spin_unlock_irqrestore(&tx_ring->tx_lock, irq_flags);
        return NETDEV_TX_OK;
 }
 
 static int igb_xmit_frame_adv(struct sk_buff *skb, struct net_device *netdev)
 {
        struct igb_adapter *adapter = netdev_priv(netdev);
-       struct igb_ring *tx_ring = &adapter->tx_ring[0];
+       struct igb_ring *tx_ring;
+
+       int r_idx = 0;
+       r_idx = skb->queue_mapping & (IGB_MAX_TX_QUEUES - 1);
+       tx_ring = adapter->multi_tx_table[r_idx];
 
        /* This goes back to the question of how to logically map a tx queue
         * to a flow.  Right now, performance is impacted slightly negatively
@@ -2851,7 +3147,11 @@ static int igb_change_mtu(struct net_device *netdev, int new_mtu)
        else if (max_frame <= IGB_RXBUFFER_2048)
                adapter->rx_buffer_len = IGB_RXBUFFER_2048;
        else
-               adapter->rx_buffer_len = IGB_RXBUFFER_4096;
+#if (PAGE_SIZE / 2) > IGB_RXBUFFER_16384
+               adapter->rx_buffer_len = IGB_RXBUFFER_16384;
+#else
+               adapter->rx_buffer_len = PAGE_SIZE / 2;
+#endif
        /* adjust allocation if LPE protects us, and we aren't using SBP */
        if ((max_frame == ETH_FRAME_LEN + ETH_FCS_LEN) ||
             (max_frame == MAXIMUM_ETHERNET_VLAN_SIZE))
@@ -2996,7 +3296,7 @@ void igb_update_stats(struct igb_adapter *adapter)
        /* Phy Stats */
        if (hw->phy.media_type == e1000_media_type_copper) {
                if ((adapter->link_speed == SPEED_1000) &&
-                  (!hw->phy.ops.read_phy_reg(hw, PHY_1000T_STATUS,
+                  (!igb_read_phy_reg(hw, PHY_1000T_STATUS,
                                              &phy_tmp))) {
                        phy_tmp &= PHY_IDLE_ERROR_COUNT_MASK;
                        adapter->phy_stats.idle_errors += phy_tmp;
@@ -3015,26 +3315,19 @@ static irqreturn_t igb_msix_other(int irq, void *data)
        struct net_device *netdev = data;
        struct igb_adapter *adapter = netdev_priv(netdev);
        struct e1000_hw *hw = &adapter->hw;
-       u32 eicr;
-       /* disable interrupts from the "other" bit, avoid re-entry */
-       wr32(E1000_EIMC, E1000_EIMS_OTHER);
-
-       eicr = rd32(E1000_EICR);
-
-       if (eicr & E1000_EIMS_OTHER) {
-               u32 icr = rd32(E1000_ICR);
-               /* reading ICR causes bit 31 of EICR to be cleared */
-               if (!(icr & E1000_ICR_LSC))
-                       goto no_link_interrupt;
-               hw->mac.get_link_status = 1;
-               /* guard against interrupt when we're going down */
-               if (!test_bit(__IGB_DOWN, &adapter->state))
-                       mod_timer(&adapter->watchdog_timer, jiffies + 1);
-       }
+       u32 icr = rd32(E1000_ICR);
 
+       /* reading ICR causes bit 31 of EICR to be cleared */
+       if (!(icr & E1000_ICR_LSC))
+               goto no_link_interrupt;
+       hw->mac.get_link_status = 1;
+       /* guard against interrupt when we're going down */
+       if (!test_bit(__IGB_DOWN, &adapter->state))
+               mod_timer(&adapter->watchdog_timer, jiffies + 1);
+       
 no_link_interrupt:
        wr32(E1000_IMS, E1000_IMS_LSC);
-       wr32(E1000_EIMS, E1000_EIMS_OTHER);
+       wr32(E1000_EIMS, adapter->eims_other);
 
        return IRQ_HANDLED;
 }
@@ -3045,44 +3338,186 @@ static irqreturn_t igb_msix_tx(int irq, void *data)
        struct igb_adapter *adapter = tx_ring->adapter;
        struct e1000_hw *hw = &adapter->hw;
 
-       if (!tx_ring->itr_val)
-               wr32(E1000_EIMC, tx_ring->eims_value);
-
+#ifdef CONFIG_IGB_DCA
+       if (adapter->flags & IGB_FLAG_DCA_ENABLED)
+               igb_update_tx_dca(tx_ring);
+#endif
        tx_ring->total_bytes = 0;
        tx_ring->total_packets = 0;
-       if (!igb_clean_tx_irq(adapter, tx_ring))
+
+       /* auto mask will automatically reenable the interrupt when we write
+        * EICS */
+       if (!igb_clean_tx_irq(tx_ring))
                /* Ring was not completely cleaned, so fire another interrupt */
                wr32(E1000_EICS, tx_ring->eims_value);
-
-       if (!tx_ring->itr_val)
+       else
                wr32(E1000_EIMS, tx_ring->eims_value);
+
        return IRQ_HANDLED;
 }
 
+static void igb_write_itr(struct igb_ring *ring)
+{
+       struct e1000_hw *hw = &ring->adapter->hw;
+       if ((ring->adapter->itr_setting & 3) && ring->set_itr) {
+               switch (hw->mac.type) {
+               case e1000_82576:
+                       wr32(ring->itr_register,
+                            ring->itr_val |
+                            0x80000000);
+                       break;
+               default:
+                       wr32(ring->itr_register,
+                            ring->itr_val |
+                            (ring->itr_val << 16));
+                       break;
+               }
+               ring->set_itr = 0;
+       }
+}
+
 static irqreturn_t igb_msix_rx(int irq, void *data)
 {
        struct igb_ring *rx_ring = data;
        struct igb_adapter *adapter = rx_ring->adapter;
-       struct e1000_hw *hw = &adapter->hw;
 
-       if (!rx_ring->itr_val)
-               wr32(E1000_EIMC, rx_ring->eims_value);
+       /* Write the ITR value calculated at the end of the
+        * previous interrupt.
+        */
+
+       igb_write_itr(rx_ring);
 
-       if (netif_rx_schedule_prep(adapter->netdev, &rx_ring->napi)) {
-               rx_ring->total_bytes = 0;
-               rx_ring->total_packets = 0;
-               rx_ring->no_itr_adjust = 0;
-               __netif_rx_schedule(adapter->netdev, &rx_ring->napi);
-       } else {
-               if (!rx_ring->no_itr_adjust) {
-                       igb_lower_rx_eitr(adapter, rx_ring);
-                       rx_ring->no_itr_adjust = 1;
+       if (netif_rx_schedule_prep(&rx_ring->napi))
+               __netif_rx_schedule(&rx_ring->napi);
+
+#ifdef CONFIG_IGB_DCA
+       if (adapter->flags & IGB_FLAG_DCA_ENABLED)
+               igb_update_rx_dca(rx_ring);
+#endif
+               return IRQ_HANDLED;
+}
+
+#ifdef CONFIG_IGB_DCA
+static void igb_update_rx_dca(struct igb_ring *rx_ring)
+{
+       u32 dca_rxctrl;
+       struct igb_adapter *adapter = rx_ring->adapter;
+       struct e1000_hw *hw = &adapter->hw;
+       int cpu = get_cpu();
+       int q = rx_ring->reg_idx;
+
+       if (rx_ring->cpu != cpu) {
+               dca_rxctrl = rd32(E1000_DCA_RXCTRL(q));
+               if (hw->mac.type == e1000_82576) {
+                       dca_rxctrl &= ~E1000_DCA_RXCTRL_CPUID_MASK_82576;
+                       dca_rxctrl |= dca_get_tag(cpu) <<
+                                     E1000_DCA_RXCTRL_CPUID_SHIFT;
+               } else {
+                       dca_rxctrl &= ~E1000_DCA_RXCTRL_CPUID_MASK;
+                       dca_rxctrl |= dca_get_tag(cpu);
                }
+               dca_rxctrl |= E1000_DCA_RXCTRL_DESC_DCA_EN;
+               dca_rxctrl |= E1000_DCA_RXCTRL_HEAD_DCA_EN;
+               dca_rxctrl |= E1000_DCA_RXCTRL_DATA_DCA_EN;
+               wr32(E1000_DCA_RXCTRL(q), dca_rxctrl);
+               rx_ring->cpu = cpu;
        }
+       put_cpu();
+}
 
-       return IRQ_HANDLED;
+static void igb_update_tx_dca(struct igb_ring *tx_ring)
+{
+       u32 dca_txctrl;
+       struct igb_adapter *adapter = tx_ring->adapter;
+       struct e1000_hw *hw = &adapter->hw;
+       int cpu = get_cpu();
+       int q = tx_ring->reg_idx;
+
+       if (tx_ring->cpu != cpu) {
+               dca_txctrl = rd32(E1000_DCA_TXCTRL(q));
+               if (hw->mac.type == e1000_82576) {
+                       dca_txctrl &= ~E1000_DCA_TXCTRL_CPUID_MASK_82576;
+                       dca_txctrl |= dca_get_tag(cpu) <<
+                                     E1000_DCA_TXCTRL_CPUID_SHIFT;
+               } else {
+                       dca_txctrl &= ~E1000_DCA_TXCTRL_CPUID_MASK;
+                       dca_txctrl |= dca_get_tag(cpu);
+               }
+               dca_txctrl |= E1000_DCA_TXCTRL_DESC_DCA_EN;
+               wr32(E1000_DCA_TXCTRL(q), dca_txctrl);
+               tx_ring->cpu = cpu;
+       }
+       put_cpu();
 }
 
+static void igb_setup_dca(struct igb_adapter *adapter)
+{
+       int i;
+
+       if (!(adapter->flags & IGB_FLAG_DCA_ENABLED))
+               return;
+
+       for (i = 0; i < adapter->num_tx_queues; i++) {
+               adapter->tx_ring[i].cpu = -1;
+               igb_update_tx_dca(&adapter->tx_ring[i]);
+       }
+       for (i = 0; i < adapter->num_rx_queues; i++) {
+               adapter->rx_ring[i].cpu = -1;
+               igb_update_rx_dca(&adapter->rx_ring[i]);
+       }
+}
+
+static int __igb_notify_dca(struct device *dev, void *data)
+{
+       struct net_device *netdev = dev_get_drvdata(dev);
+       struct igb_adapter *adapter = netdev_priv(netdev);
+       struct e1000_hw *hw = &adapter->hw;
+       unsigned long event = *(unsigned long *)data;
+
+       if (!(adapter->flags & IGB_FLAG_HAS_DCA))
+               goto out;
+
+       switch (event) {
+       case DCA_PROVIDER_ADD:
+               /* if already enabled, don't do it again */
+               if (adapter->flags & IGB_FLAG_DCA_ENABLED)
+                       break;
+               adapter->flags |= IGB_FLAG_DCA_ENABLED;
+               /* Always use CB2 mode, difference is masked
+                * in the CB driver. */
+               wr32(E1000_DCA_CTRL, 2);
+               if (dca_add_requester(dev) == 0) {
+                       dev_info(&adapter->pdev->dev, "DCA enabled\n");
+                       igb_setup_dca(adapter);
+                       break;
+               }
+               /* Fall Through since DCA is disabled. */
+       case DCA_PROVIDER_REMOVE:
+               if (adapter->flags & IGB_FLAG_DCA_ENABLED) {
+                       /* without this a class_device is left
+                        * hanging around in the sysfs model */
+                       dca_remove_requester(dev);
+                       dev_info(&adapter->pdev->dev, "DCA disabled\n");
+                       adapter->flags &= ~IGB_FLAG_DCA_ENABLED;
+                       wr32(E1000_DCA_CTRL, 1);
+               }
+               break;
+       }
+out:
+       return 0;
+}
+
+static int igb_notify_dca(struct notifier_block *nb, unsigned long event,
+                          void *p)
+{
+       int ret_val;
+
+       ret_val = driver_for_each_device(&igb_driver.driver, NULL, &event,
+                                        __igb_notify_dca);
+
+       return ret_val ? NOTIFY_BAD : NOTIFY_DONE;
+}
+#endif /* CONFIG_IGB_DCA */
 
 /**
  * igb_intr_msi - Interrupt Handler
@@ -3093,34 +3528,19 @@ static irqreturn_t igb_intr_msi(int irq, void *data)
 {
        struct net_device *netdev = data;
        struct igb_adapter *adapter = netdev_priv(netdev);
-       struct napi_struct *napi = &adapter->napi;
        struct e1000_hw *hw = &adapter->hw;
        /* read ICR disables interrupts using IAM */
        u32 icr = rd32(E1000_ICR);
 
-       /* Write the ITR value calculated at the end of the
-        * previous interrupt.
-        */
-       if (adapter->set_itr) {
-               wr32(E1000_ITR,
-                       1000000000 / (adapter->itr * 256));
-               adapter->set_itr = 0;
-       }
+       igb_write_itr(adapter->rx_ring);
 
-       /* read ICR disables interrupts using IAM */
        if (icr & (E1000_ICR_RXSEQ | E1000_ICR_LSC)) {
                hw->mac.get_link_status = 1;
                if (!test_bit(__IGB_DOWN, &adapter->state))
                        mod_timer(&adapter->watchdog_timer, jiffies + 1);
        }
 
-       if (netif_rx_schedule_prep(netdev, napi)) {
-               adapter->tx_ring->total_bytes = 0;
-               adapter->tx_ring->total_packets = 0;
-               adapter->rx_ring->total_bytes = 0;
-               adapter->rx_ring->total_packets = 0;
-               __netif_rx_schedule(netdev, napi);
-       }
+       netif_rx_schedule(&adapter->rx_ring[0].napi);
 
        return IRQ_HANDLED;
 }
@@ -3134,7 +3554,6 @@ static irqreturn_t igb_intr(int irq, void *data)
 {
        struct net_device *netdev = data;
        struct igb_adapter *adapter = netdev_priv(netdev);
-       struct napi_struct *napi = &adapter->napi;
        struct e1000_hw *hw = &adapter->hw;
        /* Interrupt Auto-Mask...upon reading ICR, interrupts are masked.  No
         * need for the IMC write */
@@ -3143,14 +3562,7 @@ static irqreturn_t igb_intr(int irq, void *data)
        if (!icr)
                return IRQ_NONE;  /* Not our interrupt */
 
-       /* Write the ITR value calculated at the end of the
-        * previous interrupt.
-        */
-       if (adapter->set_itr) {
-               wr32(E1000_ITR,
-                       1000000000 / (adapter->itr * 256));
-               adapter->set_itr = 0;
-       }
+       igb_write_itr(adapter->rx_ring);
 
        /* IMS will not auto-mask if INT_ASSERTED is not set, and if it is
         * not set, then the adapter didn't send an interrupt */
@@ -3166,58 +3578,42 @@ static irqreturn_t igb_intr(int irq, void *data)
                        mod_timer(&adapter->watchdog_timer, jiffies + 1);
        }
 
-       if (netif_rx_schedule_prep(netdev, napi)) {
-               adapter->tx_ring->total_bytes = 0;
-               adapter->rx_ring->total_bytes = 0;
-               adapter->tx_ring->total_packets = 0;
-               adapter->rx_ring->total_packets = 0;
-               __netif_rx_schedule(netdev, napi);
-       }
+       netif_rx_schedule(&adapter->rx_ring[0].napi);
 
        return IRQ_HANDLED;
 }
 
 /**
- * igb_clean - NAPI Rx polling callback
- * @adapter: board private structure
+ * igb_poll - NAPI Rx polling callback
+ * @napi: napi polling structure
+ * @budget: count of how many packets we should handle
  **/
-static int igb_clean(struct napi_struct *napi, int budget)
+static int igb_poll(struct napi_struct *napi, int budget)
 {
-       struct igb_adapter *adapter = container_of(napi, struct igb_adapter,
-                                                  napi);
+       struct igb_ring *rx_ring = container_of(napi, struct igb_ring, napi);
+       struct igb_adapter *adapter = rx_ring->adapter;
        struct net_device *netdev = adapter->netdev;
-       int tx_clean_complete = 1, work_done = 0;
-       int i;
-
-       /* Must NOT use netdev_priv macro here. */
-       adapter = netdev->priv;
+       int tx_clean_complete, work_done = 0;
 
-       /* Keep link state information with original netdev */
-       if (!netif_carrier_ok(netdev))
-               goto quit_polling;
-
-       /* igb_clean is called per-cpu.  This lock protects tx_ring[i] from
-        * being cleaned by multiple cpus simultaneously.  A failure obtaining
-        * the lock means tx_ring[i] is currently being cleaned anyway. */
-       for (i = 0; i < adapter->num_tx_queues; i++) {
-               if (spin_trylock(&adapter->tx_ring[i].tx_clean_lock)) {
-                       tx_clean_complete &= igb_clean_tx_irq(adapter,
-                                                       &adapter->tx_ring[i]);
-                       spin_unlock(&adapter->tx_ring[i].tx_clean_lock);
-               }
-       }
+       /* this poll routine only supports one tx and one rx queue */
+#ifdef CONFIG_IGB_DCA
+       if (adapter->flags & IGB_FLAG_DCA_ENABLED)
+               igb_update_tx_dca(&adapter->tx_ring[0]);
+#endif
+       tx_clean_complete = igb_clean_tx_irq(&adapter->tx_ring[0]);
 
-       for (i = 0; i < adapter->num_rx_queues; i++)
-               igb_clean_rx_irq_adv(adapter, &adapter->rx_ring[i], &work_done,
-                                    adapter->rx_ring[i].napi.weight);
+#ifdef CONFIG_IGB_DCA
+       if (adapter->flags & IGB_FLAG_DCA_ENABLED)
+               igb_update_rx_dca(&adapter->rx_ring[0]);
+#endif
+       igb_clean_rx_irq_adv(&adapter->rx_ring[0], &work_done, budget);
 
        /* If no Tx and not enough Rx work done, exit the polling mode */
        if ((tx_clean_complete && (work_done < budget)) ||
            !netif_running(netdev)) {
-quit_polling:
                if (adapter->itr_setting & 3)
-                       igb_set_itr(adapter, E1000_ITR, false);
-               netif_rx_complete(netdev, napi);
+                       igb_set_itr(adapter);
+               netif_rx_complete(napi);
                if (!test_bit(__IGB_DOWN, &adapter->state))
                        igb_irq_enable(adapter);
                return 0;
@@ -3234,68 +3630,60 @@ static int igb_clean_rx_ring_msix(struct napi_struct *napi, int budget)
        struct net_device *netdev = adapter->netdev;
        int work_done = 0;
 
-       /* Keep link state information with original netdev */
-       if (!netif_carrier_ok(netdev))
-               goto quit_polling;
-
-       igb_clean_rx_irq_adv(adapter, rx_ring, &work_done, budget);
+#ifdef CONFIG_IGB_DCA
+       if (adapter->flags & IGB_FLAG_DCA_ENABLED)
+               igb_update_rx_dca(rx_ring);
+#endif
+       igb_clean_rx_irq_adv(rx_ring, &work_done, budget);
 
 
        /* If not enough Rx work done, exit the polling mode */
        if ((work_done == 0) || !netif_running(netdev)) {
-quit_polling:
-               netif_rx_complete(netdev, napi);
-
-               wr32(E1000_EIMS, rx_ring->eims_value);
-               if ((adapter->itr_setting & 3) && !rx_ring->no_itr_adjust &&
-                   (rx_ring->total_packets > IGB_DYN_ITR_PACKET_THRESHOLD)) {
-                       int mean_size = rx_ring->total_bytes /
-                                       rx_ring->total_packets;
-                       if (mean_size < IGB_DYN_ITR_LENGTH_LOW)
-                               igb_raise_rx_eitr(adapter, rx_ring);
-                       else if (mean_size > IGB_DYN_ITR_LENGTH_HIGH)
-                               igb_lower_rx_eitr(adapter, rx_ring);
+               netif_rx_complete(napi);
+
+               if (adapter->itr_setting & 3) {
+                       if (adapter->num_rx_queues == 1)
+                               igb_set_itr(adapter);
+                       else
+                               igb_update_ring_itr(rx_ring);
                }
+
+               if (!test_bit(__IGB_DOWN, &adapter->state))
+                       wr32(E1000_EIMS, rx_ring->eims_value);
+
                return 0;
        }
 
        return 1;
 }
 
-static inline u32 get_head(struct igb_ring *tx_ring)
-{
-       void *end = (struct e1000_tx_desc *)tx_ring->desc + tx_ring->count;
-       return le32_to_cpu(*(volatile __le32 *)end);
-}
-
 /**
  * igb_clean_tx_irq - Reclaim resources after transmit completes
  * @adapter: board private structure
  * returns true if ring is completely cleaned
  **/
-static bool igb_clean_tx_irq(struct igb_adapter *adapter,
-                                 struct igb_ring *tx_ring)
+static bool igb_clean_tx_irq(struct igb_ring *tx_ring)
 {
+       struct igb_adapter *adapter = tx_ring->adapter;
        struct net_device *netdev = adapter->netdev;
        struct e1000_hw *hw = &adapter->hw;
-       struct e1000_tx_desc *tx_desc;
        struct igb_buffer *buffer_info;
        struct sk_buff *skb;
-       unsigned int i;
-       u32 head, oldhead;
-       unsigned int count = 0;
-       bool cleaned = false;
-       bool retval = true;
+       union e1000_adv_tx_desc *tx_desc, *eop_desc;
        unsigned int total_bytes = 0, total_packets = 0;
+       unsigned int i, eop, count = 0;
+       bool cleaned = false;
 
-       rmb();
-       head = get_head(tx_ring);
        i = tx_ring->next_to_clean;
-       while (1) {
-               while (i != head) {
-                       cleaned = true;
-                       tx_desc = E1000_TX_DESC(*tx_ring, i);
+       eop = tx_ring->buffer_info[i].next_to_watch;
+       eop_desc = E1000_TX_DESC_ADV(*tx_ring, eop);
+
+       while ((eop_desc->wb.status & cpu_to_le32(E1000_TXD_STAT_DD)) &&
+              (count < tx_ring->count)) {
+               for (cleaned = false; !cleaned; count++) {
+                       tx_desc = E1000_TX_DESC_ADV(*tx_ring, i);
                        buffer_info = &tx_ring->buffer_info[i];
+                       cleaned = (i == eop);
                        skb = buffer_info->skb;
 
                        if (skb) {
@@ -3310,38 +3698,29 @@ static bool igb_clean_tx_irq(struct igb_adapter *adapter,
                        }
 
                        igb_unmap_and_free_tx_resource(adapter, buffer_info);
-                       tx_desc->upper.data = 0;
+                       tx_desc->wb.status = 0;
 
                        i++;
                        if (i == tx_ring->count)
                                i = 0;
-
-                       count++;
-                       if (count == IGB_MAX_TX_CLEAN) {
-                               retval = false;
-                               goto done_cleaning;
-                       }
                }
-               oldhead = head;
-               rmb();
-               head = get_head(tx_ring);
-               if (head == oldhead)
-                       goto done_cleaning;
-       }  /* while (1) */
-
-done_cleaning:
+
+               eop = tx_ring->buffer_info[i].next_to_watch;
+               eop_desc = E1000_TX_DESC_ADV(*tx_ring, eop);
+       }
+
        tx_ring->next_to_clean = i;
 
-       if (unlikely(cleaned &&
+       if (unlikely(count &&
                     netif_carrier_ok(netdev) &&
                     IGB_DESC_UNUSED(tx_ring) >= IGB_TX_QUEUE_WAKE)) {
                /* Make sure that anybody stopping the queue after this
                 * sees the new next_to_clean.
                 */
                smp_mb();
-               if (netif_queue_stopped(netdev) &&
+               if (__netif_subqueue_stopped(netdev, tx_ring->queue_index) &&
                    !(test_bit(__IGB_DOWN, &adapter->state))) {
-                       netif_wake_queue(netdev);
+                       netif_wake_subqueue(netdev, tx_ring->queue_index);
                        ++adapter->restart_queue;
                }
        }
@@ -3356,57 +3735,109 @@ done_cleaning:
                    && !(rd32(E1000_STATUS) &
                         E1000_STATUS_TXOFF)) {
 
-                       tx_desc = E1000_TX_DESC(*tx_ring, i);
                        /* detected Tx unit hang */
                        dev_err(&adapter->pdev->dev,
                                "Detected Tx Unit Hang\n"
-                               "  Tx Queue             <%lu>\n"
+                               "  Tx Queue             <%d>\n"
                                "  TDH                  <%x>\n"
                                "  TDT                  <%x>\n"
                                "  next_to_use          <%x>\n"
                                "  next_to_clean        <%x>\n"
-                               "  head (WB)            <%x>\n"
                                "buffer_info[next_to_clean]\n"
                                "  time_stamp           <%lx>\n"
+                               "  next_to_watch        <%x>\n"
                                "  jiffies              <%lx>\n"
                                "  desc.status          <%x>\n",
-                               (unsigned long)((tx_ring - adapter->tx_ring) /
-                                       sizeof(struct igb_ring)),
+                               tx_ring->queue_index,
                                readl(adapter->hw.hw_addr + tx_ring->head),
                                readl(adapter->hw.hw_addr + tx_ring->tail),
                                tx_ring->next_to_use,
                                tx_ring->next_to_clean,
-                               head,
                                tx_ring->buffer_info[i].time_stamp,
+                               eop,
                                jiffies,
-                               tx_desc->upper.fields.status);
-                       netif_stop_queue(netdev);
+                               eop_desc->wb.status);
+                       netif_stop_subqueue(netdev, tx_ring->queue_index);
                }
        }
        tx_ring->total_bytes += total_bytes;
        tx_ring->total_packets += total_packets;
+       tx_ring->tx_stats.bytes += total_bytes;
+       tx_ring->tx_stats.packets += total_packets;
        adapter->net_stats.tx_bytes += total_bytes;
        adapter->net_stats.tx_packets += total_packets;
-       return retval;
+       return (count < tx_ring->count);
 }
 
+#ifdef CONFIG_IGB_LRO
+ /**
+ * igb_get_skb_hdr - helper function for LRO header processing
+ * @skb: pointer to sk_buff to be added to LRO packet
+ * @iphdr: pointer to ip header structure
+ * @tcph: pointer to tcp header structure
+ * @hdr_flags: pointer to header flags
+ * @priv: pointer to the receive descriptor for the current sk_buff
+ **/
+static int igb_get_skb_hdr(struct sk_buff *skb, void **iphdr, void **tcph,
+                           u64 *hdr_flags, void *priv)
+{
+       union e1000_adv_rx_desc *rx_desc = priv;
+       u16 pkt_type = rx_desc->wb.lower.lo_dword.pkt_info &
+                      (E1000_RXDADV_PKTTYPE_IPV4 | E1000_RXDADV_PKTTYPE_TCP);
+
+       /* Verify that this is a valid IPv4 TCP packet */
+       if (pkt_type != (E1000_RXDADV_PKTTYPE_IPV4 |
+                         E1000_RXDADV_PKTTYPE_TCP))
+               return -1;
+
+       /* Set network headers */
+       skb_reset_network_header(skb);
+       skb_set_transport_header(skb, ip_hdrlen(skb));
+       *iphdr = ip_hdr(skb);
+       *tcph = tcp_hdr(skb);
+       *hdr_flags = LRO_IPV4 | LRO_TCP;
+
+       return 0;
+
+}
+#endif /* CONFIG_IGB_LRO */
 
 /**
  * igb_receive_skb - helper function to handle rx indications
- * @adapter: board private structure
+ * @ring: pointer to receive ring receving this packet 
  * @status: descriptor status field as written by hardware
  * @vlan: descriptor vlan field as written by hardware (no le/be conversion)
  * @skb: pointer to sk_buff to be indicated to stack
  **/
-static void igb_receive_skb(struct igb_adapter *adapter, u8 status, __le16 vlan,
-                           struct sk_buff *skb)
+static void igb_receive_skb(struct igb_ring *ring, u8 status,
+                            union e1000_adv_rx_desc * rx_desc,
+                            struct sk_buff *skb)
 {
-       if (adapter->vlgrp && (status & E1000_RXD_STAT_VP))
-               vlan_hwaccel_receive_skb(skb, adapter->vlgrp,
-                                        le16_to_cpu(vlan) &
-                                        E1000_RXD_SPC_VLAN_MASK);
-       else
-               netif_receive_skb(skb);
+       struct igb_adapter * adapter = ring->adapter;
+       bool vlan_extracted = (adapter->vlgrp && (status & E1000_RXD_STAT_VP));
+
+#ifdef CONFIG_IGB_LRO
+       if (adapter->netdev->features & NETIF_F_LRO &&
+           skb->ip_summed == CHECKSUM_UNNECESSARY) {
+               if (vlan_extracted)
+                       lro_vlan_hwaccel_receive_skb(&ring->lro_mgr, skb,
+                                          adapter->vlgrp,
+                                          le16_to_cpu(rx_desc->wb.upper.vlan),
+                                          rx_desc);
+               else
+                       lro_receive_skb(&ring->lro_mgr,skb, rx_desc);
+               ring->lro_used = 1;
+       } else {
+#endif
+               if (vlan_extracted)
+                       vlan_hwaccel_receive_skb(skb, adapter->vlgrp,
+                                         le16_to_cpu(rx_desc->wb.upper.vlan));
+               else
+
+                       netif_receive_skb(skb);
+#ifdef CONFIG_IGB_LRO
+       }
+#endif
 }
 
 
@@ -3432,16 +3863,16 @@ static inline void igb_rx_checksum_adv(struct igb_adapter *adapter,
        adapter->hw_csum_good++;
 }
 
-static bool igb_clean_rx_irq_adv(struct igb_adapter *adapter,
-                                     struct igb_ring *rx_ring,
-                                     int *work_done, int budget)
+static bool igb_clean_rx_irq_adv(struct igb_ring *rx_ring,
+                                int *work_done, int budget)
 {
+       struct igb_adapter *adapter = rx_ring->adapter;
        struct net_device *netdev = adapter->netdev;
        struct pci_dev *pdev = adapter->pdev;
        union e1000_adv_rx_desc *rx_desc , *next_rxd;
        struct igb_buffer *buffer_info , *next_buffer;
        struct sk_buff *skb;
-       unsigned int i, j;
+       unsigned int i;
        u32 length, hlen, staterr;
        bool cleaned = false;
        int cleaned_count = 0;
@@ -3471,64 +3902,48 @@ static bool igb_clean_rx_irq_adv(struct igb_adapter *adapter,
                cleaned = true;
                cleaned_count++;
 
-               if (rx_ring->pending_skb != NULL) {
-                       skb = rx_ring->pending_skb;
-                       rx_ring->pending_skb = NULL;
-                       j = rx_ring->pending_skb_page;
-               } else {
-                       skb = buffer_info->skb;
-                       prefetch(skb->data - NET_IP_ALIGN);
-                       buffer_info->skb = NULL;
-                       if (hlen) {
-                               pci_unmap_single(pdev, buffer_info->dma,
-                                                adapter->rx_ps_hdr_size +
-                                                  NET_IP_ALIGN,
-                                                PCI_DMA_FROMDEVICE);
-                               skb_put(skb, hlen);
-                       } else {
-                               pci_unmap_single(pdev, buffer_info->dma,
-                                                adapter->rx_buffer_len +
-                                                  NET_IP_ALIGN,
-                                                PCI_DMA_FROMDEVICE);
-                               skb_put(skb, length);
-                               goto send_up;
-                       }
-                       j = 0;
+               skb = buffer_info->skb;
+               prefetch(skb->data - NET_IP_ALIGN);
+               buffer_info->skb = NULL;
+               if (!adapter->rx_ps_hdr_size) {
+                       pci_unmap_single(pdev, buffer_info->dma,
+                                        adapter->rx_buffer_len +
+                                          NET_IP_ALIGN,
+                                        PCI_DMA_FROMDEVICE);
+                       skb_put(skb, length);
+                       goto send_up;
+               }
+
+               if (!skb_shinfo(skb)->nr_frags) {
+                       pci_unmap_single(pdev, buffer_info->dma,
+                                        adapter->rx_ps_hdr_size +
+                                          NET_IP_ALIGN,
+                                        PCI_DMA_FROMDEVICE);
+                       skb_put(skb, hlen);
                }
 
-               while (length) {
+               if (length) {
                        pci_unmap_page(pdev, buffer_info->page_dma,
-                               PAGE_SIZE, PCI_DMA_FROMDEVICE);
+                                      PAGE_SIZE / 2, PCI_DMA_FROMDEVICE);
                        buffer_info->page_dma = 0;
-                       skb_fill_page_desc(skb, j, buffer_info->page,
-                                               0, length);
-                       buffer_info->page = NULL;
+
+                       skb_fill_page_desc(skb, skb_shinfo(skb)->nr_frags++,
+                                               buffer_info->page,
+                                               buffer_info->page_offset,
+                                               length);
+
+                       if ((adapter->rx_buffer_len > (PAGE_SIZE / 2)) ||
+                           (page_count(buffer_info->page) != 1))
+                               buffer_info->page = NULL;
+                       else
+                               get_page(buffer_info->page);
 
                        skb->len += length;
                        skb->data_len += length;
-                       skb->truesize += length;
-                       rx_desc->wb.upper.status_error = 0;
-                       if (staterr & E1000_RXD_STAT_EOP)
-                               break;
 
-                       j++;
-                       cleaned_count++;
-                       i++;
-                       if (i == rx_ring->count)
-                               i = 0;
-
-                       buffer_info = &rx_ring->buffer_info[i];
-                       rx_desc = E1000_RX_DESC_ADV(*rx_ring, i);
-                       staterr = le32_to_cpu(rx_desc->wb.upper.status_error);
-                       length = le16_to_cpu(rx_desc->wb.upper.length);
-                       if (!(staterr & E1000_RXD_STAT_DD)) {
-                               rx_ring->pending_skb = skb;
-                               rx_ring->pending_skb_page = j;
-                               goto out;
-                       }
+                       skb->truesize += length;
                }
 send_up:
-               pskb_trim(skb, skb->len - 4);
                i++;
                if (i == rx_ring->count)
                        i = 0;
@@ -3536,11 +3951,18 @@ send_up:
                prefetch(next_rxd);
                next_buffer = &rx_ring->buffer_info[i];
 
+               if (!(staterr & E1000_RXD_STAT_EOP)) {
+                       buffer_info->skb = next_buffer->skb;
+                       buffer_info->dma = next_buffer->dma;
+                       next_buffer->skb = skb;
+                       next_buffer->dma = 0;
+                       goto next_desc;
+               }
+
                if (staterr & E1000_RXDEXT_ERR_FRAME_ERR_MASK) {
                        dev_kfree_skb_irq(skb);
                        goto next_desc;
                }
-               rx_ring->no_itr_adjust |= (staterr & E1000_RXD_STAT_DYNINT);
 
                total_bytes += skb->len;
                total_packets++;
@@ -3549,17 +3971,14 @@ send_up:
 
                skb->protocol = eth_type_trans(skb, netdev);
 
-               igb_receive_skb(adapter, staterr, rx_desc->wb.upper.vlan, skb);
-
-               netdev->last_rx = jiffies;
+               igb_receive_skb(rx_ring, staterr, rx_desc, skb);
 
 next_desc:
                rx_desc->wb.upper.status_error = 0;
 
                /* return some buffers to hardware, one at a time is too slow */
                if (cleaned_count >= IGB_RX_BUFFER_WRITE) {
-                       igb_alloc_rx_buffers_adv(adapter, rx_ring,
-                                                cleaned_count);
+                       igb_alloc_rx_buffers_adv(rx_ring, cleaned_count);
                        cleaned_count = 0;
                }
 
@@ -3569,12 +3988,19 @@ next_desc:
 
                staterr = le32_to_cpu(rx_desc->wb.upper.status_error);
        }
-out:
+
        rx_ring->next_to_clean = i;
        cleaned_count = IGB_DESC_UNUSED(rx_ring);
 
+#ifdef CONFIG_IGB_LRO
+       if (rx_ring->lro_used) {
+               lro_flush_all(&rx_ring->lro_mgr);
+               rx_ring->lro_used = 0;
+       }
+#endif
+
        if (cleaned_count)
-               igb_alloc_rx_buffers_adv(adapter, rx_ring, cleaned_count);
+               igb_alloc_rx_buffers_adv(rx_ring, cleaned_count);
 
        rx_ring->total_packets += total_packets;
        rx_ring->total_bytes += total_bytes;
@@ -3590,10 +4016,10 @@ out:
  * igb_alloc_rx_buffers_adv - Replace used receive buffers; packet split
  * @adapter: address of board private structure
  **/
-static void igb_alloc_rx_buffers_adv(struct igb_adapter *adapter,
-                                    struct igb_ring *rx_ring,
+static void igb_alloc_rx_buffers_adv(struct igb_ring *rx_ring,
                                     int cleaned_count)
 {
+       struct igb_adapter *adapter = rx_ring->adapter;
        struct net_device *netdev = adapter->netdev;
        struct pci_dev *pdev = adapter->pdev;
        union e1000_adv_rx_desc *rx_desc;
@@ -3607,16 +4033,22 @@ static void igb_alloc_rx_buffers_adv(struct igb_adapter *adapter,
        while (cleaned_count--) {
                rx_desc = E1000_RX_DESC_ADV(*rx_ring, i);
 
-               if (adapter->rx_ps_hdr_size && !buffer_info->page) {
-                       buffer_info->page = alloc_page(GFP_ATOMIC);
+               if (adapter->rx_ps_hdr_size && !buffer_info->page_dma) {
                        if (!buffer_info->page) {
-                               adapter->alloc_rx_buff_failed++;
-                               goto no_buffers;
+                               buffer_info->page = alloc_page(GFP_ATOMIC);
+                               if (!buffer_info->page) {
+                                       adapter->alloc_rx_buff_failed++;
+                                       goto no_buffers;
+                               }
+                               buffer_info->page_offset = 0;
+                       } else {
+                               buffer_info->page_offset ^= PAGE_SIZE / 2;
                        }
                        buffer_info->page_dma =
                                pci_map_page(pdev,
                                             buffer_info->page,
-                                            0, PAGE_SIZE,
+                                            buffer_info->page_offset,
+                                            PAGE_SIZE / 2,
                                             PCI_DMA_FROMDEVICE);
                }
 
@@ -3703,9 +4135,8 @@ static int igb_mii_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)
        case SIOCGMIIREG:
                if (!capable(CAP_NET_ADMIN))
                        return -EPERM;
-               if (adapter->hw.phy.ops.read_phy_reg(&adapter->hw,
-                                                    data->reg_num
-                                                    & 0x1F, &data->val_out))
+               if (igb_read_phy_reg(&adapter->hw, data->reg_num & 0x1F,
+                                    &data->val_out))
                        return -EIO;
                break;
        case SIOCSMIIREG:
@@ -3751,7 +4182,6 @@ static void igb_vlan_rx_register(struct net_device *netdev,
 
                /* enable VLAN receive filtering */
                rctl = rd32(E1000_RCTL);
-               rctl |= E1000_RCTL_VFE;
                rctl &= ~E1000_RCTL_CFIEN;
                wr32(E1000_RCTL, rctl);
                igb_update_mng_vlan(adapter);
@@ -3763,10 +4193,6 @@ static void igb_vlan_rx_register(struct net_device *netdev,
                ctrl &= ~E1000_CTRL_VME;
                wr32(E1000_CTRL, ctrl);
 
-               /* disable VLAN filtering */
-               rctl = rd32(E1000_RCTL);
-               rctl &= ~E1000_RCTL_VFE;
-               wr32(E1000_RCTL, rctl);
                if (adapter->mng_vlan_id != (u16)IGB_MNG_VLAN_NONE) {
                        igb_vlan_rx_kill_vid(netdev, adapter->mng_vlan_id);
                        adapter->mng_vlan_id = IGB_MNG_VLAN_NONE;
@@ -3883,7 +4309,7 @@ static int igb_suspend(struct pci_dev *pdev, pm_message_t state)
        struct net_device *netdev = pci_get_drvdata(pdev);
        struct igb_adapter *adapter = netdev_priv(netdev);
        struct e1000_hw *hw = &adapter->hw;
-       u32 ctrl, ctrl_ext, rctl, status;
+       u32 ctrl, rctl, status;
        u32 wufc = adapter->wol;
 #ifdef CONFIG_PM
        int retval = 0;
@@ -3891,11 +4317,12 @@ static int igb_suspend(struct pci_dev *pdev, pm_message_t state)
 
        netif_device_detach(netdev);
 
-       if (netif_running(netdev)) {
-               WARN_ON(test_bit(__IGB_RESETTING, &adapter->state));
-               igb_down(adapter);
-               igb_free_irq(adapter);
-       }
+       if (netif_running(netdev))
+               igb_close(netdev);
+
+       igb_reset_interrupt_capability(adapter);
+
+       igb_free_queues(adapter);
 
 #ifdef CONFIG_PM
        retval = pci_save_state(pdev);
@@ -3926,33 +4353,24 @@ static int igb_suspend(struct pci_dev *pdev, pm_message_t state)
                ctrl |= E1000_CTRL_ADVD3WUC;
                wr32(E1000_CTRL, ctrl);
 
-               if (adapter->hw.phy.media_type == e1000_media_type_fiber ||
-                  adapter->hw.phy.media_type ==
-                                       e1000_media_type_internal_serdes) {
-                       /* keep the laser running in D3 */
-                       ctrl_ext = rd32(E1000_CTRL_EXT);
-                       ctrl_ext |= E1000_CTRL_EXT_SDP7_DATA;
-                       wr32(E1000_CTRL_EXT, ctrl_ext);
-               }
-
                /* Allow time for pending master requests to run */
                igb_disable_pcie_master(&adapter->hw);
 
                wr32(E1000_WUC, E1000_WUC_PME_EN);
                wr32(E1000_WUFC, wufc);
-               pci_enable_wake(pdev, PCI_D3hot, 1);
-               pci_enable_wake(pdev, PCI_D3cold, 1);
        } else {
                wr32(E1000_WUC, 0);
                wr32(E1000_WUFC, 0);
-               pci_enable_wake(pdev, PCI_D3hot, 0);
-               pci_enable_wake(pdev, PCI_D3cold, 0);
        }
 
-       /* make sure adapter isn't asleep if manageability is enabled */
-       if (adapter->en_mng_pt) {
+       /* make sure adapter isn't asleep if manageability/wol is enabled */
+       if (wufc || adapter->en_mng_pt) {
                pci_enable_wake(pdev, PCI_D3hot, 1);
                pci_enable_wake(pdev, PCI_D3cold, 1);
+       } else {
+               igb_shutdown_fiber_serdes_link_82575(hw);
+               pci_enable_wake(pdev, PCI_D3hot, 0);
+               pci_enable_wake(pdev, PCI_D3cold, 0);
        }
 
        /* Release control of h/w to f/w.  If f/w is AMT enabled, this
@@ -3976,7 +4394,11 @@ static int igb_resume(struct pci_dev *pdev)
 
        pci_set_power_state(pdev, PCI_D0);
        pci_restore_state(pdev);
-       err = pci_enable_device(pdev);
+
+       if (adapter->need_ioport)
+               err = pci_enable_device(pdev);
+       else
+               err = pci_enable_device_mem(pdev);
        if (err) {
                dev_err(&pdev->dev,
                        "igb: Cannot enable PCI device from suspend\n");
@@ -3987,10 +4409,11 @@ static int igb_resume(struct pci_dev *pdev)
        pci_enable_wake(pdev, PCI_D3hot, 0);
        pci_enable_wake(pdev, PCI_D3cold, 0);
 
-       if (netif_running(netdev)) {
-               err = igb_request_irq(adapter);
-               if (err)
-                       return err;
+       igb_set_interrupt_capability(adapter);
+
+       if (igb_alloc_queues(adapter)) {
+               dev_err(&pdev->dev, "Unable to allocate memory for queues\n");
+               return -ENOMEM;
        }
 
        /* e1000_power_up_phy(adapter); */
@@ -3998,10 +4421,11 @@ static int igb_resume(struct pci_dev *pdev)
        igb_reset(adapter);
        wr32(E1000_WUS, ~0);
 
-       igb_init_manageability(adapter);
-
-       if (netif_running(netdev))
-               igb_up(adapter);
+       if (netif_running(netdev)) {
+               err = igb_open(netdev);
+               if (err)
+                       return err;
+       }
 
        netif_device_attach(netdev);
 
@@ -4031,14 +4455,17 @@ static void igb_netpoll(struct net_device *netdev)
        int work_done = 0;
 
        igb_irq_disable(adapter);
+       adapter->flags |= IGB_FLAG_IN_NETPOLL;
+
        for (i = 0; i < adapter->num_tx_queues; i++)
-               igb_clean_tx_irq(adapter, &adapter->tx_ring[i]);
+               igb_clean_tx_irq(&adapter->tx_ring[i]);
 
        for (i = 0; i < adapter->num_rx_queues; i++)
-               igb_clean_rx_irq_adv(adapter, &adapter->rx_ring[i],
+               igb_clean_rx_irq_adv(&adapter->rx_ring[i],
                                     &work_done,
                                     adapter->rx_ring[i].napi.weight);
 
+       adapter->flags &= ~IGB_FLAG_IN_NETPOLL;
        igb_irq_enable(adapter);
 }
 #endif /* CONFIG_NET_POLL_CONTROLLER */
@@ -4079,22 +4506,38 @@ static pci_ers_result_t igb_io_slot_reset(struct pci_dev *pdev)
        struct net_device *netdev = pci_get_drvdata(pdev);
        struct igb_adapter *adapter = netdev_priv(netdev);
        struct e1000_hw *hw = &adapter->hw;
+       pci_ers_result_t result;
+       int err;
+
+       if (adapter->need_ioport)
+               err = pci_enable_device(pdev);
+       else
+               err = pci_enable_device_mem(pdev);
 
-       if (pci_enable_device(pdev)) {
+       if (err) {
                dev_err(&pdev->dev,
                        "Cannot re-enable PCI device after reset.\n");
-               return PCI_ERS_RESULT_DISCONNECT;
-       }
-       pci_set_master(pdev);
-       pci_restore_state(pdev);
+               result = PCI_ERS_RESULT_DISCONNECT;
+       } else {
+               pci_set_master(pdev);
+               pci_restore_state(pdev);
 
-       pci_enable_wake(pdev, PCI_D3hot, 0);
-       pci_enable_wake(pdev, PCI_D3cold, 0);
+               pci_enable_wake(pdev, PCI_D3hot, 0);
+               pci_enable_wake(pdev, PCI_D3cold, 0);
 
-       igb_reset(adapter);
-       wr32(E1000_WUS, ~0);
+               igb_reset(adapter);
+               wr32(E1000_WUS, ~0);
+               result = PCI_ERS_RESULT_RECOVERED;
+       }
 
-       return PCI_ERS_RESULT_RECOVERED;
+       err = pci_cleanup_aer_uncorrect_error_status(pdev);
+       if (err) {
+               dev_err(&pdev->dev, "pci_cleanup_aer_uncorrect_error_status "
+                       "failed 0x%0x\n", err);
+               /* non-fatal, continue */
+       }
+
+       return result;
 }
 
 /**
@@ -4110,8 +4553,6 @@ static void igb_io_resume(struct pci_dev *pdev)
        struct net_device *netdev = pci_get_drvdata(pdev);
        struct igb_adapter *adapter = netdev_priv(netdev);
 
-       igb_init_manageability(adapter);
-
        if (netif_running(netdev)) {
                if (igb_up(adapter)) {
                        dev_err(&pdev->dev, "igb_up failed after reset\n");
@@ -4124,7 +4565,6 @@ static void igb_io_resume(struct pci_dev *pdev)
        /* let the f/w know that the h/w is now under the control of the
         * driver. */
        igb_get_hw_control(adapter);
-
 }
 
 /* igb_main.c */