diff --git a/components/cmn_services/policy_mgr/inc/wlan_policy_mgr_api.h b/components/cmn_services/policy_mgr/inc/wlan_policy_mgr_api.h index b713c6c91265..2a9ec491dd27 100644 --- a/components/cmn_services/policy_mgr/inc/wlan_policy_mgr_api.h +++ b/components/cmn_services/policy_mgr/inc/wlan_policy_mgr_api.h @@ -3020,6 +3020,7 @@ void policy_mgr_nan_sap_post_disable_conc_check(struct wlan_objmgr_psoc *psoc); * required * after sta disconnection * @psoc: psoc object data + * @sap_vdev_id: sap vdev id * @intf_ch: sap channel * * Check if SAP should be moved to a non dfs channel after STA disconnection. @@ -3029,7 +3030,8 @@ void policy_mgr_nan_sap_post_disable_conc_check(struct wlan_objmgr_psoc *psoc); * Return: true if sap restart is required, otherwise false */ bool policy_mgr_is_sap_restart_required_after_sta_disconnect( - struct wlan_objmgr_psoc *psoc, uint8_t *intf_ch); + struct wlan_objmgr_psoc *psoc, + uint32_t sap_vdev_id, uint8_t *intf_ch); /** * policy_mgr_is_sta_sap_scc() - check whether SAP is doing SCC with 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 8974d557332c..f4516b97b3ac 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 @@ -1320,37 +1320,121 @@ bool policy_mgr_is_safe_channel(struct wlan_objmgr_psoc *psoc, } bool policy_mgr_is_sap_restart_required_after_sta_disconnect( - struct wlan_objmgr_psoc *psoc, uint8_t *intf_ch) + struct wlan_objmgr_psoc *psoc, + uint32_t sap_vdev_id, uint8_t *intf_ch) { struct policy_mgr_psoc_priv_obj *pm_ctx; - uint8_t sap_chan = policy_mgr_mode_specific_get_channel(psoc, - PM_SAP_MODE); + uint8_t curr_sap_chan = 0, new_sap_ch = 0; bool sta_sap_scc_on_dfs_chan = policy_mgr_is_sta_sap_scc_allowed_on_dfs_chan(psoc); - - *intf_ch = 0; + bool sta_sap_scc_on_lte_coex_chan = + policy_mgr_sta_sap_scc_on_lte_coex_chan(psoc); + uint32_t cc_count, i, go_index_start, pcl_len = 0; + uint8_t op_ch[MAX_NUMBER_OF_CONC_CONNECTIONS]; + uint8_t vdev_id[MAX_NUMBER_OF_CONC_CONNECTIONS]; + enum policy_mgr_con_mode mode; + uint8_t pcl_channels[QDF_MAX_NUM_CHAN + 1]; + uint8_t pcl_weight[QDF_MAX_NUM_CHAN + 1]; + struct policy_mgr_conc_connection_info info = {0}; + uint8_t num_cxn_del = 0; + QDF_STATUS status; pm_ctx = policy_mgr_get_context(psoc); if (!pm_ctx) { policy_mgr_err("Invalid pm context"); return false; } - - policy_mgr_debug("sta_sap_scc_on_dfs_chan %u, sap_chan %u", - sta_sap_scc_on_dfs_chan, sap_chan); - - if ((!sta_sap_scc_on_dfs_chan || - !(sap_chan && WLAN_REG_IS_5GHZ_CH(sap_chan) && - (wlan_reg_get_channel_state(pm_ctx->pdev, sap_chan) == - CHANNEL_STATE_DFS))) && - (!policy_mgr_sta_sap_scc_on_lte_coex_chan(psoc) || - policy_mgr_is_safe_channel(psoc, sap_chan))) { + if (!pm_ctx->do_sap_unsafe_ch_check) return false; + if (!sta_sap_scc_on_dfs_chan && !sta_sap_scc_on_lte_coex_chan) + return false; + + if (!policy_mgr_is_hw_dbs_capable(psoc)) + if (policy_mgr_get_connection_count(psoc) > 1) + return false; + + cc_count = policy_mgr_get_mode_specific_conn_info( + psoc, + &op_ch[0], + &vdev_id[0], + PM_SAP_MODE); + go_index_start = cc_count; + if (cc_count < MAX_NUMBER_OF_CONC_CONNECTIONS) + cc_count += policy_mgr_get_mode_specific_conn_info(psoc, + &op_ch[cc_count], + &vdev_id[cc_count], + PM_P2P_GO_MODE); + + for (i = 0 ; i < cc_count; i++) { + if (sap_vdev_id != INVALID_VDEV_ID && + sap_vdev_id != vdev_id[i]) + continue; + if (policy_mgr_is_any_mode_active_on_band_along_with_session( + psoc, vdev_id[i], + WLAN_REG_IS_24GHZ_CH(op_ch[i]) ? + POLICY_MGR_BAND_24 : POLICY_MGR_BAND_5)) + continue; + if (sta_sap_scc_on_dfs_chan && + wlan_reg_is_dfs_ch(pm_ctx->pdev, op_ch[i])) { + sap_vdev_id = vdev_id[i]; + curr_sap_chan = op_ch[i]; + policy_mgr_debug("sta_sap_scc_on_dfs_chan %u, dfs sap_chan %u", + sta_sap_scc_on_dfs_chan, + curr_sap_chan); + break; + } + if (sta_sap_scc_on_lte_coex_chan && + !policy_mgr_is_safe_channel(psoc, op_ch[i])) { + sap_vdev_id = vdev_id[i]; + curr_sap_chan = op_ch[i]; + policy_mgr_debug("sta_sap_scc_on_lte_coex_chan %u unsafe sap_chan %u", + sta_sap_scc_on_lte_coex_chan, + curr_sap_chan); + break; + } } - *intf_ch = pm_ctx->user_config_sap_channel; - policy_mgr_debug("Standalone SAP is not allowed on DFS channel, Move it to channel %u", - *intf_ch); + if (!curr_sap_chan) + return false; + mode = i >= go_index_start ? PM_P2P_GO_MODE : PM_SAP_MODE; + qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); + policy_mgr_store_and_del_conn_info_by_vdev_id(psoc, sap_vdev_id, + &info, &num_cxn_del); + /* Add the user config ch as first condidate */ + pcl_channels[0] = pm_ctx->user_config_sap_channel; + pcl_weight[0] = 0; + status = policy_mgr_get_pcl(psoc, mode, &pcl_channels[1], &pcl_len, + &pcl_weight[1], + QDF_ARRAY_SIZE(pcl_weight) - 1); + if (status == QDF_STATUS_SUCCESS) + pcl_len++; + else + pcl_len = 1; + for (i = 0; i < pcl_len; i++) { + if (pcl_channels[i] == curr_sap_chan) + continue; + if (!wlan_reg_is_same_band_channels( + curr_sap_chan, pcl_channels[i])) + continue; + if (!policy_mgr_is_safe_channel(psoc, pcl_channels[i]) || + wlan_reg_is_dfs_ch(pm_ctx->pdev, pcl_channels[i])) + continue; + new_sap_ch = pcl_channels[i]; + break; + } + /* Restore the connection entry */ + if (num_cxn_del > 0) + policy_mgr_restore_deleted_conn_info(psoc, &info, num_cxn_del); + qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); + + if (new_sap_ch == 0 || curr_sap_chan == new_sap_ch) + return false; + if (!intf_ch) + return true; + + *intf_ch = new_sap_ch; + policy_mgr_debug("Standalone SAP(vdev_id %d) is not allowed on DFS/Unsafe channel, Move it to channel %u", + sap_vdev_id, *intf_ch); return true; } @@ -1717,6 +1801,7 @@ static void __policy_mgr_check_sta_ap_concurrent_ch_intf(void *data) } end: + pm_ctx->do_sap_unsafe_ch_check = false; if (work_info) { qdf_mem_free(work_info); if (pm_ctx) @@ -1886,22 +1971,20 @@ void policy_mgr_check_concurrent_intf_and_restart_sap( policy_mgr_err("Invalid context"); return; } - if (policy_mgr_get_connection_count(psoc) == 1) { - /* - * If STA+SAP sessions are on DFS channel and STA+SAP SCC is - * enabled on DFS channel then move the SAP out of DFS channel - * as soon as STA gets disconnect. - * If STA+SAP sessions are on unsafe channel and STA+SAP SCC is - * enabled on unsafe channel then move the SAP to safe channel - * as soon as STA disconnected. - */ - if (policy_mgr_is_sap_restart_required_after_sta_disconnect( - psoc, &sap_ch)) { - policy_mgr_debug("move the SAP to configured channel %u", - sap_ch); - restart_sap = true; - goto sap_restart; - } + /* + * If STA+SAP sessions are on DFS channel and STA+SAP SCC is + * enabled on DFS channel then move the SAP out of DFS channel + * as soon as STA gets disconnect. + * If STA+SAP sessions are on unsafe channel and STA+SAP SCC is + * enabled on unsafe channel then move the SAP to safe channel + * as soon as STA disconnected. + */ + if (policy_mgr_is_sap_restart_required_after_sta_disconnect( + psoc, INVALID_VDEV_ID, &sap_ch)) { + policy_mgr_debug("move the SAP to configured channel %u", + sap_ch); + restart_sap = true; + goto sap_restart; } /* diff --git a/components/cmn_services/policy_mgr/src/wlan_policy_mgr_get_set_utils.c b/components/cmn_services/policy_mgr/src/wlan_policy_mgr_get_set_utils.c index c2a5635a0a51..7947e9b57b8e 100644 --- a/components/cmn_services/policy_mgr/src/wlan_policy_mgr_get_set_utils.c +++ b/components/cmn_services/policy_mgr/src/wlan_policy_mgr_get_set_utils.c @@ -1733,6 +1733,16 @@ QDF_STATUS policy_mgr_decr_active_session(struct wlan_objmgr_psoc *psoc, if (pm_ctx->dp_cbacks.hdd_ipa_set_mcc_mode_cb) pm_ctx->dp_cbacks.hdd_ipa_set_mcc_mode_cb(mcc_mode); } + /* + * When STA disconnected, we need to move DFS SAP + * to Non-DFS if g_sta_sap_scc_on_dfs_chan enabled. + * The same if g_sta_sap_scc_on_lte_coex_chan enabled, + * need to move SAP on unsafe channel to safe channel. + * The flag will be checked by + * policy_mgr_is_sap_restart_required_after_sta_disconnect. + */ + if (mode == QDF_STA_MODE || mode == QDF_P2P_CLIENT_MODE) + pm_ctx->do_sap_unsafe_ch_check = true; return qdf_status; } diff --git a/components/cmn_services/policy_mgr/src/wlan_policy_mgr_i.h b/components/cmn_services/policy_mgr/src/wlan_policy_mgr_i.h index 6e977fe47ad7..de3237aa7e3b 100644 --- a/components/cmn_services/policy_mgr/src/wlan_policy_mgr_i.h +++ b/components/cmn_services/policy_mgr/src/wlan_policy_mgr_i.h @@ -333,6 +333,7 @@ struct policy_mgr_psoc_priv_obj { uint8_t sap_mandatory_channels[QDF_MAX_NUM_CHAN]; uint32_t sap_mandatory_channels_len; bool do_hw_mode_change; + bool do_sap_unsafe_ch_check; uint32_t concurrency_mode; uint8_t no_of_open_sessions[QDF_MAX_NO_OF_MODE]; uint8_t no_of_active_sessions[QDF_MAX_NO_OF_MODE]; diff --git a/core/hdd/src/wlan_hdd_hostapd.c b/core/hdd/src/wlan_hdd_hostapd.c index 4a3a164370ba..8fc284d4349c 100644 --- a/core/hdd/src/wlan_hdd_hostapd.c +++ b/core/hdd/src/wlan_hdd_hostapd.c @@ -3136,19 +3136,18 @@ QDF_STATUS wlan_hdd_get_channel_for_sap_restart( return QDF_STATUS_E_FAILURE; } - if (policy_mgr_get_connection_count(psoc) == 1) { - /* - * If STA+SAP sessions are on DFS channel and STA+SAP SCC is - * enabled on DFS channel then move the SAP out of DFS channel - * as soon as STA gets disconnect. - */ - if (policy_mgr_is_sap_restart_required_after_sta_disconnect( - psoc, &intf_ch)) { - hdd_debug("Move the sap to user configured channel %u", - intf_ch); - goto sap_restart; - } + /* + * If STA+SAP sessions are on DFS channel and STA+SAP SCC is + * enabled on DFS channel then move the SAP out of DFS channel + * as soon as STA gets disconnect. + */ + if (policy_mgr_is_sap_restart_required_after_sta_disconnect( + psoc, vdev_id, &intf_ch)) { + hdd_debug("Move the sap (vdev %d) to user configured channel %u", + vdev_id, intf_ch); + goto sap_restart; } + ucfg_policy_mgr_get_mcc_scc_switch(hdd_ctx->psoc, &mcc_to_scc_switch); /*