xref: /wlan-dirver/qca-wifi-host-cmn/umac/regulatory/dispatcher/src/wlan_reg_services_api.c (revision 6ecd284e5a94a1c96e26d571dd47419ac305990d)
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 /**
89  * wlan_reg_get_5g_bonded_channel_state() - Get 5G bonded channel state
90  * @ch: channel number.
91  * @bw: channel band width
92  *
93  * Return: channel state
94  */
95 enum channel_state wlan_reg_get_5g_bonded_channel_state(
96 	struct wlan_objmgr_pdev *pdev, uint8_t ch,
97 	enum phy_ch_width bw)
98 {
99 	/*
100 	 * Get channel state from regulatory
101 	 */
102 	return reg_get_5g_bonded_channel_state(pdev, ch, bw);
103 }
104 
105 /**
106  * wlan_reg_get_2g_bonded_channel_state() - Get 2G bonded channel state
107  * @ch: channel number.
108  * @bw: channel band width
109  *
110  * Return: channel state
111  */
112 enum channel_state wlan_reg_get_2g_bonded_channel_state(
113 		struct wlan_objmgr_pdev *pdev, uint8_t ch,
114 		uint8_t sec_ch, enum phy_ch_width bw)
115 {
116 	/*
117 	 * Get channel state from regulatory
118 	 */
119 	return reg_get_2g_bonded_channel_state(pdev, ch, sec_ch, bw);
120 }
121 
122 /**
123  * wlan_reg_set_channel_params() - Sets channel parameteres for given bandwidth
124  * @ch: channel number.
125  * @ch_params: pointer to the channel parameters.
126  *
127  * Return: None
128  */
129 void wlan_reg_set_channel_params(struct wlan_objmgr_pdev *pdev, uint8_t ch,
130 				 uint8_t sec_ch_2g,
131 				 struct ch_params *ch_params)
132 {
133 	/*
134 	 * Set channel parameters like center frequency for a bonded channel
135 	 * state. Also return the maximum bandwidth supported by the channel.
136 	 */
137 	reg_set_channel_params(pdev, ch, sec_ch_2g, ch_params);
138 }
139 
140 /**
141  * wlan_reg_get_dfs_region () - Get the current dfs region
142  * @dfs_reg: pointer to dfs region
143  *
144  * Return: Status
145  */
146 QDF_STATUS wlan_reg_get_dfs_region(struct wlan_objmgr_pdev *pdev,
147 			     enum dfs_reg *dfs_reg)
148 {
149 	/*
150 	 * Get the current dfs region
151 	 */
152 	reg_get_current_dfs_region(pdev, dfs_reg);
153 
154 	return QDF_STATUS_SUCCESS;
155 }
156 
157 uint32_t wlan_reg_get_channel_reg_power(struct wlan_objmgr_pdev *pdev,
158 					uint32_t chan_num)
159 {
160 	return reg_get_channel_reg_power(pdev, chan_num);
161 }
162 
163 /**
164  * wlan_reg_get_channel_freq() - get regulatory power for channel
165  * @chan_num: channel number
166  *
167  * Return: int
168  */
169 uint32_t wlan_reg_get_channel_freq(struct wlan_objmgr_pdev *pdev,
170 				   uint32_t chan_num)
171 {
172 	return reg_get_channel_freq(pdev, chan_num);
173 }
174 
175 QDF_STATUS wlan_reg_get_current_chan_list(struct wlan_objmgr_pdev *pdev,
176 		struct regulatory_channel *chan_list)
177 {
178 	return reg_get_current_chan_list(pdev, chan_list);
179 }
180 
181 /**
182  * wlan_reg_get_bw_value() - give bandwidth value
183  * bw: bandwidth enum
184  *
185  * Return: uint16_t
186  */
187 uint16_t wlan_reg_get_bw_value(enum phy_ch_width bw)
188 {
189 	return reg_get_bw_value(bw);
190 }
191 
192 /**
193  * wlan_reg_get_bonded_channel_state() - Get 2G bonded channel state
194  * @ch: channel number.
195  * @bw: channel band width
196  *
197  * Return: channel state
198  */
199 enum channel_state wlan_reg_get_bonded_channel_state(
200 	struct wlan_objmgr_pdev *pdev, uint8_t ch,
201 	enum phy_ch_width bw, uint8_t sec_ch)
202 {
203 	if (WLAN_REG_IS_24GHZ_CH(ch))
204 		return reg_get_2g_bonded_channel_state(pdev, ch,
205 						       sec_ch, bw);
206 	else
207 		return reg_get_5g_bonded_channel_state(pdev, ch,
208 						       bw);
209 }
210 
211 /**
212  * wlan_reg_set_dfs_region () - Get the current dfs region
213  * @dfs_reg: pointer to dfs region
214  *
215  * Return: None
216  */
217 void wlan_reg_set_dfs_region(struct wlan_objmgr_pdev *pdev,
218 			     enum dfs_reg dfs_reg)
219 {
220 	reg_set_dfs_region(pdev, dfs_reg);
221 }
222 
223 QDF_STATUS wlan_reg_get_domain_from_country_code(v_REGDOMAIN_t *reg_domain_ptr,
224 		const uint8_t *country_alpha2, enum country_src source)
225 {
226 
227 	return reg_get_domain_from_country_code(reg_domain_ptr,
228 			country_alpha2, source);
229 }
230 
231 
232 uint16_t wlan_reg_dmn_get_opclass_from_channel(uint8_t *country,
233 					       uint8_t channel,
234 					       uint8_t offset)
235 {
236 	return reg_dmn_get_opclass_from_channel(country, channel,
237 						offset);
238 }
239 
240 uint16_t wlan_reg_dmn_get_chanwidth_from_opclass(uint8_t *country,
241 						 uint8_t channel,
242 						 uint8_t opclass)
243 {
244 	return reg_dmn_get_chanwidth_from_opclass(country, channel,
245 						  opclass);
246 }
247 
248 uint16_t wlan_reg_dmn_set_curr_opclasses(uint8_t num_classes,
249 					 uint8_t *class)
250 {
251 	return reg_dmn_set_curr_opclasses(num_classes, class);
252 }
253 
254 uint16_t wlan_reg_dmn_get_curr_opclasses(uint8_t *num_classes,
255 					 uint8_t *class)
256 {
257 	return reg_dmn_get_curr_opclasses(num_classes, class);
258 }
259 
260 QDF_STATUS wlan_regulatory_init(void)
261 {
262 	QDF_STATUS status;
263 
264 	status = wlan_objmgr_register_psoc_create_handler(
265 		WLAN_UMAC_COMP_REGULATORY,
266 		wlan_regulatory_psoc_obj_created_notification, NULL);
267 	if (status != QDF_STATUS_SUCCESS) {
268 		reg_err("failed to register reg psoc obj create handler");
269 		return status;
270 	}
271 
272 	status = wlan_objmgr_register_psoc_destroy_handler(
273 		WLAN_UMAC_COMP_REGULATORY,
274 		wlan_regulatory_psoc_obj_destroyed_notification, NULL);
275 	if (status != QDF_STATUS_SUCCESS) {
276 		reg_err("failed to register reg psoc obj create handler");
277 		goto unreg_psoc_create;
278 	}
279 
280 	status = wlan_objmgr_register_pdev_create_handler(
281 		WLAN_UMAC_COMP_REGULATORY,
282 		wlan_regulatory_pdev_obj_created_notification, NULL);
283 	if (status != QDF_STATUS_SUCCESS) {
284 		reg_err("failed to register reg psoc obj create handler");
285 		goto unreg_psoc_destroy;
286 	}
287 
288 	status = wlan_objmgr_register_pdev_destroy_handler(
289 		WLAN_UMAC_COMP_REGULATORY,
290 		wlan_regulatory_pdev_obj_destroyed_notification, NULL);
291 	if (status != QDF_STATUS_SUCCESS) {
292 		reg_err("failed to register reg psoc obj create handler");
293 		goto unreg_pdev_create;
294 	}
295 
296 	reg_debug("regulatory handlers registered with obj mgr");
297 
298 	return status;
299 
300 unreg_pdev_create:
301 	status = wlan_objmgr_unregister_pdev_create_handler(
302 		WLAN_UMAC_COMP_REGULATORY,
303 		wlan_regulatory_pdev_obj_created_notification,
304 		NULL);
305 
306 unreg_psoc_destroy:
307 	status = wlan_objmgr_unregister_psoc_destroy_handler(
308 		WLAN_UMAC_COMP_REGULATORY,
309 		wlan_regulatory_psoc_obj_destroyed_notification,
310 		NULL);
311 
312 unreg_psoc_create:
313 	status = wlan_objmgr_unregister_psoc_create_handler(
314 		WLAN_UMAC_COMP_REGULATORY,
315 		wlan_regulatory_psoc_obj_created_notification,
316 		NULL);
317 
318 	return QDF_STATUS_E_FAILURE;
319 }
320 
321 QDF_STATUS wlan_regulatory_deinit(void)
322 {
323 	QDF_STATUS status, ret_status = QDF_STATUS_SUCCESS;
324 
325 	status = wlan_objmgr_unregister_pdev_destroy_handler(
326 		WLAN_UMAC_COMP_REGULATORY,
327 		wlan_regulatory_pdev_obj_destroyed_notification, NULL);
328 	if (status != QDF_STATUS_SUCCESS) {
329 		reg_err("failed to unregister reg pdev obj destroy handler");
330 		ret_status = status;
331 	}
332 
333 	status = wlan_objmgr_unregister_pdev_create_handler(
334 		WLAN_UMAC_COMP_REGULATORY,
335 		wlan_regulatory_pdev_obj_created_notification, NULL);
336 	if (status != QDF_STATUS_SUCCESS) {
337 		reg_err("failed to unregister reg pdev obj create handler");
338 		ret_status = status;
339 	}
340 
341 	status = wlan_objmgr_unregister_psoc_destroy_handler(
342 		WLAN_UMAC_COMP_REGULATORY,
343 		wlan_regulatory_psoc_obj_destroyed_notification, NULL);
344 	if (status != QDF_STATUS_SUCCESS) {
345 		reg_err("failed to unregister reg psoc obj destroy handler");
346 		ret_status = status;
347 	}
348 
349 	status = wlan_objmgr_unregister_psoc_create_handler(
350 			WLAN_UMAC_COMP_REGULATORY,
351 			wlan_regulatory_psoc_obj_created_notification, NULL);
352 	if (status != QDF_STATUS_SUCCESS) {
353 		reg_err("failed to unregister reg psoc obj create handler");
354 		ret_status = status;
355 	}
356 
357 	reg_debug("deregistered callbacks with obj mgr");
358 
359 	return ret_status;
360 }
361 
362 QDF_STATUS regulatory_psoc_open(struct wlan_objmgr_psoc *psoc)
363 {
364 	struct wlan_lmac_if_reg_tx_ops *tx_ops;
365 
366 	tx_ops = reg_get_psoc_tx_ops(psoc);
367 	if (tx_ops->register_master_handler)
368 		tx_ops->register_master_handler(psoc, NULL);
369 	if (tx_ops->register_11d_new_cc_handler)
370 		tx_ops->register_11d_new_cc_handler(psoc, NULL);
371 	if (tx_ops->register_ch_avoid_event_handler)
372 		tx_ops->register_ch_avoid_event_handler(psoc, NULL);
373 
374 	return QDF_STATUS_SUCCESS;
375 }
376 
377 QDF_STATUS regulatory_psoc_close(struct wlan_objmgr_psoc *psoc)
378 {
379 	struct wlan_lmac_if_reg_tx_ops *tx_ops;
380 
381 	tx_ops = reg_get_psoc_tx_ops(psoc);
382 	if (tx_ops->unregister_11d_new_cc_handler)
383 		tx_ops->unregister_11d_new_cc_handler(psoc, NULL);
384 	if (tx_ops->unregister_master_handler)
385 		tx_ops->unregister_master_handler(psoc, NULL);
386 	if (tx_ops->unregister_ch_avoid_event_handler)
387 		tx_ops->unregister_ch_avoid_event_handler(psoc, NULL);
388 
389 	return QDF_STATUS_SUCCESS;
390 }
391 
392 QDF_STATUS regulatory_pdev_open(struct wlan_objmgr_pdev *pdev)
393 {
394 	struct wlan_objmgr_psoc *parent_psoc;
395 	QDF_STATUS status;
396 
397 	parent_psoc = wlan_pdev_get_psoc(pdev);
398 
399 	status = reg_send_scheduler_msg_sb(parent_psoc, pdev);
400 
401 	if (QDF_IS_STATUS_ERROR(status))
402 		reg_err("scheduler send msg failed");
403 
404 	return status;
405 }
406 
407 QDF_STATUS regulatory_pdev_close(struct wlan_objmgr_pdev *pdev)
408 {
409 	return QDF_STATUS_SUCCESS;
410 }
411 
412 void wlan_reg_update_nol_ch(struct wlan_objmgr_pdev *pdev, uint8_t *ch_list,
413 		uint8_t num_ch, bool nol_ch)
414 {
415 	reg_update_nol_ch(pdev, ch_list, num_ch, nol_ch);
416 }
417 
418 bool wlan_reg_is_dfs_ch(struct wlan_objmgr_pdev *pdev,
419 			uint32_t chan)
420 {
421 	return reg_is_dfs_ch(pdev, chan);
422 }
423 
424 bool wlan_reg_is_passive_or_disable_ch(struct wlan_objmgr_pdev *pdev,
425 				       uint32_t chan)
426 {
427 	return reg_is_passive_or_disable_ch(pdev, chan);
428 }
429 
430 bool wlan_reg_is_disable_ch(struct wlan_objmgr_pdev *pdev,
431 				       uint32_t chan)
432 {
433 	return reg_is_disable_ch(pdev, chan);
434 }
435 
436 uint32_t wlan_reg_freq_to_chan(struct wlan_objmgr_pdev *pdev,
437 			       uint32_t freq)
438 {
439 	return reg_freq_to_chan(pdev, freq);
440 }
441 
442 uint32_t wlan_reg_chan_to_freq(struct wlan_objmgr_pdev *pdev,
443 			       uint32_t chan_num)
444 {
445 	return reg_chan_to_freq(pdev, chan_num);
446 }
447 
448 bool wlan_reg_chan_is_49ghz(struct wlan_objmgr_pdev *pdev,
449 		uint8_t chan_num)
450 {
451 	return reg_chan_is_49ghz(pdev, chan_num);
452 }
453 
454 QDF_STATUS wlan_reg_set_country(struct wlan_objmgr_pdev *pdev,
455 				       uint8_t *country)
456 {
457 	return reg_set_country(pdev, country);
458 }
459 
460 QDF_STATUS wlan_reg_set_11d_country(struct wlan_objmgr_pdev *pdev,
461 				    uint8_t *country)
462 {
463 	return reg_set_11d_country(pdev, country);
464 }
465 
466 bool wlan_reg_is_world(uint8_t *country)
467 {
468 	return reg_is_world_alpha2(country);
469 }
470 
471 bool wlan_reg_is_us(uint8_t *country)
472 {
473 	return reg_is_us_alpha2(country);
474 }
475 
476 void wlan_reg_register_chan_change_callback(struct wlan_objmgr_psoc *psoc,
477 					    reg_chan_change_callback cbk,
478 					    void *arg)
479 {
480 	reg_register_chan_change_callback(psoc, cbk, arg);
481 
482 }
483 
484 void wlan_reg_unregister_chan_change_callback(struct wlan_objmgr_psoc *psoc,
485 					      reg_chan_change_callback cbk)
486 {
487 	reg_unregister_chan_change_callback(psoc, cbk);
488 }
489 
490 bool wlan_reg_11d_original_enabled_on_host(struct wlan_objmgr_psoc *psoc)
491 {
492 	return reg_11d_original_enabled_on_host(psoc);
493 }
494 
495 bool wlan_reg_11d_enabled_on_host(struct wlan_objmgr_psoc *psoc)
496 {
497 	return reg_11d_enabled_on_host(psoc);
498 }
499 
500 QDF_STATUS wlan_reg_get_chip_mode(struct wlan_objmgr_pdev *pdev,
501 		uint32_t *chip_mode)
502 {
503 	struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj;
504 
505 	pdev_priv_obj = wlan_objmgr_pdev_get_comp_private_obj(pdev,
506 			WLAN_UMAC_COMP_REGULATORY);
507 
508 	if (NULL == pdev_priv_obj) {
509 		reg_err("reg pdev private obj is NULL");
510 		return QDF_STATUS_E_FAULT;
511 	}
512 
513 	*chip_mode = pdev_priv_obj->wireless_modes;
514 
515 	return QDF_STATUS_SUCCESS;
516 }
517 
518 bool wlan_reg_is_11d_scan_inprogress(struct wlan_objmgr_psoc *psoc)
519 {
520 	return reg_is_11d_scan_inprogress(psoc);
521 }
522 
523 QDF_STATUS wlan_reg_get_freq_range(struct wlan_objmgr_pdev *pdev,
524 		uint32_t *low_2g,
525 		uint32_t *high_2g,
526 		uint32_t *low_5g,
527 		uint32_t *high_5g)
528 {
529 	struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj;
530 
531 	pdev_priv_obj = wlan_objmgr_pdev_get_comp_private_obj(pdev,
532 			WLAN_UMAC_COMP_REGULATORY);
533 
534 	if (NULL == pdev_priv_obj) {
535 		reg_err("reg pdev private obj is NULL");
536 		return QDF_STATUS_E_FAULT;
537 	}
538 
539 	*low_2g = pdev_priv_obj->range_2g_low;
540 	*high_2g = pdev_priv_obj->range_2g_high;
541 	*low_5g = pdev_priv_obj->range_5g_low;
542 	*high_5g = pdev_priv_obj->range_5g_high;
543 
544 	return QDF_STATUS_SUCCESS;
545 }
546 
547 struct wlan_lmac_if_reg_tx_ops *
548 wlan_reg_get_tx_ops(struct wlan_objmgr_psoc *psoc)
549 {
550 	return reg_get_psoc_tx_ops(psoc);
551 }
552 
553 QDF_STATUS wlan_reg_get_curr_regdomain(struct wlan_objmgr_pdev *pdev,
554 		struct cur_regdmn_info *cur_regdmn)
555 {
556 	return reg_get_curr_regdomain(pdev, cur_regdmn);
557 }
558