xref: /wlan-dirver/qca-wifi-host-cmn/umac/dfs/core/src/misc/dfs_process_radar_found_ind.c (revision 87a8e4458319c60b618522e263ed900e36aab528)
1 /*
2  * Copyright (c) 2017-2018 The Linux Foundation. All rights reserved.
3  *
4  * Permission to use, copy, modify, and/or distribute this software for
5  * any purpose with or without fee is hereby granted, provided that the
6  * above copyright notice and this permission notice appear in all
7  * copies.
8  *
9  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
10  * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
11  * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
12  * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
13  * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
14  * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
15  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
16  * PERFORMANCE OF THIS SOFTWARE.
17  */
18 
19 /**
20  * DOC: API for processing radar found indication.
21  *
22  */
23 
24 #include "../dfs.h"
25 #include "../dfs_zero_cac.h"
26 #include "../dfs_etsi_precac.h"
27 #include "../dfs_process_radar_found_ind.h"
28 #include <wlan_reg_services_api.h>
29 #include <wlan_dfs_utils_api.h>
30 #include "wlan_dfs_mlme_api.h"
31 #include "../dfs_internal.h"
32 /**
33  * TODO: The code is not according to the following description needs
34  * modification and correction. Code always adds left and right channels to
35  * NOL even if it is not a chirp radar.
36  *
37  * A) If chirp radar starts at boundary and ends at boundary then three channels
38  *    will be affected.
39  *    freq_offset.freq[0] = fn   (Center frequency)
40  *    freq_offset.freq[1] = fn-1 (Left of center)
41  *    freq_offset.freq[2] = fn+1 (Right of center)
42  *
43  *    Three channels, ch(n-1), ch(n)and ch(n+1) will be added to NOL.
44  *
45  *                     Chirp start freq         Chirp end freq
46  *                             |                       |
47  *                             |                       |
48  *                             V                       V
49  *      _______________________________________________________________________
50  *     |       center freq     |       center freq     |       center freq     |
51  *     |          ch(n-1)      |          ch(n)        |          ch(n+1)      |
52  *     |           |           |           |           |           |           |
53  *     |           |           |           |           |           |           |
54  *     |           |           |           |           |           |           |
55  *                fn-1                    fn         boundary     fn+1
56  *     <-------- 20 Mhz ------>
57  *
58  * B) If chirp radar starts at one channel and continues up to another channel
59  *    then two channels will be affected.
60  *    freq_offset.freq[0] = fn
61  *    freq_offset.freq[1] = 0
62  *    freq_offset.freq[2] = fn+1
63  *
64  *    Three channels, ch(n-1), ch(n)and ch(n+1) will be added to NOL.
65  *
66  *                                   Chirp start freq         Chirp end freq
67  *                                           |                       |
68  *                                           |                       |
69  *                                           V                       V
70  *      _______________________________________________________________________
71  *     |       center freq     |       center freq     |       center freq     |
72  *     |          ch(n-1)      |          ch(n)        |          ch(n+1)      |
73  *     |           |           |           |           |           |           |
74  *     |           |           |           |           |           |           |
75  *     |           |           |           |           |           |           |
76  *                fn-1                    fn         boundary     fn+1
77  *     <-------- 20 Mhz ------>
78  *
79  * C) Radar found at boundary, two channels will be affected.
80  *    freq_offset.freq[0] = fn
81  *    freq_offset.freq[1] = 0
82  *    freq_offset.freq[2] = fn+1
83  *
84  *    Two channels, ch(n) and ch(n+1) will be added to NOL.
85  *
86  *                                            dfs_freq_offset (radar found freq)
87  *                                                     |
88  *                                                     |
89  *                                                     V
90  *      _______________________________________________________________________
91  *     |       center freq     |       center freq     |       center freq     |
92  *     |          ch(n-1)      |          ch(n)        |          ch(n+1)      |
93  *     |           |           |           |           |           |           |
94  *     |           |           |           |           |           |           |
95  *     |           |           |           |           |           |           |
96  *                fn-1                    fn         boundary     fn+1
97  *     <-------- 20 Mhz ------>
98  *
99  *
100  * D) Else only one channel will be affected.
101  *    freq_offset.freq[0] = fn
102  *    freq_offset.freq[1] = 0
103  *    freq_offset.freq[2] = 0
104  *
105  *   One channel ch(n) will be added to NOL.
106  *
107  *
108  *                                            dfs_freq_offset (radar found freq)
109  *                                                |
110  *                                                |
111  *                                                V
112  *      _______________________________________________________________________
113  *     |       center freq     |       center freq     |       center freq     |
114  *     |          ch(n-1)      |          ch(n)        |          ch(n+1)      |
115  *     |           |           |           |           |           |           |
116  *     |           |           |           |           |           |           |
117  *     |           |           |           |           |           |           |
118  *                fn-1                    fn         boundary     fn+1
119  *     <-------- 20 Mhz ------>
120  */
121 
122 /**
123  * dfs_radar_add_channel_list_to_nol()- Add given channels to nol
124  * @dfs: Pointer to wlan_dfs structure.
125  * @channels: Pointer to the channel list.
126  * @num_channels: Number of channels in the list.
127  *
128  * Add list of channels to nol, only if the channel is dfs.
129  *
130  * Return: QDF_STATUS
131  */
132 static QDF_STATUS dfs_radar_add_channel_list_to_nol(struct wlan_dfs *dfs,
133 						    uint8_t *channels,
134 						    uint8_t num_channels)
135 {
136 	int i;
137 	uint8_t last_chan = 0;
138 	uint8_t nollist[NUM_CHANNELS_160MHZ];
139 	uint8_t num_ch = 0;
140 
141 	if (num_channels > NUM_CHANNELS_160MHZ) {
142 		dfs_err(dfs, WLAN_DEBUG_DFS,
143 			"Invalid num channels: %d", num_channels);
144 		return QDF_STATUS_E_FAILURE;
145 	}
146 
147 	for (i = 0; i < num_channels; i++) {
148 		if (channels[i] == 0 ||
149 		    channels[i] == last_chan)
150 			continue;
151 		if (!utils_is_dfs_ch(dfs->dfs_pdev_obj, channels[i])) {
152 			dfs_info(dfs, WLAN_DEBUG_DFS, "ch=%d is not dfs, skip",
153 				 channels[i]);
154 			continue;
155 		}
156 		last_chan = channels[i];
157 		DFS_NOL_ADD_CHAN_LOCKED(dfs,
158 				(uint16_t)utils_dfs_chan_to_freq(channels[i]),
159 				dfs->wlan_dfs_nol_timeout);
160 		nollist[num_ch++] = last_chan;
161 		dfs_info(dfs, WLAN_DEBUG_DFS_NOL, "ch=%d Added to NOL",
162 			 last_chan);
163 	}
164 
165 	if (!num_ch) {
166 		dfs_err(dfs, WLAN_DEBUG_DFS,
167 			"dfs channels not found in channel list");
168 		return QDF_STATUS_E_FAILURE;
169 	}
170 
171 	utils_dfs_reg_update_nol_ch(dfs->dfs_pdev_obj,
172 				    nollist, num_ch, DFS_NOL_SET);
173 	dfs_nol_update(dfs);
174 	utils_dfs_save_nol(dfs->dfs_pdev_obj);
175 
176 	return QDF_STATUS_SUCCESS;
177 }
178 
179 /**
180  * dfs_radar_chan_for_80()- Find frequency offsets for 80MHz
181  * @freq_offset: freq offset
182  * @center_freq: center frequency
183  *
184  * Find frequency offsets for 80MHz
185  *
186  * Return: None
187  */
188 static void dfs_radar_chan_for_80(struct freqs_offsets *freq_offset,
189 				  uint32_t center_freq)
190 {
191 	int i;
192 
193 	for (i = 0; i < DFS_NUM_FREQ_OFFSET; i++) {
194 		if (freq_offset->offset[i] < DFS_OFFSET_SECOND_LOWER)
195 			freq_offset->freq[i] =
196 				DFS_THIRD_LOWER_CHANNEL(center_freq);
197 		else if ((freq_offset->offset[i] > DFS_OFFSET_SECOND_LOWER) &&
198 			 (freq_offset->offset[i] < DFS_OFFSET_FIRST_LOWER))
199 			freq_offset->freq[i] =
200 				DFS_SECOND_LOWER_CHANNEL(center_freq);
201 		else if ((freq_offset->offset[i] > DFS_OFFSET_FIRST_LOWER) &&
202 			 (freq_offset->offset[i] < 0))
203 			freq_offset->freq[i] =
204 				DFS_FIRST_LOWER_CHANNEL(center_freq);
205 		else if ((freq_offset->offset[i] > 0) &&
206 			  (freq_offset->offset[i] < DFS_OFFSET_FIRST_UPPER))
207 			freq_offset->freq[i] =
208 				DFS_FIRST_UPPER_CHANNEL(center_freq);
209 		else if ((freq_offset->offset[i] > DFS_OFFSET_FIRST_UPPER) &&
210 			 (freq_offset->offset[i] < DFS_OFFSET_SECOND_UPPER))
211 			freq_offset->freq[i] =
212 				DFS_SECOND_UPPER_CHANNEL(center_freq);
213 		else if (freq_offset->offset[i] > DFS_OFFSET_SECOND_UPPER)
214 			freq_offset->freq[i] =
215 				DFS_THIRD_UPPER_CHANNEL(center_freq);
216 	}
217 }
218 
219 /**
220  * dfs_radar_chan_for_40()- Find frequency offsets for 40MHz
221  * @freq_offset: freq offset
222  * @center_freq: center frequency
223  *
224  * Find frequency offsets for 40MHz
225  *
226  * Return: None
227  */
228 static void dfs_radar_chan_for_40(struct freqs_offsets *freq_offset,
229 				  uint32_t center_freq)
230 {
231 	int i;
232 
233 	for (i = 0; i < DFS_NUM_FREQ_OFFSET; i++) {
234 		if (freq_offset->offset[i] < DFS_OFFSET_FIRST_LOWER)
235 			freq_offset->freq[i] =
236 				DFS_SECOND_LOWER_CHANNEL(center_freq);
237 		else if ((freq_offset->offset[i] > DFS_OFFSET_FIRST_LOWER) &&
238 			 (freq_offset->offset[i] < 0))
239 			freq_offset->freq[i] =
240 				DFS_FIRST_LOWER_CHANNEL(center_freq);
241 		else if ((freq_offset->offset[i] > 0) &&
242 			 (freq_offset->offset[i] < DFS_OFFSET_FIRST_UPPER))
243 			freq_offset->freq[i] =
244 				DFS_FIRST_UPPER_CHANNEL(center_freq);
245 		else if (freq_offset->offset[i] > DFS_OFFSET_FIRST_UPPER)
246 			freq_offset->freq[i] =
247 				DFS_SECOND_UPPER_CHANNEL(center_freq);
248 	}
249 }
250 
251 /**
252  * dfs_radar_chan_for_20()- Find frequency offsets for 20MHz
253  * @freq_offset: freq offset
254  * @center_freq: center frequency
255  *
256  * Find frequency offsets for 20MHz
257  *
258  * Return: None
259  */
260 static void dfs_radar_chan_for_20(struct freqs_offsets *freq_offset,
261 				  uint32_t center_freq)
262 {
263 	int i;
264 
265 	for (i = 0; i < DFS_NUM_FREQ_OFFSET; i++) {
266 		if (freq_offset->offset[i] <= DFS_20MZ_OFFSET_LOWER)
267 			freq_offset->freq[i] =
268 				DFS_20MHZ_LOWER_CHANNEL(center_freq);
269 		else if ((freq_offset->offset[i] > DFS_20MZ_OFFSET_LOWER) &&
270 			  (freq_offset->offset[i] < DFS_20MZ_OFFSET_UPPER))
271 			freq_offset->freq[i] = center_freq;
272 		else if (freq_offset->offset[i] >= DFS_20MZ_OFFSET_UPPER)
273 			freq_offset->freq[i] =
274 				DFS_20MHZ_UPPER_CHANNEL(center_freq);
275 	}
276 }
277 
278 /**
279  * dfs_find_radar_affected_subchans() - Finds radar affected sub channels.
280  * @dfs: Pointer to wlan_dfs structure.
281  * @radar_found: Pointer to radar_found structure.
282  * @channels: Pointer to save radar affected channels.
283  *
284  * Return: Number of channels.
285  */
286 static uint8_t dfs_find_radar_affected_subchans(struct wlan_dfs *dfs,
287 						struct radar_found_info
288 						*radar_found,
289 						uint8_t *channels)
290 {
291 	int i;
292 	uint32_t freq_center, flag;
293 	int32_t sidx;
294 	struct dfs_channel *curchan = dfs->dfs_curchan;
295 	struct freqs_offsets freq_offset;
296 
297 	qdf_mem_set(&freq_offset, sizeof(freq_offset), 0);
298 	flag = curchan->dfs_ch_flags;
299 
300 	for (i = 0; i < DFS_NUM_FREQ_OFFSET; i++)
301 		freq_offset.offset[i] = radar_found->freq_offset;
302 
303 	sidx = DFS_FREQ_OFFSET_TO_SIDX(radar_found->freq_offset);
304 
305 	if (!radar_found->segment_id)
306 		freq_center = utils_dfs_chan_to_freq(
307 				curchan->dfs_ch_vhtop_ch_freq_seg1);
308 	else {
309 		if (dfs_is_precac_timer_running(dfs)) {
310 			freq_center = utils_dfs_chan_to_freq(
311 					dfs->dfs_precac_secondary_freq);
312 		} else {
313 			freq_center = utils_dfs_chan_to_freq(
314 					curchan->dfs_ch_vhtop_ch_freq_seg2);
315 			if (flag & WLAN_CHAN_VHT160)
316 				freq_center += DFS_160MHZ_SECOND_SEG_OFFSET;
317 		}
318 	}
319 
320 	dfs_info(dfs, WLAN_DEBUG_DFS,
321 		 "seg=%d, sidx=%d, offset=%d, chirp=%d, flag=%d, f=%d",
322 		 radar_found->segment_id, sidx,
323 		 radar_found->freq_offset, radar_found->is_chirp,
324 		 flag, freq_center);
325 
326 	if ((WLAN_IS_CHAN_A(curchan)) ||
327 	    WLAN_IS_CHAN_MODE_20(curchan)) {
328 		if (radar_found->is_chirp ||
329 		    (sidx && !(abs(sidx) % DFS_BOUNDARY_SIDX))) {
330 			freq_offset.offset[LEFT_CH] -= DFS_CHIRP_OFFSET;
331 			freq_offset.offset[RIGHT_CH] += DFS_CHIRP_OFFSET;
332 		}
333 		dfs_radar_chan_for_20(&freq_offset, freq_center);
334 	} else if (WLAN_IS_CHAN_MODE_40(curchan)) {
335 		if (radar_found->is_chirp || !(abs(sidx) % DFS_BOUNDARY_SIDX)) {
336 			freq_offset.offset[LEFT_CH] -= DFS_CHIRP_OFFSET;
337 			freq_offset.offset[RIGHT_CH] += DFS_CHIRP_OFFSET;
338 		}
339 		dfs_radar_chan_for_40(&freq_offset, freq_center);
340 	} else if (WLAN_IS_CHAN_MODE_80(curchan) ||
341 			WLAN_IS_CHAN_MODE_160(curchan) ||
342 			WLAN_IS_CHAN_MODE_80_80(curchan)) {
343 		if (radar_found->is_chirp || !(abs(sidx) % DFS_BOUNDARY_SIDX)) {
344 			freq_offset.offset[LEFT_CH] -= DFS_CHIRP_OFFSET;
345 			freq_offset.offset[RIGHT_CH] += DFS_CHIRP_OFFSET;
346 		}
347 		dfs_radar_chan_for_80(&freq_offset, freq_center);
348 	} else {
349 		dfs_err(dfs, WLAN_DEBUG_DFS,
350 			"channel flag=%d is invalid", flag);
351 		return 0;
352 	}
353 
354 	for (i = 0; i < DFS_NUM_FREQ_OFFSET; i++) {
355 		channels[i] = utils_dfs_freq_to_chan(freq_offset.freq[i]);
356 		dfs_info(dfs, WLAN_DEBUG_DFS, "offset=%d, channel=%d",
357 			 i, channels[i]);
358 	}
359 
360 	return i;
361 }
362 
363 uint8_t dfs_get_bonding_channels(struct dfs_channel *curchan,
364 				 uint32_t segment_id,
365 				 uint8_t *channels)
366 {
367 	uint8_t center_chan;
368 	uint8_t nchannels = 0;
369 
370 	if (!segment_id)
371 		center_chan = curchan->dfs_ch_vhtop_ch_freq_seg1;
372 	else
373 		center_chan = curchan->dfs_ch_vhtop_ch_freq_seg2;
374 
375 	if (WLAN_IS_CHAN_MODE_20(curchan)) {
376 		nchannels = 1;
377 		channels[0] = center_chan;
378 	} else if (WLAN_IS_CHAN_MODE_40(curchan)) {
379 		nchannels = 2;
380 		channels[0] = center_chan - DFS_5GHZ_NEXT_CHAN_OFFSET;
381 		channels[1] = center_chan + DFS_5GHZ_NEXT_CHAN_OFFSET;
382 	} else if (WLAN_IS_CHAN_MODE_80(curchan) ||
383 		   WLAN_IS_CHAN_MODE_80_80(curchan)) {
384 		nchannels = 4;
385 		channels[0] = center_chan - DFS_5GHZ_2ND_CHAN_OFFSET;
386 		channels[1] = center_chan - DFS_5GHZ_NEXT_CHAN_OFFSET;
387 		channels[2] = center_chan + DFS_5GHZ_NEXT_CHAN_OFFSET;
388 		channels[3] = center_chan + DFS_5GHZ_2ND_CHAN_OFFSET;
389 	} else if (WLAN_IS_CHAN_MODE_160(curchan)) {
390 		nchannels = 8;
391 		center_chan = curchan->dfs_ch_vhtop_ch_freq_seg2;
392 		channels[0] = center_chan - DFS_5GHZ_4TH_CHAN_OFFSET;
393 		channels[1] = center_chan - DFS_5GHZ_3RD_CHAN_OFFSET;
394 		channels[2] = center_chan - DFS_5GHZ_2ND_CHAN_OFFSET;
395 		channels[3] = center_chan - DFS_5GHZ_NEXT_CHAN_OFFSET;
396 		channels[4] = center_chan + DFS_5GHZ_NEXT_CHAN_OFFSET;
397 		channels[5] = center_chan + DFS_5GHZ_2ND_CHAN_OFFSET;
398 		channels[6] = center_chan + DFS_5GHZ_3RD_CHAN_OFFSET;
399 		channels[7] = center_chan + DFS_5GHZ_4TH_CHAN_OFFSET;
400 	}
401 
402 	return nchannels;
403 }
404 
405 int dfs_radarevent_basic_sanity(struct wlan_dfs *dfs,
406 		struct dfs_channel *chan)
407 {
408 	if (!(dfs->dfs_second_segment_bangradar ||
409 				dfs_is_precac_timer_running(dfs)))
410 		if (!(WLAN_IS_PRIMARY_OR_SECONDARY_CHAN_DFS(chan))) {
411 			dfs_debug(dfs, WLAN_DEBUG_DFS2,
412 					"radar event on non-DFS chan");
413 			if (!(dfs->dfs_is_offload_enabled)) {
414 				dfs_reset_radarq(dfs);
415 				dfs_reset_alldelaylines(dfs);
416 				dfs->dfs_bangradar = 0;
417 			}
418 			return 0;
419 		}
420 
421 	return 1;
422 }
423 
424 /**
425  * dfs_send_csa_to_current_chan() - Send CSA to current channel
426  * @dfs: Pointer to wlan_dfs structure.
427  *
428  * For the test mode(usenol = 0), don't do a CSA; but setup the test timer so
429  * we get a CSA _back_ to the current operating channel.
430  */
431 static inline void dfs_send_csa_to_current_chan(struct wlan_dfs *dfs)
432 {
433 	qdf_timer_stop(&dfs->wlan_dfstesttimer);
434 	dfs->wlan_dfstest = 1;
435 	dfs->wlan_dfstest_ieeechan = dfs->dfs_curchan->dfs_ch_ieee;
436 	dfs->wlan_dfstesttime = 1;   /* 1ms */
437 	qdf_timer_mod(&dfs->wlan_dfstesttimer, dfs->wlan_dfstesttime);
438 }
439 
440 int dfs_second_segment_radar_disable(struct wlan_dfs *dfs)
441 {
442 	dfs->dfs_proc_phyerr &= ~DFS_SECOND_SEGMENT_RADAR_EN;
443 
444 	return 0;
445 }
446 
447 QDF_STATUS dfs_process_radar_ind(struct wlan_dfs *dfs,
448 				 struct radar_found_info *radar_found)
449 {
450 	bool wait_for_csa = false;
451 	uint8_t channels[NUM_CHANNELS_160MHZ];
452 	uint8_t num_channels;
453 	QDF_STATUS status;
454 
455 	if (!dfs->dfs_curchan) {
456 		dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "dfs->dfs_curchan is NULL");
457 		return QDF_STATUS_E_FAILURE;
458 	}
459 
460 	/* Check if the current channel is a non DFS channel */
461 	if (!dfs_radarevent_basic_sanity(dfs, dfs->dfs_curchan)) {
462 		dfs_err(dfs, WLAN_DEBUG_DFS,
463 			"radar event on a non-DFS channel");
464 		return QDF_STATUS_E_FAILURE;
465 	}
466 
467 	if (radar_found->segment_id == SEG_ID_SECONDARY)
468 		dfs_info(dfs, WLAN_DEBUG_DFS_ALWAYS,
469 			 "Radar found on second segment VHT80 freq=%d MHz",
470 			 dfs->dfs_precac_secondary_freq);
471 	else
472 		dfs_info(NULL, WLAN_DEBUG_DFS_ALWAYS,
473 			 "Radar found on channel=%d, freq=%d MHz",
474 			 dfs->dfs_curchan->dfs_ch_ieee,
475 			 dfs->dfs_curchan->dfs_ch_freq);
476 
477 	if (!dfs->dfs_use_nol) {
478 		dfs_send_csa_to_current_chan(dfs);
479 		return QDF_STATUS_SUCCESS;
480 	}
481 
482 	/* For Full Offload, FW sends segment id,freq_offset and
483 	 * is chirp information and gets assigned when there is radar detect.
484 	 * In case of radartool bangradar enhanced command and real radar
485 	 * for FO and PO, we assign these information here.
486 	 */
487 	if (!dfs->dfs_is_offload_enabled || dfs->dfs_enhanced_bangradar) {
488 		radar_found->segment_id = dfs->dfs_seg_id;
489 		radar_found->freq_offset = dfs->dfs_freq_offset;
490 		radar_found->is_chirp = dfs->dfs_is_chirp;
491 		dfs->dfs_enhanced_bangradar = 0;
492 	}
493 
494 	if (dfs->dfs_use_nol_subchannel_marking)
495 		num_channels = dfs_find_radar_affected_subchans(dfs,
496 								radar_found,
497 								channels);
498 	else
499 		num_channels = dfs_get_bonding_channels(dfs->dfs_curchan,
500 							radar_found->segment_id,
501 							channels);
502 
503 	status = dfs_radar_add_channel_list_to_nol(dfs, channels, num_channels);
504 	if (QDF_IS_STATUS_ERROR(status)) {
505 		dfs_err(dfs, WLAN_DEBUG_DFS,
506 			"radar event received on invalid channel");
507 		return status;
508 	}
509 
510 	/*
511 	 * If precac is running and the radar found in secondary
512 	 * VHT80 mark the channel as radar and add to NOL list.
513 	 * Otherwise random channel selection can choose this
514 	 * channel.
515 	 */
516 	dfs_debug(dfs, WLAN_DEBUG_DFS,
517 		  "found_on_second=%d is_pre=%d",
518 		  dfs->is_radar_found_on_secondary_seg,
519 		  dfs_is_precac_timer_running(dfs));
520 
521 	/*
522 	 * Even if radar found on primary, we need to move the channel
523 	 * from precac-required-list and precac-done-list to
524 	 * precac-nol-list.
525 	 */
526 	if (dfs->dfs_precac_enable)
527 		dfs_mark_precac_dfs(dfs, dfs->is_radar_found_on_secondary_seg);
528 
529 	if (utils_get_dfsdomain(dfs->dfs_pdev_obj) == DFS_ETSI_DOMAIN) {
530 		/* Remove chan from ETSI Pre-CAC Cleared List*/
531 		dfs_info(dfs, WLAN_DEBUG_DFS_NOL,
532 			 "%s : %d remove channel from ETSI PreCAC List\n",
533 			 __func__, __LINE__);
534 		dfs_mark_etsi_precac_dfs(dfs, channels, num_channels);
535 	}
536 
537 	if (!dfs->dfs_is_offload_enabled &&
538 	    dfs->is_radar_found_on_secondary_seg) {
539 		dfs_second_segment_radar_disable(dfs);
540 		dfs->is_radar_found_on_secondary_seg = 0;
541 
542 		if (dfs->is_radar_during_precac) {
543 			dfs->is_radar_during_precac = 0;
544 			return QDF_STATUS_SUCCESS;
545 		}
546 	}
547 
548 	/*
549 	 * This calls into the umac DFS code, which sets the umac
550 	 * related radar flags and begins the channel change
551 	 * machinery.
552 	 * XXX TODO: the umac NOL code isn't used, but
553 	 * WLAN_CHAN_DFS_RADAR still gets set. Since the umac
554 	 * NOL code isn't used, that flag is never cleared. This
555 	 * needs to be fixed. See EV 105776.
556 	 */
557 	dfs_mlme_start_rcsa(dfs->dfs_pdev_obj, &wait_for_csa);
558 	if (wait_for_csa)
559 		return QDF_STATUS_SUCCESS;
560 
561 	/*
562 	 * EV 129487 : We have detected radar in the channel,
563 	 * stop processing PHY error data as this can cause
564 	 * false detect in the new channel while channel
565 	 * change is in progress.
566 	 */
567 
568 	if (!dfs->dfs_is_offload_enabled) {
569 		dfs_radar_disable(dfs);
570 		dfs_second_segment_radar_disable(dfs);
571 	}
572 
573 	dfs_mlme_mark_dfs(dfs->dfs_pdev_obj,
574 			dfs->dfs_curchan->dfs_ch_ieee,
575 			dfs->dfs_curchan->dfs_ch_freq,
576 			dfs->dfs_curchan->dfs_ch_vhtop_ch_freq_seg2,
577 			dfs->dfs_curchan->dfs_ch_flags);
578 
579 	return QDF_STATUS_SUCCESS;
580 }
581