qcacmn: Update new scoring logic with configurable user value
Adds new scoring logic with configurable user value Change-Id: Ie8c051a3f380930d8a7951617b27aa8f8187619b CRs-Fixed: 2144588
This commit is contained in:
@@ -31,6 +31,10 @@
|
||||
#define P2P_WFA_VER 0x09
|
||||
|
||||
#define WSC_OUI 0x0050f204
|
||||
#define MBO_OCE_OUI 0x506f9a16
|
||||
#define MBO_OCE_OUI_SIZE 4
|
||||
#define REDUCED_WAN_METRICS_ATTR 103
|
||||
|
||||
/* WCN IE */
|
||||
/* Microsoft OUI */
|
||||
#define WCN_OUI 0xf25000
|
||||
@@ -997,6 +1001,17 @@ struct wlan_esp_ie {
|
||||
struct wlan_esp_info esp_info_AC_VI;
|
||||
struct wlan_esp_info esp_info_AC_VO;
|
||||
} qdf_packed;
|
||||
|
||||
/**
|
||||
* struct oce_reduced_wan_metrics: struct for oce wan metrics
|
||||
* @downlink_av_cap: Download available capacity
|
||||
* @uplink_av_cap: Upload available capacity
|
||||
*/
|
||||
struct oce_reduced_wan_metrics {
|
||||
uint8_t downlink_av_cap:4;
|
||||
uint8_t uplink_av_cap:4;
|
||||
};
|
||||
|
||||
/**
|
||||
* is_wpa_oui() - If vendor IE is WPA type
|
||||
* @frm: vendor IE pointer
|
||||
@@ -1026,6 +1041,20 @@ is_wps_oui(const uint8_t *frm)
|
||||
return frm[1] > 3 && BE_READ_4(frm + 2) == WSC_OUI;
|
||||
}
|
||||
|
||||
/**
|
||||
* is_mbo_oce_oui() - If vendor IE is MBO/OCE type
|
||||
* @frm: vendor IE pointer
|
||||
*
|
||||
* API to check if vendor IE is MBO/OCE
|
||||
*
|
||||
* Return: true if its MBO/OCE IE
|
||||
*/
|
||||
static inline bool
|
||||
is_mbo_oce_oui(const uint8_t *frm)
|
||||
{
|
||||
return frm[1] > 3 && BE_READ_4(frm + 2) == MBO_OCE_OUI;
|
||||
}
|
||||
|
||||
/**
|
||||
* is_wcn_oui() - If vendor IE is WCN type
|
||||
* @frm: vendor IE pointer
|
||||
@@ -1474,4 +1503,53 @@ static inline void wlan_parse_wapi_ie(uint8_t *wapi_ie,
|
||||
wapi->mc_cipher_suite = LE_READ_4(ie);
|
||||
}
|
||||
|
||||
/**
|
||||
* wlan_parse_oce_reduced_wan_metrics_ie() - parse oce wan metrics
|
||||
* @mbo_oce_ie: MBO/OCE ie ptr
|
||||
* @wan_metrics: out structure for the reduced wan metric
|
||||
*
|
||||
* API, function to parse reduced wan metric
|
||||
*
|
||||
* Return: true if oce wan metrics is present
|
||||
*/
|
||||
static inline bool
|
||||
wlan_parse_oce_reduced_wan_metrics_ie(uint8_t *mbo_oce_ie,
|
||||
struct oce_reduced_wan_metrics *wan_metrics)
|
||||
{
|
||||
uint8_t len, attribute_len, attribute_id;
|
||||
uint8_t *ie;
|
||||
|
||||
if (!mbo_oce_ie)
|
||||
return false;
|
||||
|
||||
ie = mbo_oce_ie;
|
||||
len = ie[1];
|
||||
ie += 2;
|
||||
|
||||
if (len <= MBO_OCE_OUI_SIZE)
|
||||
return false;
|
||||
|
||||
ie += MBO_OCE_OUI_SIZE;
|
||||
len -= MBO_OCE_OUI_SIZE;
|
||||
|
||||
while (len > 2) {
|
||||
attribute_id = ie[0];
|
||||
attribute_len = ie[1];
|
||||
len -= 2;
|
||||
if (attribute_len > len)
|
||||
return false;
|
||||
|
||||
if (attribute_id == REDUCED_WAN_METRICS_ATTR) {
|
||||
wan_metrics->downlink_av_cap = ie[2] & 0xff;
|
||||
wan_metrics->uplink_av_cap = ie[2] >> 4;
|
||||
return true;
|
||||
}
|
||||
|
||||
ie += (attribute_len + 2);
|
||||
len -= attribute_len;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
#endif /* _WLAN_CMN_IEEE80211_DEFS_H_ */
|
||||
|
@@ -33,36 +33,7 @@
|
||||
#define SCAN_GET_HASH(addr) \
|
||||
(((const uint8_t *)(addr))[QDF_MAC_ADDR_SIZE - 1] % SCAN_HASH_SIZE)
|
||||
|
||||
#define RSSI_THRESHOLD_5GHZ -70
|
||||
#define BEST_CANDIDATE_RSSI_WEIGHT 50
|
||||
#define MIN_RSSI (-100)
|
||||
#define MAX_RSSI 0
|
||||
#define ROAM_MAX_CHANNEL_WEIGHT 100
|
||||
#define MAX_CHANNEL_UTILIZATION 100
|
||||
#define NSS_1X1_WEIGHTAGE 3
|
||||
#define MAX_ESTIMATED_AIR_TIME_FRACTION 255
|
||||
#define MAX_AP_LOAD 255
|
||||
|
||||
#define LOW_CHANNEL_CONGESTION_WEIGHT 500
|
||||
#define MODERATE_CHANNEL_CONGESTION_WEIGHT 370
|
||||
#define CONSIDERABLE_CHANNEL_CONGESTION_WEIGHT 250
|
||||
#define HIGH_CHANNEL_CONGESTION_WEIGHT 120
|
||||
|
||||
#define LOW_CHANNEL_CONGESTION 0
|
||||
#define MODERATE_CHANNEL_CONGESTION 25
|
||||
#define CONSIDERABLE_CHANNEL_CONGESTION 50
|
||||
#define HIGH_CHANNEL_CONGESTION 75
|
||||
#define EXTREME_CHANNEL_CONGESTION 100
|
||||
|
||||
#define EXCELLENT_RSSI -55
|
||||
#define BAD_RSSI -80
|
||||
#define EXCELLENT_RSSI_WEIGHT 100
|
||||
#define RSSI_BUCKET 5
|
||||
#define RSSI_WEIGHT_BUCKET 250
|
||||
|
||||
#define BEST_CANDIDATE_80MHZ 100
|
||||
#define BEST_CANDIDATE_40MHZ 70
|
||||
#define BEST_CANDIDATE_20MHZ 30
|
||||
#define SCM_PCL_RSSI_THRESHOLD -75
|
||||
#define BEST_CANDIDATE_MAX_BSS_SCORE 10000
|
||||
|
||||
/**
|
||||
@@ -213,4 +184,13 @@ QDF_STATUS scm_db_init(struct wlan_objmgr_psoc *psoc);
|
||||
* Return: QDF_STATUS
|
||||
*/
|
||||
QDF_STATUS scm_db_deinit(struct wlan_objmgr_psoc *psoc);
|
||||
|
||||
/**
|
||||
* scm_validate_scoring_config() - validate score config
|
||||
* @score_cfg: config to be validated
|
||||
*
|
||||
* Return: void
|
||||
*/
|
||||
void scm_validate_scoring_config(
|
||||
struct scoring_config *score_cfg);
|
||||
#endif
|
||||
|
@@ -53,37 +53,11 @@ bool scm_filter_match(struct wlan_objmgr_psoc *psoc,
|
||||
bool scm_is_better_bss(struct scan_default_params *params,
|
||||
struct scan_cache_entry *bss1,
|
||||
struct scan_cache_entry *bss2);
|
||||
/**
|
||||
* scm_derive_prefer_value_from_rssi() - to derive prefer value
|
||||
* @params: scan params
|
||||
* @filter: filter
|
||||
* @rssi: RSSI of the BSS
|
||||
*
|
||||
* This routine will derive preferred value from given rssi
|
||||
*
|
||||
* Return: value between 0 to 14
|
||||
*/
|
||||
static inline int
|
||||
scm_derive_prefer_value_from_rssi(struct scan_default_params *params,
|
||||
int rssi)
|
||||
{
|
||||
int i = SCM_NUM_RSSI_CAT - 1, pref_val = 0;
|
||||
|
||||
while (i >= 0) {
|
||||
if (rssi >= params->rssi_cat[i]) {
|
||||
pref_val = params->bss_prefer_val[i];
|
||||
break;
|
||||
}
|
||||
i--;
|
||||
};
|
||||
|
||||
return pref_val;
|
||||
}
|
||||
|
||||
/**
|
||||
* scm_calculate_bss_score() - calculate BSS score used to get
|
||||
* the preference
|
||||
* psoc: psoc ptr;
|
||||
* @psoc: psoc ptr;
|
||||
* @params: scan params
|
||||
* @entry: scan entry for which score needs to be calculated
|
||||
* @pcl_chan_weight: weight for pcl channel
|
||||
|
@@ -25,205 +25,766 @@
|
||||
#include "wlan_scan_cache_db.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
|
||||
|
||||
#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
|
||||
/* 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_OCE_WAN_DL_CAP 16
|
||||
|
||||
#define SCM_MAX_WEIGHT_OF_PCL_CHANNELS 255
|
||||
#define SCM_PCL_GROUPS_WEIGHT_DIFFERENCE 20
|
||||
|
||||
bool scm_is_better_bss(struct scan_default_params *params,
|
||||
struct scan_cache_entry *bss1,
|
||||
struct scan_cache_entry *bss2)
|
||||
{
|
||||
bool ret;
|
||||
if (bss1->bss_score > bss2->bss_score)
|
||||
ret = true;
|
||||
else
|
||||
ret = false;
|
||||
return ret;
|
||||
return true;
|
||||
else if (bss1->bss_score == bss2->bss_score)
|
||||
if (bss1->rssi_raw > bss2->rssi_raw)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* scm_limit_max_per_index_score() -check if per index score does not exceed
|
||||
* 100% (0x64). If it exceed make it 100%
|
||||
*
|
||||
* @per_index_score: per_index_score as input
|
||||
*
|
||||
* Return: per_index_score within the max limit
|
||||
*/
|
||||
static uint32_t scm_limit_max_per_index_score(uint32_t per_index_score)
|
||||
{
|
||||
uint8_t i, score;
|
||||
|
||||
for (i = 0; i < MAX_INDEX_PER_INI; i++) {
|
||||
score = WLAN_GET_SCORE_PERCENTAGE(per_index_score, i);
|
||||
if (score > MAX_INDEX_SCORE)
|
||||
WLAN_SET_SCORE_PERCENTAGE(per_index_score,
|
||||
MAX_INDEX_SCORE, i);
|
||||
}
|
||||
|
||||
return per_index_score;
|
||||
}
|
||||
|
||||
void scm_validate_scoring_config(struct scoring_config *score_cfg)
|
||||
{
|
||||
int total_weight;
|
||||
|
||||
total_weight = score_cfg->weight_cfg.rssi_weightage +
|
||||
score_cfg->weight_cfg.ht_caps_weightage +
|
||||
score_cfg->weight_cfg.vht_caps_weightage +
|
||||
score_cfg->weight_cfg.chan_width_weightage +
|
||||
score_cfg->weight_cfg.chan_band_weightage +
|
||||
score_cfg->weight_cfg.nss_weightage +
|
||||
score_cfg->weight_cfg.beamforming_cap_weightage +
|
||||
score_cfg->weight_cfg.pcl_weightage +
|
||||
score_cfg->weight_cfg.channel_congestion_weightage +
|
||||
score_cfg->weight_cfg.oce_wan_weightage;
|
||||
|
||||
if (total_weight > BEST_CANDIDATE_MAX_WEIGHT) {
|
||||
|
||||
scm_err("total weight is greater than %d fallback to default values",
|
||||
BEST_CANDIDATE_MAX_WEIGHT);
|
||||
|
||||
score_cfg->weight_cfg.rssi_weightage = RSSI_WEIGHTAGE;
|
||||
score_cfg->weight_cfg.ht_caps_weightage =
|
||||
HT_CAPABILITY_WEIGHTAGE;
|
||||
score_cfg->weight_cfg.vht_caps_weightage = VHT_CAP_WEIGHTAGE;
|
||||
score_cfg->weight_cfg.chan_width_weightage =
|
||||
CHAN_WIDTH_WEIGHTAGE;
|
||||
score_cfg->weight_cfg.chan_band_weightage =
|
||||
CHAN_BAND_WEIGHTAGE;
|
||||
score_cfg->weight_cfg.nss_weightage = NSS_WEIGHTAGE;
|
||||
score_cfg->weight_cfg.beamforming_cap_weightage =
|
||||
BEAMFORMING_CAP_WEIGHTAGE;
|
||||
score_cfg->weight_cfg.pcl_weightage = PCL_WEIGHT;
|
||||
score_cfg->weight_cfg.channel_congestion_weightage =
|
||||
CHANNEL_CONGESTION_WEIGHTAGE;
|
||||
score_cfg->weight_cfg.oce_wan_weightage = OCE_WAN_WEIGHTAGE;
|
||||
}
|
||||
|
||||
score_cfg->bandwidth_weight_per_index =
|
||||
scm_limit_max_per_index_score(
|
||||
score_cfg->bandwidth_weight_per_index);
|
||||
score_cfg->nss_weight_per_index =
|
||||
scm_limit_max_per_index_score(score_cfg->nss_weight_per_index);
|
||||
score_cfg->band_weight_per_index =
|
||||
scm_limit_max_per_index_score(score_cfg->band_weight_per_index);
|
||||
|
||||
|
||||
score_cfg->esp_qbss_scoring.score_pcnt3_to_0 =
|
||||
scm_limit_max_per_index_score(
|
||||
score_cfg->esp_qbss_scoring.score_pcnt3_to_0);
|
||||
score_cfg->esp_qbss_scoring.score_pcnt7_to_4 =
|
||||
scm_limit_max_per_index_score(
|
||||
score_cfg->esp_qbss_scoring.score_pcnt7_to_4);
|
||||
score_cfg->esp_qbss_scoring.score_pcnt11_to_8 =
|
||||
scm_limit_max_per_index_score(
|
||||
score_cfg->esp_qbss_scoring.score_pcnt11_to_8);
|
||||
score_cfg->esp_qbss_scoring.score_pcnt15_to_12 =
|
||||
scm_limit_max_per_index_score(
|
||||
score_cfg->esp_qbss_scoring.score_pcnt15_to_12);
|
||||
|
||||
score_cfg->oce_wan_scoring.score_pcnt3_to_0 =
|
||||
scm_limit_max_per_index_score(
|
||||
score_cfg->oce_wan_scoring.score_pcnt3_to_0);
|
||||
score_cfg->oce_wan_scoring.score_pcnt7_to_4 =
|
||||
scm_limit_max_per_index_score(
|
||||
score_cfg->oce_wan_scoring.score_pcnt7_to_4);
|
||||
score_cfg->oce_wan_scoring.score_pcnt11_to_8 =
|
||||
scm_limit_max_per_index_score(
|
||||
score_cfg->oce_wan_scoring.score_pcnt11_to_8);
|
||||
score_cfg->oce_wan_scoring.score_pcnt15_to_12 =
|
||||
scm_limit_max_per_index_score(
|
||||
score_cfg->oce_wan_scoring.score_pcnt15_to_12);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 = (BEST_CANDIDATE_MAX_WEIGHT * 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 * BEST_CANDIDATE_MAX_WEIGHT;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 BEST_CANDIDATE_MAX_WEIGHT;
|
||||
|
||||
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;
|
||||
|
||||
bw_weight_per_idx = score_config->bandwidth_weight_per_index;
|
||||
|
||||
if (WLAN_CHAN_IS_2GHZ(entry->channel.chan_idx)) {
|
||||
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 (entry->phy_mode == WLAN_PHYMODE_11AC_VHT80_80 ||
|
||||
entry->phy_mode == WLAN_PHYMODE_11AC_VHT160)
|
||||
ch_width_index = SCM_160MHZ_BW_INDEX;
|
||||
else if (entry->phy_mode == WLAN_PHYMODE_11AC_VHT80)
|
||||
ch_width_index = SCM_80MHZ_BW_INDEX;
|
||||
else if (entry->phy_mode == WLAN_PHYMODE_11NA_HT40PLUS ||
|
||||
entry->phy_mode == WLAN_PHYMODE_11NA_HT40MINUS ||
|
||||
entry->phy_mode == WLAN_PHYMODE_11NG_HT40PLUS ||
|
||||
entry->phy_mode == WLAN_PHYMODE_11NG_HT40MINUS ||
|
||||
entry->phy_mode == WLAN_PHYMODE_11NG_HT40 ||
|
||||
entry->phy_mode == WLAN_PHYMODE_11NA_HT40 ||
|
||||
entry->phy_mode == WLAN_PHYMODE_11AC_VHT40PLUS ||
|
||||
entry->phy_mode == WLAN_PHYMODE_11AC_VHT40MINUS ||
|
||||
entry->phy_mode == WLAN_PHYMODE_11AC_VHT40)
|
||||
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) /
|
||||
BEST_CANDIDATE_MAX_WEIGHT;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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_calculate_congestion_score () - Calculate congestion score
|
||||
* @entry: bss information
|
||||
* @score_params: bss score params
|
||||
*
|
||||
* Return : congestion score
|
||||
*/
|
||||
static int32_t scm_calculate_congestion_score(
|
||||
struct scan_cache_entry *entry,
|
||||
struct scoring_config *score_params)
|
||||
{
|
||||
uint32_t ap_load = 0;
|
||||
uint32_t est_air_time_percentage = 0;
|
||||
uint32_t congestion = 0;
|
||||
uint32_t window_size;
|
||||
uint8_t index;
|
||||
int32_t good_rssi_threshold;
|
||||
|
||||
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 (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 *
|
||||
BEST_CANDIDATE_MAX_WEIGHT);
|
||||
/*
|
||||
* Calculate ap_load in % from qbss channel load from
|
||||
* 0-255 range
|
||||
*/
|
||||
congestion = qdf_do_div(ap_load, MAX_AP_LOAD);
|
||||
} else {
|
||||
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 = BEST_CANDIDATE_MAX_WEIGHT /
|
||||
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, 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)
|
||||
{
|
||||
uint8_t nss;
|
||||
uint8_t score_pct;
|
||||
uint8_t sta_nss;
|
||||
|
||||
sta_nss = score_config->nss;
|
||||
|
||||
#ifdef WLAN_POLICY_MGR_ENABLE
|
||||
if (policy_mgr_is_current_hwmode_dbs(psoc))
|
||||
sta_nss--;
|
||||
#endif
|
||||
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) / BEST_CANDIDATE_MAX_WEIGHT;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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_MAX_OCE_WAN_DL_CAP/
|
||||
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);
|
||||
/* Desired values are from 1 to 15, as 0 is for not present.*/
|
||||
index = qdf_do_div(wan_metrics.downlink_av_cap,
|
||||
window_size) + 1;
|
||||
} 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);
|
||||
}
|
||||
|
||||
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 ap_load = 0;
|
||||
int32_t normalised_width = BEST_CANDIDATE_20MHZ;
|
||||
int32_t rssi_score = 0;
|
||||
int32_t pcl_score = 0;
|
||||
uint64_t temp_pcl_chan_weight = 0;
|
||||
int32_t est_air_time_percentage = 0;
|
||||
int32_t congestion = 0;
|
||||
int32_t rssi_diff = 0;
|
||||
int32_t rssi_weight = 0;
|
||||
struct qbss_load_ie *qbss_load;
|
||||
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 oce_wan_score = 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;
|
||||
int32_t ht_score, vht_score, qbss_score = 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);
|
||||
/* If device and AP supports HT caps, extra 10% score will be added */
|
||||
if (score_config->ht_cap && entry->ie_list.htcap)
|
||||
ht_score = prorated_pcnt *
|
||||
weight_config->ht_caps_weightage;
|
||||
score += ht_score;
|
||||
|
||||
if (WLAN_CHAN_IS_2GHZ(entry->channel.chan_idx)) {
|
||||
if (score_config->vht_24G_cap)
|
||||
is_vht = true;
|
||||
} else if (score_config->vht_cap) {
|
||||
is_vht = true;
|
||||
}
|
||||
/*
|
||||
* Total weight of a BSSID is calculated on basis of 100 in which
|
||||
* contribution of every factor is considered like this.
|
||||
* RSSI: RSSI_WEIGHTAGE : 25
|
||||
* HT_CAPABILITY_WEIGHTAGE: 7
|
||||
* VHT_CAP_WEIGHTAGE: 5
|
||||
* BEAMFORMING_CAP_WEIGHTAGE: 2
|
||||
* CHAN_WIDTH_WEIGHTAGE:10
|
||||
* CHAN_BAND_WEIGHTAGE: 5
|
||||
* NSS: 5
|
||||
* PCL: 10
|
||||
* CHANNEL_CONGESTION: 5
|
||||
* Reserved: 31
|
||||
* If device and AP supports VHT caps, Extra 6% score will
|
||||
* be added to score
|
||||
*/
|
||||
/*
|
||||
* Further bucketization of rssi is also done out of 25 score.
|
||||
* RSSI > -55=> weight = 2500
|
||||
* RSSI > -60=> weight = 2250
|
||||
* RSSI >-65 =>weight = 2000
|
||||
* RSSI > -70=> weight = 1750
|
||||
* RSSI > -75=> weight = 1500
|
||||
* RSSI > -80=> weight = 1250
|
||||
*/
|
||||
if (entry->rssi_raw) {
|
||||
/*
|
||||
* if RSSI of AP is less then -80, driver should ignore that
|
||||
* candidate.
|
||||
*/
|
||||
if (entry->rssi_raw < BAD_RSSI) {
|
||||
scm_err("Drop this BSS %pM due to low rssi %d",
|
||||
entry->bssid.bytes, entry->rssi_raw);
|
||||
score = 0;
|
||||
return score;
|
||||
}
|
||||
if (entry->rssi_raw >= EXCELLENT_RSSI) {
|
||||
rssi_weight = EXCELLENT_RSSI_WEIGHT *
|
||||
RSSI_WEIGHTAGE;
|
||||
} else {
|
||||
rssi_diff = EXCELLENT_RSSI - entry->rssi_raw;
|
||||
rssi_diff = rssi_diff/5;
|
||||
rssi_weight = (rssi_diff + 1) * RSSI_WEIGHT_BUCKET;
|
||||
rssi_weight = (EXCELLENT_RSSI_WEIGHT *
|
||||
RSSI_WEIGHTAGE) - rssi_weight;
|
||||
if (is_vht && entry->ie_list.vhtcap)
|
||||
vht_score = prorated_pcnt *
|
||||
weight_config->vht_caps_weightage;
|
||||
score += vht_score;
|
||||
|
||||
}
|
||||
score += rssi_weight;
|
||||
}
|
||||
if (pcl_chan_weight) {
|
||||
temp_pcl_chan_weight =
|
||||
(SCM_MAX_WEIGHT_OF_PCL_CHANNELS - pcl_chan_weight);
|
||||
do_div(temp_pcl_chan_weight,
|
||||
20);
|
||||
pcl_score = PCL_WEIGHT - temp_pcl_chan_weight;
|
||||
if (score_config->he_cap && entry->ie_list.hecap)
|
||||
he_score = prorated_pcnt *
|
||||
weight_config->he_caps_weightage;
|
||||
score += he_score;
|
||||
|
||||
if (pcl_score < 0)
|
||||
pcl_score = 0;
|
||||
bandwidth_score = scm_calculate_bandwidth_score(entry, score_config,
|
||||
prorated_pcnt);
|
||||
score += bandwidth_score;
|
||||
|
||||
score += pcl_score * BEST_CANDIDATE_MAX_WEIGHT;
|
||||
}
|
||||
/* If AP supports HT caps, extra 10% score will be added */
|
||||
if (entry->ie_list.htcap) {
|
||||
ht_score = BEST_CANDIDATE_MAX_WEIGHT * HT_CAPABILITY_WEIGHTAGE;
|
||||
score += BEST_CANDIDATE_MAX_WEIGHT * HT_CAPABILITY_WEIGHTAGE;
|
||||
}
|
||||
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);
|
||||
|
||||
/* If AP supports VHT caps, Extra 6% score will be added to score */
|
||||
if (entry->ie_list.vhtcap) {
|
||||
vht_score = BEST_CANDIDATE_MAX_WEIGHT * VHT_CAP_WEIGHTAGE;
|
||||
score += BEST_CANDIDATE_MAX_WEIGHT * VHT_CAP_WEIGHTAGE;
|
||||
}
|
||||
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 = BEST_CANDIDATE_MAX_WEIGHT *
|
||||
weight_config->beamforming_cap_weightage;
|
||||
score += beamformee_score;
|
||||
|
||||
/*
|
||||
* Channel width is again calculated on basis of 100.
|
||||
* Where if AP is
|
||||
* 80MHZ = 100
|
||||
* 40MHZ = 70
|
||||
* 20MHZ = 30 weightage is given out of 100.
|
||||
* Channel width weightage is given as CHAN_WIDTH_WEIGHTAGE (10%).
|
||||
* If AP is on 5Ghz 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 GH.
|
||||
*/
|
||||
if (entry->phy_mode == WLAN_PHYMODE_11AC_VHT20 ||
|
||||
entry->phy_mode == WLAN_PHYMODE_11AC_VHT40PLUS ||
|
||||
entry->phy_mode == WLAN_PHYMODE_11AC_VHT40MINUS ||
|
||||
entry->phy_mode == WLAN_PHYMODE_11AC_VHT40 ||
|
||||
entry->phy_mode == WLAN_PHYMODE_11AC_VHT80 ||
|
||||
entry->phy_mode == WLAN_PHYMODE_11AC_VHT80_80 ||
|
||||
entry->phy_mode == WLAN_PHYMODE_11AC_VHT160)
|
||||
normalised_width = BEST_CANDIDATE_80MHZ;
|
||||
else if (entry->phy_mode == WLAN_PHYMODE_11NA_HT40PLUS ||
|
||||
entry->phy_mode == WLAN_PHYMODE_11NA_HT40MINUS ||
|
||||
entry->phy_mode == WLAN_PHYMODE_11NG_HT40PLUS ||
|
||||
entry->phy_mode == WLAN_PHYMODE_11NG_HT40MINUS ||
|
||||
entry->phy_mode == WLAN_PHYMODE_11NG_HT40 ||
|
||||
entry->phy_mode == WLAN_PHYMODE_11NA_HT40)
|
||||
normalised_width = BEST_CANDIDATE_40MHZ;
|
||||
else
|
||||
normalised_width = BEST_CANDIDATE_20MHZ;
|
||||
score += normalised_width * CHAN_WIDTH_WEIGHTAGE;
|
||||
if ((entry->rssi_raw > rssi_pref_5g_rssi_thresh) && !same_bucket) {
|
||||
if (WLAN_CHAN_IS_2GHZ(entry->channel.chan_idx))
|
||||
band_score = weight_config->chan_band_weightage *
|
||||
WLAN_GET_SCORE_PERCENTAGE(
|
||||
score_config->band_weight_per_index,
|
||||
SCM_BAND_5G_INDEX);
|
||||
} else if (WLAN_CHAN_IS_2GHZ(entry->channel.chan_idx)) {
|
||||
band_score = weight_config->chan_band_weightage *
|
||||
WLAN_GET_SCORE_PERCENTAGE(
|
||||
score_config->band_weight_per_index,
|
||||
SCM_BAND_2G_INDEX);
|
||||
}
|
||||
score += band_score;
|
||||
|
||||
congestion_score = scm_calculate_congestion_score(entry, score_config);
|
||||
score += congestion_score;
|
||||
|
||||
if (util_scan_scm_chan_to_band(
|
||||
entry->channel.chan_idx) == WLAN_BAND_5_GHZ &&
|
||||
entry->rssi_raw > RSSI_THRESHOLD_5GHZ)
|
||||
score += BEST_CANDIDATE_MAX_WEIGHT * CHAN_BAND_WEIGHTAGE;
|
||||
/*
|
||||
* If ESP is being transmitted by the AP, use the estimated airtime for
|
||||
* AC_BE from that, Estimated airtime 0-25% = 120, 25-50% = 250, 50-75%
|
||||
* = 370, 75-100% = 500.
|
||||
* Else if QBSSLoad is being transmitted and QBSSLoad < 25% = 500
|
||||
* else assing default weight of 370
|
||||
* 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 (entry->air_time_fraction) {
|
||||
est_air_time_percentage =
|
||||
entry->air_time_fraction * ROAM_MAX_CHANNEL_WEIGHT;
|
||||
est_air_time_percentage =
|
||||
est_air_time_percentage/MAX_ESTIMATED_AIR_TIME_FRACTION;
|
||||
/*
|
||||
* Calculate channel congestion from estimated air time
|
||||
* fraction.
|
||||
*/
|
||||
congestion = MAX_CHANNEL_UTILIZATION - est_air_time_percentage;
|
||||
if (congestion >= LOW_CHANNEL_CONGESTION &&
|
||||
congestion < MODERATE_CHANNEL_CONGESTION)
|
||||
score += LOW_CHANNEL_CONGESTION_WEIGHT;
|
||||
else if (congestion >= MODERATE_CHANNEL_CONGESTION &&
|
||||
congestion < CONSIDERABLE_CHANNEL_CONGESTION)
|
||||
score += MODERATE_CHANNEL_CONGESTION_WEIGHT;
|
||||
else if (congestion >= CONSIDERABLE_CHANNEL_CONGESTION &&
|
||||
congestion < HIGH_CHANNEL_CONGESTION)
|
||||
score += CONSIDERABLE_CHANNEL_CONGESTION_WEIGHT;
|
||||
else
|
||||
score += HIGH_CHANNEL_CONGESTION_WEIGHT;
|
||||
} else if (entry->ie_list.qbssload) {
|
||||
qbss_load = (struct qbss_load_ie *)
|
||||
util_scan_entry_qbssload(entry);
|
||||
scm_debug("qbss_load is %d", qbss_load->qbss_chan_load);
|
||||
/*
|
||||
* Calculate ap_load in % from qbss channel load from 0-255
|
||||
* range
|
||||
*/
|
||||
ap_load = (qbss_load->qbss_chan_load *
|
||||
BEST_CANDIDATE_MAX_WEIGHT);
|
||||
ap_load = ap_load/MAX_AP_LOAD;
|
||||
congestion = ap_load;
|
||||
if (congestion < MODERATE_CHANNEL_CONGESTION) {
|
||||
qbss_score = LOW_CHANNEL_CONGESTION_WEIGHT;
|
||||
score += LOW_CHANNEL_CONGESTION_WEIGHT;
|
||||
} else {
|
||||
qbss_score = HIGH_CHANNEL_CONGESTION_WEIGHT;
|
||||
score += HIGH_CHANNEL_CONGESTION_WEIGHT;
|
||||
}
|
||||
} else {
|
||||
qbss_score = MODERATE_CHANNEL_CONGESTION_WEIGHT;
|
||||
scm_debug("qbss load is not present so qbss_Score is %d",
|
||||
qbss_score);
|
||||
score += MODERATE_CHANNEL_CONGESTION_WEIGHT;
|
||||
}
|
||||
scm_debug(" ht_score %d vht_score %d and qbss_score %d",
|
||||
ht_score, vht_score, qbss_score);
|
||||
scm_debug(" BSS %pM rssi %d channel %d final score %d",
|
||||
entry->bssid.bytes,
|
||||
entry->rssi_raw, entry->channel.chan_idx,
|
||||
score);
|
||||
scm_info("nss %d", entry->nss);
|
||||
nss_score = scm_calculate_nss_score(psoc, score_config, entry->nss,
|
||||
prorated_pcnt);
|
||||
score += nss_score;
|
||||
|
||||
oce_wan_score = scm_calculate_oce_wan_score(entry, score_config);
|
||||
score += oce_wan_score;
|
||||
|
||||
scm_debug("Self Cap: 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, score_config->nss);
|
||||
|
||||
scm_debug("Candidate (BSSID: %pM Chan %d) Cap:: rssi=%d HT=%d VHT=%d HE %d su beamformer %d phymode=%d air time fraction %d qbss load %d NSS %d",
|
||||
entry->bssid.bytes, entry->channel.chan_idx,
|
||||
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, entry->nss);
|
||||
|
||||
scm_debug("Candidate Scores : prorated_pcnt %d rssi %d pcl %d ht %d vht %d he %d beamformee %d bw %d band %d congestion %d nss %d oce wan %d TOTAL score %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, score);
|
||||
|
||||
entry->bss_score = score;
|
||||
return score;
|
||||
}
|
||||
|
@@ -365,6 +365,7 @@ struct scan_default_params {
|
||||
uint32_t scan_events;
|
||||
};
|
||||
struct roam_filter_params roam_params;
|
||||
struct scoring_config score_config;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@@ -35,18 +35,6 @@ typedef uint32_t wlan_scan_id;
|
||||
#define WLAN_SCAN_MAX_NUM_BSSID 10
|
||||
#define WLAN_SCAN_MAX_NUM_CHANNELS 40
|
||||
|
||||
#define SCM_PCL_ADVANTAGE 30
|
||||
#define SCM_PCL_RSSI_THRESHOLD -75
|
||||
#define SCM_MAX_WEIGHT_OF_PCL_CHANNELS 255
|
||||
|
||||
#define SCM_BSS_CAP_VALUE_NONE 0/* not much value */
|
||||
#define SCM_BSS_CAP_VALUE_HT 1
|
||||
#define SCM_BSS_CAP_VALUE_VHT 2
|
||||
#define SCM_BSS_CAP_VALUE_HE 3
|
||||
#define SCM_BSS_CAP_VALUE_WMM 1
|
||||
#define SCM_BSS_CAP_VALUE_UAPSD 1
|
||||
#define SCM_BSS_CAP_VALUE_5GHZ 2
|
||||
|
||||
#define SCM_CANCEL_SCAN_WAIT_TIME 50
|
||||
#define SCM_CANCEL_SCAN_WAIT_ITERATION 600
|
||||
|
||||
@@ -157,6 +145,7 @@ struct element_info {
|
||||
* @srp: pointer to spatial reuse parameter sub extended ie
|
||||
* @fils_indication: pointer to FILS indication ie
|
||||
* @esp: pointer to ESP indication ie
|
||||
* @mbo_oce: pointer to mbo/oce indication ie
|
||||
*/
|
||||
struct ie_list {
|
||||
uint8_t *tim;
|
||||
@@ -200,6 +189,7 @@ struct ie_list {
|
||||
uint8_t *srp;
|
||||
uint8_t *fils_indication;
|
||||
uint8_t *esp;
|
||||
uint8_t *mbo_oce;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -268,6 +258,7 @@ struct security_info {
|
||||
* @erp: erp info
|
||||
* @dtim_period: dtime period
|
||||
* @air_time_fraction: Air time fraction from ESP param
|
||||
* @qbss_chan_load: Qbss channel load
|
||||
* @nss: supported NSS information
|
||||
* @is_p2p_ssid: is P2P entry
|
||||
* @scan_entry_time: boottime in microsec when last beacon/probe is received
|
||||
@@ -278,8 +269,6 @@ struct security_info {
|
||||
* @channel_mismatch: if channel received in metadata
|
||||
* doesnot match the one in beacon
|
||||
* @tsf_delta: TSF delta
|
||||
* @prefer_value: Preffer value calulated for the AP
|
||||
* @cap_value: Capability value calculated for the AP
|
||||
* @bss_score: bss score calculated on basis of RSSI/caps etc.
|
||||
* @neg_sec_info: negotiated security info
|
||||
* @rrm_parent_tsf: RRM parent tsf
|
||||
@@ -306,6 +295,7 @@ struct scan_cache_entry {
|
||||
uint8_t erp;
|
||||
uint8_t dtim_period;
|
||||
uint8_t air_time_fraction;
|
||||
uint8_t qbss_chan_load;
|
||||
uint8_t nss;
|
||||
bool is_p2p;
|
||||
qdf_time_t scan_entry_time;
|
||||
@@ -315,8 +305,6 @@ struct scan_cache_entry {
|
||||
bool channel_mismatch;
|
||||
struct mlme_info mlme_info;
|
||||
uint32_t tsf_delta;
|
||||
uint32_t prefer_value;
|
||||
uint32_t cap_val;
|
||||
uint32_t bss_score;
|
||||
struct security_info neg_sec_info;
|
||||
uint32_t rrm_parent_tsf;
|
||||
@@ -335,40 +323,137 @@ struct scan_cache_entry {
|
||||
* avoid connecting to. It is like a
|
||||
* blacklist of BSSID's.
|
||||
* also for roaming apart from the connected one's
|
||||
* @num_bssid_favored: Number of BSSID's which have a preference over
|
||||
* others
|
||||
* @raise_rssi_thresh_5g: The RSSI threshold below which the
|
||||
* raise_factor_5g (boost factor) should be
|
||||
* applied.
|
||||
* @drop_rssi_thresh_5g: The RSSI threshold beyond which the
|
||||
* drop_factor_5g (penalty factor) should be
|
||||
* applied
|
||||
* @raise_factor_5g: Boost factor
|
||||
* @drop_factor_5g: Penalty factor
|
||||
* @max_raise_rssi_5g: Maximum amount of Boost that can added
|
||||
* @max_drop_rssi_5g: Maximum amount of penalty that can be subtracted
|
||||
* @is_5g_pref_enabled: 5GHz BSSID preference feature enable/disable.
|
||||
* @bssid_avoid_list: Blacklist SSID's
|
||||
* @bssid_favored: Favorable BSSID's
|
||||
* @bssid_favored_factor: RSSI to be added to this BSSID to prefer it
|
||||
*
|
||||
* This structure holds all the key parameters related to
|
||||
* initial connection and also roaming connections.
|
||||
*/
|
||||
struct roam_filter_params {
|
||||
uint32_t num_bssid_avoid_list;
|
||||
uint32_t num_bssid_favored;
|
||||
int raise_rssi_thresh_5g;
|
||||
int drop_rssi_thresh_5g;
|
||||
uint32_t raise_factor_5g;
|
||||
uint32_t drop_factor_5g;
|
||||
int max_raise_rssi_5g;
|
||||
int max_drop_rssi_5g;
|
||||
uint32_t is_5g_pref_enabled;
|
||||
/* Variable params list */
|
||||
struct qdf_mac_addr bssid_avoid_list[MAX_AVOID_LIST_BSSID];
|
||||
struct qdf_mac_addr bssid_favored[MAX_FAVORED_BSSID];
|
||||
uint8_t bssid_favored_factor[MAX_FAVORED_BSSID];
|
||||
};
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
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;
|
||||
};
|
||||
|
||||
/**
|
||||
* 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 nss;
|
||||
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
|
||||
@@ -1112,6 +1197,7 @@ struct pno_user_cfg {
|
||||
* @ie_whitelist: probe req IE whitelist attrs
|
||||
* @is_bssid_hint_priority: True if bssid_hint is priority
|
||||
* @enable_mac_spoofing: enable mac address spoof in scan
|
||||
* @score_config: scoring logic configuration
|
||||
*/
|
||||
struct scan_user_cfg {
|
||||
uint32_t active_dwell;
|
||||
@@ -1134,6 +1220,7 @@ struct scan_user_cfg {
|
||||
uint32_t usr_cfg_num_probes;
|
||||
bool is_bssid_hint_priority;
|
||||
bool enable_mac_spoofing;
|
||||
struct scoring_config score_config;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@@ -652,6 +652,7 @@ util_scan_copy_beacon_data(struct scan_cache_entry *new_entry,
|
||||
ie_lst->fils_indication = conv_ptr(ie_lst->fils_indication,
|
||||
old_ptr, new_ptr);
|
||||
ie_lst->esp = conv_ptr(ie_lst->esp, old_ptr, new_ptr);
|
||||
ie_lst->mbo_oce = conv_ptr(ie_lst->mbo_oce, old_ptr, new_ptr);
|
||||
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
@@ -1369,6 +1370,20 @@ util_scan_entry_esp_info(struct scan_cache_entry *scan_entry)
|
||||
return scan_entry->ie_list.esp;
|
||||
}
|
||||
|
||||
/**
|
||||
* util_scan_entry_mbo_oce() - function to read MBO/OCE ie
|
||||
* @scan_entry: scan entry
|
||||
*
|
||||
* API, function to read MBO/OCE ie
|
||||
*
|
||||
* Return: MBO/OCE ie
|
||||
*/
|
||||
static inline uint8_t *
|
||||
util_scan_entry_mbo_oce(struct scan_cache_entry *scan_entry)
|
||||
{
|
||||
return scan_entry->ie_list.mbo_oce;
|
||||
}
|
||||
|
||||
/**
|
||||
* util_scan_scm_chan_to_band() - function to tell band for channel number
|
||||
* @chan: Channel number
|
||||
|
@@ -1313,8 +1313,14 @@ QDF_STATUS ucfg_scan_update_user_config(struct wlan_objmgr_psoc *psoc,
|
||||
scan_cfg->scan_bucket_threshold,
|
||||
scan_cfg->rssi_cat_gap);
|
||||
|
||||
return ucfg_scan_update_pno_config(&scan_obj->pno_cfg,
|
||||
ucfg_scan_update_pno_config(&scan_obj->pno_cfg,
|
||||
&scan_cfg->pno_cfg);
|
||||
|
||||
qdf_mem_copy(&scan_def->score_config, &scan_cfg->score_config,
|
||||
sizeof(struct scoring_config));
|
||||
scm_validate_scoring_config(&scan_def->score_config);
|
||||
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
QDF_STATUS ucfg_scan_update_roam_params(struct wlan_objmgr_psoc *psoc,
|
||||
|
@@ -417,6 +417,8 @@ util_scan_parse_vendor_ie(struct scan_cache_entry *scan_params,
|
||||
* hence copy data just after version byte
|
||||
*/
|
||||
scan_params->ie_list.bwnss_map = (((uint8_t *)ie) + 8);
|
||||
} else if (is_mbo_oce_oui((uint8_t *)ie)) {
|
||||
scan_params->ie_list.mbo_oce = (uint8_t *)ie;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -727,6 +729,7 @@ util_scan_unpack_beacon_frame(uint8_t *frame,
|
||||
QDF_STATUS status;
|
||||
struct ie_ssid *ssid;
|
||||
struct scan_cache_entry *scan_entry = NULL;
|
||||
struct qbss_load_ie *qbss_load;
|
||||
|
||||
scan_entry = qdf_mem_malloc(sizeof(*scan_entry));
|
||||
if (!scan_entry) {
|
||||
@@ -832,6 +835,10 @@ util_scan_unpack_beacon_frame(uint8_t *frame,
|
||||
|
||||
scan_entry->nss = util_scan_scm_calc_nss_supported_by_ap(scan_entry);
|
||||
util_scan_scm_update_bss_with_esp_data(scan_entry);
|
||||
qbss_load = (struct qbss_load_ie *)
|
||||
util_scan_entry_qbssload(scan_entry);
|
||||
if (qbss_load)
|
||||
scan_entry->qbss_chan_load = qbss_load->qbss_chan_load;
|
||||
|
||||
/* TODO calculate channel struct */
|
||||
return scan_entry;
|
||||
|
Reference in New Issue
Block a user