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