xref: /wlan-dirver/qca-wifi-host-cmn/umac/regulatory/core/src/reg_build_chan_list.c (revision 11f5a63a6cbdda84849a730de22f0a71e635d58c)
1 /*
2  * Copyright (c) 2014-2019 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 		    ((reg_rule_ptr[count].max_bw +
189 		      reg_rule_ptr[count + 1].max_bw) <= max_bw)) {
190 			new_bw = reg_rule_ptr[count].max_bw +
191 				reg_rule_ptr[count + 1].max_bw;
192 			reg_rule_ptr[count].max_bw = new_bw;
193 			reg_rule_ptr[count + 1].max_bw = new_bw;
194 		}
195 	}
196 }
197 
198 /**
199  * reg_modify_chan_list_for_dfs_channels() - disable the DFS channels if
200  * dfs_enable set to false.
201  * @chan_list: Pointer to regulatory channel list.
202  * @dfs_enabled: if false, then disable the DFS channels.
203  */
204 static void reg_modify_chan_list_for_dfs_channels(
205 		struct regulatory_channel *chan_list, bool dfs_enabled)
206 {
207 	enum channel_enum chan_enum;
208 
209 	if (dfs_enabled)
210 		return;
211 
212 	for (chan_enum = 0; chan_enum < NUM_CHANNELS; chan_enum++) {
213 		if (chan_list[chan_enum].state == CHANNEL_STATE_DFS) {
214 			chan_list[chan_enum].state = CHANNEL_STATE_DISABLE;
215 			chan_list[chan_enum].chan_flags |=
216 				REGULATORY_CHAN_DISABLED;
217 		}
218 	}
219 }
220 
221 /**
222  * reg_modify_chan_list_for_indoor_channels() - Disable the indoor channels if
223  * indoor_chan_enabled flag is set to false.
224  * @pdev_priv_obj: Pointer to regulatory private pdev structure.
225  */
226 static void reg_modify_chan_list_for_indoor_channels(
227 		struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj)
228 {
229 	enum channel_enum chan_enum;
230 	struct regulatory_channel *chan_list = pdev_priv_obj->cur_chan_list;
231 
232 	if (!pdev_priv_obj->indoor_chan_enabled) {
233 		for (chan_enum = 0; chan_enum < NUM_CHANNELS; chan_enum++) {
234 			if (REGULATORY_CHAN_INDOOR_ONLY &
235 			    chan_list[chan_enum].chan_flags) {
236 				chan_list[chan_enum].state =
237 					CHANNEL_STATE_DFS;
238 				chan_list[chan_enum].chan_flags |=
239 					REGULATORY_CHAN_NO_IR;
240 			}
241 		}
242 	}
243 
244 	if (pdev_priv_obj->force_ssc_disable_indoor_channel &&
245 	    pdev_priv_obj->sap_state) {
246 		for (chan_enum = 0; chan_enum < NUM_CHANNELS; chan_enum++) {
247 			if (REGULATORY_CHAN_INDOOR_ONLY &
248 			    chan_list[chan_enum].chan_flags) {
249 				chan_list[chan_enum].state =
250 					CHANNEL_STATE_DISABLE;
251 				chan_list[chan_enum].chan_flags |=
252 					REGULATORY_CHAN_DISABLED;
253 			}
254 		}
255 	}
256 }
257 
258 /**
259  * reg_modify_chan_list_for_band() - Based on the input band value, either
260  * disable 2GHz or 5GHz channels.
261  * @chan_list: Pointer to regulatory channel list.
262  * @band_val: Input band value.
263  */
264 static void reg_modify_chan_list_for_band(struct regulatory_channel *chan_list,
265 					  enum band_info band_val)
266 {
267 	enum channel_enum chan_enum;
268 
269 	if (band_val == BAND_2G) {
270 		for (chan_enum = MIN_5GHZ_CHANNEL;
271 		     chan_enum <= MAX_5GHZ_CHANNEL; chan_enum++) {
272 			chan_list[chan_enum].chan_flags |=
273 				REGULATORY_CHAN_DISABLED;
274 			chan_list[chan_enum].state = CHANNEL_STATE_DISABLE;
275 		}
276 	}
277 
278 	if (band_val == BAND_5G) {
279 		for (chan_enum = MIN_24GHZ_CHANNEL;
280 		     chan_enum <= MAX_24GHZ_CHANNEL; chan_enum++) {
281 			chan_list[chan_enum].chan_flags |=
282 				REGULATORY_CHAN_DISABLED;
283 			chan_list[chan_enum].state = CHANNEL_STATE_DISABLE;
284 		}
285 	}
286 }
287 
288 /**
289  * reg_modify_chan_list_for_fcc_channel() - Set maximum FCC txpower for channel
290  * 12 and 13 if set_fcc_channel flag is set to true.
291  * @chan_list: Pointer to regulatory channel list.
292  * @set_fcc_channel: If this flag is set to true, then set the max FCC txpower
293  * for channel 12 and 13.
294  */
295 static void reg_modify_chan_list_for_fcc_channel(
296 		struct regulatory_channel *chan_list, bool set_fcc_channel)
297 {
298 	enum channel_enum chan_enum;
299 
300 	if (!set_fcc_channel)
301 		return;
302 
303 	for (chan_enum = 0; chan_enum < NUM_CHANNELS; chan_enum++) {
304 		if (chan_list[chan_enum].center_freq == CHAN_12_CENT_FREQ)
305 			chan_list[chan_enum].tx_power = MAX_PWR_FCC_CHAN_12;
306 
307 		if (chan_list[chan_enum].center_freq == CHAN_13_CENT_FREQ)
308 			chan_list[chan_enum].tx_power = MAX_PWR_FCC_CHAN_13;
309 	}
310 }
311 
312 /**
313  * reg_modify_chan_list_for_chan_144() - Disable channel 144 if en_chan_144 flag
314  * is set to false.
315  * @chan_list: Pointer to regulatory channel list.
316  * @en_chan_144: if false, then disable channel 144.
317  */
318 static void reg_modify_chan_list_for_chan_144(
319 		struct regulatory_channel *chan_list, bool en_chan_144)
320 {
321 	enum channel_enum chan_enum;
322 
323 	if (en_chan_144)
324 		return;
325 
326 	for (chan_enum = 0; chan_enum < NUM_CHANNELS; chan_enum++) {
327 		if (chan_list[chan_enum].center_freq == CHAN_144_CENT_FREQ) {
328 			chan_list[chan_enum].chan_flags |=
329 				REGULATORY_CHAN_DISABLED;
330 			chan_list[chan_enum].state = CHANNEL_STATE_DISABLE;
331 		}
332 	}
333 }
334 
335 /**
336  * reg_modify_chan_list_for_nol_list() - Disable the channel if nol_chan flag is
337  * set.
338  * @chan_list: Pointer to regulatory channel list.
339  */
340 static void reg_modify_chan_list_for_nol_list(
341 		struct regulatory_channel *chan_list)
342 {
343 	enum channel_enum chan_enum;
344 
345 	for (chan_enum = 0; chan_enum < NUM_CHANNELS; chan_enum++) {
346 		if (chan_list[chan_enum].nol_chan) {
347 			chan_list[chan_enum].state = CHANNEL_STATE_DISABLE;
348 			chan_list[chan_enum].chan_flags |=
349 				REGULATORY_CHAN_DISABLED;
350 		}
351 	}
352 }
353 
354 /**
355  * reg_find_low_limit_chan_enum() - Find low limit 2G and 5G channel enums.
356  * @chan_list: Pointer to regulatory channel list.
357  * @low_freq: low limit frequency.
358  * @low_limit: pointer to output low limit enum.
359  *
360  * Return: None
361  */
362 static void reg_find_low_limit_chan_enum(
363 		struct regulatory_channel *chan_list, uint32_t low_freq,
364 		uint32_t *low_limit)
365 {
366 	enum channel_enum chan_enum;
367 	uint16_t min_bw;
368 	uint16_t max_bw;
369 	uint32_t center_freq;
370 
371 	for (chan_enum = 0; chan_enum < NUM_CHANNELS; chan_enum++) {
372 		min_bw = chan_list[chan_enum].min_bw;
373 		max_bw = chan_list[chan_enum].max_bw;
374 		center_freq = chan_list[chan_enum].center_freq;
375 
376 		if ((center_freq - min_bw / 2) >= low_freq) {
377 			if ((center_freq - max_bw / 2) < low_freq) {
378 				if (max_bw <= 20)
379 					max_bw = ((center_freq - low_freq) * 2);
380 				if (max_bw < min_bw)
381 					max_bw = min_bw;
382 				chan_list[chan_enum].max_bw = max_bw;
383 			}
384 			*low_limit = chan_enum;
385 			break;
386 		}
387 	}
388 }
389 
390 /**
391  * reg_find_high_limit_chan_enum() - Find high limit 2G and 5G channel enums.
392  * @chan_list: Pointer to regulatory channel list.
393  * @high_freq: high limit frequency.
394  * @high_limit: pointer to output high limit enum.
395  *
396  * Return: None
397  */
398 static void reg_find_high_limit_chan_enum(
399 		struct regulatory_channel *chan_list, uint32_t high_freq,
400 		uint32_t *high_limit)
401 {
402 	enum channel_enum chan_enum;
403 	uint16_t min_bw;
404 	uint16_t max_bw;
405 	uint32_t center_freq;
406 
407 	for (chan_enum = NUM_CHANNELS - 1; chan_enum >= 0; chan_enum--) {
408 		min_bw = chan_list[chan_enum].min_bw;
409 		max_bw = chan_list[chan_enum].max_bw;
410 		center_freq = chan_list[chan_enum].center_freq;
411 
412 		if (center_freq + min_bw / 2 <= high_freq) {
413 			if ((center_freq + max_bw / 2) > high_freq) {
414 				if (max_bw <= 20)
415 					max_bw = ((high_freq -
416 						   center_freq) * 2);
417 				if (max_bw < min_bw)
418 					max_bw = min_bw;
419 				chan_list[chan_enum].max_bw = max_bw;
420 			}
421 			*high_limit = chan_enum;
422 			break;
423 		}
424 
425 		if (chan_enum == 0)
426 			break;
427 	}
428 }
429 
430 /**
431  * reg_modify_chan_list_for_freq_range() - Modify channel list for the given low
432  * and high frequency range.
433  * @chan_list: Pointer to regulatory channel list.
434  * @low_freq_2g: Low frequency 2G.
435  * @high_freq_2g: High frequency 2G.
436  * @low_freq_5g: Low frequency 5G.
437  * @high_freq_5g: High frequency 5G.
438  *
439  * Return: None
440  */
441 static void
442 reg_modify_chan_list_for_freq_range(struct regulatory_channel *chan_list,
443 				    uint32_t low_freq_2g,
444 				    uint32_t high_freq_2g,
445 				    uint32_t low_freq_5g,
446 				    uint32_t high_freq_5g)
447 {
448 	uint32_t low_limit_2g = NUM_CHANNELS;
449 	uint32_t high_limit_2g = NUM_CHANNELS;
450 	uint32_t low_limit_5g = NUM_CHANNELS;
451 	uint32_t high_limit_5g = NUM_CHANNELS;
452 	enum channel_enum chan_enum;
453 	bool chan_in_range;
454 
455 	reg_find_low_limit_chan_enum(chan_list, low_freq_2g, &low_limit_2g);
456 	reg_find_low_limit_chan_enum(chan_list, low_freq_5g, &low_limit_5g);
457 	reg_find_high_limit_chan_enum(chan_list, high_freq_2g, &high_limit_2g);
458 	reg_find_high_limit_chan_enum(chan_list, high_freq_5g, &high_limit_5g);
459 
460 	for (chan_enum = 0; chan_enum < NUM_CHANNELS; chan_enum++) {
461 		chan_in_range = false;
462 		if  ((low_limit_2g <= chan_enum) &&
463 		     (high_limit_2g >= chan_enum) &&
464 		     (low_limit_2g != NUM_CHANNELS) &&
465 		     (high_limit_2g != NUM_CHANNELS))
466 			chan_in_range = true;
467 
468 		if  ((low_limit_5g <= chan_enum) &&
469 		     (high_limit_5g >= chan_enum) &&
470 		     (low_limit_5g != NUM_CHANNELS) &&
471 		     (high_limit_5g != NUM_CHANNELS))
472 			chan_in_range = true;
473 
474 		if (!chan_in_range) {
475 			chan_list[chan_enum].chan_flags |=
476 				REGULATORY_CHAN_DISABLED;
477 			chan_list[chan_enum].state = CHANNEL_STATE_DISABLE;
478 		}
479 	}
480 }
481 
482 void reg_init_pdev_mas_chan_list(
483 		struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj,
484 		struct mas_chan_params *mas_chan_params)
485 {
486 	qdf_mem_copy(pdev_priv_obj->mas_chan_list,
487 		     mas_chan_params->mas_chan_list,
488 		     NUM_CHANNELS * sizeof(struct regulatory_channel));
489 
490 	pdev_priv_obj->dfs_region = mas_chan_params->dfs_region;
491 
492 	pdev_priv_obj->phybitmap = mas_chan_params->phybitmap;
493 
494 	pdev_priv_obj->reg_dmn_pair = mas_chan_params->reg_dmn_pair;
495 	pdev_priv_obj->ctry_code =  mas_chan_params->ctry_code;
496 
497 	pdev_priv_obj->def_region_domain = mas_chan_params->reg_dmn_pair;
498 	pdev_priv_obj->def_country_code =  mas_chan_params->ctry_code;
499 
500 	qdf_mem_copy(pdev_priv_obj->default_country,
501 		     mas_chan_params->default_country, REG_ALPHA2_LEN + 1);
502 
503 	qdf_mem_copy(pdev_priv_obj->current_country,
504 		     mas_chan_params->current_country, REG_ALPHA2_LEN + 1);
505 }
506 
507 /**
508  * reg_modify_chan_list_for_cached_channels() - If num_cache_channels are
509  * non-zero, then disable the pdev channels which is given in
510  * cache_disable_chan_list.
511  * @pdev_priv_obj: Pointer to regulatory pdev private object.
512  */
513 #ifdef DISABLE_CHANNEL_LIST
514 static void reg_modify_chan_list_for_cached_channels(
515 		struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj)
516 {
517 	uint32_t i, j;
518 	uint32_t num_cache_channels = pdev_priv_obj->num_cache_channels;
519 	struct regulatory_channel *chan_list = pdev_priv_obj->cur_chan_list;
520 	struct regulatory_channel *cache_chan_list =
521 					pdev_priv_obj->cache_disable_chan_list;
522 
523 	if (!num_cache_channels)
524 		return;
525 
526 	if (pdev_priv_obj->disable_cached_channels) {
527 		for (i = 0; i < num_cache_channels; i++)
528 			for (j = 0; j < NUM_CHANNELS; j++)
529 				if (cache_chan_list[i].chan_num ==
530 							chan_list[j].chan_num) {
531 					chan_list[j].state =
532 							CHANNEL_STATE_DISABLE;
533 					chan_list[j].chan_flags |=
534 						REGULATORY_CHAN_DISABLED;
535 				}
536 	}
537 }
538 #else
539 static void reg_modify_chan_list_for_cached_channels(
540 		struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj)
541 {
542 }
543 #endif
544 
545 #ifdef CONFIG_REG_CLIENT
546 /**
547  * reg_modify_chan_list_for_srd_channels() - Modify SRD channels in ETSI13
548  * @pdev: Pointer to pdev object
549  * @chan_list: Current channel list
550  *
551  * This function converts SRD channels to passive in ETSI13 regulatory domain
552  * when enable_srd_chan_in_master_mode is not set.
553  */
554 static void
555 reg_modify_chan_list_for_srd_channels(struct wlan_objmgr_pdev *pdev,
556 				      struct regulatory_channel *chan_list)
557 {
558 	enum channel_enum chan_enum;
559 
560 	if (!reg_is_etsi13_regdmn(pdev))
561 		return;
562 
563 	if (reg_is_etsi13_srd_chan_allowed_master_mode(pdev))
564 		return;
565 
566 	for (chan_enum = 0; chan_enum < NUM_CHANNELS; chan_enum++) {
567 		if (chan_list[chan_enum].chan_flags & REGULATORY_CHAN_DISABLED)
568 			continue;
569 
570 		if (reg_is_etsi13_srd_chan(pdev,
571 					   chan_list[chan_enum].chan_num)) {
572 			chan_list[chan_enum].state =
573 				CHANNEL_STATE_DFS;
574 			chan_list[chan_enum].chan_flags |=
575 				REGULATORY_CHAN_NO_IR;
576 		}
577 	}
578 }
579 #else
580 static inline void
581 reg_modify_chan_list_for_srd_channels(struct wlan_objmgr_pdev *pdev,
582 				      struct regulatory_channel *chan_list)
583 {
584 }
585 #endif
586 
587 void reg_compute_pdev_current_chan_list(struct wlan_regulatory_pdev_priv_obj
588 					*pdev_priv_obj)
589 {
590 	qdf_mem_copy(pdev_priv_obj->cur_chan_list, pdev_priv_obj->mas_chan_list,
591 		     NUM_CHANNELS * sizeof(struct regulatory_channel));
592 
593 	reg_modify_chan_list_for_freq_range(pdev_priv_obj->cur_chan_list,
594 					    pdev_priv_obj->range_2g_low,
595 					    pdev_priv_obj->range_2g_high,
596 					    pdev_priv_obj->range_5g_low,
597 					    pdev_priv_obj->range_5g_high);
598 
599 	reg_modify_chan_list_for_band(pdev_priv_obj->cur_chan_list,
600 				      pdev_priv_obj->band_capability);
601 
602 	reg_modify_chan_list_for_dfs_channels(pdev_priv_obj->cur_chan_list,
603 					      pdev_priv_obj->dfs_enabled);
604 
605 	reg_modify_chan_list_for_nol_list(pdev_priv_obj->cur_chan_list);
606 
607 	reg_modify_chan_list_for_indoor_channels(pdev_priv_obj);
608 
609 	reg_modify_chan_list_for_fcc_channel(pdev_priv_obj->cur_chan_list,
610 					     pdev_priv_obj->set_fcc_channel);
611 
612 	reg_modify_chan_list_for_chan_144(pdev_priv_obj->cur_chan_list,
613 					  pdev_priv_obj->en_chan_144);
614 
615 	reg_modify_chan_list_for_cached_channels(pdev_priv_obj);
616 
617 	reg_modify_chan_list_for_srd_channels(pdev_priv_obj->pdev_ptr,
618 					      pdev_priv_obj->cur_chan_list);
619 }
620 
621 void reg_reset_reg_rules(struct reg_rule_info *reg_rules)
622 {
623 	qdf_mem_zero(reg_rules, sizeof(*reg_rules));
624 }
625 
626 void reg_save_reg_rules_to_pdev(
627 		struct reg_rule_info *psoc_reg_rules,
628 		struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj)
629 {
630 	uint32_t reg_rule_len;
631 	struct reg_rule_info *pdev_reg_rules;
632 
633 	qdf_spin_lock_bh(&pdev_priv_obj->reg_rules_lock);
634 
635 	pdev_reg_rules = &pdev_priv_obj->reg_rules;
636 	reg_reset_reg_rules(pdev_reg_rules);
637 
638 	pdev_reg_rules->num_of_reg_rules = psoc_reg_rules->num_of_reg_rules;
639 	if (!pdev_reg_rules->num_of_reg_rules) {
640 		qdf_spin_unlock_bh(&pdev_priv_obj->reg_rules_lock);
641 		reg_err("no reg rules in psoc");
642 		return;
643 	}
644 
645 	reg_rule_len = pdev_reg_rules->num_of_reg_rules *
646 		       sizeof(struct cur_reg_rule);
647 	qdf_mem_copy(pdev_reg_rules->reg_rules, psoc_reg_rules->reg_rules,
648 		     reg_rule_len);
649 
650 	qdf_mem_copy(pdev_reg_rules->alpha2, pdev_priv_obj->current_country,
651 		     REG_ALPHA2_LEN + 1);
652 	pdev_reg_rules->dfs_region = pdev_priv_obj->dfs_region;
653 
654 	qdf_spin_unlock_bh(&pdev_priv_obj->reg_rules_lock);
655 }
656 
657 void reg_propagate_mas_chan_list_to_pdev(struct wlan_objmgr_psoc *psoc,
658 					 void *object, void *arg)
659 {
660 	struct wlan_objmgr_pdev *pdev = (struct wlan_objmgr_pdev *)object;
661 	struct wlan_regulatory_psoc_priv_obj *psoc_priv_obj;
662 	struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj;
663 	enum direction *dir = arg;
664 	uint32_t pdev_id;
665 	struct wlan_lmac_if_reg_tx_ops *reg_tx_ops;
666 	struct reg_rule_info *psoc_reg_rules;
667 
668 	psoc_priv_obj = (struct wlan_regulatory_psoc_priv_obj *)
669 		wlan_objmgr_psoc_get_comp_private_obj(
670 				psoc, WLAN_UMAC_COMP_REGULATORY);
671 
672 	if (!psoc_priv_obj) {
673 		reg_err("psoc priv obj is NULL");
674 		return;
675 	}
676 
677 	pdev_priv_obj = reg_get_pdev_obj(pdev);
678 
679 	if (!IS_VALID_PDEV_REG_OBJ(pdev_priv_obj)) {
680 		reg_err("reg pdev priv obj is NULL");
681 		return;
682 	}
683 
684 	pdev_id = wlan_objmgr_pdev_get_pdev_id(pdev);
685 	reg_init_pdev_mas_chan_list(
686 			pdev_priv_obj,
687 			&psoc_priv_obj->mas_chan_params[pdev_id]);
688 	psoc_reg_rules = &psoc_priv_obj->mas_chan_params[pdev_id].reg_rules;
689 	reg_save_reg_rules_to_pdev(psoc_reg_rules, pdev_priv_obj);
690 	reg_compute_pdev_current_chan_list(pdev_priv_obj);
691 
692 	reg_tx_ops = reg_get_psoc_tx_ops(psoc);
693 	if (reg_tx_ops->fill_umac_legacy_chanlist) {
694 		reg_tx_ops->fill_umac_legacy_chanlist(
695 				pdev, pdev_priv_obj->cur_chan_list);
696 	} else {
697 		if (*dir == NORTHBOUND)
698 			reg_send_scheduler_msg_nb(psoc, pdev);
699 		else
700 			reg_send_scheduler_msg_sb(psoc, pdev);
701 	}
702 }
703 
704 /**
705  * reg_populate_6g_band_channels() - For all the valid 6GHz regdb channels
706  * in the master channel list, find the regulatory rules and call
707  * reg_fill_channel_info() to populate master channel list with txpower,
708  * antennagain, BW info, etc.
709  * @reg_rule_5g: Pointer to regulatory rule.
710  * @num_5g_reg_rules: Number of regulatory rules.
711  * @min_bw_5g: Minimum regulatory bandwidth.
712  * @mas_chan_list: Pointer to the master channel list.
713  */
714 #ifdef CONFIG_BAND_6GHZ
715 static void
716 reg_populate_6g_band_channels(struct cur_reg_rule *reg_rule_5g,
717 			      uint32_t num_5g_reg_rules,
718 			      uint16_t min_bw_5g,
719 			      struct regulatory_channel *mas_chan_list)
720 {
721 	reg_populate_band_channels(MIN_6GHZ_CHANNEL,
722 				   MAX_6GHZ_CHANNEL,
723 				   reg_rule_5g,
724 				   num_5g_reg_rules,
725 				   min_bw_5g,
726 				   mas_chan_list);
727 }
728 #else
729 static void
730 reg_populate_6g_band_channels(struct cur_reg_rule *reg_rule_5g,
731 			      uint32_t num_5g_reg_rules,
732 			      uint16_t min_bw_5g,
733 			      struct regulatory_channel *mas_chan_list)
734 {
735 }
736 #endif /* CONFIG_BAND_6GHZ */
737 
738 QDF_STATUS reg_process_master_chan_list(
739 		struct cur_regulatory_info *regulat_info)
740 {
741 	struct wlan_regulatory_psoc_priv_obj *soc_reg;
742 	uint32_t num_2g_reg_rules, num_5g_reg_rules;
743 	struct cur_reg_rule *reg_rule_2g, *reg_rule_5g;
744 	uint16_t min_bw_2g, max_bw_2g, min_bw_5g, max_bw_5g;
745 	struct regulatory_channel *mas_chan_list;
746 	struct wlan_objmgr_psoc *psoc;
747 	enum channel_enum chan_enum;
748 	wlan_objmgr_ref_dbgid dbg_id;
749 	enum direction dir;
750 	uint8_t phy_id;
751 	struct wlan_objmgr_pdev *pdev;
752 	struct wlan_lmac_if_reg_tx_ops *tx_ops;
753 	struct reg_rule_info *reg_rules;
754 	QDF_STATUS status;
755 
756 	psoc = regulat_info->psoc;
757 	soc_reg = reg_get_psoc_obj(psoc);
758 
759 	if (!IS_VALID_PSOC_REG_OBJ(soc_reg)) {
760 		reg_err("psoc reg component is NULL");
761 		return QDF_STATUS_E_FAILURE;
762 	}
763 
764 	tx_ops = reg_get_psoc_tx_ops(psoc);
765 	phy_id = regulat_info->phy_id;
766 
767 	if (reg_ignore_default_country(soc_reg, regulat_info)) {
768 		status = reg_set_curr_country(soc_reg, regulat_info, tx_ops);
769 		if (QDF_IS_STATUS_SUCCESS(status)) {
770 			reg_debug("WLAN restart - Ignore default CC for phy_id: %u",
771 				  phy_id);
772 			return QDF_STATUS_SUCCESS;
773 		}
774 	}
775 
776 	reg_debug("process reg master chan list");
777 
778 	if (soc_reg->offload_enabled) {
779 		dbg_id = WLAN_REGULATORY_NB_ID;
780 		dir = NORTHBOUND;
781 	} else {
782 		dbg_id = WLAN_REGULATORY_SB_ID;
783 		dir = SOUTHBOUND;
784 	}
785 
786 	if (regulat_info->status_code != REG_SET_CC_STATUS_PASS) {
787 		reg_err("Setting country code failed, status code is %d",
788 			regulat_info->status_code);
789 
790 		pdev = wlan_objmgr_get_pdev_by_id(psoc, phy_id, dbg_id);
791 		if (!pdev) {
792 			reg_err("pdev is NULL");
793 			return QDF_STATUS_E_FAILURE;
794 		}
795 
796 		if (tx_ops->set_country_failed)
797 			tx_ops->set_country_failed(pdev);
798 
799 		wlan_objmgr_pdev_release_ref(pdev, dbg_id);
800 
801 		if (regulat_info->status_code != REG_CURRENT_ALPHA2_NOT_FOUND)
802 			return QDF_STATUS_E_FAILURE;
803 
804 		soc_reg->new_user_ctry_pending[phy_id] = false;
805 		soc_reg->new_11d_ctry_pending[phy_id] = false;
806 		soc_reg->world_country_pending[phy_id] = true;
807 	}
808 
809 	mas_chan_list = soc_reg->mas_chan_params[phy_id].mas_chan_list;
810 
811 	reg_init_channel_map(regulat_info->dfs_region);
812 
813 	for (chan_enum = 0; chan_enum < NUM_CHANNELS;
814 	     chan_enum++) {
815 		mas_chan_list[chan_enum].chan_num =
816 			channel_map[chan_enum].chan_num;
817 		mas_chan_list[chan_enum].center_freq =
818 			channel_map[chan_enum].center_freq;
819 		mas_chan_list[chan_enum].chan_flags =
820 			REGULATORY_CHAN_DISABLED;
821 		mas_chan_list[chan_enum].state =
822 			CHANNEL_STATE_DISABLE;
823 		mas_chan_list[chan_enum].nol_chan = false;
824 	}
825 
826 	soc_reg->num_phy = regulat_info->num_phy;
827 	soc_reg->mas_chan_params[phy_id].phybitmap =
828 		regulat_info->phybitmap;
829 	soc_reg->mas_chan_params[phy_id].dfs_region =
830 		regulat_info->dfs_region;
831 	soc_reg->mas_chan_params[phy_id].ctry_code =
832 		regulat_info->ctry_code;
833 	soc_reg->mas_chan_params[phy_id].reg_dmn_pair =
834 		regulat_info->reg_dmn_pair;
835 	qdf_mem_copy(soc_reg->mas_chan_params[phy_id].current_country,
836 		     regulat_info->alpha2,
837 		     REG_ALPHA2_LEN + 1);
838 	qdf_mem_copy(soc_reg->cur_country,
839 		     regulat_info->alpha2,
840 		     REG_ALPHA2_LEN + 1);
841 	reg_debug("set cur_country %.2s", soc_reg->cur_country);
842 
843 	min_bw_2g = regulat_info->min_bw_2g;
844 	max_bw_2g = regulat_info->max_bw_2g;
845 	reg_rule_2g = regulat_info->reg_rules_2g_ptr;
846 	num_2g_reg_rules = regulat_info->num_2g_reg_rules;
847 	reg_update_max_bw_per_rule(num_2g_reg_rules,
848 				   reg_rule_2g, max_bw_2g);
849 
850 	min_bw_5g = regulat_info->min_bw_5g;
851 	max_bw_5g = regulat_info->max_bw_5g;
852 	reg_rule_5g = regulat_info->reg_rules_5g_ptr;
853 	num_5g_reg_rules = regulat_info->num_5g_reg_rules;
854 	reg_update_max_bw_per_rule(num_5g_reg_rules,
855 				   reg_rule_5g, max_bw_5g);
856 
857 	reg_rules = &soc_reg->mas_chan_params[phy_id].reg_rules;
858 	reg_reset_reg_rules(reg_rules);
859 
860 	reg_rules->num_of_reg_rules = num_5g_reg_rules + num_2g_reg_rules;
861 	if (reg_rules->num_of_reg_rules > MAX_REG_RULES) {
862 		reg_err("number of reg rules exceeds limit");
863 		return QDF_STATUS_E_FAILURE;
864 	}
865 
866 	if (reg_rules->num_of_reg_rules) {
867 		if (num_2g_reg_rules)
868 			qdf_mem_copy(reg_rules->reg_rules,
869 				     reg_rule_2g, num_2g_reg_rules *
870 				     sizeof(struct cur_reg_rule));
871 		if (num_5g_reg_rules)
872 			qdf_mem_copy(reg_rules->reg_rules +
873 				     num_2g_reg_rules, reg_rule_5g,
874 				     num_5g_reg_rules *
875 				     sizeof(struct cur_reg_rule));
876 	}
877 
878 	if (num_5g_reg_rules != 0)
879 		reg_do_auto_bw_correction(num_5g_reg_rules,
880 					  reg_rule_5g, max_bw_5g);
881 
882 	if (num_2g_reg_rules != 0)
883 		reg_populate_band_channels(MIN_24GHZ_CHANNEL, MAX_24GHZ_CHANNEL,
884 					   reg_rule_2g, num_2g_reg_rules,
885 					   min_bw_2g, mas_chan_list);
886 
887 	if (num_5g_reg_rules != 0) {
888 		reg_populate_band_channels(MIN_5GHZ_CHANNEL, MAX_5GHZ_CHANNEL,
889 					   reg_rule_5g, num_5g_reg_rules,
890 					   min_bw_5g, mas_chan_list);
891 		reg_populate_band_channels(MIN_49GHZ_CHANNEL,
892 					   MAX_49GHZ_CHANNEL,
893 					   reg_rule_5g, num_5g_reg_rules,
894 					   min_bw_5g, mas_chan_list);
895 		reg_populate_6g_band_channels(reg_rule_5g,
896 					      num_5g_reg_rules,
897 					      min_bw_5g,
898 					      mas_chan_list);
899 	}
900 
901 	if (soc_reg->new_user_ctry_pending[phy_id]) {
902 		soc_reg->new_user_ctry_pending[phy_id] = false;
903 		soc_reg->cc_src = SOURCE_USERSPACE;
904 		soc_reg->user_ctry_set = true;
905 		reg_debug("new user country is set");
906 		reg_run_11d_state_machine(psoc);
907 	} else if (soc_reg->new_init_ctry_pending[phy_id]) {
908 		soc_reg->new_init_ctry_pending[phy_id] = false;
909 		soc_reg->cc_src = SOURCE_USERSPACE;
910 		reg_debug("new init country is set");
911 	} else if (soc_reg->new_11d_ctry_pending[phy_id]) {
912 		soc_reg->new_11d_ctry_pending[phy_id] = false;
913 		soc_reg->cc_src = SOURCE_11D;
914 		soc_reg->user_ctry_set = false;
915 		reg_run_11d_state_machine(psoc);
916 	} else if (soc_reg->world_country_pending[phy_id]) {
917 		soc_reg->world_country_pending[phy_id] = false;
918 		soc_reg->cc_src = SOURCE_CORE;
919 		soc_reg->user_ctry_set = false;
920 		reg_run_11d_state_machine(psoc);
921 	} else {
922 		if (soc_reg->cc_src == SOURCE_UNKNOWN &&
923 		    soc_reg->num_phy == phy_id + 1)
924 			soc_reg->cc_src = SOURCE_DRIVER;
925 
926 		qdf_mem_copy(soc_reg->mas_chan_params[phy_id].default_country,
927 			     regulat_info->alpha2,
928 			     REG_ALPHA2_LEN + 1);
929 
930 		soc_reg->mas_chan_params[phy_id].def_country_code =
931 			regulat_info->ctry_code;
932 		soc_reg->mas_chan_params[phy_id].def_region_domain =
933 			regulat_info->reg_dmn_pair;
934 
935 		if (soc_reg->cc_src == SOURCE_DRIVER) {
936 			qdf_mem_copy(soc_reg->def_country,
937 				     regulat_info->alpha2,
938 				     REG_ALPHA2_LEN + 1);
939 
940 			soc_reg->def_country_code = regulat_info->ctry_code;
941 			soc_reg->def_region_domain =
942 				regulat_info->reg_dmn_pair;
943 
944 			if (reg_is_world_alpha2(regulat_info->alpha2)) {
945 				soc_reg->cc_src = SOURCE_CORE;
946 				reg_run_11d_state_machine(psoc);
947 			}
948 		}
949 	}
950 
951 	pdev = wlan_objmgr_get_pdev_by_id(psoc, phy_id, dbg_id);
952 	if (pdev) {
953 		reg_propagate_mas_chan_list_to_pdev(psoc, pdev, &dir);
954 		wlan_objmgr_pdev_release_ref(pdev, dbg_id);
955 	}
956 
957 	return QDF_STATUS_SUCCESS;
958 }
959 
960 QDF_STATUS reg_get_current_chan_list(struct wlan_objmgr_pdev *pdev,
961 				     struct regulatory_channel *chan_list)
962 {
963 	struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj;
964 
965 	pdev_priv_obj = reg_get_pdev_obj(pdev);
966 
967 	if (!IS_VALID_PDEV_REG_OBJ(pdev_priv_obj)) {
968 		reg_err("reg pdev private obj is NULL");
969 		return QDF_STATUS_E_FAILURE;
970 	}
971 
972 	qdf_mem_copy(chan_list, pdev_priv_obj->cur_chan_list,
973 		     NUM_CHANNELS * sizeof(struct regulatory_channel));
974 
975 	return QDF_STATUS_SUCCESS;
976 }
977