From 7af2c5d1e70e88aad96c3bd2bb03a56eb1e10d5d Mon Sep 17 00:00:00 2001 From: Utkarsh Bhatnagar Date: Wed, 29 Dec 2021 12:21:49 +0530 Subject: [PATCH] qcacld-3.0: Fix force SCC logic to consider 1 inactive link A MLO with 1 link not active will lead to HW mode as SMM instead of SBS, so check and see if SBS MLO is present and take decision as per it. Change-Id: Ide487d56d6375892b91ab615b9ad314dba2c9991 CRs-Fixed: 3102349 --- .../interface_mgr/src/wlan_if_mgr_sta.c | 4 +- .../policy_mgr/inc/wlan_policy_mgr_api.h | 23 +- .../policy_mgr/src/wlan_policy_mgr_core.c | 284 +++++++++++++++--- .../src/wlan_policy_mgr_get_set_utils.c | 35 ++- core/sme/src/csr/csr_util.c | 4 +- 5 files changed, 283 insertions(+), 67 deletions(-) diff --git a/components/cmn_services/interface_mgr/src/wlan_if_mgr_sta.c b/components/cmn_services/interface_mgr/src/wlan_if_mgr_sta.c index 8eecec4e83..9d8525bcb5 100644 --- a/components/cmn_services/interface_mgr/src/wlan_if_mgr_sta.c +++ b/components/cmn_services/interface_mgr/src/wlan_if_mgr_sta.c @@ -332,8 +332,8 @@ if_mgr_handle_sap_plus_sta_mlo_connect(struct wlan_objmgr_psoc *psoc, if (!wlan_reg_is_24ghz_ch_freq(sap_freq_list[0])) return; - is_mlo_sbs = policy_mgr_is_mlo_sta_sbs_link(psoc, mlo_vdev_lst, - &num_mlo); + is_mlo_sbs = policy_mgr_is_mlo_in_mode_sbs(psoc, PM_STA_MODE, + mlo_vdev_lst, &num_mlo); if (num_mlo < 2) return; 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 f012d6b5dc..d99796e1eb 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 @@ -4070,20 +4070,21 @@ policy_mgr_get_conc_ext_flags(struct wlan_objmgr_vdev *vdev, bool force_mlo); bool policy_mgr_is_mlo_sta_present(struct wlan_objmgr_psoc *psoc); /** - * policy_mgr_is_mlo_sta_sbs_link() - Check whether MLO STA is present with both - * links on 5 or 6 ghz band (SBS link) - * + * policy_mgr_is_mlo_in_mode_sbs() - Check whether MLO present is SBS (with both + * links on 5/6 ghz band) * @psoc: PSOC object information + * @mode: mlo mode to check * @mlo_vdev_lst: Pointer to mlo vdev list, this function wil fill this with * list of mlo vdev * @num_mlo: Pointer to number of mlo link, this function will fill this with * number of mlo links * - * Return: True if MLO STA is present with both links on 5 and 6ghz band + * Return: True if MLO is present with both links on 5 and 6ghz band */ -bool policy_mgr_is_mlo_sta_sbs_link(struct wlan_objmgr_psoc *psoc, - uint8_t *mlo_vdev_lst, - uint8_t *num_mlo); +bool policy_mgr_is_mlo_in_mode_sbs(struct wlan_objmgr_psoc *psoc, + enum policy_mgr_con_mode mode, + uint8_t *mlo_vdev_lst, uint8_t *num_mlo); + #else static inline bool policy_mgr_is_mlo_sap_concurrency_allowed( @@ -4103,6 +4104,14 @@ static inline bool policy_mgr_is_mlo_sta_present(struct wlan_objmgr_psoc *psoc) { return false; } + +static inline +bool policy_mgr_is_mlo_in_mode_sbs(struct wlan_objmgr_psoc *psoc, + enum policy_mgr_con_mode mode, + uint8_t *mlo_vdev_lst, uint8_t *num_mlo) +{ + return false; +} #endif /** diff --git a/components/cmn_services/policy_mgr/src/wlan_policy_mgr_core.c b/components/cmn_services/policy_mgr/src/wlan_policy_mgr_core.c index f923138276..087f89b7a7 100644 --- a/components/cmn_services/policy_mgr/src/wlan_policy_mgr_core.c +++ b/components/cmn_services/policy_mgr/src/wlan_policy_mgr_core.c @@ -3486,6 +3486,174 @@ policy_mgr_get_same_band_iface_frq(struct wlan_objmgr_psoc *psoc, policy_mgr_get_iface_5g_freq(psoc)); } +static void +policy_mgr_check_force_scc_two_connection(struct wlan_objmgr_psoc *psoc, + qdf_freq_t *intf_ch_freq, + qdf_freq_t sap_ch_freq, + uint8_t cc_mode, + bool same_band_present, + uint32_t acs_band) +{ + bool sbs_mlo_present = false; + + /* + * 1st: 2nd: 3rd(SAP): Action: + * ------------------------------------------------- + * 2Ghz 2Ghz(SMM/DBS) 5Ghz Start on 5Ghz + * 2Ghz 5Ghz(DBS) 5Ghz Force SCC to 5Ghz + * 2Ghz 5Ghz(DBS) 2Ghz Force SCC to 5Ghz + * 5Ghz 5Ghz(SBS) 2Ghz If acs is ALL band force SCC + * else start on 2.4Ghz + * 5Ghz 5Ghz(SBS) 5Ghz Force SCC to one of 5Ghz + * 5Ghz 5Ghz(SMM) 2Ghz Start on 2.4Ghz + * 5Ghz 5Ghz(SMM) 5Ghz Allow SAP on sap_ch_freq if all + * 3, 5Ghz freq does't end up + * on same mac, ie 2 of them lead + * to SBS. Else force SCC on + * one of the freq (3 home channel + * will not be allowed) + * 2Ghz 2Ghz(SMM/DBS) 2Ghz force SCC on one of the freq + * (3 home channel + * will not be allowed) + */ + + /* Check if STA or SAP SBS MLO is present */ + if (policy_mgr_is_hw_sbs_capable(psoc) && + (policy_mgr_is_mlo_in_mode_sbs(psoc, PM_STA_MODE, + NULL, NULL) || + policy_mgr_is_mlo_in_mode_sbs(psoc, PM_SAP_MODE, + NULL, NULL))) + sbs_mlo_present = true; + + /* + * Check for SBS mlo present as if 1 link is inactive the + * HW mode will be SMM and not SBS. + */ + if (policy_mgr_is_current_hwmode_sbs(psoc) || sbs_mlo_present) { + /* + * 1st: 2nd: 3rd(SAP): Action: + * ------------------------------------------------- + * 5Ghz 5Ghz(SBS) 2Ghz If acs is ALL band force SCC + * else start on 2.4Ghz + * 5Ghz 5Ghz(SBS) 5Ghz Force SCC to one of 5Ghz + */ + if (acs_band == QCA_ACS_MODE_IEEE80211ANY || + !WLAN_REG_IS_24GHZ_CH_FREQ(sap_ch_freq)) + *intf_ch_freq = + policy_mgr_get_iface_5g_freq(psoc); + else + *intf_ch_freq = + policy_mgr_get_same_band_iface_frq(psoc, + sap_ch_freq); + return; + } + if (policy_mgr_is_current_hwmode_dbs(psoc)) { + /* + * 1st: 2nd: 3rd(SAP): Action: + * ------------------------------------------------- + * 2Ghz 2Ghz(DBS) 5Ghz Start on 5Ghz + * 2Ghz 5Ghz(DBS) 5Ghz Force SCC to 5Ghz + * 2Ghz 5Ghz(DBS) 2Ghz Force SCC to 5Ghz + * 2Ghz 2Ghz(DBS) 2Ghz force SCC on one of + * the freq (3 home + * channel will not be + * allowed) + */ + *intf_ch_freq = + policy_mgr_get_same_band_iface_frq(psoc, + sap_ch_freq); + return; + } + + if (!same_band_present) { + /* + * 1st: 2nd: 3rd(SAP): Action: + * ------------------------------------------------- + * 2Ghz 2Ghz(SMM) 5Ghz Start on 5Ghz(DBS) + * 5Ghz 5Ghz(SMM) 2Ghz Start on 2.4Ghz(DBS) + */ + if (policy_mgr_is_hw_dbs_capable(psoc)) + *intf_ch_freq = 0; + return; + } + + if (!policy_mgr_are_3_freq_on_same_mac(psoc, sap_ch_freq, + pm_conc_connection_list[0].freq, + pm_conc_connection_list[1].freq)) { + /* + * 1st: 2nd: 3rd(SAP): Action: + * ------------------------------------------------- + * 5Ghz 5Ghz(SMM) 5Ghz Allow SAP on sap_ch_freq + * if all 3, 5Ghz freq + * does't end up, on same + * mac, ie 2 of them lead + * to SBS, ie at least one + * of them is high 5Ghz and + * one low 5Ghz. + */ + *intf_ch_freq = 0; + return; + } + + /* + * 1st: 2nd: 3rd(SAP): Action: + * ------------------------------------------------- + * 5Ghz 5Ghz(SMM) 5Ghz force SCC on one of the freq + * (3 home channel will not be + * allowed) + * 2Ghz 2Ghz(SMM) 2Ghz force SCC on one of the freq + * (3 home channel will not be + * allowed) + */ + policy_mgr_debug("%d Can lead to 3 home channel on same MAC", + sap_ch_freq); +} + +static void +policy_mgr_check_force_scc_one_connection(struct wlan_objmgr_psoc *psoc, + qdf_freq_t *intf_ch_freq, + qdf_freq_t sap_ch_freq, + bool same_band_present, + uint8_t cc_mode) +{ + /* + * 1st: 2nd(SAP): Action: + * ------------------------------------ + * 2Ghz 2Ghz Force SCC on 2Ghz + * 5Ghz 5Ghz Force SCC on 5Ghz for non SBS, for SBS freq + * allow sap freq + * 2Ghz 5Ghz Start on 5Ghz (DBS) + * 5Ghz 2Ghz Start on 2.4Ghz(DBS) + */ + + if (same_band_present) { + /* + * 1st: 2nd(SAP): Action: + * ------------------------------------ + * 2Ghz 2Ghz Force SCC on 2Ghz + * 5Ghz 5Ghz Force SCC on 5Ghz for non SBS, + * for SBS freq allow sap freq + */ + if (policy_mgr_are_sbs_chan(psoc, sap_ch_freq, *intf_ch_freq)) { + policy_mgr_debug("Do not overwrite as sap_ch_freq %d intf_ch_freq %d are SBS freq", + sap_ch_freq, *intf_ch_freq); + *intf_ch_freq = 0; + } + return; + } + if (policy_mgr_is_hw_dbs_capable(psoc) || + cc_mode == QDF_MCC_TO_SCC_WITH_PREFERRED_BAND) { + /* + * 1st: 2nd(SAP): Action: + * ------------------------------------ + * 2Ghz 5Ghz Start on 5Ghz (DBS) + * 5Ghz 2Ghz Start on 2.4Ghz(DBS) + */ + /* Different bands can do DBS so dont overwrite */ + *intf_ch_freq = 0; + } +} + void policy_mgr_check_scc_sbs_channel(struct wlan_objmgr_psoc *psoc, qdf_freq_t *intf_ch_freq, qdf_freq_t sap_ch_freq, @@ -3497,6 +3665,8 @@ void policy_mgr_check_scc_sbs_channel(struct wlan_objmgr_psoc *psoc, struct policy_mgr_conc_connection_info info[MAX_NUMBER_OF_CONC_CONNECTIONS] = { {0} }; uint8_t num_cxn_del = 0; + bool same_band_present = false; + bool sbs_mlo_present = false; pm_ctx = policy_mgr_get_context(psoc); if (!pm_ctx) { @@ -3504,25 +3674,58 @@ void policy_mgr_check_scc_sbs_channel(struct wlan_objmgr_psoc *psoc, return; } - if (pm_ctx->hdd_cbacks.wlan_get_sap_acs_band) { - status = pm_ctx->hdd_cbacks.wlan_get_sap_acs_band(psoc, - vdev_id, - &acs_band); - if (QDF_IS_STATUS_SUCCESS(status)) - policy_mgr_debug("acs_band: %d", acs_band); - } - + /* Always do force SCC on non-DBS platforms */ + if (!policy_mgr_is_hw_dbs_capable(psoc) && + cc_mode != QDF_MCC_TO_SCC_WITH_PREFERRED_BAND) + return; /* - * Different band, this also means that there is only one interface - * which is not on same band as csr_check_concurrent_channel_overlap - * try to find same band vdev if available + * If same band interface is present, as + * csr_check_concurrent_channel_overlap try to find same band vdev + * if available */ if ((WLAN_REG_IS_24GHZ_CH_FREQ(sap_ch_freq) && - !WLAN_REG_IS_24GHZ_CH_FREQ(*intf_ch_freq)) || - (WLAN_REG_IS_24GHZ_CH_FREQ(*intf_ch_freq) && - !WLAN_REG_IS_24GHZ_CH_FREQ(sap_ch_freq))) { - if (policy_mgr_is_current_hwmode_sbs(psoc)) + WLAN_REG_IS_24GHZ_CH_FREQ(*intf_ch_freq)) || + (!WLAN_REG_IS_24GHZ_CH_FREQ(*intf_ch_freq) && + !WLAN_REG_IS_24GHZ_CH_FREQ(sap_ch_freq))) + same_band_present = true; + + /* Check if STA or SAP SBS MLO is present */ + if (policy_mgr_is_hw_sbs_capable(psoc) && + (policy_mgr_is_mlo_in_mode_sbs(psoc, PM_STA_MODE, + NULL, NULL) || + policy_mgr_is_mlo_in_mode_sbs(psoc, PM_SAP_MODE, + NULL, NULL))) + sbs_mlo_present = true; + + /* + * Different band, this also mean that there is no other interface on + * on same band as csr_check_concurrent_channel_overlap + * try to find same band vdev if available. + * this mean for DBS HW we can use the other available band and thus + * set *intf_ch_freq = 0, to bring sap on sap_ch_freq. + */ + if (!same_band_present) { + if (policy_mgr_is_current_hwmode_sbs(psoc) || sbs_mlo_present) goto sbs_check; + /* + * #1 port: + * 1st: 2nd(SAP): Action: + * ------------------------------------ + * 2Ghz 5Ghz Start on 5Ghz(DBS) + * 5Ghz 2Ghz Start on 2.4Ghz(DBS) + * + * #2 port: + * 1st: 2nd: 3rd(SAP): Action: + * ------------------------------------------------- + * 2Ghz 2Ghz(SMM/DBS) 5Ghz Start on 5Ghz(DBS) + * 5Ghz 5Ghz(SMM) 2Ghz Start on 2.4Ghz(DBS) + * + * #3 port: + * 1st: 2nd: 3rd: 4th(SAP) Action: + * ------------------------------------------------- + * 2Ghz 2Ghz 2Ghz 5Ghz Start on 5Ghz(DBS) + * 5Ghz 5Ghz 5Ghz 2Ghz Start on 2.4Ghz(DBS) + */ if (policy_mgr_is_hw_dbs_capable(psoc) || cc_mode == QDF_MCC_TO_SCC_WITH_PREFERRED_BAND) { *intf_ch_freq = 0; @@ -3541,6 +3744,15 @@ void policy_mgr_check_scc_sbs_channel(struct wlan_objmgr_psoc *psoc, policy_mgr_debug("no mandatory channels (%d, %d)", sap_ch_freq, *intf_ch_freq); } + + if (pm_ctx->hdd_cbacks.wlan_get_sap_acs_band) { + status = pm_ctx->hdd_cbacks.wlan_get_sap_acs_band(psoc, + vdev_id, + &acs_band); + if (QDF_IS_STATUS_SUCCESS(status)) + policy_mgr_debug("acs_band: %d", acs_band); + } + sbs_check: qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); /* @@ -3549,9 +3761,10 @@ sbs_check: */ policy_mgr_store_and_del_conn_info_by_vdev_id(psoc, vdev_id, info, &num_cxn_del); + /* - * If at least one interface is in same band as the required freq, try - * and set SBS/SCC. + * If at least one interface is in same band OR HW mode is SBS OR + * SBS MLO is present, try set SBS/DBS/SCC. */ num_connections = policy_mgr_get_connection_count(psoc); policy_mgr_dump_sbs_freq_range(pm_ctx); @@ -3561,38 +3774,23 @@ sbs_check: *intf_ch_freq = 0; break; case 1: - /* Do not overwrite if the channel can create SBS */ - if (policy_mgr_are_sbs_chan(psoc, sap_ch_freq, - *intf_ch_freq)) { - policy_mgr_debug("Do not overwrite as sap_ch_freq %d intf_ch_freq %d are SBS freq", - sap_ch_freq, *intf_ch_freq); - *intf_ch_freq = 0; - } + policy_mgr_check_force_scc_one_connection(psoc, intf_ch_freq, + sap_ch_freq, + same_band_present, + cc_mode); break; case 2: - if (policy_mgr_is_current_hwmode_sbs(psoc)) { - if (WLAN_REG_IS_24GHZ_CH_FREQ(sap_ch_freq)) { - if (acs_band == QCA_ACS_MODE_IEEE80211ANY) - *intf_ch_freq = - policy_mgr_get_iface_5g_freq(psoc); - else - /* keep the sap req unchanged, MCC on MAC 0 */ - *intf_ch_freq = 0; - } else { - *intf_ch_freq = - policy_mgr_get_iface_5g_freq(psoc); - } - } else if (policy_mgr_is_current_hwmode_dbs(psoc)) { - *intf_ch_freq = - policy_mgr_get_same_band_iface_frq(psoc, - sap_ch_freq); - } - /* This mean Force SCC on *intf_ch_freq */ + policy_mgr_check_force_scc_two_connection(psoc, intf_ch_freq, + sap_ch_freq, + cc_mode, + same_band_present, + acs_band); break; default: + policy_mgr_debug("invalid num_connections: %d", + num_connections); break; } - /* Restore the connection entry */ if (num_cxn_del > 0) policy_mgr_restore_deleted_conn_info(psoc, info, num_cxn_del); 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 a32fd160ae..17c57b5186 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 @@ -3703,47 +3703,56 @@ bool policy_mgr_is_mlo_sta_present(struct wlan_objmgr_psoc *psoc) return mlo_sta_present; } -bool policy_mgr_is_mlo_sta_sbs_link(struct wlan_objmgr_psoc *psoc, - uint8_t *mlo_vdev_lst, - uint8_t *num_mlo) +bool policy_mgr_is_mlo_in_mode_sbs(struct wlan_objmgr_psoc *psoc, + enum policy_mgr_con_mode mode, + uint8_t *mlo_vdev_lst, uint8_t *num_mlo) { - uint32_t sta_num = 0; + uint32_t mode_num = 0; uint8_t i, mlo_idx = 0; struct wlan_objmgr_vdev *temp_vdev; qdf_freq_t mlo_freq_list[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0}; uint8_t vdev_id_list[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0}; bool is_sbs_link = true; - sta_num = policy_mgr_get_mode_specific_conn_info(psoc, NULL, - vdev_id_list, - PM_STA_MODE); - if (!sta_num) + mode_num = policy_mgr_get_mode_specific_conn_info(psoc, NULL, + vdev_id_list, mode); + if (!mode_num || mode_num < 2) return false; - for (i = 0; i < sta_num; i++) { + for (i = 0; i < mode_num; i++) { temp_vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id_list[i], WLAN_POLICY_MGR_ID); if (!temp_vdev) { - sme_err("invalid vdev for id %d", vdev_id_list[i]); + policy_mgr_err("invalid vdev for id %d", + vdev_id_list[i]); return false; } if (wlan_vdev_mlme_is_mlo_vdev(temp_vdev)) { - mlo_vdev_lst[mlo_idx] = vdev_id_list[i]; + if (mlo_vdev_lst) + mlo_vdev_lst[mlo_idx] = vdev_id_list[i]; mlo_freq_list[mlo_idx] = wlan_get_operation_chan_freq(temp_vdev); if (wlan_reg_is_24ghz_ch_freq(mlo_freq_list[mlo_idx])) is_sbs_link = false; - mlo_idx++; } wlan_objmgr_vdev_release_ref(temp_vdev, WLAN_POLICY_MGR_ID); } - *num_mlo = mlo_idx; + if (num_mlo) + *num_mlo = mlo_idx; if (mlo_idx < 2) is_sbs_link = false; + if (is_sbs_link && + !policy_mgr_are_sbs_chan(psoc, mlo_freq_list[0], + mlo_freq_list[1])) { + policy_mgr_debug("Freq %d and %d are not SBS, set SBS false", + mlo_freq_list[0], + mlo_freq_list[1]); + is_sbs_link = false; + } return is_sbs_link; } diff --git a/core/sme/src/csr/csr_util.c b/core/sme/src/csr/csr_util.c index 89b6ad2877..c22a31523e 100644 --- a/core/sme/src/csr/csr_util.c +++ b/core/sme/src/csr/csr_util.c @@ -1464,8 +1464,8 @@ void csr_handle_sap_mlo_sta_concurrency(struct wlan_objmgr_vdev *vdev, if (!mac_ctx) return; - is_mlo_sbs = policy_mgr_is_mlo_sta_sbs_link(mac_ctx->psoc, mlo_vdev_lst, - &num_mlo); + is_mlo_sbs = policy_mgr_is_mlo_in_mode_sbs(mac_ctx->psoc, PM_STA_MODE, + mlo_vdev_lst, &num_mlo); if (num_mlo < 2) { sme_debug("vdev %d AP_state %d MLO Sta links %d",