1 /* 2 * Copyright (c) 2017-2021 The Linux Foundation. All rights reserved. 3 * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved. 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: wlan_serialization_utils.c 22 * This file defines the utility helper functions for serialization component. 23 */ 24 25 #include <wlan_objmgr_vdev_obj.h> 26 #include <wlan_objmgr_pdev_obj.h> 27 #include <qdf_mc_timer.h> 28 #include <wlan_utility.h> 29 #include "wlan_serialization_utils_i.h" 30 #include "wlan_serialization_main_i.h" 31 #include "wlan_serialization_queue_i.h" 32 #include "wlan_serialization_api.h" 33 34 #ifndef WLAN_SER_DEBUG 35 void wlan_ser_update_cmd_history( 36 struct wlan_serialization_pdev_queue *pdev_queue, 37 struct wlan_serialization_command *cmd, 38 enum ser_queue_reason ser_reason, 39 bool add_remove, 40 bool active_queue){ } 41 #endif 42 43 struct wlan_objmgr_pdev* 44 wlan_serialization_get_pdev_from_cmd(struct wlan_serialization_command *cmd) 45 { 46 struct wlan_objmgr_pdev *pdev = NULL; 47 48 if (!cmd) { 49 ser_err("invalid cmd"); 50 return pdev; 51 } 52 if (!cmd->vdev) { 53 ser_err("invalid cmd->vdev"); 54 return pdev; 55 } 56 pdev = wlan_vdev_get_pdev(cmd->vdev); 57 58 return pdev; 59 } 60 61 struct wlan_objmgr_psoc* 62 wlan_serialization_get_psoc_from_cmd(struct wlan_serialization_command *cmd) 63 { 64 struct wlan_objmgr_psoc *psoc = NULL; 65 66 if (!cmd) { 67 ser_err("invalid cmd"); 68 return psoc; 69 } 70 if (!cmd->vdev) { 71 ser_err("invalid cmd->vdev"); 72 return psoc; 73 } 74 psoc = wlan_vdev_get_psoc(cmd->vdev); 75 76 return psoc; 77 } 78 79 struct wlan_objmgr_vdev* 80 wlan_serialization_get_vdev_from_cmd(struct wlan_serialization_command *cmd) 81 { 82 struct wlan_objmgr_vdev *vdev = NULL; 83 84 if (!cmd) { 85 ser_err("invalid cmd"); 86 goto error; 87 } 88 89 vdev = cmd->vdev; 90 91 error: 92 return vdev; 93 } 94 95 QDF_STATUS 96 wlan_serialization_get_cmd_from_queue(qdf_list_t *queue, 97 qdf_list_node_t **nnode) 98 { 99 QDF_STATUS status = QDF_STATUS_E_FAILURE; 100 qdf_list_node_t *pnode; 101 102 if (!queue) { 103 ser_err("input parameters are invalid"); 104 goto error; 105 } 106 107 pnode = *nnode; 108 if (!pnode) 109 status = wlan_serialization_peek_front(queue, nnode); 110 else 111 status = wlan_serialization_peek_next(queue, pnode, nnode); 112 113 if (status != QDF_STATUS_SUCCESS) 114 ser_err("can't get next node from queue"); 115 116 error: 117 return status; 118 } 119 120 QDF_STATUS wlan_serialization_timer_destroy( 121 struct wlan_serialization_timer *ser_timer) 122 { 123 QDF_STATUS qdf_status = QDF_STATUS_SUCCESS; 124 125 if (!ser_timer || !ser_timer->cmd) { 126 ser_debug("Invalid ser_timer"); 127 qdf_status = QDF_STATUS_E_FAILURE; 128 goto error; 129 } 130 /* Wait till timeout CB is completed */ 131 qdf_timer_sync_cancel(&ser_timer->timer); 132 ser_timer->cmd = NULL; 133 134 error: 135 return qdf_status; 136 } 137 138 QDF_STATUS 139 wlan_serialization_stop_timer(struct wlan_serialization_timer *ser_timer) 140 { 141 wlan_serialization_timer_destroy(ser_timer); 142 143 return QDF_STATUS_SUCCESS; 144 } 145 146 QDF_STATUS wlan_serialization_cleanup_vdev_timers( 147 struct wlan_objmgr_vdev *vdev) 148 { 149 struct wlan_ser_psoc_obj *psoc_ser_obj; 150 struct wlan_serialization_timer *ser_timer; 151 QDF_STATUS status = QDF_STATUS_SUCCESS; 152 uint32_t i = 0; 153 struct wlan_objmgr_pdev *pdev = NULL; 154 struct wlan_objmgr_psoc *psoc = NULL; 155 156 pdev = wlan_vdev_get_pdev(vdev); 157 if (!pdev) { 158 QDF_BUG(0); 159 ser_err("pdev is null"); 160 status = QDF_STATUS_E_FAILURE; 161 goto error; 162 } 163 164 psoc = wlan_pdev_get_psoc(pdev); 165 if (!psoc) { 166 QDF_BUG(0); 167 ser_err("psoc is null"); 168 status = QDF_STATUS_E_FAILURE; 169 goto error; 170 } 171 172 psoc_ser_obj = wlan_serialization_get_psoc_obj(psoc); 173 174 if (!psoc_ser_obj) { 175 ser_err("Invalid psoc_ser_obj"); 176 status = QDF_STATUS_E_FAILURE; 177 goto error; 178 } 179 180 wlan_serialization_acquire_lock(&psoc_ser_obj->timer_lock); 181 182 for (i = 0; psoc_ser_obj->max_active_cmds > i; i++) { 183 ser_timer = &psoc_ser_obj->timers[i]; 184 if (!ser_timer->cmd) 185 continue; 186 /* 187 * Check if the timer is for the given vdev 188 */ 189 if (ser_timer->cmd->vdev != vdev) 190 continue; 191 192 ser_debug("Stopping the timer for vdev id[%d]", 193 wlan_vdev_get_id(vdev)); 194 195 status = wlan_serialization_stop_timer(ser_timer); 196 if (QDF_STATUS_SUCCESS != status) { 197 /* lets not break the loop but report error */ 198 ser_err("some error in stopping timer"); 199 } 200 } 201 202 wlan_serialization_release_lock(&psoc_ser_obj->timer_lock); 203 error: 204 return status; 205 } 206 207 QDF_STATUS wlan_serialization_cleanup_all_timers( 208 struct wlan_ser_psoc_obj *psoc_ser_obj) 209 { 210 struct wlan_serialization_timer *ser_timer; 211 QDF_STATUS status = QDF_STATUS_SUCCESS; 212 uint32_t i = 0; 213 214 if (!psoc_ser_obj) { 215 ser_err("Invalid psoc_ser_obj"); 216 status = QDF_STATUS_E_FAILURE; 217 goto error; 218 } 219 220 wlan_serialization_acquire_lock(&psoc_ser_obj->timer_lock); 221 222 for (i = 0; psoc_ser_obj->max_active_cmds > i; i++) { 223 ser_timer = &psoc_ser_obj->timers[i]; 224 if (!ser_timer->cmd) 225 continue; 226 status = wlan_serialization_stop_timer(ser_timer); 227 if (QDF_STATUS_SUCCESS != status) { 228 /* lets not break the loop but report error */ 229 ser_err("some error in stopping timer"); 230 } 231 } 232 233 wlan_serialization_release_lock(&psoc_ser_obj->timer_lock); 234 error: 235 236 return status; 237 } 238 239 QDF_STATUS wlan_serialization_validate_cmdtype( 240 enum wlan_serialization_cmd_type cmd_type) 241 { 242 if (cmd_type < 0 || cmd_type >= WLAN_SER_CMD_MAX) { 243 ser_err("Invalid cmd %d passed", cmd_type); 244 return QDF_STATUS_E_INVAL; 245 } 246 247 return QDF_STATUS_SUCCESS; 248 } 249 250 QDF_STATUS wlan_serialization_validate_cmd( 251 enum wlan_umac_comp_id comp_id, 252 enum wlan_serialization_cmd_type cmd_type) 253 { 254 QDF_STATUS status = QDF_STATUS_E_INVAL; 255 256 if (cmd_type < 0 || comp_id < 0 || cmd_type >= WLAN_SER_CMD_MAX || 257 comp_id >= WLAN_UMAC_COMP_ID_MAX) { 258 ser_err("Invalid cmd or comp passed comp %d type %d", 259 comp_id, cmd_type); 260 goto error; 261 } 262 263 status = QDF_STATUS_SUCCESS; 264 error: 265 return status; 266 } 267 268 QDF_STATUS wlan_serialization_validate_cmd_list( 269 struct wlan_serialization_command_list *cmd_list) 270 { 271 QDF_STATUS status = QDF_STATUS_E_INVAL; 272 273 if (!cmd_list->cmd.cmd_cb) { 274 ser_err("no cmd_cb for cmd type:%d, id: %d", 275 cmd_list->cmd.cmd_type, cmd_list->cmd.cmd_id); 276 QDF_ASSERT(0); 277 goto error; 278 } 279 280 if (!cmd_list->cmd.vdev) { 281 ser_err("invalid cmd.vdev"); 282 goto error; 283 } 284 285 status = QDF_STATUS_SUCCESS; 286 287 error: 288 return status; 289 } 290 291 static void wlan_serialization_release_pdev_list_cmds( 292 struct wlan_serialization_pdev_queue *pdev_queue) 293 { 294 qdf_list_node_t *node = NULL; 295 296 while (!wlan_serialization_list_empty(&pdev_queue->active_list)) { 297 wlan_serialization_remove_front( 298 &pdev_queue->active_list, &node); 299 wlan_serialization_insert_back( 300 &pdev_queue->cmd_pool_list, node); 301 } 302 303 while (!wlan_serialization_list_empty(&pdev_queue->pending_list)) { 304 wlan_serialization_remove_front( 305 &pdev_queue->pending_list, &node); 306 wlan_serialization_insert_back( 307 &pdev_queue->cmd_pool_list, node); 308 } 309 310 } 311 312 static void wlan_serialization_release_vdev_list_cmds(qdf_list_t *list) 313 { 314 qdf_list_node_t *node = NULL; 315 316 317 while (!wlan_serialization_list_empty(list)) 318 wlan_serialization_remove_front(list, &node); 319 320 } 321 322 void wlan_serialization_destroy_pdev_list( 323 struct wlan_serialization_pdev_queue *pdev_queue) 324 { 325 326 wlan_serialization_release_pdev_list_cmds(pdev_queue); 327 qdf_list_destroy(&pdev_queue->pending_list); 328 qdf_list_destroy(&pdev_queue->active_list); 329 330 } 331 332 void wlan_serialization_destroy_vdev_list(qdf_list_t *list) 333 { 334 335 wlan_serialization_release_vdev_list_cmds(list); 336 qdf_list_destroy(list); 337 338 } 339 340 struct wlan_ser_psoc_obj *wlan_serialization_get_psoc_obj( 341 struct wlan_objmgr_psoc *psoc) 342 { 343 struct wlan_ser_psoc_obj *ser_soc_obj; 344 345 ser_soc_obj = 346 wlan_objmgr_psoc_get_comp_private_obj( 347 psoc, WLAN_UMAC_COMP_SERIALIZATION); 348 349 return ser_soc_obj; 350 } 351 352 struct wlan_ser_pdev_obj *wlan_serialization_get_pdev_obj( 353 struct wlan_objmgr_pdev *pdev) 354 { 355 struct wlan_ser_pdev_obj *obj; 356 357 obj = wlan_objmgr_pdev_get_comp_private_obj( 358 pdev, WLAN_UMAC_COMP_SERIALIZATION); 359 360 return obj; 361 } 362 363 struct wlan_ser_vdev_obj *wlan_serialization_get_vdev_obj( 364 struct wlan_objmgr_vdev *vdev) 365 { 366 struct wlan_ser_vdev_obj *obj; 367 368 obj = wlan_objmgr_vdev_get_comp_private_obj( 369 vdev, WLAN_UMAC_COMP_SERIALIZATION); 370 371 return obj; 372 } 373 374 bool wlan_serialization_is_cmd_in_vdev_list( 375 struct wlan_objmgr_vdev *vdev, 376 qdf_list_t *queue, 377 enum wlan_serialization_node node_type) 378 { 379 qdf_list_node_t *node = NULL; 380 bool cmd_found = false; 381 382 node = wlan_serialization_find_cmd( 383 queue, WLAN_SER_MATCH_VDEV, 384 NULL, 0, NULL, vdev, node_type); 385 386 if (node) 387 cmd_found = true; 388 389 return cmd_found; 390 } 391 392 bool wlan_serialization_is_cmd_in_pdev_list( 393 struct wlan_objmgr_pdev *pdev, 394 qdf_list_t *queue) 395 { 396 qdf_list_node_t *node = NULL; 397 bool cmd_found = false; 398 399 node = wlan_serialization_find_cmd( 400 queue, WLAN_SER_MATCH_PDEV, 401 NULL, 0, pdev, NULL, WLAN_SER_PDEV_NODE); 402 403 if (node) 404 cmd_found = true; 405 406 return cmd_found; 407 } 408 409 enum wlan_serialization_cmd_status 410 wlan_serialization_is_cmd_in_active_pending(bool cmd_in_active, 411 bool cmd_in_pending) 412 { 413 enum wlan_serialization_cmd_status status; 414 415 if (cmd_in_active && cmd_in_pending) 416 status = WLAN_SER_CMDS_IN_ALL_LISTS; 417 else if (cmd_in_active) 418 status = WLAN_SER_CMD_IN_ACTIVE_LIST; 419 else if (cmd_in_pending) 420 status = WLAN_SER_CMD_IN_PENDING_LIST; 421 else 422 status = WLAN_SER_CMD_NOT_FOUND; 423 424 return status; 425 } 426 427 bool 428 wlan_serialization_is_cmd_present_in_given_queue( 429 qdf_list_t *queue, 430 struct wlan_serialization_command *cmd, 431 enum wlan_serialization_node node_type) 432 { 433 qdf_list_node_t *node = NULL; 434 bool found = false; 435 436 node = wlan_serialization_find_cmd( 437 queue, WLAN_SER_MATCH_CMD_ID_VDEV, 438 cmd, 0, NULL, cmd->vdev, node_type); 439 440 if (node) 441 found = true; 442 443 return found; 444 } 445 446 QDF_STATUS 447 wlan_serialization_remove_cmd_from_queue( 448 qdf_list_t *queue, 449 struct wlan_serialization_command *cmd, 450 struct wlan_serialization_command_list **pcmd_list, 451 struct wlan_ser_pdev_obj *ser_pdev_obj, 452 enum wlan_serialization_node node_type) 453 { 454 struct wlan_serialization_command_list *cmd_list; 455 qdf_list_node_t *node = NULL; 456 QDF_STATUS status = QDF_STATUS_E_FAILURE; 457 458 if (!cmd) 459 goto error; 460 461 if (!queue || wlan_serialization_list_empty(queue)) { 462 ser_debug("Empty queue"); 463 goto error; 464 } 465 466 node = wlan_serialization_find_cmd(queue, WLAN_SER_MATCH_CMD_ID_VDEV, 467 cmd, 0, NULL, cmd->vdev, node_type); 468 469 if (!node) { 470 ser_info("fail to find node %d for removal", node_type); 471 goto error; 472 } 473 474 if (node_type == WLAN_SER_PDEV_NODE) 475 cmd_list = 476 qdf_container_of(node, 477 struct wlan_serialization_command_list, 478 pdev_node); 479 else 480 cmd_list = 481 qdf_container_of(node, 482 struct wlan_serialization_command_list, 483 vdev_node); 484 485 if (qdf_atomic_test_bit(CMD_MARKED_FOR_ACTIVATION, 486 &cmd_list->cmd_in_use)) { 487 qdf_atomic_set_bit(CMD_ACTIVE_MARKED_FOR_REMOVAL, 488 &cmd_list->cmd_in_use); 489 status = QDF_STATUS_E_PENDING; 490 goto error; 491 } 492 493 status = wlan_serialization_remove_node(queue, node); 494 495 if (QDF_STATUS_SUCCESS != status) 496 ser_err("Fail to add to free pool type %d", 497 cmd->cmd_type); 498 499 *pcmd_list = cmd_list; 500 501 error: 502 return status; 503 } 504 505 enum wlan_serialization_status 506 wlan_serialization_add_cmd_to_queue( 507 qdf_list_t *queue, 508 struct wlan_serialization_command_list *cmd_list, 509 struct wlan_ser_pdev_obj *ser_pdev_obj, 510 uint8_t is_cmd_for_active_queue, 511 enum wlan_serialization_node node_type) 512 { 513 enum wlan_serialization_status status = WLAN_SER_CMD_DENIED_UNSPECIFIED; 514 QDF_STATUS qdf_status; 515 qdf_list_node_t *node; 516 517 if (!cmd_list || !queue || !ser_pdev_obj) { 518 ser_err("Input arguments are not valid"); 519 goto error; 520 } 521 522 if (node_type == WLAN_SER_PDEV_NODE) 523 node = &cmd_list->pdev_node; 524 else 525 node = &cmd_list->vdev_node; 526 527 if (qdf_list_size(queue) == qdf_list_max_size(queue)) { 528 status = WLAN_SER_CMD_DENIED_LIST_FULL; 529 ser_err("Queue size reached max %d, fail to add type %d id %d", 530 qdf_list_max_size(queue), cmd_list->cmd.cmd_type, 531 cmd_list->cmd.cmd_id); 532 goto error; 533 } 534 535 if (cmd_list->cmd.is_high_priority) 536 qdf_status = wlan_serialization_insert_front(queue, node); 537 else 538 qdf_status = wlan_serialization_insert_back(queue, node); 539 540 if (QDF_IS_STATUS_ERROR(qdf_status)) 541 goto error; 542 543 if (is_cmd_for_active_queue) 544 status = WLAN_SER_CMD_ACTIVE; 545 else 546 status = WLAN_SER_CMD_PENDING; 547 548 error: 549 return status; 550 } 551 552 bool wlan_serialization_list_empty(qdf_list_t *queue) 553 { 554 bool is_empty; 555 556 if (qdf_list_empty(queue)) 557 is_empty = true; 558 else 559 is_empty = false; 560 561 return is_empty; 562 } 563 564 uint32_t wlan_serialization_list_size(qdf_list_t *queue) 565 { 566 uint32_t size; 567 568 size = qdf_list_size(queue); 569 570 return size; 571 } 572 573 QDF_STATUS wlan_serialization_remove_front(qdf_list_t *list, 574 qdf_list_node_t **node) 575 { 576 QDF_STATUS status; 577 578 if (wlan_serialization_list_empty(list)) { 579 ser_err("The list is empty"); 580 status = QDF_STATUS_E_EMPTY; 581 goto error; 582 } 583 584 status = qdf_list_remove_front(list, node); 585 error: 586 return status; 587 } 588 589 QDF_STATUS wlan_serialization_remove_node(qdf_list_t *list, 590 qdf_list_node_t *node) 591 { 592 QDF_STATUS status; 593 594 if (wlan_serialization_list_empty(list)) { 595 ser_err("The list is empty"); 596 status = QDF_STATUS_E_EMPTY; 597 goto error; 598 } 599 status = qdf_list_remove_node(list, node); 600 601 error: 602 return status; 603 } 604 605 QDF_STATUS wlan_serialization_insert_front(qdf_list_t *list, 606 qdf_list_node_t *node) 607 { 608 QDF_STATUS status; 609 610 status = qdf_list_insert_front(list, node); 611 612 return status; 613 } 614 615 QDF_STATUS wlan_serialization_insert_back(qdf_list_t *list, 616 qdf_list_node_t *node) 617 { 618 QDF_STATUS status; 619 620 status = qdf_list_insert_back(list, node); 621 622 return status; 623 } 624 625 QDF_STATUS wlan_serialization_peek_front(qdf_list_t *list, 626 qdf_list_node_t **node) 627 { 628 QDF_STATUS status; 629 630 status = qdf_list_peek_front(list, node); 631 632 return status; 633 } 634 635 QDF_STATUS wlan_serialization_peek_next(qdf_list_t *list, 636 qdf_list_node_t *node1, 637 qdf_list_node_t **node2) 638 { 639 QDF_STATUS status; 640 641 status = qdf_list_peek_next(list, node1, node2); 642 643 return status; 644 } 645 646 bool 647 wlan_serialization_match_cmd_type(qdf_list_node_t *nnode, 648 enum wlan_serialization_cmd_type cmd_type, 649 enum wlan_serialization_node node_type) 650 { 651 struct wlan_serialization_command_list *cmd_list = NULL; 652 bool match_found = true; 653 654 if (node_type == WLAN_SER_PDEV_NODE) 655 cmd_list = 656 qdf_container_of(nnode, 657 struct wlan_serialization_command_list, 658 pdev_node); 659 else 660 cmd_list = 661 qdf_container_of(nnode, 662 struct wlan_serialization_command_list, 663 vdev_node); 664 665 if (cmd_list->cmd.cmd_type != cmd_type) 666 match_found = false; 667 668 return match_found; 669 } 670 671 bool 672 wlan_serialization_match_cmd_id_type(qdf_list_node_t *nnode, 673 struct wlan_serialization_command *cmd, 674 enum wlan_serialization_node node_type) 675 { 676 struct wlan_serialization_command_list *cmd_list = NULL; 677 bool match_found = true; 678 679 if (!cmd) { 680 match_found = false; 681 goto error; 682 } 683 684 if (node_type == WLAN_SER_PDEV_NODE) 685 cmd_list = 686 qdf_container_of(nnode, 687 struct wlan_serialization_command_list, 688 pdev_node); 689 else 690 cmd_list = 691 qdf_container_of(nnode, 692 struct wlan_serialization_command_list, 693 vdev_node); 694 695 if ((cmd_list->cmd.cmd_id != cmd->cmd_id) || 696 (cmd_list->cmd.cmd_type != cmd->cmd_type)) { 697 match_found = false; 698 }; 699 700 error: 701 return match_found; 702 } 703 704 bool wlan_serialization_match_cmd_vdev(qdf_list_node_t *nnode, 705 struct wlan_objmgr_vdev *vdev, 706 enum wlan_serialization_node node_type) 707 { 708 struct wlan_serialization_command_list *cmd_list = NULL; 709 bool match_found = false; 710 711 if (node_type == WLAN_SER_PDEV_NODE) 712 cmd_list = 713 qdf_container_of(nnode, 714 struct wlan_serialization_command_list, 715 pdev_node); 716 else 717 cmd_list = 718 qdf_container_of(nnode, 719 struct wlan_serialization_command_list, 720 vdev_node); 721 722 if (cmd_list->cmd.vdev == vdev) 723 match_found = true; 724 725 if (!match_found) 726 ser_debug("matching cmd not found for (vdev:%pK)", vdev); 727 728 return match_found; 729 } 730 731 bool wlan_serialization_match_cmd_pdev(qdf_list_node_t *nnode, 732 struct wlan_objmgr_pdev *pdev, 733 enum wlan_serialization_node node_type) 734 { 735 struct wlan_serialization_command_list *cmd_list = NULL; 736 bool match_found = false; 737 struct wlan_objmgr_pdev *node_pdev = NULL; 738 739 if (node_type == WLAN_SER_PDEV_NODE) 740 cmd_list = 741 qdf_container_of(nnode, 742 struct wlan_serialization_command_list, 743 pdev_node); 744 else 745 cmd_list = 746 qdf_container_of(nnode, 747 struct wlan_serialization_command_list, 748 vdev_node); 749 750 node_pdev = wlan_vdev_get_pdev(cmd_list->cmd.vdev); 751 if (node_pdev == pdev) 752 match_found = true; 753 754 return match_found; 755 } 756 757 bool wlan_serialization_match_cmd_blocking( 758 qdf_list_node_t *nnode, 759 enum wlan_serialization_node node_type) 760 { 761 struct wlan_serialization_command_list *cmd_list = NULL; 762 bool match_found = false; 763 764 if (node_type == WLAN_SER_PDEV_NODE) 765 cmd_list = 766 qdf_container_of(nnode, 767 struct wlan_serialization_command_list, 768 pdev_node); 769 else 770 cmd_list = 771 qdf_container_of(nnode, 772 struct wlan_serialization_command_list, 773 vdev_node); 774 775 if (cmd_list->cmd.is_blocking) 776 match_found = true; 777 778 return match_found; 779 } 780 781 qdf_list_node_t * 782 wlan_serialization_find_cmd(qdf_list_t *queue, 783 enum wlan_serialization_match_type match_type, 784 struct wlan_serialization_command *cmd, 785 enum wlan_serialization_cmd_type cmd_type, 786 struct wlan_objmgr_pdev *pdev, 787 struct wlan_objmgr_vdev *vdev, 788 enum wlan_serialization_node node_type) 789 { 790 qdf_list_node_t *cmd_node = NULL; 791 uint32_t queuelen; 792 qdf_list_node_t *nnode = NULL; 793 QDF_STATUS status; 794 bool node_found = 0; 795 796 queuelen = wlan_serialization_list_size(queue); 797 798 if (!queuelen) 799 goto error; 800 801 while (queuelen--) { 802 status = wlan_serialization_get_cmd_from_queue(queue, &nnode); 803 if (status != QDF_STATUS_SUCCESS) 804 break; 805 806 switch (match_type) { 807 case WLAN_SER_MATCH_PDEV: 808 if (wlan_serialization_match_cmd_pdev( 809 nnode, pdev, WLAN_SER_PDEV_NODE)) 810 node_found = 1; 811 break; 812 case WLAN_SER_MATCH_VDEV: 813 if (wlan_serialization_match_cmd_vdev( 814 nnode, vdev, node_type)) 815 node_found = 1; 816 break; 817 case WLAN_SER_MATCH_CMD_TYPE_VDEV: 818 if (wlan_serialization_match_cmd_type( 819 nnode, cmd_type, node_type) && 820 wlan_serialization_match_cmd_vdev( 821 nnode, vdev, node_type)) 822 node_found = 1; 823 break; 824 case WLAN_SER_MATCH_CMD_ID_VDEV: 825 if (wlan_serialization_match_cmd_id_type( 826 nnode, cmd, node_type) && 827 wlan_serialization_match_cmd_vdev( 828 nnode, vdev, node_type)) 829 node_found = 1; 830 break; 831 default: 832 break; 833 } 834 835 if (node_found) { 836 cmd_node = nnode; 837 break; 838 } 839 } 840 error: 841 return cmd_node; 842 } 843 844 QDF_STATUS 845 wlan_serialization_acquire_lock(qdf_spinlock_t *lock) 846 { 847 qdf_spin_lock_bh(lock); 848 849 return QDF_STATUS_SUCCESS; 850 } 851 852 QDF_STATUS 853 wlan_serialization_release_lock(qdf_spinlock_t *lock) 854 { 855 qdf_spin_unlock_bh(lock); 856 857 return QDF_STATUS_SUCCESS; 858 } 859 860 QDF_STATUS 861 wlan_serialization_create_lock(qdf_spinlock_t *lock) 862 { 863 qdf_spinlock_create(lock); 864 865 return QDF_STATUS_SUCCESS; 866 } 867 868 QDF_STATUS 869 wlan_serialization_destroy_lock(qdf_spinlock_t *lock) 870 { 871 qdf_spinlock_destroy(lock); 872 873 return QDF_STATUS_SUCCESS; 874 } 875 876 bool wlan_serialization_any_vdev_cmd_active( 877 struct wlan_serialization_pdev_queue *pdev_queue) 878 { 879 uint32_t vdev_bitmap_size; 880 881 vdev_bitmap_size = 882 (QDF_CHAR_BIT * sizeof(pdev_queue->vdev_active_cmd_bitmap)); 883 884 return !qdf_bitmap_empty(pdev_queue->vdev_active_cmd_bitmap, 885 vdev_bitmap_size); 886 } 887