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