diff options
| author | Komal Seelam <kseelam@qti.qualcomm.com> | 2016-08-10 14:46:36 +0530 |
|---|---|---|
| committer | Anjaneedevi Kapparapu <akappa@codeaurora.org> | 2016-08-11 17:37:23 +0530 |
| commit | 291bf43cfba55f4494c2fc312dae47afe85c1dd3 (patch) | |
| tree | e7d3d2e8dcc39467036f84899bd92485e156c4cf | |
| parent | 37864a495b1c9770eac35bc84be613cd5dfb8514 (diff) | |
qcacld-2.0: Prevent NOC/Link Access in resume when Link is down
PCIe link training failure will not be indicated to cnss client driver
as a link down indication.
In System/Runtime PM resume callbacks, client driver will access the target
registers results in L2 errors.
Fix it by ensuring the PCIe link resume training is completed by reading
config space device-id.
Change-Id: I8be902330215cf3c8cb0700e6f0da5b69e274c96
CRs-Fixed: 1052965
| -rw-r--r-- | CORE/SERVICES/HIF/PCIe/if_pci.c | 37 |
1 files changed, 37 insertions, 0 deletions
diff --git a/CORE/SERVICES/HIF/PCIe/if_pci.c b/CORE/SERVICES/HIF/PCIe/if_pci.c index 20e2e4835ad2..c792f1ec3d7e 100644 --- a/CORE/SERVICES/HIF/PCIe/if_pci.c +++ b/CORE/SERVICES/HIF/PCIe/if_pci.c @@ -2873,6 +2873,39 @@ static int hif_pci_suspend(struct pci_dev *pdev, pm_message_t state) return ret; } +/** + * __hif_check_link_status() - API to check if PCIe link is active/not + * + * @pdev: PCIe device structure + * + * API reads the PCIe config space to verify if PCIe link training is + * successful or not. + * + * Return: Success/Failure + */ +static int __hif_check_link_status(struct pci_dev *pdev) +{ + uint16_t dev_id; + struct hif_pci_softc *sc = pci_get_drvdata(pdev); + + if (!sc) { + pr_err("%s: HIF Bus Context is Invalid\n", __func__); + return -EINVAL; + } + + pci_read_config_word(sc->pdev, PCI_DEVICE_ID, &dev_id); + + if (dev_id == sc->devid) + return 0; + + pr_err("%s: Invalid PCIe Config Space; PCIe link down dev_id:0x%04x\n", + __func__, dev_id); + sc->recovery = true; + vos_set_logp_in_progress(VOS_MODULE_ID_VOSS, TRUE); + vos_wlan_pci_link_down(); + return -EACCES; +} + static int __hif_pci_resume(struct pci_dev *pdev, bool runtime_pm) { @@ -2889,6 +2922,10 @@ __hif_pci_resume(struct pci_dev *pdev, bool runtime_pm) if (vos_is_logp_in_progress(VOS_MODULE_ID_HIF, NULL)) return err; + err = __hif_check_link_status(pdev); + if (err) + return err; + adf_os_atomic_set(&sc->pci_link_suspended, 0); adf_os_atomic_set(&sc->wow_done, 0); |
