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
diff --git a/components/mlme/core/src/wlan_mlme_main.c b/components/mlme/core/src/wlan_mlme_main.c
index 4cf415c..45ffc09 100644
--- a/components/mlme/core/src/wlan_mlme_main.c
+++ b/components/mlme/core/src/wlan_mlme_main.c
@@ -1710,17 +1710,17 @@
 	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 eab93a1..81763ef 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 dade1f7..96f9925 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 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 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 c87f15e..40e1a1a 100644
--- a/components/mlme/dispatcher/inc/wlan_mlme_ucfg_api.h
+++ b/components/mlme/dispatcher/inc/wlan_mlme_ucfg_api.h
@@ -102,6 +102,17 @@
 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 d8f3a01..e74f2b0 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 @@
 	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 be619ed..01d19a6 100644
--- a/core/hdd/src/wlan_hdd_main.c
+++ b/core/hdd/src/wlan_hdd_main.c
@@ -2020,6 +2020,11 @@
 }
 #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 @@
 		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 66fb944..c799827 100644
--- a/core/mac/src/pe/lim/lim_utils.c
+++ b/core/mac/src/pe/lim/lim_utils.c
@@ -8227,10 +8227,11 @@
 {
 	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 @@
 	}
 
 	/* 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 887bc2c..46760fb 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 @@
 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 @@
 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 @@
 
 	/* 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 1ec7797..f2d9891 100644
--- a/core/sme/src/csr/csr_api_roam.c
+++ b/core/sme/src/csr/csr_api_roam.c
@@ -13647,10 +13647,11 @@
 {
 	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 @@
 	}
 
 	/* 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 ff17c83..d4dab35 100644
--- a/core/sme/src/csr/csr_api_scan.c
+++ b/core/sme/src/csr/csr_api_scan.c
@@ -1582,13 +1582,23 @@
 		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);