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