xref: /wlan-dirver/qca-wifi-host-cmn/umac/regulatory/core/src/reg_utils.c (revision 3ea9fb0844508b933f0a76c36153a857532b8bee)
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 QDF_STATUS reg_set_default_country(struct wlan_objmgr_psoc *psoc,
108 				   uint8_t *country)
109 {
110 	struct wlan_regulatory_psoc_priv_obj *psoc_reg;
111 
112 	if (!country) {
113 		reg_err("country is NULL");
114 		return QDF_STATUS_E_INVAL;
115 	}
116 
117 	psoc_reg = reg_get_psoc_obj(psoc);
118 	if (!IS_VALID_PSOC_REG_OBJ(psoc_reg)) {
119 		reg_err("psoc reg component is NULL");
120 		return QDF_STATUS_E_INVAL;
121 	}
122 
123 	reg_info("set default_country: %s", country);
124 
125 	qdf_mem_copy(psoc_reg->def_country, country, REG_ALPHA2_LEN + 1);
126 
127 	return QDF_STATUS_SUCCESS;
128 }
129 
130 bool reg_is_world_alpha2(uint8_t *alpha2)
131 {
132 	if ((alpha2[0] == '0') && (alpha2[1] == '0'))
133 		return true;
134 
135 	return false;
136 }
137 
138 bool reg_is_us_alpha2(uint8_t *alpha2)
139 {
140 	if ((alpha2[0] == 'U') && (alpha2[1] == 'S'))
141 		return true;
142 
143 	return false;
144 }
145 
146 bool reg_is_etsi_alpha2(uint8_t *alpha2)
147 {
148 	if ((alpha2[0] == 'G') && (alpha2[1] == 'B'))
149 		return true;
150 
151 	return false;
152 }
153 
154 static
155 const char *reg_get_power_mode_string(uint16_t reg_dmn_pair_id)
156 {
157 	switch (reg_dmn_pair_id) {
158 	case FCC3_FCCA:
159 	case FCC6_FCCA:
160 		return "NON_VLP";
161 	default:
162 		return "VLP";
163 	}
164 }
165 
166 static bool reg_ctry_domain_supports_vlp(uint8_t *alpha2)
167 {
168 	uint16_t i;
169 	int no_of_countries;
170 
171 	reg_get_num_countries(&no_of_countries);
172 	for (i = 0; i < no_of_countries; i++) {
173 		if (g_all_countries[i].alpha2[0] == alpha2[0] &&
174 		    g_all_countries[i].alpha2[1] == alpha2[1]) {
175 			if (!qdf_str_cmp(reg_get_power_mode_string(
176 			    g_all_countries[i].reg_dmn_pair_id), "NON_VLP"))
177 				return false;
178 			else
179 				return true;
180 		}
181 	}
182 	return true;
183 }
184 
185 bool reg_ctry_support_vlp(uint8_t *alpha2)
186 {
187 	if (((alpha2[0] == 'A') && (alpha2[1] == 'E')) ||
188 	    ((alpha2[0] == 'P') && (alpha2[1] == 'E')) ||
189 	    ((alpha2[0] == 'U') && (alpha2[1] == 'S')) ||
190 	   !reg_ctry_domain_supports_vlp(alpha2))
191 		return false;
192 	else
193 		return true;
194 }
195 
196 static QDF_STATUS reg_set_non_offload_country(struct wlan_objmgr_pdev *pdev,
197 					      struct set_country *cc)
198 {
199 	struct wlan_objmgr_psoc *psoc;
200 	struct wlan_lmac_if_reg_tx_ops *tx_ops;
201 	struct wlan_regulatory_psoc_priv_obj *psoc_reg;
202 	struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj;
203 	struct cc_regdmn_s rd;
204 	uint8_t pdev_id;
205 	uint8_t phy_id;
206 
207 	if (!pdev) {
208 		reg_err("pdev is NULL");
209 		return QDF_STATUS_E_INVAL;
210 	}
211 
212 	pdev_id = wlan_objmgr_pdev_get_pdev_id(pdev);
213 	psoc = wlan_pdev_get_psoc(pdev);
214 	tx_ops = reg_get_psoc_tx_ops(psoc);
215 	if (tx_ops->get_phy_id_from_pdev_id)
216 		tx_ops->get_phy_id_from_pdev_id(psoc, pdev_id, &phy_id);
217 	else
218 		phy_id = pdev_id;
219 
220 	psoc_reg = reg_get_psoc_obj(psoc);
221 	if (!IS_VALID_PSOC_REG_OBJ(psoc_reg)) {
222 		reg_err("psoc reg component is NULL");
223 		return QDF_STATUS_E_INVAL;
224 	}
225 
226 	if (reg_is_world_alpha2(cc->country)) {
227 		pdev_priv_obj = reg_get_pdev_obj(pdev);
228 		if (!IS_VALID_PDEV_REG_OBJ(pdev_priv_obj)) {
229 			reg_err("reg component pdev priv is NULL");
230 			psoc_reg->world_country_pending[phy_id] = false;
231 			return QDF_STATUS_E_INVAL;
232 		}
233 		if (reg_is_world_ctry_code(pdev_priv_obj->def_region_domain))
234 			rd.cc.regdmn.reg_2g_5g_pair_id =
235 				pdev_priv_obj->def_region_domain;
236 		else
237 			rd.cc.regdmn.reg_2g_5g_pair_id = DEFAULT_WORLD_REGDMN;
238 		rd.flags = REGDMN_IS_SET;
239 	} else {
240 		qdf_mem_copy(rd.cc.alpha, cc->country, REG_ALPHA2_LEN + 1);
241 		rd.flags = ALPHA_IS_SET;
242 	}
243 
244 	reg_program_chan_list(pdev, &rd);
245 	return QDF_STATUS_SUCCESS;
246 }
247 
248 #ifdef WLAN_REG_PARTIAL_OFFLOAD
249 /**
250  * reg_restore_def_country_for_po() - API to restore country code to default
251  * value if given country is invalid for Partial Offload
252  * @offload_enabled: Is offload enabled
253  * @country: Country code
254  * @cc_country: Country code array
255  * Return- void
256  */
257 static void reg_restore_def_country_for_po(bool offload_enabled,
258 					   uint8_t *country,
259 					   uint8_t cc_country[]){
260 	if (!offload_enabled && !reg_is_world_alpha2(country)) {
261 		QDF_STATUS status;
262 
263 		status = reg_is_country_code_valid(country);
264 		if (!QDF_IS_STATUS_SUCCESS(status)) {
265 			reg_err("Unable to set country code: %s\n", country);
266 			reg_err("Restoring to world domain");
267 			qdf_mem_copy(cc_country, REG_WORLD_ALPHA2,
268 				     REG_ALPHA2_LEN + 1);
269 		}
270 	}
271 }
272 #else
273 static void reg_restore_def_country_for_po(bool offload_enabled,
274 					   uint8_t *country,
275 					   uint8_t cc_country[]){
276 }
277 #endif
278 
279 QDF_STATUS reg_set_country(struct wlan_objmgr_pdev *pdev,
280 			   uint8_t *country)
281 {
282 	struct wlan_regulatory_psoc_priv_obj *psoc_reg;
283 	struct wlan_lmac_if_reg_tx_ops *tx_ops;
284 	struct set_country cc;
285 	struct wlan_objmgr_psoc *psoc;
286 	uint8_t pdev_id;
287 	uint8_t phy_id;
288 
289 	if (!pdev) {
290 		reg_err("pdev is NULL");
291 		return QDF_STATUS_E_INVAL;
292 	}
293 
294 	if (!country) {
295 		reg_err("country code is NULL");
296 		return QDF_STATUS_E_INVAL;
297 	}
298 
299 	pdev_id = wlan_objmgr_pdev_get_pdev_id(pdev);
300 
301 	psoc = wlan_pdev_get_psoc(pdev);
302 
303 	tx_ops = reg_get_psoc_tx_ops(psoc);
304 	if (tx_ops->get_phy_id_from_pdev_id)
305 		tx_ops->get_phy_id_from_pdev_id(psoc, pdev_id, &phy_id);
306 	else
307 		phy_id = pdev_id;
308 
309 	psoc_reg = reg_get_psoc_obj(psoc);
310 	if (!IS_VALID_PSOC_REG_OBJ(psoc_reg)) {
311 		reg_err("psoc reg component is NULL");
312 		return QDF_STATUS_E_INVAL;
313 	}
314 
315 	if (!qdf_mem_cmp(psoc_reg->cur_country, country, REG_ALPHA2_LEN)) {
316 		if (psoc_reg->cc_src == SOURCE_USERSPACE ||
317 		    psoc_reg->cc_src == SOURCE_CORE) {
318 			reg_debug("country is not different");
319 			return QDF_STATUS_E_INVAL;
320 		}
321 	}
322 
323 	reg_debug("programming new country: %s to firmware", country);
324 
325 	qdf_mem_copy(cc.country, country, REG_ALPHA2_LEN + 1);
326 	/*
327 	 * Need firmware to send channel list event
328 	 * for all phys. Therefore set pdev_id to 0xFF.
329 	 */
330 	cc.pdev_id = WMI_HOST_PDEV_ID_SOC;
331 
332 	reg_restore_def_country_for_po(psoc_reg->offload_enabled,
333 				       country,
334 				       cc.country);
335 
336 	if (reg_is_world_alpha2(cc.country))
337 		psoc_reg->world_country_pending[phy_id] = true;
338 	else
339 		psoc_reg->new_user_ctry_pending[phy_id] = true;
340 
341 	if (psoc_reg->offload_enabled) {
342 		tx_ops = reg_get_psoc_tx_ops(psoc);
343 		if (tx_ops->set_country_code) {
344 			tx_ops->set_country_code(psoc, &cc);
345 		} else {
346 			reg_err("country set fw handler not present");
347 			psoc_reg->new_user_ctry_pending[phy_id] = false;
348 			return QDF_STATUS_E_FAULT;
349 		}
350 	} else {
351 		return reg_set_non_offload_country(pdev, &cc);
352 	}
353 
354 	return QDF_STATUS_SUCCESS;
355 }
356 
357 QDF_STATUS reg_reset_country(struct wlan_objmgr_psoc *psoc)
358 {
359 	struct wlan_regulatory_psoc_priv_obj *psoc_reg;
360 
361 	psoc_reg = reg_get_psoc_obj(psoc);
362 	if (!IS_VALID_PSOC_REG_OBJ(psoc_reg)) {
363 		reg_err("psoc reg component is NULL");
364 		return QDF_STATUS_E_INVAL;
365 	}
366 
367 	qdf_mem_copy(psoc_reg->cur_country,
368 		     psoc_reg->def_country,
369 		     REG_ALPHA2_LEN + 1);
370 	reg_debug("set cur_country %.2s", psoc_reg->cur_country);
371 
372 	return QDF_STATUS_SUCCESS;
373 }
374 
375 QDF_STATUS reg_get_domain_from_country_code(v_REGDOMAIN_t *reg_domain_ptr,
376 					    const uint8_t *country_alpha2,
377 					    enum country_src source)
378 {
379 	if (!reg_domain_ptr) {
380 		reg_err("Invalid reg domain pointer");
381 		return QDF_STATUS_E_FAULT;
382 	}
383 
384 	*reg_domain_ptr = 0;
385 
386 	if (!country_alpha2) {
387 		reg_err("Country code is NULL");
388 		return QDF_STATUS_E_FAULT;
389 	}
390 
391 	return QDF_STATUS_SUCCESS;
392 }
393 
394 #if defined(CONFIG_REG_CLIENT) && defined(CONFIG_BAND_6GHZ)
395 QDF_STATUS
396 reg_get_6ghz_cli_pwr_type_per_ap_pwr_type(
397 				struct wlan_objmgr_pdev *pdev,
398 				enum reg_6g_ap_type ap_pwr_type,
399 				enum supported_6g_pwr_types *cli_pwr_type)
400 {
401 	enum reg_6g_client_type client_type;
402 
403 	reg_get_cur_6g_client_type(pdev, &client_type);
404 
405 	if (client_type == REG_DEFAULT_CLIENT) {
406 		if (ap_pwr_type == REG_INDOOR_AP)
407 			*cli_pwr_type = REG_CLI_DEF_LPI;
408 		else if (ap_pwr_type == REG_VERY_LOW_POWER_AP)
409 			*cli_pwr_type = REG_CLI_DEF_VLP;
410 		else if (ap_pwr_type == REG_STANDARD_POWER_AP)
411 			*cli_pwr_type = REG_CLI_DEF_SP;
412 		else
413 			return QDF_STATUS_E_FAILURE;
414 	} else if (client_type == REG_SUBORDINATE_CLIENT) {
415 		if (ap_pwr_type == REG_INDOOR_AP)
416 			*cli_pwr_type = REG_CLI_SUB_LPI;
417 		else if (ap_pwr_type == REG_VERY_LOW_POWER_AP)
418 			*cli_pwr_type = REG_CLI_SUB_VLP;
419 		else if (ap_pwr_type == REG_STANDARD_POWER_AP)
420 			*cli_pwr_type = REG_CLI_SUB_SP;
421 		else
422 			return QDF_STATUS_E_FAILURE;
423 	} else {
424 		return QDF_STATUS_E_FAILURE;
425 	}
426 
427 	return QDF_STATUS_SUCCESS;
428 }
429 #endif
430 
431 #ifdef CONFIG_REG_CLIENT
432 #ifdef CONFIG_BAND_6GHZ
433 /**
434  * reg_check_if_6g_pwr_type_supp_for_chan() - Check if 6 GHz power type is
435  *                                            supported for the channel
436  * @pdev: Pointer to pdev
437  * @pwr_type: 6 GHz power type
438  * @chan_idx: Connection channel index
439  *
440  * Return: Return QDF_STATUS_SUCCESS if 6 GHz power type supported for
441  *         the given channel, else return QDF_STATUS_E_FAILURE.
442  */
443 static
444 QDF_STATUS reg_check_if_6g_pwr_type_supp_for_chan(
445 			struct wlan_objmgr_pdev *pdev,
446 			enum reg_6g_ap_type pwr_type,
447 			enum channel_enum chan_idx)
448 {
449 	struct super_chan_info *super_chan_list;
450 	enum channel_state *chan_state_arr;
451 	uint32_t *chan_flags_arr;
452 	enum supported_6g_pwr_types cli_pwr_type;
453 	struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj;
454 	uint16_t sup_idx;
455 
456 	pdev_priv_obj = reg_get_pdev_obj(pdev);
457 	if (!pdev_priv_obj) {
458 		reg_err("pdev priv obj null");
459 		return QDF_STATUS_E_FAILURE;
460 	}
461 
462 	sup_idx = reg_convert_enum_to_6g_idx(chan_idx);
463 	if (sup_idx >= NUM_6GHZ_CHANNELS) {
464 		reg_err("Invalid channel");
465 		return QDF_STATUS_E_NOSUPPORT;
466 	}
467 
468 	if (QDF_IS_STATUS_ERROR(reg_get_6ghz_cli_pwr_type_per_ap_pwr_type(
469 					pdev, pwr_type, &cli_pwr_type)))
470 		goto no_support;
471 
472 	super_chan_list = pdev_priv_obj->super_chan_list;
473 	chan_state_arr = super_chan_list[sup_idx].state_arr;
474 	chan_flags_arr = super_chan_list[sup_idx].chan_flags_arr;
475 	if (reg_is_state_allowed(chan_state_arr[cli_pwr_type]) &&
476 	    !(chan_flags_arr[cli_pwr_type] & REGULATORY_CHAN_DISABLED))
477 		return QDF_STATUS_SUCCESS;
478 
479 no_support:
480 	reg_err("6 GHz power type = %d not supported for 6 GHz channel idx = %d",
481 		cli_pwr_type, sup_idx);
482 	return QDF_STATUS_E_NOSUPPORT;
483 }
484 
485 QDF_STATUS
486 reg_get_best_6g_power_type(struct wlan_objmgr_psoc *psoc,
487 			   struct wlan_objmgr_pdev *pdev,
488 			   enum reg_6g_ap_type *pwr_type_6g,
489 			   enum reg_6g_ap_type ap_pwr_type,
490 			   uint32_t chan_freq)
491 {
492 	struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj;
493 	enum channel_enum chan_idx = reg_get_chan_enum_for_freq(chan_freq);
494 
495 	*pwr_type_6g = ap_pwr_type;
496 	pdev_priv_obj = reg_get_pdev_obj(pdev);
497 	if (!pdev_priv_obj) {
498 		reg_err("pdev priv obj null");
499 		return QDF_STATUS_E_FAILURE;
500 	}
501 
502 	/*
503 	 * If AP doesn't advertise 6 GHz power type or advertised invalid power
504 	 * type, select VLP power type if VLP rules are present for the
505 	 * connection channel, if not select LPI power type if LPI rules are
506 	 * present for connection channel, otherwise don't connect.
507 	 */
508 	if (ap_pwr_type < REG_INDOOR_AP ||
509 	    ap_pwr_type >= REG_CURRENT_MAX_AP_TYPE) {
510 		if (QDF_IS_STATUS_SUCCESS(
511 			reg_check_if_6g_pwr_type_supp_for_chan(pdev,
512 							REG_VERY_LOW_POWER_AP,
513 							chan_idx))) {
514 			reg_debug("Invalid AP power type: %d , selected power type: %d",
515 				  ap_pwr_type, REG_VERY_LOW_POWER_AP);
516 			*pwr_type_6g = REG_VERY_LOW_POWER_AP;
517 			return QDF_STATUS_SUCCESS;
518 		} else if (QDF_IS_STATUS_SUCCESS(
519 				reg_check_if_6g_pwr_type_supp_for_chan(pdev,
520 								REG_INDOOR_AP,
521 								chan_idx))) {
522 			reg_debug("Invalid AP power type: %d , selected power type: %d",
523 				  ap_pwr_type, REG_INDOOR_AP);
524 			*pwr_type_6g = REG_INDOOR_AP;
525 			return QDF_STATUS_SUCCESS;
526 		} else {
527 			reg_err("Invalid AP power type: %d, couldn't find suitable power type",
528 				ap_pwr_type);
529 			return QDF_STATUS_E_NOSUPPORT;
530 		}
531 	}
532 
533 	if (pdev_priv_obj->reg_rules.num_of_6g_client_reg_rules[ap_pwr_type] &&
534 	    QDF_IS_STATUS_SUCCESS(reg_check_if_6g_pwr_type_supp_for_chan(
535 						pdev,
536 						ap_pwr_type, chan_idx))) {
537 		reg_debug("AP power type: %d , is supported by client",
538 			  ap_pwr_type);
539 		return QDF_STATUS_SUCCESS;
540 	}
541 
542 	if (ap_pwr_type == REG_INDOOR_AP) {
543 		if (pdev_priv_obj->reg_rules.num_of_6g_client_reg_rules[REG_VERY_LOW_POWER_AP] &&
544 		    QDF_IS_STATUS_SUCCESS(
545 			reg_check_if_6g_pwr_type_supp_for_chan(pdev,
546 							REG_VERY_LOW_POWER_AP,
547 							chan_idx))) {
548 			*pwr_type_6g = REG_VERY_LOW_POWER_AP;
549 			reg_debug("AP power type = %d, selected power type = %d",
550 				  ap_pwr_type, *pwr_type_6g);
551 			return QDF_STATUS_SUCCESS;
552 		} else {
553 			goto no_support;
554 		}
555 	} else if (ap_pwr_type == REG_STANDARD_POWER_AP) {
556 		if (pdev_priv_obj->reg_rules.num_of_6g_client_reg_rules[REG_VERY_LOW_POWER_AP] &&
557 		    QDF_IS_STATUS_SUCCESS(
558 			reg_check_if_6g_pwr_type_supp_for_chan(pdev,
559 							REG_VERY_LOW_POWER_AP,
560 							chan_idx))) {
561 			if (wlan_cm_get_disable_vlp_sta_conn_to_sp_ap(psoc)) {
562 				reg_debug("AP SP and STA VLP connection disabled");
563 				return QDF_STATUS_E_NOSUPPORT;
564 			}
565 			*pwr_type_6g = REG_VERY_LOW_POWER_AP;
566 			reg_debug("AP power type = %d, selected power type = %d",
567 				  ap_pwr_type, *pwr_type_6g);
568 			return QDF_STATUS_SUCCESS;
569 		} else {
570 			goto no_support;
571 		}
572 	}
573 
574 no_support:
575 	reg_err("AP power type = %d, not supported", ap_pwr_type);
576 	return QDF_STATUS_E_NOSUPPORT;
577 }
578 #else
579 QDF_STATUS
580 reg_get_best_6g_power_type(struct wlan_objmgr_psoc *psoc,
581 			   struct wlan_objmgr_pdev *pdev,
582 			   enum reg_6g_ap_type *pwr_type_6g,
583 			   enum reg_6g_ap_type ap_pwr_type,
584 			   uint32_t chan_freq)
585 {
586 	return QDF_STATUS_SUCCESS;
587 }
588 #endif
589 #endif
590 
591 #ifdef FEATURE_WLAN_CH_AVOID_EXT
592 static inline
593 void reg_get_coex_unsafe_chan_nb_user_prefer(
594 		struct wlan_regulatory_psoc_priv_obj
595 		*psoc_priv_obj,
596 		 struct reg_config_vars config_vars)
597 {
598 	psoc_priv_obj->coex_unsafe_chan_nb_user_prefer =
599 		config_vars.coex_unsafe_chan_nb_user_prefer;
600 }
601 
602 static inline
603 void reg_get_coex_unsafe_chan_reg_disable(
604 		struct wlan_regulatory_psoc_priv_obj *psoc_priv_obj,
605 		struct reg_config_vars config_vars)
606 {
607 	psoc_priv_obj->coex_unsafe_chan_reg_disable =
608 		config_vars.coex_unsafe_chan_reg_disable;
609 }
610 #else
611 static inline
612 void reg_get_coex_unsafe_chan_nb_user_prefer(
613 		struct wlan_regulatory_psoc_priv_obj
614 		*psoc_priv_obj,
615 		struct reg_config_vars config_vars)
616 {
617 }
618 
619 static inline
620 void reg_get_coex_unsafe_chan_reg_disable(
621 		struct wlan_regulatory_psoc_priv_obj *psoc_priv_obj,
622 		struct reg_config_vars config_vars)
623 {
624 }
625 #endif
626 
627 #ifdef CONFIG_CHAN_FREQ_API
628 bool reg_is_passive_or_disable_for_pwrmode(
629 				struct wlan_objmgr_pdev *pdev,
630 				qdf_freq_t freq,
631 				enum supported_6g_pwr_types in_6g_pwr_mode)
632 {
633 	enum channel_state chan_state;
634 
635 	chan_state = reg_get_channel_state_for_pwrmode(pdev, freq,
636 						       in_6g_pwr_mode);
637 
638 	return (chan_state == CHANNEL_STATE_DFS) ||
639 		(chan_state == CHANNEL_STATE_DISABLE);
640 }
641 #endif /* CONFIG_CHAN_FREQ_API */
642 
643 #ifdef WLAN_FEATURE_DSRC
644 #ifdef CONFIG_CHAN_FREQ_API
645 bool reg_is_dsrc_freq(qdf_freq_t freq)
646 {
647 	if (!REG_IS_5GHZ_FREQ(freq))
648 		return false;
649 
650 	if (!(freq >= REG_DSRC_START_FREQ && freq <= REG_DSRC_END_FREQ))
651 		return false;
652 
653 	return true;
654 }
655 #endif  /*CONFIG_CHAN_FREQ_API*/
656 #else
657 bool reg_is_etsi13_regdmn(struct wlan_objmgr_pdev *pdev)
658 {
659 	struct cur_regdmn_info cur_reg_dmn;
660 	QDF_STATUS status;
661 
662 	status = reg_get_curr_regdomain(pdev, &cur_reg_dmn);
663 	if (status != QDF_STATUS_SUCCESS) {
664 		reg_debug_rl("Failed to get reg domain");
665 		return false;
666 	}
667 
668 	return reg_etsi13_regdmn(cur_reg_dmn.dmn_id_5g);
669 }
670 
671 #ifdef CONFIG_CHAN_FREQ_API
672 bool reg_is_etsi13_srd_chan_for_freq(struct wlan_objmgr_pdev *pdev,
673 				     uint16_t freq)
674 {
675 	if (!REG_IS_5GHZ_FREQ(freq))
676 		return false;
677 
678 	if (!(freq >= REG_ETSI13_SRD_START_FREQ &&
679 	      freq <= REG_ETSI13_SRD_END_FREQ))
680 		return false;
681 
682 	return reg_is_etsi13_regdmn(pdev);
683 }
684 #endif /* CONFIG_CHAN_FREQ_API */
685 
686 bool reg_is_etsi13_srd_chan_allowed_master_mode(struct wlan_objmgr_pdev *pdev)
687 {
688 	struct wlan_objmgr_psoc *psoc;
689 	struct wlan_regulatory_psoc_priv_obj *psoc_priv_obj;
690 
691 	if (!pdev) {
692 		reg_alert("pdev is NULL");
693 		return true;
694 	}
695 	psoc = wlan_pdev_get_psoc(pdev);
696 
697 	psoc_priv_obj = reg_get_psoc_obj(psoc);
698 	if (!IS_VALID_PSOC_REG_OBJ(psoc_priv_obj)) {
699 		reg_alert("psoc reg component is NULL");
700 		return true;
701 	}
702 
703 	return psoc_priv_obj->enable_srd_chan_in_master_mode &&
704 	       reg_is_etsi13_regdmn(pdev);
705 }
706 #endif
707 
708 QDF_STATUS reg_set_band(struct wlan_objmgr_pdev *pdev, uint32_t band_bitmap)
709 {
710 	struct wlan_regulatory_psoc_priv_obj *psoc_priv_obj;
711 	struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj;
712 	struct wlan_objmgr_psoc *psoc;
713 	QDF_STATUS status;
714 
715 	pdev_priv_obj = reg_get_pdev_obj(pdev);
716 
717 	if (!IS_VALID_PDEV_REG_OBJ(pdev_priv_obj)) {
718 		reg_err("pdev reg component is NULL");
719 		return QDF_STATUS_E_INVAL;
720 	}
721 
722 	/*
723 	 * If SET_FCC_CHANNEL 0 command is received first then 6 GHz band would
724 	 * be disabled and band_capability would be set to 3 but existing 6 GHz
725 	 * STA and P2P client connections won't be disconnected.
726 	 * If set band comes again for 6 GHz band disabled and band_bitmap is
727 	 * equal to band_capability, proceed to disable 6 GHz band completely.
728 	 */
729 	if (pdev_priv_obj->band_capability == band_bitmap &&
730 	    !reg_get_keep_6ghz_sta_cli_connection(pdev)) {
731 		reg_info("same band %d", band_bitmap);
732 		return QDF_STATUS_SUCCESS;
733 	}
734 
735 	/*
736 	 * If in current band_capability 6 GHz bit is not set, in current
737 	 * request 6 GHz band might be enabled/disabled. Hence reset
738 	 * reg_set_keep_6ghz_sta_cli_connection flag.
739 	 */
740 	if (!wlan_reg_is_6ghz_band_set(pdev)) {
741 		status = reg_set_keep_6ghz_sta_cli_connection(pdev, false);
742 		if (QDF_IS_STATUS_ERROR(status))
743 			return status;
744 	}
745 
746 	psoc = wlan_pdev_get_psoc(pdev);
747 	if (!psoc) {
748 		reg_err("psoc is NULL");
749 		return QDF_STATUS_E_INVAL;
750 	}
751 
752 	psoc_priv_obj = reg_get_psoc_obj(psoc);
753 	if (!IS_VALID_PSOC_REG_OBJ(psoc_priv_obj)) {
754 		reg_err("psoc reg component is NULL");
755 		return QDF_STATUS_E_INVAL;
756 	}
757 
758 	reg_info("set band bitmap: %d", band_bitmap);
759 	pdev_priv_obj->band_capability = band_bitmap;
760 
761 	reg_compute_pdev_current_chan_list(pdev_priv_obj);
762 
763 	status = reg_send_scheduler_msg_sb(psoc, pdev);
764 
765 	return status;
766 }
767 
768 QDF_STATUS reg_get_band(struct wlan_objmgr_pdev *pdev,
769 			uint32_t *band_bitmap)
770 {
771 	struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj;
772 
773 	pdev_priv_obj = reg_get_pdev_obj(pdev);
774 
775 	if (!IS_VALID_PDEV_REG_OBJ(pdev_priv_obj)) {
776 		reg_err("pdev reg component is NULL");
777 		return QDF_STATUS_E_INVAL;
778 	}
779 
780 	reg_debug("get band bitmap: %d", pdev_priv_obj->band_capability);
781 	*band_bitmap = pdev_priv_obj->band_capability;
782 
783 	return QDF_STATUS_SUCCESS;
784 }
785 
786 #ifdef DISABLE_CHANNEL_LIST
787 QDF_STATUS reg_restore_cached_channels(struct wlan_objmgr_pdev *pdev)
788 {
789 	struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj;
790 	struct wlan_objmgr_psoc *psoc;
791 	QDF_STATUS status;
792 
793 	pdev_priv_obj = reg_get_pdev_obj(pdev);
794 	if (!IS_VALID_PDEV_REG_OBJ(pdev_priv_obj)) {
795 		reg_err("pdev reg component is NULL");
796 		return QDF_STATUS_E_INVAL;
797 	}
798 
799 	psoc = wlan_pdev_get_psoc(pdev);
800 	if (!psoc) {
801 		reg_err("psoc is NULL");
802 		return QDF_STATUS_E_INVAL;
803 	}
804 
805 	pdev_priv_obj->disable_cached_channels = false;
806 	reg_compute_pdev_current_chan_list(pdev_priv_obj);
807 	status = reg_send_scheduler_msg_sb(psoc, pdev);
808 	return status;
809 }
810 
811 QDF_STATUS reg_disable_cached_channels(struct wlan_objmgr_pdev *pdev)
812 {
813 	struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj;
814 	struct wlan_objmgr_psoc *psoc;
815 	QDF_STATUS status;
816 
817 	pdev_priv_obj = reg_get_pdev_obj(pdev);
818 	if (!IS_VALID_PDEV_REG_OBJ(pdev_priv_obj)) {
819 		reg_err("pdev reg component is NULL");
820 		return QDF_STATUS_E_INVAL;
821 	}
822 
823 	psoc = wlan_pdev_get_psoc(pdev);
824 	if (!psoc) {
825 		reg_err("psoc is NULL");
826 		return QDF_STATUS_E_INVAL;
827 	}
828 
829 	pdev_priv_obj->disable_cached_channels = true;
830 	reg_compute_pdev_current_chan_list(pdev_priv_obj);
831 	status = reg_send_scheduler_msg_sb(psoc, pdev);
832 	return status;
833 }
834 
835 #ifdef CONFIG_CHAN_FREQ_API
836 QDF_STATUS reg_cache_channel_freq_state(struct wlan_objmgr_pdev *pdev,
837 					uint32_t *channel_list,
838 					uint32_t num_channels)
839 {
840 	struct wlan_regulatory_psoc_priv_obj *psoc_priv_obj;
841 	struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj;
842 	struct wlan_objmgr_psoc *psoc;
843 	uint16_t i, j;
844 
845 	pdev_priv_obj = reg_get_pdev_obj(pdev);
846 
847 	if (!IS_VALID_PDEV_REG_OBJ(pdev_priv_obj)) {
848 		reg_err("pdev reg component is NULL");
849 		return QDF_STATUS_E_INVAL;
850 	}
851 
852 	psoc = wlan_pdev_get_psoc(pdev);
853 	if (!psoc) {
854 		reg_err("psoc is NULL");
855 		return QDF_STATUS_E_INVAL;
856 	}
857 
858 	psoc_priv_obj = reg_get_psoc_obj(psoc);
859 	if (!IS_VALID_PSOC_REG_OBJ(psoc_priv_obj)) {
860 		reg_err("psoc reg component is NULL");
861 		return QDF_STATUS_E_INVAL;
862 	}
863 	if (pdev_priv_obj->num_cache_channels > 0) {
864 		pdev_priv_obj->num_cache_channels = 0;
865 		qdf_mem_zero(&pdev_priv_obj->cache_disable_chan_list,
866 			     sizeof(pdev_priv_obj->cache_disable_chan_list));
867 	}
868 
869 	for (i = 0; i < num_channels; i++) {
870 		for (j = 0; j < NUM_CHANNELS; j++) {
871 			if (channel_list[i] == pdev_priv_obj->
872 						cur_chan_list[j].center_freq) {
873 				pdev_priv_obj->
874 					cache_disable_chan_list[i].center_freq =
875 							channel_list[i];
876 				pdev_priv_obj->
877 					cache_disable_chan_list[i].state =
878 					pdev_priv_obj->cur_chan_list[j].state;
879 				pdev_priv_obj->
880 					cache_disable_chan_list[i].chan_flags =
881 					pdev_priv_obj->
882 						cur_chan_list[j].chan_flags;
883 			}
884 		}
885 	}
886 	pdev_priv_obj->num_cache_channels = num_channels;
887 
888 	return QDF_STATUS_SUCCESS;
889 }
890 #endif /* CONFIG_CHAN_FREQ_API */
891 #endif
892 
893 #ifdef CONFIG_REG_CLIENT
894 bool reg_get_keep_6ghz_sta_cli_connection(struct wlan_objmgr_pdev *pdev)
895 {
896 	struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj;
897 
898 	pdev_priv_obj = reg_get_pdev_obj(pdev);
899 	if (!IS_VALID_PDEV_REG_OBJ(pdev_priv_obj)) {
900 		reg_err("pdev reg component is NULL");
901 		return false;
902 	}
903 
904 	return pdev_priv_obj->keep_6ghz_sta_cli_connection;
905 }
906 
907 QDF_STATUS reg_set_keep_6ghz_sta_cli_connection(struct wlan_objmgr_pdev *pdev,
908 					bool keep_6ghz_sta_cli_connection)
909 {
910 	struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj;
911 
912 	pdev_priv_obj = reg_get_pdev_obj(pdev);
913 	if (!IS_VALID_PDEV_REG_OBJ(pdev_priv_obj)) {
914 		reg_err("pdev reg component is NULL");
915 		return QDF_STATUS_E_INVAL;
916 	}
917 
918 	pdev_priv_obj->keep_6ghz_sta_cli_connection =
919 			keep_6ghz_sta_cli_connection;
920 
921 	reg_debug("set keep_6ghz_sta_cli_connection = %d",
922 		  keep_6ghz_sta_cli_connection);
923 	return QDF_STATUS_SUCCESS;
924 }
925 
926 QDF_STATUS reg_set_fcc_constraint(struct wlan_objmgr_pdev *pdev,
927 				  bool fcc_constraint)
928 {
929 	struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj;
930 	struct wlan_regulatory_psoc_priv_obj *psoc_priv_obj;
931 	struct wlan_objmgr_psoc *psoc;
932 
933 	pdev_priv_obj = reg_get_pdev_obj(pdev);
934 	if (!IS_VALID_PDEV_REG_OBJ(pdev_priv_obj)) {
935 		reg_err("pdev reg component is NULL");
936 		return QDF_STATUS_E_INVAL;
937 	}
938 
939 	if (pdev_priv_obj->set_fcc_channel == fcc_constraint) {
940 		reg_debug("same fcc_constraint %d", fcc_constraint);
941 		return QDF_STATUS_SUCCESS;
942 	}
943 
944 	reg_debug("set fcc_constraint: %d", fcc_constraint);
945 
946 	psoc = wlan_pdev_get_psoc(pdev);
947 	if (!psoc) {
948 		reg_err("psoc is NULL");
949 		return QDF_STATUS_E_INVAL;
950 	}
951 
952 	psoc_priv_obj = reg_get_psoc_obj(psoc);
953 	if (!IS_VALID_PSOC_REG_OBJ(psoc_priv_obj)) {
954 		reg_err("psoc reg component is NULL");
955 		return QDF_STATUS_E_INVAL;
956 	}
957 
958 	psoc_priv_obj->set_fcc_channel = fcc_constraint;
959 	pdev_priv_obj->set_fcc_channel = fcc_constraint;
960 
961 	return QDF_STATUS_SUCCESS;
962 }
963 
964 bool reg_is_6ghz_band_set(struct wlan_objmgr_pdev *pdev)
965 {
966 	struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj;
967 
968 	pdev_priv_obj = reg_get_pdev_obj(pdev);
969 	if (!IS_VALID_PDEV_REG_OBJ(pdev_priv_obj)) {
970 		reg_err("pdev reg component is NULL");
971 		return false;
972 	}
973 
974 	if (!(pdev_priv_obj->band_capability & BIT(REG_BAND_6G)))
975 		return false;
976 
977 	return true;
978 }
979 
980 bool reg_get_fcc_constraint(struct wlan_objmgr_pdev *pdev, uint32_t freq)
981 {
982 	struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj;
983 
984 	pdev_priv_obj = reg_get_pdev_obj(pdev);
985 	if (!IS_VALID_PDEV_REG_OBJ(pdev_priv_obj)) {
986 		reg_err("pdev reg component is NULL");
987 		return false;
988 	}
989 
990 	if (freq != CHAN_12_CENT_FREQ && freq != CHAN_13_CENT_FREQ)
991 		return false;
992 
993 	if (!pdev_priv_obj->set_fcc_channel)
994 		return false;
995 
996 	return true;
997 }
998 
999 bool reg_is_user_country_set_allowed(struct wlan_objmgr_psoc *psoc)
1000 {
1001 	struct wlan_regulatory_psoc_priv_obj *psoc_reg;
1002 
1003 	psoc_reg = reg_get_psoc_obj(psoc);
1004 	if (!IS_VALID_PSOC_REG_OBJ(psoc_reg)) {
1005 		reg_err("psoc reg component is NULL");
1006 		return false;
1007 	}
1008 
1009 	if (!psoc_reg->user_ctry_priority &&
1010 	    psoc_reg->enable_11d_supp_original) {
1011 		reg_err_rl("country set from userspace is not allowed");
1012 		return false;
1013 	}
1014 
1015 	return true;
1016 }
1017 
1018 bool reg_is_fcc_constraint_set(struct wlan_objmgr_pdev *pdev)
1019 {
1020 	struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj;
1021 
1022 	pdev_priv_obj = reg_get_pdev_obj(pdev);
1023 	if (!IS_VALID_PDEV_REG_OBJ(pdev_priv_obj)) {
1024 		reg_err("pdev reg component is NULL");
1025 		return false;
1026 	}
1027 
1028 	if (!pdev_priv_obj->set_fcc_channel)
1029 		return false;
1030 
1031 	return true;
1032 }
1033 
1034 #ifdef CONFIG_BAND_6GHZ
1035 enum reg_6g_ap_type reg_decide_6g_ap_pwr_type(struct wlan_objmgr_pdev *pdev)
1036 {
1037 	struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj;
1038 	enum reg_6g_ap_type ap_pwr_type = REG_INDOOR_AP;
1039 
1040 	pdev_priv_obj = reg_get_pdev_obj(pdev);
1041 	if (!IS_VALID_PDEV_REG_OBJ(pdev_priv_obj)) {
1042 		reg_err("pdev reg component is NULL");
1043 		return REG_VERY_LOW_POWER_AP;
1044 	}
1045 
1046 	if (wlan_reg_is_afc_power_event_received(pdev) &&
1047 	    pdev_priv_obj->reg_rules.num_of_6g_ap_reg_rules[REG_STANDARD_POWER_AP]) {
1048 		ap_pwr_type = REG_STANDARD_POWER_AP;
1049 	} else if (pdev_priv_obj->indoor_chan_enabled) {
1050 		if (pdev_priv_obj->reg_rules.num_of_6g_ap_reg_rules[REG_INDOOR_AP])
1051 			ap_pwr_type = REG_INDOOR_AP;
1052 		else
1053 			ap_pwr_type = REG_VERY_LOW_POWER_AP;
1054 	} else if (pdev_priv_obj->reg_rules.num_of_6g_ap_reg_rules[REG_VERY_LOW_POWER_AP]) {
1055 		ap_pwr_type = REG_VERY_LOW_POWER_AP;
1056 	}
1057 	reg_debug("indoor_chan_enabled %d ap_pwr_type %d",
1058 		  pdev_priv_obj->indoor_chan_enabled, ap_pwr_type);
1059 
1060 	reg_set_ap_pwr_and_update_chan_list(pdev, ap_pwr_type);
1061 
1062 	return ap_pwr_type;
1063 }
1064 #endif /* CONFIG_BAND_6GHZ */
1065 
1066 #endif /* CONFIG_REG_CLIENT */
1067 
1068 /**
1069  * reg_change_pdev_for_config() - Update user configuration in pdev private obj.
1070  * @psoc: Pointer to global psoc structure.
1071  * @object: Pointer to global pdev structure.
1072  * @arg: Pointer to argument list.
1073  */
1074 static void reg_change_pdev_for_config(struct wlan_objmgr_psoc *psoc,
1075 				       void *object, void *arg)
1076 {
1077 	struct wlan_objmgr_pdev *pdev = (struct wlan_objmgr_pdev *)object;
1078 	struct wlan_regulatory_psoc_priv_obj *psoc_priv_obj;
1079 	struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj;
1080 
1081 	psoc_priv_obj = reg_get_psoc_obj(psoc);
1082 	if (!psoc_priv_obj) {
1083 		reg_err("psoc priv obj is NULL");
1084 		return;
1085 	}
1086 
1087 	pdev_priv_obj = reg_get_pdev_obj(pdev);
1088 
1089 	if (!IS_VALID_PDEV_REG_OBJ(pdev_priv_obj)) {
1090 		reg_err("reg pdev private obj is NULL");
1091 		return;
1092 	}
1093 
1094 	pdev_priv_obj->dfs_enabled = psoc_priv_obj->dfs_enabled;
1095 	pdev_priv_obj->indoor_chan_enabled = psoc_priv_obj->indoor_chan_enabled;
1096 	pdev_priv_obj->force_ssc_disable_indoor_channel =
1097 		psoc_priv_obj->force_ssc_disable_indoor_channel;
1098 	pdev_priv_obj->band_capability = psoc_priv_obj->band_capability;
1099 	pdev_priv_obj->sta_sap_scc_on_indoor_channel =
1100 		psoc_priv_obj->sta_sap_scc_on_indoor_channel;
1101 	pdev_priv_obj->p2p_indoor_ch_support =
1102 		psoc_priv_obj->p2p_indoor_ch_support;
1103 
1104 	reg_compute_pdev_current_chan_list(pdev_priv_obj);
1105 
1106 	reg_send_scheduler_msg_sb(psoc, pdev);
1107 }
1108 
1109 #if defined(CONFIG_BAND_6GHZ) && defined(CONFIG_AFC_SUPPORT)
1110 static inline void
1111 reg_set_afc_vars(struct wlan_regulatory_psoc_priv_obj *psoc_priv_obj,
1112 		 struct reg_config_vars *config_vars)
1113 {
1114 	psoc_priv_obj->enable_6ghz_sp_pwrmode_supp =
1115 		config_vars->enable_6ghz_sp_pwrmode_supp;
1116 	psoc_priv_obj->afc_disable_timer_check =
1117 		config_vars->afc_disable_timer_check;
1118 	psoc_priv_obj->afc_disable_request_id_check =
1119 		config_vars->afc_disable_request_id_check;
1120 	psoc_priv_obj->is_afc_reg_noaction =
1121 		config_vars->is_afc_reg_noaction;
1122 }
1123 #else
1124 static inline void
1125 reg_set_afc_vars(struct wlan_regulatory_psoc_priv_obj *psoc_priv_obj,
1126 		 struct reg_config_vars *config_vars)
1127 {
1128 }
1129 #endif
1130 
1131 QDF_STATUS reg_set_config_vars(struct wlan_objmgr_psoc *psoc,
1132 			       struct reg_config_vars config_vars)
1133 {
1134 	struct wlan_regulatory_psoc_priv_obj *psoc_priv_obj;
1135 	QDF_STATUS status;
1136 
1137 	psoc_priv_obj = reg_get_psoc_obj(psoc);
1138 	if (!psoc_priv_obj) {
1139 		reg_err("psoc priv obj is NULL");
1140 		return QDF_STATUS_E_FAILURE;
1141 	}
1142 
1143 	psoc_priv_obj->enable_11d_supp_original =
1144 		config_vars.enable_11d_support;
1145 	psoc_priv_obj->scan_11d_interval = config_vars.scan_11d_interval;
1146 	psoc_priv_obj->user_ctry_priority = config_vars.userspace_ctry_priority;
1147 	psoc_priv_obj->dfs_enabled = config_vars.dfs_enabled;
1148 	psoc_priv_obj->indoor_chan_enabled = config_vars.indoor_chan_enabled;
1149 	psoc_priv_obj->force_ssc_disable_indoor_channel =
1150 		config_vars.force_ssc_disable_indoor_channel;
1151 	psoc_priv_obj->band_capability = config_vars.band_capability;
1152 	psoc_priv_obj->restart_beaconing = config_vars.restart_beaconing;
1153 	psoc_priv_obj->enable_srd_chan_in_master_mode =
1154 		config_vars.enable_srd_chan_in_master_mode;
1155 	psoc_priv_obj->enable_11d_in_world_mode =
1156 		config_vars.enable_11d_in_world_mode;
1157 	psoc_priv_obj->enable_5dot9_ghz_chan_in_master_mode =
1158 		config_vars.enable_5dot9_ghz_chan_in_master_mode;
1159 	psoc_priv_obj->retain_nol_across_regdmn_update =
1160 		config_vars.retain_nol_across_regdmn_update;
1161 	reg_get_coex_unsafe_chan_nb_user_prefer(psoc_priv_obj, config_vars);
1162 	reg_get_coex_unsafe_chan_reg_disable(psoc_priv_obj, config_vars);
1163 	psoc_priv_obj->sta_sap_scc_on_indoor_channel =
1164 		config_vars.sta_sap_scc_on_indoor_channel;
1165 	psoc_priv_obj->p2p_indoor_ch_support =
1166 		config_vars.p2p_indoor_ch_support;
1167 
1168 	reg_set_afc_vars(psoc_priv_obj, &config_vars);
1169 
1170 	status = wlan_objmgr_psoc_try_get_ref(psoc, WLAN_REGULATORY_SB_ID);
1171 	if (QDF_IS_STATUS_ERROR(status)) {
1172 		reg_err("error taking psoc ref cnt");
1173 		return status;
1174 	}
1175 	status = wlan_objmgr_iterate_obj_list(psoc, WLAN_PDEV_OP,
1176 					      reg_change_pdev_for_config,
1177 					      NULL, 1, WLAN_REGULATORY_SB_ID);
1178 	wlan_objmgr_psoc_release_ref(psoc, WLAN_REGULATORY_SB_ID);
1179 
1180 	return status;
1181 }
1182 
1183 void reg_program_mas_chan_list(struct wlan_objmgr_psoc *psoc,
1184 			       struct regulatory_channel *reg_channels,
1185 			       uint8_t *alpha2,
1186 			       enum dfs_reg dfs_region)
1187 {
1188 	struct wlan_regulatory_psoc_priv_obj *psoc_priv_obj;
1189 	QDF_STATUS status;
1190 	uint32_t count;
1191 	enum direction dir;
1192 	uint32_t phy_cnt;
1193 
1194 	psoc_priv_obj = reg_get_psoc_obj(psoc);
1195 	if (!psoc_priv_obj) {
1196 		reg_err("reg psoc private obj is NULL");
1197 		return;
1198 	}
1199 
1200 	qdf_mem_copy(psoc_priv_obj->cur_country, alpha2,
1201 		     REG_ALPHA2_LEN);
1202 	reg_debug("set cur_country %.2s", psoc_priv_obj->cur_country);
1203 	for (count = 0; count < NUM_CHANNELS; count++) {
1204 		reg_channels[count].chan_num = channel_map[count].chan_num;
1205 		reg_channels[count].center_freq =
1206 			channel_map[count].center_freq;
1207 		reg_channels[count].nol_chan = false;
1208 	}
1209 
1210 	for (phy_cnt = 0; phy_cnt < PSOC_MAX_PHY_REG_CAP; phy_cnt++) {
1211 		qdf_mem_copy(psoc_priv_obj->mas_chan_params[phy_cnt].
1212 			     mas_chan_list, reg_channels,
1213 			     NUM_CHANNELS * sizeof(struct regulatory_channel));
1214 
1215 		psoc_priv_obj->mas_chan_params[phy_cnt].dfs_region =
1216 			dfs_region;
1217 	}
1218 
1219 	dir = SOUTHBOUND;
1220 	status = wlan_objmgr_psoc_try_get_ref(psoc, WLAN_REGULATORY_SB_ID);
1221 	if (QDF_IS_STATUS_ERROR(status)) {
1222 		reg_err("error taking psoc ref cnt");
1223 		return;
1224 	}
1225 	status = wlan_objmgr_iterate_obj_list(
1226 			psoc, WLAN_PDEV_OP, reg_propagate_mas_chan_list_to_pdev,
1227 			&dir, 1, WLAN_REGULATORY_SB_ID);
1228 	wlan_objmgr_psoc_release_ref(psoc, WLAN_REGULATORY_SB_ID);
1229 }
1230 
1231 enum country_src reg_get_cc_and_src(struct wlan_objmgr_psoc *psoc,
1232 				    uint8_t *alpha2)
1233 {
1234 	struct wlan_regulatory_psoc_priv_obj *psoc_priv_obj;
1235 
1236 	psoc_priv_obj = reg_get_psoc_obj(psoc);
1237 	if (!psoc_priv_obj) {
1238 		reg_err("reg psoc private obj is NULL");
1239 		return SOURCE_UNKNOWN;
1240 	}
1241 
1242 	qdf_mem_copy(alpha2, psoc_priv_obj->cur_country, REG_ALPHA2_LEN + 1);
1243 
1244 	return psoc_priv_obj->cc_src;
1245 }
1246 
1247 void reg_reset_ctry_pending_hints(struct wlan_regulatory_psoc_priv_obj
1248 				  *soc_reg)
1249 {
1250 	uint8_t ctr;
1251 
1252 	if (!soc_reg->offload_enabled)
1253 		return;
1254 
1255 	for (ctr = 0; ctr < PSOC_MAX_PHY_REG_CAP; ctr++) {
1256 		soc_reg->new_user_ctry_pending[ctr] = false;
1257 		soc_reg->new_init_ctry_pending[ctr] = false;
1258 		soc_reg->new_11d_ctry_pending[ctr] = false;
1259 		soc_reg->world_country_pending[ctr] = false;
1260 	}
1261 }
1262 
1263 QDF_STATUS reg_set_curr_country(struct wlan_regulatory_psoc_priv_obj *soc_reg,
1264 				struct cur_regulatory_info *regulat_info,
1265 				struct wlan_lmac_if_reg_tx_ops *tx_ops)
1266 {
1267 	struct wlan_objmgr_psoc *psoc = regulat_info->psoc;
1268 	struct wlan_objmgr_pdev *pdev;
1269 	uint8_t pdev_id;
1270 	uint8_t phy_id;
1271 	uint8_t phy_num;
1272 	struct set_country country_code;
1273 	QDF_STATUS status;
1274 
1275 	/*
1276 	 * During SSR/WLAN restart ignore master channel list
1277 	 * for all events and in the last event handling if
1278 	 * current country and default country is different, send the last
1279 	 * configured (soc_reg->cur_country) country.
1280 	 */
1281 	if ((regulat_info->num_phy != regulat_info->phy_id + 1) ||
1282 	    (!qdf_mem_cmp(soc_reg->cur_country, regulat_info->alpha2,
1283 			  REG_ALPHA2_LEN)))
1284 		return QDF_STATUS_SUCCESS;
1285 
1286 	/*
1287 	 * Need firmware to send channel list event
1288 	 * for all phys. Therefore set pdev_id to 0xFF.
1289 	 */
1290 	pdev_id = WMI_HOST_PDEV_ID_SOC;
1291 	for (phy_num = 0; phy_num < regulat_info->num_phy; phy_num++) {
1292 		if (soc_reg->cc_src == SOURCE_USERSPACE)
1293 			soc_reg->new_user_ctry_pending[phy_num] = true;
1294 		else if (soc_reg->cc_src == SOURCE_11D)
1295 			soc_reg->new_11d_ctry_pending[phy_num] = true;
1296 		else
1297 			soc_reg->world_country_pending[phy_num] = true;
1298 	}
1299 
1300 	qdf_mem_zero(&country_code, sizeof(country_code));
1301 	qdf_mem_copy(country_code.country, soc_reg->cur_country,
1302 		     sizeof(soc_reg->cur_country));
1303 	country_code.pdev_id = pdev_id;
1304 
1305 	if (soc_reg->offload_enabled) {
1306 		if (!tx_ops || !tx_ops->set_country_code) {
1307 			reg_err("No regulatory tx_ops");
1308 			status = QDF_STATUS_E_FAULT;
1309 			goto error;
1310 		}
1311 		status = tx_ops->set_country_code(psoc, &country_code);
1312 		if (QDF_IS_STATUS_ERROR(status)) {
1313 			reg_err("Failed to send country code to fw");
1314 			goto error;
1315 		}
1316 	} else {
1317 		phy_id = regulat_info->phy_id;
1318 		if (tx_ops->get_pdev_id_from_phy_id)
1319 			tx_ops->get_pdev_id_from_phy_id(psoc, phy_id, &pdev_id);
1320 		else
1321 			pdev_id = phy_id;
1322 
1323 		pdev = wlan_objmgr_get_pdev_by_id(psoc, pdev_id,
1324 						  WLAN_REGULATORY_NB_ID);
1325 		status = reg_set_non_offload_country(pdev, &country_code);
1326 		wlan_objmgr_pdev_release_ref(pdev, WLAN_REGULATORY_NB_ID);
1327 		if (QDF_IS_STATUS_ERROR(status)) {
1328 			reg_err("Failed to set country code");
1329 			goto error;
1330 		}
1331 	}
1332 
1333 	reg_debug("Target CC: %.2s, Restore to Previous CC: %.2s",
1334 		  regulat_info->alpha2, soc_reg->cur_country);
1335 
1336 	return status;
1337 
1338 error:
1339 	reg_reset_ctry_pending_hints(soc_reg);
1340 
1341 	return status;
1342 }
1343 
1344 bool reg_ignore_default_country(struct wlan_regulatory_psoc_priv_obj *soc_reg,
1345 				struct cur_regulatory_info *regulat_info)
1346 {
1347 	uint8_t phy_num;
1348 
1349 	if (soc_reg->cc_src == SOURCE_UNKNOWN)
1350 		return false;
1351 
1352 	phy_num = regulat_info->phy_id;
1353 	if (soc_reg->new_user_ctry_pending[phy_num] ||
1354 	    soc_reg->new_init_ctry_pending[phy_num] ||
1355 	    soc_reg->new_11d_ctry_pending[phy_num] ||
1356 	    soc_reg->world_country_pending[phy_num])
1357 		return false;
1358 
1359 	return true;
1360 }
1361