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