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