|
@@ -2057,51 +2057,235 @@ policy_mgr_are_3_freq_on_same_mac(struct wlan_objmgr_psoc *psoc,
|
|
}
|
|
}
|
|
|
|
|
|
#ifdef FEATURE_FOURTH_CONNECTION
|
|
#ifdef FEATURE_FOURTH_CONNECTION
|
|
|
|
+static void
|
|
|
|
+policy_mgr_get_mac_freq_list(struct policy_mgr_freq_range *freq_range,
|
|
|
|
+ uint8_t mac_id,
|
|
|
|
+ uint8_t mac_freq_list[MAX_NUMBER_OF_CONC_CONNECTIONS],
|
|
|
|
+ uint8_t mac_mode_list[MAX_NUMBER_OF_CONC_CONNECTIONS],
|
|
|
|
+ uint8_t *mac_freq_num,
|
|
|
|
+ qdf_freq_t freq_1, enum policy_mgr_con_mode mode_1,
|
|
|
|
+ qdf_freq_t freq_2, enum policy_mgr_con_mode mode_2,
|
|
|
|
+ qdf_freq_t freq_3, enum policy_mgr_con_mode mode_3,
|
|
|
|
+ qdf_freq_t freq_4, enum policy_mgr_con_mode mode_4)
|
|
|
|
+{
|
|
|
|
+ uint8_t j = 0;
|
|
|
|
+
|
|
|
|
+ if (freq_1 && IS_FREQ_ON_MAC_ID(freq_range, freq_1, mac_id)) {
|
|
|
|
+ mac_freq_list[j] = freq_1;
|
|
|
|
+ mac_mode_list[j++] = mode_1;
|
|
|
|
+ }
|
|
|
|
+ if (freq_2 && IS_FREQ_ON_MAC_ID(freq_range, freq_2, mac_id)) {
|
|
|
|
+ mac_freq_list[j] = freq_2;
|
|
|
|
+ mac_mode_list[j++] = mode_2;
|
|
|
|
+ }
|
|
|
|
+ if (freq_3 && IS_FREQ_ON_MAC_ID(freq_range, freq_3, mac_id)) {
|
|
|
|
+ mac_freq_list[j] = freq_3;
|
|
|
|
+ mac_mode_list[j++] = mode_3;
|
|
|
|
+ }
|
|
|
|
+ if (freq_4 && IS_FREQ_ON_MAC_ID(freq_range, freq_4, mac_id)) {
|
|
|
|
+ mac_freq_list[j] = freq_4;
|
|
|
|
+ mac_mode_list[j++] = mode_4;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ *mac_freq_num = j;
|
|
|
|
+}
|
|
|
|
|
|
-/**
|
|
|
|
- * policy_mgr_4_freq_always_on_same_mac() - Function to check if 4 freq can
|
|
|
|
- * lead to 3 home freq on same mac in all modes
|
|
|
|
- * @psoc: Pointer to Psoc
|
|
|
|
- * @freq1: Frequency 1
|
|
|
|
- * @freq2: Frequency 2
|
|
|
|
- * @freq3: Frequency 3
|
|
|
|
- * @freq4: Frequency 4
|
|
|
|
- *
|
|
|
|
- * Return:true if any 3 freq cause 3 home frequency on same mac in all modes
|
|
|
|
- *
|
|
|
|
- */
|
|
|
|
static bool
|
|
static bool
|
|
-policy_mgr_4_freq_always_on_same_mac(struct wlan_objmgr_psoc *psoc,
|
|
|
|
- qdf_freq_t freq1, qdf_freq_t freq2,
|
|
|
|
- qdf_freq_t freq3, qdf_freq_t freq4)
|
|
|
|
-{
|
|
|
|
- /* check if any 3 freq are leading to 3 home freq */
|
|
|
|
- if (policy_mgr_3_freq_always_on_same_mac(psoc, freq1, freq2, freq3) ||
|
|
|
|
- policy_mgr_3_freq_always_on_same_mac(psoc, freq1, freq2, freq4) ||
|
|
|
|
- policy_mgr_3_freq_always_on_same_mac(psoc, freq1, freq3, freq4) ||
|
|
|
|
- policy_mgr_3_freq_always_on_same_mac(psoc, freq2, freq3, freq4))
|
|
|
|
|
|
+policy_mgr_is_supported_hw_mode(struct wlan_objmgr_psoc *psoc,
|
|
|
|
+ struct policy_mgr_psoc_priv_obj *pm_ctx,
|
|
|
|
+ enum policy_mgr_mode hw_mode)
|
|
|
|
+{
|
|
|
|
+ if (hw_mode == MODE_SMM)
|
|
return true;
|
|
return true;
|
|
|
|
|
|
|
|
+ if (hw_mode == MODE_DBS)
|
|
|
|
+ return policy_mgr_is_hw_dbs_capable(psoc);
|
|
|
|
+
|
|
|
|
+ if (hw_mode == MODE_SBS_UPPER_SHARE ||
|
|
|
|
+ hw_mode == MODE_SBS_LOWER_SHARE)
|
|
|
|
+ return policy_mgr_is_hw_sbs_capable(psoc) &&
|
|
|
|
+ pm_ctx->hw_mode.sbs_lower_band_end_freq;
|
|
|
|
+
|
|
|
|
+ if (hw_mode == MODE_SBS)
|
|
|
|
+ return policy_mgr_is_hw_sbs_capable(psoc);
|
|
|
|
+
|
|
return false;
|
|
return false;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+static bool
|
|
|
|
+policy_mgr_mac_freq_list_allow(uint8_t mac_freq_list[MAX_NUMBER_OF_CONC_CONNECTIONS],
|
|
|
|
+ uint8_t mac_mode_list[MAX_NUMBER_OF_CONC_CONNECTIONS],
|
|
|
|
+ uint8_t mac_freq_num)
|
|
|
|
+{
|
|
|
|
+ uint8_t sta = 0, ap = 0, i;
|
|
|
|
+
|
|
|
|
+ switch (mac_freq_num) {
|
|
|
|
+ case 1:
|
|
|
|
+ case 2:
|
|
|
|
+ return true;
|
|
|
|
+ case 3:
|
|
|
|
+ /* If 3 vifs are active in same mac, target only support:
|
|
|
|
+ * 3 vifs are in SCC and 3 vifs are :
|
|
|
|
+ * 1 STA + 2 APs, or 3 APs
|
|
|
|
+ */
|
|
|
|
+ if (mac_freq_list[0] != mac_freq_list[1] ||
|
|
|
|
+ mac_freq_list[0] != mac_freq_list[2])
|
|
|
|
+ return false;
|
|
|
|
+ for (i = 0; i < mac_freq_num; i++) {
|
|
|
|
+ if (mac_mode_list[i] == PM_STA_MODE ||
|
|
|
|
+ mac_mode_list[i] == PM_P2P_CLIENT_MODE)
|
|
|
|
+ sta++;
|
|
|
|
+ else
|
|
|
|
+ ap++;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (sta == 1 && ap == 2)
|
|
|
|
+ return true;
|
|
|
|
+ if (ap == 3)
|
|
|
|
+ return true;
|
|
|
|
+ return false;
|
|
|
|
+ default:
|
|
|
|
+ return false;
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+#ifdef WLAN_FEATURE_11BE_MLO
|
|
|
|
+static void
|
|
|
|
+policy_mgr_ml_sta_active_freq(struct wlan_objmgr_psoc *psoc,
|
|
|
|
+ qdf_freq_t ch_freq,
|
|
|
|
+ enum policy_mgr_con_mode mode,
|
|
|
|
+ uint32_t ext_flags,
|
|
|
|
+ qdf_freq_t *ml_sta_link0_freq,
|
|
|
|
+ qdf_freq_t *ml_sta_link1_freq)
|
|
|
|
+{
|
|
|
|
+ uint8_t num_ml_sta = 0, num_disabled_ml_sta = 0;
|
|
|
|
+ uint8_t num_active_ml_sta;
|
|
|
|
+ uint8_t ml_sta_vdev_lst[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0};
|
|
|
|
+ qdf_freq_t ml_freq_lst[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0};
|
|
|
|
+ union conc_ext_flag conc_ext_flags;
|
|
|
|
+
|
|
|
|
+ conc_ext_flags.value = ext_flags;
|
|
|
|
+ /* find the two active ml sta home channels */
|
|
|
|
+ policy_mgr_get_ml_sta_info_psoc(psoc, &num_ml_sta,
|
|
|
|
+ &num_disabled_ml_sta,
|
|
|
|
+ ml_sta_vdev_lst, ml_freq_lst,
|
|
|
|
+ NULL, NULL, NULL);
|
|
|
|
+ if (num_ml_sta > MAX_NUMBER_OF_CONC_CONNECTIONS ||
|
|
|
|
+ num_disabled_ml_sta > MAX_NUMBER_OF_CONC_CONNECTIONS ||
|
|
|
|
+ num_ml_sta <= num_disabled_ml_sta) {
|
|
|
|
+ policy_mgr_debug("unexpected ml sta num %d %d",
|
|
|
|
+ num_ml_sta, num_disabled_ml_sta);
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+ num_active_ml_sta = num_ml_sta;
|
|
|
|
+ if (num_ml_sta >= num_disabled_ml_sta)
|
|
|
|
+ num_active_ml_sta = num_ml_sta - num_disabled_ml_sta;
|
|
|
|
+ if (num_active_ml_sta > 1) {
|
|
|
|
+ *ml_sta_link0_freq = ml_freq_lst[0];
|
|
|
|
+ *ml_sta_link1_freq = ml_freq_lst[1];
|
|
|
|
+ } else if (num_active_ml_sta > 0 && conc_ext_flags.mlo &&
|
|
|
|
+ mode == PM_STA_MODE) {
|
|
|
|
+ *ml_sta_link0_freq = ml_freq_lst[0];
|
|
|
|
+ *ml_sta_link1_freq = ch_freq;
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+#else
|
|
|
|
+static void
|
|
|
|
+policy_mgr_ml_sta_active_freq(struct wlan_objmgr_psoc *psoc,
|
|
|
|
+ qdf_freq_t ch_freq,
|
|
|
|
+ enum policy_mgr_con_mode mode,
|
|
|
|
+ uint32_t ext_flags,
|
|
|
|
+ qdf_freq_t *ml_sta_link0_freq,
|
|
|
|
+ qdf_freq_t *ml_sta_link1_freq)
|
|
|
|
+{
|
|
|
|
+}
|
|
|
|
+#endif
|
|
|
|
+
|
|
bool
|
|
bool
|
|
policy_mgr_allow_4th_new_freq(struct wlan_objmgr_psoc *psoc,
|
|
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)
|
|
|
|
|
|
+ qdf_freq_t ch_freq,
|
|
|
|
+ enum policy_mgr_con_mode mode,
|
|
|
|
+ uint32_t ext_flags)
|
|
{
|
|
{
|
|
|
|
+ struct policy_mgr_conc_connection_info *conn = pm_conc_connection_list;
|
|
|
|
+ uint8_t mac_freq_list[MAX_NUMBER_OF_CONC_CONNECTIONS];
|
|
|
|
+ uint8_t mac_mode_list[MAX_NUMBER_OF_CONC_CONNECTIONS];
|
|
|
|
+ uint8_t mac_freq_num;
|
|
|
|
+ struct policy_mgr_psoc_priv_obj *pm_ctx;
|
|
|
|
+ qdf_freq_t ml_sta_link0_freq = 0;
|
|
|
|
+ qdf_freq_t ml_sta_link1_freq = 0;
|
|
|
|
+ uint8_t i, j;
|
|
|
|
+ struct policy_mgr_freq_range *freq_range;
|
|
|
|
+
|
|
|
|
+ pm_ctx = policy_mgr_get_context(psoc);
|
|
|
|
+ if (!pm_ctx) {
|
|
|
|
+ policy_mgr_err("Invalid Context");
|
|
|
|
+ return false;
|
|
|
|
+ }
|
|
|
|
+
|
|
/* if HW is not DBS return false */
|
|
/* if HW is not DBS return false */
|
|
if (!policy_mgr_is_hw_dbs_capable(psoc))
|
|
if (!policy_mgr_is_hw_dbs_capable(psoc))
|
|
return false;
|
|
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;
|
|
|
|
|
|
+ /* Find the two active ml sta home channels */
|
|
|
|
+ policy_mgr_ml_sta_active_freq(psoc, ch_freq, mode, ext_flags,
|
|
|
|
+ &ml_sta_link0_freq,
|
|
|
|
+ &ml_sta_link1_freq);
|
|
|
|
+
|
|
|
|
+ /* Check if any hw mode can support the 4th channel frequency
|
|
|
|
+ * and device mode.
|
|
|
|
+ */
|
|
|
|
+ for (j = 0; j < MODE_HW_MAX; j++) {
|
|
|
|
+ if (!policy_mgr_is_supported_hw_mode(psoc, pm_ctx, j))
|
|
|
|
+ continue;
|
|
|
|
+ freq_range = pm_ctx->hw_mode.freq_range_caps[j];
|
|
|
|
+
|
|
|
|
+ /* If ml sta present, the two links should be in
|
|
|
|
+ * different mac always. Skip the hw mode which
|
|
|
|
+ * causes they in same mac.
|
|
|
|
+ */
|
|
|
|
+ if (ml_sta_link0_freq && ml_sta_link1_freq &&
|
|
|
|
+ policy_mgr_2_freq_same_mac_in_freq_range(pm_ctx,
|
|
|
|
+ freq_range,
|
|
|
|
+ ml_sta_link0_freq,
|
|
|
|
+ ml_sta_link1_freq))
|
|
|
|
+ continue;
|
|
|
|
+ for (i = 0; i < MAX_MAC; i++) {
|
|
|
|
+ /* Get the freq list which are in the MAC
|
|
|
|
+ * supported freq range.
|
|
|
|
+ */
|
|
|
|
+ policy_mgr_get_mac_freq_list(
|
|
|
|
+ freq_range,
|
|
|
|
+ i,
|
|
|
|
+ mac_freq_list, mac_mode_list, &mac_freq_num,
|
|
|
|
+ conn[0].freq, conn[0].mode,
|
|
|
|
+ conn[1].freq, conn[1].mode,
|
|
|
|
+ conn[2].freq, conn[2].mode,
|
|
|
|
+ ch_freq, mode);
|
|
|
|
+
|
|
|
|
+ /* Check the freq & mode list support or not in the
|
|
|
|
+ * MAC.
|
|
|
|
+ */
|
|
|
|
+ if (!policy_mgr_mac_freq_list_allow(
|
|
|
|
+ mac_freq_list, mac_mode_list, mac_freq_num))
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /* If the frequency/mode combination meet requirement in the
|
|
|
|
+ * hw mode, then the 4th new ch_freq/mode are allowed to start
|
|
|
|
+ * in this hw mode.
|
|
|
|
+ */
|
|
|
|
+ if (i == MAX_MAC) {
|
|
|
|
+ policy_mgr_debug("new freq %d mode %s is allowed in hw mode %s",
|
|
|
|
+ ch_freq, device_mode_to_string(mode),
|
|
|
|
+ policy_mgr_hw_mode_to_str(j));
|
|
|
|
+ return true;
|
|
|
|
+ }
|
|
}
|
|
}
|
|
|
|
+ policy_mgr_debug("the 4th new freq %d mode %s is not allowed in any hw mode",
|
|
|
|
+ ch_freq, device_mode_to_string(mode));
|
|
|
|
|
|
- return !policy_mgr_4_freq_always_on_same_mac(psoc, freq1, freq2, freq3,
|
|
|
|
- new_ch_freq);
|
|
|
|
|
|
+ return false;
|
|
}
|
|
}
|
|
#endif
|
|
#endif
|
|
|
|
|
|
@@ -3605,6 +3789,34 @@ policy_mgr_get_ml_sta_info(struct policy_mgr_psoc_priv_obj *pm_ctx,
|
|
qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
|
|
qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+void
|
|
|
|
+policy_mgr_get_ml_sta_info_psoc(struct wlan_objmgr_psoc *psoc,
|
|
|
|
+ uint8_t *num_ml_sta,
|
|
|
|
+ uint8_t *num_disabled_ml_sta,
|
|
|
|
+ uint8_t *ml_vdev_lst,
|
|
|
|
+ qdf_freq_t *ml_freq_lst,
|
|
|
|
+ uint8_t *num_non_ml,
|
|
|
|
+ uint8_t *non_ml_vdev_lst,
|
|
|
|
+ qdf_freq_t *non_ml_freq_lst)
|
|
|
|
+{
|
|
|
|
+ struct policy_mgr_psoc_priv_obj *pm_ctx;
|
|
|
|
+
|
|
|
|
+ pm_ctx = policy_mgr_get_context(psoc);
|
|
|
|
+ if (!pm_ctx) {
|
|
|
|
+ policy_mgr_err("Invalid pm_ctx");
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return policy_mgr_get_ml_sta_info(pm_ctx,
|
|
|
|
+ num_ml_sta,
|
|
|
|
+ num_disabled_ml_sta,
|
|
|
|
+ ml_vdev_lst,
|
|
|
|
+ ml_freq_lst,
|
|
|
|
+ num_non_ml,
|
|
|
|
+ non_ml_vdev_lst,
|
|
|
|
+ non_ml_freq_lst);
|
|
|
|
+}
|
|
|
|
+
|
|
uint32_t policy_mgr_get_disabled_ml_links_count(struct wlan_objmgr_psoc *psoc)
|
|
uint32_t policy_mgr_get_disabled_ml_links_count(struct wlan_objmgr_psoc *psoc)
|
|
{
|
|
{
|
|
uint32_t i, count = 0;
|
|
uint32_t i, count = 0;
|
|
@@ -7236,7 +7448,8 @@ bool policy_mgr_is_concurrency_allowed(struct wlan_objmgr_psoc *psoc,
|
|
*/
|
|
*/
|
|
if (!policy_mgr_allow_new_home_channel(psoc, mode, ch_freq,
|
|
if (!policy_mgr_allow_new_home_channel(psoc, mode, ch_freq,
|
|
num_connections,
|
|
num_connections,
|
|
- is_dfs_ch))
|
|
|
|
|
|
+ is_dfs_ch,
|
|
|
|
+ ext_flags))
|
|
return status;
|
|
return status;
|
|
|
|
|
|
/*
|
|
/*
|
|
@@ -9825,6 +10038,7 @@ bool policy_mgr_is_ap_ap_mcc_allow(struct wlan_objmgr_psoc *psoc,
|
|
uint32_t num_connections;
|
|
uint32_t num_connections;
|
|
bool is_dfs_ch = false;
|
|
bool is_dfs_ch = false;
|
|
struct ch_params ch_params;
|
|
struct ch_params ch_params;
|
|
|
|
+ union conc_ext_flag conc_ext_flags;
|
|
|
|
|
|
if (!psoc || !vdev || !pdev) {
|
|
if (!psoc || !vdev || !pdev) {
|
|
policy_mgr_debug("psoc or vdev or pdev is NULL");
|
|
policy_mgr_debug("psoc or vdev or pdev is NULL");
|
|
@@ -9846,11 +10060,13 @@ bool policy_mgr_is_ap_ap_mcc_allow(struct wlan_objmgr_psoc *psoc,
|
|
* 2 beaconing entities with STA in SCC.
|
|
* 2 beaconing entities with STA in SCC.
|
|
* 3 beaconing entities in SCC.
|
|
* 3 beaconing entities in SCC.
|
|
*/
|
|
*/
|
|
|
|
+ conc_ext_flags.value = policy_mgr_get_conc_ext_flags(vdev, false);
|
|
num_connections = policy_mgr_get_connection_count(psoc);
|
|
num_connections = policy_mgr_get_connection_count(psoc);
|
|
if (num_connections > 1 &&
|
|
if (num_connections > 1 &&
|
|
(mode == QDF_P2P_GO_MODE || mode == QDF_SAP_MODE) &&
|
|
(mode == QDF_P2P_GO_MODE || mode == QDF_SAP_MODE) &&
|
|
!policy_mgr_allow_new_home_channel(psoc, con_mode, ch_freq,
|
|
!policy_mgr_allow_new_home_channel(psoc, con_mode, ch_freq,
|
|
- num_connections, is_dfs_ch))
|
|
|
|
|
|
+ num_connections, is_dfs_ch,
|
|
|
|
+ conc_ext_flags.value))
|
|
return false;
|
|
return false;
|
|
|
|
|
|
policy_mgr_get_mcc_scc_switch(psoc, &mcc_to_scc_switch);
|
|
policy_mgr_get_mcc_scc_switch(psoc, &mcc_to_scc_switch);
|