diff options
author | Sergei Maksimenko <smaksimenko@quantenna.com> | 2018-02-10 17:04:18 +0300 |
---|---|---|
committer | Kalle Valo <kvalo@codeaurora.org> | 2018-02-27 19:18:43 +0300 |
commit | a34d7bcb73f553f1ea65eeff744c66e77b167175 (patch) | |
tree | bd9c9f8e0a5ee52e61939d7ec72e800021cd5f8a /drivers/net/wireless/quantenna | |
parent | 1d5e3b90ab0160375d15dd8f322c1bfdb8a83e1e (diff) | |
download | linux-a34d7bcb73f553f1ea65eeff744c66e77b167175.tar.xz |
qtnfmac: enable reloading of qtnfmac kernel modules
This patch enables rmmod/insmod for qtnfmac kernel modules:
- do not 'pin' pci device in order to disable it on module unload
- implement card reset procedure
- restore PCI bar addresses for restarted wireless card
Signed-off-by: Sergei Maksimenko <smaksimenko@quantenna.com>
Signed-off-by: Sergey Matyukevich <sergey.matyukevich.os@quantenna.com>
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
Diffstat (limited to 'drivers/net/wireless/quantenna')
3 files changed, 16 insertions, 1 deletions
diff --git a/drivers/net/wireless/quantenna/qtnfmac/pearl/pcie.c b/drivers/net/wireless/quantenna/qtnfmac/pearl/pcie.c index be5813aa1486..7aa222286d8e 100644 --- a/drivers/net/wireless/quantenna/qtnfmac/pearl/pcie.c +++ b/drivers/net/wireless/quantenna/qtnfmac/pearl/pcie.c @@ -162,6 +162,17 @@ static void qtnf_deassert_intx(struct qtnf_pcie_bus_priv *priv) qtnf_non_posted_write(cfg, reg); } +static void qtnf_reset_card(struct qtnf_pcie_bus_priv *priv) +{ + const u32 data = QTN_PEARL_IPC_IRQ_WORD(QTN_PEARL_LHOST_EP_RESET); + void __iomem *reg = priv->sysctl_bar + + QTN_PEARL_SYSCTL_LHOST_IRQ_OFFSET; + + qtnf_non_posted_write(data, reg); + msleep(QTN_EP_RESET_WAIT_MS); + pci_restore_state(priv->pdev); +} + static void qtnf_ipc_gen_ep_int(void *arg) { const struct qtnf_pcie_bus_priv *priv = arg; @@ -1308,7 +1319,6 @@ static int qtnf_pcie_probe(struct pci_dev *pdev, const struct pci_device_id *id) goto err_base; } - pcim_pin_device(pdev); pci_set_master(pdev); ret = qtnf_pcie_init_irq(pcie_priv); @@ -1323,6 +1333,8 @@ static int qtnf_pcie_probe(struct pci_dev *pdev, const struct pci_device_id *id) goto err_base; } + pci_save_state(pdev); + ret = qtnf_pcie_init_shm_ipc(pcie_priv); if (ret < 0) { pr_err("PCIE SHM IPC init failed\n"); @@ -1425,6 +1437,7 @@ static void qtnf_pcie_remove(struct pci_dev *pdev) qtnf_debugfs_remove(bus); qtnf_pcie_free_shm_ipc(priv); + qtnf_reset_card(priv); } #ifdef CONFIG_PM_SLEEP diff --git a/drivers/net/wireless/quantenna/qtnfmac/pearl/pcie_ipc.h b/drivers/net/wireless/quantenna/qtnfmac/pearl/pcie_ipc.h index c5a4e46d26ef..00bb21a1c47a 100644 --- a/drivers/net/wireless/quantenna/qtnfmac/pearl/pcie_ipc.h +++ b/drivers/net/wireless/quantenna/qtnfmac/pearl/pcie_ipc.h @@ -46,6 +46,7 @@ /* state transition timeouts */ #define QTN_FW_DL_TIMEOUT_MS 3000 #define QTN_FW_QLINK_TIMEOUT_MS 30000 +#define QTN_EP_RESET_WAIT_MS 1000 #define PCIE_HDP_INT_RX_BITS (0 \ | PCIE_HDP_INT_EP_TXDMA \ diff --git a/drivers/net/wireless/quantenna/qtnfmac/pearl/pcie_regs_pearl.h b/drivers/net/wireless/quantenna/qtnfmac/pearl/pcie_regs_pearl.h index 5b48b425fa7f..0bfe285b6b48 100644 --- a/drivers/net/wireless/quantenna/qtnfmac/pearl/pcie_regs_pearl.h +++ b/drivers/net/wireless/quantenna/qtnfmac/pearl/pcie_regs_pearl.h @@ -351,5 +351,6 @@ #define QTN_PEARL_IPC_IRQ_WORD(irq) (BIT(irq) | BIT(irq + 16)) #define QTN_PEARL_LHOST_IPC_IRQ (6) +#define QTN_PEARL_LHOST_EP_RESET (7) #endif /* __PEARL_PCIE_H */ |