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