|
@@ -696,46 +696,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,
|
|
@@ -1054,51 +1091,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)
|
|
@@ -1108,13 +1114,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
|
|
@@ -1124,13 +1133,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;
|
|
|
}
|
|
|
|
|
|
/**
|