aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorCarolyn Wyborny <carolyn.wyborny@intel.com>2013-12-10 02:58:34 -0500
committerJeff Kirsher <jeffrey.t.kirsher@intel.com>2013-12-18 01:43:14 -0500
commitcd14ef54d25bcf0b8e9205e75369e33b1d188417 (patch)
tree887b05587af35d176f4657f5181910bb35e6c164
parent02ef6e1d0b00233a89d2c8bced880d8ea39603b6 (diff)
igb: Change to use statically allocated array for MSIx entries
This patch changes how the driver initializes MSIx and checks for MSIx configuration. This change makes it easier to reconfigure the device when queue changes happen at runtime using ethtool's set_channels feature. Signed-off-by: Carolyn Wyborny <carolyn.wyborny@intel.com> Tested-by: Aaron Brown <aaron.f.brown@intel.com> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
-rw-r--r--drivers/net/ethernet/intel/igb/igb.h9
-rw-r--r--drivers/net/ethernet/intel/igb/igb_ethtool.c6
-rw-r--r--drivers/net/ethernet/intel/igb/igb_main.c38
3 files changed, 24 insertions, 29 deletions
diff --git a/drivers/net/ethernet/intel/igb/igb.h b/drivers/net/ethernet/intel/igb/igb.h
index 8aaca0a1dca0..ccf472f073dd 100644
--- a/drivers/net/ethernet/intel/igb/igb.h
+++ b/drivers/net/ethernet/intel/igb/igb.h
@@ -41,6 +41,7 @@
41#include <linux/if_vlan.h> 41#include <linux/if_vlan.h>
42#include <linux/i2c.h> 42#include <linux/i2c.h>
43#include <linux/i2c-algo-bit.h> 43#include <linux/i2c-algo-bit.h>
44#include <linux/pci.h>
44 45
45struct igb_adapter; 46struct igb_adapter;
46 47
@@ -67,6 +68,7 @@ struct igb_adapter;
67#define IGB_MIN_ITR_USECS 10 68#define IGB_MIN_ITR_USECS 10
68#define NON_Q_VECTORS 1 69#define NON_Q_VECTORS 1
69#define MAX_Q_VECTORS 8 70#define MAX_Q_VECTORS 8
71#define MAX_MSIX_ENTRIES 10
70 72
71/* Transmit and receive queues */ 73/* Transmit and receive queues */
72#define IGB_MAX_RX_QUEUES 8 74#define IGB_MAX_RX_QUEUES 8
@@ -127,9 +129,9 @@ struct vf_data_storage {
127#define IGB_TX_PTHRESH ((hw->mac.type == e1000_i354) ? 20 : 8) 129#define IGB_TX_PTHRESH ((hw->mac.type == e1000_i354) ? 20 : 8)
128#define IGB_TX_HTHRESH 1 130#define IGB_TX_HTHRESH 1
129#define IGB_RX_WTHRESH ((hw->mac.type == e1000_82576 && \ 131#define IGB_RX_WTHRESH ((hw->mac.type == e1000_82576 && \
130 adapter->msix_entries) ? 1 : 4) 132 (adapter->flags & IGB_FLAG_HAS_MSIX)) ? 1 : 4)
131#define IGB_TX_WTHRESH ((hw->mac.type == e1000_82576 && \ 133#define IGB_TX_WTHRESH ((hw->mac.type == e1000_82576 && \
132 adapter->msix_entries) ? 1 : 16) 134 (adapter->flags & IGB_FLAG_HAS_MSIX)) ? 1 : 16)
133 135
134/* this is the size past which hardware will drop packets when setting LPE=0 */ 136/* this is the size past which hardware will drop packets when setting LPE=0 */
135#define MAXIMUM_ETHERNET_VLAN_SIZE 1522 137#define MAXIMUM_ETHERNET_VLAN_SIZE 1522
@@ -357,7 +359,7 @@ struct igb_adapter {
357 unsigned int flags; 359 unsigned int flags;
358 360
359 unsigned int num_q_vectors; 361 unsigned int num_q_vectors;
360 struct msix_entry *msix_entries; 362 struct msix_entry msix_entries[MAX_MSIX_ENTRIES];
361 363
362 /* Interrupt Throttle Rate */ 364 /* Interrupt Throttle Rate */
363 u32 rx_itr_setting; 365 u32 rx_itr_setting;
@@ -469,6 +471,7 @@ struct igb_adapter {
469#define IGB_FLAG_MEDIA_RESET (1 << 10) 471#define IGB_FLAG_MEDIA_RESET (1 << 10)
470#define IGB_FLAG_MAS_CAPABLE (1 << 11) 472#define IGB_FLAG_MAS_CAPABLE (1 << 11)
471#define IGB_FLAG_MAS_ENABLE (1 << 12) 473#define IGB_FLAG_MAS_ENABLE (1 << 12)
474#define IGB_FLAG_HAS_MSIX (1 << 13)
472 475
473/* Media Auto Sense */ 476/* Media Auto Sense */
474#define IGB_MAS_ENABLE_0 0X0001 477#define IGB_MAS_ENABLE_0 0X0001
diff --git a/drivers/net/ethernet/intel/igb/igb_ethtool.c b/drivers/net/ethernet/intel/igb/igb_ethtool.c
index 1c7d2381af8c..1df02378de69 100644
--- a/drivers/net/ethernet/intel/igb/igb_ethtool.c
+++ b/drivers/net/ethernet/intel/igb/igb_ethtool.c
@@ -1386,7 +1386,7 @@ static int igb_intr_test(struct igb_adapter *adapter, u64 *data)
1386 *data = 0; 1386 *data = 0;
1387 1387
1388 /* Hook up test interrupt handler just for this test */ 1388 /* Hook up test interrupt handler just for this test */
1389 if (adapter->msix_entries) { 1389 if (adapter->flags & IGB_FLAG_HAS_MSIX) {
1390 if (request_irq(adapter->msix_entries[0].vector, 1390 if (request_irq(adapter->msix_entries[0].vector,
1391 igb_test_intr, 0, netdev->name, adapter)) { 1391 igb_test_intr, 0, netdev->name, adapter)) {
1392 *data = 1; 1392 *data = 1;
@@ -1519,7 +1519,7 @@ static int igb_intr_test(struct igb_adapter *adapter, u64 *data)
1519 msleep(10); 1519 msleep(10);
1520 1520
1521 /* Unhook test interrupt handler */ 1521 /* Unhook test interrupt handler */
1522 if (adapter->msix_entries) 1522 if (adapter->flags & IGB_FLAG_HAS_MSIX)
1523 free_irq(adapter->msix_entries[0].vector, adapter); 1523 free_irq(adapter->msix_entries[0].vector, adapter);
1524 else 1524 else
1525 free_irq(irq, adapter); 1525 free_irq(irq, adapter);
@@ -2933,7 +2933,7 @@ static void igb_get_channels(struct net_device *netdev,
2933 ch->max_combined = igb_max_channels(adapter); 2933 ch->max_combined = igb_max_channels(adapter);
2934 2934
2935 /* Report info for other vector */ 2935 /* Report info for other vector */
2936 if (adapter->msix_entries) { 2936 if (adapter->flags & IGB_FLAG_HAS_MSIX) {
2937 ch->max_other = NON_Q_VECTORS; 2937 ch->max_other = NON_Q_VECTORS;
2938 ch->other_count = NON_Q_VECTORS; 2938 ch->other_count = NON_Q_VECTORS;
2939 } 2939 }
diff --git a/drivers/net/ethernet/intel/igb/igb_main.c b/drivers/net/ethernet/intel/igb/igb_main.c
index db040d6e0f22..46d31a49f5ea 100644
--- a/drivers/net/ethernet/intel/igb/igb_main.c
+++ b/drivers/net/ethernet/intel/igb/igb_main.c
@@ -803,7 +803,7 @@ static void igb_assign_vector(struct igb_q_vector *q_vector, int msix_vector)
803 msixbm = E1000_EICR_RX_QUEUE0 << rx_queue; 803 msixbm = E1000_EICR_RX_QUEUE0 << rx_queue;
804 if (tx_queue > IGB_N0_QUEUE) 804 if (tx_queue > IGB_N0_QUEUE)
805 msixbm |= E1000_EICR_TX_QUEUE0 << tx_queue; 805 msixbm |= E1000_EICR_TX_QUEUE0 << tx_queue;
806 if (!adapter->msix_entries && msix_vector == 0) 806 if (!(adapter->flags & IGB_FLAG_HAS_MSIX) && msix_vector == 0)
807 msixbm |= E1000_EIMS_OTHER; 807 msixbm |= E1000_EIMS_OTHER;
808 array_wr32(E1000_MSIXBM(0), msix_vector, msixbm); 808 array_wr32(E1000_MSIXBM(0), msix_vector, msixbm);
809 q_vector->eims_value = msixbm; 809 q_vector->eims_value = msixbm;
@@ -1028,13 +1028,10 @@ static void igb_reset_interrupt_capability(struct igb_adapter *adapter)
1028{ 1028{
1029 int v_idx = adapter->num_q_vectors; 1029 int v_idx = adapter->num_q_vectors;
1030 1030
1031 if (adapter->msix_entries) { 1031 if (adapter->flags & IGB_FLAG_HAS_MSIX)
1032 pci_disable_msix(adapter->pdev); 1032 pci_disable_msix(adapter->pdev);
1033 kfree(adapter->msix_entries); 1033 else if (adapter->flags & IGB_FLAG_HAS_MSI)
1034 adapter->msix_entries = NULL;
1035 } else if (adapter->flags & IGB_FLAG_HAS_MSI) {
1036 pci_disable_msi(adapter->pdev); 1034 pci_disable_msi(adapter->pdev);
1037 }
1038 1035
1039 while (v_idx--) 1036 while (v_idx--)
1040 igb_reset_q_vector(adapter, v_idx); 1037 igb_reset_q_vector(adapter, v_idx);
@@ -1090,6 +1087,7 @@ static void igb_set_interrupt_capability(struct igb_adapter *adapter, bool msix)
1090 1087
1091 if (!msix) 1088 if (!msix)
1092 goto msi_only; 1089 goto msi_only;
1090 adapter->flags |= IGB_FLAG_HAS_MSIX;
1093 1091
1094 /* Number of supported queues. */ 1092 /* Number of supported queues. */
1095 adapter->num_rx_queues = adapter->rss_queues; 1093 adapter->num_rx_queues = adapter->rss_queues;
@@ -1110,12 +1108,6 @@ static void igb_set_interrupt_capability(struct igb_adapter *adapter, bool msix)
1110 1108
1111 /* add 1 vector for link status interrupts */ 1109 /* add 1 vector for link status interrupts */
1112 numvecs++; 1110 numvecs++;
1113 adapter->msix_entries = kcalloc(numvecs, sizeof(struct msix_entry),
1114 GFP_KERNEL);
1115
1116 if (!adapter->msix_entries)
1117 goto msi_only;
1118
1119 for (i = 0; i < numvecs; i++) 1111 for (i = 0; i < numvecs; i++)
1120 adapter->msix_entries[i].entry = i; 1112 adapter->msix_entries[i].entry = i;
1121 1113
@@ -1392,7 +1384,7 @@ static int igb_request_irq(struct igb_adapter *adapter)
1392 struct pci_dev *pdev = adapter->pdev; 1384 struct pci_dev *pdev = adapter->pdev;
1393 int err = 0; 1385 int err = 0;
1394 1386
1395 if (adapter->msix_entries) { 1387 if (adapter->flags & IGB_FLAG_HAS_MSIX) {
1396 err = igb_request_msix(adapter); 1388 err = igb_request_msix(adapter);
1397 if (!err) 1389 if (!err)
1398 goto request_done; 1390 goto request_done;
@@ -1436,7 +1428,7 @@ request_done:
1436 1428
1437static void igb_free_irq(struct igb_adapter *adapter) 1429static void igb_free_irq(struct igb_adapter *adapter)
1438{ 1430{
1439 if (adapter->msix_entries) { 1431 if (adapter->flags & IGB_FLAG_HAS_MSIX) {
1440 int vector = 0, i; 1432 int vector = 0, i;
1441 1433
1442 free_irq(adapter->msix_entries[vector++].vector, adapter); 1434 free_irq(adapter->msix_entries[vector++].vector, adapter);
@@ -1461,7 +1453,7 @@ static void igb_irq_disable(struct igb_adapter *adapter)
1461 * mapped into these registers and so clearing the bits can cause 1453 * mapped into these registers and so clearing the bits can cause
1462 * issues on the VF drivers so we only need to clear what we set 1454 * issues on the VF drivers so we only need to clear what we set
1463 */ 1455 */
1464 if (adapter->msix_entries) { 1456 if (adapter->flags & IGB_FLAG_HAS_MSIX) {
1465 u32 regval = rd32(E1000_EIAM); 1457 u32 regval = rd32(E1000_EIAM);
1466 wr32(E1000_EIAM, regval & ~adapter->eims_enable_mask); 1458 wr32(E1000_EIAM, regval & ~adapter->eims_enable_mask);
1467 wr32(E1000_EIMC, adapter->eims_enable_mask); 1459 wr32(E1000_EIMC, adapter->eims_enable_mask);
@@ -1472,7 +1464,7 @@ static void igb_irq_disable(struct igb_adapter *adapter)
1472 wr32(E1000_IAM, 0); 1464 wr32(E1000_IAM, 0);
1473 wr32(E1000_IMC, ~0); 1465 wr32(E1000_IMC, ~0);
1474 wrfl(); 1466 wrfl();
1475 if (adapter->msix_entries) { 1467 if (adapter->flags & IGB_FLAG_HAS_MSIX) {
1476 int i; 1468 int i;
1477 for (i = 0; i < adapter->num_q_vectors; i++) 1469 for (i = 0; i < adapter->num_q_vectors; i++)
1478 synchronize_irq(adapter->msix_entries[i].vector); 1470 synchronize_irq(adapter->msix_entries[i].vector);
@@ -1489,7 +1481,7 @@ static void igb_irq_enable(struct igb_adapter *adapter)
1489{ 1481{
1490 struct e1000_hw *hw = &adapter->hw; 1482 struct e1000_hw *hw = &adapter->hw;
1491 1483
1492 if (adapter->msix_entries) { 1484 if (adapter->flags & IGB_FLAG_HAS_MSIX) {
1493 u32 ims = E1000_IMS_LSC | E1000_IMS_DOUTSYNC | E1000_IMS_DRSTA; 1485 u32 ims = E1000_IMS_LSC | E1000_IMS_DOUTSYNC | E1000_IMS_DRSTA;
1494 u32 regval = rd32(E1000_EIAC); 1486 u32 regval = rd32(E1000_EIAC);
1495 wr32(E1000_EIAC, regval | adapter->eims_enable_mask); 1487 wr32(E1000_EIAC, regval | adapter->eims_enable_mask);
@@ -1712,7 +1704,7 @@ int igb_up(struct igb_adapter *adapter)
1712 for (i = 0; i < adapter->num_q_vectors; i++) 1704 for (i = 0; i < adapter->num_q_vectors; i++)
1713 napi_enable(&(adapter->q_vector[i]->napi)); 1705 napi_enable(&(adapter->q_vector[i]->napi));
1714 1706
1715 if (adapter->msix_entries) 1707 if (adapter->flags & IGB_FLAG_HAS_MSIX)
1716 igb_configure_msix(adapter); 1708 igb_configure_msix(adapter);
1717 else 1709 else
1718 igb_assign_vector(adapter->q_vector[0], 0); 1710 igb_assign_vector(adapter->q_vector[0], 0);
@@ -2565,7 +2557,7 @@ static int igb_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
2565 dev_info(&pdev->dev, "%s: PBA No: %s\n", netdev->name, part_str); 2557 dev_info(&pdev->dev, "%s: PBA No: %s\n", netdev->name, part_str);
2566 dev_info(&pdev->dev, 2558 dev_info(&pdev->dev,
2567 "Using %s interrupts. %d rx queue(s), %d tx queue(s)\n", 2559 "Using %s interrupts. %d rx queue(s), %d tx queue(s)\n",
2568 adapter->msix_entries ? "MSI-X" : 2560 (adapter->flags & IGB_FLAG_HAS_MSIX) ? "MSI-X" :
2569 (adapter->flags & IGB_FLAG_HAS_MSI) ? "MSI" : "legacy", 2561 (adapter->flags & IGB_FLAG_HAS_MSI) ? "MSI" : "legacy",
2570 adapter->num_rx_queues, adapter->num_tx_queues); 2562 adapter->num_rx_queues, adapter->num_tx_queues);
2571 switch (hw->mac.type) { 2563 switch (hw->mac.type) {
@@ -2653,7 +2645,7 @@ static int igb_enable_sriov(struct pci_dev *pdev, int num_vfs)
2653 int err = 0; 2645 int err = 0;
2654 int i; 2646 int i;
2655 2647
2656 if (!adapter->msix_entries || num_vfs > 7) { 2648 if (!(adapter->flags & IGB_FLAG_HAS_MSIX) || num_vfs > 7) {
2657 err = -EPERM; 2649 err = -EPERM;
2658 goto out; 2650 goto out;
2659 } 2651 }
@@ -4273,7 +4265,7 @@ static void igb_watchdog_task(struct work_struct *work)
4273 } 4265 }
4274 4266
4275 /* Cause software interrupt to ensure Rx ring is cleaned */ 4267 /* Cause software interrupt to ensure Rx ring is cleaned */
4276 if (adapter->msix_entries) { 4268 if (adapter->flags & IGB_FLAG_HAS_MSIX) {
4277 u32 eics = 0; 4269 u32 eics = 0;
4278 for (i = 0; i < adapter->num_q_vectors; i++) 4270 for (i = 0; i < adapter->num_q_vectors; i++)
4279 eics |= adapter->q_vector[i]->eims_value; 4271 eics |= adapter->q_vector[i]->eims_value;
@@ -6194,7 +6186,7 @@ static void igb_ring_irq_enable(struct igb_q_vector *q_vector)
6194 } 6186 }
6195 6187
6196 if (!test_bit(__IGB_DOWN, &adapter->state)) { 6188 if (!test_bit(__IGB_DOWN, &adapter->state)) {
6197 if (adapter->msix_entries) 6189 if (adapter->flags & IGB_FLAG_HAS_MSIX)
6198 wr32(E1000_EIMS, q_vector->eims_value); 6190 wr32(E1000_EIMS, q_vector->eims_value);
6199 else 6191 else
6200 igb_irq_enable(adapter); 6192 igb_irq_enable(adapter);
@@ -7561,7 +7553,7 @@ static void igb_netpoll(struct net_device *netdev)
7561 7553
7562 for (i = 0; i < adapter->num_q_vectors; i++) { 7554 for (i = 0; i < adapter->num_q_vectors; i++) {
7563 q_vector = adapter->q_vector[i]; 7555 q_vector = adapter->q_vector[i];
7564 if (adapter->msix_entries) 7556 if (adapter->flags & IGB_FLAG_HAS_MSIX)
7565 wr32(E1000_EIMC, q_vector->eims_value); 7557 wr32(E1000_EIMC, q_vector->eims_value);
7566 else 7558 else
7567 igb_irq_disable(adapter); 7559 igb_irq_disable(adapter);