diff --git a/umac/mlme/connection_mgr/core/src/wlan_cm_bss_scoring.c b/umac/mlme/connection_mgr/core/src/wlan_cm_bss_scoring.c index 3271a0a74c07..988b4621292a 100644 --- a/umac/mlme/connection_mgr/core/src/wlan_cm_bss_scoring.c +++ b/umac/mlme/connection_mgr/core/src/wlan_cm_bss_scoring.c @@ -27,6 +27,10 @@ #include "wlan_cm_bss_score_param.h" #include "wlan_scan_api.h" #include "wlan_crypto_global_api.h" +#include "wlan_mgmt_txrx_utils_api.h" +#ifdef CONN_MGR_ADV_FEATURE +#include "wlan_mlme_api.h" +#endif #define CM_20MHZ_BW_INDEX 0 #define CM_40MHZ_BW_INDEX 1 @@ -96,6 +100,29 @@ #define CM_SET_SCORE_PERCENTAGE(value32, score_pcnt, bw_index) \ QDF_SET_BITS(value32, (8 * (bw_index)), 8, score_pcnt) +#ifdef CONN_MGR_ADV_FEATURE +/* 3.2 us + 0.8 us(GI) */ +#define PPDU_PAYLOAD_SYMBOL_DUR_US 4 +/* 12.8 us + (0.8 + 1.6)/2 us(GI) */ +#define HE_PPDU_PAYLOAD_SYMBOL_DUR_US 14 +#define MAC_HEADER_LEN 26 +/* Minimum snrDb supported by LUT */ +#define SNR_DB_TO_BIT_PER_TONE_LUT_MIN -10 +/* Maximum snrDb supported by LUT */ +#define SNR_DB_TO_BIT_PER_TONE_LUT_MAX 9 +#define DB_NUM 20 +/* + * A fudge factor to represent HW implementation margin in dB. + * Predicted throughput matches pretty well with OTA throughput with this + * fudge factor. + */ +#define SNR_MARGIN_DB 16 +#define TWO_IN_DB 3 +static int32_t +SNR_DB_TO_BIT_PER_TONE_LUT[DB_NUM] = {0, 171, 212, 262, 323, 396, 484, +586, 706, 844, 1000, 1176, 1370, 1583, 1812, 2058, 2317, 2588, 2870, 3161}; +#endif + static bool cm_is_better_bss(struct scan_cache_entry *bss1, struct scan_cache_entry *bss2) { @@ -815,6 +842,455 @@ void wlan_cm_get_check_assoc_disallowed(struct wlan_objmgr_psoc *psoc, *value = mlme_psoc_obj->psoc_cfg.score_config.check_assoc_disallowed; } +static enum phy_ch_width +cm_calculate_bandwidth(struct scan_cache_entry *entry, + struct psoc_phy_config *phy_config) +{ + uint8_t bw_above_20 = 0; + bool is_vht = false; + enum phy_ch_width ch_width; + + if (WLAN_REG_IS_24GHZ_CH_FREQ(entry->channel.chan_freq)) { + bw_above_20 = phy_config->bw_above_20_24ghz; + if (phy_config->vht_24G_cap) + is_vht = true; + } else if (phy_config->vht_cap) { + is_vht = true; + bw_above_20 = phy_config->bw_above_20_5ghz; + } + + if (IS_WLAN_PHYMODE_160MHZ(entry->phy_mode)) + ch_width = CH_WIDTH_160MHZ; + else if (IS_WLAN_PHYMODE_80MHZ(entry->phy_mode)) + ch_width = CH_WIDTH_80MHZ; + else if (IS_WLAN_PHYMODE_40MHZ(entry->phy_mode)) + ch_width = CH_WIDTH_40MHZ; + else + ch_width = CH_WIDTH_20MHZ; + + if (!phy_config->ht_cap && + ch_width >= CH_WIDTH_20MHZ) + ch_width = CH_WIDTH_20MHZ; + + if (!is_vht && ch_width > CH_WIDTH_40MHZ) + ch_width = CH_WIDTH_40MHZ; + + if (!bw_above_20) + ch_width = CH_WIDTH_20MHZ; + + return ch_width; +} + +static uint8_t cm_etp_get_ba_win_size_from_esp(uint8_t esp_ba_win_size) +{ + /* + * BA Window Size subfield is three bits in length and indicates the + * size of the Block Ack window that is. + * 802.11-2016.pdf Table 9-262 BA Window Size subfield encoding + */ + switch (esp_ba_win_size) { + case 1: return 2; + case 2: return 4; + case 3: return 6; + case 4: return 8; + case 5: return 16; + case 6: return 32; + case 7: return 64; + default: return 1; + } +} + +static uint16_t cm_get_etp_ntone(bool is_ht, bool is_vht, + enum phy_ch_width ch_width) +{ + uint16_t n_sd = 52, n_seg = 1; + + if (is_vht) { + /* Refer Table 21-5 in IEEE80211-2016 Spec */ + if (ch_width == CH_WIDTH_20MHZ) + n_sd = 52; + else if (ch_width == CH_WIDTH_40MHZ) + n_sd = 108; + else if (ch_width == CH_WIDTH_80MHZ) + n_sd = 234; + else if (ch_width == CH_WIDTH_80P80MHZ) + n_sd = 234, n_seg = 2; + else if (ch_width == CH_WIDTH_160MHZ) + n_sd = 468; + } else if (is_ht) { + /* Refer Table 19-6 in IEEE80211-2016 Spec */ + if (ch_width == CH_WIDTH_20MHZ) + n_sd = 52; + if (ch_width == CH_WIDTH_40MHZ) + n_sd = 108; + } else { + n_sd = 48; + } + + return (n_sd * n_seg); +} + +/* Refer Table 27-64 etc in Draft P802.11ax_D7.0.txt */ +static uint16_t cm_get_etp_he_ntone(enum phy_ch_width ch_width) +{ + uint16_t n_sd = 234, n_seg = 1; + + if (ch_width == CH_WIDTH_20MHZ) + n_sd = 234; + else if (ch_width == CH_WIDTH_40MHZ) + n_sd = 468; + else if (ch_width == CH_WIDTH_80MHZ) + n_sd = 980; + else if (ch_width == CH_WIDTH_80P80MHZ) + n_sd = 980, n_seg = 2; + else if (ch_width == CH_WIDTH_160MHZ) + n_sd = 1960; + + return (n_sd * n_seg); +} + +static uint16_t cm_get_etp_phy_header_dur_us(bool is_ht, bool is_vht, + uint8_t nss) +{ + uint16_t dur_us = 0; + + if (is_vht) { + /* + * Refer Figure 21-4 in 80211-2016 Spec + * 8 (L-STF) + 8 (L-LTF) + 4 (L-SIG) + + * 8 (VHT-SIG-A) + 4 (VHT-STF) + 4 (VHT-SIG-B) + */ + dur_us = 36; + /* (nss * VHT-LTF) = (nss * 4) */ + dur_us += (nss << 2); + } else if (is_ht) { + /* + * Refer Figure 19-1 in 80211-2016 Spec + * 8 (L-STF) + 8 (L-LTF) + 4 (L-SIG) + 8 (HT-SIG) + + * 4 (HT-STF) + */ + dur_us = 32; + /* (nss * HT-LTF = nss * 4) */ + dur_us += (nss << 2); + } else { + /* + * non-HT + * Refer Figure 19-1 in 80211-2016 Spec + * 8 (L-STF) + 8 (L-LTF) + 4 (L-SIG) + */ + dur_us = 20; + } + return dur_us; +} + +static uint32_t +cm_get_etp_max_bits_per_sc_1000x_for_nss(struct wlan_objmgr_psoc *psoc, + struct scan_cache_entry *entry, + uint8_t nss, + struct psoc_phy_config *phy_config) +{ + uint32_t max_bits_per_sc_1000x = 5000; /* 5 * 1000 */ + uint8_t mcs_map; + struct wlan_ie_vhtcaps *bss_vht_cap; + struct wlan_ie_hecaps *bss_he_cap; + uint32_t self_rx_mcs_map; + QDF_STATUS status; + + bss_vht_cap = (struct wlan_ie_vhtcaps *)util_scan_entry_vhtcap(entry); + bss_he_cap = (struct wlan_ie_hecaps *)util_scan_entry_hecap(entry); + if (!phy_config->vht_cap || !bss_vht_cap) { + mlme_err("vht unsupported"); + return max_bits_per_sc_1000x; + } + + status = wlan_mlme_cfg_get_vht_rx_mcs_map(psoc, &self_rx_mcs_map); + if (QDF_IS_STATUS_ERROR(status)) + return max_bits_per_sc_1000x; + + if (nss == 4) { + mcs_map = (self_rx_mcs_map & 0xC0) >> 6; + mcs_map = QDF_MIN(mcs_map, + (bss_vht_cap->rx_mcs_map & 0xC0) >> 6); + } else if (nss == 3) { + mcs_map = (self_rx_mcs_map & 0x30) >> 4; + mcs_map = QDF_MIN(mcs_map, + (bss_vht_cap->rx_mcs_map & 0x30) >> 4); + } else if (nss == 2) { + mcs_map = (self_rx_mcs_map & 0x0C) >> 2; + mcs_map = QDF_MIN(mcs_map, + (bss_vht_cap->rx_mcs_map & 0x0C) >> 2); + } else { + mcs_map = (self_rx_mcs_map & 0x03); + mcs_map = QDF_MIN(mcs_map, (bss_vht_cap->rx_mcs_map & 0x03)); + } + if (bss_he_cap) { + if (mcs_map == 2) + max_bits_per_sc_1000x = 8333; /* 10 *5/6 * 1000 */ + else if (mcs_map == 1) + max_bits_per_sc_1000x = 7500; /* 10 * 3/4 * 1000 */ + } else { + if (mcs_map == 2) + max_bits_per_sc_1000x = 6667; /* 8 * 5/6 * 1000 */ + else if (mcs_map == 1) + max_bits_per_sc_1000x = 6000; /* 8 * 3/4 * 1000 */ + } + return max_bits_per_sc_1000x; +} + +/* Refer Table 9-163 in 80211-2016 Spec */ +static uint32_t cm_etp_get_min_mpdu_ss_us_100x(struct htcap_cmn_ie *htcap) +{ + tSirMacHTParametersInfo *ampdu_param; + uint8_t ampdu_density; + + ampdu_param = (tSirMacHTParametersInfo *)&htcap->ampdu_param; + ampdu_density = ampdu_param->mpduDensity; + + if (ampdu_density == 1) + return 25; /* (1/4) * 100 */ + else if (ampdu_density == 2) + return 50; /* (1/2) * 100 */ + else if (ampdu_density == 3) + return 100; /* 1 * 100 */ + else if (ampdu_density == 4) + return 200; /* 2 * 100 */ + else if (ampdu_density == 5) + return 400; /* 4 * 100 */ + else if (ampdu_density == 6) + return 800; /* 8 * 100 */ + else if (ampdu_density == 7) + return 1600; /* 16 * 100 */ + else + return 100; +} + +/* Refer Table 9-162 in 80211-2016 Spec */ +static uint32_t cm_etp_get_max_amsdu_len(struct wlan_objmgr_psoc *psoc, + struct htcap_cmn_ie *htcap) +{ + uint8_t bss_max_amsdu; + uint32_t bss_max_amsdu_len; + QDF_STATUS status; + + status = wlan_mlme_get_max_amsdu_num(psoc, &bss_max_amsdu); + if (QDF_IS_STATUS_ERROR(status)) + bss_max_amsdu_len = 3839; + else if (bss_max_amsdu == 1) + bss_max_amsdu_len = 7935; + else + bss_max_amsdu_len = 3839; + + return bss_max_amsdu_len; +} + + // Calculate the number of bits per tone based on the input of SNR in dB + // The output is scaled up by BIT_PER_TONE_SCALE for integer representation +static uint32_t +calculate_bit_per_tone(int32_t rssi, enum phy_ch_width ch_width) +{ + int32_t noise_floor_db_boost; + int32_t noise_floor_dbm; + int32_t snr_db; + int32_t bit_per_tone; + int32_t lut_in_idx; + + noise_floor_db_boost = TWO_IN_DB * ch_width; + noise_floor_dbm = WLAN_NOISE_FLOOR_DBM_DEFAULT + noise_floor_db_boost + + SNR_MARGIN_DB; + snr_db = rssi - noise_floor_dbm; + if (snr_db <= SNR_DB_TO_BIT_PER_TONE_LUT_MAX) { + lut_in_idx = QDF_MAX(snr_db, SNR_DB_TO_BIT_PER_TONE_LUT_MIN) + - SNR_DB_TO_BIT_PER_TONE_LUT_MIN; + lut_in_idx = QDF_MIN(lut_in_idx, DB_NUM - 1); + bit_per_tone = SNR_DB_TO_BIT_PER_TONE_LUT[lut_in_idx]; + } else { + /* + * SNR_tone = 10^(SNR/10) + * log2(1+SNR_tone) ~= log2(SNR_tone) = + * log10(SNR_tone)/log10(2) = log10(10^(SNR/10)) / 0.3 + * = (SNR/10) / 0.3 = SNR/3 + * So log2(1+SNR_tone) = SNR/3. 1000x for this is SNR*334 + */ + bit_per_tone = snr_db * 334; + } + + return bit_per_tone; +} + +static uint32_t +cm_calculate_etp(struct wlan_objmgr_psoc *psoc, + struct scan_cache_entry *entry, + struct etp_params *etp_param, + uint8_t max_nss, enum phy_ch_width ch_width, + bool is_ht, bool is_vht, bool is_he, + int8_t rssi, + struct psoc_phy_config *phy_config) +{ + uint16_t ntone; + uint16_t phy_hdr_dur_us, max_amsdu_len = 1500, min_mpdu_ss_us_100x = 0; + uint32_t max_bits_per_sc_1000x, log_2_snr_tone_1000x; + uint32_t ppdu_payload_dur_us = 0, mpdu_per_ampdu, mpdu_per_ppdu; + uint32_t single_ppdu_dur_us, estimated_throughput_mbps, data_rate_kbps; + struct htcap_cmn_ie *htcap; + + htcap = (struct htcap_cmn_ie *)util_scan_entry_htcap(entry); + if (ch_width > CH_WIDTH_160MHZ) + return CM_AVOID_CANDIDATE_MIN_SCORE; + + if (is_he) + ntone = cm_get_etp_he_ntone(ch_width); + else + ntone = cm_get_etp_ntone(is_ht, is_vht, ch_width); + phy_hdr_dur_us = cm_get_etp_phy_header_dur_us(is_ht, is_vht, max_nss); + + max_bits_per_sc_1000x = + cm_get_etp_max_bits_per_sc_1000x_for_nss(psoc, entry, + max_nss, phy_config); + if (rssi < WLAN_NOISE_FLOOR_DBM_DEFAULT) + return CM_AVOID_CANDIDATE_MIN_SCORE; + + log_2_snr_tone_1000x = calculate_bit_per_tone(rssi, ch_width); + + /* Eq. R-2 Pg:3508 in 80211-2016 Spec */ + if (is_he) + data_rate_kbps = + QDF_MIN(log_2_snr_tone_1000x, max_bits_per_sc_1000x) * + (max_nss * ntone) / HE_PPDU_PAYLOAD_SYMBOL_DUR_US; + else + data_rate_kbps = + QDF_MIN(log_2_snr_tone_1000x, max_bits_per_sc_1000x) * + (max_nss * ntone) / PPDU_PAYLOAD_SYMBOL_DUR_US; + mlme_debug("data_rate_kbps: %d", data_rate_kbps); + if (data_rate_kbps < 1000) { + /* Return ETP as 1 since datarate is not even 1 Mbps */ + return CM_AVOID_CANDIDATE_MIN_SCORE; + } + /* compute MPDU_p_PPDU */ + if (is_ht) { + min_mpdu_ss_us_100x = + cm_etp_get_min_mpdu_ss_us_100x(htcap); + max_amsdu_len = + cm_etp_get_max_amsdu_len(psoc, htcap); + ppdu_payload_dur_us = + etp_param->data_ppdu_dur_target_us - phy_hdr_dur_us; + mpdu_per_ampdu = + QDF_MIN(qdf_ceil(ppdu_payload_dur_us * 100, + min_mpdu_ss_us_100x), + qdf_ceil(ppdu_payload_dur_us * + (data_rate_kbps / 1000), + (MAC_HEADER_LEN + max_amsdu_len) * 8)); + mpdu_per_ppdu = QDF_MIN(etp_param->ba_window_size, + QDF_MAX(1, mpdu_per_ampdu)); + } else { + mpdu_per_ppdu = 1; + } + + /* compute PPDU_Dur */ + single_ppdu_dur_us = + qdf_ceil((MAC_HEADER_LEN + max_amsdu_len) * mpdu_per_ppdu * 8, + (data_rate_kbps / 1000) * PPDU_PAYLOAD_SYMBOL_DUR_US); + single_ppdu_dur_us *= PPDU_PAYLOAD_SYMBOL_DUR_US; + single_ppdu_dur_us += phy_hdr_dur_us; + + estimated_throughput_mbps = + qdf_ceil(mpdu_per_ppdu * max_amsdu_len * 8, single_ppdu_dur_us); + estimated_throughput_mbps = + (estimated_throughput_mbps * + etp_param->airtime_fraction) / + CM_MAX_ESTIMATED_AIR_TIME_FRACTION; + + if (estimated_throughput_mbps < CM_AVOID_CANDIDATE_MIN_SCORE) + estimated_throughput_mbps = CM_AVOID_CANDIDATE_MIN_SCORE; + if (estimated_throughput_mbps > CM_BEST_CANDIDATE_MAX_BSS_SCORE) + estimated_throughput_mbps = CM_BEST_CANDIDATE_MAX_BSS_SCORE; + + mlme_nofl_debug("Candidate("QDF_MAC_ADDR_FMT" freq %d): rssi %d HT %d VHT %d HE %d ATF: %d NSS %d, ch_width: %d", + QDF_MAC_ADDR_REF(entry->bssid.bytes), + entry->channel.chan_freq, + entry->rssi_raw, is_ht, is_vht, is_he, + etp_param->airtime_fraction, + entry->nss, ch_width); + if (is_ht) + mlme_nofl_debug("min_mpdu_ss_us_100x = %d, max_amsdu_len = %d, ppdu_payload_dur_us = %d, mpdu_per_ampdu = %d, mpdu_per_ppdu = %d, ba_window_size = %d", + min_mpdu_ss_us_100x, max_amsdu_len, + ppdu_payload_dur_us, mpdu_per_ampdu, + mpdu_per_ppdu, etp_param->ba_window_size); + mlme_nofl_debug("ETP score params: ntone: %d, phy_hdr_dur_us: %d, max_bits_per_sc_1000x: %d, log_2_snr_tone_1000x: %d mpdu_p_ppdu = %d, max_amsdu_len = %d, ppdu_dur_us = %d, total score = %d", + ntone, phy_hdr_dur_us, max_bits_per_sc_1000x, + log_2_snr_tone_1000x, mpdu_per_ppdu, max_amsdu_len, + single_ppdu_dur_us, estimated_throughput_mbps); + + return estimated_throughput_mbps; +} + +static uint32_t +cm_calculate_etp_score(struct wlan_objmgr_psoc *psoc, + struct scan_cache_entry *entry, + struct psoc_phy_config *phy_config) +{ + enum phy_ch_width ch_width; + uint32_t nss; + bool is_he_intersect = false; + bool is_vht_intersect = false; + bool is_ht_intersect = false; + struct wlan_esp_info *esp; + struct wlan_esp_ie *esp_ie; + struct etp_params etp_param; + + if (phy_config->he_cap && entry->ie_list.hecap) + is_he_intersect = true; + if ((phy_config->vht_cap || phy_config->vht_24G_cap) && + (entry->ie_list.vhtcap || + WLAN_REG_IS_6GHZ_CHAN_FREQ(entry->channel.chan_freq))) + is_vht_intersect = true; + if (phy_config->ht_cap && entry->ie_list.htcap) + is_ht_intersect = true; + nss = cm_get_sta_nss(psoc, entry->channel.chan_freq, + phy_config->vdev_nss_24g, + phy_config->vdev_nss_5g); + nss = QDF_MIN(nss, entry->nss); + ch_width = cm_calculate_bandwidth(entry, phy_config); + + /* Initialize default ETP params */ + etp_param.airtime_fraction = 255 / 2; + etp_param.ba_window_size = 32; + etp_param.data_ppdu_dur_target_us = 5000; /* 5 msec */ + + if (entry->air_time_fraction) { + etp_param.airtime_fraction = entry->air_time_fraction; + esp_ie = (struct wlan_esp_ie *) + util_scan_entry_esp_info(entry); + if (esp_ie) { + esp = &esp_ie->esp_info_AC_BE; + etp_param.ba_window_size = + cm_etp_get_ba_win_size_from_esp(esp->ba_window_size); + etp_param.data_ppdu_dur_target_us = + 50 * esp->ppdu_duration; + mlme_debug("esp ba_window_size: %d, ppdu_duration: %d", + esp->ba_window_size, esp->ppdu_duration); + } + } else if (entry->qbss_chan_load) { + mlme_debug("qbss_chan_load: %d", entry->qbss_chan_load); + etp_param.airtime_fraction = + CM_MAX_ESTIMATED_AIR_TIME_FRACTION - + entry->qbss_chan_load; + } + /* If ini vendor_roam_score_algorithm=1, just calculate ETP of all + * bssid of ssid selected by high layer, and try to connect AP by + * order of ETP, legacy algorithm with following Parameters/Weightage + * becomes useless. ETP should be [1Mbps, 20000Mbps],matches score + * range: [1, 20000] + */ + return cm_calculate_etp(psoc, entry, + &etp_param, + nss, + ch_width, + is_ht_intersect, + is_vht_intersect, + is_he_intersect, + entry->rssi_raw, + phy_config); +} #else static bool cm_get_pcl_weight_of_channel(uint32_t chan_freq, @@ -865,6 +1341,14 @@ static inline bool cm_is_assoc_allowed(struct psoc_mlme_obj *mlme_psoc_obj, { return true; } + +static uint32_t +cm_calculate_etp_score(struct wlan_objmgr_psoc *psoc, + struct scan_cache_entry *entry, + struct psoc_phy_config *phy_config) +{ + return 0; +} #endif /** @@ -934,9 +1418,9 @@ static int cm_calculate_bss_score(struct wlan_objmgr_psoc *psoc, struct psoc_phy_config *phy_config; mlme_psoc_obj = wlan_psoc_mlme_get_cmpt_obj(psoc); - if (!mlme_psoc_obj) return 0; + phy_config = &mlme_psoc_obj->psoc_cfg.phy_config; score_config = &mlme_psoc_obj->psoc_cfg.score_config; weight_config = &score_config->weight_config; @@ -951,7 +1435,11 @@ static int cm_calculate_bss_score(struct wlan_objmgr_psoc *psoc, CM_BEST_CANDIDATE_MAX_BSS_SCORE); return CM_BEST_CANDIDATE_MAX_BSS_SCORE; } - + if (score_config->vendor_roam_score_algorithm) { + score = cm_calculate_etp_score(psoc, entry, phy_config); + entry->bss_score = score; + return score; + } rssi_score = cm_calculate_rssi_score(&score_config->rssi_score, entry->rssi_raw, weight_config->rssi_weightage); @@ -1401,5 +1889,7 @@ void wlan_cm_init_score_config(struct wlan_objmgr_psoc *psoc, cfg_get(psoc, CFG_SCORING_BAND_WEIGHT_PER_IDX)); score_cfg->is_bssid_hint_priority = cfg_get(psoc, CFG_IS_BSSID_HINT_PRIORITY); + score_cfg->vendor_roam_score_algorithm = + cfg_get(psoc, CFG_VENDOR_ROAM_SCORE_ALGORITHM); score_cfg->check_assoc_disallowed = true; } diff --git a/umac/mlme/connection_mgr/dispatcher/inc/cfg_mlme_score_params.h b/umac/mlme/connection_mgr/dispatcher/inc/cfg_mlme_score_params.h index 70d07b37c958..85e845afd65b 100644 --- a/umac/mlme/connection_mgr/dispatcher/inc/cfg_mlme_score_params.h +++ b/umac/mlme/connection_mgr/dispatcher/inc/cfg_mlme_score_params.h @@ -1080,6 +1080,30 @@ CFG_VALUE_OR_DEFAULT, \ "Set priority for connection with bssid_hint") +/* + * + * vendor_roam_score_algorithm - Algorithm to calculate AP score + * @Min: false + * @Max: true + * @Default: false + * + * By default the value is false and default roam algorithm will be used. + * When the value is true, the V2 roaming algorithm will be used: + * For this V2 algo, AP score calculation is based on ETP and below equation: + * AP Score = (RSSIfactor * rssiweight(0.65)) + (CUfactor *cuweight(0.35)) + * + * Related: None + * + * Supported Feature: roam score algorithm + * + * Usage: External + * + * + */ +#define CFG_VENDOR_ROAM_SCORE_ALGORITHM \ + CFG_INI_BOOL("vendor_roam_score_algorithm", false, \ + "Roam candidate selection score algorithm") + #define CFG_MLME_SCORE_ALL \ CFG(CFG_SCORING_RSSI_WEIGHTAGE) \ CFG(CFG_SCORING_HT_CAPS_WEIGHTAGE) \ @@ -1116,6 +1140,7 @@ CFG(CFG_SCORING_OCE_WAN_SCORE_IDX_7_TO_4) \ CFG(CFG_SCORING_OCE_WAN_SCORE_IDX_11_TO_8) \ CFG(CFG_SCORING_OCE_WAN_SCORE_IDX_15_TO_12) \ - CFG(CFG_IS_BSSID_HINT_PRIORITY) + CFG(CFG_IS_BSSID_HINT_PRIORITY) \ + CFG(CFG_VENDOR_ROAM_SCORE_ALGORITHM) #endif /* __CFG_MLME_SCORE_PARAMS_H */ diff --git a/umac/mlme/connection_mgr/dispatcher/inc/wlan_cm_bss_score_param.h b/umac/mlme/connection_mgr/dispatcher/inc/wlan_cm_bss_score_param.h index 7a07049bdad5..11d3338a9ab9 100644 --- a/umac/mlme/connection_mgr/dispatcher/inc/wlan_cm_bss_score_param.h +++ b/umac/mlme/connection_mgr/dispatcher/inc/wlan_cm_bss_score_param.h @@ -127,6 +127,7 @@ struct per_slot_score { * @band_weight_per_index: band weight per index * @is_bssid_hint_priority: True if bssid_hint is given priority * @check_assoc_disallowed: Should assoc be disallowed if MBO OCE IE indicate so + * @vendor_roam_score_algorithm: Preferred ETP vendor roam score algorithm */ struct scoring_cfg { struct weight_cfg weight_config; @@ -138,6 +139,7 @@ struct scoring_cfg { uint32_t band_weight_per_index; bool is_bssid_hint_priority; bool check_assoc_disallowed; + bool vendor_roam_score_algorithm; }; /** @@ -164,6 +166,18 @@ enum cm_blacklist_action { CM_BLM_AVOID, }; +/** + * struct etp_params - params for estimated throughput + * @airtime_fraction: Portion of airtime available for outbound transmissions + * @data_ppdu_dur_target_us: Expected duration of a single PPDU, in us + * @ba_window_size: Block ack window size of the transmitter + */ +struct etp_params { + uint32_t airtime_fraction; + uint32_t data_ppdu_dur_target_us; + uint32_t ba_window_size; +}; + #ifdef FEATURE_BLACKLIST_MGR enum cm_blacklist_action wlan_blacklist_action_on_bssid(struct wlan_objmgr_pdev *pdev,