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