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) && 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 * @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 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 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 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 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_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) && defined(HOST_DFS_SPOOF_TEST) 729 void dfs_send_avg_params_to_fw(struct wlan_dfs *dfs, 730 struct dfs_radar_found_params *params) 731 { 732 tgt_dfs_send_avg_params_to_fw(dfs->dfs_pdev_obj, params); 733 } 734 735 /* 736 * dfs_no_res_from_fw_task() - The timer function that is called if there is no 737 * response from fw after sending the average radar pulse parameters. 738 * 739 * NB: not using kernel-doc format since the kernel-doc script doesn't 740 * handle the os_timer_func() macro 741 */ 742 static os_timer_func(dfs_no_res_from_fw_task) 743 { 744 struct wlan_dfs *dfs = NULL; 745 746 OS_GET_TIMER_ARG(dfs, struct wlan_dfs *); 747 748 if (!dfs) { 749 dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "dfs is NULL"); 750 return; 751 } 752 753 dfs_debug(dfs, WLAN_DEBUG_DFS_ALWAYS, "Host wait timer expired"); 754 755 dfs->dfs_is_host_wait_running = 0; 756 dfs->dfs_no_res_from_fw = 1; 757 dfs_radarfound_action_generic(dfs, dfs->dfs_seg_id); 758 dfs->dfs_seg_id = 0; 759 } 760 761 void dfs_host_wait_timer_init(struct wlan_dfs *dfs) 762 { 763 qdf_timer_init(NULL, 764 &(dfs->dfs_host_wait_timer), 765 dfs_no_res_from_fw_task, 766 (void *)(dfs), 767 QDF_TIMER_TYPE_WAKE_APPS); 768 dfs->dfs_status_timeout_override = -1; 769 } 770 771 QDF_STATUS dfs_set_override_status_timeout(struct wlan_dfs *dfs, 772 int status_timeout) 773 { 774 if (!dfs) { 775 dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "dfs is NULL"); 776 return QDF_STATUS_E_FAILURE; 777 } 778 779 dfs->dfs_status_timeout_override = status_timeout; 780 781 dfs_debug(dfs, WLAN_DEBUG_DFS_ALWAYS, 782 "Host wait status timeout is now %s : %d", 783 (status_timeout == -1) ? "default" : "overridden", 784 status_timeout); 785 786 return QDF_STATUS_SUCCESS; 787 } 788 789 QDF_STATUS dfs_get_override_status_timeout(struct wlan_dfs *dfs, 790 int *status_timeout) 791 { 792 if (!dfs) { 793 dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "dfs is NULL"); 794 return QDF_STATUS_E_FAILURE; 795 } 796 797 *status_timeout = dfs->dfs_status_timeout_override; 798 799 return QDF_STATUS_SUCCESS; 800 } 801 802 /** 803 * dfs_extract_radar_found_params() - Copy the contents of average radar 804 * parameters to dfs_radar_found_params parameter structure. 805 * 806 * @dfs: Pointer to wlan_dfs structure which contains the average radar 807 * parameters. 808 * @params: Pointer to dfs_radar_found_params structure. 809 */ 810 static 811 void dfs_extract_radar_found_params(struct wlan_dfs *dfs, 812 struct dfs_radar_found_params *params) 813 { 814 qdf_mem_zero(params, sizeof(*params)); 815 params->pri_min = dfs->dfs_average_pri; 816 params->pri_max = dfs->dfs_average_pri; 817 params->duration_min = dfs->dfs_average_duration; 818 params->duration_max = dfs->dfs_average_duration; 819 params->sidx_min = dfs->dfs_average_sidx; 820 params->sidx_max = dfs->dfs_average_sidx; 821 822 /* Bangradar will not populate any of these average 823 * parameters as pulse is not received. If these variables 824 * are not reset here, these go as radar_found params 825 * for bangradar if bangradar is issued after real radar. 826 */ 827 dfs->dfs_average_sidx = 0; 828 dfs->dfs_average_duration = 0; 829 dfs->dfs_average_pri = 0; 830 } 831 832 void 833 dfs_disable_radar_and_flush_pulses(struct wlan_dfs *dfs) 834 { 835 dfs_radar_disable(dfs); 836 dfs_second_segment_radar_disable(dfs); 837 dfs_flush_additional_pulses(dfs); 838 } 839 840 void dfs_radarfound_action_fcc(struct wlan_dfs *dfs, uint8_t seg_id) 841 { 842 struct dfs_radar_found_params params; 843 844 qdf_mem_copy(&dfs->dfs_radar_found_chan, dfs->dfs_curchan, 845 sizeof(dfs->dfs_radar_found_chan)); 846 dfs_extract_radar_found_params(dfs, ¶ms); 847 dfs->dfs_is_host_wait_running = 1; 848 qdf_timer_mod(&dfs->dfs_host_wait_timer, 849 (dfs->dfs_status_timeout_override == 850 -1) ? HOST_DFS_STATUS_WAIT_TIMER_MS : 851 dfs->dfs_status_timeout_override); 852 dfs->dfs_seg_id = seg_id; 853 dfs_send_avg_params_to_fw(dfs, ¶ms); 854 dfs_disable_radar_and_flush_pulses(dfs); 855 } 856 857 void dfs_host_wait_timer_reset(struct wlan_dfs *dfs) 858 { 859 dfs->dfs_is_host_wait_running = 0; 860 qdf_timer_sync_cancel(&dfs->dfs_host_wait_timer); 861 } 862 863 /** 864 * dfs_action_on_spoof_success() - DFS action on spoof test pass 865 * @dfs: Pointer to DFS object 866 */ 867 static void dfs_action_on_spoof_success(struct wlan_dfs *dfs) 868 { 869 dfs->dfs_spoof_test_done = 1; 870 871 /* On spoof success, enable the radar detection flags */ 872 dfs_radar_enable(dfs, 0, 0); 873 874 if (dfs->dfs_radar_found_chan.dfs_ch_freq == 875 dfs->dfs_curchan->dfs_ch_freq) { 876 dfs_debug(dfs, WLAN_DEBUG_DFS_ALWAYS, 877 "Handling spoof success on chan: %d", 878 dfs->dfs_curchan->dfs_ch_ieee); 879 dfs_mlme_proc_spoof_success(dfs->dfs_pdev_obj); 880 } else { 881 dfs_remove_spoof_channel_from_nol(dfs); 882 } 883 } 884 885 void dfs_action_on_fw_radar_status_check(struct wlan_dfs *dfs, 886 uint32_t *status) 887 { 888 struct wlan_objmgr_pdev *dfs_pdev; 889 int no_chans_avail = 0; 890 int error_flag = 0; 891 892 dfs_host_wait_timer_reset(dfs); 893 dfs_debug(dfs, WLAN_DEBUG_DFS_ALWAYS, "Host DFS status = %d", 894 *status); 895 896 dfs_pdev = dfs->dfs_pdev_obj; 897 if (!dfs_pdev) { 898 dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "dfs_pdev_obj is NULL"); 899 return; 900 } 901 902 switch (*status) { 903 case HOST_DFS_STATUS_CHECK_PASSED: 904 if (dfs->dfs_average_params_sent) 905 dfs_action_on_spoof_success(dfs); 906 else 907 error_flag = 1; 908 break; 909 case HOST_DFS_STATUS_CHECK_FAILED: 910 dfs->dfs_spoof_check_failed = 1; 911 no_chans_avail = 912 dfs_mlme_rebuild_chan_list_with_non_dfs_channels(dfs_pdev); 913 dfs_mlme_restart_vaps_with_non_dfs_chan(dfs_pdev, 914 no_chans_avail); 915 break; 916 case HOST_DFS_STATUS_CHECK_HW_RADAR: 917 if (dfs->dfs_average_params_sent) { 918 if (dfs->dfs_radar_found_chan.dfs_ch_freq == 919 dfs->dfs_curchan->dfs_ch_freq) { 920 dfs_radarfound_action_generic( 921 dfs, 922 dfs->dfs_seg_id); 923 } else { 924 /* Else of this case, no action is needed as 925 * dfs_action would have been done at timer 926 * expiry itself. 927 */ 928 dfs_debug(dfs, WLAN_DEBUG_DFS_ALWAYS, 929 "DFS Action already taken"); 930 } 931 } else { 932 error_flag = 1; 933 } 934 break; 935 default: 936 dfs_debug(dfs, WLAN_DEBUG_DFS_ALWAYS, 937 "Status event mismatch:%d, Ignoring it", 938 *status); 939 } 940 941 dfs->dfs_average_params_sent = 0; 942 qdf_mem_zero(&dfs->dfs_radar_found_chan, sizeof(struct dfs_channel)); 943 944 if (error_flag == 1) { 945 dfs_debug(dfs, WLAN_DEBUG_DFS_ALWAYS, 946 "Received imroper response %d. Discarding it", 947 *status); 948 } 949 } 950 951 void dfs_reset_spoof_test(struct wlan_dfs *dfs) 952 { 953 dfs->dfs_spoof_test_done = 0; 954 dfs->dfs_spoof_check_failed = 0; 955 } 956 #endif 957