1 /* 2 * Copyright (c) 2016-2020 The Linux Foundation. All rights reserved. 3 * 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 QCA_MCL_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 QCA_MCL_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 postNOL channel switch callbacks 79 * @mlme_callback: Pointer to dfs_to_mlme. 80 */ 81 #ifndef QCA_MCL_DFS_SUPPORT 82 #ifdef QCA_SUPPORT_DFS_CHAN_POSTNOL 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 QCA_MCL_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_dfs_channels_for_freq = 115 mlme_dfs_get_dfs_channels_for_freq; 116 mlme_callback->mlme_get_cac_timeout_for_freq = 117 mlme_dfs_get_cac_timeout_for_freq; 118 mlme_callback->mlme_get_extchan_for_freq = 119 mlme_dfs_get_extchan_for_freq; 120 mlme_callback->mlme_start_csa_for_freq = mlme_dfs_start_csa_for_freq; 121 } 122 #endif 123 #endif 124 125 #ifndef QCA_MCL_DFS_SUPPORT 126 void register_dfs_callbacks(void) 127 { 128 struct dfs_to_mlme *tmp_dfs_to_mlme = &global_dfs_to_mlme; 129 130 tmp_dfs_to_mlme->pdev_component_obj_attach = 131 wlan_objmgr_pdev_component_obj_attach; 132 tmp_dfs_to_mlme->pdev_component_obj_detach = 133 wlan_objmgr_pdev_component_obj_detach; 134 135 tmp_dfs_to_mlme->dfs_start_rcsa = mlme_dfs_start_rcsa; 136 tmp_dfs_to_mlme->mlme_proc_cac = mlme_dfs_proc_cac; 137 tmp_dfs_to_mlme->mlme_deliver_event_up_after_cac = 138 mlme_dfs_deliver_event_up_after_cac; 139 tmp_dfs_to_mlme->mlme_get_dfs_ch_nchans = mlme_dfs_get_dfs_ch_nchans; 140 tmp_dfs_to_mlme->mlme_set_no_chans_available = 141 mlme_dfs_set_no_chans_available; 142 tmp_dfs_to_mlme->mlme_ieee2mhz = mlme_dfs_ieee2mhz; 143 tmp_dfs_to_mlme->mlme_dfs_ch_flags_ext = mlme_dfs_dfs_ch_flags_ext; 144 tmp_dfs_to_mlme->mlme_channel_change_by_precac = 145 mlme_dfs_channel_change_by_precac; 146 tmp_dfs_to_mlme->mlme_nol_timeout_notification = 147 mlme_dfs_nol_timeout_notification; 148 tmp_dfs_to_mlme->mlme_clist_update = mlme_dfs_clist_update; 149 tmp_dfs_to_mlme->mlme_rebuild_chan_list_with_non_dfs_channels = 150 mlme_dfs_rebuild_chan_list_with_non_dfs_channels; 151 tmp_dfs_to_mlme->mlme_restart_vaps_with_non_dfs_chan = 152 mlme_dfs_restart_vaps_with_non_dfs_chan; 153 tmp_dfs_to_mlme->mlme_is_opmode_sta = 154 mlme_dfs_is_opmode_sta; 155 tmp_dfs_to_mlme->mlme_check_allowed_prim_chanlist = 156 mlme_dfs_check_allowed_prim_chanlist; 157 tmp_dfs_to_mlme->mlme_update_scan_channel_list = 158 mlme_dfs_update_scan_channel_list; 159 tmp_dfs_to_mlme->mlme_bringdown_vaps = 160 mlme_dfs_bringdown_vaps; 161 tmp_dfs_to_mlme->mlme_dfs_deliver_event = 162 mlme_dfs_deliver_event; 163 tmp_dfs_to_mlme->mlme_is_inter_band_chan_switch_allowed = 164 mlme_is_inter_band_chan_switch_allowed; 165 166 tmp_dfs_to_mlme->mlme_acquire_radar_mode_switch_lock = 167 mlme_acquire_radar_mode_switch_lock; 168 tmp_dfs_to_mlme->mlme_release_radar_mode_switch_lock = 169 mlme_release_radar_mode_switch_lock; 170 tmp_dfs_to_mlme->mlme_mark_dfs = 171 mlme_dfs_mark_dfs; 172 /* 173 * Register precac auto channel switch feature related callbacks 174 */ 175 register_dfs_precac_auto_chan_callbacks_freq(tmp_dfs_to_mlme); 176 /* Register freq based callbacks */ 177 register_dfs_callbacks_for_freq(tmp_dfs_to_mlme); 178 register_dfs_postnol_csa_callback(tmp_dfs_to_mlme); 179 } 180 #else 181 void register_dfs_callbacks(void) 182 { 183 struct dfs_to_mlme *tmp_dfs_to_mlme = &global_dfs_to_mlme; 184 185 tmp_dfs_to_mlme->pdev_component_obj_attach = 186 wlan_objmgr_pdev_component_obj_attach; 187 tmp_dfs_to_mlme->pdev_component_obj_detach = 188 wlan_objmgr_pdev_component_obj_detach; 189 } 190 #endif 191 192 /** 193 * dfs_psoc_obj_create_notification() - dfs psoc create notification handler 194 * @psoc: psoc object 195 * @arg_list: Argument list 196 * 197 * Return: QDF_STATUS 198 */ 199 static QDF_STATUS dfs_psoc_obj_create_notification(struct wlan_objmgr_psoc *psoc, 200 void *arg_list) 201 { 202 QDF_STATUS status; 203 struct dfs_soc_priv_obj *dfs_soc_obj; 204 205 dfs_soc_obj = qdf_mem_malloc(sizeof(*dfs_soc_obj)); 206 if (!dfs_soc_obj) 207 return QDF_STATUS_E_NOMEM; 208 209 dfs_soc_obj->psoc = psoc; 210 211 status = wlan_objmgr_psoc_component_obj_attach(psoc, 212 WLAN_UMAC_COMP_DFS, 213 (void *)dfs_soc_obj, 214 QDF_STATUS_SUCCESS); 215 216 if (QDF_IS_STATUS_ERROR(status)) { 217 dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS, 218 "Failed to attach psoc dfs component"); 219 qdf_mem_free(dfs_soc_obj); 220 return status; 221 } 222 /* Initialize precac timer here*/ 223 dfs_zero_cac_timer_init(dfs_soc_obj); 224 225 /* Initialize Rolling CAC timer */ 226 dfs_rcac_timer_init(dfs_soc_obj); 227 228 /* DFS Agile SM initialization */ 229 dfs_agile_sm_create(dfs_soc_obj); 230 231 dfs_debug(NULL, WLAN_DEBUG_DFS1, 232 "DFS obj attach to psoc successfully"); 233 234 return status; 235 } 236 237 /** 238 * dfs_psoc_obj_destroy_notification() - dfs psoc destroy notification handler 239 * @psoc: psoc object 240 * @arg_list: Argument list 241 * 242 * Return: QDF_STATUS 243 */ 244 static QDF_STATUS dfs_psoc_obj_destroy_notification(struct wlan_objmgr_psoc *psoc, 245 void *arg_list) 246 { 247 QDF_STATUS status; 248 struct dfs_soc_priv_obj *dfs_soc_obj; 249 250 dfs_soc_obj = wlan_objmgr_psoc_get_comp_private_obj(psoc, 251 WLAN_UMAC_COMP_DFS); 252 if (!dfs_soc_obj) { 253 dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS, 254 "Failed to get dfs obj in psoc"); 255 return QDF_STATUS_E_FAILURE; 256 } 257 258 /* Delete DFS Agile SM */ 259 dfs_agile_sm_destroy(dfs_soc_obj); 260 261 dfs_rcac_timer_deinit(dfs_soc_obj); 262 dfs_zero_cac_timer_detach(dfs_soc_obj); 263 264 status = wlan_objmgr_psoc_component_obj_detach(psoc, 265 WLAN_UMAC_COMP_DFS, 266 dfs_soc_obj); 267 268 if (QDF_IS_STATUS_ERROR(status)) 269 dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS, 270 "Failed to detach psoc dfs component"); 271 272 qdf_mem_free(dfs_soc_obj); 273 274 return status; 275 } 276 277 QDF_STATUS dfs_init(void) 278 { 279 QDF_STATUS status; 280 281 status = wlan_objmgr_register_psoc_create_handler(WLAN_UMAC_COMP_DFS, 282 dfs_psoc_obj_create_notification, 283 NULL); 284 285 if (QDF_IS_STATUS_ERROR(status)) { 286 dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS, 287 "Failed to register psoc create handler for dfs"); 288 goto err_psoc_create; 289 } 290 291 status = wlan_objmgr_register_psoc_destroy_handler(WLAN_UMAC_COMP_DFS, 292 dfs_psoc_obj_destroy_notification, 293 NULL); 294 295 if (QDF_IS_STATUS_ERROR(status)) { 296 dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS, 297 "Failed to register psoc delete handler for dfs"); 298 goto err_psoc_delete; 299 } 300 301 register_dfs_callbacks(); 302 303 status = wlan_objmgr_register_pdev_create_handler(WLAN_UMAC_COMP_DFS, 304 wlan_dfs_pdev_obj_create_notification, 305 NULL); 306 307 if (QDF_IS_STATUS_ERROR(status)) { 308 dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS, 309 "Failed to register pdev create handler for dfs"); 310 goto err_pdev_create; 311 } 312 313 status = wlan_objmgr_register_pdev_destroy_handler(WLAN_UMAC_COMP_DFS, 314 wlan_dfs_pdev_obj_destroy_notification, 315 NULL); 316 317 if (QDF_IS_STATUS_ERROR(status)) { 318 dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS, 319 "Failed to register pdev delete handler for dfs"); 320 goto err_pdev_delete; 321 } 322 323 status = qdf_print_set_category_verbose(qdf_get_pidx(), 324 QDF_MODULE_ID_DFS, 325 QDF_TRACE_LEVEL_DEBUG, 326 true); 327 328 if (QDF_IS_STATUS_ERROR(status)) { 329 dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS, 330 "Failed to set verbose for category"); 331 goto err_category_verbose; 332 } 333 334 return QDF_STATUS_SUCCESS; 335 336 err_category_verbose: 337 wlan_objmgr_unregister_pdev_destroy_handler(WLAN_UMAC_COMP_DFS, 338 wlan_dfs_pdev_obj_destroy_notification, 339 NULL); 340 err_pdev_delete: 341 wlan_objmgr_unregister_pdev_create_handler(WLAN_UMAC_COMP_DFS, 342 wlan_dfs_pdev_obj_create_notification, 343 NULL); 344 err_pdev_create: 345 wlan_objmgr_unregister_psoc_destroy_handler(WLAN_UMAC_COMP_DFS, 346 dfs_psoc_obj_destroy_notification, 347 NULL); 348 err_psoc_delete: 349 wlan_objmgr_unregister_psoc_create_handler(WLAN_UMAC_COMP_DFS, 350 dfs_psoc_obj_create_notification, 351 NULL); 352 err_psoc_create: 353 return status; 354 } 355 356 QDF_STATUS dfs_deinit(void) 357 { 358 QDF_STATUS status; 359 360 status = wlan_objmgr_unregister_psoc_create_handler(WLAN_UMAC_COMP_DFS, 361 dfs_psoc_obj_create_notification, 362 NULL); 363 364 if (QDF_IS_STATUS_ERROR(status)) 365 dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS, 366 "Failed to deregister dfs psoc obj create"); 367 368 status = wlan_objmgr_unregister_psoc_destroy_handler(WLAN_UMAC_COMP_DFS, 369 dfs_psoc_obj_destroy_notification, 370 NULL); 371 372 if (QDF_IS_STATUS_ERROR(status)) 373 dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS, 374 "Failed to deregister dfs psoc obj destroy"); 375 376 status = wlan_objmgr_unregister_pdev_create_handler(WLAN_UMAC_COMP_DFS, 377 wlan_dfs_pdev_obj_create_notification, 378 NULL); 379 380 if (QDF_IS_STATUS_ERROR(status)) 381 dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS, 382 "Failed to deregister dfs pdev obj create"); 383 384 status = wlan_objmgr_unregister_pdev_destroy_handler(WLAN_UMAC_COMP_DFS, 385 wlan_dfs_pdev_obj_destroy_notification, 386 NULL); 387 388 if (QDF_IS_STATUS_ERROR(status)) 389 dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS, 390 "Failed to deregister dfs pdev obj destroy"); 391 392 return QDF_STATUS_SUCCESS; 393 } 394 395 QDF_STATUS wlan_dfs_pdev_obj_create_notification(struct wlan_objmgr_pdev *pdev, 396 void *arg) 397 { 398 struct wlan_dfs *dfs = NULL; 399 struct wlan_objmgr_psoc *psoc; 400 struct wlan_lmac_if_dfs_tx_ops *dfs_tx_ops; 401 struct dfs_soc_priv_obj *dfs_soc_obj; 402 uint8_t pdev_id; 403 QDF_STATUS status; 404 bool is_5ghz = false; 405 bool is_6ghz_only_pdev; 406 qdf_freq_t low_5g, high_5g; 407 408 if (!pdev) { 409 dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "null pdev"); 410 return QDF_STATUS_E_FAILURE; 411 } 412 413 psoc = wlan_pdev_get_psoc(pdev); 414 if (!psoc) { 415 dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "null psoc"); 416 return QDF_STATUS_E_FAILURE; 417 } 418 419 wlan_reg_get_freq_range(pdev, NULL, NULL, &low_5g, &high_5g); 420 is_6ghz_only_pdev = wlan_reg_is_range_only6g(low_5g, high_5g); 421 422 if (is_6ghz_only_pdev) { 423 pdev_id = wlan_objmgr_pdev_get_pdev_id(pdev); 424 dfs_info(dfs, WLAN_DEBUG_DFS_ALWAYS, 425 "Do not allocate DFS object for 6G, pdev_id = %d", 426 pdev_id); 427 return QDF_STATUS_SUCCESS; 428 } 429 430 dfs_tx_ops = wlan_psoc_get_dfs_txops(psoc); 431 if (!(dfs_tx_ops && dfs_tx_ops->dfs_is_pdev_5ghz)) { 432 dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "dfs_tx_ops is null"); 433 return QDF_STATUS_E_FAILURE; 434 } 435 436 status = dfs_tx_ops->dfs_is_pdev_5ghz(pdev, &is_5ghz); 437 if (QDF_IS_STATUS_ERROR(status)) { 438 dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "Failed to get is_5ghz value"); 439 return QDF_STATUS_E_FAILURE; 440 } 441 442 if (!is_5ghz) { 443 pdev_id = wlan_objmgr_pdev_get_pdev_id(pdev); 444 dfs_info(dfs, WLAN_DEBUG_DFS_ALWAYS, 445 "Do not allocate DFS object for 2G, pdev_id = %d", 446 pdev_id); 447 return QDF_STATUS_SUCCESS; 448 } 449 450 if (dfs_create_object(&dfs) == 1) { 451 dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "failed to create object"); 452 return QDF_STATUS_E_FAILURE; 453 } 454 455 status = global_dfs_to_mlme.pdev_component_obj_attach(pdev, 456 WLAN_UMAC_COMP_DFS, (void *)dfs, QDF_STATUS_SUCCESS); 457 if (QDF_IS_STATUS_ERROR(status)) { 458 dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "obj attach failed"); 459 dfs_destroy_object(dfs); 460 return QDF_STATUS_E_FAILURE; 461 } 462 463 dfs->dfs_pdev_obj = pdev; 464 465 if (!dfs_tx_ops->dfs_is_tgt_offload) { 466 dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, 467 "dfs_is_tgt_offload is null"); 468 dfs_destroy_object(dfs); 469 return QDF_STATUS_E_FAILURE; 470 } 471 472 dfs->dfs_is_offload_enabled = dfs_tx_ops->dfs_is_tgt_offload(psoc); 473 dfs_info(dfs, WLAN_DEBUG_DFS_ALWAYS, "dfs_offload %d", 474 dfs->dfs_is_offload_enabled); 475 dfs_soc_obj = wlan_objmgr_psoc_get_comp_private_obj(psoc, 476 WLAN_UMAC_COMP_DFS); 477 dfs->dfs_soc_obj = dfs_soc_obj; 478 dfs_agile_soc_obj_init(dfs, psoc); 479 480 if (dfs_attach(dfs) == 1) { 481 dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "dfs_attch failed"); 482 dfs_destroy_object(dfs); 483 return QDF_STATUS_E_FAILURE; 484 } 485 486 return QDF_STATUS_SUCCESS; 487 } 488 489 QDF_STATUS wlan_dfs_pdev_obj_destroy_notification(struct wlan_objmgr_pdev *pdev, 490 void *arg) 491 { 492 struct wlan_dfs *dfs = NULL; 493 494 if (!pdev) { 495 dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "PDEV is NULL"); 496 return QDF_STATUS_E_FAILURE; 497 } 498 499 dfs = wlan_pdev_get_dfs_obj(pdev); 500 501 /* DFS is NULL during unload. should we call this function before */ 502 if (dfs) { 503 global_dfs_to_mlme.pdev_component_obj_detach(pdev, 504 WLAN_UMAC_COMP_DFS, 505 (void *)dfs); 506 507 dfs_detach(dfs); 508 dfs->dfs_pdev_obj = NULL; 509 dfs_destroy_object(dfs); 510 } 511 512 return QDF_STATUS_SUCCESS; 513 } 514 515 static void dfs_scan_serialization_comp_info_cb( 516 struct wlan_objmgr_vdev *vdev, 517 union wlan_serialization_rules_info *comp_info, 518 struct wlan_serialization_command *cmd) 519 { 520 struct wlan_dfs *dfs = NULL; 521 struct wlan_objmgr_pdev *pdev; 522 523 if (!comp_info) { 524 dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "comp_info is NULL"); 525 return; 526 } 527 528 if (!vdev) { 529 dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "vdev is NULL"); 530 return; 531 } 532 533 pdev = wlan_vdev_get_pdev(vdev); 534 if (!pdev) { 535 dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "pdev is NULL"); 536 return; 537 } 538 539 comp_info->scan_info.is_cac_in_progress = false; 540 541 if (!tgt_dfs_is_pdev_5ghz(pdev)) 542 return; 543 544 dfs = wlan_pdev_get_dfs_obj(pdev); 545 if (!dfs) { 546 dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "dfs is NULL"); 547 return; 548 } 549 550 if (dfs_is_ap_cac_timer_running(dfs)) 551 comp_info->scan_info.is_cac_in_progress = true; 552 } 553 554 QDF_STATUS wifi_dfs_psoc_enable(struct wlan_objmgr_psoc *psoc) 555 { 556 QDF_STATUS status; 557 558 status = tgt_dfs_reg_ev_handler(psoc); 559 if (status != QDF_STATUS_SUCCESS) { 560 dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS, "tgt_dfs_reg_ev_handler failed"); 561 return QDF_STATUS_E_FAILURE; 562 } 563 564 status = wlan_serialization_register_comp_info_cb(psoc, 565 WLAN_UMAC_COMP_DFS, 566 WLAN_SER_CMD_SCAN, 567 dfs_scan_serialization_comp_info_cb); 568 if (status != QDF_STATUS_SUCCESS) { 569 dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS, "Serialize scan cmd register failed"); 570 return status; 571 } 572 573 return QDF_STATUS_SUCCESS; 574 } 575 576 QDF_STATUS wifi_dfs_psoc_disable(struct wlan_objmgr_psoc *psoc) 577 { 578 QDF_STATUS status; 579 580 status = wlan_serialization_deregister_comp_info_cb(psoc, 581 WLAN_UMAC_COMP_DFS, 582 WLAN_SER_CMD_SCAN); 583 if (status != QDF_STATUS_SUCCESS) { 584 dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS, "Serialize scan cmd deregister failed"); 585 return status; 586 } 587 588 return QDF_STATUS_SUCCESS; 589 } 590