xref: /wlan-dirver/qca-wifi-host-cmn/umac/regulatory/core/src/reg_build_chan_list.c (revision dd4dc88b837a295134aa9869114a2efee0f4894b)
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 						REGULATORY_CHAN_DISABLED;
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 void reg_compute_pdev_current_chan_list(
546 		struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj)
547 {
548 	qdf_mem_copy(pdev_priv_obj->cur_chan_list, pdev_priv_obj->mas_chan_list,
549 		     NUM_CHANNELS * sizeof(struct regulatory_channel));
550 
551 	reg_modify_chan_list_for_freq_range(pdev_priv_obj->cur_chan_list,
552 					    pdev_priv_obj->range_2g_low,
553 					    pdev_priv_obj->range_2g_high,
554 					    pdev_priv_obj->range_5g_low,
555 					    pdev_priv_obj->range_5g_high);
556 
557 	reg_modify_chan_list_for_band(pdev_priv_obj->cur_chan_list,
558 				      pdev_priv_obj->band_capability);
559 
560 	reg_modify_chan_list_for_dfs_channels(pdev_priv_obj->cur_chan_list,
561 					      pdev_priv_obj->dfs_enabled);
562 
563 	reg_modify_chan_list_for_nol_list(pdev_priv_obj->cur_chan_list);
564 
565 	reg_modify_chan_list_for_indoor_channels(pdev_priv_obj);
566 
567 	reg_modify_chan_list_for_fcc_channel(pdev_priv_obj->cur_chan_list,
568 					     pdev_priv_obj->set_fcc_channel);
569 
570 	reg_modify_chan_list_for_chan_144(pdev_priv_obj->cur_chan_list,
571 					  pdev_priv_obj->en_chan_144);
572 
573 	reg_modify_chan_list_for_cached_channels(pdev_priv_obj);
574 }
575 
576 void reg_reset_reg_rules(struct reg_rule_info *reg_rules)
577 {
578 	qdf_mem_zero(reg_rules, sizeof(*reg_rules));
579 }
580 
581 void reg_save_reg_rules_to_pdev(
582 		struct reg_rule_info *psoc_reg_rules,
583 		struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj)
584 {
585 	uint32_t reg_rule_len;
586 	struct reg_rule_info *pdev_reg_rules;
587 
588 	qdf_spin_lock_bh(&pdev_priv_obj->reg_rules_lock);
589 
590 	pdev_reg_rules = &pdev_priv_obj->reg_rules;
591 	reg_reset_reg_rules(pdev_reg_rules);
592 
593 	pdev_reg_rules->num_of_reg_rules = psoc_reg_rules->num_of_reg_rules;
594 	if (!pdev_reg_rules->num_of_reg_rules) {
595 		qdf_spin_unlock_bh(&pdev_priv_obj->reg_rules_lock);
596 		reg_err("no reg rules in psoc");
597 		return;
598 	}
599 
600 	reg_rule_len = pdev_reg_rules->num_of_reg_rules *
601 		       sizeof(struct cur_reg_rule);
602 	qdf_mem_copy(pdev_reg_rules->reg_rules, psoc_reg_rules->reg_rules,
603 		     reg_rule_len);
604 
605 	qdf_mem_copy(pdev_reg_rules->alpha2, pdev_priv_obj->current_country,
606 		     REG_ALPHA2_LEN + 1);
607 	pdev_reg_rules->dfs_region = pdev_priv_obj->dfs_region;
608 
609 	qdf_spin_unlock_bh(&pdev_priv_obj->reg_rules_lock);
610 }
611 
612 void reg_propagate_mas_chan_list_to_pdev(struct wlan_objmgr_psoc *psoc,
613 					 void *object, void *arg)
614 {
615 	struct wlan_objmgr_pdev *pdev = (struct wlan_objmgr_pdev *)object;
616 	struct wlan_regulatory_psoc_priv_obj *psoc_priv_obj;
617 	struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj;
618 	enum direction *dir = arg;
619 	uint32_t pdev_id;
620 	struct wlan_lmac_if_reg_tx_ops *reg_tx_ops;
621 	struct reg_rule_info *psoc_reg_rules;
622 
623 	psoc_priv_obj = (struct wlan_regulatory_psoc_priv_obj *)
624 		wlan_objmgr_psoc_get_comp_private_obj(
625 				psoc, WLAN_UMAC_COMP_REGULATORY);
626 
627 	if (!psoc_priv_obj) {
628 		reg_err("psoc priv obj is NULL");
629 		return;
630 	}
631 
632 	pdev_priv_obj = reg_get_pdev_obj(pdev);
633 
634 	if (!IS_VALID_PDEV_REG_OBJ(pdev_priv_obj)) {
635 		reg_err("reg pdev priv obj is NULL");
636 		return;
637 	}
638 
639 	pdev_id = wlan_objmgr_pdev_get_pdev_id(pdev);
640 	reg_init_pdev_mas_chan_list(
641 			pdev_priv_obj,
642 			&psoc_priv_obj->mas_chan_params[pdev_id]);
643 	psoc_reg_rules = &psoc_priv_obj->mas_chan_params[pdev_id].reg_rules;
644 	reg_save_reg_rules_to_pdev(psoc_reg_rules, pdev_priv_obj);
645 	reg_compute_pdev_current_chan_list(pdev_priv_obj);
646 
647 	reg_tx_ops = reg_get_psoc_tx_ops(psoc);
648 	if (reg_tx_ops->fill_umac_legacy_chanlist) {
649 		reg_tx_ops->fill_umac_legacy_chanlist(
650 				pdev, pdev_priv_obj->cur_chan_list);
651 	} else {
652 		if (*dir == NORTHBOUND)
653 			reg_send_scheduler_msg_nb(psoc, pdev);
654 		else
655 			reg_send_scheduler_msg_sb(psoc, pdev);
656 	}
657 }
658 
659 QDF_STATUS reg_process_master_chan_list(
660 		struct cur_regulatory_info *regulat_info)
661 {
662 	struct wlan_regulatory_psoc_priv_obj *soc_reg;
663 	uint32_t num_2g_reg_rules, num_5g_reg_rules;
664 	struct cur_reg_rule *reg_rule_2g, *reg_rule_5g;
665 	uint16_t min_bw_2g, max_bw_2g, min_bw_5g, max_bw_5g;
666 	struct regulatory_channel *mas_chan_list;
667 	struct wlan_objmgr_psoc *psoc;
668 	enum channel_enum chan_enum;
669 	wlan_objmgr_ref_dbgid dbg_id;
670 	enum direction dir;
671 	uint8_t phy_id;
672 	struct wlan_objmgr_pdev *pdev;
673 	struct wlan_lmac_if_reg_tx_ops *tx_ops;
674 	struct reg_rule_info *reg_rules;
675 	QDF_STATUS status;
676 
677 	psoc = regulat_info->psoc;
678 	soc_reg = reg_get_psoc_obj(psoc);
679 
680 	if (!IS_VALID_PSOC_REG_OBJ(soc_reg)) {
681 		reg_err("psoc reg component is NULL");
682 		return QDF_STATUS_E_FAILURE;
683 	}
684 
685 	tx_ops = reg_get_psoc_tx_ops(psoc);
686 	phy_id = regulat_info->phy_id;
687 
688 	if (reg_ignore_default_country(soc_reg, regulat_info)) {
689 		status = reg_set_curr_country(soc_reg, regulat_info, tx_ops);
690 		if (QDF_IS_STATUS_SUCCESS(status)) {
691 			reg_debug("WLAN restart - Ignore default CC for phy_id: %u",
692 				  phy_id);
693 			return QDF_STATUS_SUCCESS;
694 		}
695 	}
696 
697 	reg_debug("process reg master chan list");
698 
699 	if (soc_reg->offload_enabled) {
700 		dbg_id = WLAN_REGULATORY_NB_ID;
701 		dir = NORTHBOUND;
702 	} else {
703 		dbg_id = WLAN_REGULATORY_SB_ID;
704 		dir = SOUTHBOUND;
705 	}
706 
707 	if (regulat_info->status_code != REG_SET_CC_STATUS_PASS) {
708 		reg_err("Setting country code failed, status code is %d",
709 			regulat_info->status_code);
710 
711 		pdev = wlan_objmgr_get_pdev_by_id(psoc, phy_id, dbg_id);
712 		if (!pdev) {
713 			reg_err("pdev is NULL");
714 			return QDF_STATUS_E_FAILURE;
715 		}
716 
717 		if (tx_ops->set_country_failed)
718 			tx_ops->set_country_failed(pdev);
719 
720 		wlan_objmgr_pdev_release_ref(pdev, dbg_id);
721 
722 		if (regulat_info->status_code != REG_CURRENT_ALPHA2_NOT_FOUND)
723 			return QDF_STATUS_E_FAILURE;
724 
725 		soc_reg->new_user_ctry_pending[phy_id] = false;
726 		soc_reg->new_11d_ctry_pending[phy_id] = false;
727 		soc_reg->world_country_pending[phy_id] = true;
728 	}
729 
730 	mas_chan_list = soc_reg->mas_chan_params[phy_id].mas_chan_list;
731 
732 	reg_init_channel_map(regulat_info->dfs_region);
733 
734 	for (chan_enum = 0; chan_enum < NUM_CHANNELS;
735 	     chan_enum++) {
736 		mas_chan_list[chan_enum].chan_num =
737 			channel_map[chan_enum].chan_num;
738 		mas_chan_list[chan_enum].center_freq =
739 			channel_map[chan_enum].center_freq;
740 		mas_chan_list[chan_enum].chan_flags =
741 			REGULATORY_CHAN_DISABLED;
742 		mas_chan_list[chan_enum].state =
743 			CHANNEL_STATE_DISABLE;
744 		mas_chan_list[chan_enum].nol_chan = false;
745 	}
746 
747 	soc_reg->num_phy = regulat_info->num_phy;
748 	soc_reg->mas_chan_params[phy_id].phybitmap =
749 		regulat_info->phybitmap;
750 	soc_reg->mas_chan_params[phy_id].dfs_region =
751 		regulat_info->dfs_region;
752 	soc_reg->mas_chan_params[phy_id].ctry_code =
753 		regulat_info->ctry_code;
754 	soc_reg->mas_chan_params[phy_id].reg_dmn_pair =
755 		regulat_info->reg_dmn_pair;
756 	qdf_mem_copy(soc_reg->mas_chan_params[phy_id].current_country,
757 		     regulat_info->alpha2,
758 		     REG_ALPHA2_LEN + 1);
759 	qdf_mem_copy(soc_reg->cur_country,
760 		     regulat_info->alpha2,
761 		     REG_ALPHA2_LEN + 1);
762 	reg_debug("set cur_country %.2s", soc_reg->cur_country);
763 
764 	min_bw_2g = regulat_info->min_bw_2g;
765 	max_bw_2g = regulat_info->max_bw_2g;
766 	reg_rule_2g = regulat_info->reg_rules_2g_ptr;
767 	num_2g_reg_rules = regulat_info->num_2g_reg_rules;
768 	reg_update_max_bw_per_rule(num_2g_reg_rules,
769 				   reg_rule_2g, max_bw_2g);
770 
771 	min_bw_5g = regulat_info->min_bw_5g;
772 	max_bw_5g = regulat_info->max_bw_5g;
773 	reg_rule_5g = regulat_info->reg_rules_5g_ptr;
774 	num_5g_reg_rules = regulat_info->num_5g_reg_rules;
775 	reg_update_max_bw_per_rule(num_5g_reg_rules,
776 				   reg_rule_5g, max_bw_5g);
777 
778 	reg_rules = &soc_reg->mas_chan_params[phy_id].reg_rules;
779 	reg_reset_reg_rules(reg_rules);
780 
781 	reg_rules->num_of_reg_rules = num_5g_reg_rules + num_2g_reg_rules;
782 	if (reg_rules->num_of_reg_rules > MAX_REG_RULES) {
783 		reg_err("number of reg rules exceeds limit");
784 		return QDF_STATUS_E_FAILURE;
785 	}
786 
787 	if (reg_rules->num_of_reg_rules) {
788 		if (num_2g_reg_rules)
789 			qdf_mem_copy(reg_rules->reg_rules,
790 				     reg_rule_2g, num_2g_reg_rules *
791 				     sizeof(struct cur_reg_rule));
792 		if (num_5g_reg_rules)
793 			qdf_mem_copy(reg_rules->reg_rules +
794 				     num_2g_reg_rules, reg_rule_5g,
795 				     num_5g_reg_rules *
796 				     sizeof(struct cur_reg_rule));
797 	}
798 
799 	if (num_5g_reg_rules != 0)
800 		reg_do_auto_bw_correction(num_5g_reg_rules,
801 					  reg_rule_5g, max_bw_5g);
802 
803 	if (num_2g_reg_rules != 0)
804 		reg_populate_band_channels(MIN_24GHZ_CHANNEL, MAX_24GHZ_CHANNEL,
805 					   reg_rule_2g, num_2g_reg_rules,
806 					   min_bw_2g, mas_chan_list);
807 
808 	if (num_5g_reg_rules != 0)
809 		reg_populate_band_channels(MIN_5GHZ_CHANNEL, MAX_5GHZ_CHANNEL,
810 					   reg_rule_5g, num_5g_reg_rules,
811 					   min_bw_5g, mas_chan_list);
812 
813 	if (num_5g_reg_rules != 0)
814 		reg_populate_band_channels(MIN_49GHZ_CHANNEL,
815 					   MAX_49GHZ_CHANNEL,
816 					reg_rule_5g, num_5g_reg_rules,
817 					min_bw_5g, mas_chan_list);
818 
819 	if (soc_reg->new_user_ctry_pending[phy_id]) {
820 		soc_reg->new_user_ctry_pending[phy_id] = false;
821 		soc_reg->cc_src = SOURCE_USERSPACE;
822 		soc_reg->user_ctry_set = true;
823 		reg_debug("new user country is set");
824 		reg_run_11d_state_machine(psoc);
825 	} else if (soc_reg->new_init_ctry_pending[phy_id]) {
826 		soc_reg->new_init_ctry_pending[phy_id] = false;
827 		soc_reg->cc_src = SOURCE_USERSPACE;
828 		reg_debug("new init country is set");
829 	} else if (soc_reg->new_11d_ctry_pending[phy_id]) {
830 		soc_reg->new_11d_ctry_pending[phy_id] = false;
831 		soc_reg->cc_src = SOURCE_11D;
832 		soc_reg->user_ctry_set = false;
833 		reg_run_11d_state_machine(psoc);
834 	} else if (soc_reg->world_country_pending[phy_id]) {
835 		soc_reg->world_country_pending[phy_id] = false;
836 		soc_reg->cc_src = SOURCE_CORE;
837 		soc_reg->user_ctry_set = false;
838 		reg_run_11d_state_machine(psoc);
839 	} else {
840 		if (soc_reg->cc_src == SOURCE_UNKNOWN &&
841 		    soc_reg->num_phy == phy_id + 1)
842 			soc_reg->cc_src = SOURCE_DRIVER;
843 
844 		qdf_mem_copy(soc_reg->mas_chan_params[phy_id].default_country,
845 			     regulat_info->alpha2,
846 			     REG_ALPHA2_LEN + 1);
847 
848 		soc_reg->mas_chan_params[phy_id].def_country_code =
849 			regulat_info->ctry_code;
850 		soc_reg->mas_chan_params[phy_id].def_region_domain =
851 			regulat_info->reg_dmn_pair;
852 
853 		if (soc_reg->cc_src == SOURCE_DRIVER) {
854 			qdf_mem_copy(soc_reg->def_country,
855 				     regulat_info->alpha2,
856 				     REG_ALPHA2_LEN + 1);
857 
858 			soc_reg->def_country_code = regulat_info->ctry_code;
859 			soc_reg->def_region_domain =
860 				regulat_info->reg_dmn_pair;
861 
862 			if (reg_is_world_alpha2(regulat_info->alpha2)) {
863 				soc_reg->cc_src = SOURCE_CORE;
864 				reg_run_11d_state_machine(psoc);
865 			}
866 		}
867 	}
868 
869 	pdev = wlan_objmgr_get_pdev_by_id(psoc, phy_id, dbg_id);
870 	if (pdev) {
871 		reg_propagate_mas_chan_list_to_pdev(psoc, pdev, &dir);
872 		wlan_objmgr_pdev_release_ref(pdev, dbg_id);
873 		reg_reset_reg_rules(reg_rules);
874 	}
875 
876 	return QDF_STATUS_SUCCESS;
877 }
878 
879 QDF_STATUS reg_get_current_chan_list(struct wlan_objmgr_pdev *pdev,
880 				     struct regulatory_channel *chan_list)
881 {
882 	struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj;
883 
884 	pdev_priv_obj = reg_get_pdev_obj(pdev);
885 
886 	if (!IS_VALID_PDEV_REG_OBJ(pdev_priv_obj)) {
887 		reg_err("reg pdev private obj is NULL");
888 		return QDF_STATUS_E_FAILURE;
889 	}
890 
891 	qdf_mem_copy(chan_list, pdev_priv_obj->cur_chan_list,
892 		     NUM_CHANNELS * sizeof(struct regulatory_channel));
893 
894 	return QDF_STATUS_SUCCESS;
895 }
896