aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/vmxnet3
diff options
context:
space:
mode:
authorAlexander Gordeev <agordeev@redhat.com>2014-02-18 05:12:02 -0500
committerDavid S. Miller <davem@davemloft.net>2014-02-18 15:33:34 -0500
commitb60b869d5f9f0987cf4e3fee22fb88786a281de7 (patch)
tree018ccc1c83901b5814004fac228ffa51e3e7a62d /drivers/net/vmxnet3
parent9e7df17e2e98aa82aaff9ef79235799a75e05f13 (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.c101
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
2739static int 2738static int
2740vmxnet3_acquire_msix_vectors(struct vmxnet3_adapter *adapter, 2739vmxnet3_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
2829msix_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;