From 06869dc0286001c981addd4bb9124721df574bc7 Mon Sep 17 00:00:00 2001 From: sheenam monga Date: Mon, 16 Mar 2020 15:50:04 +0530 Subject: [PATCH] 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 --- .../cmn_defs/inc/wlan_cmn_ieee80211.h | 48 ++++++++++ umac/scan/core/src/wlan_scan_bss_score.c | 88 ++++++++++++++++++- .../dispatcher/inc/wlan_scan_public_structs.h | 3 + wmi/inc/wmi_unified_roam_param.h | 2 + wmi/src/wmi_unified_roam_tlv.c | 5 +- 5 files changed, 142 insertions(+), 4 deletions(-) diff --git a/umac/cmn_services/cmn_defs/inc/wlan_cmn_ieee80211.h b/umac/cmn_services/cmn_defs/inc/wlan_cmn_ieee80211.h index 050bb28d051c..f6b719851cf2 100644 --- a/umac/cmn_services/cmn_defs/inc/wlan_cmn_ieee80211.h +++ b/umac/cmn_services/cmn_defs/inc/wlan_cmn_ieee80211.h @@ -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_ */ diff --git a/umac/scan/core/src/wlan_scan_bss_score.c b/umac/scan/core/src/wlan_scan_bss_score.c index 4e1bf7b38a34..36319051e155 100644 --- a/umac/scan/core/src/wlan_scan_bss_score.c +++ b/umac/scan/core/src/wlan_scan_bss_score.c @@ -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; diff --git a/umac/scan/dispatcher/inc/wlan_scan_public_structs.h b/umac/scan/dispatcher/inc/wlan_scan_public_structs.h index 7952dc2c38c0..a619887d8d4e 100644 --- a/umac/scan/dispatcher/inc/wlan_scan_public_structs.h +++ b/umac/scan/dispatcher/inc/wlan_scan_public_structs.h @@ -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; }; /** diff --git a/wmi/inc/wmi_unified_roam_param.h b/wmi/inc/wmi_unified_roam_param.h index 472fd880e5cc..29842f53874d 100644 --- a/wmi/inc/wmi_unified_roam_param.h +++ b/wmi/inc/wmi_unified_roam_param.h @@ -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; diff --git a/wmi/src/wmi_unified_roam_tlv.c b/wmi/src/wmi_unified_roam_tlv.c index 28ae2d4d719a..707957f408ba 100644 --- a/wmi/src/wmi_unified_roam_tlv.c +++ b/wmi/src/wmi_unified_roam_tlv.c @@ -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;