]> err.no Git - linux-2.6/blobdiff - drivers/net/igb/igb_main.c
Merge branch 'master' of master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6
[linux-2.6] / drivers / net / igb / igb_main.c
index 7b6b780dc8a6884ebacc63e0ebe61d5c8863005b..afd4ce3f7b53f0ac27141c06e888cca7d395c40f 100644 (file)
@@ -71,8 +71,8 @@ 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 *);
+static void igb_free_tx_resources(struct igb_ring *);
+static void igb_free_rx_resources(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 +84,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 +102,10 @@ 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 bool igb_clean_tx_irq(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);
+static bool igb_clean_rx_irq_adv(struct igb_ring *, int *, int);
+static void igb_alloc_rx_buffers_adv(struct igb_ring *, int);
 static int igb_ioctl(struct net_device *, struct ifreq *, int cmd);
 static void igb_tx_timeout(struct net_device *);
 static void igb_reset_task(struct work_struct *);
@@ -229,12 +227,11 @@ static int igb_alloc_queues(struct igb_adapter *adapter)
        for (i = 0; i < adapter->num_rx_queues; i++) {
                struct igb_ring *ring = &(adapter->rx_ring[i]);
                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_clean, 64);
        }
        return 0;
 }
@@ -302,9 +299,6 @@ static void igb_configure_msix(struct igb_adapter *adapter)
                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,6 +309,7 @@ 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;
 
        wrfl();
 }
@@ -357,6 +352,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 +363,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:
@@ -436,12 +431,8 @@ 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))
@@ -450,7 +441,11 @@ static int igb_request_irq(struct igb_adapter *adapter)
                igb_free_all_rx_resources(adapter);
                adapter->num_rx_queues = 1;
                igb_alloc_queues(adapter);
+       } else {
+               wr32(E1000_MSIXBM(0), (E1000_EICR_RX_QUEUE0 |
+                                      E1000_EIMS_OTHER));
        }
+
        if (adapter->msi_enabled) {
                err = request_irq(adapter->pdev->irq, &igb_intr_msi, 0,
                                  netdev->name, netdev);
@@ -502,9 +497,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 +517,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)
@@ -632,12 +631,15 @@ static void igb_configure(struct igb_adapter *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 +662,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);
@@ -703,11 +702,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);
@@ -718,7 +715,8 @@ void igb_down(struct igb_adapter *adapter)
        adapter->link_speed = 0;
        adapter->link_duplex = 0;
 
-       igb_reset(adapter);
+       if (!pci_channel_offline(adapter->pdev))
+               igb_reset(adapter);
        igb_clean_all_tx_rings(adapter);
        igb_clean_all_rx_rings(adapter);
 }
@@ -819,6 +817,21 @@ void igb_reset(struct igb_adapter *adapter)
                adapter->hw.phy.ops.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;
+       }
+}
+
 /**
  * igb_probe - Device Initialization Routine
  * @pdev: PCI device information struct
@@ -838,13 +851,21 @@ static int __devinit igb_probe(struct pci_dev *pdev,
        struct e1000_hw *hw;
        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;
        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;
 
@@ -866,7 +887,7 @@ static int __devinit igb_probe(struct pci_dev *pdev,
                }
        }
 
-       err = pci_request_regions(pdev, igb_driver_name);
+       err = pci_request_selected_regions(pdev, bars, igb_driver_name);
        if (err)
                goto err_pci_reg;
 
@@ -887,6 +908,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);
@@ -906,7 +929,6 @@ static int __devinit igb_probe(struct pci_dev *pdev,
        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;
@@ -920,8 +942,6 @@ static int __devinit igb_probe(struct pci_dev *pdev,
        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;
@@ -1106,7 +1126,6 @@ static int __devinit igb_probe(struct pci_dev *pdev,
                adapter->msi_enabled ? "MSI" : "legacy",
                adapter->num_rx_queues, adapter->num_tx_queues);
 
-       cards_found++;
        return 0;
 
 err_register:
@@ -1127,7 +1146,7 @@ err_hw_init:
 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);
@@ -1174,7 +1193,7 @@ static void __devexit igb_remove(struct pci_dev *pdev)
        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);
 
@@ -1274,15 +1293,14 @@ 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);
+
        /* Fire a link status change interrupt to start the watchdog. */
        wr32(E1000_ICS, E1000_ICS_LSC);
 
@@ -1396,8 +1414,7 @@ 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;
                }
        }
@@ -1511,8 +1528,6 @@ int igb_setup_rx_resources(struct igb_adapter *adapter,
        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;
 
@@ -1540,8 +1555,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;
                }
        }
@@ -1769,12 +1783,11 @@ static void igb_configure_rx(struct igb_adapter *adapter)
  *
  * Free all transmit software resources
  **/
-static void igb_free_tx_resources(struct igb_adapter *adapter,
-                                 struct igb_ring *tx_ring)
+static 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;
@@ -1795,7 +1808,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,
@@ -1821,9 +1834,9 @@ static void igb_unmap_and_free_tx_resource(struct igb_adapter *adapter,
  * @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;
@@ -1860,7 +1873,7 @@ 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]);
 }
 
 /**
@@ -1870,12 +1883,11 @@ static void igb_clean_all_tx_rings(struct igb_adapter *adapter)
  *
  * Free all receive software resources
  **/
-static void igb_free_rx_resources(struct igb_adapter *adapter,
-                                 struct igb_ring *rx_ring)
+static 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;
@@ -1896,7 +1908,7 @@ 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]);
 }
 
 /**
@@ -1904,9 +1916,9 @@ static void igb_free_all_rx_resources(struct igb_adapter *adapter)
  * @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;
@@ -1970,7 +1982,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]);
 }
 
 /**
@@ -3014,26 +3026,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);
+       u32 icr = rd32(E1000_ICR);
 
-       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);
-       }
+       /* 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;
 }
@@ -3049,7 +3054,7 @@ static irqreturn_t igb_msix_tx(int irq, void *data)
 
        tx_ring->total_bytes = 0;
        tx_ring->total_packets = 0;
-       if (!igb_clean_tx_irq(adapter, tx_ring))
+       if (!igb_clean_tx_irq(tx_ring))
                /* Ring was not completely cleaned, so fire another interrupt */
                wr32(E1000_EICS, tx_ring->eims_value);
 
@@ -3064,21 +3069,19 @@ static irqreturn_t igb_msix_rx(int irq, void *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.
+        */
 
-       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 (adapter->set_itr) {
+               wr32(rx_ring->itr_register,
+                    1000000000 / (rx_ring->itr_val * 256));
+               adapter->set_itr = 0;
        }
 
+       if (netif_rx_schedule_prep(adapter->netdev, &rx_ring->napi))
+               __netif_rx_schedule(adapter->netdev, &rx_ring->napi);
+
        return IRQ_HANDLED;
 }
 
@@ -3092,7 +3095,6 @@ 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);
@@ -3101,25 +3103,17 @@ static irqreturn_t igb_intr_msi(int irq, void *data)
         * previous interrupt.
         */
        if (adapter->set_itr) {
-               wr32(E1000_ITR,
-                       1000000000 / (adapter->itr * 256));
+               wr32(E1000_ITR, 1000000000 / (adapter->itr * 256));
                adapter->set_itr = 0;
        }
 
-       /* 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(netdev, &adapter->rx_ring[0].napi);
 
        return IRQ_HANDLED;
 }
@@ -3133,7 +3127,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 */
@@ -3146,8 +3139,7 @@ static irqreturn_t igb_intr(int irq, void *data)
         * previous interrupt.
         */
        if (adapter->set_itr) {
-               wr32(E1000_ITR,
-                       1000000000 / (adapter->itr * 256));
+               wr32(E1000_ITR, 1000000000 / (adapter->itr * 256));
                adapter->set_itr = 0;
        }
 
@@ -3165,13 +3157,7 @@ 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(netdev, &adapter->rx_ring[0].napi);
 
        return IRQ_HANDLED;
 }
@@ -3200,14 +3186,13 @@ static int igb_clean(struct napi_struct *napi, int budget)
         * 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]);
+                       tx_clean_complete &= igb_clean_tx_irq(&adapter->tx_ring[i]);
                        spin_unlock(&adapter->tx_ring[i].tx_clean_lock);
                }
        }
 
        for (i = 0; i < adapter->num_rx_queues; i++)
-               igb_clean_rx_irq_adv(adapter, &adapter->rx_ring[i], &work_done,
+               igb_clean_rx_irq_adv(&adapter->rx_ring[i], &work_done,
                                     adapter->rx_ring[i].napi.weight);
 
        /* If no Tx and not enough Rx work done, exit the polling mode */
@@ -3237,7 +3222,7 @@ static int igb_clean_rx_ring_msix(struct napi_struct *napi, int budget)
        if (!netif_carrier_ok(netdev))
                goto quit_polling;
 
-       igb_clean_rx_irq_adv(adapter, rx_ring, &work_done, budget);
+       igb_clean_rx_irq_adv(rx_ring, &work_done, budget);
 
 
        /* If not enough Rx work done, exit the polling mode */
@@ -3255,6 +3240,10 @@ quit_polling:
                        else if (mean_size > IGB_DYN_ITR_LENGTH_HIGH)
                                igb_lower_rx_eitr(adapter, rx_ring);
                }
+
+               if (!test_bit(__IGB_DOWN, &adapter->state))
+                       wr32(E1000_EIMS, rx_ring->eims_value);
+
                return 0;
        }
 
@@ -3272,11 +3261,11 @@ static inline u32 get_head(struct igb_ring *tx_ring)
  * @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 net_device *netdev = adapter->netdev;
+       struct igb_adapter *adapter = tx_ring->adapter;
        struct e1000_hw *hw = &adapter->hw;
+       struct net_device *netdev = adapter->netdev;
        struct e1000_tx_desc *tx_desc;
        struct igb_buffer *buffer_info;
        struct sk_buff *skb;
@@ -3402,8 +3391,7 @@ static void igb_receive_skb(struct igb_adapter *adapter, u8 status, __le16 vlan,
 {
        if (adapter->vlgrp && (status & E1000_RXD_STAT_VP))
                vlan_hwaccel_receive_skb(skb, adapter->vlgrp,
-                                        le16_to_cpu(vlan) &
-                                        E1000_RXD_SPC_VLAN_MASK);
+                                        le16_to_cpu(vlan));
        else
                netif_receive_skb(skb);
 }
@@ -3431,10 +3419,10 @@ 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;
@@ -3557,8 +3545,7 @@ next_desc:
 
                /* 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;
                }
 
@@ -3573,7 +3560,7 @@ out:
        cleaned_count = IGB_DESC_UNUSED(rx_ring);
 
        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;
@@ -3589,10 +3576,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;
@@ -3975,7 +3962,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");
@@ -4031,10 +4022,10 @@ static void igb_netpoll(struct net_device *netdev)
 
        igb_irq_disable(adapter);
        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);
 
@@ -4078,8 +4069,13 @@ 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;
+       int err;
 
-       if (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,
                        "Cannot re-enable PCI device after reset.\n");
                return PCI_ERS_RESULT_DISCONNECT;