From c0d084118372bbd671fac4c1a7d59c57566e14b3 Mon Sep 17 00:00:00 2001 From: gaurank kathpalia Date: Sun, 22 Sep 2019 13:34:53 +0530 Subject: [PATCH] qcacld-3.0: Normalize the channel weights according to ini Normalize the weights of the frequencies for ACS scan if the user has changed them in the ini. This is done as legacy devices wont be able to scan the newly added 6ghz frequencies, and thus wont be able to associate with the SAP if it starts on 6ghz channels. Change-Id: I2dd2f706c248f5339bde06963540d0874d08b847 CRs-Fixed: 2543007 --- components/mlme/core/src/wlan_mlme_main.c | 86 +++++++++++++++++++ components/mlme/dispatcher/inc/cfg_mlme_acs.h | 27 +++++- .../dispatcher/inc/wlan_mlme_public_struct.h | 32 +++++++ core/sap/src/sap_ch_select.c | 46 ++++++++++ core/sap/src/sap_fsm.c | 44 +++++++++- 5 files changed, 232 insertions(+), 3 deletions(-) diff --git a/components/mlme/core/src/wlan_mlme_main.c b/components/mlme/core/src/wlan_mlme_main.c index f7d4889c9436..26d907ddf05e 100644 --- a/components/mlme/core/src/wlan_mlme_main.c +++ b/components/mlme/core/src/wlan_mlme_main.c @@ -1291,6 +1291,90 @@ static void mlme_init_threshold_cfg(struct wlan_objmgr_psoc *psoc, threshold->frag_threshold = cfg_get(psoc, CFG_FRAG_THRESHOLD); } +static bool +mlme_is_freq_present_in_list(struct acs_weight *normalize_weight_chan_list, + uint8_t num_freq, uint32_t freq, uint8_t *index) +{ + uint8_t i; + + for (i = 0; i < num_freq; i++) { + if (normalize_weight_chan_list[i].chan_freq == freq) { + *index = i; + return true; + } + } + + return false; +} + +static void +mlme_acs_parse_weight_list(struct wlan_objmgr_psoc *psoc, + struct wlan_mlme_acs *acs) +{ + char *acs_weight, *str1, *str2 = NULL, *acs_weight_temp, is_range = '-'; + int freq1, freq2, normalize_factor; + uint8_t num_acs_weight = 0, num_acs_weight_range = 0, index = 0; + struct acs_weight *weight_list = acs->normalize_weight_chan; + struct acs_weight_range *range_list = acs->normalize_weight_range; + + if (!qdf_str_len(cfg_get(psoc, CFG_NORMALIZE_ACS_WEIGHT))) + return; + + acs_weight = qdf_mem_malloc(ACS_WEIGHT_MAX_STR_LEN); + + if (!acs_weight) + return; + + qdf_mem_copy(acs_weight, cfg_get(psoc, CFG_NORMALIZE_ACS_WEIGHT), + ACS_WEIGHT_MAX_STR_LEN); + acs_weight_temp = acs_weight; + + while(acs_weight_temp) { + str1 = strsep(&acs_weight_temp, ","); + if (!str1) + goto end; + freq1 = 0; + freq2 = 0; + if (strchr(str1, is_range)) { + str2 = strsep(&str1, "-"); + sscanf(str2, "%d", &freq1); + sscanf(str1, "%d", &freq2); + strsep(&str1, "="); + sscanf(str1, "%d", &normalize_factor); + + if (num_acs_weight_range == MAX_ACS_WEIGHT_RANGE) + continue; + range_list[num_acs_weight_range].normalize_weight = + normalize_factor; + range_list[num_acs_weight_range].start_freq = freq1; + range_list[num_acs_weight_range++].end_freq = freq2; + } else { + sscanf(str1, "%d", &freq1); + strsep(&str1, "="); + sscanf(str1, "%d", &normalize_factor); + if (mlme_is_freq_present_in_list(weight_list, + num_acs_weight, freq1, + &index)) { + weight_list[index].normalize_weight = + normalize_factor; + } else { + if (num_acs_weight == QDF_MAX_NUM_CHAN) + continue; + + weight_list[num_acs_weight].chan_freq = freq1; + weight_list[num_acs_weight++].normalize_weight = + normalize_factor; + } + } + } + + acs->normalize_weight_num_chan = num_acs_weight; + acs->num_weight_range = num_acs_weight_range; + +end: + qdf_mem_free(acs_weight); +} + static void mlme_init_acs_cfg(struct wlan_objmgr_psoc *psoc, struct wlan_mlme_acs *acs) { @@ -1304,6 +1388,8 @@ static void mlme_init_acs_cfg(struct wlan_objmgr_psoc *psoc, cfg_get(psoc, CFG_USER_ACS_DFS_LTE); acs->is_external_acs_policy = cfg_get(psoc, CFG_EXTERNAL_ACS_POLICY); + + mlme_acs_parse_weight_list(psoc, acs); } QDF_STATUS mlme_init_ibss_cfg(struct wlan_objmgr_psoc *psoc, diff --git a/components/mlme/dispatcher/inc/cfg_mlme_acs.h b/components/mlme/dispatcher/inc/cfg_mlme_acs.h index eeb412a5ba31..405aea11d539 100644 --- a/components/mlme/dispatcher/inc/cfg_mlme_acs.h +++ b/components/mlme/dispatcher/inc/cfg_mlme_acs.h @@ -155,11 +155,36 @@ 1, \ "External ACS Policy Control") +#define ACS_WEIGHT_MAX_STR_LEN 500 + +/* + * + * normalize_acs_weight - Used to control the ACS channel weightage. + * + * This ini is used to specify the weight percentage of the channel. Channel + * weights can be controlled by user to prioritize or de-prioritize channels. + * + * Related: ACS + * + * Supported Feature: ACS + * + * Usage: External + * + * + */ +#define CFG_NORMALIZE_ACS_WEIGHT CFG_INI_STRING( \ + "normalize_acs_weight", \ + 0, \ + ACS_WEIGHT_MAX_STR_LEN, \ + "", \ + "Used to specify the channel weights") + #define CFG_ACS_ALL \ CFG(CFG_ACS_WITH_MORE_PARAM) \ CFG(CFG_AUTO_CHANNEL_SELECT_WEIGHT) \ CFG(CFG_USER_AUTO_CHANNEL_SELECTION) \ CFG(CFG_USER_ACS_DFS_LTE) \ - CFG(CFG_EXTERNAL_ACS_POLICY) + CFG(CFG_EXTERNAL_ACS_POLICY) \ + CFG(CFG_NORMALIZE_ACS_WEIGHT) #endif /* __CFG_MLME_ACS_H */ diff --git a/components/mlme/dispatcher/inc/wlan_mlme_public_struct.h b/components/mlme/dispatcher/inc/wlan_mlme_public_struct.h index 543043d784e1..a34aa65dbc23 100644 --- a/components/mlme/dispatcher/inc/wlan_mlme_public_struct.h +++ b/components/mlme/dispatcher/inc/wlan_mlme_public_struct.h @@ -1161,6 +1161,30 @@ struct wlan_mlme_product_details_cfg { char manufacture_product_version[WLAN_CFG_MFR_PRODUCT_VERSION_LEN + 1]; }; +/* + * struct acs_weight - Normalize ACS weight for mentioned channels + * @chan_freq: frequency of the channel + * @normalize_weight: Normalization factor of the frequency + */ +struct acs_weight { + uint32_t chan_freq; + uint8_t normalize_weight; +}; + +/* + * struct acs_weight_range - Normalize ACS weight for mentioned channel range + * @start_freq: frequency of the start channel + * @end_freq: frequency of the end channel + * @normalize_weight: Normalization factor for freq range + */ +struct acs_weight_range { + uint32_t start_freq; + uint32_t end_freq; + uint8_t normalize_weight; +}; + +#define MAX_ACS_WEIGHT_RANGE 10 + /* * struct wlan_mlme_acs - All acs related cfg items * @is_acs_with_more_param - to enable acs with more param @@ -1168,6 +1192,10 @@ struct wlan_mlme_product_details_cfg { * @is_vendor_acs_support - enable application based channel selection * @is_acs_support_for_dfs_ltecoex - enable channel for dfs and lte coex * @is_external_acs_policy - control external policy + * @normalize_weight_chan: Weight factor to be considered in ACS + * @normalize_weight_num_chan: Number of freq items for normalization. + * @normalize_weight_range: Frequency range for weight normalization + * @num_weight_range: num of ranges provided by user */ struct wlan_mlme_acs { bool is_acs_with_more_param; @@ -1175,6 +1203,10 @@ struct wlan_mlme_acs { bool is_vendor_acs_support; bool is_acs_support_for_dfs_ltecoex; bool is_external_acs_policy; + struct acs_weight normalize_weight_chan[QDF_MAX_NUM_CHAN]; + uint16_t normalize_weight_num_chan; + struct acs_weight_range normalize_weight_range[MAX_ACS_WEIGHT_RANGE]; + uint16_t num_weight_range; }; /* diff --git a/core/sap/src/sap_ch_select.c b/core/sap/src/sap_ch_select.c index 2ad41540ddc2..f0405b04d0c9 100644 --- a/core/sap/src/sap_ch_select.c +++ b/core/sap/src/sap_ch_select.c @@ -1399,6 +1399,14 @@ static void sap_compute_spect_weight(tSapChSelSpectInfo *pSpectInfoParams, pSpectInfoParams->numSpectChans; qdf_list_node_t *cur_lst = NULL, *next_lst = NULL; struct scan_cache_node *cur_node = NULL; + uint32_t normalized_weight; + uint8_t normalize_factor; + uint32_t chan_freq; + struct acs_weight *weight_list = + mac->mlme_cfg->acs.normalize_weight_chan; + struct acs_weight_range *range_list = + mac->mlme_cfg->acs.normalize_weight_range; + bool freq_present_in_list = false; bcn_struct = qdf_mem_malloc(sizeof(tSirProbeRespBeacon)); if (!bcn_struct) @@ -1578,6 +1586,44 @@ static void sap_compute_spect_weight(tSapChSelSpectInfo *pSpectInfoParams, pSpectCh->bssCount = SOFTAP_MIN_COUNT; } + chan_freq = wlan_reg_chan_to_freq(mac->pdev, pSpectCh->chNum); + + /* Check if the freq is present in range list */ + for (i = 0; i < mac->mlme_cfg->acs.num_weight_range; i++) { + if (chan_freq >= range_list[i].start_freq && + chan_freq <= range_list[i].end_freq) { + normalize_factor = + range_list[i].normalize_weight; + sap_debug("Range list, freq %d normalize weight factor %d", + chan_freq, normalize_factor); + freq_present_in_list = true; + } + } + + /* Check if user wants a special factor for this freq */ + + for (i = 0; i < mac->mlme_cfg->acs.normalize_weight_num_chan; + i++) { + if (chan_freq == weight_list[i].chan_freq) { + normalize_factor = + weight_list[i].normalize_weight; + sap_debug("freq %d normalize weight factor %d", + chan_freq, normalize_factor); + freq_present_in_list = true; + } + } + + if (freq_present_in_list) { + normalized_weight = + ((SAP_ACS_WEIGHT_MAX - pSpectCh->weight) * + (100 - normalize_factor)) / 100; + sap_debug("freq %d old weight %d new weight %d", + chan_freq, pSpectCh->weight, + pSpectCh->weight + normalized_weight); + pSpectCh->weight += normalized_weight; + freq_present_in_list = false; + } + if (pSpectCh->weight > SAP_ACS_WEIGHT_MAX) pSpectCh->weight = SAP_ACS_WEIGHT_MAX; pSpectCh->weight_copy = pSpectCh->weight; diff --git a/core/sap/src/sap_fsm.c b/core/sap/src/sap_fsm.c index 4f30bb7bf838..cd7ef6ca6f5b 100644 --- a/core/sap/src/sap_fsm.c +++ b/core/sap/src/sap_fsm.c @@ -3241,6 +3241,12 @@ static QDF_STATUS sap_get_freq_list(struct sap_context *sap_ctx, struct mac_context *mac_ctx; tSapChSelSpectInfo spect_info_obj = { NULL, 0 }; uint16_t ch_width; + uint8_t normalize_factor = 100; + uint32_t chan_freq; + struct acs_weight *weight_list; + struct acs_weight_range *range_list; + bool freq_present_in_list = false; + uint8_t i; mac_ctx = sap_get_mac_context(); if (!mac_ctx) { @@ -3250,6 +3256,9 @@ static QDF_STATUS sap_get_freq_list(struct sap_context *sap_ctx, return QDF_STATUS_E_FAULT; } + weight_list = mac_ctx->mlme_cfg->acs.normalize_weight_chan; + range_list = mac_ctx->mlme_cfg->acs.normalize_weight_range; + dfs_master_enable = mac_ctx->mlme_cfg->dfs_cfg.dfs_master_capable; if (sap_ctx->dfs_mode == ACS_DFS_MODE_DISABLE) dfs_master_enable = false; @@ -3284,8 +3293,7 @@ static QDF_STATUS sap_get_freq_list(struct sap_context *sap_ctx, } /* Allocate the max number of channel supported */ - list = qdf_mem_malloc((NUM_5GHZ_CHANNELS + NUM_24GHZ_CHANNELS) * - sizeof(uint32_t)); + list = qdf_mem_malloc((NUM_CHANNELS) * sizeof(uint32_t)); if (!list) { *num_ch = 0; *freq_list = NULL; @@ -3363,6 +3371,38 @@ static QDF_STATUS sap_get_freq_list(struct sap_context *sap_ctx, WLAN_REG_CH_NUM(loop_count))) continue; + chan_freq = wlan_reg_chan_to_freq(mac_ctx->pdev, + WLAN_REG_CH_NUM(loop_count)); + /* Check if the freq is present in range list */ + for (i = 0; i < mac_ctx->mlme_cfg->acs.num_weight_range; i++) { + if (chan_freq >= range_list[i].start_freq && + chan_freq <= range_list[i].end_freq) { + normalize_factor = + range_list[i].normalize_weight; + sap_debug("Range list, freq %d normalize weight factor %d", + chan_freq, normalize_factor); + freq_present_in_list = true; + } + } + + for (i = 0; + i < mac_ctx->mlme_cfg->acs.normalize_weight_num_chan; + i++) { + if (chan_freq == weight_list[i].chan_freq) { + normalize_factor = + weight_list[i].normalize_weight; + sap_debug("freq %d normalize weight factor %d", + chan_freq, normalize_factor); + freq_present_in_list = true; + } + } + + /* This would mean that the user does not want this freq */ + if (freq_present_in_list && !normalize_factor) { + sap_debug("chan_freq %d ecluded normalize weight 0", + chan_freq); + continue; + } #ifdef FEATURE_WLAN_AP_AP_ACS_OPTIMIZE if ((sap_ctx->acs_cfg->skip_scan_status == eSAP_DO_PAR_ACS_SCAN)) {