qcacld-3.0: add concurrency checking for MLO STA

Update the concurrency policy for STA mode.
For an upcoming STA connection:
1. Disallow the 2nd STA connection if multiple STA connections are
   not allowed.
2. Allow the secondary MLO link when primary link is connected.
3. Disallow ML STA when ML STA/SAP is present.
4. Disallow the 3rd STA.
5. Allow for the other cases.

Change-Id: I70c41177b7a3a9aa9cbac0aaced08c6eafca2b6d
CRs-Fixed: 3012577
This commit is contained in:
Yu Wang
2021-10-12 16:33:42 +08:00
committed by Madan Koyyalamudi
parent a12b4ac946
commit cd3585de7d
8 changed files with 266 additions and 38 deletions

View File

@@ -717,6 +717,29 @@ static void if_mgr_get_vdev_id_from_bssid(struct wlan_objmgr_pdev *pdev,
wlan_objmgr_peer_release_ref(peer, WLAN_IF_MGR_ID);
}
#ifdef WLAN_FEATURE_11BE_MLO
/**
* if_mgr_get_conc_ext_flags() - get extended flags for concurrency check
* @vdev: pointer to vdev on which new connection is coming up
* @candidate_info: interface manager validate candidate data
*
* Return: extended flags for concurrency check
*/
static inline uint32_t
if_mgr_get_conc_ext_flags(struct wlan_objmgr_vdev *vdev,
struct validate_bss_data *candidate_info)
{
return policy_mgr_get_conc_ext_flags(vdev, candidate_info->is_mlo);
}
#else
static inline uint32_t
if_mgr_get_conc_ext_flags(struct wlan_objmgr_vdev *vdev,
struct validate_bss_data *candidate_info)
{
return 0;
}
#endif
QDF_STATUS if_mgr_validate_candidate(struct wlan_objmgr_vdev *vdev,
struct if_mgr_event_data *event_data)
{
@@ -728,7 +751,7 @@ QDF_STATUS if_mgr_validate_candidate(struct wlan_objmgr_vdev *vdev,
struct validate_bss_data *candidate_info =
&event_data->validate_bss_info;
uint32_t chan_freq = candidate_info->chan_freq;
uint32_t conc_freq = 0;
uint32_t conc_freq = 0, conc_ext_flags;
op_mode = wlan_vdev_mlme_get_opmode(vdev);
@@ -764,9 +787,12 @@ QDF_STATUS if_mgr_validate_candidate(struct wlan_objmgr_vdev *vdev,
* Valid multichannel concurrent sessions exempted
*/
mode = policy_mgr_convert_device_mode_to_qdf_type(op_mode);
/* If concurrency is not allowed select next bss */
conc_ext_flags = if_mgr_get_conc_ext_flags(vdev, candidate_info);
if (!policy_mgr_is_concurrency_allowed(psoc, mode, chan_freq,
HW_MODE_20_MHZ)) {
HW_MODE_20_MHZ,
conc_ext_flags)) {
ifmgr_info("Concurrency not allowed for this channel freq %d bssid "QDF_MAC_ADDR_FMT", selecting next",
chan_freq,
QDF_MAC_ADDR_REF(bssid_arg.peer_addr.bytes));

View File

@@ -1026,6 +1026,7 @@ bool policy_mgr_is_any_dfs_beaconing_session_present(
* @mode: new connection mode
* @ch_freq: channel frequency on which new connection is coming up
* @bw: Bandwidth requested by the connection (optional)
* @ext_flags: extended flags for concurrency check (union conc_ext_flag)
*
* When a new connection is about to come up check if current
* concurrency combination including the new connection is
@@ -1036,7 +1037,8 @@ bool policy_mgr_is_any_dfs_beaconing_session_present(
bool policy_mgr_allow_concurrency(struct wlan_objmgr_psoc *psoc,
enum policy_mgr_con_mode mode,
uint32_t ch_freq,
enum hw_mode_bandwidth bw);
enum hw_mode_bandwidth bw,
uint32_t ext_flags);
/**
* policy_mgr_nan_sap_pre_enable_conc_check() - Check if NAN+SAP SCC is
@@ -2361,6 +2363,7 @@ QDF_STATUS policy_mgr_get_pcl_for_vdev_id(struct wlan_objmgr_psoc *psoc,
* @weight: Pointer to the structure containing pcl, saved channel list and
* weighed channel list
* @mode: Policy manager connection mode
* @vdev: pointer to vdev on which new connection is coming up
*
* Provides the weightage for all valid channels. This compares the PCL list
* with the valid channel list. The channels present in the PCL get their
@@ -2371,7 +2374,7 @@ QDF_STATUS policy_mgr_get_pcl_for_vdev_id(struct wlan_objmgr_psoc *psoc,
*/
QDF_STATUS policy_mgr_get_valid_chan_weights(struct wlan_objmgr_psoc *psoc,
struct policy_mgr_pcl_chan_weights *weight,
enum policy_mgr_con_mode mode);
enum policy_mgr_con_mode mode, struct wlan_objmgr_vdev *vdev);
/**
* policy_mgr_set_hw_mode_on_channel_switch() - Set hw mode
@@ -3988,6 +3991,20 @@ void policy_mgr_get_hw_dbs_max_bw(struct wlan_objmgr_psoc *psoc,
*/
bool policy_mgr_is_mlo_sap_concurrency_allowed(struct wlan_objmgr_psoc *psoc,
bool is_new_vdev_mlo);
/**
* policy_mgr_get_conc_ext_flags() - get extended flags for concurrency check
* @vdev: pointer to vdev on which new connection is coming up
* @force_mlo: true means it's a MLO connection, false means uncertain
*
* In some scenario the flag WLAN_VDEV_FEXT2_MLO may not set for vdev when
* checking concurrency, then caller can set force_mlo accordingly to get
* proper extended flags.
*
* Return: extended flags for concurrency check
*/
uint32_t
policy_mgr_get_conc_ext_flags(struct wlan_objmgr_vdev *vdev, bool force_mlo);
#else
static inline bool policy_mgr_is_mlo_sap_concurrency_allowed(
@@ -3996,6 +4013,12 @@ static inline bool policy_mgr_is_mlo_sap_concurrency_allowed(
{
return true;
}
static inline uint32_t
policy_mgr_get_conc_ext_flags(struct wlan_objmgr_vdev *vdev, bool force_mlo)
{
return 0;
}
#endif
/**

View File

@@ -39,6 +39,10 @@
#include "wlan_mlme_api.h"
#include "wlan_mlme_main.h"
#include "wlan_mlme_vdev_mgr_interface.h"
#ifdef WLAN_FEATURE_11BE_MLO
#include "wlan_mlo_mgr_sta.h"
#endif
/* invalid channel id. */
#define INVALID_CHANNEL_ID 0
@@ -3357,14 +3361,11 @@ static inline bool policy_mgr_is_concurrency_allowed_4_port(
* policy_mgr_allow_multiple_sta_connections() - check whether multiple STA
* concurrency is allowed and F/W supported
* @psoc: Pointer to soc
* @second_sta_freq: 2nd STA channel frequency
* @first_sta_freq: 1st STA channel frequency
*
* Return: true if supports else false.
*/
static bool policy_mgr_allow_multiple_sta_connections(struct wlan_objmgr_psoc *psoc,
uint32_t second_sta_freq,
uint32_t first_sta_freq)
static bool
policy_mgr_allow_multiple_sta_connections(struct wlan_objmgr_psoc *psoc)
{
struct wmi_unified *wmi_handle;
@@ -3456,8 +3457,127 @@ static bool policy_mgr_is_6g_channel_allowed(
}
#ifdef WLAN_FEATURE_11BE_MLO
bool policy_mgr_is_mlo_sap_concurrency_allowed(struct wlan_objmgr_psoc *psoc,
bool is_new_vdev_mlo)
uint32_t
policy_mgr_get_conc_ext_flags(struct wlan_objmgr_vdev *vdev, bool force_mlo)
{
struct wlan_objmgr_vdev *assoc_vdev;
union conc_ext_flag conc_ext_flags;
conc_ext_flags.value = 0;
if (!vdev || wlan_vdev_mlme_get_opmode(vdev) != QDF_STA_MODE)
return conc_ext_flags.value;
if (!force_mlo && !wlan_vdev_mlme_is_mlo_vdev(vdev))
return conc_ext_flags.value;
conc_ext_flags.mlo = 1;
if (wlan_vdev_mlme_is_mlo_link_vdev(vdev)) {
assoc_vdev = ucfg_mlo_get_assoc_link_vdev(vdev);
if (assoc_vdev && ucfg_cm_is_vdev_active(assoc_vdev))
conc_ext_flags.mlo_link_assoc_connected = 1;
}
return conc_ext_flags.value;
}
/**
* policy_mgr_allow_sta_concurrency() - check whether STA concurrency is allowed
* @psoc: Pointer to soc
* @freq: frequency to be checked
* @ext_flags: extended flags for concurrency check
*
* Return: true if supports else false.
*/
static bool
policy_mgr_allow_sta_concurrency(struct wlan_objmgr_psoc *psoc,
qdf_freq_t freq,
uint32_t ext_flags)
{
uint32_t conn_index = 0;
struct policy_mgr_psoc_priv_obj *pm_ctx;
struct wlan_objmgr_vdev *vdev;
bool is_mlo, mlo_sap_present = false, mlo_sta_present = false;
uint8_t vdev_id, sta_cnt = 0;
enum policy_mgr_con_mode mode;
union conc_ext_flag conc_ext_flags;
pm_ctx = policy_mgr_get_context(psoc);
if (!pm_ctx) {
policy_mgr_err("Invalid Context");
return false;
}
conc_ext_flags.value = ext_flags;
qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
for (conn_index = 0; conn_index < MAX_NUMBER_OF_CONC_CONNECTIONS;
conn_index++) {
mode = pm_conc_connection_list[conn_index].mode;
if ((mode != PM_STA_MODE && mode != PM_SAP_MODE) ||
!pm_conc_connection_list[conn_index].in_use)
continue;
vdev_id = pm_conc_connection_list[conn_index].vdev_id;
vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id,
WLAN_POLICY_MGR_ID);
if (!vdev)
continue;
is_mlo = wlan_vdev_mlme_is_mlo_vdev(vdev);
if (mode == PM_SAP_MODE) {
if (is_mlo)
mlo_sap_present = true;
goto next;
}
/* Skip the link vdev for MLO STA */
if (wlan_vdev_mlme_is_mlo_link_vdev(vdev))
goto next;
sta_cnt++;
if (!is_mlo)
goto next;
mlo_sta_present = true;
next:
wlan_objmgr_vdev_release_ref(vdev, WLAN_POLICY_MGR_ID);
}
qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
/* Reject if multiple STA connections are not allowed */
if (sta_cnt &&
!policy_mgr_allow_multiple_sta_connections(psoc)) {
policy_mgr_rl_debug("Disallow Multiple STA connections");
return false;
}
if (mlo_sta_present && conc_ext_flags.mlo_link_assoc_connected) {
policy_mgr_rl_debug("Allow secondary MLO link");
return true;
}
if (conc_ext_flags.mlo && (mlo_sta_present || mlo_sap_present)) {
policy_mgr_rl_debug("Disallow ML STA when ML STA/SAP is present");
return false;
}
/*
* Reject a 3rd STA.
* Treat a MLO STA(including the primary and secondary link vdevs)
* as 1 STA here.
*/
if (sta_cnt >= 2) {
policy_mgr_rl_debug("Disallow 3rd STA");
return false;
}
return true;
}
bool
policy_mgr_is_mlo_sap_concurrency_allowed(struct wlan_objmgr_psoc *psoc,
bool is_new_vdev_mlo)
{
struct policy_mgr_psoc_priv_obj *pm_ctx;
uint32_t conn_index;
@@ -3505,6 +3625,31 @@ bool policy_mgr_is_mlo_sap_concurrency_allowed(struct wlan_objmgr_psoc *psoc,
return ret;
}
#else
static bool
policy_mgr_allow_sta_concurrency(struct wlan_objmgr_psoc *psoc,
qdf_freq_t freq,
uint32_t ext_flags)
{
uint32_t count;
count = policy_mgr_mode_specific_connection_count(psoc, PM_STA_MODE,
NULL);
if (!count)
return true;
if (count >= 2) {
policy_mgr_rl_debug("Disallow 3rd STA");
return false;
}
if (!policy_mgr_allow_multiple_sta_connections(psoc)) {
policy_mgr_rl_debug("Multiple STA connections is not allowed");
return false;
}
return true;
}
#endif
#ifdef WLAN_FEATURE_P2P_P2P_STA
@@ -3583,7 +3728,8 @@ static bool policy_mgr_is_third_conn_sta_p2p_p2p_valid(
bool policy_mgr_is_concurrency_allowed(struct wlan_objmgr_psoc *psoc,
enum policy_mgr_con_mode mode,
uint32_t ch_freq,
enum hw_mode_bandwidth bw)
enum hw_mode_bandwidth bw,
uint32_t ext_flags)
{
uint32_t num_connections = 0, count = 0, index = 0;
bool status = false, match = false;
@@ -3591,7 +3737,6 @@ bool policy_mgr_is_concurrency_allowed(struct wlan_objmgr_psoc *psoc,
struct policy_mgr_psoc_priv_obj *pm_ctx;
bool sta_sap_scc_on_dfs_chan;
bool go_force_scc;
uint32_t sta_freq;
enum channel_state chan_state;
bool is_dfs_ch = false;
@@ -3677,19 +3822,9 @@ 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);
if (mode == PM_STA_MODE && count) {
if (count >= 2) {
policy_mgr_rl_debug("3rd STA isn't permitted");
return status;
}
sta_freq = pm_conc_connection_list[list[0]].freq;
if (!policy_mgr_allow_multiple_sta_connections(psoc, ch_freq,
sta_freq))
return status;
}
if (mode == PM_STA_MODE &&
!policy_mgr_allow_sta_concurrency(psoc, ch_freq, ext_flags))
return status;
if (!policy_mgr_allow_sap_go_concurrency(psoc, mode, ch_freq,
WLAN_INVALID_VDEV_ID)) {
@@ -3739,7 +3874,8 @@ bool policy_mgr_is_concurrency_allowed(struct wlan_objmgr_psoc *psoc,
bool policy_mgr_allow_concurrency(struct wlan_objmgr_psoc *psoc,
enum policy_mgr_con_mode mode,
uint32_t ch_freq,
enum hw_mode_bandwidth bw)
enum hw_mode_bandwidth bw,
uint32_t ext_flags)
{
QDF_STATUS status;
struct policy_mgr_pcl_list pcl;
@@ -3754,7 +3890,8 @@ bool policy_mgr_allow_concurrency(struct wlan_objmgr_psoc *psoc,
return false;
}
allowed = policy_mgr_is_concurrency_allowed(psoc, mode, ch_freq, bw);
allowed = policy_mgr_is_concurrency_allowed(psoc, mode, ch_freq,
bw, ext_flags);
/* Fourth connection concurrency check */
if (allowed && policy_mgr_get_connection_count(psoc) == 3)
@@ -3777,8 +3914,9 @@ policy_mgr_allow_concurrency_csa(struct wlan_objmgr_psoc *psoc,
info[MAX_NUMBER_OF_CONC_CONNECTIONS];
uint8_t num_cxn_del = 0;
struct policy_mgr_psoc_priv_obj *pm_ctx;
uint32_t old_ch_freq;
uint32_t old_ch_freq, conc_ext_flags;
QDF_STATUS status;
struct wlan_objmgr_vdev *vdev;
pm_ctx = policy_mgr_get_context(psoc);
if (!pm_ctx) {
@@ -3824,8 +3962,14 @@ policy_mgr_allow_concurrency_csa(struct wlan_objmgr_psoc *psoc,
policy_mgr_store_and_del_conn_info_by_vdev_id(
psoc, vdev_id, info, &num_cxn_del);
vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id,
WLAN_POLICY_MGR_ID);
conc_ext_flags = policy_mgr_get_conc_ext_flags(vdev, false);
allow = policy_mgr_allow_concurrency(psoc, mode, ch_freq,
HW_MODE_20_MHZ);
HW_MODE_20_MHZ, conc_ext_flags);
if (vdev)
wlan_objmgr_vdev_release_ref(vdev, WLAN_POLICY_MGR_ID);
/* Restore the connection entry */
if (num_cxn_del > 0)
policy_mgr_restore_deleted_conn_info(psoc, info, num_cxn_del);
@@ -3964,6 +4108,8 @@ bool policy_mgr_check_for_session_conc(struct wlan_objmgr_psoc *psoc,
enum policy_mgr_con_mode mode;
bool ret;
struct policy_mgr_psoc_priv_obj *pm_ctx;
struct wlan_objmgr_vdev *vdev;
uint32_t conc_ext_flags;
pm_ctx = policy_mgr_get_context(psoc);
if (!pm_ctx) {
@@ -3986,8 +4132,16 @@ bool policy_mgr_check_for_session_conc(struct wlan_objmgr_psoc *psoc,
return false;
}
vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, session_id,
WLAN_POLICY_MGR_ID);
/* Take care of 160MHz and 80+80Mhz later */
ret = policy_mgr_allow_concurrency(psoc, mode, ch_freq, HW_MODE_20_MHZ);
conc_ext_flags = policy_mgr_get_conc_ext_flags(vdev, false);
ret = policy_mgr_allow_concurrency(psoc, mode, ch_freq, HW_MODE_20_MHZ,
conc_ext_flags);
if (vdev)
wlan_objmgr_vdev_release_ref(vdev, WLAN_POLICY_MGR_ID);
if (false == ret) {
policy_mgr_err("Connection failed due to conc check fail");
return 0;

View File

@@ -389,6 +389,25 @@ struct policy_mgr_mac_ss_bw_info {
uint32_t mac_band_cap;
};
#ifdef WLAN_FEATURE_11BE_MLO
/**
* union conc_ext_flag - extended flags for concurrency check
*
* @mlo: the new connection is MLO
* @mlo_link_assoc_connected: the new connection is secondary MLO link and
* the corresponding assoc link is connected
* @value: uint32 value for extended flags
*/
union conc_ext_flag {
struct {
uint32_t mlo: 1;
uint32_t mlo_link_assoc_connected: 1;
};
uint32_t value;
};
#endif
struct policy_mgr_psoc_priv_obj *policy_mgr_get_context(
struct wlan_objmgr_psoc *psoc);
QDF_STATUS policy_mgr_get_updated_scan_config(
@@ -792,6 +811,7 @@ QDF_STATUS policy_mgr_nss_update(struct wlan_objmgr_psoc *psoc,
* @mode: new connection mode
* @ch_freq: channel frequency on which new connection is coming up
* @bw: Bandwidth requested by the connection (optional)
* @ext_flags: extended flags for concurrency check (union conc_ext_flag)
*
* When a new connection is about to come up check if current
* concurrency combination including the new connection is
@@ -803,5 +823,6 @@ QDF_STATUS policy_mgr_nss_update(struct wlan_objmgr_psoc *psoc,
bool policy_mgr_is_concurrency_allowed(struct wlan_objmgr_psoc *psoc,
enum policy_mgr_con_mode mode,
uint32_t ch_freq,
enum hw_mode_bandwidth bw);
enum hw_mode_bandwidth bw,
uint32_t ext_flags);
#endif

View File

@@ -2379,7 +2379,7 @@ policy_mgr_get_sap_mandatory_channel(struct wlan_objmgr_psoc *psoc,
QDF_STATUS policy_mgr_get_valid_chan_weights(struct wlan_objmgr_psoc *psoc,
struct policy_mgr_pcl_chan_weights *weight,
enum policy_mgr_con_mode mode)
enum policy_mgr_con_mode mode, struct wlan_objmgr_vdev *vdev)
{
uint32_t i, j;
struct policy_mgr_conc_connection_info
@@ -2418,7 +2418,8 @@ QDF_STATUS policy_mgr_get_valid_chan_weights(struct wlan_objmgr_psoc *psoc,
for (i = 0; i < weight->saved_num_chan; i++) {
if (policy_mgr_is_concurrency_allowed
(psoc, mode, weight->saved_chan_list[i],
HW_MODE_20_MHZ)) {
HW_MODE_20_MHZ,
policy_mgr_get_conc_ext_flags(vdev, false))) {
weight->weighed_valid_list[i] =
WEIGHT_OF_NON_PCL_CHANNELS;
}

View File

@@ -1114,7 +1114,8 @@ bool nan_is_enable_allowed(struct wlan_objmgr_psoc *psoc, uint32_t nan_ch_freq)
return (NAN_DISC_DISABLED == nan_get_discovery_state(psoc) &&
ucfg_is_nan_conc_control_supported(psoc) &&
policy_mgr_allow_concurrency(psoc, PM_NAN_DISC_MODE,
nan_ch_freq, HW_MODE_20_MHZ));
nan_ch_freq, HW_MODE_20_MHZ,
0));
}
bool nan_is_disc_active(struct wlan_objmgr_psoc *psoc)

View File

@@ -1069,7 +1069,7 @@ bool ucfg_nan_is_sta_ndp_concurrency_allowed(struct wlan_objmgr_psoc *psoc,
{
uint8_t vdev_id_list[MAX_NUMBER_OF_CONC_CONNECTIONS];
uint32_t freq_list[MAX_NUMBER_OF_CONC_CONNECTIONS];
uint32_t ndi_cnt, sta_cnt, id;
uint32_t ndi_cnt, sta_cnt, id, conc_ext_flags;
sta_cnt = policy_mgr_mode_specific_connection_count(psoc,
PM_STA_MODE, NULL);
@@ -1113,9 +1113,11 @@ bool ucfg_nan_is_sta_ndp_concurrency_allowed(struct wlan_objmgr_psoc *psoc,
if (!ucfg_nan_is_sta_nan_ndi_4_port_allowed(psoc))
return false;
conc_ext_flags = policy_mgr_get_conc_ext_flags(vdev, false);
/* The final freq would be provided by FW, it is not known now */
return policy_mgr_allow_concurrency(psoc, PM_NDI_MODE, 0,
HW_MODE_20_MHZ);
HW_MODE_20_MHZ, conc_ext_flags);
}
bool

View File

@@ -111,7 +111,7 @@ wlan_cm_roam_send_set_vdev_pcl(struct wlan_objmgr_psoc *psoc,
status = policy_mgr_get_valid_chan_weights(
psoc, (struct policy_mgr_pcl_chan_weights *)weights,
PM_STA_MODE);
PM_STA_MODE, vdev);
qdf_mem_free(freq_list);