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