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