Bläddra i källkod

qcacld-3.0: Fix race condition between CND and UI

Currently when Zeta feature is enabled, there is a
race condition between WiFi DISABLE from TZ/CND, and
WiFi ON from UI.

Whenever TZ/CND sends WiFi DISABLE, driver will initiate
idle_psoc_shutdown, and sets is_wlan_disabled flag in the
hdd context, which will block WiFi from turning on.
But if the driver receives WiFi ON from UI before setting
the flag, it leads to a race condition.

To avoid this issue, set the is_wlan_disabled flag before
initiating idle_psoc_shutdown, and reset it if idle shutdown
isn't successful.

Change-Id: Ie643b02ebd492f637cc910be00d8226a843c2884
CRs-Fixed: 3282845
Aditya Kodukula 2 år sedan
förälder
incheckning
8bc148d726
1 ändrade filer med 29 tillägg och 11 borttagningar
  1. 29 11
      core/hdd/src/wlan_hdd_main.c

+ 29 - 11
core/hdd/src/wlan_hdd_main.c

@@ -16695,21 +16695,15 @@ static void hdd_wlan_soft_driver_unload(void)
 	hdd_driver_unload();
 }
 
-static int hdd_disable_wifi(struct hdd_context *hdd_ctx)
+static int hdd_wlan_idle_shutdown(struct hdd_context *hdd_ctx)
 {
 	int ret;
 	int retries = 0;
 	void *hif_ctx;
 
-	if (hdd_ctx->is_wlan_disabled) {
-		hdd_err_rl("Wifi is already disabled");
-		return 0;
-	}
-
-	hdd_debug("Initiating WLAN idle shutdown");
-	if (hdd_is_any_interface_open(hdd_ctx)) {
-		hdd_err("Interfaces still open, cannot process wifi disable");
-		return -EAGAIN;
+	if (!hdd_ctx) {
+		hdd_err_rl("hdd_ctx is Null");
+		return -EINVAL;
 	}
 
 	hif_ctx = cds_get_context(QDF_MODULE_ID_HIF);
@@ -16732,6 +16726,7 @@ static int hdd_disable_wifi(struct hdd_context *hdd_ctx)
 				  retries);
 			msleep(WIFI_DISABLE_SLEEP);
 			retries++;
+			continue;
 		}
 		break;
 	}
@@ -16741,11 +16736,34 @@ static int hdd_disable_wifi(struct hdd_context *hdd_ctx)
 		hdd_debug("Max retries reached");
 		return -EINVAL;
 	}
-	hdd_ctx->is_wlan_disabled = true;
 	hdd_debug_rl("WiFi is disabled");
 
 	return 0;
 }
+
+static int hdd_disable_wifi(struct hdd_context *hdd_ctx)
+{
+	int ret;
+
+	if (hdd_ctx->is_wlan_disabled) {
+		hdd_err_rl("Wifi is already disabled");
+		return 0;
+	}
+
+	hdd_debug("Initiating WLAN idle shutdown");
+	if (hdd_is_any_interface_open(hdd_ctx)) {
+		hdd_err("Interfaces still open, cannot process wifi disable");
+		return -EAGAIN;
+	}
+
+	hdd_ctx->is_wlan_disabled = true;
+
+	ret = hdd_wlan_idle_shutdown(hdd_ctx);
+	if (ret)
+		hdd_ctx->is_wlan_disabled = false;
+
+	return ret;
+}
 #else
 static int hdd_wlan_soft_driver_load(void)
 {