qcacmn: Send oce_ap_tx_pwr_weightage_pcnt to firmware

In struct weight_config, "oce_ap_tx_pwr_weightage" added newly.
Station uses "oce_ap_tx_pwr_weightage" as one of the parameter for
selecting AP candidate during initial connection. Host sends
"oce_ap_tx_pwr_weightage" ini value to firmware over WMI command
WMI_ROAM_AP_PROFILE.

Add oce_ap_tx_pwr_weightage in scan object scoring param to calculate
weightage based on AP tx power and select candidate accordingly.

Change-Id: I7f717e9cc398e8b9307f2f464f972b095c06364b
CRs-Fixed: 2647116
This commit is contained in:
sheenam monga 2020-03-16 15:50:04 +05:30 • committed by nshrivas
commit 06869dc028
5 changed files with 142 additions and 4 deletions

View file

@ -43,6 +43,7 @@
#define MBO_OCE_OUI 0x506f9a16
#define MBO_OCE_OUI_SIZE 4
#define REDUCED_WAN_METRICS_ATTR 103
#define AP_TX_PWR_ATTR 107
/* WCN IE */
/* Microsoft OUI */
@ -1901,4 +1902,51 @@ wlan_parse_oce_reduced_wan_metrics_ie(uint8_t *mbo_oce_ie,
return false;
}
/*
* wlan_parse_oce_ap_tx_pwr_ie() - parse oce ap tx pwr
* @mbo_oce_ie: MBO/OCE ie ptr
* @ap_tx_pwr: pointer to hold value of ap_tx_pwr in dbm
*
* Return: true if oce ap tx pwr is present, else false
*/
static inline bool
wlan_parse_oce_ap_tx_pwr_ie(uint8_t *mbo_oce_ie, int8_t *ap_tx_pwr_dbm)
{
uint8_t len, attribute_len, attribute_id;
uint8_t *ie;
int8_t ap_tx_power_in_2_complement;
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 == AP_TX_PWR_ATTR) {
ap_tx_power_in_2_complement = ie[2];
*ap_tx_pwr_dbm =
(int8_t)(256 - ap_tx_power_in_2_complement);
return true;
}
ie += (attribute_len + 2);
len -= attribute_len;
}
return false;
}
#endif /* _WLAN_CMN_IEEE80211_DEFS_H_ */

View file

@ -114,7 +114,8 @@ void scm_validate_scoring_config(struct scoring_config *score_cfg)
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;
score_cfg->weight_cfg.oce_wan_weightage +
score_cfg->weight_cfg.oce_ap_tx_pwr_weightage;
if (total_weight > BEST_CANDIDATE_MAX_WEIGHT) {
@ -136,6 +137,8 @@ void scm_validate_scoring_config(struct scoring_config *score_cfg)
score_cfg->weight_cfg.channel_congestion_weightage =
CHANNEL_CONGESTION_WEIGHTAGE;
score_cfg->weight_cfg.oce_wan_weightage = OCE_WAN_WEIGHTAGE;
score_cfg->weight_cfg.oce_ap_tx_pwr_weightage =
OCE_AP_TX_POWER_WEIGHTAGE;
}
score_cfg->bandwidth_weight_per_index =
@ -636,6 +639,81 @@ static int32_t scm_calculate_oce_wan_score(
&score_params->oce_wan_scoring);
}
/**
* scm_calculate_oce_ap_tx_pwr_weightage () - Calculate oce ap tx pwr weightage
* @entry: bss entry
* @score_params: bss score params
*
* 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 = 0;
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 = BEST_CANDIDATE_MAX_WEIGHT;
} 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;
scm_debug("ap_tx_pwr_cap_present %d ap_tx_pwr_dbm %d rssi %d normalize_ap_tx_pwr %d score %d weight %d",
ap_tx_pwr_cap_present, ap_tx_pwr_dbm, entry->rssi_raw,
normalized_ap_tx_pwr, score,
score_params->weight_cfg.oce_ap_tx_pwr_weightage);
return score;
}
#ifdef WLAN_POLICY_MGR_ENABLE
static uint32_t scm_get_sta_nss(struct wlan_objmgr_psoc *psoc,
@ -689,6 +767,7 @@ int scm_calculate_bss_score(struct wlan_objmgr_psoc *psoc,
int32_t congestion_score = 0;
int32_t congestion_pct = 0;
int32_t oce_wan_score = 0;
uint8_t oce_ap_tx_pwr_score;
uint8_t prorated_pcnt;
bool is_vht = false;
int8_t good_rssi_threshold;
@ -805,6 +884,9 @@ int scm_calculate_bss_score(struct wlan_objmgr_psoc *psoc,
score += oce_wan_score;
}
oce_ap_tx_pwr_score =
scm_calculate_oce_ap_tx_pwr_weightage(entry, score_config);
score += oce_ap_tx_pwr_score;
pdev = wlan_objmgr_get_pdev_by_id(psoc, entry->pdev_id, WLAN_SCAN_ID);
if (!pdev) {
scm_err("pdev is NULL");
@ -840,11 +922,11 @@ int scm_calculate_bss_score(struct wlan_objmgr_psoc *psoc,
entry->phy_mode, entry->air_time_fraction,
entry->qbss_chan_load, congestion_pct, entry->nss);
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 TOTAL %d",
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 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,
score);
oce_ap_tx_pwr_score, score);
entry->bss_score = score;
return score;

View file

@ -68,6 +68,7 @@ typedef uint32_t wlan_scan_id;
#define PCL_WEIGHT 10
#define CHANNEL_CONGESTION_WEIGHTAGE 5
#define OCE_WAN_WEIGHTAGE 0
#define OCE_AP_TX_POWER_WEIGHTAGE 5
#define BEST_CANDIDATE_MAX_WEIGHT 100
#define MAX_INDEX_SCORE 100
#define MAX_INDEX_PER_INI 4
@ -478,6 +479,7 @@ struct scan_cache_entry {
* @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
*/
struct weight_config {
uint8_t rssi_weightage;
@ -491,6 +493,7 @@ struct weight_config {
uint8_t pcl_weightage;
uint8_t channel_congestion_weightage;
uint8_t oce_wan_weightage;
uint8_t oce_ap_tx_pwr_weightage;
};
/**

View file

@ -375,6 +375,7 @@ struct param_slot_scoring {
* @beamforming_weightage: Beamforming weightage out of total score in %.
* @pcl_weightage: PCL weightage out of total score in %.
* @oce_wan_weightage OCE WAN metrics weightage out of total score in %.
* @oce_ap_tx_pwr_weightage: OCE AP TX power score in %
* @bw_index_score: channel BW scoring percentage information.
* BITS 0-7 :- It contains scoring percentage of 20MHz BW
* BITS 8-15 :- It contains scoring percentage of 40MHz BW
@ -416,6 +417,7 @@ struct scoring_param {
int32_t beamforming_weightage;
int32_t pcl_weightage;
int32_t oce_wan_weightage;
uint32_t oce_ap_tx_pwr_weightage;
uint32_t bw_index_score;
uint32_t band_index_score;
uint32_t nss_index_score;

View file

@ -1597,10 +1597,12 @@ send_roam_scan_offload_ap_profile_cmd_tlv(wmi_unified_t wmi_handle,
score_param->pcl_weightage_pcnt = ap_profile->param.pcl_weightage;
score_param->oce_wan_weightage_pcnt =
ap_profile->param.oce_wan_weightage;
score_param->oce_ap_tx_pwr_weightage_pcnt =
ap_profile->param.oce_ap_tx_pwr_weightage;
score_param->vendor_roam_score_algorithm_id =
ap_profile->param.vendor_roam_score_algorithm;
WMI_LOGD("Score params weightage: disable_bitmap %x rssi %d ht %d vht %d he %d BW %d band %d NSS %d ESP %d BF %d PCL %d OCE WAN %d roam score algo %d",
WMI_LOGD("Score params weightage: disable_bitmap %x rssi %d ht %d vht %d he %d BW %d band %d NSS %d ESP %d BF %d PCL %d OCE WAN %d APTX %d roam score algo %d",
score_param->disable_bitmap, score_param->rssi_weightage_pcnt,
score_param->ht_weightage_pcnt,
score_param->vht_weightage_pcnt,
@ -1611,6 +1613,7 @@ send_roam_scan_offload_ap_profile_cmd_tlv(wmi_unified_t wmi_handle,
score_param->beamforming_weightage_pcnt,
score_param->pcl_weightage_pcnt,
score_param->oce_wan_weightage_pcnt,
score_param->oce_ap_tx_pwr_weightage_pcnt,
score_param->vendor_roam_score_algorithm_id);
score_param->bw_scoring.score_pcnt = ap_profile->param.bw_index_score;