xref: /wlan-dirver/qca-wifi-host-cmn/umac/dfs/dispatcher/src/wlan_dfs_utils_api.c (revision 302a1d9701784af5f4797b1a9fe07ae820b51907)
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_is_precac_done(struct wlan_objmgr_pdev *pdev,
163 		bool *is_precac_done)
164 {
165 	struct wlan_dfs *dfs;
166 
167 	dfs = global_dfs_to_mlme.pdev_get_comp_private_obj(pdev);
168 	if (!dfs)
169 		return  QDF_STATUS_E_FAILURE;
170 
171 	*is_precac_done = dfs_is_precac_done(dfs, dfs->dfs_curchan);
172 
173 	return QDF_STATUS_SUCCESS;
174 }
175 qdf_export_symbol(utils_dfs_is_precac_done);
176 
177 #ifdef QCA_SUPPORT_ETSI_PRECAC_DFS
178 QDF_STATUS utils_dfs_is_etsi_precac_done(struct wlan_objmgr_pdev *pdev,
179 					 bool *is_etsi_precac_done)
180 {
181 	struct wlan_dfs *dfs;
182 
183 	dfs = global_dfs_to_mlme.pdev_get_comp_private_obj(pdev);
184 	if (!dfs)
185 		return  QDF_STATUS_E_FAILURE;
186 
187 	*is_etsi_precac_done = dfs_is_etsi_precac_done(dfs);
188 
189 	return QDF_STATUS_SUCCESS;
190 }
191 
192 qdf_export_symbol(utils_dfs_is_etsi_precac_done);
193 #endif
194 
195 QDF_STATUS utils_dfs_cancel_cac_timer(struct wlan_objmgr_pdev *pdev)
196 {
197 	struct wlan_dfs *dfs;
198 
199 	dfs = global_dfs_to_mlme.pdev_get_comp_private_obj(pdev);
200 	if (!dfs)
201 		return  QDF_STATUS_E_FAILURE;
202 
203 	dfs_cancel_cac_timer(dfs);
204 
205 	return QDF_STATUS_SUCCESS;
206 }
207 qdf_export_symbol(utils_dfs_cancel_cac_timer);
208 
209 QDF_STATUS utils_dfs_start_cac_timer(struct wlan_objmgr_pdev *pdev)
210 {
211 	struct wlan_dfs *dfs;
212 
213 	dfs = global_dfs_to_mlme.pdev_get_comp_private_obj(pdev);
214 	if (!dfs)
215 		return  QDF_STATUS_E_FAILURE;
216 
217 	dfs_start_cac_timer(dfs);
218 
219 	return QDF_STATUS_SUCCESS;
220 }
221 qdf_export_symbol(utils_dfs_start_cac_timer);
222 
223 QDF_STATUS utils_dfs_cac_stop(struct wlan_objmgr_pdev *pdev)
224 {
225 	struct wlan_dfs *dfs;
226 
227 	dfs = global_dfs_to_mlme.pdev_get_comp_private_obj(pdev);
228 	if (!dfs)
229 		return  QDF_STATUS_E_FAILURE;
230 
231 	dfs_cac_stop(dfs);
232 	return  QDF_STATUS_SUCCESS;
233 }
234 qdf_export_symbol(utils_dfs_cac_stop);
235 
236 QDF_STATUS utils_dfs_stacac_stop(struct wlan_objmgr_pdev *pdev)
237 {
238 	struct wlan_dfs *dfs;
239 
240 	dfs = global_dfs_to_mlme.pdev_get_comp_private_obj(pdev);
241 	if (!dfs)
242 		return  QDF_STATUS_E_FAILURE;
243 
244 	dfs_stacac_stop(dfs);
245 
246 	return QDF_STATUS_SUCCESS;
247 }
248 qdf_export_symbol(utils_dfs_stacac_stop);
249 
250 QDF_STATUS utils_dfs_get_usenol(struct wlan_objmgr_pdev *pdev, uint16_t *usenol)
251 {
252 	struct wlan_dfs *dfs;
253 
254 	dfs = global_dfs_to_mlme.pdev_get_comp_private_obj(pdev);
255 	if (!dfs)
256 		return  QDF_STATUS_E_FAILURE;
257 
258 	*usenol = dfs_get_use_nol(dfs);
259 
260 	return QDF_STATUS_SUCCESS;
261 }
262 qdf_export_symbol(utils_dfs_get_usenol);
263 
264 QDF_STATUS utils_dfs_radar_disable(struct wlan_objmgr_pdev *pdev)
265 {
266 	struct wlan_dfs *dfs;
267 
268 	dfs = global_dfs_to_mlme.pdev_get_comp_private_obj(pdev);
269 	if (!dfs)
270 		return  QDF_STATUS_E_FAILURE;
271 
272 	dfs_radar_disable(dfs);
273 
274 	return QDF_STATUS_SUCCESS;
275 }
276 qdf_export_symbol(utils_dfs_radar_disable);
277 
278 QDF_STATUS utils_dfs_set_update_nol_flag(struct wlan_objmgr_pdev *pdev,
279 		bool val)
280 {
281 	struct wlan_dfs *dfs;
282 
283 	dfs = global_dfs_to_mlme.pdev_get_comp_private_obj(pdev);
284 	if (!dfs)
285 		return  QDF_STATUS_E_FAILURE;
286 
287 	dfs_set_update_nol_flag(dfs, val);
288 
289 	return QDF_STATUS_SUCCESS;
290 }
291 qdf_export_symbol(utils_dfs_set_update_nol_flag);
292 
293 QDF_STATUS utils_dfs_get_update_nol_flag(struct wlan_objmgr_pdev *pdev,
294 		bool *nol_flag)
295 {
296 	struct wlan_dfs *dfs;
297 
298 	dfs = global_dfs_to_mlme.pdev_get_comp_private_obj(pdev);
299 	if (!dfs)
300 		return  QDF_STATUS_E_FAILURE;
301 
302 	*nol_flag = dfs_get_update_nol_flag(dfs);
303 
304 	return QDF_STATUS_SUCCESS;
305 }
306 qdf_export_symbol(utils_dfs_get_update_nol_flag);
307 
308 QDF_STATUS utils_dfs_get_dfs_use_nol(struct wlan_objmgr_pdev *pdev,
309 		int *dfs_use_nol)
310 {
311 	struct wlan_dfs *dfs;
312 
313 	dfs = global_dfs_to_mlme.pdev_get_comp_private_obj(pdev);
314 	if (!dfs)
315 		return  QDF_STATUS_E_FAILURE;
316 
317 	*dfs_use_nol = dfs_get_use_nol(dfs);
318 
319 	return QDF_STATUS_SUCCESS;
320 }
321 qdf_export_symbol(utils_dfs_get_dfs_use_nol);
322 
323 QDF_STATUS utils_dfs_get_nol_timeout(struct wlan_objmgr_pdev *pdev,
324 		int *dfs_nol_timeout)
325 {
326 	struct wlan_dfs *dfs;
327 
328 	dfs = global_dfs_to_mlme.pdev_get_comp_private_obj(pdev);
329 	if (!dfs)
330 		return  QDF_STATUS_E_FAILURE;
331 
332 	*dfs_nol_timeout = dfs_get_nol_timeout(dfs);
333 
334 	return QDF_STATUS_SUCCESS;
335 }
336 qdf_export_symbol(utils_dfs_get_nol_timeout);
337 
338 QDF_STATUS utils_dfs_nol_addchan(struct wlan_objmgr_pdev *pdev,
339 		uint16_t freq,
340 		uint32_t dfs_nol_timeout)
341 {
342 	struct wlan_dfs *dfs;
343 
344 	dfs = global_dfs_to_mlme.pdev_get_comp_private_obj(pdev);
345 	if (!dfs)
346 		return  QDF_STATUS_E_FAILURE;
347 
348 	DFS_NOL_ADD_CHAN_LOCKED(dfs, freq, dfs_nol_timeout);
349 
350 	return QDF_STATUS_SUCCESS;
351 }
352 qdf_export_symbol(utils_dfs_nol_addchan);
353 
354 QDF_STATUS utils_dfs_nol_update(struct wlan_objmgr_pdev *pdev)
355 {
356 	struct wlan_dfs *dfs;
357 
358 	dfs = global_dfs_to_mlme.pdev_get_comp_private_obj(pdev);
359 	if (!dfs)
360 		return  QDF_STATUS_E_FAILURE;
361 
362 	dfs_nol_update(dfs);
363 
364 	return QDF_STATUS_SUCCESS;
365 }
366 qdf_export_symbol(utils_dfs_nol_update);
367 
368 QDF_STATUS utils_dfs_second_segment_radar_disable(struct wlan_objmgr_pdev *pdev)
369 {
370 	struct wlan_dfs *dfs;
371 
372 	dfs = global_dfs_to_mlme.pdev_get_comp_private_obj(pdev);
373 	if (!dfs)
374 		return  QDF_STATUS_E_FAILURE;
375 
376 	dfs_second_segment_radar_disable(dfs);
377 
378 	return QDF_STATUS_SUCCESS;
379 }
380 
381 QDF_STATUS utils_dfs_is_ignore_dfs(struct wlan_objmgr_pdev *pdev,
382 		bool *ignore_dfs)
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 	*ignore_dfs = dfs->dfs_ignore_dfs;
391 
392 	return QDF_STATUS_SUCCESS;
393 }
394 qdf_export_symbol(utils_dfs_is_ignore_dfs);
395 
396 QDF_STATUS utils_dfs_is_cac_valid(struct wlan_objmgr_pdev *pdev,
397 		bool *is_cac_valid)
398 {
399 	struct wlan_dfs *dfs;
400 
401 	dfs = global_dfs_to_mlme.pdev_get_comp_private_obj(pdev);
402 	if (!dfs)
403 		return  QDF_STATUS_E_FAILURE;
404 
405 	*is_cac_valid = dfs->dfs_cac_valid;
406 
407 	return QDF_STATUS_SUCCESS;
408 }
409 qdf_export_symbol(utils_dfs_is_cac_valid);
410 
411 QDF_STATUS utils_dfs_is_ignore_cac(struct wlan_objmgr_pdev *pdev,
412 		bool *ignore_cac)
413 {
414 	struct wlan_dfs *dfs;
415 
416 	dfs = global_dfs_to_mlme.pdev_get_comp_private_obj(pdev);
417 	if (!dfs)
418 		return  QDF_STATUS_E_FAILURE;
419 
420 	*ignore_cac = dfs->dfs_ignore_cac;
421 
422 	/*
423 	 * This is needed as, if after channel bandwidth reduction, channel
424 	 * change occurs using dothchanswitch or chan commands, resetting.
425 	 * dfs->dfs_ignore_cac will make sure we not skip CAC on the new channel
426 	 */
427 
428 	if (dfs->dfs_bw_reduced)
429 		dfs->dfs_ignore_cac = 0;
430 
431 	return QDF_STATUS_SUCCESS;
432 }
433 qdf_export_symbol(utils_dfs_is_ignore_cac);
434 
435 QDF_STATUS utils_dfs_set_cac_timer_running(struct wlan_objmgr_pdev *pdev,
436 		int val)
437 {
438 	struct wlan_dfs *dfs;
439 
440 	dfs = global_dfs_to_mlme.pdev_get_comp_private_obj(pdev);
441 	if (!dfs)
442 		return  QDF_STATUS_E_FAILURE;
443 
444 	dfs->dfs_cac_timer_running = val;
445 
446 	return QDF_STATUS_SUCCESS;
447 }
448 qdf_export_symbol(utils_dfs_set_cac_timer_running);
449 
450 QDF_STATUS utils_dfs_get_nol_chfreq_and_chwidth(struct wlan_objmgr_pdev *pdev,
451 		void *nollist,
452 		uint32_t *nol_chfreq,
453 		uint32_t *nol_chwidth,
454 		int index)
455 {
456 	struct wlan_dfs *dfs;
457 
458 	dfs = global_dfs_to_mlme.pdev_get_comp_private_obj(pdev);
459 	if (!dfs)
460 		return  QDF_STATUS_E_FAILURE;
461 
462 	dfs_get_nol_chfreq_and_chwidth(nollist, nol_chfreq, nol_chwidth, index);
463 
464 	return QDF_STATUS_SUCCESS;
465 }
466 qdf_export_symbol(utils_dfs_get_nol_chfreq_and_chwidth);
467 
468 QDF_STATUS utils_dfs_update_cur_chan_flags(struct wlan_objmgr_pdev *pdev,
469 		uint64_t flags,
470 		uint16_t flagext)
471 {
472 	struct wlan_dfs *dfs;
473 
474 	dfs = global_dfs_to_mlme.pdev_get_comp_private_obj(pdev);
475 	if (!dfs)
476 		return  QDF_STATUS_E_FAILURE;
477 
478 	dfs_update_cur_chan_flags(dfs, flags, flagext);
479 
480 	return QDF_STATUS_SUCCESS;
481 }
482 
483 static void utils_dfs_get_max_phy_mode(struct wlan_objmgr_pdev *pdev,
484 		uint32_t *phy_mode)
485 {
486 	return;
487 }
488 
489 static void utils_dfs_get_max_sup_width(struct wlan_objmgr_pdev *pdev,
490 		uint8_t *ch_width)
491 {
492 	return;
493 }
494 
495 /**
496  * utils_dfs_get_chan_list() - Get channel list from regdb based on current
497  *                             operating channel.
498  * @pdev: Pointer to DFS pdev object.
499  * @chan_list: Pointer to current channel list
500  * @num_chan: number of channels in the current channel list.
501  */
502 #ifndef QCA_DFS_USE_POLICY_MANAGER
503 static void utils_dfs_get_chan_list(struct wlan_objmgr_pdev *pdev,
504 	struct dfs_channel *chan_list, uint32_t *num_chan)
505 {
506 	int i = 0, j = 0;
507 	enum channel_state state;
508 	struct regulatory_channel *cur_chan_list;
509 	struct wlan_dfs *dfs;
510 
511 	dfs = global_dfs_to_mlme.pdev_get_comp_private_obj(pdev);
512 	if (!dfs)
513 		return;
514 
515 	cur_chan_list = qdf_mem_malloc(NUM_CHANNELS *
516 			sizeof(struct regulatory_channel));
517 	if (!cur_chan_list) {
518 		dfs_alert(dfs, WLAN_DEBUG_DFS_ALWAYS, "fail to alloc");
519 		*num_chan = 0;
520 		return;
521 	}
522 
523 	if (wlan_reg_get_current_chan_list(
524 			pdev, cur_chan_list) != QDF_STATUS_SUCCESS) {
525 		*num_chan = 0;
526 		dfs_alert(dfs, WLAN_DEBUG_DFS_ALWAYS,
527 				"failed to get curr channel list");
528 		return;
529 	}
530 
531 	for (i = 0; i < NUM_CHANNELS; i++) {
532 		state = cur_chan_list[i].state;
533 		if (state == CHANNEL_STATE_DFS ||
534 				state == CHANNEL_STATE_ENABLE) {
535 			chan_list[j].dfs_ch_ieee = cur_chan_list[i].chan_num;
536 			chan_list[j].dfs_ch_freq = cur_chan_list[i].center_freq;
537 			if (state == CHANNEL_STATE_DFS)
538 				chan_list[j].dfs_ch_flagext =
539 					WLAN_CHAN_DFS;
540 			j++;
541 		}
542 	}
543 	*num_chan = j;
544 	qdf_mem_free(cur_chan_list);
545 
546 	return;
547 }
548 
549 /**
550  * utils_dfs_get_channel_list() - Get channel list from regdb component based
551  * on current channel list.
552  * @pdev: Pointer to pdev structure.
553  * @chan_list: Pointer to regdb channel list.
554  * @num_chan: number of channels.
555  *
556  * Get regdb channel list based on dfs current channel.
557  * ex: When  AP is operating in 5GHz channel, filter 2.4GHz and 4.9GHZ channels
558  * so that the random channel function does not select either 2.4GHz or 4.9GHz
559  * channel.
560  */
561 static void utils_dfs_get_channel_list(struct wlan_objmgr_pdev *pdev,
562 	struct dfs_channel *chan_list, uint32_t *num_chan)
563 {
564 	struct dfs_channel *tmp_chan_list = NULL;
565 	struct wlan_dfs *dfs;
566 	bool is_curchan_5g;
567 	bool is_curchan_24g;
568 	bool is_curchan_49g;
569 	uint32_t chan_num;
570 	uint32_t center_freq;
571 	uint16_t flagext;
572 	int i, j = 0;
573 
574 	dfs = global_dfs_to_mlme.pdev_get_comp_private_obj(pdev);
575 	if (!dfs) {
576 		dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "null dfs");
577 		return;
578 	}
579 
580 	tmp_chan_list = qdf_mem_malloc(*num_chan * sizeof(*tmp_chan_list));
581 	if (!tmp_chan_list) {
582 		dfs_alert(dfs, WLAN_DEBUG_DFS_ALWAYS, "mem alloc failed");
583 		return;
584 	}
585 
586 	utils_dfs_get_chan_list(pdev, tmp_chan_list, num_chan);
587 
588 	chan_num = dfs->dfs_curchan->dfs_ch_ieee;
589 	center_freq = dfs->dfs_curchan->dfs_ch_freq;
590 	is_curchan_5g = WLAN_REG_IS_5GHZ_CH(chan_num);
591 	is_curchan_24g = WLAN_REG_IS_24GHZ_CH(chan_num);
592 	is_curchan_49g = WLAN_REG_IS_49GHZ_FREQ(center_freq);
593 
594 	for (i = 0; i < *num_chan; i++) {
595 		chan_num = tmp_chan_list[i].dfs_ch_ieee;
596 		center_freq = tmp_chan_list[i].dfs_ch_freq;
597 		flagext = tmp_chan_list[i].dfs_ch_flagext;
598 
599 		if (!dfs_mlme_check_allowed_prim_chanlist(pdev, chan_num))
600 			continue;
601 
602 		if ((is_curchan_5g) && WLAN_REG_IS_5GHZ_CH(chan_num)) {
603 			chan_list[j].dfs_ch_ieee = chan_num;
604 			chan_list[j].dfs_ch_freq = center_freq;
605 			chan_list[j].dfs_ch_flagext = flagext;
606 			j++;
607 		} else if ((is_curchan_24g) &&
608 				WLAN_REG_IS_24GHZ_CH(chan_num)) {
609 			chan_list[j].dfs_ch_ieee = chan_num;
610 			chan_list[j].dfs_ch_freq = center_freq;
611 			j++;
612 		} else if ((is_curchan_49g) &&
613 				WLAN_REG_IS_49GHZ_FREQ(center_freq)) {
614 			chan_list[j].dfs_ch_ieee = chan_num;
615 			chan_list[j].dfs_ch_freq = center_freq;
616 			j++;
617 		}
618 	}
619 
620 	*num_chan = j;
621 
622 	qdf_mem_free(tmp_chan_list);
623 }
624 
625 #else
626 
627 static void utils_dfs_get_chan_list(struct wlan_objmgr_pdev *pdev,
628 	struct dfs_channel *chan_list, uint32_t *num_chan)
629 {
630 	uint8_t pcl_ch[QDF_MAX_NUM_CHAN] = {0};
631 	uint8_t weight_list[QDF_MAX_NUM_CHAN] = {0};
632 	uint32_t len;
633 	uint32_t weight_len;
634 	int i;
635 	struct wlan_objmgr_psoc *psoc;
636 	uint32_t conn_count = 0;
637 
638 	psoc = wlan_pdev_get_psoc(pdev);
639 	if (!psoc) {
640 		*num_chan = 0;
641 		dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS,  "null psoc");
642 		return;
643 	}
644 
645 	len = QDF_ARRAY_SIZE(pcl_ch);
646 	weight_len = QDF_ARRAY_SIZE(weight_list);
647 	conn_count = policy_mgr_mode_specific_connection_count(
648 			psoc, PM_SAP_MODE, NULL);
649 	if (0 == conn_count)
650 		policy_mgr_get_pcl(psoc, PM_SAP_MODE, pcl_ch,
651 				&len, weight_list, weight_len);
652 	else
653 		policy_mgr_get_pcl_for_existing_conn(psoc, PM_SAP_MODE, pcl_ch,
654 				&len, weight_list, weight_len, true);
655 
656 	if (*num_chan < len) {
657 		dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS,
658 				"Invalid len src=%d, dst=%d",
659 				*num_chan, len);
660 		*num_chan = 0;
661 		return;
662 	}
663 
664 	for (i = 0; i < len; i++) {
665 		chan_list[i].dfs_ch_ieee  = pcl_ch[i];
666 		chan_list[i].dfs_ch_freq  =
667 			wlan_reg_chan_to_freq(pdev, pcl_ch[i]);
668 	}
669 	*num_chan = i;
670 	dfs_info(NULL, WLAN_DEBUG_DFS_ALWAYS, "num channels %d", i);
671 }
672 
673 /**
674  * utils_dfs_get_channel_list() - Wrapper function to get channel list from
675  * regdb component.
676  * @pdev: Pointer to pdev structure.
677  * @chan_list: Pointer to regdb channel list.
678  * @num_chan: number of channels.
679  */
680 static void utils_dfs_get_channel_list(struct wlan_objmgr_pdev *pdev,
681 	struct dfs_channel *chan_list, uint32_t *num_chan)
682 {
683 	utils_dfs_get_chan_list(pdev, chan_list, num_chan);
684 }
685 #endif
686 
687 QDF_STATUS utils_dfs_get_random_channel(
688 	struct wlan_objmgr_pdev *pdev,
689 	uint16_t flags,
690 	struct ch_params *ch_params,
691 	uint32_t *hw_mode,
692 	uint8_t *target_chan,
693 	struct dfs_acs_info *acs_info)
694 {
695 	uint32_t dfs_reg;
696 	uint32_t num_chan = NUM_CHANNELS;
697 	struct wlan_dfs *dfs = NULL;
698 	struct wlan_objmgr_psoc *psoc;
699 	struct dfs_channel *chan_list = NULL;
700 	struct dfs_channel cur_chan;
701 	QDF_STATUS status = QDF_STATUS_E_FAILURE;
702 
703 	*target_chan = 0;
704 	psoc = wlan_pdev_get_psoc(pdev);
705 	if (!psoc) {
706 		dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS,  "null psoc");
707 		goto random_chan_error;
708 	}
709 
710 	dfs = global_dfs_to_mlme.pdev_get_comp_private_obj(pdev);
711 	if (!dfs) {
712 		dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS,  "null dfs");
713 		goto random_chan_error;
714 	}
715 
716 	wlan_reg_get_dfs_region(pdev, &dfs_reg);
717 	chan_list = qdf_mem_malloc(num_chan * sizeof(*chan_list));
718 	if (!chan_list) {
719 		dfs_alert(dfs, WLAN_DEBUG_DFS_ALWAYS, "mem alloc failed");
720 		goto random_chan_error;
721 	}
722 
723 	utils_dfs_get_channel_list(pdev, chan_list, &num_chan);
724 	if (!num_chan) {
725 		dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS,  "zero channels");
726 		goto random_chan_error;
727 	}
728 
729 	cur_chan.dfs_ch_vhtop_ch_freq_seg1 = ch_params->center_freq_seg0;
730 	cur_chan.dfs_ch_vhtop_ch_freq_seg2 = ch_params->center_freq_seg1;
731 
732 	if (!ch_params->ch_width)
733 		utils_dfs_get_max_sup_width(pdev,
734 				(uint8_t *)&ch_params->ch_width);
735 
736 	*target_chan = dfs_prepare_random_channel(dfs, chan_list,
737 		num_chan, flags, (uint8_t *)&ch_params->ch_width,
738 		&cur_chan, (uint8_t)dfs_reg, acs_info);
739 
740 	ch_params->center_freq_seg0 = cur_chan.dfs_ch_vhtop_ch_freq_seg1;
741 	ch_params->center_freq_seg1 = cur_chan.dfs_ch_vhtop_ch_freq_seg2;
742 	dfs_info(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN,
743 			"input width=%d", ch_params->ch_width);
744 
745 	if (*target_chan) {
746 		wlan_reg_set_channel_params(pdev,
747 				*target_chan, 0, ch_params);
748 		utils_dfs_get_max_phy_mode(pdev, hw_mode);
749 		status = QDF_STATUS_SUCCESS;
750 	}
751 
752 	dfs_info(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN,
753 			"ch=%d, seg0=%d, seg1=%d, width=%d",
754 			*target_chan, ch_params->center_freq_seg0,
755 			ch_params->center_freq_seg1, ch_params->ch_width);
756 
757 random_chan_error:
758 	qdf_mem_free(chan_list);
759 
760 	return status;
761 }
762 qdf_export_symbol(utils_dfs_get_random_channel);
763 
764 QDF_STATUS utils_dfs_bw_reduced_channel(
765 	struct wlan_objmgr_pdev *pdev,
766 	uint16_t flags,
767 	struct ch_params *ch_params,
768 	uint32_t *hw_mode,
769 	uint8_t *target_chan)
770 {
771 	struct wlan_dfs *dfs = NULL;
772 	struct wlan_objmgr_psoc *psoc;
773 	enum channel_state ch_state;
774 	QDF_STATUS status = QDF_STATUS_E_FAILURE;
775 
776 	*target_chan = 0;
777 	psoc = wlan_pdev_get_psoc(pdev);
778 	if (!psoc) {
779 		dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS,  "null psoc");
780 		return status;
781 	}
782 
783 	dfs = global_dfs_to_mlme.pdev_get_comp_private_obj(pdev);
784 	if (!dfs) {
785 		dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS,  "null dfs");
786 		return status;
787 	}
788 
789 	ch_state = reg_get_channel_state(pdev, dfs->dfs_curchan->dfs_ch_ieee);
790 
791 	if (ch_state == CHANNEL_STATE_DFS ||
792 	    ch_state == CHANNEL_STATE_ENABLE) {
793 		ch_params->center_freq_seg0 =
794 			dfs->dfs_curchan->dfs_ch_vhtop_ch_freq_seg1;
795 		ch_params->center_freq_seg1 =
796 			dfs->dfs_curchan->dfs_ch_vhtop_ch_freq_seg2;
797 		/*If bandwidth reduction is applied,
798 		 * dfs_ignore_cac ensures we skip CAC.
799 		 */
800 		dfs->dfs_ignore_cac = 1;
801 		dfs->dfs_bw_reduced = 1;
802 		wlan_reg_set_channel_params(pdev,
803 					    dfs->dfs_curchan->dfs_ch_ieee,
804 					    0, ch_params);
805 
806 		*target_chan = dfs->dfs_curchan->dfs_ch_ieee;
807 		utils_dfs_get_max_phy_mode(pdev, hw_mode);
808 
809 		return QDF_STATUS_SUCCESS;
810 	}
811 
812 	return status;
813 }
814 
815 #ifdef QCA_DFS_NOL_PLATFORM_DRV_SUPPORT
816 void utils_dfs_init_nol(struct wlan_objmgr_pdev *pdev)
817 {
818 	struct wlan_dfs *dfs;
819 	struct wlan_objmgr_psoc *psoc;
820 	qdf_device_t qdf_dev;
821 	struct dfs_nol_info dfs_nolinfo;
822 	int len;
823 
824 	dfs = global_dfs_to_mlme.pdev_get_comp_private_obj(pdev);
825 	psoc = wlan_pdev_get_psoc(pdev);
826 	if (!dfs || !psoc) {
827 		dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS,
828 				"dfs %pK, psoc %pK", dfs, psoc);
829 		return;
830 	}
831 
832 	qdf_dev = psoc->soc_objmgr.qdf_dev;
833 	if (!qdf_dev->dev) {
834 		dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS,  "null device");
835 		return;
836 	}
837 
838 	qdf_mem_zero(&dfs_nolinfo, sizeof(dfs_nolinfo));
839 	len = pld_wlan_get_dfs_nol(qdf_dev->dev, (void *)&dfs_nolinfo,
840 			(uint16_t)sizeof(dfs_nolinfo));
841 	if (len > 0) {
842 		dfs_set_nol(dfs, dfs_nolinfo.dfs_nol, dfs_nolinfo.num_chans);
843 		dfs_info(dfs, WLAN_DEBUG_DFS_ALWAYS, "nol channels in pld");
844 		DFS_PRINT_NOL_LOCKED(dfs);
845 	} else {
846 		dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS,  "no nol in pld");
847 	}
848 }
849 #endif
850 qdf_export_symbol(utils_dfs_init_nol);
851 
852 #ifndef QCA_DFS_NOL_PLATFORM_DRV_SUPPORT
853 void utils_dfs_save_nol(struct wlan_objmgr_pdev *pdev)
854 {
855 }
856 #else
857 void utils_dfs_save_nol(struct wlan_objmgr_pdev *pdev)
858 {
859 	struct dfs_nol_info dfs_nolinfo;
860 	struct wlan_dfs *dfs = NULL;
861 	struct wlan_objmgr_psoc *psoc;
862 	qdf_device_t qdf_dev;
863 	int num_chans = 0;
864 
865 	dfs = global_dfs_to_mlme.pdev_get_comp_private_obj(pdev);
866 	if (!dfs) {
867 		dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS,  "null dfs");
868 		return;
869 	}
870 
871 	psoc = wlan_pdev_get_psoc(pdev);
872 	if (!psoc) {
873 		dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS,  "null psoc");
874 		return;
875 	}
876 
877 	qdf_dev = psoc->soc_objmgr.qdf_dev;
878 	if (!qdf_dev->dev) {
879 		dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS,  "null device");
880 		return;
881 	}
882 
883 	qdf_mem_zero(&dfs_nolinfo, sizeof(dfs_nolinfo));
884 	DFS_GET_NOL_LOCKED(dfs, dfs_nolinfo.dfs_nol, &num_chans);
885 	if (num_chans > 0) {
886 
887 		if (num_chans > DFS_MAX_NOL_CHANNEL)
888 			dfs_nolinfo.num_chans = DFS_MAX_NOL_CHANNEL;
889 		else
890 			dfs_nolinfo.num_chans = num_chans;
891 
892 		pld_wlan_set_dfs_nol(qdf_dev->dev, (void *)&dfs_nolinfo,
893 				(uint16_t)sizeof(dfs_nolinfo));
894 	}
895 }
896 #endif
897 qdf_export_symbol(utils_dfs_save_nol);
898 
899 void utils_dfs_print_nol_channels(struct wlan_objmgr_pdev *pdev)
900 {
901 	struct wlan_dfs *dfs = NULL;
902 
903 	dfs = global_dfs_to_mlme.pdev_get_comp_private_obj(pdev);
904 	if (!dfs) {
905 		dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS,  "null dfs");
906 		return;
907 	}
908 
909 	DFS_PRINT_NOL_LOCKED(dfs);
910 }
911 qdf_export_symbol(utils_dfs_print_nol_channels);
912 
913 void utils_dfs_clear_nol_channels(struct wlan_objmgr_pdev *pdev)
914 {
915 	struct wlan_dfs *dfs = NULL;
916 
917 	dfs = global_dfs_to_mlme.pdev_get_comp_private_obj(pdev);
918 	if (!dfs) {
919 		dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS,  "null dfs");
920 		return;
921 	}
922 
923 	/* First print list */
924 	DFS_PRINT_NOL_LOCKED(dfs);
925 
926 	/* clear local cache first */
927 	dfs_nol_timer_cleanup(dfs);
928 	dfs_nol_update(dfs);
929 
930 	/*
931 	 * update platform driver nol list with local cache which is zero,
932 	 * cleared in above step, so this will clear list in platform driver.
933 	 */
934 	utils_dfs_save_nol(pdev);
935 }
936 qdf_export_symbol(utils_dfs_clear_nol_channels);
937 
938 void utils_dfs_reg_update_nol_ch(struct wlan_objmgr_pdev *pdev,
939 		uint8_t *ch_list,
940 		uint8_t num_ch,
941 		bool nol_ch)
942 {
943 	/* TODO : Need locking?*/
944 	wlan_reg_update_nol_ch(pdev, ch_list, num_ch, nol_ch);
945 }
946 qdf_export_symbol(utils_dfs_reg_update_nol_ch);
947 
948 uint8_t utils_dfs_freq_to_chan(uint32_t freq)
949 {
950 	uint8_t chan;
951 
952 	if (freq == 0)
953 		return 0;
954 
955 	if (freq > DFS_24_GHZ_BASE_FREQ && freq < DFS_CHAN_14_FREQ)
956 		chan = ((freq - DFS_24_GHZ_BASE_FREQ) / DFS_CHAN_SPACING_5MHZ);
957 	else if (freq == DFS_CHAN_14_FREQ)
958 		chan = DFS_24_GHZ_CHANNEL_14;
959 	else if ((freq > DFS_24_GHZ_BASE_FREQ) && (freq < DFS_5_GHZ_BASE_FREQ))
960 		chan = (((freq - DFS_CHAN_15_FREQ) / DFS_CHAN_SPACING_20MHZ) +
961 			DFS_24_GHZ_CHANNEL_15);
962 	else
963 		chan = (freq - DFS_5_GHZ_BASE_FREQ) / DFS_CHAN_SPACING_5MHZ;
964 
965 	return chan;
966 }
967 qdf_export_symbol(utils_dfs_freq_to_chan);
968 
969 uint32_t utils_dfs_chan_to_freq(uint8_t chan)
970 {
971 	if (chan == 0)
972 		return 0;
973 
974 	if (chan < DFS_24_GHZ_CHANNEL_14)
975 		return DFS_24_GHZ_BASE_FREQ + (chan * DFS_CHAN_SPACING_5MHZ);
976 	else if (chan == DFS_24_GHZ_CHANNEL_14)
977 		return DFS_CHAN_14_FREQ;
978 	else if (chan < DFS_24_GHZ_CHANNEL_27)
979 		return DFS_CHAN_15_FREQ + ((chan - DFS_24_GHZ_CHANNEL_15) *
980 				DFS_CHAN_SPACING_20MHZ);
981 	else if (chan == DFS_5_GHZ_CHANNEL_170)
982 		return DFS_CHAN_170_FREQ;
983 	else
984 		return DFS_5_GHZ_BASE_FREQ + (chan * DFS_CHAN_SPACING_5MHZ);
985 }
986 qdf_export_symbol(utils_dfs_chan_to_freq);
987 
988 #ifdef QCA_MCL_DFS_SUPPORT
989 QDF_STATUS utils_dfs_mark_leaking_ch(struct wlan_objmgr_pdev *pdev,
990 	enum phy_ch_width ch_width,
991 	uint8_t temp_ch_lst_sz,
992 	uint8_t *temp_ch_lst)
993 {
994 	struct wlan_dfs *dfs = NULL;
995 
996 	dfs = global_dfs_to_mlme.pdev_get_comp_private_obj(pdev);
997 	if (!dfs) {
998 		dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS,  "null dfs");
999 		return  QDF_STATUS_E_FAILURE;
1000 	}
1001 
1002 	return dfs_mark_leaking_ch(dfs, ch_width, temp_ch_lst_sz, temp_ch_lst);
1003 }
1004 qdf_export_symbol(utils_dfs_mark_leaking_ch);
1005 #endif
1006 
1007 int utils_get_dfsdomain(struct wlan_objmgr_pdev *pdev)
1008 {
1009 	enum dfs_reg dfsdomain;
1010 
1011 	wlan_reg_get_dfs_region(pdev, &dfsdomain);
1012 
1013 	return dfsdomain;
1014 }
1015 
1016 uint16_t utils_dfs_get_cur_rd(struct wlan_objmgr_pdev *pdev)
1017 {
1018 	struct cur_regdmn_info cur_regdmn;
1019 
1020 	wlan_reg_get_curr_regdomain(pdev, &cur_regdmn);
1021 
1022 	return cur_regdmn.regdmn_pair_id;
1023 }
1024 
1025 #if defined(WLAN_DFS_PARTIAL_OFFLOAD) && defined(HOST_DFS_SPOOF_TEST)
1026 QDF_STATUS utils_dfs_is_spoof_check_failed(struct wlan_objmgr_pdev *pdev,
1027 					   bool *is_spoof_check_failed)
1028 {
1029 	struct wlan_dfs *dfs;
1030 
1031 	if (!tgt_dfs_is_pdev_5ghz(pdev))
1032 		return QDF_STATUS_SUCCESS;
1033 
1034 	dfs = global_dfs_to_mlme.pdev_get_comp_private_obj(pdev);
1035 	if (!dfs) {
1036 		dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS,  "dfs is null");
1037 		return  QDF_STATUS_E_FAILURE;
1038 	}
1039 
1040 	*is_spoof_check_failed = dfs->dfs_spoof_check_failed;
1041 
1042 	return QDF_STATUS_SUCCESS;
1043 }
1044 
1045 qdf_export_symbol(utils_dfs_is_spoof_check_failed);
1046 #endif
1047