qcacmn: Prevent runtime PM suspend for MGMT TX frames

Add a runtime PM wake lock for MGMT TX frames and prevent
runtime PM suspend if there are outstanding MGMT TX descriptors
in fw because fw may try to access host ddr when PCIe link is down
which can lead to system NOC errors.

Change-Id: I46b851b7babc8f0fe2c31f27892b0c7a3f255a17
CRs-Fixed: 2495612
diff --git a/umac/cmn_services/mgmt_txrx/core/src/wlan_mgmt_txrx_main.c b/umac/cmn_services/mgmt_txrx/core/src/wlan_mgmt_txrx_main.c
index 68b82de..54a4ef4 100644
--- a/umac/cmn_services/mgmt_txrx/core/src/wlan_mgmt_txrx_main.c
+++ b/umac/cmn_services/mgmt_txrx/core/src/wlan_mgmt_txrx_main.c
@@ -127,6 +127,8 @@
 	/* acquire the wakelock when there are pending mgmt tx frames */
 	qdf_wake_lock_timeout_acquire(&mgmt_txrx_pdev_ctx->wakelock_tx_cmp,
 				      MGMT_TXRX_WAKELOCK_TIMEOUT_TX_CMP);
+	qdf_runtime_pm_prevent_suspend(
+		&mgmt_txrx_pdev_ctx->wakelock_tx_runtime_cmp);
 
 	qdf_spin_unlock_bh(&mgmt_txrx_pdev_ctx->mgmt_desc_pool.desc_pool_lock);
 
@@ -160,9 +162,12 @@
 
 	/* release the wakelock if there are no pending mgmt tx frames */
 	if (mgmt_txrx_pdev_ctx->mgmt_desc_pool.free_list.count ==
-	    mgmt_txrx_pdev_ctx->mgmt_desc_pool.free_list.max_size)
+	    mgmt_txrx_pdev_ctx->mgmt_desc_pool.free_list.max_size) {
+		qdf_runtime_pm_allow_suspend(
+			&mgmt_txrx_pdev_ctx->wakelock_tx_runtime_cmp);
 		qdf_wake_lock_release(&mgmt_txrx_pdev_ctx->wakelock_tx_cmp,
 				      MGMT_TXRX_WAKELOCK_REASON_TX_CMP);
+	}
 
 	qdf_spin_unlock_bh(&mgmt_txrx_pdev_ctx->mgmt_desc_pool.desc_pool_lock);
 
diff --git a/umac/cmn_services/mgmt_txrx/core/src/wlan_mgmt_txrx_main_i.h b/umac/cmn_services/mgmt_txrx/core/src/wlan_mgmt_txrx_main_i.h
index cdaa897..8aea6af 100644
--- a/umac/cmn_services/mgmt_txrx/core/src/wlan_mgmt_txrx_main_i.h
+++ b/umac/cmn_services/mgmt_txrx/core/src/wlan_mgmt_txrx_main_i.h
@@ -186,12 +186,14 @@
  * @mgmt_desc_pool:   pointer to mgmt desc. pool
  * @mgmt_txrx_stats:  pointer to mgmt txrx stats
  * @wakelock_tx_cmp:  mgmt tx complete wake lock
+ * @wakelock_tx_runtime_cmp: mgmt tx runtime complete wake lock
  */
 struct mgmt_txrx_priv_pdev_context {
 	struct wlan_objmgr_pdev *pdev;
 	struct mgmt_desc_pool_t mgmt_desc_pool;
 	struct mgmt_txrx_stats_t *mgmt_txrx_stats;
 	qdf_wake_lock_t wakelock_tx_cmp;
+	qdf_runtime_lock_t wakelock_tx_runtime_cmp;
 };
 
 
diff --git a/umac/cmn_services/mgmt_txrx/dispatcher/src/wlan_mgmt_txrx_utils_api.c b/umac/cmn_services/mgmt_txrx/dispatcher/src/wlan_mgmt_txrx_utils_api.c
index e3e2edf..4e5b493 100644
--- a/umac/cmn_services/mgmt_txrx/dispatcher/src/wlan_mgmt_txrx_utils_api.c
+++ b/umac/cmn_services/mgmt_txrx/dispatcher/src/wlan_mgmt_txrx_utils_api.c
@@ -184,6 +184,7 @@
 
 	qdf_wake_lock_create(&mgmt_txrx_pdev_ctx->wakelock_tx_cmp,
 			     "mgmt_txrx tx_cmp");
+	qdf_runtime_lock_init(&mgmt_txrx_pdev_ctx->wakelock_tx_runtime_cmp);
 
 	if (wlan_objmgr_pdev_component_obj_attach(pdev,
 			WLAN_UMAC_COMP_MGMT_TXRX,
@@ -201,6 +202,7 @@
 	return QDF_STATUS_SUCCESS;
 
 err_pdev_attach:
+	qdf_runtime_lock_deinit(&mgmt_txrx_pdev_ctx->wakelock_tx_runtime_cmp);
 	qdf_wake_lock_destroy(&mgmt_txrx_pdev_ctx->wakelock_tx_cmp);
 	qdf_mem_free(mgmt_txrx_stats);
 err_mgmt_txrx_stats:
@@ -251,6 +253,7 @@
 
 	wlan_mgmt_txrx_desc_pool_deinit(mgmt_txrx_pdev_ctx);
 	qdf_mem_free(mgmt_txrx_pdev_ctx->mgmt_txrx_stats);
+	qdf_runtime_lock_deinit(&mgmt_txrx_pdev_ctx->wakelock_tx_runtime_cmp);
 	qdf_wake_lock_destroy(&mgmt_txrx_pdev_ctx->wakelock_tx_cmp);
 	qdf_mem_free(mgmt_txrx_pdev_ctx);