qcacld-3.0: Add API to set the bonded channel parameters

Add API to CDS to add bonded channel parameters. Given an
operating channel and channel width, the API would verify and
populate the center frequencies.

Change-Id: Ib2c5029cda567308210b028b628d96419e3fd05c
CRs-Fixed: 988355
diff --git a/core/cds/inc/cds_reg_service.h b/core/cds/inc/cds_reg_service.h
index 8e85886..a0d90db 100644
--- a/core/cds/inc/cds_reg_service.h
+++ b/core/cds/inc/cds_reg_service.h
@@ -77,6 +77,64 @@
 	REGDOMAIN_COUNT
 } v_REGDOMAIN_t;
 
+
+/**
+ * enum channel_enum: channel enumeration
+ * @CHAN_ENUM_1: channel number 1
+ * @CHAN_ENUM_2: channel number 2
+ * @CHAN_ENUM_3: channel number 3
+ * @CHAN_ENUM_4: channel number 4
+ * @CHAN_ENUM_5: channel number 5
+ * @CHAN_ENUM_6: channel number 6
+ * @CHAN_ENUM_7: channel number 7
+ * @CHAN_ENUM_8: channel number 8
+ * @CHAN_ENUM_9: channel number 9
+ * @CHAN_ENUM_10: channel number 10
+ * @CHAN_ENUM_11: channel number 11
+ * @CHAN_ENUM_12: channel number 12
+ * @CHAN_ENUM_13: channel number 13
+ * @CHAN_ENUM_14: channel number 14
+ * @CHAN_ENUM_36: channel number 36
+ * @CHAN_ENUM_40: channel number 40
+ * @CHAN_ENUM_44: channel number 44
+ * @CHAN_ENUM_48: channel number 48
+ * @CHAN_ENUM_52: channel number 52
+ * @CHAN_ENUM_56: channel number 56
+ * @CHAN_ENUM_60: channel number 60
+ * @CHAN_ENUM_64: channel number 64
+ * @CHAN_ENUM_100: channel number 100
+ * @CHAN_ENUM_104: channel number 104
+ * @CHAN_ENUM_108: channel number 108
+ * @CHAN_ENUM_112: channel number 112
+ * @CHAN_ENUM_116: channel number 116
+ * @CHAN_ENUM_120: channel number 120
+ * @CHAN_ENUM_124: channel number 124
+ * @CHAN_ENUM_128: channel number 128
+ * @CHAN_ENUM_132: channel number 132
+ * @CHAN_ENUM_136: channel number 136
+ * @CHAN_ENUM_140: channel number 140
+ * @CHAN_ENUM_144: channel number 144
+ * @CHAN_ENUM_149: channel number 149
+ * @CHAN_ENUM_153: channel number 153
+ * @CHAN_ENUM_157: channel number 157
+ * @CHAN_ENUM_161: channel number 161
+ * @CHAN_ENUM_165: channel number 165
+ * @CHAN_ENUM_170: channel number 108
+ * @CHAN_ENUM_171: channel number 112
+ * @CHAN_ENUM_172: channel number 116
+ * @CHAN_ENUM_173: channel number 120
+ * @CHAN_ENUM_174: channel number 124
+ * @CHAN_ENUM_175: channel number 128
+ * @CHAN_ENUM_176: channel number 132
+ * @CHAN_ENUM_177: channel number 136
+ * @CHAN_ENUM_178: channel number 140
+ * @CHAN_ENUM_179: channel number 144
+ * @CHAN_ENUM_180: channel number 149
+ * @CHAN_ENUM_181: channel number 153
+ * @CHAN_ENUM_182: channel number 157
+ * @CHAN_ENUM_183: channel number 161
+ * @CHAN_ENUM_184: channel number 165
+ */
 enum channel_enum {
 	CHAN_ENUM_1 = 0,
 	CHAN_ENUM_2,
@@ -155,22 +213,20 @@
 
 /**
  * enum channel_state: channel state
- *
  * @CHANNEL_STATE_DISABLE: channel disabled
- * @CHANNEL_STATE_ENABLE: tx/rx enabled
  * @CHANNEL_STATE_DFS: rx enabled, tx DFS
+ * @CHANNEL_STATE_ENABLE: tx/rx enabled
  * @CHANNEL_STATE_INVALID: not a valid channel
  */
 enum channel_state {
 	CHANNEL_STATE_DISABLE,
-	CHANNEL_STATE_ENABLE,
 	CHANNEL_STATE_DFS,
-	CHANNEL_STATE_INVALID
+	CHANNEL_STATE_ENABLE,
+	CHANNEL_STATE_INVALID,
 };
 
 /**
  * struct regulatory_channel: regulatory channel
- *
  * @state: channel state
  * @flags: channel flags
  * @pwr_limit: channel tx power limit
@@ -183,7 +239,6 @@
 
 /**
  * struct chan_map: channel mapping
- *
  * @center_freq: channel center freq
  * @chan_num: channel number
  */
@@ -194,7 +249,6 @@
 
 /**
  * struct channel_power: channel power
- *
  * @chan_num: channel number
  * @power: tx power
  */
@@ -205,7 +259,6 @@
 
 /**
  * enum country_src: country source
- *
  * @SOURCE_QUERY: source query
  * @SOURCE_CORE: source regulatory core
  * @SOURCE_DRIVER: source driver
@@ -222,7 +275,6 @@
 
 /**
  * struct regulatory: regulatory information
- *
  * @reg_domain: regulatory domain pair
  * @eeprom_rd_ext: eeprom value
  * @country_code: current country in integer
@@ -248,27 +300,43 @@
 };
 
 /**
- * phy_ch_width - channel width
- * @CH_WIDTH_20MHZ: channel width 20 MHz
- * @CH_WIDTH_40MHZ: channel width 40 MHz
- * @CH_WIDTH_80MHZ: channel width 80MHz
- * @CH_WIDTH_160MHZ: channel width 160 MHz
- * @CH_WIDTH_80P80MHZ: channel width 160MHz(80+80)
- * @CH_WIDTH_5MHZ: channel width 5MHz
- * @CH_WIDTH_10MHZ: channel width 10MHz
+ * enum phy_ch_width - physical layer channel width
+ * @CH_WIDTH_20MHZ: channel width 20 mhz
+ * @CH_WIDTH_40MHZ: channel width 40 mhz
+ * @CH_WIDTH_80MHZ: channel width 80 mhz
+ * @CH_WIDTH_160MHZ: channel width 160 mhz
+ * @CH_WIDTH_80P80MHZ: channel width 80+80 mhz
+ * @CH_WIDTH_5MHZ: channel width 5 mhz
+ * @CH_WIDTH_10MHZ: channel width 10 mhz
+ * @CH_WIDTH_INVALID: invalid channel width
+ * @CH_WIDTH_MAX: maximum channel width
  */
 enum phy_ch_width {
 	CH_WIDTH_20MHZ = 0,
-	CH_WIDTH_40MHZ = 1,
-	CH_WIDTH_80MHZ = 2,
-	CH_WIDTH_160MHZ = 3,
-	CH_WIDTH_80P80MHZ = 4,
-	CH_WIDTH_5MHZ = 5,
-	CH_WIDTH_10MHZ = 6,
-	CH_WIDTH_INVALID = 7,
+	CH_WIDTH_40MHZ,
+	CH_WIDTH_80MHZ,
+	CH_WIDTH_160MHZ,
+	CH_WIDTH_80P80MHZ,
+	CH_WIDTH_5MHZ,
+	CH_WIDTH_10MHZ,
+	CH_WIDTH_INVALID,
 	CH_WIDTH_MAX
 };
 
+/**
+ * struct ch_params_s
+ * @ch_width: channel width
+ * @sec_ch_offset: secondary channel offset
+ * @center_freq_seg0: center freq for segment 0
+ * @center_freq_seg1: center freq for segment 1
+ */
+struct ch_params_s {
+	enum phy_ch_width ch_width;
+	uint8_t sec_ch_offset;
+	uint8_t center_freq_seg0;
+	uint8_t center_freq_seg1;
+};
+
 extern const struct chan_map chan_mapping[NUM_CHANNELS];
 extern struct regulatory_channel reg_channels[NUM_CHANNELS];
 
@@ -286,11 +354,16 @@
 QDF_STATUS cds_get_dfs_region(uint8_t *dfs_region);
 QDF_STATUS cds_put_dfs_region(uint8_t dfs_region);
 
-bool cds_is_dsrc_channel(uint16_t);
-enum channel_state cds_get_bonded_channel_state(uint32_t chan_num,
-					   enum phy_ch_width chan_width);
+bool cds_is_dsrc_channel(uint16_t center_freq);
+enum channel_state cds_get_5g_bonded_channel_state(uint16_t chan_num,
+						 enum phy_ch_width chan_width);
 
-enum phy_ch_width cds_get_max_channel_bw(uint32_t chan_num);
+enum channel_state cds_get_2g_bonded_channel_state(uint16_t chan_num,
+						   enum phy_ch_width chan_width,
+						   uint16_t sec_ch);
+
+void cds_set_channel_params(uint16_t oper_ch, uint16_t ht_offset_2g,
+			    struct ch_params_s *ch_params);
 
 QDF_STATUS cds_set_reg_domain(void *client_ctxt, v_REGDOMAIN_t reg_domain);
 QDF_STATUS cds_put_default_country(uint8_t *def_country);
diff --git a/core/cds/inc/cds_regdomain.h b/core/cds/inc/cds_regdomain.h
index 594eea8..336a20d 100644
--- a/core/cds/inc/cds_regdomain.h
+++ b/core/cds/inc/cds_regdomain.h
@@ -525,20 +525,6 @@
 };
 
 /**
- * struct ch_params_s
- * @ch_width: channel width
- * @sec_ch_offset: secondary channel offset
- * @center_freq_seg0: center freq for segment 0
- * @center_freq_seg1: center freq for segment 1
- */
-struct ch_params_s {
-	enum phy_ch_width ch_width;
-	uint8_t sec_ch_offset;
-	uint8_t center_freq_seg0;
-	uint8_t center_freq_seg1;
-};
-
-/**
  * struct reg_dmn: regulatory domain structure
  * @reg_dmn: regulatory domain
  * @conformance_test_limit:  CTL limit
diff --git a/core/cds/src/cds_reg_service.c b/core/cds/src/cds_reg_service.c
index d43acc0..cd0ed13 100644
--- a/core/cds/src/cds_reg_service.c
+++ b/core/cds/src/cds_reg_service.c
@@ -101,9 +101,58 @@
 	[CHAN_ENUM_184] = {5920, 184},
 };
 
+/**
+ * struct bonded_chan
+ * @start_ch: start channel
+ * @end_ch: end channel
+ */
+struct bonded_chan {
+	uint16_t start_ch;
+	uint16_t end_ch;
+};
+
+static const struct bonded_chan bonded_chan_40mhz_array[] = {
+	{36, 40},
+	{44, 48},
+	{52, 56},
+	{60, 64},
+	{100, 104},
+	{108, 112},
+	{116, 120},
+	{124, 128},
+	{132, 136},
+	{140, 144},
+	{149, 153},
+	{157, 161}
+};
+
+static const struct bonded_chan bonded_chan_80mhz_array[] = {
+	{36, 48},
+	{52, 64},
+	{100, 112},
+	{116, 128},
+	{132, 144},
+	{149, 161}
+};
+
+static const struct bonded_chan bonded_chan_160mhz_array[] = {
+	{36, 64},
+	{100, 128}
+};
+
+static const enum phy_ch_width next_lower_bw[] = {
+	[CH_WIDTH_80P80MHZ] = CH_WIDTH_160MHZ,
+	[CH_WIDTH_160MHZ] = CH_WIDTH_80MHZ,
+	[CH_WIDTH_80MHZ] = CH_WIDTH_40MHZ,
+	[CH_WIDTH_40MHZ] = CH_WIDTH_20MHZ,
+	[CH_WIDTH_20MHZ] = CH_WIDTH_10MHZ,
+	[CH_WIDTH_10MHZ] = CH_WIDTH_5MHZ,
+	[CH_WIDTH_5MHZ] = CH_WIDTH_INVALID
+};
+
 struct regulatory_channel reg_channels[NUM_CHANNELS];
-uint8_t default_country[CDS_COUNTRY_CODE_LEN + 1];
-uint8_t dfs_region;
+static uint8_t default_country[CDS_COUNTRY_CODE_LEN + 1];
+static uint8_t dfs_region;
 
 /**
  * cds_get_channel_list_with_power() - retrieve channel list with power
@@ -121,15 +170,7 @@
 
 	if (base_channels && num_base_channels) {
 		count = 0;
-		for (i = 0; i <= CHAN_ENUM_14; i++) {
-			if (reg_channels[i].state) {
-				base_channels[count].chan_num =
-					chan_mapping[i].chan_num;
-				base_channels[count++].power =
-					reg_channels[i].pwr_limit;
-			}
-		}
-		for (i = CHAN_ENUM_36; i <= CHAN_ENUM_184; i++) {
+		for (i = 0; i < NUM_CHANNELS; i++) {
 			if (reg_channels[i].state) {
 				base_channels[count].chan_num =
 					chan_mapping[i].chan_num;
@@ -203,82 +244,308 @@
 
 
 /**
- * cds_get_bonded_channel_state() - get the bonded channel state
- * @channel_num: channel number
+ * cds_search_5g_bonded_chan_array() - get ptr to bonded channel
+ * @oper_ch: operating channel number
+ * @bonded_chan_ar: bonded channel array
+ * @bonded_chan_ptr_ptr: bonded channel ptr ptr
+ *
+ * Return: bonded channel state
+ */
+static enum channel_state cds_search_5g_bonded_chan_array(uint32_t oper_chan,
+							const struct bonded_chan
+							bonded_chan_ar[],
+							uint16_t array_size,
+							const struct bonded_chan
+							**bonded_chan_ptr_ptr)
+{
+	int i;
+	uint8_t chan_num;
+	const struct bonded_chan *bonded_chan_ptr = NULL;
+	enum channel_state chan_state = CHANNEL_STATE_INVALID;
+	enum channel_state temp_chan_state;
+
+	for (i = 0; i < array_size; i++) {
+		if ((oper_chan >= bonded_chan_ar[i].start_ch) &&
+		    (oper_chan <= bonded_chan_ar[i].end_ch)) {
+			bonded_chan_ptr =  &(bonded_chan_ar[i]);
+			break;
+		}
+	}
+
+	if (NULL == bonded_chan_ptr)
+		return chan_state;
+
+	*bonded_chan_ptr_ptr = bonded_chan_ptr;
+	chan_num =  bonded_chan_ptr->start_ch;
+	while (chan_num <= bonded_chan_ptr->end_ch) {
+		temp_chan_state = cds_get_channel_state(chan_num);
+		if (temp_chan_state < chan_state)
+			chan_state = temp_chan_state;
+		chan_num = chan_num + 4;
+	}
+
+	return chan_state;
+}
+
+/**
+ * cds_search_5g_bonded_channel() - get the 5G bonded channel state
+ * @chan_num: channel number
+ * @ch_width: channel width
+ * @bonded_chan_ptr_ptr: bonded channel ptr ptr
  *
  * Return: channel state
  */
-enum channel_state cds_get_bonded_channel_state(uint32_t chan_num,
-					   enum phy_ch_width ch_width)
+static enum channel_state cds_search_5g_bonded_channel(uint32_t chan_num,
+						enum phy_ch_width ch_width,
+						const struct bonded_chan
+						**bonded_chan_ptr_ptr)
+{
+
+	if (CH_WIDTH_80P80MHZ == ch_width)
+		return cds_search_5g_bonded_chan_array(chan_num,
+						       bonded_chan_80mhz_array,
+						       QDF_ARRAY_SIZE(bonded_chan_80mhz_array),
+						       bonded_chan_ptr_ptr);
+	else if (CH_WIDTH_160MHZ == ch_width)
+		return cds_search_5g_bonded_chan_array(chan_num,
+						       bonded_chan_160mhz_array,
+						       QDF_ARRAY_SIZE(bonded_chan_160mhz_array),
+						       bonded_chan_ptr_ptr);
+	else if (CH_WIDTH_80MHZ == ch_width)
+		return cds_search_5g_bonded_chan_array(chan_num,
+						       bonded_chan_80mhz_array,
+						       QDF_ARRAY_SIZE(bonded_chan_80mhz_array),
+						       bonded_chan_ptr_ptr);
+	else if (CH_WIDTH_40MHZ == ch_width)
+		return cds_search_5g_bonded_chan_array(chan_num,
+						       bonded_chan_40mhz_array,
+						       QDF_ARRAY_SIZE(bonded_chan_40mhz_array),
+						       bonded_chan_ptr_ptr);
+	else
+		return cds_get_channel_state(chan_num);
+}
+
+/**
+ * cds_get_2g_bonded_channel_state() - get the 2G bonded channel state
+ * @oper_ch: operating channel
+ * @ch_width: channel width
+ * @sec_ch: secondary channel
+ *
+ * Return: channel state
+ */
+enum channel_state cds_get_2g_bonded_channel_state(uint16_t oper_ch,
+						  enum phy_ch_width ch_width,
+						  uint16_t sec_ch)
 {
 	enum channel_enum chan_enum;
+	enum channel_state chan_state;
 	bool bw_enabled = false;
+	enum channel_state chan_state2 = CHANNEL_STATE_INVALID;
 
-	chan_enum = cds_get_channel_enum(chan_num);
-	if (INVALID_CHANNEL == chan_enum)
+	if (CH_WIDTH_40MHZ < ch_width)
 		return CHANNEL_STATE_INVALID;
 
-	if (reg_channels[chan_enum].state) {
-		if (CH_WIDTH_5MHZ == ch_width)
-			bw_enabled = 1;
-		else if (CH_WIDTH_10MHZ == ch_width)
-			bw_enabled = !(reg_channels[chan_enum].flags &
-				       IEEE80211_CHAN_NO_10MHZ);
-		else if (CH_WIDTH_20MHZ == ch_width)
-			bw_enabled = !(reg_channels[chan_enum].flags &
-				       IEEE80211_CHAN_NO_20MHZ);
-		else if (CH_WIDTH_40MHZ == ch_width)
-			bw_enabled = !(reg_channels[chan_enum].flags &
-				       IEEE80211_CHAN_NO_HT40);
-		else if (CH_WIDTH_80MHZ == ch_width)
-			bw_enabled = !(reg_channels[chan_enum].flags &
-				       IEEE80211_CHAN_NO_80MHZ);
-		else if (CH_WIDTH_160MHZ == ch_width)
-			bw_enabled = !(reg_channels[chan_enum].flags &
-				       IEEE80211_CHAN_NO_160MHZ);
+	if (CH_WIDTH_40MHZ == ch_width) {
+		if ((sec_ch + 4 != oper_ch) ||
+		    (oper_ch + 4 != sec_ch))
+			return CHANNEL_STATE_INVALID;
+		chan_state2 = cds_get_channel_state(sec_ch);
+		if (CHANNEL_STATE_INVALID == chan_state2)
+			return chan_state2;
 	}
 
+	chan_state = cds_get_channel_state(oper_ch);
+	if (chan_state2 < chan_state)
+		chan_state = chan_state2;
+
+	if ((CHANNEL_STATE_INVALID == chan_state) ||
+	    (CHANNEL_STATE_DISABLE == chan_state))
+		return chan_state;
+
+	chan_enum = cds_get_channel_enum(oper_ch);
+	if (CH_WIDTH_5MHZ == ch_width)
+		bw_enabled = true;
+	else if (CH_WIDTH_10MHZ == ch_width)
+		bw_enabled = !(reg_channels[chan_enum].flags &
+			       IEEE80211_CHAN_NO_10MHZ);
+	else if (CH_WIDTH_20MHZ == ch_width)
+		bw_enabled = !(reg_channels[chan_enum].flags &
+			       IEEE80211_CHAN_NO_20MHZ);
+	else if (CH_WIDTH_40MHZ == ch_width)
+		bw_enabled = !(reg_channels[chan_enum].flags &
+			       IEEE80211_CHAN_NO_HT40);
+
 	if (bw_enabled)
-		return reg_channels[chan_enum].state;
+		return chan_state;
 	else
 		return CHANNEL_STATE_DISABLE;
 }
 
 /**
- * cds_get_max_channel_bw() - get the max channel bandwidth
- * @channel_num: channel number
+ * cds_get_5g_bonded_channel_state() - get the 5G bonded channel state
+ * @chan_num: channel number
+ * @ch_width: channel width
  *
- * Return: channel_width
+ * Return: channel state
  */
-enum phy_ch_width cds_get_max_channel_bw(uint32_t chan_num)
+enum channel_state cds_get_5g_bonded_channel_state(
+	uint16_t chan_num,
+	enum phy_ch_width ch_width)
 {
 	enum channel_enum chan_enum;
-	enum phy_ch_width chan_bw = CH_WIDTH_INVALID;
+	enum channel_state chan_state;
+	bool bw_enabled = false;
+	const struct bonded_chan *bonded_chan_ptr = NULL;
+
+	if (CH_WIDTH_80P80MHZ < ch_width)
+		return CHANNEL_STATE_INVALID;
+
+	chan_state = cds_search_5g_bonded_channel(chan_num, ch_width,
+						  &bonded_chan_ptr);
+
+	if ((CHANNEL_STATE_INVALID == chan_state) ||
+	    (CHANNEL_STATE_DISABLE == chan_state))
+		return chan_state;
 
 	chan_enum = cds_get_channel_enum(chan_num);
+	if (CH_WIDTH_5MHZ == ch_width)
+		bw_enabled = true;
+	else if (CH_WIDTH_10MHZ == ch_width)
+		bw_enabled = !(reg_channels[chan_enum].flags &
+			       IEEE80211_CHAN_NO_10MHZ);
+	else if (CH_WIDTH_20MHZ == ch_width)
+		bw_enabled = !(reg_channels[chan_enum].flags &
+			       IEEE80211_CHAN_NO_20MHZ);
+	else if (CH_WIDTH_40MHZ == ch_width)
+		bw_enabled = !(reg_channels[chan_enum].flags &
+			       IEEE80211_CHAN_NO_HT40);
+	else if (CH_WIDTH_80MHZ == ch_width)
+		bw_enabled = !(reg_channels[chan_enum].flags &
+			       IEEE80211_CHAN_NO_80MHZ);
+	else if (CH_WIDTH_160MHZ == ch_width)
+		bw_enabled = !(reg_channels[chan_enum].flags &
+			       IEEE80211_CHAN_NO_160MHZ);
+	else if (CH_WIDTH_80P80MHZ == ch_width)
+		bw_enabled = !(reg_channels[chan_enum].flags &
+			       IEEE80211_CHAN_NO_80MHZ);
 
-	if ((INVALID_CHANNEL != chan_enum) &&
-	    (CHANNEL_STATE_DISABLE != reg_channels[chan_enum].state)) {
+	if (bw_enabled)
+		return chan_state;
+	else
+		return CHANNEL_STATE_DISABLE;
+}
 
-		if (!(reg_channels[chan_enum].flags &
-		      IEEE80211_CHAN_NO_160MHZ))
-			chan_bw = CH_WIDTH_160MHZ;
-		else if (!(reg_channels[chan_enum].flags &
-			   IEEE80211_CHAN_NO_80MHZ))
-			chan_bw = CH_WIDTH_80MHZ;
-		else if (!(reg_channels[chan_enum].flags &
-			   IEEE80211_CHAN_NO_HT40))
-			chan_bw = CH_WIDTH_40MHZ;
-		else if (!(reg_channels[chan_enum].flags &
-			   IEEE80211_CHAN_NO_20MHZ))
-			chan_bw = CH_WIDTH_20MHZ;
-		else if (!(reg_channels[chan_enum].flags &
-			   IEEE80211_CHAN_NO_10MHZ))
-			chan_bw = CH_WIDTH_10MHZ;
-		else
-			chan_bw = CH_WIDTH_5MHZ;
+
+/**
+ * cds_set_5g_channel_params() - set the 5G bonded channel parameters
+ * @oper_ch: opetrating channel
+ * @ch_params: channel parameters
+ *
+ * Return: void
+ */
+static void cds_set_5g_channel_params(uint16_t oper_ch,
+				      struct ch_params_s *ch_params)
+{
+	enum channel_state chan_state = CHANNEL_STATE_ENABLE;
+	enum channel_state chan_state2 = CHANNEL_STATE_ENABLE;
+	const struct bonded_chan *bonded_chan_ptr;
+
+	if (CH_WIDTH_MAX >= ch_params->ch_width)
+		ch_params->ch_width = CH_WIDTH_80P80MHZ;
+
+	while (ch_params->ch_width != CH_WIDTH_INVALID) {
+		chan_state = cds_search_5g_bonded_channel(oper_ch,
+							  ch_params->ch_width,
+							  &bonded_chan_ptr);
+
+		chan_state = cds_get_5g_bonded_channel_state(oper_ch,
+							  ch_params->ch_width);
+
+		if (CH_WIDTH_80P80MHZ == ch_params->ch_width)
+			chan_state2 = cds_get_5g_bonded_channel_state(
+				ch_params->center_freq_seg1 - 2,
+				CH_WIDTH_80MHZ);
+
+		if (chan_state2 < chan_state)
+			chan_state = chan_state2;
+		if ((CHANNEL_STATE_ENABLE == chan_state) ||
+		    (CHANNEL_STATE_DFS == chan_state)) {
+			if (CH_WIDTH_20MHZ >= ch_params->ch_width)
+				ch_params->sec_ch_offset
+					= PHY_SINGLE_CHANNEL_CENTERED;
+			else if (CH_WIDTH_40MHZ == ch_params->ch_width) {
+				if (oper_ch == bonded_chan_ptr->start_ch)
+					ch_params->sec_ch_offset =
+						PHY_DOUBLE_CHANNEL_LOW_PRIMARY;
+				else
+					ch_params->sec_ch_offset =
+						PHY_DOUBLE_CHANNEL_HIGH_PRIMARY;
+			}
+
+			ch_params->center_freq_seg0 =
+				(bonded_chan_ptr->start_ch +
+				 bonded_chan_ptr->end_ch)/2;
+			break;
+		}
+
+		ch_params->ch_width = next_lower_bw[ch_params->ch_width];
 	}
-	return chan_bw;
+}
+
+/**
+ * cds_set_2g_channel_params() - set the 2.4G bonded channel parameters
+ * @oper_ch: operating channel
+ * @ch_params: channel parameters
+ * @sec_ch_2g: 2.4G secondary channel
+ *
+ * Return: void
+ */
+static void cds_set_2g_channel_params(uint16_t oper_ch,
+			       struct ch_params_s *ch_params,
+			       uint16_t sec_ch_2g)
+{
+	enum channel_state chan_state = CHANNEL_STATE_ENABLE;
+
+	if (CH_WIDTH_MAX >= ch_params->ch_width)
+		ch_params->ch_width = CH_WIDTH_80P80MHZ;
+
+	while (ch_params->ch_width != CH_WIDTH_INVALID) {
+		chan_state = cds_get_2g_bonded_channel_state(oper_ch,
+							    ch_params->ch_width,
+							    sec_ch_2g);
+		if (CHANNEL_STATE_ENABLE == chan_state) {
+			if (CH_WIDTH_40MHZ == ch_params->ch_width) {
+				if (oper_ch < sec_ch_2g)
+					ch_params->sec_ch_offset =
+						PHY_DOUBLE_CHANNEL_LOW_PRIMARY;
+				else
+					ch_params->sec_ch_offset =
+						PHY_DOUBLE_CHANNEL_HIGH_PRIMARY;
+			} else
+				ch_params->sec_ch_offset =
+					PHY_SINGLE_CHANNEL_CENTERED;
+			break;
+		}
+
+		ch_params->ch_width = next_lower_bw[ch_params->ch_width];
+	}
+}
+
+/**
+ * cds_set_channel_params() - set the bonded channel parameters
+ * @oper_ch: operating channel
+ * @sec_ch_2g: 2.4G secondary channel
+ * @ch_params: chanel parameters
+ *
+ * Return: void
+ */
+void cds_set_channel_params(uint16_t oper_ch, uint16_t sec_ch_2g,
+			    struct ch_params_s *ch_params)
+{
+	if (CDS_IS_CHANNEL_5GHZ(oper_ch))
+		cds_set_5g_channel_params(oper_ch, ch_params);
+	else if  (CDS_IS_CHANNEL_24GHZ(oper_ch))
+		cds_set_2g_channel_params(oper_ch, ch_params, sec_ch_2g);
 }
 
 /**
@@ -347,9 +614,9 @@
 {
 	if (center_freq >= 5852 &&
 	    center_freq <= 5920)
-		return 1;
+		return true;
 
-	return 0;
+	return false;
 }
 
 /**
diff --git a/core/wma/src/wma_features.c b/core/wma/src/wma_features.c
index 669854c..4086ea1 100644
--- a/core/wma/src/wma_features.c
+++ b/core/wma/src/wma_features.c
@@ -6138,9 +6138,12 @@
 		dfs_ic->ic_curchan->ic_ieee_ext = ext_channel;
 
 		/* verify both the 80MHz are DFS bands or not */
-		if (CHANNEL_STATE_DFS == cds_get_channel_state(req->chan) &&
-		    CHANNEL_STATE_DFS == cds_get_channel_state(ext_channel -
-						WMA_80MHZ_START_CENTER_CH_DIFF))
+		if ((CHANNEL_STATE_DFS ==
+		     cds_get_5g_bonded_channel_state(req->chan ,
+						     CH_WIDTH_80MHZ)) &&
+		    (CHANNEL_STATE_DFS == cds_get_5g_bonded_channel_state(
+			    ext_channel - WMA_80MHZ_START_CENTER_CH_DIFF,
+			    CH_WIDTH_80MHZ)))
 			dfs_ic->ic_curchan->ic_80p80_both_dfs = true;
 		break;
 	case CH_WIDTH_160MHZ: