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