diff options
| -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); |
