xref: /wlan-dirver/qca-wifi-host-cmn/umac/dfs/core/src/filtering/dfs_partial_offload_radar.c (revision a86b23ee68a2491aede2e03991f3fb37046f4e41)
1 /*
2  * Copyright (c) 2016-2020 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_objmgr_vdev_obj.h>
26 #include "wlan_dfs_utils_api.h"
27 #include "wlan_dfs_lmac_api.h"
28 #include "../dfs_internal.h"
29 #include "../dfs_partial_offload_radar.h"
30 #if defined(WLAN_DFS_PARTIAL_OFFLOAD) && defined(HOST_DFS_SPOOF_TEST)
31 #include "../dfs_process_radar_found_ind.h"
32 #endif
33 #include "../dfs_confirm_radar.h"
34 
35 /**
36  * struct dfs_pulse dfs_fcc_radars - FCC radar table for Offload chipsets.
37  */
38 static struct dfs_pulse dfs_fcc_radars[] = {
39 	/* FCC TYPE 1 */
40 	{18,  1,  700, 700, 0,  4,  5,  0,  1, 18,  0, 3,  1, 5, 0, 0},
41 	{18,  1,  350, 350, 0,  4,  5,  0,  1, 18,  0, 3,  0, 5, 0, 0},
42 
43 	/* FCC TYPE 6 */
44 	{9,   1, 3003, 3003, 1,  7,  5,  0,  1, 18,  0, 0,  1, 1000, 0, 1},
45 
46 	/* FCC TYPE 2 */
47 	{23, 5, 4347, 6666, 0,  4, 11,  0,  7, 22,  0, 3,  0, 5, 0, 2},
48 
49 	/* FCC TYPE 3 */
50 	{18, 10, 2000, 5000, 0,  4,  8,  6, 13, 22,  0, 3, 0, 5, 0, 5},
51 
52 	/* FCC TYPE 4 */
53 	{16, 15, 2000, 5000, 0,  4,  7, 11, 23, 22,  0, 3, 0, 5, 0, 11},
54 
55 	/* FCC NEW TYPE 1 */
56 	/* 518us to 938us pulses (min 56 pulses) */
57 	{57, 1, 1066, 1930, 0, 4,  20,  0,  1, 22,  0, 3,  0, 5, 0, 21},
58 
59 	/* 938us to 2000 pulses (min 26 pulses) */
60 	{27, 1,  500, 1066, 0, 4,  13,  0,  1, 22,  0, 3,  0, 5, 0, 22},
61 
62 	/* 2000 to 3067us pulses (min 17 pulses) */
63 	{18, 1,  325,  500, 0, 4,  9,   0,  1, 22,  0, 3,  0, 5, 0, 23},
64 };
65 
66 /**
67  * struct dfs_pulse dfs_mkk4_radars - MKK4 radar table for Offload chipsets.
68  */
69 static struct dfs_pulse dfs_mkk4_radars[] = {
70 
71 	/* following two filters are specific to Japan/MKK4 */
72 	/* 1389 +/- 6 us */
73 	{18,  1,  720,  720, 0,  4,  6,  0,  1, 18,  0, 3, 0, 5, 0, 17},
74 
75 	/* 4000 +/- 6 us */
76 	{18,  4,  250,  250, 0,  4,  5,  1,  6, 18,  0, 3, 0, 5, 0, 18},
77 
78 	/* 3846 +/- 7 us */
79 	{18,  5,  260,  260, 0,  4,  6,  1,  6, 18,  0, 3, 1, 5, 0, 19},
80 
81 	/* following filters are common to both FCC and JAPAN */
82 
83 	/* FCC TYPE 1 */
84 	{18,  1,  700, 700, 0,  4,  5,  0,  1, 18,  0, 3,  1, 5, 0, 0},
85 	{18,  1,  350, 350, 0,  4,  5,  0,  1, 18,  0, 3,  0, 5, 0, 0},
86 
87 	/* FCC TYPE 6 */
88 	{9,   1, 3003, 3003, 1,  7,  5,  0,  1, 18,  0, 0, 1,  1000, 0, 1},
89 
90 	/* FCC TYPE 2 */
91 	{23, 5, 4347, 6666, 0,  4, 11,  0,  7, 22,  0, 3,  0, 5, 0, 2},
92 
93 	/* FCC TYPE 3 */
94 	{18, 10, 2000, 5000, 0,  4,  8,  6, 13, 22,  0, 3, 0, 5, 0, 5},
95 
96 	/* FCC TYPE 4 */
97 	{16, 15, 2000, 5000, 0,  4,  7, 11, 23, 22,  0, 3, 0, 5, 0, 11},
98 };
99 
100 /**
101  * struct dfs_bin5pulse dfs_fcc_bin5pulses - FCC BIN5 pulses for Offload
102  *                                           chipsets.
103  */
104 static struct dfs_bin5pulse dfs_fcc_bin5pulses[] = {
105 	{6, 28, 105, 12, 18, 5},
106 };
107 
108 /**
109  * struct dfs_bin5pulse dfs_jpn_bin5pulses - JAPAN BIN5 pulses for Offload
110  *                                           chipsets.
111  */
112 static struct dfs_bin5pulse dfs_jpn_bin5pulses[] = {
113 	{5, 28, 105, 12, 22, 5},
114 };
115 
116 /**
117  * dfs_bin5pulse dfs_fcc_bin5pulses_ar900b - FCC BIN5 pulses for AR9300
118  *                                           chipsets.
119  *
120  * WAR : IR 42631
121  * Beeliner 2 is tested at -65dbm as opposed to -62 dbm.
122  * For FCC/JPN chirping pulses, HW reports RSSI value that is lower by 2dbm
123  * when we enable noise floor claibration. This is specially true for
124  * frequencies that are greater than center frequency and in VHT80 mode.
125  */
126 
127 static struct dfs_bin5pulse dfs_fcc_bin5pulses_ar900b[] = {
128 	{5, 28, 105, 12, 20, 5},
129 };
130 
131 /**
132  * dfs_bin5pulse dfs_jpn_bin5pulses_ar900b - JAPAN BIN5 pulses for AR9300
133  *                                           chipsets.
134  */
135 static struct dfs_bin5pulse dfs_jpn_bin5pulses_ar900b[] = {
136 	{5, 28, 105, 12, 20, 5},
137 };
138 
139 /**
140  * dfs_bin5pulse dfs_fcc_bin5pulses_qca9984 - FCC BIN5 pulses for QCA9984
141  *                                            chipsets.
142  * WAR : IR-83400
143  * Cascade is tested at -65dbm as opposed to -62 dbm.
144  * For FCC/JPN chirping pulses, HW reports RSSI value that is significantly
145  * lower at left edge especially in HT80_80 mode. Also, duration may be
146  * significantly low. This can result in false detection and we may have to
147  * raise the threshold.
148  */
149 static struct dfs_bin5pulse dfs_fcc_bin5pulses_qca9984[] = {
150 	{5, 20, 105, 12, 20, 0},
151 };
152 
153 /**
154  * dfs_bin5pulse dfs_jpn_bin5pulses_qca9984 - JAPAN BIN5 pulses for QCA9984
155  *                                            chipsets.
156  */
157 static struct dfs_bin5pulse dfs_jpn_bin5pulses_qca9984[] = {
158 	{5, 20, 105, 12, 20, 0},
159 };
160 
161 /**
162  * dfs_pulse dfs_etsi_radars - ETSI radar table.
163  */
164 static struct dfs_pulse dfs_etsi_radars[] = {
165 
166 	/* EN 302 502 frequency hopping pulse */
167 	/* PRF 3000, 1us duration, 9 pulses per burst */
168 	{9,   1, 3000, 3000, 1,  4,  5,  0,  1, 18,  0, 0, 1,  1000, 0, 40},
169 	/* PRF 4500, 20us duration, 9 pulses per burst */
170 	{9,  20, 4500, 4500, 1,  4,  5, 19, 21, 18,  0, 0, 1,  1000, 0, 41},
171 
172 	/* Type 3 */
173 	/* 10 15us, 200-1000 PRF, 15 pulses */
174 	{15, 15, 200, 1000, 0, 4, 5, 8, 18, 22, 0, 0, 0, 5, 0, 42},
175 
176 	/* Type 4 */
177 	/* 1-15us, 1200-1600 PRF, 15 pulses */
178 	{15, 15, 1200, 1600, 0, 4, 5, 0, 18, 22, 0, 0, 0, 5, 0, 43},
179 
180 	/* TYPE staggered pulse */
181 	/* Type 5*/
182 	/* 0.8-2us, 2-3 bursts,300-400 PRF, 10 pulses each */
183 	{30,  2,  300,  400, 2, 30,  3,  0,  5, 15, 0,   0, 1, 5, 0, 31},
184 	/* Type 6 */
185 	/* 0.8-2us, 2-3 bursts, 400-1200 PRF, 15 pulses each */
186 	{30,  2,  400, 1200, 2, 30,  7,  0,  5, 15, 0,   0, 0, 5, 0, 32},
187 
188 	/* constant PRF based */
189 	/* Type 1 */
190 	/* 0.8-5us, 200  300 PRF, 10 pulses */
191 	{10, 5,   200,  400, 0,  4,  5,  0,  8, 15, 0,   0, 2, 5, 0, 33},
192 	{10, 5,   400,  600, 0,  4,  5,  0,  8, 15, 0,   0, 2, 5, 0, 37},
193 	{10, 5,   600,  800, 0,  4,  5,  0,  8, 15, 0,   0, 2, 5, 0, 38},
194 	{10, 5,   800, 1000, 0,  4,  5,  0,  8, 15, 0,   0, 2, 5, 0, 39},
195 	/* {10, 5,   200, 1000, 0,  6,  5,  0,  8, 15, 0,   0, 2, 5, 33}, */
196 
197 	/* Type 2 */
198 	/* 0.8-15us, 200-1600 PRF, 15 pulses */
199 	{15, 15,  200, 1600, 0,  4, 8,  0, 18, 24, 0,   0, 0, 5, 0, 34},
200 
201 	/* Type 3 */
202 	/* 0.8-15us, 2300-4000 PRF, 25 pulses*/
203 	{25, 15, 2300, 4000, 0,  4, 10, 0, 18, 24, 0,   0, 0, 5, 0, 35},
204 
205 	/* Type 4 */
206 	/* 20-30us, 2000-4000 PRF, 20 pulses*/
207 	{20, 30, 2000, 4000, 0,  4, 6, 19, 33, 24, 0,   0, 0, 24,  1, 36},
208 };
209 
210 /**
211  * dfs_pulse dfs_china_radars - CHINA radar table.
212  */
213 static struct dfs_pulse dfs_china_radars[] = {
214 
215 	/* TYPE staggered pulse */
216 	/* Type 5*/
217 	/* 0.8-2us, 2-3 bursts,300-400 PRF, 12 pulses each */
218 	{36,  2,  300,  400, 2, 30,  3,  0,  5, 15, 0,   0, 1, 0, 0, 51},
219 	/* Type 6 */
220 	/* 0.8-2us, 2-3 bursts, 400-1200 PRF, 16 pulses each */
221 	{48,  2,  400, 1200, 2, 30,  7,  0,  5, 15, 0,   0, 0, 0, 0, 52},
222 
223 	/* constant PRF based */
224 	/* Type 1 */
225 	/* 0.5-5us, 200  1000 PRF, 12 pulses */
226 	{12, 5,   200,  400, 0, 24,  5,  0,  8, 15, 0,   0, 2, 0, 0, 53},
227 	{12, 5,   400,  600, 0, 24,  5,  0,  8, 15, 0,   0, 2, 0, 0, 57},
228 	{12, 5,   600,  800, 0, 24,  5,  0,  8, 15, 0,   0, 2, 0, 0, 58},
229 	{12, 5,   800, 1000, 0, 24,  5,  0,  8, 15, 0,   0, 2, 0, 0, 59},
230 
231 	/* Type 2 */
232 	/* 0.5-15us, 200-1600 PRF, 16 pulses */
233 	{16, 15,  200, 1600, 0, 24, 8,  0, 18, 24, 0,   0, 0, 0, 0, 54},
234 
235 	/* Type 3 */
236 	/* 0.5-30us, 2300-4000 PRF, 24 pulses*/
237 	{24, 15, 2300, 4000,  0, 24, 10, 0, 33, 24, 0,   0, 0, 0, 0, 55},
238 
239 	/* Type 4 */
240 	/* 20-30us, 2000-4000 PRF, 20 pulses*/
241 	{20, 30, 2000, 4000, 0, 24, 6, 19, 33, 24, 0,   0, 0, 0, 0, 56},
242 
243 	/* 1us, 1000 PRF, 20 pulses */
244 	/* 1000 us PRI */
245 	{20,  1, 1000, 1000, 0,  6,  6,  0,  1, 18,  0, 3, 0, 0, 0, 50},
246 };
247 
248 /**
249  * dfs_pulse dfs_korea_radars - KOREA radar table.
250  */
251 static struct dfs_pulse dfs_korea_radars[] = {
252 	/* Korea Type 1 */
253 	{18,  1,  700, 700,  0, 4,  5,  0,  1, 18,  0, 3,  1, 5, 0, 40},
254 
255 	/* Korea Type 2 */
256 	{10,  1, 1800, 1800, 0, 4,  4,  0,  1, 18,  0, 3,  1, 5, 0, 41},
257 
258 	/* Korea Type 3 */
259 	{70,  1,  330, 330,  0, 4, 20,  0,  3, 18,  0, 3,  1, 5, 0, 42},
260 
261 	/* Korea Type 4 */
262 	{3,   1, 3003, 3003, 1, 7,  2,  0,  1, 18,  0, 0, 1,  1000, 0, 43},
263 };
264 
265 #define RSSI_THERSH_AR900B    15
266 #define RSSI_THERSH_ADRASTEA  18
267 
268 /**
269  * dfs_assign_fcc_pulse_table() - Assign FCC pulse table
270  * @rinfo: Pointer to wlan_dfs_radar_tab_info structure.
271  * @target_type: Target type.
272  * @tx_ops: target tx ops.
273  */
274 static inline void dfs_assign_fcc_pulse_table(
275 		struct wlan_dfs_radar_tab_info *rinfo,
276 		uint32_t target_type,
277 		struct wlan_lmac_if_target_tx_ops *tx_ops)
278 {
279 	rinfo->dfs_radars = dfs_fcc_radars;
280 	rinfo->numradars = QDF_ARRAY_SIZE(dfs_fcc_radars);
281 
282 	if (tx_ops->tgt_is_tgt_type_ar900b(target_type) ||
283 			tx_ops->tgt_is_tgt_type_ipq4019(target_type)) {
284 		rinfo->b5pulses = dfs_fcc_bin5pulses_ar900b;
285 		rinfo->numb5radars = QDF_ARRAY_SIZE(dfs_fcc_bin5pulses_ar900b);
286 	} else if (tx_ops->tgt_is_tgt_type_qca9984(target_type) ||
287 			tx_ops->tgt_is_tgt_type_qca9888(target_type)) {
288 		rinfo->b5pulses = dfs_fcc_bin5pulses_qca9984;
289 		rinfo->numb5radars =
290 			QDF_ARRAY_SIZE(dfs_fcc_bin5pulses_qca9984);
291 	} else {
292 		rinfo->b5pulses = dfs_fcc_bin5pulses;
293 		rinfo->numb5radars = QDF_ARRAY_SIZE(dfs_fcc_bin5pulses);
294 	}
295 }
296 
297 #ifdef DFS_OVERRIDE_RF_THRESHOLD
298 static void dfs_set_adrastea_rf_thrshold(
299 		struct wlan_objmgr_psoc *psoc,
300 		int dfsdomain,
301 		uint32_t target_type,
302 		struct wlan_dfs_radar_tab_info *rinfo)
303 {
304 	int i;
305 	struct wlan_lmac_if_target_tx_ops *tgt_tx_ops;
306 	struct wlan_lmac_if_tx_ops *tx_ops;
307 
308 	tx_ops = wlan_psoc_get_lmac_if_txops(psoc);
309 	if (!tx_ops) {
310 		dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS,  "tx_ops is null");
311 		return;
312 	}
313 
314 	tgt_tx_ops = &tx_ops->target_tx_ops;
315 
316 	if (tgt_tx_ops->tgt_is_tgt_type_adrastea(target_type) &&
317 	    dfsdomain == DFS_ETSI_DOMAIN) {
318 		for (i = 0; i < rinfo->numradars; i++) {
319 			rinfo->dfs_radars[i].rp_rssithresh =
320 				DFS_MIN(rinfo->dfs_radars[i].rp_rssithresh,
321 					RSSI_THERSH_ADRASTEA);
322 		}
323 	}
324 }
325 #else
326 static inline void dfs_set_adrastea_rf_thrshold(
327 		struct wlan_objmgr_psoc *psoc,
328 		int dfsdomain,
329 		uint32_t target_type,
330 		struct wlan_dfs_radar_tab_info *rinfo)
331 {
332 }
333 #endif
334 
335 static
336 void dfs_handle_radar_tab_init_failure(struct wlan_dfs_radar_tab_info *rinfo)
337 {
338 	rinfo->dfsdomain = DFS_UNINIT_DOMAIN;
339 	rinfo->dfs_radars = NULL;
340 	rinfo->numradars = 0;
341 	rinfo->b5pulses = NULL;
342 	rinfo->numb5radars = 0;
343 }
344 
345 /**
346  * dfs_merge_external_radar() - Get and merge the external radar table with
347  * internal radar table.
348  * @dfs: Pointer to the DFS structure.
349  * @rinfo: Pointer to wlan_dfs_radar_tab_info structure.
350  * @dfsdomain: dfs domain.
351  *
352  * Return: Pointer to the allocated merged radar table if success, else NULL.
353  * The caller is responsible for freeing up the allocated memory when no longer
354  * needed.
355  */
356 static struct dfs_pulse
357 *dfs_merge_external_radar(struct wlan_dfs_radar_tab_info *rinfo,
358 			  struct dfs_pulse *external_radars,
359 			  int dfsdomain,
360 			  uint8_t num_ext_radars)
361 {
362 	struct dfs_pulse *merged_radars;
363 
364 	merged_radars = qdf_mem_malloc((rinfo->numradars + num_ext_radars) *
365 				       sizeof(struct dfs_pulse));
366 	if (!merged_radars)
367 		return NULL;
368 	qdf_mem_copy(merged_radars,
369 		     rinfo->dfs_radars,
370 		     rinfo->numradars * sizeof(struct dfs_pulse));
371 	qdf_mem_copy(merged_radars + rinfo->numradars,
372 		     external_radars,
373 		     num_ext_radars * sizeof(struct dfs_pulse));
374 	return merged_radars;
375 }
376 
377 static
378 void dfs_update_radar_info(struct wlan_dfs_radar_tab_info *rinfo,
379 			   struct dfs_pulse *merged_radars,
380 			   uint8_t num_ext_radars)
381 {
382 	rinfo->dfs_radars = merged_radars;
383 	rinfo->numradars += num_ext_radars;
384 }
385 
386 /**
387  * dfs_assign_mkk_bin5_radars() - Assign the MKK bin5 radar table
388  * @rinfo: Pointer to wlan_dfs_radar_tab_info structure.
389  * @target_type: Target type.
390  * @tx_ops: target tx ops.
391  */
392 static void
393 dfs_assign_mkk_bin5_radars(struct wlan_dfs_radar_tab_info *rinfo,
394 			   uint32_t target_type,
395 			   struct wlan_lmac_if_target_tx_ops *tgt_tx_ops)
396 {
397 	if (tgt_tx_ops->tgt_is_tgt_type_ar900b(target_type) ||
398 	    tgt_tx_ops->tgt_is_tgt_type_ipq4019(target_type)) {
399 		rinfo->b5pulses = dfs_jpn_bin5pulses_ar900b;
400 		rinfo->numb5radars = QDF_ARRAY_SIZE(
401 				dfs_jpn_bin5pulses_ar900b);
402 	} else if (tgt_tx_ops->tgt_is_tgt_type_qca9984(target_type) ||
403 			tgt_tx_ops->tgt_is_tgt_type_qca9888(target_type)) {
404 		rinfo->b5pulses = dfs_jpn_bin5pulses_qca9984;
405 		rinfo->numb5radars = QDF_ARRAY_SIZE
406 			(dfs_jpn_bin5pulses_qca9984);
407 	} else {
408 		rinfo->b5pulses = dfs_jpn_bin5pulses;
409 		rinfo->numb5radars = QDF_ARRAY_SIZE(
410 				dfs_jpn_bin5pulses);
411 	}
412 }
413 
414 void dfs_get_po_radars(struct wlan_dfs *dfs)
415 {
416 	struct wlan_dfs_radar_tab_info rinfo;
417 	struct wlan_objmgr_psoc *psoc;
418 	struct wlan_lmac_if_target_tx_ops *tgt_tx_ops;
419 	int i;
420 	uint32_t target_type;
421 	int dfsdomain = DFS_FCC_DOMAIN;
422 	struct dfs_pulse *external_radars, *merged_radars = NULL;
423 	uint8_t num_ext_radars;
424 	struct wlan_lmac_if_tx_ops *tx_ops;
425 
426 	/* Fetch current radar patterns from the lmac */
427 	qdf_mem_zero(&rinfo, sizeof(rinfo));
428 
429 	/*
430 	 * Look up the current DFS regulatory domain and decide
431 	 * which radar pulses to use.
432 	 */
433 	dfsdomain = utils_get_dfsdomain(dfs->dfs_pdev_obj);
434 	target_type = lmac_get_target_type(dfs->dfs_pdev_obj);
435 
436 	psoc = wlan_pdev_get_psoc(dfs->dfs_pdev_obj);
437 	if (!psoc) {
438 		dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS,  "psoc is NULL");
439 		return;
440 	}
441 
442 	tx_ops = wlan_psoc_get_lmac_if_txops(psoc);
443 	if (!tx_ops) {
444 		dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS,  "tx_ops is null");
445 		return;
446 	}
447 
448 	tgt_tx_ops = &tx_ops->target_tx_ops;
449 	switch (dfsdomain) {
450 	case DFS_FCC_DOMAIN:
451 		dfs_debug(dfs, WLAN_DEBUG_DFS_ALWAYS, "FCC domain");
452 		rinfo.dfsdomain = DFS_FCC_DOMAIN;
453 		dfs_assign_fcc_pulse_table(&rinfo, target_type, tgt_tx_ops);
454 		dfs->dfs_lowest_pri_limit = DFS_INVALID_PRI_LIMIT;
455 		break;
456 	case DFS_CN_DOMAIN:
457 		dfs_info(dfs, WLAN_DEBUG_DFS_ALWAYS,
458 				"FCC domain -- Country China(156) override FCC radar pattern"
459 				);
460 		rinfo.dfsdomain = DFS_FCC_DOMAIN;
461 		/*
462 		 * China uses a radar pattern that is similar to ETSI but it
463 		 * follows FCC in all other respect like transmit power, CCA
464 		 * threshold etc.
465 		 */
466 		rinfo.dfs_radars = dfs_china_radars;
467 		rinfo.numradars = QDF_ARRAY_SIZE(dfs_china_radars);
468 		rinfo.b5pulses = NULL;
469 		rinfo.numb5radars = 0;
470 		dfs->dfs_lowest_pri_limit = DFS_INVALID_PRI_LIMIT;
471 		break;
472 	case DFS_ETSI_DOMAIN:
473 		dfs_info(dfs, WLAN_DEBUG_DFS_ALWAYS, "ETSI domain");
474 		rinfo.dfsdomain = DFS_ETSI_DOMAIN;
475 
476 		if (dfs_is_en302_502_applicable(dfs)) {
477 			rinfo.dfs_radars = dfs_etsi_radars;
478 			rinfo.numradars = QDF_ARRAY_SIZE(dfs_etsi_radars);
479 		} else {
480 			uint8_t offset = ETSI_LEGACY_PULSE_ARR_OFFSET;
481 
482 			rinfo.dfs_radars = &dfs_etsi_radars[offset];
483 			rinfo.numradars =
484 				QDF_ARRAY_SIZE(dfs_etsi_radars) - offset;
485 		}
486 		rinfo.b5pulses = NULL;
487 		rinfo.numb5radars = 0;
488 		dfs->dfs_lowest_pri_limit = DFS_INVALID_PRI_LIMIT;
489 		break;
490 	case DFS_KR_DOMAIN:
491 		dfs_info(dfs, WLAN_DEBUG_DFS_ALWAYS,
492 				"ETSI domain -- Korea(412)");
493 		rinfo.dfsdomain = DFS_ETSI_DOMAIN;
494 
495 		/*
496 		 * So far we have treated Korea as part of ETSI and did not
497 		 * support any radar patters specific to Korea other than
498 		 * standard ETSI radar patterns. Ideally we would want to
499 		 * treat Korea as a different domain. This is something that
500 		 * we will address in the future. However, for now override
501 		 * ETSI tables for Korea.
502 		 */
503 		rinfo.dfs_radars = dfs_korea_radars;
504 		rinfo.numradars = QDF_ARRAY_SIZE(dfs_korea_radars);
505 		rinfo.b5pulses = NULL;
506 		rinfo.numb5radars = 0;
507 		dfs->dfs_lowest_pri_limit = DFS_INVALID_PRI_LIMIT;
508 		break;
509 	case DFS_MKKN_DOMAIN:
510 		dfs_info(dfs, WLAN_DEBUG_DFS_ALWAYS, "MKKN domain");
511 		rinfo.dfsdomain = DFS_MKKN_DOMAIN;
512 		rinfo.dfs_radars = dfs_mkk4_radars;
513 		rinfo.numradars = QDF_ARRAY_SIZE(dfs_mkk4_radars);
514 		dfs_assign_mkk_bin5_radars(&rinfo, target_type, tgt_tx_ops);
515 		dfs->dfs_lowest_pri_limit = DFS_INVALID_PRI_LIMIT_MKKN;
516 		break;
517 	case DFS_MKK4_DOMAIN:
518 		dfs_info(dfs, WLAN_DEBUG_DFS_ALWAYS, "MKK4 domain");
519 		rinfo.dfsdomain = DFS_MKK4_DOMAIN;
520 		rinfo.dfs_radars = dfs_mkk4_radars;
521 		rinfo.numradars = QDF_ARRAY_SIZE(dfs_mkk4_radars);
522 		dfs_assign_mkk_bin5_radars(&rinfo, target_type, tgt_tx_ops);
523 		dfs->dfs_lowest_pri_limit = DFS_INVALID_PRI_LIMIT;
524 		break;
525 	default:
526 		dfs_info(dfs, WLAN_DEBUG_DFS_ALWAYS, "UNINIT domain");
527 		dfs_handle_radar_tab_init_failure(&rinfo);
528 		break;
529 	}
530 
531 	external_radars = dfs_get_ext_filter(dfsdomain, &num_ext_radars);
532 	if (external_radars) {
533 		merged_radars = dfs_merge_external_radar(&rinfo,
534 							 external_radars,
535 							 dfsdomain,
536 							 num_ext_radars);
537 		if (!merged_radars)
538 			dfs_handle_radar_tab_init_failure(&rinfo);
539 		else
540 			dfs_update_radar_info(&rinfo,
541 					      merged_radars,
542 					      num_ext_radars);
543 	}
544 
545 	if (tgt_tx_ops->tgt_is_tgt_type_ar900b(target_type) ||
546 			tgt_tx_ops->tgt_is_tgt_type_ipq4019(target_type) ||
547 			tgt_tx_ops->tgt_is_tgt_type_qca9984(target_type) ||
548 			tgt_tx_ops->tgt_is_tgt_type_qca9888(target_type)) {
549 		/* Beeliner WAR: lower RSSI threshold to improve detection of
550 		 * certian radar types
551 		 */
552 		/* Cascade WAR:
553 		 * Cascade can report lower RSSI near the channel boundary then
554 		 * expected. It can also report significantly low RSSI at center
555 		 * (as low as 16) at center. So we are lowering threshold for
556 		 * all types of radar for * Cascade.
557 		 * This may increase the possibility of false radar detection.
558 		 * IR -- 083703, 083398, 083387
559 		 */
560 
561 		for (i = 0; i < rinfo.numradars; i++)
562 			rinfo.dfs_radars[i].rp_rssithresh = RSSI_THERSH_AR900B;
563 	}
564 
565 	dfs_set_adrastea_rf_thrshold(psoc, dfsdomain, target_type, &rinfo);
566 
567 	WLAN_DFS_DATA_STRUCT_LOCK(dfs);
568 	dfs_init_radar_filters(dfs, &rinfo);
569 	WLAN_DFS_DATA_STRUCT_UNLOCK(dfs);
570 	qdf_mem_free(merged_radars);
571 }
572 
573 #if defined(WLAN_DFS_PARTIAL_OFFLOAD) && defined(HOST_DFS_SPOOF_TEST)
574 void dfs_send_avg_params_to_fw(struct wlan_dfs *dfs,
575 			       struct dfs_radar_found_params *params)
576 {
577 	tgt_dfs_send_avg_params_to_fw(dfs->dfs_pdev_obj, params);
578 }
579 
580 /**
581  * dfs_no_res_from_fw_task() - The timer function that is called if there is no
582  * response from fw after sending the average radar pulse parameters.
583  */
584 static os_timer_func(dfs_no_res_from_fw_task)
585 {
586 	struct wlan_dfs *dfs = NULL;
587 
588 	OS_GET_TIMER_ARG(dfs, struct wlan_dfs *);
589 
590 	if (!dfs) {
591 		dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS,  "dfs is NULL");
592 		return;
593 	}
594 
595 	dfs_info(dfs, WLAN_DEBUG_DFS_ALWAYS, "Host wait timer expired");
596 
597 	dfs->dfs_is_host_wait_running = 0;
598 	dfs->dfs_no_res_from_fw = 1;
599 	dfs_radarfound_action_generic(dfs, dfs->dfs_seg_id);
600 	dfs->dfs_seg_id = 0;
601 }
602 
603 void dfs_host_wait_timer_init(struct wlan_dfs *dfs)
604 {
605 	qdf_timer_init(NULL,
606 		       &(dfs->dfs_host_wait_timer),
607 			dfs_no_res_from_fw_task,
608 			(void *)(dfs),
609 			QDF_TIMER_TYPE_WAKE_APPS);
610 	dfs->dfs_status_timeout_override = -1;
611 }
612 
613 QDF_STATUS dfs_set_override_status_timeout(struct wlan_dfs *dfs,
614 				       int status_timeout)
615 {
616 	if (!dfs) {
617 		dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS,  "dfs is NULL");
618 		return QDF_STATUS_E_FAILURE;
619 	}
620 
621 	dfs->dfs_status_timeout_override = status_timeout;
622 
623 	dfs_info(dfs, WLAN_DEBUG_DFS_ALWAYS,
624 		 "Host wait status timeout is now %s : %d",
625 		(status_timeout == -1) ? "default" : "overridden",
626 		status_timeout);
627 
628 	return QDF_STATUS_SUCCESS;
629 }
630 
631 QDF_STATUS dfs_get_override_status_timeout(struct wlan_dfs *dfs,
632 					   int *status_timeout)
633 {
634 	if (!dfs) {
635 		dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS,  "dfs is NULL");
636 		return QDF_STATUS_E_FAILURE;
637 	}
638 
639 	*status_timeout = dfs->dfs_status_timeout_override;
640 
641 	return QDF_STATUS_SUCCESS;
642 }
643 
644 /**
645  * dfs_extract_radar_found_params() - Copy the contents of average radar
646  * parameters to dfs_radar_found_params parameter structure.
647  *
648  * @dfs: Pointer to wlan_dfs structure which contains the average radar
649  * parameters.
650  * @params: Pointer to dfs_radar_found_params structure.
651  */
652 static
653 void dfs_extract_radar_found_params(struct wlan_dfs *dfs,
654 				    struct dfs_radar_found_params *params)
655 {
656 	qdf_mem_zero(params, sizeof(*params));
657 	params->pri_min = dfs->dfs_average_pri;
658 	params->pri_max = dfs->dfs_average_pri;
659 	params->duration_min = dfs->dfs_average_duration;
660 	params->duration_max = dfs->dfs_average_duration;
661 	params->sidx_min = dfs->dfs_average_sidx;
662 	params->sidx_max = dfs->dfs_average_sidx;
663 
664 	/* Bangradar will not populate any of these average
665 	 * parameters as pulse is not received. If these variables
666 	 * are not resetted here, these go as radar_found params
667 	 * for bangradar if bangradar is issued after real radar.
668 	 */
669 	dfs->dfs_average_sidx = 0;
670 	dfs->dfs_average_duration = 0;
671 	dfs->dfs_average_pri = 0;
672 }
673 
674 void dfs_radarfound_action_fcc(struct wlan_dfs *dfs, uint8_t seg_id)
675 {
676 	struct dfs_radar_found_params params;
677 
678 	qdf_mem_copy(&dfs->dfs_radar_found_chan, dfs->dfs_curchan,
679 		     sizeof(dfs->dfs_radar_found_chan));
680 	dfs_extract_radar_found_params(dfs, &params);
681 	dfs->dfs_is_host_wait_running = 1;
682 	qdf_timer_mod(&dfs->dfs_host_wait_timer,
683 		      (dfs->dfs_status_timeout_override ==
684 		       -1) ? HOST_DFS_STATUS_WAIT_TIMER_MS :
685 		      dfs->dfs_status_timeout_override);
686 	dfs->dfs_seg_id = seg_id;
687 	dfs_send_avg_params_to_fw(dfs, &params);
688 }
689 
690 void dfs_host_wait_timer_reset(struct wlan_dfs *dfs)
691 {
692 	dfs->dfs_is_host_wait_running = 0;
693 	qdf_timer_sync_cancel(&dfs->dfs_host_wait_timer);
694 }
695 
696 /**
697  * dfs_action_on_spoof_success() - DFS action on spoof test pass
698  * @dfs: Pointer to DFS object
699  */
700 static void dfs_action_on_spoof_success(struct wlan_dfs *dfs)
701 {
702 	dfs->dfs_spoof_test_done = 1;
703 	if (dfs->dfs_radar_found_chan.dfs_ch_freq ==
704 			dfs->dfs_curchan->dfs_ch_freq) {
705 		dfs_info(dfs, WLAN_DEBUG_DFS_ALWAYS,
706 			 "cac timer started for channel %d",
707 			 dfs->dfs_curchan->dfs_ch_ieee);
708 		dfs_start_cac_timer(dfs);
709 	} else{
710 		dfs_remove_spoof_channel_from_nol(dfs);
711 	}
712 }
713 
714 void dfs_action_on_fw_radar_status_check(struct wlan_dfs *dfs,
715 					 uint32_t *status)
716 {
717 	struct wlan_objmgr_pdev *dfs_pdev;
718 	int no_chans_avail = 0;
719 	int error_flag = 0;
720 
721 	dfs_host_wait_timer_reset(dfs);
722 	dfs_info(dfs, WLAN_DEBUG_DFS_ALWAYS, "Host DFS status = %d",
723 		 *status);
724 
725 	dfs_pdev = dfs->dfs_pdev_obj;
726 	if (!dfs_pdev) {
727 		dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "dfs_pdev_obj is NULL");
728 		return;
729 	}
730 
731 	switch (*status) {
732 	case HOST_DFS_STATUS_CHECK_PASSED:
733 		if (dfs->dfs_average_params_sent)
734 			dfs_action_on_spoof_success(dfs);
735 		else
736 			error_flag = 1;
737 		break;
738 	case HOST_DFS_STATUS_CHECK_FAILED:
739 		dfs->dfs_spoof_check_failed = 1;
740 		no_chans_avail =
741 		    dfs_mlme_rebuild_chan_list_with_non_dfs_channels(dfs_pdev);
742 		dfs_mlme_restart_vaps_with_non_dfs_chan(dfs_pdev,
743 							no_chans_avail);
744 		break;
745 	case HOST_DFS_STATUS_CHECK_HW_RADAR:
746 		if (dfs->dfs_average_params_sent) {
747 			if (dfs->dfs_radar_found_chan.dfs_ch_freq ==
748 			    dfs->dfs_curchan->dfs_ch_freq) {
749 				dfs_radarfound_action_generic(
750 						dfs,
751 						dfs->dfs_seg_id);
752 			} else {
753 				/* Else of this case, no action is needed as
754 				 * dfs_action would have been done at timer
755 				 * expiry itself.
756 				 */
757 				dfs_info(dfs, WLAN_DEBUG_DFS_ALWAYS,
758 					 "DFS Action already taken");
759 			}
760 		} else {
761 			error_flag = 1;
762 		}
763 		break;
764 	default:
765 		dfs_info(dfs, WLAN_DEBUG_DFS_ALWAYS,
766 			 "Status event mismatch:%d, Ignoring it",
767 			 *status);
768 	}
769 
770 	dfs->dfs_average_params_sent = 0;
771 	qdf_mem_zero(&dfs->dfs_radar_found_chan, sizeof(struct dfs_channel));
772 
773 	if (error_flag == 1) {
774 		dfs_info(dfs, WLAN_DEBUG_DFS_ALWAYS,
775 			 "Received imroper response %d. Discarding it",
776 			 *status);
777 	}
778 }
779 
780 void dfs_reset_spoof_test(struct wlan_dfs *dfs)
781 {
782 	dfs->dfs_spoof_test_done = 0;
783 	dfs->dfs_spoof_check_failed = 0;
784 }
785 #endif
786