1 /* 2 * Copyright (c) 2017-2020 The Linux Foundation. All rights reserved. 3 * 4 * Permission to use, copy, modify, and/or distribute this software for 5 * any purpose with or without fee is hereby granted, provided that the 6 * above copyright notice and this permission notice appear in all 7 * copies. 8 * 9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL 10 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED 11 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE 12 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL 13 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR 14 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 15 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 16 * PERFORMANCE OF THIS SOFTWARE. 17 */ 18 19 /** 20 * DOC: wlan_serialization_main.c 21 * This file defines the important functions pertinent to 22 * serialization to initialize and de-initialize the 23 * component. 24 */ 25 #include <qdf_status.h> 26 #include <qdf_list.h> 27 #include <wlan_objmgr_cmn.h> 28 #include <wlan_objmgr_global_obj.h> 29 #include <wlan_objmgr_psoc_obj.h> 30 #include "wlan_serialization_main_i.h" 31 #include "wlan_serialization_rules_i.h" 32 #include "wlan_serialization_utils_i.h" 33 34 QDF_STATUS wlan_serialization_psoc_disable(struct wlan_objmgr_psoc *psoc) 35 { 36 QDF_STATUS status = QDF_STATUS_E_FAILURE; 37 struct wlan_ser_psoc_obj *ser_soc_obj = 38 wlan_serialization_get_psoc_obj(psoc); 39 40 if (!ser_soc_obj) { 41 ser_err("invalid ser_soc_obj"); 42 goto error; 43 } 44 45 /* 46 * purge all serialization command if there are any pending to make 47 * sure memory and vdev ref are freed. 48 */ 49 wlan_serialization_purge_all_cmd(psoc); 50 /* clean up all timers before exiting */ 51 status = wlan_serialization_cleanup_all_timers(ser_soc_obj); 52 if (status != QDF_STATUS_SUCCESS) 53 ser_err("ser cleanning up all timer failed"); 54 55 /* Use lock to free to avoid any race where timer is still in use */ 56 wlan_serialization_acquire_lock(&ser_soc_obj->timer_lock); 57 qdf_mem_free(ser_soc_obj->timers); 58 ser_soc_obj->timers = NULL; 59 ser_soc_obj->max_active_cmds = 0; 60 wlan_serialization_release_lock(&ser_soc_obj->timer_lock); 61 error: 62 return status; 63 } 64 65 QDF_STATUS wlan_serialization_psoc_enable(struct wlan_objmgr_psoc *psoc) 66 { 67 uint8_t pdev_count; 68 struct wlan_ser_psoc_obj *ser_soc_obj = 69 wlan_serialization_get_psoc_obj(psoc); 70 QDF_STATUS status = QDF_STATUS_E_FAILURE; 71 72 if (!ser_soc_obj) { 73 ser_err("invalid ser_soc_obj"); 74 goto error; 75 } 76 77 pdev_count = wlan_psoc_get_pdev_count(psoc); 78 ser_soc_obj->max_active_cmds = WLAN_SER_MAX_ACTIVE_SCAN_CMDS + 79 (pdev_count * WLAN_SER_MAX_VDEVS); 80 81 ser_debug("max_active_cmds %d", ser_soc_obj->max_active_cmds); 82 83 ser_soc_obj->timers = 84 qdf_mem_malloc(sizeof(struct wlan_serialization_timer) * 85 ser_soc_obj->max_active_cmds); 86 if (!ser_soc_obj->timers) { 87 status = QDF_STATUS_E_NOMEM; 88 goto error; 89 } 90 91 status = QDF_STATUS_SUCCESS; 92 93 error: 94 return status; 95 } 96 97 /** 98 * wlan_serialization_psoc_create_handler() - PSOC obj create callback 99 * @psoc: PSOC object 100 * @arg_list: Variable argument list 101 * 102 * This callback is registered with object manager during initialization and 103 * when obj manager gets its turn to create the object, it would notify each 104 * component with the corresponding callback registered to inform the 105 * completion of the creation of the respective object. 106 * 107 * Return: QDF Status 108 */ 109 static QDF_STATUS wlan_serialization_psoc_create_handler( 110 struct wlan_objmgr_psoc *psoc, void *arg_list) 111 { 112 struct wlan_ser_psoc_obj *soc_ser_obj; 113 QDF_STATUS status = QDF_STATUS_E_NOMEM; 114 115 soc_ser_obj = 116 qdf_mem_malloc(sizeof(*soc_ser_obj)); 117 if (!soc_ser_obj) 118 goto error; 119 120 status = wlan_objmgr_psoc_component_obj_attach( 121 psoc, 122 WLAN_UMAC_COMP_SERIALIZATION, 123 soc_ser_obj, 124 QDF_STATUS_SUCCESS); 125 if (QDF_IS_STATUS_ERROR(status)) { 126 qdf_mem_free(soc_ser_obj); 127 ser_err("Obj attach failed"); 128 goto error; 129 } 130 wlan_serialization_create_lock(&soc_ser_obj->timer_lock); 131 ser_debug("ser psoc obj created"); 132 status = QDF_STATUS_SUCCESS; 133 134 error: 135 return status; 136 } 137 138 /** 139 * wlan_serialization_destroy_cmd_pool() - Destroy the global cmd pool 140 * @ser_pdev_obj: Serialization private pdev object 141 * 142 * Return: None 143 */ 144 static void wlan_serialization_destroy_cmd_pool( 145 struct wlan_serialization_pdev_queue *pdev_queue) 146 { 147 qdf_list_node_t *node = NULL; 148 struct wlan_serialization_command_list *cmd_list; 149 150 ser_debug("Destroy cmd pool list %pK, size %d", 151 &pdev_queue->cmd_pool_list, 152 qdf_list_size(&pdev_queue->cmd_pool_list)); 153 while (!qdf_list_empty(&pdev_queue->cmd_pool_list)) { 154 qdf_list_remove_front(&pdev_queue->cmd_pool_list, 155 &node); 156 cmd_list = (struct wlan_serialization_command_list *)node; 157 qdf_mem_free(cmd_list); 158 } 159 160 qdf_list_destroy(&pdev_queue->cmd_pool_list); 161 162 } 163 164 /** 165 * wlan_serialization_create_cmd_pool() - Create the global cmd pool 166 * @pdev: PDEV Object 167 * @ser_pdev_obj: Serialization private pdev object 168 * 169 * Global command pool of memory is created here. 170 * It is safe to allocate memory individually for each command rather than 171 * requesting for a huge chunk of memory at once. 172 * 173 * The individual command nodes allocated above will keep moving between 174 * the active, pending and global pool lists dynamically, but all the 175 * memory will be freed during driver unload only. 176 * 177 * Return: QDF Status 178 */ 179 static QDF_STATUS 180 wlan_serialization_create_cmd_pool( 181 struct wlan_serialization_pdev_queue *pdev_queue, 182 uint16_t cmd_pool_size) 183 { 184 struct wlan_serialization_command_list *cmd_list_ptr; 185 uint8_t i; 186 QDF_STATUS status = QDF_STATUS_E_NOMEM; 187 188 qdf_list_create(&pdev_queue->cmd_pool_list, cmd_pool_size); 189 190 for (i = 0; i < cmd_pool_size; i++) { 191 cmd_list_ptr = qdf_mem_malloc(sizeof(*cmd_list_ptr)); 192 if (!cmd_list_ptr) { 193 wlan_serialization_destroy_cmd_pool(pdev_queue); 194 goto error; 195 } 196 197 qdf_mem_zero(cmd_list_ptr, sizeof(*cmd_list_ptr)); 198 qdf_list_insert_back( 199 &pdev_queue->cmd_pool_list, 200 &cmd_list_ptr->pdev_node); 201 cmd_list_ptr->cmd_in_use = 0; 202 } 203 204 ser_debug("Create cmd pool list %pK, size %d", 205 &pdev_queue->cmd_pool_list, 206 qdf_list_size(&pdev_queue->cmd_pool_list)); 207 208 status = QDF_STATUS_SUCCESS; 209 210 error: 211 return status; 212 } 213 214 /** 215 * wlan_serialization_pdev_create_handler() - PDEV obj create callback 216 * @pdev: PDEV object 217 * @arg_list: Variable argument list 218 * 219 * This callback is registered with object manager during initialization and 220 * when obj manager gets its turn to create the object, it would notify each 221 * component with the corresponding callback registered to inform the 222 * completion of the creation of the respective object. 223 * 224 * Return: QDF Status 225 */ 226 static QDF_STATUS wlan_serialization_pdev_create_handler( 227 struct wlan_objmgr_pdev *pdev, void *arg_list) 228 { 229 struct wlan_ser_pdev_obj *ser_pdev_obj; 230 struct wlan_serialization_pdev_queue *pdev_queue; 231 QDF_STATUS status = QDF_STATUS_E_NOMEM; 232 uint8_t index; 233 uint8_t free_index; 234 uint8_t max_active_cmds; 235 uint8_t max_pending_cmds; 236 uint16_t cmd_pool_size; 237 238 ser_pdev_obj = 239 qdf_mem_malloc(sizeof(*ser_pdev_obj)); 240 if (!ser_pdev_obj) 241 goto error; 242 243 for (index = 0; index < SER_PDEV_QUEUE_COMP_MAX; index++) { 244 pdev_queue = &ser_pdev_obj->pdev_q[index]; 245 246 wlan_serialization_create_lock(&pdev_queue->pdev_queue_lock); 247 248 switch (index) { 249 case SER_PDEV_QUEUE_COMP_SCAN: 250 max_active_cmds = WLAN_SER_MAX_ACTIVE_SCAN_CMDS; 251 max_pending_cmds = WLAN_SER_MAX_PENDING_SCAN_CMDS; 252 cmd_pool_size = max_active_cmds + max_pending_cmds; 253 break; 254 255 case SER_PDEV_QUEUE_COMP_NON_SCAN: 256 max_active_cmds = WLAN_SER_MAX_ACTIVE_CMDS; 257 max_pending_cmds = WLAN_SER_MAX_PENDING_CMDS; 258 cmd_pool_size = max_active_cmds + max_pending_cmds; 259 ser_debug("max_active_cmds %d max_pending_cmds %d", 260 max_active_cmds, max_pending_cmds); 261 break; 262 } 263 qdf_list_create(&pdev_queue->active_list, 264 max_active_cmds); 265 qdf_list_create(&pdev_queue->pending_list, 266 max_pending_cmds); 267 268 status = wlan_serialization_create_cmd_pool(pdev_queue, 269 cmd_pool_size); 270 if (status != QDF_STATUS_SUCCESS) { 271 ser_err("Create cmd pool failed, status %d", status); 272 goto error_free; 273 } 274 275 qdf_mem_zero(pdev_queue->vdev_active_cmd_bitmap, 276 sizeof(pdev_queue->vdev_active_cmd_bitmap)); 277 278 pdev_queue->blocking_cmd_active = 0; 279 pdev_queue->blocking_cmd_waiting = 0; 280 } 281 282 status = wlan_objmgr_pdev_component_obj_attach( 283 pdev, WLAN_UMAC_COMP_SERIALIZATION, 284 ser_pdev_obj, QDF_STATUS_SUCCESS); 285 286 if (status != QDF_STATUS_SUCCESS) { 287 ser_err("Pdev obj attach failed, status %d", status); 288 goto error_free; 289 } 290 291 return QDF_STATUS_SUCCESS; 292 293 error_free: 294 for (free_index = 0; free_index <= index; free_index++) { 295 pdev_queue = &ser_pdev_obj->pdev_q[free_index]; 296 297 wlan_serialization_destroy_cmd_pool(pdev_queue); 298 qdf_list_destroy(&pdev_queue->pending_list); 299 qdf_list_destroy(&pdev_queue->active_list); 300 wlan_serialization_destroy_lock(&pdev_queue->pdev_queue_lock); 301 } 302 error: 303 return status; 304 } 305 306 /** 307 * wlan_serialization_psoc_destroy_handler() - PSOC obj delete callback 308 * @psoc: PSOC object 309 * @arg_list: Variable argument list 310 * 311 * This callback is registered with object manager during initialization and 312 * when obj manager gets its turn to delete the object, it would notify each 313 * component with the corresponding callback registered to inform the 314 * completion of the deletion of the respective object. 315 * 316 * Return: QDF Status 317 */ 318 static QDF_STATUS 319 wlan_serialization_psoc_destroy_handler(struct wlan_objmgr_psoc *psoc, 320 void *arg_list) 321 { 322 QDF_STATUS status = QDF_STATUS_E_FAULT; 323 struct wlan_ser_psoc_obj *ser_soc_obj = 324 wlan_serialization_get_psoc_obj(psoc); 325 326 if (!ser_soc_obj) { 327 ser_err("invalid ser_soc_obj"); 328 goto error; 329 } 330 status = wlan_objmgr_psoc_component_obj_detach( 331 psoc, WLAN_UMAC_COMP_SERIALIZATION, ser_soc_obj); 332 if (status != QDF_STATUS_SUCCESS) 333 ser_err("ser psoc private obj detach failed"); 334 335 wlan_serialization_destroy_lock(&ser_soc_obj->timer_lock); 336 ser_debug("ser psoc obj deleted with status %d", status); 337 qdf_mem_free(ser_soc_obj); 338 339 error: 340 return status; 341 } 342 343 /** 344 * wlan_serialization_pdev_destroy_handler() - PDEV obj delete callback 345 * @pdev: PDEV object 346 * @arg_list: Variable argument list 347 * 348 * This callback is registered with object manager during initialization and 349 * when obj manager gets its turn to delete the object, it would notify each 350 * component with the corresponding callback registered to inform the 351 * completion of the deletion of the respective object. 352 * 353 * Return: QDF Status 354 */ 355 static QDF_STATUS wlan_serialization_pdev_destroy_handler( 356 struct wlan_objmgr_pdev *pdev, void *arg_list) 357 { 358 QDF_STATUS status; 359 struct wlan_serialization_pdev_queue *pdev_queue; 360 struct wlan_ser_pdev_obj *ser_pdev_obj = 361 wlan_serialization_get_pdev_obj(pdev); 362 uint8_t index; 363 364 if (!ser_pdev_obj) { 365 ser_err("ser_pdev_obj NULL"); 366 return QDF_STATUS_E_INVAL; 367 } 368 status = wlan_objmgr_pdev_component_obj_detach( 369 pdev, WLAN_UMAC_COMP_SERIALIZATION, ser_pdev_obj); 370 371 for (index = 0; index < SER_PDEV_QUEUE_COMP_MAX; index++) { 372 pdev_queue = &ser_pdev_obj->pdev_q[index]; 373 374 wlan_serialization_destroy_pdev_list(pdev_queue); 375 wlan_serialization_destroy_cmd_pool(pdev_queue); 376 377 wlan_serialization_destroy_lock(&pdev_queue->pdev_queue_lock); 378 } 379 qdf_mem_free(ser_pdev_obj); 380 381 return status; 382 } 383 384 /** 385 * wlan_serialization_vdev_create_handler() - VDEV obj create callback 386 * @vdev: VDEV object 387 * @arg_list: Variable argument list 388 * 389 * This callback is registered with object manager during initialization and 390 * when obj manager gets its turn to create the object, it would notify each 391 * component with the corresponding callback registered to inform the 392 * completion of the creation of the respective object. 393 * 394 * Return: QDF Status 395 */ 396 static QDF_STATUS 397 wlan_serialization_vdev_create_handler(struct wlan_objmgr_vdev *vdev, 398 void *arg_list) 399 { 400 struct wlan_ser_vdev_obj *ser_vdev_obj; 401 struct wlan_serialization_vdev_queue *vdev_q; 402 QDF_STATUS status = QDF_STATUS_E_NOMEM; 403 uint8_t index; 404 uint8_t max_active_cmds; 405 uint8_t max_pending_cmds; 406 407 ser_vdev_obj = qdf_mem_malloc(sizeof(*ser_vdev_obj)); 408 if (!ser_vdev_obj) 409 goto error; 410 411 for (index = 0; index < SER_VDEV_QUEUE_COMP_MAX; index++) { 412 vdev_q = &ser_vdev_obj->vdev_q[index]; 413 414 switch (index) { 415 case SER_VDEV_QUEUE_COMP_NON_SCAN: 416 max_active_cmds = WLAN_SER_MAX_ACTIVE_CMDS / 417 WLAN_SER_MAX_VDEVS; 418 if (wlan_vdev_mlme_get_opmode(vdev) == QDF_SAP_MODE || 419 wlan_vdev_mlme_get_opmode(vdev) == QDF_P2P_GO_MODE) 420 max_pending_cmds = WLAN_SER_MAX_PENDING_CMDS_AP; 421 else 422 max_pending_cmds = 423 WLAN_SER_MAX_PENDING_CMDS_STA; 424 425 ser_debug("Vdev type %d max_pending_cmds %d", 426 wlan_vdev_mlme_get_opmode(vdev), 427 max_pending_cmds); 428 break; 429 } 430 431 qdf_list_create(&vdev_q->active_list, 432 max_active_cmds); 433 qdf_list_create(&vdev_q->pending_list, 434 max_pending_cmds); 435 } 436 437 status = wlan_objmgr_vdev_component_obj_attach( 438 vdev, WLAN_UMAC_COMP_SERIALIZATION, ser_vdev_obj, 439 QDF_STATUS_SUCCESS); 440 441 if (status != QDF_STATUS_SUCCESS) { 442 for (index = 0; index < SER_VDEV_QUEUE_COMP_MAX; index++) { 443 vdev_q = &ser_vdev_obj->vdev_q[index]; 444 qdf_list_destroy(&vdev_q->pending_list); 445 qdf_list_destroy(&vdev_q->active_list); 446 } 447 qdf_mem_free(ser_vdev_obj); 448 ser_err("serialization vdev obj attach failed"); 449 } 450 error: 451 return status; 452 } 453 454 /** 455 * wlan_serialization_vdev_destroy_handler() - vdev obj delete callback 456 * @vdev: VDEV object 457 * @arg_list: Variable argument list 458 * 459 * This callback is registered with object manager during initialization and 460 * when obj manager gets its turn to delete the object, it would notify each 461 * component with the corresponding callback registered to inform the 462 * completion of the deletion of the respective object. 463 * 464 * Return: QDF Status 465 */ 466 static QDF_STATUS wlan_serialization_vdev_destroy_handler( 467 struct wlan_objmgr_vdev *vdev, void *arg_list) 468 { 469 QDF_STATUS status = QDF_STATUS_SUCCESS; 470 struct wlan_serialization_vdev_queue *vdev_q; 471 struct wlan_ser_vdev_obj *ser_vdev_obj = 472 wlan_serialization_get_vdev_obj(vdev); 473 uint8_t index; 474 475 if (!ser_vdev_obj) { 476 ser_err("ser_vdev_obj NULL"); 477 return QDF_STATUS_E_INVAL; 478 } 479 480 status = wlan_objmgr_vdev_component_obj_detach( 481 vdev, WLAN_UMAC_COMP_SERIALIZATION, ser_vdev_obj); 482 483 /*Clean up serialization timers if any for this vdev*/ 484 wlan_serialization_cleanup_vdev_timers(vdev); 485 486 for (index = 0; index < SER_VDEV_QUEUE_COMP_MAX; index++) { 487 vdev_q = &ser_vdev_obj->vdev_q[index]; 488 wlan_serialization_destroy_vdev_list(&vdev_q->pending_list); 489 wlan_serialization_destroy_vdev_list(&vdev_q->active_list); 490 } 491 492 qdf_mem_free(ser_vdev_obj); 493 494 return status; 495 } 496 497 QDF_STATUS wlan_serialization_init(void) 498 { 499 QDF_STATUS status = QDF_STATUS_SUCCESS; 500 501 status = wlan_objmgr_register_psoc_create_handler( 502 WLAN_UMAC_COMP_SERIALIZATION, 503 wlan_serialization_psoc_create_handler, NULL); 504 if (status != QDF_STATUS_SUCCESS) { 505 ser_err("Failed to reg soc ser obj create handler"); 506 goto err_psoc_create; 507 } 508 509 status = wlan_objmgr_register_psoc_destroy_handler( 510 WLAN_UMAC_COMP_SERIALIZATION, 511 wlan_serialization_psoc_destroy_handler, NULL); 512 if (status != QDF_STATUS_SUCCESS) { 513 ser_err("Failed to reg soc ser obj delete handler"); 514 goto err_psoc_delete; 515 } 516 517 status = wlan_objmgr_register_pdev_create_handler( 518 WLAN_UMAC_COMP_SERIALIZATION, 519 wlan_serialization_pdev_create_handler, NULL); 520 if (status != QDF_STATUS_SUCCESS) { 521 ser_err("Failed to reg pdev ser obj create handler"); 522 goto err_pdev_create; 523 } 524 525 status = wlan_objmgr_register_pdev_destroy_handler( 526 WLAN_UMAC_COMP_SERIALIZATION, 527 wlan_serialization_pdev_destroy_handler, NULL); 528 if (status != QDF_STATUS_SUCCESS) { 529 ser_err("Failed to reg pdev ser obj delete handler"); 530 goto err_pdev_delete; 531 } 532 533 status = wlan_objmgr_register_vdev_create_handler( 534 WLAN_UMAC_COMP_SERIALIZATION, 535 wlan_serialization_vdev_create_handler, NULL); 536 if (status != QDF_STATUS_SUCCESS) { 537 ser_err("Failed to reg vdev ser obj create handler"); 538 goto err_vdev_create; 539 } 540 541 status = wlan_objmgr_register_vdev_destroy_handler( 542 WLAN_UMAC_COMP_SERIALIZATION, 543 wlan_serialization_vdev_destroy_handler, NULL); 544 if (status != QDF_STATUS_SUCCESS) { 545 ser_err("Failed to reg vdev ser obj delete handler"); 546 goto err_vdev_delete; 547 } 548 549 status = QDF_STATUS_SUCCESS; 550 goto exit; 551 552 err_vdev_delete: 553 wlan_objmgr_unregister_vdev_create_handler( 554 WLAN_UMAC_COMP_SERIALIZATION, 555 wlan_serialization_vdev_create_handler, 556 NULL); 557 err_vdev_create: 558 wlan_objmgr_unregister_pdev_destroy_handler( 559 WLAN_UMAC_COMP_SERIALIZATION, 560 wlan_serialization_pdev_destroy_handler, 561 NULL); 562 err_pdev_delete: 563 wlan_objmgr_unregister_pdev_create_handler( 564 WLAN_UMAC_COMP_SERIALIZATION, 565 wlan_serialization_pdev_create_handler, 566 NULL); 567 err_pdev_create: 568 wlan_objmgr_unregister_psoc_destroy_handler( 569 WLAN_UMAC_COMP_SERIALIZATION, 570 wlan_serialization_psoc_destroy_handler, 571 NULL); 572 err_psoc_delete: 573 wlan_objmgr_unregister_psoc_create_handler( 574 WLAN_UMAC_COMP_SERIALIZATION, 575 wlan_serialization_psoc_create_handler, 576 NULL); 577 err_psoc_create: 578 exit: 579 return status; 580 } 581 582 QDF_STATUS wlan_serialization_deinit(void) 583 { 584 QDF_STATUS status; 585 QDF_STATUS ret_status = QDF_STATUS_SUCCESS; 586 587 status = wlan_objmgr_unregister_psoc_create_handler( 588 WLAN_UMAC_COMP_SERIALIZATION, 589 wlan_serialization_psoc_create_handler, 590 NULL); 591 592 if (status != QDF_STATUS_SUCCESS) { 593 ser_err("unreg fail for psoc ser obj create notf:%d", status); 594 ret_status = QDF_STATUS_E_FAILURE; 595 } 596 status = wlan_objmgr_unregister_psoc_destroy_handler( 597 WLAN_UMAC_COMP_SERIALIZATION, 598 wlan_serialization_psoc_destroy_handler, 599 NULL); 600 601 if (status != QDF_STATUS_SUCCESS) { 602 ser_err("unreg fail for psoc ser obj destroy notf:%d", status); 603 ret_status = QDF_STATUS_E_FAILURE; 604 } 605 606 status = wlan_objmgr_unregister_pdev_create_handler( 607 WLAN_UMAC_COMP_SERIALIZATION, 608 wlan_serialization_pdev_create_handler, 609 NULL); 610 if (status != QDF_STATUS_SUCCESS) { 611 ser_err("unreg fail for pdev ser obj create notf:%d", status); 612 ret_status = QDF_STATUS_E_FAILURE; 613 } 614 615 status = wlan_objmgr_unregister_pdev_destroy_handler( 616 WLAN_UMAC_COMP_SERIALIZATION, 617 wlan_serialization_pdev_destroy_handler, 618 NULL); 619 620 if (status != QDF_STATUS_SUCCESS) { 621 ser_err("unreg fail for pdev ser destroy notf:%d", status); 622 ret_status = QDF_STATUS_E_FAILURE; 623 } 624 625 ser_debug("deregistered callbacks with obj mgr successfully"); 626 627 return ret_status; 628 } 629