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