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