qcacmn: Move scoring logic to connection manager

Move bss scoring logic to connection manager.

Change-Id: If8484ec2fa8b3e2d153ae4a6caed76f3354b8965
CRs-Fixed: 2707106
This commit is contained in:
gaurank kathpalia
2020-05-29 03:28:42 +05:30
committed by nshrivas
parent e85e67ce9b
commit 506f49a0ff
18 changed files with 2612 additions and 1262 deletions

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,175 @@
/*
* Copyright (c) 2020, The Linux Foundation. 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
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/**
* DOC: Define bss scoring structures and APIs
*/
#ifndef _WLAN_CM_BSS_SCORE_H
#define _WLAN_CM_BSS_SCORE_H
#include <wlan_scan_utils_api.h>
#include "wlan_reg_services_api.h"
/**
* struct weight_cfg - weight params to calculate best candidate
* @rssi_weightage: RSSI weightage
* @ht_caps_weightage: HT caps weightage
* @vht_caps_weightage: VHT caps weightage
* @he_caps_weightage: HE caps weightage
* @chan_width_weightage: Channel width weightage
* @chan_band_weightage: Channel band weightage
* @nss_weightage: NSS weightage
* @beamforming_cap_weightage: Beamforming caps weightage
* @pcl_weightage: PCL weightage
* @channel_congestion_weightage: channel congestion weightage
* @oce_wan_weightage: OCE WAN metrics weightage
* @oce_ap_tx_pwr_weightage: OCE AP tx power weigtage
* @oce_subnet_id_weightage: OCE subnet id weigtage
*/
struct weight_cfg {
uint8_t rssi_weightage;
uint8_t ht_caps_weightage;
uint8_t vht_caps_weightage;
uint8_t he_caps_weightage;
uint8_t chan_width_weightage;
uint8_t chan_band_weightage;
uint8_t nss_weightage;
uint8_t beamforming_cap_weightage;
uint8_t pcl_weightage;
uint8_t channel_congestion_weightage;
uint8_t oce_wan_weightage;
uint8_t oce_ap_tx_pwr_weightage;
uint8_t oce_subnet_id_weightage;
};
/**
* struct rssi_config_score - rssi related params for scoring logic
* @best_rssi_threshold: RSSI weightage
* @good_rssi_threshold: HT caps weightage
* @bad_rssi_threshold: VHT caps weightage
* @good_rssi_pcnt: HE caps weightage
* @bad_rssi_pcnt: Channel width weightage
* @good_rssi_bucket_size: Channel band weightage
* @bad_rssi_bucket_size: NSS weightage
* @rssi_pref_5g_rssi_thresh: Beamforming caps weightage
*/
struct rssi_config_score {
uint32_t best_rssi_threshold;
uint32_t good_rssi_threshold;
uint32_t bad_rssi_threshold;
uint32_t good_rssi_pcnt;
uint32_t bad_rssi_pcnt;
uint32_t good_rssi_bucket_size;
uint32_t bad_rssi_bucket_size;
uint32_t rssi_pref_5g_rssi_thresh;
};
/**
* struct per_slot_score - define % score for differents slots for a
* scoring param.
* num_slot: number of slots in which the param will be divided.
* Max 15. index 0 is used for 'not_present. Num_slot will
* equally divide 100. e.g, if num_slot = 4 slot 0 = 0-25%, slot
* 1 = 26-50% slot 2 = 51-75%, slot 3 = 76-100%
* score_pcnt3_to_0: Conatins score percentage for slot 0-3
* BITS 0-7 :- the scoring pcnt when not present
* BITS 8-15 :- SLOT_1
* BITS 16-23 :- SLOT_2
* BITS 24-31 :- SLOT_3
* score_pcnt7_to_4: Conatins score percentage for slot 4-7
* BITS 0-7 :- SLOT_4
* BITS 8-15 :- SLOT_5
* BITS 16-23 :- SLOT_6
* BITS 24-31 :- SLOT_7
* score_pcnt11_to_8: Conatins score percentage for slot 8-11
* BITS 0-7 :- SLOT_8
* BITS 8-15 :- SLOT_9
* BITS 16-23 :- SLOT_10
* BITS 24-31 :- SLOT_11
* score_pcnt15_to_12: Conatins score percentage for slot 12-15
* BITS 0-7 :- SLOT_12
* BITS 8-15 :- SLOT_13
* BITS 16-23 :- SLOT_14
* BITS 24-31 :- SLOT_15
*/
struct per_slot_score {
uint32_t num_slot;
uint32_t score_pcnt3_to_0;
uint32_t score_pcnt7_to_4;
uint32_t score_pcnt11_to_8;
uint32_t score_pcnt15_to_12;
};
/**
* struct scoring_cfg - Scoring related configuration
* @weight_cfg: weigtage config for config
* @rssi_score: Rssi related config for scoring config
* @esp_qbss_scoring: esp and qbss related scoring config
* @oce_wan_scoring: oce related scoring config
* @bandwidth_weight_per_index: BW wight per index
* @nss_weight_per_index: nss weight per index
* @band_weight_per_index: band weight per index
* @is_bssid_hint_priority: True if bssid_hint is given priority
*/
struct scoring_cfg {
struct weight_cfg weight_config;
struct rssi_config_score rssi_score;
struct per_slot_score esp_qbss_scoring;
struct per_slot_score oce_wan_scoring;
uint32_t bandwidth_weight_per_index;
uint32_t nss_weight_per_index;
uint32_t band_weight_per_index;
bool is_bssid_hint_priority;
};
/**
* struct pcl_freq_weight_list - pcl freq weight info
* @num_of_pcl_channels: number of pcl channel
* @pcl_freq_list: pcl freq list
* @pcl_weight_list: pcl freq weight list
*/
struct pcl_freq_weight_list {
uint32_t num_of_pcl_channels;
uint32_t pcl_freq_list[NUM_CHANNELS];
uint8_t pcl_weight_list[NUM_CHANNELS];
};
/**
* wlan_cm_calculate_bss_score() - calculate bss score for the scan list
* @psoc: pointer to psoc object
* @pcl_list: pcl list for scoring
* @scan_list: scan list, contains the input list and after the
* func it will have sorted list
* @bssid_hint: bssid hint
*
* Return: void
*/
void wlan_cm_calculate_bss_score(struct wlan_objmgr_psoc *psoc,
struct pcl_freq_weight_list *pcl_lst,
qdf_list_t *scan_list,
struct qdf_mac_addr *bssid_hint);
/**
* wlan_cm_init_score_config() - Init score INI and config
* @psoc: pointer to psoc object
* @score_cfg: score config
*
* Return: void
*/
void wlan_cm_init_score_config(struct wlan_objmgr_psoc *psoc,
struct scoring_cfg *score_cfg);
#endif

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2019 The Linux Foundation. All rights reserved.
* Copyright (c) 2019-2020 The Linux Foundation. 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
@@ -23,6 +23,7 @@
#include <wlan_ext_mlme_obj_types.h>
#include <wlan_vdev_mgr_tgt_if_rx_defs.h>
#include <qdf_timer.h>
#include <wlan_cm_bss_score_param.h>
/* Max RNR size given max vaps are 16 */
#define MAX_RNR_SIZE 256
@@ -39,13 +40,39 @@ struct wlan_6ghz_rnr_global_cache {
uint16_t rnr_size;
};
/**
* struct psoc_phy_config - psoc phy caps
* @vdev_nss_24g: Number of NSS the device support in 2.4Ghz
* @vdev_nss_5g: Number of NSS the device support in 5Ghz
* @ht_cap: If dev is configured as HT capable
* @vht_cap:If dev is configured as VHT capable
* @he_cap: If dev is configured as HE capable
* @vht_24G_cap:If dev is configured as VHT capable for 2.4Ghz
* @beamformee_cap:If dev is configured as BF capable
* @bw_above_20_5ghz: BW greater than 20Mhz supprted for 5Ghz
* @bw_above_20_24ghz: BW greater than 20Mhz supprted for 2.4Ghz
*/
struct psoc_phy_config {
uint8_t vdev_nss_24g;
uint8_t vdev_nss_5g;
uint32_t ht_cap:1,
vht_cap:1,
he_cap:1,
vht_24G_cap:1,
beamformee_cap:1,
bw_above_20_5ghz:1,
bw_above_20_24ghz:1;
};
/**
* struct psoc_mlme_obj - PSoC MLME component object
* @psoc: PSoC object
* @ext_psoc_ptr: PSoC legacy pointer
* @psoc_vdev_rt: PSoC Vdev response timer
* @psoc_mlme_wakelock: Wakelock to prevent system going to suspend
* @ext_psoc_ptr: PSoC legacy pointer
* @psoc_vdev_rt: PSoC Vdev response timer
* @psoc_mlme_wakelock: Wakelock to prevent system going to suspend
* @rnr_6ghz_cache: Cache of 6Ghz vap in RNR ie format
* @score_config: BSS scoring related config
* @phy_config: Psoc Phy config
*/
struct psoc_mlme_obj {
struct wlan_objmgr_psoc *psoc;
@@ -55,6 +82,8 @@ struct psoc_mlme_obj {
struct psoc_mlme_wakelock psoc_mlme_wakelock;
#endif
struct wlan_6ghz_rnr_global_cache rnr_6ghz_cache;
struct scoring_cfg score_config;
struct psoc_phy_config phy_config;
};
#endif

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2019 The Linux Foundation. All rights reserved.
* Copyright (c) 2019-2020 The Linux Foundation. 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
@@ -21,6 +21,8 @@
#ifndef _WLAN_PSOC_MLME_API_H_
#define _WLAN_PSOC_MLME_API_H_
#include <include/wlan_psoc_mlme.h>
/**
* wlan_psoc_mlme_get_cmpt_obj() - Returns PSOC MLME component object
* @psoc: PSOC object
@@ -56,4 +58,34 @@ mlme_psoc_ext_t *wlan_psoc_mlme_get_ext_hdl(struct wlan_objmgr_psoc *psoc);
void wlan_psoc_mlme_set_ext_hdl(struct psoc_mlme_obj *psoc_mlme,
mlme_psoc_ext_t *psoc_ext_hdl);
/**
* wlan_psoc_set_phy_config() - Init psoc phy related configs
* @psoc: pointer to psoc object
* @phy_config: phy related configs score config
*
* Return: void
*/
void wlan_psoc_set_phy_config(struct wlan_objmgr_psoc *psoc,
struct psoc_phy_config *phy_config);
/**
* mlme_psoc_open() - MLME component Open
* @psoc: pointer to psoc object
*
* Open the MLME component and initialize the MLME structure
*
* Return: QDF Status
*/
QDF_STATUS mlme_psoc_open(struct wlan_objmgr_psoc *psoc);
/**
* mlme_psoc_close() - MLME component close
* @psoc: pointer to psoc object
*
* Open the MLME component and initialize the MLME structure
*
* Return: QDF Status
*/
QDF_STATUS mlme_psoc_close(struct wlan_objmgr_psoc *psoc);
#endif

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2019 The Linux Foundation. All rights reserved.
* Copyright (c) 2019-2020 The Linux Foundation. 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
@@ -59,4 +59,47 @@ void wlan_psoc_mlme_set_ext_hdl(struct psoc_mlme_obj *psoc_mlme,
psoc_mlme->ext_psoc_ptr = psoc_ext_hdl;
}
void wlan_psoc_set_phy_config(struct wlan_objmgr_psoc *psoc,
struct psoc_phy_config *phy_config)
{
struct psoc_mlme_obj *mlme_psoc_obj;
struct psoc_phy_config *config;
if (!phy_config) {
mlme_err("phy_config is NUll");
return;
}
mlme_psoc_obj = wlan_psoc_mlme_get_cmpt_obj(psoc);
if (!mlme_psoc_obj)
return;
config = &mlme_psoc_obj->phy_config;
qdf_mem_copy(config, phy_config, sizeof(*config));
}
static void mlme_init_cfg(struct wlan_objmgr_psoc *psoc)
{
struct psoc_mlme_obj *mlme_psoc_obj;
mlme_psoc_obj = wlan_psoc_mlme_get_cmpt_obj(psoc);
if (!mlme_psoc_obj)
return;
wlan_cm_init_score_config(psoc, &mlme_psoc_obj->score_config);
}
QDF_STATUS mlme_psoc_open(struct wlan_objmgr_psoc *psoc)
{
mlme_init_cfg(psoc);
return QDF_STATUS_SUCCESS;
}
QDF_STATUS mlme_psoc_close(struct wlan_objmgr_psoc *psoc)
{
return QDF_STATUS_SUCCESS;
}
qdf_export_symbol(wlan_psoc_mlme_set_ext_hdl);

View File

@@ -1,920 +0,0 @@
/*
* Copyright (c) 2017-2020 The Linux Foundation. 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 copyright notice and this permission notice appear in all
* copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
* WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
* AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
/*
* DOC: contains scan bss scoring logic
*/
#include <wlan_scan_utils_api.h>
#include "wlan_scan_main.h"
#include "wlan_scan_cache_db_i.h"
#ifdef WLAN_POLICY_MGR_ENABLE
#include "wlan_policy_mgr_api.h"
#endif
#include "wlan_reg_services_api.h"
#define SCM_20MHZ_BW_INDEX 0
#define SCM_40MHZ_BW_INDEX 1
#define SCM_80MHZ_BW_INDEX 2
#define SCM_160MHZ_BW_INDEX 3
#define SCM_MAX_BW_INDEX 4
#define SCM_NSS_1x1_INDEX 0
#define SCM_NSS_2x2_INDEX 1
#define SCM_NSS_3x3_INDEX 2
#define SCM_NSS_4x4_INDEX 3
#define SCM_MAX_NSS_INDEX 4
#define SCM_BAND_2G_INDEX 0
#define SCM_BAND_5G_INDEX 1
#define SCM_BAND_6G_INDEX 2
/* 2 and 3 are reserved */
#define SCM_MAX_BAND_INDEX 4
#define SCM_SCORE_INDEX_0 0
#define SCM_SCORE_INDEX_3 3
#define SCM_SCORE_INDEX_7 7
#define SCM_SCORE_OFFSET_INDEX_7_4 4
#define SCM_SCORE_INDEX_11 11
#define SCM_SCORE_OFFSET_INDEX_11_8 8
#define SCM_SCORE_MAX_INDEX 15
#define SCM_SCORE_OFFSET_INDEX_15_12 12
#define SCM_MAX_OCE_WAN_DL_CAP 16
#define SCM_MAX_CHANNEL_WEIGHT 100
#define SCM_MAX_CHANNEL_UTILIZATION 100
#define SCM_MAX_ESTIMATED_AIR_TIME_FRACTION 255
#define MAX_AP_LOAD 255
#define SCM_MAX_WEIGHT_OF_PCL_CHANNELS 255
#define SCM_PCL_GROUPS_WEIGHT_DIFFERENCE 20
/* Congestion threshold (channel load %) to consider band and OCE WAN score */
#define CONGESTION_THRSHOLD_FOR_BAND_OCE_SCORE 75
bool scm_is_better_bss(struct scan_default_params *params,
struct scan_cache_entry *bss1,
struct scan_cache_entry *bss2)
{
if (bss1->bss_score > bss2->bss_score)
return true;
else if (bss1->bss_score == bss2->bss_score)
if (bss1->rssi_raw > bss2->rssi_raw)
return true;
return false;
}
/**
* scm_get_rssi_pcnt_for_slot () - calculate rssi % score based on the slot
* index between the high rssi and low rssi threshold
* @high_rssi_threshold: High rssi of the window
* @low_rssi_threshold: low rssi of the window
* @high_rssi_pcnt: % score for the high rssi
* @low_rssi_pcnt: %score for the low rssi
* @bucket_size: bucket size of the window
* @bss_rssi: Input rssi for which value need to be calculated
*
* Return : rssi pct to use for the given rssi
*/
static inline
int8_t scm_get_rssi_pcnt_for_slot(int32_t high_rssi_threshold,
int32_t low_rssi_threshold, uint32_t high_rssi_pcnt,
uint32_t low_rssi_pcnt, uint32_t bucket_size, int8_t bss_rssi)
{
int8_t slot_index, slot_size, rssi_diff, num_slot, rssi_pcnt;
num_slot = ((high_rssi_threshold -
low_rssi_threshold) / bucket_size) + 1;
slot_size = ((high_rssi_pcnt - low_rssi_pcnt) +
(num_slot / 2)) / (num_slot);
rssi_diff = high_rssi_threshold - bss_rssi;
slot_index = (rssi_diff / bucket_size) + 1;
rssi_pcnt = high_rssi_pcnt - (slot_size * slot_index);
if (rssi_pcnt < low_rssi_pcnt)
rssi_pcnt = low_rssi_pcnt;
scm_debug("Window %d -> %d pcnt range %d -> %d bucket_size %d bss_rssi %d num_slot %d slot_size %d rssi_diff %d slot_index %d rssi_pcnt %d",
high_rssi_threshold, low_rssi_threshold, high_rssi_pcnt,
low_rssi_pcnt, bucket_size, bss_rssi, num_slot, slot_size,
rssi_diff, slot_index, rssi_pcnt);
return rssi_pcnt;
}
/**
* scm_calculate_rssi_score () - Calculate RSSI score based on AP RSSI
* @score_param: rssi score params
* @rssi: rssi of the AP
* @rssi_weightage: rssi_weightage out of total weightage
*
* Return : rssi score
*/
static int32_t scm_calculate_rssi_score(
struct rssi_cfg_score *score_param,
int32_t rssi, uint8_t rssi_weightage)
{
int8_t rssi_pcnt;
int32_t total_rssi_score;
int32_t best_rssi_threshold;
int32_t good_rssi_threshold;
int32_t bad_rssi_threshold;
uint32_t good_rssi_pcnt;
uint32_t bad_rssi_pcnt;
uint32_t good_bucket_size;
uint32_t bad_bucket_size;
best_rssi_threshold = score_param->best_rssi_threshold*(-1);
good_rssi_threshold = score_param->good_rssi_threshold*(-1);
bad_rssi_threshold = score_param->bad_rssi_threshold*(-1);
good_rssi_pcnt = score_param->good_rssi_pcnt;
bad_rssi_pcnt = score_param->bad_rssi_pcnt;
good_bucket_size = score_param->good_rssi_bucket_size;
bad_bucket_size = score_param->bad_rssi_bucket_size;
total_rssi_score = (MAX_PCT_SCORE * rssi_weightage);
/*
* If RSSI is better than the best rssi threshold then it return full
* score.
*/
if (rssi > best_rssi_threshold)
return total_rssi_score;
/*
* If RSSI is less or equal to bad rssi threshold then it return
* least score.
*/
if (rssi <= bad_rssi_threshold)
return (total_rssi_score * bad_rssi_pcnt) / 100;
/* RSSI lies between best to good rssi threshold */
if (rssi > good_rssi_threshold)
rssi_pcnt = scm_get_rssi_pcnt_for_slot(best_rssi_threshold,
good_rssi_threshold, 100, good_rssi_pcnt,
good_bucket_size, rssi);
else
rssi_pcnt = scm_get_rssi_pcnt_for_slot(good_rssi_threshold,
bad_rssi_threshold, good_rssi_pcnt,
bad_rssi_pcnt, bad_bucket_size,
rssi);
return (total_rssi_score * rssi_pcnt) / 100;
}
/**
* scm_calculate_pcl_score () - Calculate PCL score based on PCL weightage
* @pcl_chan_weight: pcl weight of BSS channel
* @pcl_weightage: PCL _weightage out of total weightage
*
* Return : pcl score
*/
static int32_t scm_calculate_pcl_score(int pcl_chan_weight,
uint8_t pcl_weightage)
{
int32_t pcl_score = 0;
int32_t temp_pcl_chan_weight = 0;
if (pcl_chan_weight) {
temp_pcl_chan_weight =
(SCM_MAX_WEIGHT_OF_PCL_CHANNELS - pcl_chan_weight);
temp_pcl_chan_weight = qdf_do_div(temp_pcl_chan_weight,
SCM_PCL_GROUPS_WEIGHT_DIFFERENCE);
pcl_score = pcl_weightage - temp_pcl_chan_weight;
if (pcl_score < 0)
pcl_score = 0;
}
return pcl_score * MAX_PCT_SCORE;
}
/**
* scm_rssi_is_same_bucket () - check if both rssi fall in same bucket
* @rssi_top_thresh: high rssi threshold of the the window
* @low_rssi_threshold: low rssi of the window
* @rssi_ref1: rssi ref one
* @rssi_ref2: rssi ref two
* @bucket_size: bucket size of the window
*
* Return : true if both fall in same window
*/
static inline bool scm_rssi_is_same_bucket(int8_t rssi_top_thresh,
int8_t rssi_ref1, int8_t rssi_ref2, int8_t bucket_size)
{
int8_t rssi_diff1 = 0;
int8_t rssi_diff2 = 0;
rssi_diff1 = rssi_top_thresh - rssi_ref1;
rssi_diff2 = rssi_top_thresh - rssi_ref2;
return (rssi_diff1 / bucket_size) == (rssi_diff2 / bucket_size);
}
/**
* scm_roam_calculate_prorated_pcnt_by_rssi () - Calculate prorated RSSI score
* based on AP RSSI. This will be used to determine HT VHT score
* @score_param: rssi score params
* @rssi: bss rssi
* @rssi_weightage: rssi_weightage out of total weightage
*
* If rssi is greater than good threshold return 100, if less than bad return 0,
* if between good and bad, return prorated rssi score for the index.
*
* Return : rssi prorated score
*/
static int8_t scm_roam_calculate_prorated_pcnt_by_rssi(
struct rssi_cfg_score *score_param,
int32_t rssi, uint8_t rssi_weightage)
{
int32_t good_rssi_threshold;
int32_t bad_rssi_threshold;
int8_t rssi_pref_5g_rssi_thresh;
bool same_bucket;
good_rssi_threshold = score_param->good_rssi_threshold * (-1);
bad_rssi_threshold = score_param->bad_rssi_threshold * (-1);
rssi_pref_5g_rssi_thresh = score_param->rssi_pref_5g_rssi_thresh * (-1);
/* If RSSI is greater than good rssi return full weight */
if (rssi > good_rssi_threshold)
return MAX_PCT_SCORE;
same_bucket = scm_rssi_is_same_bucket(good_rssi_threshold,
rssi, rssi_pref_5g_rssi_thresh,
score_param->bad_rssi_bucket_size);
if (same_bucket || (rssi < rssi_pref_5g_rssi_thresh))
return 0;
/* If RSSI is less or equal to bad rssi threshold then it return 0 */
if (rssi <= bad_rssi_threshold)
return 0;
/* If RSSI is between good and bad threshold */
return scm_get_rssi_pcnt_for_slot(good_rssi_threshold,
bad_rssi_threshold,
score_param->good_rssi_pcnt,
score_param->bad_rssi_pcnt,
score_param->bad_rssi_bucket_size,
rssi);
}
/**
* scm_calculate_bandwidth_score () - Calculate BW score
* @entry: scan entry
* @score_config: scoring config
* @prorated_pct: prorated % to return dependent on RSSI
*
* Return : bw score
*/
static int32_t scm_calculate_bandwidth_score(
struct scan_cache_entry *entry,
struct scoring_config *score_config, uint8_t prorated_pct)
{
uint32_t score;
int32_t bw_weight_per_idx;
uint8_t cbmode = 0;
uint8_t ch_width_index;
bool is_vht = false;
bw_weight_per_idx = score_config->bandwidth_weight_per_index;
if (WLAN_REG_IS_24GHZ_CH_FREQ(entry->channel.chan_freq)) {
cbmode = score_config->cb_mode_24G;
if (score_config->vht_24G_cap)
is_vht = true;
} else if (score_config->vht_cap) {
is_vht = true;
cbmode = score_config->cb_mode_5G;
}
if (IS_WLAN_PHYMODE_160MHZ(entry->phy_mode))
ch_width_index = SCM_160MHZ_BW_INDEX;
else if (IS_WLAN_PHYMODE_80MHZ(entry->phy_mode))
ch_width_index = SCM_80MHZ_BW_INDEX;
else if (IS_WLAN_PHYMODE_40MHZ(entry->phy_mode))
ch_width_index = SCM_40MHZ_BW_INDEX;
else
ch_width_index = SCM_20MHZ_BW_INDEX;
if (!score_config->ht_cap && ch_width_index > SCM_20MHZ_BW_INDEX)
ch_width_index = SCM_20MHZ_BW_INDEX;
if (!is_vht && ch_width_index > SCM_40MHZ_BW_INDEX)
ch_width_index = SCM_40MHZ_BW_INDEX;
if (cbmode && ch_width_index > SCM_20MHZ_BW_INDEX)
score = WLAN_GET_SCORE_PERCENTAGE(bw_weight_per_idx,
ch_width_index);
else
score = WLAN_GET_SCORE_PERCENTAGE(bw_weight_per_idx,
SCM_20MHZ_BW_INDEX);
return (prorated_pct * score *
score_config->weight_cfg.chan_width_weightage) / MAX_PCT_SCORE;
}
/**
* scm_get_score_for_index () - get score for the given index
* @index: index for which we need the score
* @weightage: weigtage for the param
* @score: per slot score
*
* Return : score for the index
*/
static int32_t scm_get_score_for_index(uint8_t index,
uint8_t weightage, struct per_slot_scoring *score)
{
if (index <= SCM_SCORE_INDEX_3)
return weightage * WLAN_GET_SCORE_PERCENTAGE(
score->score_pcnt3_to_0,
index);
else if (index <= SCM_SCORE_INDEX_7)
return weightage * WLAN_GET_SCORE_PERCENTAGE(
score->score_pcnt7_to_4,
index - SCM_SCORE_OFFSET_INDEX_7_4);
else if (index <= SCM_SCORE_INDEX_11)
return weightage * WLAN_GET_SCORE_PERCENTAGE(
score->score_pcnt11_to_8,
index - SCM_SCORE_OFFSET_INDEX_11_8);
else
return weightage * WLAN_GET_SCORE_PERCENTAGE(
score->score_pcnt15_to_12,
index - SCM_SCORE_OFFSET_INDEX_15_12);
}
/**
* scm_get_congestion_pct () - Calculate congestion pct from esp/qbss load
* @entry: bss information
*
* Return : congestion pct
*/
static int32_t scm_get_congestion_pct(struct scan_cache_entry *entry)
{
uint32_t ap_load = 0;
uint32_t est_air_time_percentage = 0;
uint32_t congestion = 0;
if (entry->air_time_fraction) {
/* Convert 0-255 range to percentage */
est_air_time_percentage = entry->air_time_fraction *
SCM_MAX_CHANNEL_WEIGHT;
est_air_time_percentage = qdf_do_div(est_air_time_percentage,
SCM_MAX_ESTIMATED_AIR_TIME_FRACTION);
/*
* Calculate channel congestion from estimated air time
* fraction.
*/
congestion = SCM_MAX_CHANNEL_UTILIZATION -
est_air_time_percentage;
} else if (entry->qbss_chan_load) {
ap_load = (entry->qbss_chan_load * MAX_PCT_SCORE);
/*
* Calculate ap_load in % from qbss channel load from
* 0-255 range
*/
congestion = qdf_do_div(ap_load, MAX_AP_LOAD);
}
return congestion;
}
/**
* scm_calculate_congestion_score () - Calculate congestion score
* @entry: bss information
* @score_params: bss score params
* @congestion_pct: congestion pct
*
* Return : congestion score
*/
static int32_t scm_calculate_congestion_score(
struct scan_cache_entry *entry,
struct scoring_config *score_params,
uint32_t *congestion_pct)
{
uint32_t window_size;
uint8_t index;
int32_t good_rssi_threshold;
*congestion_pct = scm_get_congestion_pct(entry);
if (!score_params->esp_qbss_scoring.num_slot)
return 0;
if (score_params->esp_qbss_scoring.num_slot >
SCM_SCORE_MAX_INDEX)
score_params->esp_qbss_scoring.num_slot =
SCM_SCORE_MAX_INDEX;
good_rssi_threshold =
score_params->rssi_score.good_rssi_threshold * (-1);
/* For bad zone rssi get score from last index */
if (entry->rssi_raw <= good_rssi_threshold)
return scm_get_score_for_index(
score_params->esp_qbss_scoring.num_slot,
score_params->weight_cfg.
channel_congestion_weightage,
&score_params->esp_qbss_scoring);
if (!*congestion_pct)
return score_params->weight_cfg.channel_congestion_weightage *
WLAN_GET_SCORE_PERCENTAGE(
score_params->esp_qbss_scoring.score_pcnt3_to_0,
SCM_SCORE_INDEX_0);
window_size = MAX_PCT_SCORE / score_params->esp_qbss_scoring.num_slot;
/* Desired values are from 1 to 15, as 0 is for not present. so do +1 */
index = qdf_do_div(*congestion_pct, window_size) + 1;
if (index > score_params->esp_qbss_scoring.num_slot)
index = score_params->esp_qbss_scoring.num_slot;
return scm_get_score_for_index(index, score_params->weight_cfg.
channel_congestion_weightage,
&score_params->esp_qbss_scoring);
}
/**
* scm_calculate_nss_score () - Calculate congestion score
* @psoc: psoc ptr
* @score_config: scoring config
* @ap_nss: ap nss
* @prorated_pct: prorated % to return dependent on RSSI
*
* Return : nss score
*/
static int32_t scm_calculate_nss_score(struct wlan_objmgr_psoc *psoc,
struct scoring_config *score_config, uint8_t ap_nss,
uint8_t prorated_pct, uint32_t sta_nss)
{
uint8_t nss;
uint8_t score_pct;
nss = ap_nss;
if (sta_nss < nss)
nss = sta_nss;
if (nss == 4)
score_pct = WLAN_GET_SCORE_PERCENTAGE(
score_config->nss_weight_per_index,
SCM_NSS_4x4_INDEX);
else if (nss == 3)
score_pct = WLAN_GET_SCORE_PERCENTAGE(
score_config->nss_weight_per_index,
SCM_NSS_3x3_INDEX);
else if (nss == 2)
score_pct = WLAN_GET_SCORE_PERCENTAGE(
score_config->nss_weight_per_index,
SCM_NSS_2x2_INDEX);
else
score_pct = WLAN_GET_SCORE_PERCENTAGE(
score_config->nss_weight_per_index,
SCM_NSS_1x1_INDEX);
return (score_config->weight_cfg.nss_weightage * score_pct *
prorated_pct) / MAX_PCT_SCORE;
}
/**
* scm_calculate_oce_wan_score () - Calculate oce wan score
* @entry: bss information
* @score_params: bss score params
*
* Return : oce wan score
*/
static int32_t scm_calculate_oce_wan_score(
struct scan_cache_entry *entry,
struct scoring_config *score_params)
{
uint32_t window_size;
uint8_t index;
struct oce_reduced_wan_metrics wan_metrics;
uint8_t *mbo_oce_ie;
if (!score_params->oce_wan_scoring.num_slot)
return 0;
if (score_params->oce_wan_scoring.num_slot >
SCM_SCORE_MAX_INDEX)
score_params->oce_wan_scoring.num_slot =
SCM_SCORE_MAX_INDEX;
window_size = SCM_SCORE_MAX_INDEX/
score_params->oce_wan_scoring.num_slot;
mbo_oce_ie = util_scan_entry_mbo_oce(entry);
if (wlan_parse_oce_reduced_wan_metrics_ie(mbo_oce_ie,
&wan_metrics)) {
scm_err("downlink_av_cap %d", wan_metrics.downlink_av_cap);
/* if capacity is 0 return 0 score */
if (!wan_metrics.downlink_av_cap)
return 0;
/* Desired values are from 1 to WLAN_SCORE_MAX_INDEX */
index = qdf_do_div(wan_metrics.downlink_av_cap,
window_size);
} else {
index = SCM_SCORE_INDEX_0;
}
if (index > score_params->oce_wan_scoring.num_slot)
index = score_params->oce_wan_scoring.num_slot;
return scm_get_score_for_index(index,
score_params->weight_cfg.oce_wan_weightage,
&score_params->oce_wan_scoring);
}
/**
* scm_calculate_oce_subnet_id_weightage () - Calculate oce subnet id weightage
* @entry: bss entry
* @score_params: bss score params
*
* Return : oce subnet id score
*/
static uint32_t
scm_calculate_oce_subnet_id_weightage(struct scan_cache_entry *entry,
struct scoring_config *score_params,
bool *oce_subnet_id_present)
{
uint32_t score = 0;
uint8_t *mbo_oce_ie;
mbo_oce_ie = util_scan_entry_mbo_oce(entry);
*oce_subnet_id_present = wlan_parse_oce_subnet_id_ie(mbo_oce_ie);
if (*oce_subnet_id_present)
/* Consider 50% weightage of subnet id */
score = (score_params->weight_cfg.oce_subnet_id_weightage *
(MAX_PCT_SCORE / 2));
return score;
}
/**
* scm_calculate_oce_ap_tx_pwr_weightage () - Calculate oce ap tx pwr weightage
* @entry: bss entry
* @score_params: bss score params
* @ap_tx_pwr_dbm: pointer to hold ap tx power
*
* Return : oce ap tx power score
*/
static uint32_t
scm_calculate_oce_ap_tx_pwr_weightage(struct scan_cache_entry *entry,
struct scoring_config *score_params,
int8_t *ap_tx_pwr_dbm)
{
uint8_t *mbo_oce_ie, ap_tx_pwr_factor;
struct rssi_cfg_score *rssi_score_param;
int32_t best_rssi_threshold, good_rssi_threshold, bad_rssi_threshold;
uint32_t good_rssi_pcnt, bad_rssi_pcnt, good_bucket_size;
uint32_t score, normalized_ap_tx_pwr, bad_bucket_size;
bool ap_tx_pwr_cap_present = true;
mbo_oce_ie = util_scan_entry_mbo_oce(entry);
if (!wlan_parse_oce_ap_tx_pwr_ie(mbo_oce_ie, ap_tx_pwr_dbm)) {
ap_tx_pwr_cap_present = false;
/* If no OCE AP TX pwr, consider Uplink RSSI = Downlink RSSI */
normalized_ap_tx_pwr = entry->rssi_raw;
} else {
/*
* Normalized ap_tx_pwr =
* Uplink RSSI = (STA TX Power - * (AP TX power - RSSI)) in dBm.
* Currently assuming STA Tx Power to be 20dBm, though later it
* need to fetched from hal-phy API.
*/
normalized_ap_tx_pwr = (20 - (*ap_tx_pwr_dbm - entry->rssi_raw));
}
rssi_score_param = &score_params->rssi_score;
best_rssi_threshold = rssi_score_param->best_rssi_threshold * (-1);
good_rssi_threshold = rssi_score_param->good_rssi_threshold * (-1);
bad_rssi_threshold = rssi_score_param->bad_rssi_threshold * (-1);
good_rssi_pcnt = rssi_score_param->good_rssi_pcnt;
bad_rssi_pcnt = rssi_score_param->bad_rssi_pcnt;
good_bucket_size = rssi_score_param->good_rssi_bucket_size;
bad_bucket_size = rssi_score_param->bad_rssi_bucket_size;
/* Uplink RSSI is better than best rssi threshold */
if (normalized_ap_tx_pwr > best_rssi_threshold) {
ap_tx_pwr_factor = MAX_PCT_SCORE;
} else if (normalized_ap_tx_pwr <= bad_rssi_threshold) {
/* Uplink RSSI is less or equal to bad rssi threshold */
ap_tx_pwr_factor = rssi_score_param->bad_rssi_pcnt;
} else if (normalized_ap_tx_pwr > good_rssi_threshold) {
/* Uplink RSSI lies between best to good rssi threshold */
ap_tx_pwr_factor =
scm_get_rssi_pcnt_for_slot(best_rssi_threshold,
good_rssi_threshold, 100, good_rssi_pcnt,
good_bucket_size, normalized_ap_tx_pwr);
} else {
/* Uplink RSSI lies between good to best rssi threshold */
ap_tx_pwr_factor =
scm_get_rssi_pcnt_for_slot(good_rssi_threshold,
bad_rssi_threshold, good_rssi_pcnt,
bad_rssi_pcnt, bad_bucket_size,
normalized_ap_tx_pwr);
}
score = score_params->weight_cfg.oce_ap_tx_pwr_weightage *
ap_tx_pwr_factor;
return score;
}
#ifdef WLAN_POLICY_MGR_ENABLE
static uint32_t scm_get_sta_nss(struct wlan_objmgr_psoc *psoc,
qdf_freq_t bss_channel_freq,
uint8_t vdev_nss_2g,
uint8_t vdev_nss_5g)
{
/*
* If station support nss as 2*2 but AP support NSS as 1*1,
* this AP will be given half weight compare to AP which are having
* NSS as 2*2.
*/
if (policy_mgr_is_chnl_in_diff_band(
psoc, bss_channel_freq) &&
policy_mgr_is_hw_dbs_capable(psoc) &&
!(policy_mgr_is_hw_dbs_2x2_capable(psoc)))
return 1;
return (WLAN_REG_IS_24GHZ_CH_FREQ(bss_channel_freq) ?
vdev_nss_2g :
vdev_nss_5g);
}
#else
static uint32_t scm_get_sta_nss(struct wlan_objmgr_psoc *psoc,
qdf_freq_t bss_channel_freq,
uint8_t vdev_nss_2g,
uint8_t vdev_nss_5g)
{
return (WLAN_REG_IS_24GHZ_CH_FREQ(bss_channel_freq) ?
vdev_nss_2g :
vdev_nss_5g);
}
#endif
/**
* scm_get_band_score() - Get band prefernce weightage
* freq: Operating frequency of the AP
* @score_config: Score configuration
*
* Return : Band score for AP.
*/
static int
scm_get_band_score(uint32_t freq, struct scoring_config *score_config)
{
uint8_t band_index;
struct weight_config *weight_config;
weight_config = &score_config->weight_cfg;
if (WLAN_REG_IS_5GHZ_CH_FREQ(freq))
band_index = SCM_BAND_5G_INDEX;
else if (WLAN_REG_IS_24GHZ_CH_FREQ(freq))
band_index = SCM_BAND_2G_INDEX;
else if (WLAN_REG_IS_6GHZ_CHAN_FREQ(freq))
band_index = SCM_BAND_6G_INDEX;
else
return 0;
return weight_config->chan_band_weightage *
WLAN_GET_SCORE_PERCENTAGE(score_config->band_weight_per_index,
band_index);
}
int scm_calculate_bss_score(struct wlan_objmgr_psoc *psoc,
struct scan_default_params *params,
struct scan_cache_entry *entry,
int pcl_chan_weight)
{
int32_t score = 0;
int32_t rssi_score = 0;
int32_t pcl_score = 0;
int32_t ht_score = 0;
int32_t vht_score = 0;
int32_t he_score = 0;
int32_t bandwidth_score = 0;
int32_t beamformee_score = 0;
int32_t band_score = 0;
int32_t nss_score = 0;
int32_t congestion_score = 0;
int32_t congestion_pct = 0;
int32_t oce_wan_score = 0;
uint8_t oce_ap_tx_pwr_score = 0;
uint8_t oce_subnet_id_score = 0;
bool oce_subnet_id_present = 0;
uint8_t prorated_pcnt;
bool is_vht = false;
int8_t good_rssi_threshold;
int8_t rssi_pref_5g_rssi_thresh;
bool same_bucket = false;
bool ap_su_beam_former = false;
struct wlan_ie_vhtcaps *vht_cap;
struct scoring_config *score_config;
struct weight_config *weight_config;
struct wlan_scan_obj *scan_obj;
uint32_t sta_nss;
struct wlan_objmgr_pdev *pdev = NULL;
int8_t ap_tx_pwr_dbm = 0;
scan_obj = wlan_psoc_get_scan_obj(psoc);
if (!scan_obj) {
scm_err("scan_obj is NULL");
return 0;
}
score_config = &scan_obj->scan_def.score_config;
weight_config = &score_config->weight_cfg;
rssi_score = scm_calculate_rssi_score(&score_config->rssi_score,
entry->rssi_raw, weight_config->rssi_weightage);
score += rssi_score;
pcl_score = scm_calculate_pcl_score(pcl_chan_weight,
weight_config->pcl_weightage);
score += pcl_score;
prorated_pcnt = scm_roam_calculate_prorated_pcnt_by_rssi(
&score_config->rssi_score, entry->rssi_raw,
weight_config->rssi_weightage);
/*
* Add HT weight if HT is supported by the AP. In case
* of 6 GHZ AP, HT and VHT won't be supported so that
* these weightage to the same by default to match
* with 2.4/5 GHZ APs where HT, VHT is supported
*/
if (score_config->ht_cap && (entry->ie_list.htcap ||
WLAN_REG_IS_6GHZ_CHAN_FREQ(entry->channel.chan_freq)))
ht_score = prorated_pcnt *
weight_config->ht_caps_weightage;
score += ht_score;
if (WLAN_REG_IS_24GHZ_CH_FREQ(entry->channel.chan_freq)) {
if (score_config->vht_24G_cap)
is_vht = true;
} else if (score_config->vht_cap) {
is_vht = true;
}
/* Add VHT score to 6 GHZ AP to match with 2.4/5 GHZ APs */
if (is_vht && (entry->ie_list.vhtcap ||
WLAN_REG_IS_6GHZ_CHAN_FREQ(entry->channel.chan_freq)))
vht_score = prorated_pcnt *
weight_config->vht_caps_weightage;
score += vht_score;
if (score_config->he_cap && entry->ie_list.hecap)
he_score = prorated_pcnt *
weight_config->he_caps_weightage;
score += he_score;
bandwidth_score = scm_calculate_bandwidth_score(entry, score_config,
prorated_pcnt);
score += bandwidth_score;
good_rssi_threshold =
score_config->rssi_score.good_rssi_threshold * (-1);
rssi_pref_5g_rssi_thresh =
score_config->rssi_score.rssi_pref_5g_rssi_thresh * (-1);
if (entry->rssi_raw < good_rssi_threshold)
same_bucket = scm_rssi_is_same_bucket(good_rssi_threshold,
entry->rssi_raw, rssi_pref_5g_rssi_thresh,
score_config->rssi_score.bad_rssi_bucket_size);
vht_cap = (struct wlan_ie_vhtcaps *) util_scan_entry_vhtcap(entry);
if (vht_cap && vht_cap->su_beam_former)
ap_su_beam_former = true;
if (is_vht && ap_su_beam_former &&
(entry->rssi_raw > rssi_pref_5g_rssi_thresh) && !same_bucket)
beamformee_score = MAX_PCT_SCORE *
weight_config->beamforming_cap_weightage;
score += beamformee_score;
congestion_score = scm_calculate_congestion_score(entry, score_config,
&congestion_pct);
score += congestion_score;
/*
* Consider OCE WAN score and band preference score only if
* congestion_pct is greater than CONGESTION_THRSHOLD_FOR_BAND_OCE_SCORE
*/
if (congestion_pct < CONGESTION_THRSHOLD_FOR_BAND_OCE_SCORE) {
/*
* If AP is on 5/6 GHZ channel , extra weigtage is added to BSS
* score. if RSSI is greater tha 5g rssi threshold or fall in
* same bucket else give weigtage to 2.4 GHZ AP.
*/
if ((entry->rssi_raw > rssi_pref_5g_rssi_thresh) &&
!same_bucket) {
if (!WLAN_REG_IS_24GHZ_CH_FREQ(entry->channel.chan_freq))
band_score = scm_get_band_score(
entry->channel.chan_freq,
score_config);
} else if (WLAN_REG_IS_24GHZ_CH_FREQ(
entry->channel.chan_freq)) {
band_score =
scm_get_band_score(entry->channel.chan_freq,
score_config);
}
score += band_score;
oce_wan_score = scm_calculate_oce_wan_score(entry,
score_config);
score += oce_wan_score;
}
oce_ap_tx_pwr_score =
scm_calculate_oce_ap_tx_pwr_weightage(entry, score_config,
&ap_tx_pwr_dbm);
score += oce_ap_tx_pwr_score;
oce_subnet_id_score = scm_calculate_oce_subnet_id_weightage(entry,
score_config, &oce_subnet_id_present);
score += oce_subnet_id_score;
pdev = wlan_objmgr_get_pdev_by_id(psoc, entry->pdev_id, WLAN_SCAN_ID);
if (!pdev) {
scm_err("pdev is NULL");
return 0;
}
sta_nss = scm_get_sta_nss(psoc,
entry->channel.chan_freq,
score_config->vdev_nss_24g,
score_config->vdev_nss_5g);
wlan_objmgr_pdev_release_ref(pdev, WLAN_SCAN_ID);
/*
* If station support nss as 2*2 but AP support NSS as 1*1,
* this AP will be given half weight compare to AP which are having
* NSS as 2*2.
*/
nss_score = scm_calculate_nss_score(psoc, score_config, entry->nss,
prorated_pcnt, sta_nss);
score += nss_score;
scm_nofl_debug("Self: HT %d VHT %d HE %d VHT_24Ghz %d BF cap %d cb_mode_24g %d cb_mode_5G %d NSS %d",
score_config->ht_cap, score_config->vht_cap,
score_config->he_cap, score_config->vht_24G_cap,
score_config->beamformee_cap, score_config->cb_mode_24G,
score_config->cb_mode_5G, sta_nss);
scm_nofl_debug("Candidate(%pM freq %d): rssi %d HT %d VHT %d HE %d su bfer %d phy %d air time frac %d qbss %d cong_pct %d NSS %d ap_tx_pwr_dbm %d oce_subnet_id_present %d",
entry->bssid.bytes, entry->channel.chan_freq,
entry->rssi_raw, util_scan_entry_htcap(entry) ? 1 : 0,
util_scan_entry_vhtcap(entry) ? 1 : 0,
util_scan_entry_hecap(entry) ? 1 : 0, ap_su_beam_former,
entry->phy_mode, entry->air_time_fraction,
entry->qbss_chan_load, congestion_pct, entry->nss,
ap_tx_pwr_dbm, oce_subnet_id_present);
scm_nofl_debug("Scores: prorated_pcnt %d rssi %d pcl %d ht %d vht %d he %d bfee %d bw %d band %d congestion %d nss %d oce wan %d oce ap tx pwr %d subnet id score %d TOTAL %d",
prorated_pcnt, rssi_score, pcl_score, ht_score,
vht_score, he_score, beamformee_score, bandwidth_score,
band_score, congestion_score, nss_score, oce_wan_score,
oce_ap_tx_pwr_score, oce_subnet_id_score, score);
entry->bss_score = score;
return score;
}
bool scm_get_pcl_weight_of_channel(uint32_t chan_freq,
struct scan_filter *filter,
int *pcl_chan_weight,
uint8_t *weight_list)
{
int i;
bool found = false;
if (!filter)
return found;
for (i = 0; i < filter->num_of_pcl_channels; i++) {
if (filter->pcl_freq_list[i] == chan_freq) {
*pcl_chan_weight = filter->pcl_weight_list[i];
found = true;
break;
}
}
return found;
}

View File

@@ -1001,82 +1001,6 @@ QDF_STATUS scm_handle_bcn_probe(struct scheduler_msg *msg)
return __scm_handle_bcn_probe(msg->bodyptr);
}
/**
* scm_list_insert_sorted() - add the entries in scan_list in sorted way
* @psoc: psoc ptr
* @filter: scan filter
* @scan_node: node entry to be inserted
* @scan_list: Temp scan list
*
* Add the entries in scan_list in sorted way considering
* cap_val and prefer val. The node is copy of original scan entry and
* thus no lock is required.
*
* Return: void
*/
static void scm_list_insert_sorted(struct wlan_objmgr_psoc *psoc,
struct scan_filter *filter,
struct scan_cache_node *scan_node,
qdf_list_t *scan_list)
{
struct scan_cache_node *cur_node;
qdf_list_node_t *cur_lst = NULL, *next_lst = NULL;
struct scan_default_params *params;
int pcl_chan_weight = 0;
params = wlan_scan_psoc_get_def_params(psoc);
if (!params) {
scm_err("wlan_scan_psoc_get_def_params failed");
return;
}
if (filter->num_of_pcl_channels > 0 &&
(scan_node->entry->rssi_raw > SCM_PCL_RSSI_THRESHOLD)) {
if (scm_get_pcl_weight_of_channel(
scan_node->entry->channel.chan_freq,
filter, &pcl_chan_weight,
filter->pcl_weight_list)) {
scm_debug("pcl freq %d pcl_chan_weight %d",
scan_node->entry->channel.chan_freq,
pcl_chan_weight);
}
}
if (params->is_bssid_hint_priority &&
!qdf_mem_cmp(filter->bssid_hint.bytes,
scan_node->entry->bssid.bytes,
QDF_MAC_ADDR_SIZE))
scan_node->entry->bss_score = BEST_CANDIDATE_MAX_BSS_SCORE;
else
scm_calculate_bss_score(psoc, params,
scan_node->entry, pcl_chan_weight);
if (qdf_list_empty(scan_list)) {
qdf_list_insert_front(scan_list, &scan_node->node);
return;
}
qdf_list_peek_front(scan_list, &cur_lst);
while (cur_lst) {
cur_node = qdf_container_of(cur_lst,
struct scan_cache_node, node);
if (scm_is_better_bss(params,
scan_node->entry, cur_node->entry)) {
qdf_list_insert_before(scan_list,
&scan_node->node,
&cur_node->node);
break;
}
qdf_list_peek_next(scan_list,
cur_lst, &next_lst);
cur_lst = next_lst;
next_lst = NULL;
}
if (!cur_lst)
qdf_list_insert_back(scan_list,
&scan_node->node);
}
/**
* scm_scan_apply_filter_get_entry() - apply filter and get the
* scan entry
@@ -1121,11 +1045,7 @@ scm_scan_apply_filter_get_entry(struct wlan_objmgr_psoc *psoc,
qdf_mem_copy(&scan_node->entry->neg_sec_info,
&security, sizeof(scan_node->entry->neg_sec_info));
if (!filter || !filter->bss_scoring_required)
qdf_list_insert_front(scan_list,
&scan_node->node);
else
scm_list_insert_sorted(psoc, filter, scan_node, scan_list);
qdf_list_insert_front(scan_list, &scan_node->node);
return QDF_STATUS_SUCCESS;
}

View File

@@ -33,9 +33,6 @@
#define SCAN_GET_HASH(addr) \
(((const uint8_t *)(addr))[QDF_MAC_ADDR_SIZE - 1] % SCAN_HASH_SIZE)
#define SCM_PCL_RSSI_THRESHOLD -75
#define BEST_CANDIDATE_MAX_BSS_SCORE 10000
#define ADJACENT_CHANNEL_RSSI_THRESHOLD -80
/**

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2017, 2019 The Linux Foundation. All rights reserved.
* Copyright (c) 2017, 2019-2020 The Linux Foundation. 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
@@ -37,39 +37,6 @@ bool scm_filter_match(struct wlan_objmgr_psoc *psoc,
struct scan_filter *filter,
struct security_info *security);
/**
* scm_is_better_bss() - Is bss1 better than bss2
* @params: scan params
* @bss1: Pointer to the first BSS.
* @bss2: Pointer to the second BSS.
*
* This routine helps in determining the preference value
* of a particular BSS in the scan result which is further
* used in the sorting logic of the final candidate AP's.
*
* Return: true, if bss1 is better than bss2
* false, if bss2 is better than bss1.
*/
bool scm_is_better_bss(struct scan_default_params *params,
struct scan_cache_entry *bss1,
struct scan_cache_entry *bss2);
/**
* scm_calculate_bss_score() - calculate BSS score used to get
* the preference
* @psoc: psoc ptr;
* @params: scan params
* @entry: scan entry for which score needs to be calculated
* @pcl_chan_weight: weight for pcl channel
*
* Return: scan db for the pdev id
*/
int scm_calculate_bss_score(
struct wlan_objmgr_psoc *psoc,
struct scan_default_params *params,
struct scan_cache_entry *entry,
int pcl_chan_weight);
/**
* wlan_pdevid_get_scan_db() - private API to get scan db from pdev id
* @psoc: psoc object
@@ -115,19 +82,4 @@ wlan_pdev_get_scan_db(struct wlan_objmgr_psoc *psoc,
return wlan_pdevid_get_scan_db(psoc, pdev_id);
}
/**
* scm_get_pcl_weight_of_channel() - Get PCL weight if channel is present in pcl
* @chan_freq: channel frequency of bss, unit: MHz
* @filter: filter
* @pcl_chan_weight: Get PCL weight for corresponding channel
* @weight_list: Weight list for all the pcl channels.
*
* Get pcl_chan_weight if provided channel is present in pcl list
*
* Return: true or false
*/
bool scm_get_pcl_weight_of_channel(uint32_t chan_freq,
struct scan_filter *filter,
int *pcl_chan_weight,
uint8_t *weight_list);
#endif

View File

@@ -313,7 +313,6 @@ struct extscan_def_config {
* @select_5gh_margin: Prefer connecting to 5G AP even if
* its RSSI is lower by select_5gh_margin dbm than 2.4G AP.
* applicable if prefer_5ghz is set.
* @is_bssid_hint_priority: True if bssid_hint is given priority
* @enable_mac_spoofing: enable mac address spoof in scan
* @max_bss_per_pdev: maximum number of bss entries to be maintained per pdev
* @max_active_scans_allowed: maximum number of active parallel scan allowed
@@ -397,7 +396,6 @@ struct scan_default_params {
qdf_time_t scan_cache_aging_time;
uint32_t select_5ghz_margin;
bool enable_mac_spoofing;
bool is_bssid_hint_priority;
uint32_t usr_cfg_probe_rpt_time;
uint32_t usr_cfg_num_probes;
uint16_t max_bss_per_pdev;
@@ -461,7 +459,6 @@ struct scan_default_params {
};
uint32_t scan_events;
};
struct scoring_config score_config;
};
/**

View File

@@ -210,4 +210,17 @@ wlan_scan_process_bcn_probe_rx_sync(struct wlan_objmgr_psoc *psoc,
*/
qdf_time_t wlan_scan_get_aging_time(struct wlan_objmgr_psoc *psoc);
/**
* wlan_scan_purge_results() - purge the scan list
* @scan_list: scan list to be purged
*
* This function purge the temp scan list
*
* Return: QDF_STATUS
*/
static inline QDF_STATUS wlan_scan_purge_results(qdf_list_t *scan_list)
{
return scm_purge_scan_results(scan_list);
}
#endif

View File

@@ -336,31 +336,6 @@ enum scan_mode_6ghz {
true, \
"honour NL80211 scan policy flags")
/*
* <ini>
* is_bssid_hint_priority - Set priority for connection with bssid_hint
* BSSID.
* @Min: 0
* @Max: 1
* @Default: 1
*
* This ini is used to give priority to BSS for connection which comes
* as part of bssid_hint
*
* Related: None
*
* Supported Feature: STA
*
* Usage: External
*
* </ini>
*/
#define CFG_IS_BSSID_HINT_PRIORITY CFG_INI_UINT(\
"is_bssid_hint_priority",\
0, 1, 0,\
CFG_VALUE_OR_DEFAULT, \
"Set priority for connection with bssid_hint")
#ifdef FEATURE_WLAN_SCAN_PNO
/*
* <ini>
@@ -1245,7 +1220,6 @@ enum scan_mode_6ghz {
CFG(CFG_ADAPTIVE_SCAN_DWELL_MODE) \
CFG(CFG_ADAPTIVE_SCAN_DWELL_MODE_NC) \
CFG(CFG_HONOUR_NL_SCAN_POLICY_FLAGS) \
CFG(CFG_IS_BSSID_HINT_PRIORITY) \
CFG(CFG_PASSIVE_MAX_CHANNEL_TIME_CONC) \
CFG(CFG_ACTIVE_MAX_CHANNEL_TIME_CONC) \
CFG(CFG_MAX_REST_TIME_CONC) \

View File

@@ -58,36 +58,6 @@ typedef uint32_t wlan_scan_id;
#define PROBE_REQ_BITMAP_LEN 8
#define MAX_PROBE_REQ_OUIS 16
#define RSSI_WEIGHTAGE 20
#define HT_CAPABILITY_WEIGHTAGE 2
#define VHT_CAP_WEIGHTAGE 1
#define HE_CAP_WEIGHTAGE 2
#define CHAN_WIDTH_WEIGHTAGE 12
#define CHAN_BAND_WEIGHTAGE 2
#define NSS_WEIGHTAGE 16
#define BEAMFORMING_CAP_WEIGHTAGE 2
#define PCL_WEIGHT 10
#define CHANNEL_CONGESTION_WEIGHTAGE 5
#define OCE_WAN_WEIGHTAGE 2
#define OCE_AP_TX_POWER_WEIGHTAGE 5
#define OCE_SUBNET_ID_WEIGHTAGE 3
#define BEST_CANDIDATE_MAX_WEIGHT 200
#define MAX_PCT_SCORE 100
#define MAX_INDEX_PER_INI 4
#define WLAN_GET_BITS(_val, _index, _num_bits) \
(((_val) >> (_index)) & ((1 << (_num_bits)) - 1))
#define WLAN_SET_BITS(_var, _index, _num_bits, _val) do { \
(_var) &= ~(((1 << (_num_bits)) - 1) << (_index)); \
(_var) |= (((_val) & ((1 << (_num_bits)) - 1)) << (_index)); \
} while (0)
#define WLAN_GET_SCORE_PERCENTAGE(value32, bw_index) \
WLAN_GET_BITS(value32, (8 * (bw_index)), 8)
#define WLAN_SET_SCORE_PERCENTAGE(value32, score_pcnt, bw_index) \
WLAN_SET_BITS(value32, (8 * (bw_index)), 8, score_pcnt)
/* forward declaration */
struct wlan_objmgr_vdev;
struct wlan_objmgr_pdev;
@@ -468,133 +438,6 @@ struct scan_cache_entry {
#define MAX_FAVORED_BSSID 16
#define MAX_ALLOWED_SSID_LIST 4
/**
* struct weight_config - weight params to calculate best candidate
* @rssi_weightage: RSSI weightage
* @ht_caps_weightage: HT caps weightage
* @vht_caps_weightage: VHT caps weightage
* @he_caps_weightage: HE caps weightage
* @chan_width_weightage: Channel width weightage
* @chan_band_weightage: Channel band weightage
* @nss_weightage: NSS weightage
* @beamforming_cap_weightage: Beamforming caps weightage
* @pcl_weightage: PCL weightage
* @channel_congestion_weightage: channel congestion weightage
* @oce_wan_weightage: OCE WAN metrics weightage
* @oce_ap_tx_pwr_weightage: OCE AP tx power weigtage
* @oce_subnet_id_weightage: OCE subnet id weigtage
*/
struct weight_config {
uint8_t rssi_weightage;
uint8_t ht_caps_weightage;
uint8_t vht_caps_weightage;
uint8_t he_caps_weightage;
uint8_t chan_width_weightage;
uint8_t chan_band_weightage;
uint8_t nss_weightage;
uint8_t beamforming_cap_weightage;
uint8_t pcl_weightage;
uint8_t channel_congestion_weightage;
uint8_t oce_wan_weightage;
uint8_t oce_ap_tx_pwr_weightage;
uint8_t oce_subnet_id_weightage;
};
/**
* struct rssi_cfg_score - rssi related params for scoring logic
* @best_rssi_threshold: RSSI weightage
* @good_rssi_threshold: HT caps weightage
* @bad_rssi_threshold: VHT caps weightage
* @good_rssi_pcnt: HE caps weightage
* @bad_rssi_pcnt: Channel width weightage
* @good_rssi_bucket_size: Channel band weightage
* @bad_rssi_bucket_size: NSS weightage
* @rssi_pref_5g_rssi_thresh: Beamforming caps weightage
*/
struct rssi_cfg_score {
uint32_t best_rssi_threshold;
uint32_t good_rssi_threshold;
uint32_t bad_rssi_threshold;
uint32_t good_rssi_pcnt;
uint32_t bad_rssi_pcnt;
uint32_t good_rssi_bucket_size;
uint32_t bad_rssi_bucket_size;
uint32_t rssi_pref_5g_rssi_thresh;
};
/**
* struct per_slot_scoring - define % score for differents slots for a
* scoring param.
* num_slot: number of slots in which the param will be divided.
* Max 15. index 0 is used for 'not_present. Num_slot will
* equally divide 100. e.g, if num_slot = 4 slot 0 = 0-25%, slot
* 1 = 26-50% slot 2 = 51-75%, slot 3 = 76-100%
* score_pcnt3_to_0: Conatins score percentage for slot 0-3
* BITS 0-7 :- the scoring pcnt when not present
* BITS 8-15 :- SLOT_1
* BITS 16-23 :- SLOT_2
* BITS 24-31 :- SLOT_3
* score_pcnt7_to_4: Conatins score percentage for slot 4-7
* BITS 0-7 :- SLOT_4
* BITS 8-15 :- SLOT_5
* BITS 16-23 :- SLOT_6
* BITS 24-31 :- SLOT_7
* score_pcnt11_to_8: Conatins score percentage for slot 8-11
* BITS 0-7 :- SLOT_8
* BITS 8-15 :- SLOT_9
* BITS 16-23 :- SLOT_10
* BITS 24-31 :- SLOT_11
* score_pcnt15_to_12: Conatins score percentage for slot 12-15
* BITS 0-7 :- SLOT_12
* BITS 8-15 :- SLOT_13
* BITS 16-23 :- SLOT_14
* BITS 24-31 :- SLOT_15
*/
struct per_slot_scoring {
uint32_t num_slot;
uint32_t score_pcnt3_to_0;
uint32_t score_pcnt7_to_4;
uint32_t score_pcnt11_to_8;
uint32_t score_pcnt15_to_12;
};
/**
* struct scoring_config - Scoring related configuration
* @weight_cfg: weigtage config for config
* @rssi_score: Rssi related config for scoring config
* @esp_qbss_scoring: esp and qbss related scoring config
* @oce_wan_scoring: oce related scoring config
* @bandwidth_weight_per_index: BW wight per index
* @nss_weight_per_index: nss weight per index
* @band_weight_per_index: band weight per index
* @cb_mode_24G: cb mode supprted for 2.4Ghz
* @cb_mode_5G: cb mode supprted for 5Ghz
* @nss: Number of NSS the device support
* @ht_cap: If dev is configured as HT capable
* @vht_cap:If dev is configured as VHT capable
* @he_cap: If dev is configured as HE capable
* @vht_24G_cap:If dev is configured as VHT capable for 2.4Ghz
* @beamformee_cap:If dev is configured as BF capable
*/
struct scoring_config {
struct weight_config weight_cfg;
struct rssi_cfg_score rssi_score;
struct per_slot_scoring esp_qbss_scoring;
struct per_slot_scoring oce_wan_scoring;
uint32_t bandwidth_weight_per_index;
uint32_t nss_weight_per_index;
uint32_t band_weight_per_index;
uint8_t cb_mode_24G;
uint8_t cb_mode_5G;
uint8_t vdev_nss_24g;
uint8_t vdev_nss_5g;
uint8_t ht_cap:1,
vht_cap:1,
he_cap:1,
vht_24G_cap:1,
beamformee_cap:1;
};
#define WLAN_SCAN_FILTER_NUM_SSID 5
#define WLAN_SCAN_FILTER_NUM_BSSID 5
@@ -615,7 +458,7 @@ struct fils_filter_info {
};
/**
* @bss_scoring_required :- flag to bypass scoring filtered results
* struct scan_filter: scan filter
* @enable_adaptive_11r: flag to check if adaptive 11r ini is enabled
* @age_threshold: If set return entry which are newer than the age_threshold
* @p2p_results: If only p2p entries is required
@@ -629,7 +472,6 @@ struct fils_filter_info {
* @num_of_mc_enc_type: number of multicast enc type
* @pmf_cap: Pmf capability
* @ignore_pmf_cap: Ignore pmf capability match
* @num_of_pcl_channels: number of pcl channels
* @bss_type: bss type BSS/IBSS etc
* @dot11_mode: operating modes 0 mean any
* 11a , 11g, 11n , 11ac , 11b etc
@@ -647,13 +489,10 @@ struct fils_filter_info {
* @auth_type: auth type list
* @enc_type: unicast enc type list
* @mc_enc_type: multicast cast enc type list
* @pcl_freq_list: PCL channel frequency list, frequency unit: MHz
* @fils_scan_filter: FILS info
* @pcl_weight_list: PCL Weight list
* @bssid_hint: Mac address of bssid_hint
*/
struct scan_filter {
bool bss_scoring_required;
bool enable_adaptive_11r;
qdf_time_t age_threshold;
uint32_t p2p_results;
@@ -666,7 +505,6 @@ struct scan_filter {
uint32_t num_of_mc_enc_type;
enum wlan_pmf_cap pmf_cap;
bool ignore_pmf_cap;
uint32_t num_of_pcl_channels;
enum wlan_bss_type bss_type;
enum wlan_phymode dot11_mode;
enum wlan_band band;
@@ -682,9 +520,7 @@ struct scan_filter {
enum wlan_auth_type auth_type[WLAN_NUM_OF_SUPPORT_AUTH_TYPE];
enum wlan_enc_type enc_type[WLAN_NUM_OF_ENCRYPT_TYPE];
enum wlan_enc_type mc_enc_type[WLAN_NUM_OF_ENCRYPT_TYPE];
uint32_t pcl_freq_list[NUM_CHANNELS];
struct fils_filter_info fils_scan_filter;
uint8_t pcl_weight_list[NUM_CHANNELS];
struct qdf_mac_addr bssid_hint;
};
@@ -1399,12 +1235,10 @@ struct pno_scan_req_params {
* struct scan_user_cfg - user configuration required for for scan
* @ie_whitelist: probe req IE whitelist attrs
* @sta_miracast_mcc_rest_time: sta miracast mcc rest time
* @score_config: scoring logic configuration
*/
struct scan_user_cfg {
struct probe_req_whitelist_attr ie_whitelist;
uint32_t sta_miracast_mcc_rest_time;
struct scoring_config score_config;
};
/**

View File

@@ -990,8 +990,6 @@ wlan_scan_global_init(struct wlan_objmgr_psoc *psoc,
cfg_get(psoc, CFG_HONOUR_NL_SCAN_POLICY_FLAGS);
scan_obj->scan_def.enable_mac_spoofing =
cfg_get(psoc, CFG_ENABLE_MAC_ADDR_SPOOFING);
scan_obj->scan_def.is_bssid_hint_priority =
cfg_get(psoc, CFG_IS_BSSID_HINT_PRIORITY);
scan_obj->scan_def.extscan_adaptive_dwell_mode =
cfg_get(psoc, CFG_ADAPTIVE_EXTSCAN_DWELL_MODE);
@@ -1490,9 +1488,6 @@ QDF_STATUS ucfg_scan_update_user_config(struct wlan_objmgr_psoc *psoc,
scan_def->sta_miracast_mcc_rest_time =
scan_cfg->sta_miracast_mcc_rest_time;
qdf_mem_copy(&scan_def->score_config, &scan_cfg->score_config,
sizeof(struct scoring_config));
return QDF_STATUS_SUCCESS;
}