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