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