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 staggered pulse */ 172 /* Type 5*/ 173 /* 0.8-2us, 2-3 bursts,300-400 PRF, 10 pulses each */ 174 {30, 2, 300, 400, 2, 30, 3, 0, 5, 15, 0, 0, 1, 5, 0, 31}, 175 /* Type 6 */ 176 /* 0.8-2us, 2-3 bursts, 400-1200 PRF, 15 pulses each */ 177 {30, 2, 400, 1200, 2, 30, 7, 0, 5, 15, 0, 0, 0, 5, 0, 32}, 178 179 /* constant PRF based */ 180 /* Type 1 */ 181 /* 0.8-5us, 200 300 PRF, 10 pulses */ 182 {10, 5, 200, 400, 0, 4, 5, 0, 8, 15, 0, 0, 2, 5, 0, 33}, 183 {10, 5, 400, 600, 0, 4, 5, 0, 8, 15, 0, 0, 2, 5, 0, 37}, 184 {10, 5, 600, 800, 0, 4, 5, 0, 8, 15, 0, 0, 2, 5, 0, 38}, 185 {10, 5, 800, 1000, 0, 4, 5, 0, 8, 15, 0, 0, 2, 5, 0, 39}, 186 /* {10, 5, 200, 1000, 0, 6, 5, 0, 8, 15, 0, 0, 2, 5, 33}, */ 187 188 /* Type 2 */ 189 /* 0.8-15us, 200-1600 PRF, 15 pulses */ 190 {15, 15, 200, 1600, 0, 4, 8, 0, 18, 24, 0, 0, 0, 5, 0, 34}, 191 192 /* Type 3 */ 193 /* 0.8-15us, 2300-4000 PRF, 25 pulses*/ 194 {25, 15, 2300, 4000, 0, 4, 10, 0, 18, 24, 0, 0, 0, 5, 0, 35}, 195 196 /* Type 4 */ 197 /* 20-30us, 2000-4000 PRF, 20 pulses*/ 198 {20, 30, 2000, 4000, 0, 4, 6, 19, 33, 24, 0, 0, 0, 24, 1, 36}, 199 }; 200 201 /** 202 * dfs_pulse dfs_china_radars - CHINA radar table. 203 */ 204 static struct dfs_pulse dfs_china_radars[] = { 205 206 /* TYPE staggered pulse */ 207 /* Type 5*/ 208 /* 0.8-2us, 2-3 bursts,300-400 PRF, 12 pulses each */ 209 {36, 2, 300, 400, 2, 30, 3, 0, 5, 15, 0, 0, 1, 51}, 210 /* Type 6 */ 211 /* 0.8-2us, 2-3 bursts, 400-1200 PRF, 16 pulses each */ 212 {48, 2, 400, 1200, 2, 30, 7, 0, 5, 15, 0, 0, 0, 52}, 213 214 /* constant PRF based */ 215 /* Type 1 */ 216 /* 0.5-5us, 200 1000 PRF, 12 pulses */ 217 {12, 5, 200, 400, 0, 24, 5, 0, 8, 15, 0, 0, 2, 53}, 218 {12, 5, 400, 600, 0, 24, 5, 0, 8, 15, 0, 0, 2, 57}, 219 {12, 5, 600, 800, 0, 24, 5, 0, 8, 15, 0, 0, 2, 58}, 220 {12, 5, 800, 1000, 0, 24, 5, 0, 8, 15, 0, 0, 2, 59}, 221 222 /* Type 2 */ 223 /* 0.5-15us, 200-1600 PRF, 16 pulses */ 224 {16, 15, 200, 1600, 0, 24, 8, 0, 18, 24, 0, 0, 0, 54}, 225 226 /* Type 3 */ 227 /* 0.5-30us, 2300-4000 PRF, 24 pulses*/ 228 {24, 15, 2300, 4000, 0, 24, 10, 0, 33, 24, 0, 0, 0, 55}, 229 230 /* Type 4 */ 231 /* 20-30us, 2000-4000 PRF, 20 pulses*/ 232 {20, 30, 2000, 4000, 0, 24, 6, 19, 33, 24, 0, 0, 0, 56}, 233 234 /* 1us, 1000 PRF, 20 pulses */ 235 /* 1000 us PRI */ 236 {20, 1, 1000, 1000, 0, 6, 6, 0, 1, 18, 0, 3, 0, 50}, 237 }; 238 239 /** 240 * dfs_pulse dfs_korea_radars - KOREA radar table. 241 */ 242 static struct dfs_pulse dfs_korea_radars[] = { 243 /* Korea Type 1 */ 244 {18, 1, 700, 700, 0, 4, 5, 0, 1, 18, 0, 3, 1, 5, 0, 40}, 245 246 /* Korea Type 2 */ 247 {10, 1, 1800, 1800, 0, 4, 4, 0, 1, 18, 0, 3, 1, 5, 0, 41}, 248 249 /* Korea Type 3 */ 250 {70, 1, 330, 330, 0, 4, 20, 0, 2, 18, 0, 3, 1, 5, 0, 42}, 251 252 /* Korea Type 4 */ 253 {3, 1, 3003, 3003, 1, 7, 2, 0, 1, 18, 0, 0, 1, 1000, 0, 43}, 254 }; 255 256 #define RSSI_THERSH_AR900B 15 257 258 /** 259 * dfs_assign_fcc_pulse_table() - Assign FCC pulse table 260 * @rinfo: Pointer to wlan_dfs_radar_tab_info structure. 261 * @target_type: Target type. 262 * @tx_ops: target tx ops. 263 */ 264 static inline void dfs_assign_fcc_pulse_table( 265 struct wlan_dfs_radar_tab_info *rinfo, 266 uint32_t target_type, 267 struct wlan_lmac_if_target_tx_ops *tx_ops) 268 { 269 rinfo->dfs_radars = dfs_fcc_radars; 270 rinfo->numradars = QDF_ARRAY_SIZE(dfs_fcc_radars); 271 272 if (tx_ops->tgt_is_tgt_type_ar900b(target_type) || 273 tx_ops->tgt_is_tgt_type_ipq4019(target_type)) { 274 rinfo->b5pulses = dfs_fcc_bin5pulses_ar900b; 275 rinfo->numb5radars = QDF_ARRAY_SIZE(dfs_fcc_bin5pulses_ar900b); 276 } else if (tx_ops->tgt_is_tgt_type_qca9984(target_type) || 277 tx_ops->tgt_is_tgt_type_qca9888(target_type)) { 278 rinfo->b5pulses = dfs_fcc_bin5pulses_qca9984; 279 rinfo->numb5radars = 280 QDF_ARRAY_SIZE(dfs_fcc_bin5pulses_qca9984); 281 } else { 282 rinfo->b5pulses = dfs_fcc_bin5pulses; 283 rinfo->numb5radars = QDF_ARRAY_SIZE(dfs_fcc_bin5pulses); 284 } 285 } 286 287 void dfs_get_po_radars(struct wlan_dfs *dfs) 288 { 289 struct wlan_dfs_radar_tab_info rinfo; 290 struct wlan_objmgr_psoc *psoc; 291 struct wlan_lmac_if_target_tx_ops *tx_ops; 292 int i; 293 uint32_t target_type; 294 int dfsdomain = DFS_FCC_DOMAIN; 295 296 /* Fetch current radar patterns from the lmac */ 297 qdf_mem_zero(&rinfo, sizeof(rinfo)); 298 299 /* 300 * Look up the current DFS regulatory domain and decide 301 * which radar pulses to use. 302 */ 303 dfsdomain = utils_get_dfsdomain(dfs->dfs_pdev_obj); 304 target_type = lmac_get_target_type(dfs->dfs_pdev_obj); 305 306 psoc = wlan_pdev_get_psoc(dfs->dfs_pdev_obj); 307 if (!psoc) { 308 dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "psoc is NULL"); 309 return; 310 } 311 312 tx_ops = &(psoc->soc_cb.tx_ops.target_tx_ops); 313 switch (dfsdomain) { 314 case DFS_FCC_DOMAIN: 315 dfs_debug(dfs, WLAN_DEBUG_DFS_ALWAYS, "FCC domain"); 316 rinfo.dfsdomain = DFS_FCC_DOMAIN; 317 dfs_assign_fcc_pulse_table(&rinfo, target_type, tx_ops); 318 break; 319 case DFS_CN_DOMAIN: 320 dfs_info(dfs, WLAN_DEBUG_DFS_ALWAYS, 321 "FCC domain -- Country China(156) override FCC radar pattern" 322 ); 323 rinfo.dfsdomain = DFS_FCC_DOMAIN; 324 /* 325 * China uses a radar pattern that is similar to ETSI but it 326 * follows FCC in all other respect like transmit power, CCA 327 * threshold etc. 328 */ 329 rinfo.dfs_radars = dfs_china_radars; 330 rinfo.numradars = QDF_ARRAY_SIZE(dfs_china_radars); 331 rinfo.b5pulses = NULL; 332 rinfo.numb5radars = 0; 333 break; 334 case DFS_ETSI_DOMAIN: 335 dfs_info(dfs, WLAN_DEBUG_DFS_ALWAYS, "ETSI domain"); 336 rinfo.dfsdomain = DFS_ETSI_DOMAIN; 337 338 if (dfs_is_en302_502_applicable(dfs)) { 339 rinfo.dfs_radars = dfs_etsi_radars; 340 rinfo.numradars = QDF_ARRAY_SIZE(dfs_etsi_radars); 341 } else { 342 uint8_t offset = ETSI_LEGACY_PULSE_ARR_OFFSET; 343 344 rinfo.dfs_radars = &dfs_etsi_radars[offset]; 345 rinfo.numradars = 346 QDF_ARRAY_SIZE(dfs_etsi_radars) - offset; 347 } 348 rinfo.b5pulses = NULL; 349 rinfo.numb5radars = 0; 350 break; 351 case DFS_KR_DOMAIN: 352 dfs_info(dfs, WLAN_DEBUG_DFS_ALWAYS, 353 "ETSI domain -- Korea(412)"); 354 rinfo.dfsdomain = DFS_ETSI_DOMAIN; 355 356 /* 357 * So far we have treated Korea as part of ETSI and did not 358 * support any radar patters specific to Korea other than 359 * standard ETSI radar patterns. Ideally we would want to 360 * treat Korea as a different domain. This is something that 361 * we will address in the future. However, for now override 362 * ETSI tables for Korea. 363 */ 364 rinfo.dfs_radars = dfs_korea_radars; 365 rinfo.numradars = QDF_ARRAY_SIZE(dfs_korea_radars); 366 rinfo.b5pulses = NULL; 367 rinfo.numb5radars = 0; 368 break; 369 case DFS_MKK4_DOMAIN: 370 dfs_info(dfs, WLAN_DEBUG_DFS_ALWAYS, "MKK4 domain"); 371 rinfo.dfsdomain = DFS_MKK4_DOMAIN; 372 rinfo.dfs_radars = dfs_mkk4_radars; 373 rinfo.numradars = QDF_ARRAY_SIZE(dfs_mkk4_radars); 374 375 if (tx_ops->tgt_is_tgt_type_ar900b(target_type) || 376 tx_ops->tgt_is_tgt_type_ipq4019(target_type)) { 377 rinfo.b5pulses = dfs_jpn_bin5pulses_ar900b; 378 rinfo.numb5radars = QDF_ARRAY_SIZE( 379 dfs_jpn_bin5pulses_ar900b); 380 } else if (tx_ops->tgt_is_tgt_type_qca9984(target_type) || 381 tx_ops->tgt_is_tgt_type_qca9888(target_type)) { 382 rinfo.b5pulses = dfs_jpn_bin5pulses_qca9984; 383 rinfo.numb5radars = QDF_ARRAY_SIZE 384 (dfs_jpn_bin5pulses_qca9984); 385 } else { 386 rinfo.b5pulses = dfs_jpn_bin5pulses; 387 rinfo.numb5radars = QDF_ARRAY_SIZE( 388 dfs_jpn_bin5pulses); 389 } 390 break; 391 default: 392 dfs_info(dfs, WLAN_DEBUG_DFS_ALWAYS, "UNINIT domain"); 393 rinfo.dfsdomain = DFS_UNINIT_DOMAIN; 394 rinfo.dfs_radars = NULL; 395 rinfo.numradars = 0; 396 rinfo.b5pulses = NULL; 397 rinfo.numb5radars = 0; 398 break; 399 } 400 401 if (tx_ops->tgt_is_tgt_type_ar900b(target_type) || 402 tx_ops->tgt_is_tgt_type_ipq4019(target_type) || 403 tx_ops->tgt_is_tgt_type_qca9984(target_type) || 404 tx_ops->tgt_is_tgt_type_qca9888(target_type)) { 405 /* Beeliner WAR: lower RSSI threshold to improve detection of 406 * certian radar types 407 */ 408 /* Cascade WAR: 409 * Cascade can report lower RSSI near the channel boundary then 410 * expected. It can also report significantly low RSSI at center 411 * (as low as 16) at center. So we are lowering threshold for 412 * all types of radar for * Cascade. 413 * This may increase the possibility of false radar detection. 414 * IR -- 083703, 083398, 083387 415 */ 416 417 for (i = 0; i < rinfo.numradars; i++) 418 rinfo.dfs_radars[i].rp_rssithresh = RSSI_THERSH_AR900B; 419 } 420 421 WLAN_DFS_DATA_STRUCT_LOCK(dfs); 422 dfs_init_radar_filters(dfs, &rinfo); 423 WLAN_DFS_DATA_STRUCT_UNLOCK(dfs); 424 } 425 426 #if defined(WLAN_DFS_PARTIAL_OFFLOAD) && defined(HOST_DFS_SPOOF_TEST) 427 void dfs_send_avg_params_to_fw(struct wlan_dfs *dfs, 428 struct dfs_radar_found_params *params) 429 { 430 tgt_dfs_send_avg_params_to_fw(dfs->dfs_pdev_obj, params); 431 } 432 433 /** 434 * dfs_no_res_from_fw_task() - The timer function that is called if there is no 435 * response from fw after sending the average radar pulse parameters. 436 */ 437 static os_timer_func(dfs_no_res_from_fw_task) 438 { 439 struct wlan_dfs *dfs = NULL; 440 441 OS_GET_TIMER_ARG(dfs, struct wlan_dfs *); 442 443 if (!dfs) { 444 dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "dfs is NULL"); 445 return; 446 } 447 448 dfs_info(dfs, WLAN_DEBUG_DFS_ALWAYS, "Host wait timer expired"); 449 450 dfs->dfs_is_host_wait_running = 0; 451 dfs->dfs_no_res_from_fw = 1; 452 dfs_radarfound_action_generic(dfs, dfs->dfs_seg_id); 453 dfs->dfs_seg_id = 0; 454 } 455 456 void dfs_host_wait_timer_init(struct wlan_dfs *dfs) 457 { 458 qdf_timer_init(NULL, 459 &(dfs->dfs_host_wait_timer), 460 dfs_no_res_from_fw_task, 461 (void *)(dfs), 462 QDF_TIMER_TYPE_WAKE_APPS); 463 dfs->dfs_status_timeout_override = -1; 464 } 465 466 QDF_STATUS dfs_set_override_status_timeout(struct wlan_dfs *dfs, 467 int status_timeout) 468 { 469 if (!dfs) { 470 dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "dfs is NULL"); 471 return QDF_STATUS_E_FAILURE; 472 } 473 474 dfs->dfs_status_timeout_override = status_timeout; 475 476 dfs_info(dfs, WLAN_DEBUG_DFS_ALWAYS, 477 "Host wait status timeout is now %s : %d", 478 (status_timeout == -1) ? "default" : "overridden", 479 status_timeout); 480 481 return QDF_STATUS_SUCCESS; 482 } 483 484 QDF_STATUS dfs_get_override_status_timeout(struct wlan_dfs *dfs, 485 int *status_timeout) 486 { 487 if (!dfs) { 488 dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "dfs is NULL"); 489 return QDF_STATUS_E_FAILURE; 490 } 491 492 *status_timeout = dfs->dfs_status_timeout_override; 493 494 return QDF_STATUS_SUCCESS; 495 } 496 497 /** 498 * dfs_extract_radar_found_params() - Copy the contents of average radar 499 * parameters to dfs_radar_found_params parameter structure. 500 * 501 * @dfs: Pointer to wlan_dfs structure which contains the average radar 502 * parameters. 503 * @params: Pointer to dfs_radar_found_params structure. 504 */ 505 static 506 void dfs_extract_radar_found_params(struct wlan_dfs *dfs, 507 struct dfs_radar_found_params *params) 508 { 509 qdf_mem_zero(params, sizeof(*params)); 510 params->pri_min = dfs->dfs_average_pri; 511 params->pri_max = dfs->dfs_average_pri; 512 params->duration_min = dfs->dfs_average_duration; 513 params->duration_max = dfs->dfs_average_duration; 514 params->sidx_min = dfs->dfs_average_sidx; 515 params->sidx_max = dfs->dfs_average_sidx; 516 517 /* Bangradar will not populate any of these average 518 * parameters as pulse is not received. If these variables 519 * are not resetted here, these go as radar_found params 520 * for bangradar if bangradar is issued after real radar. 521 */ 522 dfs->dfs_average_sidx = 0; 523 dfs->dfs_average_duration = 0; 524 dfs->dfs_average_pri = 0; 525 } 526 527 void dfs_radarfound_action_fcc(struct wlan_dfs *dfs, uint8_t seg_id) 528 { 529 struct dfs_radar_found_params params; 530 531 qdf_mem_copy(&dfs->dfs_radar_found_chan, dfs->dfs_curchan, 532 sizeof(dfs->dfs_radar_found_chan)); 533 dfs_extract_radar_found_params(dfs, ¶ms); 534 dfs_send_avg_params_to_fw(dfs, ¶ms); 535 dfs->dfs_is_host_wait_running = 1; 536 dfs->dfs_seg_id = seg_id; 537 qdf_timer_mod(&dfs->dfs_host_wait_timer, 538 (dfs->dfs_status_timeout_override == 539 -1) ? HOST_DFS_STATUS_WAIT_TIMER_MS : 540 dfs->dfs_status_timeout_override); 541 } 542 543 void dfs_host_wait_timer_reset(struct wlan_dfs *dfs) 544 { 545 dfs->dfs_is_host_wait_running = 0; 546 qdf_timer_sync_cancel(&dfs->dfs_host_wait_timer); 547 } 548 549 /** 550 * dfs_action_on_spoof_success() - DFS action on spoof test pass 551 * @dfs: Pointer to DFS object 552 */ 553 static void dfs_action_on_spoof_success(struct wlan_dfs *dfs) 554 { 555 dfs->dfs_spoof_test_done = 1; 556 if (dfs->dfs_radar_found_chan.dfs_ch_freq == 557 dfs->dfs_curchan->dfs_ch_freq) { 558 dfs_info(dfs, WLAN_DEBUG_DFS_ALWAYS, 559 "cac timer started for channel %d", 560 dfs->dfs_curchan->dfs_ch_ieee); 561 dfs_start_cac_timer(dfs); 562 } else{ 563 dfs_remove_spoof_channel_from_nol(dfs); 564 } 565 } 566 567 void dfs_action_on_fw_radar_status_check(struct wlan_dfs *dfs, 568 uint32_t *status) 569 { 570 struct wlan_objmgr_pdev *dfs_pdev; 571 int no_chans_avail = 0; 572 int error_flag = 0; 573 574 dfs_host_wait_timer_reset(dfs); 575 dfs_info(dfs, WLAN_DEBUG_DFS_ALWAYS, "Host DFS status = %d", 576 *status); 577 578 dfs_pdev = dfs->dfs_pdev_obj; 579 if (!dfs_pdev) { 580 dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "dfs_pdev_obj is NULL"); 581 return; 582 } 583 584 switch (*status) { 585 case HOST_DFS_STATUS_CHECK_PASSED: 586 if (dfs->dfs_average_params_sent) 587 dfs_action_on_spoof_success(dfs); 588 else 589 error_flag = 1; 590 break; 591 case HOST_DFS_STATUS_CHECK_FAILED: 592 dfs->dfs_spoof_check_failed = 1; 593 no_chans_avail = 594 dfs_mlme_rebuild_chan_list_with_non_dfs_channels(dfs_pdev); 595 dfs_mlme_restart_vaps_with_non_dfs_chan(dfs_pdev, 596 no_chans_avail); 597 break; 598 case HOST_DFS_STATUS_CHECK_HW_RADAR: 599 if (dfs->dfs_average_params_sent) { 600 if (dfs->dfs_radar_found_chan.dfs_ch_freq == 601 dfs->dfs_curchan->dfs_ch_freq) { 602 dfs_radarfound_action_generic( 603 dfs, 604 dfs->dfs_seg_id); 605 } else { 606 /* Else of this case, no action is needed as 607 * dfs_action would have been done at timer 608 * expiry itself. 609 */ 610 dfs_info(dfs, WLAN_DEBUG_DFS_ALWAYS, 611 "DFS Action already taken"); 612 } 613 } else { 614 error_flag = 1; 615 } 616 break; 617 default: 618 dfs_info(dfs, WLAN_DEBUG_DFS_ALWAYS, 619 "Status event mismatch:%d, Ignoring it", 620 *status); 621 } 622 623 dfs->dfs_average_params_sent = 0; 624 qdf_mem_zero(&dfs->dfs_radar_found_chan, sizeof(struct dfs_channel)); 625 626 if (error_flag == 1) { 627 dfs_info(dfs, WLAN_DEBUG_DFS_ALWAYS, 628 "Received imroper response %d. Discarding it", 629 *status); 630 } 631 } 632 633 void dfs_reset_spoof_test(struct wlan_dfs *dfs) 634 { 635 dfs->dfs_spoof_test_done = 0; 636 dfs->dfs_spoof_check_failed = 0; 637 } 638 #endif 639