1 /* 2 * Copyright (c) 2016-2021 The Linux Foundation. All rights reserved. 3 * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. 4 * 5 * Permission to use, copy, modify, and/or distribute this software for 6 * any purpose with or without fee is hereby granted, provided that the 7 * above copyright notice and this permission notice appear in all 8 * copies. 9 * 10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL 11 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED 12 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE 13 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL 14 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR 15 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 16 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 17 * PERFORMANCE OF THIS SOFTWARE. 18 */ 19 20 /** 21 * DOC: This file init/deint functions for DFS module. 22 */ 23 24 #include "wlan_dfs_ucfg_api.h" 25 #include "wlan_dfs_tgt_api.h" 26 #include <wlan_objmgr_vdev_obj.h> 27 #include "wlan_dfs_utils_api.h" 28 #ifndef MOBILE_DFS_SUPPORT 29 #include "ieee80211_mlme_dfs_interface.h" 30 #endif 31 #include "wlan_objmgr_global_obj.h" 32 #include "wlan_dfs_init_deinit_api.h" 33 #include "wlan_dfs_lmac_api.h" 34 #include "../../core/src/dfs.h" 35 #include "a_types.h" 36 #include "wlan_serialization_api.h" 37 #include <qdf_trace.h> 38 #include "wlan_scan_ucfg_api.h" 39 #include "wlan_dfs_mlme_api.h" 40 #include "../../core/src/dfs_zero_cac.h" 41 42 struct dfs_to_mlme global_dfs_to_mlme; 43 44 struct wlan_dfs *wlan_pdev_get_dfs_obj(struct wlan_objmgr_pdev *pdev) 45 { 46 struct wlan_dfs *dfs; 47 dfs = wlan_objmgr_pdev_get_comp_private_obj(pdev, 48 WLAN_UMAC_COMP_DFS); 49 50 return dfs; 51 } 52 53 /* 54 * register_dfs_precac_auto_chan_callbacks_freq() - Register auto chan switch 55 * frequency based APIs callback. 56 * @mlme_callback: Pointer to dfs_to_mlme. 57 */ 58 #ifndef MOBILE_DFS_SUPPORT 59 #if defined(WLAN_DFS_PRECAC_AUTO_CHAN_SUPPORT) && defined(CONFIG_CHAN_FREQ_API) 60 static inline void 61 register_dfs_precac_auto_chan_callbacks_freq(struct dfs_to_mlme *mlme_callback) 62 { 63 if (!mlme_callback) 64 return; 65 66 mlme_callback->mlme_precac_chan_change_csa_for_freq = 67 mlme_dfs_precac_chan_change_csa_for_freq; 68 } 69 #else 70 static inline void 71 register_dfs_precac_auto_chan_callbacks_freq(struct dfs_to_mlme *mlme_callback) 72 { 73 } 74 #endif 75 #endif 76 77 /** 78 * register_dfs_postnol_csa_callback - Register CSA callback 79 * @mlme_callback: Pointer to dfs_to_mlme. 80 */ 81 #ifndef MOBILE_DFS_SUPPORT 82 #if defined(QCA_SUPPORT_DFS_CHAN_POSTNOL) || defined(QCA_DFS_BW_EXPAND) 83 static inline void 84 register_dfs_postnol_csa_callback(struct dfs_to_mlme *mlme_callback) 85 { 86 if (!mlme_callback) 87 return; 88 89 mlme_callback->mlme_postnol_chan_switch = 90 mlme_dfs_postnol_chan_switch; 91 } 92 #else 93 static inline void 94 register_dfs_postnol_csa_callback(struct dfs_to_mlme *mlme_callback) 95 { 96 } 97 #endif 98 #endif 99 100 /* 101 * register_dfs_callbacks_for_freq() - Register dfs callbacks. 102 * @mlme_callback: Pointer to dfs_to_mlme. 103 */ 104 #ifndef MOBILE_DFS_SUPPORT 105 #ifdef CONFIG_CHAN_FREQ_API 106 static inline void 107 register_dfs_callbacks_for_freq(struct dfs_to_mlme *mlme_callback) 108 { 109 if (!mlme_callback) 110 return; 111 112 mlme_callback->mlme_find_dot11_chan_for_freq = 113 mlme_dfs_find_dot11_chan_for_freq; 114 mlme_callback->mlme_get_cac_timeout_for_freq = 115 mlme_dfs_get_cac_timeout_for_freq; 116 mlme_callback->mlme_get_extchan_for_freq = 117 mlme_dfs_get_extchan_for_freq; 118 mlme_callback->mlme_start_csa_for_freq = mlme_dfs_start_csa_for_freq; 119 } 120 #endif 121 #endif 122 123 #if defined(WLAN_DFS_PARTIAL_OFFLOAD) && defined(HOST_DFS_SPOOF_TEST) 124 static void register_dfs_callbacks_spoof_success_failure( 125 struct dfs_to_mlme *tmp_dfs_to_mlme) 126 { 127 tmp_dfs_to_mlme->mlme_rebuild_chan_list_with_non_dfs_channels = 128 mlme_dfs_rebuild_chan_list_with_non_dfs_channels; 129 tmp_dfs_to_mlme->mlme_proc_spoof_success = 130 mlme_dfs_proc_spoof_success; 131 } 132 #else 133 static inline void register_dfs_callbacks_spoof_success_failure( 134 struct dfs_to_mlme *tmp_dfs_to_mlme) 135 { 136 } 137 #endif 138 139 #ifndef MOBILE_DFS_SUPPORT 140 void register_dfs_callbacks(void) 141 { 142 struct dfs_to_mlme *tmp_dfs_to_mlme = &global_dfs_to_mlme; 143 144 tmp_dfs_to_mlme->pdev_component_obj_attach = 145 wlan_objmgr_pdev_component_obj_attach; 146 tmp_dfs_to_mlme->pdev_component_obj_detach = 147 wlan_objmgr_pdev_component_obj_detach; 148 149 tmp_dfs_to_mlme->dfs_start_rcsa = mlme_dfs_start_rcsa; 150 tmp_dfs_to_mlme->mlme_proc_cac = mlme_dfs_proc_cac; 151 tmp_dfs_to_mlme->mlme_deliver_event_up_after_cac = 152 mlme_dfs_deliver_event_up_after_cac; 153 tmp_dfs_to_mlme->mlme_set_no_chans_available = 154 mlme_dfs_set_no_chans_available; 155 tmp_dfs_to_mlme->mlme_ieee2mhz = mlme_dfs_ieee2mhz; 156 tmp_dfs_to_mlme->mlme_dfs_ch_flags_ext = mlme_dfs_dfs_ch_flags_ext; 157 tmp_dfs_to_mlme->mlme_channel_change_by_precac = 158 mlme_dfs_channel_change_by_precac; 159 tmp_dfs_to_mlme->mlme_nol_timeout_notification = 160 mlme_dfs_nol_timeout_notification; 161 tmp_dfs_to_mlme->mlme_clist_update = mlme_dfs_clist_update; 162 163 register_dfs_callbacks_spoof_success_failure(tmp_dfs_to_mlme); 164 165 tmp_dfs_to_mlme->mlme_restart_vaps_with_non_dfs_chan = 166 mlme_dfs_restart_vaps_with_non_dfs_chan; 167 tmp_dfs_to_mlme->mlme_is_opmode_sta = 168 mlme_dfs_is_opmode_sta; 169 tmp_dfs_to_mlme->mlme_check_allowed_prim_chanlist = 170 mlme_dfs_check_allowed_prim_chanlist; 171 tmp_dfs_to_mlme->mlme_update_scan_channel_list = 172 mlme_dfs_update_scan_channel_list; 173 tmp_dfs_to_mlme->mlme_bringdown_vaps = 174 mlme_dfs_bringdown_vaps; 175 tmp_dfs_to_mlme->mlme_dfs_deliver_event = 176 mlme_dfs_deliver_event; 177 tmp_dfs_to_mlme->mlme_is_inter_band_chan_switch_allowed = 178 mlme_is_inter_band_chan_switch_allowed; 179 180 tmp_dfs_to_mlme->mlme_acquire_radar_mode_switch_lock = 181 mlme_acquire_radar_mode_switch_lock; 182 tmp_dfs_to_mlme->mlme_release_radar_mode_switch_lock = 183 mlme_release_radar_mode_switch_lock; 184 tmp_dfs_to_mlme->mlme_mark_dfs = 185 mlme_dfs_mark_dfs; 186 /* 187 * Register precac auto channel switch feature related callbacks 188 */ 189 register_dfs_precac_auto_chan_callbacks_freq(tmp_dfs_to_mlme); 190 /* Register freq based callbacks */ 191 register_dfs_callbacks_for_freq(tmp_dfs_to_mlme); 192 register_dfs_postnol_csa_callback(tmp_dfs_to_mlme); 193 } 194 #else 195 void register_dfs_callbacks(void) 196 { 197 struct dfs_to_mlme *tmp_dfs_to_mlme = &global_dfs_to_mlme; 198 199 tmp_dfs_to_mlme->pdev_component_obj_attach = 200 wlan_objmgr_pdev_component_obj_attach; 201 tmp_dfs_to_mlme->pdev_component_obj_detach = 202 wlan_objmgr_pdev_component_obj_detach; 203 } 204 #endif 205 206 /** 207 * dfs_psoc_obj_create_notification() - dfs psoc create notification handler 208 * @psoc: psoc object 209 * @arg_list: Argument list 210 * 211 * Return: QDF_STATUS 212 */ 213 static QDF_STATUS dfs_psoc_obj_create_notification(struct wlan_objmgr_psoc *psoc, 214 void *arg_list) 215 { 216 QDF_STATUS status; 217 struct dfs_soc_priv_obj *dfs_soc_obj; 218 219 dfs_soc_obj = qdf_mem_malloc(sizeof(*dfs_soc_obj)); 220 if (!dfs_soc_obj) 221 return QDF_STATUS_E_NOMEM; 222 223 dfs_soc_obj->psoc = psoc; 224 225 status = wlan_objmgr_psoc_component_obj_attach(psoc, 226 WLAN_UMAC_COMP_DFS, 227 (void *)dfs_soc_obj, 228 QDF_STATUS_SUCCESS); 229 230 if (QDF_IS_STATUS_ERROR(status)) { 231 dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS, 232 "Failed to attach psoc dfs component"); 233 qdf_mem_free(dfs_soc_obj); 234 return status; 235 } 236 /* Initialize precac timer here*/ 237 dfs_zero_cac_timer_init(dfs_soc_obj); 238 239 /* Initialize Rolling CAC timer */ 240 dfs_rcac_timer_init(dfs_soc_obj); 241 242 /* DFS Agile SM initialization */ 243 dfs_agile_sm_create(dfs_soc_obj); 244 245 dfs_debug(NULL, WLAN_DEBUG_DFS1, 246 "DFS obj attach to psoc successfully"); 247 248 return status; 249 } 250 251 /** 252 * dfs_psoc_obj_destroy_notification() - dfs psoc destroy notification handler 253 * @psoc: psoc object 254 * @arg_list: Argument list 255 * 256 * Return: QDF_STATUS 257 */ 258 static QDF_STATUS dfs_psoc_obj_destroy_notification(struct wlan_objmgr_psoc *psoc, 259 void *arg_list) 260 { 261 QDF_STATUS status; 262 struct dfs_soc_priv_obj *dfs_soc_obj; 263 264 dfs_soc_obj = wlan_objmgr_psoc_get_comp_private_obj(psoc, 265 WLAN_UMAC_COMP_DFS); 266 if (!dfs_soc_obj) { 267 dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS, 268 "Failed to get dfs obj in psoc"); 269 return QDF_STATUS_E_FAILURE; 270 } 271 272 /* Delete DFS Agile SM */ 273 dfs_agile_sm_destroy(dfs_soc_obj); 274 275 dfs_rcac_timer_deinit(dfs_soc_obj); 276 dfs_zero_cac_timer_detach(dfs_soc_obj); 277 278 status = wlan_objmgr_psoc_component_obj_detach(psoc, 279 WLAN_UMAC_COMP_DFS, 280 dfs_soc_obj); 281 282 if (QDF_IS_STATUS_ERROR(status)) 283 dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS, 284 "Failed to detach psoc dfs component"); 285 286 qdf_mem_free(dfs_soc_obj); 287 288 return status; 289 } 290 291 QDF_STATUS dfs_init(void) 292 { 293 QDF_STATUS status; 294 295 status = wlan_objmgr_register_psoc_create_handler(WLAN_UMAC_COMP_DFS, 296 dfs_psoc_obj_create_notification, 297 NULL); 298 299 if (QDF_IS_STATUS_ERROR(status)) { 300 dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS, 301 "Failed to register psoc create handler for dfs"); 302 goto err_psoc_create; 303 } 304 305 status = wlan_objmgr_register_psoc_destroy_handler(WLAN_UMAC_COMP_DFS, 306 dfs_psoc_obj_destroy_notification, 307 NULL); 308 309 if (QDF_IS_STATUS_ERROR(status)) { 310 dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS, 311 "Failed to register psoc delete handler for dfs"); 312 goto err_psoc_delete; 313 } 314 315 register_dfs_callbacks(); 316 317 status = wlan_objmgr_register_pdev_create_handler(WLAN_UMAC_COMP_DFS, 318 wlan_dfs_pdev_obj_create_notification, 319 NULL); 320 321 if (QDF_IS_STATUS_ERROR(status)) { 322 dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS, 323 "Failed to register pdev create handler for dfs"); 324 goto err_pdev_create; 325 } 326 327 status = wlan_objmgr_register_pdev_destroy_handler(WLAN_UMAC_COMP_DFS, 328 wlan_dfs_pdev_obj_destroy_notification, 329 NULL); 330 331 if (QDF_IS_STATUS_ERROR(status)) { 332 dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS, 333 "Failed to register pdev delete handler for dfs"); 334 goto err_pdev_delete; 335 } 336 337 status = qdf_print_set_category_verbose(qdf_get_pidx(), 338 QDF_MODULE_ID_DFS, 339 QDF_TRACE_LEVEL_DEBUG, 340 true); 341 342 if (QDF_IS_STATUS_ERROR(status)) { 343 dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS, 344 "Failed to set verbose for category"); 345 goto err_category_verbose; 346 } 347 348 return QDF_STATUS_SUCCESS; 349 350 err_category_verbose: 351 wlan_objmgr_unregister_pdev_destroy_handler(WLAN_UMAC_COMP_DFS, 352 wlan_dfs_pdev_obj_destroy_notification, 353 NULL); 354 err_pdev_delete: 355 wlan_objmgr_unregister_pdev_create_handler(WLAN_UMAC_COMP_DFS, 356 wlan_dfs_pdev_obj_create_notification, 357 NULL); 358 err_pdev_create: 359 wlan_objmgr_unregister_psoc_destroy_handler(WLAN_UMAC_COMP_DFS, 360 dfs_psoc_obj_destroy_notification, 361 NULL); 362 err_psoc_delete: 363 wlan_objmgr_unregister_psoc_create_handler(WLAN_UMAC_COMP_DFS, 364 dfs_psoc_obj_create_notification, 365 NULL); 366 err_psoc_create: 367 return status; 368 } 369 370 QDF_STATUS dfs_deinit(void) 371 { 372 QDF_STATUS status; 373 374 status = wlan_objmgr_unregister_psoc_create_handler(WLAN_UMAC_COMP_DFS, 375 dfs_psoc_obj_create_notification, 376 NULL); 377 378 if (QDF_IS_STATUS_ERROR(status)) 379 dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS, 380 "Failed to deregister dfs psoc obj create"); 381 382 status = wlan_objmgr_unregister_psoc_destroy_handler(WLAN_UMAC_COMP_DFS, 383 dfs_psoc_obj_destroy_notification, 384 NULL); 385 386 if (QDF_IS_STATUS_ERROR(status)) 387 dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS, 388 "Failed to deregister dfs psoc obj destroy"); 389 390 status = wlan_objmgr_unregister_pdev_create_handler(WLAN_UMAC_COMP_DFS, 391 wlan_dfs_pdev_obj_create_notification, 392 NULL); 393 394 if (QDF_IS_STATUS_ERROR(status)) 395 dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS, 396 "Failed to deregister dfs pdev obj create"); 397 398 status = wlan_objmgr_unregister_pdev_destroy_handler(WLAN_UMAC_COMP_DFS, 399 wlan_dfs_pdev_obj_destroy_notification, 400 NULL); 401 402 if (QDF_IS_STATUS_ERROR(status)) 403 dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS, 404 "Failed to deregister dfs pdev obj destroy"); 405 406 return QDF_STATUS_SUCCESS; 407 } 408 409 QDF_STATUS wlan_dfs_pdev_obj_create_notification(struct wlan_objmgr_pdev *pdev, 410 void *arg) 411 { 412 struct wlan_dfs *dfs = NULL; 413 struct wlan_objmgr_psoc *psoc; 414 struct wlan_lmac_if_dfs_tx_ops *dfs_tx_ops; 415 struct dfs_soc_priv_obj *dfs_soc_obj; 416 uint8_t pdev_id; 417 QDF_STATUS status; 418 bool is_5ghz = false; 419 bool is_6ghz_only_pdev; 420 qdf_freq_t low_5g, high_5g; 421 422 if (!pdev) { 423 dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "null pdev"); 424 return QDF_STATUS_E_FAILURE; 425 } 426 427 psoc = wlan_pdev_get_psoc(pdev); 428 if (!psoc) { 429 dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "null psoc"); 430 return QDF_STATUS_E_FAILURE; 431 } 432 433 wlan_reg_get_freq_range(pdev, NULL, NULL, &low_5g, &high_5g); 434 is_6ghz_only_pdev = wlan_reg_is_range_only6g(low_5g, high_5g); 435 436 if (is_6ghz_only_pdev) { 437 pdev_id = wlan_objmgr_pdev_get_pdev_id(pdev); 438 dfs_info(dfs, WLAN_DEBUG_DFS_ALWAYS, 439 "Do not allocate DFS object for 6G, pdev_id = %d", 440 pdev_id); 441 return QDF_STATUS_SUCCESS; 442 } 443 444 dfs_tx_ops = wlan_psoc_get_dfs_txops(psoc); 445 if (!(dfs_tx_ops && dfs_tx_ops->dfs_is_pdev_5ghz)) { 446 dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "dfs_tx_ops is null"); 447 return QDF_STATUS_E_FAILURE; 448 } 449 450 status = dfs_tx_ops->dfs_is_pdev_5ghz(pdev, &is_5ghz); 451 if (QDF_IS_STATUS_ERROR(status)) { 452 dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "Failed to get is_5ghz value"); 453 return QDF_STATUS_E_FAILURE; 454 } 455 456 if (!is_5ghz) { 457 pdev_id = wlan_objmgr_pdev_get_pdev_id(pdev); 458 dfs_info(dfs, WLAN_DEBUG_DFS_ALWAYS, 459 "Do not allocate DFS object for 2G, pdev_id = %d", 460 pdev_id); 461 return QDF_STATUS_SUCCESS; 462 } 463 464 if (dfs_create_object(&dfs) == 1) { 465 dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "failed to create object"); 466 return QDF_STATUS_E_FAILURE; 467 } 468 469 status = global_dfs_to_mlme.pdev_component_obj_attach(pdev, 470 WLAN_UMAC_COMP_DFS, (void *)dfs, QDF_STATUS_SUCCESS); 471 if (QDF_IS_STATUS_ERROR(status)) { 472 dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "obj attach failed"); 473 dfs_destroy_object(dfs); 474 return QDF_STATUS_E_FAILURE; 475 } 476 477 dfs->dfs_pdev_obj = pdev; 478 479 if (!dfs_tx_ops->dfs_is_tgt_offload) { 480 dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, 481 "dfs_is_tgt_offload is null"); 482 dfs_destroy_object(dfs); 483 return QDF_STATUS_E_FAILURE; 484 } 485 486 dfs->dfs_is_offload_enabled = dfs_tx_ops->dfs_is_tgt_offload(psoc); 487 dfs_info(dfs, WLAN_DEBUG_DFS_ALWAYS, "dfs_offload %d", 488 dfs->dfs_is_offload_enabled); 489 490 if (!dfs_tx_ops->dfs_is_tgt_bangradar_320_supp) { 491 dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, 492 "dfs_is_tgt_bangradar_320_supp is null"); 493 dfs_destroy_object(dfs); 494 return QDF_STATUS_E_FAILURE; 495 } 496 497 dfs->dfs_is_bangradar_320_supported = 498 dfs_tx_ops->dfs_is_tgt_bangradar_320_supp(psoc); 499 dfs_info(dfs, WLAN_DEBUG_DFS_ALWAYS, "dfs_bangradar_320_support %d", 500 dfs->dfs_is_bangradar_320_supported); 501 502 if (!dfs_tx_ops->dfs_is_tgt_radar_found_chan_freq_eq_center_freq) { 503 dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, 504 "dfs_is_radar_found_chan_freq_eq_center_freq is null"); 505 dfs_destroy_object(dfs); 506 return QDF_STATUS_E_FAILURE; 507 } 508 509 dfs->dfs_is_radar_found_chan_freq_eq_center_freq = 510 dfs_tx_ops->dfs_is_tgt_radar_found_chan_freq_eq_center_freq(psoc); 511 dfs_info(dfs, WLAN_DEBUG_DFS, 512 "dfs_is_radar_found_chan_freq_eq_center_freq %d", 513 dfs->dfs_is_radar_found_chan_freq_eq_center_freq); 514 515 dfs_soc_obj = wlan_objmgr_psoc_get_comp_private_obj(psoc, 516 WLAN_UMAC_COMP_DFS); 517 dfs->dfs_soc_obj = dfs_soc_obj; 518 dfs_agile_soc_obj_init(dfs, psoc); 519 520 if (dfs_attach(dfs) == 1) { 521 dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "dfs_attch failed"); 522 dfs_destroy_object(dfs); 523 return QDF_STATUS_E_FAILURE; 524 } 525 526 return QDF_STATUS_SUCCESS; 527 } 528 529 QDF_STATUS wlan_dfs_pdev_obj_destroy_notification(struct wlan_objmgr_pdev *pdev, 530 void *arg) 531 { 532 struct wlan_dfs *dfs = NULL; 533 534 if (!pdev) { 535 dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "PDEV is NULL"); 536 return QDF_STATUS_E_FAILURE; 537 } 538 539 dfs = wlan_pdev_get_dfs_obj(pdev); 540 541 /* DFS is NULL during unload. should we call this function before */ 542 if (dfs) { 543 dfs_detach(dfs); 544 global_dfs_to_mlme.pdev_component_obj_detach(pdev, 545 WLAN_UMAC_COMP_DFS, 546 (void *)dfs); 547 548 dfs->dfs_pdev_obj = NULL; 549 dfs_destroy_object(dfs); 550 } 551 552 return QDF_STATUS_SUCCESS; 553 } 554 555 static void dfs_scan_serialization_comp_info_cb( 556 struct wlan_objmgr_vdev *vdev, 557 union wlan_serialization_rules_info *comp_info, 558 struct wlan_serialization_command *cmd) 559 { 560 struct wlan_dfs *dfs = NULL; 561 struct wlan_objmgr_pdev *pdev; 562 563 if (!comp_info) { 564 dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "comp_info is NULL"); 565 return; 566 } 567 568 if (!vdev) { 569 dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "vdev is NULL"); 570 return; 571 } 572 573 pdev = wlan_vdev_get_pdev(vdev); 574 if (!pdev) { 575 dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "pdev is NULL"); 576 return; 577 } 578 579 comp_info->scan_info.is_cac_in_progress = false; 580 581 if (!tgt_dfs_is_5ghz_supported_in_pdev(pdev)) 582 return; 583 584 dfs = wlan_pdev_get_dfs_obj(pdev); 585 if (!dfs) { 586 dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "dfs is NULL"); 587 return; 588 } 589 590 if (dfs_is_ap_cac_timer_running(dfs)) 591 comp_info->scan_info.is_cac_in_progress = true; 592 } 593 594 QDF_STATUS wifi_dfs_psoc_enable(struct wlan_objmgr_psoc *psoc) 595 { 596 QDF_STATUS status; 597 598 status = tgt_dfs_reg_ev_handler(psoc); 599 if (status != QDF_STATUS_SUCCESS) { 600 dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS, "tgt_dfs_reg_ev_handler failed"); 601 return QDF_STATUS_E_FAILURE; 602 } 603 604 status = wlan_serialization_register_comp_info_cb(psoc, 605 WLAN_UMAC_COMP_DFS, 606 WLAN_SER_CMD_SCAN, 607 dfs_scan_serialization_comp_info_cb); 608 if (status != QDF_STATUS_SUCCESS) { 609 dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS, "Serialize scan cmd register failed"); 610 return status; 611 } 612 613 return QDF_STATUS_SUCCESS; 614 } 615 616 QDF_STATUS wifi_dfs_psoc_disable(struct wlan_objmgr_psoc *psoc) 617 { 618 QDF_STATUS status; 619 620 status = wlan_serialization_deregister_comp_info_cb(psoc, 621 WLAN_UMAC_COMP_DFS, 622 WLAN_SER_CMD_SCAN); 623 if (status != QDF_STATUS_SUCCESS) { 624 dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS, "Serialize scan cmd deregister failed"); 625 return status; 626 } 627 628 return QDF_STATUS_SUCCESS; 629 } 630