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 5ed4a4ee0548..2c0af0e02787 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 @@ -2955,15 +2955,17 @@ bool policy_mgr_allow_sap_go_concurrency(struct wlan_objmgr_psoc *psoc, uint32_t vdev_id); /** - * policy_mgr_allow_multiple_sta_connections() - API to get FW support + * policy_mgr_allow_multiple_sta_connections() - check whether multiple STA + * concurrency is allowed and F/W supported * @psoc: Pointer to soc - * - * This function checks FW support for simultaneous connections on - * concurrent STA interfaces. + * @second_sta_chan: 2nd STA channel + * @first_sta_chan: 2nd STA channel * * Return: true if supports else false. */ -bool policy_mgr_allow_multiple_sta_connections(struct wlan_objmgr_psoc *psoc); +bool policy_mgr_allow_multiple_sta_connections(struct wlan_objmgr_psoc *psoc, + uint8_t second_sta_chan, + uint8_t first_sta_chan); /** * policy_mgr_dual_beacon_on_single_mac_scc_capable() - get capability that 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 ecd6284c3875..5e639f31f91e 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 @@ -34,6 +34,7 @@ #include "wlan_objmgr_vdev_obj.h" #include "wlan_nan_api.h" #include "nan_public_structs.h" +#include "wlan_reg_services_api.h" /* invalid channel id. */ #define INVALID_CHANNEL_ID 0 @@ -2114,6 +2115,7 @@ bool policy_mgr_is_concurrency_allowed(struct wlan_objmgr_psoc *psoc, uint32_t list[MAX_NUMBER_OF_CONC_CONNECTIONS]; struct policy_mgr_psoc_priv_obj *pm_ctx; bool sta_sap_scc_on_dfs_chan; + uint8_t chan; pm_ctx = policy_mgr_get_context(psoc); if (!pm_ctx) { @@ -2186,14 +2188,18 @@ bool policy_mgr_is_concurrency_allowed(struct wlan_objmgr_psoc *psoc, } } + /* Check for STA+STA concurrency */ count = policy_mgr_mode_specific_connection_count(psoc, PM_STA_MODE, list); - - /* Check for STA+STA concurrency */ - if (mode == PM_STA_MODE && count && - !policy_mgr_allow_multiple_sta_connections(psoc)) { - policy_mgr_err("No 2nd STA connection, already one STA is connected"); - goto done; + if (mode == PM_STA_MODE && count) { + if (count >= 2) { + policy_mgr_err("3rd STA isn't permitted"); + goto done; + } + chan = pm_conc_connection_list[list[0]].chan; + if (!policy_mgr_allow_multiple_sta_connections(psoc, channel, + chan)) + goto done; } /* @@ -3753,7 +3759,9 @@ bool policy_mgr_allow_sap_go_concurrency(struct wlan_objmgr_psoc *psoc, return true; } -bool policy_mgr_allow_multiple_sta_connections(struct wlan_objmgr_psoc *psoc) +bool policy_mgr_allow_multiple_sta_connections(struct wlan_objmgr_psoc *psoc, + uint8_t second_sta_chan, + uint8_t first_sta_chan) { struct wmi_unified *wmi_handle; @@ -3762,13 +3770,17 @@ bool policy_mgr_allow_multiple_sta_connections(struct wlan_objmgr_psoc *psoc) policy_mgr_debug("Invalid WMI handle"); return false; } + if (!wmi_service_enabled(wmi_handle, + wmi_service_sta_plus_sta_support)) + return false; - if (wmi_service_enabled(wmi_handle, - wmi_service_sta_plus_sta_support)) - return true; + if (second_sta_chan && second_sta_chan != first_sta_chan && + wlan_reg_is_same_band_channels(second_sta_chan, first_sta_chan)) { + policy_mgr_err("STA+STA MCC isn't permitted"); + return false; + } - policy_mgr_debug("Concurrent STA connections are not supported"); - return false; + return true; } bool policy_mgr_dual_beacon_on_single_mac_scc_capable( diff --git a/core/sme/src/csr/csr_api_roam.c b/core/sme/src/csr/csr_api_roam.c index ba2a71fc4b94..b1dcf293dcbb 100644 --- a/core/sme/src/csr/csr_api_roam.c +++ b/core/sme/src/csr/csr_api_roam.c @@ -63,6 +63,7 @@ #include #include "wlan_qct_sys.h" #include "wlan_blm_api.h" +#include "wlan_policy_mgr_i.h" #define RSN_AUTH_KEY_MGMT_SAE WLAN_RSN_SEL(WLAN_AKM_SAE) #define MAX_PWR_FCC_CHAN_12 8 @@ -5379,6 +5380,20 @@ static bool csr_roam_select_bss(struct mac_context *mac_ctx, bool status = false; struct tag_csrscan_result *scan_result = NULL; tCsrScanResultInfo *result = NULL; + enum QDF_OPMODE op_mode; + struct wlan_objmgr_vdev *vdev; + enum policy_mgr_con_mode mode; + + vdev = wlan_objmgr_get_vdev_by_id_from_pdev(mac_ctx->pdev, + session_id, + WLAN_LEGACY_SME_ID); + if (!vdev) { + sme_err("Vdev ref error"); + return true; + } + op_mode = wlan_vdev_mlme_get_opmode(vdev); + + wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_SME_ID); while (*roam_bss_entry) { scan_result = GET_BASE_ADDR(*roam_bss_entry, struct @@ -5394,6 +5409,22 @@ static bool csr_roam_select_bss(struct mac_context *mac_ctx, chan_id = wlan_reg_freq_to_chan( mac_ctx->pdev, result->BssDescriptor.chan_freq); + mode = policy_mgr_convert_device_mode_to_qdf_type(op_mode); + /* If concurrency is not allowed select next bss */ + if (!policy_mgr_is_concurrency_allowed(mac_ctx->psoc, + mode, + chan_id, + HW_MODE_20_MHZ)) { + sme_err("Concurrency not allowed for this channel %d bssid %pM, selecting next", + chan_id, result->BssDescriptor.bssId); + *roam_state = eCsrStopRoamingDueToConcurrency; + status = true; + *roam_bss_entry = csr_ll_next(&bss_list->List, + *roam_bss_entry, + LL_ACCESS_LOCK); + continue; + } + /* * check if channel is allowed for current hw mode, if not fetch * next BSS.