e100/e1000*/igb*/ixgb*: Add missing read memory barrier
[deliverable/linux.git] / drivers / net / igb / igb_main.c
index 3881918f5382c4e1305e4c5127bfbb2180bb85cd..9b4e5895f5f9d978992b204c3cbbbd8190b2340f 100644 (file)
@@ -630,9 +630,6 @@ static void igb_cache_ring_register(struct igb_adapter *adapter)
                        for (; i < adapter->rss_queues; i++)
                                adapter->rx_ring[i]->reg_idx = rbase_offset +
                                                               Q_IDX_82576(i);
-                       for (; j < adapter->rss_queues; j++)
-                               adapter->tx_ring[j]->reg_idx = rbase_offset +
-                                                              Q_IDX_82576(j);
                }
        case e1000_82575:
        case e1000_82580:
@@ -996,7 +993,10 @@ static void igb_set_interrupt_capability(struct igb_adapter *adapter)
 
        /* Number of supported queues. */
        adapter->num_rx_queues = adapter->rss_queues;
-       adapter->num_tx_queues = adapter->rss_queues;
+       if (adapter->vfs_allocated_count)
+               adapter->num_tx_queues = 1;
+       else
+               adapter->num_tx_queues = adapter->rss_queues;
 
        /* start with one vector for every rx queue */
        numvecs = adapter->num_rx_queues;
@@ -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;
@@ -2091,9 +2106,6 @@ static void __devinit igb_probe_vfs(struct igb_adapter * adapter)
 #ifdef CONFIG_PCI_IOV
        struct pci_dev *pdev = adapter->pdev;
 
-       if (adapter->vfs_allocated_count > 7)
-               adapter->vfs_allocated_count = 7;
-
        if (adapter->vfs_allocated_count) {
                adapter->vf_data = kcalloc(adapter->vfs_allocated_count,
                                           sizeof(struct vf_data_storage),
@@ -2258,7 +2270,7 @@ static int __devinit igb_sw_init(struct igb_adapter *adapter)
 
 #ifdef CONFIG_PCI_IOV
        if (hw->mac.type == e1000_82576)
-               adapter->vfs_allocated_count = max_vfs;
+               adapter->vfs_allocated_count = (max_vfs > 7) ? 7 : max_vfs;
 
 #endif /* CONFIG_PCI_IOV */
        adapter->rss_queues = min_t(u32, IGB_MAX_RX_QUEUES, num_online_cpus());
@@ -2720,14 +2732,16 @@ static void igb_setup_mrqc(struct igb_adapter *adapter)
        }
        igb_vmm_control(adapter);
 
-       mrqc |= (E1000_MRQC_RSS_FIELD_IPV4 |
-                E1000_MRQC_RSS_FIELD_IPV4_TCP);
-       mrqc |= (E1000_MRQC_RSS_FIELD_IPV6 |
-                E1000_MRQC_RSS_FIELD_IPV6_TCP);
-       mrqc |= (E1000_MRQC_RSS_FIELD_IPV4_UDP |
-                E1000_MRQC_RSS_FIELD_IPV6_UDP);
-       mrqc |= (E1000_MRQC_RSS_FIELD_IPV6_UDP_EX |
-                E1000_MRQC_RSS_FIELD_IPV6_TCP_EX);
+       /*
+        * Generate RSS hash based on TCP port numbers and/or
+        * IPv4/v6 src and dst addresses since UDP cannot be
+        * hashed reliably due to IP fragmentation
+        */
+       mrqc |= E1000_MRQC_RSS_FIELD_IPV4 |
+               E1000_MRQC_RSS_FIELD_IPV4_TCP |
+               E1000_MRQC_RSS_FIELD_IPV6 |
+               E1000_MRQC_RSS_FIELD_IPV6_TCP |
+               E1000_MRQC_RSS_FIELD_IPV6_TCP_EX;
 
        wr32(E1000_MRQC, mrqc);
 }
@@ -4977,6 +4991,10 @@ static void igb_vf_reset_msg(struct igb_adapter *adapter, u32 vf)
 
 static int igb_set_vf_mac_addr(struct igb_adapter *adapter, u32 *msg, int vf)
 {
+       /*
+        * The VF MAC Address is stored in a packed array of bytes
+        * starting at the second 32 bit word of the msg array
+        */
        unsigned char *addr = (char *)&msg[1];
        int err = -1;
 
@@ -5335,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];
@@ -5540,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.028286 seconds and 5 git commands to generate.