xref: /wlan-dirver/qca-wifi-host-cmn/umac/regulatory/core/src/reg_utils.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_utils.c
21  * This file defines the APIs to set and get the regulatory variables.
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_db.h"
32 #include "reg_db_parser.h"
33 #include "reg_host_11d.h"
34 #include <scheduler_api.h>
35 #include <wlan_reg_services_api.h>
36 #include <qdf_platform.h>
37 #include "reg_services_common.h"
38 #include "reg_build_chan_list.h"
39 
40 #define DEFAULT_WORLD_REGDMN 0x60
41 
42 #define IS_VALID_PSOC_REG_OBJ(psoc_priv_obj) (psoc_priv_obj)
43 #define IS_VALID_PDEV_REG_OBJ(pdev_priv_obj) (pdev_priv_obj)
44 
45 bool reg_chan_has_dfs_attribute(struct wlan_objmgr_pdev *pdev, uint32_t ch)
46 {
47 	enum channel_enum ch_idx;
48 	struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj;
49 
50 	ch_idx = reg_get_chan_enum(ch);
51 
52 	if (ch_idx == INVALID_CHANNEL)
53 		return false;
54 
55 	pdev_priv_obj = reg_get_pdev_obj(pdev);
56 
57 	if (!IS_VALID_PDEV_REG_OBJ(pdev_priv_obj)) {
58 		reg_err("pdev reg obj is NULL");
59 		return false;
60 	}
61 
62 	if (pdev_priv_obj->cur_chan_list[ch_idx].chan_flags &
63 	    REGULATORY_CHAN_RADAR)
64 		return true;
65 
66 	return false;
67 }
68 
69 /**
70  * reg_is_world_ctry_code() - Check if the given country code is WORLD regdomain
71  * @ctry_code: Country code value.
72  */
73 static bool reg_is_world_ctry_code(uint16_t ctry_code)
74 {
75 	if ((ctry_code & 0xFFF0) == DEFAULT_WORLD_REGDMN)
76 		return true;
77 
78 	return false;
79 }
80 
81 QDF_STATUS reg_read_current_country(struct wlan_objmgr_psoc *psoc,
82 				    uint8_t *country_code)
83 {
84 	struct wlan_regulatory_psoc_priv_obj *psoc_reg;
85 
86 	if (!country_code) {
87 		reg_err("country_code is NULL");
88 		return QDF_STATUS_E_INVAL;
89 	}
90 
91 	psoc_reg = reg_get_psoc_obj(psoc);
92 	if (!IS_VALID_PSOC_REG_OBJ(psoc_reg)) {
93 		reg_err("psoc reg component is NULL");
94 		return QDF_STATUS_E_INVAL;
95 	}
96 
97 	qdf_mem_copy(country_code, psoc_reg->cur_country, REG_ALPHA2_LEN + 1);
98 
99 	return QDF_STATUS_SUCCESS;
100 }
101 
102 /**
103  * reg_set_default_country() - Read the default country for the regdomain
104  * @country: country code.
105  *
106  * Return: QDF_STATUS
107  */
108 QDF_STATUS reg_set_default_country(struct wlan_objmgr_psoc *psoc,
109 				   uint8_t *country)
110 {
111 	struct wlan_regulatory_psoc_priv_obj *psoc_reg;
112 
113 	if (!country) {
114 		reg_err("country is NULL");
115 		return QDF_STATUS_E_INVAL;
116 	}
117 
118 	psoc_reg = reg_get_psoc_obj(psoc);
119 	if (!IS_VALID_PSOC_REG_OBJ(psoc_reg)) {
120 		reg_err("psoc reg component is NULL");
121 		return QDF_STATUS_E_INVAL;
122 	}
123 
124 	reg_info("setting default_country: %s", country);
125 
126 	qdf_mem_copy(psoc_reg->def_country, country, REG_ALPHA2_LEN + 1);
127 
128 	return QDF_STATUS_SUCCESS;
129 }
130 
131 bool reg_is_world_alpha2(uint8_t *alpha2)
132 {
133 	if ((alpha2[0] == '0') && (alpha2[1] == '0'))
134 		return true;
135 
136 	return false;
137 }
138 
139 bool reg_is_us_alpha2(uint8_t *alpha2)
140 {
141 	if ((alpha2[0] == 'U') && (alpha2[1] == 'S'))
142 		return true;
143 
144 	return false;
145 }
146 
147 QDF_STATUS reg_set_country(struct wlan_objmgr_pdev *pdev,
148 			   uint8_t *country)
149 {
150 	struct wlan_regulatory_psoc_priv_obj *psoc_reg;
151 	struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj;
152 	struct wlan_lmac_if_reg_tx_ops *tx_ops;
153 	struct set_country country_code;
154 	struct wlan_objmgr_psoc *psoc;
155 	struct cc_regdmn_s rd;
156 	uint8_t pdev_id;
157 
158 	if (!pdev) {
159 		reg_err("pdev is NULL");
160 		return QDF_STATUS_E_INVAL;
161 	}
162 
163 	if (!country) {
164 		reg_err("country code is NULL");
165 		return QDF_STATUS_E_INVAL;
166 	}
167 
168 	pdev_id = wlan_objmgr_pdev_get_pdev_id(pdev);
169 
170 	psoc = wlan_pdev_get_psoc(pdev);
171 
172 	psoc_reg = reg_get_psoc_obj(psoc);
173 	if (!IS_VALID_PSOC_REG_OBJ(psoc_reg)) {
174 		reg_err("psoc reg component is NULL");
175 		return QDF_STATUS_E_INVAL;
176 	}
177 
178 	if (!qdf_mem_cmp(psoc_reg->cur_country, country, REG_ALPHA2_LEN)) {
179 		reg_err("country is not different");
180 		return QDF_STATUS_SUCCESS;
181 	}
182 
183 	reg_debug("programming new country:%s to firmware", country);
184 
185 	qdf_mem_copy(country_code.country, country, REG_ALPHA2_LEN + 1);
186 	country_code.pdev_id = pdev_id;
187 
188 	if (reg_is_world_alpha2(country))
189 		psoc_reg->world_country_pending[pdev_id] = true;
190 	else
191 		psoc_reg->new_user_ctry_pending[pdev_id] = true;
192 
193 	if (psoc_reg->offload_enabled) {
194 		tx_ops = reg_get_psoc_tx_ops(psoc);
195 		if (tx_ops->set_country_code) {
196 			tx_ops->set_country_code(psoc, &country_code);
197 		} else {
198 			reg_err("country set fw handler not present");
199 			psoc_reg->new_user_ctry_pending[pdev_id] = false;
200 			return QDF_STATUS_E_FAULT;
201 		}
202 	} else {
203 		if (reg_is_world_alpha2(country)) {
204 			pdev_priv_obj = reg_get_pdev_obj(pdev);
205 			if (!IS_VALID_PDEV_REG_OBJ(pdev_priv_obj)) {
206 				reg_err("reg component pdev priv is NULL");
207 				psoc_reg->new_user_ctry_pending[pdev_id] =
208 									false;
209 				return QDF_STATUS_E_INVAL;
210 			}
211 			if (reg_is_world_ctry_code(
212 				    pdev_priv_obj->def_region_domain))
213 				rd.cc.regdmn_id =
214 					pdev_priv_obj->def_region_domain;
215 			else
216 				rd.cc.regdmn_id = DEFAULT_WORLD_REGDMN;
217 			rd.flags = REGDMN_IS_SET;
218 		} else {
219 			qdf_mem_copy(rd.cc.alpha, country, REG_ALPHA2_LEN + 1);
220 			rd.flags = ALPHA_IS_SET;
221 		}
222 
223 		reg_program_chan_list(pdev, &rd);
224 	}
225 
226 	return QDF_STATUS_SUCCESS;
227 }
228 
229 QDF_STATUS reg_reset_country(struct wlan_objmgr_psoc *psoc)
230 {
231 	struct wlan_regulatory_psoc_priv_obj *psoc_reg;
232 
233 	psoc_reg = reg_get_psoc_obj(psoc);
234 	if (!IS_VALID_PSOC_REG_OBJ(psoc_reg)) {
235 		reg_err("psoc reg component is NULL");
236 		return QDF_STATUS_E_INVAL;
237 	}
238 
239 	reg_info("re-setting user country to default");
240 	qdf_mem_copy(psoc_reg->cur_country,
241 		     psoc_reg->def_country,
242 		     REG_ALPHA2_LEN + 1);
243 	reg_debug("set cur_country %.2s", psoc_reg->cur_country);
244 
245 	return QDF_STATUS_SUCCESS;
246 }
247 
248 QDF_STATUS reg_get_domain_from_country_code(v_REGDOMAIN_t *reg_domain_ptr,
249 					    const uint8_t *country_alpha2,
250 					    enum country_src source)
251 {
252 	if (!reg_domain_ptr) {
253 		reg_err("Invalid reg domain pointer");
254 		return QDF_STATUS_E_FAULT;
255 	}
256 
257 	*reg_domain_ptr = 0;
258 
259 	if (!country_alpha2) {
260 		reg_err("Country code array is NULL");
261 		return QDF_STATUS_E_FAULT;
262 	}
263 
264 	return QDF_STATUS_SUCCESS;
265 }
266 
267 bool reg_is_passive_or_disable_ch(struct wlan_objmgr_pdev *pdev,
268 				  uint32_t chan)
269 {
270 	enum channel_state ch_state;
271 
272 	ch_state = reg_get_channel_state(pdev, chan);
273 
274 	return (ch_state == CHANNEL_STATE_DFS) ||
275 		(ch_state == CHANNEL_STATE_DISABLE);
276 }
277 
278 #ifdef WLAN_FEATURE_DSRC
279 bool reg_is_dsrc_chan(struct wlan_objmgr_pdev *pdev, uint32_t chan)
280 {
281 	struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj;
282 	uint32_t freq = 0;
283 
284 	pdev_priv_obj = reg_get_pdev_obj(pdev);
285 
286 	if (!IS_VALID_PDEV_REG_OBJ(pdev_priv_obj)) {
287 		reg_err("reg pdev priv obj is NULL");
288 		return false;
289 	}
290 
291 	if (!REG_IS_5GHZ_CH(chan))
292 		return false;
293 
294 	freq = reg_chan_to_freq(pdev, chan);
295 
296 	if (!(freq >= REG_DSRC_START_FREQ && freq <= REG_DSRC_END_FREQ))
297 		return false;
298 
299 	return true;
300 }
301 
302 #else
303 
304 bool reg_is_etsi13_regdmn(struct wlan_objmgr_pdev *pdev)
305 {
306 	struct cur_regdmn_info cur_reg_dmn;
307 	QDF_STATUS status;
308 
309 	status = reg_get_curr_regdomain(pdev, &cur_reg_dmn);
310 	if (status != QDF_STATUS_SUCCESS) {
311 		reg_err("Failed to get reg domain");
312 		return false;
313 	}
314 
315 	return reg_etsi13_regdmn(cur_reg_dmn.dmn_id_5g);
316 }
317 
318 bool reg_is_etsi13_srd_chan(struct wlan_objmgr_pdev *pdev, uint32_t chan)
319 {
320 	struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj;
321 	uint32_t freq = 0;
322 
323 	pdev_priv_obj = reg_get_pdev_obj(pdev);
324 
325 	if (!IS_VALID_PDEV_REG_OBJ(pdev_priv_obj)) {
326 		reg_err("reg pdev priv obj is NULL");
327 		return false;
328 	}
329 
330 	if (!REG_IS_5GHZ_CH(chan))
331 		return false;
332 
333 	freq = reg_chan_to_freq(pdev, chan);
334 
335 	if (!(freq >= REG_ETSI13_SRD_START_FREQ &&
336 	      freq <= REG_ETSI13_SRD_END_FREQ))
337 		return false;
338 
339 	return reg_is_etsi13_regdmn(pdev);
340 }
341 
342 bool reg_is_etsi13_srd_chan_allowed_master_mode(struct wlan_objmgr_pdev *pdev)
343 {
344 	struct wlan_objmgr_psoc *psoc;
345 	struct wlan_regulatory_psoc_priv_obj *psoc_priv_obj;
346 
347 	if (!pdev) {
348 		reg_alert("pdev is NULL");
349 		return true;
350 	}
351 	psoc = wlan_pdev_get_psoc(pdev);
352 
353 	psoc_priv_obj = reg_get_psoc_obj(psoc);
354 	if (!IS_VALID_PSOC_REG_OBJ(psoc_priv_obj)) {
355 		reg_alert("psoc reg component is NULL");
356 		return true;
357 	}
358 
359 	return psoc_priv_obj->enable_srd_chan_in_master_mode &&
360 	       reg_is_etsi13_regdmn(pdev);
361 }
362 #endif
363 
364 QDF_STATUS reg_set_band(struct wlan_objmgr_pdev *pdev,
365 			enum band_info band)
366 {
367 	struct wlan_regulatory_psoc_priv_obj *psoc_priv_obj;
368 	struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj;
369 	struct wlan_objmgr_psoc *psoc;
370 	QDF_STATUS status;
371 
372 	pdev_priv_obj = reg_get_pdev_obj(pdev);
373 
374 	if (!IS_VALID_PDEV_REG_OBJ(pdev_priv_obj)) {
375 		reg_err("pdev reg component is NULL");
376 		return QDF_STATUS_E_INVAL;
377 	}
378 
379 	if (pdev_priv_obj->band_capability == band) {
380 		reg_info("band is already set to %d", band);
381 		return QDF_STATUS_SUCCESS;
382 	}
383 
384 	psoc = wlan_pdev_get_psoc(pdev);
385 	if (!psoc) {
386 		reg_err("psoc is NULL");
387 		return QDF_STATUS_E_INVAL;
388 	}
389 
390 	psoc_priv_obj = reg_get_psoc_obj(psoc);
391 	if (!IS_VALID_PSOC_REG_OBJ(psoc_priv_obj)) {
392 		reg_err("psoc reg component is NULL");
393 		return QDF_STATUS_E_INVAL;
394 	}
395 
396 	reg_info("setting band_info: %d", band);
397 	pdev_priv_obj->band_capability = band;
398 
399 	reg_compute_pdev_current_chan_list(pdev_priv_obj);
400 
401 	status = reg_send_scheduler_msg_sb(psoc, pdev);
402 
403 	return status;
404 }
405 
406 QDF_STATUS reg_get_band(struct wlan_objmgr_pdev *pdev,
407 			enum band_info *band)
408 {
409 	struct wlan_regulatory_psoc_priv_obj *psoc_priv_obj;
410 	struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj;
411 	struct wlan_objmgr_psoc *psoc;
412 
413 	pdev_priv_obj = reg_get_pdev_obj(pdev);
414 
415 	if (!IS_VALID_PDEV_REG_OBJ(pdev_priv_obj)) {
416 		reg_err("pdev reg component is NULL");
417 		return QDF_STATUS_E_INVAL;
418 	}
419 
420 	psoc = wlan_pdev_get_psoc(pdev);
421 	if (!psoc) {
422 		reg_err("psoc is NULL");
423 		return QDF_STATUS_E_INVAL;
424 	}
425 
426 	psoc_priv_obj = reg_get_psoc_obj(psoc);
427 	if (!IS_VALID_PSOC_REG_OBJ(psoc_priv_obj)) {
428 		reg_err("psoc reg component is NULL");
429 		return QDF_STATUS_E_INVAL;
430 	}
431 
432 	reg_debug("getting band_info: %d", pdev_priv_obj->band_capability);
433 	*band = pdev_priv_obj->band_capability;
434 
435 	return QDF_STATUS_SUCCESS;
436 }
437 
438 #ifdef DISABLE_CHANNEL_LIST
439 QDF_STATUS reg_restore_cached_channels(struct wlan_objmgr_pdev *pdev)
440 {
441 	struct wlan_regulatory_psoc_priv_obj *psoc_priv_obj;
442 	struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj;
443 	struct wlan_objmgr_psoc *psoc;
444 	QDF_STATUS status;
445 
446 	pdev_priv_obj = reg_get_pdev_obj(pdev);
447 	if (!IS_VALID_PDEV_REG_OBJ(pdev_priv_obj)) {
448 		reg_err("pdev reg component is NULL");
449 		return QDF_STATUS_E_INVAL;
450 	}
451 
452 	psoc = wlan_pdev_get_psoc(pdev);
453 	if (!psoc) {
454 		reg_err("psoc is NULL");
455 		return QDF_STATUS_E_INVAL;
456 	}
457 
458 	psoc_priv_obj = reg_get_psoc_obj(psoc);
459 	if (!IS_VALID_PSOC_REG_OBJ(psoc_priv_obj)) {
460 		reg_err("psoc reg component is NULL");
461 		return QDF_STATUS_E_INVAL;
462 	}
463 
464 	pdev_priv_obj->disable_cached_channels = false;
465 	reg_compute_pdev_current_chan_list(pdev_priv_obj);
466 	status = reg_send_scheduler_msg_sb(psoc, pdev);
467 	return status;
468 }
469 
470 QDF_STATUS reg_cache_channel_state(struct wlan_objmgr_pdev *pdev,
471 				   uint32_t *channel_list,
472 				   uint32_t num_channels)
473 {
474 	struct wlan_regulatory_psoc_priv_obj *psoc_priv_obj;
475 	struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj;
476 	struct wlan_objmgr_psoc *psoc;
477 	uint8_t i, j;
478 
479 	pdev_priv_obj = reg_get_pdev_obj(pdev);
480 
481 	if (!IS_VALID_PDEV_REG_OBJ(pdev_priv_obj)) {
482 		reg_err("pdev reg component is NULL");
483 		return QDF_STATUS_E_INVAL;
484 	}
485 
486 	psoc = wlan_pdev_get_psoc(pdev);
487 	if (!psoc) {
488 		reg_err("psoc is NULL");
489 		return QDF_STATUS_E_INVAL;
490 	}
491 
492 	psoc_priv_obj = reg_get_psoc_obj(psoc);
493 	if (!IS_VALID_PSOC_REG_OBJ(psoc_priv_obj)) {
494 		reg_err("psoc reg component is NULL");
495 		return QDF_STATUS_E_INVAL;
496 	}
497 	if (pdev_priv_obj->num_cache_channels > 0) {
498 		pdev_priv_obj->num_cache_channels = 0;
499 		qdf_mem_zero(&pdev_priv_obj->cache_disable_chan_list,
500 			     sizeof(pdev_priv_obj->cache_disable_chan_list));
501 	}
502 
503 	for (i = 0; i < num_channels; i++) {
504 		for (j = 0; j < NUM_CHANNELS; j++) {
505 			if (channel_list[i] == pdev_priv_obj->
506 						cur_chan_list[j].chan_num) {
507 				pdev_priv_obj->
508 					cache_disable_chan_list[i].chan_num =
509 							channel_list[i];
510 				pdev_priv_obj->
511 					cache_disable_chan_list[i].state =
512 					pdev_priv_obj->cur_chan_list[j].state;
513 				pdev_priv_obj->
514 					cache_disable_chan_list[i].chan_flags =
515 					pdev_priv_obj->
516 						cur_chan_list[j].chan_flags;
517 			}
518 		}
519 	}
520 	pdev_priv_obj->num_cache_channels = num_channels;
521 
522 	return QDF_STATUS_SUCCESS;
523 }
524 
525 void set_disable_channel_state(
526 	struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj)
527 {
528 	pdev_priv_obj->disable_cached_channels = pdev_priv_obj->sap_state;
529 }
530 #endif
531 
532 #ifdef CONFIG_REG_CLIENT
533 
534 QDF_STATUS reg_set_fcc_constraint(struct wlan_objmgr_pdev *pdev,
535 				  bool fcc_constraint)
536 {
537 	struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj;
538 	struct wlan_regulatory_psoc_priv_obj *psoc_priv_obj;
539 	struct wlan_objmgr_psoc *psoc;
540 	QDF_STATUS status;
541 
542 	pdev_priv_obj = reg_get_pdev_obj(pdev);
543 	if (!IS_VALID_PDEV_REG_OBJ(pdev_priv_obj)) {
544 		reg_err("pdev reg component is NULL");
545 		return QDF_STATUS_E_INVAL;
546 	}
547 
548 	if (pdev_priv_obj->set_fcc_channel == fcc_constraint) {
549 		reg_info("fcc_constraint is already set to %d", fcc_constraint);
550 		return QDF_STATUS_SUCCESS;
551 	}
552 
553 	reg_info("setting set_fcc_channel: %d", fcc_constraint);
554 	pdev_priv_obj->set_fcc_channel = fcc_constraint;
555 
556 	psoc = wlan_pdev_get_psoc(pdev);
557 	if (!psoc) {
558 		reg_err("psoc is NULL");
559 		return QDF_STATUS_E_INVAL;
560 	}
561 
562 	psoc_priv_obj = reg_get_psoc_obj(psoc);
563 	if (!IS_VALID_PSOC_REG_OBJ(psoc_priv_obj)) {
564 		reg_err("psoc reg component is NULL");
565 		return QDF_STATUS_E_INVAL;
566 	}
567 
568 	reg_compute_pdev_current_chan_list(pdev_priv_obj);
569 
570 	status = reg_send_scheduler_msg_sb(psoc, pdev);
571 
572 	return status;
573 }
574 
575 bool reg_get_fcc_constraint(struct wlan_objmgr_pdev *pdev, uint32_t freq)
576 {
577 	struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj;
578 
579 	pdev_priv_obj = reg_get_pdev_obj(pdev);
580 	if (!IS_VALID_PDEV_REG_OBJ(pdev_priv_obj)) {
581 		reg_err("pdev reg component is NULL");
582 		return false;
583 	}
584 
585 	if (freq != CHAN_12_CENT_FREQ && freq != CHAN_13_CENT_FREQ)
586 		return false;
587 
588 	if (!pdev_priv_obj->set_fcc_channel)
589 		return false;
590 
591 	return true;
592 }
593 
594 #endif /* CONFIG_REG_CLIENT */
595 
596 /**
597  * reg_change_pdev_for_config() - Update user configuration in pdev private obj.
598  * @psoc: Pointer to global psoc structure.
599  * @object: Pointer to global pdev structure.
600  * @arg: Pointer to argument list.
601  */
602 static void reg_change_pdev_for_config(struct wlan_objmgr_psoc *psoc,
603 				       void *object, void *arg)
604 {
605 	struct wlan_objmgr_pdev *pdev = (struct wlan_objmgr_pdev *)object;
606 	struct wlan_regulatory_psoc_priv_obj *psoc_priv_obj;
607 	struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj;
608 
609 	psoc_priv_obj = reg_get_psoc_obj(psoc);
610 	if (!psoc_priv_obj) {
611 		reg_err("psoc priv obj is NULL");
612 		return;
613 	}
614 
615 	pdev_priv_obj = reg_get_pdev_obj(pdev);
616 
617 	if (!IS_VALID_PDEV_REG_OBJ(pdev_priv_obj)) {
618 		reg_err("reg pdev private obj is NULL");
619 		return;
620 	}
621 
622 	pdev_priv_obj->dfs_enabled = psoc_priv_obj->dfs_enabled;
623 	pdev_priv_obj->indoor_chan_enabled = psoc_priv_obj->indoor_chan_enabled;
624 	pdev_priv_obj->force_ssc_disable_indoor_channel =
625 		psoc_priv_obj->force_ssc_disable_indoor_channel;
626 	pdev_priv_obj->band_capability = psoc_priv_obj->band_capability;
627 
628 	reg_compute_pdev_current_chan_list(pdev_priv_obj);
629 
630 	reg_send_scheduler_msg_sb(psoc, pdev);
631 }
632 
633 QDF_STATUS reg_set_config_vars(struct wlan_objmgr_psoc *psoc,
634 			       struct reg_config_vars config_vars)
635 {
636 	struct wlan_regulatory_psoc_priv_obj *psoc_priv_obj;
637 	QDF_STATUS status;
638 
639 	psoc_priv_obj = reg_get_psoc_obj(psoc);
640 	if (!psoc_priv_obj) {
641 		reg_err("psoc priv obj is NULL");
642 		return QDF_STATUS_E_FAILURE;
643 	}
644 
645 	psoc_priv_obj->enable_11d_supp_original =
646 		config_vars.enable_11d_support;
647 	psoc_priv_obj->scan_11d_interval = config_vars.scan_11d_interval;
648 	psoc_priv_obj->user_ctry_priority = config_vars.userspace_ctry_priority;
649 	psoc_priv_obj->dfs_enabled = config_vars.dfs_enabled;
650 	psoc_priv_obj->indoor_chan_enabled = config_vars.indoor_chan_enabled;
651 	psoc_priv_obj->force_ssc_disable_indoor_channel =
652 		config_vars.force_ssc_disable_indoor_channel;
653 	psoc_priv_obj->band_capability = config_vars.band_capability;
654 	psoc_priv_obj->restart_beaconing = config_vars.restart_beaconing;
655 	psoc_priv_obj->enable_srd_chan_in_master_mode =
656 		config_vars.enable_srd_chan_in_master_mode;
657 	psoc_priv_obj->enable_11d_in_world_mode =
658 		config_vars.enable_11d_in_world_mode;
659 
660 	status = wlan_objmgr_psoc_try_get_ref(psoc, WLAN_REGULATORY_SB_ID);
661 	if (QDF_IS_STATUS_ERROR(status)) {
662 		reg_err("error taking psoc ref cnt");
663 		return status;
664 	}
665 	status = wlan_objmgr_iterate_obj_list(psoc, WLAN_PDEV_OP,
666 					      reg_change_pdev_for_config,
667 					      NULL, 1, WLAN_REGULATORY_SB_ID);
668 	wlan_objmgr_psoc_release_ref(psoc, WLAN_REGULATORY_SB_ID);
669 
670 	return status;
671 }
672 
673 bool reg_is_disable_ch(struct wlan_objmgr_pdev *pdev, uint32_t chan)
674 {
675 	enum channel_state ch_state;
676 
677 	ch_state = reg_get_channel_state(pdev, chan);
678 
679 	return ch_state == CHANNEL_STATE_DISABLE;
680 }
681 
682 bool reg_is_regdb_offloaded(struct wlan_objmgr_psoc *psoc)
683 {
684 	struct wlan_regulatory_psoc_priv_obj *psoc_priv_obj;
685 
686 	psoc_priv_obj = reg_get_psoc_obj(psoc);
687 	if (!psoc_priv_obj) {
688 		reg_err("reg psoc private obj is NULL");
689 		return false;
690 	}
691 
692 	return psoc_priv_obj->offload_enabled;
693 }
694 
695 void reg_program_mas_chan_list(struct wlan_objmgr_psoc *psoc,
696 			       struct regulatory_channel *reg_channels,
697 			       uint8_t *alpha2,
698 			       enum dfs_reg dfs_region)
699 {
700 	struct wlan_regulatory_psoc_priv_obj *psoc_priv_obj;
701 	QDF_STATUS status;
702 	uint32_t count;
703 	enum direction dir;
704 	uint32_t pdev_cnt;
705 
706 	psoc_priv_obj = reg_get_psoc_obj(psoc);
707 	if (!psoc_priv_obj) {
708 		reg_err("reg psoc private obj is NULL");
709 		return;
710 	}
711 
712 	qdf_mem_copy(psoc_priv_obj->cur_country, alpha2,
713 		     REG_ALPHA2_LEN);
714 	reg_debug("set cur_country %.2s", psoc_priv_obj->cur_country);
715 	for (count = 0; count < NUM_CHANNELS; count++) {
716 		reg_channels[count].chan_num = channel_map[count].chan_num;
717 		reg_channels[count].center_freq =
718 			channel_map[count].center_freq;
719 		reg_channels[count].nol_chan = false;
720 	}
721 
722 	for (pdev_cnt = 0; pdev_cnt < PSOC_MAX_PHY_REG_CAP; pdev_cnt++) {
723 		qdf_mem_copy(psoc_priv_obj->mas_chan_params[pdev_cnt].
724 			     mas_chan_list, reg_channels,
725 			     NUM_CHANNELS * sizeof(struct regulatory_channel));
726 
727 		psoc_priv_obj->mas_chan_params[pdev_cnt].dfs_region =
728 			dfs_region;
729 	}
730 
731 	dir = SOUTHBOUND;
732 	status = wlan_objmgr_psoc_try_get_ref(psoc, WLAN_REGULATORY_SB_ID);
733 	if (QDF_IS_STATUS_ERROR(status)) {
734 		reg_err("error taking psoc ref cnt");
735 		return;
736 	}
737 	status = wlan_objmgr_iterate_obj_list(
738 			psoc, WLAN_PDEV_OP, reg_propagate_mas_chan_list_to_pdev,
739 			&dir, 1, WLAN_REGULATORY_SB_ID);
740 	wlan_objmgr_psoc_release_ref(psoc, WLAN_REGULATORY_SB_ID);
741 }
742 
743 enum country_src reg_get_cc_and_src(struct wlan_objmgr_psoc *psoc,
744 				    uint8_t *alpha2)
745 {
746 	struct wlan_regulatory_psoc_priv_obj *psoc_priv_obj;
747 
748 	psoc_priv_obj = reg_get_psoc_obj(psoc);
749 	if (!psoc_priv_obj) {
750 		reg_err("reg psoc private obj is NULL");
751 		return SOURCE_UNKNOWN;
752 	}
753 
754 	qdf_mem_copy(alpha2, psoc_priv_obj->cur_country, REG_ALPHA2_LEN + 1);
755 
756 	return psoc_priv_obj->cc_src;
757 }
758 
759 QDF_STATUS reg_get_regd_rules(struct wlan_objmgr_pdev *pdev,
760 			      struct reg_rule_info *reg_rules)
761 {
762 	struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj;
763 
764 	if (!pdev) {
765 		reg_err("pdev is NULL");
766 		return QDF_STATUS_E_FAILURE;
767 	}
768 
769 	pdev_priv_obj = reg_get_pdev_obj(pdev);
770 	if (!pdev_priv_obj) {
771 		reg_err("pdev priv obj is NULL");
772 		return QDF_STATUS_E_FAILURE;
773 	}
774 
775 	qdf_spin_lock_bh(&pdev_priv_obj->reg_rules_lock);
776 	qdf_mem_copy(reg_rules, &pdev_priv_obj->reg_rules,
777 		     sizeof(struct reg_rule_info));
778 	qdf_spin_unlock_bh(&pdev_priv_obj->reg_rules_lock);
779 
780 	return QDF_STATUS_SUCCESS;
781 }
782 
783 void reg_reset_ctry_pending_hints(struct wlan_regulatory_psoc_priv_obj
784 				  *soc_reg)
785 {
786 	uint8_t ctr;
787 
788 	if (!soc_reg->offload_enabled)
789 		return;
790 
791 	for (ctr = 0; ctr < PSOC_MAX_PHY_REG_CAP; ctr++) {
792 		soc_reg->new_user_ctry_pending[ctr] = false;
793 		soc_reg->new_init_ctry_pending[ctr] = false;
794 		soc_reg->new_11d_ctry_pending[ctr] = false;
795 		soc_reg->world_country_pending[ctr] = false;
796 	}
797 }
798 
799 QDF_STATUS reg_set_curr_country(
800 		struct wlan_regulatory_psoc_priv_obj *soc_reg,
801 		struct cur_regulatory_info *regulat_info,
802 		struct wlan_lmac_if_reg_tx_ops *tx_ops)
803 {
804 	struct wlan_objmgr_psoc *psoc = regulat_info->psoc;
805 	uint8_t pdev_id;
806 	struct set_country country_code;
807 	QDF_STATUS status;
808 
809 	/*
810 	 * During SSR/WLAN restart ignore master channel list
811 	 * for all events and in the last event handling if
812 	 * current country and default country is different, send the last
813 	 * configured (soc_reg->cur_country) country.
814 	 */
815 	if ((regulat_info->num_phy != regulat_info->phy_id + 1) ||
816 	    (!qdf_mem_cmp(soc_reg->cur_country, regulat_info->alpha2,
817 			  REG_ALPHA2_LEN)))
818 		return QDF_STATUS_SUCCESS;
819 
820 	pdev_id = soc_reg->def_pdev_id;
821 	if (soc_reg->cc_src == SOURCE_USERSPACE)
822 		soc_reg->new_user_ctry_pending[pdev_id] = true;
823 	else if (soc_reg->cc_src == SOURCE_11D)
824 		soc_reg->new_11d_ctry_pending[pdev_id] = true;
825 	else
826 		soc_reg->world_country_pending[pdev_id] = true;
827 
828 	qdf_mem_zero(&country_code, sizeof(country_code));
829 	qdf_mem_copy(country_code.country, soc_reg->cur_country,
830 		     sizeof(soc_reg->cur_country));
831 	country_code.pdev_id = pdev_id;
832 
833 	if (!tx_ops || !tx_ops->set_country_code) {
834 		reg_err("No regulatory tx_ops for set_country_code");
835 		status = QDF_STATUS_E_FAULT;
836 		goto error;
837 	}
838 
839 	status = tx_ops->set_country_code(psoc, &country_code);
840 	if (QDF_IS_STATUS_ERROR(status)) {
841 		reg_err("Failed to send country code to firmware");
842 		goto error;
843 	}
844 
845 	reg_debug("Target CC: %.2s, Restore to Previous CC: %.2s",
846 		  regulat_info->alpha2, soc_reg->cur_country);
847 
848 	return status;
849 
850 error:
851 	reg_reset_ctry_pending_hints(soc_reg);
852 
853 	return status;
854 }
855 
856 bool reg_ignore_default_country(struct wlan_regulatory_psoc_priv_obj *soc_reg,
857 				struct cur_regulatory_info *regulat_info)
858 {
859 	uint8_t pdev_id;
860 
861 	if (!soc_reg->offload_enabled)
862 		return false;
863 
864 	if (soc_reg->cc_src == SOURCE_UNKNOWN)
865 		return false;
866 
867 	pdev_id = regulat_info->phy_id;
868 
869 	if (soc_reg->new_user_ctry_pending[pdev_id] ||
870 	    soc_reg->new_init_ctry_pending[pdev_id] ||
871 	    soc_reg->new_11d_ctry_pending[pdev_id] ||
872 	    soc_reg->world_country_pending[pdev_id])
873 		return false;
874 
875 	return true;
876 }
877