xref: /wlan-dirver/qca-wifi-host-cmn/umac/regulatory/core/src/reg_utils.c (revision 8cfe6b10058a04cafb17eed051f2ddf11bee8931)
1 /*
2  * Copyright (c) 2014-2021 The Linux Foundation. All rights reserved.
3  * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
4  *
5  * Permission to use, copy, modify, and/or distribute this software for
6  * any purpose with or without fee is hereby granted, provided that the
7  * above copyright notice and this permission notice appear in all
8  * copies.
9  *
10  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
11  * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
12  * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
13  * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
14  * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
15  * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
16  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
17  * PERFORMANCE OF THIS SOFTWARE.
18  */
19 
20 /**
21  * DOC: reg_utils.c
22  * This file defines the APIs to set and get the regulatory variables.
23  */
24 
25 #include <wlan_cmn.h>
26 #include <reg_services_public_struct.h>
27 #include <wlan_objmgr_psoc_obj.h>
28 #include <wlan_objmgr_pdev_obj.h>
29 #include "reg_priv_objs.h"
30 #include "reg_utils.h"
31 #include "reg_callbacks.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 <wlan_reg_services_api.h>
37 #include <qdf_platform.h>
38 #include "reg_services_common.h"
39 #include "reg_build_chan_list.h"
40 #include "wlan_cm_bss_score_param.h"
41 #include "qdf_str.h"
42 #include "wmi_unified_param.h"
43 
44 #define DEFAULT_WORLD_REGDMN 0x60
45 #define FCC3_FCCA 0x3A
46 #define FCC6_FCCA 0x14
47 
48 #define IS_VALID_PSOC_REG_OBJ(psoc_priv_obj) (psoc_priv_obj)
49 #define IS_VALID_PDEV_REG_OBJ(pdev_priv_obj) (pdev_priv_obj)
50 
51 #ifdef CONFIG_CHAN_FREQ_API
52 bool reg_chan_has_dfs_attribute_for_freq(struct wlan_objmgr_pdev *pdev,
53 					 qdf_freq_t freq)
54 {
55 	enum channel_enum ch_idx;
56 	struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj;
57 
58 	ch_idx = reg_get_chan_enum_for_freq(freq);
59 
60 	if (reg_is_chan_enum_invalid(ch_idx))
61 		return false;
62 
63 	pdev_priv_obj = reg_get_pdev_obj(pdev);
64 
65 	if (!IS_VALID_PDEV_REG_OBJ(pdev_priv_obj)) {
66 		reg_err("pdev reg obj is NULL");
67 		return false;
68 	}
69 
70 	if (pdev_priv_obj->cur_chan_list[ch_idx].chan_flags &
71 	    REGULATORY_CHAN_RADAR)
72 		return true;
73 
74 	return false;
75 }
76 #endif /* CONFIG_CHAN_FREQ_API */
77 
78 bool reg_is_world_ctry_code(uint16_t ctry_code)
79 {
80 	if ((ctry_code & 0xFFF0) == DEFAULT_WORLD_REGDMN)
81 		return true;
82 
83 	return false;
84 }
85 
86 QDF_STATUS reg_read_current_country(struct wlan_objmgr_psoc *psoc,
87 				    uint8_t *country_code)
88 {
89 	struct wlan_regulatory_psoc_priv_obj *psoc_reg;
90 
91 	if (!country_code) {
92 		reg_err("country_code is NULL");
93 		return QDF_STATUS_E_INVAL;
94 	}
95 
96 	psoc_reg = reg_get_psoc_obj(psoc);
97 	if (!IS_VALID_PSOC_REG_OBJ(psoc_reg)) {
98 		reg_err("psoc reg component is NULL");
99 		return QDF_STATUS_E_INVAL;
100 	}
101 
102 	qdf_mem_copy(country_code, psoc_reg->cur_country, REG_ALPHA2_LEN + 1);
103 
104 	return QDF_STATUS_SUCCESS;
105 }
106 
107 /**
108  * reg_set_default_country() - Read the default country for the regdomain
109  * @country: country code.
110  *
111  * Return: QDF_STATUS
112  */
113 QDF_STATUS reg_set_default_country(struct wlan_objmgr_psoc *psoc,
114 				   uint8_t *country)
115 {
116 	struct wlan_regulatory_psoc_priv_obj *psoc_reg;
117 
118 	if (!country) {
119 		reg_err("country is NULL");
120 		return QDF_STATUS_E_INVAL;
121 	}
122 
123 	psoc_reg = reg_get_psoc_obj(psoc);
124 	if (!IS_VALID_PSOC_REG_OBJ(psoc_reg)) {
125 		reg_err("psoc reg component is NULL");
126 		return QDF_STATUS_E_INVAL;
127 	}
128 
129 	reg_info("set default_country: %s", country);
130 
131 	qdf_mem_copy(psoc_reg->def_country, country, REG_ALPHA2_LEN + 1);
132 
133 	return QDF_STATUS_SUCCESS;
134 }
135 
136 bool reg_is_world_alpha2(uint8_t *alpha2)
137 {
138 	if ((alpha2[0] == '0') && (alpha2[1] == '0'))
139 		return true;
140 
141 	return false;
142 }
143 
144 bool reg_is_us_alpha2(uint8_t *alpha2)
145 {
146 	if ((alpha2[0] == 'U') && (alpha2[1] == 'S'))
147 		return true;
148 
149 	return false;
150 }
151 
152 bool reg_is_etsi_alpha2(uint8_t *alpha2)
153 {
154 	if ((alpha2[0] == 'G') && (alpha2[1] == 'B'))
155 		return true;
156 
157 	return false;
158 }
159 
160 static
161 const char *reg_get_power_mode_string(uint16_t reg_dmn_pair_id)
162 {
163 	switch (reg_dmn_pair_id) {
164 	case FCC3_FCCA:
165 	case FCC6_FCCA:
166 		return "NON_VLP";
167 	default:
168 		return "VLP";
169 	}
170 }
171 
172 static bool reg_ctry_domain_supports_vlp(uint8_t *alpha2)
173 {
174 	uint16_t i;
175 	int no_of_countries;
176 
177 	reg_get_num_countries(&no_of_countries);
178 	for (i = 0; i < no_of_countries; i++) {
179 		if (g_all_countries[i].alpha2[0] == alpha2[0] &&
180 		    g_all_countries[i].alpha2[1] == alpha2[1]) {
181 			if (!qdf_str_cmp(reg_get_power_mode_string(
182 			    g_all_countries[i].reg_dmn_pair_id), "NON_VLP"))
183 				return false;
184 			else
185 				return true;
186 		}
187 	}
188 	return true;
189 }
190 
191 bool reg_ctry_support_vlp(uint8_t *alpha2)
192 {
193 	if (((alpha2[0] == 'A') && (alpha2[1] == 'E')) ||
194 	    ((alpha2[0] == 'P') && (alpha2[1] == 'E')) ||
195 	    ((alpha2[0] == 'U') && (alpha2[1] == 'S')) ||
196 	   !reg_ctry_domain_supports_vlp(alpha2))
197 		return false;
198 	else
199 		return true;
200 }
201 
202 static QDF_STATUS reg_set_non_offload_country(struct wlan_objmgr_pdev *pdev,
203 					      struct set_country *cc)
204 {
205 	struct wlan_objmgr_psoc *psoc;
206 	struct wlan_lmac_if_reg_tx_ops *tx_ops;
207 	struct wlan_regulatory_psoc_priv_obj *psoc_reg;
208 	struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj;
209 	struct cc_regdmn_s rd;
210 	uint8_t pdev_id;
211 	uint8_t phy_id;
212 
213 	if (!pdev) {
214 		reg_err("pdev is NULL");
215 		return QDF_STATUS_E_INVAL;
216 	}
217 
218 	pdev_id = wlan_objmgr_pdev_get_pdev_id(pdev);
219 	psoc = wlan_pdev_get_psoc(pdev);
220 	tx_ops = reg_get_psoc_tx_ops(psoc);
221 	if (tx_ops->get_phy_id_from_pdev_id)
222 		tx_ops->get_phy_id_from_pdev_id(psoc, pdev_id, &phy_id);
223 	else
224 		phy_id = pdev_id;
225 
226 	psoc_reg = reg_get_psoc_obj(psoc);
227 	if (!IS_VALID_PSOC_REG_OBJ(psoc_reg)) {
228 		reg_err("psoc reg component is NULL");
229 		return QDF_STATUS_E_INVAL;
230 	}
231 
232 	if (reg_is_world_alpha2(cc->country)) {
233 		pdev_priv_obj = reg_get_pdev_obj(pdev);
234 		if (!IS_VALID_PDEV_REG_OBJ(pdev_priv_obj)) {
235 			reg_err("reg component pdev priv is NULL");
236 			psoc_reg->world_country_pending[phy_id] = false;
237 			return QDF_STATUS_E_INVAL;
238 		}
239 		if (reg_is_world_ctry_code(pdev_priv_obj->def_region_domain))
240 			rd.cc.regdmn.reg_2g_5g_pair_id =
241 				pdev_priv_obj->def_region_domain;
242 		else
243 			rd.cc.regdmn.reg_2g_5g_pair_id = DEFAULT_WORLD_REGDMN;
244 		rd.flags = REGDMN_IS_SET;
245 	} else {
246 		qdf_mem_copy(rd.cc.alpha, cc->country, REG_ALPHA2_LEN + 1);
247 		rd.flags = ALPHA_IS_SET;
248 	}
249 
250 	reg_program_chan_list(pdev, &rd);
251 	return QDF_STATUS_SUCCESS;
252 }
253 
254 #ifdef WLAN_REG_PARTIAL_OFFLOAD
255 /**
256  * reg_restore_def_country_for_po() - API to restore country code to default
257  * value if given country is invalid for Partial Offload
258  * @offload_enabled: Is offload enabled
259  * @country: Country code
260  * @cc_country: Country code array
261  * Return- void
262  */
263 static void reg_restore_def_country_for_po(bool offload_enabled,
264 					   uint8_t *country,
265 					   uint8_t cc_country[]){
266 	if (!offload_enabled && !reg_is_world_alpha2(country)) {
267 		QDF_STATUS status;
268 
269 		status = reg_is_country_code_valid(country);
270 		if (!QDF_IS_STATUS_SUCCESS(status)) {
271 			reg_err("Unable to set country code: %s\n", country);
272 			reg_err("Restoring to world domain");
273 			qdf_mem_copy(cc_country, REG_WORLD_ALPHA2,
274 				     REG_ALPHA2_LEN + 1);
275 		}
276 	}
277 }
278 #else
279 static void reg_restore_def_country_for_po(bool offload_enabled,
280 					   uint8_t *country,
281 					   uint8_t cc_country[]){
282 }
283 #endif
284 
285 QDF_STATUS reg_set_country(struct wlan_objmgr_pdev *pdev,
286 			   uint8_t *country)
287 {
288 	struct wlan_regulatory_psoc_priv_obj *psoc_reg;
289 	struct wlan_lmac_if_reg_tx_ops *tx_ops;
290 	struct set_country cc;
291 	struct wlan_objmgr_psoc *psoc;
292 	uint8_t pdev_id;
293 	uint8_t phy_id;
294 
295 	if (!pdev) {
296 		reg_err("pdev is NULL");
297 		return QDF_STATUS_E_INVAL;
298 	}
299 
300 	if (!country) {
301 		reg_err("country code is NULL");
302 		return QDF_STATUS_E_INVAL;
303 	}
304 
305 	pdev_id = wlan_objmgr_pdev_get_pdev_id(pdev);
306 
307 	psoc = wlan_pdev_get_psoc(pdev);
308 
309 	tx_ops = reg_get_psoc_tx_ops(psoc);
310 	if (tx_ops->get_phy_id_from_pdev_id)
311 		tx_ops->get_phy_id_from_pdev_id(psoc, pdev_id, &phy_id);
312 	else
313 		phy_id = pdev_id;
314 
315 	psoc_reg = reg_get_psoc_obj(psoc);
316 	if (!IS_VALID_PSOC_REG_OBJ(psoc_reg)) {
317 		reg_err("psoc reg component is NULL");
318 		return QDF_STATUS_E_INVAL;
319 	}
320 
321 	if (!qdf_mem_cmp(psoc_reg->cur_country, country, REG_ALPHA2_LEN)) {
322 		if (psoc_reg->cc_src == SOURCE_USERSPACE ||
323 		    psoc_reg->cc_src == SOURCE_CORE) {
324 			reg_debug("country is not different");
325 			return QDF_STATUS_E_INVAL;
326 		}
327 	}
328 
329 	reg_debug("programming new country: %s to firmware", country);
330 
331 	qdf_mem_copy(cc.country, country, REG_ALPHA2_LEN + 1);
332 	/*
333 	 * Need firmware to send channel list event
334 	 * for all phys. Therefore set pdev_id to 0xFF.
335 	 */
336 	cc.pdev_id = WMI_HOST_PDEV_ID_SOC;
337 
338 	reg_restore_def_country_for_po(psoc_reg->offload_enabled,
339 				       country,
340 				       cc.country);
341 
342 	if (reg_is_world_alpha2(cc.country))
343 		psoc_reg->world_country_pending[phy_id] = true;
344 	else
345 		psoc_reg->new_user_ctry_pending[phy_id] = true;
346 
347 	if (psoc_reg->offload_enabled) {
348 		tx_ops = reg_get_psoc_tx_ops(psoc);
349 		if (tx_ops->set_country_code) {
350 			tx_ops->set_country_code(psoc, &cc);
351 		} else {
352 			reg_err("country set fw handler not present");
353 			psoc_reg->new_user_ctry_pending[phy_id] = false;
354 			return QDF_STATUS_E_FAULT;
355 		}
356 	} else {
357 		return reg_set_non_offload_country(pdev, &cc);
358 	}
359 
360 	return QDF_STATUS_SUCCESS;
361 }
362 
363 QDF_STATUS reg_reset_country(struct wlan_objmgr_psoc *psoc)
364 {
365 	struct wlan_regulatory_psoc_priv_obj *psoc_reg;
366 
367 	psoc_reg = reg_get_psoc_obj(psoc);
368 	if (!IS_VALID_PSOC_REG_OBJ(psoc_reg)) {
369 		reg_err("psoc reg component is NULL");
370 		return QDF_STATUS_E_INVAL;
371 	}
372 
373 	qdf_mem_copy(psoc_reg->cur_country,
374 		     psoc_reg->def_country,
375 		     REG_ALPHA2_LEN + 1);
376 	reg_debug("set cur_country %.2s", psoc_reg->cur_country);
377 
378 	return QDF_STATUS_SUCCESS;
379 }
380 
381 QDF_STATUS reg_get_domain_from_country_code(v_REGDOMAIN_t *reg_domain_ptr,
382 					    const uint8_t *country_alpha2,
383 					    enum country_src source)
384 {
385 	if (!reg_domain_ptr) {
386 		reg_err("Invalid reg domain pointer");
387 		return QDF_STATUS_E_FAULT;
388 	}
389 
390 	*reg_domain_ptr = 0;
391 
392 	if (!country_alpha2) {
393 		reg_err("Country code is NULL");
394 		return QDF_STATUS_E_FAULT;
395 	}
396 
397 	return QDF_STATUS_SUCCESS;
398 }
399 
400 #ifdef CONFIG_REG_CLIENT
401 #ifdef CONFIG_BAND_6GHZ
402 QDF_STATUS
403 reg_get_6g_power_type_for_ctry(struct wlan_objmgr_psoc *psoc,
404 			       struct wlan_objmgr_pdev *pdev,
405 			       uint8_t *ap_ctry, uint8_t *sta_ctry,
406 			       enum reg_6g_ap_type *pwr_type_6g,
407 			       bool *ctry_code_match,
408 			       enum reg_6g_ap_type ap_pwr_type)
409 {
410 	struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj;
411 
412 	*pwr_type_6g = ap_pwr_type;
413 	pdev_priv_obj = reg_get_pdev_obj(pdev);
414 	if (!pdev_priv_obj) {
415 		reg_err("pdev priv obj null");
416 		return QDF_STATUS_E_FAILURE;
417 	}
418 
419 	reg_debug("STA country: %c%c, AP country: %c%c, AP power type: %d",
420 		  sta_ctry[0], sta_ctry[1], ap_ctry[0], ap_ctry[1],
421 		  ap_pwr_type);
422 
423 	if (!qdf_mem_cmp(ap_ctry, sta_ctry, REG_ALPHA2_LEN)) {
424 		*ctry_code_match = true;
425 		if (ap_pwr_type == REG_VERY_LOW_POWER_AP) {
426 			if (!pdev_priv_obj->reg_rules.num_of_6g_client_reg_rules[ap_pwr_type]) {
427 				reg_err("VLP not supported, can't connect");
428 				return QDF_STATUS_E_NOSUPPORT;
429 			}
430 		}
431 		return QDF_STATUS_SUCCESS;
432 	}
433 
434 	*ctry_code_match = false;
435 	/*
436 	 * If reg_info=0 not included, STA should operate in VLP mode.
437 	 * If STA country doesn't support VLP, do not return if Wi-Fi
438 	 * safe mode or RF test mode or enable relaxed connection policy,
439 	 * rather STA should operate in LPI mode.
440 	 * wlan_cm_get_check_6ghz_security API returns true if
441 	 * neither Safe mode nor RF test mode are enabled.
442 	 * wlan_cm_get_relaxed_6ghz_conn_policy API returns true if
443 	 * enabled.
444 	 */
445 	if (ap_pwr_type != REG_INDOOR_AP) {
446 		if (wlan_reg_ctry_support_vlp(sta_ctry) &&
447 		    wlan_reg_ctry_support_vlp(ap_ctry)) {
448 			reg_debug("STA ctry doesn't match with AP ctry, switch to VLP");
449 			*pwr_type_6g = REG_VERY_LOW_POWER_AP;
450 		} else {
451 			reg_debug("AP or STA doesn't support VLP");
452 			*pwr_type_6g = REG_INDOOR_AP;
453 		}
454 
455 		if (!wlan_reg_ctry_support_vlp(sta_ctry) &&
456 		    wlan_cm_get_check_6ghz_security(psoc) &&
457 		    !wlan_cm_get_relaxed_6ghz_conn_policy(psoc)) {
458 			reg_err("VLP not supported, can't connect");
459 			return QDF_STATUS_E_NOSUPPORT;
460 		}
461 	}
462 
463 	if (ap_pwr_type == REG_INDOOR_AP) {
464 		reg_debug("Indoor AP, allow STA IN LPI");
465 		*pwr_type_6g = REG_INDOOR_AP;
466 	}
467 
468 	return QDF_STATUS_SUCCESS;
469 }
470 #else
471 QDF_STATUS
472 reg_get_6g_power_type_for_ctry(struct wlan_objmgr_psoc *psoc,
473 			       struct wlan_objmgr_pdev *pdev,
474 			       uint8_t *ap_ctry, uint8_t *sta_ctry,
475 			       enum reg_6g_ap_type *pwr_type_6g,
476 			       bool *ctry_code_match,
477 			       enum reg_6g_ap_type ap_pwr_type)
478 {
479 	return QDF_STATUS_SUCCESS;
480 }
481 #endif
482 #endif
483 
484 #ifdef FEATURE_WLAN_CH_AVOID_EXT
485 static inline
486 void reg_get_coex_unsafe_chan_nb_user_prefer(
487 		struct wlan_regulatory_psoc_priv_obj
488 		*psoc_priv_obj,
489 		 struct reg_config_vars config_vars)
490 {
491 	psoc_priv_obj->coex_unsafe_chan_nb_user_prefer =
492 		config_vars.coex_unsafe_chan_nb_user_prefer;
493 }
494 
495 static inline
496 void reg_get_coex_unsafe_chan_reg_disable(
497 		struct wlan_regulatory_psoc_priv_obj *psoc_priv_obj,
498 		struct reg_config_vars config_vars)
499 {
500 	psoc_priv_obj->coex_unsafe_chan_reg_disable =
501 		config_vars.coex_unsafe_chan_reg_disable;
502 }
503 #else
504 static inline
505 void reg_get_coex_unsafe_chan_nb_user_prefer(
506 		struct wlan_regulatory_psoc_priv_obj
507 		*psoc_priv_obj,
508 		struct reg_config_vars config_vars)
509 {
510 }
511 
512 static inline
513 void reg_get_coex_unsafe_chan_reg_disable(
514 		struct wlan_regulatory_psoc_priv_obj *psoc_priv_obj,
515 		struct reg_config_vars config_vars)
516 {
517 }
518 #endif
519 
520 #ifdef CONFIG_CHAN_FREQ_API
521 bool reg_is_passive_or_disable_for_pwrmode(
522 				struct wlan_objmgr_pdev *pdev,
523 				qdf_freq_t freq,
524 				enum supported_6g_pwr_types in_6g_pwr_mode)
525 {
526 	enum channel_state chan_state;
527 
528 	chan_state = reg_get_channel_state_for_pwrmode(pdev, freq,
529 						       in_6g_pwr_mode);
530 
531 	return (chan_state == CHANNEL_STATE_DFS) ||
532 		(chan_state == CHANNEL_STATE_DISABLE);
533 }
534 #endif /* CONFIG_CHAN_FREQ_API */
535 
536 #ifdef WLAN_FEATURE_DSRC
537 #ifdef CONFIG_CHAN_FREQ_API
538 bool reg_is_dsrc_freq(qdf_freq_t freq)
539 {
540 	if (!REG_IS_5GHZ_FREQ(freq))
541 		return false;
542 
543 	if (!(freq >= REG_DSRC_START_FREQ && freq <= REG_DSRC_END_FREQ))
544 		return false;
545 
546 	return true;
547 }
548 #endif  /*CONFIG_CHAN_FREQ_API*/
549 #else
550 bool reg_is_etsi13_regdmn(struct wlan_objmgr_pdev *pdev)
551 {
552 	struct cur_regdmn_info cur_reg_dmn;
553 	QDF_STATUS status;
554 
555 	status = reg_get_curr_regdomain(pdev, &cur_reg_dmn);
556 	if (status != QDF_STATUS_SUCCESS) {
557 		reg_debug_rl("Failed to get reg domain");
558 		return false;
559 	}
560 
561 	return reg_etsi13_regdmn(cur_reg_dmn.dmn_id_5g);
562 }
563 
564 #ifdef CONFIG_CHAN_FREQ_API
565 bool reg_is_etsi13_srd_chan_for_freq(struct wlan_objmgr_pdev *pdev,
566 				     uint16_t freq)
567 {
568 	if (!REG_IS_5GHZ_FREQ(freq))
569 		return false;
570 
571 	if (!(freq >= REG_ETSI13_SRD_START_FREQ &&
572 	      freq <= REG_ETSI13_SRD_END_FREQ))
573 		return false;
574 
575 	return reg_is_etsi13_regdmn(pdev);
576 }
577 #endif /* CONFIG_CHAN_FREQ_API */
578 
579 bool reg_is_etsi13_srd_chan_allowed_master_mode(struct wlan_objmgr_pdev *pdev)
580 {
581 	struct wlan_objmgr_psoc *psoc;
582 	struct wlan_regulatory_psoc_priv_obj *psoc_priv_obj;
583 
584 	if (!pdev) {
585 		reg_alert("pdev is NULL");
586 		return true;
587 	}
588 	psoc = wlan_pdev_get_psoc(pdev);
589 
590 	psoc_priv_obj = reg_get_psoc_obj(psoc);
591 	if (!IS_VALID_PSOC_REG_OBJ(psoc_priv_obj)) {
592 		reg_alert("psoc reg component is NULL");
593 		return true;
594 	}
595 
596 	return psoc_priv_obj->enable_srd_chan_in_master_mode &&
597 	       reg_is_etsi13_regdmn(pdev);
598 }
599 #endif
600 
601 QDF_STATUS reg_set_band(struct wlan_objmgr_pdev *pdev, uint32_t band_bitmap)
602 {
603 	struct wlan_regulatory_psoc_priv_obj *psoc_priv_obj;
604 	struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj;
605 	struct wlan_objmgr_psoc *psoc;
606 	QDF_STATUS status;
607 
608 	pdev_priv_obj = reg_get_pdev_obj(pdev);
609 
610 	if (!IS_VALID_PDEV_REG_OBJ(pdev_priv_obj)) {
611 		reg_err("pdev reg component is NULL");
612 		return QDF_STATUS_E_INVAL;
613 	}
614 
615 	if (pdev_priv_obj->band_capability == band_bitmap) {
616 		reg_info("same band %d", band_bitmap);
617 		return QDF_STATUS_SUCCESS;
618 	}
619 
620 	psoc = wlan_pdev_get_psoc(pdev);
621 	if (!psoc) {
622 		reg_err("psoc is NULL");
623 		return QDF_STATUS_E_INVAL;
624 	}
625 
626 	psoc_priv_obj = reg_get_psoc_obj(psoc);
627 	if (!IS_VALID_PSOC_REG_OBJ(psoc_priv_obj)) {
628 		reg_err("psoc reg component is NULL");
629 		return QDF_STATUS_E_INVAL;
630 	}
631 
632 	reg_info("set band bitmap: %d", band_bitmap);
633 	pdev_priv_obj->band_capability = band_bitmap;
634 
635 	reg_compute_pdev_current_chan_list(pdev_priv_obj);
636 
637 	status = reg_send_scheduler_msg_sb(psoc, pdev);
638 
639 	return status;
640 }
641 
642 QDF_STATUS reg_get_band(struct wlan_objmgr_pdev *pdev,
643 			uint32_t *band_bitmap)
644 {
645 	struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj;
646 
647 	pdev_priv_obj = reg_get_pdev_obj(pdev);
648 
649 	if (!IS_VALID_PDEV_REG_OBJ(pdev_priv_obj)) {
650 		reg_err("pdev reg component is NULL");
651 		return QDF_STATUS_E_INVAL;
652 	}
653 
654 	reg_debug("get band bitmap: %d", pdev_priv_obj->band_capability);
655 	*band_bitmap = pdev_priv_obj->band_capability;
656 
657 	return QDF_STATUS_SUCCESS;
658 }
659 
660 #ifdef DISABLE_CHANNEL_LIST
661 QDF_STATUS reg_restore_cached_channels(struct wlan_objmgr_pdev *pdev)
662 {
663 	struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj;
664 	struct wlan_objmgr_psoc *psoc;
665 	QDF_STATUS status;
666 
667 	pdev_priv_obj = reg_get_pdev_obj(pdev);
668 	if (!IS_VALID_PDEV_REG_OBJ(pdev_priv_obj)) {
669 		reg_err("pdev reg component is NULL");
670 		return QDF_STATUS_E_INVAL;
671 	}
672 
673 	psoc = wlan_pdev_get_psoc(pdev);
674 	if (!psoc) {
675 		reg_err("psoc is NULL");
676 		return QDF_STATUS_E_INVAL;
677 	}
678 
679 	pdev_priv_obj->disable_cached_channels = false;
680 	reg_compute_pdev_current_chan_list(pdev_priv_obj);
681 	status = reg_send_scheduler_msg_sb(psoc, pdev);
682 	return status;
683 }
684 
685 QDF_STATUS reg_disable_cached_channels(struct wlan_objmgr_pdev *pdev)
686 {
687 	struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj;
688 	struct wlan_objmgr_psoc *psoc;
689 	QDF_STATUS status;
690 
691 	pdev_priv_obj = reg_get_pdev_obj(pdev);
692 	if (!IS_VALID_PDEV_REG_OBJ(pdev_priv_obj)) {
693 		reg_err("pdev reg component is NULL");
694 		return QDF_STATUS_E_INVAL;
695 	}
696 
697 	psoc = wlan_pdev_get_psoc(pdev);
698 	if (!psoc) {
699 		reg_err("psoc is NULL");
700 		return QDF_STATUS_E_INVAL;
701 	}
702 
703 	pdev_priv_obj->disable_cached_channels = true;
704 	reg_compute_pdev_current_chan_list(pdev_priv_obj);
705 	status = reg_send_scheduler_msg_sb(psoc, pdev);
706 	return status;
707 }
708 
709 #ifdef CONFIG_CHAN_FREQ_API
710 QDF_STATUS reg_cache_channel_freq_state(struct wlan_objmgr_pdev *pdev,
711 					uint32_t *channel_list,
712 					uint32_t num_channels)
713 {
714 	struct wlan_regulatory_psoc_priv_obj *psoc_priv_obj;
715 	struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj;
716 	struct wlan_objmgr_psoc *psoc;
717 	uint16_t i, j;
718 
719 	pdev_priv_obj = reg_get_pdev_obj(pdev);
720 
721 	if (!IS_VALID_PDEV_REG_OBJ(pdev_priv_obj)) {
722 		reg_err("pdev reg component is NULL");
723 		return QDF_STATUS_E_INVAL;
724 	}
725 
726 	psoc = wlan_pdev_get_psoc(pdev);
727 	if (!psoc) {
728 		reg_err("psoc is NULL");
729 		return QDF_STATUS_E_INVAL;
730 	}
731 
732 	psoc_priv_obj = reg_get_psoc_obj(psoc);
733 	if (!IS_VALID_PSOC_REG_OBJ(psoc_priv_obj)) {
734 		reg_err("psoc reg component is NULL");
735 		return QDF_STATUS_E_INVAL;
736 	}
737 	if (pdev_priv_obj->num_cache_channels > 0) {
738 		pdev_priv_obj->num_cache_channels = 0;
739 		qdf_mem_zero(&pdev_priv_obj->cache_disable_chan_list,
740 			     sizeof(pdev_priv_obj->cache_disable_chan_list));
741 	}
742 
743 	for (i = 0; i < num_channels; i++) {
744 		for (j = 0; j < NUM_CHANNELS; j++) {
745 			if (channel_list[i] == pdev_priv_obj->
746 						cur_chan_list[j].center_freq) {
747 				pdev_priv_obj->
748 					cache_disable_chan_list[i].center_freq =
749 							channel_list[i];
750 				pdev_priv_obj->
751 					cache_disable_chan_list[i].state =
752 					pdev_priv_obj->cur_chan_list[j].state;
753 				pdev_priv_obj->
754 					cache_disable_chan_list[i].chan_flags =
755 					pdev_priv_obj->
756 						cur_chan_list[j].chan_flags;
757 			}
758 		}
759 	}
760 	pdev_priv_obj->num_cache_channels = num_channels;
761 
762 	return QDF_STATUS_SUCCESS;
763 }
764 #endif /* CONFIG_CHAN_FREQ_API */
765 #endif
766 
767 #ifdef CONFIG_REG_CLIENT
768 
769 QDF_STATUS reg_set_fcc_constraint(struct wlan_objmgr_pdev *pdev,
770 				  bool fcc_constraint)
771 {
772 	struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj;
773 	struct wlan_regulatory_psoc_priv_obj *psoc_priv_obj;
774 	struct wlan_objmgr_psoc *psoc;
775 	QDF_STATUS status;
776 
777 	pdev_priv_obj = reg_get_pdev_obj(pdev);
778 	if (!IS_VALID_PDEV_REG_OBJ(pdev_priv_obj)) {
779 		reg_err("pdev reg component is NULL");
780 		return QDF_STATUS_E_INVAL;
781 	}
782 
783 	if (pdev_priv_obj->set_fcc_channel == fcc_constraint) {
784 		reg_debug("same fcc_constraint %d", fcc_constraint);
785 		return QDF_STATUS_SUCCESS;
786 	}
787 
788 	reg_debug("set fcc_constraint: %d", fcc_constraint);
789 
790 	psoc = wlan_pdev_get_psoc(pdev);
791 	if (!psoc) {
792 		reg_err("psoc is NULL");
793 		return QDF_STATUS_E_INVAL;
794 	}
795 
796 	psoc_priv_obj = reg_get_psoc_obj(psoc);
797 	if (!IS_VALID_PSOC_REG_OBJ(psoc_priv_obj)) {
798 		reg_err("psoc reg component is NULL");
799 		return QDF_STATUS_E_INVAL;
800 	}
801 
802 	psoc_priv_obj->set_fcc_channel = fcc_constraint;
803 	pdev_priv_obj->set_fcc_channel = fcc_constraint;
804 
805 	reg_compute_pdev_current_chan_list(pdev_priv_obj);
806 
807 	status = reg_send_scheduler_msg_sb(psoc, pdev);
808 
809 	return status;
810 }
811 
812 bool reg_get_fcc_constraint(struct wlan_objmgr_pdev *pdev, uint32_t freq)
813 {
814 	struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj;
815 
816 	pdev_priv_obj = reg_get_pdev_obj(pdev);
817 	if (!IS_VALID_PDEV_REG_OBJ(pdev_priv_obj)) {
818 		reg_err("pdev reg component is NULL");
819 		return false;
820 	}
821 
822 	if (freq != CHAN_12_CENT_FREQ && freq != CHAN_13_CENT_FREQ)
823 		return false;
824 
825 	if (!pdev_priv_obj->set_fcc_channel)
826 		return false;
827 
828 	return true;
829 }
830 
831 #ifdef CONFIG_BAND_6GHZ
832 /**
833  * reg_is_afc_available() - check if the automated frequency control system is
834  * available, function will need to be updated once AFC is implemented
835  * @pdev: Pointer to pdev structure
836  *
837  * Return: false since the AFC system is not yet available
838  */
839 static bool reg_is_afc_available(struct wlan_objmgr_pdev *pdev)
840 {
841 	return false;
842 }
843 
844 enum reg_6g_ap_type reg_decide_6g_ap_pwr_type(struct wlan_objmgr_pdev *pdev)
845 {
846 	struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj;
847 	enum reg_6g_ap_type ap_pwr_type = REG_INDOOR_AP;
848 
849 	pdev_priv_obj = reg_get_pdev_obj(pdev);
850 	if (!IS_VALID_PDEV_REG_OBJ(pdev_priv_obj)) {
851 		reg_err("pdev reg component is NULL");
852 		return REG_VERY_LOW_POWER_AP;
853 	}
854 
855 	if (reg_is_afc_available(pdev)) {
856 		ap_pwr_type = REG_STANDARD_POWER_AP;
857 	} else if (pdev_priv_obj->indoor_chan_enabled) {
858 		if (pdev_priv_obj->reg_rules.num_of_6g_ap_reg_rules[REG_INDOOR_AP])
859 			ap_pwr_type = REG_INDOOR_AP;
860 		else
861 			ap_pwr_type = REG_VERY_LOW_POWER_AP;
862 	} else if (pdev_priv_obj->reg_rules.num_of_6g_ap_reg_rules[REG_VERY_LOW_POWER_AP]) {
863 		ap_pwr_type = REG_VERY_LOW_POWER_AP;
864 	}
865 	reg_debug("indoor_chan_enabled %d ap_pwr_type %d",
866 		  pdev_priv_obj->indoor_chan_enabled, ap_pwr_type);
867 
868 	reg_set_ap_pwr_and_update_chan_list(pdev, ap_pwr_type);
869 
870 	return ap_pwr_type;
871 }
872 #endif /* CONFIG_BAND_6GHZ */
873 
874 #endif /* CONFIG_REG_CLIENT */
875 
876 /**
877  * reg_change_pdev_for_config() - Update user configuration in pdev private obj.
878  * @psoc: Pointer to global psoc structure.
879  * @object: Pointer to global pdev structure.
880  * @arg: Pointer to argument list.
881  */
882 static void reg_change_pdev_for_config(struct wlan_objmgr_psoc *psoc,
883 				       void *object, void *arg)
884 {
885 	struct wlan_objmgr_pdev *pdev = (struct wlan_objmgr_pdev *)object;
886 	struct wlan_regulatory_psoc_priv_obj *psoc_priv_obj;
887 	struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj;
888 
889 	psoc_priv_obj = reg_get_psoc_obj(psoc);
890 	if (!psoc_priv_obj) {
891 		reg_err("psoc priv obj is NULL");
892 		return;
893 	}
894 
895 	pdev_priv_obj = reg_get_pdev_obj(pdev);
896 
897 	if (!IS_VALID_PDEV_REG_OBJ(pdev_priv_obj)) {
898 		reg_err("reg pdev private obj is NULL");
899 		return;
900 	}
901 
902 	pdev_priv_obj->dfs_enabled = psoc_priv_obj->dfs_enabled;
903 	pdev_priv_obj->indoor_chan_enabled = psoc_priv_obj->indoor_chan_enabled;
904 	pdev_priv_obj->force_ssc_disable_indoor_channel =
905 		psoc_priv_obj->force_ssc_disable_indoor_channel;
906 	pdev_priv_obj->band_capability = psoc_priv_obj->band_capability;
907 	pdev_priv_obj->sta_sap_scc_on_indoor_channel =
908 		psoc_priv_obj->sta_sap_scc_on_indoor_channel;
909 
910 	reg_compute_pdev_current_chan_list(pdev_priv_obj);
911 
912 	reg_send_scheduler_msg_sb(psoc, pdev);
913 }
914 
915 #if defined(CONFIG_BAND_6GHZ) && defined(CONFIG_AFC_SUPPORT)
916 static inline void
917 reg_set_afc_vars(struct wlan_regulatory_psoc_priv_obj *psoc_priv_obj,
918 		 struct reg_config_vars *config_vars)
919 {
920 	psoc_priv_obj->enable_6ghz_sp_pwrmode_supp =
921 		config_vars->enable_6ghz_sp_pwrmode_supp;
922 	psoc_priv_obj->afc_disable_timer_check =
923 		config_vars->afc_disable_timer_check;
924 	psoc_priv_obj->afc_disable_request_id_check =
925 		config_vars->afc_disable_request_id_check;
926 	psoc_priv_obj->is_afc_reg_noaction =
927 		config_vars->is_afc_reg_noaction;
928 }
929 #else
930 static inline void
931 reg_set_afc_vars(struct wlan_regulatory_psoc_priv_obj *psoc_priv_obj,
932 		 struct reg_config_vars *config_vars)
933 {
934 }
935 #endif
936 
937 QDF_STATUS reg_set_config_vars(struct wlan_objmgr_psoc *psoc,
938 			       struct reg_config_vars config_vars)
939 {
940 	struct wlan_regulatory_psoc_priv_obj *psoc_priv_obj;
941 	QDF_STATUS status;
942 
943 	psoc_priv_obj = reg_get_psoc_obj(psoc);
944 	if (!psoc_priv_obj) {
945 		reg_err("psoc priv obj is NULL");
946 		return QDF_STATUS_E_FAILURE;
947 	}
948 
949 	psoc_priv_obj->enable_11d_supp_original =
950 		config_vars.enable_11d_support;
951 	psoc_priv_obj->scan_11d_interval = config_vars.scan_11d_interval;
952 	psoc_priv_obj->user_ctry_priority = config_vars.userspace_ctry_priority;
953 	psoc_priv_obj->dfs_enabled = config_vars.dfs_enabled;
954 	psoc_priv_obj->indoor_chan_enabled = config_vars.indoor_chan_enabled;
955 	psoc_priv_obj->force_ssc_disable_indoor_channel =
956 		config_vars.force_ssc_disable_indoor_channel;
957 	psoc_priv_obj->band_capability = config_vars.band_capability;
958 	psoc_priv_obj->restart_beaconing = config_vars.restart_beaconing;
959 	psoc_priv_obj->enable_srd_chan_in_master_mode =
960 		config_vars.enable_srd_chan_in_master_mode;
961 	psoc_priv_obj->enable_11d_in_world_mode =
962 		config_vars.enable_11d_in_world_mode;
963 	psoc_priv_obj->enable_5dot9_ghz_chan_in_master_mode =
964 		config_vars.enable_5dot9_ghz_chan_in_master_mode;
965 	psoc_priv_obj->retain_nol_across_regdmn_update =
966 		config_vars.retain_nol_across_regdmn_update;
967 	reg_get_coex_unsafe_chan_nb_user_prefer(psoc_priv_obj, config_vars);
968 	reg_get_coex_unsafe_chan_reg_disable(psoc_priv_obj, config_vars);
969 	psoc_priv_obj->sta_sap_scc_on_indoor_channel =
970 		config_vars.sta_sap_scc_on_indoor_channel;
971 	reg_set_afc_vars(psoc_priv_obj, &config_vars);
972 
973 	status = wlan_objmgr_psoc_try_get_ref(psoc, WLAN_REGULATORY_SB_ID);
974 	if (QDF_IS_STATUS_ERROR(status)) {
975 		reg_err("error taking psoc ref cnt");
976 		return status;
977 	}
978 	status = wlan_objmgr_iterate_obj_list(psoc, WLAN_PDEV_OP,
979 					      reg_change_pdev_for_config,
980 					      NULL, 1, WLAN_REGULATORY_SB_ID);
981 	wlan_objmgr_psoc_release_ref(psoc, WLAN_REGULATORY_SB_ID);
982 
983 	return status;
984 }
985 
986 void reg_program_mas_chan_list(struct wlan_objmgr_psoc *psoc,
987 			       struct regulatory_channel *reg_channels,
988 			       uint8_t *alpha2,
989 			       enum dfs_reg dfs_region)
990 {
991 	struct wlan_regulatory_psoc_priv_obj *psoc_priv_obj;
992 	QDF_STATUS status;
993 	uint32_t count;
994 	enum direction dir;
995 	uint32_t phy_cnt;
996 
997 	psoc_priv_obj = reg_get_psoc_obj(psoc);
998 	if (!psoc_priv_obj) {
999 		reg_err("reg psoc private obj is NULL");
1000 		return;
1001 	}
1002 
1003 	qdf_mem_copy(psoc_priv_obj->cur_country, alpha2,
1004 		     REG_ALPHA2_LEN);
1005 	reg_debug("set cur_country %.2s", psoc_priv_obj->cur_country);
1006 	for (count = 0; count < NUM_CHANNELS; count++) {
1007 		reg_channels[count].chan_num = channel_map[count].chan_num;
1008 		reg_channels[count].center_freq =
1009 			channel_map[count].center_freq;
1010 		reg_channels[count].nol_chan = false;
1011 	}
1012 
1013 	for (phy_cnt = 0; phy_cnt < PSOC_MAX_PHY_REG_CAP; phy_cnt++) {
1014 		qdf_mem_copy(psoc_priv_obj->mas_chan_params[phy_cnt].
1015 			     mas_chan_list, reg_channels,
1016 			     NUM_CHANNELS * sizeof(struct regulatory_channel));
1017 
1018 		psoc_priv_obj->mas_chan_params[phy_cnt].dfs_region =
1019 			dfs_region;
1020 	}
1021 
1022 	dir = SOUTHBOUND;
1023 	status = wlan_objmgr_psoc_try_get_ref(psoc, WLAN_REGULATORY_SB_ID);
1024 	if (QDF_IS_STATUS_ERROR(status)) {
1025 		reg_err("error taking psoc ref cnt");
1026 		return;
1027 	}
1028 	status = wlan_objmgr_iterate_obj_list(
1029 			psoc, WLAN_PDEV_OP, reg_propagate_mas_chan_list_to_pdev,
1030 			&dir, 1, WLAN_REGULATORY_SB_ID);
1031 	wlan_objmgr_psoc_release_ref(psoc, WLAN_REGULATORY_SB_ID);
1032 }
1033 
1034 enum country_src reg_get_cc_and_src(struct wlan_objmgr_psoc *psoc,
1035 				    uint8_t *alpha2)
1036 {
1037 	struct wlan_regulatory_psoc_priv_obj *psoc_priv_obj;
1038 
1039 	psoc_priv_obj = reg_get_psoc_obj(psoc);
1040 	if (!psoc_priv_obj) {
1041 		reg_err("reg psoc private obj is NULL");
1042 		return SOURCE_UNKNOWN;
1043 	}
1044 
1045 	qdf_mem_copy(alpha2, psoc_priv_obj->cur_country, REG_ALPHA2_LEN + 1);
1046 
1047 	return psoc_priv_obj->cc_src;
1048 }
1049 
1050 void reg_reset_ctry_pending_hints(struct wlan_regulatory_psoc_priv_obj
1051 				  *soc_reg)
1052 {
1053 	uint8_t ctr;
1054 
1055 	if (!soc_reg->offload_enabled)
1056 		return;
1057 
1058 	for (ctr = 0; ctr < PSOC_MAX_PHY_REG_CAP; ctr++) {
1059 		soc_reg->new_user_ctry_pending[ctr] = false;
1060 		soc_reg->new_init_ctry_pending[ctr] = false;
1061 		soc_reg->new_11d_ctry_pending[ctr] = false;
1062 		soc_reg->world_country_pending[ctr] = false;
1063 	}
1064 }
1065 
1066 QDF_STATUS reg_set_curr_country(struct wlan_regulatory_psoc_priv_obj *soc_reg,
1067 				struct cur_regulatory_info *regulat_info,
1068 				struct wlan_lmac_if_reg_tx_ops *tx_ops)
1069 {
1070 	struct wlan_objmgr_psoc *psoc = regulat_info->psoc;
1071 	struct wlan_objmgr_pdev *pdev;
1072 	uint8_t pdev_id;
1073 	uint8_t phy_id;
1074 	uint8_t phy_num;
1075 	struct set_country country_code;
1076 	QDF_STATUS status;
1077 
1078 	/*
1079 	 * During SSR/WLAN restart ignore master channel list
1080 	 * for all events and in the last event handling if
1081 	 * current country and default country is different, send the last
1082 	 * configured (soc_reg->cur_country) country.
1083 	 */
1084 	if ((regulat_info->num_phy != regulat_info->phy_id + 1) ||
1085 	    (!qdf_mem_cmp(soc_reg->cur_country, regulat_info->alpha2,
1086 			  REG_ALPHA2_LEN)))
1087 		return QDF_STATUS_SUCCESS;
1088 
1089 	/*
1090 	 * Need firmware to send channel list event
1091 	 * for all phys. Therefore set pdev_id to 0xFF.
1092 	 */
1093 	pdev_id = WMI_HOST_PDEV_ID_SOC;
1094 	for (phy_num = 0; phy_num < regulat_info->num_phy; phy_num++) {
1095 		if (soc_reg->cc_src == SOURCE_USERSPACE)
1096 			soc_reg->new_user_ctry_pending[phy_num] = true;
1097 		else if (soc_reg->cc_src == SOURCE_11D)
1098 			soc_reg->new_11d_ctry_pending[phy_num] = true;
1099 		else
1100 			soc_reg->world_country_pending[phy_num] = true;
1101 	}
1102 
1103 	qdf_mem_zero(&country_code, sizeof(country_code));
1104 	qdf_mem_copy(country_code.country, soc_reg->cur_country,
1105 		     sizeof(soc_reg->cur_country));
1106 	country_code.pdev_id = pdev_id;
1107 
1108 	if (soc_reg->offload_enabled) {
1109 		if (!tx_ops || !tx_ops->set_country_code) {
1110 			reg_err("No regulatory tx_ops");
1111 			status = QDF_STATUS_E_FAULT;
1112 			goto error;
1113 		}
1114 		status = tx_ops->set_country_code(psoc, &country_code);
1115 		if (QDF_IS_STATUS_ERROR(status)) {
1116 			reg_err("Failed to send country code to fw");
1117 			goto error;
1118 		}
1119 	} else {
1120 		phy_id = regulat_info->phy_id;
1121 		if (tx_ops->get_pdev_id_from_phy_id)
1122 			tx_ops->get_pdev_id_from_phy_id(psoc, phy_id, &pdev_id);
1123 		else
1124 			pdev_id = phy_id;
1125 
1126 		pdev = wlan_objmgr_get_pdev_by_id(psoc, pdev_id,
1127 						  WLAN_REGULATORY_NB_ID);
1128 		status = reg_set_non_offload_country(pdev, &country_code);
1129 		wlan_objmgr_pdev_release_ref(pdev, WLAN_REGULATORY_NB_ID);
1130 		if (QDF_IS_STATUS_ERROR(status)) {
1131 			reg_err("Failed to set country code");
1132 			goto error;
1133 		}
1134 	}
1135 
1136 	reg_debug("Target CC: %.2s, Restore to Previous CC: %.2s",
1137 		  regulat_info->alpha2, soc_reg->cur_country);
1138 
1139 	return status;
1140 
1141 error:
1142 	reg_reset_ctry_pending_hints(soc_reg);
1143 
1144 	return status;
1145 }
1146 
1147 bool reg_ignore_default_country(struct wlan_regulatory_psoc_priv_obj *soc_reg,
1148 				struct cur_regulatory_info *regulat_info)
1149 {
1150 	uint8_t phy_num;
1151 
1152 	if (soc_reg->cc_src == SOURCE_UNKNOWN)
1153 		return false;
1154 
1155 	phy_num = regulat_info->phy_id;
1156 	if (soc_reg->new_user_ctry_pending[phy_num] ||
1157 	    soc_reg->new_init_ctry_pending[phy_num] ||
1158 	    soc_reg->new_11d_ctry_pending[phy_num] ||
1159 	    soc_reg->world_country_pending[phy_num])
1160 		return false;
1161 
1162 	return true;
1163 }
1164