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