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