xref: /wlan-dirver/qca-wifi-host-cmn/umac/regulatory/core/src/reg_build_chan_list.c (revision 70a19e16789e308182f63b15c75decec7bf0b342)
1 /*
2  * Copyright (c) 2014-2021 The Linux Foundation. All rights reserved.
3  * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
4  *
5  * Permission to use, copy, modify, and/or distribute this software for
6  * any purpose with or without fee is hereby granted, provided that the
7  * above copyright notice and this permission notice appear in all
8  * copies.
9  *
10  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
11  * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
12  * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
13  * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
14  * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
15  * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
16  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
17  * PERFORMANCE OF THIS SOFTWARE.
18  */
19 
20 /**
21  * DOC: reg_build_chan_list.c
22  * This file defines the API to build master and current channel list.
23  */
24 
25 #include <wlan_cmn.h>
26 #include <reg_services_public_struct.h>
27 #include <wlan_objmgr_psoc_obj.h>
28 #include <wlan_objmgr_pdev_obj.h>
29 #include "reg_priv_objs.h"
30 #include "reg_utils.h"
31 #include "reg_callbacks.h"
32 #include "reg_services_common.h"
33 #include "reg_db.h"
34 #include "reg_db_parser.h"
35 #include "reg_offload_11d_scan.h"
36 #include <scheduler_api.h>
37 #include "reg_build_chan_list.h"
38 #include <qdf_platform.h>
39 #include <wlan_reg_services_api.h>
40 
41 #define MAX_PWR_FCC_CHAN_12 8
42 #define MAX_PWR_FCC_CHAN_13 2
43 #define CHAN_144_CENT_FREQ 5720
44 
45 /**
46  * reg_init_chan() - Initialize the channel list from the channel_map global
47  *	list
48  * @dst_list: list to initialize
49  * @beg_enum: starting point in list(inclusive)
50  * @end_enum: ending point in list(inclusive)
51  * @dst_idx_adj: offset between channel_map and dst_list
52  * @soc_reg: soc private object for regulatory
53  *
54  * Return: none
55  */
56 static void reg_init_chan(struct regulatory_channel *dst_list,
57 			  enum channel_enum beg_enum,
58 			  enum channel_enum end_enum, uint8_t dst_idx_adj,
59 			  struct wlan_regulatory_psoc_priv_obj *soc_reg)
60 {
61 	enum channel_enum chan_enum;
62 	uint8_t dst_idx;
63 
64 	for (chan_enum = beg_enum; chan_enum <= end_enum; chan_enum++) {
65 		dst_idx = chan_enum - dst_idx_adj;
66 
67 		dst_list[dst_idx].chan_num = channel_map[chan_enum].chan_num;
68 		dst_list[dst_idx].center_freq =
69 					channel_map[chan_enum].center_freq;
70 		dst_list[dst_idx].chan_flags = REGULATORY_CHAN_DISABLED;
71 		dst_list[dst_idx].state = CHANNEL_STATE_DISABLE;
72 		if (!soc_reg->retain_nol_across_regdmn_update)
73 			dst_list[dst_idx].nol_chan = false;
74 	}
75 }
76 
77 static inline bool
78 reg_nol_and_history_not_set(struct regulatory_channel *chan)
79 {
80 	return ((!chan->nol_chan) && (!chan->nol_history));
81 }
82 
83 bool reg_is_chan_disabled_and_not_nol(struct regulatory_channel *chan)
84 {
85 	return (!reg_is_state_allowed(chan->state) &&
86 		(chan->chan_flags & REGULATORY_CHAN_DISABLED) &&
87 		reg_nol_and_history_not_set(chan));
88 }
89 #ifdef CONFIG_BAND_6GHZ
90 static void reg_fill_psd_info(enum channel_enum chan_enum,
91 			      struct cur_reg_rule *reg_rule,
92 			      struct regulatory_channel *master_list)
93 {
94 	master_list[chan_enum].psd_flag = reg_rule->psd_flag;
95 
96 	master_list[chan_enum].psd_eirp = reg_rule->psd_eirp;
97 }
98 
99 /**
100  * reg_init_6ghz_master_chan() - Init 6 GHz channel list
101  * @dst_list: pointer to 6 GHz channel list
102  * @soc_reg: pointer to regulatory psoc private object.
103  *
104  * Return: None
105  */
106 static void
107 reg_init_6ghz_master_chan(struct regulatory_channel *dst_list,
108 			  struct wlan_regulatory_psoc_priv_obj *soc_reg)
109 {
110 	reg_init_chan(dst_list, MIN_6GHZ_CHANNEL, MAX_6GHZ_CHANNEL,
111 		      MIN_6GHZ_CHANNEL, soc_reg);
112 }
113 #else
114 static inline void reg_fill_psd_info(enum channel_enum chan_enum,
115 				     struct cur_reg_rule *reg_rule,
116 				     struct regulatory_channel *master_list)
117 {
118 }
119 
120 static inline void
121 reg_init_6ghz_master_chan(struct regulatory_channel *dst_list,
122 			  struct wlan_regulatory_psoc_priv_obj *soc_reg)
123 {
124 }
125 #endif
126 
127 /**
128  * reg_fill_channel_info() - Populate TX power, antenna gain, channel state,
129  * channel flags, min and max bandwidth to master channel list.
130  * @chan_enum: Channel enum.
131  * @reg_rule: Pointer to regulatory rule which has tx power and antenna gain.
132  * @master_list: Pointer to master channel list.
133  * @min_bw: minimum bandwidth to be used for given channel.
134  */
135 static void reg_fill_channel_info(enum channel_enum chan_enum,
136 				  struct cur_reg_rule *reg_rule,
137 				  struct regulatory_channel *master_list,
138 				  uint16_t min_bw)
139 {
140 	master_list[chan_enum].chan_flags &= ~REGULATORY_CHAN_DISABLED;
141 
142 	reg_fill_psd_info(chan_enum, reg_rule, master_list);
143 	master_list[chan_enum].tx_power = reg_rule->reg_power;
144 	master_list[chan_enum].ant_gain = reg_rule->ant_gain;
145 	master_list[chan_enum].state = CHANNEL_STATE_ENABLE;
146 
147 	if (reg_rule->flags & REGULATORY_CHAN_NO_IR) {
148 		master_list[chan_enum].chan_flags |= REGULATORY_CHAN_NO_IR;
149 		master_list[chan_enum].state = CHANNEL_STATE_DFS;
150 	}
151 
152 	if (reg_rule->flags & REGULATORY_CHAN_RADAR) {
153 		master_list[chan_enum].chan_flags |= REGULATORY_CHAN_RADAR;
154 		master_list[chan_enum].state = CHANNEL_STATE_DFS;
155 	}
156 
157 	if (reg_rule->flags & REGULATORY_CHAN_INDOOR_ONLY)
158 		master_list[chan_enum].chan_flags |=
159 			REGULATORY_CHAN_INDOOR_ONLY;
160 
161 	if (reg_rule->flags & REGULATORY_CHAN_NO_OFDM)
162 		master_list[chan_enum].chan_flags |= REGULATORY_CHAN_NO_OFDM;
163 
164 	master_list[chan_enum].min_bw = min_bw;
165 	if (master_list[chan_enum].max_bw == 20)
166 		master_list[chan_enum].max_bw = reg_rule->max_bw;
167 }
168 
169 #ifdef CONFIG_BAND_6GHZ
170 /**
171  * reg_dis_chan_state_and_flags() - Disable the input channel state
172  * and chan_flags
173  * @state: Channel state
174  * @chan_flags: Channel flags
175  *
176  * Return: void
177  */
178 static void reg_dis_chan_state_and_flags(enum channel_state *state,
179 					 uint32_t *chan_flags)
180 {
181 	*state = CHANNEL_STATE_DISABLE;
182 	*chan_flags |= REGULATORY_CHAN_DISABLED;
183 }
184 
185 /**
186  * reg_populate_band_channels_ext_for_6g() - For all the valid regdb channels in
187  *	the master channel list, find the regulatory rules and call
188  *	reg_fill_channel_info() to populate master channel list with txpower,
189  *	antennagain, BW info, etc.
190  * @start_idx: Start channel range in list
191  * @end_idx: End channel range in list
192  * @rule_start_ptr: Pointer to regulatory rules
193  * @num_reg_rules: Number of regulatory rules
194  * @min_reg_bw: Minimum regulatory bandwidth
195  * @mas_chan_list: Pointer to master channel list
196  */
197 static void reg_populate_band_channels_ext_for_6g(uint16_t start_idx,
198 				       uint16_t end_idx,
199 				       struct cur_reg_rule *rule_start_ptr,
200 				       uint32_t num_reg_rules,
201 				       uint16_t min_reg_bw,
202 				       struct regulatory_channel *mas_chan_list)
203 {
204 	struct cur_reg_rule *found_rule_ptr;
205 	struct cur_reg_rule *cur_rule_ptr;
206 	struct regulatory_channel;
207 	uint32_t rule_num, bw;
208 	uint16_t i, min_bw, max_bw;
209 
210 	for (i = start_idx; i <= end_idx; i++) {
211 		found_rule_ptr = NULL;
212 
213 		max_bw = QDF_MIN((uint16_t)20,
214 				 channel_map[MIN_6GHZ_CHANNEL + i].max_bw);
215 		min_bw = QDF_MAX(min_reg_bw,
216 				 channel_map[MIN_6GHZ_CHANNEL + i].min_bw);
217 
218 		if (channel_map[MIN_6GHZ_CHANNEL + i].chan_num ==
219 		    INVALID_CHANNEL_NUM)
220 			continue;
221 
222 		for (bw = max_bw; bw >= min_bw; bw = bw / 2) {
223 			for (rule_num = 0, cur_rule_ptr = rule_start_ptr;
224 			     rule_num < num_reg_rules;
225 			     cur_rule_ptr++, rule_num++) {
226 				if ((cur_rule_ptr->start_freq <=
227 				     mas_chan_list[i].center_freq -
228 				     bw / 2) &&
229 				    (cur_rule_ptr->end_freq >=
230 				     mas_chan_list[i].center_freq +
231 				     bw / 2) && (min_bw <= bw)) {
232 					found_rule_ptr = cur_rule_ptr;
233 					break;
234 				}
235 			}
236 
237 			if (found_rule_ptr)
238 				break;
239 		}
240 
241 		if (found_rule_ptr) {
242 			mas_chan_list[i].max_bw = bw;
243 			reg_fill_channel_info(i, found_rule_ptr,
244 					      mas_chan_list, min_bw);
245 		}
246 	}
247 }
248 #else
249 static inline void
250 reg_populate_band_channels_ext_for_6g(enum channel_enum start_chan,
251 				      enum channel_enum end_chan,
252 				      struct cur_reg_rule *rule_start_ptr,
253 				      uint32_t num_reg_rules,
254 				      uint16_t min_reg_bw,
255 				      struct regulatory_channel *mas_chan_list)
256 {
257 }
258 #endif
259 
260 /**
261  * reg_populate_band_channels() - For all the valid regdb channels in the master
262  * channel list, find the regulatory rules and call reg_fill_channel_info() to
263  * populate master channel list with txpower, antennagain, BW info, etc.
264  * @start_chan: Start channel enum.
265  * @end_chan: End channel enum.
266  * @rule_start_ptr: Pointer to regulatory rules.
267  * @num_reg_rules: Number of regulatory rules.
268  * @min_reg_bw: Minimum regulatory bandwidth.
269  * @mas_chan_list: Pointer to master channel list.
270  */
271 static void reg_populate_band_channels(enum channel_enum start_chan,
272 				       enum channel_enum end_chan,
273 				       struct cur_reg_rule *rule_start_ptr,
274 				       uint32_t num_reg_rules,
275 				       uint16_t min_reg_bw,
276 				       struct regulatory_channel *mas_chan_list)
277 {
278 	struct cur_reg_rule *found_rule_ptr;
279 	struct cur_reg_rule *cur_rule_ptr;
280 	struct regulatory_channel;
281 	enum channel_enum chan_enum;
282 	uint32_t rule_num, bw;
283 	uint16_t max_bw;
284 	uint16_t min_bw;
285 
286 	for (chan_enum = start_chan; chan_enum <= end_chan; chan_enum++) {
287 		found_rule_ptr = NULL;
288 
289 		max_bw = QDF_MIN((uint16_t)20, channel_map[chan_enum].max_bw);
290 		min_bw = QDF_MAX(min_reg_bw, channel_map[chan_enum].min_bw);
291 
292 		if (channel_map[chan_enum].chan_num == INVALID_CHANNEL_NUM)
293 			continue;
294 
295 		for (bw = max_bw; bw >= min_bw; bw = bw / 2) {
296 			for (rule_num = 0, cur_rule_ptr = rule_start_ptr;
297 			     rule_num < num_reg_rules;
298 			     cur_rule_ptr++, rule_num++) {
299 				if ((cur_rule_ptr->start_freq <=
300 				     mas_chan_list[chan_enum].center_freq -
301 				     bw / 2) &&
302 				    (cur_rule_ptr->end_freq >=
303 				     mas_chan_list[chan_enum].center_freq +
304 				     bw / 2) && (min_bw <= bw)) {
305 					found_rule_ptr = cur_rule_ptr;
306 					break;
307 				}
308 			}
309 
310 			if (found_rule_ptr)
311 				break;
312 		}
313 
314 		if (found_rule_ptr) {
315 			mas_chan_list[chan_enum].max_bw = bw;
316 			reg_fill_channel_info(chan_enum, found_rule_ptr,
317 					      mas_chan_list, min_bw);
318 			/* Disable 2.4 Ghz channels that dont have 20 mhz bw */
319 			if (start_chan == MIN_24GHZ_CHANNEL &&
320 			    mas_chan_list[chan_enum].max_bw < 20) {
321 				mas_chan_list[chan_enum].chan_flags |=
322 						REGULATORY_CHAN_DISABLED;
323 				mas_chan_list[chan_enum].state =
324 						CHANNEL_STATE_DISABLE;
325 			}
326 		}
327 	}
328 }
329 
330 /**
331  * reg_update_max_bw_per_rule() - Update max bandwidth value for given regrules.
332  * @num_reg_rules: Number of regulatory rules.
333  * @reg_rule_start: Pointer to regulatory rules.
334  * @max_bw: Maximum bandwidth
335  */
336 static void reg_update_max_bw_per_rule(uint32_t num_reg_rules,
337 				       struct cur_reg_rule *reg_rule_start,
338 				       uint16_t max_bw)
339 {
340 	uint32_t count;
341 
342 	for (count = 0; count < num_reg_rules; count++)
343 		reg_rule_start[count].max_bw =
344 			min(reg_rule_start[count].max_bw, max_bw);
345 }
346 
347 #ifdef CONFIG_REG_CLIENT
348 /**
349  * reg_bw_floor() - Calculate floor of a given bandwidth. Find the nearest
350  * bandwidth, from the set = {5, 10, 20, 40, 80, 160, 320}, which is less
351  * than or  equal to the given bandwidth. Any input bandwidth less than 5MHz
352  * is converted to 0.
353  * @in_bw: A positive bandwidth value
354  *
355  * Return: The floor of the given bandwidth.
356  */
357 static uint16_t reg_bw_floor(uint16_t in_bw)
358 {
359 	static const uint16_t chwidth_array[] = {5, 10, 20, 40, 80, 160, 320};
360 	int16_t i;
361 
362 	for (i = QDF_ARRAY_SIZE(chwidth_array) - 1; i >= 0; i--) {
363 		if (in_bw >= chwidth_array[i])
364 			return chwidth_array[i];
365 	}
366 	return 0;
367 }
368 
369 /**
370  * reg_find_enhanced_bw() - Given two adjacent reg rules, it first finds the
371  * coalesced bandwidth limited by the country/regulatory domain bandwidth. Then
372  * it finds the nearest discrete bandwidth from the discrete
373  * set = {5, 10, 20, 40, 80, 160, 320} of bandwidths.
374  * @reg_rule_ptr: Pointer to reg rule
375  * @cur_idx: Current index to be considered
376  * @max_reg_bw: Maximum bandwidth of the country/regulatory domain
377  *
378  * Return: Return enhanced bandwidth of the coalesced band
379  */
380 static uint16_t reg_find_enhanced_bw(struct cur_reg_rule *reg_rule_ptr,
381 				     uint32_t cur_idx,
382 				     uint16_t max_reg_bw)
383 {
384 	uint16_t cur_rule_diff_freq;
385 	uint16_t next_rule_diff_freq;
386 	uint16_t new_bw;
387 	uint16_t enhanced_bw;
388 
389 	cur_rule_diff_freq = reg_rule_ptr[cur_idx].end_freq -
390 			reg_rule_ptr[cur_idx].start_freq;
391 	next_rule_diff_freq = reg_rule_ptr[cur_idx + 1].end_freq -
392 			reg_rule_ptr[cur_idx + 1].start_freq;
393 
394 	new_bw = QDF_MIN(max_reg_bw, cur_rule_diff_freq + next_rule_diff_freq);
395 	enhanced_bw = reg_bw_floor(new_bw);
396 
397 	return enhanced_bw;
398 }
399 
400 /**
401  * reg_do_auto_bw_correction() - Calculate and update the maximum bandwidth
402  * value.
403  * @num_reg_rules: Number of regulatory rules.
404  * @reg_rule_ptr: Pointer to regulatory rules.
405  * @max_bw: Maximum bandwidth
406  */
407 static void reg_do_auto_bw_correction(uint32_t num_reg_rules,
408 				      struct cur_reg_rule *reg_rule_ptr,
409 				      uint16_t max_bw)
410 {
411 	uint32_t count;
412 	uint16_t enhanced_bw;
413 
414 	for (count = 0; count < num_reg_rules - 1; count++) {
415 		if (reg_rule_ptr[count].end_freq ==
416 		    reg_rule_ptr[count + 1].start_freq) {
417 			enhanced_bw = reg_find_enhanced_bw(reg_rule_ptr,
418 							   count,
419 							   max_bw);
420 			reg_rule_ptr[count].max_bw = enhanced_bw;
421 			reg_rule_ptr[count + 1].max_bw = enhanced_bw;
422 		}
423 	}
424 }
425 #else
426 /**
427  * reg_do_auto_bw_correction() - Calculate and update the maximum bandwidth
428  * value.
429  * @num_reg_rules: Number of regulatory rules.
430  * @reg_rule_ptr: Pointer to regulatory rules.
431  * @max_bw: Maximum bandwidth
432  */
433 static void reg_do_auto_bw_correction(uint32_t num_reg_rules,
434 				      struct cur_reg_rule *reg_rule_ptr,
435 				      uint16_t max_bw)
436 {
437 	uint32_t count;
438 	uint16_t new_bw;
439 
440 	for (count = 0; count < num_reg_rules - 1; count++) {
441 		if (reg_rule_ptr[count].end_freq ==
442 		    reg_rule_ptr[count + 1].start_freq) {
443 			new_bw = QDF_MIN(max_bw, reg_rule_ptr[count].max_bw +
444 					 reg_rule_ptr[count + 1].max_bw);
445 			reg_rule_ptr[count].max_bw = new_bw;
446 			reg_rule_ptr[count + 1].max_bw = new_bw;
447 		}
448 	}
449 }
450 #endif
451 
452 /**
453  * reg_modify_chan_list_for_dfs_channels() - disable the DFS channels if
454  * dfs_enable set to false.
455  * @chan_list: Pointer to regulatory channel list.
456  * @dfs_enabled: if false, then disable the DFS channels.
457  */
458 static void reg_modify_chan_list_for_dfs_channels(
459 		struct regulatory_channel *chan_list, bool dfs_enabled)
460 {
461 	enum channel_enum chan_enum;
462 
463 	if (dfs_enabled)
464 		return;
465 
466 	for (chan_enum = 0; chan_enum < NUM_CHANNELS; chan_enum++) {
467 		if (chan_list[chan_enum].chan_flags & REGULATORY_CHAN_RADAR) {
468 			chan_list[chan_enum].state = CHANNEL_STATE_DISABLE;
469 			chan_list[chan_enum].chan_flags |=
470 				REGULATORY_CHAN_DISABLED;
471 		}
472 	}
473 }
474 
475 #if defined(CONFIG_BAND_6GHZ) && defined(CONFIG_REG_CLIENT)
476 /**
477  * reg_is_lpi_cli_supp_pwr_mode() - Check if the input supported power mode is a
478  * client LPI power mode
479  *
480  * @supp_pwr_mode: 6G supported power mode
481  *
482  * Return: bool
483  */
484 static bool
485 reg_is_lpi_cli_supp_pwr_mode(enum supported_6g_pwr_types supp_pwr_mode)
486 {
487 	return ((supp_pwr_mode == REG_CLI_DEF_LPI) ||
488 		(supp_pwr_mode == REG_CLI_SUB_LPI));
489 }
490 
491 /**
492  * reg_modify_super_chan_list_for_indoor_channels() - Disable the indoor
493  * channels in super channel list if indoor_chan_enabled flag is set to false.
494  *
495  * @pdev_priv_obj: Pointer to regulatory private pdev structure.
496  * @chn_idx: Channel index for which indoor channel needs to be disabled in
497  * super channel list.
498  * pwr_mode: Input power mode
499  *
500  * Return: None
501  */
502 static void reg_modify_super_chan_list_for_indoor_channels(
503 			struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj,
504 			uint16_t chn_idx,
505 			enum supported_6g_pwr_types pwr_mode)
506 {
507 	struct super_chan_info *super_chan_list;
508 
509 	if (!reg_is_lpi_cli_supp_pwr_mode(pwr_mode))
510 		return;
511 
512 	super_chan_list = pdev_priv_obj->super_chan_list;
513 
514 	if (!pdev_priv_obj->indoor_chan_enabled) {
515 		if (!reg_is_chan_disabled(
516 			super_chan_list[chn_idx].chan_flags_arr[pwr_mode],
517 			super_chan_list[chn_idx].state_arr[pwr_mode])) {
518 			super_chan_list[chn_idx].chan_flags_arr[pwr_mode] |=
519 							REGULATORY_CHAN_NO_IR;
520 			super_chan_list[chn_idx].state_arr[pwr_mode] =
521 							CHANNEL_STATE_DFS;
522 		}
523 	}
524 
525 	if (pdev_priv_obj->force_ssc_disable_indoor_channel &&
526 	    pdev_priv_obj->sap_state) {
527 		if (!reg_is_chan_disabled(
528 			super_chan_list[chn_idx].chan_flags_arr[pwr_mode],
529 			super_chan_list[chn_idx].state_arr[pwr_mode])) {
530 			super_chan_list[chn_idx].chan_flags_arr[pwr_mode] |=
531 							REGULATORY_CHAN_NO_IR;
532 			super_chan_list[chn_idx].state_arr[pwr_mode] =
533 							CHANNEL_STATE_DISABLE;
534 		}
535 	}
536 }
537 
538 static void
539 reg_dis_6g_chan_in_super_chan_list(struct wlan_objmgr_pdev *pdev,
540 				   struct super_chan_info *chan_info,
541 				   enum supported_6g_pwr_types pwr_type)
542 {
543 	struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj;
544 	uint32_t band_bitmap;
545 
546 	if (!pdev) {
547 		reg_debug("pdev is NULL");
548 		return;
549 	}
550 
551 	if (!chan_info) {
552 		reg_debug("chan_info is NULL");
553 		return;
554 	}
555 
556 	pdev_priv_obj = reg_get_pdev_obj(pdev);
557 	band_bitmap = pdev_priv_obj->band_capability;
558 
559 	if (!(band_bitmap & BIT(REG_BAND_6G)))
560 		reg_dis_chan_state_and_flags(
561 					&chan_info->state_arr[pwr_type],
562 					&chan_info->chan_flags_arr[pwr_type]);
563 }
564 #else
565 static inline bool
566 reg_is_lpi_cli_supp_pwr_mode(enum supported_6g_pwr_types supp_pwr_mode)
567 {
568 	return false;
569 }
570 
571 static inline void
572 reg_modify_super_chan_list_for_indoor_channels(
573 			struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj,
574 			uint16_t chn_idx,
575 			enum supported_6g_pwr_types pwr_mode)
576 {
577 }
578 
579 static inline void
580 reg_dis_6g_chan_in_super_chan_list(struct wlan_objmgr_pdev *pdev,
581 				   struct super_chan_info *chan_info,
582 				   enum supported_6g_pwr_types pwr_type)
583 {
584 }
585 #endif /* CONFIG_BAND_6GHZ && CONFIG_REG_CLIENT */
586 
587 /**
588  * reg_modify_chan_list_for_indoor_channels() - Disable the indoor channels if
589  * indoor_chan_enabled flag is set to false.
590  * @pdev_priv_obj: Pointer to regulatory private pdev structure.
591  */
592 #ifdef CONFIG_REG_CLIENT
593 static void reg_modify_chan_list_for_indoor_channels(
594 		struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj)
595 {
596 	enum channel_enum chan_enum;
597 	struct regulatory_channel *chan_list = pdev_priv_obj->cur_chan_list;
598 
599 	if (!pdev_priv_obj->indoor_chan_enabled) {
600 		for (chan_enum = 0; chan_enum < NUM_CHANNELS; chan_enum++) {
601 			if (!(REGULATORY_CHAN_DISABLED &
602 			      chan_list[chan_enum].chan_flags) &&
603 			    (REGULATORY_CHAN_INDOOR_ONLY &
604 			     chan_list[chan_enum].chan_flags)) {
605 				chan_list[chan_enum].state =
606 					CHANNEL_STATE_DFS;
607 				chan_list[chan_enum].chan_flags |=
608 					REGULATORY_CHAN_NO_IR;
609 			}
610 		}
611 	}
612 	if (pdev_priv_obj->force_ssc_disable_indoor_channel &&
613 	    pdev_priv_obj->sap_state) {
614 		for (chan_enum = 0; chan_enum < NUM_CHANNELS; chan_enum++) {
615 			if (!(REGULATORY_CHAN_DISABLED &
616 			      chan_list[chan_enum].chan_flags) &&
617 			    (REGULATORY_CHAN_INDOOR_ONLY &
618 			    chan_list[chan_enum].chan_flags)) {
619 				chan_list[chan_enum].state =
620 					CHANNEL_STATE_DISABLE;
621 				chan_list[chan_enum].chan_flags |=
622 					REGULATORY_CHAN_DISABLED;
623 			}
624 		}
625 	}
626 }
627 
628 /**
629  *reg_modify_chan_list_for_indoor_concurrency() - Enable/Disable the indoor
630  *channels for SAP operation based on the indoor concurrency list
631  *
632  * @pdev_priv_obj: Pointer to regulatory private pdev structure.
633  */
634 static void reg_modify_chan_list_for_indoor_concurrency(
635 		struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj)
636 {
637 	struct indoor_concurrency_list *indoor_list = NULL;
638 	struct regulatory_channel *chan_list = pdev_priv_obj->cur_chan_list;
639 	enum channel_enum chan, min_enum, max_enum;
640 	uint8_t i;
641 
642 	if (pdev_priv_obj->indoor_chan_enabled ||
643 	    !pdev_priv_obj->sta_sap_scc_on_indoor_channel)
644 		return;
645 
646 	indoor_list = pdev_priv_obj->indoor_list;
647 
648 	if (!indoor_list)
649 		return;
650 
651 	for (i = 0; i < MAX_INDOOR_LIST_SIZE; i++, indoor_list++) {
652 		if (indoor_list->freq == 0 &&
653 		    indoor_list->vdev_id == INVALID_VDEV_ID)
654 			continue;
655 
656 		if (!indoor_list->chan_range) {
657 			min_enum =
658 				reg_get_chan_enum_for_freq(indoor_list->freq);
659 			max_enum = min_enum;
660 		} else {
661 			min_enum =
662 				reg_get_chan_enum_for_freq(
663 					indoor_list->chan_range->start_freq);
664 			max_enum =
665 				reg_get_chan_enum_for_freq(
666 					indoor_list->chan_range->end_freq);
667 		}
668 
669 		if (min_enum == NUM_CHANNELS || max_enum == NUM_CHANNELS)
670 			continue;
671 
672 		for (chan = min_enum; chan <= max_enum; chan++) {
673 			if (chan_list[chan].chan_flags & REGULATORY_CHAN_INDOOR_ONLY &&
674 			    !(chan_list[chan].chan_flags & REGULATORY_CHAN_DISABLED)) {
675 				chan_list[chan].chan_flags &= ~REGULATORY_CHAN_NO_IR;
676 			}
677 		}
678 	}
679 }
680 
681 #else
682 static void reg_modify_chan_list_for_indoor_channels(
683 		struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj)
684 {
685 }
686 
687 static void reg_modify_chan_list_for_indoor_concurrency(
688 		struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj)
689 {
690 }
691 #endif
692 
693 #ifdef CONFIG_BAND_6GHZ
694 static void reg_modify_chan_list_for_band_6G(
695 					struct regulatory_channel *chan_list)
696 {
697 	enum channel_enum chan_enum;
698 
699 	reg_debug("disabling 6G");
700 	for (chan_enum = MIN_6GHZ_CHANNEL;
701 	     chan_enum <= MAX_6GHZ_CHANNEL; chan_enum++) {
702 		chan_list[chan_enum].chan_flags |=
703 			REGULATORY_CHAN_DISABLED;
704 		chan_list[chan_enum].state = CHANNEL_STATE_DISABLE;
705 	}
706 }
707 #else
708 static inline void reg_modify_chan_list_for_band_6G(
709 					struct regulatory_channel *chan_list)
710 {
711 }
712 #endif
713 
714 /**
715  * reg_modify_chan_list_for_band() - Based on the input band bitmap, either
716  * disable 2GHz, 5GHz, or 6GHz channels.
717  * @chan_list: Pointer to regulatory channel list.
718  * @band_bitmap: Input bitmap of reg_wifi_band values.
719  */
720 static void reg_modify_chan_list_for_band(struct regulatory_channel *chan_list,
721 					  uint32_t band_bitmap)
722 {
723 	enum channel_enum chan_enum;
724 
725 	if (!band_bitmap)
726 		return;
727 
728 	if (!(band_bitmap & BIT(REG_BAND_5G))) {
729 		reg_debug("disabling 5G");
730 		for (chan_enum = MIN_5GHZ_CHANNEL;
731 		     chan_enum <= MAX_5GHZ_CHANNEL; chan_enum++) {
732 			chan_list[chan_enum].chan_flags |=
733 				REGULATORY_CHAN_DISABLED;
734 			chan_list[chan_enum].state = CHANNEL_STATE_DISABLE;
735 		}
736 	}
737 
738 	if (!(band_bitmap & BIT(REG_BAND_2G))) {
739 		reg_debug("disabling 2G");
740 		for (chan_enum = MIN_24GHZ_CHANNEL;
741 		     chan_enum <= MAX_24GHZ_CHANNEL; chan_enum++) {
742 			chan_list[chan_enum].chan_flags |=
743 				REGULATORY_CHAN_DISABLED;
744 			chan_list[chan_enum].state = CHANNEL_STATE_DISABLE;
745 		}
746 	}
747 
748 	if (!(band_bitmap & BIT(REG_BAND_6G)))
749 		reg_modify_chan_list_for_band_6G(chan_list);
750 
751 }
752 
753 #ifdef CONFIG_REG_CLIENT
754 /**
755  * reg_get_tx_power_for_fcc_channel() - Set FCC txpower received from firmware
756  * @chan_list: Regulatory channel to be updated
757  * @fcc_rule: Pointer to current fcc rule array
758  *
759  * Return: true if regulatory channel is present in current fcc rules array
760  */
761 static bool reg_get_tx_power_for_fcc_channel(
762 		struct regulatory_channel *chan_list,
763 		struct cur_fcc_rule *fcc_rule)
764 {
765 	int index = 0;
766 
767 	if (!chan_list || !fcc_rule)
768 		return false;
769 
770 	for (index = 0; index < MAX_NUM_FCC_RULES; index++) {
771 		if (chan_list->center_freq == fcc_rule[index].center_freq) {
772 			chan_list->tx_power = fcc_rule[index].tx_power;
773 			return true;
774 		}
775 	}
776 
777 	return false;
778 }
779 
780 /**
781  * reg_modify_chan_list_for_fcc_channel() - Set maximum FCC txpower for channel
782  * 12 and 13 if set_fcc_channel flag is set to true.
783  * @pdev_priv_obj: Pointer to pdev private object.
784  */
785 static void reg_modify_chan_list_for_fcc_channel(
786 		struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj)
787 {
788 	struct regulatory_channel *chan_list = pdev_priv_obj->cur_chan_list;
789 	struct cur_fcc_rule *fcc_rules = pdev_priv_obj->fcc_rules_ptr;
790 
791 	if (!pdev_priv_obj->set_fcc_channel)
792 		return;
793 
794 	if (!chan_list || !fcc_rules)
795 		return;
796 
797 	if (!reg_get_tx_power_for_fcc_channel(
798 			&chan_list[CHAN_ENUM_2467], fcc_rules)) {
799 		chan_list[CHAN_ENUM_2467].tx_power = MAX_PWR_FCC_CHAN_12;
800 		reg_debug("Channel 12 not found from BDF");
801 	}
802 	if (!reg_get_tx_power_for_fcc_channel(
803 			&chan_list[CHAN_ENUM_2472], fcc_rules)) {
804 		chan_list[CHAN_ENUM_2472].tx_power = MAX_PWR_FCC_CHAN_13;
805 		reg_debug("Channel 13 not found from BDF");
806 	}
807 	reg_debug("Channel 12 tx_power = %d, 13 tx_power = %d",
808 		  chan_list[CHAN_ENUM_2467].tx_power,
809 		  chan_list[CHAN_ENUM_2472].tx_power);
810 }
811 #else
812 static inline void reg_modify_chan_list_for_fcc_channel(
813 		struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj)
814 {
815 }
816 #endif
817 
818 /**
819  * reg_modify_chan_list_for_chan_144() - Disable channel 144 if en_chan_144 flag
820  * is set to false.
821  * @chan_list: Pointer to regulatory channel list.
822  * @en_chan_144: if false, then disable channel 144.
823  */
824 static void reg_modify_chan_list_for_chan_144(
825 		struct regulatory_channel *chan_list, bool en_chan_144)
826 {
827 	enum channel_enum chan_enum;
828 
829 	if (en_chan_144)
830 		return;
831 
832 	for (chan_enum = 0; chan_enum < NUM_CHANNELS; chan_enum++) {
833 		if (chan_list[chan_enum].center_freq == CHAN_144_CENT_FREQ) {
834 			chan_list[chan_enum].chan_flags |=
835 				REGULATORY_CHAN_DISABLED;
836 			chan_list[chan_enum].state = CHANNEL_STATE_DISABLE;
837 		}
838 	}
839 }
840 
841 /**
842  * reg_modify_chan_list_for_nol_list() - Disable the channel if nol_chan flag is
843  * set.
844  * @chan_list: Pointer to regulatory channel list.
845  */
846 static void reg_modify_chan_list_for_nol_list(
847 		struct regulatory_channel *chan_list)
848 {
849 	enum channel_enum chan_enum;
850 
851 	for (chan_enum = 0; chan_enum < NUM_CHANNELS; chan_enum++) {
852 		if (chan_list[chan_enum].nol_chan) {
853 			chan_list[chan_enum].state = CHANNEL_STATE_DISABLE;
854 			chan_list[chan_enum].chan_flags |=
855 				REGULATORY_CHAN_DISABLED;
856 		}
857 	}
858 }
859 
860 #ifdef CONFIG_REG_CLIENT
861 /**
862  * reg_modify_chan_list_for_static_puncture() - Disable the channel if
863  * static_puncture is set.
864  * @chan_list: Pointer to regulatory channel list.
865  */
866 static void
867 reg_modify_chan_list_for_static_puncture(struct regulatory_channel *chan_list)
868 {
869 	enum channel_enum chan_enum;
870 
871 	for (chan_enum = 0; chan_enum < NUM_CHANNELS; chan_enum++) {
872 		if (chan_list[chan_enum].is_static_punctured) {
873 			chan_list[chan_enum].state = CHANNEL_STATE_DISABLE;
874 			chan_list[chan_enum].chan_flags |=
875 				REGULATORY_CHAN_DISABLED;
876 		}
877 	}
878 }
879 #else
880 static void
881 reg_modify_chan_list_for_static_puncture(struct regulatory_channel *chan_list)
882 {
883 }
884 #endif
885 
886 /**
887  * reg_find_low_limit_chan_enum() - Find low limit 2G and 5G channel enums.
888  * @chan_list: Pointer to regulatory channel list.
889  * @low_freq: low limit frequency.
890  * @low_limit: pointer to output low limit enum.
891  *
892  * Return: None
893  */
894 static void reg_find_low_limit_chan_enum(
895 		struct regulatory_channel *chan_list, qdf_freq_t low_freq,
896 		uint32_t *low_limit)
897 {
898 	enum channel_enum chan_enum;
899 	uint16_t min_bw;
900 	uint16_t max_bw;
901 	qdf_freq_t center_freq;
902 
903 	for (chan_enum = 0; chan_enum < NUM_CHANNELS; chan_enum++) {
904 		min_bw = chan_list[chan_enum].min_bw;
905 		max_bw = chan_list[chan_enum].max_bw;
906 		center_freq = chan_list[chan_enum].center_freq;
907 
908 		if ((center_freq - min_bw / 2) >= low_freq) {
909 			if ((center_freq - max_bw / 2) < low_freq) {
910 				if (max_bw <= 20)
911 					max_bw = ((center_freq - low_freq) * 2);
912 				if (max_bw < min_bw)
913 					max_bw = min_bw;
914 				chan_list[chan_enum].max_bw = max_bw;
915 			}
916 			*low_limit = chan_enum;
917 			break;
918 		}
919 	}
920 }
921 
922 /**
923  * reg_find_high_limit_chan_enum() - Find high limit 2G and 5G channel enums.
924  * @chan_list: Pointer to regulatory channel list.
925  * @high_freq: high limit frequency.
926  * @high_limit: pointer to output high limit enum.
927  *
928  * Return: None
929  */
930 static void reg_find_high_limit_chan_enum(
931 		struct regulatory_channel *chan_list,
932 		qdf_freq_t high_freq,
933 		uint32_t *high_limit)
934 {
935 	enum channel_enum chan_enum;
936 	uint16_t min_bw;
937 	uint16_t max_bw;
938 	qdf_freq_t center_freq;
939 
940 	for (chan_enum = NUM_CHANNELS - 1; chan_enum >= 0; chan_enum--) {
941 		min_bw = chan_list[chan_enum].min_bw;
942 		max_bw = chan_list[chan_enum].max_bw;
943 		center_freq = chan_list[chan_enum].center_freq;
944 
945 		if (center_freq + min_bw / 2 <= high_freq) {
946 			if ((center_freq + max_bw / 2) > high_freq) {
947 				if (max_bw <= 20)
948 					max_bw = ((high_freq -
949 						   center_freq) * 2);
950 				if (max_bw < min_bw)
951 					max_bw = min_bw;
952 				chan_list[chan_enum].max_bw = max_bw;
953 			}
954 			*high_limit = chan_enum;
955 			break;
956 		}
957 
958 		if (chan_enum == 0)
959 			break;
960 	}
961 }
962 
963 #ifdef CONFIG_AFC_SUPPORT
964 /**
965  * reg_modify_chan_list_for_outdoor() - Set the channel flag for the
966  * enabled SP channels as REGULATORY_CHAN_AFC_NOT_DONE.
967  * @pdev_priv_obj: Regulatory pdev private object.
968  *
969  * Return: void
970  */
971 static void
972 reg_modify_chan_list_for_outdoor(struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj)
973 {
974 	struct regulatory_channel *sp_chan_list;
975 	int i;
976 
977 	sp_chan_list =  pdev_priv_obj->mas_chan_list_6g_ap[REG_STANDARD_POWER_AP];
978 	if (pdev_priv_obj->reg_afc_dev_deployment_type != AFC_DEPLOYMENT_OUTDOOR)
979 		return;
980 
981 	if (pdev_priv_obj->is_6g_afc_power_event_received)
982 		return;
983 
984 	if (!pdev_priv_obj->is_6g_channel_list_populated)
985 		return;
986 
987 	for (i = 0; i < NUM_6GHZ_CHANNELS; i++) {
988 		if (sp_chan_list[i].state == CHANNEL_STATE_ENABLE)
989 			sp_chan_list[i].chan_flags |= REGULATORY_CHAN_AFC_NOT_DONE;
990 	}
991 }
992 #else
993 static inline void
994 reg_modify_chan_list_for_outdoor(struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj)
995 {
996 }
997 #endif
998 
999 /**
1000  * reg_modify_chan_list_for_freq_range() - Modify channel list for the given low
1001  * and high frequency range.
1002  * @chan_list: Pointer to regulatory channel list.
1003  * @low_freq_2g: Low frequency 2G.
1004  * @high_freq_2g: High frequency 2G.
1005  * @low_freq_5g: Low frequency 5G.
1006  * @high_freq_5g: High frequency 5G.
1007  *
1008  * Return: None
1009  */
1010 static void
1011 reg_modify_chan_list_for_freq_range(struct regulatory_channel *chan_list,
1012 				    qdf_freq_t low_freq_2g,
1013 				    qdf_freq_t high_freq_2g,
1014 				    qdf_freq_t low_freq_5g,
1015 				    qdf_freq_t high_freq_5g)
1016 {
1017 	uint32_t low_limit_2g = NUM_CHANNELS;
1018 	uint32_t high_limit_2g = NUM_CHANNELS;
1019 	uint32_t low_limit_5g = NUM_CHANNELS;
1020 	uint32_t high_limit_5g = NUM_CHANNELS;
1021 	enum channel_enum chan_enum;
1022 	bool chan_in_range;
1023 
1024 	reg_find_low_limit_chan_enum(chan_list, low_freq_2g, &low_limit_2g);
1025 	reg_find_low_limit_chan_enum(chan_list, low_freq_5g, &low_limit_5g);
1026 	reg_find_high_limit_chan_enum(chan_list, high_freq_2g, &high_limit_2g);
1027 	reg_find_high_limit_chan_enum(chan_list, high_freq_5g, &high_limit_5g);
1028 
1029 	for (chan_enum = 0; chan_enum < NUM_CHANNELS; chan_enum++) {
1030 		chan_in_range = false;
1031 		if  ((low_limit_2g <= chan_enum) &&
1032 		     (high_limit_2g >= chan_enum) &&
1033 		     (low_limit_2g != NUM_CHANNELS) &&
1034 		     (high_limit_2g != NUM_CHANNELS))
1035 			chan_in_range = true;
1036 
1037 		if  ((low_limit_5g <= chan_enum) &&
1038 		     (high_limit_5g >= chan_enum) &&
1039 		     (low_limit_5g != NUM_CHANNELS) &&
1040 		     (high_limit_5g != NUM_CHANNELS))
1041 			chan_in_range = true;
1042 
1043 		if (!chan_in_range) {
1044 			chan_list[chan_enum].chan_flags |=
1045 				REGULATORY_CHAN_DISABLED;
1046 			chan_list[chan_enum].state = CHANNEL_STATE_DISABLE;
1047 		}
1048 	}
1049 }
1050 
1051 #ifdef CONFIG_BAND_6GHZ
1052 /**
1053  * reg_propagate_6g_mas_channel_list() - Copy master chan list from PSOC to PDEV
1054  * @pdev_priv_obj: Pointer to pdev
1055  * @mas_chan_params: Master channel parameters
1056  *
1057  * Return: None
1058  */
1059 static void reg_propagate_6g_mas_channel_list(
1060 		struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj,
1061 		struct mas_chan_params *mas_chan_params)
1062 {
1063 	uint8_t i, j;
1064 	struct regulatory_channel *src_6g_chan, *dst_6g_chan;
1065 	uint32_t size_of_6g_chan_list =
1066 		NUM_6GHZ_CHANNELS * sizeof(struct regulatory_channel);
1067 
1068 	for (i = 0; i < REG_CURRENT_MAX_AP_TYPE; i++) {
1069 		qdf_mem_copy(pdev_priv_obj->mas_chan_list_6g_ap[i],
1070 			     mas_chan_params->mas_chan_list_6g_ap[i],
1071 			     size_of_6g_chan_list);
1072 
1073 		for (j = 0; j < REG_MAX_CLIENT_TYPE; j++) {
1074 			dst_6g_chan =
1075 				pdev_priv_obj->mas_chan_list_6g_client[i][j];
1076 			src_6g_chan =
1077 				mas_chan_params->mas_chan_list_6g_client[i][j];
1078 			qdf_mem_copy(dst_6g_chan, src_6g_chan,
1079 				     size_of_6g_chan_list);
1080 		}
1081 	}
1082 
1083 	pdev_priv_obj->reg_cur_6g_client_mobility_type =
1084 				mas_chan_params->client_type;
1085 	pdev_priv_obj->reg_target_client_type =
1086 				mas_chan_params->client_type;
1087 	pdev_priv_obj->reg_rnr_tpe_usable = mas_chan_params->rnr_tpe_usable;
1088 	pdev_priv_obj->reg_unspecified_ap_usable =
1089 				mas_chan_params->unspecified_ap_usable;
1090 	pdev_priv_obj->is_6g_channel_list_populated =
1091 		mas_chan_params->is_6g_channel_list_populated;
1092 	pdev_priv_obj->reg_6g_superid =
1093 		mas_chan_params->reg_6g_superid;
1094 	pdev_priv_obj->reg_6g_thresh_priority_freq =
1095 				mas_chan_params->reg_6g_thresh_priority_freq;
1096 	reg_set_ap_pwr_type(pdev_priv_obj);
1097 }
1098 
1099 #ifdef CONFIG_AFC_SUPPORT
1100 void reg_set_ap_pwr_type(struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj)
1101 {
1102 	uint8_t  *num_rules = pdev_priv_obj->reg_rules.num_of_6g_ap_reg_rules;
1103 
1104 	if (pdev_priv_obj->reg_afc_dev_deployment_type ==
1105 	    AFC_DEPLOYMENT_OUTDOOR) {
1106 		if (num_rules[REG_VERY_LOW_POWER_AP])
1107 			pdev_priv_obj->reg_cur_6g_ap_pwr_type =
1108 				REG_VERY_LOW_POWER_AP;
1109 		else
1110 			pdev_priv_obj->reg_cur_6g_ap_pwr_type =
1111 				REG_STANDARD_POWER_AP;
1112 	} else {
1113 		if (num_rules[REG_INDOOR_AP])
1114 			pdev_priv_obj->reg_cur_6g_ap_pwr_type =
1115 				REG_INDOOR_AP;
1116 		else if (num_rules[REG_VERY_LOW_POWER_AP])
1117 			pdev_priv_obj->reg_cur_6g_ap_pwr_type =
1118 				REG_VERY_LOW_POWER_AP;
1119 		else
1120 			pdev_priv_obj->reg_cur_6g_ap_pwr_type =
1121 				REG_INDOOR_AP;
1122 	}
1123 }
1124 #else
1125 void reg_set_ap_pwr_type(struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj)
1126 {
1127 	pdev_priv_obj->reg_cur_6g_ap_pwr_type = REG_INDOOR_AP;
1128 }
1129 #endif /* CONFIG_AFC_SUPPORT */
1130 #else
1131 static inline void reg_propagate_6g_mas_channel_list(
1132 		struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj,
1133 		struct mas_chan_params *mas_chan_params)
1134 {
1135 }
1136 #endif /* CONFIG_BAND_6GHZ */
1137 
1138 void reg_init_pdev_mas_chan_list(
1139 		struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj,
1140 		struct mas_chan_params *mas_chan_params)
1141 {
1142 	qdf_mem_copy(pdev_priv_obj->mas_chan_list,
1143 		     mas_chan_params->mas_chan_list,
1144 		     NUM_CHANNELS * sizeof(struct regulatory_channel));
1145 
1146 	reg_propagate_6g_mas_channel_list(pdev_priv_obj, mas_chan_params);
1147 
1148 	pdev_priv_obj->dfs_region = mas_chan_params->dfs_region;
1149 
1150 	pdev_priv_obj->phybitmap = mas_chan_params->phybitmap;
1151 
1152 	pdev_priv_obj->reg_dmn_pair = mas_chan_params->reg_dmn_pair;
1153 	pdev_priv_obj->ctry_code =  mas_chan_params->ctry_code;
1154 
1155 	pdev_priv_obj->def_region_domain = mas_chan_params->reg_dmn_pair;
1156 	pdev_priv_obj->def_country_code =  mas_chan_params->ctry_code;
1157 	qdf_mem_copy(pdev_priv_obj->default_country,
1158 		     mas_chan_params->default_country, REG_ALPHA2_LEN + 1);
1159 
1160 	qdf_mem_copy(pdev_priv_obj->current_country,
1161 		     mas_chan_params->current_country, REG_ALPHA2_LEN + 1);
1162 }
1163 
1164 /**
1165  * reg_modify_chan_list_for_cached_channels() - If num_cache_channels are
1166  * non-zero, then disable the pdev channels which is given in
1167  * cache_disable_chan_list.
1168  * @pdev_priv_obj: Pointer to regulatory pdev private object.
1169  */
1170 #ifdef DISABLE_CHANNEL_LIST
1171 static void reg_modify_chan_list_for_cached_channels(
1172 		struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj)
1173 {
1174 	uint32_t i, j;
1175 	uint32_t num_cache_channels = pdev_priv_obj->num_cache_channels;
1176 	struct regulatory_channel *chan_list = pdev_priv_obj->cur_chan_list;
1177 	struct regulatory_channel *cache_chan_list =
1178 					pdev_priv_obj->cache_disable_chan_list;
1179 
1180 	if (!num_cache_channels)
1181 		return;
1182 
1183 	if (pdev_priv_obj->disable_cached_channels) {
1184 		for (i = 0; i < num_cache_channels; i++)
1185 			for (j = 0; j < NUM_CHANNELS; j++)
1186 				if (cache_chan_list[i].center_freq ==
1187 				    chan_list[j].center_freq) {
1188 					chan_list[j].state =
1189 							CHANNEL_STATE_DISABLE;
1190 					chan_list[j].chan_flags |=
1191 						REGULATORY_CHAN_DISABLED;
1192 				}
1193 	}
1194 }
1195 #else
1196 static void reg_modify_chan_list_for_cached_channels(
1197 		struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj)
1198 {
1199 }
1200 #endif
1201 
1202 #ifdef CONFIG_REG_CLIENT
1203 /**
1204  * reg_modify_chan_list_for_srd_channels() - Modify SRD channels in ETSI13
1205  * @pdev: Pointer to pdev object
1206  * @chan_list: Current channel list
1207  *
1208  * This function converts SRD channels to passive in ETSI13 regulatory domain
1209  * when enable_srd_chan_in_master_mode is not set.
1210  */
1211 static void
1212 reg_modify_chan_list_for_srd_channels(struct wlan_objmgr_pdev *pdev,
1213 				      struct regulatory_channel *chan_list)
1214 {
1215 	enum channel_enum chan_enum;
1216 
1217 	if (!reg_is_etsi13_regdmn(pdev))
1218 		return;
1219 
1220 	if (reg_is_etsi13_srd_chan_allowed_master_mode(pdev))
1221 		return;
1222 
1223 	for (chan_enum = 0; chan_enum < NUM_CHANNELS; chan_enum++) {
1224 		if (chan_list[chan_enum].chan_flags & REGULATORY_CHAN_DISABLED)
1225 			continue;
1226 
1227 		if (reg_is_etsi13_srd_chan_for_freq(
1228 					pdev,
1229 					chan_list[chan_enum].center_freq)) {
1230 			chan_list[chan_enum].state =
1231 				CHANNEL_STATE_DFS;
1232 			chan_list[chan_enum].chan_flags |=
1233 				REGULATORY_CHAN_NO_IR;
1234 		}
1235 	}
1236 }
1237 #else
1238 static inline void
1239 reg_modify_chan_list_for_srd_channels(struct wlan_objmgr_pdev *pdev,
1240 				      struct regulatory_channel *chan_list)
1241 {
1242 }
1243 #endif
1244 
1245 #ifdef CONFIG_REG_CLIENT
1246 
1247 /**
1248  * reg_is_disabling_5dot9_needed() - Checks if 5.9GHz channels should
1249  * be disabled.
1250  * @psoc: Pointer to psoc object
1251  *
1252  * This function checks only if F/W has enabled the BDF bit for 5.9GHz
1253  * channels for AP target and both the BDF bit as well as if offload is
1254  * enabled for STA target.
1255  */
1256 static inline bool
1257 reg_is_disabling_5dot9_needed(struct wlan_objmgr_psoc *psoc)
1258 {
1259 	return (!reg_is_5dot9_ghz_supported(psoc) ||
1260 		!reg_is_regdb_offloaded(psoc));
1261 }
1262 #else
1263 static inline bool
1264 reg_is_disabling_5dot9_needed(struct wlan_objmgr_psoc *psoc)
1265 {
1266 	return (!reg_is_5dot9_ghz_supported(psoc));
1267 }
1268 #endif
1269 
1270 /**
1271  * reg_modify_chan_list_for_5dot9_ghz_channels() - Modify 5.9 GHz channels
1272  * in FCC
1273  * @pdev: Pointer to pdev object
1274  * @chan_list: Current channel list
1275  *
1276  * This function disables 5.9 GHz channels if service bit
1277  * wmi_service_5dot9_ghz_support is not set or the reg db is not offloaded
1278  * to FW. If service bit is set but ini enable_5dot9_ghz_chan_in_master_mode
1279  * is not set, it converts these channels to passive in FCC regulatory domain.
1280  * If both service bit and ini are set, the channels remain enabled.
1281  */
1282 static void
1283 reg_modify_chan_list_for_5dot9_ghz_channels(struct wlan_objmgr_pdev *pdev,
1284 					    struct regulatory_channel
1285 					    *chan_list)
1286 {
1287 	enum channel_enum chan_enum;
1288 	struct wlan_objmgr_psoc *psoc;
1289 
1290 	psoc = wlan_pdev_get_psoc(pdev);
1291 
1292 	if (!reg_is_fcc_regdmn(pdev))
1293 		return;
1294 
1295 	if (reg_is_disabling_5dot9_needed(psoc)) {
1296 		for (chan_enum = 0; chan_enum < NUM_CHANNELS; chan_enum++) {
1297 			if (reg_is_5dot9_ghz_freq(pdev, chan_list[chan_enum].
1298 						  center_freq)) {
1299 				chan_list[chan_enum].state =
1300 					CHANNEL_STATE_DISABLE;
1301 				chan_list[chan_enum].chan_flags =
1302 					REGULATORY_CHAN_DISABLED;
1303 			}
1304 		}
1305 		return;
1306 	}
1307 
1308 	if (reg_is_5dot9_ghz_chan_allowed_master_mode(pdev))
1309 		return;
1310 
1311 	for (chan_enum = 0; chan_enum < NUM_CHANNELS; chan_enum++) {
1312 		if (chan_list[chan_enum].chan_flags & REGULATORY_CHAN_DISABLED)
1313 			continue;
1314 
1315 		if (reg_is_5dot9_ghz_freq(pdev,
1316 					  chan_list[chan_enum].center_freq)) {
1317 			chan_list[chan_enum].state =
1318 				CHANNEL_STATE_DFS;
1319 			chan_list[chan_enum].chan_flags |=
1320 				REGULATORY_CHAN_NO_IR;
1321 		}
1322 	}
1323 }
1324 
1325 #if defined(CONFIG_BAND_6GHZ)
1326 /**
1327  * reg_modify_chan_list_for_6g_edge_channels() - Modify 6 GHz edge channels
1328  *
1329  * @pdev: Pointer to pdev object
1330  * @chan_list: Current channel list
1331  *
1332  * This function disables lower 6G edge channel (5935MHz) if service bit
1333  * wmi_service_lower_6g_edge_ch_supp is not set. If service bit is set
1334  * the channels remain enabled. It disables upper 6G edge channel (7115MHz)
1335  * if the service bit wmi_service_disable_upper_6g_edge_ch_supp is set, it
1336  * is enabled by default.
1337  *
1338  */
1339 static void
1340 reg_modify_chan_list_for_6g_edge_channels(struct wlan_objmgr_pdev *pdev,
1341 					  struct regulatory_channel
1342 					  *chan_list)
1343 {
1344 	struct wlan_objmgr_psoc *psoc;
1345 
1346 	psoc = wlan_pdev_get_psoc(pdev);
1347 
1348 	if (!reg_is_lower_6g_edge_ch_supp(psoc)) {
1349 		chan_list[CHAN_ENUM_5935].state = CHANNEL_STATE_DISABLE;
1350 		chan_list[CHAN_ENUM_5935].chan_flags |=
1351 						REGULATORY_CHAN_DISABLED;
1352 	}
1353 
1354 	if (reg_is_upper_6g_edge_ch_disabled(psoc)) {
1355 		chan_list[CHAN_ENUM_7115].state = CHANNEL_STATE_DISABLE;
1356 		chan_list[CHAN_ENUM_7115].chan_flags |=
1357 						REGULATORY_CHAN_DISABLED;
1358 	}
1359 }
1360 #else
1361 static inline void
1362 reg_modify_chan_list_for_6g_edge_channels(struct wlan_objmgr_pdev *pdev,
1363 					  struct regulatory_channel
1364 					  *chan_list)
1365 {
1366 }
1367 #endif
1368 
1369 #ifdef DISABLE_UNII_SHARED_BANDS
1370 /**
1371  * reg_is_reg_unii_band_1_set() - Check UNII bitmap
1372  * @unii_bitmap: 5G UNII band bitmap
1373  *
1374  * This function checks the input bitmap to disable UNII-1 band channels.
1375  *
1376  * Return: Return true if UNII-1 channels need to be disabled,
1377  * else return false.
1378  */
1379 static bool reg_is_reg_unii_band_1_set(uint8_t unii_bitmap)
1380 {
1381 	return !!(unii_bitmap & BIT(REG_UNII_BAND_1));
1382 }
1383 
1384 /**
1385  * reg_is_reg_unii_band_2a_set() - Check UNII bitmap
1386  * @unii_bitmap: 5G UNII band bitmap
1387  *
1388  * This function checks the input bitmap to disable UNII-2A band channels.
1389  *
1390  * Return: Return true if UNII-2A channels need to be disabled,
1391  * else return false.
1392  */
1393 static bool reg_is_reg_unii_band_2a_set(uint8_t unii_bitmap)
1394 {
1395 	return !!(unii_bitmap & BIT(REG_UNII_BAND_2A));
1396 }
1397 
1398 /**
1399  * reg_is_5g_enum() - Check if channel enum is a 5G channel enum
1400  * @chan_enum: channel enum
1401  *
1402  * Return: Return true if the input channel enum is 5G, else return false.
1403  */
1404 static bool reg_is_5g_enum(enum channel_enum chan_enum)
1405 {
1406 	return (chan_enum >= MIN_5GHZ_CHANNEL && chan_enum <= MAX_5GHZ_CHANNEL);
1407 }
1408 
1409 /**
1410  * reg_remove_unii_chan_from_chan_list() - Remove UNII band channels
1411  * @chan_list: Pointer to current channel list
1412  * @start_enum: starting enum value
1413  * @end_enum: ending enum value
1414  *
1415  * Remove channels in a unii band based in on the input start_enum and end_enum.
1416  * Disable the state and flags. Set disable_coex flag to true.
1417  *
1418  * return: void.
1419  */
1420 static void
1421 reg_remove_unii_chan_from_chan_list(struct regulatory_channel *chan_list,
1422 				    enum channel_enum start_enum,
1423 				    enum channel_enum end_enum)
1424 {
1425 	enum channel_enum chan_enum;
1426 
1427 	if (!(reg_is_5g_enum(start_enum) && reg_is_5g_enum(end_enum))) {
1428 		reg_err_rl("start_enum or end_enum is invalid");
1429 		return;
1430 	}
1431 
1432 	for (chan_enum = start_enum; chan_enum <= end_enum; chan_enum++) {
1433 		chan_list[chan_enum].state = CHANNEL_STATE_DISABLE;
1434 		chan_list[chan_enum].chan_flags |= REGULATORY_CHAN_DISABLED;
1435 	}
1436 }
1437 
1438 /**
1439  * reg_modify_disable_chan_list_for_unii1_and_unii2a() - Disable UNII-1 and
1440  * UNII2A band
1441  * @pdev_priv_obj: Pointer to pdev private object
1442  *
1443  * This function disables the UNII-1 and UNII-2A band channels
1444  * based on input unii_5g_bitmap.
1445  *
1446  * Return: void.
1447  */
1448 static void
1449 reg_modify_disable_chan_list_for_unii1_and_unii2a(
1450 		struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj)
1451 {
1452 	uint8_t unii_bitmap = pdev_priv_obj->unii_5g_bitmap;
1453 	struct regulatory_channel *chan_list = pdev_priv_obj->cur_chan_list;
1454 
1455 	if (reg_is_reg_unii_band_1_set(unii_bitmap)) {
1456 		reg_remove_unii_chan_from_chan_list(chan_list,
1457 						    MIN_UNII_1_BAND_CHANNEL,
1458 						    MAX_UNII_1_BAND_CHANNEL);
1459 	}
1460 
1461 	if (reg_is_reg_unii_band_2a_set(unii_bitmap)) {
1462 		reg_remove_unii_chan_from_chan_list(chan_list,
1463 						    MIN_UNII_2A_BAND_CHANNEL,
1464 						    MAX_UNII_2A_BAND_CHANNEL);
1465 	}
1466 }
1467 #else
1468 static inline bool reg_is_reg_unii_band_1_set(uint8_t unii_bitmap)
1469 {
1470 	return false;
1471 }
1472 
1473 static inline bool reg_is_reg_unii_band_2a_set(uint8_t unii_bitmap)
1474 {
1475 	return false;
1476 }
1477 
1478 static inline bool reg_is_5g_enum(enum channel_enum chan_enum)
1479 {
1480 	return false;
1481 }
1482 
1483 static inline void
1484 reg_remove_unii_chan_from_chan_list(struct regulatory_channel *chan_list,
1485 				    enum channel_enum start_enum,
1486 				    enum channel_enum end_enum)
1487 {
1488 }
1489 
1490 static inline void
1491 reg_modify_disable_chan_list_for_unii1_and_unii2a(
1492 		struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj)
1493 {
1494 }
1495 #endif
1496 
1497 #ifdef CONFIG_BAND_6GHZ
1498 #ifdef CONFIG_REG_CLIENT
1499 
1500 #ifdef CONFIG_AFC_SUPPORT
1501 /**
1502  * reg_append_mas_chan_list_for_6g_sp() - Append SP channels to the master
1503  * channel list
1504  * @pdev_priv_obj: Pointer to pdev private object
1505  *
1506  * This function appends SP channels to the master channel list
1507  *
1508  * Return: void.
1509  */
1510 static void
1511 reg_append_mas_chan_list_for_6g_sp(struct wlan_regulatory_pdev_priv_obj
1512 			       *pdev_priv_obj)
1513 {
1514 	struct regulatory_channel *master_chan_list_6g_client_sp;
1515 
1516 	master_chan_list_6g_client_sp = pdev_priv_obj->afc_chan_list;
1517 
1518 	qdf_mem_copy(&pdev_priv_obj->mas_chan_list[MIN_6GHZ_CHANNEL],
1519 		     master_chan_list_6g_client_sp,
1520 		     NUM_6GHZ_CHANNELS *
1521 		     sizeof(struct regulatory_channel));
1522 }
1523 #else
1524 static inline void
1525 reg_append_mas_chan_list_for_6g_sp(struct wlan_regulatory_pdev_priv_obj
1526 			       *pdev_priv_obj)
1527 {
1528 }
1529 #endif
1530 
1531 /**
1532  * reg_append_mas_chan_list_for_6g_lpi() - Append LPI channels to the master
1533  * channel list
1534  * @pdev_priv_obj: Pointer to pdev private object
1535  *
1536  * This function appends LPI channels to the master channel list
1537  *
1538  * Return: void.
1539  */
1540 static void
1541 reg_append_mas_chan_list_for_6g_lpi(struct wlan_regulatory_pdev_priv_obj
1542 			       *pdev_priv_obj)
1543 {
1544 	struct regulatory_channel *master_chan_list_6g_client_lpi;
1545 	uint8_t i, j;
1546 
1547 	if (!pdev_priv_obj->reg_rules.num_of_6g_client_reg_rules[REG_INDOOR_AP]) {
1548 		reg_debug("No LPI reg rules");
1549 		return;
1550 	}
1551 
1552 	master_chan_list_6g_client_lpi =
1553 		pdev_priv_obj->mas_chan_list_6g_client[REG_INDOOR_AP]
1554 			[pdev_priv_obj->reg_cur_6g_client_mobility_type];
1555 
1556 	for (i = MIN_6GHZ_CHANNEL, j = 0;
1557 	     i <= MAX_6GHZ_CHANNEL && j < NUM_6GHZ_CHANNELS; i++, j++) {
1558 		if ((pdev_priv_obj->mas_chan_list[i].state ==
1559 			CHANNEL_STATE_DISABLE) ||
1560 			(pdev_priv_obj->mas_chan_list[i].chan_flags &
1561 			REGULATORY_CHAN_DISABLED)) {
1562 			qdf_mem_copy(&pdev_priv_obj->mas_chan_list[i],
1563 				     &master_chan_list_6g_client_lpi[j],
1564 				     sizeof(struct regulatory_channel));
1565 		}
1566 	}
1567 }
1568 
1569 /**
1570  * reg_append_mas_chan_list_for_6g_VLP() - Append VLP channels to the master
1571  * channel list
1572  * @pdev_priv_obj: Pointer to pdev private object
1573  *
1574  * This function appends VLP channels to the master channel list
1575  *
1576  * Return: void.
1577  */
1578 static void
1579 reg_append_mas_chan_list_for_6g_vlp(struct wlan_regulatory_pdev_priv_obj
1580 			       *pdev_priv_obj)
1581 {
1582 	struct regulatory_channel *master_chan_list_6g_client_vlp;
1583 	uint8_t i, j;
1584 
1585 	if (!pdev_priv_obj->reg_rules.num_of_6g_client_reg_rules[REG_VERY_LOW_POWER_AP]) {
1586 		reg_debug("No VLP reg rules");
1587 		return;
1588 	}
1589 
1590 	master_chan_list_6g_client_vlp =
1591 		pdev_priv_obj->mas_chan_list_6g_client[REG_VERY_LOW_POWER_AP]
1592 			[pdev_priv_obj->reg_cur_6g_client_mobility_type];
1593 
1594 	for (i = MIN_6GHZ_CHANNEL, j = 0;
1595 	     i <= MAX_6GHZ_CHANNEL && j < NUM_6GHZ_CHANNELS; i++, j++) {
1596 		if ((pdev_priv_obj->mas_chan_list[i].state ==
1597 			CHANNEL_STATE_DISABLE) ||
1598 		    (pdev_priv_obj->mas_chan_list[i].chan_flags &
1599 		      REGULATORY_CHAN_DISABLED)) {
1600 			qdf_mem_copy(&pdev_priv_obj->mas_chan_list[i],
1601 				     &master_chan_list_6g_client_vlp[j],
1602 				     sizeof(struct regulatory_channel));
1603 		}
1604 	}
1605 }
1606 
1607 static void
1608 reg_append_mas_chan_list_for_6g(struct wlan_regulatory_pdev_priv_obj
1609 				*pdev_priv_obj)
1610 {
1611 	if (pdev_priv_obj->reg_cur_6g_ap_pwr_type >= REG_CURRENT_MAX_AP_TYPE ||
1612 	    pdev_priv_obj->reg_cur_6g_client_mobility_type >=
1613 	    REG_MAX_CLIENT_TYPE) {
1614 		reg_debug("invalid 6G AP or client power type");
1615 		return;
1616 	}
1617 
1618 	/* Client should be able to scan all types of APs, so prepare the
1619 	 * client list which has all the enabled channels, first priority is
1620 	 * given to AFC power type and then second priority is decided based on
1621 	 * gindoor_channel_support ini value
1622 	 */
1623 	reg_append_mas_chan_list_for_6g_sp(pdev_priv_obj);
1624 
1625 	if (pdev_priv_obj->indoor_chan_enabled) {
1626 		reg_append_mas_chan_list_for_6g_lpi(pdev_priv_obj);
1627 		reg_append_mas_chan_list_for_6g_vlp(pdev_priv_obj);
1628 	} else {
1629 		reg_append_mas_chan_list_for_6g_vlp(pdev_priv_obj);
1630 		reg_append_mas_chan_list_for_6g_lpi(pdev_priv_obj);
1631 	}
1632 }
1633 
1634 /**
1635  * reg_dump_valid_6ghz_channel_list() - Function to print valid 6 GHz channel
1636  * list state and attribute.
1637  * @chan: Pointer to array of 6 GHz channel list
1638  *
1639  * Return: None
1640  */
1641 static void
1642 reg_dump_valid_6ghz_channel_list(struct regulatory_channel *chan)
1643 {
1644 #define MAX_CHAN_LOG_ONE_LINE 18
1645 	uint32_t buf_size = MAX_CHAN_LOG_ONE_LINE * 24 + 1;
1646 	uint8_t *buf;
1647 	uint32_t i, len = 0, count = 0;
1648 
1649 	buf = qdf_mem_malloc(buf_size);
1650 	if (!buf)
1651 		return;
1652 
1653 	for (i = MIN_6GHZ_CHANNEL; i <= MAX_6GHZ_CHANNEL; i++, chan++) {
1654 		if (chan->state == CHANNEL_STATE_DISABLE)
1655 			continue;
1656 		len += qdf_scnprintf(buf + len, buf_size - len,
1657 				    "%d:%d:%d:%d:%d:%x ",
1658 				    chan->center_freq, chan->state,
1659 				    chan->psd_flag, chan->tx_power,
1660 				    (int16_t)chan->psd_eirp,
1661 				    chan->chan_flags);
1662 		count++;
1663 		if (count >= MAX_CHAN_LOG_ONE_LINE) {
1664 			reg_nofl_debug("%s", buf);
1665 			count = 0;
1666 			len = 0;
1667 		}
1668 	}
1669 
1670 	if (len)
1671 		reg_nofl_debug("%s", buf);
1672 
1673 	qdf_mem_free(buf);
1674 }
1675 
1676 /**
1677  * reg_dump_valid_6ghz_cur_chan_list() - API to dump pdev current/secondary
1678  * channel list state
1679  * @pdev_priv_obj: pointer to pdev private object
1680  *
1681  * Return: None
1682  */
1683 static void
1684 reg_dump_valid_6ghz_cur_chan_list(struct wlan_regulatory_pdev_priv_obj
1685 				  *pdev_priv_obj)
1686 {
1687 	reg_debug("sta freq:state:ispsd:pwr:psd:flags(hex):");
1688 	reg_dump_valid_6ghz_channel_list(
1689 			&pdev_priv_obj->cur_chan_list[MIN_6GHZ_CHANNEL]);
1690 	reg_debug("sap freq:state:ispsd:pwr:psd:flags(hex):");
1691 	reg_dump_valid_6ghz_channel_list(
1692 		&pdev_priv_obj->secondary_cur_chan_list[MIN_6GHZ_CHANNEL]);
1693 }
1694 
1695 #ifdef CONFIG_AFC_SUPPORT
1696 /**
1697  * reg_populate_afc_secondary_cur_chan_list() - Function to populate AFC
1698  * channel list to secondary current channel list
1699  * @pdev_priv_obj: Pointer to pdev regulatory private object
1700  * @chan_list: Pointer to array of 6 GHz channel list
1701  *
1702  * Return: None
1703  */
1704 static void reg_populate_afc_secondary_cur_chan_list(
1705 			struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj,
1706 			struct regulatory_channel *chan_list)
1707 {
1708 	uint32_t i;
1709 	struct regulatory_channel *afc_chan_list;
1710 	struct regulatory_channel *sp_chan_list;
1711 
1712 	if (!pdev_priv_obj->is_6g_afc_power_event_received)
1713 		return;
1714 
1715 	afc_chan_list = pdev_priv_obj->afc_chan_list;
1716 	sp_chan_list = pdev_priv_obj->
1717 			mas_chan_list_6g_ap[REG_STANDARD_POWER_AP];
1718 	for (i = 0; i < NUM_6GHZ_CHANNELS; i++) {
1719 		if (afc_chan_list[i].state == CHANNEL_STATE_DISABLE &&
1720 		    sp_chan_list[i].state == CHANNEL_STATE_ENABLE) {
1721 			chan_list[i].state = CHANNEL_STATE_DISABLE;
1722 			chan_list[i].chan_flags |= REGULATORY_CHAN_DISABLED;
1723 		} else if (afc_chan_list[i].state == CHANNEL_STATE_ENABLE) {
1724 			qdf_mem_copy(&chan_list[i],
1725 				     &afc_chan_list[i],
1726 				     sizeof(chan_list[i]));
1727 			chan_list[i].chan_flags |= REGULATORY_CHAN_AFC;
1728 		}
1729 	}
1730 }
1731 #else
1732 static inline void reg_populate_afc_secondary_cur_chan_list(
1733 			struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj,
1734 			struct regulatory_channel *chan_list)
1735 {
1736 }
1737 #endif
1738 
1739 static void
1740 reg_populate_secondary_cur_chan_list(struct wlan_regulatory_pdev_priv_obj
1741 				     *pdev_priv_obj)
1742 {
1743 	struct wlan_objmgr_psoc *psoc;
1744 	struct wlan_lmac_if_reg_tx_ops *reg_tx_ops;
1745 	struct wlan_regulatory_psoc_priv_obj *soc_reg;
1746 	struct regulatory_channel *chan_list;
1747 	uint32_t len_6ghz;
1748 
1749 	psoc = wlan_pdev_get_psoc(pdev_priv_obj->pdev_ptr);
1750 	if (!psoc) {
1751 		reg_err("psoc is NULL");
1752 		return;
1753 	}
1754 
1755 	soc_reg = reg_get_psoc_obj(psoc);
1756 	if (!IS_VALID_PSOC_REG_OBJ(soc_reg)) {
1757 		reg_err("psoc reg component is NULL");
1758 		return;
1759 	}
1760 
1761 	reg_tx_ops = reg_get_psoc_tx_ops(psoc);
1762 	if (!reg_tx_ops) {
1763 		reg_err("reg_tx_ops null");
1764 		return;
1765 	}
1766 
1767 	if (!reg_tx_ops->register_master_ext_handler ||
1768 	    !wlan_psoc_nif_fw_ext_cap_get(psoc, WLAN_SOC_EXT_EVENT_SUPPORTED)) {
1769 		qdf_mem_copy(pdev_priv_obj->secondary_cur_chan_list,
1770 			     pdev_priv_obj->cur_chan_list,
1771 			     (NUM_CHANNELS) *
1772 			     sizeof(struct regulatory_channel));
1773 		return;
1774 	}
1775 
1776 	len_6ghz = NUM_6GHZ_CHANNELS * sizeof(struct regulatory_channel);
1777 	chan_list = qdf_mem_malloc(len_6ghz);
1778 	if (!chan_list)
1779 		return;
1780 
1781 	if (pdev_priv_obj->indoor_chan_enabled &&
1782 	    pdev_priv_obj->reg_rules.num_of_6g_ap_reg_rules[REG_INDOOR_AP]) {
1783 		qdf_mem_copy(chan_list,
1784 			     pdev_priv_obj->mas_chan_list_6g_ap[REG_INDOOR_AP],
1785 			     len_6ghz);
1786 		/* has flag REGULATORY_CHAN_INDOOR_ONLY */
1787 	} else if (pdev_priv_obj->reg_rules.num_of_6g_ap_reg_rules
1788 		   [REG_VERY_LOW_POWER_AP]) {
1789 		qdf_mem_copy(chan_list,
1790 			     pdev_priv_obj->mas_chan_list_6g_ap
1791 			     [REG_VERY_LOW_POWER_AP],
1792 			     len_6ghz);
1793 	} else {
1794 		reg_init_6ghz_master_chan(chan_list, soc_reg);
1795 	}
1796 
1797 	reg_populate_afc_secondary_cur_chan_list(pdev_priv_obj, chan_list);
1798 
1799 	qdf_mem_copy(pdev_priv_obj->secondary_cur_chan_list,
1800 		     pdev_priv_obj->cur_chan_list,
1801 		     (NUM_CHANNELS - NUM_6GHZ_CHANNELS) *
1802 		     sizeof(struct regulatory_channel));
1803 	qdf_mem_copy(&pdev_priv_obj->secondary_cur_chan_list[MIN_6GHZ_CHANNEL],
1804 		     chan_list,
1805 		     len_6ghz);
1806 	qdf_mem_free(chan_list);
1807 	reg_dump_valid_6ghz_cur_chan_list(pdev_priv_obj);
1808 }
1809 #else /* CONFIG_REG_CLIENT */
1810 
1811 /**
1812  * reg_copy_ap_chan_list_to_mas_chan_list() - Copy the 6G ap channel list to
1813  * the MIN_6GHZ_CHANNEL index of the mas_chan_list based on the AP power type
1814  * In case of standard power type, if the afc channel list is available from
1815  * the afc server, use afc channel list (intersected with SP power list)
1816  * for the copy instead of using the standard power list directly.
1817  * @pdev_priv_obj: pointer to pdev_priv_obj.
1818  * @ap_pwr_type: 6G AP power type
1819  *
1820  * Return type: void.
1821  */
1822 #ifdef CONFIG_AFC_SUPPORT
1823 static void
1824 reg_copy_ap_chan_list_to_mas_chan_list(struct wlan_regulatory_pdev_priv_obj
1825 				       *pdev_priv_obj,
1826 				       enum reg_6g_ap_type ap_pwr_type)
1827 {
1828 	if (ap_pwr_type == REG_STANDARD_POWER_AP &&
1829 	    pdev_priv_obj->is_6g_afc_power_event_received) {
1830 		qdf_mem_copy(&pdev_priv_obj->mas_chan_list[MIN_6GHZ_CHANNEL],
1831 			     pdev_priv_obj->afc_chan_list,
1832 			     NUM_6GHZ_CHANNELS *
1833 			     sizeof(struct regulatory_channel));
1834 	} else {
1835 		qdf_mem_copy(&pdev_priv_obj->mas_chan_list[MIN_6GHZ_CHANNEL],
1836 			     pdev_priv_obj->mas_chan_list_6g_ap[ap_pwr_type],
1837 			     NUM_6GHZ_CHANNELS *
1838 			     sizeof(struct regulatory_channel));
1839 	}
1840 }
1841 #else
1842 static void
1843 reg_copy_ap_chan_list_to_mas_chan_list(struct wlan_regulatory_pdev_priv_obj
1844 				       *pdev_priv_obj,
1845 				       enum reg_6g_ap_type ap_pwr_type)
1846 {
1847 	qdf_mem_copy(&pdev_priv_obj->mas_chan_list[MIN_6GHZ_CHANNEL],
1848 		     pdev_priv_obj->mas_chan_list_6g_ap[ap_pwr_type],
1849 		     NUM_6GHZ_CHANNELS * sizeof(struct regulatory_channel));
1850 }
1851 #endif
1852 static void
1853 reg_append_mas_chan_list_for_6g(struct wlan_regulatory_pdev_priv_obj
1854 				*pdev_priv_obj)
1855 {
1856 	enum reg_6g_ap_type ap_pwr_type = pdev_priv_obj->reg_cur_6g_ap_pwr_type;
1857 
1858 	if (ap_pwr_type >= REG_CURRENT_MAX_AP_TYPE) {
1859 		reg_debug("invalid 6G AP power type");
1860 		return;
1861 	}
1862 
1863 	reg_copy_ap_chan_list_to_mas_chan_list(pdev_priv_obj, ap_pwr_type);
1864 }
1865 
1866 static inline void
1867 reg_populate_secondary_cur_chan_list(struct wlan_regulatory_pdev_priv_obj
1868 				     *pdev_priv_obj)
1869 {
1870 }
1871 #endif /* CONFIG_REG_CLIENT */
1872 
1873 #ifdef CONFIG_AFC_SUPPORT
1874 /* reg_intersect_6g_afc_chan_list() - Do intersection of tx_powers of AFC master
1875  * channel list and SP channel list and store the power in the AFC channel list.
1876  * @pdev_priv_obj: pointer to pdev_priv_obj.
1877  *
1878  * Return type: void.
1879  */
1880 static void
1881 reg_intersect_6g_afc_chan_list(struct wlan_regulatory_pdev_priv_obj
1882 			       *pdev_priv_obj)
1883 {
1884 	struct regulatory_channel *afc_chan_list;
1885 	struct regulatory_channel *afc_mas_chan_list;
1886 	struct regulatory_channel *sp_chan_list;
1887 	uint8_t i;
1888 
1889 	afc_chan_list = pdev_priv_obj->afc_chan_list;
1890 	afc_mas_chan_list = pdev_priv_obj->mas_chan_list_6g_afc;
1891 	sp_chan_list =
1892 		pdev_priv_obj->mas_chan_list_6g_ap[REG_STANDARD_POWER_AP];
1893 
1894 	qdf_mem_copy(afc_chan_list, afc_mas_chan_list,
1895 		     NUM_6GHZ_CHANNELS * sizeof(struct regulatory_channel));
1896 
1897 	for (i = 0; i < NUM_6GHZ_CHANNELS; i++) {
1898 		if ((afc_chan_list[i].state != CHANNEL_STATE_DISABLE) &&
1899 		    !(afc_chan_list[i].chan_flags &
1900 		      REGULATORY_CHAN_DISABLED)) {
1901 			afc_chan_list[i].tx_power =
1902 				QDF_MIN(sp_chan_list[i].tx_power,
1903 					afc_mas_chan_list[i].tx_power);
1904 			afc_chan_list[i].psd_eirp =
1905 				QDF_MIN((int16_t)sp_chan_list[i].psd_eirp,
1906 					(int16_t)afc_mas_chan_list[i].psd_eirp);
1907 			 afc_chan_list[i].chan_flags &=
1908 				 ~REGULATORY_CHAN_AFC_NOT_DONE;
1909 		} else if ((pdev_priv_obj->reg_afc_dev_deployment_type ==
1910 			    AFC_DEPLOYMENT_OUTDOOR) &&
1911 			   (sp_chan_list[i].chan_flags &
1912 			    REGULATORY_CHAN_AFC_NOT_DONE)) {
1913 			/* This is for the SP channels supported by
1914 			 * regulatory list that are not supported by AFC i.e.
1915 			 * SP channel list - AFC Channel list.
1916 			 */
1917 			afc_chan_list[i].tx_power = sp_chan_list[i].tx_power;
1918 			afc_chan_list[i].psd_eirp = sp_chan_list[i].psd_eirp;
1919 			afc_chan_list[i].chan_flags &= ~REGULATORY_CHAN_DISABLED;
1920 			afc_chan_list[i].chan_flags |= REGULATORY_CHAN_AFC_NOT_DONE;
1921 			afc_chan_list[i].state = CHANNEL_STATE_ENABLE;
1922 		}
1923 	}
1924 }
1925 
1926 /* reg_modify_6g_afc_chan_list() - Modify the AFC channel list if the AFC WMI
1927  * power event is received from the target
1928  * @pdev_priv_obj: pointer to pdev_priv_obj.
1929  *
1930  * Return type: void.
1931  */
1932 static void
1933 reg_modify_6g_afc_chan_list(struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj)
1934 {
1935 	if (pdev_priv_obj->is_6g_afc_power_event_received)
1936 		reg_intersect_6g_afc_chan_list(pdev_priv_obj);
1937 }
1938 #else
1939 static inline void
1940 reg_modify_6g_afc_chan_list(struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj)
1941 {
1942 }
1943 #endif
1944 
1945 static void reg_copy_6g_cur_mas_chan_list_to_cmn(
1946 			struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj)
1947 {
1948 	if (pdev_priv_obj->is_6g_channel_list_populated)
1949 		reg_append_mas_chan_list_for_6g(pdev_priv_obj);
1950 }
1951 #else /* CONFIG_BAND_6GHZ */
1952 static inline void
1953 reg_copy_6g_cur_mas_chan_list_to_cmn(
1954 			struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj)
1955 {
1956 }
1957 
1958 static inline void
1959 reg_append_mas_chan_list_for_6g(
1960 			struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj)
1961 {
1962 }
1963 
1964 #ifdef CONFIG_REG_CLIENT
1965 static void
1966 reg_populate_secondary_cur_chan_list(struct wlan_regulatory_pdev_priv_obj
1967 				     *pdev_priv_obj)
1968 {
1969 	qdf_mem_copy(pdev_priv_obj->secondary_cur_chan_list,
1970 		     pdev_priv_obj->cur_chan_list,
1971 		     NUM_CHANNELS * sizeof(struct regulatory_channel));
1972 }
1973 #else /* CONFIG_REG_CLIENT */
1974 static inline void
1975 reg_populate_secondary_cur_chan_list(struct wlan_regulatory_pdev_priv_obj
1976 				     *pdev_priv_obj)
1977 {
1978 }
1979 #endif /* CONFIG_REG_CLIENT */
1980 static inline void
1981 reg_modify_6g_afc_chan_list(struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj)
1982 {
1983 }
1984 #endif /* CONFIG_BAND_6GHZ */
1985 
1986 #if defined(CONFIG_BAND_6GHZ) && defined(CONFIG_REG_CLIENT)
1987 /**
1988  * reg_modify_sec_chan_list_for_6g_edge_chan() - Modify 6 GHz edge channels
1989  * for SAP (for MCC use case)
1990  *
1991  * @pdev_priv_obj: pointer to pdev_priv_obj.
1992  *
1993  * This is a wrapper function that calls the API
1994  * reg_modify_chan_list_for_6g_edge_channels() by passing secondary channel
1995  * list (used by beaconing entities like SAP). This API enables/disables 6GHz
1996  * edge channels ch2 (5935 MHz) and ch233 (7115 MHz) based on service bits.
1997  *
1998  */
1999 static void
2000 reg_modify_sec_chan_list_for_6g_edge_chan(struct wlan_regulatory_pdev_priv_obj
2001 					  *pdev_priv_obj)
2002 {
2003 	reg_modify_chan_list_for_6g_edge_channels(pdev_priv_obj->pdev_ptr,
2004 						  pdev_priv_obj->
2005 						  secondary_cur_chan_list);
2006 }
2007 #else
2008 static inline void
2009 reg_modify_sec_chan_list_for_6g_edge_chan(struct wlan_regulatory_pdev_priv_obj
2010 					  *pdev_priv_obj)
2011 {
2012 }
2013 #endif
2014 
2015 #ifdef FEATURE_WLAN_CH_AVOID_EXT
2016 struct chan_5g_center_freq center_5g[MAX_5G_CHAN_NUM] = {
2017 	/*36*/
2018 	{5180, 5190, 5210, 5250},
2019 	/*40*/
2020 	{5200, 5190, 5210, 5250},
2021 	/*44*/
2022 	{5220, 5230, 5210, 5250},
2023 	/*48*/
2024 	{5240, 5230, 5210, 5250},
2025 
2026 	/*52*/
2027 	{5260, 5270, 5290, 5250},
2028 	/*56*/
2029 	{5280, 5270, 5290, 5250},
2030 	/*60*/
2031 	{5300, 5310, 5290, 5250},
2032 	/*64*/
2033 	{5320, 5310, 5290, 5250},
2034 
2035 	/*100*/
2036 	{5500, 5510, 5530, 5570},
2037 	/*104*/
2038 	{5520, 5510, 5530, 5570},
2039 	/*108*/
2040 	{5540, 5550, 5530, 5570},
2041 	/*112*/
2042 	{5560, 5550, 5530, 5570},
2043 
2044 	/*116*/
2045 	{5580, 5590, 5610, 5570},
2046 	/*120*/
2047 	{5600, 5590, 5610, 5570},
2048 	/*124*/
2049 	{5620, 5630, 5610, 5570},
2050 	/*128*/
2051 	{5640, 5630, 5610, 5570},
2052 
2053 	/*132*/
2054 	{5660, 5670, 5690, INVALID_CENTER_FREQ},
2055 	/*136*/
2056 	{5680, 5670, 5690, INVALID_CENTER_FREQ},
2057 	/*140*/
2058 	{5700, 5710, 5690, INVALID_CENTER_FREQ},
2059 	/*144*/
2060 	{5720, 5710, 5690, INVALID_CENTER_FREQ},
2061 
2062 	/*149*/
2063 	{5745, 5755, 5775, 5815},
2064 	/*153*/
2065 	{5765, 5755, 5775, 5815},
2066 	/*157*/
2067 	{5785, 5795, 5775, 5815},
2068 	/*161*/
2069 	{5805, 5795, 5775, 5815},
2070 
2071 	/*165*/
2072 	{5825, 5835, 5855, 5815},
2073 	/*169*/
2074 	{5845, 5835, 5855, 5815},
2075 	/*173*/
2076 	{5865, 5875, 5855, 5815},
2077 	/*177*/
2078 	{5885, 5875, 5855, 5815},
2079 };
2080 
2081 /**
2082  * reg_modify_5g_maxbw() - Update the max bandwidth for 5G channel
2083  * @chan: Pointer to current channel
2084  * @avoid_freq: current avoid frequency range
2085  *
2086  * This function updates the max bandwidth for the 5G channels if
2087  * it has overlap with avoid frequency range. For example, if the
2088  * avoid frequency range is []5755-5775], and current channel is 149 with
2089  * max bandwidth 80Mhz by default, then has to change the max bandwidth
2090  * to 20Mhz, since both 40Mhz [5735-5775] and 80M [5735-5815] has
2091  * overlap with avoid frequency [5755-5775].
2092  *
2093  * Return: void.
2094  */
2095 static void
2096 reg_modify_5g_maxbw(struct regulatory_channel *chan,
2097 		    struct ch_avoid_freq_type *avoid_freq)
2098 {
2099 	int i;
2100 	qdf_freq_t start = 0;
2101 	qdf_freq_t end = 0;
2102 	qdf_freq_t cur;
2103 	bool found = false;
2104 
2105 	for (i = 0; i < MAX_5G_CHAN_NUM; i++) {
2106 		cur = center_5g[i].center_freq_20;
2107 		if (chan->center_freq == cur) {
2108 			while (!found) {
2109 				uint16_t h_bw;
2110 
2111 				if (chan->max_bw < 20 ||
2112 				    chan->max_bw > 160)
2113 					break;
2114 
2115 				switch (chan->max_bw) {
2116 				case 160:
2117 					cur = center_5g[i].center_freq_160;
2118 					if (!cur) {
2119 						chan->max_bw = chan->max_bw / 2;
2120 						break;
2121 					}
2122 					start = cur - HALF_160MHZ_BW;
2123 					end = cur + HALF_160MHZ_BW;
2124 					break;
2125 				case 80:
2126 					cur = center_5g[i].center_freq_80;
2127 					start = cur - HALF_80MHZ_BW;
2128 					end = cur + HALF_80MHZ_BW;
2129 					break;
2130 				case 40:
2131 					cur = center_5g[i].center_freq_40;
2132 					start = cur - HALF_40MHZ_BW;
2133 					end = cur + HALF_40MHZ_BW;
2134 					break;
2135 				case 20:
2136 					cur = center_5g[i].center_freq_20;
2137 					start = cur - HALF_20MHZ_BW;
2138 					end = cur + HALF_20MHZ_BW;
2139 					break;
2140 				default:
2141 					break;
2142 				}
2143 
2144 				if (avoid_freq->end_freq <= end &&
2145 				    avoid_freq->start_freq >= start) {
2146 					/* avoid freq inside */
2147 					h_bw = chan->max_bw / 2;
2148 					chan->max_bw = min(chan->max_bw, h_bw);
2149 					continue;
2150 				} else if ((avoid_freq->start_freq > start &&
2151 					   avoid_freq->start_freq < end) ||
2152 					   (avoid_freq->end_freq > start &&
2153 					   avoid_freq->end_freq < end)) {
2154 					/* avoid freq part overlap */
2155 					h_bw = chan->max_bw / 2;
2156 					chan->max_bw = min(chan->max_bw, h_bw);
2157 					continue;
2158 				} else if (avoid_freq->start_freq >= end ||
2159 					   avoid_freq->end_freq <= start) {
2160 					/* beyond the range freq */
2161 					found = true;
2162 				}
2163 			}
2164 		}
2165 	}
2166 }
2167 
2168 /**
2169  * reg_modify_chan_list_for_avoid_chan_ext() - Update the state and bandwidth
2170  * for each channel in the current channel list.
2171  * @pdev_priv_obj: Pointer to wlan regulatory pdev private object.
2172  *
2173  * This function update the state and bandwidth for each channel in the current
2174  * channel list if it is affected by avoid frequency list.
2175  * For 2.4G/5G, all the center frequency of specific channel in the
2176  * avoid_chan_ext_list (avoid frequency list) will be disabled.
2177  * For example, avoid frequency list include [2412,2417,2422],
2178  * then channel 1, 2 and 3 will be disabled. Same logic apply for 5g.
2179  * For 5G, if the max bandwidth of the channel affected by avoid frequency
2180  * range then need to reduce the bandwidth or finally disabled.
2181  * For other bands, to-do in future if need.
2182  *
2183  * Return: void.
2184  */
2185 static void
2186 reg_modify_chan_list_for_avoid_chan_ext(struct wlan_regulatory_pdev_priv_obj
2187 				     *pdev_priv_obj)
2188 {
2189 	uint32_t i, j, k;
2190 	struct wlan_objmgr_psoc *psoc;
2191 	struct wlan_regulatory_psoc_priv_obj *psoc_priv_obj;
2192 	uint32_t num_avoid_channels;
2193 	struct regulatory_channel *chan_list = pdev_priv_obj->cur_chan_list;
2194 	struct regulatory_channel *sec_chan_list;
2195 	uint16_t *avoid_chan_ext_list;
2196 	uint32_t num_avoid_freq;
2197 	struct ch_avoid_freq_type *avoid_freq_ext, *avoid_freq_ext_t;
2198 
2199 	sec_chan_list = pdev_priv_obj->secondary_cur_chan_list;
2200 
2201 	avoid_chan_ext_list = pdev_priv_obj->avoid_chan_ext_list.chan_freq_list;
2202 	num_avoid_channels = pdev_priv_obj->avoid_chan_ext_list.chan_cnt;
2203 
2204 	psoc = wlan_pdev_get_psoc(pdev_priv_obj->pdev_ptr);
2205 	if (!psoc)
2206 		return;
2207 
2208 	if (!reg_check_coex_unsafe_chan_reg_disable(psoc)) {
2209 		reg_debug("Don't disable reg channels for Coex unsafe channels");
2210 		return;
2211 	}
2212 
2213 	psoc_priv_obj = reg_get_psoc_obj(psoc);
2214 	if (!psoc_priv_obj)
2215 		return;
2216 
2217 	if (!num_avoid_channels || !psoc_priv_obj->ch_avoid_ext_ind)
2218 		return;
2219 
2220 	num_avoid_freq = psoc_priv_obj->avoid_freq_ext_list.ch_avoid_range_cnt;
2221 	avoid_freq_ext = psoc_priv_obj->avoid_freq_ext_list.avoid_freq_range;
2222 
2223 	for (i = 0; i < num_avoid_channels; i++)
2224 		for (j = 0; j < NUM_CHANNELS; j++) {
2225 			qdf_freq_t c_freq, avoid_tmp = avoid_chan_ext_list[i];
2226 
2227 			if (chan_list[j].state == CHANNEL_STATE_DISABLE)
2228 				goto second_chan_handle;
2229 
2230 			/* For 2.4G, just only disable the channel if center
2231 			 * frequecy is in avoid_chan_ext_list.
2232 			 * For 5G, customer ask for bandwidth reduction if
2233 			 * it affect by the nearby channel that in the
2234 			 * avoid_chan_ext_list.
2235 			 * For example, if block out frequency range is
2236 			 * [5755-5775], then except for channel 153 need
2237 			 * to be disabled, and 149 has to change max 80Mhz
2238 			 * to 20Mhz, since 149 only has [5735-5755] available.
2239 			 * channel 157/161 [5775-5815] has to change max 80
2240 			 * to 40.
2241 			 * For 6G: to-do in future.
2242 			 */
2243 			c_freq = chan_list[j].center_freq;
2244 			if (avoid_tmp == c_freq) {
2245 				chan_list[j].state = CHANNEL_STATE_DISABLE;
2246 				chan_list[j].chan_flags |=
2247 					REGULATORY_CHAN_DISABLED;
2248 			} else if (reg_is_5ghz_ch_freq(c_freq)) {
2249 				for (k = 0; k < num_avoid_freq; k++) {
2250 					qdf_freq_t s_freq, e_freq;
2251 
2252 					avoid_freq_ext_t = &avoid_freq_ext[k];
2253 					s_freq = avoid_freq_ext_t->start_freq;
2254 					e_freq = avoid_freq_ext_t->end_freq;
2255 
2256 					/* need to cover [5170-5190] case*/
2257 					if ((!reg_is_5ghz_ch_freq(s_freq) &&
2258 					     ((s_freq + HALF_20MHZ_BW) <
2259 					       reg_min_5ghz_chan_freq())) ||
2260 					    (!reg_is_5ghz_ch_freq(e_freq) &&
2261 					      ((e_freq - HALF_20MHZ_BW) >
2262 					       reg_max_5ghz_chan_freq())))
2263 						continue;
2264 
2265 					/* if current center freq is in the
2266 					 * avoid rang, then skip it, it will be
2267 					 * handled in the branch (avoid_tmp
2268 					 * == c_freq)
2269 					 */
2270 					if ((c_freq > s_freq &&
2271 					     c_freq < e_freq))
2272 						continue;
2273 
2274 					reg_modify_5g_maxbw(&chan_list[j],
2275 							    avoid_freq_ext_t);
2276 
2277 					if (chan_list[j].max_bw <
2278 					    HALF_40MHZ_BW) {
2279 						chan_list[j].state =
2280 							CHANNEL_STATE_DISABLE;
2281 						chan_list[j].chan_flags |=
2282 						REGULATORY_CHAN_DISABLED;
2283 						break;
2284 					}
2285 				}
2286 			}
2287 second_chan_handle:
2288 
2289 			if (sec_chan_list[j].state ==
2290 			   CHANNEL_STATE_DISABLE)
2291 				continue;
2292 
2293 			c_freq = sec_chan_list[j].center_freq;
2294 			if (avoid_tmp == c_freq) {
2295 				sec_chan_list[j].state = CHANNEL_STATE_DISABLE;
2296 				sec_chan_list[j].chan_flags |=
2297 					REGULATORY_CHAN_DISABLED;
2298 			} else if (reg_is_5ghz_ch_freq(c_freq)) {
2299 				for (k = 0; k < num_avoid_freq; k++) {
2300 					qdf_freq_t s_freq, e_freq;
2301 
2302 					avoid_freq_ext_t = &avoid_freq_ext[k];
2303 					s_freq = avoid_freq_ext_t->start_freq;
2304 					e_freq = avoid_freq_ext_t->end_freq;
2305 
2306 					/* need to cover [5170-5190] case*/
2307 					if ((!reg_is_5ghz_ch_freq(s_freq) &&
2308 					     ((s_freq + HALF_20MHZ_BW) <
2309 					       reg_min_5ghz_chan_freq())) ||
2310 					    (!reg_is_5ghz_ch_freq(e_freq) &&
2311 					      ((e_freq - HALF_20MHZ_BW) >
2312 					       reg_max_5ghz_chan_freq())))
2313 						continue;
2314 
2315 					/* if current center freq is in the
2316 					 * avoid rang, then skip it, it will be
2317 					 * handled in the branch (avoid_tmp
2318 					 * == c_freq)
2319 					 */
2320 					if ((c_freq > s_freq &&
2321 					     c_freq < e_freq))
2322 						continue;
2323 
2324 					reg_modify_5g_maxbw(&sec_chan_list[j],
2325 							    avoid_freq_ext_t);
2326 
2327 					if (sec_chan_list[j].max_bw <
2328 					    HALF_40MHZ_BW) {
2329 						sec_chan_list[j].state =
2330 							CHANNEL_STATE_DISABLE;
2331 						sec_chan_list[j].chan_flags |=
2332 						REGULATORY_CHAN_DISABLED;
2333 						break;
2334 					}
2335 				}
2336 			}
2337 		}
2338 }
2339 #else
2340 static inline void
2341 reg_modify_chan_list_for_avoid_chan_ext(struct wlan_regulatory_pdev_priv_obj
2342 				     *pdev_priv_obj)
2343 {
2344 }
2345 #endif
2346 
2347 #ifdef CONFIG_BAND_6GHZ
2348 /**
2349  * reg_init_super_chan_entry() - Initialize the super channel list entry
2350  * for an input channel index by disabling the state and chan flags.
2351  * @pdev_priv_obj: Pointer to pdev_priv_obj
2352  *
2353  * Return: void
2354  */
2355 static void reg_init_super_chan_entry(
2356 		struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj,
2357 		uint8_t chan_idx)
2358 {
2359 	enum supported_6g_pwr_types pwr_type;
2360 	struct super_chan_info *chan_info;
2361 
2362 	chan_info = &pdev_priv_obj->super_chan_list[chan_idx];
2363 
2364 	for (pwr_type = REG_CURRENT_PWR_MODE; pwr_type <= REG_CLI_SUB_VLP;
2365 	     pwr_type++)
2366 		reg_dis_chan_state_and_flags(&chan_info->state_arr[pwr_type],
2367 					     &chan_info->chan_flags_arr
2368 					     [pwr_type]);
2369 }
2370 
2371 /**
2372  * reg_init_pdev_super_chan_list() - Initialize the super channel list.
2373  * @pdev_priv_obj: Pointer to pdev_priv_obj
2374  *
2375  * Return: void
2376  */
2377 static void reg_init_pdev_super_chan_list(
2378 		struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj)
2379 {
2380 	uint8_t i;
2381 
2382 	qdf_mem_zero(pdev_priv_obj->super_chan_list, NUM_6GHZ_CHANNELS *
2383 		     sizeof(struct super_chan_info));
2384 	for (i = 0; i < NUM_6GHZ_CHANNELS; i++)
2385 		reg_init_super_chan_entry(pdev_priv_obj, i);
2386 }
2387 
2388 /**
2389  * reg_is_edge_chan_disable_needed() - Check if the 6G edge channels are
2390  * disabled
2391  * @psoc: Pointer to psoc
2392  * @chan_idx: Channel index
2393  *
2394  * Return: bool
2395  */
2396 static bool reg_is_edge_chan_disable_needed(struct wlan_objmgr_psoc *psoc,
2397 					    uint16_t chan_idx)
2398 {
2399 	bool is_lower_edge_disable =
2400 		((chan_idx == (CHAN_ENUM_5935 - MIN_6GHZ_CHANNEL)) &&
2401 		!reg_is_lower_6g_edge_ch_supp(psoc));
2402 	bool is_upper_edge_disable =
2403 		((chan_idx == (CHAN_ENUM_7115 - MIN_6GHZ_CHANNEL)) &&
2404 		 reg_is_upper_6g_edge_ch_disabled(psoc));
2405 
2406 	return is_lower_edge_disable || is_upper_edge_disable;
2407 }
2408 
2409 #ifdef CONFIG_AFC_SUPPORT
2410 /**
2411  * reg_set_flag_afc_not_done() - Set channel flag REGULATORY_CHAN_AFC_NOT_DONE
2412  * @chan_flags: Channel flags
2413  * @is_set:     boolean to set/unset the flag
2414  *
2415  * Return: void
2416  */
2417 static inline void
2418 reg_set_flag_afc_not_done(uint32_t *chan_flags, bool is_set)
2419 {
2420 	if (is_set)
2421 		*chan_flags |= REGULATORY_CHAN_AFC_NOT_DONE;
2422 	else
2423 		*chan_flags &= ~REGULATORY_CHAN_AFC_NOT_DONE;
2424 }
2425 
2426 #else
2427 static inline void
2428 reg_set_flag_afc_not_done(uint32_t *chan_flags, bool is_set)
2429 {
2430 }
2431 #endif
2432 
2433 /**
2434  * reg_dis_6g_edge_chan_in_enh_chan() - Disable the 6g edge
2435  * channels in the super channel list
2436  * @pdev: Pointer to pdev
2437  * @chan_info: Pointer to chan_info
2438  * @chan_idx: Channel index
2439  * @pwr_type: 6G power type bitmap
2440  *
2441  * Return: void
2442  */
2443 static void
2444 reg_dis_6g_edge_chan_in_enh_chan(struct wlan_objmgr_pdev *pdev,
2445 				 struct super_chan_info *chan_info,
2446 				 uint16_t chan_idx,
2447 				 enum supported_6g_pwr_types pwr_type)
2448 {
2449 	struct wlan_objmgr_psoc *psoc;
2450 
2451 	if (!pdev) {
2452 		reg_debug("pdev is NULL");
2453 		return;
2454 	}
2455 
2456 	if (!chan_info) {
2457 		reg_debug("chan_info is NULL");
2458 		return;
2459 	}
2460 
2461 	if (reg_is_supp_pwr_mode_invalid(pwr_type)) {
2462 		reg_debug("pwr_type invalid");
2463 		return;
2464 	}
2465 
2466 	if (chan_idx >= NUM_6GHZ_CHANNELS) {
2467 		reg_debug("chan_idx is out bounds");
2468 		return;
2469 	}
2470 
2471 	psoc = wlan_pdev_get_psoc(pdev);
2472 	if (!psoc) {
2473 		reg_debug("psoc is NULL");
2474 		return;
2475 	}
2476 
2477 	if (reg_is_edge_chan_disable_needed(psoc, chan_idx))
2478 		reg_dis_chan_state_and_flags(&chan_info->state_arr[pwr_type],
2479 					     &chan_info->chan_flags_arr
2480 					     [pwr_type]);
2481 }
2482 
2483 /**
2484  * copy_enh_chan_info_from_reg_chan() - Copy the mas_chan_list entry to the
2485  * super channel list entry
2486  * @chan_info: Pointer to chan_info
2487  * @pwr_type: 6G power type bitmap
2488  * @reg_chan: Pointer to reg_chan
2489  *
2490  * Return: void
2491  */
2492 static void
2493 copy_enh_chan_info_from_reg_chan(struct super_chan_info *chan_info,
2494 				 enum supported_6g_pwr_types pwr_type,
2495 				 struct regulatory_channel *reg_chan)
2496 {
2497 	if (!chan_info) {
2498 		reg_debug("chan_info is NULL");
2499 		return;
2500 	}
2501 
2502 	if (reg_is_supp_pwr_mode_invalid(pwr_type)) {
2503 		reg_debug("pwr_type invalid");
2504 		return;
2505 	}
2506 
2507 	if (!reg_chan) {
2508 		reg_debug("reg_chan is NULL");
2509 		return;
2510 	}
2511 
2512 	chan_info->reg_chan_pwr[pwr_type].psd_flag = reg_chan->psd_flag;
2513 	chan_info->reg_chan_pwr[pwr_type].psd_eirp = reg_chan->psd_eirp;
2514 	chan_info->reg_chan_pwr[pwr_type].tx_power = reg_chan->tx_power;
2515 	chan_info->chan_flags_arr[pwr_type] = reg_chan->chan_flags;
2516 	chan_info->state_arr[pwr_type] = reg_chan->state;
2517 	chan_info->min_bw[pwr_type] = reg_chan->min_bw;
2518 	chan_info->max_bw[pwr_type] = reg_chan->max_bw;
2519 }
2520 
2521 const struct ap_cli_pwr_mode_info reg_pwr_enum_2_ap_cli_pwrmode[] = {
2522 	[REG_AP_LPI] =       {true, REG_INVALID_CLIENT_TYPE, REG_INDOOR_AP},
2523 	[REG_AP_SP]  =       {true, REG_INVALID_CLIENT_TYPE,
2524 							REG_STANDARD_POWER_AP},
2525 	[REG_AP_VLP] =       {true, REG_INVALID_CLIENT_TYPE,
2526 							REG_VERY_LOW_POWER_AP},
2527 	[REG_CLI_DEF_LPI] =  {false, REG_DEFAULT_CLIENT, REG_INDOOR_AP},
2528 	[REG_CLI_DEF_SP]  =  {false, REG_DEFAULT_CLIENT, REG_STANDARD_POWER_AP},
2529 	[REG_CLI_DEF_VLP] =  {false, REG_DEFAULT_CLIENT, REG_VERY_LOW_POWER_AP},
2530 	[REG_CLI_SUB_LPI] =  {false, REG_SUBORDINATE_CLIENT, REG_INDOOR_AP},
2531 	[REG_CLI_SUB_SP]  =  {false, REG_SUBORDINATE_CLIENT,
2532 							REG_STANDARD_POWER_AP},
2533 	[REG_CLI_SUB_VLP] =  {false, REG_SUBORDINATE_CLIENT,
2534 							REG_VERY_LOW_POWER_AP},
2535 };
2536 
2537 enum reg_6g_ap_type
2538 reg_convert_supported_6g_pwr_type_to_ap_pwr_type(enum supported_6g_pwr_types
2539 						in_6g_pwr_type)
2540 {
2541 	if (reg_is_supp_pwr_mode_invalid(in_6g_pwr_type))
2542 		return REG_MAX_AP_TYPE;
2543 
2544 	return reg_pwr_enum_2_ap_cli_pwrmode[in_6g_pwr_type].ap_pwr_mode;
2545 }
2546 
2547 struct regulatory_channel *reg_get_reg_maschan_lst_frm_6g_pwr_mode(
2548 			enum supported_6g_pwr_types supp_pwr_mode,
2549 			struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj,
2550 			uint16_t chan_idx)
2551 {
2552 	struct regulatory_channel *mas_chan_list = NULL;
2553 	bool is_ap_chan_lst;
2554 	enum reg_6g_ap_type ap_pwr_mode; /* LPI, SP or VLP */
2555 
2556 	if (reg_is_supp_pwr_mode_invalid(supp_pwr_mode)) {
2557 		reg_debug("Unsupported 6G AP power type");
2558 		return mas_chan_list;
2559 	}
2560 
2561 	is_ap_chan_lst =
2562 			reg_pwr_enum_2_ap_cli_pwrmode[supp_pwr_mode].is_mode_ap;
2563 	ap_pwr_mode = reg_pwr_enum_2_ap_cli_pwrmode[supp_pwr_mode].ap_pwr_mode;
2564 
2565 	if (ap_pwr_mode > REG_MAX_SUPP_AP_TYPE) {
2566 		reg_debug("Unsupported 6G AP power type");
2567 		return mas_chan_list;
2568 	}
2569 
2570 	if (is_ap_chan_lst) {
2571 		mas_chan_list =
2572 		&pdev_priv_obj->mas_chan_list_6g_ap[ap_pwr_mode][chan_idx];
2573 	} else {
2574 		enum reg_6g_client_type cli_type;
2575 
2576 		cli_type =
2577 			reg_pwr_enum_2_ap_cli_pwrmode[supp_pwr_mode].cli_type;
2578 		if (cli_type >= REG_MAX_CLIENT_TYPE) {
2579 			reg_debug("Unsupported 6G client power type");
2580 			return mas_chan_list;
2581 		}
2582 
2583 		mas_chan_list =
2584 		&pdev_priv_obj->mas_chan_list_6g_client[ap_pwr_mode][cli_type]
2585 						       [chan_idx];
2586 	}
2587 
2588 	return mas_chan_list;
2589 }
2590 
2591 /**
2592  * reg_disable_out_of_range_chan_entry() - Disable the input channel if it is
2593  * out of the range of the 6G radio and return true, else return false
2594  * @reg_chan: Pointer to reg_chan
2595  * @pdev_priv_obj: Pointer to pdev_priv_obj
2596  *
2597  * Return: bool
2598  */
2599 static bool reg_is_chan_out_of_chip_range(
2600 		struct regulatory_channel *reg_chan,
2601 		struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj)
2602 {
2603 	return ((reg_chan->center_freq < pdev_priv_obj->range_5g_low) ||
2604 		(reg_chan->center_freq > pdev_priv_obj->range_5g_high));
2605 }
2606 
2607 /**
2608  * reg_accumulate_pwr_type() - Accumulate the power type in the super channel
2609  * list entry for a given input channel index.
2610  * @supp_pwr_mode: 6G supported power mode
2611  * @super_chan_list: Pointer to super channel list
2612  * @chn_idx: Channel index
2613  *
2614  * Return: void
2615  */
2616 static void reg_accumulate_pwr_type(
2617 		enum supported_6g_pwr_types supp_pwr_mode,
2618 		struct super_chan_info *super_chan_list,
2619 		uint16_t chn_idx)
2620 {
2621 	if (reg_is_supp_pwr_mode_invalid(supp_pwr_mode))
2622 		return;
2623 
2624 	super_chan_list[chn_idx].power_types |= BIT(supp_pwr_mode);
2625 }
2626 
2627 /**
2628  * reg_is_sp_supp_pwr_mode() - Check if the input supported power mode is a
2629  * SP power mode
2630  * @supp_pwr_mode: 6G supported power mode
2631  *
2632  * Return: bool
2633  */
2634 static bool
2635 reg_is_sp_supp_pwr_mode(enum supported_6g_pwr_types supp_pwr_mode)
2636 {
2637 	return ((supp_pwr_mode == REG_AP_SP) ||
2638 		(supp_pwr_mode == REG_CLI_DEF_SP) ||
2639 		(supp_pwr_mode == REG_CLI_SUB_SP));
2640 }
2641 
2642 /**
2643  * reg_fill_best_pwr_mode() - Fill the best power mode
2644  * @pdev_priv_obj: Pointer to pdev_priv_obj
2645  * @super_chan_list: Pointer to super_chan_list
2646  * @chn_idx: Channel index
2647  * @supp_pwr_mode: Supported power mode
2648  * @mas_chan_list_power: EIRP of the channel in the mas_chan_list
2649  * @max_eirp_pwr: Maximum EIRP
2650  *
2651  * Return: void
2652  */
2653 #ifdef CONFIG_REG_CLIENT
2654 static void
2655 reg_fill_best_pwr_mode(struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj,
2656 		       struct super_chan_info *super_chan_list,
2657 		       uint8_t chn_idx,
2658 		       enum supported_6g_pwr_types supp_pwr_mode,
2659 		       uint8_t mas_chan_list_power,
2660 		       uint8_t *max_eirp_pwr)
2661 {
2662 	enum reg_6g_client_type curr_6g_client_type;
2663 	enum reg_6g_client_type client_type =
2664 			reg_pwr_enum_2_ap_cli_pwrmode[supp_pwr_mode].cli_type;
2665 
2666 	reg_get_cur_6g_client_type(pdev_priv_obj->pdev_ptr,
2667 				   &curr_6g_client_type);
2668 	if (client_type != curr_6g_client_type)
2669 		return;
2670 
2671 	if (reg_is_sp_supp_pwr_mode(supp_pwr_mode) &&
2672 	    !wlan_reg_is_afc_power_event_received(pdev_priv_obj->pdev_ptr))
2673 		return;
2674 
2675 	if (*max_eirp_pwr == 0) {
2676 		*max_eirp_pwr = mas_chan_list_power;
2677 		super_chan_list[chn_idx].best_power_mode = supp_pwr_mode;
2678 		return;
2679 	} else if (pdev_priv_obj->indoor_chan_enabled &&
2680 		   (mas_chan_list_power > *max_eirp_pwr)) {
2681 		*max_eirp_pwr = mas_chan_list_power;
2682 		super_chan_list[chn_idx].best_power_mode = supp_pwr_mode;
2683 		return;
2684 	}
2685 
2686 	if (reg_is_lpi_cli_supp_pwr_mode(
2687 				super_chan_list[chn_idx].best_power_mode) &&
2688 	    !reg_is_lpi_cli_supp_pwr_mode(supp_pwr_mode)) {
2689 		*max_eirp_pwr = mas_chan_list_power;
2690 		super_chan_list[chn_idx].best_power_mode = supp_pwr_mode;
2691 		return;
2692 	} else if (!reg_is_lpi_cli_supp_pwr_mode(super_chan_list[chn_idx].
2693 		   best_power_mode) &&
2694 		   reg_is_lpi_cli_supp_pwr_mode(supp_pwr_mode)) {
2695 		return;
2696 	} else if (mas_chan_list_power > *max_eirp_pwr) {
2697 		*max_eirp_pwr = mas_chan_list_power;
2698 		super_chan_list[chn_idx].best_power_mode = supp_pwr_mode;
2699 	}
2700 }
2701 #else
2702 static void
2703 reg_fill_best_pwr_mode(struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj,
2704 		       struct super_chan_info *super_chan_list,
2705 		       uint8_t chn_idx,
2706 		       enum supported_6g_pwr_types supp_pwr_mode,
2707 		       uint8_t mas_chan_list_power,
2708 		       uint8_t *max_eirp_pwr)
2709 {
2710 	if (mas_chan_list_power > *max_eirp_pwr) {
2711 		*max_eirp_pwr = mas_chan_list_power;
2712 		super_chan_list[chn_idx].best_power_mode = supp_pwr_mode;
2713 	}
2714 }
2715 #endif
2716 
2717 #ifdef CONFIG_AFC_SUPPORT
2718 /**
2719  * reg_assign_afc_chan_entry_to_mas_chan() - Assign the AFC channel list entry
2720  * to the mas_chan
2721  * @pdev_priv_obj: Pointer to pdev_priv_obj
2722  * @mas_chan: Pointer to address of mas_chan
2723  * @chn_idx: Channel index
2724  *
2725  * Return: void
2726  */
2727 static void
2728 reg_assign_afc_chan_entry_to_mas_chan(
2729 		struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj,
2730 		struct regulatory_channel **mas_chan,
2731 		uint8_t chn_idx)
2732 {
2733 	*mas_chan = &pdev_priv_obj->afc_chan_list[chn_idx];
2734 }
2735 
2736 /**
2737  * reg_is_deployment_outdoor() - Check if device deployment type is outdoor
2738  * @pdev_priv_obj: Pointer to pdev_priv_obj
2739  *
2740  * Return: True if deployment is outdoor, else false
2741  */
2742 static bool
2743 reg_is_deployment_outdoor(struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj)
2744 {
2745 	return pdev_priv_obj->reg_afc_dev_deployment_type ==
2746 		AFC_DEPLOYMENT_OUTDOOR;
2747 }
2748 #else
2749 static inline void
2750 reg_assign_afc_chan_entry_to_mas_chan(
2751 		struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj,
2752 		struct regulatory_channel **mas_chan,
2753 		uint8_t chn_idx)
2754 {
2755 }
2756 
2757 static inline bool
2758 reg_is_deployment_outdoor(struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj)
2759 {
2760 	return false;
2761 }
2762 #endif
2763 
2764 /**
2765  * reg_update_sup_ch_entry_for_mode() - Construct the super channel list entry
2766  * for a mode
2767  * @pdev_priv_obj: Pointer to pdev_priv_obj
2768  * @supp_pwr_mode: Supported power mode
2769  * @chn_idx: Channel index
2770  *
2771  * Return: void
2772  */
2773 static void reg_update_sup_ch_entry_for_mode(
2774 		struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj,
2775 		enum supported_6g_pwr_types supp_pwr_mode,
2776 		uint16_t chn_idx,
2777 		uint8_t *max_eirp_pwr)
2778 {
2779 	struct super_chan_info *super_chan_list;
2780 	struct wlan_objmgr_pdev *pdev = pdev_priv_obj->pdev_ptr;
2781 	struct regulatory_channel *mas_chan;
2782 	struct regulatory_channel temp_reg_chan;
2783 
2784 	mas_chan = reg_get_reg_maschan_lst_frm_6g_pwr_mode(supp_pwr_mode,
2785 							   pdev_priv_obj,
2786 							   chn_idx);
2787 	if (!mas_chan)
2788 		return;
2789 
2790 	/*
2791 	 * If AFC is invalid, copy from Regulatory SP channel list.
2792 	 * If AFC is valid, copy from AFC response channel list.
2793 	 */
2794 	if (reg_is_sp_supp_pwr_mode(supp_pwr_mode)) {
2795 		if (wlan_reg_is_afc_power_event_received(pdev))
2796 			reg_assign_afc_chan_entry_to_mas_chan(pdev_priv_obj,
2797 							      &mas_chan,
2798 							      chn_idx);
2799 		/* In INDOOR mode, before AFC response is received, the SP
2800 		 * channels should be totally disabled. Therefore, return from
2801 		 * here so that super channel entry remain disabled
2802 		 */
2803 		else if (!reg_is_deployment_outdoor(pdev_priv_obj))
2804 			return;
2805 	}
2806 
2807 	if (!mas_chan)
2808 		return;
2809 
2810 	qdf_mem_copy(&temp_reg_chan, mas_chan,
2811 		     sizeof(struct regulatory_channel));
2812 	/*
2813 	 * Intersect the hardware frequency range with the
2814 	 * 6GHz channels.
2815 	 * If a channel is out of chip range, disable it.
2816 	 */
2817 	if (reg_is_chan_out_of_chip_range(&temp_reg_chan, pdev_priv_obj)) {
2818 		reg_dis_chan_state_and_flags(&temp_reg_chan.state,
2819 					     &temp_reg_chan.chan_flags);
2820 	}
2821 
2822 	super_chan_list = pdev_priv_obj->super_chan_list;
2823 	copy_enh_chan_info_from_reg_chan(&super_chan_list[chn_idx],
2824 					 supp_pwr_mode,
2825 					 &temp_reg_chan);
2826 	if (reg_is_chan_disabled_and_not_nol(&temp_reg_chan))
2827 		return;
2828 
2829 	reg_modify_super_chan_list_for_indoor_channels(pdev_priv_obj, chn_idx,
2830 						       supp_pwr_mode);
2831 
2832 	reg_dis_6g_chan_in_super_chan_list(pdev, &super_chan_list[chn_idx],
2833 					   supp_pwr_mode);
2834 
2835 	reg_dis_6g_edge_chan_in_enh_chan(pdev, &super_chan_list[chn_idx],
2836 					 chn_idx, supp_pwr_mode);
2837 	reg_fill_best_pwr_mode(pdev_priv_obj, super_chan_list, chn_idx,
2838 			       supp_pwr_mode, temp_reg_chan.tx_power,
2839 			       max_eirp_pwr);
2840 	reg_accumulate_pwr_type(supp_pwr_mode, super_chan_list, chn_idx);
2841 }
2842 
2843 /**
2844  * reg_update_super_chan_entry() - Construct the super channel list entry for an
2845  * input channel index
2846  * @pdev_priv_obj: Pointer to pdev_priv_obj
2847  * @chn_idx: Channel index
2848  *
2849  * Return: void
2850  */
2851 static void
2852 reg_update_super_chan_entry(struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj,
2853 			    uint16_t chn_idx)
2854 {
2855 	enum supported_6g_pwr_types supp_pwr_mode;
2856 	uint8_t max_eirp_pwr = 0;
2857 
2858 	for (supp_pwr_mode = REG_AP_LPI; supp_pwr_mode <= REG_CLI_SUB_VLP;
2859 	     supp_pwr_mode++) {
2860 		reg_update_sup_ch_entry_for_mode(pdev_priv_obj, supp_pwr_mode,
2861 						 chn_idx, &max_eirp_pwr);
2862 	}
2863 }
2864 
2865 /**
2866  * reg_compute_super_chan_list() - Construct the super channel list
2867  * @pdev_priv_obj: Pointer to pdev_priv_obj
2868  *
2869  * Return: void
2870  */
2871 static void
2872 reg_compute_super_chan_list(struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj)
2873 {
2874 	uint8_t i;
2875 
2876 	if (!pdev_priv_obj->is_6g_channel_list_populated)
2877 		return;
2878 
2879 	for (i = 0; i < NUM_6GHZ_CHANNELS; i++)
2880 		reg_update_super_chan_entry(pdev_priv_obj, i);
2881 }
2882 #else /* CONFIG_BAND_6GHZ */
2883 static void reg_init_pdev_super_chan_list(
2884 			struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj)
2885 {
2886 }
2887 
2888 static inline void
2889 reg_compute_super_chan_list(struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj)
2890 {
2891 }
2892 #endif /* CONFIG_BAND_6GHZ */
2893 
2894 void reg_compute_pdev_current_chan_list(struct wlan_regulatory_pdev_priv_obj
2895 					*pdev_priv_obj)
2896 {
2897 	reg_modify_6g_afc_chan_list(pdev_priv_obj);
2898 
2899 	reg_copy_6g_cur_mas_chan_list_to_cmn(pdev_priv_obj);
2900 
2901 	reg_compute_super_chan_list(pdev_priv_obj);
2902 
2903 	qdf_mem_copy(pdev_priv_obj->cur_chan_list, pdev_priv_obj->mas_chan_list,
2904 		     NUM_CHANNELS * sizeof(struct regulatory_channel));
2905 
2906 	reg_modify_chan_list_for_freq_range(pdev_priv_obj->cur_chan_list,
2907 					    pdev_priv_obj->range_2g_low,
2908 					    pdev_priv_obj->range_2g_high,
2909 					    pdev_priv_obj->range_5g_low,
2910 					    pdev_priv_obj->range_5g_high);
2911 
2912 	reg_modify_chan_list_for_band(pdev_priv_obj->cur_chan_list,
2913 				      pdev_priv_obj->band_capability);
2914 
2915 	reg_modify_disable_chan_list_for_unii1_and_unii2a(pdev_priv_obj);
2916 
2917 	reg_modify_chan_list_for_dfs_channels(pdev_priv_obj->cur_chan_list,
2918 					      pdev_priv_obj->dfs_enabled);
2919 
2920 	reg_modify_chan_list_for_nol_list(pdev_priv_obj->cur_chan_list);
2921 	reg_modify_chan_list_for_static_puncture(pdev_priv_obj->cur_chan_list);
2922 
2923 	reg_modify_chan_list_for_indoor_channels(pdev_priv_obj);
2924 
2925 	reg_modify_chan_list_for_indoor_concurrency(pdev_priv_obj);
2926 
2927 	reg_modify_chan_list_for_fcc_channel(pdev_priv_obj);
2928 
2929 	reg_modify_chan_list_for_chan_144(pdev_priv_obj->cur_chan_list,
2930 					  pdev_priv_obj->en_chan_144);
2931 
2932 	reg_modify_chan_list_for_cached_channels(pdev_priv_obj);
2933 
2934 	reg_modify_chan_list_for_srd_channels(pdev_priv_obj->pdev_ptr,
2935 					      pdev_priv_obj->cur_chan_list);
2936 
2937 	reg_modify_chan_list_for_5dot9_ghz_channels(pdev_priv_obj->pdev_ptr,
2938 						    pdev_priv_obj->
2939 						    cur_chan_list);
2940 
2941 	reg_modify_chan_list_for_max_chwidth_for_pwrmode(
2942 						pdev_priv_obj->pdev_ptr,
2943 						pdev_priv_obj->cur_chan_list,
2944 						REG_CURRENT_PWR_MODE);
2945 
2946 	reg_modify_chan_list_for_6g_edge_channels(pdev_priv_obj->pdev_ptr,
2947 						  pdev_priv_obj->
2948 						  cur_chan_list);
2949 
2950 	reg_populate_secondary_cur_chan_list(pdev_priv_obj);
2951 
2952 	reg_modify_chan_list_for_avoid_chan_ext(pdev_priv_obj);
2953 
2954 	reg_modify_sec_chan_list_for_6g_edge_chan(pdev_priv_obj);
2955 }
2956 
2957 void reg_reset_reg_rules(struct reg_rule_info *reg_rules)
2958 {
2959 	qdf_mem_zero(reg_rules, sizeof(*reg_rules));
2960 }
2961 
2962 #ifdef CONFIG_REG_CLIENT
2963 /**
2964  * reg_get_num_reg_rules() - Get number of reg rules.
2965  * @psoc_reg_rules: pointer to psoc reg rules
2966  * @pdev_priv_obj: pointer to pdev priv object
2967  *
2968  * Return: int
2969  */
2970 static int reg_get_num_reg_rules(
2971 				 struct reg_rule_info *psoc_reg_rules,
2972 				 struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj)
2973 {
2974 	struct reg_rule_info *pdev_reg_rules;
2975 
2976 	pdev_reg_rules = &pdev_priv_obj->reg_rules;
2977 	return pdev_reg_rules->num_of_reg_rules;
2978 }
2979 #else
2980 /**
2981  * reg_get_num_reg_rules() - Get number of reg rules.
2982  * @psoc_reg_rules: pointer to psoc reg rules
2983  * @pdev_priv_obj: pointer to pdev priv object
2984  *
2985  * Return: int.
2986  */
2987 static int reg_get_num_reg_rules(
2988 				 struct reg_rule_info *psoc_reg_rules,
2989 				 struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj)
2990 {
2991 	enum reg_6g_ap_type cur_6g_ap_pwr_type;
2992 	struct reg_rule_info *pdev_reg_rules;
2993 
2994 	cur_6g_ap_pwr_type = pdev_priv_obj->reg_cur_6g_ap_pwr_type;
2995 	pdev_reg_rules = &pdev_priv_obj->reg_rules;
2996 
2997 	return (pdev_reg_rules->num_of_reg_rules +
2998 		psoc_reg_rules->num_of_6g_ap_reg_rules[cur_6g_ap_pwr_type]);
2999 }
3000 #endif
3001 
3002 #ifdef CONFIG_BAND_6GHZ
3003 #ifdef CONFIG_REG_CLIENT
3004 /**
3005  * reg_append_6g_reg_rules_in_pdev() - Append the 6G reg rules to the reg rules
3006  * list in pdev so that all currently used reg rules are in one common list
3007  * @pdev_priv_obj: Pointer to pdev private object
3008  *
3009  * Return: void
3010  */
3011 static void reg_append_6g_reg_rules_in_pdev(
3012 			struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj)
3013 {
3014 	struct reg_rule_info *pdev_reg_rules;
3015 	enum reg_6g_ap_type cur_pwr_type = REG_INDOOR_AP;
3016 	uint8_t num_reg_rules;
3017 
3018 	pdev_reg_rules = &pdev_priv_obj->reg_rules;
3019 
3020 	num_reg_rules = pdev_reg_rules->num_of_reg_rules;
3021 	pdev_reg_rules->num_of_reg_rules +=
3022 		pdev_reg_rules->num_of_6g_client_reg_rules[cur_pwr_type];
3023 
3024 	qdf_mem_copy(&pdev_reg_rules->reg_rules[num_reg_rules],
3025 		     pdev_reg_rules->reg_rules_6g_client[cur_pwr_type],
3026 		     pdev_reg_rules->num_of_6g_client_reg_rules[cur_pwr_type] *
3027 		     sizeof(struct cur_reg_rule));
3028 }
3029 #else /* CONFIG_REG_CLIENT */
3030 /**
3031  * reg_append_6g_reg_rules_in_pdev() - Append 6 GHz reg rules to reg rules list
3032  * @pdev_priv_obj: Pointer to pdev private object
3033  *
3034  * Append 6 GHz reg rules to the reg rules list in pdev so that all currently
3035  * used reg rules are in one common list.
3036  *
3037  * Return: void
3038  */
3039 static void reg_append_6g_reg_rules_in_pdev(
3040 			struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj)
3041 {
3042 	struct reg_rule_info *pdev_reg_rules;
3043 	enum reg_6g_ap_type cur_pwr_type;
3044 	uint8_t num_reg_rules;
3045 
3046 	cur_pwr_type = pdev_priv_obj->reg_cur_6g_ap_pwr_type;
3047 	pdev_reg_rules = &pdev_priv_obj->reg_rules;
3048 
3049 	num_reg_rules = pdev_reg_rules->num_of_reg_rules;
3050 	pdev_reg_rules->num_of_reg_rules +=
3051 		pdev_reg_rules->num_of_6g_ap_reg_rules[cur_pwr_type];
3052 
3053 	qdf_mem_copy(&pdev_reg_rules->reg_rules[num_reg_rules],
3054 		     pdev_reg_rules->reg_rules_6g_ap[cur_pwr_type],
3055 		     pdev_reg_rules->num_of_6g_ap_reg_rules[cur_pwr_type] *
3056 		     sizeof(struct cur_reg_rule));
3057 }
3058 #endif /* CONFIG_REG_CLIENT */
3059 
3060 /**
3061  * reg_copy_6g_reg_rules() - Copy the 6GHz reg rules from PSOC to PDEV
3062  * @pdev_reg_rules: Pointer to pdev reg rules
3063  * @psoc_reg_rules: Pointer to psoc reg rules
3064  *
3065  * Return: void
3066  */
3067 static void reg_copy_6g_reg_rules(struct reg_rule_info *pdev_reg_rules,
3068 				  struct reg_rule_info *psoc_reg_rules)
3069 {
3070 	uint32_t reg_rule_len_6g_ap, reg_rule_len_6g_client;
3071 	uint8_t i;
3072 
3073 	for (i = 0; i < REG_CURRENT_MAX_AP_TYPE; i++) {
3074 		pdev_reg_rules->num_of_6g_ap_reg_rules[i] =
3075 			psoc_reg_rules->num_of_6g_ap_reg_rules[i];
3076 		reg_rule_len_6g_ap = psoc_reg_rules->num_of_6g_ap_reg_rules[i] *
3077 			sizeof(struct cur_reg_rule);
3078 		qdf_mem_copy(pdev_reg_rules->reg_rules_6g_ap[i],
3079 			     psoc_reg_rules->reg_rules_6g_ap[i],
3080 			     reg_rule_len_6g_ap);
3081 
3082 		pdev_reg_rules->num_of_6g_client_reg_rules[i] =
3083 			psoc_reg_rules->num_of_6g_client_reg_rules[i];
3084 		reg_rule_len_6g_client =
3085 			psoc_reg_rules->num_of_6g_client_reg_rules[i] *
3086 			sizeof(struct cur_reg_rule);
3087 		qdf_mem_copy(pdev_reg_rules->reg_rules_6g_client[i],
3088 			     psoc_reg_rules->reg_rules_6g_client[i],
3089 			     reg_rule_len_6g_client);
3090 	}
3091 }
3092 #else /* CONFIG_BAND_6GHZ */
3093 static inline void reg_copy_6g_reg_rules(struct reg_rule_info *pdev_reg_rules,
3094 					 struct reg_rule_info *psoc_reg_rules)
3095 {
3096 }
3097 
3098 static inline void
3099 reg_append_6g_reg_rules_in_pdev(
3100 			struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj)
3101 {
3102 }
3103 #endif /* CONFIG_BAND_6GHZ */
3104 
3105 void reg_save_reg_rules_to_pdev(struct reg_rule_info *psoc_reg_rules,
3106 				struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj)
3107 {
3108 	uint32_t reg_rule_len;
3109 	struct reg_rule_info *pdev_reg_rules;
3110 
3111 	qdf_spin_lock_bh(&pdev_priv_obj->reg_rules_lock);
3112 
3113 	pdev_reg_rules = &pdev_priv_obj->reg_rules;
3114 	reg_reset_reg_rules(pdev_reg_rules);
3115 
3116 	pdev_reg_rules->num_of_reg_rules = psoc_reg_rules->num_of_reg_rules;
3117 
3118 	if (!reg_get_num_reg_rules(psoc_reg_rules, pdev_priv_obj)) {
3119 		qdf_spin_unlock_bh(&pdev_priv_obj->reg_rules_lock);
3120 		reg_err("no reg rules in psoc");
3121 		return;
3122 	}
3123 
3124 	reg_rule_len = pdev_reg_rules->num_of_reg_rules *
3125 		sizeof(struct cur_reg_rule);
3126 	qdf_mem_copy(pdev_reg_rules->reg_rules, psoc_reg_rules->reg_rules,
3127 		     reg_rule_len);
3128 
3129 	reg_copy_6g_reg_rules(pdev_reg_rules, psoc_reg_rules);
3130 	reg_append_6g_reg_rules_in_pdev(pdev_priv_obj);
3131 
3132 	qdf_mem_copy(pdev_reg_rules->alpha2, pdev_priv_obj->current_country,
3133 		     REG_ALPHA2_LEN + 1);
3134 	pdev_reg_rules->dfs_region = pdev_priv_obj->dfs_region;
3135 
3136 	qdf_spin_unlock_bh(&pdev_priv_obj->reg_rules_lock);
3137 }
3138 
3139 #ifdef CONFIG_REG_CLIENT
3140 /**
3141  * reg_set_pdev_fcc_rules - Set pdev fcc rules array
3142  * @psoc_priv_obj - PSOC private object pointer
3143  * @pdev_priv_obj - PDEV private object pointer
3144  *
3145  */
3146 
3147 static void reg_set_pdev_fcc_rules(
3148 		struct wlan_regulatory_psoc_priv_obj *psoc_priv_obj,
3149 		struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj)
3150 {
3151 	if (!psoc_priv_obj) {
3152 		reg_err("psoc priv obj is NULL");
3153 		return;
3154 	}
3155 
3156 	if (!IS_VALID_PDEV_REG_OBJ(pdev_priv_obj)) {
3157 		reg_err("reg pdev priv obj is NULL");
3158 		return;
3159 	}
3160 
3161 	qdf_mem_copy(pdev_priv_obj->fcc_rules_ptr,
3162 		     psoc_priv_obj->fcc_rules_ptr,
3163 		     sizeof(struct cur_fcc_rule) * MAX_NUM_FCC_RULES);
3164 }
3165 #else
3166 static inline void reg_set_pdev_fcc_rules(
3167 		struct wlan_regulatory_psoc_priv_obj *psoc_priv_obj,
3168 		struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj)
3169 {
3170 }
3171 #endif
3172 
3173 void reg_propagate_mas_chan_list_to_pdev(struct wlan_objmgr_psoc *psoc,
3174 					 void *object, void *arg)
3175 {
3176 	struct wlan_objmgr_pdev *pdev = (struct wlan_objmgr_pdev *)object;
3177 	struct wlan_regulatory_psoc_priv_obj *psoc_priv_obj;
3178 	struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj;
3179 	enum direction *dir = arg;
3180 	uint8_t pdev_id;
3181 	uint8_t phy_id;
3182 	struct wlan_lmac_if_reg_tx_ops *reg_tx_ops;
3183 	struct reg_rule_info *psoc_reg_rules;
3184 
3185 	psoc_priv_obj = (struct wlan_regulatory_psoc_priv_obj *)
3186 		wlan_objmgr_psoc_get_comp_private_obj(
3187 				psoc, WLAN_UMAC_COMP_REGULATORY);
3188 
3189 	if (!psoc_priv_obj) {
3190 		reg_err("psoc priv obj is NULL");
3191 		return;
3192 	}
3193 
3194 	pdev_priv_obj = reg_get_pdev_obj(pdev);
3195 
3196 	if (!IS_VALID_PDEV_REG_OBJ(pdev_priv_obj)) {
3197 		reg_err("reg pdev priv obj is NULL");
3198 		return;
3199 	}
3200 
3201 	pdev_id = wlan_objmgr_pdev_get_pdev_id(pdev);
3202 
3203 	reg_tx_ops = reg_get_psoc_tx_ops(psoc);
3204 	if (reg_tx_ops->get_phy_id_from_pdev_id)
3205 		reg_tx_ops->get_phy_id_from_pdev_id(psoc, pdev_id, &phy_id);
3206 	else
3207 		phy_id = pdev_id;
3208 
3209 	reg_set_pdev_fcc_rules(psoc_priv_obj, pdev_priv_obj);
3210 	reg_init_pdev_mas_chan_list(
3211 			pdev_priv_obj,
3212 			&psoc_priv_obj->mas_chan_params[phy_id]);
3213 	psoc_reg_rules = &psoc_priv_obj->mas_chan_params[phy_id].reg_rules;
3214 	reg_save_reg_rules_to_pdev(psoc_reg_rules, pdev_priv_obj);
3215 	reg_set_ap_pwr_type(pdev_priv_obj);
3216 	reg_init_pdev_super_chan_list(pdev_priv_obj);
3217 	pdev_priv_obj->chan_list_recvd =
3218 		psoc_priv_obj->chan_list_recvd[phy_id];
3219 
3220 	reg_init_indoor_channel_list(pdev);
3221 	reg_compute_indoor_list_on_cc_change(psoc, pdev);
3222 
3223 	reg_update_max_phymode_chwidth_for_pdev(pdev);
3224 	reg_update_channel_ranges(pdev);
3225 	reg_modify_chan_list_for_outdoor(pdev_priv_obj);
3226 	reg_compute_pdev_current_chan_list(pdev_priv_obj);
3227 
3228 	if (reg_tx_ops->fill_umac_legacy_chanlist) {
3229 		reg_tx_ops->fill_umac_legacy_chanlist(
3230 				pdev, pdev_priv_obj->cur_chan_list);
3231 	} else {
3232 		if (*dir == NORTHBOUND)
3233 			reg_send_scheduler_msg_nb(psoc, pdev);
3234 		else
3235 			reg_send_scheduler_msg_sb(psoc, pdev);
3236 	}
3237 }
3238 
3239 /**
3240  * reg_populate_49g_band_channels() - For all the valid 4.9GHz regdb channels
3241  * in the master channel list, find the regulatory rules and call
3242  * reg_fill_channel_info() to populate master channel list with txpower,
3243  * antennagain, BW info, etc.
3244  * @reg_rule_5g: Pointer to regulatory rule.
3245  * @num_5g_reg_rules: Number of regulatory rules.
3246  * @min_bw_5g: Minimum regulatory bandwidth.
3247  * @mas_chan_list: Pointer to the master channel list.
3248  */
3249 #ifdef CONFIG_49GHZ_CHAN
3250 static void
3251 reg_populate_49g_band_channels(struct cur_reg_rule *reg_rule_5g,
3252 			       uint32_t num_5g_reg_rules,
3253 			       uint16_t min_bw_5g,
3254 			       struct regulatory_channel *mas_chan_list)
3255 {
3256 	reg_populate_band_channels(MIN_49GHZ_CHANNEL,
3257 				   MAX_49GHZ_CHANNEL,
3258 				   reg_rule_5g,
3259 				   num_5g_reg_rules,
3260 				   min_bw_5g,
3261 				   mas_chan_list);
3262 }
3263 #else
3264 static void
3265 reg_populate_49g_band_channels(struct cur_reg_rule *reg_rule_5g,
3266 			       uint32_t num_5g_reg_rules,
3267 			       uint16_t min_bw_5g,
3268 			       struct regulatory_channel *mas_chan_list)
3269 {
3270 }
3271 #endif /* CONFIG_49GHZ_CHAN */
3272 
3273 #ifdef CONFIG_BAND_6GHZ
3274 /**
3275  * reg_populate_6g_band_channels() - For all the valid 6GHz regdb channels
3276  * in the master channel list, find the regulatory rules and call
3277  * reg_fill_channel_info() to populate master channel list with txpower,
3278  * antennagain, BW info, etc.
3279  * @reg_rule_5g: Pointer to regulatory rule.
3280  * @num_5g_reg_rules: Number of regulatory rules.
3281  * @min_bw_5g: Minimum regulatory bandwidth.
3282  * @mas_chan_list: Pointer to the master channel list.
3283  */
3284 static void
3285 reg_populate_6g_band_channels(struct cur_reg_rule *reg_rule_5g,
3286 			      uint32_t num_5g_reg_rules,
3287 			      uint16_t min_bw_5g,
3288 			      struct regulatory_channel *mas_chan_list)
3289 {
3290 	reg_populate_band_channels(MIN_6GHZ_CHANNEL,
3291 				   MAX_6GHZ_CHANNEL,
3292 				   reg_rule_5g,
3293 				   num_5g_reg_rules,
3294 				   min_bw_5g,
3295 				   mas_chan_list);
3296 }
3297 
3298 void
3299 reg_copy_from_super_chan_info_to_reg_channel(struct regulatory_channel *chan,
3300 					     const struct super_chan_info sc_entry,
3301 					     enum supported_6g_pwr_types
3302 					     in_6g_pwr_mode)
3303 {
3304 	if (in_6g_pwr_mode == REG_BEST_PWR_MODE)
3305 		in_6g_pwr_mode = sc_entry.best_power_mode;
3306 
3307 	if (reg_is_supp_pwr_mode_invalid(in_6g_pwr_mode))
3308 		return;
3309 
3310 	chan->state = sc_entry.state_arr[in_6g_pwr_mode];
3311 	chan->chan_flags = sc_entry.chan_flags_arr[in_6g_pwr_mode];
3312 	chan->tx_power = sc_entry.reg_chan_pwr[in_6g_pwr_mode].tx_power;
3313 	chan->min_bw = sc_entry.min_bw[in_6g_pwr_mode];
3314 	chan->max_bw = sc_entry.max_bw[in_6g_pwr_mode];
3315 	chan->psd_flag = sc_entry.reg_chan_pwr[in_6g_pwr_mode].psd_flag;
3316 	chan->psd_eirp = sc_entry.reg_chan_pwr[in_6g_pwr_mode].psd_eirp;
3317 }
3318 
3319 static QDF_STATUS
3320 reg_get_6g_pwrmode_chan_list(struct wlan_regulatory_pdev_priv_obj
3321 			     *pdev_priv_obj,
3322 			     struct regulatory_channel *chan_list,
3323 			     enum supported_6g_pwr_types in_6g_pwr_mode)
3324 {
3325 	uint8_t i;
3326 
3327 	/*
3328 	 * If 6GHz channel list is present, populate it with desired
3329 	 * power type
3330 	 */
3331 	if (!pdev_priv_obj->is_6g_channel_list_populated) {
3332 		reg_debug("6G channel list is empty");
3333 		return QDF_STATUS_SUCCESS;
3334 	}
3335 
3336 	/* Copy the regulatory_channel fields from super_chan_info */
3337 	for (i = 0; i < NUM_6GHZ_CHANNELS; i++)
3338 		reg_copy_from_super_chan_info_to_reg_channel(
3339 					&chan_list[i + MIN_6GHZ_CHANNEL],
3340 					pdev_priv_obj->super_chan_list[i],
3341 					in_6g_pwr_mode);
3342 
3343 	return QDF_STATUS_SUCCESS;
3344 }
3345 #else
3346 static void
3347 reg_populate_6g_band_channels(struct cur_reg_rule *reg_rule_5g,
3348 			      uint32_t num_5g_reg_rules,
3349 			      uint16_t min_bw_5g,
3350 			      struct regulatory_channel *mas_chan_list)
3351 {
3352 }
3353 
3354 static inline QDF_STATUS
3355 reg_get_6g_pwrmode_chan_list(struct wlan_regulatory_pdev_priv_obj
3356 			     *pdev_priv_obj,
3357 			     struct regulatory_channel *chan_list,
3358 			     enum supported_6g_pwr_types in_6g_pwr_mode)
3359 {
3360 	return QDF_STATUS_E_INVAL;
3361 }
3362 #endif /* CONFIG_BAND_6GHZ */
3363 
3364 QDF_STATUS reg_get_pwrmode_chan_list(struct wlan_objmgr_pdev *pdev,
3365 				     struct regulatory_channel *chan_list,
3366 				     enum supported_6g_pwr_types in_6g_pwr_mode)
3367 {
3368 	struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj;
3369 
3370 	if (!pdev) {
3371 		reg_err_rl("invalid pdev");
3372 		return QDF_STATUS_E_INVAL;
3373 	}
3374 
3375 	if (!chan_list) {
3376 		reg_err_rl("invalid chanlist");
3377 		return QDF_STATUS_E_INVAL;
3378 	}
3379 
3380 	pdev_priv_obj = reg_get_pdev_obj(pdev);
3381 
3382 	if (!IS_VALID_PDEV_REG_OBJ(pdev_priv_obj)) {
3383 		reg_err_rl("reg pdev priv obj is NULL");
3384 		return QDF_STATUS_E_INVAL;
3385 	}
3386 
3387 	/* Get the current channel list */
3388 	qdf_mem_copy(chan_list, pdev_priv_obj->cur_chan_list,
3389 		     NUM_CHANNELS * sizeof(struct regulatory_channel));
3390 
3391 	if (in_6g_pwr_mode == REG_CURRENT_PWR_MODE)
3392 		return QDF_STATUS_SUCCESS;
3393 
3394 	return reg_get_6g_pwrmode_chan_list(pdev_priv_obj, chan_list,
3395 					    in_6g_pwr_mode);
3396 }
3397 
3398 #ifdef CONFIG_REG_CLIENT
3399 /**
3400  * reg_send_ctl_info() - Send CTL info to firmware when regdb is not offloaded
3401  * @soc_reg: soc private object for regulatory
3402  * @regulatory_info: regulatory info
3403  * @tx_ops: send operations for regulatory component
3404  *
3405  * Return: QDF_STATUS
3406  */
3407 static QDF_STATUS
3408 reg_send_ctl_info(struct wlan_regulatory_psoc_priv_obj *soc_reg,
3409 		  struct cur_regulatory_info *regulatory_info,
3410 		  struct wlan_lmac_if_reg_tx_ops *tx_ops)
3411 {
3412 	struct wlan_objmgr_psoc *psoc = regulatory_info->psoc;
3413 	struct reg_ctl_params params = {0};
3414 	QDF_STATUS status;
3415 	uint16_t regd_index;
3416 	uint32_t index_2g, index_5g;
3417 
3418 	if (soc_reg->offload_enabled)
3419 		return QDF_STATUS_SUCCESS;
3420 
3421 	if (!tx_ops || !tx_ops->send_ctl_info) {
3422 		reg_err("No regulatory tx_ops");
3423 		return QDF_STATUS_E_FAULT;
3424 	}
3425 
3426 	status = reg_get_rdpair_from_regdmn_id(regulatory_info->reg_dmn_pair,
3427 					       &regd_index);
3428 	if (QDF_IS_STATUS_ERROR(status)) {
3429 		reg_err("Failed to get regdomain index for regdomain pair: %x",
3430 			regulatory_info->reg_dmn_pair);
3431 		return status;
3432 	}
3433 
3434 	index_2g = g_reg_dmn_pairs[regd_index].dmn_id_2g;
3435 	index_5g = g_reg_dmn_pairs[regd_index].dmn_id_5g;
3436 	params.ctl_2g = regdomains_2g[index_2g].ctl_val;
3437 	params.ctl_5g = regdomains_5g[index_5g].ctl_val;
3438 	params.regd_2g = reg_2g_sub_dmn_code[index_2g];
3439 	params.regd_5g = reg_5g_sub_dmn_code[index_5g];
3440 
3441 	if (reg_is_world_ctry_code(regulatory_info->reg_dmn_pair))
3442 		params.regd = regulatory_info->reg_dmn_pair;
3443 	else
3444 		params.regd = regulatory_info->ctry_code | COUNTRY_ERD_FLAG;
3445 
3446 	reg_debug("regdomain pair = %u, regdomain index = %u",
3447 		  regulatory_info->reg_dmn_pair, regd_index);
3448 	reg_debug("index_2g = %u, index_5g = %u, ctl_2g = %x, ctl_5g = %x",
3449 		  index_2g, index_5g, params.ctl_2g, params.ctl_5g);
3450 	reg_debug("regd_2g = %x, regd_5g = %x, regd = %x",
3451 		  params.regd_2g, params.regd_5g, params.regd);
3452 
3453 	status = tx_ops->send_ctl_info(psoc, &params);
3454 	if (QDF_IS_STATUS_ERROR(status))
3455 		reg_err("Failed to send CTL info to firmware");
3456 
3457 	return status;
3458 }
3459 #else
3460 static QDF_STATUS
3461 reg_send_ctl_info(struct wlan_regulatory_psoc_priv_obj *soc_reg,
3462 		  struct cur_regulatory_info *regulatory_info,
3463 		  struct wlan_lmac_if_reg_tx_ops *tx_ops)
3464 {
3465 	return QDF_STATUS_SUCCESS;
3466 }
3467 #endif
3468 
3469 /**
3470  * reg_soc_vars_reset_on_failure() - Reset the PSOC private object variables
3471  *	when there is a failure
3472  * @status_code: status code of CC setting event
3473  * @soc_reg: soc private object for regulatory
3474  * @tx_ops: send operations for regulatory component
3475  * @psoc: pointer to PSOC object
3476  * @dbg_id: object manager reference debug ID
3477  * @phy_id: physical ID
3478  *
3479  * Return: QDF_STATUS
3480  */
3481 static QDF_STATUS
3482 reg_soc_vars_reset_on_failure(enum cc_setting_code status_code,
3483 			      struct wlan_regulatory_psoc_priv_obj *soc_reg,
3484 			      struct wlan_lmac_if_reg_tx_ops *tx_ops,
3485 			      struct wlan_objmgr_psoc *psoc,
3486 			      wlan_objmgr_ref_dbgid dbg_id,
3487 			      uint8_t phy_id)
3488 {
3489 	struct wlan_objmgr_pdev *pdev;
3490 
3491 	if (status_code != REG_SET_CC_STATUS_PASS) {
3492 		reg_err("Set country code failed, status code %d",
3493 			status_code);
3494 
3495 		pdev = wlan_objmgr_get_pdev_by_id(psoc, phy_id, dbg_id);
3496 		if (!pdev) {
3497 			reg_err("pdev is NULL");
3498 			return QDF_STATUS_E_FAILURE;
3499 		}
3500 
3501 		if (tx_ops->set_country_failed)
3502 			tx_ops->set_country_failed(pdev);
3503 
3504 		wlan_objmgr_pdev_release_ref(pdev, dbg_id);
3505 
3506 		if (status_code != REG_CURRENT_ALPHA2_NOT_FOUND)
3507 			return QDF_STATUS_E_FAILURE;
3508 
3509 		soc_reg->new_user_ctry_pending[phy_id] = false;
3510 		soc_reg->new_11d_ctry_pending[phy_id] = false;
3511 		soc_reg->world_country_pending[phy_id] = true;
3512 	}
3513 
3514 	return QDF_STATUS_SUCCESS;
3515 }
3516 
3517 static void reg_init_legacy_master_chan(struct regulatory_channel *dst_list,
3518 				struct wlan_regulatory_psoc_priv_obj *soc_reg)
3519 {
3520 	reg_init_chan(dst_list, 0, NUM_CHANNELS - 1, 0, soc_reg);
3521 }
3522 
3523 #ifdef CONFIG_REG_CLIENT
3524 /**
3525  * reg_set_psoc_fcc_rules - Set PSOC fcc rules array
3526  * @soc_reg - PSOC private object pointer
3527  * @regulat_info - Regulatory info pointer
3528  *
3529  * Return - QDF_STATUS
3530  */
3531 static QDF_STATUS reg_set_psoc_fcc_rules(
3532 		struct wlan_regulatory_psoc_priv_obj *soc_reg,
3533 		struct cur_regulatory_info *regulat_info)
3534 {
3535 	if (!IS_VALID_PSOC_REG_OBJ(soc_reg)) {
3536 		reg_err("psoc reg component is NULL");
3537 		return QDF_STATUS_E_FAILURE;
3538 	}
3539 
3540 	if (regulat_info->num_fcc_rules)
3541 		qdf_mem_copy(soc_reg->fcc_rules_ptr,
3542 			     regulat_info->fcc_rules_ptr,
3543 			     sizeof(struct cur_fcc_rule) *
3544 			     regulat_info->num_fcc_rules);
3545 
3546 	return QDF_STATUS_SUCCESS;
3547 }
3548 #else
3549 static inline QDF_STATUS reg_set_psoc_fcc_rules(
3550 		struct wlan_regulatory_psoc_priv_obj *soc_reg,
3551 		struct cur_regulatory_info *regulat_info)
3552 {
3553 	return QDF_STATUS_SUCCESS;
3554 }
3555 #endif
3556 
3557 #ifdef CONFIG_BAND_6GHZ
3558 static void reg_init_2g_5g_master_chan(struct regulatory_channel *dst_list,
3559 				struct wlan_regulatory_psoc_priv_obj *soc_reg)
3560 {
3561 	reg_init_chan(dst_list, 0, MAX_5GHZ_CHANNEL, 0, soc_reg);
3562 }
3563 
3564 /**
3565  * reg_store_regulatory_ext_info_to_socpriv() - Copy ext info from regulatory
3566  *	to regulatory PSOC private obj
3567  * @soc_reg: soc private object for regulatory
3568  * @regulat_info: regulatory info from CC event
3569  * @phy_id: physical ID
3570  *
3571  * Return: none
3572  */
3573 static void reg_store_regulatory_ext_info_to_socpriv(
3574 				struct wlan_regulatory_psoc_priv_obj *soc_reg,
3575 				struct cur_regulatory_info *regulat_info,
3576 				uint8_t phy_id)
3577 {
3578 	uint32_t i;
3579 
3580 	soc_reg->num_phy = regulat_info->num_phy;
3581 	soc_reg->mas_chan_params[phy_id].phybitmap = regulat_info->phybitmap;
3582 	soc_reg->mas_chan_params[phy_id].dfs_region = regulat_info->dfs_region;
3583 	soc_reg->mas_chan_params[phy_id].ctry_code = regulat_info->ctry_code;
3584 	soc_reg->mas_chan_params[phy_id].reg_dmn_pair =
3585 		regulat_info->reg_dmn_pair;
3586 	soc_reg->mas_chan_params[phy_id].reg_6g_superid =
3587 		regulat_info->domain_code_6g_super_id;
3588 	soc_reg->mas_chan_params[phy_id].max_bw_5g = regulat_info->max_bw_5g;
3589 	qdf_mem_copy(soc_reg->mas_chan_params[phy_id].current_country,
3590 		     regulat_info->alpha2,
3591 		     REG_ALPHA2_LEN + 1);
3592 	qdf_mem_copy(soc_reg->cur_country,
3593 		     regulat_info->alpha2,
3594 		     REG_ALPHA2_LEN + 1);
3595 	reg_debug("set cur_country %.2s", soc_reg->cur_country);
3596 
3597 	soc_reg->mas_chan_params[phy_id].ap_pwr_type = REG_INDOOR_AP;
3598 	soc_reg->mas_chan_params[phy_id].client_type =
3599 					regulat_info->client_type;
3600 	soc_reg->mas_chan_params[phy_id].rnr_tpe_usable =
3601 					regulat_info->rnr_tpe_usable;
3602 	soc_reg->mas_chan_params[phy_id].unspecified_ap_usable =
3603 					regulat_info->unspecified_ap_usable;
3604 	soc_reg->mas_chan_params[phy_id].reg_6g_thresh_priority_freq =
3605 				regulat_info->reg_6g_thresh_priority_freq;
3606 
3607 	for (i = 0; i < REG_CURRENT_MAX_AP_TYPE; i++) {
3608 		soc_reg->domain_code_6g_ap[i] =
3609 			regulat_info->domain_code_6g_ap[i];
3610 
3611 		soc_reg->mas_chan_params[phy_id].
3612 			is_6g_channel_list_populated = true;
3613 
3614 		qdf_mem_copy(soc_reg->domain_code_6g_client[i],
3615 			     regulat_info->domain_code_6g_client[i],
3616 			     REG_MAX_CLIENT_TYPE * sizeof(uint8_t));
3617 	}
3618 }
3619 
3620 #ifdef WLAN_FEATURE_11BE
3621 static bool
3622 reg_is_bonded_ch_subset_of_regrule(struct cur_reg_rule *cur_rule_ptr,
3623 				   const struct bonded_channel_freq
3624 				   *bonded_ch_ptr)
3625 {
3626 	if (bonded_ch_ptr->start_freq >= cur_rule_ptr->start_freq &&
3627 	    bonded_ch_ptr->end_freq <= cur_rule_ptr->end_freq)
3628 		return true;
3629 
3630 	return false;
3631 }
3632 #endif
3633 
3634 /**
3635  * reg_is_5g_240chan_in_rule() - Determine if the given reg rule supports
3636  * 5g 240MHZ chan [100 - 144] and the BW of the rule is greater than 160MHZ.
3637  * @cur_rule_ptr: Pointer to struct cur_reg_rule
3638  * @bonded_ch_ptr: Pointer to  const struct bonded_channel_freq
3639  *
3640  * Return -True if 240 chan rule is found, false otherwise.
3641  */
3642 #ifdef WLAN_FEATURE_11BE
3643 static bool
3644 reg_is_5g_240chan_in_rule(struct cur_reg_rule *cur_rule_ptr,
3645 			  const struct bonded_channel_freq *bonded_ch_ptr)
3646 {
3647 	if (!bonded_ch_ptr)
3648 		return false;
3649 
3650 	if (reg_is_bonded_ch_subset_of_regrule(cur_rule_ptr, bonded_ch_ptr) &&
3651 	    cur_rule_ptr->max_bw > BW_160_MHZ)
3652 		return true;
3653 
3654 	return false;
3655 }
3656 #endif
3657 
3658 /**
3659  * reg_is_chip_cc_11be_cap() - Determine if country supports a max BW
3660  * greater than 160MHZ and if chip is 11BE capable.
3661  * @psoc: Pointer to struct wlan_objmgr_psoc
3662  * @phy_id: Phy-id
3663  * @max_cc_bw: Maximum 5g BW supported by the country
3664  *
3665  * Return - True if cc_max is greater than 160MHZ and chip is 11BE cap,
3666  * false otherwise.
3667  */
3668 #ifdef WLAN_FEATURE_11BE
3669 static bool reg_is_chip_cc_11be_cap(struct wlan_objmgr_psoc *psoc,
3670 				    uint16_t phy_id,
3671 				    uint16_t max_cc_bw)
3672 {
3673 	struct wlan_lmac_if_reg_tx_ops *tx_ops;
3674 
3675 	tx_ops = reg_get_psoc_tx_ops(psoc);
3676 	if (!tx_ops)
3677 		return false;
3678 
3679 	if (max_cc_bw > BW_160_MHZ && tx_ops->is_chip_11be(psoc, phy_id))
3680 		return true;
3681 
3682 	return false;
3683 }
3684 #endif
3685 
3686 /**
3687  * reg_modify_max_bw_for_240mhz_5g_chans() - Manually update the bandwidh
3688  * of the 240MHz channels in 5GHz band [IEEE channels 100 - 144 support 240MHz
3689  * bandwidth using puncturing; 240MHz = 320MHz - 80Mhz(punctured)].
3690  * The max bandwidth for these channels should be 320MHz.
3691  *
3692  * Modify reg rule BW of 100 - 144 channels to 320 if
3693  * a) Chip supports 11BE
3694  * b) Country supports 320MHZ BW.
3695  * c) Reg rule BW advertised by FW is 240MHZ.
3696  * d) Channel is between 5500 and 5720.
3697  *
3698  * @regulat_info: Pointer to struct cur_regulatory_info
3699  * @reg_rule_5g: Pointer to  struct cur_reg_rule
3700  */
3701 #ifdef WLAN_FEATURE_11BE
3702 static void
3703 reg_modify_max_bw_for_240mhz_5g_chans(struct cur_regulatory_info *regulat_info,
3704 				      struct cur_reg_rule *reg_rule_5g)
3705 
3706 {
3707 #define FREQ_5500_MHZ  5500
3708 
3709 	uint16_t num_5g_reg_rules = regulat_info->num_5g_reg_rules;
3710 	uint16_t rule_num;
3711 	struct cur_reg_rule *cur_rule_ptr;
3712 	const struct bonded_channel_freq *bonded_ch_ptr;
3713 
3714 	bonded_ch_ptr = reg_get_bonded_chan_entry(FREQ_5500_MHZ,
3715 						  CH_WIDTH_320MHZ, 0);
3716 	if (!reg_is_chip_cc_11be_cap(regulat_info->psoc,
3717 				     regulat_info->phy_id,
3718 				     regulat_info->max_bw_5g))
3719 		return;
3720 
3721 	for (rule_num = 0, cur_rule_ptr = reg_rule_5g;
3722 	     rule_num < num_5g_reg_rules; cur_rule_ptr++, rule_num++) {
3723 		if (reg_is_5g_240chan_in_rule(cur_rule_ptr, bonded_ch_ptr)) {
3724 			cur_rule_ptr->max_bw = BW_320_MHZ;
3725 			break;
3726 		}
3727 	}
3728 }
3729 #else
3730 static void
3731 reg_modify_max_bw_for_240mhz_5g_chans(struct cur_regulatory_info *regulat_info,
3732 				      struct cur_reg_rule *reg_rule_5g)
3733 {
3734 }
3735 #endif
3736 
3737 /**
3738  * reg_is_pwrmode_not_required - Check if given power mode is needed.
3739  * @soc_reg: soc private object for regulatory
3740  * @pwr_type: input AP power type
3741  *
3742  * Return: True if deployemnt is outdoor and power type is LPI, else false.
3743  */
3744 #if !defined(CONFIG_REG_CLIENT) && defined(CONFIG_AFC_SUPPORT)
3745 static bool reg_is_pwrmode_not_required(
3746 				struct wlan_regulatory_psoc_priv_obj *soc_reg,
3747 				enum reg_6g_ap_type pwr_type)
3748 {
3749 	/*
3750 	 * In outdoor deployment, LPI(AP INDDOR and  CLI INDOOR)
3751 	 * rules are not needed.
3752 	 */
3753 	return ((soc_reg->reg_afc_dev_type == AFC_DEPLOYMENT_OUTDOOR) &&
3754 		(pwr_type == REG_INDOOR_AP));
3755 }
3756 #else
3757 static bool reg_is_pwrmode_not_required(
3758 				struct wlan_regulatory_psoc_priv_obj *soc_reg,
3759 				enum reg_6g_ap_type pwr_mode)
3760 {
3761 	return false;
3762 }
3763 #endif
3764 
3765 /**
3766  * reg_fill_master_channels() - Fill the master channel lists based on the
3767  *	regulatory rules
3768  * @regulat_info: regulatory info
3769  * @reg_rules: regulatory rules
3770  * @client_mobility_type: client mobility type
3771  * @mas_chan_list_2g_5g: master chan list to fill with 2GHz and 5GHz channels
3772  * @mas_chan_list_6g_ap: master AP chan list to fill with 6GHz channels
3773  * @mas_chan_list_6g_client: master client chan list to fill with 6GHz channels
3774  * @soc_reg: soc private object for regulatory
3775  *
3776  * Return: QDF_STATUS
3777  */
3778 static QDF_STATUS
3779 reg_fill_master_channels(struct cur_regulatory_info *regulat_info,
3780 			 struct reg_rule_info *reg_rules,
3781 			 enum reg_6g_client_type client_mobility_type,
3782 			 struct regulatory_channel *mas_chan_list_2g_5g,
3783 	struct regulatory_channel *mas_chan_list_6g_ap[REG_CURRENT_MAX_AP_TYPE],
3784 	struct regulatory_channel *mas_chan_list_6g_client
3785 		[REG_CURRENT_MAX_AP_TYPE][REG_MAX_CLIENT_TYPE],
3786 	struct wlan_regulatory_psoc_priv_obj *soc_reg)
3787 {
3788 	uint32_t i, j, k, curr_reg_rule_location;
3789 	uint32_t num_2g_reg_rules, num_5g_reg_rules;
3790 	uint32_t num_6g_reg_rules_ap[REG_CURRENT_MAX_AP_TYPE];
3791 	uint32_t *num_6g_reg_rules_client[REG_CURRENT_MAX_AP_TYPE];
3792 	struct cur_reg_rule *reg_rule_2g, *reg_rule_5g,
3793 		*reg_rule_6g_ap[REG_CURRENT_MAX_AP_TYPE],
3794 		**reg_rule_6g_client[REG_CURRENT_MAX_AP_TYPE];
3795 	uint32_t min_bw_2g, max_bw_2g, min_bw_5g, max_bw_5g,
3796 		min_bw_6g_ap[REG_CURRENT_MAX_AP_TYPE],
3797 		max_bw_6g_ap[REG_CURRENT_MAX_AP_TYPE],
3798 		*min_bw_6g_client[REG_CURRENT_MAX_AP_TYPE],
3799 		*max_bw_6g_client[REG_CURRENT_MAX_AP_TYPE];
3800 
3801 	min_bw_2g = regulat_info->min_bw_2g;
3802 	max_bw_2g = regulat_info->max_bw_2g;
3803 	reg_rule_2g = regulat_info->reg_rules_2g_ptr;
3804 	num_2g_reg_rules = regulat_info->num_2g_reg_rules;
3805 	reg_update_max_bw_per_rule(num_2g_reg_rules, reg_rule_2g, max_bw_2g);
3806 
3807 	min_bw_5g = regulat_info->min_bw_5g;
3808 	max_bw_5g = regulat_info->max_bw_5g;
3809 	reg_rule_5g = regulat_info->reg_rules_5g_ptr;
3810 	num_5g_reg_rules = regulat_info->num_5g_reg_rules;
3811 	reg_update_max_bw_per_rule(num_5g_reg_rules, reg_rule_5g, max_bw_5g);
3812 
3813 	for (i = 0; i < REG_CURRENT_MAX_AP_TYPE; i++) {
3814 		min_bw_6g_ap[i] = regulat_info->min_bw_6g_ap[i];
3815 		max_bw_6g_ap[i] = regulat_info->max_bw_6g_ap[i];
3816 		reg_rule_6g_ap[i] = regulat_info->reg_rules_6g_ap_ptr[i];
3817 		num_6g_reg_rules_ap[i] = regulat_info->num_6g_reg_rules_ap[i];
3818 		reg_update_max_bw_per_rule(num_6g_reg_rules_ap[i],
3819 					   reg_rule_6g_ap[i], max_bw_6g_ap[i]);
3820 	}
3821 
3822 	for (j = 0; j < REG_CURRENT_MAX_AP_TYPE; j++) {
3823 		min_bw_6g_client[j] = regulat_info->min_bw_6g_client[j];
3824 		max_bw_6g_client[j] = regulat_info->max_bw_6g_client[j];
3825 		reg_rule_6g_client[j] =
3826 			regulat_info->reg_rules_6g_client_ptr[j];
3827 		num_6g_reg_rules_client[j] =
3828 			regulat_info->num_6g_reg_rules_client[j];
3829 		for (k = 0; k < REG_MAX_CLIENT_TYPE; k++) {
3830 			reg_update_max_bw_per_rule(
3831 						num_6g_reg_rules_client[j][k],
3832 						reg_rule_6g_client[j][k],
3833 						max_bw_6g_client[j][k]);
3834 		}
3835 	}
3836 
3837 	reg_reset_reg_rules(reg_rules);
3838 
3839 	reg_rules->num_of_reg_rules = num_5g_reg_rules + num_2g_reg_rules;
3840 
3841 	for (i = 0; i < REG_CURRENT_MAX_AP_TYPE; i++) {
3842 		reg_rules->num_of_6g_ap_reg_rules[i] = num_6g_reg_rules_ap[i];
3843 		if (num_6g_reg_rules_ap[i] > MAX_6G_REG_RULES) {
3844 			reg_err("number of reg rules for 6g ap exceeds limit");
3845 			return QDF_STATUS_E_FAILURE;
3846 		}
3847 
3848 		reg_rules->num_of_6g_client_reg_rules[i] =
3849 			num_6g_reg_rules_client[i][client_mobility_type];
3850 		for (j = 0; j < REG_MAX_CLIENT_TYPE; j++) {
3851 			if (num_6g_reg_rules_client[i][j] > MAX_6G_REG_RULES) {
3852 				reg_err("number of reg rules for 6g client exceeds limit");
3853 				return QDF_STATUS_E_FAILURE;
3854 			}
3855 		}
3856 	}
3857 
3858 	if (reg_rules->num_of_reg_rules > MAX_REG_RULES) {
3859 		reg_err("number of reg rules exceeds limit");
3860 		return QDF_STATUS_E_FAILURE;
3861 	}
3862 
3863 	if (reg_rules->num_of_reg_rules) {
3864 		if (num_2g_reg_rules)
3865 			qdf_mem_copy(reg_rules->reg_rules,
3866 				     reg_rule_2g, num_2g_reg_rules *
3867 				     sizeof(struct cur_reg_rule));
3868 		curr_reg_rule_location = num_2g_reg_rules;
3869 		if (num_5g_reg_rules) {
3870 			qdf_mem_copy(reg_rules->reg_rules +
3871 				     curr_reg_rule_location, reg_rule_5g,
3872 				     num_5g_reg_rules *
3873 				     sizeof(struct cur_reg_rule));
3874 			reg_modify_max_bw_for_240mhz_5g_chans(regulat_info,
3875 							      reg_rule_5g);
3876 		}
3877 	}
3878 
3879 	for (i = 0; i < REG_CURRENT_MAX_AP_TYPE; i++) {
3880 		if (num_6g_reg_rules_ap[i])
3881 			qdf_mem_copy(reg_rules->reg_rules_6g_ap[i],
3882 				     reg_rule_6g_ap[i],
3883 				     num_6g_reg_rules_ap[i] *
3884 				     sizeof(struct cur_reg_rule));
3885 
3886 		if (num_6g_reg_rules_client[i][client_mobility_type])
3887 			qdf_mem_copy(reg_rules->reg_rules_6g_client[i],
3888 				reg_rule_6g_client[i][client_mobility_type],
3889 				num_6g_reg_rules_client[i]
3890 				[client_mobility_type] *
3891 				sizeof(struct cur_reg_rule));
3892 	}
3893 
3894 
3895 	if (num_5g_reg_rules)
3896 		reg_do_auto_bw_correction(num_5g_reg_rules,
3897 					  reg_rule_5g, max_bw_5g);
3898 
3899 	if (num_2g_reg_rules)
3900 		reg_populate_band_channels(MIN_24GHZ_CHANNEL, MAX_24GHZ_CHANNEL,
3901 					   reg_rule_2g, num_2g_reg_rules,
3902 					   min_bw_2g, mas_chan_list_2g_5g);
3903 
3904 	if (num_5g_reg_rules) {
3905 		reg_populate_band_channels(MIN_5GHZ_CHANNEL, MAX_5GHZ_CHANNEL,
3906 					   reg_rule_5g, num_5g_reg_rules,
3907 					   min_bw_5g, mas_chan_list_2g_5g);
3908 		reg_populate_49g_band_channels(reg_rule_5g,
3909 					       num_5g_reg_rules,
3910 					       min_bw_5g,
3911 					       mas_chan_list_2g_5g);
3912 	}
3913 
3914 	for (i = 0; i < REG_CURRENT_MAX_AP_TYPE; i++) {
3915 		if (reg_is_pwrmode_not_required(soc_reg, i))
3916 			continue;
3917 
3918 		if (num_6g_reg_rules_ap[i])
3919 			reg_populate_band_channels_ext_for_6g(0,
3920 							NUM_6GHZ_CHANNELS - 1,
3921 							reg_rule_6g_ap[i],
3922 							num_6g_reg_rules_ap[i],
3923 							min_bw_6g_ap[i],
3924 							mas_chan_list_6g_ap[i]);
3925 
3926 		for (j = 0; j < REG_MAX_CLIENT_TYPE; j++) {
3927 			if (num_6g_reg_rules_client[i][j])
3928 				reg_populate_band_channels_ext_for_6g(0,
3929 						NUM_6GHZ_CHANNELS - 1,
3930 						reg_rule_6g_client[i][j],
3931 						num_6g_reg_rules_client[i][j],
3932 						min_bw_6g_client[i][j],
3933 						mas_chan_list_6g_client[i][j]);
3934 		}
3935 	}
3936 
3937 	return QDF_STATUS_SUCCESS;
3938 }
3939 
3940 /**
3941  * reg_set_socpriv_vars() - Set the regulatory PSOC variables based on
3942  *	pending country status
3943  * @soc_reg: regulatory PSOC private object
3944  * @regulat_info: regulatory info
3945  * @psoc: pointer to PSOC object
3946  * @phy_id: physical ID
3947  *
3948  * Return: none
3949  */
3950 static void reg_set_socpriv_vars(struct wlan_regulatory_psoc_priv_obj *soc_reg,
3951 				 struct cur_regulatory_info *regulat_info,
3952 				 struct wlan_objmgr_psoc *psoc,
3953 				 uint8_t phy_id)
3954 {
3955 	soc_reg->chan_list_recvd[phy_id] = true;
3956 
3957 	if (soc_reg->new_user_ctry_pending[phy_id]) {
3958 		soc_reg->new_user_ctry_pending[phy_id] = false;
3959 		soc_reg->cc_src = SOURCE_USERSPACE;
3960 		soc_reg->user_ctry_set = true;
3961 		reg_debug("new user country is set");
3962 		reg_run_11d_state_machine(psoc);
3963 	} else if (soc_reg->new_init_ctry_pending[phy_id]) {
3964 		soc_reg->new_init_ctry_pending[phy_id] = false;
3965 		soc_reg->cc_src = SOURCE_USERSPACE;
3966 		reg_debug("new init country is set");
3967 	} else if (soc_reg->new_11d_ctry_pending[phy_id]) {
3968 		soc_reg->new_11d_ctry_pending[phy_id] = false;
3969 		soc_reg->cc_src = SOURCE_11D;
3970 		soc_reg->user_ctry_set = false;
3971 		reg_run_11d_state_machine(psoc);
3972 	} else if (soc_reg->world_country_pending[phy_id]) {
3973 		soc_reg->world_country_pending[phy_id] = false;
3974 		soc_reg->cc_src = SOURCE_CORE;
3975 		soc_reg->user_ctry_set = false;
3976 		reg_run_11d_state_machine(psoc);
3977 	} else {
3978 		if (soc_reg->cc_src == SOURCE_UNKNOWN &&
3979 		    soc_reg->num_phy == phy_id + 1)
3980 			soc_reg->cc_src = SOURCE_DRIVER;
3981 
3982 		qdf_mem_copy(soc_reg->mas_chan_params[phy_id].default_country,
3983 			     regulat_info->alpha2,
3984 			     REG_ALPHA2_LEN + 1);
3985 
3986 		soc_reg->mas_chan_params[phy_id].def_country_code =
3987 			regulat_info->ctry_code;
3988 		soc_reg->mas_chan_params[phy_id].def_region_domain =
3989 			regulat_info->reg_dmn_pair;
3990 
3991 		if (soc_reg->cc_src == SOURCE_DRIVER) {
3992 			qdf_mem_copy(soc_reg->def_country,
3993 				     regulat_info->alpha2,
3994 				     REG_ALPHA2_LEN + 1);
3995 
3996 			soc_reg->def_country_code = regulat_info->ctry_code;
3997 			soc_reg->def_region_domain =
3998 				regulat_info->reg_dmn_pair;
3999 
4000 			if (reg_is_world_alpha2(regulat_info->alpha2)) {
4001 				soc_reg->cc_src = SOURCE_CORE;
4002 				reg_run_11d_state_machine(psoc);
4003 			}
4004 		}
4005 	}
4006 }
4007 
4008 QDF_STATUS reg_process_master_chan_list_ext(
4009 		struct cur_regulatory_info *regulat_info)
4010 {
4011 	struct wlan_regulatory_psoc_priv_obj *soc_reg;
4012 	uint32_t i, j;
4013 	struct regulatory_channel *mas_chan_list_2g_5g,
4014 		*mas_chan_list_6g_ap[REG_CURRENT_MAX_AP_TYPE],
4015 		*mas_chan_list_6g_client[REG_CURRENT_MAX_AP_TYPE]
4016 							[REG_MAX_CLIENT_TYPE];
4017 	struct wlan_objmgr_psoc *psoc;
4018 	wlan_objmgr_ref_dbgid dbg_id;
4019 	enum direction dir;
4020 	uint8_t phy_id;
4021 	uint8_t pdev_id;
4022 	struct wlan_objmgr_pdev *pdev;
4023 	struct wlan_lmac_if_reg_tx_ops *tx_ops;
4024 	QDF_STATUS status;
4025 	struct mas_chan_params *this_mchan_params;
4026 
4027 	psoc = regulat_info->psoc;
4028 	soc_reg = reg_get_psoc_obj(psoc);
4029 
4030 	if (!IS_VALID_PSOC_REG_OBJ(soc_reg)) {
4031 		reg_err("psoc reg component is NULL");
4032 		return QDF_STATUS_E_FAILURE;
4033 	}
4034 
4035 	tx_ops = reg_get_psoc_tx_ops(psoc);
4036 	phy_id = regulat_info->phy_id;
4037 
4038 	if (tx_ops->get_pdev_id_from_phy_id)
4039 		tx_ops->get_pdev_id_from_phy_id(psoc, phy_id, &pdev_id);
4040 	else
4041 		pdev_id = phy_id;
4042 
4043 	if (reg_ignore_default_country(soc_reg, regulat_info)) {
4044 		status = reg_set_curr_country(soc_reg, regulat_info, tx_ops);
4045 		if (QDF_IS_STATUS_SUCCESS(status)) {
4046 			reg_debug("WLAN restart - Ignore default CC for phy_id: %u",
4047 				  phy_id);
4048 			return QDF_STATUS_SUCCESS;
4049 		}
4050 	}
4051 
4052 	reg_debug("process reg master chan extended list");
4053 
4054 	if (soc_reg->offload_enabled) {
4055 		dbg_id = WLAN_REGULATORY_NB_ID;
4056 		dir = NORTHBOUND;
4057 	} else {
4058 		dbg_id = WLAN_REGULATORY_SB_ID;
4059 		dir = SOUTHBOUND;
4060 	}
4061 
4062 	status = reg_soc_vars_reset_on_failure(regulat_info->status_code,
4063 					       soc_reg, tx_ops, psoc, dbg_id,
4064 					       phy_id);
4065 
4066 	if (!QDF_IS_STATUS_SUCCESS(status))
4067 		return status;
4068 
4069 	this_mchan_params = &soc_reg->mas_chan_params[phy_id];
4070 	mas_chan_list_2g_5g = this_mchan_params->mas_chan_list;
4071 
4072 	for (i = 0; i < REG_CURRENT_MAX_AP_TYPE; i++) {
4073 		mas_chan_list_6g_ap[i] =
4074 			this_mchan_params->mas_chan_list_6g_ap[i];
4075 
4076 		for (j = 0; j < REG_MAX_CLIENT_TYPE; j++)
4077 			mas_chan_list_6g_client[i][j] =
4078 				this_mchan_params->mas_chan_list_6g_client[i][j];
4079 	}
4080 
4081 	reg_init_channel_map(regulat_info->dfs_region);
4082 
4083 	reg_init_2g_5g_master_chan(mas_chan_list_2g_5g, soc_reg);
4084 
4085 	for (i = 0; i < REG_CURRENT_MAX_AP_TYPE; i++) {
4086 		reg_init_6ghz_master_chan(mas_chan_list_6g_ap[i], soc_reg);
4087 		for (j = 0; j < REG_MAX_CLIENT_TYPE; j++)
4088 			reg_init_6ghz_master_chan(mas_chan_list_6g_client[i][j],
4089 						  soc_reg);
4090 	}
4091 
4092 	reg_store_regulatory_ext_info_to_socpriv(soc_reg, regulat_info, phy_id);
4093 
4094 	status = reg_fill_master_channels(regulat_info,
4095 					  &this_mchan_params->reg_rules,
4096 					  this_mchan_params->client_type,
4097 					  mas_chan_list_2g_5g,
4098 					  mas_chan_list_6g_ap,
4099 					  mas_chan_list_6g_client,
4100 					  soc_reg);
4101 	if (!QDF_IS_STATUS_SUCCESS(status))
4102 		return status;
4103 
4104 	status = reg_send_ctl_info(soc_reg, regulat_info, tx_ops);
4105 	if (!QDF_IS_STATUS_SUCCESS(status))
4106 		return status;
4107 
4108 	reg_set_socpriv_vars(soc_reg, regulat_info, psoc, phy_id);
4109 
4110 	status = reg_set_psoc_fcc_rules(soc_reg, regulat_info);
4111 	if (!QDF_IS_STATUS_SUCCESS(status))
4112 		return status;
4113 
4114 	pdev = wlan_objmgr_get_pdev_by_id(psoc, pdev_id, dbg_id);
4115 	if (pdev) {
4116 		reg_propagate_mas_chan_list_to_pdev(psoc, pdev, &dir);
4117 		wlan_objmgr_pdev_release_ref(pdev, dbg_id);
4118 	}
4119 
4120 	return QDF_STATUS_SUCCESS;
4121 }
4122 
4123 QDF_STATUS reg_get_6g_ap_master_chan_list(struct wlan_objmgr_pdev *pdev,
4124 					  enum reg_6g_ap_type ap_pwr_type,
4125 					  struct regulatory_channel *chan_list)
4126 {
4127 	struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj;
4128 	struct regulatory_channel *master_chan_list_6g;
4129 
4130 	pdev_priv_obj = reg_get_pdev_obj(pdev);
4131 
4132 	if (!IS_VALID_PDEV_REG_OBJ(pdev_priv_obj)) {
4133 		reg_err("reg pdev private obj is NULL");
4134 		return QDF_STATUS_E_FAILURE;
4135 	}
4136 
4137 	if (ap_pwr_type >= REG_CURRENT_MAX_AP_TYPE)
4138 		return QDF_STATUS_E_FAILURE;
4139 
4140 	master_chan_list_6g = pdev_priv_obj->mas_chan_list_6g_ap[ap_pwr_type];
4141 	qdf_mem_copy(chan_list, master_chan_list_6g,
4142 		     NUM_6GHZ_CHANNELS * sizeof(struct regulatory_channel));
4143 
4144 	return QDF_STATUS_SUCCESS;
4145 }
4146 
4147 #ifdef CONFIG_AFC_SUPPORT
4148 static void reg_disable_afc_mas_chan_list_channels(
4149 		struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj)
4150 {
4151 	struct regulatory_channel *afc_mas_chan_list;
4152 	enum channel_enum chan_idx;
4153 
4154 	QDF_TRACE(QDF_MODULE_ID_AFC, QDF_TRACE_LEVEL_DEBUG,
4155 		  "Processing AFC Switch to LPI event");
4156 
4157 	afc_mas_chan_list = pdev_priv_obj->mas_chan_list_6g_afc;
4158 
4159 	for (chan_idx = 0; chan_idx < NUM_6GHZ_CHANNELS; chan_idx++) {
4160 		if (afc_mas_chan_list[chan_idx].state == CHANNEL_STATE_ENABLE) {
4161 			if (pdev_priv_obj->reg_afc_dev_deployment_type ==
4162 			    AFC_DEPLOYMENT_OUTDOOR) {
4163 				afc_mas_chan_list[chan_idx].chan_flags |=
4164 					REGULATORY_CHAN_AFC_NOT_DONE;
4165 			} else {
4166 				afc_mas_chan_list[chan_idx].state =
4167 					CHANNEL_STATE_DISABLE;
4168 				afc_mas_chan_list[chan_idx].chan_flags |=
4169 					REGULATORY_CHAN_DISABLED;
4170 				afc_mas_chan_list[chan_idx].psd_eirp = 0;
4171 				afc_mas_chan_list[chan_idx].tx_power = 0;
4172 			}
4173 		}
4174 	}
4175 
4176 	qdf_mem_zero(pdev_priv_obj->afc_chan_list,
4177 		     NUM_6GHZ_CHANNELS * sizeof(struct regulatory_channel));
4178 }
4179 
4180 static void reg_free_expiry_afc_info(struct afc_regulatory_info *afc_info)
4181 {
4182 	qdf_mem_free(afc_info->expiry_info);
4183 }
4184 
4185 /**
4186  * reg_disable_sp_entries_in_supr_chan_entry() - Disable the SP entries in the
4187  * super channel list
4188  * @chan_info: Pointer to chan_info
4189  * @reg_afc_dev_type: AFC device deployment type
4190  *
4191  * Return: void
4192  */
4193 static void reg_disable_sp_entries_in_supr_chan_entry(
4194 				struct super_chan_info *chan_info,
4195 				enum reg_afc_dev_deploy_type reg_afc_dev_type)
4196 {
4197 	uint8_t j;
4198 	static enum supported_6g_pwr_types list_of_sp_lists[] = {
4199 		REG_AP_SP,
4200 		REG_CLI_DEF_SP,
4201 		REG_CLI_SUB_SP
4202 	};
4203 	uint8_t num_sp_lists = QDF_ARRAY_SIZE(list_of_sp_lists);
4204 
4205 	for (j = 0; j < num_sp_lists; j++) {
4206 		enum supported_6g_pwr_types  idx = list_of_sp_lists[j];
4207 
4208 		if (reg_is_supp_pwr_mode_invalid(idx))
4209 			continue;
4210 
4211 		if (chan_info->state_arr[idx] == CHANNEL_STATE_DISABLE)
4212 			continue;
4213 
4214 		if (reg_afc_dev_type == AFC_DEPLOYMENT_OUTDOOR)
4215 			reg_set_flag_afc_not_done(
4216 					&chan_info->chan_flags_arr[idx],
4217 					true);
4218 		else
4219 			reg_dis_chan_state_and_flags(
4220 					&chan_info->state_arr[idx],
4221 					&chan_info->chan_flags_arr[idx]);
4222 	}
4223 }
4224 
4225 /**
4226  * reg_disable_sp_channels_in_super_chan_list() - Disable the SP channels in
4227  * the super channel list
4228  * @pdev_priv_obj: Pointer to pdev_priv_obj
4229  *
4230  * Return: void
4231  */
4232 static void
4233 reg_disable_sp_channels_in_super_chan_list(
4234 		struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj)
4235 {
4236 	uint8_t i;
4237 	struct super_chan_info *super_chan_list;
4238 
4239 	super_chan_list = pdev_priv_obj->super_chan_list;
4240 	for (i = 0; i < NUM_6GHZ_CHANNELS; i++) {
4241 		struct super_chan_info *chan_info =
4242 						&super_chan_list[i];
4243 		reg_disable_sp_entries_in_supr_chan_entry(
4244 				chan_info,
4245 				pdev_priv_obj->reg_afc_dev_deployment_type);
4246 	}
4247 }
4248 
4249 #if defined(CONFIG_AFC_SUPPORT) && defined(CONFIG_REG_CLIENT)
4250 /**
4251  * reg_client_afc_populate_channels() - Function to populate channels and
4252  * invoke callbacks to notify the channel list change.
4253  * @psoc: Pointer to PSOC object
4254  * @pdev: Pointer to PDEV object
4255  *
4256  * Return: None
4257  */
4258 static void
4259 reg_client_afc_populate_channels(struct wlan_objmgr_psoc *psoc,
4260 				 struct wlan_objmgr_pdev *pdev)
4261 {
4262 	struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj;
4263 
4264 	pdev_priv_obj = reg_get_pdev_obj(pdev);
4265 	if (!IS_VALID_PDEV_REG_OBJ(pdev_priv_obj)) {
4266 		reg_alert("pdev reg component is NULL");
4267 		return;
4268 	}
4269 	reg_compute_pdev_current_chan_list(pdev_priv_obj);
4270 	reg_send_scheduler_msg_nb(psoc, pdev);
4271 }
4272 #else
4273 static inline void
4274 reg_client_afc_populate_channels(struct wlan_objmgr_psoc *psoc,
4275 				 struct wlan_objmgr_pdev *pdev)
4276 {
4277 }
4278 #endif
4279 
4280 /**
4281  * reg_process_afc_expiry_event() - Process the afc expiry event and get the
4282  * afc request id
4283  * @afc_info: Pointer to afc info
4284  *
4285  * Return: QDF_STATUS
4286  */
4287 static QDF_STATUS
4288 reg_process_afc_expiry_event(struct afc_regulatory_info *afc_info)
4289 {
4290 	struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj;
4291 	uint8_t phy_id;
4292 	uint8_t pdev_id;
4293 	struct wlan_objmgr_psoc *psoc;
4294 	struct wlan_regulatory_psoc_priv_obj *soc_reg;
4295 	struct wlan_objmgr_pdev *pdev;
4296 	struct wlan_lmac_if_reg_tx_ops *tx_ops;
4297 	wlan_objmgr_ref_dbgid dbg_id;
4298 
4299 	psoc = afc_info->psoc;
4300 	soc_reg = reg_get_psoc_obj(psoc);
4301 
4302 	if (!IS_VALID_PSOC_REG_OBJ(soc_reg)) {
4303 		reg_err("psoc reg component is NULL");
4304 		return QDF_STATUS_E_FAILURE;
4305 	}
4306 
4307 	phy_id = afc_info->phy_id;
4308 	tx_ops = reg_get_psoc_tx_ops(psoc);
4309 
4310 	if (soc_reg->offload_enabled)
4311 		dbg_id = WLAN_REGULATORY_NB_ID;
4312 	else
4313 		dbg_id = WLAN_REGULATORY_SB_ID;
4314 
4315 	if (tx_ops->get_pdev_id_from_phy_id)
4316 		tx_ops->get_pdev_id_from_phy_id(psoc, phy_id, &pdev_id);
4317 	else
4318 		pdev_id = phy_id;
4319 
4320 	pdev = wlan_objmgr_get_pdev_by_id(psoc, pdev_id, dbg_id);
4321 
4322 	if (!pdev) {
4323 		reg_err("pdev is NULL");
4324 		return QDF_STATUS_E_FAILURE;
4325 	}
4326 
4327 	pdev_priv_obj = reg_get_pdev_obj(pdev);
4328 
4329 	if (!IS_VALID_PDEV_REG_OBJ(pdev_priv_obj)) {
4330 		reg_err("reg pdev priv obj is NULL");
4331 		wlan_objmgr_pdev_release_ref(pdev, dbg_id);
4332 		return QDF_STATUS_E_FAILURE;
4333 	}
4334 
4335 	reg_debug("AFC event subtype: %d",
4336 		  afc_info->expiry_info->event_subtype);
4337 	switch (afc_info->expiry_info->event_subtype) {
4338 	case REG_AFC_EXPIRY_EVENT_START:
4339 	case REG_AFC_EXPIRY_EVENT_RENEW:
4340 		pdev_priv_obj->afc_request_id =
4341 					afc_info->expiry_info->request_id;
4342 		pdev_priv_obj->is_6g_afc_expiry_event_received = true;
4343 		reg_afc_start(pdev, pdev_priv_obj->afc_request_id);
4344 		break;
4345 	case REG_AFC_EXPIRY_EVENT_SWITCH_TO_LPI:
4346 	case REG_AFC_EXPIRY_EVENT_STOP_TX:
4347 		pdev_priv_obj->is_6g_afc_power_event_received = false;
4348 		reg_disable_afc_mas_chan_list_channels(pdev_priv_obj);
4349 		reg_disable_sp_channels_in_super_chan_list(pdev_priv_obj);
4350 		reg_client_afc_populate_channels(psoc, pdev);
4351 		if (tx_ops->trigger_acs_for_afc)
4352 			tx_ops->trigger_acs_for_afc(pdev);
4353 		break;
4354 	default:
4355 		reg_err_rl("Invalid event subtype");
4356 	};
4357 
4358 	wlan_objmgr_pdev_release_ref(pdev, dbg_id);
4359 	reg_free_expiry_afc_info(afc_info);
4360 
4361 	return QDF_STATUS_SUCCESS;
4362 }
4363 
4364 /**
4365  * reg_fill_min_max_bw_for_afc_list() - Fill min and max bw in afc list from
4366  * from the SP AFC list
4367  * @pdev_priv_obj: Pointer to pdev_priv_obj
4368  * @afc_chan_list: Pointer to afc_chan_list
4369  *
4370  * Return: void
4371  */
4372 static void
4373 reg_fill_min_max_bw_for_afc_list(
4374 		struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj,
4375 		struct regulatory_channel *afc_chan_list)
4376 {
4377 	uint8_t chan_idx;
4378 
4379 	for (chan_idx = 0; chan_idx < NUM_6GHZ_CHANNELS; chan_idx++) {
4380 		afc_chan_list[chan_idx].min_bw = MIN_AFC_BW;
4381 		afc_chan_list[chan_idx].max_bw = MAX_AFC_BW;
4382 	}
4383 }
4384 
4385 /**
4386  * reg_fill_subchan_centers() - Fill the subchannels for the given cfi.
4387  * @nchans: Number of sub-channels
4388  * @cfi: Center frequency index
4389  * @subchannels: Array of subchannels to be filled
4390  *
4391  * eg: subchannels[0] = cfi - 6 : The second left hand channel is
4392  *     4 MHz to the left of the previous channel.
4393  *     subchannels[1] = cfi - 2 : The first left hand channel is 2 MHz
4394  *     to the left of the CFI.
4395  *     subchannels[2] = cfi + 2 : The first right hand channel is 2 MHz
4396  *     to the right of the center (or CFI) as the distance between
4397  *     two IEEE channels is 4 MHz.
4398  *     subchannels[3] = cfi + 6 : The second right hand channel is 4 MHz to the
4399  *     right the of previous channel
4400  *
4401  * Return: void
4402  */
4403 static void
4404 reg_fill_subchan_centers(uint8_t nchans, uint8_t cfi, uint8_t *subchannels)
4405 {
4406 	uint8_t last_idx = nchans - 1;
4407 	uint8_t offset = HALF_IEEE_CH_SEP;
4408 	uint8_t i;
4409 
4410 	if (nchans == 1) {
4411 		subchannels[0] = cfi;
4412 		return;
4413 	}
4414 
4415 	for (i = nchans / 2; i < nchans; i++) {
4416 		subchannels[i] = cfi + offset;
4417 		subchannels[last_idx - i] = cfi - offset;
4418 		offset += IEEE_20MHZ_CH_SEP;
4419 	}
4420 }
4421 
4422 /**
4423  * reg_get_subchannels_for_opclass() - Get the list of subchannels based on the
4424  * the channel frequency index and opclass.
4425  * @cfi: Channel frequency index
4426  * @opclass: Operating class
4427  * @subchannels: Pointer to list of subchannels
4428  *
4429  * Return: void
4430  */
4431 uint8_t reg_get_subchannels_for_opclass(uint8_t cfi,
4432 					uint8_t opclass,
4433 					uint8_t *subchannels)
4434 {
4435 	uint8_t nchans;
4436 
4437 	switch (opclass) {
4438 	case 131:
4439 	case 136:
4440 		nchans = 1;
4441 		break;
4442 	case 132:
4443 		nchans = 2;
4444 		break;
4445 	case 133:
4446 		nchans = 4;
4447 		break;
4448 	case 134:
4449 		nchans = 8;
4450 		break;
4451 	case 137:
4452 		nchans = 16;
4453 		break;
4454 
4455 	default:
4456 		nchans = 0;
4457 		break;
4458 	}
4459 
4460 	reg_fill_subchan_centers(nchans, cfi, subchannels);
4461 
4462 	return nchans;
4463 }
4464 
4465 /**
4466  * reg_search_afc_power_info_for_freq() - Search the chan_eirp object for the
4467  * eirp power for a given frequency
4468  * @pdev: Pointer to pdev
4469  * @power_info: Pointer to power_info
4470  * @freq: Channel frequency
4471  * @eirp_power: Pointer to eirp_power
4472  *
4473  * Return: QDF_STATUS
4474  */
4475 static QDF_STATUS
4476 reg_search_afc_power_info_for_freq(
4477 		struct wlan_objmgr_pdev *pdev,
4478 		struct reg_fw_afc_power_event *power_info,
4479 		qdf_freq_t freq,
4480 		uint16_t *eirp_power)
4481 {
4482 	uint8_t i;
4483 
4484 	if (!power_info->num_chan_objs) {
4485 		reg_err("num chan objs cannot be zero");
4486 		return QDF_STATUS_E_FAILURE;
4487 	}
4488 
4489 	*eirp_power = 0;
4490 	for (i = 0; i < power_info->num_chan_objs; i++) {
4491 		uint8_t j;
4492 		struct afc_chan_obj *chan_obj = &power_info->afc_chan_info[i];
4493 
4494 		if (!chan_obj->num_chans) {
4495 			reg_err("num chans cannot be zero");
4496 			return QDF_STATUS_E_FAILURE;
4497 		}
4498 
4499 		for (j = 0; j < chan_obj->num_chans; j++) {
4500 			uint8_t k;
4501 			struct chan_eirp_obj *eirp_obj =
4502 						&chan_obj->chan_eirp_info[j];
4503 			uint8_t opclass = chan_obj->global_opclass;
4504 			uint8_t subchannels[REG_MAX_20M_SUB_CH];
4505 			uint8_t nchans;
4506 
4507 			nchans =
4508 			reg_get_subchannels_for_opclass(eirp_obj->cfi,
4509 							opclass, subchannels);
4510 
4511 			for (k = 0; k < nchans; k++) {
4512 				if (reg_chan_band_to_freq(pdev,
4513 							  subchannels[k],
4514 							  BIT(REG_BAND_6G)) ==
4515 							  freq) {
4516 					*eirp_power = eirp_obj->eirp_power;
4517 					return QDF_STATUS_SUCCESS;
4518 				}
4519 			}
4520 		}
4521 	}
4522 
4523 	return QDF_STATUS_E_FAILURE;
4524 }
4525 
4526 /**
4527  * reg_process_cfi_chan_list() - Fill eirp power and state in the cfi chan list
4528  * @pdev: Pointer to pdev
4529  * @cfi_chan_list: Pointer to cfi_chan_list
4530  * @power_info: Pointer to power_info
4531  *
4532  * Return: QDF_STATUS
4533  */
4534 static QDF_STATUS reg_process_cfi_chan_list(
4535 		struct wlan_objmgr_pdev *pdev,
4536 		struct regulatory_channel *cfi_chan_list,
4537 		struct reg_fw_afc_power_event *power_info)
4538 
4539 {
4540 	uint8_t chan_idx;
4541 	uint16_t eirp_power;
4542 	QDF_STATUS status = QDF_STATUS_SUCCESS;
4543 
4544 	for (chan_idx = 0; chan_idx < NUM_6GHZ_CHANNELS; chan_idx++) {
4545 		status =
4546 		reg_search_afc_power_info_for_freq(pdev,
4547 						   power_info,
4548 						   cfi_chan_list[chan_idx].
4549 						   center_freq,
4550 						   &eirp_power);
4551 		/*
4552 		 * The eirp_power is divided by 100 because the target
4553 		 * sends the EIRP in the units of 0.01 dbm.
4554 		 */
4555 		if (QDF_IS_STATUS_SUCCESS(status)) {
4556 			cfi_chan_list[chan_idx].tx_power = eirp_power / 100;
4557 			cfi_chan_list[chan_idx].state = CHANNEL_STATE_ENABLE;
4558 			cfi_chan_list[chan_idx].chan_flags &=
4559 						~REGULATORY_CHAN_DISABLED;
4560 		}
4561 	}
4562 
4563 	return status;
4564 }
4565 
4566 /**
4567  * reg_find_low_limit_chan_enum_for_6g() - Find 6G channel enum for a given 6G
4568  * lower edge frequency in the input channel list
4569  * @chan_list: Pointer to regulatory channel list.
4570  * @low_freq: Channel frequency.
4571  * @channel_enum: pointer to output channel enum.
4572  *
4573  * Return: None
4574  */
4575 static void reg_find_low_limit_chan_enum_for_6g(
4576 		struct regulatory_channel *chan_list, qdf_freq_t low_freq,
4577 		enum channel_enum *channel_enum)
4578 {
4579 	enum channel_enum chan_enum;
4580 	uint16_t min_bw, max_bw, left_edge_of_min_band, left_edge_of_max_band;
4581 	qdf_freq_t center_freq;
4582 
4583 	*channel_enum = 0;
4584 	for (chan_enum = 0; chan_enum < NUM_6GHZ_CHANNELS; chan_enum++) {
4585 		min_bw = chan_list[chan_enum].min_bw;
4586 		max_bw = chan_list[chan_enum].max_bw;
4587 		center_freq = chan_list[chan_enum].center_freq;
4588 		left_edge_of_min_band = center_freq - min_bw / 2;
4589 
4590 		if ((left_edge_of_min_band) >= low_freq) {
4591 			left_edge_of_max_band = center_freq - max_bw / 2;
4592 			if (left_edge_of_max_band < low_freq) {
4593 				if (max_bw <= 20)
4594 					max_bw = ((center_freq - low_freq) * 2);
4595 				if (max_bw < min_bw)
4596 					max_bw = min_bw;
4597 				chan_list[chan_enum].max_bw = max_bw;
4598 			}
4599 			*channel_enum = chan_enum;
4600 			break;
4601 		}
4602 	}
4603 }
4604 
4605 /**
4606  * reg_find_high_limit_chan_enum_for_6g() - Find 6G channel enum for a given
4607  * 6G higher edge frequency in the input channel list
4608  * @chan_list: Pointer to regulatory channel list.
4609  * @freq: Channel frequency.
4610  * @channel_enum: pointer to output channel enum.
4611  *
4612  * Return: None
4613  */
4614 static void reg_find_high_limit_chan_enum_for_6g(
4615 		struct regulatory_channel *chan_list,
4616 		qdf_freq_t high_freq,
4617 		enum channel_enum *channel_enum)
4618 {
4619 	enum channel_enum chan_enum;
4620 	uint16_t min_bw, max_bw, right_edge_of_min_band, right_edge_of_max_band;
4621 	qdf_freq_t center_freq;
4622 
4623 	*channel_enum = 0;
4624 	for (chan_enum = NUM_6GHZ_CHANNELS - 1; chan_enum >= 0; chan_enum--) {
4625 		min_bw = chan_list[chan_enum].min_bw;
4626 		max_bw = chan_list[chan_enum].max_bw;
4627 		center_freq = chan_list[chan_enum].center_freq;
4628 		right_edge_of_min_band = center_freq + min_bw / 2;
4629 
4630 		if (right_edge_of_min_band <= high_freq) {
4631 			right_edge_of_max_band = center_freq + max_bw / 2;
4632 			if (right_edge_of_max_band > high_freq) {
4633 				if (max_bw <= 20)
4634 					max_bw = ((high_freq -
4635 						   center_freq) * 2);
4636 				if (max_bw < min_bw)
4637 					max_bw = min_bw;
4638 				chan_list[chan_enum].max_bw = max_bw;
4639 			}
4640 			*channel_enum = chan_enum;
4641 			break;
4642 		}
4643 
4644 		if (chan_enum == 0)
4645 			break;
4646 	}
4647 }
4648 
4649 /**
4650  * reg_fill_max_psd_in_afc_chan_list() - Fill max_psd in the afc master chan
4651  * list
4652  * @pdev_priv_obj: Pointer to pdev_priv_obj
4653  * @afc_chan_list: Pointer to afc_chan_list
4654  * @power_info: Pointer to power_info
4655  *
4656  * Return: QDF_STATUS
4657  */
4658 static QDF_STATUS reg_fill_max_psd_in_afc_chan_list(
4659 		struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj,
4660 		struct regulatory_channel *afc_chan_list,
4661 		struct reg_fw_afc_power_event *power_info)
4662 {
4663 	uint8_t i;
4664 	struct regulatory_channel *sp_chan_list;
4665 	struct regulatory_channel *cfi_chan_list;
4666 
4667 	if (!power_info) {
4668 		reg_err("power_info is NULL");
4669 		return QDF_STATUS_E_FAILURE;
4670 	}
4671 
4672 	if (!power_info->num_freq_objs) {
4673 		reg_err("num freq objs cannot be zero");
4674 		return QDF_STATUS_E_FAILURE;
4675 	}
4676 
4677 	cfi_chan_list = qdf_mem_malloc(sizeof(struct regulatory_channel) *
4678 				       NUM_6GHZ_CHANNELS);
4679 
4680 	if (!cfi_chan_list)
4681 		return QDF_STATUS_E_NOMEM;
4682 
4683 	qdf_mem_copy(cfi_chan_list, afc_chan_list,
4684 		     sizeof(struct regulatory_channel) * NUM_6GHZ_CHANNELS);
4685 	sp_chan_list =
4686 		pdev_priv_obj->mas_chan_list_6g_ap[REG_STANDARD_POWER_AP];
4687 
4688 	reg_process_cfi_chan_list(pdev_priv_obj->pdev_ptr, cfi_chan_list,
4689 				  power_info);
4690 
4691 	for (i = 0; i < power_info->num_freq_objs; i++) {
4692 		struct afc_freq_obj *freq_obj = &power_info->afc_freq_info[i];
4693 		enum channel_enum low_limit_enum, high_limit_enum;
4694 		uint8_t j;
4695 
4696 		reg_find_low_limit_chan_enum_for_6g(afc_chan_list,
4697 						    freq_obj->low_freq,
4698 						    &low_limit_enum);
4699 		reg_find_high_limit_chan_enum_for_6g(afc_chan_list,
4700 						     freq_obj->high_freq,
4701 						     &high_limit_enum);
4702 		for (j = low_limit_enum; j <= high_limit_enum; j++) {
4703 			if ((sp_chan_list[j].state == CHANNEL_STATE_ENABLE) &&
4704 			    (cfi_chan_list[j].state == CHANNEL_STATE_ENABLE)) {
4705 				afc_chan_list[j].state = CHANNEL_STATE_ENABLE;
4706 				afc_chan_list[j].chan_flags &=
4707 						~REGULATORY_CHAN_DISABLED;
4708 				/*
4709 				 * The max_psd is divided by 100 because the
4710 				 * target sends the PSD in the units of
4711 				 * 0.01 dbm/MHz.
4712 				 */
4713 				afc_chan_list[j].psd_eirp =
4714 							freq_obj->max_psd / 100;
4715 				afc_chan_list[j].psd_flag = true;
4716 				afc_chan_list[j].tx_power =
4717 						cfi_chan_list[j].tx_power;
4718 			}
4719 		}
4720 	}
4721 
4722 	qdf_mem_free(cfi_chan_list);
4723 
4724 	return QDF_STATUS_SUCCESS;
4725 }
4726 
4727 /**
4728  * reg_is_afc_mas_chan_list_valid() - Check if the AFC master channel list
4729  * is non-empty
4730  * @afc_mas_chan_list: Pointer to afc_mas_chan_list.
4731  *
4732  * Return: True, if atleast one channel has the state "CHANNEL_STATE_ENABLE",
4733  * else false.
4734  */
4735 static bool
4736 reg_is_afc_mas_chan_list_valid(struct regulatory_channel *afc_mas_chan_list)
4737 {
4738 	uint8_t i;
4739 
4740 	for (i = 0; i < NUM_6GHZ_CHANNELS; i++)
4741 		if (afc_mas_chan_list[i].state == CHANNEL_STATE_ENABLE)
4742 			return true;
4743 
4744 	return false;
4745 }
4746 
4747 /**
4748  * reg_process_afc_power_event() - Process the afc event and compute the 6G AFC
4749  * channel list based on the frequency range and channel frequency indice set.
4750  * @afc_info: Pointer to afc info
4751  *
4752  * Return: QDF_STATUS
4753  */
4754 static QDF_STATUS
4755 reg_process_afc_power_event(struct afc_regulatory_info *afc_info)
4756 {
4757 	struct wlan_objmgr_psoc *psoc;
4758 	uint8_t phy_id;
4759 	uint8_t pdev_id;
4760 	wlan_objmgr_ref_dbgid dbg_id;
4761 	struct wlan_objmgr_pdev *pdev;
4762 	struct mas_chan_params *this_mchan_params;
4763 	struct wlan_lmac_if_reg_tx_ops *tx_ops;
4764 	struct regulatory_channel *afc_mas_chan_list;
4765 	struct wlan_regulatory_psoc_priv_obj *soc_reg;
4766 	struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj;
4767 	uint32_t size_of_6g_chan_list =
4768 		NUM_6GHZ_CHANNELS * sizeof(struct regulatory_channel);
4769 	QDF_STATUS status;
4770 
4771 	QDF_TRACE(QDF_MODULE_ID_AFC, QDF_TRACE_LEVEL_DEBUG,
4772 		  "Processing AFC Power event");
4773 
4774 	if (afc_info->power_info->fw_status_code !=
4775 	    REG_FW_AFC_POWER_EVENT_SUCCESS) {
4776 		reg_err_rl("AFC Power event failure status code %d",
4777 			   afc_info->power_info->fw_status_code);
4778 		return QDF_STATUS_E_FAILURE;
4779 	}
4780 
4781 	psoc = afc_info->psoc;
4782 	soc_reg = reg_get_psoc_obj(psoc);
4783 
4784 	if (!IS_VALID_PSOC_REG_OBJ(soc_reg)) {
4785 		reg_err("psoc reg component is NULL");
4786 		return QDF_STATUS_E_FAILURE;
4787 	}
4788 
4789 	tx_ops = reg_get_psoc_tx_ops(psoc);
4790 	phy_id = afc_info->phy_id;
4791 
4792 	if (tx_ops->get_pdev_id_from_phy_id)
4793 		tx_ops->get_pdev_id_from_phy_id(psoc, phy_id, &pdev_id);
4794 	else
4795 		pdev_id = phy_id;
4796 
4797 	if (soc_reg->offload_enabled)
4798 		dbg_id = WLAN_REGULATORY_NB_ID;
4799 	else
4800 		dbg_id = WLAN_REGULATORY_SB_ID;
4801 
4802 	reg_debug("process reg afc master chan list");
4803 	this_mchan_params = &soc_reg->mas_chan_params[phy_id];
4804 	afc_mas_chan_list = this_mchan_params->mas_chan_list_6g_afc;
4805 	qdf_mem_zero(afc_mas_chan_list,
4806 		     NUM_6GHZ_CHANNELS * sizeof(struct regulatory_channel));
4807 	reg_init_6ghz_master_chan(afc_mas_chan_list, soc_reg);
4808 	soc_reg->mas_chan_params[phy_id].is_6g_afc_power_event_received = true;
4809 	pdev = wlan_objmgr_get_pdev_by_id(psoc, pdev_id, dbg_id);
4810 
4811 	if (!pdev) {
4812 		reg_err("pdev is NULL");
4813 		return QDF_STATUS_E_FAILURE;
4814 	}
4815 
4816 	pdev_priv_obj = reg_get_pdev_obj(pdev);
4817 
4818 	if (!IS_VALID_PDEV_REG_OBJ(pdev_priv_obj)) {
4819 		reg_err("reg pdev priv obj is NULL");
4820 		wlan_objmgr_pdev_release_ref(pdev, dbg_id);
4821 		return QDF_STATUS_E_FAILURE;
4822 	}
4823 
4824 	reg_init_pdev_super_chan_list(pdev_priv_obj);
4825 	reg_init_6ghz_master_chan(pdev_priv_obj->afc_chan_list, soc_reg);
4826 	/* Free the old power_info event if it was allocated */
4827 	if (pdev_priv_obj->power_info)
4828 		reg_free_afc_pwr_info(pdev_priv_obj);
4829 
4830 	pdev_priv_obj->power_info = afc_info->power_info;
4831 	reg_fill_min_max_bw_for_afc_list(pdev_priv_obj,
4832 					 afc_mas_chan_list);
4833 	status = reg_fill_max_psd_in_afc_chan_list(pdev_priv_obj,
4834 						   afc_mas_chan_list,
4835 						   afc_info->power_info);
4836 	if (QDF_IS_STATUS_ERROR(status)) {
4837 		reg_err("Error in filling max_psd in AFC chan list");
4838 		wlan_objmgr_pdev_release_ref(pdev, dbg_id);
4839 		return status;
4840 	}
4841 
4842 	qdf_mem_copy(pdev_priv_obj->mas_chan_list_6g_afc,
4843 		     afc_mas_chan_list,
4844 		     size_of_6g_chan_list);
4845 	pdev_priv_obj->is_6g_afc_power_event_received =
4846 	soc_reg->mas_chan_params[phy_id].is_6g_afc_power_event_received;
4847 
4848 	reg_modify_6g_afc_chan_list(pdev_priv_obj);
4849 	reg_compute_super_chan_list(pdev_priv_obj);
4850 	reg_client_afc_populate_channels(psoc, pdev);
4851 
4852 	if (tx_ops->trigger_acs_for_afc &&
4853 	    !wlan_reg_is_noaction_on_afc_pwr_evt(pdev) &&
4854 	    reg_is_afc_mas_chan_list_valid(pdev_priv_obj->mas_chan_list_6g_afc))
4855 		tx_ops->trigger_acs_for_afc(pdev);
4856 
4857 	reg_send_afc_power_event(pdev, afc_info->power_info);
4858 	wlan_objmgr_pdev_release_ref(pdev, dbg_id);
4859 
4860 	return QDF_STATUS_SUCCESS;
4861 }
4862 
4863 /**
4864  * reg_process_afc_event() - Process the afc event received from the target.
4865  * @afc_info: Pointer to afc_info
4866  *
4867  * Return: QDF_STATUS
4868  */
4869 QDF_STATUS
4870 reg_process_afc_event(struct afc_regulatory_info *afc_info)
4871 {
4872 	switch (afc_info->event_type) {
4873 	case REG_AFC_EVENT_POWER_INFO:
4874 		return reg_process_afc_power_event(afc_info);
4875 	case REG_AFC_EVENT_TIMER_EXPIRY:
4876 		return reg_process_afc_expiry_event(afc_info);
4877 	default:
4878 		reg_err_rl("Invalid event type");
4879 		return QDF_STATUS_E_FAILURE;
4880 	}
4881 }
4882 #endif /* CONFIG_AFC_SUPPORT */
4883 #ifdef CONFIG_REG_CLIENT
4884 const char *reg_get_power_string(enum reg_6g_ap_type power_type)
4885 {
4886 	switch (power_type) {
4887 	case REG_INDOOR_AP:
4888 		return "LP";
4889 	case REG_STANDARD_POWER_AP:
4890 		return "SP";
4891 	case REG_VERY_LOW_POWER_AP:
4892 		return "VLP";
4893 	default:
4894 		return "INVALID";
4895 	}
4896 }
4897 #endif
4898 #endif /* CONFIG_BAND_6GHZ */
4899 
4900 QDF_STATUS reg_process_master_chan_list(
4901 		struct cur_regulatory_info *regulat_info)
4902 {
4903 	struct wlan_regulatory_psoc_priv_obj *soc_reg;
4904 	uint32_t num_2g_reg_rules, num_5g_reg_rules;
4905 	struct cur_reg_rule *reg_rule_2g, *reg_rule_5g;
4906 	uint16_t min_bw_2g, max_bw_2g, min_bw_5g, max_bw_5g;
4907 	struct regulatory_channel *mas_chan_list;
4908 	struct wlan_objmgr_psoc *psoc;
4909 	wlan_objmgr_ref_dbgid dbg_id;
4910 	enum direction dir;
4911 	uint8_t phy_id;
4912 	uint8_t pdev_id;
4913 	struct wlan_objmgr_pdev *pdev;
4914 	struct wlan_lmac_if_reg_tx_ops *tx_ops;
4915 	struct reg_rule_info *reg_rules;
4916 	QDF_STATUS status;
4917 
4918 	psoc = regulat_info->psoc;
4919 	soc_reg = reg_get_psoc_obj(psoc);
4920 
4921 	if (!IS_VALID_PSOC_REG_OBJ(soc_reg)) {
4922 		reg_err("psoc reg component is NULL");
4923 		return QDF_STATUS_E_FAILURE;
4924 	}
4925 
4926 	tx_ops = reg_get_psoc_tx_ops(psoc);
4927 	phy_id = regulat_info->phy_id;
4928 
4929 	if (tx_ops->get_pdev_id_from_phy_id)
4930 		tx_ops->get_pdev_id_from_phy_id(psoc, phy_id, &pdev_id);
4931 	else
4932 		pdev_id = phy_id;
4933 
4934 	if (reg_ignore_default_country(soc_reg, regulat_info)) {
4935 		status = reg_set_curr_country(soc_reg, regulat_info, tx_ops);
4936 		if (QDF_IS_STATUS_SUCCESS(status)) {
4937 			reg_debug("WLAN restart - Ignore default CC for phy_id: %u",
4938 				  phy_id);
4939 			return QDF_STATUS_SUCCESS;
4940 		}
4941 	}
4942 
4943 	reg_debug("process reg master chan list");
4944 
4945 	if (soc_reg->offload_enabled) {
4946 		dbg_id = WLAN_REGULATORY_NB_ID;
4947 		dir = NORTHBOUND;
4948 	} else {
4949 		dbg_id = WLAN_REGULATORY_SB_ID;
4950 		dir = SOUTHBOUND;
4951 	}
4952 
4953 	status = reg_soc_vars_reset_on_failure(regulat_info->status_code,
4954 					       soc_reg, tx_ops, psoc, dbg_id,
4955 					       phy_id);
4956 
4957 	if (!QDF_IS_STATUS_SUCCESS(status))
4958 		return status;
4959 
4960 	mas_chan_list = soc_reg->mas_chan_params[phy_id].mas_chan_list;
4961 
4962 	reg_init_channel_map(regulat_info->dfs_region);
4963 
4964 	reg_init_legacy_master_chan(mas_chan_list, soc_reg);
4965 
4966 	soc_reg->num_phy = regulat_info->num_phy;
4967 	soc_reg->mas_chan_params[phy_id].phybitmap =
4968 		regulat_info->phybitmap;
4969 	soc_reg->mas_chan_params[phy_id].dfs_region =
4970 		regulat_info->dfs_region;
4971 	soc_reg->mas_chan_params[phy_id].ctry_code =
4972 		regulat_info->ctry_code;
4973 	soc_reg->mas_chan_params[phy_id].reg_dmn_pair =
4974 		regulat_info->reg_dmn_pair;
4975 	qdf_mem_copy(soc_reg->mas_chan_params[phy_id].current_country,
4976 		     regulat_info->alpha2,
4977 		     REG_ALPHA2_LEN + 1);
4978 	qdf_mem_copy(soc_reg->cur_country,
4979 		     regulat_info->alpha2,
4980 		     REG_ALPHA2_LEN + 1);
4981 	reg_debug("set cur_country %.2s", soc_reg->cur_country);
4982 
4983 	min_bw_2g = regulat_info->min_bw_2g;
4984 	max_bw_2g = regulat_info->max_bw_2g;
4985 	reg_rule_2g = regulat_info->reg_rules_2g_ptr;
4986 	num_2g_reg_rules = regulat_info->num_2g_reg_rules;
4987 	reg_update_max_bw_per_rule(num_2g_reg_rules,
4988 				   reg_rule_2g, max_bw_2g);
4989 
4990 	min_bw_5g = regulat_info->min_bw_5g;
4991 	max_bw_5g = regulat_info->max_bw_5g;
4992 	reg_rule_5g = regulat_info->reg_rules_5g_ptr;
4993 	num_5g_reg_rules = regulat_info->num_5g_reg_rules;
4994 	reg_update_max_bw_per_rule(num_5g_reg_rules,
4995 				   reg_rule_5g, max_bw_5g);
4996 	soc_reg->mas_chan_params[phy_id].max_bw_5g = regulat_info->max_bw_5g;
4997 	reg_rules = &soc_reg->mas_chan_params[phy_id].reg_rules;
4998 	reg_reset_reg_rules(reg_rules);
4999 
5000 	reg_rules->num_of_reg_rules = num_5g_reg_rules + num_2g_reg_rules;
5001 	if (reg_rules->num_of_reg_rules > MAX_REG_RULES) {
5002 		reg_err("number of reg rules exceeds limit");
5003 		return QDF_STATUS_E_FAILURE;
5004 	}
5005 
5006 	if (reg_rules->num_of_reg_rules) {
5007 		if (num_2g_reg_rules)
5008 			qdf_mem_copy(reg_rules->reg_rules,
5009 				     reg_rule_2g, num_2g_reg_rules *
5010 				     sizeof(struct cur_reg_rule));
5011 		if (num_5g_reg_rules)
5012 			qdf_mem_copy(reg_rules->reg_rules +
5013 				     num_2g_reg_rules, reg_rule_5g,
5014 				     num_5g_reg_rules *
5015 				     sizeof(struct cur_reg_rule));
5016 	}
5017 
5018 	if (num_5g_reg_rules != 0)
5019 		reg_do_auto_bw_correction(num_5g_reg_rules,
5020 					  reg_rule_5g, max_bw_5g);
5021 
5022 	if (num_2g_reg_rules != 0)
5023 		reg_populate_band_channels(MIN_24GHZ_CHANNEL, MAX_24GHZ_CHANNEL,
5024 					   reg_rule_2g, num_2g_reg_rules,
5025 					   min_bw_2g, mas_chan_list);
5026 
5027 	if (num_5g_reg_rules != 0) {
5028 		reg_populate_band_channels(MIN_5GHZ_CHANNEL, MAX_5GHZ_CHANNEL,
5029 					   reg_rule_5g, num_5g_reg_rules,
5030 					   min_bw_5g, mas_chan_list);
5031 		reg_populate_49g_band_channels(reg_rule_5g,
5032 					       num_5g_reg_rules,
5033 					       min_bw_5g,
5034 					       mas_chan_list);
5035 		reg_populate_6g_band_channels(reg_rule_5g,
5036 					      num_5g_reg_rules,
5037 					      min_bw_5g,
5038 					      mas_chan_list);
5039 	}
5040 
5041 	soc_reg->chan_list_recvd[phy_id] = true;
5042 	status = reg_send_ctl_info(soc_reg, regulat_info, tx_ops);
5043 	if (!QDF_IS_STATUS_SUCCESS(status))
5044 		return status;
5045 
5046 	if (soc_reg->new_user_ctry_pending[phy_id]) {
5047 		soc_reg->new_user_ctry_pending[phy_id] = false;
5048 		soc_reg->cc_src = SOURCE_USERSPACE;
5049 		soc_reg->user_ctry_set = true;
5050 		reg_debug("new user country is set");
5051 		reg_run_11d_state_machine(psoc);
5052 	} else if (soc_reg->new_init_ctry_pending[phy_id]) {
5053 		soc_reg->new_init_ctry_pending[phy_id] = false;
5054 		soc_reg->cc_src = SOURCE_USERSPACE;
5055 		reg_debug("new init country is set");
5056 	} else if (soc_reg->new_11d_ctry_pending[phy_id]) {
5057 		soc_reg->new_11d_ctry_pending[phy_id] = false;
5058 		soc_reg->cc_src = SOURCE_11D;
5059 		soc_reg->user_ctry_set = false;
5060 		reg_run_11d_state_machine(psoc);
5061 	} else if (soc_reg->world_country_pending[phy_id]) {
5062 		soc_reg->world_country_pending[phy_id] = false;
5063 		soc_reg->cc_src = SOURCE_CORE;
5064 		soc_reg->user_ctry_set = false;
5065 		reg_run_11d_state_machine(psoc);
5066 	} else {
5067 		if (soc_reg->cc_src == SOURCE_UNKNOWN &&
5068 		    soc_reg->num_phy == phy_id + 1)
5069 			soc_reg->cc_src = SOURCE_DRIVER;
5070 
5071 		qdf_mem_copy(soc_reg->mas_chan_params[phy_id].default_country,
5072 			     regulat_info->alpha2,
5073 			     REG_ALPHA2_LEN + 1);
5074 
5075 		soc_reg->mas_chan_params[phy_id].def_country_code =
5076 			regulat_info->ctry_code;
5077 		soc_reg->mas_chan_params[phy_id].def_region_domain =
5078 			regulat_info->reg_dmn_pair;
5079 
5080 		if (soc_reg->cc_src == SOURCE_DRIVER) {
5081 			qdf_mem_copy(soc_reg->def_country,
5082 				     regulat_info->alpha2,
5083 				     REG_ALPHA2_LEN + 1);
5084 
5085 			soc_reg->def_country_code = regulat_info->ctry_code;
5086 			soc_reg->def_region_domain =
5087 				regulat_info->reg_dmn_pair;
5088 
5089 			if (reg_is_world_alpha2(regulat_info->alpha2)) {
5090 				soc_reg->cc_src = SOURCE_CORE;
5091 				reg_run_11d_state_machine(psoc);
5092 			}
5093 		}
5094 	}
5095 
5096 	status = reg_set_psoc_fcc_rules(soc_reg, regulat_info);
5097 	if (!QDF_IS_STATUS_SUCCESS(status))
5098 		return status;
5099 
5100 	pdev = wlan_objmgr_get_pdev_by_id(psoc, pdev_id, dbg_id);
5101 	if (pdev) {
5102 		reg_propagate_mas_chan_list_to_pdev(psoc, pdev, &dir);
5103 		wlan_objmgr_pdev_release_ref(pdev, dbg_id);
5104 	}
5105 
5106 	return QDF_STATUS_SUCCESS;
5107 }
5108 
5109 QDF_STATUS reg_get_current_chan_list(struct wlan_objmgr_pdev *pdev,
5110 				     struct regulatory_channel *chan_list)
5111 {
5112 	struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj;
5113 
5114 	pdev_priv_obj = reg_get_pdev_obj(pdev);
5115 
5116 	if (!IS_VALID_PDEV_REG_OBJ(pdev_priv_obj)) {
5117 		reg_err("reg pdev private obj is NULL");
5118 		return QDF_STATUS_E_FAILURE;
5119 	}
5120 
5121 	qdf_mem_copy(chan_list, pdev_priv_obj->cur_chan_list,
5122 		     NUM_CHANNELS * sizeof(struct regulatory_channel));
5123 
5124 	return QDF_STATUS_SUCCESS;
5125 }
5126 
5127 #ifdef CONFIG_REG_CLIENT
5128 QDF_STATUS
5129 reg_get_secondary_current_chan_list(struct wlan_objmgr_pdev *pdev,
5130 				    struct regulatory_channel *chan_list)
5131 {
5132 	struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj;
5133 
5134 	pdev_priv_obj = reg_get_pdev_obj(pdev);
5135 
5136 	if (!IS_VALID_PDEV_REG_OBJ(pdev_priv_obj)) {
5137 		reg_err("reg pdev private obj is NULL");
5138 		return QDF_STATUS_E_FAILURE;
5139 	}
5140 
5141 	qdf_mem_copy(chan_list, pdev_priv_obj->secondary_cur_chan_list,
5142 		     NUM_CHANNELS * sizeof(struct regulatory_channel));
5143 
5144 	return QDF_STATUS_SUCCESS;
5145 }
5146 #endif
5147 
5148 #if defined(CONFIG_AFC_SUPPORT) && defined(CONFIG_BAND_6GHZ)
5149 QDF_STATUS reg_get_6g_afc_chan_list(struct wlan_objmgr_pdev *pdev,
5150 				    struct regulatory_channel *chan_list)
5151 {
5152 	struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj;
5153 	struct regulatory_channel *afc_chan_list;
5154 
5155 	pdev_priv_obj = reg_get_pdev_obj(pdev);
5156 
5157 	if (!IS_VALID_PDEV_REG_OBJ(pdev_priv_obj)) {
5158 		reg_err("reg pdev private obj is NULL");
5159 		return QDF_STATUS_E_FAILURE;
5160 	}
5161 
5162 	afc_chan_list = pdev_priv_obj->afc_chan_list;
5163 	qdf_mem_copy(chan_list, afc_chan_list,
5164 		     NUM_6GHZ_CHANNELS * sizeof(struct regulatory_channel));
5165 
5166 	return QDF_STATUS_SUCCESS;
5167 }
5168 
5169 QDF_STATUS
5170 reg_get_6g_afc_mas_chan_list(struct wlan_objmgr_pdev *pdev,
5171 			     struct regulatory_channel *chan_list)
5172 {
5173 	struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj;
5174 
5175 	pdev_priv_obj = reg_get_pdev_obj(pdev);
5176 
5177 	if (!IS_VALID_PDEV_REG_OBJ(pdev_priv_obj)) {
5178 		reg_err("reg pdev private obj is NULL");
5179 		return QDF_STATUS_E_FAILURE;
5180 	}
5181 
5182 	qdf_mem_copy(chan_list, pdev_priv_obj->mas_chan_list_6g_afc,
5183 		     NUM_6GHZ_CHANNELS * sizeof(struct regulatory_channel));
5184 
5185 	return QDF_STATUS_SUCCESS;
5186 }
5187 #endif
5188 
5189 #ifdef CONFIG_BAND_6GHZ
5190 /**
5191  * struct bw_10log10_pair - The bandwidth and 10*log10(bandwidth) pair.
5192  * ten_l_len = trunc(10*log10(bw)).  'trunc' is truncation function.
5193  * @bw: The input bandwidth
5194  * @ten_l_ten: Integer value of 10 times the Logarithm (to the base-10) of the
5195  * input bandwidth(@bw).
5196  */
5197 struct bw_10log10_pair {
5198 	uint16_t bw;
5199 	int16_t ten_l_ten;
5200 };
5201 
5202 /* The array of bandwidth to trunc(10log10(bandwidth)) mapping */
5203 static const struct bw_10log10_pair bw_to_10log10_map[] = {
5204 	{ 20, 13}, /* 10* 1.30102 = 13.0102 */
5205 	{ 40, 16}, /* 10* 1.60205 = 16.0205 */
5206 	{ 80, 19}, /* 10* 1.90308 = 19.0308 */
5207 	{160, 22}, /* 10* 2.20411 = 22.0411 */
5208 #ifdef WLAN_FEATURE_11BE
5209 	{320, 25}, /* 10* 2.50514 = 25.0514 */
5210 	{ 60, 18}, /* 10* 1.77815 = 17.7815 */
5211 	{140, 21}, /* 10* 2.14612 = 21.4612 */
5212 	{120, 21}, /* 10* 2.07918 = 20.7918 */
5213 	{200, 23}, /* 10* 2.30102 = 23.0102 */
5214 	{240, 24}, /* 10* 2.38021 = 23.8021 */
5215 	{280, 24}, /* 10* 2.44715 = 24.4715 */
5216 #endif
5217 };
5218 
5219 QDF_STATUS reg_psd_2_eirp(struct wlan_objmgr_pdev *pdev,
5220 			  int16_t psd,
5221 			  uint16_t ch_bw,
5222 			  int16_t *eirp)
5223 {
5224 	struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj;
5225 	int16_t ten_log10_bw;
5226 	uint8_t i;
5227 	uint8_t num_bws;
5228 
5229 	pdev_priv_obj = reg_get_pdev_obj(pdev);
5230 
5231 	if (!IS_VALID_PDEV_REG_OBJ(pdev_priv_obj)) {
5232 		reg_err("reg pdev private obj is NULL");
5233 		return QDF_STATUS_E_FAILURE;
5234 	}
5235 
5236 	/* EIRP = PSD + (10 * log10(CH_BW)) */
5237 	num_bws = QDF_ARRAY_SIZE(bw_to_10log10_map);
5238 	for (i = 0; i < num_bws; i++) {
5239 		if (ch_bw == bw_to_10log10_map[i].bw) {
5240 			ten_log10_bw = bw_to_10log10_map[i].ten_l_ten;
5241 			*eirp = psd + ten_log10_bw;
5242 			return QDF_STATUS_SUCCESS;
5243 		}
5244 	}
5245 	reg_err("Invalid input bandwidth %hd", ch_bw);
5246 	return QDF_STATUS_E_FAILURE;
5247 }
5248 
5249 QDF_STATUS reg_eirp_2_psd(struct wlan_objmgr_pdev *pdev,
5250 			  uint16_t ch_bw,
5251 			  int16_t eirp,
5252 			  int16_t *psd)
5253 {
5254 	struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj;
5255 	int16_t ten_log10_bw;
5256 	uint8_t i;
5257 	uint8_t num_bws;
5258 
5259 	pdev_priv_obj = reg_get_pdev_obj(pdev);
5260 
5261 	if (!IS_VALID_PDEV_REG_OBJ(pdev_priv_obj)) {
5262 		reg_err("reg pdev private obj is NULL");
5263 		return QDF_STATUS_E_FAILURE;
5264 	}
5265 
5266 	/* EIRP = PSD + (10 * log10(CH_BW)) */
5267 	num_bws = QDF_ARRAY_SIZE(bw_to_10log10_map);
5268 	for (i = 0; i < num_bws; i++) {
5269 		if (ch_bw == bw_to_10log10_map[i].bw) {
5270 			ten_log10_bw = bw_to_10log10_map[i].ten_l_ten;
5271 			*psd = eirp - ten_log10_bw;
5272 			return QDF_STATUS_SUCCESS;
5273 		}
5274 	}
5275 	reg_err("Invalid input bandwidth %hd", ch_bw);
5276 	return QDF_STATUS_E_FAILURE;
5277 }
5278 #endif
5279