xref: /wlan-dirver/qca-wifi-host-cmn/umac/dfs/dispatcher/src/wlan_dfs_utils_api.c (revision 6ecd284e5a94a1c96e26d571dd47419ac305990d)
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];
540 	uint8_t weight_list[NUM_CHANNELS];
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 #ifndef QCA_DFS_NOL_PLATFORM_DRV_SUPPORT
674 void utils_dfs_init_nol(struct wlan_objmgr_pdev *pdev)
675 {
676 }
677 #else
678 void utils_dfs_init_nol(struct wlan_objmgr_pdev *pdev)
679 {
680 	struct wlan_dfs *dfs;
681 	struct wlan_objmgr_psoc *psoc;
682 	qdf_device_t qdf_dev;
683 	struct dfs_nol_info dfs_nolinfo;
684 	int len;
685 
686 	dfs = global_dfs_to_mlme.pdev_get_comp_private_obj(pdev);
687 	psoc = wlan_pdev_get_psoc(pdev);
688 	if (!dfs || !psoc) {
689 		dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS,
690 				"dfs %pK, psoc %pK", dfs, psoc);
691 		return;
692 	}
693 
694 	qdf_dev = psoc->soc_objmgr.qdf_dev;
695 	if (!qdf_dev->dev) {
696 		dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS,  "null device");
697 		return;
698 	}
699 
700 	qdf_mem_zero(&dfs_nolinfo, sizeof(dfs_nolinfo));
701 	len = pld_wlan_get_dfs_nol(qdf_dev->dev, (void *)&dfs_nolinfo,
702 			(uint16_t)sizeof(dfs_nolinfo));
703 	if (len > 0) {
704 		dfs_set_nol(dfs, dfs_nolinfo.dfs_nol, dfs_nolinfo.num_chans);
705 		dfs_info(dfs, WLAN_DEBUG_DFS_ALWAYS, "nol channels in pld");
706 		DFS_PRINT_NOL_LOCKED(dfs);
707 	} else {
708 		dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS,  "no nol in pld");
709 	}
710 }
711 #endif
712 qdf_export_symbol(utils_dfs_init_nol);
713 
714 #ifndef QCA_DFS_NOL_PLATFORM_DRV_SUPPORT
715 void utils_dfs_save_nol(struct wlan_objmgr_pdev *pdev)
716 {
717 }
718 #else
719 void utils_dfs_save_nol(struct wlan_objmgr_pdev *pdev)
720 {
721 	struct dfs_nol_info dfs_nolinfo;
722 	struct wlan_dfs *dfs = NULL;
723 	struct wlan_objmgr_psoc *psoc;
724 	qdf_device_t qdf_dev;
725 	int num_chans = 0;
726 
727 	dfs = global_dfs_to_mlme.pdev_get_comp_private_obj(pdev);
728 	if (!dfs) {
729 		dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS,  "null dfs");
730 		return;
731 	}
732 
733 	psoc = wlan_pdev_get_psoc(pdev);
734 	if (!psoc) {
735 		dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS,  "null psoc");
736 		return;
737 	}
738 
739 	qdf_dev = psoc->soc_objmgr.qdf_dev;
740 	if (!qdf_dev->dev) {
741 		dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS,  "null device");
742 		return;
743 	}
744 
745 	qdf_mem_zero(&dfs_nolinfo, sizeof(dfs_nolinfo));
746 	DFS_GET_NOL_LOCKED(dfs, dfs_nolinfo.dfs_nol, &num_chans);
747 	if (num_chans > 0) {
748 
749 		if (num_chans > DFS_MAX_NOL_CHANNEL)
750 			dfs_nolinfo.num_chans = DFS_MAX_NOL_CHANNEL;
751 		else
752 			dfs_nolinfo.num_chans = num_chans;
753 
754 		pld_wlan_set_dfs_nol(qdf_dev->dev, (void *)&dfs_nolinfo,
755 				(uint16_t)sizeof(dfs_nolinfo));
756 	}
757 }
758 #endif
759 qdf_export_symbol(utils_dfs_save_nol);
760 
761 void utils_dfs_print_nol_channels(struct wlan_objmgr_pdev *pdev)
762 {
763 	struct wlan_dfs *dfs = NULL;
764 
765 	dfs = global_dfs_to_mlme.pdev_get_comp_private_obj(pdev);
766 	if (!dfs) {
767 		dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS,  "null dfs");
768 		return;
769 	}
770 
771 	DFS_PRINT_NOL_LOCKED(dfs);
772 }
773 qdf_export_symbol(utils_dfs_print_nol_channels);
774 
775 void utils_dfs_clear_nol_channels(struct wlan_objmgr_pdev *pdev)
776 {
777 	struct wlan_dfs *dfs = NULL;
778 
779 	dfs = global_dfs_to_mlme.pdev_get_comp_private_obj(pdev);
780 	if (!dfs) {
781 		dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS,  "null dfs");
782 		return;
783 	}
784 
785 	/* First print list */
786 	DFS_PRINT_NOL_LOCKED(dfs);
787 
788 	/* clear local cache first */
789 	dfs_nol_timer_cleanup(dfs);
790 	dfs_nol_update(dfs);
791 
792 	/*
793 	 * update platform driver nol list with local cache which is zero,
794 	 * cleared in above step, so this will clear list in platform driver.
795 	 */
796 	utils_dfs_save_nol(pdev);
797 }
798 qdf_export_symbol(utils_dfs_clear_nol_channels);
799 
800 bool utils_is_dfs_ch(struct wlan_objmgr_pdev *pdev, uint32_t chan)
801 {
802 	return wlan_reg_is_dfs_ch(pdev, chan);
803 }
804 qdf_export_symbol(utils_is_dfs_ch);
805 
806 void utils_dfs_reg_update_nol_ch(struct wlan_objmgr_pdev *pdev,
807 		uint8_t *ch_list,
808 		uint8_t num_ch,
809 		bool nol_ch)
810 {
811 	/* TODO : Need locking?*/
812 	wlan_reg_update_nol_ch(pdev, ch_list, num_ch, nol_ch);
813 }
814 qdf_export_symbol(utils_dfs_reg_update_nol_ch);
815 
816 uint8_t utils_dfs_freq_to_chan(uint32_t freq)
817 {
818 	uint8_t chan;
819 
820 	if (freq == 0)
821 		return 0;
822 
823 	if (freq > DFS_24_GHZ_BASE_FREQ && freq < DFS_CHAN_14_FREQ)
824 		chan = ((freq - DFS_24_GHZ_BASE_FREQ) / DFS_CHAN_SPACING_5MHZ);
825 	else if (freq == DFS_CHAN_14_FREQ)
826 		chan = DFS_24_GHZ_CHANNEL_14;
827 	else if ((freq > DFS_24_GHZ_BASE_FREQ) && (freq < DFS_5_GHZ_BASE_FREQ))
828 		chan = (((freq - DFS_CHAN_15_FREQ) / DFS_CHAN_SPACING_20MHZ) +
829 			DFS_24_GHZ_CHANNEL_15);
830 	else
831 		chan = (freq - DFS_5_GHZ_BASE_FREQ) / DFS_CHAN_SPACING_5MHZ;
832 
833 	return chan;
834 }
835 qdf_export_symbol(utils_dfs_freq_to_chan);
836 
837 uint32_t utils_dfs_chan_to_freq(uint8_t chan)
838 {
839 	if (chan == 0)
840 		return 0;
841 
842 	if (chan < DFS_24_GHZ_CHANNEL_14)
843 		return DFS_24_GHZ_BASE_FREQ + (chan * DFS_CHAN_SPACING_5MHZ);
844 	else if (chan == DFS_24_GHZ_CHANNEL_14)
845 		return DFS_CHAN_14_FREQ;
846 	else if (chan < DFS_24_GHZ_CHANNEL_27)
847 		return DFS_CHAN_15_FREQ + ((chan - DFS_24_GHZ_CHANNEL_15) *
848 				DFS_CHAN_SPACING_20MHZ);
849 	else if (chan == DFS_5_GHZ_CHANNEL_170)
850 		return DFS_CHAN_170_FREQ;
851 	else
852 		return DFS_5_GHZ_BASE_FREQ + (chan * DFS_CHAN_SPACING_5MHZ);
853 }
854 qdf_export_symbol(utils_dfs_chan_to_freq);
855 
856 #ifdef QCA_MCL_DFS_SUPPORT
857 QDF_STATUS utils_dfs_mark_leaking_ch(struct wlan_objmgr_pdev *pdev,
858 	enum phy_ch_width ch_width,
859 	uint8_t temp_ch_lst_sz,
860 	uint8_t *temp_ch_lst)
861 {
862 	struct wlan_dfs *dfs = NULL;
863 
864 	dfs = global_dfs_to_mlme.pdev_get_comp_private_obj(pdev);
865 	if (!dfs) {
866 		dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS,  "null dfs");
867 		return  QDF_STATUS_E_FAILURE;
868 	}
869 
870 	return dfs_mark_leaking_ch(dfs, ch_width, temp_ch_lst_sz, temp_ch_lst);
871 }
872 qdf_export_symbol(utils_dfs_mark_leaking_ch);
873 #endif
874 
875 int utils_get_dfsdomain(struct wlan_objmgr_pdev *pdev)
876 {
877 	enum dfs_reg dfsdomain;
878 
879 	wlan_reg_get_dfs_region(pdev, &dfsdomain);
880 
881 	return dfsdomain;
882 }
883 
884 uint16_t utils_dfs_get_cur_rd(struct wlan_objmgr_pdev *pdev)
885 {
886 	struct cur_regdmn_info cur_regdmn;
887 
888 	wlan_reg_get_curr_regdomain(pdev, &cur_regdmn);
889 
890 	return cur_regdmn.regdmn_pair_id;
891 }
892