xref: /wlan-dirver/qca-wifi-host-cmn/umac/regulatory/core/src/reg_utils.c (revision ccf6794c7efeda37a9772e5eb4d4dab2ab5af07a)
1 /*
2  * Copyright (c) 2014-2021 The Linux Foundation. All rights reserved.
3  * Copyright (c) 2021 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 
42 #define DEFAULT_WORLD_REGDMN 0x60
43 
44 #define IS_VALID_PSOC_REG_OBJ(psoc_priv_obj) (psoc_priv_obj)
45 #define IS_VALID_PDEV_REG_OBJ(pdev_priv_obj) (pdev_priv_obj)
46 
47 #ifdef CONFIG_CHAN_FREQ_API
48 bool reg_chan_has_dfs_attribute_for_freq(struct wlan_objmgr_pdev *pdev,
49 					 qdf_freq_t freq)
50 {
51 	enum channel_enum ch_idx;
52 	struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj;
53 
54 	ch_idx = reg_get_chan_enum_for_freq(freq);
55 
56 	if (ch_idx == INVALID_CHANNEL)
57 		return false;
58 
59 	pdev_priv_obj = reg_get_pdev_obj(pdev);
60 
61 	if (!IS_VALID_PDEV_REG_OBJ(pdev_priv_obj)) {
62 		reg_err("pdev reg obj is NULL");
63 		return false;
64 	}
65 
66 	if (pdev_priv_obj->cur_chan_list[ch_idx].chan_flags &
67 	    REGULATORY_CHAN_RADAR)
68 		return true;
69 
70 	return false;
71 }
72 #endif /* CONFIG_CHAN_FREQ_API */
73 
74 bool reg_is_world_ctry_code(uint16_t ctry_code)
75 {
76 	if ((ctry_code & 0xFFF0) == DEFAULT_WORLD_REGDMN)
77 		return true;
78 
79 	return false;
80 }
81 
82 QDF_STATUS reg_read_current_country(struct wlan_objmgr_psoc *psoc,
83 				    uint8_t *country_code)
84 {
85 	struct wlan_regulatory_psoc_priv_obj *psoc_reg;
86 
87 	if (!country_code) {
88 		reg_err("country_code is NULL");
89 		return QDF_STATUS_E_INVAL;
90 	}
91 
92 	psoc_reg = reg_get_psoc_obj(psoc);
93 	if (!IS_VALID_PSOC_REG_OBJ(psoc_reg)) {
94 		reg_err("psoc reg component is NULL");
95 		return QDF_STATUS_E_INVAL;
96 	}
97 
98 	qdf_mem_copy(country_code, psoc_reg->cur_country, REG_ALPHA2_LEN + 1);
99 
100 	return QDF_STATUS_SUCCESS;
101 }
102 
103 /**
104  * reg_set_default_country() - Read the default country for the regdomain
105  * @country: country code.
106  *
107  * Return: QDF_STATUS
108  */
109 QDF_STATUS reg_set_default_country(struct wlan_objmgr_psoc *psoc,
110 				   uint8_t *country)
111 {
112 	struct wlan_regulatory_psoc_priv_obj *psoc_reg;
113 
114 	if (!country) {
115 		reg_err("country is NULL");
116 		return QDF_STATUS_E_INVAL;
117 	}
118 
119 	psoc_reg = reg_get_psoc_obj(psoc);
120 	if (!IS_VALID_PSOC_REG_OBJ(psoc_reg)) {
121 		reg_err("psoc reg component is NULL");
122 		return QDF_STATUS_E_INVAL;
123 	}
124 
125 	reg_info("set default_country: %s", country);
126 
127 	qdf_mem_copy(psoc_reg->def_country, country, REG_ALPHA2_LEN + 1);
128 
129 	return QDF_STATUS_SUCCESS;
130 }
131 
132 bool reg_is_world_alpha2(uint8_t *alpha2)
133 {
134 	if ((alpha2[0] == '0') && (alpha2[1] == '0'))
135 		return true;
136 
137 	return false;
138 }
139 
140 bool reg_is_us_alpha2(uint8_t *alpha2)
141 {
142 	if ((alpha2[0] == 'U') && (alpha2[1] == 'S'))
143 		return true;
144 
145 	return false;
146 }
147 
148 bool reg_is_etsi_alpha2(uint8_t *alpha2)
149 {
150 	if ((alpha2[0] == 'G') && (alpha2[1] == 'B'))
151 		return true;
152 
153 	return false;
154 }
155 
156 static QDF_STATUS reg_set_non_offload_country(struct wlan_objmgr_pdev *pdev,
157 					      struct set_country *cc)
158 {
159 	struct wlan_objmgr_psoc *psoc;
160 	struct wlan_lmac_if_reg_tx_ops *tx_ops;
161 	struct wlan_regulatory_psoc_priv_obj *psoc_reg;
162 	struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj;
163 	struct cc_regdmn_s rd;
164 	uint8_t pdev_id;
165 	uint8_t phy_id;
166 
167 	if (!pdev) {
168 		reg_err("pdev is NULL");
169 		return QDF_STATUS_E_INVAL;
170 	}
171 
172 	pdev_id = wlan_objmgr_pdev_get_pdev_id(pdev);
173 	psoc = wlan_pdev_get_psoc(pdev);
174 	tx_ops = reg_get_psoc_tx_ops(psoc);
175 	if (tx_ops->get_phy_id_from_pdev_id)
176 		tx_ops->get_phy_id_from_pdev_id(psoc, pdev_id, &phy_id);
177 	else
178 		phy_id = pdev_id;
179 
180 	psoc_reg = reg_get_psoc_obj(psoc);
181 	if (!IS_VALID_PSOC_REG_OBJ(psoc_reg)) {
182 		reg_err("psoc reg component is NULL");
183 		return QDF_STATUS_E_INVAL;
184 	}
185 
186 	if (reg_is_world_alpha2(cc->country)) {
187 		pdev_priv_obj = reg_get_pdev_obj(pdev);
188 		if (!IS_VALID_PDEV_REG_OBJ(pdev_priv_obj)) {
189 			reg_err("reg component pdev priv is NULL");
190 			psoc_reg->world_country_pending[phy_id] = false;
191 			return QDF_STATUS_E_INVAL;
192 		}
193 		if (reg_is_world_ctry_code(pdev_priv_obj->def_region_domain))
194 			rd.cc.regdmn.reg_2g_5g_pair_id =
195 				pdev_priv_obj->def_region_domain;
196 		else
197 			rd.cc.regdmn.reg_2g_5g_pair_id = DEFAULT_WORLD_REGDMN;
198 		rd.flags = REGDMN_IS_SET;
199 	} else {
200 		qdf_mem_copy(rd.cc.alpha, cc->country, REG_ALPHA2_LEN + 1);
201 		rd.flags = ALPHA_IS_SET;
202 	}
203 
204 	reg_program_chan_list(pdev, &rd);
205 	return QDF_STATUS_SUCCESS;
206 }
207 
208 QDF_STATUS reg_set_country(struct wlan_objmgr_pdev *pdev,
209 			   uint8_t *country)
210 {
211 	struct wlan_regulatory_psoc_priv_obj *psoc_reg;
212 	struct wlan_lmac_if_reg_tx_ops *tx_ops;
213 	struct set_country cc;
214 	struct wlan_objmgr_psoc *psoc;
215 	uint8_t pdev_id;
216 	uint8_t phy_id;
217 
218 	if (!pdev) {
219 		reg_err("pdev is NULL");
220 		return QDF_STATUS_E_INVAL;
221 	}
222 
223 	if (!country) {
224 		reg_err("country code is NULL");
225 		return QDF_STATUS_E_INVAL;
226 	}
227 
228 	pdev_id = wlan_objmgr_pdev_get_pdev_id(pdev);
229 
230 	psoc = wlan_pdev_get_psoc(pdev);
231 
232 	tx_ops = reg_get_psoc_tx_ops(psoc);
233 	if (tx_ops->get_phy_id_from_pdev_id)
234 		tx_ops->get_phy_id_from_pdev_id(psoc, pdev_id, &phy_id);
235 	else
236 		phy_id = pdev_id;
237 
238 	psoc_reg = reg_get_psoc_obj(psoc);
239 	if (!IS_VALID_PSOC_REG_OBJ(psoc_reg)) {
240 		reg_err("psoc reg component is NULL");
241 		return QDF_STATUS_E_INVAL;
242 	}
243 
244 	if (!qdf_mem_cmp(psoc_reg->cur_country, country, REG_ALPHA2_LEN)) {
245 		if (psoc_reg->cc_src == SOURCE_USERSPACE ||
246 		    psoc_reg->cc_src == SOURCE_CORE) {
247 			reg_debug("country is not different");
248 			return QDF_STATUS_E_INVAL;
249 		}
250 	}
251 
252 	reg_debug("programming new country: %s to firmware", country);
253 
254 	qdf_mem_copy(cc.country, country, REG_ALPHA2_LEN + 1);
255 	cc.pdev_id = pdev_id;
256 
257 	if (!psoc_reg->offload_enabled && !reg_is_world_alpha2(country)) {
258 		QDF_STATUS status;
259 
260 		status = reg_is_country_code_valid(country);
261 		if (!QDF_IS_STATUS_SUCCESS(status)) {
262 			reg_err("Unable to set country code: %s\n", country);
263 			reg_err("Restoring to world domain");
264 			qdf_mem_copy(cc.country, REG_WORLD_ALPHA2,
265 				     REG_ALPHA2_LEN + 1);
266 		}
267 	}
268 
269 
270 	if (reg_is_world_alpha2(cc.country))
271 		psoc_reg->world_country_pending[phy_id] = true;
272 	else
273 		psoc_reg->new_user_ctry_pending[phy_id] = true;
274 
275 	if (psoc_reg->offload_enabled) {
276 		tx_ops = reg_get_psoc_tx_ops(psoc);
277 		if (tx_ops->set_country_code) {
278 			tx_ops->set_country_code(psoc, &cc);
279 		} else {
280 			reg_err("country set fw handler not present");
281 			psoc_reg->new_user_ctry_pending[phy_id] = false;
282 			return QDF_STATUS_E_FAULT;
283 		}
284 	} else {
285 		return reg_set_non_offload_country(pdev, &cc);
286 	}
287 
288 	return QDF_STATUS_SUCCESS;
289 }
290 
291 QDF_STATUS reg_reset_country(struct wlan_objmgr_psoc *psoc)
292 {
293 	struct wlan_regulatory_psoc_priv_obj *psoc_reg;
294 
295 	psoc_reg = reg_get_psoc_obj(psoc);
296 	if (!IS_VALID_PSOC_REG_OBJ(psoc_reg)) {
297 		reg_err("psoc reg component is NULL");
298 		return QDF_STATUS_E_INVAL;
299 	}
300 
301 	qdf_mem_copy(psoc_reg->cur_country,
302 		     psoc_reg->def_country,
303 		     REG_ALPHA2_LEN + 1);
304 	reg_debug("set cur_country %.2s", psoc_reg->cur_country);
305 
306 	return QDF_STATUS_SUCCESS;
307 }
308 
309 QDF_STATUS reg_get_domain_from_country_code(v_REGDOMAIN_t *reg_domain_ptr,
310 					    const uint8_t *country_alpha2,
311 					    enum country_src source)
312 {
313 	if (!reg_domain_ptr) {
314 		reg_err("Invalid reg domain pointer");
315 		return QDF_STATUS_E_FAULT;
316 	}
317 
318 	*reg_domain_ptr = 0;
319 
320 	if (!country_alpha2) {
321 		reg_err("Country code is NULL");
322 		return QDF_STATUS_E_FAULT;
323 	}
324 
325 	return QDF_STATUS_SUCCESS;
326 }
327 
328 #ifdef CONFIG_REG_CLIENT
329 QDF_STATUS
330 reg_get_6g_power_type_for_ctry(struct wlan_objmgr_psoc *psoc,
331 			       uint8_t *ap_ctry, uint8_t *sta_ctry,
332 			       enum reg_6g_ap_type *pwr_type_6g,
333 			       bool *ctry_code_match)
334 {
335 	*pwr_type_6g = REG_INDOOR_AP;
336 
337 	if (qdf_mem_cmp(ap_ctry, sta_ctry, REG_ALPHA2_LEN)) {
338 		reg_debug("Country IE:%c%c, STA country:%c%c", ap_ctry[0],
339 			  ap_ctry[1], sta_ctry[0], sta_ctry[1]);
340 		*ctry_code_match = false;
341 
342 		/**
343 		 * Do not return if Wi-Fi safe mode or RF test mode is
344 		 * enabled, rather STA should operate in LPI mode.
345 		 * wlan_cm_get_check_6ghz_security API returns true if
346 		 * neither Safe mode nor RF test mode are enabled.
347 		 */
348 		if (wlan_reg_is_us(sta_ctry) &&
349 		    wlan_cm_get_check_6ghz_security(psoc)) {
350 			reg_err("US VLP not in place yet, connection not allowed");
351 			return QDF_STATUS_E_NOSUPPORT;
352 		}
353 
354 		if (wlan_reg_is_etsi(sta_ctry)) {
355 			reg_debug("STA ctry:%c%c, doesn't match with AP ctry, switch to VLP",
356 				  sta_ctry[0], sta_ctry[1]);
357 			*pwr_type_6g = REG_VERY_LOW_POWER_AP;
358 		}
359 	} else {
360 		*ctry_code_match = true;
361 	}
362 
363 	return QDF_STATUS_SUCCESS;
364 }
365 #endif
366 
367 #ifdef CONFIG_CHAN_FREQ_API
368 bool reg_is_passive_or_disable_for_freq(struct wlan_objmgr_pdev *pdev,
369 					qdf_freq_t freq)
370 {
371 	enum channel_state chan_state;
372 
373 	chan_state = reg_get_channel_state_for_freq(pdev, freq);
374 
375 	return (chan_state == CHANNEL_STATE_DFS) ||
376 		(chan_state == CHANNEL_STATE_DISABLE);
377 }
378 #endif /* CONFIG_CHAN_FREQ_API */
379 
380 #ifdef WLAN_FEATURE_DSRC
381 #ifdef CONFIG_CHAN_FREQ_API
382 bool reg_is_dsrc_freq(qdf_freq_t freq)
383 {
384 	if (!REG_IS_5GHZ_FREQ(freq))
385 		return false;
386 
387 	if (!(freq >= REG_DSRC_START_FREQ && freq <= REG_DSRC_END_FREQ))
388 		return false;
389 
390 	return true;
391 }
392 #endif  /*CONFIG_CHAN_FREQ_API*/
393 #else
394 bool reg_is_etsi13_regdmn(struct wlan_objmgr_pdev *pdev)
395 {
396 	struct cur_regdmn_info cur_reg_dmn;
397 	QDF_STATUS status;
398 
399 	status = reg_get_curr_regdomain(pdev, &cur_reg_dmn);
400 	if (status != QDF_STATUS_SUCCESS) {
401 		reg_debug_rl("Failed to get reg domain");
402 		return false;
403 	}
404 
405 	return reg_etsi13_regdmn(cur_reg_dmn.dmn_id_5g);
406 }
407 
408 #ifdef CONFIG_CHAN_FREQ_API
409 bool reg_is_etsi13_srd_chan_for_freq(struct wlan_objmgr_pdev *pdev,
410 				     uint16_t freq)
411 {
412 	if (!REG_IS_5GHZ_FREQ(freq))
413 		return false;
414 
415 	if (!(freq >= REG_ETSI13_SRD_START_FREQ &&
416 	      freq <= REG_ETSI13_SRD_END_FREQ))
417 		return false;
418 
419 	return reg_is_etsi13_regdmn(pdev);
420 }
421 #endif /* CONFIG_CHAN_FREQ_API */
422 
423 bool reg_is_etsi13_srd_chan_allowed_master_mode(struct wlan_objmgr_pdev *pdev)
424 {
425 	struct wlan_objmgr_psoc *psoc;
426 	struct wlan_regulatory_psoc_priv_obj *psoc_priv_obj;
427 
428 	if (!pdev) {
429 		reg_alert("pdev is NULL");
430 		return true;
431 	}
432 	psoc = wlan_pdev_get_psoc(pdev);
433 
434 	psoc_priv_obj = reg_get_psoc_obj(psoc);
435 	if (!IS_VALID_PSOC_REG_OBJ(psoc_priv_obj)) {
436 		reg_alert("psoc reg component is NULL");
437 		return true;
438 	}
439 
440 	return psoc_priv_obj->enable_srd_chan_in_master_mode &&
441 	       reg_is_etsi13_regdmn(pdev);
442 }
443 #endif
444 
445 QDF_STATUS reg_set_band(struct wlan_objmgr_pdev *pdev, uint32_t band_bitmap)
446 {
447 	struct wlan_regulatory_psoc_priv_obj *psoc_priv_obj;
448 	struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj;
449 	struct wlan_objmgr_psoc *psoc;
450 	QDF_STATUS status;
451 
452 	pdev_priv_obj = reg_get_pdev_obj(pdev);
453 
454 	if (!IS_VALID_PDEV_REG_OBJ(pdev_priv_obj)) {
455 		reg_err("pdev reg component is NULL");
456 		return QDF_STATUS_E_INVAL;
457 	}
458 
459 	if (pdev_priv_obj->band_capability == band_bitmap) {
460 		reg_info("same band %d", band_bitmap);
461 		return QDF_STATUS_SUCCESS;
462 	}
463 
464 	psoc = wlan_pdev_get_psoc(pdev);
465 	if (!psoc) {
466 		reg_err("psoc is NULL");
467 		return QDF_STATUS_E_INVAL;
468 	}
469 
470 	psoc_priv_obj = reg_get_psoc_obj(psoc);
471 	if (!IS_VALID_PSOC_REG_OBJ(psoc_priv_obj)) {
472 		reg_err("psoc reg component is NULL");
473 		return QDF_STATUS_E_INVAL;
474 	}
475 
476 	reg_info("set band bitmap: %d", band_bitmap);
477 	pdev_priv_obj->band_capability = band_bitmap;
478 
479 	reg_compute_pdev_current_chan_list(pdev_priv_obj);
480 
481 	status = reg_send_scheduler_msg_sb(psoc, pdev);
482 
483 	return status;
484 }
485 
486 QDF_STATUS reg_get_band(struct wlan_objmgr_pdev *pdev,
487 			uint32_t *band_bitmap)
488 {
489 	struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj;
490 
491 	pdev_priv_obj = reg_get_pdev_obj(pdev);
492 
493 	if (!IS_VALID_PDEV_REG_OBJ(pdev_priv_obj)) {
494 		reg_err("pdev reg component is NULL");
495 		return QDF_STATUS_E_INVAL;
496 	}
497 
498 	reg_debug("get band bitmap: %d", pdev_priv_obj->band_capability);
499 	*band_bitmap = pdev_priv_obj->band_capability;
500 
501 	return QDF_STATUS_SUCCESS;
502 }
503 
504 #ifdef DISABLE_CHANNEL_LIST
505 QDF_STATUS reg_restore_cached_channels(struct wlan_objmgr_pdev *pdev)
506 {
507 	struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj;
508 	struct wlan_objmgr_psoc *psoc;
509 	QDF_STATUS status;
510 
511 	pdev_priv_obj = reg_get_pdev_obj(pdev);
512 	if (!IS_VALID_PDEV_REG_OBJ(pdev_priv_obj)) {
513 		reg_err("pdev reg component is NULL");
514 		return QDF_STATUS_E_INVAL;
515 	}
516 
517 	psoc = wlan_pdev_get_psoc(pdev);
518 	if (!psoc) {
519 		reg_err("psoc is NULL");
520 		return QDF_STATUS_E_INVAL;
521 	}
522 
523 	pdev_priv_obj->disable_cached_channels = false;
524 	reg_compute_pdev_current_chan_list(pdev_priv_obj);
525 	status = reg_send_scheduler_msg_sb(psoc, pdev);
526 	return status;
527 }
528 
529 QDF_STATUS reg_disable_cached_channels(struct wlan_objmgr_pdev *pdev)
530 {
531 	struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj;
532 	struct wlan_objmgr_psoc *psoc;
533 	QDF_STATUS status;
534 
535 	pdev_priv_obj = reg_get_pdev_obj(pdev);
536 	if (!IS_VALID_PDEV_REG_OBJ(pdev_priv_obj)) {
537 		reg_err("pdev reg component is NULL");
538 		return QDF_STATUS_E_INVAL;
539 	}
540 
541 	psoc = wlan_pdev_get_psoc(pdev);
542 	if (!psoc) {
543 		reg_err("psoc is NULL");
544 		return QDF_STATUS_E_INVAL;
545 	}
546 
547 	pdev_priv_obj->disable_cached_channels = true;
548 	reg_compute_pdev_current_chan_list(pdev_priv_obj);
549 	status = reg_send_scheduler_msg_sb(psoc, pdev);
550 	return status;
551 }
552 
553 #ifdef CONFIG_CHAN_FREQ_API
554 QDF_STATUS reg_cache_channel_freq_state(struct wlan_objmgr_pdev *pdev,
555 					uint32_t *channel_list,
556 					uint32_t num_channels)
557 {
558 	struct wlan_regulatory_psoc_priv_obj *psoc_priv_obj;
559 	struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj;
560 	struct wlan_objmgr_psoc *psoc;
561 	uint16_t i, j;
562 
563 	pdev_priv_obj = reg_get_pdev_obj(pdev);
564 
565 	if (!IS_VALID_PDEV_REG_OBJ(pdev_priv_obj)) {
566 		reg_err("pdev reg component is NULL");
567 		return QDF_STATUS_E_INVAL;
568 	}
569 
570 	psoc = wlan_pdev_get_psoc(pdev);
571 	if (!psoc) {
572 		reg_err("psoc is NULL");
573 		return QDF_STATUS_E_INVAL;
574 	}
575 
576 	psoc_priv_obj = reg_get_psoc_obj(psoc);
577 	if (!IS_VALID_PSOC_REG_OBJ(psoc_priv_obj)) {
578 		reg_err("psoc reg component is NULL");
579 		return QDF_STATUS_E_INVAL;
580 	}
581 	if (pdev_priv_obj->num_cache_channels > 0) {
582 		pdev_priv_obj->num_cache_channels = 0;
583 		qdf_mem_zero(&pdev_priv_obj->cache_disable_chan_list,
584 			     sizeof(pdev_priv_obj->cache_disable_chan_list));
585 	}
586 
587 	for (i = 0; i < num_channels; i++) {
588 		for (j = 0; j < NUM_CHANNELS; j++) {
589 			if (channel_list[i] == pdev_priv_obj->
590 						cur_chan_list[j].center_freq) {
591 				pdev_priv_obj->
592 					cache_disable_chan_list[i].center_freq =
593 							channel_list[i];
594 				pdev_priv_obj->
595 					cache_disable_chan_list[i].state =
596 					pdev_priv_obj->cur_chan_list[j].state;
597 				pdev_priv_obj->
598 					cache_disable_chan_list[i].chan_flags =
599 					pdev_priv_obj->
600 						cur_chan_list[j].chan_flags;
601 			}
602 		}
603 	}
604 	pdev_priv_obj->num_cache_channels = num_channels;
605 
606 	return QDF_STATUS_SUCCESS;
607 }
608 #endif /* CONFIG_CHAN_FREQ_API */
609 #endif
610 
611 #ifdef CONFIG_REG_CLIENT
612 
613 QDF_STATUS reg_set_fcc_constraint(struct wlan_objmgr_pdev *pdev,
614 				  bool fcc_constraint)
615 {
616 	struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj;
617 	struct wlan_regulatory_psoc_priv_obj *psoc_priv_obj;
618 	struct wlan_objmgr_psoc *psoc;
619 	QDF_STATUS status;
620 
621 	pdev_priv_obj = reg_get_pdev_obj(pdev);
622 	if (!IS_VALID_PDEV_REG_OBJ(pdev_priv_obj)) {
623 		reg_err("pdev reg component is NULL");
624 		return QDF_STATUS_E_INVAL;
625 	}
626 
627 	if (pdev_priv_obj->set_fcc_channel == fcc_constraint) {
628 		reg_info("same fcc_constraint %d", fcc_constraint);
629 		return QDF_STATUS_SUCCESS;
630 	}
631 
632 	reg_info("set fcc_constraint: %d", fcc_constraint);
633 	pdev_priv_obj->set_fcc_channel = fcc_constraint;
634 
635 	psoc = wlan_pdev_get_psoc(pdev);
636 	if (!psoc) {
637 		reg_err("psoc is NULL");
638 		return QDF_STATUS_E_INVAL;
639 	}
640 
641 	psoc_priv_obj = reg_get_psoc_obj(psoc);
642 	if (!IS_VALID_PSOC_REG_OBJ(psoc_priv_obj)) {
643 		reg_err("psoc reg component is NULL");
644 		return QDF_STATUS_E_INVAL;
645 	}
646 
647 	reg_compute_pdev_current_chan_list(pdev_priv_obj);
648 
649 	status = reg_send_scheduler_msg_sb(psoc, pdev);
650 
651 	return status;
652 }
653 
654 bool reg_get_fcc_constraint(struct wlan_objmgr_pdev *pdev, uint32_t freq)
655 {
656 	struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj;
657 
658 	pdev_priv_obj = reg_get_pdev_obj(pdev);
659 	if (!IS_VALID_PDEV_REG_OBJ(pdev_priv_obj)) {
660 		reg_err("pdev reg component is NULL");
661 		return false;
662 	}
663 
664 	if (freq != CHAN_12_CENT_FREQ && freq != CHAN_13_CENT_FREQ)
665 		return false;
666 
667 	if (!pdev_priv_obj->set_fcc_channel)
668 		return false;
669 
670 	return true;
671 }
672 
673 #ifdef CONFIG_BAND_6GHZ
674 /**
675  * reg_is_afc_available() - check if the automated frequency control system is
676  * available, function will need to be updated once AFC is implemented
677  * @pdev: Pointer to pdev structure
678  *
679  * Return: false since the AFC system is not yet available
680  */
681 static bool reg_is_afc_available(struct wlan_objmgr_pdev *pdev)
682 {
683 	return false;
684 }
685 
686 enum reg_6g_ap_type reg_decide_6g_ap_pwr_type(struct wlan_objmgr_pdev *pdev)
687 {
688 	struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj;
689 	enum reg_6g_ap_type ap_pwr_type = REG_INDOOR_AP;
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 REG_VERY_LOW_POWER_AP;
695 	}
696 
697 	if (reg_is_afc_available(pdev)) {
698 		ap_pwr_type = REG_STANDARD_POWER_AP;
699 	} else if (pdev_priv_obj->indoor_chan_enabled) {
700 		if (pdev_priv_obj->reg_rules.num_of_6g_ap_reg_rules[REG_INDOOR_AP])
701 			ap_pwr_type = REG_INDOOR_AP;
702 		else
703 			ap_pwr_type = REG_VERY_LOW_POWER_AP;
704 	} else if (pdev_priv_obj->reg_rules.num_of_6g_ap_reg_rules[REG_VERY_LOW_POWER_AP]) {
705 		ap_pwr_type = REG_VERY_LOW_POWER_AP;
706 	}
707 	reg_debug("indoor_chan_enabled %d ap_pwr_type %d",
708 		  pdev_priv_obj->indoor_chan_enabled, ap_pwr_type);
709 
710 	reg_set_ap_pwr_and_update_chan_list(pdev, ap_pwr_type);
711 
712 	return ap_pwr_type;
713 }
714 #endif /* CONFIG_BAND_6GHZ */
715 
716 #endif /* CONFIG_REG_CLIENT */
717 
718 /**
719  * reg_change_pdev_for_config() - Update user configuration in pdev private obj.
720  * @psoc: Pointer to global psoc structure.
721  * @object: Pointer to global pdev structure.
722  * @arg: Pointer to argument list.
723  */
724 static void reg_change_pdev_for_config(struct wlan_objmgr_psoc *psoc,
725 				       void *object, void *arg)
726 {
727 	struct wlan_objmgr_pdev *pdev = (struct wlan_objmgr_pdev *)object;
728 	struct wlan_regulatory_psoc_priv_obj *psoc_priv_obj;
729 	struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj;
730 
731 	psoc_priv_obj = reg_get_psoc_obj(psoc);
732 	if (!psoc_priv_obj) {
733 		reg_err("psoc priv obj is NULL");
734 		return;
735 	}
736 
737 	pdev_priv_obj = reg_get_pdev_obj(pdev);
738 
739 	if (!IS_VALID_PDEV_REG_OBJ(pdev_priv_obj)) {
740 		reg_err("reg pdev private obj is NULL");
741 		return;
742 	}
743 
744 	pdev_priv_obj->dfs_enabled = psoc_priv_obj->dfs_enabled;
745 	pdev_priv_obj->indoor_chan_enabled = psoc_priv_obj->indoor_chan_enabled;
746 	pdev_priv_obj->force_ssc_disable_indoor_channel =
747 		psoc_priv_obj->force_ssc_disable_indoor_channel;
748 	pdev_priv_obj->band_capability = psoc_priv_obj->band_capability;
749 
750 	reg_compute_pdev_current_chan_list(pdev_priv_obj);
751 
752 	reg_send_scheduler_msg_sb(psoc, pdev);
753 }
754 
755 QDF_STATUS reg_set_config_vars(struct wlan_objmgr_psoc *psoc,
756 			       struct reg_config_vars config_vars)
757 {
758 	struct wlan_regulatory_psoc_priv_obj *psoc_priv_obj;
759 	QDF_STATUS status;
760 
761 	psoc_priv_obj = reg_get_psoc_obj(psoc);
762 	if (!psoc_priv_obj) {
763 		reg_err("psoc priv obj is NULL");
764 		return QDF_STATUS_E_FAILURE;
765 	}
766 
767 	psoc_priv_obj->enable_11d_supp_original =
768 		config_vars.enable_11d_support;
769 	psoc_priv_obj->scan_11d_interval = config_vars.scan_11d_interval;
770 	psoc_priv_obj->user_ctry_priority = config_vars.userspace_ctry_priority;
771 	psoc_priv_obj->dfs_enabled = config_vars.dfs_enabled;
772 	psoc_priv_obj->indoor_chan_enabled = config_vars.indoor_chan_enabled;
773 	psoc_priv_obj->force_ssc_disable_indoor_channel =
774 		config_vars.force_ssc_disable_indoor_channel;
775 	psoc_priv_obj->band_capability = config_vars.band_capability;
776 	psoc_priv_obj->restart_beaconing = config_vars.restart_beaconing;
777 	psoc_priv_obj->enable_srd_chan_in_master_mode =
778 		config_vars.enable_srd_chan_in_master_mode;
779 	psoc_priv_obj->enable_11d_in_world_mode =
780 		config_vars.enable_11d_in_world_mode;
781 	psoc_priv_obj->enable_5dot9_ghz_chan_in_master_mode =
782 		config_vars.enable_5dot9_ghz_chan_in_master_mode;
783 	psoc_priv_obj->retain_nol_across_regdmn_update =
784 		config_vars.retain_nol_across_regdmn_update;
785 
786 	status = wlan_objmgr_psoc_try_get_ref(psoc, WLAN_REGULATORY_SB_ID);
787 	if (QDF_IS_STATUS_ERROR(status)) {
788 		reg_err("error taking psoc ref cnt");
789 		return status;
790 	}
791 	status = wlan_objmgr_iterate_obj_list(psoc, WLAN_PDEV_OP,
792 					      reg_change_pdev_for_config,
793 					      NULL, 1, WLAN_REGULATORY_SB_ID);
794 	wlan_objmgr_psoc_release_ref(psoc, WLAN_REGULATORY_SB_ID);
795 
796 	return status;
797 }
798 
799 void reg_program_mas_chan_list(struct wlan_objmgr_psoc *psoc,
800 			       struct regulatory_channel *reg_channels,
801 			       uint8_t *alpha2,
802 			       enum dfs_reg dfs_region)
803 {
804 	struct wlan_regulatory_psoc_priv_obj *psoc_priv_obj;
805 	QDF_STATUS status;
806 	uint32_t count;
807 	enum direction dir;
808 	uint32_t phy_cnt;
809 
810 	psoc_priv_obj = reg_get_psoc_obj(psoc);
811 	if (!psoc_priv_obj) {
812 		reg_err("reg psoc private obj is NULL");
813 		return;
814 	}
815 
816 	qdf_mem_copy(psoc_priv_obj->cur_country, alpha2,
817 		     REG_ALPHA2_LEN);
818 	reg_debug("set cur_country %.2s", psoc_priv_obj->cur_country);
819 	for (count = 0; count < NUM_CHANNELS; count++) {
820 		reg_channels[count].chan_num = channel_map[count].chan_num;
821 		reg_channels[count].center_freq =
822 			channel_map[count].center_freq;
823 		reg_channels[count].nol_chan = false;
824 	}
825 
826 	for (phy_cnt = 0; phy_cnt < PSOC_MAX_PHY_REG_CAP; phy_cnt++) {
827 		qdf_mem_copy(psoc_priv_obj->mas_chan_params[phy_cnt].
828 			     mas_chan_list, reg_channels,
829 			     NUM_CHANNELS * sizeof(struct regulatory_channel));
830 
831 		psoc_priv_obj->mas_chan_params[phy_cnt].dfs_region =
832 			dfs_region;
833 	}
834 
835 	dir = SOUTHBOUND;
836 	status = wlan_objmgr_psoc_try_get_ref(psoc, WLAN_REGULATORY_SB_ID);
837 	if (QDF_IS_STATUS_ERROR(status)) {
838 		reg_err("error taking psoc ref cnt");
839 		return;
840 	}
841 	status = wlan_objmgr_iterate_obj_list(
842 			psoc, WLAN_PDEV_OP, reg_propagate_mas_chan_list_to_pdev,
843 			&dir, 1, WLAN_REGULATORY_SB_ID);
844 	wlan_objmgr_psoc_release_ref(psoc, WLAN_REGULATORY_SB_ID);
845 }
846 
847 enum country_src reg_get_cc_and_src(struct wlan_objmgr_psoc *psoc,
848 				    uint8_t *alpha2)
849 {
850 	struct wlan_regulatory_psoc_priv_obj *psoc_priv_obj;
851 
852 	psoc_priv_obj = reg_get_psoc_obj(psoc);
853 	if (!psoc_priv_obj) {
854 		reg_err("reg psoc private obj is NULL");
855 		return SOURCE_UNKNOWN;
856 	}
857 
858 	qdf_mem_copy(alpha2, psoc_priv_obj->cur_country, REG_ALPHA2_LEN + 1);
859 
860 	return psoc_priv_obj->cc_src;
861 }
862 
863 QDF_STATUS reg_get_regd_rules(struct wlan_objmgr_pdev *pdev,
864 			      struct reg_rule_info *reg_rules)
865 {
866 	struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj;
867 
868 	if (!pdev) {
869 		reg_err("pdev is NULL");
870 		return QDF_STATUS_E_FAILURE;
871 	}
872 
873 	pdev_priv_obj = reg_get_pdev_obj(pdev);
874 	if (!pdev_priv_obj) {
875 		reg_err("pdev priv obj is NULL");
876 		return QDF_STATUS_E_FAILURE;
877 	}
878 
879 	qdf_spin_lock_bh(&pdev_priv_obj->reg_rules_lock);
880 	qdf_mem_copy(reg_rules, &pdev_priv_obj->reg_rules,
881 		     sizeof(struct reg_rule_info));
882 	qdf_spin_unlock_bh(&pdev_priv_obj->reg_rules_lock);
883 
884 	return QDF_STATUS_SUCCESS;
885 }
886 
887 void reg_reset_ctry_pending_hints(struct wlan_regulatory_psoc_priv_obj
888 				  *soc_reg)
889 {
890 	uint8_t ctr;
891 
892 	if (!soc_reg->offload_enabled)
893 		return;
894 
895 	for (ctr = 0; ctr < PSOC_MAX_PHY_REG_CAP; ctr++) {
896 		soc_reg->new_user_ctry_pending[ctr] = false;
897 		soc_reg->new_init_ctry_pending[ctr] = false;
898 		soc_reg->new_11d_ctry_pending[ctr] = false;
899 		soc_reg->world_country_pending[ctr] = false;
900 	}
901 }
902 
903 QDF_STATUS reg_set_curr_country(struct wlan_regulatory_psoc_priv_obj *soc_reg,
904 				struct cur_regulatory_info *regulat_info,
905 				struct wlan_lmac_if_reg_tx_ops *tx_ops)
906 {
907 	struct wlan_objmgr_psoc *psoc = regulat_info->psoc;
908 	struct wlan_objmgr_pdev *pdev;
909 	uint8_t pdev_id;
910 	uint8_t phy_id;
911 	uint8_t phy_num;
912 	struct set_country country_code;
913 	QDF_STATUS status;
914 
915 	/*
916 	 * During SSR/WLAN restart ignore master channel list
917 	 * for all events and in the last event handling if
918 	 * current country and default country is different, send the last
919 	 * configured (soc_reg->cur_country) country.
920 	 */
921 	if ((regulat_info->num_phy != regulat_info->phy_id + 1) ||
922 	    (!qdf_mem_cmp(soc_reg->cur_country, regulat_info->alpha2,
923 			  REG_ALPHA2_LEN)))
924 		return QDF_STATUS_SUCCESS;
925 
926 	/*
927 	 * Need firmware to send channel list event
928 	 * for all phys. Therefore set pdev_id to 0xFF
929 	 */
930 	pdev_id = 0xFF;
931 	for (phy_num = 0; phy_num < regulat_info->num_phy; phy_num++) {
932 		if (soc_reg->cc_src == SOURCE_USERSPACE)
933 			soc_reg->new_user_ctry_pending[phy_num] = true;
934 		else if (soc_reg->cc_src == SOURCE_11D)
935 			soc_reg->new_11d_ctry_pending[phy_num] = true;
936 		else
937 			soc_reg->world_country_pending[phy_num] = true;
938 	}
939 
940 	qdf_mem_zero(&country_code, sizeof(country_code));
941 	qdf_mem_copy(country_code.country, soc_reg->cur_country,
942 		     sizeof(soc_reg->cur_country));
943 	country_code.pdev_id = pdev_id;
944 
945 	if (soc_reg->offload_enabled) {
946 		if (!tx_ops || !tx_ops->set_country_code) {
947 			reg_err("No regulatory tx_ops");
948 			status = QDF_STATUS_E_FAULT;
949 			goto error;
950 		}
951 		status = tx_ops->set_country_code(psoc, &country_code);
952 		if (QDF_IS_STATUS_ERROR(status)) {
953 			reg_err("Failed to send country code to fw");
954 			goto error;
955 		}
956 	} else {
957 		phy_id = regulat_info->phy_id;
958 		if (tx_ops->get_pdev_id_from_phy_id)
959 			tx_ops->get_pdev_id_from_phy_id(psoc, phy_id, &pdev_id);
960 		else
961 			pdev_id = phy_id;
962 
963 		pdev = wlan_objmgr_get_pdev_by_id(psoc, pdev_id,
964 						  WLAN_REGULATORY_NB_ID);
965 		status = reg_set_non_offload_country(pdev, &country_code);
966 		wlan_objmgr_pdev_release_ref(pdev, WLAN_REGULATORY_NB_ID);
967 		if (QDF_IS_STATUS_ERROR(status)) {
968 			reg_err("Failed to set country code");
969 			goto error;
970 		}
971 	}
972 
973 	reg_debug("Target CC: %.2s, Restore to Previous CC: %.2s",
974 		  regulat_info->alpha2, soc_reg->cur_country);
975 
976 	return status;
977 
978 error:
979 	reg_reset_ctry_pending_hints(soc_reg);
980 
981 	return status;
982 }
983 
984 bool reg_ignore_default_country(struct wlan_regulatory_psoc_priv_obj *soc_reg,
985 				struct cur_regulatory_info *regulat_info)
986 {
987 	uint8_t phy_num;
988 
989 	if (soc_reg->cc_src == SOURCE_UNKNOWN)
990 		return false;
991 
992 	phy_num = regulat_info->phy_id;
993 	if (soc_reg->new_user_ctry_pending[phy_num] ||
994 	    soc_reg->new_init_ctry_pending[phy_num] ||
995 	    soc_reg->new_11d_ctry_pending[phy_num] ||
996 	    soc_reg->world_country_pending[phy_num])
997 		return false;
998 
999 	return true;
1000 }
1001