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