xref: /wlan-dirver/qca-wifi-host-cmn/umac/dfs/dispatcher/src/wlan_dfs_utils_api.c (revision 3149adf58a329e17232a4c0e58d460d025edd55a)
1 /*
2  * Copyright (c) 2016-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  * 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 <wlan_reg_services_api.h>
28 #include "../../core/src/dfs_random_chan_sel.h"
29 #ifdef QCA_DFS_USE_POLICY_MANAGER
30 #include "wlan_policy_mgr_api.h"
31 #endif
32 #ifdef QCA_DFS_NOL_PLATFORM_DRV_SUPPORT
33 #include <pld_common.h>
34 #endif
35 
36 struct dfs_nol_info {
37 	uint16_t num_chans;
38 	struct dfsreq_nolelem dfs_nol[DFS_MAX_NOL_CHANNEL];
39 };
40 
41 QDF_STATUS utils_dfs_reset(struct wlan_objmgr_pdev *pdev)
42 {
43 	struct wlan_dfs *dfs;
44 
45 	dfs = global_dfs_to_mlme.pdev_get_comp_private_obj(pdev);
46 	if (!dfs)
47 		return  QDF_STATUS_E_FAILURE;
48 
49 	dfs_reset(dfs);
50 	dfs_nol_update(dfs);
51 	dfs_reset_precaclists(dfs);
52 
53 	return QDF_STATUS_SUCCESS;
54 }
55 
56 QDF_STATUS utils_dfs_cac_valid_reset(struct wlan_objmgr_pdev *pdev,
57 		uint8_t prevchan_ieee,
58 		uint32_t prevchan_flags)
59 {
60 	struct wlan_dfs *dfs;
61 
62 	dfs = global_dfs_to_mlme.pdev_get_comp_private_obj(pdev);
63 	if (!dfs)
64 		return  QDF_STATUS_E_FAILURE;
65 
66 	dfs_cac_valid_reset(dfs, prevchan_ieee, prevchan_flags);
67 
68 	return QDF_STATUS_SUCCESS;
69 }
70 EXPORT_SYMBOL(utils_dfs_cac_valid_reset);
71 
72 QDF_STATUS utils_dfs_reset_precaclists(struct wlan_objmgr_pdev *pdev)
73 {
74 	struct wlan_dfs *dfs;
75 
76 	dfs = global_dfs_to_mlme.pdev_get_comp_private_obj(pdev);
77 	if (!dfs)
78 		return  QDF_STATUS_E_FAILURE;
79 
80 	dfs_reset_precaclists(dfs);
81 
82 	return QDF_STATUS_SUCCESS;
83 }
84 EXPORT_SYMBOL(utils_dfs_reset_precaclists);
85 
86 QDF_STATUS utils_dfs_cancel_precac_timer(struct wlan_objmgr_pdev *pdev)
87 {
88 	struct wlan_dfs *dfs;
89 
90 	dfs = global_dfs_to_mlme.pdev_get_comp_private_obj(pdev);
91 	if (!dfs)
92 		return  QDF_STATUS_E_FAILURE;
93 
94 	dfs_cancel_precac_timer(dfs);
95 
96 	return QDF_STATUS_SUCCESS;
97 }
98 EXPORT_SYMBOL(utils_dfs_cancel_precac_timer);
99 
100 QDF_STATUS utils_dfs_is_precac_done(struct wlan_objmgr_pdev *pdev,
101 		bool *is_precac_done)
102 {
103 	struct wlan_dfs *dfs;
104 
105 	dfs = global_dfs_to_mlme.pdev_get_comp_private_obj(pdev);
106 	if (!dfs)
107 		return  QDF_STATUS_E_FAILURE;
108 
109 	*is_precac_done = dfs_is_precac_done(dfs);
110 
111 	return QDF_STATUS_SUCCESS;
112 }
113 EXPORT_SYMBOL(utils_dfs_is_precac_done);
114 
115 QDF_STATUS utils_dfs_cancel_cac_timer(struct wlan_objmgr_pdev *pdev)
116 {
117 	struct wlan_dfs *dfs;
118 
119 	dfs = global_dfs_to_mlme.pdev_get_comp_private_obj(pdev);
120 	if (!dfs)
121 		return  QDF_STATUS_E_FAILURE;
122 
123 	dfs_cancel_cac_timer(dfs);
124 
125 	return QDF_STATUS_SUCCESS;
126 }
127 EXPORT_SYMBOL(utils_dfs_cancel_cac_timer);
128 
129 QDF_STATUS utils_dfs_start_cac_timer(struct wlan_objmgr_pdev *pdev)
130 {
131 	struct wlan_dfs *dfs;
132 
133 	dfs = global_dfs_to_mlme.pdev_get_comp_private_obj(pdev);
134 	if (!dfs)
135 		return  QDF_STATUS_E_FAILURE;
136 
137 	dfs_start_cac_timer(dfs);
138 
139 	return QDF_STATUS_SUCCESS;
140 }
141 EXPORT_SYMBOL(utils_dfs_start_cac_timer);
142 
143 QDF_STATUS utils_dfs_cac_stop(struct wlan_objmgr_pdev *pdev)
144 {
145 	struct wlan_dfs *dfs;
146 
147 	dfs = global_dfs_to_mlme.pdev_get_comp_private_obj(pdev);
148 	if (!dfs)
149 		return  QDF_STATUS_E_FAILURE;
150 
151 	dfs_cac_stop(dfs);
152 	return  QDF_STATUS_SUCCESS;
153 }
154 EXPORT_SYMBOL(utils_dfs_cac_stop);
155 
156 QDF_STATUS utils_dfs_stacac_stop(struct wlan_objmgr_pdev *pdev)
157 {
158 	struct wlan_dfs *dfs;
159 
160 	dfs = global_dfs_to_mlme.pdev_get_comp_private_obj(pdev);
161 	if (!dfs)
162 		return  QDF_STATUS_E_FAILURE;
163 
164 	dfs_stacac_stop(dfs);
165 
166 	return QDF_STATUS_SUCCESS;
167 }
168 EXPORT_SYMBOL(utils_dfs_stacac_stop);
169 
170 QDF_STATUS utils_dfs_get_usenol(struct wlan_objmgr_pdev *pdev, uint16_t *usenol)
171 {
172 	struct wlan_dfs *dfs;
173 
174 	dfs = global_dfs_to_mlme.pdev_get_comp_private_obj(pdev);
175 	if (!dfs)
176 		return  QDF_STATUS_E_FAILURE;
177 
178 	*usenol = dfs_get_use_nol(dfs);
179 
180 	return QDF_STATUS_SUCCESS;
181 }
182 EXPORT_SYMBOL(utils_dfs_get_usenol);
183 
184 QDF_STATUS utils_dfs_radar_disable(struct wlan_objmgr_pdev *pdev)
185 {
186 	struct wlan_dfs *dfs;
187 
188 	dfs = global_dfs_to_mlme.pdev_get_comp_private_obj(pdev);
189 	if (!dfs)
190 		return  QDF_STATUS_E_FAILURE;
191 
192 	dfs_radar_disable(dfs);
193 
194 	return QDF_STATUS_SUCCESS;
195 }
196 EXPORT_SYMBOL(utils_dfs_radar_disable);
197 
198 QDF_STATUS utils_dfs_set_update_nol_flag(struct wlan_objmgr_pdev *pdev,
199 		bool val)
200 {
201 	struct wlan_dfs *dfs;
202 
203 	dfs = global_dfs_to_mlme.pdev_get_comp_private_obj(pdev);
204 	if (!dfs)
205 		return  QDF_STATUS_E_FAILURE;
206 
207 	dfs_set_update_nol_flag(dfs, val);
208 
209 	return QDF_STATUS_SUCCESS;
210 }
211 EXPORT_SYMBOL(utils_dfs_set_update_nol_flag);
212 
213 QDF_STATUS utils_dfs_get_update_nol_flag(struct wlan_objmgr_pdev *pdev,
214 		bool *nol_flag)
215 {
216 	struct wlan_dfs *dfs;
217 
218 	dfs = global_dfs_to_mlme.pdev_get_comp_private_obj(pdev);
219 	if (!dfs)
220 		return  QDF_STATUS_E_FAILURE;
221 
222 	*nol_flag = dfs_get_update_nol_flag(dfs);
223 
224 	return QDF_STATUS_SUCCESS;
225 }
226 EXPORT_SYMBOL(utils_dfs_get_update_nol_flag);
227 
228 QDF_STATUS utils_dfs_get_dfs_use_nol(struct wlan_objmgr_pdev *pdev,
229 		int *dfs_use_nol)
230 {
231 	struct wlan_dfs *dfs;
232 
233 	dfs = global_dfs_to_mlme.pdev_get_comp_private_obj(pdev);
234 	if (!dfs)
235 		return  QDF_STATUS_E_FAILURE;
236 
237 	*dfs_use_nol = dfs_get_use_nol(dfs);
238 
239 	return QDF_STATUS_SUCCESS;
240 }
241 EXPORT_SYMBOL(utils_dfs_get_dfs_use_nol);
242 
243 QDF_STATUS utils_dfs_get_nol_timeout(struct wlan_objmgr_pdev *pdev,
244 		int *dfs_nol_timeout)
245 {
246 	struct wlan_dfs *dfs;
247 
248 	dfs = global_dfs_to_mlme.pdev_get_comp_private_obj(pdev);
249 	if (!dfs)
250 		return  QDF_STATUS_E_FAILURE;
251 
252 	*dfs_nol_timeout = dfs_get_nol_timeout(dfs);
253 
254 	return QDF_STATUS_SUCCESS;
255 }
256 EXPORT_SYMBOL(utils_dfs_get_nol_timeout);
257 
258 QDF_STATUS utils_dfs_nol_addchan(struct wlan_objmgr_pdev *pdev,
259 		uint16_t freq,
260 		uint32_t dfs_nol_timeout)
261 {
262 	struct wlan_dfs *dfs;
263 
264 	dfs = global_dfs_to_mlme.pdev_get_comp_private_obj(pdev);
265 	if (!dfs)
266 		return  QDF_STATUS_E_FAILURE;
267 
268 	DFS_NOL_ADD_CHAN_LOCKED(dfs, freq, dfs_nol_timeout);
269 
270 	return QDF_STATUS_SUCCESS;
271 }
272 EXPORT_SYMBOL(utils_dfs_nol_addchan);
273 
274 QDF_STATUS utils_dfs_nol_update(struct wlan_objmgr_pdev *pdev)
275 {
276 	struct wlan_dfs *dfs;
277 
278 	dfs = global_dfs_to_mlme.pdev_get_comp_private_obj(pdev);
279 	if (!dfs)
280 		return  QDF_STATUS_E_FAILURE;
281 
282 	dfs_nol_update(dfs);
283 
284 	return QDF_STATUS_SUCCESS;
285 }
286 EXPORT_SYMBOL(utils_dfs_nol_update);
287 
288 QDF_STATUS utils_dfs_second_segment_radar_disable(struct wlan_objmgr_pdev *pdev)
289 {
290 	struct wlan_dfs *dfs;
291 
292 	dfs = global_dfs_to_mlme.pdev_get_comp_private_obj(pdev);
293 	if (!dfs)
294 		return  QDF_STATUS_E_FAILURE;
295 
296 	dfs_second_segment_radar_disable(dfs);
297 
298 	return QDF_STATUS_SUCCESS;
299 }
300 
301 QDF_STATUS utils_dfs_is_ignore_dfs(struct wlan_objmgr_pdev *pdev,
302 		bool *ignore_dfs)
303 {
304 	struct wlan_dfs *dfs;
305 
306 	dfs = global_dfs_to_mlme.pdev_get_comp_private_obj(pdev);
307 	if (!dfs)
308 		return  QDF_STATUS_E_FAILURE;
309 
310 	*ignore_dfs = dfs->dfs_ignore_dfs;
311 
312 	return QDF_STATUS_SUCCESS;
313 }
314 EXPORT_SYMBOL(utils_dfs_is_ignore_dfs);
315 
316 QDF_STATUS utils_dfs_is_cac_valid(struct wlan_objmgr_pdev *pdev,
317 		bool *is_cac_valid)
318 {
319 	struct wlan_dfs *dfs;
320 
321 	dfs = global_dfs_to_mlme.pdev_get_comp_private_obj(pdev);
322 	if (!dfs)
323 		return  QDF_STATUS_E_FAILURE;
324 
325 	*is_cac_valid = dfs->dfs_cac_valid;
326 
327 	return QDF_STATUS_SUCCESS;
328 }
329 EXPORT_SYMBOL(utils_dfs_is_cac_valid);
330 
331 QDF_STATUS utils_dfs_is_ignore_cac(struct wlan_objmgr_pdev *pdev,
332 		bool *ignore_cac)
333 {
334 	struct wlan_dfs *dfs;
335 
336 	dfs = global_dfs_to_mlme.pdev_get_comp_private_obj(pdev);
337 	if (!dfs)
338 		return  QDF_STATUS_E_FAILURE;
339 
340 	*ignore_cac = dfs->dfs_ignore_cac;
341 
342 	return QDF_STATUS_SUCCESS;
343 }
344 EXPORT_SYMBOL(utils_dfs_is_ignore_cac);
345 
346 QDF_STATUS utils_dfs_set_cac_timer_running(struct wlan_objmgr_pdev *pdev,
347 		int val)
348 {
349 	struct wlan_dfs *dfs;
350 
351 	dfs = global_dfs_to_mlme.pdev_get_comp_private_obj(pdev);
352 	if (!dfs)
353 		return  QDF_STATUS_E_FAILURE;
354 
355 	dfs->dfs_cac_timer_running = val;
356 
357 	return QDF_STATUS_SUCCESS;
358 }
359 EXPORT_SYMBOL(utils_dfs_set_cac_timer_running);
360 
361 QDF_STATUS utils_dfs_get_nol_chfreq_and_chwidth(struct wlan_objmgr_pdev *pdev,
362 		void *nollist,
363 		uint32_t *nol_chfreq,
364 		uint32_t *nol_chwidth,
365 		int index)
366 {
367 	struct wlan_dfs *dfs;
368 
369 	dfs = global_dfs_to_mlme.pdev_get_comp_private_obj(pdev);
370 	if (!dfs)
371 		return  QDF_STATUS_E_FAILURE;
372 
373 	dfs_get_nol_chfreq_and_chwidth(nollist, nol_chfreq, nol_chwidth, index);
374 
375 	return QDF_STATUS_SUCCESS;
376 }
377 EXPORT_SYMBOL(utils_dfs_get_nol_chfreq_and_chwidth);
378 
379 QDF_STATUS utils_dfs_update_cur_chan_flags(struct wlan_objmgr_pdev *pdev,
380 		uint64_t flags,
381 		uint16_t flagext)
382 {
383 	struct wlan_dfs *dfs;
384 
385 	dfs = global_dfs_to_mlme.pdev_get_comp_private_obj(pdev);
386 	if (!dfs)
387 		return  QDF_STATUS_E_FAILURE;
388 
389 	dfs_update_cur_chan_flags(dfs, flags, flagext);
390 
391 	return QDF_STATUS_SUCCESS;
392 }
393 
394 static void utils_dfs_get_max_phy_mode(struct wlan_objmgr_pdev *pdev,
395 		uint32_t *phy_mode)
396 {
397 	return;
398 }
399 
400 static void utils_dfs_get_max_sup_width(struct wlan_objmgr_pdev *pdev,
401 		uint8_t *ch_width)
402 {
403 	return;
404 }
405 
406 /**
407  * utils_dfs_get_chan_list() - Get channel list from regdb based on current
408  *                             operating channel.
409  * @pdev: Pointer to DFS pdev object.
410  * @chan_list: Pointer to current channel list
411  * @num_chan: number of channels in the current channel list.
412  */
413 #ifndef QCA_DFS_USE_POLICY_MANAGER
414 static void utils_dfs_get_chan_list(struct wlan_objmgr_pdev *pdev,
415 	struct dfs_channel *chan_list, uint32_t *num_chan)
416 {
417 	int i = 0, j = 0;
418 	enum channel_state state;
419 	struct regulatory_channel *cur_chan_list;
420 	struct wlan_dfs *dfs;
421 
422 	dfs = global_dfs_to_mlme.pdev_get_comp_private_obj(pdev);
423 	if (!dfs)
424 		return;
425 
426 	cur_chan_list = qdf_mem_malloc(NUM_CHANNELS *
427 			sizeof(struct regulatory_channel));
428 	if (!cur_chan_list) {
429 		dfs_alert(dfs, WLAN_DEBUG_DFS_ALWAYS, "fail to alloc");
430 		*num_chan = 0;
431 		return;
432 	}
433 
434 	if (wlan_reg_get_current_chan_list(
435 			pdev, cur_chan_list) != QDF_STATUS_SUCCESS) {
436 		*num_chan = 0;
437 		dfs_alert(dfs, WLAN_DEBUG_DFS_ALWAYS,
438 				"failed to get curr channel list");
439 		return;
440 	}
441 
442 	for (i = 0; i < NUM_CHANNELS; i++) {
443 		state = cur_chan_list[i].state;
444 		if (state == CHANNEL_STATE_DFS ||
445 				state == CHANNEL_STATE_ENABLE) {
446 			chan_list[j].dfs_ch_ieee = cur_chan_list[i].chan_num;
447 			chan_list[j].dfs_ch_freq = cur_chan_list[i].center_freq;
448 			if (state == CHANNEL_STATE_DFS)
449 				chan_list[j].dfs_ch_flagext =
450 					WLAN_CHAN_DFS;
451 			j++;
452 		}
453 	}
454 	*num_chan = j;
455 	qdf_mem_free(cur_chan_list);
456 
457 	return;
458 }
459 
460 /**
461  * utils_dfs_get_channel_list() - Get channel list from regdb component based
462  * on current channel list.
463  * @pdev: Pointer to pdev structure.
464  * @chan_list: Pointer to regdb channel list.
465  * @num_chan: number of channels.
466  *
467  * Get regdb channel list based on dfs current channel.
468  * ex: When  AP is operating in 5GHz channel, filter 2.4GHz and 4.9GHZ channels
469  * so that the random channel function does not select either 2.4GHz or 4.9GHz
470  * channel.
471  */
472 static void utils_dfs_get_channel_list(struct wlan_objmgr_pdev *pdev,
473 	struct dfs_channel *chan_list, uint32_t *num_chan)
474 {
475 	struct dfs_channel *tmp_chan_list = NULL;
476 	struct wlan_dfs *dfs;
477 	bool is_curchan_5g;
478 	bool is_curchan_24g;
479 	bool is_curchan_49g;
480 	uint32_t chan_num;
481 	uint32_t center_freq;
482 	uint16_t flagext;
483 	int i, j = 0;
484 
485 	dfs = global_dfs_to_mlme.pdev_get_comp_private_obj(pdev);
486 	if (!dfs) {
487 		dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "null dfs");
488 		return;
489 	}
490 
491 	tmp_chan_list = qdf_mem_malloc(*num_chan * sizeof(*tmp_chan_list));
492 	if (!tmp_chan_list) {
493 		dfs_alert(dfs, WLAN_DEBUG_DFS_ALWAYS, "mem alloc failed");
494 		return;
495 	}
496 
497 	utils_dfs_get_chan_list(pdev, tmp_chan_list, num_chan);
498 
499 	chan_num = dfs->dfs_curchan->dfs_ch_ieee;
500 	center_freq = dfs->dfs_curchan->dfs_ch_freq;
501 	is_curchan_5g = WLAN_REG_IS_5GHZ_CH(chan_num);
502 	is_curchan_24g = WLAN_REG_IS_24GHZ_CH(chan_num);
503 	is_curchan_49g = WLAN_REG_IS_49GHZ_FREQ(center_freq);
504 
505 	for (i = 0; i < *num_chan; i++) {
506 		chan_num = tmp_chan_list[i].dfs_ch_ieee;
507 		center_freq = tmp_chan_list[i].dfs_ch_freq;
508 		flagext = tmp_chan_list[i].dfs_ch_flagext;
509 
510 		if ((is_curchan_5g) && WLAN_REG_IS_5GHZ_CH(chan_num)) {
511 			chan_list[j].dfs_ch_ieee = chan_num;
512 			chan_list[j].dfs_ch_freq = center_freq;
513 			chan_list[j].dfs_ch_flagext = flagext;
514 			j++;
515 		} else if ((is_curchan_24g) &&
516 				WLAN_REG_IS_24GHZ_CH(chan_num)) {
517 			chan_list[j].dfs_ch_ieee = chan_num;
518 			chan_list[j].dfs_ch_freq = center_freq;
519 			j++;
520 		} else if ((is_curchan_49g) &&
521 				WLAN_REG_IS_49GHZ_FREQ(center_freq)) {
522 			chan_list[j].dfs_ch_ieee = chan_num;
523 			chan_list[j].dfs_ch_freq = center_freq;
524 			j++;
525 		}
526 	}
527 
528 	*num_chan = j;
529 
530 	qdf_mem_free(tmp_chan_list);
531 }
532 
533 #else
534 
535 static void utils_dfs_get_chan_list(struct wlan_objmgr_pdev *pdev,
536 	struct dfs_channel *chan_list, uint32_t *num_chan)
537 {
538 	uint8_t pcl_ch[NUM_CHANNELS];
539 	uint8_t weight_list[NUM_CHANNELS];
540 	uint32_t len;
541 	uint32_t weight_len;
542 	int i;
543 	struct wlan_objmgr_psoc *psoc;
544 	uint32_t conn_count = 0;
545 
546 	psoc = wlan_pdev_get_psoc(pdev);
547 	if (!psoc) {
548 		*num_chan = 0;
549 		dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS,  "null psoc");
550 		return;
551 	}
552 
553 	len = QDF_ARRAY_SIZE(pcl_ch);
554 	weight_len = QDF_ARRAY_SIZE(weight_list);
555 	conn_count = policy_mgr_mode_specific_connection_count(
556 			psoc, PM_SAP_MODE, NULL);
557 	if (0 == conn_count)
558 		policy_mgr_get_pcl(psoc, PM_SAP_MODE, pcl_ch,
559 				&len, weight_list, weight_len);
560 	else
561 		policy_mgr_get_pcl_for_existing_conn(psoc, PM_SAP_MODE, pcl_ch,
562 				&len, weight_list, weight_len, true);
563 
564 	if (*num_chan < len) {
565 		dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS,
566 				"Invalid len src=%d, dst=%d",
567 				*num_chan, len);
568 		*num_chan = 0;
569 		return;
570 	}
571 
572 	for (i = 0; i < len; i++) {
573 		chan_list[i].dfs_ch_ieee  = pcl_ch[i];
574 		chan_list[i].dfs_ch_freq  =
575 			wlan_reg_chan_to_freq(pdev, pcl_ch[i]);
576 	}
577 	*num_chan = i;
578 	dfs_info(NULL, WLAN_DEBUG_DFS_ALWAYS, "num channels %d", i);
579 }
580 
581 /**
582  * utils_dfs_get_channel_list() - Wrapper function to get channel list from
583  * regdb component.
584  * @pdev: Pointer to pdev structure.
585  * @chan_list: Pointer to regdb channel list.
586  * @num_chan: number of channels.
587  */
588 static void utils_dfs_get_channel_list(struct wlan_objmgr_pdev *pdev,
589 	struct dfs_channel *chan_list, uint32_t *num_chan)
590 {
591 	utils_dfs_get_chan_list(pdev, chan_list, num_chan);
592 }
593 #endif
594 
595 QDF_STATUS utils_dfs_get_random_channel(
596 	struct wlan_objmgr_pdev *pdev,
597 	uint16_t flags,
598 	struct ch_params *ch_params,
599 	uint32_t *hw_mode,
600 	uint8_t *target_chan,
601 	struct dfs_acs_info *acs_info)
602 {
603 	uint32_t dfs_reg;
604 	uint32_t num_chan = NUM_CHANNELS;
605 	struct wlan_dfs *dfs = NULL;
606 	struct wlan_objmgr_psoc *psoc;
607 	struct dfs_channel *chan_list = NULL;
608 	struct dfs_channel cur_chan;
609 	QDF_STATUS status = QDF_STATUS_E_FAILURE;
610 
611 	*target_chan = 0;
612 	psoc = wlan_pdev_get_psoc(pdev);
613 	if (!psoc) {
614 		dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS,  "null psoc");
615 		goto random_chan_error;
616 	}
617 
618 	dfs = global_dfs_to_mlme.pdev_get_comp_private_obj(pdev);
619 	if (!dfs) {
620 		dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS,  "null dfs");
621 		goto random_chan_error;
622 	}
623 
624 	wlan_reg_get_dfs_region(pdev, &dfs_reg);
625 	chan_list = qdf_mem_malloc(num_chan * sizeof(*chan_list));
626 	if (!chan_list) {
627 		dfs_alert(dfs, WLAN_DEBUG_DFS_ALWAYS, "mem alloc failed");
628 		goto random_chan_error;
629 	}
630 
631 	utils_dfs_get_channel_list(pdev, chan_list, &num_chan);
632 	if (!num_chan) {
633 		dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS,  "zero channels");
634 		goto random_chan_error;
635 	}
636 
637 	cur_chan.dfs_ch_vhtop_ch_freq_seg1 = ch_params->center_freq_seg0;
638 	cur_chan.dfs_ch_vhtop_ch_freq_seg2 = ch_params->center_freq_seg1;
639 
640 	if (!ch_params->ch_width)
641 		utils_dfs_get_max_sup_width(pdev,
642 				(uint8_t *)&ch_params->ch_width);
643 
644 	*target_chan = dfs_prepare_random_channel(dfs, chan_list,
645 		num_chan, flags, (uint8_t *)&ch_params->ch_width,
646 		&cur_chan, (uint8_t)dfs_reg, acs_info);
647 
648 	ch_params->center_freq_seg0 = cur_chan.dfs_ch_vhtop_ch_freq_seg1;
649 	ch_params->center_freq_seg1 = cur_chan.dfs_ch_vhtop_ch_freq_seg2;
650 	dfs_info(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN,
651 			"input width=%d", ch_params->ch_width);
652 
653 	if (*target_chan) {
654 		wlan_reg_set_channel_params(pdev,
655 				*target_chan, 0, ch_params);
656 		utils_dfs_get_max_phy_mode(pdev, hw_mode);
657 		status = QDF_STATUS_SUCCESS;
658 	}
659 
660 	dfs_info(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN,
661 			"ch=%d, seg0=%d, seg1=%d, width=%d",
662 			*target_chan, ch_params->center_freq_seg0,
663 			ch_params->center_freq_seg1, ch_params->ch_width);
664 
665 random_chan_error:
666 	qdf_mem_free(chan_list);
667 
668 	return status;
669 }
670 EXPORT_SYMBOL(utils_dfs_get_random_channel);
671 
672 #ifndef QCA_DFS_NOL_PLATFORM_DRV_SUPPORT
673 void utils_dfs_init_nol(struct wlan_objmgr_pdev *pdev)
674 {
675 }
676 #else
677 void utils_dfs_init_nol(struct wlan_objmgr_pdev *pdev)
678 {
679 	struct wlan_dfs *dfs;
680 	struct wlan_objmgr_psoc *psoc;
681 	qdf_device_t qdf_dev;
682 	struct dfs_nol_info dfs_nolinfo;
683 	int len;
684 
685 	dfs = global_dfs_to_mlme.pdev_get_comp_private_obj(pdev);
686 	psoc = wlan_pdev_get_psoc(pdev);
687 	if (!dfs || !psoc) {
688 		dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS,
689 				"dfs %pK, psoc %pK", dfs, psoc);
690 		return;
691 	}
692 
693 	qdf_dev = psoc->soc_objmgr.qdf_dev;
694 	if (!qdf_dev->dev) {
695 		dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS,  "null device");
696 		return;
697 	}
698 
699 	qdf_mem_zero(&dfs_nolinfo, sizeof(dfs_nolinfo));
700 	len = pld_wlan_get_dfs_nol(qdf_dev->dev, (void *)&dfs_nolinfo,
701 			(uint16_t)sizeof(dfs_nolinfo));
702 	if (len > 0) {
703 		dfs_set_nol(dfs, dfs_nolinfo.dfs_nol, dfs_nolinfo.num_chans);
704 		dfs_info(dfs, WLAN_DEBUG_DFS_ALWAYS, "nol channels in pld");
705 		DFS_PRINT_NOL_LOCKED(dfs);
706 	} else {
707 		dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS,  "no nol in pld");
708 	}
709 }
710 #endif
711 EXPORT_SYMBOL(utils_dfs_init_nol);
712 
713 #ifndef QCA_DFS_NOL_PLATFORM_DRV_SUPPORT
714 void utils_dfs_save_nol(struct wlan_objmgr_pdev *pdev)
715 {
716 }
717 #else
718 void utils_dfs_save_nol(struct wlan_objmgr_pdev *pdev)
719 {
720 	struct dfs_nol_info dfs_nolinfo;
721 	struct wlan_dfs *dfs = NULL;
722 	struct wlan_objmgr_psoc *psoc;
723 	qdf_device_t qdf_dev;
724 	int num_chans = 0;
725 
726 	dfs = global_dfs_to_mlme.pdev_get_comp_private_obj(pdev);
727 	if (!dfs) {
728 		dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS,  "null dfs");
729 		return;
730 	}
731 
732 	psoc = wlan_pdev_get_psoc(pdev);
733 	if (!psoc) {
734 		dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS,  "null psoc");
735 		return;
736 	}
737 
738 	qdf_dev = psoc->soc_objmgr.qdf_dev;
739 	if (!qdf_dev->dev) {
740 		dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS,  "null device");
741 		return;
742 	}
743 
744 	qdf_mem_zero(&dfs_nolinfo, sizeof(dfs_nolinfo));
745 	DFS_GET_NOL_LOCKED(dfs, dfs_nolinfo.dfs_nol, &num_chans);
746 	if (num_chans > 0) {
747 
748 		if (num_chans > DFS_MAX_NOL_CHANNEL)
749 			dfs_nolinfo.num_chans = DFS_MAX_NOL_CHANNEL;
750 		else
751 			dfs_nolinfo.num_chans = num_chans;
752 
753 		pld_wlan_set_dfs_nol(qdf_dev->dev, (void *)&dfs_nolinfo,
754 				(uint16_t)sizeof(dfs_nolinfo));
755 	}
756 }
757 #endif
758 EXPORT_SYMBOL(utils_dfs_save_nol);
759 
760 void utils_dfs_print_nol_channels(struct wlan_objmgr_pdev *pdev)
761 {
762 	struct wlan_dfs *dfs = NULL;
763 
764 	dfs = global_dfs_to_mlme.pdev_get_comp_private_obj(pdev);
765 	if (!dfs) {
766 		dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS,  "null dfs");
767 		return;
768 	}
769 
770 	DFS_PRINT_NOL_LOCKED(dfs);
771 }
772 EXPORT_SYMBOL(utils_dfs_print_nol_channels);
773 
774 void utils_dfs_clear_nol_channels(struct wlan_objmgr_pdev *pdev)
775 {
776 	struct wlan_dfs *dfs = NULL;
777 
778 	dfs = global_dfs_to_mlme.pdev_get_comp_private_obj(pdev);
779 	if (!dfs) {
780 		dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS,  "null dfs");
781 		return;
782 	}
783 
784 	/* First print list */
785 	DFS_PRINT_NOL_LOCKED(dfs);
786 
787 	/* clear local cache first */
788 	dfs_nol_timer_cleanup(dfs);
789 	dfs_nol_update(dfs);
790 
791 	/*
792 	 * update platform driver nol list with local cache which is zero,
793 	 * cleared in above step, so this will clear list in platform driver.
794 	 */
795 	utils_dfs_save_nol(pdev);
796 }
797 EXPORT_SYMBOL(utils_dfs_clear_nol_channels);
798 
799 bool utils_is_dfs_ch(struct wlan_objmgr_pdev *pdev, uint32_t chan)
800 {
801 	return wlan_reg_is_dfs_ch(pdev, chan);
802 }
803 EXPORT_SYMBOL(utils_is_dfs_ch);
804 
805 void utils_dfs_reg_update_nol_ch(struct wlan_objmgr_pdev *pdev,
806 		uint8_t *ch_list,
807 		uint8_t num_ch,
808 		bool nol_ch)
809 {
810 	/* TODO : Need locking?*/
811 	wlan_reg_update_nol_ch(pdev, ch_list, num_ch, nol_ch);
812 }
813 EXPORT_SYMBOL(utils_dfs_reg_update_nol_ch);
814 
815 uint8_t utils_dfs_freq_to_chan(uint32_t freq)
816 {
817 	uint8_t chan;
818 
819 	if (freq == 0)
820 		return 0;
821 
822 	if (freq > DFS_24_GHZ_BASE_FREQ && freq < DFS_CHAN_14_FREQ)
823 		chan = ((freq - DFS_24_GHZ_BASE_FREQ) / DFS_CHAN_SPACING_5MHZ);
824 	else if (freq == DFS_CHAN_14_FREQ)
825 		chan = DFS_24_GHZ_CHANNEL_14;
826 	else if ((freq > DFS_24_GHZ_BASE_FREQ) && (freq < DFS_5_GHZ_BASE_FREQ))
827 		chan = (((freq - DFS_CHAN_15_FREQ) / DFS_CHAN_SPACING_20MHZ) +
828 			DFS_24_GHZ_CHANNEL_15);
829 	else
830 		chan = (freq - DFS_5_GHZ_BASE_FREQ) / DFS_CHAN_SPACING_5MHZ;
831 
832 	return chan;
833 }
834 EXPORT_SYMBOL(utils_dfs_freq_to_chan);
835 
836 uint32_t utils_dfs_chan_to_freq(uint8_t chan)
837 {
838 	if (chan == 0)
839 		return 0;
840 
841 	if (chan < DFS_24_GHZ_CHANNEL_14)
842 		return DFS_24_GHZ_BASE_FREQ + (chan * DFS_CHAN_SPACING_5MHZ);
843 	else if (chan == DFS_24_GHZ_CHANNEL_14)
844 		return DFS_CHAN_14_FREQ;
845 	else if (chan < DFS_24_GHZ_CHANNEL_27)
846 		return DFS_CHAN_15_FREQ + ((chan - DFS_24_GHZ_CHANNEL_15) *
847 				DFS_CHAN_SPACING_20MHZ);
848 	else if (chan == DFS_5_GHZ_CHANNEL_170)
849 		return DFS_CHAN_170_FREQ;
850 	else
851 		return DFS_5_GHZ_BASE_FREQ + (chan * DFS_CHAN_SPACING_5MHZ);
852 }
853 EXPORT_SYMBOL(utils_dfs_chan_to_freq);
854 
855 #ifdef QCA_MCL_DFS_SUPPORT
856 QDF_STATUS utils_dfs_mark_leaking_ch(struct wlan_objmgr_pdev *pdev,
857 	enum phy_ch_width ch_width,
858 	uint8_t temp_ch_lst_sz,
859 	uint8_t *temp_ch_lst)
860 {
861 	struct wlan_dfs *dfs = NULL;
862 
863 	dfs = global_dfs_to_mlme.pdev_get_comp_private_obj(pdev);
864 	if (!dfs) {
865 		dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS,  "null dfs");
866 		return  QDF_STATUS_E_FAILURE;
867 	}
868 
869 	return dfs_mark_leaking_ch(dfs, ch_width, temp_ch_lst_sz, temp_ch_lst);
870 }
871 EXPORT_SYMBOL(utils_dfs_mark_leaking_ch);
872 #endif
873 
874 int utils_get_dfsdomain(struct wlan_objmgr_pdev *pdev)
875 {
876 	enum dfs_reg dfsdomain;
877 
878 	wlan_reg_get_dfs_region(pdev, &dfsdomain);
879 
880 	return dfsdomain;
881 }
882 
883 uint16_t utils_dfs_get_cur_rd(struct wlan_objmgr_pdev *pdev)
884 {
885 	struct cur_regdmn_info cur_regdmn;
886 
887 	wlan_reg_get_curr_regdomain(pdev, &cur_regdmn);
888 
889 	return cur_regdmn.regdmn_pair_id;
890 }
891