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 5106786d4f..4383c5a37a 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 @@ -2816,9 +2816,27 @@ bool policy_mgr_is_dbs_scan_allowed(struct wlan_objmgr_psoc *psoc); */ bool policy_mgr_is_hw_sbs_capable(struct wlan_objmgr_psoc *psoc); +/** + * policy_mgr_2_freq_always_on_same_mac() - Function to check whether both the + * input frequencies are on same mac in all supported mode/freq range + * + * @psoc: Pointer to Psoc + * @freq_1: Frequency 1 to check + * @freq_2: Frequency 2 to check + * + * This Function check whether both the input frequency exist in the same mac + * in all supported mode/freq range + * + * Return:True if both the frequency exist on the same mac in all supported + * mode/freq range. + * + */ +bool policy_mgr_2_freq_always_on_same_mac(struct wlan_objmgr_psoc *psoc, + qdf_freq_t freq_1, qdf_freq_t freq_2); + /** * policy_mgr_are_2_freq_on_same_mac() - Function to check whether both the - * input frequencies are on same mac + * input frequencies are on same mac in current freq range * * @psoc: Pointer to Psoc * @freq_1: Frequency 1 to check @@ -2834,9 +2852,30 @@ policy_mgr_are_2_freq_on_same_mac(struct wlan_objmgr_psoc *psoc, qdf_freq_t freq_1, qdf_freq_t freq_2); +/** + * policy_mgr_3_freq_always_on_same_mac() - Function to check whether all three + * input frequencies will always in same mac in all supported mode/freq range + * + * @psoc: Pointer to Psoc + * @freq_1: Frequency 1 to check + * @freq_2: Frequency 2 to check + * @freq_3: Frequency 3 to check + * + * This Function check whether all three input frequencies exist in the same + * mac in all supported mode/freq range. + * + * Return:True if all three frequency exist on the same mac in all supported + * mode/freq range + * + */ +bool +policy_mgr_3_freq_always_on_same_mac(struct wlan_objmgr_psoc *psoc, + qdf_freq_t freq_1, qdf_freq_t freq_2, + qdf_freq_t freq_3); + /** * policy_mgr_are_3_freq_on_same_mac() - Function to check whether all three - * input frequencies are in same mac + * input frequencies are in same mac in current freq range * * @psoc: Pointer to Psoc * @freq_1: Frequency 1 to check @@ -2854,6 +2893,34 @@ policy_mgr_are_3_freq_on_same_mac(struct wlan_objmgr_psoc *psoc, qdf_freq_t freq_1, qdf_freq_t freq_2, qdf_freq_t freq_3); +/** + * policy_mgr_allow_4th_new_freq() - Function to check whether 4th freq can + * be allowed wthout leading to 3 home freq on same mac + * + * @psoc: Pointer to Psoc + * @freq1: Frequency 1 + * @freq2: Frequency 2 + * @freq3: Frequency 3 + * @new_ch_freq: freq to check with reference to freq1 freq2 and freq3 + * + * Return:True if all 4 freq doesnt cause 3 home frequency on same mac + * + */ +#ifdef FEATURE_FOURTH_CONNECTION +bool +policy_mgr_allow_4th_new_freq(struct wlan_objmgr_psoc *psoc, + qdf_freq_t freq1, qdf_freq_t freq2, + qdf_freq_t freq3, qdf_freq_t new_ch_freq); +#else +static inline bool +policy_mgr_allow_4th_new_freq(struct wlan_objmgr_psoc *psoc, + qdf_freq_t freq1, qdf_freq_t freq2, + qdf_freq_t freq3, qdf_freq_t new_ch_freq) +{ + return false; +} +#endif + /** * policy_mgr_are_sbs_chan() - Function to check whether both the * input frequency are in SBS frequency range 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 8bdf71cd2d..3a965950bf 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 @@ -3411,7 +3411,7 @@ bool policy_mgr_allow_same_mac_diff_freq(struct wlan_objmgr_psoc *psoc, policy_mgr_rl_debug("don't allow 3rd home channel on same MAC"); allow = false; } - } else if (policy_mgr_are_3_freq_on_same_mac(psoc, ch_freq, + } else if (policy_mgr_3_freq_always_on_same_mac(psoc, ch_freq, pm_conc_connection_list[0].freq, pm_conc_connection_list[1].freq)) { policy_mgr_rl_debug("don't allow 3rd home channel on same MAC"); @@ -3454,7 +3454,7 @@ bool policy_mgr_allow_same_mac_same_freq(struct wlan_objmgr_psoc *psoc, * and therefore a 3rd connection with the * same MAC is possible. */ - } else if (policy_mgr_are_2_freq_on_same_mac(psoc, ch_freq, + } else if (policy_mgr_2_freq_always_on_same_mac(psoc, ch_freq, pm_conc_connection_list[0].freq) && !policy_mgr_is_3rd_conn_on_same_band_allowed(psoc, mode)) { policy_mgr_rl_debug("don't allow 3rd home channel on same MAC – for sta+multi-AP"); @@ -3464,23 +3464,9 @@ bool policy_mgr_allow_same_mac_same_freq(struct wlan_objmgr_psoc *psoc, return allow; } -/** - * policy_mgr_allow_new_home_channel() - Check for allowed number of - * home channels - * @mode: policy_mgr_con_mode of new connection, - * @channel: channel on which new connection is coming up - * @num_connections: number of current connections - * @is_dfs_ch: DFS channel or not - * - * When a new connection is about to come up check if current - * concurrency combination including the new connection is - * allowed or not based on the HW capability - * - * Return: True/False - */ bool policy_mgr_allow_new_home_channel( struct wlan_objmgr_psoc *psoc, enum policy_mgr_con_mode mode, - uint32_t ch_freq, uint32_t num_connections, bool is_dfs_ch) + qdf_freq_t ch_freq, uint32_t num_connections, bool is_dfs_ch) { bool status = true; struct policy_mgr_psoc_priv_obj *pm_ctx; @@ -3497,11 +3483,17 @@ bool policy_mgr_allow_new_home_channel( QDF_MCC_TO_SCC_SWITCH_FORCE_PREFERRED_WITHOUT_DISCONNECTION; qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); - if (num_connections == 2) { + if (num_connections == 3) { + status = policy_mgr_allow_4th_new_freq(psoc, + pm_conc_connection_list[0].freq, + pm_conc_connection_list[1].freq, + pm_conc_connection_list[2].freq, + ch_freq); + } else if (num_connections == 2) { /* No SCC or MCC combination is allowed with / on DFS channel */ - on_same_mac = policy_mgr_are_2_freq_on_same_mac(psoc, - pm_conc_connection_list[0].freq, - pm_conc_connection_list[1].freq); + on_same_mac = policy_mgr_2_freq_always_on_same_mac(psoc, + pm_conc_connection_list[0].freq, + pm_conc_connection_list[1].freq); if (force_switch_without_dis && is_dfs_ch && ((pm_conc_connection_list[0].ch_flagext & (IEEE80211_CHAN_DFS | IEEE80211_CHAN_DFS_CFREQ2)) || @@ -3533,7 +3525,7 @@ bool policy_mgr_allow_new_home_channel( */ if ((pm_conc_connection_list[0].mode != PM_NAN_DISC_MODE) && (mode != PM_NAN_DISC_MODE)) - status = policy_mgr_are_2_freq_on_same_mac(psoc, + status = policy_mgr_2_freq_always_on_same_mac(psoc, ch_freq, pm_conc_connection_list[0].freq); } @@ -3742,7 +3734,7 @@ policy_mgr_check_force_scc_two_connection(struct wlan_objmgr_psoc *psoc, return; } - if (!policy_mgr_are_3_freq_on_same_mac(psoc, sap_ch_freq, + if (!policy_mgr_3_freq_always_on_same_mac(psoc, sap_ch_freq, pm_conc_connection_list[0].freq, pm_conc_connection_list[1].freq)) { /* 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 7320a79419..98706f78a2 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 @@ -1361,6 +1361,54 @@ policy_mgr_is_cur_freq_range_sbs(struct wlan_objmgr_psoc *psoc) return false; } +bool policy_mgr_2_freq_always_on_same_mac(struct wlan_objmgr_psoc *psoc, + qdf_freq_t freq_1, qdf_freq_t freq_2) +{ + struct policy_mgr_psoc_priv_obj *pm_ctx; + struct policy_mgr_freq_range *freq_range; + bool is_dbs_mode_same_mac = true; + bool is_sbs_mode_same_mac = true; + + pm_ctx = policy_mgr_get_context(psoc); + if (!pm_ctx) + return false; + + /* if HW is not DBS return true*/ + if (!policy_mgr_is_hw_dbs_capable(psoc)) + return true; + + /* Check for DBS mode first */ + freq_range = pm_ctx->hw_mode.freq_range_caps[MODE_DBS]; + is_dbs_mode_same_mac = + policy_mgr_are_2_freq_in_freq_range(pm_ctx, freq_range, + freq_1, freq_2); + + /* + * if not leading to same mac in dbs mode or SBS not supported no need + * to check further + */ + if (!is_dbs_mode_same_mac || + !policy_mgr_is_hw_sbs_capable(psoc)) + goto skip_sbs; + + /* Check for SBS mode */ + is_sbs_mode_same_mac = + policy_mgr_are_2_freq_in_sbs_freq_range(pm_ctx, freq_1, freq_2); + +skip_sbs: + policy_mgr_debug("freq1 %d freq2 %d: Same mac:: DBS:%d SBS:%d", + freq_1, freq_2, is_dbs_mode_same_mac, + is_sbs_mode_same_mac); + /* + * if in SBS and DBS mode, both is leading to freqs on same mac, + * return true else return false. + */ + if (is_dbs_mode_same_mac && is_sbs_mode_same_mac) + return true; + + return false; +} + bool policy_mgr_are_2_freq_on_same_mac(struct wlan_objmgr_psoc *psoc, qdf_freq_t freq_1, qdf_freq_t freq_2) @@ -1380,12 +1428,6 @@ bool policy_mgr_are_2_freq_on_same_mac(struct wlan_objmgr_psoc *psoc, return true; policy_mgr_rl_debug("freq_1 %d freq_2 %d", freq_1, freq_2); - if (!policy_mgr_is_hw_sbs_capable(psoc)) { - /* If not SBS capable but DBS capable */ - freq_range = pm_ctx->hw_mode.freq_range_caps[MODE_DBS]; - return policy_mgr_are_2_freq_in_freq_range(pm_ctx, freq_range, - freq_1, freq_2); - } /* HW is DBS/SBS capable */ status = policy_mgr_get_current_hw_mode(psoc, &hw_mode); @@ -1406,19 +1448,10 @@ bool policy_mgr_are_2_freq_on_same_mac(struct wlan_objmgr_psoc *psoc, freq_1, freq_2); /* - * Current HW is SMM check, if they can lead to SBS or DBS without being - * in same mac, return true only if Both will lead to same mac + * If current HW mode is not DBS/SBS, check if in all supported mode + * it they will be on same mac */ - if (!policy_mgr_are_2_freq_in_sbs_freq_range(pm_ctx, freq_1, freq_2)) - return false; - - /* - * If SBS lead to same mac, check if DBS mode will also lead to same - * mac - */ - freq_range = pm_ctx->hw_mode.freq_range_caps[MODE_DBS]; - return policy_mgr_are_2_freq_in_freq_range(pm_ctx, freq_range, - freq_1, freq_2); + return policy_mgr_2_freq_always_on_same_mac(psoc, freq_1, freq_2); } static bool @@ -1468,6 +1501,57 @@ policy_mgr_are_3_freq_in_sbs_freq_range(struct policy_mgr_psoc_priv_obj *pm_ctx, freq_1, freq_2, freq_3); } +bool +policy_mgr_3_freq_always_on_same_mac(struct wlan_objmgr_psoc *psoc, + qdf_freq_t freq_1, qdf_freq_t freq_2, + qdf_freq_t freq_3) +{ + struct policy_mgr_psoc_priv_obj *pm_ctx; + struct policy_mgr_freq_range *freq_range; + bool is_dbs_mode_same_mac = true; + bool is_sbs_mode_same_mac = true; + + pm_ctx = policy_mgr_get_context(psoc); + if (!pm_ctx) + return false; + + /* if HW is not DBS return true*/ + if (!policy_mgr_is_hw_dbs_capable(psoc)) + return true; + + /* Check for DBS mode first */ + freq_range = pm_ctx->hw_mode.freq_range_caps[MODE_DBS]; + is_dbs_mode_same_mac = + policy_mgr_are_3_freq_in_freq_range(pm_ctx, freq_range, + freq_1, freq_2, freq_3); + + /* + * if not leading to same mac in dbs mode or SBS not supported no need + * to check further + */ + if (!is_dbs_mode_same_mac || + !policy_mgr_is_hw_sbs_capable(psoc)) + goto skip_sbs; + + /* Check for SBS mode */ + is_sbs_mode_same_mac = + policy_mgr_are_3_freq_in_sbs_freq_range(pm_ctx, freq_1, freq_2, + freq_3); + +skip_sbs: + policy_mgr_debug("freq1 %d freq2 %d freq3 %d: Same mac:: DBS:%d SBS:%d", + freq_1, freq_2, freq_3, is_dbs_mode_same_mac, + is_sbs_mode_same_mac); + /* + * if in SBS and DBS mode, both is leading to freqs on same mac, + * return true else return false. + */ + if (is_dbs_mode_same_mac && is_sbs_mode_same_mac) + return true; + + return false; +} + bool policy_mgr_are_3_freq_on_same_mac(struct wlan_objmgr_psoc *psoc, qdf_freq_t freq_1, qdf_freq_t freq_2, @@ -1489,13 +1573,6 @@ policy_mgr_are_3_freq_on_same_mac(struct wlan_objmgr_psoc *psoc, policy_mgr_rl_debug("freq_1 %d freq_2 %d freq_3 %d", freq_1, freq_2, freq_3); - if (!policy_mgr_is_hw_sbs_capable(psoc)) { - /* If not SBS capable but DBS capable */ - freq_range = pm_ctx->hw_mode.freq_range_caps[MODE_DBS]; - return policy_mgr_are_3_freq_in_freq_range(pm_ctx, freq_range, - freq_1, freq_2, - freq_3); - } /* HW is DBS/SBS capable, get current HW mode */ status = policy_mgr_get_current_hw_mode(psoc, &hw_mode); @@ -1516,21 +1593,92 @@ policy_mgr_are_3_freq_on_same_mac(struct wlan_objmgr_psoc *psoc, freq_1, freq_2, freq_3); /* - * Current HW is SMM check, if they can lead to SBS or DBS without being - * in same mac, return true only if both will lead to same mac + * If current HW mode is not DBS/SBS, check if in all supported mode + * it they will be on same mac */ - if (!policy_mgr_are_3_freq_in_sbs_freq_range(pm_ctx, freq_1, freq_2, - freq_3)) - return false; - /* - * If SBS lead to same mac, check if DBS mode will also lead to same mac - */ - freq_range = pm_ctx->hw_mode.freq_range_caps[MODE_DBS]; - - return policy_mgr_are_3_freq_in_freq_range(pm_ctx, freq_range, freq_1, - freq_2, freq_3); + return policy_mgr_3_freq_always_on_same_mac(psoc, freq_1, freq_2, + freq_3); } +#ifdef FEATURE_FOURTH_CONNECTION +bool +policy_mgr_allow_4th_new_freq(struct wlan_objmgr_psoc *psoc, + qdf_freq_t freq1, qdf_freq_t freq2, + qdf_freq_t freq3, qdf_freq_t new_ch_freq) +{ + struct policy_mgr_freq_range *dbs_freq_range; + bool is_dbs_mode_3_home_freq = false; + bool is_sbs_mode_3_home_freq = false; + struct policy_mgr_psoc_priv_obj *pm_ctx; + + pm_ctx = policy_mgr_get_context(psoc); + if (!pm_ctx) + return false; + + if (!freq1 || !freq2 || !freq3 || !new_ch_freq) { + policy_mgr_info("one or more freq are 0: freq1 %d freq2 %d freq3 %d new_freq %d", + freq1, freq2, freq3, new_ch_freq); + return false; + } + + /* Check for DBS mode first */ + dbs_freq_range = pm_ctx->hw_mode.freq_range_caps[MODE_DBS]; + /* + * If existing freq leading to 3 home channel in DBS mode, check SBS. + * Else check if new_ch_freq can cause 3 home freq with existing 2 home + * freq on same mac. + */ + if (policy_mgr_are_3_freq_in_freq_range(pm_ctx, dbs_freq_range, freq1, + freq2, freq3) || + policy_mgr_are_3_freq_in_freq_range(pm_ctx, dbs_freq_range, freq1, + freq2, new_ch_freq) || + policy_mgr_are_3_freq_in_freq_range(pm_ctx, dbs_freq_range, freq1, + freq3, new_ch_freq) || + policy_mgr_are_3_freq_in_freq_range(pm_ctx, dbs_freq_range, freq2, + freq3, new_ch_freq)) + is_dbs_mode_3_home_freq = true; + + /* + * if allowed in dbs mode or SBS not supported no need + * to check further + */ + if (!is_dbs_mode_3_home_freq || + !policy_mgr_is_hw_sbs_capable(psoc)) + goto skip_sbs_check; + + /* Check for SBS mode */ + /* + * If existing freq leading to 3 home channel in SBS mode, skip the + * check. Else check if new_ch_freq can cause 3 home freq with + * existing 2 home home freq on same mac + */ + if (policy_mgr_are_3_freq_in_sbs_freq_range(pm_ctx, freq1, + freq2, freq3) || + policy_mgr_are_3_freq_in_sbs_freq_range(pm_ctx, freq1, freq2, + new_ch_freq) || + policy_mgr_are_3_freq_in_sbs_freq_range(pm_ctx, freq1, freq3, + new_ch_freq) || + policy_mgr_are_3_freq_in_sbs_freq_range(pm_ctx, freq2, freq3, + new_ch_freq)) + is_sbs_mode_3_home_freq = true; + +skip_sbs_check: + policy_mgr_debug("freq1 %d freq2 %d freq3 %d new_freq %d: leads to 3 home freq:: DBS:%d SBS:%d", + freq1, freq2, freq3, new_ch_freq, + is_dbs_mode_3_home_freq, is_sbs_mode_3_home_freq); + /* + * if in SBS or DBS mode, it can be allowed without leading to 3 home + * freq on same mac, return true. + * Return false only if in both mode it will lead to 3 home freq on same + * mac. + */ + if (!is_dbs_mode_3_home_freq || !is_sbs_mode_3_home_freq) + return true; + + return false; +} +#endif + bool policy_mgr_are_sbs_chan(struct wlan_objmgr_psoc *psoc, qdf_freq_t freq_1, qdf_freq_t freq_2) {