From b035570f53d98252ab4f0afc06a628d5b28f293a Mon Sep 17 00:00:00 2001 From: Ashish Kumar Dhanotiya Date: Thu, 19 Sep 2019 18:06:30 +0530 Subject: [PATCH] qcacld-3.0: Fill correct txpower information As a part of 802.11ax amendment, 6GHz band operation is added. Since the 6 GHz channel numbers are overlapping with existing 2.4GHz and 5GHz channel numbers, use frequency to identify unique channel operation instead of channel number. Channel frequency is unique across bands. As a part of above requirement frequency attribute is added to the struct sSirMacChanInfo, in driver some APIs directly copies this structure info considering as every member of the structure as uint8_t, as frequency is uint32_t this breaks above asumption and results into corrupt info and gives undefined behaviour. To address above issue, use the structure members individually and give the information by member-by-member copy. Change-Id: Ied6ad30d8a0800211f99371969ddd192ff40545c CRs-Fixed: 2537975 --- components/mlme/core/src/wlan_mlme_main.c | 16 +-- .../mlme/dispatcher/inc/cfg_mlme_power.h | 6 + .../dispatcher/inc/wlan_mlme_public_struct.h | 18 ++- .../mlme/dispatcher/inc/wlan_mlme_ucfg_api.h | 11 ++ .../mlme/dispatcher/src/wlan_mlme_ucfg_api.c | 98 +++++++++++++ core/hdd/src/wlan_hdd_main.c | 10 ++ core/mac/src/pe/lim/lim_utils.c | 16 ++- .../src/sys/legacy/src/utils/src/parser_api.c | 134 ++++++++++++------ core/sme/src/csr/csr_api_roam.c | 18 ++- core/sme/src/csr/csr_api_scan.c | 14 +- 10 files changed, 272 insertions(+), 69 deletions(-) diff --git a/components/mlme/core/src/wlan_mlme_main.c b/components/mlme/core/src/wlan_mlme_main.c index 4cf415c4e543e..45ffc0990421b 100644 --- a/components/mlme/core/src/wlan_mlme_main.c +++ b/components/mlme/core/src/wlan_mlme_main.c @@ -1710,17 +1710,17 @@ static void mlme_init_power_cfg(struct wlan_objmgr_psoc *psoc, power->tx_power_2g = cfg_get(psoc, CFG_SET_TXPOWER_LIMIT2G); power->tx_power_5g = cfg_get(psoc, CFG_SET_TXPOWER_LIMIT5G); - power->max_tx_power_24.max_len = CFG_MAX_TX_POWER_2_4_LEN; + power->max_tx_power_24_chan.max_len = CFG_MAX_TX_POWER_2_4_LEN; qdf_uint8_array_parse(cfg_default(CFG_MAX_TX_POWER_2_4), - power->max_tx_power_24.data, - sizeof(power->max_tx_power_24.data), - &power->max_tx_power_24.len); + power->max_tx_power_24_chan.data, + sizeof(power->max_tx_power_24_chan.data), + &power->max_tx_power_24_chan.len); - power->max_tx_power_5.max_len = CFG_MAX_TX_POWER_5_LEN; + power->max_tx_power_5_chan.max_len = CFG_MAX_TX_POWER_5_LEN; qdf_uint8_array_parse(cfg_default(CFG_MAX_TX_POWER_5), - power->max_tx_power_5.data, - sizeof(power->max_tx_power_5.data), - &power->max_tx_power_5.len); + power->max_tx_power_5_chan.data, + sizeof(power->max_tx_power_5_chan.data), + &power->max_tx_power_5_chan.len); power->power_usage.max_len = CFG_POWER_USAGE_MAX_LEN; power->power_usage.len = CFG_POWER_USAGE_MAX_LEN; diff --git a/components/mlme/dispatcher/inc/cfg_mlme_power.h b/components/mlme/dispatcher/inc/cfg_mlme_power.h index eab93a1f6e40f..81763ef8bc41d 100644 --- a/components/mlme/dispatcher/inc/cfg_mlme_power.h +++ b/components/mlme/dispatcher/inc/cfg_mlme_power.h @@ -29,6 +29,9 @@ * @Min: 0 minimum length of tx power * @Max: default data length of tx power in string format * @Default: 1, 14, 20 + * + * This ini contains the string in the form of first_channel number, + * number of channels and max tx power triplets */ #define CFG_MAX_TX_POWER_2_4_DATA "1, 14, 20" #define CFG_MAX_TX_POWER_2_4 CFG_STRING( \ @@ -44,6 +47,9 @@ * @Min: 0 minimum length of tx power * @Max: default data length of tx power in string format * @Default: 36, 126, 20 + * + * This ini contains the string in the form of first_channel number, + * number of channels and max tx power triplets */ #define CFG_MAX_TX_POWER_5_DATA "36, 126, 20" #define CFG_MAX_TX_POWER_5 CFG_STRING( \ diff --git a/components/mlme/dispatcher/inc/wlan_mlme_public_struct.h b/components/mlme/dispatcher/inc/wlan_mlme_public_struct.h index dade1f79976d4..96f9925108f92 100644 --- a/components/mlme/dispatcher/inc/wlan_mlme_public_struct.h +++ b/components/mlme/dispatcher/inc/wlan_mlme_public_struct.h @@ -54,7 +54,7 @@ #define CFG_STR_DATA_LEN 17 #define CFG_EDCA_DATA_LEN 17 #define CFG_MAX_TX_POWER_2_4_LEN 128 -#define CFG_MAX_TX_POWER_5_LEN 128 +#define CFG_MAX_TX_POWER_5_LEN 256 #define CFG_POWER_USAGE_MAX_LEN 4 #define CFG_MAX_STR_LEN 256 #define MAX_VENDOR_IES_LEN 1532 @@ -1882,8 +1882,18 @@ struct mlme_power_usage { /* * struct wlan_mlme_power - power related config items - * @max_tx_power_24: max power Tx for 2.4 ghz - * @max_tx_power_5: max power Tx for 5 ghz + * @max_tx_power_24: max power Tx for 2.4 ghz, this is based on frequencies + * @max_tx_power_5: max power Tx for 5 ghz, this is based on frequencies + * @max_tx_power_24_chan: max power Tx for 2.4 ghz, this is based on channel + * numbers, this is added to parse the ini values to maintain the backward + * compatibility, these channel numbers are converted to frequencies and copied + * to max_tx_power_24 structure, once this conversion is done this structure + * should not be used. + * @max_tx_power_5_chan: max power Tx for 5 ghz, this is based on channel + * numbers, this is added to parse the ini values to maintain the backward + * compatibility, these channel numbers are converted to frequencies and copied + * to max_tx_power_24 structure, once this conversion is done this structure + * should not be used. * @power_usage: power usage mode, min, max, mod * @tx_power_2g: limit tx power in 2.4 ghz * @tx_power_5g: limit tx power in 5 ghz @@ -1894,6 +1904,8 @@ struct mlme_power_usage { struct wlan_mlme_power { struct mlme_max_tx_power_24 max_tx_power_24; struct mlme_max_tx_power_5 max_tx_power_5; + struct mlme_max_tx_power_24 max_tx_power_24_chan; + struct mlme_max_tx_power_5 max_tx_power_5_chan; struct mlme_power_usage power_usage; uint8_t tx_power_2g; uint8_t tx_power_5g; diff --git a/components/mlme/dispatcher/inc/wlan_mlme_ucfg_api.h b/components/mlme/dispatcher/inc/wlan_mlme_ucfg_api.h index c87f15ea2742e..40e1a1a48da93 100644 --- a/components/mlme/dispatcher/inc/wlan_mlme_ucfg_api.h +++ b/components/mlme/dispatcher/inc/wlan_mlme_ucfg_api.h @@ -101,6 +101,17 @@ QDF_STATUS ucfg_mlme_global_init(void); */ QDF_STATUS ucfg_mlme_global_deinit(void); +/** + * ucfg_mlme_cfg_chan_to_freq() - convert channel numbers to frequencies + * @pdev: pointer to pdev object + * + * convert the channels numbers received as part of cfg items to + * frequencies. + * + * Return: None + */ +void ucfg_mlme_cfg_chan_to_freq(struct wlan_objmgr_pdev *pdev); + /** * wlan_mlme_get_power_usage() - Get the power usage info * @psoc: pointer to psoc object diff --git a/components/mlme/dispatcher/src/wlan_mlme_ucfg_api.c b/components/mlme/dispatcher/src/wlan_mlme_ucfg_api.c index d8f3a01761cbd..e74f2b0748fe8 100644 --- a/components/mlme/dispatcher/src/wlan_mlme_ucfg_api.c +++ b/components/mlme/dispatcher/src/wlan_mlme_ucfg_api.c @@ -155,6 +155,104 @@ QDF_STATUS ucfg_mlme_pdev_close(struct wlan_objmgr_pdev *pdev) return QDF_STATUS_SUCCESS; } +/** + * ucfg_mlme_convert_power_cfg_chan_to_freq() - converts channel numbers to + * frequencies and copies the triplets to power_freq_data array + * @pdev: pointer to pdev object + * @max_length: Max length of the power chan data array + * @length: length of the data present in power_chan_data array + * @power_chan_data: Power data array from which channel numbers needs to be + * converted to frequencies + * @power_freq_data: Power data array in which the power data needs to be copied + * after conversion of channel numbers to frequencies + * + * power_data is received in the form of (first_channel_number, + * number_of_channels, max_tx_power) triplet, convert the channel numbers from + * the power_chan_data array to frequencies and copy the triplets + * (first_frequency, number_of_channels, max_tx_power) values to + * the power_freq_data array + * + * Return: Number of bytes filled in power_freq_data + */ + +static uint32_t ucfg_mlme_convert_power_cfg_chan_to_freq( + struct wlan_objmgr_pdev *pdev, + uint32_t max_length, + qdf_size_t length, + uint8_t *power_chan_data, + uint8_t *power_freq_data) +{ + uint32_t count = 0, rem_length = length, copied_length = 0, i = 0; + tSirMacChanInfo *pwr_cfg_data; + + pwr_cfg_data = qdf_mem_malloc(max_length); + if (!pwr_cfg_data) + return 0; + + mlme_legacy_debug("max_length %d length %zu", max_length, length); + while ((rem_length >= 3) && + (copied_length <= (max_length - (sizeof(tSirMacChanInfo))))) { + pwr_cfg_data[i].first_freq = wlan_reg_chan_to_freq( + pdev, + power_chan_data[count++]); + pwr_cfg_data[i].numChannels = power_chan_data[count++]; + pwr_cfg_data[i].maxTxPower = power_chan_data[count++]; + copied_length += sizeof(tSirMacChanInfo); + rem_length -= 3; + mlme_legacy_debug("First freq %d num channels %d max tx power %d", + pwr_cfg_data[i].first_freq, + pwr_cfg_data[i].numChannels, + pwr_cfg_data[i].maxTxPower); + i++; + } + + qdf_mem_zero(power_freq_data, max_length); + qdf_mem_copy(power_freq_data, pwr_cfg_data, copied_length); + qdf_mem_free(pwr_cfg_data); + return copied_length; +} + +void ucfg_mlme_cfg_chan_to_freq(struct wlan_objmgr_pdev *pdev) +{ + struct wlan_objmgr_psoc *psoc = wlan_pdev_get_psoc(pdev); + struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_cfg *mlme_cfg; + uint32_t converted_data_len = 0; + + mlme_obj = mlme_get_psoc_obj(psoc); + if (!mlme_obj) + return; + + mlme_cfg = &mlme_obj->cfg; + + mlme_cfg->power.max_tx_power_24.max_len = CFG_MAX_TX_POWER_2_4_LEN; + converted_data_len = ucfg_mlme_convert_power_cfg_chan_to_freq( + pdev, + mlme_cfg->power.max_tx_power_24_chan.max_len, + mlme_cfg->power.max_tx_power_24_chan.len, + mlme_cfg->power.max_tx_power_24_chan.data, + mlme_cfg->power.max_tx_power_24.data); + if (!converted_data_len) { + mlme_legacy_err("mlme cfg power 2_4 data chan number to freq failed"); + return; + } + + mlme_cfg->power.max_tx_power_24.len = converted_data_len; + + mlme_cfg->power.max_tx_power_5.max_len = CFG_MAX_TX_POWER_5_LEN; + converted_data_len = ucfg_mlme_convert_power_cfg_chan_to_freq( + pdev, + mlme_cfg->power.max_tx_power_5_chan.max_len, + mlme_cfg->power.max_tx_power_5_chan.len, + mlme_cfg->power.max_tx_power_5_chan.data, + mlme_cfg->power.max_tx_power_5.data); + if (!converted_data_len) { + mlme_legacy_err("mlme cfg power 5 data chan number to freq failed"); + return; + } + mlme_cfg->power.max_tx_power_5.len = converted_data_len; +} + QDF_STATUS ucfg_mlme_get_sta_keep_alive_period(struct wlan_objmgr_psoc *psoc, uint32_t *val) diff --git a/core/hdd/src/wlan_hdd_main.c b/core/hdd/src/wlan_hdd_main.c index be619ededcbe1..01d19a638acd2 100644 --- a/core/hdd/src/wlan_hdd_main.c +++ b/core/hdd/src/wlan_hdd_main.c @@ -2020,6 +2020,11 @@ static void hdd_update_wiphy_he_cap(struct hdd_context *hdd_ctx) } #endif +static void hdd_component_cfg_chan_to_freq(struct wlan_objmgr_pdev *pdev) +{ + ucfg_mlme_cfg_chan_to_freq(pdev); +} + int hdd_update_tgt_cfg(hdd_handle_t hdd_handle, struct wma_tgt_cfg *cfg) { int ret; @@ -2063,6 +2068,11 @@ int hdd_update_tgt_cfg(hdd_handle_t hdd_handle, struct wma_tgt_cfg *cfg) ret = qdf_status_to_os_return(status); goto dispatcher_close; } + /* + * For 6GHz support this api is added to convert mlme cfgs + * channel numbers to frequency + */ + hdd_component_cfg_chan_to_freq(hdd_ctx->pdev); cdp_pdev_set_ctrl_pdev(cds_get_context(QDF_MODULE_ID_SOC), cds_get_context(QDF_MODULE_ID_TXRX), diff --git a/core/mac/src/pe/lim/lim_utils.c b/core/mac/src/pe/lim/lim_utils.c index 66fb944152fb2..c799827dc4cce 100644 --- a/core/mac/src/pe/lim/lim_utils.c +++ b/core/mac/src/pe/lim/lim_utils.c @@ -8227,10 +8227,11 @@ lim_get_dot11d_transmit_power(struct mac_context *mac, uint8_t channel) { uint32_t cfg_length = 0; int8_t max_tx_pwr = 0; - uint8_t *country_info = NULL; + tSirMacChanInfo *country_info = NULL; uint8_t count = 0; uint8_t first_channel; uint8_t maxChannels; + int32_t rem_length = 0; if (WLAN_REG_IS_5GHZ_CH(channel)) cfg_length = mac->mlme_cfg->power.max_tx_power_5.len; @@ -8258,10 +8259,15 @@ lim_get_dot11d_transmit_power(struct mac_context *mac, uint8_t channel) } /* Identify the channel and maxtxpower */ - while (count <= (cfg_length - (sizeof(tSirMacChanInfo)))) { - first_channel = country_info[count++]; - maxChannels = country_info[count++]; - max_tx_pwr = country_info[count++]; + rem_length = cfg_length; + while (rem_length >= (sizeof(tSirMacChanInfo))) { + first_channel = wlan_reg_freq_to_chan( + mac->pdev, + country_info[count].first_freq); + maxChannels = country_info[count].numChannels; + max_tx_pwr = country_info[count].maxTxPower; + count++; + rem_length -= (sizeof(tSirMacChanInfo)); if ((channel >= first_channel) && (channel < (first_channel + maxChannels))) { diff --git a/core/mac/src/sys/legacy/src/utils/src/parser_api.c b/core/mac/src/sys/legacy/src/utils/src/parser_api.c index 887bc2ca4e921..46760fb9bc919 100644 --- a/core/mac/src/sys/legacy/src/utils/src/parser_api.c +++ b/core/mac/src/sys/legacy/src/utils/src/parser_api.c @@ -385,52 +385,80 @@ QDF_STATUS populate_dot11f_country(struct mac_context *mac, tDot11fIECountry *pDot11f, struct pe_session *pe_session) { - uint32_t len; + uint32_t len, j = 0; enum band_info rfBand; uint8_t temp[CFG_MAX_STR_LEN], code[3]; + tSirMacChanInfo *max_tx_power_data; + uint32_t rem_length = 0, copied_length = 0; - if (pe_session->lim11dEnabled) { - lim_get_rf_band_new(mac, &rfBand, pe_session); - if (rfBand == BAND_5G) { - len = mac->mlme_cfg->power.max_tx_power_5.len; - qdf_mem_copy(temp, - mac->mlme_cfg->power.max_tx_power_5.data, - len); - } else { - len = mac->mlme_cfg->power.max_tx_power_24.len; - qdf_mem_copy(temp, - mac->mlme_cfg->power.max_tx_power_24.data, - len); + if (!pe_session->lim11dEnabled) + return QDF_STATUS_SUCCESS; + + lim_get_rf_band_new(mac, &rfBand, pe_session); + if (rfBand == BAND_5G) { + len = mac->mlme_cfg->power.max_tx_power_5.len; + max_tx_power_data = + (tSirMacChanInfo *)mac->mlme_cfg->power.max_tx_power_5.data; + rem_length = len; + while (rem_length >= (sizeof(tSirMacChanInfo))) { + temp[copied_length++] = + (uint8_t)wlan_reg_freq_to_chan( + mac->pdev, + max_tx_power_data[j].first_freq); + temp[copied_length++] = + max_tx_power_data[j].numChannels; + temp[copied_length++] = + max_tx_power_data[j].maxTxPower; + j++; + rem_length -= (sizeof(tSirMacChanInfo)); } - - if (3 > len) { - /* no limit on tx power, cannot include the IE because at least */ - /* one (channel,num,tx power) must be present */ - return QDF_STATUS_SUCCESS; + } else { + len = mac->mlme_cfg->power.max_tx_power_24.len; + max_tx_power_data = + (tSirMacChanInfo *)mac->mlme_cfg->power.max_tx_power_24.data; + rem_length = len; + while (rem_length >= (sizeof(tSirMacChanInfo))) { + temp[copied_length++] = + (uint8_t)wlan_reg_freq_to_chan( + mac->pdev, + max_tx_power_data[j].first_freq); + temp[copied_length++] = + max_tx_power_data[j].numChannels; + temp[copied_length++] = + max_tx_power_data[j].maxTxPower; + j++; + rem_length -= (sizeof(tSirMacChanInfo)); } - - wlan_reg_read_current_country(mac->psoc, code); - - qdf_mem_copy(pDot11f->country, code, 2); - - /* a wi-fi agile multiband AP shall include a country */ - /* element in all beacon and probe response frames */ - /* where the last octet of country string field is */ - /* set to 0x04 */ - if (mac->mlme_cfg->oce.oce_sap_enabled) - pDot11f->country[2] = 0x04; - - if (len > MAX_SIZE_OF_TRIPLETS_IN_COUNTRY_IE) { - pe_err("len:%d is out of bounds, resetting", len); - len = MAX_SIZE_OF_TRIPLETS_IN_COUNTRY_IE; - } - - pDot11f->num_triplets = (uint8_t) (len / 3); - qdf_mem_copy((uint8_t *) pDot11f->triplets, temp, len); - - pDot11f->present = 1; } + if (sizeof(tSirMacChanInfo) > len) { + /* no limit on tx power, cannot include the IE because at */ + /* atleast one (channel,num,tx power) must be present */ + return QDF_STATUS_SUCCESS; + } + + wlan_reg_read_current_country(mac->psoc, code); + + qdf_mem_copy(pDot11f->country, code, 2); + + /* a wi-fi agile multiband AP shall include a country */ + /* element in all beacon and probe response frames */ + /* where the last octet of country string field is */ + /* set to 0x04 */ + if (mac->mlme_cfg->oce.oce_sap_enabled) + pDot11f->country[2] = 0x04; + + if (copied_length > MAX_SIZE_OF_TRIPLETS_IN_COUNTRY_IE) { + pe_err("len:%d is out of bounds, resetting", len); + copied_length = MAX_SIZE_OF_TRIPLETS_IN_COUNTRY_IE; + } + + pDot11f->num_triplets = (uint8_t)(copied_length / 3); + + qdf_mem_copy((uint8_t *)pDot11f->triplets, temp, copied_length); + + pDot11f->present = 1; + return QDF_STATUS_SUCCESS; } /* End populate_dot11f_country. */ @@ -5882,8 +5910,10 @@ QDF_STATUS populate_dot11f_timing_advert_frame(struct mac_context *mac_ctx, tDot11fTimingAdvertisementFrame *frame) { - uint32_t val, len; + uint32_t val, len, j = 0; uint8_t temp[CFG_MAX_STR_LEN], code[3]; + tSirMacChanInfo *max_tx_power_data; + int32_t rem_length = 0, copied_length = 0; /* Capabilities */ val = mac_ctx->mlme_cfg->wep_params.is_privacy_enabled; @@ -5910,14 +5940,28 @@ populate_dot11f_timing_advert_frame(struct mac_context *mac_ctx, /* Country */ len = mac_ctx->mlme_cfg->power.max_tx_power_5.len; - qdf_mem_copy(temp, mac_ctx->mlme_cfg->power.max_tx_power_5.data, len); + max_tx_power_data = + (tSirMacChanInfo *)mac_ctx->mlme_cfg->power.max_tx_power_5.data; + rem_length = len; + while (rem_length >= (sizeof(tSirMacChanInfo))) { + temp[copied_length++] = + (uint8_t)wlan_reg_freq_to_chan( + mac_ctx->pdev, + max_tx_power_data[j].first_freq); + + temp[copied_length++] = max_tx_power_data[j].numChannels; + temp[copied_length++] = max_tx_power_data[j].maxTxPower; + j++; + rem_length -= (sizeof(tSirMacChanInfo)); + } + wlan_reg_read_current_country(mac_ctx->psoc, code); qdf_mem_copy(&frame->Country, code, 2); - if (len > MAX_SIZE_OF_TRIPLETS_IN_COUNTRY_IE) - len = MAX_SIZE_OF_TRIPLETS_IN_COUNTRY_IE; + if (copied_length > MAX_SIZE_OF_TRIPLETS_IN_COUNTRY_IE) + copied_length = MAX_SIZE_OF_TRIPLETS_IN_COUNTRY_IE; - frame->Country.num_triplets = (uint8_t)(len / 3); - qdf_mem_copy((uint8_t *)&frame->Country.triplets, temp, len); + frame->Country.num_triplets = (uint8_t)(copied_length / 3); + qdf_mem_copy((uint8_t *)&frame->Country.triplets, temp, copied_length); frame->Country.present = 1; /* PowerConstraints */ diff --git a/core/sme/src/csr/csr_api_roam.c b/core/sme/src/csr/csr_api_roam.c index 1ec779774a335..f2d98917b8958 100644 --- a/core/sme/src/csr/csr_api_roam.c +++ b/core/sme/src/csr/csr_api_roam.c @@ -13647,10 +13647,11 @@ int8_t csr_get_cfg_max_tx_power(struct mac_context *mac, uint8_t channel) { uint32_t cfg_length = 0; int8_t maxTxPwr = 0; - uint8_t *pCountryInfo = NULL; + tSirMacChanInfo *pCountryInfo = NULL; uint8_t count = 0; - uint8_t firstChannel; uint8_t maxChannels; + uint8_t firstChannel; + int32_t rem_length = 0; if (WLAN_REG_IS_5GHZ_CH(channel)) { cfg_length = mac->mlme_cfg->power.max_tx_power_5.len; @@ -13679,10 +13680,15 @@ int8_t csr_get_cfg_max_tx_power(struct mac_context *mac, uint8_t channel) } /* Identify the channel and maxtxpower */ - while (count <= (cfg_length - (sizeof(tSirMacChanInfo)))) { - firstChannel = pCountryInfo[count++]; - maxChannels = pCountryInfo[count++]; - maxTxPwr = pCountryInfo[count++]; + rem_length = cfg_length; + while (rem_length >= (sizeof(tSirMacChanInfo))) { + firstChannel = wlan_reg_freq_to_chan( + mac->pdev, + pCountryInfo[count].first_freq); + maxChannels = pCountryInfo[count].numChannels; + maxTxPwr = pCountryInfo[count].maxTxPower; + count++; + rem_length -= (sizeof(tSirMacChanInfo)); if ((channel >= firstChannel) && (channel < (firstChannel + maxChannels))) { diff --git a/core/sme/src/csr/csr_api_scan.c b/core/sme/src/csr/csr_api_scan.c index ff17c83cd1b80..d4dab3587d5d8 100644 --- a/core/sme/src/csr/csr_api_scan.c +++ b/core/sme/src/csr/csr_api_scan.c @@ -1582,13 +1582,23 @@ static void csr_save_tx_power_to_cfg(struct mac_context *mac, pEntry = csr_ll_next(pList, pEntry, LL_ACCESS_LOCK); } if (band == BAND_2G) { - mac->mlme_cfg->power.max_tx_power_24.len = 3 * count; + mac->mlme_cfg->power.max_tx_power_24.len = + sizeof(tSirMacChanInfo) * count; + if (mac->mlme_cfg->power.max_tx_power_24.len > + CFG_MAX_TX_POWER_2_4_LEN) + mac->mlme_cfg->power.max_tx_power_24.len = + CFG_MAX_TX_POWER_2_4_LEN; qdf_mem_copy(mac->mlme_cfg->power.max_tx_power_24.data, (uint8_t *)p_buf, mac->mlme_cfg->power.max_tx_power_24.len); } if (band == BAND_5G) { - mac->mlme_cfg->power.max_tx_power_5.len = 3 * count; + mac->mlme_cfg->power.max_tx_power_5.len = + sizeof(tSirMacChanInfo) * count; + if (mac->mlme_cfg->power.max_tx_power_5.len > + CFG_MAX_TX_POWER_5_LEN) + mac->mlme_cfg->power.max_tx_power_5.len = + CFG_MAX_TX_POWER_5_LEN; qdf_mem_copy(mac->mlme_cfg->power.max_tx_power_5.data, (uint8_t *)p_buf, mac->mlme_cfg->power.max_tx_power_5.len);