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
This commit is contained in:
Aditya Kodukula
2022-09-12 14:41:08 -07:00
committed by Madan Koyyalamudi
parent 749291ea8c
commit 8bc148d726

View File

@@ -16695,21 +16695,15 @@ static void hdd_wlan_soft_driver_unload(void)
hdd_driver_unload(); 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 ret;
int retries = 0; int retries = 0;
void *hif_ctx; void *hif_ctx;
if (hdd_ctx->is_wlan_disabled) { if (!hdd_ctx) {
hdd_err_rl("Wifi is already disabled"); hdd_err_rl("hdd_ctx is Null");
return 0; return -EINVAL;
}
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;
} }
hif_ctx = cds_get_context(QDF_MODULE_ID_HIF); hif_ctx = cds_get_context(QDF_MODULE_ID_HIF);
@@ -16732,6 +16726,7 @@ static int hdd_disable_wifi(struct hdd_context *hdd_ctx)
retries); retries);
msleep(WIFI_DISABLE_SLEEP); msleep(WIFI_DISABLE_SLEEP);
retries++; retries++;
continue;
} }
break; break;
} }
@@ -16741,11 +16736,34 @@ static int hdd_disable_wifi(struct hdd_context *hdd_ctx)
hdd_debug("Max retries reached"); hdd_debug("Max retries reached");
return -EINVAL; return -EINVAL;
} }
hdd_ctx->is_wlan_disabled = true;
hdd_debug_rl("WiFi is disabled"); hdd_debug_rl("WiFi is disabled");
return 0; 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 #else
static int hdd_wlan_soft_driver_load(void) static int hdd_wlan_soft_driver_load(void)
{ {