diff --git a/core/hdd/inc/wlan_hdd_main.h b/core/hdd/inc/wlan_hdd_main.h index 28bbc266be80..b621e6971212 100644 --- a/core/hdd/inc/wlan_hdd_main.h +++ b/core/hdd/inc/wlan_hdd_main.h @@ -197,6 +197,8 @@ static inline bool in_compat_syscall(void) { return is_compat_task(); } #define NUM_CPUS 1 #endif +#define ACS_COMPLETE_TIMEOUT 3000 + #define HDD_PSOC_IDLE_SHUTDOWN_SUSPEND_DELAY (1000) /** * enum hdd_adapter_flags - event bitmap flags registered net device @@ -1043,7 +1045,7 @@ struct hdd_context; * @mic_work: mic work information * @gpio_tsf_sync_work: work to sync send TSF CAP WMI command * @cache_sta_count: number of currently cached stations - * + * @acs_complete_event: acs complete event */ struct hdd_adapter { /* Magic cookie for adapter sanity verification. Note that this @@ -1168,6 +1170,7 @@ struct hdd_adapter { } session; qdf_atomic_t ch_switch_in_progress; + qdf_event_t acs_complete_event; #ifdef WLAN_FEATURE_TSF /* tsf value received from firmware */ diff --git a/core/hdd/src/wlan_hdd_cfg80211.c b/core/hdd/src/wlan_hdd_cfg80211.c index a4f225078887..65bce41f270e 100644 --- a/core/hdd/src/wlan_hdd_cfg80211.c +++ b/core/hdd/src/wlan_hdd_cfg80211.c @@ -2760,6 +2760,7 @@ static int __wlan_hdd_cfg80211_do_acs(struct wiphy *wiphy, return -EINVAL; } else { qdf_atomic_set(&adapter->session.ap.acs_in_progress, 1); + qdf_event_reset(&adapter->acs_complete_event); } ret = wlan_cfg80211_nla_parse(tb, QCA_WLAN_VENDOR_ATTR_ACS_MAX, data, @@ -15561,11 +15562,6 @@ static int hdd_change_adapter_mode(struct hdd_adapter *adapter, hdd_enter(); - if (test_bit(ACS_IN_PROGRESS, &hdd_ctx->g_event_flags)) { - hdd_warn("Can't change interface: ACS in progress"); - return -EBUSY; - } - hdd_stop_adapter(hdd_ctx, adapter); hdd_deinit_adapter(hdd_ctx, adapter, true); adapter->device_mode = new_mode; diff --git a/core/hdd/src/wlan_hdd_hostapd.c b/core/hdd/src/wlan_hdd_hostapd.c index 274ceff38123..5a8352d9cc60 100644 --- a/core/hdd/src/wlan_hdd_hostapd.c +++ b/core/hdd/src/wlan_hdd_hostapd.c @@ -2600,6 +2600,8 @@ QDF_STATUS hdd_hostapd_sap_event_cb(struct sap_event *sap_event, sap_event->sapevt.sap_ch_selected.ch_width; wlan_hdd_cfg80211_acs_ch_select_evt(adapter); qdf_atomic_set(&adapter->session.ap.acs_in_progress, 0); + qdf_event_set(&adapter->acs_complete_event); + return QDF_STATUS_SUCCESS; case eSAP_ECSA_CHANGE_CHAN_IND: hdd_debug("Channel change indication from peer for channel %d", @@ -3459,6 +3461,7 @@ void hdd_deinit_ap_mode(struct hdd_context *hdd_ctx, clear_bit(WMM_INIT_DONE, &adapter->event_flags); } qdf_atomic_set(&adapter->session.ap.acs_in_progress, 0); + hdd_softap_deinit_tx_rx(adapter); /* * if we are being called during driver unload, diff --git a/core/hdd/src/wlan_hdd_main.c b/core/hdd/src/wlan_hdd_main.c index 5a766ed47169..460c48599578 100644 --- a/core/hdd/src/wlan_hdd_main.c +++ b/core/hdd/src/wlan_hdd_main.c @@ -5622,6 +5622,7 @@ struct hdd_adapter *hdd_open_adapter(struct hdd_context *hdd_ctx, uint8_t sessio INIT_WORK(&adapter->scan_block_work, wlan_hdd_cfg80211_scan_block_cb); qdf_list_create(&adapter->blocked_scan_request_q, WLAN_MAX_SCAN_COUNT); qdf_mutex_create(&adapter->blocked_scan_request_q_lock); + qdf_event_create(&adapter->acs_complete_event); if (QDF_STATUS_SUCCESS == status) { /* Add it to the hdd's session list. */ @@ -5679,7 +5680,7 @@ static void __hdd_close_adapter(struct hdd_context *hdd_ctx, qdf_list_destroy(&adapter->blocked_scan_request_q); qdf_mutex_destroy(&adapter->blocked_scan_request_q_lock); policy_mgr_clear_concurrency_mode(hdd_ctx->psoc, adapter->device_mode); - + qdf_event_destroy(&adapter->acs_complete_event); hdd_cleanup_adapter(hdd_ctx, adapter, rtnl_held); if (hdd_ctx->current_intf_count != 0) @@ -5970,7 +5971,12 @@ QDF_STATUS hdd_stop_adapter(struct hdd_context *hdd_ctx, case QDF_P2P_GO_MODE: cds_flush_work(&adapter->sap_stop_bss_work); - qdf_atomic_set(&adapter->session.ap.acs_in_progress, 0); + if (qdf_atomic_read(&adapter->session.ap.acs_in_progress)) { + hdd_info("ACS in progress, wait for complete"); + qdf_wait_for_event_completion( + &adapter->acs_complete_event, + ACS_COMPLETE_TIMEOUT); + } wlan_hdd_undo_acs(adapter); if (adapter->device_mode == QDF_P2P_GO_MODE)