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