xref: /wlan-dirver/qca-wifi-host-cmn/umac/regulatory/dispatcher/src/wlan_reg_services_api.c (revision dae10a5fbc53d54c53c4ba24fa018ad8b1e7c008)
1 /*
2  * Copyright (c) 2017-2018 The Linux Foundation. All rights reserved.
3  *
4  *
5  * Permission to use, copy, modify, and/or distribute this software for
6  * any purpose with or without fee is hereby granted, provided that the
7  * above copyright notice and this permission notice appear in all
8  * copies.
9  *
10  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
11  * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
12  * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
13  * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
14  * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
15  * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
16  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
17  * PERFORMANCE OF THIS SOFTWARE.
18  */
19 
20  /**
21  * @file wlan_reg_services_api.c
22  * @brief contains regulatory service functions
23  */
24 
25 
26 #include <qdf_status.h>
27 #include <qdf_types.h>
28 #include <wlan_reg_services_api.h>
29 #include "../../core/src/reg_services.h"
30 #include "../../core/src/reg_priv.h"
31 #include "../../core/src/reg_db_parser.h"
32 
33 /**
34  * wlan_reg_get_channel_list_with_power() - Provide the channel list with power
35  * @ch_list: pointer to the channel list.
36  *
37  * Return: QDF_STATUS
38  */
39 QDF_STATUS wlan_reg_get_channel_list_with_power(struct wlan_objmgr_pdev *pdev,
40 						struct channel_power *ch_list,
41 						uint8_t *num_chan)
42 {
43 	/*
44 	 * Update the channel list with channel information with power.
45 	 */
46 	return reg_get_channel_list_with_power(pdev, ch_list, num_chan);
47 }
48 
49 /**
50  * wlan_reg_read_default_country() - Read the default country for the regdomain
51  * @country: pointer to the country code.
52  *
53  * Return: None
54  */
55 QDF_STATUS wlan_reg_read_default_country(struct wlan_objmgr_psoc *psoc,
56 					 uint8_t *country)
57 {
58 	/*
59 	 * Get the default country information
60 	 */
61 	return reg_read_default_country(psoc, country);
62 }
63 
64 QDF_STATUS wlan_reg_read_current_country(struct wlan_objmgr_psoc *psoc,
65 					 uint8_t *country)
66 {
67 	/*
68 	 * Get the current country information
69 	 */
70 	return reg_read_current_country(psoc, country);
71 }
72 
73 /**
74  * wlan_reg_get_channel_state() - Get channel state from regulatory
75  * @ch: channel number.
76  *
77  * Return: channel state
78  */
79 enum channel_state wlan_reg_get_channel_state(struct wlan_objmgr_pdev *pdev,
80 					      uint32_t ch)
81 {
82 	/*
83 	 * Get channel state from regulatory
84 	 */
85 	return reg_get_channel_state(pdev, ch);
86 }
87 
88 bool
89 wlan_reg_chan_has_dfs_attribute(struct wlan_objmgr_pdev *pdev, uint32_t ch)
90 {
91 	return reg_chan_has_dfs_attribute(pdev, ch);
92 }
93 
94 /**
95  * wlan_reg_get_5g_bonded_channel_state() - Get 5G bonded channel state
96  * @ch: channel number.
97  * @bw: channel band width
98  *
99  * Return: channel state
100  */
101 enum channel_state wlan_reg_get_5g_bonded_channel_state(
102 	struct wlan_objmgr_pdev *pdev, uint8_t ch,
103 	enum phy_ch_width bw)
104 {
105 	/*
106 	 * Get channel state from regulatory
107 	 */
108 	return reg_get_5g_bonded_channel_state(pdev, ch, bw);
109 }
110 
111 /**
112  * wlan_reg_get_2g_bonded_channel_state() - Get 2G bonded channel state
113  * @ch: channel number.
114  * @bw: channel band width
115  *
116  * Return: channel state
117  */
118 enum channel_state wlan_reg_get_2g_bonded_channel_state(
119 		struct wlan_objmgr_pdev *pdev, uint8_t ch,
120 		uint8_t sec_ch, enum phy_ch_width bw)
121 {
122 	/*
123 	 * Get channel state from regulatory
124 	 */
125 	return reg_get_2g_bonded_channel_state(pdev, ch, sec_ch, bw);
126 }
127 
128 /**
129  * wlan_reg_set_channel_params() - Sets channel parameteres for given bandwidth
130  * @ch: channel number.
131  * @ch_params: pointer to the channel parameters.
132  *
133  * Return: None
134  */
135 void wlan_reg_set_channel_params(struct wlan_objmgr_pdev *pdev, uint8_t ch,
136 				 uint8_t sec_ch_2g,
137 				 struct ch_params *ch_params)
138 {
139 	/*
140 	 * Set channel parameters like center frequency for a bonded channel
141 	 * state. Also return the maximum bandwidth supported by the channel.
142 	 */
143 	reg_set_channel_params(pdev, ch, sec_ch_2g, ch_params);
144 }
145 
146 /**
147  * wlan_reg_get_dfs_region () - Get the current dfs region
148  * @dfs_reg: pointer to dfs region
149  *
150  * Return: Status
151  */
152 QDF_STATUS wlan_reg_get_dfs_region(struct wlan_objmgr_pdev *pdev,
153 			     enum dfs_reg *dfs_reg)
154 {
155 	/*
156 	 * Get the current dfs region
157 	 */
158 	reg_get_current_dfs_region(pdev, dfs_reg);
159 
160 	return QDF_STATUS_SUCCESS;
161 }
162 
163 uint32_t wlan_reg_get_channel_reg_power(struct wlan_objmgr_pdev *pdev,
164 					uint32_t chan_num)
165 {
166 	return reg_get_channel_reg_power(pdev, chan_num);
167 }
168 
169 /**
170  * wlan_reg_get_channel_freq() - get regulatory power for channel
171  * @chan_num: channel number
172  *
173  * Return: int
174  */
175 uint32_t wlan_reg_get_channel_freq(struct wlan_objmgr_pdev *pdev,
176 				   uint32_t chan_num)
177 {
178 	return reg_get_channel_freq(pdev, chan_num);
179 }
180 
181 QDF_STATUS wlan_reg_get_current_chan_list(struct wlan_objmgr_pdev *pdev,
182 		struct regulatory_channel *chan_list)
183 {
184 	return reg_get_current_chan_list(pdev, chan_list);
185 }
186 
187 /**
188  * wlan_reg_get_bw_value() - give bandwidth value
189  * bw: bandwidth enum
190  *
191  * Return: uint16_t
192  */
193 uint16_t wlan_reg_get_bw_value(enum phy_ch_width bw)
194 {
195 	return reg_get_bw_value(bw);
196 }
197 
198 /**
199  * wlan_reg_get_bonded_channel_state() - Get 2G bonded channel state
200  * @ch: channel number.
201  * @bw: channel band width
202  *
203  * Return: channel state
204  */
205 enum channel_state wlan_reg_get_bonded_channel_state(
206 	struct wlan_objmgr_pdev *pdev, uint8_t ch,
207 	enum phy_ch_width bw, uint8_t sec_ch)
208 {
209 	if (WLAN_REG_IS_24GHZ_CH(ch))
210 		return reg_get_2g_bonded_channel_state(pdev, ch,
211 						       sec_ch, bw);
212 	else
213 		return reg_get_5g_bonded_channel_state(pdev, ch,
214 						       bw);
215 }
216 
217 /**
218  * wlan_reg_set_dfs_region () - Get the current dfs region
219  * @dfs_reg: pointer to dfs region
220  *
221  * Return: None
222  */
223 void wlan_reg_set_dfs_region(struct wlan_objmgr_pdev *pdev,
224 			     enum dfs_reg dfs_reg)
225 {
226 	reg_set_dfs_region(pdev, dfs_reg);
227 }
228 
229 QDF_STATUS wlan_reg_get_domain_from_country_code(v_REGDOMAIN_t *reg_domain_ptr,
230 		const uint8_t *country_alpha2, enum country_src source)
231 {
232 
233 	return reg_get_domain_from_country_code(reg_domain_ptr,
234 			country_alpha2, source);
235 }
236 
237 
238 uint16_t wlan_reg_dmn_get_opclass_from_channel(uint8_t *country,
239 					       uint8_t channel,
240 					       uint8_t offset)
241 {
242 	return reg_dmn_get_opclass_from_channel(country, channel,
243 						offset);
244 }
245 
246 uint16_t wlan_reg_dmn_get_chanwidth_from_opclass(uint8_t *country,
247 						 uint8_t channel,
248 						 uint8_t opclass)
249 {
250 	return reg_dmn_get_chanwidth_from_opclass(country, channel,
251 						  opclass);
252 }
253 
254 uint16_t wlan_reg_dmn_set_curr_opclasses(uint8_t num_classes,
255 					 uint8_t *class)
256 {
257 	return reg_dmn_set_curr_opclasses(num_classes, class);
258 }
259 
260 uint16_t wlan_reg_dmn_get_curr_opclasses(uint8_t *num_classes,
261 					 uint8_t *class)
262 {
263 	return reg_dmn_get_curr_opclasses(num_classes, class);
264 }
265 
266 QDF_STATUS wlan_regulatory_init(void)
267 {
268 	QDF_STATUS status;
269 
270 	status = wlan_objmgr_register_psoc_create_handler(
271 		WLAN_UMAC_COMP_REGULATORY,
272 		wlan_regulatory_psoc_obj_created_notification, NULL);
273 	if (status != QDF_STATUS_SUCCESS) {
274 		reg_err("failed to register reg psoc obj create handler");
275 		return status;
276 	}
277 
278 	status = wlan_objmgr_register_psoc_destroy_handler(
279 		WLAN_UMAC_COMP_REGULATORY,
280 		wlan_regulatory_psoc_obj_destroyed_notification, NULL);
281 	if (status != QDF_STATUS_SUCCESS) {
282 		reg_err("failed to register reg psoc obj create handler");
283 		goto unreg_psoc_create;
284 	}
285 
286 	status = wlan_objmgr_register_pdev_create_handler(
287 		WLAN_UMAC_COMP_REGULATORY,
288 		wlan_regulatory_pdev_obj_created_notification, NULL);
289 	if (status != QDF_STATUS_SUCCESS) {
290 		reg_err("failed to register reg psoc obj create handler");
291 		goto unreg_psoc_destroy;
292 	}
293 
294 	status = wlan_objmgr_register_pdev_destroy_handler(
295 		WLAN_UMAC_COMP_REGULATORY,
296 		wlan_regulatory_pdev_obj_destroyed_notification, NULL);
297 	if (status != QDF_STATUS_SUCCESS) {
298 		reg_err("failed to register reg psoc obj create handler");
299 		goto unreg_pdev_create;
300 	}
301 
302 	reg_debug("regulatory handlers registered with obj mgr");
303 
304 	return status;
305 
306 unreg_pdev_create:
307 	status = wlan_objmgr_unregister_pdev_create_handler(
308 		WLAN_UMAC_COMP_REGULATORY,
309 		wlan_regulatory_pdev_obj_created_notification,
310 		NULL);
311 
312 unreg_psoc_destroy:
313 	status = wlan_objmgr_unregister_psoc_destroy_handler(
314 		WLAN_UMAC_COMP_REGULATORY,
315 		wlan_regulatory_psoc_obj_destroyed_notification,
316 		NULL);
317 
318 unreg_psoc_create:
319 	status = wlan_objmgr_unregister_psoc_create_handler(
320 		WLAN_UMAC_COMP_REGULATORY,
321 		wlan_regulatory_psoc_obj_created_notification,
322 		NULL);
323 
324 	return QDF_STATUS_E_FAILURE;
325 }
326 
327 QDF_STATUS wlan_regulatory_deinit(void)
328 {
329 	QDF_STATUS status, ret_status = QDF_STATUS_SUCCESS;
330 
331 	status = wlan_objmgr_unregister_pdev_destroy_handler(
332 		WLAN_UMAC_COMP_REGULATORY,
333 		wlan_regulatory_pdev_obj_destroyed_notification, NULL);
334 	if (status != QDF_STATUS_SUCCESS) {
335 		reg_err("failed to unregister reg pdev obj destroy handler");
336 		ret_status = status;
337 	}
338 
339 	status = wlan_objmgr_unregister_pdev_create_handler(
340 		WLAN_UMAC_COMP_REGULATORY,
341 		wlan_regulatory_pdev_obj_created_notification, NULL);
342 	if (status != QDF_STATUS_SUCCESS) {
343 		reg_err("failed to unregister reg pdev obj create handler");
344 		ret_status = status;
345 	}
346 
347 	status = wlan_objmgr_unregister_psoc_destroy_handler(
348 		WLAN_UMAC_COMP_REGULATORY,
349 		wlan_regulatory_psoc_obj_destroyed_notification, NULL);
350 	if (status != QDF_STATUS_SUCCESS) {
351 		reg_err("failed to unregister reg psoc obj destroy handler");
352 		ret_status = status;
353 	}
354 
355 	status = wlan_objmgr_unregister_psoc_create_handler(
356 			WLAN_UMAC_COMP_REGULATORY,
357 			wlan_regulatory_psoc_obj_created_notification, NULL);
358 	if (status != QDF_STATUS_SUCCESS) {
359 		reg_err("failed to unregister reg psoc obj create handler");
360 		ret_status = status;
361 	}
362 
363 	reg_debug("deregistered callbacks with obj mgr");
364 
365 	return ret_status;
366 }
367 
368 QDF_STATUS regulatory_psoc_open(struct wlan_objmgr_psoc *psoc)
369 {
370 	struct wlan_lmac_if_reg_tx_ops *tx_ops;
371 
372 	tx_ops = reg_get_psoc_tx_ops(psoc);
373 	if (tx_ops->register_master_handler)
374 		tx_ops->register_master_handler(psoc, NULL);
375 	if (tx_ops->register_11d_new_cc_handler)
376 		tx_ops->register_11d_new_cc_handler(psoc, NULL);
377 	if (tx_ops->register_ch_avoid_event_handler)
378 		tx_ops->register_ch_avoid_event_handler(psoc, NULL);
379 
380 	return QDF_STATUS_SUCCESS;
381 }
382 
383 QDF_STATUS regulatory_psoc_close(struct wlan_objmgr_psoc *psoc)
384 {
385 	struct wlan_lmac_if_reg_tx_ops *tx_ops;
386 	struct wlan_regulatory_psoc_priv_obj *soc_reg;
387 	uint8_t i;
388 
389 	tx_ops = reg_get_psoc_tx_ops(psoc);
390 	if (tx_ops->unregister_11d_new_cc_handler)
391 		tx_ops->unregister_11d_new_cc_handler(psoc, NULL);
392 	if (tx_ops->unregister_master_handler)
393 		tx_ops->unregister_master_handler(psoc, NULL);
394 	if (tx_ops->unregister_ch_avoid_event_handler)
395 		tx_ops->unregister_ch_avoid_event_handler(psoc, NULL);
396 
397 	soc_reg = reg_get_psoc_obj(psoc);
398 
399 	if (!soc_reg) {
400 		reg_err("reg psoc private obj is NULL");
401 		return QDF_STATUS_E_FAULT;
402 	}
403 	for (i = 0; i < PSOC_MAX_PHY_REG_CAP; i++)
404 		reg_reset_reg_rules(&soc_reg->mas_chan_params[i].reg_rules);
405 
406 	return QDF_STATUS_SUCCESS;
407 }
408 
409 QDF_STATUS regulatory_pdev_open(struct wlan_objmgr_pdev *pdev)
410 {
411 	struct wlan_objmgr_psoc *parent_psoc;
412 	QDF_STATUS status;
413 
414 	parent_psoc = wlan_pdev_get_psoc(pdev);
415 
416 	status = reg_send_scheduler_msg_sb(parent_psoc, pdev);
417 
418 	if (QDF_IS_STATUS_ERROR(status))
419 		reg_err("scheduler send msg failed");
420 
421 	return status;
422 }
423 
424 QDF_STATUS regulatory_pdev_close(struct wlan_objmgr_pdev *pdev)
425 {
426 	return QDF_STATUS_SUCCESS;
427 }
428 
429 void wlan_reg_update_nol_ch(struct wlan_objmgr_pdev *pdev, uint8_t *ch_list,
430 		uint8_t num_ch, bool nol_ch)
431 {
432 	reg_update_nol_ch(pdev, ch_list, num_ch, nol_ch);
433 }
434 
435 bool wlan_reg_is_dfs_ch(struct wlan_objmgr_pdev *pdev,
436 			uint32_t chan)
437 {
438 	return reg_is_dfs_ch(pdev, chan);
439 }
440 
441 bool wlan_reg_is_passive_or_disable_ch(struct wlan_objmgr_pdev *pdev,
442 				       uint32_t chan)
443 {
444 	return reg_is_passive_or_disable_ch(pdev, chan);
445 }
446 
447 bool wlan_reg_is_disable_ch(struct wlan_objmgr_pdev *pdev,
448 				       uint32_t chan)
449 {
450 	return reg_is_disable_ch(pdev, chan);
451 }
452 
453 uint32_t wlan_reg_freq_to_chan(struct wlan_objmgr_pdev *pdev,
454 			       uint32_t freq)
455 {
456 	return reg_freq_to_chan(pdev, freq);
457 }
458 
459 uint32_t wlan_reg_chan_to_freq(struct wlan_objmgr_pdev *pdev,
460 			       uint32_t chan_num)
461 {
462 	return reg_chan_to_freq(pdev, chan_num);
463 }
464 
465 bool wlan_reg_chan_is_49ghz(struct wlan_objmgr_pdev *pdev,
466 		uint8_t chan_num)
467 {
468 	return reg_chan_is_49ghz(pdev, chan_num);
469 }
470 
471 QDF_STATUS wlan_reg_set_country(struct wlan_objmgr_pdev *pdev,
472 				       uint8_t *country)
473 {
474 	return reg_set_country(pdev, country);
475 }
476 
477 QDF_STATUS wlan_reg_set_11d_country(struct wlan_objmgr_pdev *pdev,
478 				    uint8_t *country)
479 {
480 	return reg_set_11d_country(pdev, country);
481 }
482 
483 bool wlan_reg_is_world(uint8_t *country)
484 {
485 	return reg_is_world_alpha2(country);
486 }
487 
488 bool wlan_reg_is_us(uint8_t *country)
489 {
490 	return reg_is_us_alpha2(country);
491 }
492 
493 void wlan_reg_register_chan_change_callback(struct wlan_objmgr_psoc *psoc,
494 					    reg_chan_change_callback cbk,
495 					    void *arg)
496 {
497 	reg_register_chan_change_callback(psoc, cbk, arg);
498 
499 }
500 
501 void wlan_reg_unregister_chan_change_callback(struct wlan_objmgr_psoc *psoc,
502 					      reg_chan_change_callback cbk)
503 {
504 	reg_unregister_chan_change_callback(psoc, cbk);
505 }
506 
507 bool wlan_reg_is_11d_offloaded(struct wlan_objmgr_psoc *psoc)
508 {
509 	return reg_is_11d_offloaded(psoc);
510 }
511 
512 bool wlan_reg_11d_enabled_on_host(struct wlan_objmgr_psoc *psoc)
513 {
514 	return reg_11d_enabled_on_host(psoc);
515 }
516 
517 bool wlan_reg_is_dsrc_chan(struct wlan_objmgr_pdev *pdev, uint8_t chan_num)
518 {
519 	return reg_is_dsrc_chan(pdev, chan_num);
520 }
521 
522 bool wlan_reg_is_etsi13_srd_chan(struct wlan_objmgr_pdev *pdev,
523 				 uint8_t chan_num)
524 {
525 	return reg_is_etsi13_srd_chan(pdev, chan_num);
526 }
527 
528 bool wlan_reg_is_etsi13_regdmn(struct wlan_objmgr_pdev *pdev)
529 {
530 	return reg_is_etsi13_regdmn(pdev);
531 }
532 
533 bool wlan_reg_is_etsi13_srd_chan_allowed_master_mode(struct wlan_objmgr_pdev
534 						     *pdev)
535 {
536 	return reg_is_etsi13_srd_chan_allowed_master_mode(pdev);
537 }
538 
539 QDF_STATUS wlan_reg_get_chip_mode(struct wlan_objmgr_pdev *pdev,
540 		uint32_t *chip_mode)
541 {
542 	struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj;
543 
544 	pdev_priv_obj = wlan_objmgr_pdev_get_comp_private_obj(pdev,
545 			WLAN_UMAC_COMP_REGULATORY);
546 
547 	if (NULL == pdev_priv_obj) {
548 		reg_err("reg pdev private obj is NULL");
549 		return QDF_STATUS_E_FAULT;
550 	}
551 
552 	*chip_mode = pdev_priv_obj->wireless_modes;
553 
554 	return QDF_STATUS_SUCCESS;
555 }
556 
557 bool wlan_reg_is_11d_scan_inprogress(struct wlan_objmgr_psoc *psoc)
558 {
559 	return reg_is_11d_scan_inprogress(psoc);
560 }
561 
562 QDF_STATUS wlan_reg_get_freq_range(struct wlan_objmgr_pdev *pdev,
563 		uint32_t *low_2g,
564 		uint32_t *high_2g,
565 		uint32_t *low_5g,
566 		uint32_t *high_5g)
567 {
568 	struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj;
569 
570 	pdev_priv_obj = wlan_objmgr_pdev_get_comp_private_obj(pdev,
571 			WLAN_UMAC_COMP_REGULATORY);
572 
573 	if (NULL == pdev_priv_obj) {
574 		reg_err("reg pdev private obj is NULL");
575 		return QDF_STATUS_E_FAULT;
576 	}
577 
578 	*low_2g = pdev_priv_obj->range_2g_low;
579 	*high_2g = pdev_priv_obj->range_2g_high;
580 	*low_5g = pdev_priv_obj->range_5g_low;
581 	*high_5g = pdev_priv_obj->range_5g_high;
582 
583 	return QDF_STATUS_SUCCESS;
584 }
585 
586 struct wlan_lmac_if_reg_tx_ops *
587 wlan_reg_get_tx_ops(struct wlan_objmgr_psoc *psoc)
588 {
589 	return reg_get_psoc_tx_ops(psoc);
590 }
591 
592 QDF_STATUS wlan_reg_get_curr_regdomain(struct wlan_objmgr_pdev *pdev,
593 		struct cur_regdmn_info *cur_regdmn)
594 {
595 	return reg_get_curr_regdomain(pdev, cur_regdmn);
596 }
597