diff --git a/core/hdd/inc/wlan_hdd_assoc.h b/core/hdd/inc/wlan_hdd_assoc.h index e98a4fd686f2..d17093869a3e 100644 --- a/core/hdd/inc/wlan_hdd_assoc.h +++ b/core/hdd/inc/wlan_hdd_assoc.h @@ -1,5 +1,6 @@ /* * Copyright (c) 2013-2020 The Linux Foundation. All rights reserved. + * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -273,6 +274,17 @@ struct hdd_adapter *hdd_get_sta_connection_in_progress( */ void hdd_abort_ongoing_sta_connection(struct hdd_context *hdd_ctx); +/** + * hdd_abort_ongoing_sta_sae_connection() - Disconnect the sta for which the + * sae connection is in progress. + * @hdd_ctx: hdd context + * @adapter: pointer to the adapter + * + * Return: none + */ +void hdd_abort_ongoing_sta_sae_connection(struct hdd_context *hdd_ctx, + struct hdd_adapter *adapter); + /** * hdd_is_any_sta_connected() - check if any sta in connected state * @hdd_ctx: hdd context diff --git a/core/hdd/src/wlan_hdd_assoc.c b/core/hdd/src/wlan_hdd_assoc.c index 7fd32192150a..e02c72eadb1e 100644 --- a/core/hdd/src/wlan_hdd_assoc.c +++ b/core/hdd/src/wlan_hdd_assoc.c @@ -460,6 +460,47 @@ void hdd_abort_ongoing_sta_connection(struct hdd_context *hdd_ctx) } } +void hdd_abort_ongoing_sta_sae_connection(struct hdd_context *hdd_ctx, + struct hdd_adapter *adapter) +{ + struct hdd_adapter *sta_adapter; + struct wlan_objmgr_vdev *vdev; + int32_t key_mgmt; + QDF_STATUS status; + + sta_adapter = hdd_get_sta_connection_in_progress(hdd_ctx); + if (!sta_adapter) { + hdd_err("sta_adapter is NULL"); + return; + } + + vdev = hdd_objmgr_get_vdev(adapter); + if (!vdev) { + hdd_err("vdev is NULL"); + return; + } + + key_mgmt = wlan_crypto_get_param(vdev, WLAN_CRYPTO_PARAM_KEY_MGMT); + hdd_objmgr_put_vdev(vdev); + + if (key_mgmt < 0) { + hdd_debug_rl("Invalid key_mgmt: %d", key_mgmt); + return; + } + + if (QDF_HAS_PARAM(key_mgmt, WLAN_CRYPTO_KEY_MGMT_SAE) || + QDF_HAS_PARAM(key_mgmt, WLAN_CRYPTO_KEY_MGMT_FT_SAE)) { + hdd_debug("Disconnecting STA on vdev: %d", + sta_adapter->vdev_id); + status = wlan_hdd_disconnect(sta_adapter, + eCSR_DISCONNECT_REASON_DEAUTH, + REASON_DISASSOC_NETWORK_LEAVING); + if (QDF_IS_STATUS_ERROR(status)) + hdd_err("wlan_hdd_disconnect failed, status: %d", + status); + } +} + bool hdd_is_any_sta_connected(struct hdd_context *hdd_ctx) { struct hdd_adapter *adapter = NULL, *next_adapter = NULL; diff --git a/core/hdd/src/wlan_hdd_hostapd.c b/core/hdd/src/wlan_hdd_hostapd.c index d1d8318f2802..075de779d2d5 100644 --- a/core/hdd/src/wlan_hdd_hostapd.c +++ b/core/hdd/src/wlan_hdd_hostapd.c @@ -5274,6 +5274,21 @@ int wlan_hdd_cfg80211_start_bss(struct hdd_adapter *adapter, } } + /* + * For STA+SAP/GO concurrency support from GUI, In case if + * START AP/GO request comes just before the SAE authentication + * completion on STA, SAE AUTH REQ waits for START AP RSP and + * START AP RSP waits to complete SAE AUTH REQ. + * Driver completes START AP RSP only upon SAE AUTH REQ timeout(5 sec) + * as start ap will be in serialization pending queue, and SAE auth + * sequence cannot complete as hostap thread is blocked in start ap + * cfg80211 ops. + * To avoid above deadlock until SAE timeout, abort the SAE connection + * immediately and complete START AP/GO asap so that the upper layer + * can trigger a fresh connection after START AP/GO completion. + */ + hdd_abort_ongoing_sta_sae_connection(hdd_ctx, adapter); + mac_handle = hdd_ctx->mac_handle; sme_config = qdf_mem_malloc(sizeof(*sme_config)); @@ -6043,6 +6058,21 @@ static int __wlan_hdd_cfg80211_stop_ap(struct wiphy *wiphy, goto exit; } + /* + * For STA+SAP/GO concurrency support from GUI, In case if + * STOP AP/GO request comes just before the SAE authentication + * completion on STA, SAE AUTH REQ waits for STOP AP RSP and + * STOP AP RSP waits to complete SAE AUTH REQ. + * Driver completes STOP AP RSP only upon SAE AUTH REQ timeout(5 sec) + * as stop ap will be in serialization pending queue, and SAE auth + * sequence cannot complete as hostap thread is blocked in stop ap + * cfg80211 ops. + * To avoid above deadlock until SAE timeout, abort the SAE connection + * immediately and complete STOP AP/GO asap so that the upper layer + * can trigger a fresh connection after STOP AP/GO completion. + */ + hdd_abort_ongoing_sta_sae_connection(hdd_ctx, adapter); + /* Clear SOFTAP_INIT_DONE flag to mark stop_ap deinit. So that we do * not restart SAP after SSR as SAP is already stopped from user space. * This update is moved to start of this function to resolve stop_ap