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