diff --git a/components/cmn_services/policy_mgr/src/wlan_policy_mgr_action.c b/components/cmn_services/policy_mgr/src/wlan_policy_mgr_action.c index 605cb7c5b214..74e22a846dba 100644 --- a/components/cmn_services/policy_mgr/src/wlan_policy_mgr_action.c +++ b/components/cmn_services/policy_mgr/src/wlan_policy_mgr_action.c @@ -363,6 +363,9 @@ QDF_STATUS policy_mgr_update_connection_info(struct wlan_objmgr_psoc *psoc, chain_mask, nss, vdev_id, true, true); + /* do we need to change the HW mode */ + policy_mgr_check_n_start_opportunistic_timer(psoc); + return QDF_STATUS_SUCCESS; } @@ -1922,6 +1925,25 @@ QDF_STATUS policy_mgr_set_hw_mode_before_channel_switch( return QDF_STATUS_E_NOSUPPORT; } + /* + * Stop opportunistic timer as current connection info will change once + * channel is switched and thus if required it will be started once + * channel switch is completed. With new connection info. + */ + policy_mgr_stop_opportunistic_timer(psoc); + + /* + * Return if driver is already in the dbs mode, movement to + * Single mac/SBS mode will be decided and changed once channel + * switch is completed. This will avoid changing to SBS/Single mac + * till new channel is configured, while the old channel still + * requires DBS. + */ + if (policy_mgr_is_current_hwmode_dbs(psoc)) { + policy_mgr_err("Already in DBS mode"); + return QDF_STATUS_E_ALREADY; + } + /* * Store the connection's parameter and temporarily delete it * from the concurrency table. This way the allow concurrency @@ -1934,13 +1956,19 @@ QDF_STATUS policy_mgr_set_hw_mode_before_channel_switch( status = policy_mgr_update_and_wait_for_connection_update(psoc, vdev_id, chan, POLICY_MGR_UPDATE_REASON_CHANNEL_SWITCH); - if (QDF_IS_STATUS_ERROR(status)) - policy_mgr_err("Failed to update HW modeStatus %d", status); - /* Restore the connection entry */ if (num_cxn_del) policy_mgr_restore_deleted_conn_info(psoc, &info, num_cxn_del); + /* + * If hw mode change failed restart the opportunistic timer to + * Switch to single mac if required. + */ + if (QDF_IS_STATUS_ERROR(status)) { + policy_mgr_err("Failed to update HW modeStatus %d", status); + policy_mgr_check_n_start_opportunistic_timer(psoc); + } + return status; } @@ -1957,6 +1985,13 @@ QDF_STATUS policy_mgr_check_and_set_hw_mode_sta_channel_switch( return QDF_STATUS_E_NOSUPPORT; } + /* + * Stop opportunistic timer as current connection info will change once + * channel is switched and thus if required it will be started once + * channel switch is completed. With new connection info. + */ + policy_mgr_stop_opportunistic_timer(psoc); + if (policy_mgr_is_current_hwmode_dbs(psoc)) { policy_mgr_err("Already in DBS mode"); return QDF_STATUS_E_ALREADY; @@ -1982,6 +2017,15 @@ QDF_STATUS policy_mgr_check_and_set_hw_mode_sta_channel_switch( if (num_cxn_del) policy_mgr_restore_deleted_conn_info(psoc, &info, num_cxn_del); + /* + * If hw mode change failed restart the opportunistic timer to + * Switch to single mac if required. + */ + if (status == QDF_STATUS_E_FAILURE) { + policy_mgr_err("Failed to update HW modeStatus %d", status); + policy_mgr_check_n_start_opportunistic_timer(psoc); + } + return status; } diff --git a/core/hdd/src/wlan_hdd_assoc.c b/core/hdd/src/wlan_hdd_assoc.c index 0dc694c147eb..93bcdadd8d67 100644 --- a/core/hdd/src/wlan_hdd_assoc.c +++ b/core/hdd/src/wlan_hdd_assoc.c @@ -3323,13 +3323,10 @@ hdd_association_completion_handler(struct hdd_adapter *adapter, qdf_mem_zero(&adapter->hdd_stats.hdd_pmf_stats, sizeof(adapter->hdd_stats.hdd_pmf_stats)); #endif + policy_mgr_check_n_start_opportunistic_timer(hdd_ctx->psoc); hdd_debug("check for SAP restart"); policy_mgr_check_concurrent_intf_and_restart_sap( hdd_ctx->psoc); - if (roam_info->pBssDesc) - policy_mgr_checkn_update_hw_mode_single_mac_mode - (hdd_ctx->psoc, - roam_info->pBssDesc->channelId); } else { bool connect_timeout = false; /* do we need to change the HW mode */ @@ -4626,13 +4623,13 @@ static void hdd_roam_channel_switch_handler(struct hdd_adapter *adapter, if (QDF_IS_STATUS_ERROR(status)) hdd_err("channel change notification failed"); - hdd_debug("check for SAP restart"); - policy_mgr_check_concurrent_intf_and_restart_sap(hdd_ctx->psoc); - status = policy_mgr_set_hw_mode_on_channel_switch(hdd_ctx->psoc, adapter->vdev_id); if (QDF_IS_STATUS_ERROR(status)) hdd_debug("set hw mode change not done"); + + hdd_debug("check for SAP restart"); + policy_mgr_check_concurrent_intf_and_restart_sap(hdd_ctx->psoc); } /** diff --git a/core/hdd/src/wlan_hdd_hostapd.c b/core/hdd/src/wlan_hdd_hostapd.c index 401a07f428da..9ebb6d442f5e 100644 --- a/core/hdd/src/wlan_hdd_hostapd.c +++ b/core/hdd/src/wlan_hdd_hostapd.c @@ -1923,10 +1923,6 @@ QDF_STATUS hdd_hostapd_sap_event_cb(struct sap_event *sap_event, we_custom_event_generic = we_custom_start_event; hdd_ipa_set_tx_flow_info(); - hdd_debug("check for SAP restart"); - policy_mgr_check_concurrent_intf_and_restart_sap( - hdd_ctx->psoc); - if (policy_mgr_is_hw_mode_change_after_vdev_up( hdd_ctx->psoc)) { hdd_debug("check for possible hw mode change"); @@ -1937,6 +1933,9 @@ QDF_STATUS hdd_hostapd_sap_event_cb(struct sap_event *sap_event, policy_mgr_set_do_hw_mode_change_flag( hdd_ctx->psoc, false); } + hdd_debug("check for SAP restart"); + policy_mgr_check_concurrent_intf_and_restart_sap( + hdd_ctx->psoc); /* * set this event at the very end because once this events * get set, caller thread is waiting to do further processing. diff --git a/core/mac/src/pe/lim/lim_process_action_frame.c b/core/mac/src/pe/lim/lim_process_action_frame.c index 753daa00bf1f..f1ab1f67241a 100644 --- a/core/mac/src/pe/lim/lim_process_action_frame.c +++ b/core/mac/src/pe/lim/lim_process_action_frame.c @@ -93,6 +93,23 @@ void lim_stop_tx_and_switch_channel(struct mac_context *mac, uint8_t sessionId) status = policy_mgr_check_and_set_hw_mode_sta_channel_switch(mac->psoc, pe_session->smeSessionId, pe_session->gLimChannelSwitch.primaryChannel); + + /* + * If status is QDF_STATUS_E_FAILURE, mean HW mode change was required + * but driver failed to set HW mode so ignore CSA for the channel. + * If status is QDF_STATUS_SUCCESS mean HW mode change was required + * and was sucessfully changed so the channel switch will continue after + * HW mode change completion. + * If status is QDF_STATUS_E_NOSUPPORT or QDF_STATUS_E_ALREADY, mean + * DBS is not supported or required HW mode is already set, so + * So contunue with CSA from here. + */ + if (status == QDF_STATUS_E_FAILURE) { + pe_err("Failed to set required HW mode for channel %d, ignore CSA", + pe_session->gLimChannelSwitch.primaryChannel); + return; + } + if (QDF_IS_STATUS_SUCCESS(status)) { pe_info("Channel change will continue after HW mode change"); return; diff --git a/core/sap/src/sap_module.c b/core/sap/src/sap_module.c index c3e8cd53d208..1f9377ba175b 100644 --- a/core/sap/src/sap_module.c +++ b/core/sap/src/sap_module.c @@ -1376,9 +1376,20 @@ QDF_STATUS wlansap_set_channel_change_with_csa(struct sap_context *sapContext, if (status != QDF_STATUS_SUCCESS) return status; - policy_mgr_set_hw_mode_before_channel_switch(mac->psoc, + status = policy_mgr_set_hw_mode_before_channel_switch( + mac->psoc, sapContext->sessionId, targetChannel); + /* + * If status is QDF_STATUS_E_FAILURE that mean HW mode + * change was required but set HW mode change failed. + */ + if (status == QDF_STATUS_E_FAILURE) { + QDF_TRACE(QDF_MODULE_ID_SAP, + QDF_TRACE_LEVEL_ERROR, + FL("HW change required but failed to set hw mode")); + return status; + } /* * Copy the requested target channel diff --git a/core/sme/src/csr/csr_api_roam.c b/core/sme/src/csr/csr_api_roam.c index 8cdb88971ef7..fde31f8ff449 100644 --- a/core/sme/src/csr/csr_api_roam.c +++ b/core/sme/src/csr/csr_api_roam.c @@ -21128,8 +21128,8 @@ static QDF_STATUS csr_process_roam_sync_callback(struct mac_context *mac_ctx, session->disable_hi_rssi = false; } - policy_mgr_check_concurrent_intf_and_restart_sap(mac_ctx->psoc); policy_mgr_check_n_start_opportunistic_timer(mac_ctx->psoc); + policy_mgr_check_concurrent_intf_and_restart_sap(mac_ctx->psoc); csr_roam_offload_scan(mac_ctx, session_id, ROAM_SCAN_OFFLOAD_UPDATE_CFG, REASON_CONNECT);