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, SER_REMOVE, 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, SER_REQUEST); 796 797 error: 798 ser_exit(); 799 return serialization_status; 800 } 801 802 QDF_STATUS 803 wlan_serialization_update_timer(struct wlan_serialization_command *cmd) 804 { 805 QDF_STATUS status = QDF_STATUS_E_FAILURE; 806 struct wlan_objmgr_pdev *pdev; 807 struct wlan_objmgr_psoc *psoc; 808 809 if (!cmd) { 810 ser_err("NULL command"); 811 goto error; 812 } 813 814 pdev = wlan_serialization_get_pdev_from_cmd(cmd); 815 if (!pdev) { 816 ser_err("invalid pdev"); 817 goto error; 818 } 819 820 psoc = wlan_pdev_get_psoc(pdev); 821 if (!psoc) { 822 ser_err("invalid psoc"); 823 goto error; 824 } 825 826 status = wlan_serialization_find_and_update_timer(psoc, cmd); 827 828 error: 829 return status; 830 } 831 832 enum wlan_serialization_cmd_status 833 wlan_serialization_vdev_scan_status(struct wlan_objmgr_vdev *vdev) 834 { 835 bool cmd_in_active = 0, cmd_in_pending = 0; 836 struct wlan_objmgr_pdev *pdev = wlan_vdev_get_pdev(vdev); 837 struct wlan_ser_pdev_obj *ser_pdev_obj = 838 wlan_serialization_get_pdev_obj(pdev); 839 struct wlan_serialization_pdev_queue *pdev_q; 840 enum wlan_serialization_cmd_status status; 841 842 ser_enter(); 843 844 pdev_q = &ser_pdev_obj->pdev_q[SER_PDEV_QUEUE_COMP_SCAN]; 845 846 wlan_serialization_acquire_lock(&pdev_q->pdev_queue_lock); 847 848 cmd_in_active = 849 wlan_serialization_is_cmd_in_vdev_list( 850 vdev, &pdev_q->active_list, WLAN_SER_PDEV_NODE); 851 852 cmd_in_pending = 853 wlan_serialization_is_cmd_in_vdev_list( 854 vdev, &pdev_q->pending_list, WLAN_SER_PDEV_NODE); 855 856 status = wlan_serialization_is_cmd_in_active_pending( 857 cmd_in_active, cmd_in_pending); 858 859 wlan_serialization_release_lock(&pdev_q->pdev_queue_lock); 860 ser_exit(); 861 862 return status; 863 } 864 865 void wlan_serialization_flush_cmd( 866 struct wlan_serialization_queued_cmd_info *cmd) 867 { 868 ser_enter(); 869 870 if (!cmd) { 871 ser_err("cmd is null, can't flush"); 872 goto error; 873 } 874 875 error: 876 ser_exit(); 877 } 878 879 enum wlan_serialization_cmd_status 880 wlan_serialization_pdev_scan_status(struct wlan_objmgr_pdev *pdev) 881 { 882 bool cmd_in_active, cmd_in_pending; 883 struct wlan_ser_pdev_obj *ser_pdev_obj = 884 wlan_serialization_get_pdev_obj(pdev); 885 struct wlan_serialization_pdev_queue *pdev_q; 886 enum wlan_serialization_cmd_status status; 887 888 pdev_q = &ser_pdev_obj->pdev_q[SER_PDEV_QUEUE_COMP_SCAN]; 889 890 wlan_serialization_acquire_lock(&pdev_q->pdev_queue_lock); 891 892 cmd_in_active = !qdf_list_empty(&pdev_q->active_list); 893 cmd_in_pending = !qdf_list_empty(&pdev_q->pending_list); 894 895 status = wlan_serialization_is_cmd_in_active_pending( 896 cmd_in_active, cmd_in_pending); 897 898 wlan_serialization_release_lock(&pdev_q->pdev_queue_lock); 899 900 return status; 901 } 902 903 struct wlan_serialization_command* 904 wlan_serialization_get_scan_cmd_using_scan_id( 905 struct wlan_objmgr_psoc *psoc, 906 uint8_t vdev_id, uint16_t scan_id, 907 uint8_t is_scan_cmd_from_active_queue) 908 { 909 struct wlan_objmgr_vdev *vdev; 910 struct wlan_objmgr_pdev *pdev; 911 struct wlan_ser_pdev_obj *ser_pdev_obj; 912 struct wlan_serialization_command cmd = {0}; 913 struct wlan_serialization_command *pcmd = NULL; 914 struct wlan_serialization_command_list *cmd_list; 915 qdf_list_node_t *node = NULL; 916 qdf_list_t *queue; 917 struct wlan_serialization_pdev_queue *pdev_q; 918 919 if (!psoc) { 920 ser_err("invalid psoc"); 921 goto error; 922 } 923 vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id, 924 WLAN_SERIALIZATION_ID); 925 if (!vdev) { 926 ser_err("invalid vdev"); 927 goto error; 928 } 929 930 pdev = wlan_vdev_get_pdev(vdev); 931 if (!pdev) { 932 ser_err("invalid pdev"); 933 goto release_vdev_ref; 934 } 935 936 ser_pdev_obj = wlan_serialization_get_pdev_obj(pdev); 937 if (!ser_pdev_obj) { 938 ser_err("invalid ser_pdev_obj"); 939 goto release_vdev_ref; 940 } 941 942 pdev_q = &ser_pdev_obj->pdev_q[SER_PDEV_QUEUE_COMP_SCAN]; 943 944 wlan_serialization_acquire_lock(&pdev_q->pdev_queue_lock); 945 946 if (is_scan_cmd_from_active_queue) 947 queue = &pdev_q->active_list; 948 else 949 queue = &pdev_q->pending_list; 950 951 cmd.cmd_type = WLAN_SER_CMD_SCAN; 952 cmd.cmd_id = scan_id; 953 cmd.vdev = vdev; 954 955 node = wlan_serialization_find_cmd( 956 queue, WLAN_SER_MATCH_CMD_ID_VDEV, 957 &cmd, 0, NULL, vdev, WLAN_SER_PDEV_NODE); 958 959 if (node) { 960 cmd_list = qdf_container_of( 961 node, 962 struct wlan_serialization_command_list, 963 pdev_node); 964 965 pcmd = &cmd_list->cmd; 966 } 967 968 wlan_serialization_release_lock(&pdev_q->pdev_queue_lock); 969 970 release_vdev_ref: 971 wlan_objmgr_vdev_release_ref(vdev, WLAN_SERIALIZATION_ID); 972 error: 973 return pcmd; 974 } 975 976 void *wlan_serialization_get_active_cmd( 977 struct wlan_objmgr_psoc *psoc, 978 uint8_t vdev_id, 979 enum wlan_serialization_cmd_type cmd_type) 980 { 981 struct wlan_objmgr_vdev *vdev; 982 struct wlan_objmgr_pdev *pdev; 983 struct wlan_ser_pdev_obj *ser_pdev_obj; 984 struct wlan_serialization_command_list *cmd_list = NULL; 985 void *umac_cmd = NULL; 986 qdf_list_node_t *node = NULL; 987 qdf_list_t *queue; 988 struct wlan_serialization_pdev_queue *pdev_q; 989 990 ser_enter(); 991 992 if (!psoc) { 993 ser_err("invalid psoc"); 994 goto error; 995 } 996 vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id, 997 WLAN_SERIALIZATION_ID); 998 if (!vdev) { 999 ser_err("invalid vdev"); 1000 goto error; 1001 } 1002 1003 pdev = wlan_vdev_get_pdev(vdev); 1004 if (!pdev) { 1005 ser_err("invalid pdev"); 1006 goto release_vdev_ref; 1007 } 1008 1009 ser_pdev_obj = wlan_serialization_get_pdev_obj(pdev); 1010 if (!ser_pdev_obj) { 1011 ser_err("invalid ser_pdev_obj"); 1012 goto release_vdev_ref; 1013 } 1014 1015 pdev_q = wlan_serialization_get_pdev_queue_obj(ser_pdev_obj, cmd_type); 1016 1017 wlan_serialization_acquire_lock(&pdev_q->pdev_queue_lock); 1018 1019 queue = &pdev_q->active_list; 1020 1021 node = wlan_serialization_find_cmd( 1022 queue, WLAN_SER_MATCH_CMD_TYPE_VDEV, 1023 NULL, cmd_type, NULL, vdev, WLAN_SER_PDEV_NODE); 1024 1025 if (node) { 1026 cmd_list = qdf_container_of( 1027 node, 1028 struct wlan_serialization_command_list, 1029 pdev_node); 1030 1031 umac_cmd = cmd_list->cmd.umac_cmd; 1032 } 1033 1034 wlan_serialization_release_lock(&pdev_q->pdev_queue_lock); 1035 1036 release_vdev_ref: 1037 wlan_objmgr_vdev_release_ref(vdev, WLAN_SERIALIZATION_ID); 1038 error: 1039 ser_exit(); 1040 return umac_cmd; 1041 } 1042 1043 enum wlan_serialization_cmd_type 1044 wlan_serialization_get_vdev_active_cmd_type(struct wlan_objmgr_vdev *vdev) 1045 { 1046 enum wlan_serialization_cmd_type cmd_type = WLAN_SER_CMD_MAX; 1047 struct wlan_ser_pdev_obj *ser_pdev_obj; 1048 struct wlan_ser_vdev_obj *ser_vdev_obj; 1049 struct wlan_serialization_pdev_queue *pdev_queue; 1050 struct wlan_serialization_vdev_queue *vdev_queue; 1051 struct wlan_serialization_command_list *cmd_list = NULL; 1052 qdf_list_node_t *node; 1053 1054 ser_pdev_obj = wlan_serialization_get_pdev_obj( 1055 wlan_vdev_get_pdev(vdev)); 1056 1057 if (!ser_pdev_obj) { 1058 ser_err("invalid ser_pdev_obj"); 1059 goto error; 1060 } 1061 pdev_queue = wlan_serialization_get_pdev_queue_obj( 1062 ser_pdev_obj, cmd_type); 1063 1064 ser_vdev_obj = wlan_serialization_get_vdev_obj(vdev); 1065 if (!ser_vdev_obj) { 1066 ser_err("invalid ser_vdev_obj"); 1067 goto error; 1068 } 1069 vdev_queue = wlan_serialization_get_vdev_queue_obj( 1070 ser_vdev_obj, WLAN_SER_CMD_NONSCAN); 1071 1072 wlan_serialization_acquire_lock(&pdev_queue->pdev_queue_lock); 1073 1074 if (wlan_serialization_peek_front( 1075 &vdev_queue->active_list, &node) == QDF_STATUS_SUCCESS) { 1076 cmd_list = qdf_container_of( 1077 node, 1078 struct wlan_serialization_command_list, 1079 vdev_node); 1080 1081 cmd_type = cmd_list->cmd.cmd_type; 1082 } 1083 1084 wlan_serialization_release_lock(&pdev_queue->pdev_queue_lock); 1085 1086 error: 1087 return cmd_type; 1088 } 1089 #endif 1090