qcacmn: Prevent NOC/Link Access in resume when Link is down

propagation from qcacld-2.0 to qcacmn.

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
diff --git a/hif/src/pcie/if_pci.c b/hif/src/pcie/if_pci.c
index 8260431..6fd8187 100644
--- a/hif/src/pcie/if_pci.c
+++ b/hif/src/pcie/if_pci.c
@@ -2675,6 +2675,45 @@
 }
 
 /**
+ * __hif_check_link_status() - API to check if PCIe link is active/not
+ * @scn: HIF Context
+ *
+ * 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 hif_softc *scn)
+{
+	uint16_t dev_id;
+	struct hif_pci_softc *sc = HIF_GET_PCI_SOFTC(scn);
+	struct hif_driver_state_callbacks *cbk = hif_get_callbacks_handle(scn);
+
+	if (!sc) {
+		HIF_ERROR("%s: HIF Bus Context is Invalid", __func__);
+		return -EINVAL;
+	}
+
+	pci_read_config_word(sc->pdev, PCI_DEVICE_ID, &dev_id);
+
+	if (dev_id == sc->devid)
+		return 0;
+
+	HIF_ERROR("%s: Invalid PCIe Config Space; PCIe link down dev_id:0x%04x",
+	       __func__, dev_id);
+
+	scn->recovery = true;
+
+	if (cbk && cbk->set_recovery_in_progress)
+		cbk->set_recovery_in_progress(cbk->context, true);
+	else
+		HIF_ERROR("%s: Driver Global Recovery is not set", __func__);
+
+	pld_is_pci_link_down(sc->dev);
+	return -EACCES;
+}
+
+/**
  * hif_bus_resume(): prepare hif for resume
  *
  * chose suspend type based on link suspend voting.
@@ -2683,6 +2722,12 @@
  */
 int hif_pci_bus_resume(struct hif_softc *scn)
 {
+	int ret;
+
+	ret = __hif_check_link_status(scn);
+	if (ret)
+		return ret;
+
 	if (hif_can_suspend_link(GET_HIF_OPAQUE_HDL(scn)))
 		return hif_bus_resume_link_down(scn);
 	else