]> nv-tegra.nvidia Code Review - linux-2.6.git/blobdiff - drivers/net/igb/igb_main.c
igb: remove 82576 quad adapter
[linux-2.6.git] / drivers / net / igb / igb_main.c
index 660a786532878e8b45bc3f5d0c881e02929e74cc..634c4c9d87bed037911c5a4b37cc5d410b425706 100644 (file)
@@ -61,7 +61,6 @@ 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_82576_QUAD_COPPER), board_82575 },
        { PCI_VDEVICE(INTEL, E1000_DEV_ID_82575EB_COPPER), board_82575 },
        { PCI_VDEVICE(INTEL, E1000_DEV_ID_82575EB_FIBER_SERDES), board_82575 },
        { PCI_VDEVICE(INTEL, E1000_DEV_ID_82575GB_QUAD_COPPER), board_82575 },
@@ -116,6 +115,9 @@ 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 *);
@@ -252,6 +254,8 @@ 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->adapter = adapter;
@@ -269,6 +273,17 @@ static int igb_alloc_queues(struct igb_adapter *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)
@@ -295,7 +310,7 @@ static void igb_assign_vector(struct igb_adapter *adapter, int rx_queue,
                array_wr32(E1000_MSIXBM(0), msix_vector, msixbm);
                break;
        case e1000_82576:
-               /* Kawela uses a table-based method for assigning vectors.
+               /* The 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. */
@@ -361,7 +376,7 @@ static void igb_configure_msix(struct igb_adapter *adapter)
                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);
@@ -369,10 +384,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);
@@ -435,7 +451,7 @@ static int igb_request_msix(struct igb_adapter *adapter)
                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++) {
@@ -504,7 +520,7 @@ 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);
 
@@ -514,11 +530,9 @@ msi_only:
        adapter->num_tx_queues = 1;
        if (!pci_enable_msi(adapter->pdev))
                adapter->flags |= IGB_FLAG_HAS_MSI;
-
-#ifdef CONFIG_NETDEVICES_MULTIQUEUE
+out:
        /* Notify the stack of the (possibly) reduced Tx Queue count. */
-       adapter->netdev->egress_subqueue_count = adapter->num_tx_queues;
-#endif
+       adapter->netdev->real_num_tx_queues = adapter->num_tx_queues;
        return;
 }
 
@@ -705,28 +719,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
@@ -740,7 +732,6 @@ 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);
@@ -806,11 +797,7 @@ void igb_down(struct igb_adapter *adapter)
        wr32(E1000_RCTL, rctl & ~E1000_RCTL_EN);
        /* flush and sleep below */
 
-       netif_stop_queue(netdev);
-#ifdef CONFIG_NETDEVICES_MULTIQUEUE
-       for (i = 0; i < adapter->num_tx_queues; i++)
-               netif_stop_subqueue(netdev, i);
-#endif
+       netif_tx_stop_all_queues(netdev);
 
        /* disable transmits in the hardware */
        tctl = rd32(E1000_TCTL);
@@ -1025,11 +1012,7 @@ static int __devinit igb_probe(struct pci_dev *pdev,
        pci_save_state(pdev);
 
        err = -ENOMEM;
-#ifdef CONFIG_NETDEVICES_MULTIQUEUE
        netdev = alloc_etherdev_mq(sizeof(struct igb_adapter), IGB_MAX_TX_QUEUES);
-#else
-       netdev = alloc_etherdev(sizeof(struct igb_adapter));
-#endif /* CONFIG_NETDEVICES_MULTIQUEUE */
        if (!netdev)
                goto err_alloc_etherdev;
 
@@ -1134,6 +1117,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;
@@ -1142,10 +1129,6 @@ static int __devinit igb_probe(struct pci_dev *pdev,
        if (pci_using_dac)
                netdev->features |= NETIF_F_HIGHDMA;
 
-#ifdef CONFIG_NETDEVICES_MULTIQUEUE
-       netdev->features |= NETIF_F_MULTI_QUEUE;
-#endif
-
        netdev->features |= NETIF_F_LLTX;
        adapter->en_mng_pt = igb_enable_mng_pass_thru(&adapter->hw);
 
@@ -1233,16 +1216,6 @@ static int __devinit igb_probe(struct pci_dev *pdev,
                if (rd32(E1000_STATUS) & E1000_STATUS_FUNC_1)
                        adapter->eeprom_wol = 0;
                break;
-       case E1000_DEV_ID_82576_QUAD_COPPER:
-               /* if quad port adapter, disable WoL on all but port A */
-               if (global_quad_port_a != 0)
-                       adapter->eeprom_wol = 0;
-               else
-                       adapter->flags |= IGB_FLAG_QUAD_PORT_A;
-               /* Reset for multiple quad port adapters */
-               if (++global_quad_port_a == 4)
-                       global_quad_port_a = 0;
-               break;
        }
 
        /* initialize the wol settings based on the eeprom settings */
@@ -1257,11 +1230,7 @@ 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);
-#ifdef CONFIG_NETDEVICES_MULTIQUEUE
-       for (i = 0; i < adapter->num_tx_queues; i++)
-               netif_stop_subqueue(netdev, i);
-#endif
+       netif_tx_stop_all_queues(netdev);
 
        strcpy(netdev->name, "eth%d");
        err = register_netdev(netdev);
@@ -1315,8 +1284,7 @@ err_eeprom:
                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);
@@ -1343,7 +1311,9 @@ 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_DCA
        struct e1000_hw *hw = &adapter->hw;
+#endif
 
        /* flush_scheduled work may reschedule our watchdog task, so
         * explicitly disable watchdog tasks from being rescheduled  */
@@ -1368,14 +1338,14 @@ static void __devexit igb_remove(struct pci_dev *pdev)
 
        unregister_netdev(netdev);
 
-       if (!igb_check_reset_block(&adapter->hw))
+       if (adapter->hw.phy.ops.reset_phy &&
+           !igb_check_reset_block(&adapter->hw))
                adapter->hw.phy.ops.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)
@@ -1411,11 +1381,7 @@ 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_rx_queues = min((u32)IGB_MAX_RX_QUEUES, (u32)num_online_cpus());
-#ifdef CONFIG_NETDEVICES_MULTIQUEUE
        adapter->num_tx_queues = min(IGB_MAX_TX_QUEUES, num_online_cpus());
-#else
-       adapter->num_tx_queues = 1;
-#endif /* CONFIG_NET_MULTI_QUEUE_DEVICE */
 
        /* This call may decrease the number of queues depending on
         * interrupt mode. */
@@ -1494,6 +1460,8 @@ static int igb_open(struct net_device *netdev)
 
        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);
 
@@ -1598,9 +1566,7 @@ err:
 static int igb_setup_all_tx_resources(struct igb_adapter *adapter)
 {
        int i, err = 0;
-#ifdef CONFIG_NETDEVICES_MULTIQUEUE
        int r_idx;
-#endif 
 
        for (i = 0; i < adapter->num_tx_queues; i++) {
                err = igb_setup_tx_resources(adapter, &adapter->tx_ring[i]);
@@ -1613,12 +1579,10 @@ static int igb_setup_all_tx_resources(struct igb_adapter *adapter)
                }
        }
 
-#ifdef CONFIG_NETDEVICES_MULTIQUEUE
        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];
        }       
-#endif         
        return err;
 }
 
@@ -1705,6 +1669,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)
@@ -1731,6 +1703,10 @@ int igb_setup_rx_resources(struct igb_adapter *adapter,
        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");
@@ -1868,8 +1844,7 @@ 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 */
@@ -1894,6 +1869,16 @@ static void igb_configure_rx(struct igb_adapter *adapter)
                rxdctl |= IGB_RX_HTHRESH << 8;
                rxdctl |= IGB_RX_WTHRESH << 16;
                wr32(E1000_RXDCTL(i), 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) {
@@ -2085,6 +2070,11 @@ static void igb_free_rx_resources(struct igb_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;
@@ -2221,14 +2211,17 @@ 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) {
@@ -2286,10 +2279,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;
-#ifdef CONFIG_NETDEVICES_MULTIQUEUE
        int i;
-#endif
 
        if ((netif_carrier_ok(netdev)) &&
            (rd32(E1000_STATUS) & E1000_STATUS_LU))
@@ -2345,11 +2337,7 @@ static void igb_watchdog_task(struct work_struct *work)
                        }
 
                        netif_carrier_on(netdev);
-                       netif_wake_queue(netdev);
-#ifdef CONFIG_NETDEVICES_MULTIQUEUE
-                       for (i = 0; i < adapter->num_tx_queues; i++)
-                               netif_wake_subqueue(netdev, i);
-#endif
+                       netif_tx_wake_all_queues(netdev);
 
                        if (!test_bit(__IGB_DOWN, &adapter->state))
                                mod_timer(&adapter->phy_info_timer,
@@ -2361,11 +2349,7 @@ static void igb_watchdog_task(struct work_struct *work)
                        adapter->link_duplex = 0;
                        dev_info(&adapter->pdev->dev, "NIC Link is Down\n");
                        netif_carrier_off(netdev);
-                       netif_stop_queue(netdev);
-#ifdef CONFIG_NETDEVICES_MULTIQUEUE
-                       for (i = 0; i < adapter->num_tx_queues; i++)
-                               netif_stop_subqueue(netdev, i);
-#endif
+                       netif_tx_stop_all_queues(netdev);
                        if (!test_bit(__IGB_DOWN, &adapter->state))
                                mod_timer(&adapter->phy_info_timer,
                                          round_jiffies(jiffies + 2 * HZ));
@@ -2399,7 +2383,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;
@@ -2418,38 +2408,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;
 }
 
 /**
@@ -2516,8 +2528,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;
@@ -2533,26 +2544,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:
@@ -2569,6 +2577,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
@@ -2583,7 +2598,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;
@@ -2867,11 +2883,7 @@ static int __igb_maybe_stop_tx(struct net_device *netdev,
 {
        struct igb_adapter *adapter = netdev_priv(netdev);
 
-#ifdef CONFIG_NETDEVICES_MULTIQUEUE
        netif_stop_subqueue(netdev, tx_ring->queue_index);
-#else
-       netif_stop_queue(netdev);
-#endif
 
        /* Herbert's original patch had:
         *  smp_mb__after_netif_stop_queue();
@@ -2884,11 +2896,7 @@ static int __igb_maybe_stop_tx(struct net_device *netdev,
                return -EBUSY;
 
        /* A reprieve! */
-#ifdef CONFIG_NETDEVICES_MULTIQUEUE
        netif_wake_subqueue(netdev, tx_ring->queue_index);
-#else
-       netif_wake_queue(netdev);
-#endif 
        ++adapter->restart_queue;
        return 0;
 }
@@ -2934,6 +2942,7 @@ static int igb_xmit_frame_ring_adv(struct sk_buff *skb,
                /* this is a hard error */
                return NETDEV_TX_BUSY;
        }
+       skb_orphan(skb);
 
        if (adapter->vlgrp && vlan_tx_tag_present(skb)) {
                tx_flags |= IGB_TX_FLAGS_VLAN;
@@ -2974,14 +2983,9 @@ 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;
 
-#ifdef CONFIG_NETDEVICES_MULTIQUEUE
        int r_idx = 0;
        r_idx = skb->queue_mapping & (IGB_MAX_TX_QUEUES - 1);
        tx_ring = adapter->multi_tx_table[r_idx];
-#else
-       tx_ring = &adapter->tx_ring[0];
-#endif
-
 
        /* This goes back to the question of how to logically map a tx queue
         * to a flow.  Right now, performance is impacted slightly negatively
@@ -3267,8 +3271,6 @@ 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_DCA
        if (adapter->flags & IGB_FLAG_DCA_ENABLED)
                igb_update_tx_dca(tx_ring);
@@ -3287,21 +3289,36 @@ static irqreturn_t igb_msix_tx(int irq, void *data)
        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;
 
        /* Write the ITR value calculated at the end of the
         * previous interrupt.
         */
 
-       if (adapter->set_itr) {
-               wr32(rx_ring->itr_register,
-                    1000000000 / (rx_ring->itr_val * 256));
-               adapter->set_itr = 0;
-       }
+       igb_write_itr(rx_ring);
 
        if (netif_rx_schedule_prep(adapter->netdev, &rx_ring->napi))
                __netif_rx_schedule(adapter->netdev, &rx_ring->napi);
@@ -3448,13 +3465,7 @@ static irqreturn_t igb_intr_msi(int irq, void *data)
        /* 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);
 
        if (icr & (E1000_ICR_RXSEQ | E1000_ICR_LSC)) {
                hw->mac.get_link_status = 1;
@@ -3484,13 +3495,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 */
@@ -3540,7 +3545,7 @@ static int igb_poll(struct napi_struct *napi, int budget)
        if ((tx_clean_complete && (work_done < budget)) ||
            !netif_running(netdev)) {
                if (adapter->itr_setting & 3)
-                       igb_set_itr(adapter, E1000_ITR, false);
+                       igb_set_itr(adapter);
                netif_rx_complete(netdev, napi);
                if (!test_bit(__IGB_DOWN, &adapter->state))
                        igb_irq_enable(adapter);
@@ -3574,15 +3579,11 @@ static int igb_clean_rx_ring_msix(struct napi_struct *napi, int budget)
 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);
+               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))
@@ -3671,19 +3672,11 @@ done_cleaning:
                 * sees the new next_to_clean.
                 */
                smp_mb();
-#ifdef CONFIG_NETDEVICES_MULTIQUEUE
                if (__netif_subqueue_stopped(netdev, tx_ring->queue_index) &&
                    !(test_bit(__IGB_DOWN, &adapter->state))) {
                        netif_wake_subqueue(netdev, tx_ring->queue_index);
                        ++adapter->restart_queue;
                }
-#else
-               if (netif_queue_stopped(netdev) &&
-                   !(test_bit(__IGB_DOWN, &adapter->state))) {
-                       netif_wake_queue(netdev);
-                       ++adapter->restart_queue;
-               }
-#endif         
        }
 
        if (tx_ring->detect_tx_hung) {
@@ -3719,11 +3712,7 @@ done_cleaning:
                                tx_ring->buffer_info[i].time_stamp,
                                jiffies,
                                tx_desc->upper.fields.status);
-#ifdef CONFIG_NETDEVICES_MULTIQUEUE
                        netif_stop_subqueue(netdev, tx_ring->queue_index);
-#else
-                       netif_stop_queue(netdev);
-#endif
                }
        }
        tx_ring->total_bytes += total_bytes;
@@ -3735,22 +3724,75 @@ done_cleaning:
        return retval;
 }
 
+#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));
-       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
 }
 
 
@@ -3874,7 +3916,6 @@ send_up:
                        dev_kfree_skb_irq(skb);
                        goto next_desc;
                }
-               rx_ring->no_itr_adjust |= (staterr & E1000_RXD_STAT_DYNINT);
 
                total_bytes += skb->len;
                total_packets++;
@@ -3883,7 +3924,7 @@ send_up:
 
                skb->protocol = eth_type_trans(skb, netdev);
 
-               igb_receive_skb(adapter, staterr, rx_desc->wb.upper.vlan, skb);
+               igb_receive_skb(rx_ring, staterr, rx_desc, skb);
 
                netdev->last_rx = jiffies;
 
@@ -3906,6 +3947,13 @@ next_desc:
        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(rx_ring, cleaned_count);
 
@@ -4090,7 +4138,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);
@@ -4102,10 +4149,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;
@@ -4230,11 +4273,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);
@@ -4321,10 +4365,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); */
@@ -4332,10 +4377,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);
 
@@ -4452,8 +4498,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");