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