e100/e1000*/igb*/ixgb*: Add missing read memory barrier
[deliverable/linux.git] / drivers / net / igb / igb_main.c
index 94656179441dd43ce4f21c91c24d3ca719dcbfc4..9b4e5895f5f9d978992b204c3cbbbd8190b2340f 100644 (file)
@@ -1290,7 +1290,13 @@ static void igb_irq_disable(struct igb_adapter *adapter)
        wr32(E1000_IAM, 0);
        wr32(E1000_IMC, ~0);
        wrfl();
-       synchronize_irq(adapter->pdev->irq);
+       if (adapter->msix_entries) {
+               int i;
+               for (i = 0; i < adapter->num_q_vectors; i++)
+                       synchronize_irq(adapter->msix_entries[i].vector);
+       } else {
+               synchronize_irq(adapter->pdev->irq);
+       }
 }
 
 /**
@@ -1722,6 +1728,15 @@ static int __devinit igb_probe(struct pci_dev *pdev,
        u16 eeprom_apme_mask = IGB_EEPROM_APME;
        u32 part_num;
 
+       /* Catch broken hardware that put the wrong VF device ID in
+        * the PCIe SR-IOV capability.
+        */
+       if (pdev->is_virtfn) {
+               WARN(1, KERN_ERR "%s (%hx:%hx) should not be a VF!\n",
+                    pci_name(pdev), pdev->vendor, pdev->device);
+               return -EINVAL;
+       }
+
        err = pci_enable_device_mem(pdev);
        if (err)
                return err;
@@ -5338,6 +5353,7 @@ static bool igb_clean_tx_irq(struct igb_q_vector *q_vector)
 
        while ((eop_desc->wb.status & cpu_to_le32(E1000_TXD_STAT_DD)) &&
               (count < tx_ring->count)) {
+               rmb();  /* read buffer_info after eop_desc status */
                for (cleaned = false; !cleaned; count++) {
                        tx_desc = E1000_TX_DESC_ADV(*tx_ring, i);
                        buffer_info = &tx_ring->buffer_info[i];
@@ -5543,6 +5559,7 @@ static bool igb_clean_rx_irq_adv(struct igb_q_vector *q_vector,
                if (*work_done >= budget)
                        break;
                (*work_done)++;
+               rmb(); /* read descriptor and rx_buffer_info after status DD */
 
                skb = buffer_info->skb;
                prefetch(skb->data - NET_IP_ALIGN);
This page took 0.086072 seconds and 5 git commands to generate.