diff options
author | Carolyn Wyborny <carolyn.wyborny@intel.com> | 2013-12-10 02:58:34 -0500 |
---|---|---|
committer | Jeff Kirsher <jeffrey.t.kirsher@intel.com> | 2013-12-18 01:43:14 -0500 |
commit | cd14ef54d25bcf0b8e9205e75369e33b1d188417 (patch) | |
tree | 887b05587af35d176f4657f5181910bb35e6c164 | |
parent | 02ef6e1d0b00233a89d2c8bced880d8ea39603b6 (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.h | 9 | ||||
-rw-r--r-- | drivers/net/ethernet/intel/igb/igb_ethtool.c | 6 | ||||
-rw-r--r-- | drivers/net/ethernet/intel/igb/igb_main.c | 38 |
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 | ||
45 | struct igb_adapter; | 46 | struct 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 | ||
1437 | static void igb_free_irq(struct igb_adapter *adapter) | 1429 | static 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); |