1 /* 2 * Copyright (c) 2017-2018 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 #ifdef CONFIG_SERIALIZATION_V1 26 #include "qdf_status.h" 27 #include "qdf_list.h" 28 #include "wlan_objmgr_cmn.h" 29 #include "wlan_objmgr_global_obj.h" 30 #include "wlan_objmgr_psoc_obj.h" 31 #include "wlan_serialization_main_i.h" 32 #include "wlan_serialization_rules_i.h" 33 #include "wlan_serialization_utils_i.h" 34 35 QDF_STATUS wlan_serialization_psoc_close(struct wlan_objmgr_psoc *psoc) 36 { 37 QDF_STATUS status; 38 struct wlan_serialization_psoc_priv_obj *ser_soc_obj = 39 wlan_serialization_get_psoc_priv_obj(psoc); 40 41 if (!ser_soc_obj) { 42 serialization_err("invalid ser_soc_obj"); 43 return QDF_STATUS_E_FAILURE; 44 } 45 /* clean up all timers before exiting */ 46 status = wlan_serialization_cleanup_all_timers(ser_soc_obj); 47 if (status != QDF_STATUS_SUCCESS) 48 serialization_err("ser cleanning up all timer failed"); 49 50 qdf_mem_free(ser_soc_obj->timers); 51 ser_soc_obj->timers = NULL; 52 ser_soc_obj->max_active_cmds = 0; 53 54 return status; 55 } 56 57 QDF_STATUS wlan_serialization_psoc_open(struct wlan_objmgr_psoc *psoc) 58 { 59 uint8_t pdev_count; 60 struct wlan_serialization_psoc_priv_obj *ser_soc_obj = 61 wlan_serialization_get_psoc_priv_obj(psoc); 62 63 if (!ser_soc_obj) { 64 serialization_err("invalid ser_soc_obj"); 65 return QDF_STATUS_E_FAILURE; 66 } 67 /* TODO:Get WLAN_SERIALIZATION_MAX_ACTIVE_SCAN_CMDS frm service ready */ 68 pdev_count = wlan_psoc_get_pdev_count(psoc); 69 ser_soc_obj->max_active_cmds = WLAN_SERIALIZATION_MAX_ACTIVE_SCAN_CMDS + 70 pdev_count; 71 ser_soc_obj->timers = 72 qdf_mem_malloc(sizeof(struct wlan_serialization_timer) * 73 ser_soc_obj->max_active_cmds); 74 if (NULL == ser_soc_obj->timers) { 75 serialization_alert("Mem alloc failed for ser timers"); 76 return QDF_STATUS_E_NOMEM; 77 } 78 79 return QDF_STATUS_SUCCESS; 80 } 81 82 /** 83 * wlan_serialization_psoc_obj_create_notification() - PSOC obj create callback 84 * @psoc: PSOC object 85 * @arg_list: Variable argument list 86 * 87 * This callback is registered with object manager during initialization and 88 * when obj manager gets its turn to create the object, it would notify each 89 * component with the corresponding callback registered to inform the 90 * completion of the creation of the respective object. 91 * 92 * Return: QDF Status 93 */ 94 static QDF_STATUS wlan_serialization_psoc_obj_create_notification( 95 struct wlan_objmgr_psoc *psoc, void *arg_list) 96 { 97 struct wlan_serialization_psoc_priv_obj *soc_ser_obj; 98 99 soc_ser_obj = 100 qdf_mem_malloc(sizeof(*soc_ser_obj)); 101 if (NULL == soc_ser_obj) { 102 serialization_alert("Mem alloc failed for ser psoc priv obj"); 103 return QDF_STATUS_E_NOMEM; 104 } 105 wlan_objmgr_psoc_component_obj_attach(psoc, 106 WLAN_UMAC_COMP_SERIALIZATION, soc_ser_obj, 107 QDF_STATUS_SUCCESS); 108 serialization_debug("ser psoc obj created"); 109 110 return QDF_STATUS_SUCCESS; 111 } 112 113 /** 114 * wlan_serialization_destroy_cmd_pool() - Destroy the global cmd pool 115 * @ser_pdev_obj: Serialization private pdev object 116 * 117 * Return: None 118 */ 119 static void wlan_serialization_destroy_cmd_pool( 120 struct wlan_serialization_pdev_priv_obj *ser_pdev_obj) 121 { 122 123 qdf_list_node_t *node = NULL; 124 struct wlan_serialization_command_list *cmd_list; 125 126 while (!qdf_list_empty(&ser_pdev_obj->global_cmd_pool_list)) { 127 qdf_list_remove_front(&ser_pdev_obj->global_cmd_pool_list, 128 &node); 129 cmd_list = (struct wlan_serialization_command_list *)node; 130 serialization_debug("Node being freed from global pool %pK", 131 cmd_list); 132 qdf_mem_free(cmd_list); 133 134 } 135 qdf_list_destroy(&ser_pdev_obj->global_cmd_pool_list); 136 } 137 138 /** 139 * wlan_serialization_create_cmd_pool() - Create the global cmd pool 140 * @pdev: PDEV Object 141 * @ser_pdev_obj: Serialization private pdev object 142 * 143 * Global command pool of memory is created here. 144 * It is safe to allocate memory individually for each command rather than 145 * requesting for a huge chunk of memory at once. 146 * 147 * The individual command nodes allocated above will keep moving between 148 * the active, pending and global pool lists dynamically, but all the 149 * memory will be freed during driver unload only. 150 * 151 * Return: QDF Status 152 */ 153 static QDF_STATUS 154 wlan_serialization_create_cmd_pool(struct wlan_objmgr_pdev *pdev, 155 struct wlan_serialization_pdev_priv_obj *ser_pdev_obj) 156 { 157 struct wlan_serialization_command_list *cmd_list_ptr; 158 uint8_t i; 159 160 for (i = 0; i < WLAN_SERIALIZATION_MAX_GLOBAL_POOL_CMDS; i++) { 161 cmd_list_ptr = qdf_mem_malloc(sizeof(*cmd_list_ptr)); 162 if (NULL == cmd_list_ptr) { 163 serialization_alert("Mem alloc failed for cmd node"); 164 wlan_serialization_destroy_cmd_pool(ser_pdev_obj); 165 return QDF_STATUS_E_NOMEM; 166 } 167 qdf_list_insert_back( 168 &ser_pdev_obj->global_cmd_pool_list, 169 &cmd_list_ptr->node); 170 cmd_list_ptr->cmd_in_use = 0; 171 serialization_debug("Created node at %pK and inserted to pool", 172 cmd_list_ptr); 173 } 174 175 return QDF_STATUS_SUCCESS; 176 } 177 178 179 /** 180 * wlan_serialization_pdev_obj_create_notification() - PDEV obj create callback 181 * @pdev: PDEV object 182 * @arg_list: Variable argument list 183 * 184 * This callback is registered with object manager during initialization and 185 * when obj manager gets its turn to create the object, it would notify each 186 * component with the corresponding callback registered to inform the 187 * completion of the creation of the respective object. 188 * 189 * Return: QDF Status 190 */ 191 static QDF_STATUS wlan_serialization_pdev_obj_create_notification( 192 struct wlan_objmgr_pdev *pdev, void *arg_list) 193 { 194 struct wlan_serialization_pdev_priv_obj *ser_pdev_obj; 195 QDF_STATUS status; 196 197 ser_pdev_obj = 198 qdf_mem_malloc(sizeof(*ser_pdev_obj)); 199 if (NULL == ser_pdev_obj) { 200 serialization_alert("Mem alloc failed for ser pdev obj"); 201 return QDF_STATUS_E_NOMEM; 202 } 203 status = wlan_serialization_create_lock(ser_pdev_obj); 204 if (status != QDF_STATUS_SUCCESS) { 205 serialization_err("Failed to create serialization lock"); 206 return status; 207 } 208 qdf_list_create(&ser_pdev_obj->active_list, 209 WLAN_SERIALIZATION_MAX_ACTIVE_CMDS); 210 qdf_list_create(&ser_pdev_obj->pending_list, 211 WLAN_SERIALIZATION_MAX_GLOBAL_POOL_CMDS); 212 qdf_list_create(&ser_pdev_obj->active_scan_list, 213 WLAN_SERIALIZATION_MAX_ACTIVE_SCAN_CMDS); 214 qdf_list_create(&ser_pdev_obj->pending_scan_list, 215 WLAN_SERIALIZATION_MAX_GLOBAL_POOL_CMDS); 216 qdf_list_create(&ser_pdev_obj->global_cmd_pool_list, 217 WLAN_SERIALIZATION_MAX_GLOBAL_POOL_CMDS); 218 status = wlan_serialization_create_cmd_pool(pdev, ser_pdev_obj); 219 if (status != QDF_STATUS_SUCCESS) { 220 serialization_err("ser_pdev_obj failed status %d", status); 221 return status; 222 } 223 status = wlan_objmgr_pdev_component_obj_attach(pdev, 224 WLAN_UMAC_COMP_SERIALIZATION, ser_pdev_obj, 225 QDF_STATUS_SUCCESS); 226 if (status != QDF_STATUS_SUCCESS) { 227 serialization_err("serialization pdev obj attach failed"); 228 return status; 229 } 230 231 return status; 232 } 233 234 /** 235 * wlan_serialization_psoc_obj_destroy_notification() - PSOC obj delete callback 236 * @psoc: PSOC object 237 * @arg_list: Variable argument list 238 * 239 * This callback is registered with object manager during initialization and 240 * when obj manager gets its turn to delete the object, it would notify each 241 * component with the corresponding callback registered to inform the 242 * completion of the deletion of the respective object. 243 * 244 * Return: QDF Status 245 */ 246 static QDF_STATUS wlan_serialization_psoc_obj_destroy_notification( 247 struct wlan_objmgr_psoc *psoc, void *arg_list) 248 { 249 QDF_STATUS status; 250 struct wlan_serialization_psoc_priv_obj *ser_soc_obj = 251 wlan_serialization_get_psoc_priv_obj(psoc); 252 253 if (NULL == ser_soc_obj) { 254 serialization_err("invalid ser_soc_obj"); 255 return QDF_STATUS_E_FAULT; 256 } 257 status = wlan_objmgr_psoc_component_obj_detach(psoc, 258 WLAN_UMAC_COMP_SERIALIZATION, 259 ser_soc_obj); 260 if (status != QDF_STATUS_SUCCESS) 261 serialization_err("ser psoc private obj detach failed"); 262 serialization_debug("ser psoc obj deleted with status %d", status); 263 qdf_mem_free(ser_soc_obj); 264 265 return status; 266 } 267 268 /** 269 * wlan_serialization_pdev_obj_destroy_notification() - PDEV obj delete callback 270 * @pdev: PDEV object 271 * @arg_list: Variable argument list 272 * 273 * This callback is registered with object manager during initialization and 274 * when obj manager gets its turn to delete the object, it would notify each 275 * component with the corresponding callback registered to inform the 276 * completion of the deletion of the respective object. 277 * 278 * Return: QDF Status 279 */ 280 static QDF_STATUS wlan_serialization_pdev_obj_destroy_notification( 281 struct wlan_objmgr_pdev *pdev, void *arg_list) 282 { 283 QDF_STATUS status; 284 struct wlan_serialization_pdev_priv_obj *ser_pdev_obj = 285 wlan_serialization_get_pdev_priv_obj(pdev); 286 287 status = wlan_objmgr_pdev_component_obj_detach(pdev, 288 WLAN_UMAC_COMP_SERIALIZATION, ser_pdev_obj); 289 wlan_serialization_destroy_list(ser_pdev_obj, 290 &ser_pdev_obj->active_list); 291 wlan_serialization_destroy_list(ser_pdev_obj, 292 &ser_pdev_obj->pending_list); 293 wlan_serialization_destroy_list(ser_pdev_obj, 294 &ser_pdev_obj->active_scan_list); 295 wlan_serialization_destroy_list(ser_pdev_obj, 296 &ser_pdev_obj->pending_scan_list); 297 wlan_serialization_destroy_cmd_pool(ser_pdev_obj); 298 serialization_debug("ser pdev obj detached with status %d", status); 299 status = wlan_serialization_destroy_lock(ser_pdev_obj); 300 if (status != QDF_STATUS_SUCCESS) 301 serialization_err("Failed to destroy serialization lock"); 302 qdf_mem_free(ser_pdev_obj); 303 304 return status; 305 } 306 307 QDF_STATUS wlan_serialization_init(void) 308 { 309 QDF_STATUS status = QDF_STATUS_SUCCESS; 310 311 status = wlan_objmgr_register_psoc_create_handler( 312 WLAN_UMAC_COMP_SERIALIZATION, 313 wlan_serialization_psoc_obj_create_notification, NULL); 314 if (status != QDF_STATUS_SUCCESS) { 315 serialization_err("Failed to reg soc ser obj create handler"); 316 goto err_psoc_create; 317 } 318 319 status = wlan_objmgr_register_psoc_destroy_handler( 320 WLAN_UMAC_COMP_SERIALIZATION, 321 wlan_serialization_psoc_obj_destroy_notification, NULL); 322 if (status != QDF_STATUS_SUCCESS) { 323 serialization_err("Failed to reg soc ser obj delete handler"); 324 goto err_psoc_delete; 325 } 326 327 status = wlan_objmgr_register_pdev_create_handler( 328 WLAN_UMAC_COMP_SERIALIZATION, 329 wlan_serialization_pdev_obj_create_notification, NULL); 330 if (status != QDF_STATUS_SUCCESS) { 331 serialization_err("Failed to reg pdev ser obj create handler"); 332 goto err_pdev_create; 333 } 334 335 status = wlan_objmgr_register_pdev_destroy_handler( 336 WLAN_UMAC_COMP_SERIALIZATION, 337 wlan_serialization_pdev_obj_destroy_notification, NULL); 338 if (status != QDF_STATUS_SUCCESS) { 339 serialization_err("Failed to reg pdev ser obj delete handler"); 340 goto err_pdev_delete; 341 } 342 343 serialization_debug("serialization handlers registered with obj mgr"); 344 345 return QDF_STATUS_SUCCESS; 346 347 err_vdev_delete: 348 wlan_objmgr_unregister_vdev_create_handler(WLAN_UMAC_COMP_SERIALIZATION, 349 wlan_serialization_vdev_obj_create_notification, NULL); 350 err_vdev_create: 351 wlan_objmgr_unregister_pdev_destroy_handler( 352 WLAN_UMAC_COMP_SERIALIZATION, 353 wlan_serialization_pdev_obj_destroy_notification, NULL); 354 err_pdev_delete: 355 wlan_objmgr_unregister_pdev_create_handler(WLAN_UMAC_COMP_SERIALIZATION, 356 wlan_serialization_pdev_obj_create_notification, NULL); 357 err_pdev_create: 358 wlan_objmgr_unregister_psoc_destroy_handler( 359 WLAN_UMAC_COMP_SERIALIZATION, 360 wlan_serialization_psoc_obj_destroy_notification, NULL); 361 err_psoc_delete: 362 wlan_objmgr_unregister_psoc_create_handler(WLAN_UMAC_COMP_SERIALIZATION, 363 wlan_serialization_psoc_obj_create_notification, NULL); 364 err_psoc_create: 365 return status; 366 367 } 368 369 QDF_STATUS wlan_serialization_deinit(void) 370 { 371 QDF_STATUS status; 372 QDF_STATUS ret_status = QDF_STATUS_SUCCESS; 373 374 status = wlan_objmgr_unregister_psoc_create_handler( 375 WLAN_UMAC_COMP_SERIALIZATION, 376 wlan_serialization_psoc_obj_create_notification, 377 NULL); 378 if (status != QDF_STATUS_SUCCESS) { 379 serialization_err("unreg fail for psoc ser obj create notf:%d", 380 status); 381 ret_status = QDF_STATUS_E_FAILURE; 382 } 383 status = wlan_objmgr_unregister_psoc_destroy_handler( 384 WLAN_UMAC_COMP_SERIALIZATION, 385 wlan_serialization_psoc_obj_destroy_notification, 386 NULL); 387 if (status != QDF_STATUS_SUCCESS) { 388 serialization_err("unreg fail for psoc ser obj destroy notf:%d", 389 status); 390 ret_status = QDF_STATUS_E_FAILURE; 391 } 392 393 status = wlan_objmgr_unregister_pdev_create_handler( 394 WLAN_UMAC_COMP_SERIALIZATION, 395 wlan_serialization_pdev_obj_create_notification, 396 NULL); 397 if (status != QDF_STATUS_SUCCESS) { 398 serialization_err("unreg fail for pdev ser obj create notf:%d", 399 status); 400 ret_status = QDF_STATUS_E_FAILURE; 401 } 402 403 status = wlan_objmgr_unregister_pdev_destroy_handler( 404 WLAN_UMAC_COMP_SERIALIZATION, 405 wlan_serialization_pdev_obj_destroy_notification, 406 NULL); 407 if (status != QDF_STATUS_SUCCESS) { 408 serialization_err("unreg fail for pdev ser destroy notf:%d", 409 status); 410 ret_status = QDF_STATUS_E_FAILURE; 411 } 412 413 serialization_alert("deregistered callbacks with obj mgr successfully"); 414 415 return ret_status; 416 } 417 #else /* New serialition code*/ 418 #include <qdf_status.h> 419 #include <qdf_list.h> 420 #include <wlan_objmgr_cmn.h> 421 #include <wlan_objmgr_global_obj.h> 422 #include <wlan_objmgr_psoc_obj.h> 423 #include "wlan_serialization_main_i.h" 424 #include "wlan_serialization_rules_i.h" 425 #include "wlan_serialization_utils_i.h" 426 427 QDF_STATUS wlan_serialization_psoc_close(struct wlan_objmgr_psoc *psoc) 428 { 429 QDF_STATUS status = QDF_STATUS_E_FAILURE; 430 struct wlan_ser_psoc_obj *ser_soc_obj = 431 wlan_serialization_get_psoc_obj(psoc); 432 433 if (!ser_soc_obj) { 434 ser_err("invalid ser_soc_obj"); 435 goto error; 436 } 437 /* clean up all timers before exiting */ 438 status = wlan_serialization_cleanup_all_timers(ser_soc_obj); 439 if (status != QDF_STATUS_SUCCESS) 440 ser_err("ser cleanning up all timer failed"); 441 442 qdf_mem_free(ser_soc_obj->timers); 443 ser_soc_obj->timers = NULL; 444 ser_soc_obj->max_active_cmds = 0; 445 446 wlan_serialization_destroy_lock(&ser_soc_obj->timer_lock); 447 error: 448 return status; 449 } 450 451 QDF_STATUS wlan_serialization_psoc_open(struct wlan_objmgr_psoc *psoc) 452 { 453 uint8_t pdev_count; 454 struct wlan_ser_psoc_obj *ser_soc_obj = 455 wlan_serialization_get_psoc_obj(psoc); 456 QDF_STATUS status = QDF_STATUS_E_FAILURE; 457 458 if (!ser_soc_obj) { 459 ser_err("invalid ser_soc_obj"); 460 goto error; 461 } 462 463 pdev_count = wlan_psoc_get_pdev_count(psoc); 464 ser_soc_obj->max_active_cmds = WLAN_SER_MAX_ACTIVE_SCAN_CMDS + 465 (pdev_count * WLAN_SER_MAX_VDEVS); 466 467 ser_soc_obj->timers = 468 qdf_mem_malloc(sizeof(struct wlan_serialization_timer) * 469 ser_soc_obj->max_active_cmds); 470 if (!ser_soc_obj->timers) { 471 ser_alert("Mem alloc failed for ser timers"); 472 status = QDF_STATUS_E_NOMEM; 473 goto error; 474 } 475 476 wlan_serialization_create_lock(&ser_soc_obj->timer_lock); 477 status = QDF_STATUS_SUCCESS; 478 479 error: 480 return status; 481 } 482 483 /** 484 * wlan_serialization_psoc_create_handler() - PSOC obj create callback 485 * @psoc: PSOC object 486 * @arg_list: Variable argument list 487 * 488 * This callback is registered with object manager during initialization and 489 * when obj manager gets its turn to create the object, it would notify each 490 * component with the corresponding callback registered to inform the 491 * completion of the creation of the respective object. 492 * 493 * Return: QDF Status 494 */ 495 static QDF_STATUS wlan_serialization_psoc_create_handler( 496 struct wlan_objmgr_psoc *psoc, void *arg_list) 497 { 498 struct wlan_ser_psoc_obj *soc_ser_obj; 499 QDF_STATUS status = QDF_STATUS_E_NOMEM; 500 501 soc_ser_obj = 502 qdf_mem_malloc(sizeof(*soc_ser_obj)); 503 if (!soc_ser_obj) { 504 ser_alert("Mem alloc failed for ser psoc priv obj"); 505 goto error; 506 } 507 status = wlan_objmgr_psoc_component_obj_attach( 508 psoc, 509 WLAN_UMAC_COMP_SERIALIZATION, 510 soc_ser_obj, 511 QDF_STATUS_SUCCESS); 512 if (QDF_IS_STATUS_ERROR(status)) { 513 qdf_mem_free(soc_ser_obj); 514 ser_err("Obj attach failed"); 515 goto error; 516 } 517 ser_debug("ser psoc obj created"); 518 status = QDF_STATUS_SUCCESS; 519 520 error: 521 return status; 522 } 523 524 /** 525 * wlan_serialization_destroy_cmd_pool() - Destroy the global cmd pool 526 * @ser_pdev_obj: Serialization private pdev object 527 * 528 * Return: None 529 */ 530 static void wlan_serialization_destroy_cmd_pool( 531 struct wlan_serialization_pdev_queue *pdev_queue) 532 { 533 qdf_list_node_t *node = NULL; 534 struct wlan_serialization_command_list *cmd_list; 535 536 while (!qdf_list_empty(&pdev_queue->cmd_pool_list)) { 537 qdf_list_remove_front(&pdev_queue->cmd_pool_list, 538 &node); 539 cmd_list = (struct wlan_serialization_command_list *)node; 540 ser_debug("Node being freed from global pool %pK", 541 cmd_list); 542 qdf_mem_free(cmd_list); 543 } 544 545 qdf_list_destroy(&pdev_queue->cmd_pool_list); 546 547 } 548 549 /** 550 * wlan_serialization_create_cmd_pool() - Create the global cmd pool 551 * @pdev: PDEV Object 552 * @ser_pdev_obj: Serialization private pdev object 553 * 554 * Global command pool of memory is created here. 555 * It is safe to allocate memory individually for each command rather than 556 * requesting for a huge chunk of memory at once. 557 * 558 * The individual command nodes allocated above will keep moving between 559 * the active, pending and global pool lists dynamically, but all the 560 * memory will be freed during driver unload only. 561 * 562 * Return: QDF Status 563 */ 564 static QDF_STATUS 565 wlan_serialization_create_cmd_pool( 566 struct wlan_serialization_pdev_queue *pdev_queue, 567 uint16_t cmd_pool_size) 568 { 569 struct wlan_serialization_command_list *cmd_list_ptr; 570 uint8_t i; 571 QDF_STATUS status = QDF_STATUS_E_NOMEM; 572 573 qdf_list_create(&pdev_queue->cmd_pool_list, cmd_pool_size); 574 575 for (i = 0; i < cmd_pool_size; i++) { 576 cmd_list_ptr = qdf_mem_malloc(sizeof(*cmd_list_ptr)); 577 if (!cmd_list_ptr) { 578 ser_alert("Mem alloc failed for cmd node"); 579 wlan_serialization_destroy_cmd_pool(pdev_queue); 580 goto error; 581 } 582 583 qdf_mem_zero(cmd_list_ptr, sizeof(*cmd_list_ptr)); 584 qdf_list_insert_back( 585 &pdev_queue->cmd_pool_list, 586 &cmd_list_ptr->pdev_node); 587 cmd_list_ptr->cmd_in_use = 0; 588 ser_debug("Created node at %pK and inserted to pool", 589 cmd_list_ptr); 590 } 591 592 status = QDF_STATUS_SUCCESS; 593 594 error: 595 return status; 596 } 597 598 /** 599 * wlan_serialization_pdev_create_handler() - PDEV obj create callback 600 * @pdev: PDEV object 601 * @arg_list: Variable argument list 602 * 603 * This callback is registered with object manager during initialization and 604 * when obj manager gets its turn to create the object, it would notify each 605 * component with the corresponding callback registered to inform the 606 * completion of the creation of the respective object. 607 * 608 * Return: QDF Status 609 */ 610 static QDF_STATUS wlan_serialization_pdev_create_handler( 611 struct wlan_objmgr_pdev *pdev, void *arg_list) 612 { 613 struct wlan_ser_pdev_obj *ser_pdev_obj; 614 struct wlan_serialization_pdev_queue *pdev_queue; 615 QDF_STATUS status = QDF_STATUS_E_NOMEM; 616 uint8_t index; 617 uint8_t free_index; 618 uint8_t max_active_cmds; 619 uint8_t max_pending_cmds; 620 uint16_t cmd_pool_size; 621 622 ser_pdev_obj = 623 qdf_mem_malloc(sizeof(*ser_pdev_obj)); 624 if (!ser_pdev_obj) { 625 ser_alert("Mem alloc failed for ser pdev obj"); 626 goto error; 627 } 628 629 for (index = 0; index < SER_PDEV_QUEUE_COMP_MAX; index++) { 630 pdev_queue = &ser_pdev_obj->pdev_q[index]; 631 632 wlan_serialization_create_lock(&pdev_queue->pdev_queue_lock); 633 634 switch (index) { 635 case SER_PDEV_QUEUE_COMP_SCAN: 636 max_active_cmds = WLAN_SER_MAX_ACTIVE_SCAN_CMDS; 637 max_pending_cmds = WLAN_SER_MAX_PENDING_SCAN_CMDS; 638 cmd_pool_size = max_active_cmds + max_pending_cmds; 639 break; 640 641 case SER_PDEV_QUEUE_COMP_NON_SCAN: 642 max_active_cmds = WLAN_SER_MAX_ACTIVE_CMDS; 643 max_pending_cmds = WLAN_SER_MAX_PENDING_CMDS; 644 cmd_pool_size = max_active_cmds + max_pending_cmds; 645 break; 646 } 647 qdf_list_create(&pdev_queue->active_list, 648 max_active_cmds); 649 qdf_list_create(&pdev_queue->pending_list, 650 max_pending_cmds); 651 652 status = wlan_serialization_create_cmd_pool(pdev_queue, 653 cmd_pool_size); 654 if (status != QDF_STATUS_SUCCESS) { 655 ser_err("Create cmd pool failed, status %d", status); 656 goto error_free; 657 } 658 659 pdev_queue->vdev_active_cmd_bitmap = 0; 660 pdev_queue->blocking_cmd_active = 0; 661 pdev_queue->blocking_cmd_waiting = 0; 662 } 663 664 status = wlan_objmgr_pdev_component_obj_attach( 665 pdev, WLAN_UMAC_COMP_SERIALIZATION, 666 ser_pdev_obj, QDF_STATUS_SUCCESS); 667 668 if (status != QDF_STATUS_SUCCESS) { 669 ser_err("Pdev obj attach failed, status %d", status); 670 goto error_free; 671 } 672 673 return QDF_STATUS_SUCCESS; 674 675 error_free: 676 for (free_index = 0; free_index <= index; free_index++) { 677 pdev_queue = &ser_pdev_obj->pdev_q[free_index]; 678 679 wlan_serialization_destroy_cmd_pool(pdev_queue); 680 qdf_list_destroy(&pdev_queue->pending_list); 681 qdf_list_destroy(&pdev_queue->active_list); 682 wlan_serialization_destroy_lock(&pdev_queue->pdev_queue_lock); 683 } 684 error: 685 return status; 686 } 687 688 /** 689 * wlan_serialization_psoc_destroy_handler() - PSOC obj delete callback 690 * @psoc: PSOC object 691 * @arg_list: Variable argument list 692 * 693 * This callback is registered with object manager during initialization and 694 * when obj manager gets its turn to delete the object, it would notify each 695 * component with the corresponding callback registered to inform the 696 * completion of the deletion of the respective object. 697 * 698 * Return: QDF Status 699 */ 700 static QDF_STATUS 701 wlan_serialization_psoc_destroy_handler(struct wlan_objmgr_psoc *psoc, 702 void *arg_list) 703 { 704 QDF_STATUS status = QDF_STATUS_E_FAULT; 705 struct wlan_ser_psoc_obj *ser_soc_obj = 706 wlan_serialization_get_psoc_obj(psoc); 707 708 if (!ser_soc_obj) { 709 ser_err("invalid ser_soc_obj"); 710 goto error; 711 } 712 status = wlan_objmgr_psoc_component_obj_detach( 713 psoc, WLAN_UMAC_COMP_SERIALIZATION, ser_soc_obj); 714 if (status != QDF_STATUS_SUCCESS) 715 ser_err("ser psoc private obj detach failed"); 716 717 ser_debug("ser psoc obj deleted with status %d", status); 718 qdf_mem_free(ser_soc_obj); 719 720 error: 721 return status; 722 } 723 724 /** 725 * wlan_serialization_pdev_destroy_handler() - PDEV obj delete callback 726 * @pdev: PDEV object 727 * @arg_list: Variable argument list 728 * 729 * This callback is registered with object manager during initialization and 730 * when obj manager gets its turn to delete the object, it would notify each 731 * component with the corresponding callback registered to inform the 732 * completion of the deletion of the respective object. 733 * 734 * Return: QDF Status 735 */ 736 static QDF_STATUS wlan_serialization_pdev_destroy_handler( 737 struct wlan_objmgr_pdev *pdev, void *arg_list) 738 { 739 QDF_STATUS status; 740 struct wlan_serialization_pdev_queue *pdev_queue; 741 struct wlan_ser_pdev_obj *ser_pdev_obj = 742 wlan_serialization_get_pdev_obj(pdev); 743 uint8_t index; 744 745 if (!ser_pdev_obj) { 746 ser_err("ser_pdev_obj NULL"); 747 return QDF_STATUS_E_INVAL; 748 } 749 status = wlan_objmgr_pdev_component_obj_detach( 750 pdev, WLAN_UMAC_COMP_SERIALIZATION, ser_pdev_obj); 751 752 for (index = 0; index < SER_PDEV_QUEUE_COMP_MAX; index++) { 753 pdev_queue = &ser_pdev_obj->pdev_q[index]; 754 755 wlan_serialization_destroy_pdev_list(pdev_queue); 756 wlan_serialization_destroy_cmd_pool(pdev_queue); 757 758 wlan_serialization_destroy_lock(&pdev_queue->pdev_queue_lock); 759 } 760 qdf_mem_free(ser_pdev_obj); 761 762 return status; 763 } 764 765 /** 766 * wlan_serialization_vdev_create_handler() - VDEV obj create callback 767 * @vdev: VDEV object 768 * @arg_list: Variable argument list 769 * 770 * This callback is registered with object manager during initialization and 771 * when obj manager gets its turn to create the object, it would notify each 772 * component with the corresponding callback registered to inform the 773 * completion of the creation of the respective object. 774 * 775 * Return: QDF Status 776 */ 777 static QDF_STATUS 778 wlan_serialization_vdev_create_handler(struct wlan_objmgr_vdev *vdev, 779 void *arg_list) 780 { 781 struct wlan_ser_vdev_obj *ser_vdev_obj; 782 struct wlan_serialization_vdev_queue *vdev_q; 783 QDF_STATUS status = QDF_STATUS_E_NOMEM; 784 uint8_t index; 785 uint8_t max_active_cmds; 786 uint8_t max_pending_cmds; 787 788 ser_vdev_obj = qdf_mem_malloc(sizeof(*ser_vdev_obj)); 789 if (!ser_vdev_obj) { 790 ser_alert("Mem alloc failed for ser vdev obj"); 791 goto error; 792 } 793 794 for (index = 0; index < SER_VDEV_QUEUE_COMP_MAX; index++) { 795 vdev_q = &ser_vdev_obj->vdev_q[index]; 796 797 switch (index) { 798 case SER_VDEV_QUEUE_COMP_NON_SCAN: 799 max_active_cmds = WLAN_SER_MAX_ACTIVE_CMDS / 800 WLAN_SER_MAX_VDEVS; 801 max_pending_cmds = WLAN_SER_MAX_PENDING_CMDS / 802 WLAN_SER_MAX_VDEVS; 803 break; 804 } 805 806 qdf_list_create(&vdev_q->active_list, 807 max_active_cmds); 808 qdf_list_create(&vdev_q->pending_list, 809 max_pending_cmds); 810 } 811 812 status = wlan_objmgr_vdev_component_obj_attach( 813 vdev, WLAN_UMAC_COMP_SERIALIZATION, ser_vdev_obj, 814 QDF_STATUS_SUCCESS); 815 816 if (status != QDF_STATUS_SUCCESS) { 817 for (index = 0; index < SER_VDEV_QUEUE_COMP_MAX; index++) { 818 vdev_q = &ser_vdev_obj->vdev_q[index]; 819 qdf_list_destroy(&vdev_q->pending_list); 820 qdf_list_destroy(&vdev_q->active_list); 821 } 822 qdf_mem_free(ser_vdev_obj); 823 ser_err("serialization vdev obj attach failed"); 824 } 825 error: 826 return status; 827 } 828 829 /** 830 * wlan_serialization_vdev_destroy_handler() - vdev obj delete callback 831 * @vdev: VDEV object 832 * @arg_list: Variable argument list 833 * 834 * This callback is registered with object manager during initialization and 835 * when obj manager gets its turn to delete the object, it would notify each 836 * component with the corresponding callback registered to inform the 837 * completion of the deletion of the respective object. 838 * 839 * Return: QDF Status 840 */ 841 static QDF_STATUS wlan_serialization_vdev_destroy_handler( 842 struct wlan_objmgr_vdev *vdev, void *arg_list) 843 { 844 QDF_STATUS status = QDF_STATUS_SUCCESS; 845 struct wlan_serialization_vdev_queue *vdev_q; 846 struct wlan_ser_vdev_obj *ser_vdev_obj = 847 wlan_serialization_get_vdev_obj(vdev); 848 uint8_t index; 849 850 if (!ser_vdev_obj) { 851 ser_err("ser_vdev_obj NULL"); 852 return QDF_STATUS_E_INVAL; 853 } 854 855 status = wlan_objmgr_vdev_component_obj_detach( 856 vdev, WLAN_UMAC_COMP_SERIALIZATION, ser_vdev_obj); 857 858 /*Clean up serialization timers if any for this vdev*/ 859 wlan_serialization_cleanup_vdev_timers(vdev); 860 861 for (index = 0; index < SER_VDEV_QUEUE_COMP_MAX; index++) { 862 vdev_q = &ser_vdev_obj->vdev_q[index]; 863 wlan_serialization_destroy_vdev_list(&vdev_q->pending_list); 864 wlan_serialization_destroy_vdev_list(&vdev_q->active_list); 865 } 866 867 qdf_mem_free(ser_vdev_obj); 868 869 return status; 870 } 871 872 QDF_STATUS wlan_serialization_init(void) 873 { 874 QDF_STATUS status = QDF_STATUS_SUCCESS; 875 876 status = wlan_objmgr_register_psoc_create_handler( 877 WLAN_UMAC_COMP_SERIALIZATION, 878 wlan_serialization_psoc_create_handler, NULL); 879 if (status != QDF_STATUS_SUCCESS) { 880 ser_err("Failed to reg soc ser obj create handler"); 881 goto err_psoc_create; 882 } 883 884 status = wlan_objmgr_register_psoc_destroy_handler( 885 WLAN_UMAC_COMP_SERIALIZATION, 886 wlan_serialization_psoc_destroy_handler, NULL); 887 if (status != QDF_STATUS_SUCCESS) { 888 ser_err("Failed to reg soc ser obj delete handler"); 889 goto err_psoc_delete; 890 } 891 892 status = wlan_objmgr_register_pdev_create_handler( 893 WLAN_UMAC_COMP_SERIALIZATION, 894 wlan_serialization_pdev_create_handler, NULL); 895 if (status != QDF_STATUS_SUCCESS) { 896 ser_err("Failed to reg pdev ser obj create handler"); 897 goto err_pdev_create; 898 } 899 900 status = wlan_objmgr_register_pdev_destroy_handler( 901 WLAN_UMAC_COMP_SERIALIZATION, 902 wlan_serialization_pdev_destroy_handler, NULL); 903 if (status != QDF_STATUS_SUCCESS) { 904 ser_err("Failed to reg pdev ser obj delete handler"); 905 goto err_pdev_delete; 906 } 907 908 status = wlan_objmgr_register_vdev_create_handler( 909 WLAN_UMAC_COMP_SERIALIZATION, 910 wlan_serialization_vdev_create_handler, NULL); 911 if (status != QDF_STATUS_SUCCESS) { 912 ser_err("Failed to reg vdev ser obj create handler"); 913 goto err_vdev_create; 914 } 915 916 status = wlan_objmgr_register_vdev_destroy_handler( 917 WLAN_UMAC_COMP_SERIALIZATION, 918 wlan_serialization_vdev_destroy_handler, NULL); 919 if (status != QDF_STATUS_SUCCESS) { 920 ser_err("Failed to reg vdev ser obj delete handler"); 921 goto err_vdev_delete; 922 } 923 924 status = QDF_STATUS_SUCCESS; 925 goto exit; 926 927 err_vdev_delete: 928 wlan_objmgr_unregister_vdev_create_handler( 929 WLAN_UMAC_COMP_SERIALIZATION, 930 wlan_serialization_vdev_create_handler, 931 NULL); 932 err_vdev_create: 933 wlan_objmgr_unregister_pdev_destroy_handler( 934 WLAN_UMAC_COMP_SERIALIZATION, 935 wlan_serialization_pdev_destroy_handler, 936 NULL); 937 err_pdev_delete: 938 wlan_objmgr_unregister_pdev_create_handler( 939 WLAN_UMAC_COMP_SERIALIZATION, 940 wlan_serialization_pdev_create_handler, 941 NULL); 942 err_pdev_create: 943 wlan_objmgr_unregister_psoc_destroy_handler( 944 WLAN_UMAC_COMP_SERIALIZATION, 945 wlan_serialization_psoc_destroy_handler, 946 NULL); 947 err_psoc_delete: 948 wlan_objmgr_unregister_psoc_create_handler( 949 WLAN_UMAC_COMP_SERIALIZATION, 950 wlan_serialization_psoc_create_handler, 951 NULL); 952 err_psoc_create: 953 exit: 954 return status; 955 } 956 957 QDF_STATUS wlan_serialization_deinit(void) 958 { 959 QDF_STATUS status; 960 QDF_STATUS ret_status = QDF_STATUS_SUCCESS; 961 962 status = wlan_objmgr_unregister_psoc_create_handler( 963 WLAN_UMAC_COMP_SERIALIZATION, 964 wlan_serialization_psoc_create_handler, 965 NULL); 966 967 if (status != QDF_STATUS_SUCCESS) { 968 ser_err("unreg fail for psoc ser obj create notf:%d", status); 969 ret_status = QDF_STATUS_E_FAILURE; 970 } 971 status = wlan_objmgr_unregister_psoc_destroy_handler( 972 WLAN_UMAC_COMP_SERIALIZATION, 973 wlan_serialization_psoc_destroy_handler, 974 NULL); 975 976 if (status != QDF_STATUS_SUCCESS) { 977 ser_err("unreg fail for psoc ser obj destroy notf:%d", status); 978 ret_status = QDF_STATUS_E_FAILURE; 979 } 980 981 status = wlan_objmgr_unregister_pdev_create_handler( 982 WLAN_UMAC_COMP_SERIALIZATION, 983 wlan_serialization_pdev_create_handler, 984 NULL); 985 if (status != QDF_STATUS_SUCCESS) { 986 ser_err("unreg fail for pdev ser obj create notf:%d", status); 987 ret_status = QDF_STATUS_E_FAILURE; 988 } 989 990 status = wlan_objmgr_unregister_pdev_destroy_handler( 991 WLAN_UMAC_COMP_SERIALIZATION, 992 wlan_serialization_pdev_destroy_handler, 993 NULL); 994 995 if (status != QDF_STATUS_SUCCESS) { 996 ser_err("unreg fail for pdev ser destroy notf:%d", status); 997 ret_status = QDF_STATUS_E_FAILURE; 998 } 999 1000 ser_alert("deregistered callbacks with obj mgr successfully"); 1001 1002 return ret_status; 1003 } 1004 #endif 1005