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_api.c 21 * This file provides an interface for the external components 22 * to utilize the services provided by the serialization 23 * component. 24 */ 25 26 #include <wlan_objmgr_psoc_obj.h> 27 #include <wlan_objmgr_pdev_obj.h> 28 #include <wlan_objmgr_vdev_obj.h> 29 #include "wlan_serialization_main_i.h" 30 #include "wlan_serialization_utils_i.h" 31 #include "wlan_serialization_queue_i.h" 32 #include "wlan_serialization_scan_i.h" 33 #include "wlan_serialization_internal_i.h" 34 35 bool wlan_serialization_is_cmd_present_in_pending_queue( 36 struct wlan_objmgr_psoc *psoc, 37 struct wlan_serialization_command *cmd) 38 { 39 bool status = false; 40 41 if (!cmd) { 42 ser_err("invalid cmd"); 43 goto error; 44 } 45 46 status = wlan_serialization_is_cmd_present_queue(cmd, false); 47 48 error: 49 return status; 50 } 51 52 bool wlan_serialization_is_cmd_present_in_active_queue( 53 struct wlan_objmgr_psoc *psoc, 54 struct wlan_serialization_command *cmd) 55 { 56 bool status; 57 58 if (!cmd) { 59 ser_err("invalid cmd"); 60 status = false; 61 goto error; 62 } 63 64 status = wlan_serialization_is_cmd_present_queue(cmd, true); 65 66 ser_debug("Cmd type:%d id:%d present: %d", 67 cmd->cmd_type, cmd->cmd_id, status); 68 69 error: 70 return status; 71 } 72 73 QDF_STATUS 74 wlan_serialization_register_apply_rules_cb( 75 struct wlan_objmgr_psoc *psoc, 76 enum wlan_serialization_cmd_type cmd_type, 77 wlan_serialization_apply_rules_cb cb) 78 { 79 struct wlan_ser_psoc_obj *ser_soc_obj; 80 QDF_STATUS status; 81 82 status = wlan_serialization_validate_cmdtype(cmd_type); 83 if (QDF_IS_STATUS_ERROR(status)) { 84 ser_err("invalid cmd_type %d", cmd_type); 85 goto error; 86 } 87 88 ser_soc_obj = wlan_serialization_get_psoc_obj(psoc); 89 if (!ser_soc_obj) { 90 ser_err("invalid ser_soc_obj"); 91 status = QDF_STATUS_E_FAILURE; 92 goto error; 93 } 94 95 ser_soc_obj->apply_rules_cb[cmd_type] = cb; 96 status = QDF_STATUS_SUCCESS; 97 98 error: 99 return status; 100 } 101 102 QDF_STATUS 103 wlan_serialization_deregister_apply_rules_cb( 104 struct wlan_objmgr_psoc *psoc, 105 enum wlan_serialization_cmd_type cmd_type) 106 { 107 struct wlan_ser_psoc_obj *ser_soc_obj; 108 QDF_STATUS status; 109 110 status = wlan_serialization_validate_cmdtype(cmd_type); 111 if (QDF_IS_STATUS_ERROR(status)) { 112 ser_err("invalid cmd_type %d", cmd_type); 113 goto error; 114 } 115 ser_soc_obj = wlan_serialization_get_psoc_obj(psoc); 116 if (!ser_soc_obj) { 117 ser_err("invalid ser_soc_obj"); 118 status = QDF_STATUS_E_FAILURE; 119 goto error; 120 } 121 ser_soc_obj->apply_rules_cb[cmd_type] = NULL; 122 status = QDF_STATUS_SUCCESS; 123 124 error: 125 return status; 126 } 127 128 QDF_STATUS 129 wlan_serialization_register_comp_info_cb( 130 struct wlan_objmgr_psoc *psoc, 131 enum wlan_umac_comp_id comp_id, 132 enum wlan_serialization_cmd_type cmd_type, 133 wlan_serialization_comp_info_cb cb) 134 { 135 struct wlan_ser_psoc_obj *ser_soc_obj; 136 QDF_STATUS status; 137 138 status = wlan_serialization_validate_cmd(comp_id, cmd_type); 139 if (QDF_IS_STATUS_ERROR(status)) { 140 ser_err("invalid comp_id %d or cmd_type %d", 141 comp_id, cmd_type); 142 goto error; 143 } 144 ser_soc_obj = wlan_serialization_get_psoc_obj(psoc); 145 if (!ser_soc_obj) { 146 ser_err("invalid ser_soc_obj"); 147 status = QDF_STATUS_E_FAILURE; 148 goto error; 149 } 150 ser_soc_obj->comp_info_cb[cmd_type][comp_id] = cb; 151 status = QDF_STATUS_SUCCESS; 152 153 error: 154 return status; 155 } 156 157 QDF_STATUS 158 wlan_serialization_deregister_comp_info_cb(struct wlan_objmgr_psoc *psoc, 159 enum wlan_umac_comp_id comp_id, 160 enum wlan_serialization_cmd_type cmd_type) 161 { 162 struct wlan_ser_psoc_obj *ser_soc_obj; 163 QDF_STATUS status; 164 165 status = wlan_serialization_validate_cmd(comp_id, cmd_type); 166 if (QDF_IS_STATUS_ERROR(status)) { 167 ser_err("invalid comp_id %d or cmd_type %d", 168 comp_id, cmd_type); 169 goto error; 170 } 171 ser_soc_obj = wlan_serialization_get_psoc_obj(psoc); 172 if (!ser_soc_obj) { 173 ser_err("invalid ser_soc_obj"); 174 status = QDF_STATUS_E_FAILURE; 175 goto error; 176 } 177 ser_soc_obj->comp_info_cb[cmd_type][comp_id] = NULL; 178 status = QDF_STATUS_SUCCESS; 179 180 error: 181 return status; 182 } 183 184 enum wlan_serialization_cmd_status 185 wlan_serialization_non_scan_cmd_status( 186 struct wlan_objmgr_pdev *pdev, 187 enum wlan_serialization_cmd_type cmd_type) 188 { 189 bool cmd_in_active = 0; 190 bool cmd_in_pending = 0; 191 struct wlan_ser_pdev_obj *ser_pdev_obj = 192 wlan_serialization_get_pdev_obj(pdev); 193 enum wlan_serialization_cmd_status cmd_status = WLAN_SER_CMD_NOT_FOUND; 194 struct wlan_serialization_pdev_queue *pdev_q; 195 qdf_list_node_t *node = NULL; 196 qdf_list_t *queue = NULL; 197 198 ser_enter(); 199 200 pdev_q = &ser_pdev_obj->pdev_q[SER_PDEV_QUEUE_COMP_NON_SCAN]; 201 202 /* Look in the pdev non scan active queue */ 203 queue = &pdev_q->active_list; 204 205 wlan_serialization_acquire_lock(&pdev_q->pdev_queue_lock); 206 207 node = wlan_serialization_find_cmd( 208 queue, WLAN_SER_MATCH_CMD_TYPE, 209 NULL, cmd_type, NULL, NULL, WLAN_SER_PDEV_NODE); 210 211 if (node) 212 cmd_in_active = true; 213 214 node = NULL; 215 216 /* Look in the pdev non scan pending queue */ 217 queue = &pdev_q->pending_list; 218 219 node = wlan_serialization_find_cmd( 220 queue, WLAN_SER_MATCH_CMD_TYPE, 221 NULL, cmd_type, NULL, NULL, WLAN_SER_PDEV_NODE); 222 223 if (node) 224 cmd_in_pending = true; 225 226 cmd_status = wlan_serialization_is_cmd_in_active_pending( 227 cmd_in_active, cmd_in_pending); 228 229 wlan_serialization_release_lock(&pdev_q->pdev_queue_lock); 230 231 ser_exit(); 232 return cmd_status; 233 } 234 235 enum wlan_serialization_cmd_status 236 wlan_serialization_cancel_request( 237 struct wlan_serialization_queued_cmd_info *req) 238 { 239 QDF_STATUS status; 240 enum wlan_serialization_cmd_status cmd_status; 241 242 struct wlan_serialization_command cmd; 243 struct wlan_objmgr_pdev *pdev; 244 struct wlan_ser_pdev_obj *ser_pdev_obj; 245 struct wlan_serialization_pdev_queue *pdev_queue; 246 247 ser_enter(); 248 249 if (!req) { 250 ser_err("given request is empty"); 251 cmd_status = WLAN_SER_CMD_NOT_FOUND; 252 goto error; 253 } 254 255 status = wlan_serialization_validate_cmd(req->requestor, req->cmd_type); 256 if (QDF_IS_STATUS_ERROR(status)) { 257 ser_err("req is not valid"); 258 cmd_status = WLAN_SER_CMD_NOT_FOUND; 259 goto error; 260 } 261 262 cmd.cmd_type = req->cmd_type; 263 cmd.cmd_id = req->cmd_id; 264 cmd.source = req->requestor; 265 cmd.vdev = req->vdev; 266 267 pdev = wlan_serialization_get_pdev_from_cmd(&cmd); 268 if (!pdev) { 269 ser_err("pdev is invalid"); 270 cmd_status = WLAN_SER_CMD_NOT_FOUND; 271 goto error; 272 } 273 274 ser_pdev_obj = wlan_serialization_get_pdev_obj(pdev); 275 276 pdev_queue = wlan_serialization_get_pdev_queue_obj(ser_pdev_obj, 277 cmd.cmd_type); 278 279 if (!pdev_queue) { 280 ser_err("pdev_queue is invalid"); 281 cmd_status = WLAN_SER_CMD_NOT_FOUND; 282 goto error; 283 } 284 285 cmd_status = wlan_serialization_find_and_cancel_cmd( 286 &cmd, req->req_type, req->queue_type); 287 288 error: 289 ser_exit(); 290 return cmd_status; 291 } 292 293 void wlan_serialization_remove_cmd( 294 struct wlan_serialization_queued_cmd_info *cmd_info) 295 { 296 QDF_STATUS status; 297 enum wlan_serialization_cmd_status ser_status; 298 struct wlan_serialization_command cmd = {0}; 299 300 ser_enter(); 301 302 if (!cmd_info) { 303 ser_err("given request is empty"); 304 QDF_ASSERT(0); 305 return; 306 } 307 status = wlan_serialization_validate_cmd(cmd_info->requestor, 308 cmd_info->cmd_type); 309 if (QDF_IS_STATUS_ERROR(status)) { 310 ser_err("cmd is not valid"); 311 QDF_ASSERT(0); 312 goto error; 313 } 314 315 cmd.cmd_type = cmd_info->cmd_type; 316 cmd.cmd_id = cmd_info->cmd_id; 317 cmd.source = cmd_info->requestor; 318 cmd.vdev = cmd_info->vdev; 319 320 ser_status = wlan_serialization_dequeue_cmd( 321 &cmd, SER_REMOVE, true); 322 323 if (ser_status != WLAN_SER_CMD_IN_ACTIVE_LIST) { 324 if (ser_status != WLAN_SER_CMD_MARKED_FOR_ACTIVATION) 325 ser_err("Can't dequeue requested cmd_id[%d] type[%d]", 326 cmd.cmd_id, cmd.cmd_type); 327 } 328 329 error: 330 ser_exit(); 331 } 332 333 enum wlan_serialization_status 334 wlan_serialization_request(struct wlan_serialization_command *cmd) 335 { 336 QDF_STATUS status; 337 enum wlan_serialization_status serialization_status; 338 uint8_t comp_id; 339 struct wlan_ser_psoc_obj *ser_soc_obj; 340 union wlan_serialization_rules_info info; 341 struct wlan_objmgr_psoc *psoc; 342 343 ser_enter(); 344 345 serialization_status = WLAN_SER_CMD_DENIED_UNSPECIFIED; 346 347 if (!cmd) { 348 ser_err("serialization cmd is null"); 349 goto error; 350 } 351 status = wlan_serialization_validate_cmd(cmd->source, cmd->cmd_type); 352 if (QDF_IS_STATUS_ERROR(status)) { 353 ser_err("cmd is not valid"); 354 goto error; 355 } 356 357 psoc = wlan_serialization_get_psoc_from_cmd(cmd); 358 if (!psoc) { 359 ser_err("psoc _obj is invalid"); 360 return WLAN_SER_CMD_DENIED_UNSPECIFIED; 361 } 362 ser_soc_obj = wlan_serialization_get_psoc_obj(psoc); 363 364 if (!ser_soc_obj) { 365 ser_err("ser_soc_obj is invalid"); 366 return WLAN_SER_CMD_DENIED_UNSPECIFIED; 367 } 368 369 /* 370 * Get Component Info callback by calling 371 * each registered module 372 */ 373 for (comp_id = 0; comp_id < WLAN_UMAC_COMP_ID_MAX; comp_id++) { 374 if (!ser_soc_obj->comp_info_cb[cmd->cmd_type][comp_id]) 375 continue; 376 ser_soc_obj->comp_info_cb[cmd->cmd_type][comp_id](cmd->vdev, 377 &info); 378 if (!ser_soc_obj->apply_rules_cb[cmd->cmd_type]) 379 continue; 380 if (!ser_soc_obj->apply_rules_cb[cmd->cmd_type](&info, comp_id)) 381 return WLAN_SER_CMD_DENIED_RULES_FAILED; 382 } 383 384 serialization_status = wlan_serialization_enqueue_cmd(cmd, SER_REQUEST); 385 386 error: 387 ser_exit(); 388 return serialization_status; 389 } 390 391 QDF_STATUS 392 wlan_serialization_update_timer(struct wlan_serialization_command *cmd) 393 { 394 QDF_STATUS status = QDF_STATUS_E_FAILURE; 395 struct wlan_objmgr_pdev *pdev; 396 struct wlan_objmgr_psoc *psoc; 397 398 if (!cmd) { 399 ser_err("NULL command"); 400 goto error; 401 } 402 403 pdev = wlan_serialization_get_pdev_from_cmd(cmd); 404 if (!pdev) { 405 ser_err("invalid pdev"); 406 goto error; 407 } 408 409 psoc = wlan_pdev_get_psoc(pdev); 410 if (!psoc) { 411 ser_err("invalid psoc"); 412 goto error; 413 } 414 415 status = wlan_serialization_find_and_update_timer(psoc, cmd); 416 417 error: 418 return status; 419 } 420 421 enum wlan_serialization_cmd_status 422 wlan_serialization_vdev_scan_status(struct wlan_objmgr_vdev *vdev) 423 { 424 bool cmd_in_active = 0, cmd_in_pending = 0; 425 struct wlan_objmgr_pdev *pdev = wlan_vdev_get_pdev(vdev); 426 struct wlan_ser_pdev_obj *ser_pdev_obj = 427 wlan_serialization_get_pdev_obj(pdev); 428 struct wlan_serialization_pdev_queue *pdev_q; 429 enum wlan_serialization_cmd_status status; 430 431 ser_enter(); 432 433 pdev_q = &ser_pdev_obj->pdev_q[SER_PDEV_QUEUE_COMP_SCAN]; 434 435 wlan_serialization_acquire_lock(&pdev_q->pdev_queue_lock); 436 437 cmd_in_active = 438 wlan_serialization_is_cmd_in_vdev_list( 439 vdev, &pdev_q->active_list, WLAN_SER_PDEV_NODE); 440 441 cmd_in_pending = 442 wlan_serialization_is_cmd_in_vdev_list( 443 vdev, &pdev_q->pending_list, WLAN_SER_PDEV_NODE); 444 445 status = wlan_serialization_is_cmd_in_active_pending( 446 cmd_in_active, cmd_in_pending); 447 448 wlan_serialization_release_lock(&pdev_q->pdev_queue_lock); 449 ser_exit(); 450 451 return status; 452 } 453 454 void wlan_serialization_flush_cmd( 455 struct wlan_serialization_queued_cmd_info *cmd) 456 { 457 ser_enter(); 458 459 if (!cmd) { 460 ser_err("cmd is null, can't flush"); 461 goto error; 462 } 463 464 error: 465 ser_exit(); 466 } 467 468 enum wlan_serialization_cmd_status 469 wlan_serialization_pdev_scan_status(struct wlan_objmgr_pdev *pdev) 470 { 471 bool cmd_in_active, cmd_in_pending; 472 struct wlan_ser_pdev_obj *ser_pdev_obj = 473 wlan_serialization_get_pdev_obj(pdev); 474 struct wlan_serialization_pdev_queue *pdev_q; 475 enum wlan_serialization_cmd_status status; 476 477 pdev_q = &ser_pdev_obj->pdev_q[SER_PDEV_QUEUE_COMP_SCAN]; 478 479 wlan_serialization_acquire_lock(&pdev_q->pdev_queue_lock); 480 481 cmd_in_active = !qdf_list_empty(&pdev_q->active_list); 482 cmd_in_pending = !qdf_list_empty(&pdev_q->pending_list); 483 484 status = wlan_serialization_is_cmd_in_active_pending( 485 cmd_in_active, cmd_in_pending); 486 487 wlan_serialization_release_lock(&pdev_q->pdev_queue_lock); 488 489 return status; 490 } 491 492 struct wlan_serialization_command* 493 wlan_serialization_get_scan_cmd_using_scan_id( 494 struct wlan_objmgr_psoc *psoc, 495 uint8_t vdev_id, uint16_t scan_id, 496 uint8_t is_scan_cmd_from_active_queue) 497 { 498 struct wlan_objmgr_vdev *vdev; 499 struct wlan_objmgr_pdev *pdev; 500 struct wlan_ser_pdev_obj *ser_pdev_obj; 501 struct wlan_serialization_command cmd = {0}; 502 struct wlan_serialization_command *pcmd = NULL; 503 struct wlan_serialization_command_list *cmd_list; 504 qdf_list_node_t *node = NULL; 505 qdf_list_t *queue; 506 struct wlan_serialization_pdev_queue *pdev_q; 507 508 if (!psoc) { 509 ser_err("invalid psoc"); 510 goto error; 511 } 512 vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id, 513 WLAN_SERIALIZATION_ID); 514 if (!vdev) { 515 ser_err("invalid vdev"); 516 goto error; 517 } 518 519 pdev = wlan_vdev_get_pdev(vdev); 520 if (!pdev) { 521 ser_err("invalid pdev"); 522 goto release_vdev_ref; 523 } 524 525 ser_pdev_obj = wlan_serialization_get_pdev_obj(pdev); 526 if (!ser_pdev_obj) { 527 ser_err("invalid ser_pdev_obj"); 528 goto release_vdev_ref; 529 } 530 531 pdev_q = &ser_pdev_obj->pdev_q[SER_PDEV_QUEUE_COMP_SCAN]; 532 533 wlan_serialization_acquire_lock(&pdev_q->pdev_queue_lock); 534 535 if (is_scan_cmd_from_active_queue) 536 queue = &pdev_q->active_list; 537 else 538 queue = &pdev_q->pending_list; 539 540 cmd.cmd_type = WLAN_SER_CMD_SCAN; 541 cmd.cmd_id = scan_id; 542 cmd.vdev = vdev; 543 544 node = wlan_serialization_find_cmd( 545 queue, WLAN_SER_MATCH_CMD_ID_VDEV, 546 &cmd, 0, NULL, vdev, WLAN_SER_PDEV_NODE); 547 548 if (node) { 549 cmd_list = qdf_container_of( 550 node, 551 struct wlan_serialization_command_list, 552 pdev_node); 553 554 pcmd = &cmd_list->cmd; 555 } 556 557 wlan_serialization_release_lock(&pdev_q->pdev_queue_lock); 558 559 release_vdev_ref: 560 wlan_objmgr_vdev_release_ref(vdev, WLAN_SERIALIZATION_ID); 561 error: 562 return pcmd; 563 } 564 565 void *wlan_serialization_get_active_cmd( 566 struct wlan_objmgr_psoc *psoc, 567 uint8_t vdev_id, 568 enum wlan_serialization_cmd_type cmd_type) 569 { 570 struct wlan_objmgr_vdev *vdev; 571 struct wlan_objmgr_pdev *pdev; 572 struct wlan_ser_pdev_obj *ser_pdev_obj; 573 struct wlan_serialization_command_list *cmd_list = NULL; 574 void *umac_cmd = NULL; 575 qdf_list_node_t *node = NULL; 576 qdf_list_t *queue; 577 struct wlan_serialization_pdev_queue *pdev_q; 578 579 ser_enter(); 580 581 if (!psoc) { 582 ser_err("invalid psoc"); 583 goto error; 584 } 585 vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id, 586 WLAN_SERIALIZATION_ID); 587 if (!vdev) { 588 ser_err("invalid vdev"); 589 goto error; 590 } 591 592 pdev = wlan_vdev_get_pdev(vdev); 593 if (!pdev) { 594 ser_err("invalid pdev"); 595 goto release_vdev_ref; 596 } 597 598 ser_pdev_obj = wlan_serialization_get_pdev_obj(pdev); 599 if (!ser_pdev_obj) { 600 ser_err("invalid ser_pdev_obj"); 601 goto release_vdev_ref; 602 } 603 604 pdev_q = wlan_serialization_get_pdev_queue_obj(ser_pdev_obj, cmd_type); 605 606 wlan_serialization_acquire_lock(&pdev_q->pdev_queue_lock); 607 608 queue = &pdev_q->active_list; 609 610 node = wlan_serialization_find_cmd( 611 queue, WLAN_SER_MATCH_CMD_TYPE_VDEV, 612 NULL, cmd_type, NULL, vdev, WLAN_SER_PDEV_NODE); 613 614 if (node) { 615 cmd_list = qdf_container_of( 616 node, 617 struct wlan_serialization_command_list, 618 pdev_node); 619 620 umac_cmd = cmd_list->cmd.umac_cmd; 621 } 622 623 wlan_serialization_release_lock(&pdev_q->pdev_queue_lock); 624 625 release_vdev_ref: 626 wlan_objmgr_vdev_release_ref(vdev, WLAN_SERIALIZATION_ID); 627 error: 628 ser_exit(); 629 return umac_cmd; 630 } 631 632 enum wlan_serialization_cmd_type 633 wlan_serialization_get_vdev_active_cmd_type(struct wlan_objmgr_vdev *vdev) 634 { 635 enum wlan_serialization_cmd_type cmd_type = WLAN_SER_CMD_MAX; 636 struct wlan_ser_pdev_obj *ser_pdev_obj; 637 struct wlan_ser_vdev_obj *ser_vdev_obj; 638 struct wlan_serialization_pdev_queue *pdev_queue; 639 struct wlan_serialization_vdev_queue *vdev_queue; 640 struct wlan_serialization_command_list *cmd_list = NULL; 641 qdf_list_node_t *node; 642 643 ser_pdev_obj = wlan_serialization_get_pdev_obj( 644 wlan_vdev_get_pdev(vdev)); 645 646 if (!ser_pdev_obj) { 647 ser_err("invalid ser_pdev_obj"); 648 goto error; 649 } 650 pdev_queue = wlan_serialization_get_pdev_queue_obj( 651 ser_pdev_obj, cmd_type); 652 653 ser_vdev_obj = wlan_serialization_get_vdev_obj(vdev); 654 if (!ser_vdev_obj) { 655 ser_err("invalid ser_vdev_obj"); 656 goto error; 657 } 658 vdev_queue = wlan_serialization_get_vdev_queue_obj( 659 ser_vdev_obj, WLAN_SER_CMD_NONSCAN); 660 661 wlan_serialization_acquire_lock(&pdev_queue->pdev_queue_lock); 662 663 if (wlan_serialization_peek_front( 664 &vdev_queue->active_list, &node) == QDF_STATUS_SUCCESS) { 665 cmd_list = qdf_container_of( 666 node, 667 struct wlan_serialization_command_list, 668 vdev_node); 669 670 cmd_type = cmd_list->cmd.cmd_type; 671 } 672 673 wlan_serialization_release_lock(&pdev_queue->pdev_queue_lock); 674 675 error: 676 return cmd_type; 677 } 678 679 QDF_STATUS 680 wlan_ser_get_cmd_activation_status(struct wlan_objmgr_vdev *vdev) 681 { 682 struct wlan_ser_pdev_obj *ser_pdev_obj; 683 struct wlan_ser_vdev_obj *ser_vdev_obj; 684 struct wlan_serialization_pdev_queue *pdev_queue; 685 struct wlan_serialization_vdev_queue *vdev_queue; 686 struct wlan_serialization_command_list *cmd_list = NULL; 687 qdf_list_node_t *node; 688 QDF_STATUS status = QDF_STATUS_E_FAILURE; 689 690 ser_pdev_obj = wlan_serialization_get_pdev_obj( 691 wlan_vdev_get_pdev(vdev)); 692 693 if (!ser_pdev_obj) { 694 ser_err("invalid ser_pdev_obj"); 695 return QDF_STATUS_E_FAILURE; 696 } 697 698 pdev_queue = wlan_serialization_get_pdev_queue_obj( 699 ser_pdev_obj, WLAN_SER_CMD_NONSCAN); 700 701 ser_vdev_obj = wlan_serialization_get_vdev_obj(vdev); 702 if (!ser_vdev_obj) { 703 ser_err("invalid ser_vdev_obj"); 704 return QDF_STATUS_E_FAILURE; 705 } 706 vdev_queue = wlan_serialization_get_vdev_queue_obj( 707 ser_vdev_obj, WLAN_SER_CMD_NONSCAN); 708 709 wlan_serialization_acquire_lock(&pdev_queue->pdev_queue_lock); 710 711 if (wlan_serialization_peek_front( 712 &vdev_queue->active_list, &node) == QDF_STATUS_SUCCESS) { 713 cmd_list = qdf_container_of( 714 node, 715 struct wlan_serialization_command_list, 716 vdev_node); 717 718 if (qdf_atomic_test_bit(CMD_MARKED_FOR_ACTIVATION, 719 &cmd_list->cmd_in_use)) 720 status = QDF_STATUS_SUCCESS; 721 } 722 723 wlan_serialization_release_lock(&pdev_queue->pdev_queue_lock); 724 725 return status; 726 } 727 728 QDF_STATUS 729 wlan_ser_validate_umac_cmd(struct wlan_objmgr_vdev *vdev, 730 enum wlan_serialization_cmd_type cmd_type, 731 wlan_ser_umac_cmd_cb umac_cmd_cb) 732 { 733 struct wlan_objmgr_pdev *pdev; 734 struct wlan_ser_pdev_obj *ser_pdev_obj; 735 struct wlan_serialization_command_list *cmd_list = NULL; 736 void *umac_cmd = NULL; 737 qdf_list_node_t *node = NULL; 738 qdf_list_t *queue; 739 struct wlan_serialization_pdev_queue *pdev_q; 740 QDF_STATUS status = QDF_STATUS_E_INVAL; 741 742 ser_enter(); 743 744 if (!vdev) { 745 ser_err("invalid vdev"); 746 return QDF_STATUS_E_INVAL; 747 } 748 749 pdev = wlan_vdev_get_pdev(vdev); 750 if (!pdev) { 751 ser_err("invalid pdev"); 752 return QDF_STATUS_E_INVAL; 753 } 754 755 ser_pdev_obj = wlan_serialization_get_pdev_obj(pdev); 756 if (!ser_pdev_obj) { 757 ser_err("invalid ser_pdev_obj"); 758 return QDF_STATUS_E_INVAL; 759 } 760 761 pdev_q = wlan_serialization_get_pdev_queue_obj(ser_pdev_obj, cmd_type); 762 763 wlan_serialization_acquire_lock(&pdev_q->pdev_queue_lock); 764 765 queue = &pdev_q->active_list; 766 node = wlan_serialization_find_cmd( 767 queue, WLAN_SER_MATCH_CMD_TYPE_VDEV, 768 NULL, cmd_type, NULL, vdev, WLAN_SER_PDEV_NODE); 769 if (node) { 770 cmd_list = qdf_container_of( 771 node, 772 struct wlan_serialization_command_list, 773 pdev_node); 774 775 umac_cmd = cmd_list->cmd.umac_cmd; 776 status = umac_cmd_cb(umac_cmd); 777 } 778 779 wlan_serialization_release_lock(&pdev_q->pdev_queue_lock); 780 ser_exit(); 781 782 return status; 783 } 784 785 void wlan_serialization_purge_all_pdev_cmd(struct wlan_objmgr_pdev *pdev) 786 { 787 struct wlan_ser_pdev_obj *ser_pdev_obj; 788 789 if (!pdev) { 790 ser_err("NULL pdev"); 791 return; 792 } 793 794 ser_pdev_obj = wlan_serialization_get_pdev_obj(pdev); 795 if (!ser_pdev_obj) { 796 ser_err("invalid ser_pdev_obj"); 797 return; 798 } 799 800 wlan_ser_cancel_scan_cmd(ser_pdev_obj, pdev, NULL, NULL, 801 WLAN_SER_CMD_SCAN, false); 802 wlan_ser_cancel_scan_cmd(ser_pdev_obj, pdev, NULL, NULL, 803 WLAN_SER_CMD_SCAN, true); 804 wlan_ser_cancel_non_scan_cmd(ser_pdev_obj, pdev, NULL, NULL, 805 WLAN_SER_CMD_NONSCAN, false); 806 wlan_ser_cancel_non_scan_cmd(ser_pdev_obj, pdev, NULL, NULL, 807 WLAN_SER_CMD_NONSCAN, true); 808 } 809 810 static inline 811 void wlan_ser_purge_pdev_cmd_cb(struct wlan_objmgr_psoc *psoc, 812 void *object, void *arg) 813 { 814 struct wlan_objmgr_pdev *pdev = (struct wlan_objmgr_pdev *)object; 815 816 wlan_serialization_purge_all_pdev_cmd(pdev); 817 } 818 819 void wlan_serialization_purge_all_cmd(struct wlan_objmgr_psoc *psoc) 820 { 821 wlan_objmgr_iterate_obj_list(psoc, WLAN_PDEV_OP, 822 wlan_ser_purge_pdev_cmd_cb, NULL, 1, 823 WLAN_SERIALIZATION_ID); 824 } 825 826 void wlan_serialization_purge_all_pending_cmd_by_vdev_id( 827 struct wlan_objmgr_pdev *pdev, 828 uint8_t vdev_id) 829 { 830 struct wlan_objmgr_vdev *vdev; 831 struct wlan_ser_pdev_obj *ser_pdev_obj; 832 833 if (!pdev) { 834 ser_err("Invalid pdev"); 835 return; 836 } 837 838 ser_pdev_obj = wlan_serialization_get_pdev_obj(pdev); 839 if (!ser_pdev_obj) { 840 ser_err("invalid ser_pdev_obj"); 841 return; 842 } 843 844 vdev = wlan_objmgr_get_vdev_by_id_from_pdev(pdev, vdev_id, 845 WLAN_SERIALIZATION_ID); 846 if (!vdev) { 847 ser_err("Invalid vdev"); 848 return; 849 } 850 851 wlan_ser_cancel_scan_cmd(ser_pdev_obj, pdev, vdev, NULL, 852 WLAN_SER_CMD_SCAN, false); 853 wlan_ser_cancel_non_scan_cmd(ser_pdev_obj, pdev, vdev, NULL, 854 WLAN_SER_CMD_NONSCAN, false); 855 856 wlan_objmgr_vdev_release_ref(vdev, WLAN_SERIALIZATION_ID); 857 } 858 859 void wlan_serialization_purge_all_scan_cmd_by_vdev_id( 860 struct wlan_objmgr_pdev *pdev, 861 uint8_t vdev_id) 862 { 863 struct wlan_objmgr_vdev *vdev; 864 struct wlan_ser_pdev_obj *ser_pdev_obj; 865 866 if (!pdev) { 867 ser_err("Invalid pdev"); 868 return; 869 } 870 871 ser_pdev_obj = wlan_serialization_get_pdev_obj(pdev); 872 if (!ser_pdev_obj) { 873 ser_err("invalid ser_pdev_obj"); 874 return; 875 } 876 877 vdev = wlan_objmgr_get_vdev_by_id_from_pdev(pdev, vdev_id, 878 WLAN_SERIALIZATION_ID); 879 if (!vdev) { 880 ser_err("Invalid vdev"); 881 return; 882 } 883 884 wlan_ser_cancel_scan_cmd(ser_pdev_obj, pdev, vdev, NULL, 885 WLAN_SER_CMD_SCAN, false); 886 wlan_ser_cancel_scan_cmd(ser_pdev_obj, pdev, vdev, NULL, 887 WLAN_SER_CMD_SCAN, true); 888 889 wlan_objmgr_vdev_release_ref(vdev, WLAN_SERIALIZATION_ID); 890 } 891