xref: /wlan-dirver/qca-wifi-host-cmn/umac/regulatory/core/src/reg_build_chan_list.c (revision 45a38684b07295822dc8eba39e293408f203eec8)
1 /*
2  * Copyright (c) 2014-2020 The Linux Foundation. All rights reserved.
3  *
4  * Permission to use, copy, modify, and/or distribute this software for
5  * any purpose with or without fee is hereby granted, provided that the
6  * above copyright notice and this permission notice appear in all
7  * copies.
8  *
9  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
10  * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
11  * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
12  * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
13  * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
14  * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
15  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
16  * PERFORMANCE OF THIS SOFTWARE.
17  */
18 
19 /**
20  * DOC: reg_build_chan_list.c
21  * This file defines the API to build master and current channel list.
22  */
23 
24 #include <wlan_cmn.h>
25 #include <reg_services_public_struct.h>
26 #include <wlan_objmgr_psoc_obj.h>
27 #include <wlan_objmgr_pdev_obj.h>
28 #include "reg_priv_objs.h"
29 #include "reg_utils.h"
30 #include "reg_callbacks.h"
31 #include "reg_services_common.h"
32 #include "reg_db.h"
33 #include "reg_db_parser.h"
34 #include "reg_offload_11d_scan.h"
35 #include <scheduler_api.h>
36 #include "reg_build_chan_list.h"
37 #include <qdf_platform.h>
38 
39 #define MAX_PWR_FCC_CHAN_12 8
40 #define MAX_PWR_FCC_CHAN_13 2
41 #define CHAN_144_CENT_FREQ 5720
42 
43 /**
44  * reg_fill_channel_info() - Populate TX power, antenna gain, channel state,
45  * channel flags, min and max bandwidth to master channel list.
46  * @chan_enum: Channel enum.
47  * @reg_rule: Pointer to regulatory rule which has tx power and antenna gain.
48  * @master_list: Pointer to master channel list.
49  * @min_bw: minimum bandwidth to be used for given channel.
50  */
51 static void reg_fill_channel_info(enum channel_enum chan_enum,
52 				  struct cur_reg_rule *reg_rule,
53 				  struct regulatory_channel *master_list,
54 				  uint16_t min_bw)
55 {
56 	master_list[chan_enum].chan_flags &= ~REGULATORY_CHAN_DISABLED;
57 
58 	master_list[chan_enum].tx_power = reg_rule->reg_power;
59 	master_list[chan_enum].ant_gain = reg_rule->ant_gain;
60 	master_list[chan_enum].state = CHANNEL_STATE_ENABLE;
61 
62 	if (reg_rule->flags & REGULATORY_CHAN_NO_IR) {
63 		master_list[chan_enum].chan_flags |= REGULATORY_CHAN_NO_IR;
64 		master_list[chan_enum].state = CHANNEL_STATE_DFS;
65 	}
66 
67 	if (reg_rule->flags & REGULATORY_CHAN_RADAR) {
68 		master_list[chan_enum].chan_flags |= REGULATORY_CHAN_RADAR;
69 		master_list[chan_enum].state = CHANNEL_STATE_DFS;
70 	}
71 
72 	if (reg_rule->flags & REGULATORY_CHAN_INDOOR_ONLY)
73 		master_list[chan_enum].chan_flags |=
74 			REGULATORY_CHAN_INDOOR_ONLY;
75 
76 	if (reg_rule->flags & REGULATORY_CHAN_NO_OFDM)
77 		master_list[chan_enum].chan_flags |= REGULATORY_CHAN_NO_OFDM;
78 
79 	master_list[chan_enum].min_bw = min_bw;
80 	if (master_list[chan_enum].max_bw == 20)
81 		master_list[chan_enum].max_bw = reg_rule->max_bw;
82 }
83 
84 /**
85  * reg_populate_band_channels() - For all the valid regdb channels in the master
86  * channel list, find the regulatory rules and call reg_fill_channel_info() to
87  * populate master channel list with txpower, antennagain, BW info, etc.
88  * @start_chan: Start channel enum.
89  * @end_chan: End channel enum.
90  * @rule_start_ptr: Pointer to regulatory rules.
91  * @num_reg_rules: Number of regulatory rules.
92  * @min_reg_bw: Minimum regulatory bandwidth.
93  * @mas_chan_list: Pointer to master channel list.
94  */
95 static void reg_populate_band_channels(enum channel_enum start_chan,
96 				       enum channel_enum end_chan,
97 				       struct cur_reg_rule *rule_start_ptr,
98 				       uint32_t num_reg_rules,
99 				       uint16_t min_reg_bw,
100 				       struct regulatory_channel *mas_chan_list)
101 {
102 	struct cur_reg_rule *found_rule_ptr;
103 	struct cur_reg_rule *cur_rule_ptr;
104 	struct regulatory_channel;
105 	enum channel_enum chan_enum;
106 	uint32_t rule_num, bw;
107 	uint16_t max_bw;
108 	uint16_t min_bw;
109 
110 	for (chan_enum = start_chan; chan_enum <= end_chan; chan_enum++) {
111 		found_rule_ptr = NULL;
112 
113 		max_bw = QDF_MIN((uint16_t)20, channel_map[chan_enum].max_bw);
114 		min_bw = QDF_MAX(min_reg_bw, channel_map[chan_enum].min_bw);
115 
116 		if (channel_map[chan_enum].chan_num == INVALID_CHANNEL_NUM)
117 			continue;
118 
119 		for (bw = max_bw; bw >= min_bw; bw = bw / 2) {
120 			for (rule_num = 0, cur_rule_ptr = rule_start_ptr;
121 			     rule_num < num_reg_rules;
122 			     cur_rule_ptr++, rule_num++) {
123 				if ((cur_rule_ptr->start_freq <=
124 				     mas_chan_list[chan_enum].center_freq -
125 				     bw / 2) &&
126 				    (cur_rule_ptr->end_freq >=
127 				     mas_chan_list[chan_enum].center_freq +
128 				     bw / 2) && (min_bw <= bw)) {
129 					found_rule_ptr = cur_rule_ptr;
130 					break;
131 				}
132 			}
133 
134 			if (found_rule_ptr)
135 				break;
136 		}
137 
138 		if (found_rule_ptr) {
139 			mas_chan_list[chan_enum].max_bw = bw;
140 			reg_fill_channel_info(chan_enum, found_rule_ptr,
141 					      mas_chan_list, min_bw);
142 			/* Disable 2.4 Ghz channels that dont have 20 mhz bw */
143 			if (start_chan == MIN_24GHZ_CHANNEL &&
144 			    mas_chan_list[chan_enum].max_bw < 20) {
145 				mas_chan_list[chan_enum].chan_flags |=
146 						REGULATORY_CHAN_DISABLED;
147 				mas_chan_list[chan_enum].state =
148 						CHANNEL_STATE_DISABLE;
149 			}
150 		}
151 	}
152 }
153 
154 /**
155  * reg_update_max_bw_per_rule() - Update max bandwidth value for given regrules.
156  * @num_reg_rules: Number of regulatory rules.
157  * @reg_rule_start: Pointer to regulatory rules.
158  * @max_bw: Maximum bandwidth
159  */
160 static void reg_update_max_bw_per_rule(uint32_t num_reg_rules,
161 				       struct cur_reg_rule *reg_rule_start,
162 				       uint16_t max_bw)
163 {
164 	uint32_t count;
165 
166 	for (count = 0; count < num_reg_rules; count++)
167 		reg_rule_start[count].max_bw =
168 			min(reg_rule_start[count].max_bw, max_bw);
169 }
170 
171 /**
172  * reg_do_auto_bw_correction() - Calculate and update the maximum bandwidth
173  * value.
174  * @num_reg_rules: Number of regulatory rules.
175  * @reg_rule_ptr: Pointer to regulatory rules.
176  * @max_bw: Maximum bandwidth
177  */
178 static void reg_do_auto_bw_correction(uint32_t num_reg_rules,
179 				      struct cur_reg_rule *reg_rule_ptr,
180 				      uint16_t max_bw)
181 {
182 	uint32_t count;
183 	uint16_t new_bw;
184 
185 	for (count = 0; count < num_reg_rules - 1; count++) {
186 		if (reg_rule_ptr[count].end_freq ==
187 		    reg_rule_ptr[count + 1].start_freq) {
188 			new_bw = QDF_MIN(max_bw, reg_rule_ptr[count].max_bw +
189 					 reg_rule_ptr[count + 1].max_bw);
190 			reg_rule_ptr[count].max_bw = new_bw;
191 			reg_rule_ptr[count + 1].max_bw = new_bw;
192 		}
193 	}
194 }
195 
196 /**
197  * reg_modify_chan_list_for_dfs_channels() - disable the DFS channels if
198  * dfs_enable set to false.
199  * @chan_list: Pointer to regulatory channel list.
200  * @dfs_enabled: if false, then disable the DFS channels.
201  */
202 static void reg_modify_chan_list_for_dfs_channels(
203 		struct regulatory_channel *chan_list, bool dfs_enabled)
204 {
205 	enum channel_enum chan_enum;
206 
207 	if (dfs_enabled)
208 		return;
209 
210 	for (chan_enum = 0; chan_enum < NUM_CHANNELS; chan_enum++) {
211 		if (chan_list[chan_enum].state == CHANNEL_STATE_DFS) {
212 			chan_list[chan_enum].state = CHANNEL_STATE_DISABLE;
213 			chan_list[chan_enum].chan_flags |=
214 				REGULATORY_CHAN_DISABLED;
215 		}
216 	}
217 }
218 
219 /**
220  * reg_modify_chan_list_for_indoor_channels() - Disable the indoor channels if
221  * indoor_chan_enabled flag is set to false.
222  * @pdev_priv_obj: Pointer to regulatory private pdev structure.
223  */
224 static void reg_modify_chan_list_for_indoor_channels(
225 		struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj)
226 {
227 	enum channel_enum chan_enum;
228 	struct regulatory_channel *chan_list = pdev_priv_obj->cur_chan_list;
229 
230 	if (!pdev_priv_obj->indoor_chan_enabled) {
231 		for (chan_enum = 0; chan_enum < NUM_CHANNELS; chan_enum++) {
232 			if (REGULATORY_CHAN_INDOOR_ONLY &
233 			    chan_list[chan_enum].chan_flags) {
234 				chan_list[chan_enum].state =
235 					CHANNEL_STATE_DFS;
236 				chan_list[chan_enum].chan_flags |=
237 					REGULATORY_CHAN_NO_IR;
238 			}
239 		}
240 	}
241 
242 	if (pdev_priv_obj->force_ssc_disable_indoor_channel &&
243 	    pdev_priv_obj->sap_state) {
244 		for (chan_enum = 0; chan_enum < NUM_CHANNELS; chan_enum++) {
245 			if (REGULATORY_CHAN_INDOOR_ONLY &
246 			    chan_list[chan_enum].chan_flags) {
247 				chan_list[chan_enum].state =
248 					CHANNEL_STATE_DISABLE;
249 				chan_list[chan_enum].chan_flags |=
250 					REGULATORY_CHAN_DISABLED;
251 			}
252 		}
253 	}
254 }
255 
256 /**
257  * reg_modify_chan_list_for_band() - Based on the input band bitmap, either
258  * disable 2GHz, 5GHz, or 6GHz channels.
259  * @chan_list: Pointer to regulatory channel list.
260  * @band_bitmap: Input bitmap of reg_wifi_band values.
261  */
262 static void reg_modify_chan_list_for_band(struct regulatory_channel *chan_list,
263 					  uint32_t band_bitmap)
264 {
265 	enum channel_enum chan_enum;
266 
267 	if (!band_bitmap)
268 		return;
269 
270 	if (!(band_bitmap & BIT(REG_BAND_5G))) {
271 		reg_debug("disabling 5G");
272 		for (chan_enum = MIN_5GHZ_CHANNEL;
273 		     chan_enum <= MAX_5GHZ_CHANNEL; chan_enum++) {
274 			chan_list[chan_enum].chan_flags |=
275 				REGULATORY_CHAN_DISABLED;
276 			chan_list[chan_enum].state = CHANNEL_STATE_DISABLE;
277 		}
278 	}
279 
280 	if (!(band_bitmap & BIT(REG_BAND_2G))) {
281 		reg_debug("disabling 2G");
282 		for (chan_enum = MIN_24GHZ_CHANNEL;
283 		     chan_enum <= MAX_24GHZ_CHANNEL; chan_enum++) {
284 			chan_list[chan_enum].chan_flags |=
285 				REGULATORY_CHAN_DISABLED;
286 			chan_list[chan_enum].state = CHANNEL_STATE_DISABLE;
287 		}
288 	}
289 
290 	if (!(band_bitmap & BIT(REG_BAND_6G))) {
291 		reg_debug("disabling 6G");
292 		for (chan_enum = MIN_6GHZ_CHANNEL;
293 		     chan_enum <= MAX_6GHZ_CHANNEL; chan_enum++) {
294 			chan_list[chan_enum].chan_flags |=
295 				REGULATORY_CHAN_DISABLED;
296 			chan_list[chan_enum].state = CHANNEL_STATE_DISABLE;
297 		}
298 	}
299 }
300 
301 /**
302  * reg_modify_chan_list_for_fcc_channel() - Set maximum FCC txpower for channel
303  * 12 and 13 if set_fcc_channel flag is set to true.
304  * @chan_list: Pointer to regulatory channel list.
305  * @set_fcc_channel: If this flag is set to true, then set the max FCC txpower
306  * for channel 12 and 13.
307  */
308 static void reg_modify_chan_list_for_fcc_channel(
309 		struct regulatory_channel *chan_list, bool set_fcc_channel)
310 {
311 	enum channel_enum chan_enum;
312 
313 	if (!set_fcc_channel)
314 		return;
315 
316 	for (chan_enum = 0; chan_enum < NUM_CHANNELS; chan_enum++) {
317 		if (chan_list[chan_enum].center_freq == CHAN_12_CENT_FREQ)
318 			chan_list[chan_enum].tx_power = MAX_PWR_FCC_CHAN_12;
319 
320 		if (chan_list[chan_enum].center_freq == CHAN_13_CENT_FREQ)
321 			chan_list[chan_enum].tx_power = MAX_PWR_FCC_CHAN_13;
322 	}
323 }
324 
325 /**
326  * reg_modify_chan_list_for_chan_144() - Disable channel 144 if en_chan_144 flag
327  * is set to false.
328  * @chan_list: Pointer to regulatory channel list.
329  * @en_chan_144: if false, then disable channel 144.
330  */
331 static void reg_modify_chan_list_for_chan_144(
332 		struct regulatory_channel *chan_list, bool en_chan_144)
333 {
334 	enum channel_enum chan_enum;
335 
336 	if (en_chan_144)
337 		return;
338 
339 	for (chan_enum = 0; chan_enum < NUM_CHANNELS; chan_enum++) {
340 		if (chan_list[chan_enum].center_freq == CHAN_144_CENT_FREQ) {
341 			chan_list[chan_enum].chan_flags |=
342 				REGULATORY_CHAN_DISABLED;
343 			chan_list[chan_enum].state = CHANNEL_STATE_DISABLE;
344 		}
345 	}
346 }
347 
348 /**
349  * reg_modify_chan_list_for_nol_list() - Disable the channel if nol_chan flag is
350  * set.
351  * @chan_list: Pointer to regulatory channel list.
352  */
353 static void reg_modify_chan_list_for_nol_list(
354 		struct regulatory_channel *chan_list)
355 {
356 	enum channel_enum chan_enum;
357 
358 	for (chan_enum = 0; chan_enum < NUM_CHANNELS; chan_enum++) {
359 		if (chan_list[chan_enum].nol_chan) {
360 			chan_list[chan_enum].state = CHANNEL_STATE_DISABLE;
361 			chan_list[chan_enum].chan_flags |=
362 				REGULATORY_CHAN_DISABLED;
363 		}
364 	}
365 }
366 
367 /**
368  * reg_find_low_limit_chan_enum() - Find low limit 2G and 5G channel enums.
369  * @chan_list: Pointer to regulatory channel list.
370  * @low_freq: low limit frequency.
371  * @low_limit: pointer to output low limit enum.
372  *
373  * Return: None
374  */
375 static void reg_find_low_limit_chan_enum(
376 		struct regulatory_channel *chan_list, qdf_freq_t low_freq,
377 		uint32_t *low_limit)
378 {
379 	enum channel_enum chan_enum;
380 	uint16_t min_bw;
381 	uint16_t max_bw;
382 	qdf_freq_t center_freq;
383 
384 	for (chan_enum = 0; chan_enum < NUM_CHANNELS; chan_enum++) {
385 		min_bw = chan_list[chan_enum].min_bw;
386 		max_bw = chan_list[chan_enum].max_bw;
387 		center_freq = chan_list[chan_enum].center_freq;
388 
389 		if ((center_freq - min_bw / 2) >= low_freq) {
390 			if ((center_freq - max_bw / 2) < low_freq) {
391 				if (max_bw <= 20)
392 					max_bw = ((center_freq - low_freq) * 2);
393 				if (max_bw < min_bw)
394 					max_bw = min_bw;
395 				chan_list[chan_enum].max_bw = max_bw;
396 			}
397 			*low_limit = chan_enum;
398 			break;
399 		}
400 	}
401 }
402 
403 /**
404  * reg_find_high_limit_chan_enum() - Find high limit 2G and 5G channel enums.
405  * @chan_list: Pointer to regulatory channel list.
406  * @high_freq: high limit frequency.
407  * @high_limit: pointer to output high limit enum.
408  *
409  * Return: None
410  */
411 static void reg_find_high_limit_chan_enum(
412 		struct regulatory_channel *chan_list, qdf_freq_t high_freq,
413 		uint32_t *high_limit)
414 {
415 	enum channel_enum chan_enum;
416 	uint16_t min_bw;
417 	uint16_t max_bw;
418 	qdf_freq_t center_freq;
419 
420 	for (chan_enum = NUM_CHANNELS - 1; chan_enum >= 0; chan_enum--) {
421 		min_bw = chan_list[chan_enum].min_bw;
422 		max_bw = chan_list[chan_enum].max_bw;
423 		center_freq = chan_list[chan_enum].center_freq;
424 
425 		if (center_freq + min_bw / 2 <= high_freq) {
426 			if ((center_freq + max_bw / 2) > high_freq) {
427 				if (max_bw <= 20)
428 					max_bw = ((high_freq -
429 						   center_freq) * 2);
430 				if (max_bw < min_bw)
431 					max_bw = min_bw;
432 				chan_list[chan_enum].max_bw = max_bw;
433 			}
434 			*high_limit = chan_enum;
435 			break;
436 		}
437 
438 		if (chan_enum == 0)
439 			break;
440 	}
441 }
442 
443 #ifdef REG_DISABLE_JP_CH144
444 /**
445  * reg_modify_chan_list_for_japan() - Disable channel 144 for MKK17_MKKC
446  * regdomain by default.
447  * @pdev: Pointer to pdev
448  *
449  * Return: None
450  */
451 static void
452 reg_modify_chan_list_for_japan(struct wlan_objmgr_pdev *pdev)
453 {
454 #define MKK17_MKKC 0xE1
455 	struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj;
456 
457 	pdev_priv_obj = reg_get_pdev_obj(pdev);
458 	if (!IS_VALID_PDEV_REG_OBJ(pdev_priv_obj)) {
459 		reg_err("reg pdev priv obj is NULL");
460 		return;
461 	}
462 
463 	if (pdev_priv_obj->reg_dmn_pair == MKK17_MKKC)
464 		pdev_priv_obj->en_chan_144 = false;
465 
466 #undef MKK17_MKKC
467 }
468 #else
469 static inline void
470 reg_modify_chan_list_for_japan(struct wlan_objmgr_pdev *pdev)
471 {
472 }
473 #endif
474 /**
475  * reg_modify_chan_list_for_freq_range() - Modify channel list for the given low
476  * and high frequency range.
477  * @chan_list: Pointer to regulatory channel list.
478  * @low_freq_2g: Low frequency 2G.
479  * @high_freq_2g: High frequency 2G.
480  * @low_freq_5g: Low frequency 5G.
481  * @high_freq_5g: High frequency 5G.
482  *
483  * Return: None
484  */
485 static void
486 reg_modify_chan_list_for_freq_range(struct regulatory_channel *chan_list,
487 				    qdf_freq_t low_freq_2g,
488 				    qdf_freq_t high_freq_2g,
489 				    qdf_freq_t low_freq_5g,
490 				    qdf_freq_t high_freq_5g)
491 {
492 	uint32_t low_limit_2g = NUM_CHANNELS;
493 	uint32_t high_limit_2g = NUM_CHANNELS;
494 	uint32_t low_limit_5g = NUM_CHANNELS;
495 	uint32_t high_limit_5g = NUM_CHANNELS;
496 	enum channel_enum chan_enum;
497 	bool chan_in_range;
498 
499 	reg_find_low_limit_chan_enum(chan_list, low_freq_2g, &low_limit_2g);
500 	reg_find_low_limit_chan_enum(chan_list, low_freq_5g, &low_limit_5g);
501 	reg_find_high_limit_chan_enum(chan_list, high_freq_2g, &high_limit_2g);
502 	reg_find_high_limit_chan_enum(chan_list, high_freq_5g, &high_limit_5g);
503 
504 	for (chan_enum = 0; chan_enum < NUM_CHANNELS; chan_enum++) {
505 		chan_in_range = false;
506 		if  ((low_limit_2g <= chan_enum) &&
507 		     (high_limit_2g >= chan_enum) &&
508 		     (low_limit_2g != NUM_CHANNELS) &&
509 		     (high_limit_2g != NUM_CHANNELS))
510 			chan_in_range = true;
511 
512 		if  ((low_limit_5g <= chan_enum) &&
513 		     (high_limit_5g >= chan_enum) &&
514 		     (low_limit_5g != NUM_CHANNELS) &&
515 		     (high_limit_5g != NUM_CHANNELS))
516 			chan_in_range = true;
517 
518 		if (!chan_in_range) {
519 			chan_list[chan_enum].chan_flags |=
520 				REGULATORY_CHAN_DISABLED;
521 			chan_list[chan_enum].state = CHANNEL_STATE_DISABLE;
522 		}
523 	}
524 }
525 
526 void reg_init_pdev_mas_chan_list(
527 		struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj,
528 		struct mas_chan_params *mas_chan_params)
529 {
530 	qdf_mem_copy(pdev_priv_obj->mas_chan_list,
531 		     mas_chan_params->mas_chan_list,
532 		     NUM_CHANNELS * sizeof(struct regulatory_channel));
533 
534 	pdev_priv_obj->dfs_region = mas_chan_params->dfs_region;
535 
536 	pdev_priv_obj->phybitmap = mas_chan_params->phybitmap;
537 
538 	pdev_priv_obj->reg_dmn_pair = mas_chan_params->reg_dmn_pair;
539 	pdev_priv_obj->ctry_code =  mas_chan_params->ctry_code;
540 
541 	pdev_priv_obj->def_region_domain = mas_chan_params->reg_dmn_pair;
542 	pdev_priv_obj->def_country_code =  mas_chan_params->ctry_code;
543 
544 	qdf_mem_copy(pdev_priv_obj->default_country,
545 		     mas_chan_params->default_country, REG_ALPHA2_LEN + 1);
546 
547 	qdf_mem_copy(pdev_priv_obj->current_country,
548 		     mas_chan_params->current_country, REG_ALPHA2_LEN + 1);
549 }
550 
551 /**
552  * reg_modify_chan_list_for_cached_channels() - If num_cache_channels are
553  * non-zero, then disable the pdev channels which is given in
554  * cache_disable_chan_list.
555  * @pdev_priv_obj: Pointer to regulatory pdev private object.
556  */
557 #ifdef DISABLE_CHANNEL_LIST
558 static void reg_modify_chan_list_for_cached_channels(
559 		struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj)
560 {
561 	uint32_t i, j;
562 	uint32_t num_cache_channels = pdev_priv_obj->num_cache_channels;
563 	struct regulatory_channel *chan_list = pdev_priv_obj->cur_chan_list;
564 	struct regulatory_channel *cache_chan_list =
565 					pdev_priv_obj->cache_disable_chan_list;
566 
567 	if (!num_cache_channels)
568 		return;
569 
570 	if (pdev_priv_obj->disable_cached_channels) {
571 		for (i = 0; i < num_cache_channels; i++)
572 			for (j = 0; j < NUM_CHANNELS; j++)
573 				if (cache_chan_list[i].chan_num ==
574 							chan_list[j].chan_num) {
575 					chan_list[j].state =
576 							CHANNEL_STATE_DISABLE;
577 					chan_list[j].chan_flags |=
578 						REGULATORY_CHAN_DISABLED;
579 				}
580 	}
581 }
582 #else
583 static void reg_modify_chan_list_for_cached_channels(
584 		struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj)
585 {
586 }
587 #endif
588 
589 #ifdef CONFIG_REG_CLIENT
590 /**
591  * reg_modify_chan_list_for_srd_channels() - Modify SRD channels in ETSI13
592  * @pdev: Pointer to pdev object
593  * @chan_list: Current channel list
594  *
595  * This function converts SRD channels to passive in ETSI13 regulatory domain
596  * when enable_srd_chan_in_master_mode is not set.
597  */
598 static void
599 reg_modify_chan_list_for_srd_channels(struct wlan_objmgr_pdev *pdev,
600 				      struct regulatory_channel *chan_list)
601 {
602 	enum channel_enum chan_enum;
603 
604 	if (!reg_is_etsi13_regdmn(pdev))
605 		return;
606 
607 	if (reg_is_etsi13_srd_chan_allowed_master_mode(pdev))
608 		return;
609 
610 	for (chan_enum = 0; chan_enum < NUM_CHANNELS; chan_enum++) {
611 		if (chan_list[chan_enum].chan_flags & REGULATORY_CHAN_DISABLED)
612 			continue;
613 
614 		if (reg_is_etsi13_srd_chan(pdev,
615 					   chan_list[chan_enum].chan_num)) {
616 			chan_list[chan_enum].state =
617 				CHANNEL_STATE_DFS;
618 			chan_list[chan_enum].chan_flags |=
619 				REGULATORY_CHAN_NO_IR;
620 		}
621 	}
622 }
623 #else
624 static inline void
625 reg_modify_chan_list_for_srd_channels(struct wlan_objmgr_pdev *pdev,
626 				      struct regulatory_channel *chan_list)
627 {
628 }
629 #endif
630 
631 /**
632  * reg_modify_chan_list_for_5dot9_ghz_channels() - Modify 5.9 GHz channels
633  * in FCC
634  * @pdev: Pointer to pdev object
635  * @chan_list: Current channel list
636  *
637  * This function disables 5.9 GHz channels if service bit
638  * wmi_service_5dot9_ghz_support is not set or the reg db is not offloaded
639  * to FW. If service bit is set but ini enable_5dot9_ghz_chan_in_master_mode
640  * is not set, it converts these channels to passive in FCC regulatory domain.
641  * If both service bit and ini are set, the channels remain enabled.
642  */
643 static void
644 reg_modify_chan_list_for_5dot9_ghz_channels(struct wlan_objmgr_pdev *pdev,
645 					    struct regulatory_channel
646 					    *chan_list)
647 {
648 	enum channel_enum chan_enum;
649 	struct wlan_objmgr_psoc *psoc;
650 
651 	psoc = wlan_pdev_get_psoc(pdev);
652 
653 	if (!reg_is_fcc_regdmn(pdev))
654 		return;
655 
656 	if (!reg_is_5dot9_ghz_supported(psoc) ||
657 	    !reg_is_regdb_offloaded(psoc)) {
658 		for (chan_enum = 0; chan_enum < NUM_CHANNELS; chan_enum++) {
659 			if (reg_is_5dot9_ghz_freq(pdev, chan_list[chan_enum].
660 						  center_freq)) {
661 				chan_list[chan_enum].state =
662 					CHANNEL_STATE_DISABLE;
663 				chan_list[chan_enum].chan_flags =
664 					REGULATORY_CHAN_DISABLED;
665 			}
666 		}
667 		return;
668 	}
669 
670 	if (reg_is_5dot9_ghz_chan_allowed_master_mode(pdev))
671 		return;
672 
673 	for (chan_enum = 0; chan_enum < NUM_CHANNELS; chan_enum++) {
674 		if (chan_list[chan_enum].chan_flags & REGULATORY_CHAN_DISABLED)
675 			continue;
676 
677 		if (reg_is_5dot9_ghz_freq(pdev,
678 					  chan_list[chan_enum].center_freq)) {
679 			chan_list[chan_enum].state =
680 				CHANNEL_STATE_DFS;
681 			chan_list[chan_enum].chan_flags |=
682 				REGULATORY_CHAN_NO_IR;
683 		}
684 	}
685 }
686 
687 #ifdef DISABLE_UNII_SHARED_BANDS
688 /**
689  * reg_is_reg_unii_band_1_set() - Check UNII bitmap
690  * @unii_bitmap: 5G UNII band bitmap
691  *
692  * This function checks the input bitmap to disable UNII-1 band channels.
693  *
694  * Return: Return true if UNII-1 channels need to be disabled,
695  * else return false.
696  */
697 static bool reg_is_reg_unii_band_1_set(uint8_t unii_bitmap)
698 {
699 	return !!(unii_bitmap & BIT(REG_UNII_BAND_1));
700 }
701 
702 /**
703  * reg_is_reg_unii_band_2a_set() - Check UNII bitmap
704  * @unii_bitmap: 5G UNII band bitmap
705  *
706  * This function checks the input bitmap to disable UNII-2A band channels.
707  *
708  * Return: Return true if UNII-2A channels need to be disabled,
709  * else return false.
710  */
711 static bool reg_is_reg_unii_band_2a_set(uint8_t unii_bitmap)
712 {
713 	return !!(unii_bitmap & BIT(REG_UNII_BAND_2A));
714 }
715 
716 /**
717  * reg_is_5g_enum() - Check if channel enum is a 5G channel enum
718  * @chan_enum: channel enum
719  *
720  * Return: Return true if the input channel enum is 5G, else return false.
721  */
722 static bool reg_is_5g_enum(enum channel_enum chan_enum)
723 {
724 	return (chan_enum >= MIN_5GHZ_CHANNEL && chan_enum <= MAX_5GHZ_CHANNEL);
725 }
726 
727 /**
728  * reg_remove_unii_chan_from_chan_list() - Remove UNII band channels
729  * @chan_list: Pointer to current channel list
730  * @start_enum: starting enum value
731  * @end_enum: ending enum value
732  *
733  * Remove channels in a unii band based in on the input start_enum and end_enum.
734  * Disable the state and flags. Set disable_coex flag to true.
735  *
736  * return: void.
737  */
738 static void
739 reg_remove_unii_chan_from_chan_list(struct regulatory_channel *chan_list,
740 				    enum channel_enum start_enum,
741 				    enum channel_enum end_enum)
742 {
743 	enum channel_enum chan_enum;
744 
745 	if (!(reg_is_5g_enum(start_enum) && reg_is_5g_enum(end_enum))) {
746 		reg_err_rl("start_enum or end_enum is invalid");
747 		return;
748 	}
749 
750 	for (chan_enum = start_enum; chan_enum <= end_enum; chan_enum++) {
751 		chan_list[chan_enum].state = CHANNEL_STATE_DISABLE;
752 		chan_list[chan_enum].chan_flags |= REGULATORY_CHAN_DISABLED;
753 	}
754 }
755 
756 /**
757  * reg_modify_disable_chan_list_for_unii1_and_unii2a() - Disable UNII-1 and
758  * UNII2A band
759  * @pdev_priv_obj: Pointer to pdev private object
760  *
761  * This function disables the UNII-1 and UNII-2A band channels
762  * based on input unii_5g_bitmap.
763  *
764  * Return: void.
765  */
766 static void
767 reg_modify_disable_chan_list_for_unii1_and_unii2a(
768 		struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj)
769 {
770 	uint8_t unii_bitmap = pdev_priv_obj->unii_5g_bitmap;
771 	struct regulatory_channel *chan_list = pdev_priv_obj->cur_chan_list;
772 
773 	if (reg_is_reg_unii_band_1_set(unii_bitmap)) {
774 		reg_remove_unii_chan_from_chan_list(chan_list,
775 						    MIN_UNII_1_BAND_CHANNEL,
776 						    MAX_UNII_1_BAND_CHANNEL);
777 	}
778 
779 	if (reg_is_reg_unii_band_2a_set(unii_bitmap)) {
780 		reg_remove_unii_chan_from_chan_list(chan_list,
781 						    MIN_UNII_2A_BAND_CHANNEL,
782 						    MAX_UNII_2A_BAND_CHANNEL);
783 	}
784 }
785 #else
786 static inline bool reg_is_reg_unii_band_1_set(uint8_t unii_bitmap)
787 {
788 	return false;
789 }
790 
791 static inline bool reg_is_reg_unii_band_2a_set(uint8_t unii_bitmap)
792 {
793 	return false;
794 }
795 
796 static inline bool reg_is_5g_enum(enum channel_enum chan_enum)
797 {
798 	return false;
799 }
800 
801 static inline void
802 reg_remove_unii_chan_from_chan_list(struct regulatory_channel *chan_list,
803 				    enum channel_enum start_enum,
804 				    enum channel_enum end_enum)
805 {
806 }
807 
808 static inline void
809 reg_modify_disable_chan_list_for_unii1_and_unii2a(
810 		struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj)
811 {
812 }
813 #endif
814 
815 void reg_compute_pdev_current_chan_list(struct wlan_regulatory_pdev_priv_obj
816 					*pdev_priv_obj)
817 {
818 	qdf_mem_copy(pdev_priv_obj->cur_chan_list, pdev_priv_obj->mas_chan_list,
819 		     NUM_CHANNELS * sizeof(struct regulatory_channel));
820 
821 	reg_modify_chan_list_for_freq_range(pdev_priv_obj->cur_chan_list,
822 					    pdev_priv_obj->range_2g_low,
823 					    pdev_priv_obj->range_2g_high,
824 					    pdev_priv_obj->range_5g_low,
825 					    pdev_priv_obj->range_5g_high);
826 
827 	reg_modify_chan_list_for_band(pdev_priv_obj->cur_chan_list,
828 				      pdev_priv_obj->band_capability);
829 
830 	reg_modify_disable_chan_list_for_unii1_and_unii2a(pdev_priv_obj);
831 
832 	reg_modify_chan_list_for_dfs_channels(pdev_priv_obj->cur_chan_list,
833 					      pdev_priv_obj->dfs_enabled);
834 
835 	reg_modify_chan_list_for_nol_list(pdev_priv_obj->cur_chan_list);
836 
837 	reg_modify_chan_list_for_indoor_channels(pdev_priv_obj);
838 
839 	reg_modify_chan_list_for_fcc_channel(pdev_priv_obj->cur_chan_list,
840 					     pdev_priv_obj->set_fcc_channel);
841 
842 	reg_modify_chan_list_for_chan_144(pdev_priv_obj->cur_chan_list,
843 					  pdev_priv_obj->en_chan_144);
844 
845 	reg_modify_chan_list_for_cached_channels(pdev_priv_obj);
846 
847 	reg_modify_chan_list_for_srd_channels(pdev_priv_obj->pdev_ptr,
848 					      pdev_priv_obj->cur_chan_list);
849 
850 	reg_modify_chan_list_for_5dot9_ghz_channels(pdev_priv_obj->pdev_ptr,
851 						    pdev_priv_obj->
852 						    cur_chan_list);
853 }
854 
855 void reg_reset_reg_rules(struct reg_rule_info *reg_rules)
856 {
857 	qdf_mem_zero(reg_rules, sizeof(*reg_rules));
858 }
859 
860 void reg_save_reg_rules_to_pdev(
861 		struct reg_rule_info *psoc_reg_rules,
862 		struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj)
863 {
864 	uint32_t reg_rule_len;
865 	struct reg_rule_info *pdev_reg_rules;
866 
867 	qdf_spin_lock_bh(&pdev_priv_obj->reg_rules_lock);
868 
869 	pdev_reg_rules = &pdev_priv_obj->reg_rules;
870 	reg_reset_reg_rules(pdev_reg_rules);
871 
872 	pdev_reg_rules->num_of_reg_rules = psoc_reg_rules->num_of_reg_rules;
873 	if (!pdev_reg_rules->num_of_reg_rules) {
874 		qdf_spin_unlock_bh(&pdev_priv_obj->reg_rules_lock);
875 		reg_err("no reg rules in psoc");
876 		return;
877 	}
878 
879 	reg_rule_len = pdev_reg_rules->num_of_reg_rules *
880 		       sizeof(struct cur_reg_rule);
881 	qdf_mem_copy(pdev_reg_rules->reg_rules, psoc_reg_rules->reg_rules,
882 		     reg_rule_len);
883 
884 	qdf_mem_copy(pdev_reg_rules->alpha2, pdev_priv_obj->current_country,
885 		     REG_ALPHA2_LEN + 1);
886 	pdev_reg_rules->dfs_region = pdev_priv_obj->dfs_region;
887 
888 	qdf_spin_unlock_bh(&pdev_priv_obj->reg_rules_lock);
889 }
890 
891 void reg_propagate_mas_chan_list_to_pdev(struct wlan_objmgr_psoc *psoc,
892 					 void *object, void *arg)
893 {
894 	struct wlan_objmgr_pdev *pdev = (struct wlan_objmgr_pdev *)object;
895 	struct wlan_regulatory_psoc_priv_obj *psoc_priv_obj;
896 	struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj;
897 	enum direction *dir = arg;
898 	uint8_t pdev_id;
899 	uint8_t phy_id;
900 	struct wlan_lmac_if_reg_tx_ops *reg_tx_ops;
901 	struct reg_rule_info *psoc_reg_rules;
902 
903 	psoc_priv_obj = (struct wlan_regulatory_psoc_priv_obj *)
904 		wlan_objmgr_psoc_get_comp_private_obj(
905 				psoc, WLAN_UMAC_COMP_REGULATORY);
906 
907 	if (!psoc_priv_obj) {
908 		reg_err("psoc priv obj is NULL");
909 		return;
910 	}
911 
912 	pdev_priv_obj = reg_get_pdev_obj(pdev);
913 
914 	if (!IS_VALID_PDEV_REG_OBJ(pdev_priv_obj)) {
915 		reg_err("reg pdev priv obj is NULL");
916 		return;
917 	}
918 
919 	pdev_id = wlan_objmgr_pdev_get_pdev_id(pdev);
920 
921 	reg_tx_ops = reg_get_psoc_tx_ops(psoc);
922 	if (reg_tx_ops->get_phy_id_from_pdev_id)
923 		reg_tx_ops->get_phy_id_from_pdev_id(psoc, pdev_id, &phy_id);
924 	else
925 		phy_id = pdev_id;
926 
927 	reg_init_pdev_mas_chan_list(
928 			pdev_priv_obj,
929 			&psoc_priv_obj->mas_chan_params[phy_id]);
930 	psoc_reg_rules = &psoc_priv_obj->mas_chan_params[phy_id].reg_rules;
931 	reg_save_reg_rules_to_pdev(psoc_reg_rules, pdev_priv_obj);
932 	reg_modify_chan_list_for_japan(pdev);
933 	pdev_priv_obj->chan_list_recvd =
934 		psoc_priv_obj->chan_list_recvd[phy_id];
935 	reg_compute_pdev_current_chan_list(pdev_priv_obj);
936 
937 	if (reg_tx_ops->fill_umac_legacy_chanlist) {
938 		reg_tx_ops->fill_umac_legacy_chanlist(
939 				pdev, pdev_priv_obj->cur_chan_list);
940 	} else {
941 		if (*dir == NORTHBOUND)
942 			reg_send_scheduler_msg_nb(psoc, pdev);
943 		else
944 			reg_send_scheduler_msg_sb(psoc, pdev);
945 	}
946 }
947 
948 /**
949  * reg_populate_6g_band_channels() - For all the valid 6GHz regdb channels
950  * in the master channel list, find the regulatory rules and call
951  * reg_fill_channel_info() to populate master channel list with txpower,
952  * antennagain, BW info, etc.
953  * @reg_rule_5g: Pointer to regulatory rule.
954  * @num_5g_reg_rules: Number of regulatory rules.
955  * @min_bw_5g: Minimum regulatory bandwidth.
956  * @mas_chan_list: Pointer to the master channel list.
957  */
958 #ifdef CONFIG_BAND_6GHZ
959 static void
960 reg_populate_6g_band_channels(struct cur_reg_rule *reg_rule_5g,
961 			      uint32_t num_5g_reg_rules,
962 			      uint16_t min_bw_5g,
963 			      struct regulatory_channel *mas_chan_list)
964 {
965 	reg_populate_band_channels(MIN_6GHZ_CHANNEL,
966 				   MAX_6GHZ_CHANNEL,
967 				   reg_rule_5g,
968 				   num_5g_reg_rules,
969 				   min_bw_5g,
970 				   mas_chan_list);
971 }
972 #else
973 static void
974 reg_populate_6g_band_channels(struct cur_reg_rule *reg_rule_5g,
975 			      uint32_t num_5g_reg_rules,
976 			      uint16_t min_bw_5g,
977 			      struct regulatory_channel *mas_chan_list)
978 {
979 }
980 #endif /* CONFIG_BAND_6GHZ */
981 
982 #ifdef CONFIG_REG_CLIENT
983 /**
984  * reg_send_ctl_info() - Send CTL info to firmware when regdb is not offloaded
985  * @soc_reg: soc private object for regulatory
986  * @regulatory_info: regulatory info
987  * @tx_ops: send operations for regulatory component
988  *
989  * Return: QDF_STATUS
990  */
991 static QDF_STATUS
992 reg_send_ctl_info(struct wlan_regulatory_psoc_priv_obj *soc_reg,
993 		  struct cur_regulatory_info *regulatory_info,
994 		  struct wlan_lmac_if_reg_tx_ops *tx_ops)
995 {
996 	struct wlan_objmgr_psoc *psoc = regulatory_info->psoc;
997 	struct reg_ctl_params params = {0};
998 	QDF_STATUS status;
999 	uint16_t regd_index;
1000 	uint32_t index_2g, index_5g;
1001 
1002 	if (soc_reg->offload_enabled)
1003 		return QDF_STATUS_SUCCESS;
1004 
1005 	if (!tx_ops || !tx_ops->send_ctl_info) {
1006 		reg_err("No regulatory tx_ops");
1007 		return QDF_STATUS_E_FAULT;
1008 	}
1009 
1010 	status = reg_get_rdpair_from_regdmn_id(regulatory_info->reg_dmn_pair,
1011 					       &regd_index);
1012 	if (QDF_IS_STATUS_ERROR(status)) {
1013 		reg_err("Failed to get regdomain index for regdomain pair: %x",
1014 			regulatory_info->reg_dmn_pair);
1015 		return status;
1016 	}
1017 
1018 	index_2g = g_reg_dmn_pairs[regd_index].dmn_id_2g;
1019 	index_5g = g_reg_dmn_pairs[regd_index].dmn_id_5g;
1020 	params.ctl_2g = regdomains_2g[index_2g].ctl_val;
1021 	params.ctl_5g = regdomains_5g[index_5g].ctl_val;
1022 	params.regd_2g = reg_2g_sub_dmn_code[index_2g];
1023 	params.regd_5g = reg_5g_sub_dmn_code[index_5g];
1024 
1025 	if (reg_is_world_ctry_code(regulatory_info->reg_dmn_pair))
1026 		params.regd = regulatory_info->reg_dmn_pair;
1027 	else
1028 		params.regd = regulatory_info->ctry_code | COUNTRY_ERD_FLAG;
1029 
1030 	reg_debug("regdomain pair = %u, regdomain index = %u",
1031 		  regulatory_info->reg_dmn_pair, regd_index);
1032 	reg_debug("index_2g = %u, index_5g = %u, ctl_2g = %x, ctl_5g = %x",
1033 		  index_2g, index_5g, params.ctl_2g, params.ctl_5g);
1034 	reg_debug("regd_2g = %x, regd_5g = %x, regd = %x",
1035 		  params.regd_2g, params.regd_5g, params.regd);
1036 
1037 	status = tx_ops->send_ctl_info(psoc, &params);
1038 	if (QDF_IS_STATUS_ERROR(status))
1039 		reg_err("Failed to send CTL info to firmware");
1040 
1041 	return status;
1042 }
1043 #else
1044 static QDF_STATUS
1045 reg_send_ctl_info(struct wlan_regulatory_psoc_priv_obj *soc_reg,
1046 		  struct cur_regulatory_info *regulatory_info,
1047 		  struct wlan_lmac_if_reg_tx_ops *tx_ops)
1048 {
1049 	return QDF_STATUS_SUCCESS;
1050 }
1051 #endif
1052 
1053 QDF_STATUS reg_process_master_chan_list(
1054 		struct cur_regulatory_info *regulat_info)
1055 {
1056 	struct wlan_regulatory_psoc_priv_obj *soc_reg;
1057 	uint32_t num_2g_reg_rules, num_5g_reg_rules;
1058 	struct cur_reg_rule *reg_rule_2g, *reg_rule_5g;
1059 	uint16_t min_bw_2g, max_bw_2g, min_bw_5g, max_bw_5g;
1060 	struct regulatory_channel *mas_chan_list;
1061 	struct wlan_objmgr_psoc *psoc;
1062 	enum channel_enum chan_enum;
1063 	wlan_objmgr_ref_dbgid dbg_id;
1064 	enum direction dir;
1065 	uint8_t phy_id;
1066 	uint8_t pdev_id;
1067 	struct wlan_objmgr_pdev *pdev;
1068 	struct wlan_lmac_if_reg_tx_ops *tx_ops;
1069 	struct reg_rule_info *reg_rules;
1070 	QDF_STATUS status;
1071 
1072 	psoc = regulat_info->psoc;
1073 	soc_reg = reg_get_psoc_obj(psoc);
1074 
1075 	if (!IS_VALID_PSOC_REG_OBJ(soc_reg)) {
1076 		reg_err("psoc reg component is NULL");
1077 		return QDF_STATUS_E_FAILURE;
1078 	}
1079 
1080 	tx_ops = reg_get_psoc_tx_ops(psoc);
1081 	phy_id = regulat_info->phy_id;
1082 
1083 	if (tx_ops->get_pdev_id_from_phy_id)
1084 		tx_ops->get_pdev_id_from_phy_id(psoc, phy_id, &pdev_id);
1085 	else
1086 		pdev_id = phy_id;
1087 
1088 	if (reg_ignore_default_country(soc_reg, regulat_info)) {
1089 		status = reg_set_curr_country(soc_reg, regulat_info, tx_ops);
1090 		if (QDF_IS_STATUS_SUCCESS(status)) {
1091 			reg_debug("WLAN restart - Ignore default CC for phy_id: %u",
1092 				  phy_id);
1093 			return QDF_STATUS_SUCCESS;
1094 		}
1095 	}
1096 
1097 	reg_debug("process reg master chan list");
1098 
1099 	if (soc_reg->offload_enabled) {
1100 		dbg_id = WLAN_REGULATORY_NB_ID;
1101 		dir = NORTHBOUND;
1102 	} else {
1103 		dbg_id = WLAN_REGULATORY_SB_ID;
1104 		dir = SOUTHBOUND;
1105 	}
1106 
1107 	if (regulat_info->status_code != REG_SET_CC_STATUS_PASS) {
1108 		reg_err("Set country code failed, status code %d",
1109 			regulat_info->status_code);
1110 
1111 		pdev = wlan_objmgr_get_pdev_by_id(psoc, phy_id, dbg_id);
1112 		if (!pdev) {
1113 			reg_err("pdev is NULL");
1114 			return QDF_STATUS_E_FAILURE;
1115 		}
1116 
1117 		if (tx_ops->set_country_failed)
1118 			tx_ops->set_country_failed(pdev);
1119 
1120 		wlan_objmgr_pdev_release_ref(pdev, dbg_id);
1121 
1122 		if (regulat_info->status_code != REG_CURRENT_ALPHA2_NOT_FOUND)
1123 			return QDF_STATUS_E_FAILURE;
1124 
1125 		soc_reg->new_user_ctry_pending[phy_id] = false;
1126 		soc_reg->new_11d_ctry_pending[phy_id] = false;
1127 		soc_reg->world_country_pending[phy_id] = true;
1128 	}
1129 
1130 	mas_chan_list = soc_reg->mas_chan_params[phy_id].mas_chan_list;
1131 
1132 	reg_init_channel_map(regulat_info->dfs_region);
1133 
1134 	for (chan_enum = 0; chan_enum < NUM_CHANNELS;
1135 	     chan_enum++) {
1136 		mas_chan_list[chan_enum].chan_num =
1137 			channel_map[chan_enum].chan_num;
1138 		mas_chan_list[chan_enum].center_freq =
1139 			channel_map[chan_enum].center_freq;
1140 		mas_chan_list[chan_enum].chan_flags =
1141 			REGULATORY_CHAN_DISABLED;
1142 		mas_chan_list[chan_enum].state =
1143 			CHANNEL_STATE_DISABLE;
1144 		if (!soc_reg->retain_nol_across_regdmn_update)
1145 			mas_chan_list[chan_enum].nol_chan = false;
1146 	}
1147 
1148 	soc_reg->num_phy = regulat_info->num_phy;
1149 	soc_reg->mas_chan_params[phy_id].phybitmap =
1150 		regulat_info->phybitmap;
1151 	soc_reg->mas_chan_params[phy_id].dfs_region =
1152 		regulat_info->dfs_region;
1153 	soc_reg->mas_chan_params[phy_id].ctry_code =
1154 		regulat_info->ctry_code;
1155 	soc_reg->mas_chan_params[phy_id].reg_dmn_pair =
1156 		regulat_info->reg_dmn_pair;
1157 	qdf_mem_copy(soc_reg->mas_chan_params[phy_id].current_country,
1158 		     regulat_info->alpha2,
1159 		     REG_ALPHA2_LEN + 1);
1160 	qdf_mem_copy(soc_reg->cur_country,
1161 		     regulat_info->alpha2,
1162 		     REG_ALPHA2_LEN + 1);
1163 	reg_debug("set cur_country %.2s", soc_reg->cur_country);
1164 
1165 	min_bw_2g = regulat_info->min_bw_2g;
1166 	max_bw_2g = regulat_info->max_bw_2g;
1167 	reg_rule_2g = regulat_info->reg_rules_2g_ptr;
1168 	num_2g_reg_rules = regulat_info->num_2g_reg_rules;
1169 	reg_update_max_bw_per_rule(num_2g_reg_rules,
1170 				   reg_rule_2g, max_bw_2g);
1171 
1172 	min_bw_5g = regulat_info->min_bw_5g;
1173 	max_bw_5g = regulat_info->max_bw_5g;
1174 	reg_rule_5g = regulat_info->reg_rules_5g_ptr;
1175 	num_5g_reg_rules = regulat_info->num_5g_reg_rules;
1176 	reg_update_max_bw_per_rule(num_5g_reg_rules,
1177 				   reg_rule_5g, max_bw_5g);
1178 
1179 	reg_rules = &soc_reg->mas_chan_params[phy_id].reg_rules;
1180 	reg_reset_reg_rules(reg_rules);
1181 
1182 	reg_rules->num_of_reg_rules = num_5g_reg_rules + num_2g_reg_rules;
1183 	if (reg_rules->num_of_reg_rules > MAX_REG_RULES) {
1184 		reg_err("number of reg rules exceeds limit");
1185 		return QDF_STATUS_E_FAILURE;
1186 	}
1187 
1188 	if (reg_rules->num_of_reg_rules) {
1189 		if (num_2g_reg_rules)
1190 			qdf_mem_copy(reg_rules->reg_rules,
1191 				     reg_rule_2g, num_2g_reg_rules *
1192 				     sizeof(struct cur_reg_rule));
1193 		if (num_5g_reg_rules)
1194 			qdf_mem_copy(reg_rules->reg_rules +
1195 				     num_2g_reg_rules, reg_rule_5g,
1196 				     num_5g_reg_rules *
1197 				     sizeof(struct cur_reg_rule));
1198 	}
1199 
1200 	if (num_5g_reg_rules != 0)
1201 		reg_do_auto_bw_correction(num_5g_reg_rules,
1202 					  reg_rule_5g, max_bw_5g);
1203 
1204 	if (num_2g_reg_rules != 0)
1205 		reg_populate_band_channels(MIN_24GHZ_CHANNEL, MAX_24GHZ_CHANNEL,
1206 					   reg_rule_2g, num_2g_reg_rules,
1207 					   min_bw_2g, mas_chan_list);
1208 
1209 	if (num_5g_reg_rules != 0) {
1210 		reg_populate_band_channels(MIN_5GHZ_CHANNEL, MAX_5GHZ_CHANNEL,
1211 					   reg_rule_5g, num_5g_reg_rules,
1212 					   min_bw_5g, mas_chan_list);
1213 		reg_populate_band_channels(MIN_49GHZ_CHANNEL,
1214 					   MAX_49GHZ_CHANNEL,
1215 					   reg_rule_5g, num_5g_reg_rules,
1216 					   min_bw_5g, mas_chan_list);
1217 		reg_populate_6g_band_channels(reg_rule_5g,
1218 					      num_5g_reg_rules,
1219 					      min_bw_5g,
1220 					      mas_chan_list);
1221 	}
1222 
1223 	soc_reg->chan_list_recvd[phy_id] = true;
1224 	status = reg_send_ctl_info(soc_reg, regulat_info, tx_ops);
1225 	if (!QDF_IS_STATUS_SUCCESS(status))
1226 		return status;
1227 
1228 	if (soc_reg->new_user_ctry_pending[phy_id]) {
1229 		soc_reg->new_user_ctry_pending[phy_id] = false;
1230 		soc_reg->cc_src = SOURCE_USERSPACE;
1231 		soc_reg->user_ctry_set = true;
1232 		reg_debug("new user country is set");
1233 		reg_run_11d_state_machine(psoc);
1234 	} else if (soc_reg->new_init_ctry_pending[phy_id]) {
1235 		soc_reg->new_init_ctry_pending[phy_id] = false;
1236 		soc_reg->cc_src = SOURCE_USERSPACE;
1237 		reg_debug("new init country is set");
1238 	} else if (soc_reg->new_11d_ctry_pending[phy_id]) {
1239 		soc_reg->new_11d_ctry_pending[phy_id] = false;
1240 		soc_reg->cc_src = SOURCE_11D;
1241 		soc_reg->user_ctry_set = false;
1242 		reg_run_11d_state_machine(psoc);
1243 	} else if (soc_reg->world_country_pending[phy_id]) {
1244 		soc_reg->world_country_pending[phy_id] = false;
1245 		soc_reg->cc_src = SOURCE_CORE;
1246 		soc_reg->user_ctry_set = false;
1247 		reg_run_11d_state_machine(psoc);
1248 	} else {
1249 		if (soc_reg->cc_src == SOURCE_UNKNOWN &&
1250 		    soc_reg->num_phy == phy_id + 1)
1251 			soc_reg->cc_src = SOURCE_DRIVER;
1252 
1253 		qdf_mem_copy(soc_reg->mas_chan_params[phy_id].default_country,
1254 			     regulat_info->alpha2,
1255 			     REG_ALPHA2_LEN + 1);
1256 
1257 		soc_reg->mas_chan_params[phy_id].def_country_code =
1258 			regulat_info->ctry_code;
1259 		soc_reg->mas_chan_params[phy_id].def_region_domain =
1260 			regulat_info->reg_dmn_pair;
1261 
1262 		if (soc_reg->cc_src == SOURCE_DRIVER) {
1263 			qdf_mem_copy(soc_reg->def_country,
1264 				     regulat_info->alpha2,
1265 				     REG_ALPHA2_LEN + 1);
1266 
1267 			soc_reg->def_country_code = regulat_info->ctry_code;
1268 			soc_reg->def_region_domain =
1269 				regulat_info->reg_dmn_pair;
1270 
1271 			if (reg_is_world_alpha2(regulat_info->alpha2)) {
1272 				soc_reg->cc_src = SOURCE_CORE;
1273 				reg_run_11d_state_machine(psoc);
1274 			}
1275 		}
1276 	}
1277 
1278 	pdev = wlan_objmgr_get_pdev_by_id(psoc, pdev_id, dbg_id);
1279 	if (pdev) {
1280 		reg_propagate_mas_chan_list_to_pdev(psoc, pdev, &dir);
1281 		wlan_objmgr_pdev_release_ref(pdev, dbg_id);
1282 	}
1283 
1284 	return QDF_STATUS_SUCCESS;
1285 }
1286 
1287 QDF_STATUS reg_get_current_chan_list(struct wlan_objmgr_pdev *pdev,
1288 				     struct regulatory_channel *chan_list)
1289 {
1290 	struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj;
1291 
1292 	pdev_priv_obj = reg_get_pdev_obj(pdev);
1293 
1294 	if (!IS_VALID_PDEV_REG_OBJ(pdev_priv_obj)) {
1295 		reg_err("reg pdev private obj is NULL");
1296 		return QDF_STATUS_E_FAILURE;
1297 	}
1298 
1299 	qdf_mem_copy(chan_list, pdev_priv_obj->cur_chan_list,
1300 		     NUM_CHANNELS * sizeof(struct regulatory_channel));
1301 
1302 	return QDF_STATUS_SUCCESS;
1303 }
1304