aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/qlge
diff options
context:
space:
mode:
authorRon Mercer <ron.mercer@qlogic.com>2009-08-27 07:02:10 -0400
committerDavid S. Miller <davem@davemloft.net>2009-08-29 02:22:31 -0400
commita4ab613717184138763c5fb4a4b4bbc354d5b0ee (patch)
tree80a69e608482f4a169cfe6ab4d2138c40b98bce6 /drivers/net/qlge
parentb2014ff8ac314f58d6542ec4ea7b576a2de21c8b (diff)
qlge: Allow running MSIx with fewer vectors.
Currently we downshift to MSI/Legacy if we don't get enough vectors for cpu_count RSS rings plus cpu_count TX completion rings. This patch allows running MSIX with the vector count that the platform provides. Signed-off-by: Ron Mercer <ron.mercer@qlogic.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/qlge')
-rw-r--r--drivers/net/qlge/qlge_main.c85
1 files changed, 38 insertions, 47 deletions
diff --git a/drivers/net/qlge/qlge_main.c b/drivers/net/qlge/qlge_main.c
index 89ea9c7a58c8..0cbda4d47dc7 100644
--- a/drivers/net/qlge/qlge_main.c
+++ b/drivers/net/qlge/qlge_main.c
@@ -2815,17 +2815,20 @@ static void ql_disable_msix(struct ql_adapter *qdev)
2815 } 2815 }
2816} 2816}
2817 2817
2818/* We start by trying to get the number of vectors
2819 * stored in qdev->intr_count. If we don't get that
2820 * many then we reduce the count and try again.
2821 */
2818static void ql_enable_msix(struct ql_adapter *qdev) 2822static void ql_enable_msix(struct ql_adapter *qdev)
2819{ 2823{
2820 int i; 2824 int i, err;
2821 2825
2822 qdev->intr_count = 1;
2823 /* Get the MSIX vectors. */ 2826 /* Get the MSIX vectors. */
2824 if (irq_type == MSIX_IRQ) { 2827 if (irq_type == MSIX_IRQ) {
2825 /* Try to alloc space for the msix struct, 2828 /* Try to alloc space for the msix struct,
2826 * if it fails then go to MSI/legacy. 2829 * if it fails then go to MSI/legacy.
2827 */ 2830 */
2828 qdev->msi_x_entry = kcalloc(qdev->rx_ring_count, 2831 qdev->msi_x_entry = kcalloc(qdev->intr_count,
2829 sizeof(struct msix_entry), 2832 sizeof(struct msix_entry),
2830 GFP_KERNEL); 2833 GFP_KERNEL);
2831 if (!qdev->msi_x_entry) { 2834 if (!qdev->msi_x_entry) {
@@ -2833,26 +2836,36 @@ static void ql_enable_msix(struct ql_adapter *qdev)
2833 goto msi; 2836 goto msi;
2834 } 2837 }
2835 2838
2836 for (i = 0; i < qdev->rx_ring_count; i++) 2839 for (i = 0; i < qdev->intr_count; i++)
2837 qdev->msi_x_entry[i].entry = i; 2840 qdev->msi_x_entry[i].entry = i;
2838 2841
2839 if (!pci_enable_msix 2842 /* Loop to get our vectors. We start with
2840 (qdev->pdev, qdev->msi_x_entry, qdev->rx_ring_count)) { 2843 * what we want and settle for what we get.
2841 set_bit(QL_MSIX_ENABLED, &qdev->flags); 2844 */
2842 qdev->intr_count = qdev->rx_ring_count; 2845 do {
2843 QPRINTK(qdev, IFUP, DEBUG, 2846 err = pci_enable_msix(qdev->pdev,
2844 "MSI-X Enabled, got %d vectors.\n", 2847 qdev->msi_x_entry, qdev->intr_count);
2845 qdev->intr_count); 2848 if (err > 0)
2846 return; 2849 qdev->intr_count = err;
2847 } else { 2850 } while (err > 0);
2851
2852 if (err < 0) {
2848 kfree(qdev->msi_x_entry); 2853 kfree(qdev->msi_x_entry);
2849 qdev->msi_x_entry = NULL; 2854 qdev->msi_x_entry = NULL;
2850 QPRINTK(qdev, IFUP, WARNING, 2855 QPRINTK(qdev, IFUP, WARNING,
2851 "MSI-X Enable failed, trying MSI.\n"); 2856 "MSI-X Enable failed, trying MSI.\n");
2857 qdev->intr_count = 1;
2852 irq_type = MSI_IRQ; 2858 irq_type = MSI_IRQ;
2859 } else if (err == 0) {
2860 set_bit(QL_MSIX_ENABLED, &qdev->flags);
2861 QPRINTK(qdev, IFUP, INFO,
2862 "MSI-X Enabled, got %d vectors.\n",
2863 qdev->intr_count);
2864 return;
2853 } 2865 }
2854 } 2866 }
2855msi: 2867msi:
2868 qdev->intr_count = 1;
2856 if (irq_type == MSI_IRQ) { 2869 if (irq_type == MSI_IRQ) {
2857 if (!pci_enable_msi(qdev->pdev)) { 2870 if (!pci_enable_msi(qdev->pdev)) {
2858 set_bit(QL_MSI_ENABLED, &qdev->flags); 2871 set_bit(QL_MSI_ENABLED, &qdev->flags);
@@ -2876,8 +2889,6 @@ static void ql_resolve_queues_to_irqs(struct ql_adapter *qdev)
2876 int i = 0; 2889 int i = 0;
2877 struct intr_context *intr_context = &qdev->intr_context[0]; 2890 struct intr_context *intr_context = &qdev->intr_context[0];
2878 2891
2879 ql_enable_msix(qdev);
2880
2881 if (likely(test_bit(QL_MSIX_ENABLED, &qdev->flags))) { 2892 if (likely(test_bit(QL_MSIX_ENABLED, &qdev->flags))) {
2882 /* Each rx_ring has it's 2893 /* Each rx_ring has it's
2883 * own intr_context since we have separate 2894 * own intr_context since we have separate
@@ -3438,40 +3449,20 @@ static int ql_configure_rings(struct ql_adapter *qdev)
3438 int i; 3449 int i;
3439 struct rx_ring *rx_ring; 3450 struct rx_ring *rx_ring;
3440 struct tx_ring *tx_ring; 3451 struct tx_ring *tx_ring;
3441 int cpu_cnt = num_online_cpus(); 3452 int cpu_cnt = min(MAX_CPUS, (int)num_online_cpus());
3442 3453
3443 /* 3454 /* In a perfect world we have one RSS ring for each CPU
3444 * For each processor present we allocate one 3455 * and each has it's own vector. To do that we ask for
3445 * rx_ring for outbound completions, and one 3456 * cpu_cnt vectors. ql_enable_msix() will adjust the
3446 * rx_ring for inbound completions. Plus there is 3457 * vector count to what we actually get. We then
3447 * always the one default queue. For the CPU 3458 * allocate an RSS ring for each.
3448 * counts we end up with the following rx_rings: 3459 * Essentially, we are doing min(cpu_count, msix_vector_count).
3449 * rx_ring count =
3450 * one default queue +
3451 * (CPU count * outbound completion rx_ring) +
3452 * (CPU count * inbound (RSS) completion rx_ring)
3453 * To keep it simple we limit the total number of
3454 * queues to < 32, so we truncate CPU to 8.
3455 * This limitation can be removed when requested.
3456 */ 3460 */
3457 3461 qdev->intr_count = cpu_cnt;
3458 if (cpu_cnt > MAX_CPUS) 3462 ql_enable_msix(qdev);
3459 cpu_cnt = MAX_CPUS; 3463 /* Adjust the RSS ring count to the actual vector count. */
3460 3464 qdev->rss_ring_count = qdev->intr_count;
3461 /*
3462 * rx_ring[0] is always the default queue.
3463 */
3464 /* Allocate outbound completion ring for each CPU. */
3465 qdev->tx_ring_count = cpu_cnt; 3465 qdev->tx_ring_count = cpu_cnt;
3466 /* Allocate inbound completion (RSS) ring for each CPU. */
3467 qdev->rss_ring_count = cpu_cnt;
3468 /*
3469 * qdev->rx_ring_count:
3470 * Total number of rx_rings. This includes the one
3471 * default queue, a number of outbound completion
3472 * handler rx_rings, and the number of inbound
3473 * completion handler rx_rings.
3474 */
3475 qdev->rx_ring_count = qdev->tx_ring_count + qdev->rss_ring_count; 3466 qdev->rx_ring_count = qdev->tx_ring_count + qdev->rss_ring_count;
3476 3467
3477 for (i = 0; i < qdev->tx_ring_count; i++) { 3468 for (i = 0; i < qdev->tx_ring_count; i++) {