diff options
author | Alexander Gordeev <agordeev@redhat.com> | 2014-02-18 05:12:02 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2014-02-18 15:33:34 -0500 |
commit | b60b869d5f9f0987cf4e3fee22fb88786a281de7 (patch) | |
tree | 018ccc1c83901b5814004fac228ffa51e3e7a62d /drivers/net/vmxnet3 | |
parent | 9e7df17e2e98aa82aaff9ef79235799a75e05f13 (diff) |
vmxnet3: Fix MSI-X/MSI enablement code
This update cleans up the MSI-X/MSI enablement code, fixes
vmxnet3_acquire_msix_vectors() invalid return values and
enables a dead code in case VMXNET3_LINUX_MIN_MSIX_VECT
MSI-X vectors were allocated.
Signed-off-by: Alexander Gordeev <agordeev@redhat.com>
Cc: Shreyas Bhatewara <sbhatewara@vmware.com>
Cc: pv-drivers@vmware.com
Cc: netdev@vger.kernel.org
Cc: linux-pci@vger.kernel.org
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/vmxnet3')
-rw-r--r-- | drivers/net/vmxnet3/vmxnet3_drv.c | 101 |
1 files changed, 46 insertions, 55 deletions
diff --git a/drivers/net/vmxnet3/vmxnet3_drv.c b/drivers/net/vmxnet3/vmxnet3_drv.c index 3be786faaaec..3a17797e0817 100644 --- a/drivers/net/vmxnet3/vmxnet3_drv.c +++ b/drivers/net/vmxnet3/vmxnet3_drv.c | |||
@@ -2729,47 +2729,44 @@ vmxnet3_read_mac_addr(struct vmxnet3_adapter *adapter, u8 *mac) | |||
2729 | /* | 2729 | /* |
2730 | * Enable MSIx vectors. | 2730 | * Enable MSIx vectors. |
2731 | * Returns : | 2731 | * Returns : |
2732 | * 0 on successful enabling of required vectors, | ||
2733 | * VMXNET3_LINUX_MIN_MSIX_VECT when only minimum number of vectors required | 2732 | * VMXNET3_LINUX_MIN_MSIX_VECT when only minimum number of vectors required |
2734 | * could be enabled. | 2733 | * were enabled. |
2735 | * number of vectors which can be enabled otherwise (this number is smaller | 2734 | * number of vectors which were enabled otherwise (this number is greater |
2736 | * than VMXNET3_LINUX_MIN_MSIX_VECT) | 2735 | * than VMXNET3_LINUX_MIN_MSIX_VECT) |
2737 | */ | 2736 | */ |
2738 | 2737 | ||
2739 | static int | 2738 | static int |
2740 | vmxnet3_acquire_msix_vectors(struct vmxnet3_adapter *adapter, | 2739 | vmxnet3_acquire_msix_vectors(struct vmxnet3_adapter *adapter, int nvec) |
2741 | int vectors) | ||
2742 | { | 2740 | { |
2743 | int err = 0, vector_threshold; | 2741 | do { |
2744 | vector_threshold = VMXNET3_LINUX_MIN_MSIX_VECT; | 2742 | int err = pci_enable_msix(adapter->pdev, |
2745 | 2743 | adapter->intr.msix_entries, nvec); | |
2746 | while (vectors >= vector_threshold) { | ||
2747 | err = pci_enable_msix(adapter->pdev, adapter->intr.msix_entries, | ||
2748 | vectors); | ||
2749 | if (!err) { | 2744 | if (!err) { |
2750 | adapter->intr.num_intrs = vectors; | 2745 | return nvec; |
2751 | return 0; | ||
2752 | } else if (err < 0) { | 2746 | } else if (err < 0) { |
2753 | dev_err(&adapter->netdev->dev, | 2747 | dev_err(&adapter->netdev->dev, |
2754 | "Failed to enable MSI-X, error: %d\n", err); | 2748 | "Failed to enable MSI-X, error: %d\n", err); |
2755 | vectors = 0; | 2749 | return err; |
2756 | } else if (err < vector_threshold) { | 2750 | } else if (err < VMXNET3_LINUX_MIN_MSIX_VECT) { |
2757 | break; | 2751 | dev_info(&adapter->pdev->dev, |
2752 | "Number of MSI-X which can be allocated " | ||
2753 | "is lower than min threshold required.\n"); | ||
2754 | return -ENOSPC; | ||
2758 | } else { | 2755 | } else { |
2759 | /* If fails to enable required number of MSI-x vectors | 2756 | /* If fails to enable required number of MSI-x vectors |
2760 | * try enabling minimum number of vectors required. | 2757 | * try enabling minimum number of vectors required. |
2761 | */ | 2758 | */ |
2762 | dev_err(&adapter->netdev->dev, | 2759 | dev_err(&adapter->netdev->dev, |
2763 | "Failed to enable %d MSI-X, trying %d instead\n", | 2760 | "Failed to enable %d MSI-X, trying %d\n", |
2764 | vectors, vector_threshold); | 2761 | nvec, VMXNET3_LINUX_MIN_MSIX_VECT); |
2765 | vectors = vector_threshold; | 2762 | nvec = VMXNET3_LINUX_MIN_MSIX_VECT; |
2766 | } | 2763 | } |
2767 | } | 2764 | } while (nvec >= VMXNET3_LINUX_MIN_MSIX_VECT); |
2768 | 2765 | ||
2769 | dev_info(&adapter->pdev->dev, | 2766 | /* |
2770 | "Number of MSI-X interrupts which can be allocated " | 2767 | * Should never get here |
2771 | "is lower than min threshold required.\n"); | 2768 | */ |
2772 | return err; | 2769 | return -ENOSPC; |
2773 | } | 2770 | } |
2774 | 2771 | ||
2775 | 2772 | ||
@@ -2796,56 +2793,50 @@ vmxnet3_alloc_intr_resources(struct vmxnet3_adapter *adapter) | |||
2796 | 2793 | ||
2797 | #ifdef CONFIG_PCI_MSI | 2794 | #ifdef CONFIG_PCI_MSI |
2798 | if (adapter->intr.type == VMXNET3_IT_MSIX) { | 2795 | if (adapter->intr.type == VMXNET3_IT_MSIX) { |
2799 | int vector, err = 0; | 2796 | int i, nvec; |
2800 | 2797 | ||
2801 | adapter->intr.num_intrs = (adapter->share_intr == | 2798 | nvec = adapter->share_intr == VMXNET3_INTR_TXSHARE ? |
2802 | VMXNET3_INTR_TXSHARE) ? 1 : | 2799 | 1 : adapter->num_tx_queues; |
2803 | adapter->num_tx_queues; | 2800 | nvec += adapter->share_intr == VMXNET3_INTR_BUDDYSHARE ? |
2804 | adapter->intr.num_intrs += (adapter->share_intr == | 2801 | 0 : adapter->num_rx_queues; |
2805 | VMXNET3_INTR_BUDDYSHARE) ? 0 : | 2802 | nvec += 1; /* for link event */ |
2806 | adapter->num_rx_queues; | 2803 | nvec = nvec > VMXNET3_LINUX_MIN_MSIX_VECT ? |
2807 | adapter->intr.num_intrs += 1; /* for link event */ | 2804 | nvec : VMXNET3_LINUX_MIN_MSIX_VECT; |
2808 | 2805 | ||
2809 | adapter->intr.num_intrs = (adapter->intr.num_intrs > | 2806 | for (i = 0; i < nvec; i++) |
2810 | VMXNET3_LINUX_MIN_MSIX_VECT | 2807 | adapter->intr.msix_entries[i].entry = i; |
2811 | ? adapter->intr.num_intrs : | 2808 | |
2812 | VMXNET3_LINUX_MIN_MSIX_VECT); | 2809 | nvec = vmxnet3_acquire_msix_vectors(adapter, nvec); |
2813 | 2810 | if (nvec < 0) | |
2814 | for (vector = 0; vector < adapter->intr.num_intrs; vector++) | 2811 | goto msix_err; |
2815 | adapter->intr.msix_entries[vector].entry = vector; | 2812 | |
2816 | |||
2817 | err = vmxnet3_acquire_msix_vectors(adapter, | ||
2818 | adapter->intr.num_intrs); | ||
2819 | /* If we cannot allocate one MSIx vector per queue | 2813 | /* If we cannot allocate one MSIx vector per queue |
2820 | * then limit the number of rx queues to 1 | 2814 | * then limit the number of rx queues to 1 |
2821 | */ | 2815 | */ |
2822 | if (err == VMXNET3_LINUX_MIN_MSIX_VECT) { | 2816 | if (nvec == VMXNET3_LINUX_MIN_MSIX_VECT) { |
2823 | if (adapter->share_intr != VMXNET3_INTR_BUDDYSHARE | 2817 | if (adapter->share_intr != VMXNET3_INTR_BUDDYSHARE |
2824 | || adapter->num_rx_queues != 1) { | 2818 | || adapter->num_rx_queues != 1) { |
2825 | adapter->share_intr = VMXNET3_INTR_TXSHARE; | 2819 | adapter->share_intr = VMXNET3_INTR_TXSHARE; |
2826 | netdev_err(adapter->netdev, | 2820 | netdev_err(adapter->netdev, |
2827 | "Number of rx queues : 1\n"); | 2821 | "Number of rx queues : 1\n"); |
2828 | adapter->num_rx_queues = 1; | 2822 | adapter->num_rx_queues = 1; |
2829 | adapter->intr.num_intrs = | ||
2830 | VMXNET3_LINUX_MIN_MSIX_VECT; | ||
2831 | } | 2823 | } |
2832 | return; | ||
2833 | } | 2824 | } |
2834 | if (!err) | ||
2835 | return; | ||
2836 | 2825 | ||
2826 | adapter->intr.num_intrs = nvec; | ||
2827 | return; | ||
2828 | |||
2829 | msix_err: | ||
2837 | /* If we cannot allocate MSIx vectors use only one rx queue */ | 2830 | /* If we cannot allocate MSIx vectors use only one rx queue */ |
2838 | dev_info(&adapter->pdev->dev, | 2831 | dev_info(&adapter->pdev->dev, |
2839 | "Failed to enable MSI-X, error %d. " | 2832 | "Failed to enable MSI-X, error %d. " |
2840 | "Limiting #rx queues to 1, try MSI.\n", err); | 2833 | "Limiting #rx queues to 1, try MSI.\n", nvec); |
2841 | 2834 | ||
2842 | adapter->intr.type = VMXNET3_IT_MSI; | 2835 | adapter->intr.type = VMXNET3_IT_MSI; |
2843 | } | 2836 | } |
2844 | 2837 | ||
2845 | if (adapter->intr.type == VMXNET3_IT_MSI) { | 2838 | if (adapter->intr.type == VMXNET3_IT_MSI) { |
2846 | int err; | 2839 | if (!pci_enable_msi(adapter->pdev)) { |
2847 | err = pci_enable_msi(adapter->pdev); | ||
2848 | if (!err) { | ||
2849 | adapter->num_rx_queues = 1; | 2840 | adapter->num_rx_queues = 1; |
2850 | adapter->intr.num_intrs = 1; | 2841 | adapter->intr.num_intrs = 1; |
2851 | return; | 2842 | return; |