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