qcacld-3.0: Cleanup interface when loading/unloading timeout
When AP_DISCONNECT event occurs during IPA resource unloading in
progress, timeout could happen since suspending FW IPA Rx pipe took much
time. This could cause a subsequent AP_CONNECT event failed since no
interface is available.
Fix this by
- Adapter struct sanity check using hdd_validate_adapter()
- Call hdd_ipa_cleanup_iface() for AP_DISCONNECT/STA_DISCONNECT event
in loading/unloading timeout case
- Assert when no interface is available in hdd_ipa_setup_iface()
Change-Id: Ie96e4f0e96ccffacf4ce5fcc976636c440214873
CRs-Fixed: 2208347
diff --git a/components/ipa/core/src/wlan_ipa_core.c b/components/ipa/core/src/wlan_ipa_core.c
index 06ea4dc..2d47ea9 100644
--- a/components/ipa/core/src/wlan_ipa_core.c
+++ b/components/ipa/core/src/wlan_ipa_core.c
@@ -1070,6 +1070,13 @@
}
}
+ if (WLAN_IPA_MAX_IFACE == ipa_ctx->num_iface) {
+ ipa_err("Max interface reached %d", WLAN_IPA_MAX_IFACE);
+ status = QDF_STATUS_E_NOMEM;
+ QDF_ASSERT(0);
+ goto end;
+ }
+
for (i = 0; i < WLAN_IPA_MAX_IFACE; i++) {
if (ipa_ctx->iface_context[i].tl_context == NULL) {
iface_context = &(ipa_ctx->iface_context[i]);
@@ -1080,6 +1087,7 @@
if (iface_context == NULL) {
ipa_err("All the IPA interfaces are in use");
status = QDF_STATUS_E_NOMEM;
+ QDF_ASSERT(0);
goto end;
}
@@ -1338,6 +1346,19 @@
qdf_mutex_release(&ipa_ctx->ipa_lock);
+ /* Cleanup interface */
+ if (type == QDF_IPA_STA_DISCONNECT ||
+ type == QDF_IPA_AP_DISCONNECT) {
+ for (i = 0; i < WLAN_IPA_MAX_IFACE; i++) {
+ iface_ctx = &ipa_ctx->iface_context[i];
+
+ if (iface_ctx->dev == net_dev)
+ break;
+ }
+ if (iface_ctx)
+ wlan_ipa_cleanup_iface(iface_ctx);
+ }
+
return QDF_STATUS_SUCCESS;
}
ipa_info("IPA resource %s completed",