xref: /wlan-dirver/qca-wifi-host-cmn/umac/regulatory/core/src/reg_build_chan_list.c (revision fa47688f04ef001a6dcafaebdcc3c031f15ee75e)
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_getset.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_host_11d.h"
35 #include <scheduler_api.h>
36 #include "reg_build_chan_list.h"
37 #include <qdf_platform.h>
38 
39 #define CHAN_12_CENT_FREQ 2467
40 #define MAX_PWR_FCC_CHAN_12 8
41 #define CHAN_13_CENT_FREQ 2472
42 #define MAX_PWR_FCC_CHAN_13 2
43 #define CHAN_144_CENT_FREQ 5720
44 
45 /**
46  * reg_fill_channel_info() - Populate TX power, antenna gain, channel state,
47  * channel flags, min and max bandwidth to master channel list.
48  * @chan_enum: Channel enum.
49  * @reg_rule: Pointer to regulatory rule which has tx power and antenna gain.
50  * @master_list: Pointer to master channel list.
51  * @min_bw: minimum bandwidth to be used for given channel.
52  */
53 static void reg_fill_channel_info(enum channel_enum chan_enum,
54 				  struct cur_reg_rule *reg_rule,
55 				  struct regulatory_channel *master_list,
56 				  uint16_t min_bw)
57 {
58 	master_list[chan_enum].chan_flags &= ~REGULATORY_CHAN_DISABLED;
59 
60 	master_list[chan_enum].tx_power = reg_rule->reg_power;
61 	master_list[chan_enum].ant_gain = reg_rule->ant_gain;
62 	master_list[chan_enum].state = CHANNEL_STATE_ENABLE;
63 
64 	if (reg_rule->flags & REGULATORY_CHAN_NO_IR) {
65 		master_list[chan_enum].chan_flags |= REGULATORY_CHAN_NO_IR;
66 		master_list[chan_enum].state = CHANNEL_STATE_DFS;
67 	}
68 
69 	if (reg_rule->flags & REGULATORY_CHAN_RADAR) {
70 		master_list[chan_enum].chan_flags |= REGULATORY_CHAN_RADAR;
71 		master_list[chan_enum].state = CHANNEL_STATE_DFS;
72 	}
73 
74 	if (reg_rule->flags & REGULATORY_CHAN_INDOOR_ONLY)
75 		master_list[chan_enum].chan_flags |=
76 			REGULATORY_CHAN_INDOOR_ONLY;
77 
78 	if (reg_rule->flags & REGULATORY_CHAN_NO_OFDM)
79 		master_list[chan_enum].chan_flags |= REGULATORY_CHAN_NO_OFDM;
80 
81 	master_list[chan_enum].min_bw = min_bw;
82 	if (master_list[chan_enum].max_bw == 20)
83 		master_list[chan_enum].max_bw = reg_rule->max_bw;
84 }
85 
86 /**
87  * reg_populate_band_channels() - For all the valid regdb channels in the master
88  * channel list, find the regulatory rules and call reg_fill_channel_info() to
89  * populate master channel list with txpower, antennagain, BW info, etc.
90  * @start_chan: Start channel enum.
91  * @end_chan: End channel enum.
92  * @rule_start_ptr: Pointer to regulatory rules.
93  * @num_reg_rules: Number of regulatory rules.
94  * @min_reg_bw: Minimum regulatory bandwidth.
95  * @mas_chan_list: Pointer to master channel list.
96  */
97 static void reg_populate_band_channels(enum channel_enum start_chan,
98 				       enum channel_enum end_chan,
99 				       struct cur_reg_rule *rule_start_ptr,
100 				       uint32_t num_reg_rules,
101 				       uint16_t min_reg_bw,
102 				       struct regulatory_channel *mas_chan_list)
103 {
104 	struct cur_reg_rule *found_rule_ptr;
105 	struct cur_reg_rule *cur_rule_ptr;
106 	struct regulatory_channel;
107 	enum channel_enum chan_enum;
108 	uint32_t rule_num, bw;
109 	uint16_t max_bw;
110 	uint16_t min_bw;
111 
112 	for (chan_enum = start_chan; chan_enum <= end_chan; chan_enum++) {
113 		found_rule_ptr = NULL;
114 
115 		max_bw = QDF_MIN((uint16_t)20, channel_map[chan_enum].max_bw);
116 		min_bw = QDF_MAX(min_reg_bw, channel_map[chan_enum].min_bw);
117 
118 		if (channel_map[chan_enum].chan_num == INVALID_CHANNEL_NUM)
119 			continue;
120 
121 		for (bw = max_bw; bw >= min_bw; bw = bw / 2) {
122 			for (rule_num = 0, cur_rule_ptr = rule_start_ptr;
123 			     rule_num < num_reg_rules;
124 			     cur_rule_ptr++, rule_num++) {
125 				if ((cur_rule_ptr->start_freq <=
126 				     mas_chan_list[chan_enum].center_freq -
127 				     bw / 2) &&
128 				    (cur_rule_ptr->end_freq >=
129 				     mas_chan_list[chan_enum].center_freq +
130 				     bw / 2) && (min_bw <= bw)) {
131 					found_rule_ptr = cur_rule_ptr;
132 					break;
133 				}
134 			}
135 
136 			if (found_rule_ptr)
137 				break;
138 		}
139 
140 		if (found_rule_ptr) {
141 			mas_chan_list[chan_enum].max_bw = bw;
142 			reg_fill_channel_info(chan_enum, found_rule_ptr,
143 					      mas_chan_list, min_bw);
144 			/* Disable 2.4 Ghz channels that dont have 20 mhz bw */
145 			if (start_chan == MIN_24GHZ_CHANNEL &&
146 			    mas_chan_list[chan_enum].max_bw < 20) {
147 				mas_chan_list[chan_enum].chan_flags |=
148 						REGULATORY_CHAN_DISABLED;
149 				mas_chan_list[chan_enum].state =
150 						REGULATORY_CHAN_DISABLED;
151 			}
152 		}
153 	}
154 }
155 
156 /**
157  * reg_update_max_bw_per_rule() - Update max bandwidth value for given regrules.
158  * @num_reg_rules: Number of regulatory rules.
159  * @reg_rule_start: Pointer to regulatory rules.
160  * @max_bw: Maximum bandwidth
161  */
162 static void reg_update_max_bw_per_rule(uint32_t num_reg_rules,
163 				       struct cur_reg_rule *reg_rule_start,
164 				       uint16_t max_bw)
165 {
166 	uint32_t count;
167 
168 	for (count = 0; count < num_reg_rules; count++)
169 		reg_rule_start[count].max_bw =
170 			min(reg_rule_start[count].max_bw, max_bw);
171 }
172 
173 /**
174  * reg_do_auto_bw_correction() - Calculate and update the maximum bandwidth
175  * value.
176  * @num_reg_rules: Number of regulatory rules.
177  * @reg_rule_ptr: Pointer to regulatory rules.
178  * @max_bw: Maximum bandwidth
179  */
180 static void reg_do_auto_bw_correction(uint32_t num_reg_rules,
181 				      struct cur_reg_rule *reg_rule_ptr,
182 				      uint16_t max_bw)
183 {
184 	uint32_t count;
185 	uint16_t new_bw;
186 
187 	for (count = 0; count < num_reg_rules - 1; count++) {
188 		if ((reg_rule_ptr[count].end_freq ==
189 		     reg_rule_ptr[count + 1].start_freq) &&
190 		    ((reg_rule_ptr[count].max_bw +
191 		      reg_rule_ptr[count + 1].max_bw) <= max_bw)) {
192 			new_bw = reg_rule_ptr[count].max_bw +
193 				reg_rule_ptr[count + 1].max_bw;
194 			reg_rule_ptr[count].max_bw = new_bw;
195 			reg_rule_ptr[count + 1].max_bw = new_bw;
196 		}
197 	}
198 }
199 
200 /**
201  * reg_modify_chan_list_for_dfs_channels() - disable the DFS channels if
202  * dfs_enable set to false.
203  * @chan_list: Pointer to regulatory channel list.
204  * @dfs_enabled: if false, then disable the DFS channels.
205  */
206 static void reg_modify_chan_list_for_dfs_channels(
207 		struct regulatory_channel *chan_list, bool dfs_enabled)
208 {
209 	enum channel_enum chan_enum;
210 
211 	if (dfs_enabled)
212 		return;
213 
214 	for (chan_enum = 0; chan_enum < NUM_CHANNELS; chan_enum++) {
215 		if (chan_list[chan_enum].state == CHANNEL_STATE_DFS) {
216 			chan_list[chan_enum].state = CHANNEL_STATE_DISABLE;
217 			chan_list[chan_enum].chan_flags |=
218 				REGULATORY_CHAN_DISABLED;
219 		}
220 	}
221 }
222 
223 /**
224  * reg_modify_chan_list_for_indoor_channels() - Disable the indoor channels if
225  * indoor_chan_enabled flag is set to false.
226  * @pdev_priv_obj: Pointer to regulatory private pdev structure.
227  */
228 static void reg_modify_chan_list_for_indoor_channels(
229 		struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj)
230 {
231 	enum channel_enum chan_enum;
232 	struct regulatory_channel *chan_list = pdev_priv_obj->cur_chan_list;
233 
234 	if (!pdev_priv_obj->indoor_chan_enabled) {
235 		for (chan_enum = 0; chan_enum < NUM_CHANNELS; chan_enum++) {
236 			if (REGULATORY_CHAN_INDOOR_ONLY &
237 			    chan_list[chan_enum].chan_flags) {
238 				chan_list[chan_enum].state =
239 					CHANNEL_STATE_DFS;
240 				chan_list[chan_enum].chan_flags |=
241 					REGULATORY_CHAN_NO_IR;
242 			}
243 		}
244 	}
245 
246 	if (pdev_priv_obj->force_ssc_disable_indoor_channel &&
247 	    pdev_priv_obj->sap_state) {
248 		for (chan_enum = 0; chan_enum < NUM_CHANNELS; chan_enum++) {
249 			if (REGULATORY_CHAN_INDOOR_ONLY &
250 			    chan_list[chan_enum].chan_flags) {
251 				chan_list[chan_enum].state =
252 					CHANNEL_STATE_DISABLE;
253 				chan_list[chan_enum].chan_flags |=
254 					REGULATORY_CHAN_DISABLED;
255 			}
256 		}
257 	}
258 }
259 
260 /**
261  * reg_modify_chan_list_for_band() - Based on the input band value, either
262  * disable 2GHz or 5GHz channels.
263  * @chan_list: Pointer to regulatory channel list.
264  * @band_val: Input band value.
265  */
266 static void reg_modify_chan_list_for_band(struct regulatory_channel *chan_list,
267 					  enum band_info band_val)
268 {
269 	enum channel_enum chan_enum;
270 
271 	if (band_val == BAND_2G) {
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_val == BAND_5G) {
281 		for (chan_enum = MIN_24GHZ_CHANNEL;
282 		     chan_enum <= MAX_24GHZ_CHANNEL; chan_enum++) {
283 			chan_list[chan_enum].chan_flags |=
284 				REGULATORY_CHAN_DISABLED;
285 			chan_list[chan_enum].state = CHANNEL_STATE_DISABLE;
286 		}
287 	}
288 }
289 
290 /**
291  * reg_modify_chan_list_for_fcc_channel() - Set maximum FCC txpower for channel
292  * 12 and 13 if set_fcc_channel flag is set to true.
293  * @chan_list: Pointer to regulatory channel list.
294  * @set_fcc_channel: If this flag is set to true, then set the max FCC txpower
295  * for channel 12 and 13.
296  */
297 static void reg_modify_chan_list_for_fcc_channel(
298 		struct regulatory_channel *chan_list, bool set_fcc_channel)
299 {
300 	enum channel_enum chan_enum;
301 
302 	if (!set_fcc_channel)
303 		return;
304 
305 	for (chan_enum = 0; chan_enum < NUM_CHANNELS; chan_enum++) {
306 		if (chan_list[chan_enum].center_freq == CHAN_12_CENT_FREQ)
307 			chan_list[chan_enum].tx_power = MAX_PWR_FCC_CHAN_12;
308 
309 		if (chan_list[chan_enum].center_freq == CHAN_13_CENT_FREQ)
310 			chan_list[chan_enum].tx_power = MAX_PWR_FCC_CHAN_13;
311 	}
312 }
313 
314 /**
315  * reg_modify_chan_list_for_chan_144() - Disable channel 144 if en_chan_144 flag
316  * is set to false.
317  * @chan_list: Pointer to regulatory channel list.
318  * @en_chan_144: if false, then disable channel 144.
319  */
320 static void reg_modify_chan_list_for_chan_144(
321 		struct regulatory_channel *chan_list, bool en_chan_144)
322 {
323 	enum channel_enum chan_enum;
324 
325 	if (en_chan_144)
326 		return;
327 
328 	for (chan_enum = 0; chan_enum < NUM_CHANNELS; chan_enum++) {
329 		if (chan_list[chan_enum].center_freq == CHAN_144_CENT_FREQ) {
330 			chan_list[chan_enum].chan_flags |=
331 				REGULATORY_CHAN_DISABLED;
332 			chan_list[chan_enum].state = CHANNEL_STATE_DISABLE;
333 		}
334 	}
335 }
336 
337 /**
338  * reg_modify_chan_list_for_nol_list() - Disable the channel if nol_chan flag is
339  * set.
340  * @chan_list: Pointer to regulatory channel list.
341  */
342 static void reg_modify_chan_list_for_nol_list(
343 		struct regulatory_channel *chan_list)
344 {
345 	enum channel_enum chan_enum;
346 
347 	for (chan_enum = 0; chan_enum < NUM_CHANNELS; chan_enum++) {
348 		if (chan_list[chan_enum].nol_chan) {
349 			chan_list[chan_enum].state = CHANNEL_STATE_DISABLE;
350 			chan_list[chan_enum].chan_flags |=
351 				REGULATORY_CHAN_DISABLED;
352 		}
353 	}
354 }
355 
356 /**
357  * reg_find_low_limit_chan_enum() - Find low limit 2G and 5G channel enums.
358  * @chan_list: Pointer to regulatory channel list.
359  * @low_freq: low limit frequency.
360  * @low_limit: pointer to output low limit enum.
361  *
362  * Return: None
363  */
364 static void reg_find_low_limit_chan_enum(
365 		struct regulatory_channel *chan_list, uint32_t low_freq,
366 		uint32_t *low_limit)
367 {
368 	enum channel_enum chan_enum;
369 	uint16_t min_bw;
370 	uint16_t max_bw;
371 	uint32_t center_freq;
372 
373 	for (chan_enum = 0; chan_enum < NUM_CHANNELS; chan_enum++) {
374 		min_bw = chan_list[chan_enum].min_bw;
375 		max_bw = chan_list[chan_enum].max_bw;
376 		center_freq = chan_list[chan_enum].center_freq;
377 
378 		if ((center_freq - min_bw / 2) >= low_freq) {
379 			if ((center_freq - max_bw / 2) < low_freq) {
380 				if (max_bw <= 20)
381 					max_bw = ((center_freq - low_freq) * 2);
382 				if (max_bw < min_bw)
383 					max_bw = min_bw;
384 				chan_list[chan_enum].max_bw = max_bw;
385 			}
386 			*low_limit = chan_enum;
387 			break;
388 		}
389 	}
390 }
391 
392 /**
393  * reg_find_high_limit_chan_enum() - Find high limit 2G and 5G channel enums.
394  * @chan_list: Pointer to regulatory channel list.
395  * @high_freq: high limit frequency.
396  * @high_limit: pointer to output high limit enum.
397  *
398  * Return: None
399  */
400 static void reg_find_high_limit_chan_enum(
401 		struct regulatory_channel *chan_list, uint32_t high_freq,
402 		uint32_t *high_limit)
403 {
404 	enum channel_enum chan_enum;
405 	uint16_t min_bw;
406 	uint16_t max_bw;
407 	uint32_t center_freq;
408 
409 	for (chan_enum = NUM_CHANNELS - 1; chan_enum >= 0; chan_enum--) {
410 		min_bw = chan_list[chan_enum].min_bw;
411 		max_bw = chan_list[chan_enum].max_bw;
412 		center_freq = chan_list[chan_enum].center_freq;
413 
414 		if (center_freq + min_bw / 2 <= high_freq) {
415 			if ((center_freq + max_bw / 2) > high_freq) {
416 				if (max_bw <= 20)
417 					max_bw = ((high_freq -
418 						   center_freq) * 2);
419 				if (max_bw < min_bw)
420 					max_bw = min_bw;
421 				chan_list[chan_enum].max_bw = max_bw;
422 			}
423 			*high_limit = chan_enum;
424 			break;
425 		}
426 
427 		if (chan_enum == 0)
428 			break;
429 	}
430 }
431 
432 /**
433  * reg_modify_chan_list_for_freq_range() - Modify channel list for the given low
434  * and high frequency range.
435  * @chan_list: Pointer to regulatory channel list.
436  * @low_freq_2g: Low frequency 2G.
437  * @high_freq_2g: High frequency 2G.
438  * @low_freq_5g: Low frequency 5G.
439  * @high_freq_5g: High frequency 5G.
440  *
441  * Return: None
442  */
443 static void
444 reg_modify_chan_list_for_freq_range(struct regulatory_channel *chan_list,
445 				    uint32_t low_freq_2g,
446 				    uint32_t high_freq_2g,
447 				    uint32_t low_freq_5g,
448 				    uint32_t high_freq_5g)
449 {
450 	uint32_t low_limit_2g = NUM_CHANNELS;
451 	uint32_t high_limit_2g = NUM_CHANNELS;
452 	uint32_t low_limit_5g = NUM_CHANNELS;
453 	uint32_t high_limit_5g = NUM_CHANNELS;
454 	enum channel_enum chan_enum;
455 	bool chan_in_range;
456 
457 	reg_find_low_limit_chan_enum(chan_list, low_freq_2g, &low_limit_2g);
458 	reg_find_low_limit_chan_enum(chan_list, low_freq_5g, &low_limit_5g);
459 	reg_find_high_limit_chan_enum(chan_list, high_freq_2g, &high_limit_2g);
460 	reg_find_high_limit_chan_enum(chan_list, high_freq_5g, &high_limit_5g);
461 
462 	for (chan_enum = 0; chan_enum < NUM_CHANNELS; chan_enum++) {
463 		chan_in_range = false;
464 		if  ((low_limit_2g <= chan_enum) &&
465 		     (high_limit_2g >= chan_enum) &&
466 		     (low_limit_2g != NUM_CHANNELS) &&
467 		     (high_limit_2g != NUM_CHANNELS))
468 			chan_in_range = true;
469 
470 		if  ((low_limit_5g <= chan_enum) &&
471 		     (high_limit_5g >= chan_enum) &&
472 		     (low_limit_5g != NUM_CHANNELS) &&
473 		     (high_limit_5g != NUM_CHANNELS))
474 			chan_in_range = true;
475 
476 		if (!chan_in_range) {
477 			chan_list[chan_enum].chan_flags |=
478 				REGULATORY_CHAN_DISABLED;
479 			chan_list[chan_enum].state = CHANNEL_STATE_DISABLE;
480 		}
481 	}
482 }
483 
484 void reg_init_pdev_mas_chan_list(
485 		struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj,
486 		struct mas_chan_params *mas_chan_params)
487 {
488 	qdf_mem_copy(pdev_priv_obj->mas_chan_list,
489 		     mas_chan_params->mas_chan_list,
490 		     NUM_CHANNELS * sizeof(struct regulatory_channel));
491 
492 	pdev_priv_obj->dfs_region = mas_chan_params->dfs_region;
493 
494 	pdev_priv_obj->phybitmap = mas_chan_params->phybitmap;
495 
496 	pdev_priv_obj->reg_dmn_pair = mas_chan_params->reg_dmn_pair;
497 	pdev_priv_obj->ctry_code =  mas_chan_params->ctry_code;
498 
499 	pdev_priv_obj->def_region_domain = mas_chan_params->reg_dmn_pair;
500 	pdev_priv_obj->def_country_code =  mas_chan_params->ctry_code;
501 
502 	qdf_mem_copy(pdev_priv_obj->default_country,
503 		     mas_chan_params->default_country, REG_ALPHA2_LEN + 1);
504 
505 	qdf_mem_copy(pdev_priv_obj->current_country,
506 		     mas_chan_params->current_country, REG_ALPHA2_LEN + 1);
507 }
508 
509 /**
510  * reg_modify_chan_list_for_cached_channels() - If num_cache_channels are
511  * non-zero, then disable the pdev channels which is given in
512  * cache_disable_chan_list.
513  * @pdev_priv_obj: Pointer to regulatory pdev private object.
514  */
515 #ifdef DISABLE_CHANNEL_LIST
516 static void reg_modify_chan_list_for_cached_channels(
517 		struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj)
518 {
519 	uint32_t i, j;
520 	uint32_t num_cache_channels = pdev_priv_obj->num_cache_channels;
521 	struct regulatory_channel *chan_list = pdev_priv_obj->cur_chan_list;
522 	struct regulatory_channel *cache_chan_list =
523 					pdev_priv_obj->cache_disable_chan_list;
524 
525 	if (!num_cache_channels)
526 		return;
527 
528 	if (pdev_priv_obj->disable_cached_channels) {
529 		for (i = 0; i < num_cache_channels; i++)
530 			for (j = 0; j < NUM_CHANNELS; j++)
531 				if (cache_chan_list[i].chan_num ==
532 							chan_list[j].chan_num) {
533 					chan_list[j].state =
534 							CHANNEL_STATE_DISABLE;
535 					chan_list[j].chan_flags |=
536 						REGULATORY_CHAN_DISABLED;
537 				}
538 	}
539 }
540 #else
541 static void reg_modify_chan_list_for_cached_channels(
542 		struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj)
543 {
544 }
545 #endif
546 
547 void reg_compute_pdev_current_chan_list(
548 		struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj)
549 {
550 	qdf_mem_copy(pdev_priv_obj->cur_chan_list, pdev_priv_obj->mas_chan_list,
551 		     NUM_CHANNELS * sizeof(struct regulatory_channel));
552 
553 	reg_modify_chan_list_for_freq_range(pdev_priv_obj->cur_chan_list,
554 					    pdev_priv_obj->range_2g_low,
555 					    pdev_priv_obj->range_2g_high,
556 					    pdev_priv_obj->range_5g_low,
557 					    pdev_priv_obj->range_5g_high);
558 
559 	reg_modify_chan_list_for_band(pdev_priv_obj->cur_chan_list,
560 				      pdev_priv_obj->band_capability);
561 
562 	reg_modify_chan_list_for_dfs_channels(pdev_priv_obj->cur_chan_list,
563 					      pdev_priv_obj->dfs_enabled);
564 
565 	reg_modify_chan_list_for_nol_list(pdev_priv_obj->cur_chan_list);
566 
567 	reg_modify_chan_list_for_indoor_channels(pdev_priv_obj);
568 
569 	reg_modify_chan_list_for_fcc_channel(pdev_priv_obj->cur_chan_list,
570 					     pdev_priv_obj->set_fcc_channel);
571 
572 	reg_modify_chan_list_for_chan_144(pdev_priv_obj->cur_chan_list,
573 					  pdev_priv_obj->en_chan_144);
574 
575 	reg_modify_chan_list_for_cached_channels(pdev_priv_obj);
576 }
577 
578 void reg_reset_reg_rules(struct reg_rule_info *reg_rules)
579 {
580 	qdf_mem_zero(reg_rules, sizeof(*reg_rules));
581 }
582 
583 void reg_save_reg_rules_to_pdev(
584 		struct reg_rule_info *psoc_reg_rules,
585 		struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj)
586 {
587 	uint32_t reg_rule_len;
588 	struct reg_rule_info *pdev_reg_rules;
589 
590 	qdf_spin_lock_bh(&pdev_priv_obj->reg_rules_lock);
591 
592 	pdev_reg_rules = &pdev_priv_obj->reg_rules;
593 	reg_reset_reg_rules(pdev_reg_rules);
594 
595 	pdev_reg_rules->num_of_reg_rules = psoc_reg_rules->num_of_reg_rules;
596 	if (!pdev_reg_rules->num_of_reg_rules) {
597 		qdf_spin_unlock_bh(&pdev_priv_obj->reg_rules_lock);
598 		reg_err("no reg rules in psoc");
599 		return;
600 	}
601 
602 	reg_rule_len = pdev_reg_rules->num_of_reg_rules *
603 		       sizeof(struct cur_reg_rule);
604 	qdf_mem_copy(pdev_reg_rules->reg_rules, psoc_reg_rules->reg_rules,
605 		     reg_rule_len);
606 
607 	qdf_mem_copy(pdev_reg_rules->alpha2, pdev_priv_obj->current_country,
608 		     REG_ALPHA2_LEN + 1);
609 	pdev_reg_rules->dfs_region = pdev_priv_obj->dfs_region;
610 
611 	qdf_spin_unlock_bh(&pdev_priv_obj->reg_rules_lock);
612 }
613 
614 void reg_propagate_mas_chan_list_to_pdev(struct wlan_objmgr_psoc *psoc,
615 					 void *object, void *arg)
616 {
617 	struct wlan_objmgr_pdev *pdev = (struct wlan_objmgr_pdev *)object;
618 	struct wlan_regulatory_psoc_priv_obj *psoc_priv_obj;
619 	struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj;
620 	enum direction *dir = arg;
621 	uint32_t pdev_id;
622 	struct wlan_lmac_if_reg_tx_ops *reg_tx_ops;
623 	struct reg_rule_info *psoc_reg_rules;
624 
625 	psoc_priv_obj = (struct wlan_regulatory_psoc_priv_obj *)
626 		wlan_objmgr_psoc_get_comp_private_obj(
627 				psoc, WLAN_UMAC_COMP_REGULATORY);
628 
629 	if (!psoc_priv_obj) {
630 		reg_err("psoc priv obj is NULL");
631 		return;
632 	}
633 
634 	pdev_priv_obj = reg_get_pdev_obj(pdev);
635 
636 	if (!IS_VALID_PDEV_REG_OBJ(pdev_priv_obj)) {
637 		reg_err("reg pdev priv obj is NULL");
638 		return;
639 	}
640 
641 	pdev_id = wlan_objmgr_pdev_get_pdev_id(pdev);
642 	reg_init_pdev_mas_chan_list(
643 			pdev_priv_obj,
644 			&psoc_priv_obj->mas_chan_params[pdev_id]);
645 	psoc_reg_rules = &psoc_priv_obj->mas_chan_params[pdev_id].reg_rules;
646 	reg_save_reg_rules_to_pdev(psoc_reg_rules, pdev_priv_obj);
647 	reg_compute_pdev_current_chan_list(pdev_priv_obj);
648 
649 	reg_tx_ops = reg_get_psoc_tx_ops(psoc);
650 	if (reg_tx_ops->fill_umac_legacy_chanlist) {
651 		reg_tx_ops->fill_umac_legacy_chanlist(
652 				pdev, pdev_priv_obj->cur_chan_list);
653 	} else {
654 		if (*dir == NORTHBOUND)
655 			reg_send_scheduler_msg_nb(psoc, pdev);
656 		else
657 			reg_send_scheduler_msg_sb(psoc, pdev);
658 	}
659 }
660 
661 QDF_STATUS reg_process_master_chan_list(
662 		struct cur_regulatory_info *regulat_info)
663 {
664 	struct wlan_regulatory_psoc_priv_obj *soc_reg;
665 	uint32_t num_2g_reg_rules, num_5g_reg_rules;
666 	struct cur_reg_rule *reg_rule_2g, *reg_rule_5g;
667 	uint16_t min_bw_2g, max_bw_2g, min_bw_5g, max_bw_5g;
668 	struct regulatory_channel *mas_chan_list;
669 	struct wlan_objmgr_psoc *psoc;
670 	enum channel_enum chan_enum;
671 	wlan_objmgr_ref_dbgid dbg_id;
672 	enum direction dir;
673 	uint8_t phy_id;
674 	struct wlan_objmgr_pdev *pdev;
675 	struct wlan_lmac_if_reg_tx_ops *tx_ops;
676 	struct reg_rule_info *reg_rules;
677 	QDF_STATUS status;
678 
679 	psoc = regulat_info->psoc;
680 	soc_reg = reg_get_psoc_obj(psoc);
681 
682 	if (!IS_VALID_PSOC_REG_OBJ(soc_reg)) {
683 		reg_err("psoc reg component is NULL");
684 		return QDF_STATUS_E_FAILURE;
685 	}
686 
687 	tx_ops = reg_get_psoc_tx_ops(psoc);
688 	phy_id = regulat_info->phy_id;
689 
690 	if (reg_ignore_default_country(soc_reg, regulat_info)) {
691 		status = reg_set_curr_country(soc_reg, regulat_info, tx_ops);
692 		if (QDF_IS_STATUS_SUCCESS(status)) {
693 			reg_debug("WLAN restart - Ignore default CC for phy_id: %u",
694 				  phy_id);
695 			return QDF_STATUS_SUCCESS;
696 		}
697 	}
698 
699 	reg_debug("process reg master chan list");
700 
701 	if (soc_reg->offload_enabled) {
702 		dbg_id = WLAN_REGULATORY_NB_ID;
703 		dir = NORTHBOUND;
704 	} else {
705 		dbg_id = WLAN_REGULATORY_SB_ID;
706 		dir = SOUTHBOUND;
707 	}
708 
709 	if (regulat_info->status_code != REG_SET_CC_STATUS_PASS) {
710 		reg_err("Setting country code failed, status code is %d",
711 			regulat_info->status_code);
712 
713 		pdev = wlan_objmgr_get_pdev_by_id(psoc, phy_id, dbg_id);
714 		if (!pdev) {
715 			reg_err("pdev is NULL");
716 			return QDF_STATUS_E_FAILURE;
717 		}
718 
719 		if (tx_ops->set_country_failed)
720 			tx_ops->set_country_failed(pdev);
721 
722 		wlan_objmgr_pdev_release_ref(pdev, dbg_id);
723 
724 		if (regulat_info->status_code != REG_CURRENT_ALPHA2_NOT_FOUND)
725 			return QDF_STATUS_E_FAILURE;
726 
727 		soc_reg->new_user_ctry_pending[phy_id] = false;
728 		soc_reg->new_11d_ctry_pending[phy_id] = false;
729 		soc_reg->world_country_pending[phy_id] = true;
730 	}
731 
732 	mas_chan_list = soc_reg->mas_chan_params[phy_id].mas_chan_list;
733 
734 	reg_init_channel_map(regulat_info->dfs_region);
735 
736 	for (chan_enum = 0; chan_enum < NUM_CHANNELS;
737 	     chan_enum++) {
738 		mas_chan_list[chan_enum].chan_num =
739 			channel_map[chan_enum].chan_num;
740 		mas_chan_list[chan_enum].center_freq =
741 			channel_map[chan_enum].center_freq;
742 		mas_chan_list[chan_enum].chan_flags =
743 			REGULATORY_CHAN_DISABLED;
744 		mas_chan_list[chan_enum].state =
745 			CHANNEL_STATE_DISABLE;
746 		mas_chan_list[chan_enum].nol_chan = false;
747 	}
748 
749 	soc_reg->num_phy = regulat_info->num_phy;
750 	soc_reg->mas_chan_params[phy_id].phybitmap =
751 		regulat_info->phybitmap;
752 	soc_reg->mas_chan_params[phy_id].dfs_region =
753 		regulat_info->dfs_region;
754 	soc_reg->mas_chan_params[phy_id].ctry_code =
755 		regulat_info->ctry_code;
756 	soc_reg->mas_chan_params[phy_id].reg_dmn_pair =
757 		regulat_info->reg_dmn_pair;
758 	qdf_mem_copy(soc_reg->mas_chan_params[phy_id].current_country,
759 		     regulat_info->alpha2,
760 		     REG_ALPHA2_LEN + 1);
761 	qdf_mem_copy(soc_reg->cur_country,
762 		     regulat_info->alpha2,
763 		     REG_ALPHA2_LEN + 1);
764 	reg_debug("set cur_country %.2s", soc_reg->cur_country);
765 
766 	min_bw_2g = regulat_info->min_bw_2g;
767 	max_bw_2g = regulat_info->max_bw_2g;
768 	reg_rule_2g = regulat_info->reg_rules_2g_ptr;
769 	num_2g_reg_rules = regulat_info->num_2g_reg_rules;
770 	reg_update_max_bw_per_rule(num_2g_reg_rules,
771 				   reg_rule_2g, max_bw_2g);
772 
773 	min_bw_5g = regulat_info->min_bw_5g;
774 	max_bw_5g = regulat_info->max_bw_5g;
775 	reg_rule_5g = regulat_info->reg_rules_5g_ptr;
776 	num_5g_reg_rules = regulat_info->num_5g_reg_rules;
777 	reg_update_max_bw_per_rule(num_5g_reg_rules,
778 				   reg_rule_5g, max_bw_5g);
779 
780 	reg_rules = &soc_reg->mas_chan_params[phy_id].reg_rules;
781 	reg_reset_reg_rules(reg_rules);
782 
783 	reg_rules->num_of_reg_rules = num_5g_reg_rules + num_2g_reg_rules;
784 	if (reg_rules->num_of_reg_rules > MAX_REG_RULES) {
785 		reg_err("number of reg rules exceeds limit");
786 		return QDF_STATUS_E_FAILURE;
787 	}
788 
789 	if (reg_rules->num_of_reg_rules) {
790 		if (num_2g_reg_rules)
791 			qdf_mem_copy(reg_rules->reg_rules,
792 				     reg_rule_2g, num_2g_reg_rules *
793 				     sizeof(struct cur_reg_rule));
794 		if (num_5g_reg_rules)
795 			qdf_mem_copy(reg_rules->reg_rules +
796 				     num_2g_reg_rules, reg_rule_5g,
797 				     num_5g_reg_rules *
798 				     sizeof(struct cur_reg_rule));
799 	}
800 
801 	if (num_5g_reg_rules != 0)
802 		reg_do_auto_bw_correction(num_5g_reg_rules,
803 					  reg_rule_5g, max_bw_5g);
804 
805 	if (num_2g_reg_rules != 0)
806 		reg_populate_band_channels(MIN_24GHZ_CHANNEL, MAX_24GHZ_CHANNEL,
807 					   reg_rule_2g, num_2g_reg_rules,
808 					   min_bw_2g, mas_chan_list);
809 
810 	if (num_5g_reg_rules != 0)
811 		reg_populate_band_channels(MIN_5GHZ_CHANNEL, MAX_5GHZ_CHANNEL,
812 					   reg_rule_5g, num_5g_reg_rules,
813 					   min_bw_5g, mas_chan_list);
814 
815 	if (num_5g_reg_rules != 0)
816 		reg_populate_band_channels(MIN_49GHZ_CHANNEL,
817 					   MAX_49GHZ_CHANNEL,
818 					reg_rule_5g, num_5g_reg_rules,
819 					min_bw_5g, mas_chan_list);
820 
821 	if (soc_reg->new_user_ctry_pending[phy_id]) {
822 		soc_reg->new_user_ctry_pending[phy_id] = false;
823 		soc_reg->cc_src = SOURCE_USERSPACE;
824 		soc_reg->user_ctry_set = true;
825 		reg_debug("new user country is set");
826 		reg_run_11d_state_machine(psoc);
827 	} else if (soc_reg->new_init_ctry_pending[phy_id]) {
828 		soc_reg->new_init_ctry_pending[phy_id] = false;
829 		soc_reg->cc_src = SOURCE_USERSPACE;
830 		reg_debug("new init country is set");
831 	} else if (soc_reg->new_11d_ctry_pending[phy_id]) {
832 		soc_reg->new_11d_ctry_pending[phy_id] = false;
833 		soc_reg->cc_src = SOURCE_11D;
834 		soc_reg->user_ctry_set = false;
835 		reg_run_11d_state_machine(psoc);
836 	} else if (soc_reg->world_country_pending[phy_id]) {
837 		soc_reg->world_country_pending[phy_id] = false;
838 		soc_reg->cc_src = SOURCE_CORE;
839 		soc_reg->user_ctry_set = false;
840 		reg_run_11d_state_machine(psoc);
841 	} else {
842 		if (soc_reg->cc_src == SOURCE_UNKNOWN &&
843 		    soc_reg->num_phy == phy_id + 1)
844 			soc_reg->cc_src = SOURCE_DRIVER;
845 
846 		qdf_mem_copy(soc_reg->mas_chan_params[phy_id].default_country,
847 			     regulat_info->alpha2,
848 			     REG_ALPHA2_LEN + 1);
849 
850 		soc_reg->mas_chan_params[phy_id].def_country_code =
851 			regulat_info->ctry_code;
852 		soc_reg->mas_chan_params[phy_id].def_region_domain =
853 			regulat_info->reg_dmn_pair;
854 
855 		if (soc_reg->cc_src == SOURCE_DRIVER) {
856 			qdf_mem_copy(soc_reg->def_country,
857 				     regulat_info->alpha2,
858 				     REG_ALPHA2_LEN + 1);
859 
860 			soc_reg->def_country_code = regulat_info->ctry_code;
861 			soc_reg->def_region_domain =
862 				regulat_info->reg_dmn_pair;
863 
864 			if (reg_is_world_alpha2(regulat_info->alpha2)) {
865 				soc_reg->cc_src = SOURCE_CORE;
866 				reg_run_11d_state_machine(psoc);
867 			}
868 		}
869 	}
870 
871 	pdev = wlan_objmgr_get_pdev_by_id(psoc, phy_id, dbg_id);
872 	if (pdev) {
873 		reg_propagate_mas_chan_list_to_pdev(psoc, pdev, &dir);
874 		wlan_objmgr_pdev_release_ref(pdev, dbg_id);
875 		reg_reset_reg_rules(reg_rules);
876 	}
877 
878 	return QDF_STATUS_SUCCESS;
879 }
880 
881 QDF_STATUS reg_get_current_chan_list(struct wlan_objmgr_pdev *pdev,
882 				     struct regulatory_channel *chan_list)
883 {
884 	struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj;
885 
886 	pdev_priv_obj = reg_get_pdev_obj(pdev);
887 
888 	if (!IS_VALID_PDEV_REG_OBJ(pdev_priv_obj)) {
889 		reg_err("reg pdev private obj is NULL");
890 		return QDF_STATUS_E_FAILURE;
891 	}
892 
893 	qdf_mem_copy(chan_list, pdev_priv_obj->cur_chan_list,
894 		     NUM_CHANNELS * sizeof(struct regulatory_channel));
895 
896 	return QDF_STATUS_SUCCESS;
897 }
898