qcacmn: Avoid shadow register access when link is down

When the scheduler thread initiates the WMA_SET_BSSKEY_REQ
we send CMD_UPDATE_RX_REO_QUEUE to REO srng. This is done by
posting a descriptor to the reo command ring and then we
update the HP so that the HW can consume the descriptor.
Avoid accessing HP shadow address when we are in runtime
suspend state. Perform a hif_pm_runtime_get to resume the
link and access the shadow register and once done initiate a
hif_pm_runtime_put to allow device to go into runtime
suspend.

Change-Id: I24c3e046a5769f03a0f1969360cccdbe55b81d45
CRs-Fixed: 2495720
diff --git a/dp/wifi3.0/dp_main.c b/dp/wifi3.0/dp_main.c
index 26ca66c..a89c2f4 100644
--- a/dp/wifi3.0/dp_main.c
+++ b/dp/wifi3.0/dp_main.c
@@ -9167,6 +9167,25 @@
 }
 
 /**
+ * dp_flush_ring_hptp() - Update ring shadow
+ *			  register HP/TP address when runtime
+ *                        resume
+ * @opaque_soc: DP soc context
+ *
+ * Return: None
+ */
+static
+void dp_flush_ring_hptp(struct dp_soc *soc, hal_ring_handle_t hal_srng)
+{
+	if (hal_srng) {
+		/* Acquire the lock */
+		hal_srng_access_start(soc->hal_soc, hal_srng);
+
+		hal_srng_access_end(soc->hal_soc, hal_srng);
+	}
+}
+
+/**
  * dp_runtime_resume() - ensure DP is ready to runtime resume
  * @opaque_pdev: DP pdev context
  *
@@ -9178,23 +9197,17 @@
 {
 	struct dp_pdev *pdev = (struct dp_pdev *)opaque_pdev;
 	struct dp_soc *soc = pdev->soc;
-	hal_ring_handle_t hal_srng;
 	int i;
 
 	if (soc->intr_mode == DP_INTR_POLL)
 		qdf_timer_mod(&soc->int_timer, DP_INTR_POLL_TIMER_MS);
 
 	for (i = 0; i < MAX_TCL_DATA_RINGS; i++) {
-		hal_srng = soc->tcl_data_ring[i].hal_srng;
-		if (hal_srng) {
-			/* We actually only need to acquire the lock */
-			hal_srng_access_start(soc->hal_soc, hal_srng);
-			/* Update SRC ring head pointer for HW to send
-			   all pending packets */
-			hal_srng_access_end(soc->hal_soc, hal_srng);
-		}
+		dp_flush_ring_hptp(soc, soc->tcl_data_ring[i].hal_srng);
 	}
 
+	dp_flush_ring_hptp(soc, soc->reo_cmd_ring.hal_srng);
+
 	return QDF_STATUS_SUCCESS;
 }
 #endif /* FEATURE_RUNTIME_PM */
diff --git a/hal/wifi3.0/hal_internal.h b/hal/wifi3.0/hal_internal.h
index 1c858d4..42fead9 100644
--- a/hal/wifi3.0/hal_internal.h
+++ b/hal/wifi3.0/hal_internal.h
@@ -284,6 +284,9 @@
 	} u;
 
 	struct hal_soc *hal_soc;
+
+	/* Number of times hp/tp updated in runtime resume */
+	uint32_t needs_flush;
 };
 
 /* HW SRNG configuration table */
diff --git a/hal/wifi3.0/hal_reo.c b/hal/wifi3.0/hal_reo.c
index da4b947..6c9c917 100644
--- a/hal/wifi3.0/hal_reo.c
+++ b/hal/wifi3.0/hal_reo.c
@@ -684,6 +684,7 @@
 	struct hal_soc *hal_soc = (struct hal_soc *)hal_soc_hdl;
 	uint32_t *reo_desc, val;
 	struct hal_reo_cmd_update_queue_params *p;
+	struct hal_srng *srng = (struct hal_srng *)hal_ring_hdl;
 
 	p = &cmd->u.upd_queue_params;
 
@@ -880,7 +881,14 @@
 	HAL_DESC_SET_FIELD(reo_desc, REO_UPDATE_RX_REO_QUEUE_8,
 		PN_127_96, p->pn_127_96);
 
-	hal_srng_access_end(hal_soc, hal_ring_hdl);
+	if (hif_pm_runtime_get(hal_soc->hif_handle) == 0) {
+		hal_srng_access_end(hal_soc_hdl, hal_ring_hdl);
+		hif_pm_runtime_put(hal_soc->hif_handle);
+	} else {
+		hal_srng_access_end_reap(hal_soc_hdl, hal_ring_hdl);
+		srng->needs_flush++;
+	}
+
 	val = reo_desc[CMD_HEADER_DW_OFFSET];
 	return HAL_GET_FIELD(UNIFORM_REO_CMD_HEADER_0, REO_CMD_NUMBER,
 				     val);