xref: /wlan-dirver/qca-wifi-host-cmn/umac/dfs/core/src/misc/dfs_cac.c (revision 2888b71da71bce103343119fa1b31f4a0cee07c8)
1 /*
2  * Copyright (c) 2016-2021 The Linux Foundation. All rights reserved.
3  * Copyright (c) 2007-2008 Sam Leffler, Errno Consulting
4  * All rights reserved.
5  * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26  */
27 
28 /**
29  * DOC: This file has the functions related to DFS CAC.
30  */
31 
32 #include "../dfs_channel.h"
33 #include "../dfs_zero_cac.h"
34 #include <wlan_objmgr_vdev_obj.h>
35 #include "wlan_dfs_utils_api.h"
36 #include "wlan_dfs_mlme_api.h"
37 #include "../dfs_internal.h"
38 #include "../dfs_process_radar_found_ind.h"
39 
40 #define IS_CHANNEL_WEATHER_RADAR(freq) ((freq >= 5600) && (freq <= 5650))
41 #define ADJACENT_WEATHER_RADAR_CHANNEL   5580
42 #define CH100_START_FREQ                 5490
43 #define CH100                            100
44 
45 /**
46  * dfs_cac_valid_timeout() - Timeout function for dfs_cac_valid_timer
47  *                           cac_valid bit will be reset in this function.
48  */
49 static os_timer_func(dfs_cac_valid_timeout)
50 {
51 	struct wlan_dfs *dfs = NULL;
52 
53 	OS_GET_TIMER_ARG(dfs, struct wlan_dfs *);
54 	dfs->dfs_cac_valid = 0;
55 	dfs_info(dfs, WLAN_DEBUG_DFS_ALWAYS, ": Timed out!!");
56 }
57 
58 /**
59  * dfs_clear_cac_started_chan() - Clear dfs cac started channel.
60  * @dfs: Pointer to wlan_dfs structure.
61  */
62 void dfs_clear_cac_started_chan(struct wlan_dfs *dfs)
63 {
64 	qdf_mem_zero(&dfs->dfs_cac_started_chan,
65 		     sizeof(dfs->dfs_cac_started_chan));
66 }
67 
68 static void dfs_clear_nol_history_for_curchan(struct wlan_dfs *dfs)
69 {
70 	struct dfs_channel *chan = dfs->dfs_curchan;
71 	uint16_t sub_channels[MAX_20MHZ_SUBCHANS];
72 	uint8_t num_subchs;
73 
74 	num_subchs = dfs_get_bonding_channel_without_seg_info_for_freq(
75 				chan, sub_channels);
76 
77 	if (dfs->dfs_is_stadfs_enabled)
78 		if (dfs_mlme_is_opmode_sta(dfs->dfs_pdev_obj))
79 			utils_dfs_reg_update_nol_history_chan_for_freq(
80 				dfs->dfs_pdev_obj, sub_channels,
81 				num_subchs, DFS_NOL_HISTORY_RESET);
82 }
83 
84 void dfs_process_cac_completion(void *context)
85 {
86 	struct wlan_dfs *dfs = (struct wlan_dfs *)context;
87 	enum phy_ch_width ch_width = CH_WIDTH_INVALID;
88 	uint16_t primary_chan_freq = 0, sec_chan_freq = 0;
89 	struct dfs_channel *dfs_curchan;
90 
91 	dfs->dfs_cac_timer_running = 0;
92 	dfs_curchan = dfs->dfs_curchan;
93 
94 	dfs_info(dfs, WLAN_DEBUG_DFS_ALWAYS, "cac expired, chan %d cur time %d",
95 		 dfs->dfs_curchan->dfs_ch_freq,
96 		 (qdf_system_ticks_to_msecs(qdf_system_ticks()) / 1000));
97 
98 	/*
99 	 * When radar is detected during a CAC we are woken up prematurely to
100 	 * switch to a new channel. Check the channel to decide how to act.
101 	 */
102 	if (WLAN_IS_CHAN_RADAR(dfs, dfs->dfs_curchan)) {
103 		dfs_mlme_mark_dfs(dfs->dfs_pdev_obj,
104 				  dfs_curchan->dfs_ch_ieee,
105 				  dfs_curchan->dfs_ch_freq,
106 				  dfs_curchan->dfs_ch_mhz_freq_seg2,
107 				  dfs_curchan->dfs_ch_flags,
108 				  0);
109 		dfs_debug(dfs, WLAN_DEBUG_DFS,
110 			  "CAC timer on chan %u (%u MHz) stopped due to radar",
111 			  dfs_curchan->dfs_ch_ieee,
112 			  dfs_curchan->dfs_ch_freq);
113 	} else {
114 		dfs_debug(dfs, WLAN_DEBUG_DFS,
115 			  "CAC timer on channel %u (%u MHz) expired;"
116 			  "no radar detected",
117 			  dfs_curchan->dfs_ch_ieee,
118 			  dfs_curchan->dfs_ch_freq);
119 
120 		/* On CAC completion, set the bit 'cac_valid'.
121 		 * CAC will not be re-done if this bit is reset.
122 		 * The flag will be reset when dfs_cac_valid_timer
123 		 * timesout.
124 		 */
125 		if (dfs->dfs_cac_valid_time) {
126 			dfs->dfs_cac_valid = 1;
127 			qdf_timer_mod(&dfs->dfs_cac_valid_timer,
128 				      dfs->dfs_cac_valid_time * 1000);
129 		}
130 
131 		dfs_find_curchwidth_and_center_chan_for_freq(dfs,
132 							     &ch_width,
133 							     &primary_chan_freq,
134 							     &sec_chan_freq);
135 
136 		/* ETSI allows the driver to cache the CAC ( Once CAC done,
137 		 * it can be used in future).
138 		 * Therefore mark the current channel CAC done.
139 		 */
140 		if (utils_get_dfsdomain(dfs->dfs_pdev_obj) == DFS_ETSI_DOMAIN)
141 			dfs_mark_precac_done_for_freq(dfs,
142 						      primary_chan_freq,
143 						      sec_chan_freq,
144 						      ch_width);
145 	}
146 
147 	dfs_clear_cac_started_chan(dfs);
148 
149 	/* Clear NOL history for current channel on successful CAC completion */
150 	dfs_clear_nol_history_for_curchan(dfs);
151 	/* Iterate over the nodes, processing the CAC completion event. */
152 	dfs_mlme_proc_cac(dfs->dfs_pdev_obj, 0);
153 
154 	/* Send a CAC timeout, VAP up event to user space */
155 	dfs_mlme_deliver_event_up_after_cac(dfs->dfs_pdev_obj);
156 
157 	if (dfs->dfs_defer_precac_channel_change == 1) {
158 		dfs_mlme_channel_change_by_precac(dfs->dfs_pdev_obj);
159 		dfs->dfs_defer_precac_channel_change = 0;
160 	}
161 }
162 
163 /**
164  * dfs_cac_timeout() - DFS cactimeout function.
165  *
166  * Sets dfs_cac_timer_running to 0  and dfs_cac_valid_timer.
167  */
168 #ifdef CONFIG_CHAN_FREQ_API
169 static enum qdf_hrtimer_restart_status
170 dfs_cac_timeout(qdf_hrtimer_data_t *arg)
171 {
172 	struct wlan_dfs *dfs;
173 
174 	dfs = container_of(arg, struct wlan_dfs, dfs_cac_timer);
175 
176 	if (dfs_is_hw_mode_switch_in_progress(dfs))
177 		dfs->dfs_defer_params.is_cac_completed = true;
178 	else
179 		qdf_sched_work(NULL, &dfs->dfs_cac_completion_work);
180 
181 	return QDF_HRTIMER_NORESTART;
182 }
183 #endif
184 
185 #ifdef QCA_SUPPORT_DFS_CAC
186 void dfs_cac_timer_attach(struct wlan_dfs *dfs)
187 {
188 	dfs->dfs_cac_timeout_override = -1;
189 	dfs->wlan_dfs_cac_time = WLAN_DFS_WAIT_MS;
190 	qdf_hrtimer_init(&dfs->dfs_cac_timer,
191 			 dfs_cac_timeout,
192 			 QDF_CLOCK_MONOTONIC,
193 			 QDF_HRTIMER_MODE_REL,
194 			 QDF_CONTEXT_HARDWARE);
195 	qdf_create_work(NULL,
196 			&dfs->dfs_cac_completion_work,
197 			dfs_process_cac_completion,
198 			dfs);
199 	qdf_timer_init(NULL,
200 			&(dfs->dfs_cac_valid_timer),
201 			dfs_cac_valid_timeout,
202 			(void *)(dfs),
203 			QDF_TIMER_TYPE_WAKE_APPS);
204 }
205 
206 void dfs_cac_timer_reset(struct wlan_dfs *dfs)
207 {
208 	qdf_hrtimer_cancel(&dfs->dfs_cac_timer);
209 	qdf_flush_work(&dfs->dfs_cac_completion_work);
210 	dfs_get_override_cac_timeout(dfs,
211 			&(dfs->dfs_cac_timeout_override));
212 	dfs_clear_cac_started_chan(dfs);
213 }
214 
215 void dfs_cac_timer_detach(struct wlan_dfs *dfs)
216 {
217 	qdf_hrtimer_kill(&dfs->dfs_cac_timer);
218 	qdf_flush_work(&dfs->dfs_cac_completion_work);
219 	qdf_destroy_work(NULL, &dfs->dfs_cac_completion_work);
220 	qdf_timer_free(&dfs->dfs_cac_valid_timer);
221 	dfs->dfs_cac_valid = 0;
222 }
223 
224 int dfs_is_ap_cac_timer_running(struct wlan_dfs *dfs)
225 {
226 	return dfs->dfs_cac_timer_running;
227 }
228 
229 #ifdef CONFIG_CHAN_FREQ_API
230 void dfs_start_cac_timer(struct wlan_dfs *dfs)
231 {
232 	int cac_timeout = 0;
233 	struct dfs_channel *chan = dfs->dfs_curchan;
234 
235 	cac_timeout =
236 	    dfs_mlme_get_cac_timeout_for_freq(dfs->dfs_pdev_obj,
237 					      chan->dfs_ch_freq,
238 					      chan->dfs_ch_mhz_freq_seg2,
239 					      chan->dfs_ch_flags);
240 
241 	dfs->dfs_cac_started_chan = *chan;
242 
243 	dfs_deliver_cac_state_events(dfs);
244 	dfs_debug(dfs, WLAN_DEBUG_DFS,
245 		  "chan = %d cfreq2 = %d timeout = %d sec, curr_time = %d sec",
246 		  chan->dfs_ch_ieee, chan->dfs_ch_vhtop_ch_freq_seg2,
247 		  cac_timeout,
248 		  qdf_system_ticks_to_msecs(qdf_system_ticks()) / 1000);
249 
250 	qdf_hrtimer_start(&dfs->dfs_cac_timer,
251 			  qdf_time_ms_to_ktime(cac_timeout * 1000),
252 			  QDF_HRTIMER_MODE_REL);
253 	dfs->dfs_cac_aborted = 0;
254 }
255 #endif
256 
257 void dfs_cancel_cac_timer(struct wlan_dfs *dfs)
258 {
259 	qdf_hrtimer_cancel(&dfs->dfs_cac_timer);
260 	dfs_clear_cac_started_chan(dfs);
261 }
262 
263 void dfs_send_dfs_events_for_chan(struct wlan_dfs *dfs,
264 				  struct dfs_channel *chan,
265 				  enum WLAN_DFS_EVENTS event)
266 {
267 	uint8_t nchannels, i;
268 	qdf_freq_t freq_list[MAX_20MHZ_SUBCHANS];
269 
270 	nchannels =
271 		dfs_get_bonding_channel_without_seg_info_for_freq(chan,
272 								  freq_list);
273 	for (i = 0; i < nchannels; i++)
274 		utils_dfs_deliver_event(dfs->dfs_pdev_obj,
275 					freq_list[i],
276 					event);
277 }
278 
279 void dfs_cac_stop(struct wlan_dfs *dfs)
280 {
281 	uint32_t phyerr;
282 	struct dfs_channel *chan;
283 
284 	chan = &dfs->dfs_cac_started_chan;
285 	dfs_get_debug_info(dfs, (void *)&phyerr);
286 	dfs_debug(dfs, WLAN_DEBUG_DFS,
287 		"Stopping CAC Timer %d procphyerr 0x%08x",
288 		 dfs->dfs_curchan->dfs_ch_freq, phyerr);
289 	qdf_hrtimer_cancel(&dfs->dfs_cac_timer);
290 
291 	dfs_send_dfs_events_for_chan(dfs, chan, WLAN_EV_CAC_RESET);
292 
293 	if (dfs->dfs_cac_timer_running)
294 		dfs->dfs_cac_aborted = 1;
295 	dfs_clear_cac_started_chan(dfs);
296 	dfs->dfs_cac_timer_running = 0;
297 }
298 
299 void dfs_stacac_stop(struct wlan_dfs *dfs)
300 {
301 	uint32_t phyerr;
302 
303 	dfs_get_debug_info(dfs, (void *)&phyerr);
304 	dfs_debug(dfs, WLAN_DEBUG_DFS,
305 		"Stopping STA CAC Timer %d procphyerr 0x%08x",
306 		 dfs->dfs_curchan->dfs_ch_freq, phyerr);
307 	dfs_clear_cac_started_chan(dfs);
308 }
309 
310 int dfs_override_cac_timeout(struct wlan_dfs *dfs, int cac_timeout)
311 {
312 	if (!dfs)
313 		return -EIO;
314 
315 	dfs->dfs_cac_timeout_override = cac_timeout;
316 	dfs_info(dfs, WLAN_DEBUG_DFS_ALWAYS, "CAC timeout is now %s %d",
317 		 (cac_timeout == -1) ? "default" : "overridden",
318 		 cac_timeout);
319 
320 	return 0;
321 }
322 
323 int dfs_get_override_cac_timeout(struct wlan_dfs *dfs, int *cac_timeout)
324 {
325 	if (!dfs)
326 		return -EIO;
327 
328 	(*cac_timeout) = dfs->dfs_cac_timeout_override;
329 
330 	return 0;
331 }
332 
333 #ifdef CONFIG_CHAN_FREQ_API
334 void dfs_cac_valid_reset_for_freq(struct wlan_dfs *dfs,
335 				  uint16_t prevchan_freq,
336 				  uint32_t prevchan_flags)
337 {
338 	if (dfs->dfs_cac_valid_time) {
339 		if ((prevchan_freq != dfs->dfs_curchan->dfs_ch_freq) ||
340 		    (prevchan_flags != dfs->dfs_curchan->dfs_ch_flags)) {
341 			dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS,
342 				"Cancelling timer & clearing cac_valid");
343 			qdf_timer_stop(&dfs->dfs_cac_valid_timer);
344 			dfs->dfs_cac_valid = 0;
345 		}
346 	}
347 }
348 #endif
349 #endif
350 
351 #ifdef CONFIG_CHAN_FREQ_API
352 bool
353 dfs_is_subset_channel_for_freq(uint16_t *old_subchans_freq,
354 			       uint8_t old_n_chans,
355 			       uint16_t *new_subchans_freq,
356 			       uint8_t new_n_chans)
357 {
358 	bool is_found;
359 	int i, j;
360 
361 	if (!new_n_chans)
362 		return true;
363 
364 	if (new_n_chans > old_n_chans)
365 		return false;
366 
367 	for (i = 0; i < new_n_chans; i++) {
368 		is_found = false;
369 		for (j = 0; j < old_n_chans; j++) {
370 			if (new_subchans_freq[i] == old_subchans_freq[j]) {
371 				is_found = true;
372 				break;
373 			}
374 		}
375 
376 		/* If new_subchans[i] is not found in old_subchans, then,
377 		 * new_chan is not subset of old_chan.
378 		 */
379 		if (!is_found)
380 			break;
381 	}
382 
383 	return is_found;
384 }
385 #endif
386 
387 #ifdef CONFIG_CHAN_FREQ_API
388 uint8_t
389 dfs_find_dfs_sub_channels_for_freq(struct wlan_dfs *dfs,
390 				   struct dfs_channel *chan,
391 				   uint16_t *subchan_arr)
392 {
393 	if (WLAN_IS_CHAN_MODE_160(chan) || WLAN_IS_CHAN_MODE_80_80(chan)) {
394 		if (WLAN_IS_CHAN_DFS(chan) && WLAN_IS_CHAN_DFS_CFREQ2(chan))
395 			return dfs_get_bonding_channel_without_seg_info_for_freq
396 				(chan, subchan_arr);
397 		if (WLAN_IS_CHAN_DFS(chan))
398 			return dfs_get_bonding_channels_for_freq(dfs,
399 								 chan,
400 								 SEG_ID_PRIMARY,
401 								 DETECTOR_ID_0,
402 								 subchan_arr);
403 		if (WLAN_IS_CHAN_DFS_CFREQ2(chan))
404 			return dfs_get_bonding_channels_for_freq
405 				(dfs, chan, SEG_ID_SECONDARY,
406 				 DETECTOR_ID_0, subchan_arr);
407 		/* All channels in 160/80_80 BW are non DFS, return 0
408 		 * as number of subchannels
409 		 */
410 		return 0;
411 	} else if (WLAN_IS_CHAN_DFS(chan)) {
412 		return dfs_get_bonding_channel_without_seg_info_for_freq
413 			(chan, subchan_arr);
414 	}
415 	/* All channels are non DFS, return 0 as number of subchannels*/
416 	return 0;
417 }
418 #endif
419 
420 #ifdef CONFIG_CHAN_FREQ_API
421 bool
422 dfs_is_new_chan_subset_of_old_chan(struct wlan_dfs *dfs,
423 				   struct dfs_channel *new_chan,
424 				   struct dfs_channel *old_chan)
425 {
426 	uint16_t new_subchans[MAX_20MHZ_SUBCHANS];
427 	uint16_t old_subchans[MAX_20MHZ_SUBCHANS];
428 	uint8_t n_new_subchans = 0;
429 	uint8_t n_old_subchans = 0;
430 
431 	/* Given channel is the old channel. i.e. The channel which
432 	 * should have the new channel as subset.
433 	 */
434 	n_old_subchans = dfs_find_dfs_sub_channels_for_freq(dfs, old_chan,
435 							    old_subchans);
436 	/* cur_chan is the new channel to be check if subset of old channel */
437 	n_new_subchans = dfs_find_dfs_sub_channels_for_freq(dfs, new_chan,
438 							    new_subchans);
439 
440 	return dfs_is_subset_channel_for_freq(old_subchans,
441 					      n_old_subchans,
442 					      new_subchans,
443 					      n_new_subchans);
444 }
445 #endif
446 
447 #ifdef QCA_SUPPORT_DFS_CAC
448 bool dfs_is_cac_required(struct wlan_dfs *dfs,
449 			 struct dfs_channel *cur_chan,
450 			 struct dfs_channel *prev_chan,
451 			 bool *continue_current_cac,
452 			 bool is_vap_restart)
453 {
454 	struct dfs_channel *cac_started_chan = &dfs->dfs_cac_started_chan;
455 
456 	if (!WLAN_IS_PRIMARY_OR_SECONDARY_CHAN_DFS(cur_chan)) {
457 		dfs_debug(dfs, WLAN_DEBUG_DFS, "Skip CAC on non-DFS channel");
458 		return false;
459 	}
460 
461 	if (dfs->dfs_ignore_dfs || dfs->dfs_cac_valid || dfs->dfs_ignore_cac) {
462 		dfs_debug(dfs, WLAN_DEBUG_DFS,
463 			  "Skip CAC, ignore_dfs = %d cac_valid = %d ignore_cac = %d",
464 			  dfs->dfs_ignore_dfs, dfs->dfs_cac_valid,
465 			  dfs->dfs_ignore_cac);
466 		return false;
467 	}
468 
469 	/* In case of RCAC, check if CAC is completed only on the RCAC channel
470 	 * and do not check the CAC info on current operating channel.
471 	 */
472 	if (dfs_is_agile_rcac_enabled(dfs) &&
473 	    dfs_is_rcac_cac_done(dfs, cur_chan, prev_chan))
474 		return false;
475 
476 	/* If the channel has completed PRE-CAC then CAC can be skipped here. */
477 	if (dfs_is_precac_done(dfs, cur_chan)) {
478 		dfs_debug(dfs, WLAN_DEBUG_DFS,
479 			  "PRE-CAC alreay done on this channel %d",
480 			  cur_chan->dfs_ch_ieee);
481 		return false;
482 	}
483 
484 	if (dfs_is_ap_cac_timer_running(dfs)) {
485 		/* Check if we should continue the existing CAC or
486 		 * cancel the existing CAC.
487 		 * For example: - if an existing VAP(0) is already in
488 		 * DFS wait state (which means the radio(wifi) is
489 		 * running the CAC) and it is in channel A and another
490 		 * VAP(1) comes up in the same channel then instead of
491 		 * cancelling the CAC we can let the CAC continue.
492 		 */
493 		if (dfs_is_new_chan_subset_of_old_chan(dfs,
494 						       cur_chan,
495 						       cac_started_chan)) {
496 			if (continue_current_cac)
497 				*continue_current_cac = true;
498 		} else {
499 			/* New CAC is needed, cancel the running CAC
500 			 * timer.
501 			 * 1) When AP is in DFS_WAIT state and it is in
502 			 *    channel A and user restarts the AP vap in
503 			 *    channel B, then cancel the running CAC in
504 			 *    channel A and start new CAC in channel B.
505 			 *
506 			 * 2) When AP detects the RADAR during CAC in
507 			 *    channel A, it cancels the running CAC and
508 			 *    tries to find channel B with the reduced
509 			 *    bandwidth with of channel A.
510 			 *    In this case, since the CAC is aborted by
511 			 *    the RADAR, AP should start the CAC again.
512 			 */
513 			dfs_cancel_cac_timer(dfs);
514 		}
515 	} else { /* CAC timer is not running. */
516 		/* If channel change happens via VAP DOWN/UP on subset channels,
517 		 * (eg: from 52 HT80 to 64 HT80) CAC done information
518 		 * (of 52 HT80) based on subset logic
519 		 * (as 52 and 64 HT80 are subsets of each other)
520 		 * is not expected to be preserved as VAP has come up
521 		 * from DOWN state. Hence do not skip CAC on 64 HT80.
522 		 * is_vap_restart flag is used as an identifer to indicate if
523 		 * vap has come up from a DOWN state or UP state (vap restart).
524 		 */
525 		if (!is_vap_restart) {
526 			dfs_debug(dfs, WLAN_DEBUG_DFS, "CAC is needed");
527 			return true;
528 		}
529 		if (dfs_is_new_chan_subset_of_old_chan(dfs,
530 						       cur_chan,
531 						       prev_chan)) {
532 			/* AP bandwidth reduce case:
533 			 * When AP detects the RADAR in in-service monitoring
534 			 * mode in channel A, it cancels the running CAC and
535 			 * tries to find the channel B with the reduced
536 			 * bandwidth of channel A.
537 			 * If the new channel B is subset of the channel A
538 			 * then AP skips the CAC.
539 			 */
540 			if (!dfs->dfs_cac_aborted) {
541 				dfs_debug(dfs, WLAN_DEBUG_DFS, "Skip CAC");
542 				return false;
543 			}
544 		}
545 	}
546 
547 	return true;
548 }
549 #endif
550