xref: /wlan-dirver/qca-wifi-host-cmn/umac/dfs/dispatcher/src/wlan_dfs_utils_api.c (revision 7b32946958ccd00534989da3a4b46d0af59a5b5c)
1 /*
2  * Copyright (c) 2016-2017 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  * DOC: This file has the DFS dispatcher API implementation which is exposed
22  * to outside of DFS component.
23  */
24 #include "wlan_dfs_utils_api.h"
25 #include "../../core/src/dfs.h"
26 #include "../../core/src/dfs_zero_cac.h"
27 #include "../../core/src/dfs_random_chan_sel.h"
28 #ifdef QCA_DFS_USE_POLICY_MANAGER
29 #include "wlan_policy_mgr_api.h"
30 #endif
31 #ifdef QCA_DFS_NOL_PLATFORM_DRV_SUPPORT
32 #include <pld_common.h>
33 #endif
34 
35 struct dfs_nol_info {
36 	uint16_t num_chans;
37 	struct dfsreq_nolelem dfs_nol[DFS_MAX_NOL_CHANNEL];
38 };
39 
40 QDF_STATUS utils_dfs_reset(struct wlan_objmgr_pdev *pdev)
41 {
42 	struct wlan_dfs *dfs;
43 
44 	dfs = global_dfs_to_mlme.pdev_get_comp_private_obj(pdev);
45 	if (dfs == NULL)
46 		return  QDF_STATUS_E_FAILURE;
47 
48 	dfs_reset(dfs);
49 	dfs_nol_update(dfs);
50 	dfs_init_precac_list(dfs);
51 
52 	return QDF_STATUS_SUCCESS;
53 }
54 
55 QDF_STATUS utils_dfs_cac_valid_reset(struct wlan_objmgr_pdev *pdev,
56 		uint8_t prevchan_ieee,
57 		uint32_t prevchan_flags)
58 {
59 	struct wlan_dfs *dfs;
60 
61 	dfs = global_dfs_to_mlme.pdev_get_comp_private_obj(pdev);
62 	if (dfs == NULL)
63 		return  QDF_STATUS_E_FAILURE;
64 
65 	dfs_cac_valid_reset(dfs, prevchan_ieee, prevchan_flags);
66 
67 	return QDF_STATUS_SUCCESS;
68 }
69 EXPORT_SYMBOL(utils_dfs_cac_valid_reset);
70 
71 QDF_STATUS utils_dfs_reset_precaclists(struct wlan_objmgr_pdev *pdev)
72 {
73 	struct wlan_dfs *dfs;
74 
75 	dfs = global_dfs_to_mlme.pdev_get_comp_private_obj(pdev);
76 	if (dfs == NULL)
77 		return  QDF_STATUS_E_FAILURE;
78 
79 	dfs_reset_precaclists(dfs);
80 
81 	return QDF_STATUS_SUCCESS;
82 }
83 EXPORT_SYMBOL(utils_dfs_reset_precaclists);
84 
85 QDF_STATUS utils_dfs_cancel_precac_timer(struct wlan_objmgr_pdev *pdev)
86 {
87 	struct wlan_dfs *dfs;
88 
89 	dfs = global_dfs_to_mlme.pdev_get_comp_private_obj(pdev);
90 	if (dfs == NULL)
91 		return  QDF_STATUS_E_FAILURE;
92 
93 	dfs_cancel_precac_timer(dfs);
94 
95 	return QDF_STATUS_SUCCESS;
96 }
97 EXPORT_SYMBOL(utils_dfs_cancel_precac_timer);
98 
99 QDF_STATUS utils_dfs_is_precac_done(struct wlan_objmgr_pdev *pdev,
100 		bool *is_precac_done)
101 {
102 	struct wlan_dfs *dfs;
103 
104 	dfs = global_dfs_to_mlme.pdev_get_comp_private_obj(pdev);
105 	if (dfs == NULL)
106 		return  QDF_STATUS_E_FAILURE;
107 
108 	*is_precac_done = dfs_is_precac_done(dfs);
109 
110 	return QDF_STATUS_SUCCESS;
111 }
112 EXPORT_SYMBOL(utils_dfs_is_precac_done);
113 
114 QDF_STATUS utils_dfs_cancel_cac_timer(struct wlan_objmgr_pdev *pdev)
115 {
116 	struct wlan_dfs *dfs;
117 
118 	dfs = global_dfs_to_mlme.pdev_get_comp_private_obj(pdev);
119 	if (dfs == NULL)
120 		return  QDF_STATUS_E_FAILURE;
121 
122 	dfs_cancel_cac_timer(dfs);
123 
124 	return QDF_STATUS_SUCCESS;
125 }
126 EXPORT_SYMBOL(utils_dfs_cancel_cac_timer);
127 
128 QDF_STATUS utils_dfs_start_cac_timer(struct wlan_objmgr_pdev *pdev)
129 {
130 	struct wlan_dfs *dfs;
131 
132 	dfs = global_dfs_to_mlme.pdev_get_comp_private_obj(pdev);
133 	if (dfs == NULL)
134 		return  QDF_STATUS_E_FAILURE;
135 
136 	dfs_start_cac_timer(dfs);
137 
138 	return QDF_STATUS_SUCCESS;
139 }
140 EXPORT_SYMBOL(utils_dfs_start_cac_timer);
141 
142 QDF_STATUS utils_dfs_cac_stop(struct wlan_objmgr_pdev *pdev)
143 {
144 	struct wlan_dfs *dfs;
145 
146 	dfs = global_dfs_to_mlme.pdev_get_comp_private_obj(pdev);
147 	if (dfs == NULL)
148 		return  QDF_STATUS_E_FAILURE;
149 
150 	dfs_cac_stop(dfs);
151 	return  QDF_STATUS_SUCCESS;
152 }
153 EXPORT_SYMBOL(utils_dfs_cac_stop);
154 
155 QDF_STATUS utils_dfs_stacac_stop(struct wlan_objmgr_pdev *pdev)
156 {
157 	struct wlan_dfs *dfs;
158 
159 	dfs = global_dfs_to_mlme.pdev_get_comp_private_obj(pdev);
160 	if (dfs == NULL)
161 		return  QDF_STATUS_E_FAILURE;
162 
163 	dfs_stacac_stop(dfs);
164 
165 	return QDF_STATUS_SUCCESS;
166 }
167 EXPORT_SYMBOL(utils_dfs_stacac_stop);
168 
169 QDF_STATUS utils_dfs_random_channel(struct wlan_objmgr_pdev *pdev,
170 		uint8_t is_select_nondfs,
171 		uint8_t skip_curchan,
172 		int *target_channel)
173 {
174 	struct wlan_dfs *dfs;
175 
176 	dfs = global_dfs_to_mlme.pdev_get_comp_private_obj(pdev);
177 	if (dfs == NULL)
178 		return  QDF_STATUS_E_FAILURE;
179 
180 	*target_channel = dfs_random_channel(dfs,
181 			is_select_nondfs,
182 			skip_curchan);
183 
184 	return QDF_STATUS_SUCCESS;
185 }
186 EXPORT_SYMBOL(utils_dfs_random_channel);
187 
188 QDF_STATUS utils_dfs_get_usenol(struct wlan_objmgr_pdev *pdev, uint16_t *usenol)
189 {
190 	struct wlan_dfs *dfs;
191 
192 	dfs = global_dfs_to_mlme.pdev_get_comp_private_obj(pdev);
193 	if (dfs == NULL)
194 		return  QDF_STATUS_E_FAILURE;
195 
196 	*usenol = dfs_get_usenol(dfs);
197 
198 	return QDF_STATUS_SUCCESS;
199 }
200 EXPORT_SYMBOL(utils_dfs_get_usenol);
201 
202 QDF_STATUS utils_dfs_radar_disable(struct wlan_objmgr_pdev *pdev)
203 {
204 	struct wlan_dfs *dfs;
205 
206 	dfs = global_dfs_to_mlme.pdev_get_comp_private_obj(pdev);
207 	if (dfs == NULL)
208 		return  QDF_STATUS_E_FAILURE;
209 
210 	dfs_radar_disable(dfs);
211 
212 	return QDF_STATUS_SUCCESS;
213 }
214 EXPORT_SYMBOL(utils_dfs_radar_disable);
215 
216 QDF_STATUS utils_dfs_set_update_nol_flag(struct wlan_objmgr_pdev *pdev,
217 		bool val)
218 {
219 	struct wlan_dfs *dfs;
220 
221 	dfs = global_dfs_to_mlme.pdev_get_comp_private_obj(pdev);
222 	if (dfs == NULL)
223 		return  QDF_STATUS_E_FAILURE;
224 
225 	dfs_set_update_nol_flag(dfs, val);
226 
227 	return QDF_STATUS_SUCCESS;
228 }
229 EXPORT_SYMBOL(utils_dfs_set_update_nol_flag);
230 
231 QDF_STATUS utils_dfs_get_update_nol_flag(struct wlan_objmgr_pdev *pdev,
232 		bool *nol_flag)
233 {
234 	struct wlan_dfs *dfs;
235 
236 	dfs = global_dfs_to_mlme.pdev_get_comp_private_obj(pdev);
237 	if (dfs == NULL)
238 		return  QDF_STATUS_E_FAILURE;
239 
240 	*nol_flag = dfs_get_update_nol_flag(dfs);
241 
242 	return QDF_STATUS_SUCCESS;
243 }
244 EXPORT_SYMBOL(utils_dfs_get_update_nol_flag);
245 
246 QDF_STATUS utils_dfs_get_rn_use_nol(struct wlan_objmgr_pdev *pdev,
247 		int *rn_use_nol)
248 {
249 	struct wlan_dfs *dfs;
250 
251 	dfs = global_dfs_to_mlme.pdev_get_comp_private_obj(pdev);
252 	if (dfs == NULL)
253 		return  QDF_STATUS_E_FAILURE;
254 
255 	*rn_use_nol = dfs_get_rn_use_nol(dfs);
256 
257 	return QDF_STATUS_SUCCESS;
258 }
259 EXPORT_SYMBOL(utils_dfs_get_rn_use_nol);
260 
261 QDF_STATUS utils_dfs_get_nol_timeout(struct wlan_objmgr_pdev *pdev,
262 		int *dfs_nol_timeout)
263 {
264 	struct wlan_dfs *dfs;
265 
266 	dfs = global_dfs_to_mlme.pdev_get_comp_private_obj(pdev);
267 	if (dfs == NULL)
268 		return  QDF_STATUS_E_FAILURE;
269 
270 	*dfs_nol_timeout = dfs_get_nol_timeout(dfs);
271 
272 	return QDF_STATUS_SUCCESS;
273 }
274 EXPORT_SYMBOL(utils_dfs_get_nol_timeout);
275 
276 QDF_STATUS utils_dfs_nol_addchan(struct wlan_objmgr_pdev *pdev,
277 		uint16_t freq,
278 		uint32_t dfs_nol_timeout)
279 {
280 	struct wlan_dfs *dfs;
281 
282 	dfs = global_dfs_to_mlme.pdev_get_comp_private_obj(pdev);
283 	if (dfs == NULL)
284 		return  QDF_STATUS_E_FAILURE;
285 
286 	dfs_nol_addchan(dfs, freq, dfs_nol_timeout);
287 
288 	return QDF_STATUS_SUCCESS;
289 }
290 EXPORT_SYMBOL(utils_dfs_nol_addchan);
291 
292 QDF_STATUS utils_dfs_nol_update(struct wlan_objmgr_pdev *pdev)
293 {
294 	struct wlan_dfs *dfs;
295 
296 	dfs = global_dfs_to_mlme.pdev_get_comp_private_obj(pdev);
297 	if (dfs == NULL)
298 		return  QDF_STATUS_E_FAILURE;
299 
300 	dfs_nol_update(dfs);
301 
302 	return QDF_STATUS_SUCCESS;
303 }
304 EXPORT_SYMBOL(utils_dfs_nol_update);
305 
306 QDF_STATUS utils_dfs_second_segment_radar_disable(struct wlan_objmgr_pdev *pdev)
307 {
308 	struct wlan_dfs *dfs;
309 
310 	dfs = global_dfs_to_mlme.pdev_get_comp_private_obj(pdev);
311 	if (dfs == NULL)
312 		return  QDF_STATUS_E_FAILURE;
313 
314 	dfs_second_segment_radar_disable(dfs);
315 
316 	return QDF_STATUS_SUCCESS;
317 }
318 
319 QDF_STATUS utils_dfs_is_ignore_dfs(struct wlan_objmgr_pdev *pdev,
320 		bool *ignore_dfs)
321 {
322 	struct wlan_dfs *dfs;
323 
324 	dfs = global_dfs_to_mlme.pdev_get_comp_private_obj(pdev);
325 	if (dfs == NULL)
326 		return  QDF_STATUS_E_FAILURE;
327 
328 	*ignore_dfs = dfs->dfs_ignore_dfs;
329 
330 	return QDF_STATUS_SUCCESS;
331 }
332 EXPORT_SYMBOL(utils_dfs_is_ignore_dfs);
333 
334 QDF_STATUS utils_dfs_is_cac_valid(struct wlan_objmgr_pdev *pdev,
335 		bool *is_cac_valid)
336 {
337 	struct wlan_dfs *dfs;
338 
339 	dfs = global_dfs_to_mlme.pdev_get_comp_private_obj(pdev);
340 	if (dfs == NULL)
341 		return  QDF_STATUS_E_FAILURE;
342 
343 	*is_cac_valid = dfs->dfs_cac_valid;
344 
345 	return QDF_STATUS_SUCCESS;
346 }
347 EXPORT_SYMBOL(utils_dfs_is_cac_valid);
348 
349 QDF_STATUS utils_dfs_is_ignore_cac(struct wlan_objmgr_pdev *pdev,
350 		bool *ignore_cac)
351 {
352 	struct wlan_dfs *dfs;
353 
354 	dfs = global_dfs_to_mlme.pdev_get_comp_private_obj(pdev);
355 	if (dfs == NULL)
356 		return  QDF_STATUS_E_FAILURE;
357 
358 	*ignore_cac = dfs->dfs_ignore_cac;
359 
360 	return QDF_STATUS_SUCCESS;
361 }
362 EXPORT_SYMBOL(utils_dfs_is_ignore_cac);
363 
364 QDF_STATUS utils_dfs_set_cac_timer_running(struct wlan_objmgr_pdev *pdev,
365 		int val)
366 {
367 	struct wlan_dfs *dfs;
368 
369 	dfs = global_dfs_to_mlme.pdev_get_comp_private_obj(pdev);
370 	if (dfs == NULL)
371 		return  QDF_STATUS_E_FAILURE;
372 
373 	dfs->dfs_cac_timer_running = val;
374 
375 	return QDF_STATUS_SUCCESS;
376 }
377 EXPORT_SYMBOL(utils_dfs_set_cac_timer_running);
378 
379 QDF_STATUS utils_dfs_get_nol_chfreq_and_chwidth(struct wlan_objmgr_pdev *pdev,
380 		void *nollist,
381 		uint32_t *nol_chfreq,
382 		uint32_t *nol_chwidth,
383 		int index)
384 {
385 	struct wlan_dfs *dfs;
386 
387 	dfs = global_dfs_to_mlme.pdev_get_comp_private_obj(pdev);
388 	if (dfs == NULL)
389 		return  QDF_STATUS_E_FAILURE;
390 
391 	dfs_get_nol_chfreq_and_chwidth(nollist, nol_chfreq, nol_chwidth, index);
392 
393 	return QDF_STATUS_SUCCESS;
394 }
395 EXPORT_SYMBOL(utils_dfs_get_nol_chfreq_and_chwidth);
396 
397 QDF_STATUS utils_dfs_update_cur_chan_flags(struct wlan_objmgr_pdev *pdev,
398 		uint64_t flags,
399 		uint16_t flagext)
400 {
401 	struct wlan_dfs *dfs;
402 
403 	dfs = global_dfs_to_mlme.pdev_get_comp_private_obj(pdev);
404 	if (dfs == NULL)
405 		return  QDF_STATUS_E_FAILURE;
406 
407 	dfs_update_cur_chan_flags(dfs, flags, flagext);
408 
409 	return QDF_STATUS_SUCCESS;
410 }
411 
412 static void utils_dfs_get_max_phy_mode(struct wlan_objmgr_pdev *pdev,
413 		uint32_t *phy_mode)
414 {
415 	return;
416 }
417 
418 static void utils_dfs_get_max_sup_width(struct wlan_objmgr_pdev *pdev,
419 		uint8_t *ch_width)
420 {
421 	return;
422 }
423 
424 #ifndef QCA_DFS_USE_POLICY_MANAGER
425 static void utils_dfs_get_chan_list(struct wlan_objmgr_pdev *pdev,
426 	struct dfs_ieee80211_channel *chan_list, uint32_t *num_chan)
427 {
428 	return;
429 }
430 #else
431 static void utils_dfs_get_chan_list(struct wlan_objmgr_pdev *pdev,
432 	struct dfs_ieee80211_channel *chan_list, uint32_t *num_chan)
433 {
434 	uint8_t pcl_ch[NUM_CHANNELS];
435 	uint8_t weight_list[NUM_CHANNELS];
436 	uint32_t len;
437 	uint32_t weight_len;
438 	int i;
439 	struct wlan_objmgr_psoc *psoc;
440 	uint32_t conn_count = 0;
441 
442 	psoc = wlan_pdev_get_psoc(pdev);
443 	if (!psoc) {
444 		*num_chan = 0;
445 		DFS_PRINTK("%s: null psoc\n", __func__);
446 		return;
447 	}
448 
449 	len = QDF_ARRAY_SIZE(pcl_ch);
450 	weight_len = QDF_ARRAY_SIZE(weight_list);
451 	conn_count = policy_mgr_mode_specific_connection_count(
452 			psoc, PM_SAP_MODE, NULL);
453 	if (0 == conn_count)
454 		policy_mgr_get_pcl(psoc, PM_SAP_MODE, pcl_ch,
455 				&len, weight_list, weight_len);
456 	else
457 		policy_mgr_get_pcl_for_existing_conn(psoc, PM_SAP_MODE, pcl_ch,
458 				&len, weight_list, weight_len, true);
459 
460 	if (*num_chan < len) {
461 		DFS_PRINTK("%s: Invalid len src=%d, dst=%d\n",
462 			   __func__, *num_chan, len);
463 		*num_chan = 0;
464 		return;
465 	}
466 
467 	for (i = 0; i < len; i++) {
468 		chan_list[i].dfs_ch_ieee  = pcl_ch[i];
469 		chan_list[i].dfs_ch_freq  =
470 			wlan_reg_chan_to_freq(pdev, pcl_ch[i]);
471 	}
472 	*num_chan = i;
473 	DFS_PRINTK("%s: num channels %d\n", __func__, i);
474 }
475 #endif
476 
477 QDF_STATUS dfs_get_random_channel(
478 	struct wlan_objmgr_pdev *pdev,
479 	uint16_t flags,
480 	struct ch_params *ch_params,
481 	uint32_t *hw_mode,
482 	int *target_chan,
483 	struct dfs_acs_info *acs_info)
484 {
485 	uint32_t dfs_reg;
486 	uint32_t num_chan = NUM_CHANNELS;
487 	struct wlan_dfs *dfs = NULL;
488 	struct wlan_objmgr_psoc *psoc;
489 	struct dfs_ieee80211_channel *chan_list = NULL;
490 	struct dfs_ieee80211_channel cur_chan;
491 	QDF_STATUS status = QDF_STATUS_E_FAILURE;
492 
493 	*target_chan = 0;
494 	psoc = wlan_pdev_get_psoc(pdev);
495 	if (!psoc) {
496 		DFS_PRINTK("%s: null psoc\n", __func__);
497 		goto random_chan_error;
498 	}
499 
500 	dfs = global_dfs_to_mlme.pdev_get_comp_private_obj(pdev);
501 	if (!dfs) {
502 		DFS_PRINTK("%s: null dfs\n", __func__);
503 		goto random_chan_error;
504 	}
505 
506 	wlan_reg_get_dfs_region(pdev, &dfs_reg);
507 	chan_list = qdf_mem_malloc(num_chan * sizeof(*chan_list));
508 	if (!chan_list) {
509 		DFS_PRINTK("%s: mem alloc failed\n", __func__);
510 		goto random_chan_error;
511 	}
512 
513 	utils_dfs_get_chan_list(pdev, chan_list, &num_chan);
514 	if (!num_chan) {
515 		DFS_PRINTK("%s: zero channels\n", __func__);
516 		goto random_chan_error;
517 	}
518 
519 	cur_chan.dfs_ch_vhtop_ch_freq_seg1 = ch_params->center_freq_seg0;
520 	cur_chan.dfs_ch_vhtop_ch_freq_seg2 = ch_params->center_freq_seg1;
521 
522 	if (!ch_params->ch_width)
523 		utils_dfs_get_max_sup_width(pdev,
524 				(uint8_t *)&ch_params->ch_width);
525 
526 	*target_chan = dfs_prepare_random_channel(dfs, chan_list,
527 		num_chan, flags, (uint8_t *)&ch_params->ch_width,
528 		&cur_chan, (uint8_t)dfs_reg, acs_info);
529 
530 	ch_params->center_freq_seg0 = cur_chan.dfs_ch_vhtop_ch_freq_seg1;
531 	ch_params->center_freq_seg1 = cur_chan.dfs_ch_vhtop_ch_freq_seg2;
532 	DFS_PRINTK("%s: input width=%d\n", __func__, ch_params->ch_width);
533 
534 	if (*target_chan) {
535 		wlan_reg_set_channel_params(pdev,
536 			(uint8_t)*target_chan, 0, ch_params);
537 		utils_dfs_get_max_phy_mode(pdev, hw_mode);
538 		status = QDF_STATUS_SUCCESS;
539 	}
540 
541 	DFS_PRINTK("%s: ch=%d, seg0=%d, seg1=%d, width=%d\n",
542 		   __func__, *target_chan, ch_params->center_freq_seg0,
543 		   ch_params->center_freq_seg1, ch_params->ch_width);
544 random_chan_error:
545 	qdf_mem_free(chan_list);
546 
547 	return status;
548 }
549 EXPORT_SYMBOL(dfs_get_random_channel);
550 
551 #ifndef QCA_DFS_NOL_PLATFORM_DRV_SUPPORT
552 void dfs_init_nol(struct wlan_objmgr_pdev *pdev)
553 {
554 }
555 #else
556 void dfs_init_nol(struct wlan_objmgr_pdev *pdev)
557 {
558 	struct wlan_dfs *dfs;
559 	struct wlan_objmgr_psoc *psoc;
560 	qdf_device_t qdf_dev;
561 	struct dfs_nol_info dfs_nolinfo;
562 	int len;
563 
564 	dfs = global_dfs_to_mlme.pdev_get_comp_private_obj(pdev);
565 	psoc = wlan_pdev_get_psoc(pdev);
566 	if (!dfs || !psoc) {
567 		DFS_PRINTK("%s: dfs %p, psoc %p\n", __func__, dfs, psoc);
568 		return;
569 	}
570 
571 	qdf_dev = psoc->soc_objmgr.qdf_dev;
572 	if (!qdf_dev->dev) {
573 		DFS_PRINTK("%s: null device\n", __func__);
574 		return;
575 	}
576 
577 	qdf_mem_zero(&dfs_nolinfo, sizeof(dfs_nolinfo));
578 	len = pld_wlan_get_dfs_nol(qdf_dev->dev, (void *)&dfs_nolinfo,
579 			(uint16_t)sizeof(dfs_nolinfo));
580 	if (len > 0) {
581 		dfs_set_nol(dfs, dfs_nolinfo.dfs_nol, dfs_nolinfo.num_chans);
582 		DFS_PRINTK("%s: nol channels in pld\n", __func__);
583 		dfs_print_nol(dfs);
584 	} else {
585 		DFS_PRINTK("%s: no nol in pld\n", __func__);
586 	}
587 }
588 #endif
589 EXPORT_SYMBOL(dfs_init_nol);
590 
591 #ifndef QCA_DFS_NOL_PLATFORM_DRV_SUPPORT
592 void dfs_save_nol(struct wlan_objmgr_pdev *pdev)
593 {
594 }
595 #else
596 void dfs_save_nol(struct wlan_objmgr_pdev *pdev)
597 {
598 	struct dfs_nol_info dfs_nolinfo;
599 	struct wlan_dfs *dfs = NULL;
600 	struct wlan_objmgr_psoc *psoc;
601 	qdf_device_t qdf_dev;
602 	int num_chans = 0;
603 
604 	dfs = global_dfs_to_mlme.pdev_get_comp_private_obj(pdev);
605 	if (!dfs) {
606 		DFS_PRINTK("%s: null dfs\n", __func__);
607 		return;
608 	}
609 
610 	psoc = wlan_pdev_get_psoc(pdev);
611 	if (!psoc) {
612 		DFS_PRINTK("%s: null psoc\n", __func__);
613 		return;
614 	}
615 
616 	qdf_dev = psoc->soc_objmgr.qdf_dev;
617 	if (!qdf_dev->dev) {
618 		DFS_PRINTK("%s: null device\n", __func__);
619 		return;
620 	}
621 
622 	qdf_mem_zero(&dfs_nolinfo, sizeof(dfs_nolinfo));
623 	dfs_get_nol(dfs, dfs_nolinfo.dfs_nol, &num_chans);
624 	if (num_chans > 0) {
625 
626 		if (num_chans > DFS_MAX_NOL_CHANNEL)
627 			dfs_nolinfo.num_chans = DFS_MAX_NOL_CHANNEL;
628 		else
629 			dfs_nolinfo.num_chans = num_chans;
630 
631 		pld_wlan_set_dfs_nol(qdf_dev->dev, (void *)&dfs_nolinfo,
632 				(uint16_t)sizeof(dfs_nolinfo));
633 	}
634 }
635 #endif
636 EXPORT_SYMBOL(dfs_save_nol);
637 
638 void dfs_print_nol_channels(struct wlan_objmgr_pdev *pdev)
639 {
640 	struct wlan_dfs *dfs = NULL;
641 
642 	dfs = global_dfs_to_mlme.pdev_get_comp_private_obj(pdev);
643 	if (!dfs) {
644 		DFS_PRINTK("%s: null dfs\n", __func__);
645 		return;
646 	}
647 
648 	dfs_print_nol(dfs);
649 }
650 EXPORT_SYMBOL(dfs_print_nol_channels);
651 
652 void dfs_clear_nol_channels(struct wlan_objmgr_pdev *pdev)
653 {
654 	struct wlan_dfs *dfs = NULL;
655 
656 	dfs = global_dfs_to_mlme.pdev_get_comp_private_obj(pdev);
657 	if (!dfs) {
658 		DFS_PRINTK("%s: null dfs\n", __func__);
659 		return;
660 	}
661 
662 	/* First print list */
663 	dfs_print_nol(dfs);
664 
665 	/* clear local cache first */
666 	dfs_nol_timer_cleanup(dfs);
667 	dfs_nol_update(dfs);
668 
669 	/*
670 	 * update platform driver nol list with local cache which is zero,
671 	 * cleared in above step, so this will clear list in platform driver.
672 	 */
673 	dfs_save_nol(pdev);
674 }
675 EXPORT_SYMBOL(dfs_clear_nol_channels);
676 
677 bool utils_is_dfs_ch(struct wlan_objmgr_pdev *pdev, uint32_t chan)
678 {
679 	return wlan_reg_is_dfs_ch(pdev, chan);
680 }
681 EXPORT_SYMBOL(utils_is_dfs_ch);
682 
683 void utils_dfs_reg_update_nol_ch(struct wlan_objmgr_pdev *pdev,
684 		uint8_t *ch_list,
685 		uint8_t num_ch,
686 		bool nol_ch)
687 {
688 	wlan_reg_update_nol_ch(pdev, ch_list, num_ch, nol_ch);
689 }
690 EXPORT_SYMBOL(utils_dfs_reg_update_nol_ch);
691 
692 uint8_t utils_dfs_freq_to_chan(uint32_t freq)
693 {
694 	uint8_t chan;
695 
696 	if (freq > DFS_24_GHZ_BASE_FREQ && freq < DFS_CHAN_14_FREQ)
697 		chan = ((freq - DFS_24_GHZ_BASE_FREQ) / DFS_CHAN_SPACING_5MHZ);
698 	else if (freq == DFS_CHAN_14_FREQ)
699 		chan = DFS_24_GHZ_CHANNEL_14;
700 	else if ((freq > DFS_24_GHZ_BASE_FREQ) && (freq < DFS_5_GHZ_BASE_FREQ))
701 		chan = (((freq - DFS_CHAN_15_FREQ) / DFS_CHAN_SPACING_20MHZ) +
702 			DFS_24_GHZ_CHANNEL_15);
703 	else
704 		chan = (freq - DFS_5_GHZ_BASE_FREQ) / DFS_CHAN_SPACING_5MHZ;
705 
706 	return chan;
707 }
708 EXPORT_SYMBOL(utils_dfs_freq_to_chan);
709 
710 uint32_t utils_dfs_chan_to_freq(uint8_t chan)
711 {
712 	if (chan < DFS_24_GHZ_CHANNEL_14)
713 		return DFS_24_GHZ_BASE_FREQ + (chan * DFS_CHAN_SPACING_5MHZ);
714 	else if (chan == DFS_24_GHZ_CHANNEL_14)
715 		return DFS_CHAN_14_FREQ;
716 	else if (chan < DFS_24_GHZ_CHANNEL_27)
717 		return DFS_CHAN_15_FREQ + ((chan - DFS_24_GHZ_CHANNEL_15) *
718 				DFS_CHAN_SPACING_20MHZ);
719 	else if (chan == DFS_5_GHZ_CHANNEL_170)
720 		return DFS_CHAN_170_FREQ;
721 	else
722 		return DFS_5_GHZ_BASE_FREQ + (chan * DFS_CHAN_SPACING_5MHZ);
723 }
724 EXPORT_SYMBOL(utils_dfs_chan_to_freq);
725