1 /*
2 * Copyright (c) 2016-2021 The Linux Foundation. All rights reserved.
3 * Copyright (c) 2022-2023 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)
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 */
dfs_assign_fcc_pulse_table(struct wlan_dfs_radar_tab_info * rinfo,uint32_t target_type,struct wlan_lmac_if_target_tx_ops * tx_ops)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
dfs_set_adrastea_rf_thrshold(struct wlan_objmgr_psoc * psoc,int dfsdomain,uint32_t target_type,struct wlan_dfs_radar_tab_info * rinfo)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
dfs_set_adrastea_rf_thrshold(struct wlan_objmgr_psoc * psoc,int dfsdomain,uint32_t target_type,struct wlan_dfs_radar_tab_info * rinfo)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
dfs_handle_radar_tab_init_failure(struct wlan_dfs_radar_tab_info * rinfo)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 * @rinfo: Pointer to wlan_dfs_radar_tab_info structure.
475 * @external_radars: list of external radar pulses
476 * @dfsdomain: dfs domain.
477 * @num_ext_radars: number of @external_radar entries
478 *
479 * Return: Pointer to the allocated merged radar table if success, else NULL.
480 * The caller is responsible for freeing up the allocated memory when no longer
481 * needed.
482 */
483 static struct dfs_pulse
dfs_merge_external_radar(struct wlan_dfs_radar_tab_info * rinfo,struct dfs_pulse * external_radars,int dfsdomain,uint8_t num_ext_radars)484 *dfs_merge_external_radar(struct wlan_dfs_radar_tab_info *rinfo,
485 struct dfs_pulse *external_radars,
486 int dfsdomain,
487 uint8_t num_ext_radars)
488 {
489 struct dfs_pulse *merged_radars;
490
491 merged_radars = qdf_mem_malloc((rinfo->numradars + num_ext_radars) *
492 sizeof(struct dfs_pulse));
493 if (!merged_radars)
494 return NULL;
495 qdf_mem_copy(merged_radars,
496 rinfo->dfs_radars,
497 rinfo->numradars * sizeof(struct dfs_pulse));
498 qdf_mem_copy(merged_radars + rinfo->numradars,
499 external_radars,
500 num_ext_radars * sizeof(struct dfs_pulse));
501 return merged_radars;
502 }
503
504 static
dfs_update_radar_info(struct wlan_dfs_radar_tab_info * rinfo,struct dfs_pulse * merged_radars,uint8_t num_ext_radars)505 void dfs_update_radar_info(struct wlan_dfs_radar_tab_info *rinfo,
506 struct dfs_pulse *merged_radars,
507 uint8_t num_ext_radars)
508 {
509 rinfo->dfs_radars = merged_radars;
510 rinfo->numradars += num_ext_radars;
511 }
512
513 /**
514 * dfs_assign_mkk_bin5_radars() - Assign the MKK bin5 radar table
515 * @rinfo: Pointer to wlan_dfs_radar_tab_info structure.
516 * @target_type: Target type.
517 * @tgt_tx_ops: target tx ops.
518 */
519 static void
dfs_assign_mkk_bin5_radars(struct wlan_dfs_radar_tab_info * rinfo,uint32_t target_type,struct wlan_lmac_if_target_tx_ops * tgt_tx_ops)520 dfs_assign_mkk_bin5_radars(struct wlan_dfs_radar_tab_info *rinfo,
521 uint32_t target_type,
522 struct wlan_lmac_if_target_tx_ops *tgt_tx_ops)
523 {
524 if (tgt_tx_ops->tgt_is_tgt_type_ar900b(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
dfs_get_po_radars(struct wlan_dfs * dfs)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 patterns 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_qca9984(target_type) ||
703 tgt_tx_ops->tgt_is_tgt_type_qca9888(target_type)) {
704 /* Beeliner WAR: lower RSSI threshold to improve detection of
705 * certain radar types
706 */
707 /* Cascade WAR:
708 * Cascade can report lower RSSI near the channel boundary then
709 * expected. It can also report significantly low RSSI at center
710 * (as low as 16) at center. So we are lowering threshold for
711 * all types of radar for * Cascade.
712 * This may increase the possibility of false radar detection.
713 * IR -- 083703, 083398, 083387
714 */
715
716 for (i = 0; i < rinfo.numradars; i++)
717 rinfo.dfs_radars[i].rp_rssithresh = RSSI_THERSH_AR900B;
718 }
719
720 dfs_set_adrastea_rf_thrshold(psoc, dfsdomain, target_type, &rinfo);
721
722 WLAN_DFS_DATA_STRUCT_LOCK(dfs);
723 dfs_init_radar_filters(dfs, &rinfo);
724 WLAN_DFS_DATA_STRUCT_UNLOCK(dfs);
725 qdf_mem_free(merged_radars);
726 }
727
728 #if defined(WLAN_DFS_PARTIAL_OFFLOAD)
729 void
dfs_disable_radar_and_flush_pulses(struct wlan_dfs * dfs)730 dfs_disable_radar_and_flush_pulses(struct wlan_dfs *dfs)
731 {
732 dfs_radar_disable(dfs);
733 dfs_second_segment_radar_disable(dfs);
734 dfs_flush_additional_pulses(dfs);
735 }
736 #endif
737
738 #if defined(WLAN_DFS_PARTIAL_OFFLOAD) && defined(HOST_DFS_SPOOF_TEST)
dfs_send_avg_params_to_fw(struct wlan_dfs * dfs,struct dfs_radar_found_params * params)739 void dfs_send_avg_params_to_fw(struct wlan_dfs *dfs,
740 struct dfs_radar_found_params *params)
741 {
742 tgt_dfs_send_avg_params_to_fw(dfs->dfs_pdev_obj, params);
743 }
744
745 /*
746 * dfs_no_res_from_fw_task() - The timer function that is called if there is no
747 * response from fw after sending the average radar pulse parameters.
748 *
749 * NB: not using kernel-doc format since the kernel-doc script doesn't
750 * handle the os_timer_func() macro
751 */
os_timer_func(dfs_no_res_from_fw_task)752 static os_timer_func(dfs_no_res_from_fw_task)
753 {
754 struct wlan_dfs *dfs = NULL;
755
756 OS_GET_TIMER_ARG(dfs, struct wlan_dfs *);
757
758 if (!dfs) {
759 dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "dfs is NULL");
760 return;
761 }
762
763 dfs_debug(dfs, WLAN_DEBUG_DFS_ALWAYS, "Host wait timer expired");
764
765 dfs->dfs_is_host_wait_running = 0;
766 dfs->dfs_no_res_from_fw = 1;
767 dfs_radarfound_action_generic(dfs, dfs->dfs_seg_id);
768 dfs->dfs_seg_id = 0;
769 }
770
dfs_host_wait_timer_init(struct wlan_dfs * dfs)771 void dfs_host_wait_timer_init(struct wlan_dfs *dfs)
772 {
773 qdf_timer_init(NULL,
774 &(dfs->dfs_host_wait_timer),
775 dfs_no_res_from_fw_task,
776 (void *)(dfs),
777 QDF_TIMER_TYPE_WAKE_APPS);
778 dfs->dfs_status_timeout_override = -1;
779 }
780
dfs_set_override_status_timeout(struct wlan_dfs * dfs,int status_timeout)781 QDF_STATUS dfs_set_override_status_timeout(struct wlan_dfs *dfs,
782 int status_timeout)
783 {
784 if (!dfs) {
785 dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "dfs is NULL");
786 return QDF_STATUS_E_FAILURE;
787 }
788
789 dfs->dfs_status_timeout_override = status_timeout;
790
791 dfs_debug(dfs, WLAN_DEBUG_DFS_ALWAYS,
792 "Host wait status timeout is now %s : %d",
793 (status_timeout == -1) ? "default" : "overridden",
794 status_timeout);
795
796 return QDF_STATUS_SUCCESS;
797 }
798
dfs_get_override_status_timeout(struct wlan_dfs * dfs,int * status_timeout)799 QDF_STATUS dfs_get_override_status_timeout(struct wlan_dfs *dfs,
800 int *status_timeout)
801 {
802 if (!dfs) {
803 dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "dfs is NULL");
804 return QDF_STATUS_E_FAILURE;
805 }
806
807 *status_timeout = dfs->dfs_status_timeout_override;
808
809 return QDF_STATUS_SUCCESS;
810 }
811
812 /**
813 * dfs_extract_radar_found_params() - Copy the contents of average radar
814 * parameters to dfs_radar_found_params parameter structure.
815 *
816 * @dfs: Pointer to wlan_dfs structure which contains the average radar
817 * parameters.
818 * @params: Pointer to dfs_radar_found_params structure.
819 */
820 static
dfs_extract_radar_found_params(struct wlan_dfs * dfs,struct dfs_radar_found_params * params)821 void dfs_extract_radar_found_params(struct wlan_dfs *dfs,
822 struct dfs_radar_found_params *params)
823 {
824 qdf_mem_zero(params, sizeof(*params));
825 params->pri_min = dfs->dfs_average_pri;
826 params->pri_max = dfs->dfs_average_pri;
827 params->duration_min = dfs->dfs_average_duration;
828 params->duration_max = dfs->dfs_average_duration;
829 params->sidx_min = dfs->dfs_average_sidx;
830 params->sidx_max = dfs->dfs_average_sidx;
831
832 /* Bangradar will not populate any of these average
833 * parameters as pulse is not received. If these variables
834 * are not reset here, these go as radar_found params
835 * for bangradar if bangradar is issued after real radar.
836 */
837 dfs->dfs_average_sidx = 0;
838 dfs->dfs_average_duration = 0;
839 dfs->dfs_average_pri = 0;
840 }
841
dfs_radarfound_action_fcc(struct wlan_dfs * dfs,uint8_t seg_id)842 void dfs_radarfound_action_fcc(struct wlan_dfs *dfs, uint8_t seg_id)
843 {
844 struct dfs_radar_found_params params;
845
846 qdf_mem_copy(&dfs->dfs_radar_found_chan, dfs->dfs_curchan,
847 sizeof(dfs->dfs_radar_found_chan));
848 dfs_extract_radar_found_params(dfs, ¶ms);
849 dfs->dfs_is_host_wait_running = 1;
850 qdf_timer_mod(&dfs->dfs_host_wait_timer,
851 (dfs->dfs_status_timeout_override ==
852 -1) ? HOST_DFS_STATUS_WAIT_TIMER_MS :
853 dfs->dfs_status_timeout_override);
854 dfs->dfs_seg_id = seg_id;
855 dfs_send_avg_params_to_fw(dfs, ¶ms);
856 dfs_disable_radar_and_flush_pulses(dfs);
857 }
858
dfs_host_wait_timer_reset(struct wlan_dfs * dfs)859 void dfs_host_wait_timer_reset(struct wlan_dfs *dfs)
860 {
861 dfs->dfs_is_host_wait_running = 0;
862 qdf_timer_sync_cancel(&dfs->dfs_host_wait_timer);
863 }
864
865 /**
866 * dfs_action_on_spoof_success() - DFS action on spoof test pass
867 * @dfs: Pointer to DFS object
868 */
dfs_action_on_spoof_success(struct wlan_dfs * dfs)869 static void dfs_action_on_spoof_success(struct wlan_dfs *dfs)
870 {
871 dfs->dfs_spoof_test_done = 1;
872
873 /* On spoof success, enable the radar detection flags */
874 dfs_radar_enable(dfs, 0, 0);
875
876 if (dfs->dfs_radar_found_chan.dfs_ch_freq ==
877 dfs->dfs_curchan->dfs_ch_freq) {
878 dfs_debug(dfs, WLAN_DEBUG_DFS_ALWAYS,
879 "Handling spoof success on chan: %d",
880 dfs->dfs_curchan->dfs_ch_ieee);
881 dfs_mlme_proc_spoof_success(dfs->dfs_pdev_obj);
882 } else {
883 dfs_remove_spoof_channel_from_nol(dfs);
884 }
885 }
886
dfs_action_on_fw_radar_status_check(struct wlan_dfs * dfs,uint32_t * status)887 void dfs_action_on_fw_radar_status_check(struct wlan_dfs *dfs,
888 uint32_t *status)
889 {
890 struct wlan_objmgr_pdev *dfs_pdev;
891 int no_chans_avail = 0;
892 int error_flag = 0;
893
894 dfs_host_wait_timer_reset(dfs);
895 dfs_debug(dfs, WLAN_DEBUG_DFS_ALWAYS, "Host DFS status = %d",
896 *status);
897
898 dfs_pdev = dfs->dfs_pdev_obj;
899 if (!dfs_pdev) {
900 dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "dfs_pdev_obj is NULL");
901 return;
902 }
903
904 switch (*status) {
905 case HOST_DFS_STATUS_CHECK_PASSED:
906 if (dfs->dfs_average_params_sent)
907 dfs_action_on_spoof_success(dfs);
908 else
909 error_flag = 1;
910 break;
911 case HOST_DFS_STATUS_CHECK_FAILED:
912 dfs->dfs_spoof_check_failed = 1;
913 no_chans_avail =
914 dfs_mlme_rebuild_chan_list_with_non_dfs_channels(dfs_pdev);
915 dfs_mlme_restart_vaps_with_non_dfs_chan(dfs_pdev,
916 no_chans_avail);
917 break;
918 case HOST_DFS_STATUS_CHECK_HW_RADAR:
919 if (dfs->dfs_average_params_sent) {
920 if (dfs->dfs_radar_found_chan.dfs_ch_freq ==
921 dfs->dfs_curchan->dfs_ch_freq) {
922 dfs_radarfound_action_generic(
923 dfs,
924 dfs->dfs_seg_id);
925 } else {
926 /* Else of this case, no action is needed as
927 * dfs_action would have been done at timer
928 * expiry itself.
929 */
930 dfs_debug(dfs, WLAN_DEBUG_DFS_ALWAYS,
931 "DFS Action already taken");
932 }
933 } else {
934 error_flag = 1;
935 }
936 break;
937 default:
938 dfs_debug(dfs, WLAN_DEBUG_DFS_ALWAYS,
939 "Status event mismatch:%d, Ignoring it",
940 *status);
941 }
942
943 dfs->dfs_average_params_sent = 0;
944 qdf_mem_zero(&dfs->dfs_radar_found_chan, sizeof(struct dfs_channel));
945
946 if (error_flag == 1) {
947 dfs_debug(dfs, WLAN_DEBUG_DFS_ALWAYS,
948 "Received imroper response %d. Discarding it",
949 *status);
950 }
951 }
952
dfs_reset_spoof_test(struct wlan_dfs * dfs)953 void dfs_reset_spoof_test(struct wlan_dfs *dfs)
954 {
955 dfs->dfs_spoof_test_done = 0;
956 dfs->dfs_spoof_check_failed = 0;
957 }
958 #endif
959