aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/ath/wil6210/pcie_bus.c
diff options
context:
space:
mode:
authorAlexei Avshalom Lazar <ailizaro@codeaurora.org>2018-07-24 10:44:29 +0300
committerKalle Valo <kvalo@codeaurora.org>2018-07-31 11:00:33 +0300
commitaea2f8b781b2a76fb0af4de2273d0c56c6d256a4 (patch)
tree048161a7409d021a06f7a129178cf6f5d89de9a7 /drivers/net/wireless/ath/wil6210/pcie_bus.c
parentwil6210: align to latest auto generated wmi.h (diff)
downloadlinux-dev-aea2f8b781b2a76fb0af4de2273d0c56c6d256a4.tar.xz
linux-dev-aea2f8b781b2a76fb0af4de2273d0c56c6d256a4.zip
wil6210: add 3-MSI support
Extend MSI support to 3-MSI in order to load balance the tx\rx interrupts between different cores. use_msi module parameter has changed to n_msi. Usage: - Set n_msi to 0 for using INTx - Set n_msi to 1 for using single MSI - Set n_msi to 3 for using 3-MSI In 3-MSI configuration MSI 0 is used for TX interrupts, MSI 1 is used for RX interrupts and MSI 2 is used for MISC interrupts. Signed-off-by: Alexei Avshalom Lazar <ailizaro@codeaurora.org> Signed-off-by: Maya Erez <merez@codeaurora.org> Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
Diffstat (limited to 'drivers/net/wireless/ath/wil6210/pcie_bus.c')
-rw-r--r--drivers/net/wireless/ath/wil6210/pcie_bus.c60
1 files changed, 46 insertions, 14 deletions
diff --git a/drivers/net/wireless/ath/wil6210/pcie_bus.c b/drivers/net/wireless/ath/wil6210/pcie_bus.c
index 7192d9a91278..095c16fc5e8a 100644
--- a/drivers/net/wireless/ath/wil6210/pcie_bus.c
+++ b/drivers/net/wireless/ath/wil6210/pcie_bus.c
@@ -24,9 +24,9 @@
#include <linux/rtnetlink.h>
#include <linux/pm_runtime.h>
-static bool use_msi = true;
-module_param(use_msi, bool, 0444);
-MODULE_PARM_DESC(use_msi, " Use MSI interrupt, default - true");
+static int n_msi = 1;
+module_param(n_msi, int, 0444);
+MODULE_PARM_DESC(n_msi, " Use MSI interrupt: 0 - use INTx, 1 - (default) - single, or 3");
static bool ftm_mode;
module_param(ftm_mode, bool, 0444);
@@ -150,12 +150,24 @@ int wil_set_capabilities(struct wil6210_priv *wil)
void wil_disable_irq(struct wil6210_priv *wil)
{
- disable_irq(wil->pdev->irq);
+ int irq = wil->pdev->irq;
+
+ disable_irq(irq);
+ if (wil->n_msi == 3) {
+ disable_irq(irq + 1);
+ disable_irq(irq + 2);
+ }
}
void wil_enable_irq(struct wil6210_priv *wil)
{
- enable_irq(wil->pdev->irq);
+ int irq = wil->pdev->irq;
+
+ enable_irq(irq);
+ if (wil->n_msi == 3) {
+ enable_irq(irq + 1);
+ enable_irq(irq + 2);
+ }
}
static void wil_remove_all_additional_vifs(struct wil6210_priv *wil)
@@ -182,28 +194,47 @@ static int wil_if_pcie_enable(struct wil6210_priv *wil)
* and only MSI should be used
*/
int msi_only = pdev->msi_enabled;
- bool _use_msi = use_msi;
wil_dbg_misc(wil, "if_pcie_enable\n");
pci_set_master(pdev);
- wil_dbg_misc(wil, "Setup %s interrupt\n", use_msi ? "MSI" : "INTx");
+ /* how many MSI interrupts to request? */
+ switch (n_msi) {
+ case 3:
+ case 1:
+ wil_dbg_misc(wil, "Setup %d MSI interrupts\n", n_msi);
+ break;
+ case 0:
+ wil_dbg_misc(wil, "MSI interrupts disabled, use INTx\n");
+ break;
+ default:
+ wil_err(wil, "Invalid n_msi=%d, default to 1\n", n_msi);
+ n_msi = 1;
+ }
+
+ if (n_msi == 3 &&
+ pci_alloc_irq_vectors(pdev, n_msi, n_msi, PCI_IRQ_MSI) < n_msi) {
+ wil_err(wil, "3 MSI mode failed, try 1 MSI\n");
+ n_msi = 1;
+ }
- if (use_msi && pci_enable_msi(pdev)) {
+ if (n_msi == 1 && pci_enable_msi(pdev)) {
wil_err(wil, "pci_enable_msi failed, use INTx\n");
- _use_msi = false;
+ n_msi = 0;
}
- if (!_use_msi && msi_only) {
+ wil->n_msi = n_msi;
+
+ if (wil->n_msi == 0 && msi_only) {
wil_err(wil, "Interrupt pin not routed, unable to use INTx\n");
rc = -ENODEV;
goto stop_master;
}
- rc = wil6210_init_irq(wil, pdev->irq, _use_msi);
+ rc = wil6210_init_irq(wil, pdev->irq);
if (rc)
- goto stop_master;
+ goto release_vectors;
/* need reset here to obtain MAC */
mutex_lock(&wil->mutex);
@@ -216,8 +247,9 @@ static int wil_if_pcie_enable(struct wil6210_priv *wil)
release_irq:
wil6210_fini_irq(wil, pdev->irq);
- /* safe to call if no MSI */
- pci_disable_msi(pdev);
+ release_vectors:
+ /* safe to call if no allocation */
+ pci_free_irq_vectors(pdev);
stop_master:
pci_clear_master(pdev);
return rc;