xref: /wlan-dirver/qca-wifi-host-cmn/umac/dfs/core/src/filtering/dfs_partial_offload_radar.c (revision a175314c51a4ce5cec2835cc8a8c7dc0c1810915)
1 /*
2  * Copyright (c) 2016-2018 The Linux Foundation. All rights reserved.
3  * Copyright (c) 2011, Atheros Communications Inc.
4  *
5  * Permission to use, copy, modify, and/or distribute this software for any
6  * purpose with or without fee is hereby granted, provided that the above
7  * copyright notice and this permission notice appear in all copies.
8  *
9  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16  */
17 
18 /**
19  * DOC: This file has radar table and initialization function for Beeliner
20  * family of chipsets.
21  */
22 
23 #include "../dfs.h"
24 #include "wlan_dfs_mlme_api.h"
25 #include "wlan_dfs_utils_api.h"
26 #include "wlan_dfs_lmac_api.h"
27 #include "../dfs_internal.h"
28 #include "../dfs_partial_offload_radar.h"
29 #if defined(WLAN_DFS_PARTIAL_OFFLOAD) && defined(HOST_DFS_SPOOF_TEST)
30 #include "../dfs_process_radar_found_ind.h"
31 #endif
32 
33 /**
34  * struct dfs_pulse dfs_fcc_radars - FCC radar table for Offload chipsets.
35  */
36 static struct dfs_pulse dfs_fcc_radars[] = {
37 	/* FCC TYPE 1 */
38 	{18,  1,  700, 700, 0,  4,  5,  0,  1, 18,  0, 3,  1, 5, 0, 0},
39 	{18,  1,  350, 350, 0,  4,  5,  0,  1, 18,  0, 3,  0, 5, 0, 0},
40 
41 	/* FCC TYPE 6 */
42 	{9,   1, 3003, 3003, 1,  7,  5,  0,  1, 18,  0, 0,  1, 1000, 0, 1},
43 
44 	/* FCC TYPE 2 */
45 	{23, 5, 4347, 6666, 0,  4, 11,  0,  7, 22,  0, 3,  0, 5, 0, 2},
46 
47 	/* FCC TYPE 3 */
48 	{18, 10, 2000, 5000, 0,  4,  8,  6, 13, 22,  0, 3, 0, 5, 0, 5},
49 
50 	/* FCC TYPE 4 */
51 	{16, 15, 2000, 5000, 0,  4,  7, 11, 23, 22,  0, 3, 0, 5, 0, 11},
52 
53 	/* FCC NEW TYPE 1 */
54 	/* 518us to 938us pulses (min 56 pulses) */
55 	{57, 1, 1066, 1930, 0, 4,  20,  0,  1, 22,  0, 3,  0, 5, 0, 21},
56 
57 	/* 938us to 2000 pulses (min 26 pulses) */
58 	{27, 1,  500, 1066, 0, 4,  13,  0,  1, 22,  0, 3,  0, 5, 0, 22},
59 
60 	/* 2000 to 3067us pulses (min 17 pulses) */
61 	{18, 1,  325,  500, 0, 4,  9,   0,  1, 22,  0, 3,  0, 5, 0, 23},
62 };
63 
64 /**
65  * struct dfs_pulse dfs_mkk4_radars - MKK4 radar table for Offload chipsets.
66  */
67 static struct dfs_pulse dfs_mkk4_radars[] = {
68 
69 	/* following two filters are specific to Japan/MKK4 */
70 	/* 1389 +/- 6 us */
71 	{18,  1,  720,  720, 0,  4,  6,  0,  1, 18,  0, 3, 0, 5, 0, 17},
72 
73 	/* 4000 +/- 6 us */
74 	{18,  4,  250,  250, 0,  4,  5,  1,  6, 18,  0, 3, 0, 5, 0, 18},
75 
76 	/* 3846 +/- 7 us */
77 	{18,  5,  260,  260, 0,  4,  6,  1,  6, 18,  0, 3, 1, 5, 0, 19},
78 
79 	/* following filters are common to both FCC and JAPAN */
80 
81 	/* FCC TYPE 1 */
82 	{18,  1,  700, 700, 0,  4,  5,  0,  1, 18,  0, 3,  1, 5, 0, 0},
83 	{18,  1,  350, 350, 0,  4,  5,  0,  1, 18,  0, 3,  0, 5, 0, 0},
84 
85 	/* FCC TYPE 6 */
86 	{9,   1, 3003, 3003, 1,  7,  5,  0,  1, 18,  0, 0, 1,  1000, 0, 1},
87 
88 	/* FCC TYPE 2 */
89 	{23, 5, 4347, 6666, 0,  4, 11,  0,  7, 22,  0, 3,  0, 5, 0, 2},
90 
91 	/* FCC TYPE 3 */
92 	{18, 10, 2000, 5000, 0,  4,  8,  6, 13, 22,  0, 3, 0, 5, 0, 5},
93 
94 	/* FCC TYPE 4 */
95 	{16, 15, 2000, 5000, 0,  4,  7, 11, 23, 22,  0, 3, 0, 5, 0, 11},
96 };
97 
98 /**
99  * struct dfs_bin5pulse dfs_fcc_bin5pulses - FCC BIN5 pulses for Offload
100  *                                           chipsets.
101  */
102 static struct dfs_bin5pulse dfs_fcc_bin5pulses[] = {
103 	{6, 28, 105, 12, 18, 5},
104 };
105 
106 /**
107  * struct dfs_bin5pulse dfs_jpn_bin5pulses - JAPAN BIN5 pulses for Offload
108  *                                           chipsets.
109  */
110 static struct dfs_bin5pulse dfs_jpn_bin5pulses[] = {
111 	{5, 28, 105, 12, 22, 5},
112 };
113 
114 /**
115  * dfs_bin5pulse dfs_fcc_bin5pulses_ar900b - FCC BIN5 pulses for AR9300
116  *                                           chipsets.
117  *
118  * WAR : IR 42631
119  * Beeliner 2 is tested at -65dbm as opposed to -62 dbm.
120  * For FCC/JPN chirping pulses, HW reports RSSI value that is lower by 2dbm
121  * when we enable noise floor claibration. This is specially true for
122  * frequencies that are greater than center frequency and in VHT80 mode.
123  */
124 
125 static struct dfs_bin5pulse dfs_fcc_bin5pulses_ar900b[] = {
126 	{5, 28, 105, 12, 20, 5},
127 };
128 
129 /**
130  * dfs_bin5pulse dfs_jpn_bin5pulses_ar900b - JAPAN BIN5 pulses for AR9300
131  *                                           chipsets.
132  */
133 static struct dfs_bin5pulse dfs_jpn_bin5pulses_ar900b[] = {
134 	{5, 28, 105, 12, 20, 5},
135 };
136 
137 /**
138  * dfs_bin5pulse dfs_fcc_bin5pulses_qca9984 - FCC BIN5 pulses for QCA9984
139  *                                            chipsets.
140  * WAR : IR-83400
141  * Cascade is tested at -65dbm as opposed to -62 dbm.
142  * For FCC/JPN chirping pulses, HW reports RSSI value that is significantly
143  * lower at left edge especially in HT80_80 mode. Also, duration may be
144  * significantly low. This can result in false detection and we may have to
145  * raise the threshold.
146  */
147 static struct dfs_bin5pulse dfs_fcc_bin5pulses_qca9984[] = {
148 	{5, 20, 105, 12, 20, 0},
149 };
150 
151 /**
152  * dfs_bin5pulse dfs_jpn_bin5pulses_qca9984 - JAPAN BIN5 pulses for QCA9984
153  *                                            chipsets.
154  */
155 static struct dfs_bin5pulse dfs_jpn_bin5pulses_qca9984[] = {
156 	{5, 20, 105, 12, 20, 0},
157 };
158 
159 /**
160  * dfs_pulse dfs_etsi_radars - ETSI radar table.
161  */
162 static struct dfs_pulse dfs_etsi_radars[] = {
163 
164 	/* EN 302 502 frequency hopping pulse */
165 	/* PRF 3000, 1us duration, 9 pulses per burst */
166 	{9,   1, 3000, 3000, 1,  4,  5,  0,  1, 18,  0, 0, 1,  1000, 0, 40},
167 	/* PRF 4500, 20us duration, 9 pulses per burst */
168 	{9,  20, 4500, 4500, 1,  4,  5, 19, 21, 18,  0, 0, 1,  1000, 0, 41},
169 
170 	/* TYPE staggered pulse */
171 	/* Type 5*/
172 	/* 0.8-2us, 2-3 bursts,300-400 PRF, 10 pulses each */
173 	{30,  2,  300,  400, 2, 30,  3,  0,  5, 15, 0,   0, 1, 5, 0, 31},
174 	/* Type 6 */
175 	/* 0.8-2us, 2-3 bursts, 400-1200 PRF, 15 pulses each */
176 	{30,  2,  400, 1200, 2, 30,  7,  0,  5, 15, 0,   0, 0, 5, 0, 32},
177 
178 	/* constant PRF based */
179 	/* Type 1 */
180 	/* 0.8-5us, 200  300 PRF, 10 pulses */
181 	{10, 5,   200,  400, 0,  4,  5,  0,  8, 15, 0,   0, 2, 5, 0, 33},
182 	{10, 5,   400,  600, 0,  4,  5,  0,  8, 15, 0,   0, 2, 5, 0, 37},
183 	{10, 5,   600,  800, 0,  4,  5,  0,  8, 15, 0,   0, 2, 5, 0, 38},
184 	{10, 5,   800, 1000, 0,  4,  5,  0,  8, 15, 0,   0, 2, 5, 0, 39},
185 	/* {10, 5,   200, 1000, 0,  6,  5,  0,  8, 15, 0,   0, 2, 5, 33}, */
186 
187 	/* Type 2 */
188 	/* 0.8-15us, 200-1600 PRF, 15 pulses */
189 	{15, 15,  200, 1600, 0,  4, 8,  0, 18, 24, 0,   0, 0, 5, 0, 34},
190 
191 	/* Type 3 */
192 	/* 0.8-15us, 2300-4000 PRF, 25 pulses*/
193 	{25, 15, 2300, 4000, 0,  4, 10, 0, 18, 24, 0,   0, 0, 5, 0, 35},
194 
195 	/* Type 4 */
196 	/* 20-30us, 2000-4000 PRF, 20 pulses*/
197 	{20, 30, 2000, 4000, 0,  4, 6, 19, 33, 24, 0,   0, 0, 24,  1, 36},
198 };
199 
200 /**
201  * dfs_pulse dfs_china_radars - CHINA radar table.
202  */
203 static struct dfs_pulse dfs_china_radars[] = {
204 
205 	/* TYPE staggered pulse */
206 	/* Type 5*/
207 	/* 0.8-2us, 2-3 bursts,300-400 PRF, 12 pulses each */
208 	{36,  2,  300,  400, 2, 30,  3,  0,  5, 15, 0,   0, 1, 51},
209 	/* Type 6 */
210 	/* 0.8-2us, 2-3 bursts, 400-1200 PRF, 16 pulses each */
211 	{48,  2,  400, 1200, 2, 30,  7,  0,  5, 15, 0,   0, 0, 52},
212 
213 	/* constant PRF based */
214 	/* Type 1 */
215 	/* 0.5-5us, 200  1000 PRF, 12 pulses */
216 	{12, 5,   200,  400, 0, 24,  5,  0,  8, 15, 0,   0, 2, 53},
217 	{12, 5,   400,  600, 0, 24,  5,  0,  8, 15, 0,   0, 2, 57},
218 	{12, 5,   600,  800, 0, 24,  5,  0,  8, 15, 0,   0, 2, 58},
219 	{12, 5,   800, 1000, 0, 24,  5,  0,  8, 15, 0,   0, 2, 59},
220 
221 	/* Type 2 */
222 	/* 0.5-15us, 200-1600 PRF, 16 pulses */
223 	{16, 15,  200, 1600, 0, 24, 8,  0, 18, 24, 0,   0, 0, 54},
224 
225 	/* Type 3 */
226 	/* 0.5-30us, 2300-4000 PRF, 24 pulses*/
227 	{24, 15, 2300, 4000,  0, 24, 10, 0, 33, 24, 0,   0, 0, 55},
228 
229 	/* Type 4 */
230 	/* 20-30us, 2000-4000 PRF, 20 pulses*/
231 	{20, 30, 2000, 4000, 0, 24, 6, 19, 33, 24, 0,   0, 0, 56},
232 
233 	/* 1us, 1000 PRF, 20 pulses */
234 	/* 1000 us PRI */
235 	{20,  1, 1000, 1000, 0,  6,  6,  0,  1, 18,  0, 3, 0, 50},
236 };
237 
238 /**
239  * dfs_pulse dfs_korea_radars - KOREA radar table.
240  */
241 static struct dfs_pulse dfs_korea_radars[] = {
242 	/* Korea Type 1 */
243 	{18,  1,  700, 700,  0, 4,  5,  0,  1, 18,  0, 3,  1, 5, 0, 40},
244 
245 	/* Korea Type 2 */
246 	{10,  1, 1800, 1800, 0, 4,  4,  0,  1, 18,  0, 3,  1, 5, 0, 41},
247 
248 	/* Korea Type 3 */
249 	{70,  1,  330, 330,  0, 4, 20,  0,  2, 18,  0, 3,  1, 5, 0, 42},
250 
251 	/* Korea Type 4 */
252 	{3,   1, 3003, 3003, 1, 7,  2,  0,  1, 18,  0, 0, 1,  1000, 0, 43},
253 };
254 
255 #define RSSI_THERSH_AR900B    15
256 
257 /**
258  * dfs_assign_fcc_pulse_table() - Assign FCC pulse table
259  * @rinfo: Pointer to wlan_dfs_radar_tab_info structure.
260  * @target_type: Target type.
261  * @tx_ops: target tx ops.
262  */
263 static inline void dfs_assign_fcc_pulse_table(
264 		struct wlan_dfs_radar_tab_info *rinfo,
265 		uint32_t target_type,
266 		struct wlan_lmac_if_target_tx_ops *tx_ops)
267 {
268 	rinfo->dfs_radars = dfs_fcc_radars;
269 	rinfo->numradars = QDF_ARRAY_SIZE(dfs_fcc_radars);
270 
271 	if (tx_ops->tgt_is_tgt_type_ar900b(target_type) ||
272 			tx_ops->tgt_is_tgt_type_ipq4019(target_type)) {
273 		rinfo->b5pulses = dfs_fcc_bin5pulses_ar900b;
274 		rinfo->numb5radars = QDF_ARRAY_SIZE(dfs_fcc_bin5pulses_ar900b);
275 	} else if (tx_ops->tgt_is_tgt_type_qca9984(target_type) ||
276 			tx_ops->tgt_is_tgt_type_qca9888(target_type)) {
277 		rinfo->b5pulses = dfs_fcc_bin5pulses_qca9984;
278 		rinfo->numb5radars =
279 			QDF_ARRAY_SIZE(dfs_fcc_bin5pulses_qca9984);
280 	} else {
281 		rinfo->b5pulses = dfs_fcc_bin5pulses;
282 		rinfo->numb5radars = QDF_ARRAY_SIZE(dfs_fcc_bin5pulses);
283 	}
284 }
285 
286 void dfs_get_po_radars(struct wlan_dfs *dfs)
287 {
288 	struct wlan_dfs_radar_tab_info rinfo;
289 	struct wlan_objmgr_psoc *psoc;
290 	struct wlan_lmac_if_target_tx_ops *tx_ops;
291 	int i;
292 	uint32_t target_type;
293 	int dfsdomain = DFS_FCC_DOMAIN;
294 	uint16_t ch_freq;
295 	uint16_t regdmn;
296 
297 	/* Fetch current radar patterns from the lmac */
298 	qdf_mem_zero(&rinfo, sizeof(rinfo));
299 
300 	/*
301 	 * Look up the current DFS regulatory domain and decide
302 	 * which radar pulses to use.
303 	 */
304 	dfsdomain = utils_get_dfsdomain(dfs->dfs_pdev_obj);
305 	target_type = lmac_get_target_type(dfs->dfs_pdev_obj);
306 
307 	psoc = wlan_pdev_get_psoc(dfs->dfs_pdev_obj);
308 	if (!psoc) {
309 		dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS,  "psoc is NULL");
310 		return;
311 	}
312 
313 	tx_ops = &(psoc->soc_cb.tx_ops.target_tx_ops);
314 	switch (dfsdomain) {
315 	case DFS_FCC_DOMAIN:
316 		dfs_info(dfs, WLAN_DEBUG_DFS_ALWAYS, "FCC domain");
317 		rinfo.dfsdomain = DFS_FCC_DOMAIN;
318 		dfs_assign_fcc_pulse_table(&rinfo, target_type, tx_ops);
319 		break;
320 	case DFS_CN_DOMAIN:
321 		dfs_info(dfs, WLAN_DEBUG_DFS_ALWAYS,
322 				"FCC domain -- Country China(156) override FCC radar pattern"
323 				);
324 		rinfo.dfsdomain = DFS_FCC_DOMAIN;
325 		/*
326 		 * China uses a radar pattern that is similar to ETSI but it
327 		 * follows FCC in all other respect like transmit power, CCA
328 		 * threshold etc.
329 		 */
330 		rinfo.dfs_radars = dfs_china_radars;
331 		rinfo.numradars = QDF_ARRAY_SIZE(dfs_china_radars);
332 		rinfo.b5pulses = NULL;
333 		rinfo.numb5radars = 0;
334 		break;
335 	case DFS_ETSI_DOMAIN:
336 		dfs_info(dfs, WLAN_DEBUG_DFS_ALWAYS, "ETSI domain");
337 		rinfo.dfsdomain = DFS_ETSI_DOMAIN;
338 
339 		ch_freq = dfs->dfs_curchan->dfs_ch_freq;
340 		regdmn = utils_dfs_get_cur_rd(dfs->dfs_pdev_obj);
341 
342 		if (((regdmn == ETSI11_WORLD_REGDMN_PAIR_ID) ||
343 		    (regdmn == ETSI12_WORLD_REGDMN_PAIR_ID) ||
344 		    (regdmn == ETSI13_WORLD_REGDMN_PAIR_ID) ||
345 		    (regdmn == ETSI14_WORLD_REGDMN_PAIR_ID)) &&
346 		    DFS_CURCHAN_IS_58GHz(ch_freq)) {
347 			rinfo.dfs_radars = dfs_etsi_radars;
348 			rinfo.numradars = QDF_ARRAY_SIZE(dfs_etsi_radars);
349 		} else {
350 			uint8_t offset = ETSI_LEGACY_PULSE_ARR_OFFSET;
351 
352 			rinfo.dfs_radars = &dfs_etsi_radars[offset];
353 			rinfo.numradars =
354 				QDF_ARRAY_SIZE(dfs_etsi_radars) - offset;
355 		}
356 		rinfo.b5pulses = NULL;
357 		rinfo.numb5radars = 0;
358 		break;
359 	case DFS_KR_DOMAIN:
360 		dfs_info(dfs, WLAN_DEBUG_DFS_ALWAYS,
361 				"ETSI domain -- Korea(412)");
362 		rinfo.dfsdomain = DFS_ETSI_DOMAIN;
363 
364 		/*
365 		 * So far we have treated Korea as part of ETSI and did not
366 		 * support any radar patters specific to Korea other than
367 		 * standard ETSI radar patterns. Ideally we would want to
368 		 * treat Korea as a different domain. This is something that
369 		 * we will address in the future. However, for now override
370 		 * ETSI tables for Korea.
371 		 */
372 		rinfo.dfs_radars = dfs_korea_radars;
373 		rinfo.numradars = QDF_ARRAY_SIZE(dfs_korea_radars);
374 		rinfo.b5pulses = NULL;
375 		rinfo.numb5radars = 0;
376 		break;
377 	case DFS_MKK4_DOMAIN:
378 		dfs_info(dfs, WLAN_DEBUG_DFS_ALWAYS, "MKK4 domain");
379 		rinfo.dfsdomain = DFS_MKK4_DOMAIN;
380 		rinfo.dfs_radars = dfs_mkk4_radars;
381 		rinfo.numradars = QDF_ARRAY_SIZE(dfs_mkk4_radars);
382 
383 		if (tx_ops->tgt_is_tgt_type_ar900b(target_type) ||
384 				tx_ops->tgt_is_tgt_type_ipq4019(target_type)) {
385 			rinfo.b5pulses = dfs_jpn_bin5pulses_ar900b;
386 			rinfo.numb5radars = QDF_ARRAY_SIZE(
387 					dfs_jpn_bin5pulses_ar900b);
388 		} else if (tx_ops->tgt_is_tgt_type_qca9984(target_type) ||
389 				tx_ops->tgt_is_tgt_type_qca9888(target_type)) {
390 			rinfo.b5pulses = dfs_jpn_bin5pulses_qca9984;
391 			rinfo.numb5radars = QDF_ARRAY_SIZE
392 				(dfs_jpn_bin5pulses_qca9984);
393 		} else {
394 			rinfo.b5pulses = dfs_jpn_bin5pulses;
395 			rinfo.numb5radars = QDF_ARRAY_SIZE(
396 					dfs_jpn_bin5pulses);
397 		}
398 		break;
399 	default:
400 		dfs_info(dfs, WLAN_DEBUG_DFS_ALWAYS, "UNINIT domain");
401 		rinfo.dfsdomain = DFS_UNINIT_DOMAIN;
402 		rinfo.dfs_radars = NULL;
403 		rinfo.numradars = 0;
404 		rinfo.b5pulses = NULL;
405 		rinfo.numb5radars = 0;
406 		break;
407 	}
408 
409 	if (tx_ops->tgt_is_tgt_type_ar900b(target_type) ||
410 			tx_ops->tgt_is_tgt_type_ipq4019(target_type) ||
411 			tx_ops->tgt_is_tgt_type_qca9984(target_type) ||
412 			tx_ops->tgt_is_tgt_type_qca9888(target_type)) {
413 		/* Beeliner WAR: lower RSSI threshold to improve detection of
414 		 * certian radar types
415 		 */
416 		/* Cascade WAR:
417 		 * Cascade can report lower RSSI near the channel boundary then
418 		 * expected. It can also report significantly low RSSI at center
419 		 * (as low as 16) at center. So we are lowering threshold for
420 		 * all types of radar for * Cascade.
421 		 * This may increase the possibility of false radar detection.
422 		 * IR -- 083703, 083398, 083387
423 		 */
424 
425 		for (i = 0; i < rinfo.numradars; i++)
426 			rinfo.dfs_radars[i].rp_rssithresh = RSSI_THERSH_AR900B;
427 	}
428 
429 	dfs_init_radar_filters(dfs, &rinfo);
430 }
431 
432 #if defined(WLAN_DFS_PARTIAL_OFFLOAD) && defined(HOST_DFS_SPOOF_TEST)
433 void dfs_send_avg_params_to_fw(struct wlan_dfs *dfs,
434 			       struct dfs_radar_found_params *params)
435 {
436 	tgt_dfs_send_avg_params_to_fw(dfs->dfs_pdev_obj, params);
437 }
438 
439 /**
440  * dfs_no_res_from_fw_task() - The timer function that is called if there is no
441  * response from fw after sending the average radar pulse parameters.
442  */
443 static os_timer_func(dfs_no_res_from_fw_task)
444 {
445 	struct wlan_dfs *dfs = NULL;
446 
447 	OS_GET_TIMER_ARG(dfs, struct wlan_dfs *);
448 
449 	if (!dfs) {
450 		dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS,  "dfs is NULL");
451 		return;
452 	}
453 
454 	dfs_info(dfs, WLAN_DEBUG_DFS_ALWAYS, "Host wait timer expired");
455 
456 	dfs->dfs_is_host_wait_running = 0;
457 	dfs->dfs_no_res_from_fw = 1;
458 	dfs_radarfound_action_generic(dfs, dfs->dfs_seg_id,
459 				      dfs->dfs_false_radar_found);
460 	dfs->dfs_seg_id = 0;
461 	dfs->dfs_false_radar_found = 0;
462 }
463 
464 void dfs_host_wait_timer_init(struct wlan_dfs *dfs)
465 {
466 	qdf_timer_init(NULL,
467 		       &(dfs->dfs_host_wait_timer),
468 			dfs_no_res_from_fw_task,
469 			(void *)(dfs),
470 			QDF_TIMER_TYPE_WAKE_APPS);
471 	dfs->dfs_status_timeout_override = -1;
472 }
473 
474 QDF_STATUS dfs_set_override_status_timeout(struct wlan_dfs *dfs,
475 				       int status_timeout)
476 {
477 	if (!dfs) {
478 		dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS,  "dfs is NULL");
479 		return QDF_STATUS_E_FAILURE;
480 	}
481 
482 	dfs->dfs_status_timeout_override = status_timeout;
483 
484 	dfs_info(dfs, WLAN_DEBUG_DFS_ALWAYS,
485 		 "Host wait status timeout is now %s : %d",
486 		(status_timeout == -1) ? "default" : "overridden",
487 		status_timeout);
488 
489 	return QDF_STATUS_SUCCESS;
490 }
491 
492 QDF_STATUS dfs_get_override_status_timeout(struct wlan_dfs *dfs,
493 					   int *status_timeout)
494 {
495 	if (!dfs) {
496 		dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS,  "dfs is NULL");
497 		return QDF_STATUS_E_FAILURE;
498 	}
499 
500 	*status_timeout = dfs->dfs_status_timeout_override;
501 
502 	return QDF_STATUS_SUCCESS;
503 }
504 
505 /**
506  * dfs_extract_radar_found_params() - Copy the contents of average radar
507  * parameters to dfs_radar_found_params parameter structure.
508  *
509  * @dfs: Pointer to wlan_dfs structure which contains the average radar
510  * parameters.
511  * @params: Pointer to dfs_radar_found_params structure.
512  */
513 static
514 void dfs_extract_radar_found_params(struct wlan_dfs *dfs,
515 				    struct dfs_radar_found_params *params)
516 {
517 	qdf_mem_zero(params, sizeof(*params));
518 	params->pri_min = dfs->dfs_average_pri;
519 	params->pri_max = dfs->dfs_average_pri;
520 	params->duration_min = dfs->dfs_average_duration;
521 	params->duration_max = dfs->dfs_average_duration;
522 	params->sidx_min = dfs->dfs_average_sidx;
523 	params->sidx_max = dfs->dfs_average_sidx;
524 
525 	/* Bangradar will not populate any of these average
526 	 * parameters as pulse is not received. If these variables
527 	 * are not resetted here, these go as radar_found params
528 	 * for bangradar if bangradar is issued after real radar.
529 	 */
530 	dfs->dfs_average_sidx = 0;
531 	dfs->dfs_average_duration = 0;
532 	dfs->dfs_average_pri = 0;
533 }
534 
535 void dfs_radarfound_action_fcc(struct wlan_dfs *dfs, uint8_t seg_id,
536 			       int false_radar_found)
537 {
538 	struct dfs_radar_found_params params;
539 
540 	qdf_mem_copy(&dfs->dfs_radar_found_chan, dfs->dfs_curchan,
541 		     sizeof(dfs->dfs_radar_found_chan));
542 	dfs_extract_radar_found_params(dfs, &params);
543 	dfs_send_avg_params_to_fw(dfs, &params);
544 	dfs->dfs_is_host_wait_running = 1;
545 	dfs->dfs_seg_id = seg_id;
546 	dfs->dfs_false_radar_found = false_radar_found;
547 	qdf_timer_mod(&dfs->dfs_host_wait_timer,
548 		      (dfs->dfs_status_timeout_override ==
549 		       -1) ? HOST_DFS_STATUS_WAIT_TIMER_MS :
550 		      dfs->dfs_status_timeout_override);
551 }
552 
553 void dfs_host_wait_timer_reset(struct wlan_dfs *dfs)
554 {
555 	dfs->dfs_is_host_wait_running = 0;
556 	qdf_timer_sync_cancel(&dfs->dfs_host_wait_timer);
557 }
558 
559 /**
560  * dfs_action_on_spoof_success() - DFS action on spoof test pass
561  * @dfs: Pointer to DFS object
562  */
563 static void dfs_action_on_spoof_success(struct wlan_dfs *dfs)
564 {
565 	dfs->dfs_spoof_test_done = 1;
566 	if (dfs->dfs_radar_found_chan.dfs_ch_freq ==
567 			dfs->dfs_curchan->dfs_ch_freq) {
568 		dfs_info(dfs, WLAN_DEBUG_DFS_ALWAYS,
569 			 "cac timer started for channel %d",
570 			 dfs->dfs_curchan->dfs_ch_ieee);
571 		dfs_start_cac_timer(dfs);
572 	} else{
573 		dfs_remove_spoof_channel_from_nol(dfs);
574 	}
575 }
576 
577 void dfs_action_on_fw_radar_status_check(struct wlan_dfs *dfs,
578 					 uint32_t *status)
579 {
580 	struct wlan_objmgr_pdev *dfs_pdev;
581 	int no_chans_avail = 0;
582 	int error_flag = 0;
583 
584 	dfs_host_wait_timer_reset(dfs);
585 	dfs_info(dfs, WLAN_DEBUG_DFS_ALWAYS, "Host DFS status = %d",
586 		 *status);
587 
588 	dfs_pdev = dfs->dfs_pdev_obj;
589 	if (!dfs_pdev) {
590 		dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "dfs_pdev_obj is NULL");
591 		return;
592 	}
593 
594 	switch (*status) {
595 	case HOST_DFS_STATUS_CHECK_PASSED:
596 		if (dfs->dfs_average_params_sent)
597 			dfs_action_on_spoof_success(dfs);
598 		else
599 			error_flag = 1;
600 		break;
601 	case HOST_DFS_STATUS_CHECK_FAILED:
602 		dfs->dfs_spoof_check_failed = 1;
603 		no_chans_avail =
604 		    dfs_mlme_rebuild_chan_list_with_non_dfs_channels(dfs_pdev);
605 		dfs_mlme_restart_vaps_with_non_dfs_chan(dfs_pdev,
606 							no_chans_avail);
607 		break;
608 	case HOST_DFS_STATUS_CHECK_HW_RADAR:
609 		if (dfs->dfs_average_params_sent) {
610 			if (dfs->dfs_radar_found_chan.dfs_ch_freq ==
611 			    dfs->dfs_curchan->dfs_ch_freq) {
612 				dfs_radarfound_action_generic(
613 						dfs,
614 						dfs->dfs_seg_id,
615 						dfs->dfs_false_radar_found);
616 			} else {
617 				/* Else of this case, no action is needed as
618 				 * dfs_action would have been done at timer
619 				 * expiry itself.
620 				 */
621 				dfs_info(dfs, WLAN_DEBUG_DFS_ALWAYS,
622 					 "DFS Action already taken");
623 			}
624 		} else {
625 			error_flag = 1;
626 		}
627 		break;
628 	default:
629 		dfs_info(dfs, WLAN_DEBUG_DFS_ALWAYS,
630 			 "Status event mismatch:%d, Ignoring it",
631 			 *status);
632 	}
633 
634 	dfs->dfs_average_params_sent = 0;
635 	qdf_mem_zero(&dfs->dfs_radar_found_chan, sizeof(struct dfs_channel));
636 
637 	if (error_flag == 1) {
638 		dfs_info(dfs, WLAN_DEBUG_DFS_ALWAYS,
639 			 "Received imroper response %d. Discarding it",
640 			 *status);
641 	}
642 }
643 
644 void dfs_reset_spoof_test(struct wlan_dfs *dfs)
645 {
646 	dfs->dfs_spoof_test_done = 0;
647 	dfs->dfs_spoof_check_failed = 0;
648 }
649 #endif
650