qcacld-3.0: Reject 5Ghz STA connection if SBS ML STA is connected

As in SBS ML STA, both links are on 5Ghz, reject the 5Ghz
non-ML STA connection, to avoid enabling same band roaming on
both STA.

Also do not allow the SBS ML STA, if a non-ML STA is present
on 5Ghz.

Allow it only if primary interface is set OR dual STA roaming
is disabled.

Change-Id: I20a23ed3b4d87c9acac5417a6f2d484fc80f47d6
CRs-Fixed: 3103246
This commit is contained in:
Abhishek Singh
2022-01-05 10:30:42 +05:30
committed by Madan Koyyalamudi
parent e8f7384029
commit 90fd31882d
3 changed files with 109 additions and 88 deletions

View File

@@ -1,6 +1,6 @@
/*
* Copyright (c) 2020-2021, The Linux Foundation. All rights reserved.
* Copyright (c) 2021 Qualcomm Innovation Center, Inc. All rights reserved.
* Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -32,7 +32,7 @@
#include <wlan_cm_api.h>
#include <wlan_mlo_mgr_public_structs.h>
#include <wlan_mlo_mgr_cmn.h>
#include <wlan_mlme_main.h>
#include <wlan_cm_roam_api.h>
QDF_STATUS if_mgr_connect_start(struct wlan_objmgr_vdev *vdev,
struct if_mgr_event_data *event_data)
@@ -155,24 +155,26 @@ if_mgr_mlo_get_affected_links_for_sbs(struct wlan_objmgr_psoc *psoc,
uint8_t *mlo_idx, qdf_freq_t freq)
{
uint8_t i = 0;
bool same_band_sta_allowed;
/*
* STA freq: STA ML combo: SBS Action
* STA freq: ML STA combo: SBS Action
* ---------------------------------------------------
* 2Ghz 2Ghz+5/6Ghz Disable 2Ghz(Same MAC)
* 5Ghz 2Ghz+5/6Ghz Disable 2.4Ghz if 5Ghz lead to SBS
* (SBS, same MAC), else disable 5/6Ghz
* 5Ghz 2Ghz+5/6Ghz Disable 2.4Ghz if 5Ghz lead to SBS
* (SBS, same MAC) and same band STA
* allowed, else disable 5/6Ghz
* (NON SBS, same MAC)
* 5Ghz(lower) 5Ghz+6Ghz Disable 5Ghz (NON SBS, same MAC)
* 5Ghz(higher) 5Ghz+6Ghz Disable 6Ghz (NON SBS, Same MAC)
* 2Ghz 5Ghz+6Ghz Disable Any
*/
/* If legacy STA is 2.4Ghz disable 2.4Ghz if present OR disable any */
/* If non-ML STA is 2.4Ghz disable 2.4Ghz if present OR disable any */
if (wlan_reg_is_24ghz_ch_freq(freq)) {
while (i < num_mlo) {
if (wlan_reg_is_24ghz_ch_freq(freq_list[mlo_idx[i]])) {
/* Affected MLO link on 2.4Ghz */
/* Affected ML STA link on 2.4Ghz */
mlo_vdev_lst[0] = vdev_id_list[mlo_idx[i]];
return 1;
}
@@ -184,7 +186,23 @@ if_mgr_mlo_get_affected_links_for_sbs(struct wlan_objmgr_psoc *psoc,
return i;
}
/* This mean legasy STA is 5Ghz */
/* This mean non-ML STA is 5Ghz */
/* check if ML STA is DBS */
i = 0;
while (i < num_mlo &&
!wlan_reg_is_24ghz_ch_freq(freq_list[mlo_idx[i]]))
i++;
same_band_sta_allowed = wlan_cm_same_band_sta_allowed(psoc);
/*
* if ML STA is DBS ie 2.4Ghz link present and if same_band_sta_allowed
* is false, disable 5/6Ghz link to make sure we dont have all link
* on 5Ghz
*/
if (i < num_mlo && !same_band_sta_allowed)
goto check_dbs_mlo;
/* check if any link lead to SBS, so that we can disable the other*/
i = 0;
@@ -194,14 +212,14 @@ if_mgr_mlo_get_affected_links_for_sbs(struct wlan_objmgr_psoc *psoc,
/*
* if i < num_mlo then i is the SBS link, in this case disable the other
* non SBS link, this mean MLO is 5+6 or 2+5/6.
* non SBS link, this mean ML STA is 5+6 or 2+5/6.
*/
if (i < num_mlo) {
i = 0;
while (i < num_mlo) {
if (!policy_mgr_are_sbs_chan(psoc, freq,
freq_list[mlo_idx[i]])) {
/* Affected non SBS MLO link */
/* Affected non SBS ML STA link */
mlo_vdev_lst[0] = vdev_id_list[mlo_idx[i]];
return 1;
}
@@ -213,14 +231,15 @@ if_mgr_mlo_get_affected_links_for_sbs(struct wlan_objmgr_psoc *psoc,
return i;
}
check_dbs_mlo:
/*
* None of the link can lead to SBS, i.e. its 2+ 5/6 MLO in this case
* disabel 5Ghz link.
* None of the link can lead to SBS, i.e. its 2+ 5/6 ML STA in this case
* disable 5Ghz link.
*/
i = 0;
while (i < num_mlo) {
if (!wlan_reg_is_24ghz_ch_freq(freq_list[mlo_idx[i]])) {
/* Affected 5/6Ghz MLO link */
/* Affected 5/6Ghz ML STA link */
mlo_vdev_lst[0] = vdev_id_list[mlo_idx[i]];
return 1;
}

View File

@@ -1,6 +1,6 @@
/*
* Copyright (c) 2020-2021, The Linux Foundation. All rights reserved.
* Copyright (c) 2021 Qualcomm Innovation Center, Inc. All rights reserved.
* Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -812,23 +812,6 @@ void wlan_cm_roam_activate_pcl_per_vdev(struct wlan_objmgr_psoc *psoc,
bool wlan_cm_roam_is_pcl_per_vdev_active(struct wlan_objmgr_psoc *psoc,
uint8_t vdev_id);
/**
* wlan_cm_dual_sta_is_freq_allowed() - This API is used to check if the
* provided frequency is allowed for the 2nd STA vdev for connection.
* @psoc: Pointer to PSOC object
* @freq: Frequency in the given frequency list for the STA that is about to
* connect
* @opmode: Operational mode
*
* This API will be called while filling scan filter channels during connection.
*
* Return: True if this channel is allowed for connection when dual sta roaming
* is enabled
*/
bool
wlan_cm_dual_sta_is_freq_allowed(struct wlan_objmgr_psoc *psoc, uint32_t freq,
enum QDF_OPMODE opmode);
/**
* wlan_cm_dual_sta_roam_update_connect_channels() - Fill the allowed channels
* for connection of the 2nd STA based on the 1st STA connected band if dual
@@ -1150,13 +1133,6 @@ bool wlan_cm_roam_is_pcl_per_vdev_active(struct wlan_objmgr_psoc *psoc,
return false;
}
static inline bool
wlan_cm_dual_sta_is_freq_allowed(struct wlan_objmgr_psoc *psoc, uint32_t freq,
enum QDF_OPMODE opmode)
{
return true;
}
static inline void
wlan_cm_dual_sta_roam_update_connect_channels(struct wlan_objmgr_psoc *psoc,
struct scan_filter *filter)
@@ -1572,4 +1548,14 @@ wlan_cm_fw_to_host_phymode(WMI_HOST_WLAN_PHY_MODE phymode);
QDF_STATUS
wlan_cm_sta_mlme_vdev_roam_notify(struct vdev_mlme_obj *vdev_mlme,
uint16_t data_len, void *data);
/**
* wlan_cm_same_band_sta_allowed() - check if same band STA +STA is allowed
*
* @psoc: psoc ptr
*
* Return: true if same band STA+STA is allowed
*/
bool wlan_cm_same_band_sta_allowed(struct wlan_objmgr_psoc *psoc);
#endif /* WLAN_CM_ROAM_API_H__ */

View File

@@ -1,6 +1,6 @@
/*
* Copyright (c) 2020-2021, The Linux Foundation. All rights reserved.
* Copyright (c) 2021 Qualcomm Innovation Center, Inc. All rights reserved.
* Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -294,6 +294,25 @@ QDF_STATUS wlan_cm_roam_stop_req(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id,
return cm_roam_stop_req(psoc, vdev_id, reason);
}
bool wlan_cm_same_band_sta_allowed(struct wlan_objmgr_psoc *psoc)
{
struct wlan_mlme_psoc_ext_obj *mlme_obj;
struct dual_sta_policy *dual_sta_policy;
if (!wlan_mlme_get_dual_sta_roaming_enabled(psoc))
return true;
mlme_obj = mlme_get_psoc_ext_obj(psoc);
if (!mlme_obj)
return true;
dual_sta_policy = &mlme_obj->cfg.gen.dual_sta_policy;
if (dual_sta_policy->primary_vdev_id != WLAN_UMAC_VDEV_ID_MAX)
return true;
return false;
}
#ifdef WLAN_FEATURE_ROAM_OFFLOAD
QDF_STATUS
wlan_cm_fw_roam_abort_req(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id)
@@ -414,62 +433,34 @@ bool wlan_cm_roam_is_pcl_per_vdev_active(struct wlan_objmgr_psoc *psoc,
return mlme_priv->cm_roam.pcl_vdev_cmd_active;
}
bool
/**
* wlan_cm_dual_sta_is_freq_allowed() - This API is used to check if the
* provided frequency is allowed for the 2nd STA vdev for connection.
* @psoc: Pointer to PSOC object
* @freq: Frequency in the given frequency list for the STA that is about to
* connect
* @connected_sta_freq: 1st connected sta freq
* @opmode: Operational mode
*
* Make sure to validate the STA+STA condition before calling this
*
* Return: True if this channel is allowed for connection when dual sta roaming
* is enabled
*/
static bool
wlan_cm_dual_sta_is_freq_allowed(struct wlan_objmgr_psoc *psoc,
uint32_t freq,
uint32_t freq, qdf_freq_t connected_sta_freq,
enum QDF_OPMODE opmode)
{
uint32_t op_ch_freq_list[MAX_NUMBER_OF_CONC_CONNECTIONS];
uint8_t vdev_id_list[MAX_NUMBER_OF_CONC_CONNECTIONS];
enum reg_wifi_band band;
uint32_t count, connected_sta_freq;
struct wlan_mlme_psoc_ext_obj *mlme_obj;
struct dual_sta_policy *dual_sta_policy;
mlme_obj = mlme_get_psoc_ext_obj(psoc);
if (!mlme_obj)
return QDF_STATUS_E_FAILURE;
/*
* Check if primary iface is configured. If yes,
* then allow further STA connection to all
* available bands/channels irrespective of first
* STA connection band, which allow driver to
* connect with the best available AP present in
* environment, so that user can switch to second
* connection and mark it as primary.
*/
dual_sta_policy = &mlme_obj->cfg.gen.dual_sta_policy;
if (dual_sta_policy->primary_vdev_id != WLAN_UMAC_VDEV_ID_MAX) {
mlme_debug("primary iface is configured, vdev_id: %d",
dual_sta_policy->primary_vdev_id);
return true;
}
/*
* Check if already there is 1 STA connected. If this API is
* called for 2nd STA and if dual sta roaming is enabled, then
* don't allow the intra band frequencies of the 1st sta for
* connection on 2nd STA.
*/
count = policy_mgr_get_mode_specific_conn_info(psoc, op_ch_freq_list,
vdev_id_list,
PM_STA_MODE);
if (!count || !wlan_mlme_get_dual_sta_roaming_enabled(psoc) ||
opmode != QDF_STA_MODE)
if (opmode != QDF_STA_MODE || !connected_sta_freq)
return true;
/*
* For MLO STA scenario, allow further STA connections to all available
* bands/channels irrespective of existing STA connection band.
*/
if (policy_mgr_is_mlo_sta_present(psoc))
return true;
connected_sta_freq = op_ch_freq_list[0];
band = wlan_reg_freq_to_band(connected_sta_freq);
/* Reject if both are 2.4Ghz or both are not 2.4Ghz (5Ghz or 6Ghz) */
if ((band == REG_BAND_2G && WLAN_REG_IS_24GHZ_CH_FREQ(freq)) ||
(band == REG_BAND_5G && !WLAN_REG_IS_24GHZ_CH_FREQ(freq)))
(band != REG_BAND_2G && !WLAN_REG_IS_24GHZ_CH_FREQ(freq)))
return false;
return true;
@@ -489,10 +480,14 @@ wlan_cm_dual_sta_roam_update_connect_channels(struct wlan_objmgr_psoc *psoc,
char *chan_buff;
uint32_t len = 0;
uint32_t sta_count;
bool mlo_sta_present, sbs_mlo_sta_present = false;
qdf_freq_t op_ch_freq_list[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0};
uint8_t vdev_id_list[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0};
filter->num_of_channels = 0;
sta_count = policy_mgr_mode_specific_connection_count(psoc,
PM_STA_MODE, NULL);
sta_count = policy_mgr_get_mode_specific_conn_info(psoc, op_ch_freq_list,
vdev_id_list,
PM_STA_MODE);
/* No need to fill freq list, if no other STA is in conencted state */
if (!sta_count)
@@ -523,6 +518,26 @@ wlan_cm_dual_sta_roam_update_connect_channels(struct wlan_objmgr_psoc *psoc,
if (dual_sta_policy->primary_vdev_id != WLAN_UMAC_VDEV_ID_MAX)
return;
mlo_sta_present = policy_mgr_is_mlo_sta_present(psoc);
/* check for SBS mlo if MLO sta is present and sta cnt > 1 */
if (mlo_sta_present && sta_count > 1)
sbs_mlo_sta_present =
policy_mgr_is_mlo_in_mode_sbs(psoc, PM_STA_MODE,
NULL, NULL);
mlme_debug("mlo_sta_present %d sbs_mlo_sta_present %d",
mlo_sta_present, sbs_mlo_sta_present);
/*
* For ML STA (non-SBS) scenario, allow further STA connections to
* all available bands/channels irrespective of existing STA
* connection band.
* But if ML STA is SBS (both link 5Ghz), allow only 2.4Ghz STA
* connection
*/
if (mlo_sta_present && !sbs_mlo_sta_present)
return;
/*
* Get Reg domain valid channels and update to the scan filter
* if already 1st sta is in connected state. Don't allow channels
@@ -544,6 +559,7 @@ wlan_cm_dual_sta_roam_update_connect_channels(struct wlan_objmgr_psoc *psoc,
for (i = 0; i < num_channels; i++) {
is_ch_allowed =
wlan_cm_dual_sta_is_freq_allowed(psoc, channel_list[i],
op_ch_freq_list[0],
QDF_STA_MODE);
if (!is_ch_allowed)
continue;