qcacld-3.0: Add flag for ipa pipes_down_in_progress

ipa disable pipes request is honoured based on
ipa_pipes_down flag. However, there is a possible
synchronization issue if disable pipes request is
initiated from different contexts, as there is no
locking to protect this flag.

Add pipes_down_in_progress flag in ipa_ctx and
use this flag to ignore disable pipes requests if
one request is already in progress.

Change-Id: Iabf01249d4b6a551e03cea2ae96a0c6096f43ff8
CRs-Fixed: 2423155
diff --git a/components/ipa/core/src/wlan_ipa_core.c b/components/ipa/core/src/wlan_ipa_core.c
index c0277c8..5667249 100644
--- a/components/ipa/core/src/wlan_ipa_core.c
+++ b/components/ipa/core/src/wlan_ipa_core.c
@@ -1052,6 +1052,15 @@
 		goto end;
 	}
 
+	qdf_spin_lock_bh(&ipa_ctx->pipes_down_lock);
+	if (ipa_ctx->pipes_down_in_progress || ipa_ctx->ipa_pipes_down) {
+		ipa_warn("IPA WDI Pipes down already in progress");
+		qdf_spin_unlock_bh(&ipa_ctx->pipes_down_lock);
+		return QDF_STATUS_E_ALREADY;
+	}
+	ipa_ctx->pipes_down_in_progress = true;
+	qdf_spin_unlock_bh(&ipa_ctx->pipes_down_lock);
+
 	cdp_ipa_disable_autonomy(ipa_ctx->dp_soc,
 				 ipa_ctx->dp_pdev);
 
@@ -1059,10 +1068,12 @@
 				       ipa_ctx->dp_pdev);
 	if (result) {
 		ipa_err("Disable IPA WDI PIPE failed: ret=%d", result);
+		ipa_ctx->pipes_down_in_progress = false;
 		return QDF_STATUS_E_FAILURE;
 	}
 
 	ipa_ctx->ipa_pipes_down = true;
+	ipa_ctx->pipes_down_in_progress = false;
 
 end:
 	ipa_debug("exit: ipa_pipes_down=%d", ipa_ctx->ipa_pipes_down);
@@ -2517,6 +2528,7 @@
 	qdf_create_work(0, &ipa_ctx->pm_work, wlan_ipa_pm_flush, ipa_ctx);
 	qdf_spinlock_create(&ipa_ctx->pm_lock);
 	qdf_spinlock_create(&ipa_ctx->q_lock);
+	qdf_spinlock_create(&ipa_ctx->pipes_down_lock);
 	qdf_nbuf_queue_init(&ipa_ctx->pm_queue_head);
 	qdf_list_create(&ipa_ctx->pending_event, 1000);
 	qdf_mutex_create(&ipa_ctx->event_lock);
@@ -2541,6 +2553,7 @@
 		ipa_ctx->resource_unloading = false;
 		ipa_ctx->sta_connected = 0;
 		ipa_ctx->ipa_pipes_down = true;
+		ipa_ctx->pipes_down_in_progress = false;
 		ipa_ctx->wdi_enabled = false;
 		/* Setup IPA system pipes */
 		if (wlan_ipa_uc_sta_is_enabled(ipa_ctx->config)) {
@@ -2577,6 +2590,7 @@
 fail_setup_rm:
 	qdf_spinlock_destroy(&ipa_ctx->pm_lock);
 	qdf_spinlock_destroy(&ipa_ctx->q_lock);
+	qdf_spinlock_destroy(&ipa_ctx->pipes_down_lock);
 	for (i = 0; i < WLAN_IPA_MAX_IFACE; i++) {
 		iface_context = &ipa_ctx->iface_context[i];
 		qdf_spinlock_destroy(&iface_context->interface_lock);
@@ -2640,6 +2654,7 @@
 
 	qdf_spinlock_destroy(&ipa_ctx->pm_lock);
 	qdf_spinlock_destroy(&ipa_ctx->q_lock);
+	qdf_spinlock_destroy(&ipa_ctx->pipes_down_lock);
 
 	/* destroy the interface lock */
 	for (i = 0; i < WLAN_IPA_MAX_IFACE; i++) {