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