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