1 /* 2 * Copyright (c) 2016-2018 The Linux Foundation. All rights reserved. 3 * Copyright (c) 2002-2006, 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 contains the dfs_attach() and dfs_detach() functions as well 20 * as the dfs_control() function which is used to process ioctls related to DFS. 21 * For Linux/Mac, "radartool" is the command line tool that can be used to call 22 * various ioctls to set and get radar detection thresholds. 23 */ 24 25 #include "../dfs_zero_cac.h" 26 #include "wlan_dfs_lmac_api.h" 27 #include "wlan_dfs_mlme_api.h" 28 #include "wlan_dfs_tgt_api.h" 29 #include "../dfs_internal.h" 30 #include "../dfs_filter_init.h" 31 #include "../dfs_full_offload.h" 32 #include "wlan_dfs_utils_api.h" 33 #include "../dfs_etsi_precac.h" 34 #include "../dfs_partial_offload_radar.h" 35 36 /** 37 * dfs_testtimer_task() - Sends CSA in the current channel. 38 * 39 * When the user sets usenol to 0 and inject the RADAR, AP does not mark the 40 * channel as RADAR and does not add the channel to NOL. It sends the CSA in 41 * the current channel. 42 */ 43 static os_timer_func(dfs_testtimer_task) 44 { 45 struct wlan_dfs *dfs = NULL; 46 47 OS_GET_TIMER_ARG(dfs, struct wlan_dfs *); 48 dfs->wlan_dfstest = 0; 49 50 /* 51 * Flip the channel back to the original channel. 52 * Make sure this is done properly with a CSA. 53 */ 54 dfs_info(dfs, WLAN_DEBUG_DFS_ALWAYS, "go back to channel %d", 55 dfs->wlan_dfstest_ieeechan); 56 dfs_mlme_start_csa(dfs->dfs_pdev_obj, 57 dfs->wlan_dfstest_ieeechan, 58 dfs->dfs_curchan->dfs_ch_freq, 59 dfs->dfs_curchan->dfs_ch_vhtop_ch_freq_seg2, 60 dfs->dfs_curchan->dfs_ch_flags); 61 } 62 63 int dfs_get_debug_info(struct wlan_dfs *dfs, void *data) 64 { 65 if (data) 66 *(uint32_t *)data = dfs->dfs_proc_phyerr; 67 68 return (int)dfs->dfs_proc_phyerr; 69 } 70 71 void dfs_main_task_testtimer_init(struct wlan_dfs *dfs) 72 { 73 qdf_timer_init(NULL, 74 &(dfs->wlan_dfstesttimer), 75 dfs_testtimer_task, (void *)dfs, 76 QDF_TIMER_TYPE_WAKE_APPS); 77 } 78 79 int dfs_create_object(struct wlan_dfs **dfs) 80 { 81 *dfs = (struct wlan_dfs *)qdf_mem_malloc(sizeof(**dfs)); 82 if (!(*dfs)) { 83 dfs_alert(*dfs, WLAN_DEBUG_DFS_ALWAYS, "wlan_dfs allocation failed"); 84 return 1; 85 } 86 87 qdf_mem_zero(*dfs, sizeof(**dfs)); 88 89 (*dfs)->dfs_curchan = (struct dfs_channel *)qdf_mem_malloc( 90 sizeof(struct dfs_channel)); 91 92 if (!((*dfs)->dfs_curchan)) { 93 dfs_alert(*dfs, WLAN_DEBUG_DFS_ALWAYS, "dfs_curchan allocation failed"); 94 return 1; 95 } 96 97 return 0; 98 } 99 100 int dfs_attach(struct wlan_dfs *dfs) 101 { 102 int ret; 103 104 if (!dfs->dfs_is_offload_enabled) { 105 ret = dfs_main_attach(dfs); 106 107 /* 108 * For full offload we have a wmi handler registered to process 109 * a radar event from firmware in the event of a radar detect. 110 * So, init of timer, dfs_task is not required for 111 * full-offload. dfs_task timer is called in 112 * dfs_main_timer_init within dfs_main_attach for 113 * partial-offload in the event of radar detect. 114 */ 115 if (ret) { 116 dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "dfs_main_attach failed"); 117 return ret; 118 } 119 } 120 dfs_cac_attach(dfs); 121 dfs_zero_cac_attach(dfs); 122 dfs_etsi_precac_attach(dfs); 123 dfs_nol_attach(dfs); 124 dfs->dfs_use_nol_subchannel_marking = 1; 125 126 /* 127 * Init of timer ,dfs_testtimer_task is required by both partial 128 * and full offload, indicating test mode timer initialization for both. 129 */ 130 dfs_main_task_testtimer_init(dfs); 131 return 0; 132 } 133 134 void dfs_stop(struct wlan_dfs *dfs) 135 { 136 dfs_nol_timer_cleanup(dfs); 137 dfs_nol_workqueue_cleanup(dfs); 138 dfs_clear_nolhistory(dfs); 139 } 140 141 void dfs_task_testtimer_reset(struct wlan_dfs *dfs) 142 { 143 if (dfs->wlan_dfstest) { 144 qdf_timer_sync_cancel(&dfs->wlan_dfstesttimer); 145 dfs->wlan_dfstest = 0; 146 } 147 } 148 149 void dfs_task_testtimer_detach(struct wlan_dfs *dfs) 150 { 151 qdf_timer_free(&dfs->wlan_dfstesttimer); 152 dfs->wlan_dfstest = 0; 153 } 154 155 void dfs_reset(struct wlan_dfs *dfs) 156 { 157 if (!dfs) { 158 dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "dfs is NULL"); 159 return; 160 } 161 162 dfs_cac_timer_reset(dfs); 163 dfs_zero_cac_reset(dfs); 164 if (!dfs->dfs_is_offload_enabled) { 165 dfs_main_timer_reset(dfs); 166 dfs_host_wait_timer_reset(dfs); 167 dfs->dfs_event_log_count = 0; 168 } 169 dfs_task_testtimer_reset(dfs); 170 } 171 172 void dfs_timer_detach(struct wlan_dfs *dfs) 173 { 174 dfs_cac_timer_detach(dfs); 175 dfs_zero_cac_timer_detach(dfs); 176 177 if (!dfs->dfs_is_offload_enabled) { 178 dfs_main_timer_detach(dfs); 179 dfs_host_wait_timer_detach(dfs); 180 } 181 182 dfs_task_testtimer_detach(dfs); 183 dfs_nol_timer_detach(dfs); 184 } 185 186 void dfs_detach(struct wlan_dfs *dfs) 187 { 188 dfs_timer_detach(dfs); 189 if (!dfs->dfs_is_offload_enabled) 190 dfs_main_detach(dfs); 191 dfs_etsi_precac_detach(dfs); 192 dfs_zero_cac_detach(dfs); 193 dfs_nol_detach(dfs); 194 } 195 196 void dfs_destroy_object(struct wlan_dfs *dfs) 197 { 198 qdf_mem_free(dfs->dfs_curchan); 199 qdf_mem_free(dfs); 200 } 201 202 int dfs_control(struct wlan_dfs *dfs, 203 u_int id, 204 void *indata, 205 uint32_t insize, 206 void *outdata, 207 uint32_t *outsize) 208 { 209 struct wlan_dfs_phyerr_param peout; 210 struct dfs_ioctl_params *dfsparams; 211 struct dfs_bangradar_enh_params *bangradar_enh_params; 212 int error = 0; 213 uint32_t val = 0; 214 struct dfsreq_nolinfo *nol; 215 uint32_t *data = NULL; 216 int i; 217 struct dfs_emulate_bang_radar_test_cmd dfs_unit_test; 218 219 qdf_mem_zero(&dfs_unit_test, sizeof(dfs_unit_test)); 220 221 if (!dfs) { 222 dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS, "dfs is NULL"); 223 goto bad; 224 } 225 226 switch (id) { 227 case DFS_SET_THRESH: 228 if (insize < sizeof(struct dfs_ioctl_params) || !indata) { 229 dfs_debug(dfs, WLAN_DEBUG_DFS1, 230 "insize = %d, expected = %zu bytes, indata = %pK", 231 insize, 232 sizeof(struct dfs_ioctl_params), 233 indata); 234 error = -EINVAL; 235 break; 236 } 237 dfsparams = (struct dfs_ioctl_params *)indata; 238 if (!dfs_set_thresholds(dfs, DFS_PARAM_FIRPWR, 239 dfsparams->dfs_firpwr)) 240 error = -EINVAL; 241 if (!dfs_set_thresholds(dfs, DFS_PARAM_RRSSI, 242 dfsparams->dfs_rrssi)) 243 error = -EINVAL; 244 if (!dfs_set_thresholds(dfs, DFS_PARAM_HEIGHT, 245 dfsparams->dfs_height)) 246 error = -EINVAL; 247 if (!dfs_set_thresholds(dfs, DFS_PARAM_PRSSI, 248 dfsparams->dfs_prssi)) 249 error = -EINVAL; 250 if (!dfs_set_thresholds(dfs, DFS_PARAM_INBAND, 251 dfsparams->dfs_inband)) 252 error = -EINVAL; 253 254 /* 5413 speicfic. */ 255 if (!dfs_set_thresholds(dfs, DFS_PARAM_RELPWR, 256 dfsparams->dfs_relpwr)) 257 error = -EINVAL; 258 if (!dfs_set_thresholds(dfs, DFS_PARAM_RELSTEP, 259 dfsparams->dfs_relstep)) 260 error = -EINVAL; 261 if (!dfs_set_thresholds(dfs, DFS_PARAM_MAXLEN, 262 dfsparams->dfs_maxlen)) 263 error = -EINVAL; 264 break; 265 case DFS_BANGRADAR_ENH: 266 if (insize < sizeof(struct dfs_bangradar_enh_params) || 267 !indata) { 268 dfs_debug(dfs, WLAN_DEBUG_DFS1, 269 "insize = %d, expected = %zu bytes, indata = %pK", 270 insize, 271 sizeof(struct dfs_bangradar_enh_params), 272 indata); 273 error = -EINVAL; 274 break; 275 } 276 bangradar_enh_params = 277 (struct dfs_bangradar_enh_params *)indata; 278 if (bangradar_enh_params) { 279 dfs->dfs_seg_id = bangradar_enh_params->seg_id; 280 dfs->dfs_is_chirp = bangradar_enh_params->is_chirp; 281 dfs->dfs_freq_offset = 282 bangradar_enh_params->freq_offset; 283 dfs->dfs_enhanced_bangradar = 1; 284 285 if (dfs->dfs_is_offload_enabled) { 286 error = dfs_fill_emulate_bang_radar_test 287 (dfs, SEG_ID_PRIMARY, 288 &dfs_unit_test); 289 } else { 290 dfs->dfs_bangradar = 1; 291 error = dfs_start_host_based_bangradar(dfs); 292 } 293 } else { 294 dfs_info(dfs, WLAN_DEBUG_DFS_ALWAYS, "bangradar_enh_params is NULL"); 295 } 296 297 break; 298 case DFS_GET_THRESH: 299 if (!outdata || !outsize || 300 *outsize < sizeof(struct dfs_ioctl_params)) { 301 error = -EINVAL; 302 break; 303 } 304 *outsize = sizeof(struct dfs_ioctl_params); 305 dfsparams = (struct dfs_ioctl_params *) outdata; 306 307 /* Fetch the DFS thresholds using the internal representation */ 308 (void) dfs_get_thresholds(dfs, &peout); 309 310 /* Convert them to the dfs IOCTL representation. */ 311 wlan_dfs_dfsparam_to_ioctlparam(&peout, dfsparams); 312 break; 313 case DFS_RADARDETECTS: 314 if (!outdata || !outsize || *outsize < sizeof(uint32_t)) { 315 error = -EINVAL; 316 break; 317 } 318 *outsize = sizeof(uint32_t); 319 *((uint32_t *)outdata) = dfs->wlan_dfs_stats.num_radar_detects; 320 break; 321 case DFS_DISABLE_DETECT: 322 dfs->dfs_proc_phyerr &= ~DFS_RADAR_EN; 323 dfs->dfs_proc_phyerr &= ~DFS_SECOND_SEGMENT_RADAR_EN; 324 dfs->dfs_ignore_dfs = 1; 325 dfs_info(dfs, WLAN_DEBUG_DFS_ALWAYS, 326 "enable detects, ignore_dfs %d", 327 dfs->dfs_ignore_dfs ? 1:0); 328 break; 329 case DFS_ENABLE_DETECT: 330 dfs->dfs_proc_phyerr |= DFS_RADAR_EN; 331 dfs->dfs_proc_phyerr |= DFS_SECOND_SEGMENT_RADAR_EN; 332 dfs->dfs_ignore_dfs = 0; 333 dfs_info(dfs, WLAN_DEBUG_DFS_ALWAYS 334 , "enable detects, ignore_dfs %d", 335 dfs->dfs_ignore_dfs ? 1:0); 336 break; 337 case DFS_DISABLE_FFT: 338 dfs_info(dfs, WLAN_DEBUG_DFS_ALWAYS, 339 "TODO disable FFT val=0x%x", val); 340 break; 341 case DFS_ENABLE_FFT: 342 dfs_info(dfs, WLAN_DEBUG_DFS_ALWAYS, 343 "TODO enable FFT val=0x%x", val); 344 break; 345 case DFS_SET_DEBUG_LEVEL: 346 if (insize < sizeof(uint32_t) || !indata) { 347 error = -EINVAL; 348 break; 349 } 350 dfs->dfs_debug_mask = *(uint32_t *)indata; 351 352 /* Do not allow user to set the ALWAYS/MAX bit. 353 * It will be used internally by dfs print macro(s) 354 * to print messages when dfs is NULL. 355 */ 356 dfs->dfs_debug_mask &= ~(WLAN_DEBUG_DFS_ALWAYS); 357 358 dfs_info(dfs, WLAN_DEBUG_DFS_ALWAYS, 359 "debug level now = 0x%x", dfs->dfs_debug_mask); 360 if (dfs->dfs_debug_mask & WLAN_DEBUG_DFS3) { 361 /* Enable debug Radar Event */ 362 dfs->dfs_event_log_on = 1; 363 } else if ((utils_get_dfsdomain(dfs->dfs_pdev_obj) == 364 DFS_FCC_DOMAIN) && 365 lmac_is_host_dfs_check_support_enabled(dfs->dfs_pdev_obj)) { 366 dfs->dfs_event_log_on = 1; 367 } else { 368 dfs->dfs_event_log_on = 0; 369 } 370 break; 371 case DFS_SET_FALSE_RSSI_THRES: 372 if (insize < sizeof(uint32_t) || !indata) { 373 error = -EINVAL; 374 break; 375 } 376 dfs->wlan_dfs_false_rssi_thres = *(uint32_t *)indata; 377 dfs_info(dfs, WLAN_DEBUG_DFS_ALWAYS, 378 "false RSSI threshold now = 0x%x", 379 dfs->wlan_dfs_false_rssi_thres); 380 break; 381 case DFS_SET_PEAK_MAG: 382 if (insize < sizeof(uint32_t) || !indata) { 383 error = -EINVAL; 384 break; 385 } 386 dfs->wlan_dfs_peak_mag = *(uint32_t *)indata; 387 dfs_info(dfs, WLAN_DEBUG_DFS_ALWAYS, 388 "peak_mag now = 0x%x", 389 dfs->wlan_dfs_peak_mag); 390 break; 391 case DFS_GET_CAC_VALID_TIME: 392 if (!outdata || !outsize || *outsize < sizeof(uint32_t)) { 393 error = -EINVAL; 394 break; 395 } 396 *outsize = sizeof(uint32_t); 397 *((uint32_t *)outdata) = dfs->dfs_cac_valid_time; 398 break; 399 case DFS_SET_CAC_VALID_TIME: 400 if (insize < sizeof(uint32_t) || !indata) { 401 error = -EINVAL; 402 break; 403 } 404 dfs->dfs_cac_valid_time = *(uint32_t *)indata; 405 dfs_info(dfs, WLAN_DEBUG_DFS_ALWAYS, 406 "dfs timeout = %d", dfs->dfs_cac_valid_time); 407 break; 408 case DFS_IGNORE_CAC: 409 if (insize < sizeof(uint32_t) || !indata) { 410 error = -EINVAL; 411 break; 412 } 413 414 if (*(uint32_t *)indata) 415 dfs->dfs_ignore_cac = 1; 416 else 417 dfs->dfs_ignore_cac = 0; 418 419 dfs_info(dfs, WLAN_DEBUG_DFS_ALWAYS, 420 "ignore cac = 0x%x", dfs->dfs_ignore_cac); 421 break; 422 case DFS_SET_NOL_TIMEOUT: 423 if (insize < sizeof(uint32_t) || !indata) { 424 error = -EINVAL; 425 break; 426 } 427 if (*(int *)indata) 428 dfs->wlan_dfs_nol_timeout = *(int *)indata; 429 else 430 dfs->wlan_dfs_nol_timeout = DFS_NOL_TIMEOUT_S; 431 432 dfs_info(dfs, WLAN_DEBUG_DFS_ALWAYS, "nol timeout = %d sec", 433 dfs->wlan_dfs_nol_timeout); 434 break; 435 case DFS_MUTE_TIME: 436 if (insize < sizeof(uint32_t) || !indata) { 437 error = -EINVAL; 438 break; 439 } 440 data = (uint32_t *) indata; 441 dfs->wlan_dfstesttime = *data; 442 dfs->wlan_dfstesttime *= (1000); /* convert sec into ms */ 443 break; 444 case DFS_GET_USENOL: 445 if (!outdata || !outsize || *outsize < sizeof(uint32_t)) { 446 error = -EINVAL; 447 break; 448 } 449 *outsize = sizeof(uint32_t); 450 *((uint32_t *)outdata) = dfs->dfs_use_nol; 451 452 dfs_info(dfs, WLAN_DEBUG_DFS_ALWAYS, 453 "#Phyerr=%d, #false detect=%d, #queued=%d", 454 dfs->dfs_phyerr_count, 455 dfs->dfs_phyerr_reject_count, 456 dfs->dfs_phyerr_queued_count); 457 458 dfs_info(dfs, WLAN_DEBUG_DFS_ALWAYS, 459 "dfs_phyerr_freq_min=%d, dfs_phyerr_freq_max=%d", 460 dfs->dfs_phyerr_freq_min, 461 dfs->dfs_phyerr_freq_max); 462 463 dfs_info(dfs, WLAN_DEBUG_DFS_ALWAYS, 464 "Total radar events detected=%d, entries in the radar queue follows:", 465 dfs->dfs_event_log_count); 466 467 for (i = 0; (i < DFS_EVENT_LOG_SIZE) && 468 (i < dfs->dfs_event_log_count); i++) { 469 #define FREQ_OFFSET1 ((int)dfs->radar_log[i].freq_offset_khz / 1000) 470 #define FREQ_OFFSET2 ((int)abs(dfs->radar_log[i].freq_offset_khz) % 1000) 471 dfs_debug(dfs, WLAN_DEBUG_DFS, 472 "ts=%llu diff_ts=%u rssi=%u dur=%u, is_chirp=%d, seg_id=%d, sidx=%d, freq_offset=%d.%dMHz, peak_mag=%d, total_gain=%d, mb_gain=%d, relpwr_db=%d, delta_diff=%d, delta_peak=%d, psidx_diff=%d\n", 473 dfs->radar_log[i].ts, 474 dfs->radar_log[i].diff_ts, 475 dfs->radar_log[i].rssi, 476 dfs->radar_log[i].dur, 477 dfs->radar_log[i].is_chirp, 478 dfs->radar_log[i].seg_id, 479 dfs->radar_log[i].sidx, 480 FREQ_OFFSET1, 481 FREQ_OFFSET2, 482 dfs->radar_log[i].peak_mag, 483 dfs->radar_log[i].total_gain, 484 dfs->radar_log[i].mb_gain, 485 dfs->radar_log[i].relpwr_db, 486 dfs->radar_log[i].delta_diff, 487 dfs->radar_log[i].delta_peak, 488 dfs->radar_log[i].psidx_diff); 489 } 490 dfs->dfs_event_log_count = 0; 491 dfs->dfs_phyerr_count = 0; 492 dfs->dfs_phyerr_reject_count = 0; 493 dfs->dfs_phyerr_queued_count = 0; 494 dfs->dfs_phyerr_freq_min = 0x7fffffff; 495 dfs->dfs_phyerr_freq_max = 0; 496 break; 497 case DFS_SET_USENOL: 498 if (insize < sizeof(uint32_t) || !indata) { 499 error = -EINVAL; 500 break; 501 } 502 dfs->dfs_use_nol = *(uint32_t *)indata; 503 break; 504 case DFS_GET_NOL: 505 if (!outdata || !outsize || 506 *outsize < sizeof(struct dfsreq_nolinfo)) { 507 error = -EINVAL; 508 break; 509 } 510 *outsize = sizeof(struct dfsreq_nolinfo); 511 nol = (struct dfsreq_nolinfo *)outdata; 512 DFS_GET_NOL_LOCKED(dfs, 513 (struct dfsreq_nolelem *)nol->dfs_nol, 514 &nol->dfs_ch_nchans); 515 DFS_PRINT_NOL_LOCKED(dfs); 516 break; 517 case DFS_SET_NOL: 518 if (insize < sizeof(struct dfsreq_nolinfo) || !indata) { 519 error = -EINVAL; 520 break; 521 } 522 nol = (struct dfsreq_nolinfo *) indata; 523 dfs_set_nol(dfs, 524 (struct dfsreq_nolelem *)nol->dfs_nol, 525 nol->dfs_ch_nchans); 526 break; 527 case DFS_SHOW_NOL: 528 DFS_PRINT_NOL_LOCKED(dfs); 529 break; 530 case DFS_SHOW_NOLHISTORY: 531 dfs_print_nolhistory(dfs); 532 break; 533 case DFS_BANGRADAR: 534 if (dfs->dfs_is_offload_enabled) { 535 error = dfs_fill_emulate_bang_radar_test(dfs, 536 SEG_ID_PRIMARY, 537 &dfs_unit_test); 538 } else { 539 dfs->dfs_bangradar = 1; 540 error = dfs_start_host_based_bangradar(dfs); 541 } 542 break; 543 case DFS_SHOW_PRECAC_LISTS: 544 dfs_print_precaclists(dfs); 545 dfs_print_etsi_precaclists(dfs); 546 break; 547 case DFS_RESET_PRECAC_LISTS: 548 dfs_reset_precac_lists(dfs); 549 dfs_reset_etsi_precac_lists(dfs); 550 break; 551 case DFS_SECOND_SEGMENT_BANGRADAR: 552 if (dfs->dfs_is_offload_enabled) { 553 error = dfs_fill_emulate_bang_radar_test(dfs, 554 SEG_ID_SECONDARY, 555 &dfs_unit_test); 556 } else { 557 dfs->dfs_second_segment_bangradar = 1; 558 error = dfs_start_host_based_bangradar(dfs); 559 } 560 break; 561 default: 562 error = -EINVAL; 563 } 564 565 bad: 566 return error; 567 } 568 569 void dfs_set_current_channel(struct wlan_dfs *dfs, 570 uint16_t dfs_ch_freq, 571 uint64_t dfs_ch_flags, 572 uint16_t dfs_ch_flagext, 573 uint8_t dfs_ch_ieee, 574 uint8_t dfs_ch_vhtop_ch_freq_seg1, 575 uint8_t dfs_ch_vhtop_ch_freq_seg2) 576 { 577 if (!dfs) { 578 dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "dfs is NULL"); 579 return; 580 } 581 582 dfs->dfs_curchan->dfs_ch_freq = dfs_ch_freq; 583 dfs->dfs_curchan->dfs_ch_flags = dfs_ch_flags; 584 dfs->dfs_curchan->dfs_ch_flagext = dfs_ch_flagext; 585 dfs->dfs_curchan->dfs_ch_ieee = dfs_ch_ieee; 586 dfs->dfs_curchan->dfs_ch_vhtop_ch_freq_seg1 = dfs_ch_vhtop_ch_freq_seg1; 587 dfs->dfs_curchan->dfs_ch_vhtop_ch_freq_seg2 = dfs_ch_vhtop_ch_freq_seg2; 588 } 589 590 void dfs_update_cur_chan_flags(struct wlan_dfs *dfs, 591 uint64_t flags, 592 uint16_t flagext) 593 { 594 dfs->dfs_curchan->dfs_ch_flags = flags; 595 dfs->dfs_curchan->dfs_ch_flagext = flagext; 596 } 597