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_debug("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 bool wlan_ser_is_vdev_queue_enabled(struct wlan_objmgr_vdev *vdev) 680 { 681 struct wlan_ser_vdev_obj *ser_vdev_obj; 682 struct wlan_serialization_vdev_queue *vdev_queue; 683 684 ser_vdev_obj = wlan_serialization_get_vdev_obj(vdev); 685 if (!ser_vdev_obj) { 686 ser_err("invalid ser_vdev_obj"); 687 return false; 688 } 689 690 vdev_queue = wlan_serialization_get_vdev_queue_obj( 691 ser_vdev_obj, WLAN_SER_CMD_NONSCAN); 692 if (vdev_queue->queue_disable) 693 return false; 694 else 695 return true; 696 } 697 698 QDF_STATUS 699 wlan_ser_get_cmd_activation_status(struct wlan_objmgr_vdev *vdev) 700 { 701 struct wlan_ser_pdev_obj *ser_pdev_obj; 702 struct wlan_ser_vdev_obj *ser_vdev_obj; 703 struct wlan_serialization_pdev_queue *pdev_queue; 704 struct wlan_serialization_vdev_queue *vdev_queue; 705 struct wlan_serialization_command_list *cmd_list = NULL; 706 qdf_list_node_t *node; 707 QDF_STATUS status = QDF_STATUS_E_FAILURE; 708 709 ser_pdev_obj = wlan_serialization_get_pdev_obj( 710 wlan_vdev_get_pdev(vdev)); 711 712 if (!ser_pdev_obj) { 713 ser_err("invalid ser_pdev_obj"); 714 return QDF_STATUS_E_FAILURE; 715 } 716 717 pdev_queue = wlan_serialization_get_pdev_queue_obj( 718 ser_pdev_obj, WLAN_SER_CMD_NONSCAN); 719 720 ser_vdev_obj = wlan_serialization_get_vdev_obj(vdev); 721 if (!ser_vdev_obj) { 722 ser_err("invalid ser_vdev_obj"); 723 return QDF_STATUS_E_FAILURE; 724 } 725 vdev_queue = wlan_serialization_get_vdev_queue_obj( 726 ser_vdev_obj, WLAN_SER_CMD_NONSCAN); 727 728 wlan_serialization_acquire_lock(&pdev_queue->pdev_queue_lock); 729 730 if (wlan_serialization_peek_front( 731 &vdev_queue->active_list, &node) == QDF_STATUS_SUCCESS) { 732 cmd_list = qdf_container_of( 733 node, 734 struct wlan_serialization_command_list, 735 vdev_node); 736 737 if (qdf_atomic_test_bit(CMD_MARKED_FOR_ACTIVATION, 738 &cmd_list->cmd_in_use)) 739 status = QDF_STATUS_SUCCESS; 740 } 741 742 wlan_serialization_release_lock(&pdev_queue->pdev_queue_lock); 743 744 return status; 745 } 746 747 QDF_STATUS 748 wlan_ser_validate_umac_cmd(struct wlan_objmgr_vdev *vdev, 749 enum wlan_serialization_cmd_type cmd_type, 750 wlan_ser_umac_cmd_cb umac_cmd_cb) 751 { 752 struct wlan_objmgr_pdev *pdev; 753 struct wlan_ser_pdev_obj *ser_pdev_obj; 754 struct wlan_serialization_command_list *cmd_list = NULL; 755 void *umac_cmd = NULL; 756 qdf_list_node_t *node = NULL; 757 qdf_list_t *queue; 758 struct wlan_serialization_pdev_queue *pdev_q; 759 QDF_STATUS status = QDF_STATUS_E_INVAL; 760 761 ser_enter(); 762 763 if (!vdev) { 764 ser_err("invalid vdev"); 765 return QDF_STATUS_E_INVAL; 766 } 767 768 pdev = wlan_vdev_get_pdev(vdev); 769 if (!pdev) { 770 ser_err("invalid pdev"); 771 return QDF_STATUS_E_INVAL; 772 } 773 774 ser_pdev_obj = wlan_serialization_get_pdev_obj(pdev); 775 if (!ser_pdev_obj) { 776 ser_err("invalid ser_pdev_obj"); 777 return QDF_STATUS_E_INVAL; 778 } 779 780 pdev_q = wlan_serialization_get_pdev_queue_obj(ser_pdev_obj, cmd_type); 781 782 wlan_serialization_acquire_lock(&pdev_q->pdev_queue_lock); 783 784 queue = &pdev_q->active_list; 785 node = wlan_serialization_find_cmd( 786 queue, WLAN_SER_MATCH_CMD_TYPE_VDEV, 787 NULL, cmd_type, NULL, vdev, WLAN_SER_PDEV_NODE); 788 if (node) { 789 cmd_list = qdf_container_of( 790 node, 791 struct wlan_serialization_command_list, 792 pdev_node); 793 794 umac_cmd = cmd_list->cmd.umac_cmd; 795 status = umac_cmd_cb(umac_cmd); 796 } 797 798 wlan_serialization_release_lock(&pdev_q->pdev_queue_lock); 799 ser_exit(); 800 801 return status; 802 } 803 804 void wlan_serialization_purge_all_pdev_cmd(struct wlan_objmgr_pdev *pdev) 805 { 806 struct wlan_ser_pdev_obj *ser_pdev_obj; 807 808 if (!pdev) { 809 ser_err("NULL pdev"); 810 return; 811 } 812 813 ser_pdev_obj = wlan_serialization_get_pdev_obj(pdev); 814 if (!ser_pdev_obj) { 815 ser_err("invalid ser_pdev_obj"); 816 return; 817 } 818 819 wlan_ser_cancel_scan_cmd(ser_pdev_obj, pdev, NULL, NULL, 820 WLAN_SER_CMD_SCAN, false); 821 wlan_ser_cancel_scan_cmd(ser_pdev_obj, pdev, NULL, NULL, 822 WLAN_SER_CMD_SCAN, true); 823 wlan_ser_cancel_non_scan_cmd(ser_pdev_obj, pdev, NULL, NULL, 824 WLAN_SER_CMD_NONSCAN, false, 825 WLAN_SER_CMD_ATTR_NONE); 826 wlan_ser_cancel_non_scan_cmd(ser_pdev_obj, pdev, NULL, NULL, 827 WLAN_SER_CMD_NONSCAN, true, 828 WLAN_SER_CMD_ATTR_NONE); 829 } 830 831 static inline 832 void wlan_ser_purge_pdev_cmd_cb(struct wlan_objmgr_psoc *psoc, 833 void *object, void *arg) 834 { 835 struct wlan_objmgr_pdev *pdev = (struct wlan_objmgr_pdev *)object; 836 837 wlan_serialization_purge_all_pdev_cmd(pdev); 838 } 839 840 void wlan_serialization_purge_all_cmd(struct wlan_objmgr_psoc *psoc) 841 { 842 wlan_objmgr_iterate_obj_list(psoc, WLAN_PDEV_OP, 843 wlan_ser_purge_pdev_cmd_cb, NULL, 1, 844 WLAN_SERIALIZATION_ID); 845 } 846 847 void wlan_serialization_purge_all_pending_cmd_by_vdev_id( 848 struct wlan_objmgr_pdev *pdev, 849 uint8_t vdev_id) 850 { 851 struct wlan_objmgr_vdev *vdev; 852 struct wlan_ser_pdev_obj *ser_pdev_obj; 853 854 if (!pdev) { 855 ser_err("Invalid pdev"); 856 return; 857 } 858 859 ser_pdev_obj = wlan_serialization_get_pdev_obj(pdev); 860 if (!ser_pdev_obj) { 861 ser_err("invalid ser_pdev_obj"); 862 return; 863 } 864 865 vdev = wlan_objmgr_get_vdev_by_id_from_pdev(pdev, vdev_id, 866 WLAN_SERIALIZATION_ID); 867 if (!vdev) { 868 ser_err("Invalid vdev"); 869 return; 870 } 871 872 wlan_ser_cancel_scan_cmd(ser_pdev_obj, pdev, vdev, NULL, 873 WLAN_SER_CMD_SCAN, false); 874 wlan_ser_cancel_non_scan_cmd(ser_pdev_obj, pdev, vdev, NULL, 875 WLAN_SER_CMD_NONSCAN, false, 876 WLAN_SER_CMD_ATTR_NONE); 877 878 wlan_objmgr_vdev_release_ref(vdev, WLAN_SERIALIZATION_ID); 879 } 880 881 void wlan_serialization_purge_all_scan_cmd_by_vdev_id( 882 struct wlan_objmgr_pdev *pdev, 883 uint8_t vdev_id) 884 { 885 struct wlan_objmgr_vdev *vdev; 886 struct wlan_ser_pdev_obj *ser_pdev_obj; 887 888 if (!pdev) { 889 ser_err("Invalid pdev"); 890 return; 891 } 892 893 ser_pdev_obj = wlan_serialization_get_pdev_obj(pdev); 894 if (!ser_pdev_obj) { 895 ser_err("invalid ser_pdev_obj"); 896 return; 897 } 898 899 vdev = wlan_objmgr_get_vdev_by_id_from_pdev(pdev, vdev_id, 900 WLAN_SERIALIZATION_ID); 901 if (!vdev) { 902 ser_err("Invalid vdev"); 903 return; 904 } 905 906 wlan_ser_cancel_scan_cmd(ser_pdev_obj, pdev, vdev, NULL, 907 WLAN_SER_CMD_SCAN, false); 908 wlan_ser_cancel_scan_cmd(ser_pdev_obj, pdev, vdev, NULL, 909 WLAN_SER_CMD_SCAN, true); 910 911 wlan_objmgr_vdev_release_ref(vdev, WLAN_SERIALIZATION_ID); 912 } 913 914 QDF_STATUS wlan_ser_vdev_queue_disable(struct wlan_objmgr_vdev *vdev) 915 { 916 struct wlan_objmgr_pdev *pdev; 917 struct wlan_ser_vdev_obj *ser_vdev_obj; 918 struct wlan_serialization_vdev_queue *vdev_queue; 919 struct wlan_ser_pdev_obj *ser_pdev_obj; 920 struct wlan_serialization_pdev_queue *pdev_q; 921 922 pdev = wlan_vdev_get_pdev(vdev); 923 if (!pdev) { 924 ser_err("invalid PDEV object"); 925 return QDF_STATUS_E_INVAL; 926 } 927 928 ser_pdev_obj = wlan_serialization_get_pdev_obj(pdev); 929 if (!ser_pdev_obj) { 930 ser_err("invalid ser_pdev_obj"); 931 return QDF_STATUS_E_INVAL; 932 } 933 934 ser_vdev_obj = wlan_serialization_get_vdev_obj(vdev); 935 if (!ser_vdev_obj) { 936 ser_err("invalid ser_vdev_obj"); 937 return QDF_STATUS_E_INVAL; 938 } 939 940 pdev_q = &ser_pdev_obj->pdev_q[SER_PDEV_QUEUE_COMP_NON_SCAN]; 941 942 vdev_queue = wlan_serialization_get_vdev_queue_obj( 943 ser_vdev_obj, WLAN_SER_CMD_NONSCAN); 944 if (!vdev_queue) { 945 ser_err("invalid vdev_queue object"); 946 return QDF_STATUS_E_INVAL; 947 } 948 949 wlan_serialization_acquire_lock(&pdev_q->pdev_queue_lock); 950 vdev_queue->queue_disable = true; 951 wlan_serialization_release_lock(&pdev_q->pdev_queue_lock); 952 ser_info("Disabling the serialization for vdev:%d", 953 wlan_vdev_get_id(vdev)); 954 955 return QDF_STATUS_SUCCESS; 956 } 957