Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
[cascardo/linux.git] / drivers / net / ethernet / intel / ixgbe / ixgbe_lib.c
index ae36fd6..68e1e75 100644 (file)
@@ -126,6 +126,8 @@ static void ixgbe_get_first_reg_idx(struct ixgbe_adapter *adapter, u8 tc,
                break;
        case ixgbe_mac_82599EB:
        case ixgbe_mac_X540:
+       case ixgbe_mac_X550:
+       case ixgbe_mac_X550EM_x:
                if (num_tcs > 4) {
                        /*
                         * TCs    : TC0/1 TC2/3 TC4-7
@@ -696,46 +698,83 @@ static void ixgbe_set_num_queues(struct ixgbe_adapter *adapter)
        ixgbe_set_rss_queues(adapter);
 }
 
-static void ixgbe_acquire_msix_vectors(struct ixgbe_adapter *adapter,
-                                      int vectors)
+/**
+ * ixgbe_acquire_msix_vectors - acquire MSI-X vectors
+ * @adapter: board private structure
+ *
+ * Attempts to acquire a suitable range of MSI-X vector interrupts. Will
+ * return a negative error code if unable to acquire MSI-X vectors for any
+ * reason.
+ */
+static int ixgbe_acquire_msix_vectors(struct ixgbe_adapter *adapter)
 {
-       int vector_threshold;
+       struct ixgbe_hw *hw = &adapter->hw;
+       int i, vectors, vector_threshold;
+
+       /* We start by asking for one vector per queue pair */
+       vectors = max(adapter->num_rx_queues, adapter->num_tx_queues);
 
-       /* We'll want at least 2 (vector_threshold):
-        * 1) TxQ[0] + RxQ[0] handler
-        * 2) Other (Link Status Change, etc.)
+       /* It is easy to be greedy for MSI-X vectors. However, it really
+        * doesn't do much good if we have a lot more vectors than CPUs. We'll
+        * be somewhat conservative and only ask for (roughly) the same number
+        * of vectors as there are CPUs.
         */
-       vector_threshold = MIN_MSIX_COUNT;
+       vectors = min_t(int, vectors, num_online_cpus());
 
-       /*
-        * The more we get, the more we will assign to Tx/Rx Cleanup
-        * for the separate queues...where Rx Cleanup >= Tx Cleanup.
-        * Right now, we simply care about how many we'll get; we'll
-        * set them up later while requesting irq's.
+       /* Some vectors are necessary for non-queue interrupts */
+       vectors += NON_Q_VECTORS;
+
+       /* Hardware can only support a maximum of hw.mac->max_msix_vectors.
+        * With features such as RSS and VMDq, we can easily surpass the
+        * number of Rx and Tx descriptor queues supported by our device.
+        * Thus, we cap the maximum in the rare cases where the CPU count also
+        * exceeds our vector limit
         */
+       vectors = min_t(int, vectors, hw->mac.max_msix_vectors);
+
+       /* We want a minimum of two MSI-X vectors for (1) a TxQ[0] + RxQ[0]
+        * handler, and (2) an Other (Link Status Change, etc.) handler.
+        */
+       vector_threshold = MIN_MSIX_COUNT;
+
+       adapter->msix_entries = kcalloc(vectors,
+                                       sizeof(struct msix_entry),
+                                       GFP_KERNEL);
+       if (!adapter->msix_entries)
+               return -ENOMEM;
+
+       for (i = 0; i < vectors; i++)
+               adapter->msix_entries[i].entry = i;
+
        vectors = pci_enable_msix_range(adapter->pdev, adapter->msix_entries,
                                        vector_threshold, vectors);
 
        if (vectors < 0) {
-               /* Can't allocate enough MSI-X interrupts?  Oh well.
-                * This just means we'll go with either a single MSI
-                * vector or fall back to legacy interrupts.
+               /* A negative count of allocated vectors indicates an error in
+                * acquiring within the specified range of MSI-X vectors
                 */
-               netif_printk(adapter, hw, KERN_DEBUG, adapter->netdev,
-                            "Unable to allocate MSI-X interrupts\n");
+               e_dev_warn("Failed to allocate MSI-X interrupts. Err: %d\n",
+                          vectors);
+
                adapter->flags &= ~IXGBE_FLAG_MSIX_ENABLED;
                kfree(adapter->msix_entries);
                adapter->msix_entries = NULL;
-       } else {
-               adapter->flags |= IXGBE_FLAG_MSIX_ENABLED; /* Woot! */
-               /*
-                * Adjust for only the vectors we'll use, which is minimum
-                * of max_msix_q_vectors + NON_Q_VECTORS, or the number of
-                * vectors we were allocated.
-                */
-               vectors -= NON_Q_VECTORS;
-               adapter->num_q_vectors = min(vectors, adapter->max_q_vectors);
+
+               return vectors;
        }
+
+       /* we successfully allocated some number of vectors within our
+        * requested range.
+        */
+       adapter->flags |= IXGBE_FLAG_MSIX_ENABLED;
+
+       /* Adjust for only the vectors we'll use, which is minimum
+        * of max_q_vectors, or the number of vectors we were allocated.
+        */
+       vectors -= NON_Q_VECTORS;
+       adapter->num_q_vectors = min_t(int, vectors, adapter->max_q_vectors);
+
+       return 0;
 }
 
 static void ixgbe_add_ring(struct ixgbe_ring *ring,
@@ -807,6 +846,11 @@ static int ixgbe_alloc_q_vector(struct ixgbe_adapter *adapter,
                       ixgbe_poll, 64);
        napi_hash_add(&q_vector->napi);
 
+#ifdef CONFIG_NET_RX_BUSY_POLL
+       /* initialize busy poll */
+       atomic_set(&q_vector->state, IXGBE_QV_STATE_DISABLE);
+
+#endif
        /* tie q_vector and adapter together */
        adapter->q_vector[v_idx] = q_vector;
        q_vector->adapter = adapter;
@@ -1049,51 +1093,20 @@ static void ixgbe_reset_interrupt_capability(struct ixgbe_adapter *adapter)
  **/
 static void ixgbe_set_interrupt_capability(struct ixgbe_adapter *adapter)
 {
-       struct ixgbe_hw *hw = &adapter->hw;
-       int vector, v_budget, err;
-
-       /*
-        * It's easy to be greedy for MSI-X vectors, but it really
-        * doesn't do us much good if we have a lot more vectors
-        * than CPU's.  So let's be conservative and only ask for
-        * (roughly) the same number of vectors as there are CPU's.
-        * The default is to use pairs of vectors.
-        */
-       v_budget = max(adapter->num_rx_queues, adapter->num_tx_queues);
-       v_budget = min_t(int, v_budget, num_online_cpus());
-       v_budget += NON_Q_VECTORS;
-
-       /*
-        * At the same time, hardware can only support a maximum of
-        * hw.mac->max_msix_vectors vectors.  With features
-        * such as RSS and VMDq, we can easily surpass the number of Rx and Tx
-        * descriptor queues supported by our device.  Thus, we cap it off in
-        * those rare cases where the cpu count also exceeds our vector limit.
-        */
-       v_budget = min_t(int, v_budget, hw->mac.max_msix_vectors);
-
-       /* A failure in MSI-X entry allocation isn't fatal, but it does
-        * mean we disable MSI-X capabilities of the adapter. */
-       adapter->msix_entries = kcalloc(v_budget,
-                                       sizeof(struct msix_entry), GFP_KERNEL);
-       if (adapter->msix_entries) {
-               for (vector = 0; vector < v_budget; vector++)
-                       adapter->msix_entries[vector].entry = vector;
-
-               ixgbe_acquire_msix_vectors(adapter, v_budget);
+       int err;
 
-               if (adapter->flags & IXGBE_FLAG_MSIX_ENABLED)
-                       return;
-       }
+       /* We will try to get MSI-X interrupts first */
+       if (!ixgbe_acquire_msix_vectors(adapter))
+               return;
 
        /* At this point, we do not have MSI-X capabilities. We need to
         * reconfigure or disable various features which require MSI-X
         * capability.
         */
 
-       /* disable DCB if number of TCs exceeds 1 */
+       /* Disable DCB unless we only have a single traffic class */
        if (netdev_get_num_tc(adapter->netdev) > 1) {
-               e_err(probe, "num TCs exceeds number of queues - disabling DCB\n");
+               e_dev_warn("Number of DCB TCs exceeds number of available queues. Disabling DCB support.\n");
                netdev_reset_tc(adapter->netdev);
 
                if (adapter->hw.mac.type == ixgbe_mac_82598EB)
@@ -1103,13 +1116,16 @@ static void ixgbe_set_interrupt_capability(struct ixgbe_adapter *adapter)
                adapter->temp_dcb_cfg.pfc_mode_enable = false;
                adapter->dcb_cfg.pfc_mode_enable = false;
        }
+
        adapter->dcb_cfg.num_tcs.pg_tcs = 1;
        adapter->dcb_cfg.num_tcs.pfc_tcs = 1;
 
-       /* disable SR-IOV */
+       /* Disable SR-IOV support */
+       e_dev_warn("Disabling SR-IOV support\n");
        ixgbe_disable_sriov(adapter);
 
-       /* disable RSS */
+       /* Disable RSS */
+       e_dev_warn("Disabling RSS support\n");
        adapter->ring_feature[RING_F_RSS].limit = 1;
 
        /* recalculate number of queues now that many features have been
@@ -1119,13 +1135,11 @@ static void ixgbe_set_interrupt_capability(struct ixgbe_adapter *adapter)
        adapter->num_q_vectors = 1;
 
        err = pci_enable_msi(adapter->pdev);
-       if (err) {
-               netif_printk(adapter, hw, KERN_DEBUG, adapter->netdev,
-                            "Unable to allocate MSI interrupt, falling back to legacy.  Error: %d\n",
-                            err);
-               return;
-       }
-       adapter->flags |= IXGBE_FLAG_MSI_ENABLED;
+       if (err)
+               e_dev_warn("Failed to allocate MSI interrupt, falling back to legacy. Error: %d\n",
+                          err);
+       else
+               adapter->flags |= IXGBE_FLAG_MSI_ENABLED;
 }
 
 /**