1 /* 2 * Copyright (c) 2017 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 * DOC: wlan_serialization_utils.c 20 * This file defines the utility helper functions for serialization component. 21 */ 22 23 #include "wlan_serialization_utils_i.h" 24 #include "wlan_serialization_main_i.h" 25 #include "wlan_serialization_api.h" 26 #include "wlan_objmgr_vdev_obj.h" 27 #include "wlan_objmgr_pdev_obj.h" 28 #include "qdf_mc_timer.h" 29 #include "wlan_utility.h" 30 31 QDF_STATUS 32 wlan_serialization_put_back_to_global_list(qdf_list_t *queue, 33 struct wlan_serialization_pdev_priv_obj *ser_pdev_obj, 34 struct wlan_serialization_command_list *cmd_list) 35 { 36 QDF_STATUS status; 37 38 if (!queue || !ser_pdev_obj || !cmd_list) { 39 serialization_err("input parameters are invalid"); 40 return QDF_STATUS_E_FAILURE; 41 } 42 status = qdf_list_remove_node(queue, &cmd_list->node); 43 if (QDF_STATUS_SUCCESS != status) { 44 serialization_err("can't remove cmd from queue"); 45 /* assert to catch any leaks */ 46 QDF_ASSERT(0); 47 return status; 48 } 49 serialization_info("cmd_id-%d, cmd_type-%d", cmd_list->cmd.cmd_id, 50 cmd_list->cmd.cmd_type); 51 qdf_mem_zero(&cmd_list->cmd, sizeof(struct wlan_serialization_command)); 52 status = qdf_list_insert_back(&ser_pdev_obj->global_cmd_pool_list, 53 &cmd_list->node); 54 if (QDF_STATUS_SUCCESS != status) { 55 serialization_err("can't put command back to global pool"); 56 QDF_ASSERT(0); 57 return status; 58 } 59 60 return status; 61 } 62 63 struct wlan_objmgr_pdev* 64 wlan_serialization_get_pdev_from_cmd(struct wlan_serialization_command *cmd) 65 { 66 struct wlan_objmgr_pdev *pdev = NULL; 67 68 if (!cmd) { 69 serialization_err("invalid cmd"); 70 return pdev; 71 } 72 pdev = wlan_vdev_get_pdev(cmd->vdev); 73 74 return pdev; 75 } 76 77 /** 78 * wlan_serialization_get_cmd_from_queue() - to extract command from given queue 79 * @queue: pointer to queue 80 * @nnode: next node to extract 81 * 82 * This API will try to extract node from queue which is next to prev node. If 83 * no previous node is given then take out the front node of the queue. 84 * 85 * Return: QDF_STATUS 86 */ 87 QDF_STATUS wlan_serialization_get_cmd_from_queue(qdf_list_t *queue, 88 qdf_list_node_t **nnode) 89 { 90 QDF_STATUS status; 91 qdf_list_node_t *pnode; 92 93 pnode = *nnode; 94 if (!pnode) 95 status = qdf_list_peek_front(queue, nnode); 96 else 97 status = qdf_list_peek_next(queue, pnode, nnode); 98 99 if (status != QDF_STATUS_SUCCESS) { 100 serialization_err("can't get next node from queue"); 101 return status; 102 } 103 return QDF_STATUS_SUCCESS; 104 } 105 106 /** 107 * wlan_serialization_timer_destroy() - destroys the timer 108 * @ser_timer: pointer to particular timer 109 * 110 * This API destroys the memory allocated by timer and assigns cmd member of 111 * that timer structure to NULL 112 * 113 * Return: QDF_STATUS 114 */ 115 static QDF_STATUS wlan_serialization_timer_destroy( 116 struct wlan_serialization_timer *ser_timer) 117 { 118 QDF_STATUS status = QDF_STATUS_E_FAILURE; 119 120 if (!ser_timer || !ser_timer->cmd) { 121 serialization_debug("Invalid ser_timer"); 122 return status; 123 } 124 status = qdf_mc_timer_destroy(&ser_timer->timer); 125 if (!QDF_IS_STATUS_SUCCESS(status)) { 126 serialization_err("Failed to destroy timer for cmd_id[%d]", 127 ser_timer->cmd->cmd_id); 128 QDF_ASSERT(0); 129 return status; 130 } 131 ser_timer->cmd = NULL; 132 133 return status; 134 } 135 136 /** 137 * wlan_serialization_generic_timer_callback() - timer callback when timer fire 138 * @arg: argument that timer passes to this callback 139 * 140 * All the timers in serialization module calls this callback when they fire, 141 * and this API in turn calls command specific timeout callback and remove 142 * timed-out command from active queue and move any pending command to active 143 * queue of same cmd_type. 144 * 145 * Return: none 146 */ 147 static void wlan_serialization_generic_timer_callback(void *arg) 148 { 149 struct wlan_serialization_timer *timer = arg; 150 struct wlan_serialization_command *cmd = timer->cmd; 151 152 if (!cmd) { 153 serialization_err("command not found"); 154 QDF_ASSERT(0); 155 return; 156 } 157 158 serialization_err("active command timeout for cmd_id[%d]", cmd->cmd_id); 159 if (cmd->cmd_cb) 160 cmd->cmd_cb(cmd, WLAN_SER_CB_ACTIVE_CMD_TIMEOUT); 161 162 serialization_err("active command timeout for cmd_id[%d]", cmd->cmd_id); 163 if (cmd->cmd_type >= WLAN_SER_CMD_NONSCAN) 164 QDF_BUG(0); 165 /* 166 * dequeue cmd API will cleanup and destroy the timer. If it fails to 167 * dequeue command then we have to destroy the timer. It will also call 168 * cmd callback with WLAN_SER_CB_RELEASE_MEM_CMD to free the memory. 169 */ 170 if (WLAN_SER_CMD_NOT_FOUND == wlan_serialization_dequeue_cmd(cmd, true)) 171 wlan_serialization_timer_destroy(timer); 172 if (cmd->cmd_cb) 173 cmd->cmd_cb(cmd, WLAN_SER_CB_RELEASE_MEM_CMD); 174 } 175 176 /** 177 * wlan_serialization_stop_timer() - to stop particular timer 178 * @ser_timer: pointer to serialization timer 179 * 180 * This API stops the particular timer 181 * 182 * Return: QDF_STATUS 183 */ 184 static QDF_STATUS 185 wlan_serialization_stop_timer(struct wlan_serialization_timer *ser_timer) 186 { 187 QDF_TIMER_STATE state; 188 QDF_STATUS status; 189 190 state = qdf_mc_timer_get_current_state(&ser_timer->timer); 191 if (QDF_TIMER_STATE_RUNNING != state || 192 QDF_TIMER_STATE_STARTING != state) { 193 serialization_debug("nothing to stop"); 194 wlan_serialization_timer_destroy(ser_timer); 195 return QDF_STATUS_SUCCESS; 196 } 197 status = qdf_mc_timer_stop(&ser_timer->timer); 198 if (!QDF_IS_STATUS_SUCCESS(status)) { 199 serialization_err("Failed to stop timer"); 200 /* to catch the bug */ 201 QDF_ASSERT(0); 202 return status; 203 } 204 wlan_serialization_timer_destroy(ser_timer); 205 status = QDF_STATUS_SUCCESS; 206 } 207 208 QDF_STATUS wlan_serialization_cleanup_all_timers( 209 struct wlan_serialization_psoc_priv_obj *psoc_ser_obj) 210 { 211 struct wlan_serialization_timer *ser_timer; 212 QDF_STATUS status = QDF_STATUS_SUCCESS; 213 uint32_t i = 0; 214 215 if (!psoc_ser_obj) { 216 serialization_err("Invalid psoc_ser_obj"); 217 return QDF_STATUS_E_FAILURE; 218 } 219 220 for (i = 0; psoc_ser_obj->max_active_cmds > i; i++) { 221 ser_timer = &psoc_ser_obj->timers[i]; 222 if (!ser_timer->cmd) 223 continue; 224 status = wlan_serialization_stop_timer(ser_timer); 225 if (QDF_STATUS_SUCCESS != status) { 226 /* lets not break the loop but report error */ 227 serialization_err("some error in stopping timer"); 228 } 229 } 230 231 return status; 232 } 233 234 QDF_STATUS 235 wlan_serialization_find_and_stop_timer(struct wlan_objmgr_psoc *psoc, 236 struct wlan_serialization_command *cmd) 237 { 238 struct wlan_serialization_psoc_priv_obj *psoc_ser_obj; 239 struct wlan_serialization_timer *ser_timer; 240 QDF_STATUS status = QDF_STATUS_E_FAILURE; 241 int i = 0; 242 243 if (!psoc || !cmd) { 244 serialization_err("invalid param"); 245 return status; 246 } 247 248 if ((cmd->cmd_timeout_duration == 0) && 249 (wlan_is_emulation_platform(wlan_psoc_get_nif_phy_version(psoc) 250 ))) { 251 serialization_err("[SCAN-EMULATION]: Not performing timer functions\n"); 252 return QDF_STATUS_SUCCESS; 253 } 254 255 psoc_ser_obj = wlan_serialization_get_psoc_priv_obj(psoc); 256 /* 257 * Here cmd_id and cmd_type are used to locate the timer being 258 * associated with command. For scan command, cmd_id is expected to 259 * be unique and For non-scan command, there should be only one active 260 * command per pdev 261 */ 262 for (i = 0; psoc_ser_obj->max_active_cmds > i; i++) { 263 ser_timer = &psoc_ser_obj->timers[i]; 264 if (!(ser_timer->cmd) || 265 (ser_timer->cmd->cmd_id != cmd->cmd_id) || 266 (ser_timer->cmd->cmd_type != cmd->cmd_type) || 267 (ser_timer->cmd->vdev != cmd->vdev)) 268 continue; 269 status = wlan_serialization_stop_timer(ser_timer); 270 if (QDF_STATUS_SUCCESS != status) { 271 serialization_err("Failed to stop timer for cmd_id[%d]", 272 cmd->cmd_id); 273 } 274 break; 275 } 276 277 if (QDF_STATUS_SUCCESS != status) { 278 serialization_err("can't find timer for cmd_type[%d]", 279 cmd->cmd_type); 280 } 281 return status; 282 } 283 284 QDF_STATUS 285 wlan_serialization_find_and_start_timer(struct wlan_objmgr_psoc *psoc, 286 struct wlan_serialization_command *cmd) 287 { 288 QDF_STATUS status = QDF_STATUS_E_FAILURE; 289 struct wlan_serialization_psoc_priv_obj *psoc_ser_obj; 290 struct wlan_serialization_timer *ser_timer; 291 int i = 0; 292 293 if (!psoc || !cmd) { 294 serialization_err("invalid param"); 295 return status; 296 } 297 298 if ((cmd->cmd_timeout_duration == 0) && 299 (wlan_is_emulation_platform(wlan_psoc_get_nif_phy_version(psoc) 300 ))) { 301 serialization_err("[SCAN-EMULATION]: Not performing timer functions\n"); 302 return QDF_STATUS_SUCCESS; 303 } 304 305 306 psoc_ser_obj = wlan_serialization_get_psoc_priv_obj(psoc); 307 for (i = 0; psoc_ser_obj->max_active_cmds > i; i++) { 308 /* Keep trying timer */ 309 ser_timer = &psoc_ser_obj->timers[i]; 310 if (ser_timer->cmd) 311 continue; 312 /* Remember timer is pointing to command */ 313 ser_timer->cmd = cmd; 314 if (!QDF_IS_STATUS_SUCCESS(qdf_mc_timer_init(&ser_timer->timer, 315 QDF_TIMER_TYPE_SW, 316 wlan_serialization_generic_timer_callback, 317 ser_timer))) { 318 serialization_err("Failed to init timer cmdid [%d]", 319 cmd->cmd_id); 320 QDF_ASSERT(0); 321 continue; 322 } 323 if (!QDF_IS_STATUS_SUCCESS(qdf_mc_timer_start(&ser_timer->timer, 324 cmd->cmd_timeout_duration))) { 325 serialization_err("Failed to start timer cmdid [%d]", 326 cmd->cmd_id); 327 wlan_serialization_timer_destroy(ser_timer); 328 QDF_ASSERT(0); 329 continue; 330 } 331 status = QDF_STATUS_SUCCESS; 332 break; 333 } 334 335 return status; 336 } 337 338 /** 339 * wlan_serialization_active_scan_cmd_count_handler() - count active scan cmds 340 * @psoc: pointer to soc strucutre 341 * @obj : pointer to pdev object 342 * @arg: pointer to argument 343 * 344 * This API will be called while iterating each pdev object and it will count 345 * number of scan commands present in that pdev object's active queue. count 346 * will be updated in *arg 347 * 348 * Return: none 349 */ 350 static void 351 wlan_serialization_active_scan_cmd_count_handler(struct wlan_objmgr_psoc *psoc, 352 void *obj, void *arg) 353 { 354 struct wlan_objmgr_pdev *pdev = obj; 355 struct wlan_serialization_pdev_priv_obj *ser_pdev_obj; 356 uint32_t *count = arg; 357 358 if (!pdev) { 359 serialization_err("invalid pdev"); 360 return; 361 } 362 363 ser_pdev_obj = wlan_objmgr_pdev_get_comp_private_obj( 364 pdev, WLAN_UMAC_COMP_SERIALIZATION); 365 *count += qdf_list_size(&ser_pdev_obj->active_scan_list); 366 } 367 368 /** 369 * wlan_serialization_is_active_scan_cmd_allowed() - find if scan cmd allowed 370 * @pdev: pointer to pdev object 371 * 372 * This API will be called to find out if active scan cmd is allowed. It has 373 * to iterate through all pdev to find out total number of active scan cmds. 374 * If total number of active scan cmds reach to allowed threshold then don't 375 * allow more scan cmd. 376 * 377 * Return: true or false 378 */ 379 static bool 380 wlan_serialization_is_active_scan_cmd_allowed(struct wlan_objmgr_pdev *pdev) 381 { 382 uint32_t count = 0; 383 struct wlan_objmgr_psoc *psoc; 384 385 if (!pdev) { 386 serialization_err("invalid pdev"); 387 return false; 388 } 389 390 psoc = wlan_pdev_get_psoc(pdev); 391 392 if (!psoc) { 393 serialization_err("invalid psoc"); 394 return false; 395 } 396 397 wlan_objmgr_iterate_obj_list(psoc, WLAN_PDEV_OP, 398 wlan_serialization_active_scan_cmd_count_handler, 399 &count, 1, WLAN_SERIALIZATION_ID); 400 if (count < ucfg_scan_get_max_active_scans(psoc)) { 401 serialization_notice("count is [%d]", count); 402 return true; 403 } 404 405 return false; 406 } 407 408 /** 409 * wlan_serialization_is_active_nonscan_cmd_allowed() - find if cmd allowed 410 * @pdev: pointer to pdev object 411 * 412 * This API will be called to find out if non scan cmd is allowed. 413 * 414 * Return: true or false 415 */ 416 static bool 417 wlan_serialization_is_active_nonscan_cmd_allowed(struct wlan_objmgr_pdev *pdev) 418 { 419 struct wlan_serialization_pdev_priv_obj *ser_pdev_obj; 420 421 if (!pdev) { 422 serialization_err("invalid pdev"); 423 return false; 424 } 425 426 ser_pdev_obj = wlan_objmgr_pdev_get_comp_private_obj( 427 pdev, WLAN_UMAC_COMP_SERIALIZATION); 428 429 if (!ser_pdev_obj) { 430 serialization_err("invalid ser_pdev_obj"); 431 return false; 432 } 433 434 if (qdf_list_empty(&ser_pdev_obj->active_list)) 435 return true; 436 437 return false; 438 } 439 440 bool 441 wlan_serialization_is_active_cmd_allowed(struct wlan_serialization_command *cmd) 442 { 443 struct wlan_objmgr_pdev *pdev; 444 445 pdev = wlan_serialization_get_pdev_from_cmd(cmd); 446 if (!pdev) { 447 serialization_err("NULL pdev"); 448 return false; 449 } 450 451 if (cmd->cmd_type < WLAN_SER_CMD_NONSCAN) 452 return wlan_serialization_is_active_scan_cmd_allowed(pdev); 453 else 454 return wlan_serialization_is_active_nonscan_cmd_allowed(pdev); 455 } 456 457 QDF_STATUS wlan_serialization_validate_cmdtype( 458 enum wlan_serialization_cmd_type cmd_type) 459 { 460 serialization_info("validate cmd_type:%d", cmd_type); 461 462 if (cmd_type < 0 || cmd_type >= WLAN_SER_CMD_MAX) { 463 serialization_err("Invalid cmd or comp passed"); 464 return QDF_STATUS_E_INVAL; 465 } 466 467 return QDF_STATUS_SUCCESS; 468 } 469 470 QDF_STATUS wlan_serialization_validate_cmd( 471 enum wlan_umac_comp_id comp_id, 472 enum wlan_serialization_cmd_type cmd_type) 473 { 474 serialization_info("validate cmd_type:%d, comp_id:%d", 475 cmd_type, comp_id); 476 if (cmd_type < 0 || comp_id < 0 || 477 cmd_type >= WLAN_SER_CMD_MAX || 478 comp_id >= WLAN_UMAC_COMP_ID_MAX) { 479 serialization_err("Invalid cmd or comp passed"); 480 return QDF_STATUS_E_INVAL; 481 } 482 483 return QDF_STATUS_SUCCESS; 484 } 485 486 void wlan_serialization_release_list_cmds( 487 struct wlan_serialization_pdev_priv_obj *ser_pdev_obj, 488 qdf_list_t *list) 489 { 490 qdf_list_node_t *node = NULL; 491 492 while (!qdf_list_empty(list)) { 493 qdf_list_remove_front(list, &node); 494 qdf_list_insert_back(&ser_pdev_obj->global_cmd_pool_list, node); 495 } 496 497 return; 498 } 499 500 void wlan_serialization_destroy_list( 501 struct wlan_serialization_pdev_priv_obj *ser_pdev_obj, 502 qdf_list_t *list) 503 { 504 wlan_serialization_release_list_cmds(ser_pdev_obj, list); 505 qdf_list_destroy(list); 506 } 507 508 struct wlan_serialization_psoc_priv_obj *wlan_serialization_get_psoc_priv_obj( 509 struct wlan_objmgr_psoc *psoc) 510 { 511 struct wlan_serialization_psoc_priv_obj *ser_soc_obj; 512 wlan_psoc_obj_lock(psoc); 513 ser_soc_obj = wlan_objmgr_psoc_get_comp_private_obj(psoc, 514 WLAN_UMAC_COMP_SERIALIZATION); 515 wlan_psoc_obj_unlock(psoc); 516 517 return ser_soc_obj; 518 } 519 520 struct wlan_serialization_pdev_priv_obj *wlan_serialization_get_pdev_priv_obj( 521 struct wlan_objmgr_pdev *pdev) 522 { 523 struct wlan_serialization_pdev_priv_obj *obj; 524 wlan_pdev_obj_lock(pdev); 525 obj = wlan_objmgr_pdev_get_comp_private_obj(pdev, 526 WLAN_UMAC_COMP_SERIALIZATION); 527 wlan_pdev_obj_unlock(pdev); 528 529 return obj; 530 } 531 532 struct wlan_serialization_psoc_priv_obj * 533 wlan_serialization_get_obj(struct wlan_serialization_command *cmd) 534 { 535 struct wlan_serialization_psoc_priv_obj *ser_soc_obj; 536 struct wlan_objmgr_psoc *psoc; 537 538 psoc = wlan_vdev_get_psoc(cmd->vdev); 539 ser_soc_obj = wlan_serialization_get_psoc_priv_obj(psoc); 540 541 return ser_soc_obj; 542 } 543 544 bool wlan_serialization_is_cmd_in_vdev_list(struct wlan_objmgr_vdev *vdev, 545 qdf_list_t *queue) 546 { 547 uint32_t queuelen; 548 qdf_list_node_t *nnode = NULL; 549 struct wlan_serialization_command_list *cmd_list = NULL; 550 QDF_STATUS status; 551 552 queuelen = qdf_list_size(queue); 553 if (!queuelen) { 554 serialization_debug("queue empty"); 555 return false; 556 } 557 558 while (queuelen--) { 559 status = wlan_serialization_get_cmd_from_queue(queue, &nnode); 560 if (status != QDF_STATUS_SUCCESS) 561 break; 562 cmd_list = qdf_container_of(nnode, 563 struct wlan_serialization_command_list, node); 564 if (cmd_list->cmd.vdev == vdev) 565 return true; 566 }; 567 568 return false; 569 } 570 571 bool wlan_serialization_is_cmd_in_pdev_list(struct wlan_objmgr_pdev *pdev, 572 qdf_list_t *queue) 573 { 574 uint32_t queuelen; 575 qdf_list_node_t *nnode = NULL; 576 struct wlan_objmgr_pdev *node_pdev = NULL; 577 struct wlan_serialization_command_list *cmd_list = NULL; 578 QDF_STATUS status; 579 580 queuelen = qdf_list_size(queue); 581 if (!queuelen) { 582 serialization_debug("queue empty"); 583 return false; 584 } 585 586 while (queuelen--) { 587 status = wlan_serialization_get_cmd_from_queue(queue, &nnode); 588 if (status != QDF_STATUS_SUCCESS) 589 break; 590 cmd_list = qdf_container_of(nnode, 591 struct wlan_serialization_command_list, node); 592 node_pdev = wlan_vdev_get_pdev(cmd_list->cmd.vdev); 593 if (node_pdev == pdev) 594 return true; 595 } 596 597 return false; 598 } 599 600 enum wlan_serialization_cmd_status 601 wlan_serialization_is_cmd_in_active_pending(bool cmd_in_active, 602 bool cmd_in_pending) 603 { 604 if (cmd_in_active && cmd_in_pending) 605 return WLAN_SER_CMDS_IN_ALL_LISTS; 606 else if (cmd_in_active) 607 return WLAN_SER_CMD_IN_ACTIVE_LIST; 608 else if (cmd_in_pending) 609 return WLAN_SER_CMD_IN_PENDING_LIST; 610 else 611 return WLAN_SER_CMD_NOT_FOUND; 612 } 613 614 static bool wlan_serialization_is_cmd_present_in_given_queue(qdf_list_t *queue, 615 struct wlan_serialization_command *cmd) 616 { 617 uint32_t qsize; 618 QDF_STATUS status; 619 struct wlan_serialization_command_list *cmd_list = NULL; 620 qdf_list_node_t *nnode = NULL, *pnode = NULL; 621 bool found = false; 622 623 qsize = qdf_list_size(queue); 624 while (qsize--) { 625 if (!cmd_list) 626 status = qdf_list_peek_front(queue, &nnode); 627 else 628 status = qdf_list_peek_next(queue, pnode, 629 &nnode); 630 631 if (status != QDF_STATUS_SUCCESS) 632 break; 633 634 pnode = nnode; 635 cmd_list = qdf_container_of(nnode, 636 struct wlan_serialization_command_list, node); 637 if ((cmd_list->cmd.cmd_id == cmd->cmd_id) && 638 (cmd_list->cmd.cmd_type == cmd->cmd_type) && 639 (cmd_list->cmd.vdev == cmd->vdev)) { 640 found = true; 641 break; 642 } 643 nnode = NULL; 644 } 645 return found; 646 } 647 648 bool wlan_serialization_is_cmd_present_queue( 649 struct wlan_serialization_command *cmd, 650 uint8_t is_active_queue) 651 { 652 qdf_list_t *queue; 653 struct wlan_objmgr_pdev *pdev; 654 struct wlan_serialization_pdev_priv_obj *ser_pdev_obj; 655 656 if (!cmd) { 657 serialization_err("invalid params"); 658 return false; 659 } 660 pdev = wlan_serialization_get_pdev_from_cmd(cmd); 661 if (!pdev) { 662 serialization_err("invalid pdev"); 663 return false; 664 } 665 ser_pdev_obj = wlan_objmgr_pdev_get_comp_private_obj(pdev, 666 WLAN_UMAC_COMP_SERIALIZATION); 667 if (!ser_pdev_obj) { 668 serialization_err("invalid ser_pdev_obj"); 669 return false; 670 } 671 if (!is_active_queue) { 672 if (cmd->cmd_type < WLAN_SER_CMD_NONSCAN) 673 queue = &ser_pdev_obj->pending_scan_list; 674 else 675 queue = &ser_pdev_obj->pending_list; 676 } else { 677 if (cmd->cmd_type < WLAN_SER_CMD_NONSCAN) 678 queue = &ser_pdev_obj->active_scan_list; 679 else 680 queue = &ser_pdev_obj->active_list; 681 } 682 683 return wlan_serialization_is_cmd_present_in_given_queue(queue, cmd); 684 } 685