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