1 /* 2 * Copyright (c) 2018-2021 The Linux Foundation. All rights reserved. 3 * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved. 4 * 5 * Permission to use, copy, modify, and/or distribute this software for any 6 * purpose with or without fee is hereby granted, provided that the above 7 * copyright notice and this permission notice appear in all copies. 8 * 9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16 */ 17 18 /** 19 * DOC: Implements VDEV MLME SM 20 */ 21 22 #include <wlan_objmgr_vdev_obj.h> 23 #include <wlan_mlme_dbg.h> 24 #include <wlan_sm_engine.h> 25 #include "include/wlan_vdev_mlme.h" 26 #include "vdev_mlme_sm.h" 27 #include <wlan_utility.h> 28 #include <include/wlan_mlme_cmn.h> 29 30 /** 31 * mlme_vdev_set_state() - set mlme state 32 * @vdev: VDEV object 33 * @state: MLME state 34 * 35 * API to set MLME state 36 * 37 * Return: void 38 */ 39 static void mlme_vdev_set_state(struct wlan_objmgr_vdev *vdev, 40 enum wlan_vdev_state state) 41 { 42 if (state < WLAN_VDEV_S_MAX) { 43 vdev->vdev_mlme.mlme_state = state; 44 } else { 45 mlme_err("mlme state (%d) is invalid", state); 46 QDF_BUG(0); 47 } 48 } 49 50 /** 51 * mlme_vdev_set_substate() - set mlme sub state 52 * @vdev: VDEV object 53 * @substate: MLME sub state 54 * 55 * API to set MLME sub state 56 * 57 * Return: void 58 */ 59 static void mlme_vdev_set_substate(struct wlan_objmgr_vdev *vdev, 60 enum wlan_vdev_state substate) 61 { 62 if ((substate > WLAN_VDEV_S_MAX) && (substate < WLAN_VDEV_SS_MAX)) { 63 vdev->vdev_mlme.mlme_substate = substate; 64 } else { 65 mlme_err(" mlme sub state (%d) is invalid", substate); 66 QDF_BUG(0); 67 } 68 } 69 70 /** 71 * mlme_vdev_sm_state_update() - set mlme state and sub state 72 * @vdev_mlme: MLME VDEV comp object 73 * @state: MLME state 74 * @substate: MLME sub state 75 * 76 * API to invoke util APIs to set state and MLME sub state 77 * 78 * Return: void 79 */ 80 static void mlme_vdev_sm_state_update(struct vdev_mlme_obj *vdev_mlme, 81 enum wlan_vdev_state state, 82 enum wlan_vdev_state substate) 83 { 84 struct wlan_objmgr_vdev *vdev; 85 86 vdev = vdev_mlme->vdev; 87 if (!vdev) { 88 mlme_err(" VDEV is NULL"); 89 QDF_BUG(0); 90 } 91 92 mlme_vdev_set_state(vdev, state); 93 mlme_vdev_set_substate(vdev, substate); 94 } 95 96 /** 97 * mlme_vdev_sm_transition_to() - invokes state transition 98 * @vdev_mlme: MLME VDEV comp object 99 * @state: new MLME state 100 * 101 * API to invoke SM API to move to new state 102 * 103 * Return: void 104 */ 105 static void mlme_vdev_sm_transition_to(struct vdev_mlme_obj *vdev_mlme, 106 enum wlan_vdev_state state) 107 { 108 wlan_sm_transition_to(vdev_mlme->sm_hdl, state); 109 } 110 111 /** 112 * mlme_vdev_state_init_entry() - Entry API for Init state 113 * @ctx: VDEV MLME object 114 * 115 * API to perform operations on moving to INIT state 116 * 117 * Return: void 118 */ 119 static void mlme_vdev_state_init_entry(void *ctx) 120 { 121 struct vdev_mlme_obj *vdev_mlme = (struct vdev_mlme_obj *)ctx; 122 123 mlme_vdev_sm_state_update(vdev_mlme, WLAN_VDEV_S_INIT, 124 WLAN_VDEV_SS_IDLE); 125 } 126 127 /** 128 * mlme_vdev_state_init_exit() - Exit API for Init state 129 * @ctx: VDEV MLME object 130 * 131 * API to perform operations on moving out of INIT state 132 * 133 * Return: void 134 */ 135 static void mlme_vdev_state_init_exit(void *ctx) 136 { 137 /* NONE */ 138 } 139 140 /** 141 * mlme_vdev_state_init_event() - Init State event handler 142 * @ctx: VDEV MLME object 143 * 144 * API to handle events in INIT state 145 * 146 * Return: SUCCESS: on handling event 147 * FAILURE: on ignoring the event 148 */ 149 static bool mlme_vdev_state_init_event(void *ctx, uint16_t event, 150 uint16_t event_data_len, 151 void *event_data) 152 { 153 struct vdev_mlme_obj *vdev_mlme = (struct vdev_mlme_obj *)ctx; 154 bool status; 155 enum QDF_OPMODE mode; 156 157 mode = wlan_vdev_mlme_get_opmode(vdev_mlme->vdev); 158 159 switch (event) { 160 case WLAN_VDEV_SM_EV_START: 161 /* call mlme callback API for sanity checks */ 162 if (mlme_vdev_validate_basic_params(vdev_mlme, event_data_len, 163 event_data) == QDF_STATUS_SUCCESS) { 164 mlme_vdev_sm_transition_to(vdev_mlme, 165 WLAN_VDEV_S_START); 166 mlme_vdev_sm_deliver_event(vdev_mlme, 167 WLAN_VDEV_SM_EV_START_REQ, 168 event_data_len, event_data); 169 status = true; 170 } else { 171 mlme_err( 172 "failed to validate vdev init params to move to START state"); 173 /* 174 * In case of AP if false is returned, we consider as 175 * error scenario and print that the event is not 176 * handled. Hence return false only for STA. 177 */ 178 if (mode == QDF_STA_MODE) 179 status = false; 180 else 181 status = true; 182 mlme_vdev_notify_down_complete(vdev_mlme, 183 event_data_len, 184 event_data); 185 } 186 break; 187 188 case WLAN_VDEV_SM_EV_DOWN_COMPLETE: 189 case WLAN_VDEV_SM_EV_DOWN: 190 case WLAN_VDEV_SM_EV_START_REQ_FAIL: 191 /* already in down state, notify DOWN command is completed */ 192 /* NOTE: Keep this function call always at the end, to allow 193 * connection restart from this event 194 */ 195 mlme_vdev_notify_down_complete(vdev_mlme, event_data_len, 196 event_data); 197 mlme_vdev_down_cmpl_notify_mlo_mgr(vdev_mlme); 198 status = true; 199 break; 200 case WLAN_VDEV_SM_EV_ROAM: 201 /** 202 * Legacy to MLO roaming: The link vdev would be in INIT state 203 * as the previous connection was a legacy connection. 204 * Move the vdev state from INIT to UP up on receiving roam 205 * sync from firmware. The caller shall make sure the ROAM 206 * event is sent on right vdev. It's not expected to receive 207 * WLAN_VDEV_SM_EV_ROAM event on station vdev. 208 */ 209 if (wlan_vdev_mlme_is_mlo_link_vdev(vdev_mlme->vdev)) { 210 mlme_vdev_sm_transition_to(vdev_mlme, WLAN_VDEV_S_UP); 211 mlme_vdev_sm_deliver_event(vdev_mlme, event, 212 event_data_len, event_data); 213 status = true; 214 } else { 215 status = false; 216 } 217 break; 218 219 default: 220 status = false; 221 break; 222 } 223 224 return status; 225 } 226 227 /** 228 * mlme_vdev_state_start_entry() - Entry API for Start state 229 * @ctx: VDEV MLME object 230 * 231 * API to perform operations on moving to START state 232 * 233 * Return: void 234 */ 235 static void mlme_vdev_state_start_entry(void *ctx) 236 { 237 struct vdev_mlme_obj *vdev_mlme = (struct vdev_mlme_obj *)ctx; 238 239 mlme_vdev_sm_state_update(vdev_mlme, WLAN_VDEV_S_START, 240 WLAN_VDEV_SS_IDLE); 241 } 242 243 /** 244 * mlme_vdev_state_start_exit() - Exit API for Start state 245 * @ctx: VDEV MLME object 246 * 247 * API to perform operations on moving out of START state 248 * 249 * Return: void 250 */ 251 static void mlme_vdev_state_start_exit(void *ctx) 252 { 253 /* NONE */ 254 } 255 256 /** 257 * mlme_vdev_state_start_event() - Start State event handler 258 * @ctx: VDEV MLME object 259 * 260 * API to handle events in START state 261 * 262 * Return: SUCCESS: on handling event 263 * FAILURE: on ignoring the event 264 */ 265 static bool mlme_vdev_state_start_event(void *ctx, uint16_t event, 266 uint16_t event_data_len, 267 void *event_data) 268 { 269 struct vdev_mlme_obj *vdev_mlme = (struct vdev_mlme_obj *)ctx; 270 bool status; 271 272 switch (event) { 273 case WLAN_VDEV_SM_EV_START_REQ: 274 mlme_vdev_sm_transition_to(vdev_mlme, 275 WLAN_VDEV_SS_START_START_PROGRESS); 276 mlme_vdev_sm_deliver_event(vdev_mlme, event, event_data_len, 277 event_data); 278 status = true; 279 break; 280 281 case WLAN_VDEV_SM_EV_RESTART_REQ: 282 case WLAN_VDEV_SM_EV_RADAR_DETECTED: 283 mlme_vdev_sm_transition_to(vdev_mlme, 284 WLAN_VDEV_SS_START_RESTART_PROGRESS); 285 mlme_vdev_sm_deliver_event(vdev_mlme, event, event_data_len, 286 event_data); 287 status = true; 288 break; 289 290 case WLAN_VDEV_SM_EV_STA_CONN_START: 291 mlme_vdev_sm_transition_to(vdev_mlme, 292 WLAN_VDEV_SS_START_CONN_PROGRESS); 293 mlme_vdev_sm_deliver_event(vdev_mlme, event, 294 event_data_len, event_data); 295 status = true; 296 break; 297 298 default: 299 status = false; 300 break; 301 } 302 303 return status; 304 } 305 306 /** 307 * mlme_vdev_state_dfs_cac_wait_entry() - Entry API for DFS CAC WAIT state 308 * @ctx: VDEV MLME object 309 * 310 * API to perform operations on moving to DFS CAC WAIT state 311 * 312 * Return: void 313 */ 314 static void mlme_vdev_state_dfs_cac_wait_entry(void *ctx) 315 { 316 struct vdev_mlme_obj *vdev_mlme = (struct vdev_mlme_obj *)ctx; 317 318 mlme_vdev_sm_state_update(vdev_mlme, WLAN_VDEV_S_DFS_CAC_WAIT, 319 WLAN_VDEV_SS_IDLE); 320 } 321 322 /** 323 * mlme_vdev_state_dfs_cac_wait_exit() - Exit API for DFS CAC WAIT state 324 * @ctx: VDEV MLME object 325 * 326 * API to perform operations on moving out of DFS CAC WAIT state 327 * 328 * Return: void 329 */ 330 static void mlme_vdev_state_dfs_cac_wait_exit(void *ctx) 331 { 332 /* NONE */ 333 } 334 335 /** 336 * mlme_vdev_state_dfs_cac_wait_event() - DFS CAC WAIT State event handler 337 * @ctx: VDEV MLME object 338 * 339 * API to handle events in DFS CAC WAIT state 340 * 341 * Return: SUCCESS: on handling event 342 * FAILURE: on ignoring the event 343 */ 344 static bool mlme_vdev_state_dfs_cac_wait_event(void *ctx, uint16_t event, 345 uint16_t event_data_len, 346 void *event_data) 347 { 348 struct vdev_mlme_obj *vdev_mlme = (struct vdev_mlme_obj *)ctx; 349 enum QDF_OPMODE mode; 350 struct wlan_objmgr_vdev *vdev; 351 bool status; 352 353 vdev = vdev_mlme->vdev; 354 355 mode = wlan_vdev_mlme_get_opmode(vdev); 356 357 switch (event) { 358 case WLAN_VDEV_SM_EV_DFS_CAC_WAIT: 359 /* Notify MLME about CAC wait state, MLME can perform 360 * unblocking of some commands 361 */ 362 mlme_vdev_dfs_cac_wait_notify(vdev_mlme); 363 /* DFS timer should have started already, then only this event 364 * could have been triggered 365 */ 366 status = true; 367 break; 368 369 case WLAN_VDEV_SM_EV_DOWN: 370 /* stop the CAC timer, then notify state machine */ 371 mlme_vdev_dfs_cac_timer_stop(vdev_mlme, event_data_len, 372 event_data); 373 mlme_vdev_sm_transition_to(vdev_mlme, WLAN_VDEV_S_STOP); 374 mlme_vdev_sm_deliver_event(vdev_mlme, WLAN_VDEV_SM_EV_STOP_REQ, 375 event_data_len, event_data); 376 status = true; 377 break; 378 379 case WLAN_VDEV_SM_EV_RADAR_DETECTED: 380 /* the random channel should have been selected, before issuing 381 * this event 382 */ 383 mlme_vdev_sm_transition_to(vdev_mlme, WLAN_VDEV_S_START); 384 mlme_vdev_sm_deliver_event(vdev_mlme, 385 WLAN_VDEV_SM_EV_RESTART_REQ, 386 event_data_len, event_data); 387 status = true; 388 break; 389 390 case WLAN_VDEV_SM_EV_DFS_CAC_COMPLETED: 391 if (mode == QDF_STA_MODE) { 392 mlme_vdev_sm_transition_to(vdev_mlme, 393 WLAN_VDEV_S_START); 394 mlme_vdev_sm_deliver_event(vdev_mlme, 395 WLAN_VDEV_SM_EV_STA_CONN_START, 396 event_data_len, event_data); 397 } else { 398 mlme_vdev_sm_transition_to(vdev_mlme, WLAN_VDEV_S_UP); 399 mlme_vdev_sm_deliver_event(vdev_mlme, 400 WLAN_VDEV_SM_EV_START_SUCCESS, 401 event_data_len, event_data); 402 } 403 status = true; 404 break; 405 406 default: 407 status = false; 408 break; 409 } 410 411 return status; 412 } 413 414 /** 415 * mlme_vdev_state_up_entry() - Entry API for UP state 416 * @ctx: VDEV MLME object 417 * 418 * API to perform operations on moving to UP state 419 * 420 * Return: void 421 */ 422 static void mlme_vdev_state_up_entry(void *ctx) 423 { 424 struct vdev_mlme_obj *vdev_mlme = (struct vdev_mlme_obj *)ctx; 425 426 mlme_vdev_sm_state_update(vdev_mlme, WLAN_VDEV_S_UP, 427 WLAN_VDEV_SS_IDLE); 428 } 429 430 /** 431 * mlme_vdev_state_up_exit() - Exit API for UP state 432 * @ctx: VDEV MLME object 433 * 434 * API to perform operations on moving out of UP state 435 * 436 * Return: void 437 */ 438 static void mlme_vdev_state_up_exit(void *ctx) 439 { 440 /* NONE */ 441 } 442 443 /** 444 * mlme_vdev_state_up_event() - UP State event handler 445 * @ctx: VDEV MLME object 446 * 447 * API to handle events in UP state 448 * 449 * Return: SUCCESS: on handling event 450 * FAILURE: on ignoring the event 451 */ 452 static bool mlme_vdev_state_up_event(void *ctx, uint16_t event, 453 uint16_t event_data_len, void *event_data) 454 { 455 struct vdev_mlme_obj *vdev_mlme = (struct vdev_mlme_obj *)ctx; 456 enum QDF_OPMODE mode; 457 struct wlan_objmgr_vdev *vdev; 458 bool status; 459 460 vdev = vdev_mlme->vdev; 461 mode = wlan_vdev_mlme_get_opmode(vdev); 462 463 switch (event) { 464 case WLAN_VDEV_SM_EV_START_SUCCESS: 465 if (wlan_vdev_mlme_is_mlo_ap(vdev)) 466 mlme_vdev_sm_transition_to(vdev_mlme, 467 WLAN_VDEV_SS_MLO_SYNC_WAIT); 468 else 469 mlme_vdev_sm_transition_to(vdev_mlme, 470 WLAN_VDEV_SS_UP_ACTIVE); 471 mlme_vdev_sm_deliver_event(vdev_mlme, event, 472 event_data_len, event_data); 473 status = true; 474 break; 475 476 /** 477 * Channel switch disabled case, then tansition to up state 478 * and deliver EV_UP_HOST_RESTART, hand it in up state and 479 * move to up active state 480 */ 481 case WLAN_VDEV_SM_EV_UP_HOST_RESTART: 482 mlme_vdev_sm_transition_to(vdev_mlme, 483 WLAN_VDEV_SS_UP_ACTIVE); 484 mlme_vdev_sm_deliver_event(vdev_mlme, event, 485 event_data_len, event_data); 486 status = true; 487 break; 488 489 case WLAN_VDEV_SM_EV_ROAM: 490 /** 491 * Legacy to MLO roaming: 492 * Move the vdev state to substate UP active on receiving roam 493 * event. The caller shall make sure the ROAM 494 * event is sent on right vdev. It's not expected to receive 495 * WLAN_VDEV_SM_EV_ROAM event on station vdev. 496 */ 497 if (wlan_vdev_mlme_is_mlo_link_vdev(vdev_mlme->vdev)) { 498 mlme_vdev_sm_transition_to(vdev_mlme, 499 WLAN_VDEV_SS_UP_ACTIVE); 500 mlme_vdev_sm_deliver_event(vdev_mlme, event, 501 event_data_len, event_data); 502 status = true; 503 } else { 504 status = false; 505 } 506 break; 507 508 default: 509 status = false; 510 break; 511 } 512 513 return status; 514 } 515 516 /** 517 * mlme_vdev_state_suspend_entry() - Entry API for Suspend state 518 * @ctx: VDEV MLME object 519 * 520 * API to perform operations on moving to SUSPEND state 521 * 522 * Return: void 523 */ 524 static void mlme_vdev_state_suspend_entry(void *ctx) 525 { 526 struct vdev_mlme_obj *vdev_mlme = (struct vdev_mlme_obj *)ctx; 527 528 mlme_vdev_sm_state_update(vdev_mlme, WLAN_VDEV_S_SUSPEND, 529 WLAN_VDEV_SS_IDLE); 530 } 531 532 /** 533 * mlme_vdev_state_suspend_exit() - Exit API for Suspend state 534 * @ctx: VDEV MLME object 535 * 536 * API to perform operations on moving out of SUSPEND state 537 * 538 * Return: void 539 */ 540 static void mlme_vdev_state_suspend_exit(void *ctx) 541 { 542 /* NONE */ 543 } 544 545 /** 546 * mlme_vdev_state_suspend_event() - Suspend State event handler 547 * @ctx: VDEV MLME object 548 * 549 * API to handle events in SUSPEND state 550 * 551 * Return: SUCCESS: on handling event 552 * FAILURE: on ignoring the event 553 */ 554 static bool mlme_vdev_state_suspend_event(void *ctx, uint16_t event, 555 uint16_t event_data_len, 556 void *event_data) 557 { 558 struct vdev_mlme_obj *vdev_mlme = (struct vdev_mlme_obj *)ctx; 559 bool status; 560 561 switch (event) { 562 case WLAN_VDEV_SM_EV_DOWN: 563 case WLAN_VDEV_SM_EV_RESTART_REQ_FAIL: 564 mlme_vdev_sm_transition_to(vdev_mlme, 565 WLAN_VDEV_SS_SUSPEND_SUSPEND_DOWN); 566 mlme_vdev_sm_deliver_event(vdev_mlme, event, 567 event_data_len, event_data); 568 status = true; 569 break; 570 571 case WLAN_VDEV_SM_EV_SUSPEND_RESTART: 572 mlme_vdev_sm_transition_to(vdev_mlme, 573 WLAN_VDEV_SS_SUSPEND_SUSPEND_RESTART); 574 mlme_vdev_sm_deliver_event(vdev_mlme, event, 575 event_data_len, event_data); 576 status = true; 577 break; 578 579 case WLAN_VDEV_SM_EV_HOST_RESTART: 580 mlme_vdev_sm_transition_to(vdev_mlme, 581 WLAN_VDEV_SS_SUSPEND_HOST_RESTART); 582 mlme_vdev_sm_deliver_event(vdev_mlme, event, 583 event_data_len, event_data); 584 status = true; 585 break; 586 587 case WLAN_VDEV_SM_EV_CSA_RESTART: 588 mlme_vdev_sm_transition_to(vdev_mlme, 589 WLAN_VDEV_SS_SUSPEND_CSA_RESTART); 590 mlme_vdev_sm_deliver_event(vdev_mlme, event, 591 event_data_len, event_data); 592 status = true; 593 break; 594 595 case WLAN_VDEV_SM_EV_UP_FAIL: 596 mlme_vdev_sm_transition_to(vdev_mlme, 597 WLAN_VDEV_SS_SUSPEND_SUSPEND_DOWN); 598 mlme_vdev_sm_deliver_event(vdev_mlme, WLAN_VDEV_SM_EV_DOWN, 599 event_data_len, event_data); 600 status = true; 601 break; 602 603 default: 604 status = false; 605 break; 606 } 607 608 return status; 609 } 610 611 /** 612 * mlme_vdev_state_stop_entry() - Entry API for Stop state 613 * @ctx: VDEV MLME object 614 * 615 * API to perform operations on moving to STOP state 616 * 617 * Return: void 618 */ 619 static void mlme_vdev_state_stop_entry(void *ctx) 620 { 621 struct vdev_mlme_obj *vdev_mlme = (struct vdev_mlme_obj *) ctx; 622 623 mlme_vdev_sm_state_update(vdev_mlme, WLAN_VDEV_S_STOP, 624 WLAN_VDEV_SS_IDLE); 625 } 626 627 /** 628 * mlme_vdev_state_stop_exit() - Exit API for Stop state 629 * @ctx: VDEV MLME object 630 * 631 * API to perform operations on moving out of STOP state 632 * 633 * Return: void 634 */ 635 static void mlme_vdev_state_stop_exit(void *ctx) 636 { 637 /* NONE */ 638 } 639 640 /** 641 * mlme_vdev_state_stop_event() - Stop State event handler 642 * @ctx: VDEV MLME object 643 * 644 * API to handle events in STOP state 645 * 646 * Return: SUCCESS: on handling event 647 * FAILURE: on ignoring the event 648 */ 649 static bool mlme_vdev_state_stop_event(void *ctx, uint16_t event, 650 uint16_t event_data_len, 651 void *event_data) 652 { 653 QDF_BUG(0); 654 return false; 655 } 656 657 /** 658 * mlme_vdev_subst_start_start_progress_entry() - Entry API for Start Progress 659 * sub state 660 * @ctx: VDEV MLME object 661 * 662 * API to perform operations on moving to START-PROGRESS substate 663 * 664 * Return: void 665 */ 666 static void mlme_vdev_subst_start_start_progress_entry(void *ctx) 667 { 668 struct vdev_mlme_obj *vdev_mlme = (struct vdev_mlme_obj *)ctx; 669 struct wlan_objmgr_vdev *vdev; 670 671 vdev = vdev_mlme->vdev; 672 673 if (wlan_vdev_mlme_get_state(vdev) != WLAN_VDEV_S_START) 674 QDF_BUG(0); 675 676 mlme_vdev_set_substate(vdev, WLAN_VDEV_SS_START_START_PROGRESS); 677 } 678 679 /** 680 * mlme_vdev_subst_start_start_progress_exit() - Exit API for Start Progress 681 * sub state 682 * @ctx: VDEV MLME object 683 * 684 * API to perform operations on moving out of START-PROGRESS substate 685 * 686 * Return: void 687 */ 688 static void mlme_vdev_subst_start_start_progress_exit(void *ctx) 689 { 690 /* NONE */ 691 } 692 693 /** 694 * mlme_vdev_subst_start_start_progress_event() - Event handler API for Start 695 * Progress substate 696 * @ctx: VDEV MLME object 697 * 698 * API to handle events in START-PROGRESS substate 699 * 700 * Return: SUCCESS: on handling event 701 * FAILURE: on ignoring the event 702 */ 703 static bool mlme_vdev_subst_start_start_progress_event(void *ctx, 704 uint16_t event, uint16_t event_data_len, void *event_data) 705 { 706 struct vdev_mlme_obj *vdev_mlme = (struct vdev_mlme_obj *)ctx; 707 struct wlan_objmgr_vdev *vdev; 708 bool status; 709 710 vdev = vdev_mlme->vdev; 711 712 switch (event) { 713 case WLAN_VDEV_SM_EV_START_REQ: 714 /* send vdev start req command to FW */ 715 mlme_vdev_start_send(vdev_mlme, event_data_len, event_data); 716 status = true; 717 break; 718 /* While waiting for START response, move to RESTART_PROGRESS, 719 * wait for START response to send RESTART req */ 720 case WLAN_VDEV_SM_EV_RADAR_DETECTED: 721 mlme_vdev_sm_transition_to(vdev_mlme, 722 WLAN_VDEV_SS_START_RESTART_PROGRESS); 723 status = true; 724 break; 725 case WLAN_VDEV_SM_EV_START_RESP: 726 case WLAN_VDEV_SM_EV_RESTART_RESP: 727 mlme_vdev_sm_transition_to(vdev_mlme, 728 WLAN_VDEV_SS_START_CONN_PROGRESS); 729 mlme_vdev_sm_deliver_event(vdev_mlme, 730 WLAN_VDEV_SM_EV_CONN_PROGRESS, 731 event_data_len, event_data); 732 status = true; 733 break; 734 735 case WLAN_VDEV_SM_EV_START_REQ_FAIL: 736 mlme_vdev_start_req_failed(vdev_mlme, 737 event_data_len, event_data); 738 mlme_vdev_sm_transition_to(vdev_mlme, WLAN_VDEV_S_INIT); 739 mlme_vdev_sm_deliver_event(vdev_mlme, event, 740 event_data_len, event_data); 741 status = true; 742 break; 743 744 case WLAN_VDEV_SM_EV_DOWN: 745 mlme_vdev_sm_transition_to(vdev_mlme, 746 WLAN_VDEV_SS_START_DISCONN_PROGRESS); 747 /* block start request, if it is pending */ 748 mlme_vdev_stop_start_send(vdev_mlme, START_REQ, 749 event_data_len, event_data); 750 status = true; 751 break; 752 753 default: 754 status = false; 755 break; 756 } 757 758 return status; 759 } 760 761 /** 762 * mlme_vdev_subst_start_restart_progress_entry() - Entry API for Restart 763 * progress sub state 764 * @ctx: VDEV MLME object 765 * 766 * API to perform operations on moving to RESTART-PROGRESS substate 767 * 768 * Return: void 769 */ 770 static void mlme_vdev_subst_start_restart_progress_entry(void *ctx) 771 { 772 struct vdev_mlme_obj *vdev_mlme = (struct vdev_mlme_obj *)ctx; 773 struct wlan_objmgr_vdev *vdev; 774 775 vdev = vdev_mlme->vdev; 776 777 if (wlan_vdev_mlme_get_state(vdev) != WLAN_VDEV_S_START) 778 QDF_BUG(0); 779 780 mlme_vdev_set_substate(vdev, WLAN_VDEV_SS_START_RESTART_PROGRESS); 781 } 782 783 /** 784 * mlme_vdev_subst_start_restart_progress_exit() - Exit API for Restart Progress 785 * sub state 786 * @ctx: VDEV MLME object 787 * 788 * API to perform operations on moving out of RESTART-PROGRESS substate 789 * 790 * Return: void 791 */ 792 static void mlme_vdev_subst_start_restart_progress_exit(void *ctx) 793 { 794 /* NONE */ 795 } 796 797 /** 798 * mlme_vdev_subst_start_restart_progress_event() - Event handler API for 799 * Restart Progress substate 800 * @ctx: VDEV MLME object 801 * 802 * API to handle events in RESTART-PROGRESS substate 803 * 804 * Return: SUCCESS: on handling event 805 * FAILURE: on ignoring the event 806 */ 807 static bool mlme_vdev_subst_start_restart_progress_event(void *ctx, 808 uint16_t event, uint16_t event_data_len, void *event_data) 809 { 810 struct vdev_mlme_obj *vdev_mlme = (struct vdev_mlme_obj *)ctx; 811 struct wlan_objmgr_vdev *vdev; 812 bool status; 813 814 vdev = vdev_mlme->vdev; 815 816 switch (event) { 817 case WLAN_VDEV_SM_EV_RESTART_REQ: 818 /* If Start resp is pending, send restart after start response */ 819 case WLAN_VDEV_SM_EV_START_RESP: 820 /* send vdev restart req command to FW */ 821 mlme_vdev_restart_send(vdev_mlme, event_data_len, event_data); 822 status = true; 823 break; 824 case WLAN_VDEV_SM_EV_RESTART_RESP: 825 mlme_vdev_sm_transition_to(vdev_mlme, 826 WLAN_VDEV_SS_START_CONN_PROGRESS); 827 mlme_vdev_sm_deliver_event(vdev_mlme, 828 WLAN_VDEV_SM_EV_CONN_PROGRESS, 829 event_data_len, event_data); 830 status = true; 831 break; 832 833 case WLAN_VDEV_SM_EV_RESTART_REQ_FAIL: 834 mlme_vdev_sm_transition_to(vdev_mlme, WLAN_VDEV_S_SUSPEND); 835 mlme_vdev_sm_deliver_event(vdev_mlme, event, 836 event_data_len, event_data); 837 status = true; 838 break; 839 840 case WLAN_VDEV_SM_EV_DOWN: 841 mlme_vdev_sm_transition_to(vdev_mlme, 842 WLAN_VDEV_SS_START_DISCONN_PROGRESS); 843 /* block restart request, if it is pending */ 844 mlme_vdev_stop_start_send(vdev_mlme, RESTART_REQ, 845 event_data_len, event_data); 846 status = true; 847 break; 848 849 case WLAN_VDEV_SM_EV_RADAR_DETECTED: 850 /* It is complicated to handle RADAR detected in this substate, 851 * as vdev updates des channels as bss channel on response, 852 * it would be easily handled, if it is deferred by DFS module 853 */ 854 QDF_BUG(0); 855 status = true; 856 break; 857 858 default: 859 status = false; 860 break; 861 } 862 863 return status; 864 } 865 866 /** 867 * mlme_vdev_subst_start_conn_progress_entry() - Entry API for Conn. Progress 868 * sub state 869 * @ctx: VDEV MLME object 870 * 871 * API to perform operations on moving to CONN-PROGRESS substate 872 * 873 * Return: void 874 */ 875 static void mlme_vdev_subst_start_conn_progress_entry(void *ctx) 876 { 877 struct vdev_mlme_obj *vdev_mlme = (struct vdev_mlme_obj *)ctx; 878 struct wlan_objmgr_vdev *vdev; 879 880 vdev = vdev_mlme->vdev; 881 882 if (wlan_vdev_mlme_get_state(vdev) != WLAN_VDEV_S_START) 883 QDF_BUG(0); 884 885 mlme_vdev_set_substate(vdev, WLAN_VDEV_SS_START_CONN_PROGRESS); 886 } 887 888 /** 889 * mlme_vdev_subst_start_conn_progress_exit() - Exit API for Conn. Progress 890 * sub state 891 * @ctx: VDEV MLME object 892 * 893 * API to perform operations on moving out of CONN-PROGRESS substate 894 * 895 * Return: void 896 */ 897 static void mlme_vdev_subst_start_conn_progress_exit(void *ctx) 898 { 899 struct vdev_mlme_obj *vdev_mlme = (struct vdev_mlme_obj *)ctx; 900 901 mlme_vdev_notify_start_state_exit(vdev_mlme); 902 } 903 904 /** 905 * mlme_vdev_subst_start_conn_progress_event() - Event handler API for Conn. 906 * Progress substate 907 * @ctx: VDEV MLME object 908 * 909 * API to handle events in CONN-PROGRESS substate 910 * 911 * Return: SUCCESS: on handling event 912 * FAILURE: on ignoring the event 913 */ 914 static bool mlme_vdev_subst_start_conn_progress_event(void *ctx, 915 uint16_t event, 916 uint16_t event_data_len, 917 void *event_data) 918 { 919 struct vdev_mlme_obj *vdev_mlme = (struct vdev_mlme_obj *)ctx; 920 enum QDF_OPMODE mode; 921 struct wlan_objmgr_vdev *vdev; 922 bool status; 923 924 vdev = vdev_mlme->vdev; 925 926 mode = wlan_vdev_mlme_get_opmode(vdev); 927 928 switch (event) { 929 case WLAN_VDEV_SM_EV_CONN_PROGRESS: 930 /* This API decides to move to DFS CAC WAIT or UP state, 931 * for station notify connection state machine */ 932 if (mlme_vdev_start_continue(vdev_mlme, event_data_len, 933 event_data) != QDF_STATUS_SUCCESS) 934 mlme_vdev_sm_deliver_event( 935 vdev_mlme, 936 WLAN_VDEV_SM_EV_CONNECTION_FAIL, 937 event_data_len, event_data); 938 else 939 mlme_vdev_start_rsp_notify_mlo_mgr(vdev_mlme); 940 status = true; 941 break; 942 943 case WLAN_VDEV_SM_EV_DFS_CAC_WAIT: 944 mlme_vdev_sm_transition_to(vdev_mlme, WLAN_VDEV_S_DFS_CAC_WAIT); 945 mlme_vdev_sm_deliver_event(vdev_mlme, event, 946 event_data_len, event_data); 947 status = true; 948 break; 949 950 case WLAN_VDEV_SM_EV_START_SUCCESS: 951 mlme_vdev_sm_transition_to(vdev_mlme, WLAN_VDEV_S_UP); 952 mlme_vdev_sm_deliver_event(vdev_mlme, event, 953 event_data_len, event_data); 954 status = true; 955 break; 956 957 case WLAN_VDEV_SM_EV_STA_CONN_START: 958 /* This event triggers station connection, if it is blocked for 959 * CAC WAIT 960 */ 961 if (mode != QDF_STA_MODE) 962 QDF_BUG(0); 963 964 mlme_vdev_sta_conn_start(vdev_mlme, event_data_len, event_data); 965 status = true; 966 break; 967 968 case WLAN_VDEV_SM_EV_RADAR_DETECTED: 969 if (mode != QDF_STA_MODE) 970 QDF_BUG(0); 971 972 status = true; 973 break; 974 975 case WLAN_VDEV_SM_EV_DOWN: 976 case WLAN_VDEV_SM_EV_CONNECTION_FAIL: 977 mlme_vdev_sm_transition_to(vdev_mlme, 978 WLAN_VDEV_SS_START_DISCONN_PROGRESS); 979 mlme_vdev_sm_deliver_event(vdev_mlme, event, 980 event_data_len, event_data); 981 status = true; 982 break; 983 984 default: 985 status = false; 986 break; 987 } 988 989 return status; 990 } 991 992 /** 993 * mlme_vdev_subst_start_disconn_progress_entry() - Entry API for Disconn 994 * progress sub state 995 * @ctx: VDEV MLME object 996 * 997 * API to perform operations on moving to DISCONN-PROGRESS substate 998 * 999 * Return: SUCCESS: on handling event 1000 * FAILURE: on ignoring the event 1001 */ 1002 static void mlme_vdev_subst_start_disconn_progress_entry(void *ctx) 1003 { 1004 struct vdev_mlme_obj *vdev_mlme = (struct vdev_mlme_obj *)ctx; 1005 struct wlan_objmgr_vdev *vdev; 1006 1007 vdev = vdev_mlme->vdev; 1008 1009 if (wlan_vdev_mlme_get_state(vdev) != WLAN_VDEV_S_START) 1010 QDF_BUG(0); 1011 1012 mlme_vdev_set_substate(vdev, WLAN_VDEV_SS_START_DISCONN_PROGRESS); 1013 } 1014 1015 /** 1016 * mlme_vdev_subst_start_disconn_progress_exit() - Exit API for Disconn Progress 1017 * sub state 1018 * @ctx: VDEV MLME object 1019 * 1020 * API to perform operations on moving out of DISCONN-PROGRESS substate 1021 * 1022 * Return: void 1023 */ 1024 static void mlme_vdev_subst_start_disconn_progress_exit(void *ctx) 1025 { 1026 /* NONE */ 1027 } 1028 1029 /** 1030 * mlme_vdev_subst_start_disconn_progress_event() - Event handler API for Discon 1031 * Progress substate 1032 * @ctx: VDEV MLME object 1033 * 1034 * API to handle events in DISCONN-PROGRESS substate 1035 * 1036 * Return: SUCCESS: on handling event 1037 * FAILURE: on ignoring the event 1038 */ 1039 static bool mlme_vdev_subst_start_disconn_progress_event(void *ctx, 1040 uint16_t event, uint16_t event_data_len, void *event_data) 1041 { 1042 struct vdev_mlme_obj *vdev_mlme = (struct vdev_mlme_obj *)ctx; 1043 bool status; 1044 1045 switch (event) { 1046 case WLAN_VDEV_SM_EV_START_RESP: 1047 /* clean up, if any needs to be cleaned up */ 1048 case WLAN_VDEV_SM_EV_CONNECTION_FAIL: 1049 mlme_vdev_sm_transition_to(vdev_mlme, WLAN_VDEV_S_STOP); 1050 mlme_vdev_sm_deliver_event(vdev_mlme, WLAN_VDEV_SM_EV_STOP_REQ, 1051 event_data_len, event_data); 1052 status = true; 1053 break; 1054 1055 case WLAN_VDEV_SM_EV_RESTART_RESP: 1056 case WLAN_VDEV_SM_EV_RESTART_REQ_FAIL: 1057 mlme_vdev_sm_transition_to(vdev_mlme, WLAN_VDEV_S_SUSPEND); 1058 mlme_vdev_sm_deliver_event(vdev_mlme, WLAN_VDEV_SM_EV_DOWN, 1059 event_data_len, event_data); 1060 status = true; 1061 break; 1062 1063 case WLAN_VDEV_SM_EV_START_REQ_FAIL: 1064 mlme_vdev_sm_transition_to(vdev_mlme, WLAN_VDEV_S_INIT); 1065 mlme_vdev_sm_deliver_event(vdev_mlme, event, 1066 event_data_len, event_data); 1067 status = true; 1068 break; 1069 1070 case WLAN_VDEV_SM_EV_DOWN: 1071 mlme_vdev_sta_disconn_start(vdev_mlme, event_data_len, 1072 event_data); 1073 status = true; 1074 break; 1075 default: 1076 status = false; 1077 break; 1078 } 1079 1080 return status; 1081 } 1082 1083 /** 1084 * mlme_vdev_subst_suspend_suspend_down_entry() - Entry API for Suspend down 1085 * sub state 1086 * @ctx: VDEV MLME object 1087 * 1088 * API to perform operations on moving to SUSPEND-DOWN substate 1089 * 1090 * Return: void 1091 */ 1092 static void mlme_vdev_subst_suspend_suspend_down_entry(void *ctx) 1093 { 1094 struct vdev_mlme_obj *vdev_mlme = (struct vdev_mlme_obj *)ctx; 1095 struct wlan_objmgr_vdev *vdev; 1096 1097 vdev = vdev_mlme->vdev; 1098 1099 if (wlan_vdev_mlme_get_state(vdev) != WLAN_VDEV_S_SUSPEND) 1100 QDF_BUG(0); 1101 1102 mlme_vdev_set_substate(vdev, WLAN_VDEV_SS_SUSPEND_SUSPEND_DOWN); 1103 } 1104 1105 /** 1106 * mlme_vdev_subst_suspend_suspend_down_exit() - Exit API for Suspend down 1107 * sub state 1108 * @ctx: VDEV MLME object 1109 * 1110 * API to perform operations on moving out of SUSPEND-DOWN substate 1111 * 1112 * Return: void 1113 */ 1114 static void mlme_vdev_subst_suspend_suspend_down_exit(void *ctx) 1115 { 1116 /* NONE */ 1117 } 1118 1119 /** 1120 * mlme_vdev_subst_suspend_suspend_down_event() - Event handler API for Suspend 1121 * down substate 1122 * @ctx: VDEV MLME object 1123 * 1124 * API to handle events in SUSPEND-DOWN substate 1125 * 1126 * Return: SUCCESS: on handling event 1127 * FAILURE: on ignoring the event 1128 */ 1129 static bool mlme_vdev_subst_suspend_suspend_down_event(void *ctx, 1130 uint16_t event, uint16_t event_data_len, void *event_data) 1131 { 1132 struct vdev_mlme_obj *vdev_mlme = (struct vdev_mlme_obj *)ctx; 1133 bool status; 1134 1135 switch (event) { 1136 case WLAN_VDEV_SM_EV_DOWN: 1137 case WLAN_VDEV_SM_EV_RESTART_REQ_FAIL: 1138 mlme_vdev_disconnect_peers(vdev_mlme, 1139 event_data_len, event_data); 1140 status = true; 1141 break; 1142 1143 case WLAN_VDEV_SM_EV_DISCONNECT_COMPLETE: 1144 /* clean up, if any needs to be cleaned up */ 1145 mlme_vdev_sm_transition_to(vdev_mlme, WLAN_VDEV_S_STOP); 1146 mlme_vdev_sm_deliver_event(vdev_mlme, WLAN_VDEV_SM_EV_STOP_REQ, 1147 event_data_len, event_data); 1148 status = true; 1149 break; 1150 1151 default: 1152 status = false; 1153 break; 1154 } 1155 1156 return status; 1157 } 1158 1159 /** 1160 * mlme_vdev_subst_suspend_suspend_restart_entry() - Entry API for Suspend 1161 * restart substate 1162 * @ctx: VDEV MLME object 1163 * 1164 * API to perform operations on moving to SUSPEND-RESTART substate 1165 * 1166 * Return: void 1167 */ 1168 static void mlme_vdev_subst_suspend_suspend_restart_entry(void *ctx) 1169 { 1170 struct vdev_mlme_obj *vdev_mlme = (struct vdev_mlme_obj *)ctx; 1171 struct wlan_objmgr_vdev *vdev; 1172 1173 vdev = vdev_mlme->vdev; 1174 1175 if (wlan_vdev_mlme_get_state(vdev) != WLAN_VDEV_S_SUSPEND) 1176 QDF_BUG(0); 1177 1178 mlme_vdev_set_substate(vdev, WLAN_VDEV_SS_SUSPEND_SUSPEND_RESTART); 1179 } 1180 1181 /** 1182 * mlme_vdev_subst_suspend_suspend_restart_exit() - Exit API for Suspend restart 1183 * sub state 1184 * @ctx: VDEV MLME object 1185 * 1186 * API to perform operations on moving out of SUSPEND-RESTART substate 1187 * 1188 * Return: void 1189 */ 1190 static void mlme_vdev_subst_suspend_suspend_restart_exit(void *ctx) 1191 { 1192 /* NONE */ 1193 } 1194 1195 /** 1196 * mlme_vdev_subst_suspend_suspend_restart_event() - Event handler API for 1197 * Suspend restart substate 1198 * @ctx: VDEV MLME object 1199 * 1200 * API to handle events in SUSPEND-RESTART substate 1201 * 1202 * Return: SUCCESS: on handling event 1203 * FAILURE: on ignoring the event 1204 */ 1205 static bool mlme_vdev_subst_suspend_suspend_restart_event(void *ctx, 1206 uint16_t event, uint16_t event_data_len, void *event_data) 1207 { 1208 struct vdev_mlme_obj *vdev_mlme = (struct vdev_mlme_obj *)ctx; 1209 bool status; 1210 1211 switch (event) { 1212 case WLAN_VDEV_SM_EV_SUSPEND_RESTART: 1213 mlme_vdev_disconnect_peers(vdev_mlme, 1214 event_data_len, event_data); 1215 status = true; 1216 break; 1217 1218 case WLAN_VDEV_SM_EV_DISCONNECT_COMPLETE: 1219 /* clean up, if any needs to be cleaned up */ 1220 mlme_vdev_sm_transition_to(vdev_mlme, WLAN_VDEV_S_START); 1221 mlme_vdev_sm_deliver_event(vdev_mlme, 1222 WLAN_VDEV_SM_EV_RESTART_REQ, 1223 event_data_len, event_data); 1224 status = true; 1225 break; 1226 1227 case WLAN_VDEV_SM_EV_DOWN: 1228 mlme_vdev_sm_transition_to(vdev_mlme, 1229 WLAN_VDEV_SS_SUSPEND_SUSPEND_DOWN); 1230 status = true; 1231 break; 1232 1233 case WLAN_VDEV_SM_EV_RADAR_DETECTED: 1234 mlme_vdev_sm_transition_to(vdev_mlme, 1235 WLAN_VDEV_SS_SUSPEND_CSA_RESTART); 1236 mlme_vdev_sm_deliver_event(vdev_mlme, 1237 WLAN_VDEV_SM_EV_CSA_RESTART, 1238 event_data_len, event_data); 1239 status = true; 1240 break; 1241 1242 default: 1243 status = false; 1244 break; 1245 } 1246 1247 return status; 1248 } 1249 1250 /** 1251 * mlme_vdev_subst_suspend_host_restart_entry() - Entry API for Host restart 1252 * substate 1253 * @ctx: VDEV MLME object 1254 * 1255 * API to perform operations on moving to HOST-RESTART substate 1256 * 1257 * Return: void 1258 */ 1259 static void mlme_vdev_subst_suspend_host_restart_entry(void *ctx) 1260 { 1261 struct vdev_mlme_obj *vdev_mlme = (struct vdev_mlme_obj *)ctx; 1262 struct wlan_objmgr_vdev *vdev; 1263 1264 vdev = vdev_mlme->vdev; 1265 1266 if (wlan_vdev_mlme_get_state(vdev) != WLAN_VDEV_S_SUSPEND) 1267 QDF_BUG(0); 1268 1269 mlme_vdev_set_substate(vdev, WLAN_VDEV_SS_SUSPEND_HOST_RESTART); 1270 } 1271 1272 /** 1273 * mlme_vdev_subst_suspend_host_restart_exit() - Exit API for host restart 1274 * sub state 1275 * @ctx: VDEV MLME object 1276 * 1277 * API to perform operations on moving out of HOST-RESTART substate 1278 * 1279 * Return: void 1280 */ 1281 static void mlme_vdev_subst_suspend_host_restart_exit(void *ctx) 1282 { 1283 /* NONE */ 1284 } 1285 1286 /** 1287 * mlme_vdev_subst_suspend_host_restart_entry() - Event handler API for Host 1288 * restart substate 1289 * @ctx: VDEV MLME object 1290 * 1291 * API to handle events in HOST-RESTART substate 1292 * 1293 * Return: void 1294 */ 1295 static bool mlme_vdev_subst_suspend_host_restart_event(void *ctx, 1296 uint16_t event, uint16_t event_data_len, void *event_data) 1297 { 1298 struct vdev_mlme_obj *vdev_mlme = (struct vdev_mlme_obj *)ctx; 1299 bool status; 1300 1301 switch (event) { 1302 case WLAN_VDEV_SM_EV_HOST_RESTART: 1303 mlme_vdev_disconnect_peers(vdev_mlme, 1304 event_data_len, event_data); 1305 status = true; 1306 break; 1307 1308 case WLAN_VDEV_SM_EV_DISCONNECT_COMPLETE: 1309 /* VDEV up command need not be sent */ 1310 mlme_vdev_sm_transition_to(vdev_mlme, WLAN_VDEV_S_UP); 1311 mlme_vdev_sm_deliver_event(vdev_mlme, 1312 WLAN_VDEV_SM_EV_UP_HOST_RESTART, 1313 event_data_len, event_data); 1314 status = true; 1315 break; 1316 1317 case WLAN_VDEV_SM_EV_DOWN: 1318 mlme_vdev_sm_transition_to(vdev_mlme, 1319 WLAN_VDEV_SS_SUSPEND_SUSPEND_DOWN); 1320 status = true; 1321 break; 1322 1323 case WLAN_VDEV_SM_EV_RADAR_DETECTED: 1324 mlme_vdev_sm_transition_to(vdev_mlme, 1325 WLAN_VDEV_SS_SUSPEND_CSA_RESTART); 1326 mlme_vdev_sm_deliver_event(vdev_mlme, 1327 WLAN_VDEV_SM_EV_CSA_RESTART, 1328 event_data_len, event_data); 1329 status = true; 1330 break; 1331 1332 default: 1333 status = false; 1334 break; 1335 } 1336 1337 return status; 1338 } 1339 1340 /** 1341 * mlme_vdev_subst_suspend_csa_restart_entry() - Entry API for CSA restart 1342 * substate 1343 * @ctx: VDEV MLME object 1344 * 1345 * API to perform operations on moving to CSA-RESTART substate 1346 * 1347 * Return: void 1348 */ 1349 static void mlme_vdev_subst_suspend_csa_restart_entry(void *ctx) 1350 { 1351 struct vdev_mlme_obj *vdev_mlme = (struct vdev_mlme_obj *)ctx; 1352 struct wlan_objmgr_vdev *vdev; 1353 1354 vdev = vdev_mlme->vdev; 1355 1356 if (wlan_vdev_mlme_get_state(vdev) != WLAN_VDEV_S_SUSPEND) 1357 QDF_BUG(0); 1358 1359 mlme_vdev_set_substate(vdev, WLAN_VDEV_SS_SUSPEND_CSA_RESTART); 1360 } 1361 1362 /** 1363 * mlme_vdev_subst_suspend_csa_restart_exit() - Exit API for CSA restart 1364 * sub state 1365 * @ctx: VDEV MLME object 1366 * 1367 * API to perform operations on moving out of CSA-RESTART substate 1368 * 1369 * Return: void 1370 */ 1371 static void mlme_vdev_subst_suspend_csa_restart_exit(void *ctx) 1372 { 1373 /* NONE */ 1374 } 1375 1376 /** 1377 * mlme_vdev_subst_suspend_csa_restart_event() - Event handler API for CSA 1378 * restart substate 1379 * @ctx: VDEV MLME object 1380 * 1381 * API to handle events in CSA-RESTART substate 1382 * 1383 * Return: SUCCESS: on handling event 1384 * FAILURE: on ignoring the event 1385 */ 1386 static bool mlme_vdev_subst_suspend_csa_restart_event(void *ctx, 1387 uint16_t event, uint16_t event_data_len, void *event_data) 1388 { 1389 struct vdev_mlme_obj *vdev_mlme = (struct vdev_mlme_obj *)ctx; 1390 struct wlan_objmgr_psoc *psoc = wlan_vdev_get_psoc(vdev_mlme->vdev); 1391 bool status; 1392 1393 switch (event) { 1394 case WLAN_VDEV_SM_EV_CHAN_SWITCH_DISABLED: 1395 /** 1396 * This event is sent when CSA count becomes 0 without 1397 * change in channel i.e. only Beacon Probe response template 1398 * is updated (CSA / ECSA IE is removed). 1399 */ 1400 mlme_vdev_chan_switch_disable_notify_dfs(vdev_mlme); 1401 mlme_vdev_sm_transition_to(vdev_mlme, WLAN_VDEV_S_UP); 1402 mlme_vdev_sm_deliver_event(vdev_mlme, 1403 WLAN_VDEV_SM_EV_UP_HOST_RESTART, 1404 event_data_len, event_data); 1405 status = true; 1406 break; 1407 case WLAN_VDEV_SM_EV_CSA_RESTART: 1408 mlme_vdev_update_beacon(vdev_mlme, BEACON_CSA, 1409 event_data_len, event_data); 1410 status = true; 1411 break; 1412 case WLAN_VDEV_SM_EV_CSA_COMPLETE: 1413 if ((mlme_vdev_is_newchan_no_cac(vdev_mlme) == 1414 QDF_STATUS_SUCCESS) || 1415 mlme_max_chan_switch_is_set(psoc)) { 1416 mlme_vdev_sm_transition_to(vdev_mlme, 1417 WLAN_VDEV_S_START); 1418 mlme_vdev_sm_deliver_event(vdev_mlme, 1419 WLAN_VDEV_SM_EV_RESTART_REQ, 1420 event_data_len, event_data); 1421 } else { 1422 mlme_vdev_sm_transition_to 1423 (vdev_mlme, 1424 WLAN_VDEV_SS_SUSPEND_SUSPEND_RESTART); 1425 mlme_vdev_sm_deliver_event 1426 (vdev_mlme, WLAN_VDEV_SM_EV_SUSPEND_RESTART, 1427 event_data_len, event_data); 1428 } 1429 status = true; 1430 break; 1431 1432 case WLAN_VDEV_SM_EV_DOWN: 1433 mlme_vdev_sm_transition_to(vdev_mlme, 1434 WLAN_VDEV_SS_SUSPEND_SUSPEND_DOWN); 1435 mlme_vdev_sm_deliver_event(vdev_mlme, event, 1436 event_data_len, event_data); 1437 status = true; 1438 break; 1439 1440 case WLAN_VDEV_SM_EV_RADAR_DETECTED: 1441 /* since channel change is already in progress, 1442 * dfs ignore radar detected event 1443 */ 1444 status = true; 1445 break; 1446 1447 default: 1448 status = false; 1449 break; 1450 } 1451 1452 return status; 1453 } 1454 1455 /** 1456 * mlme_vdev_subst_stop_stop_progress_entry() - Entry API for Stop Progress 1457 * sub state 1458 * @ctx: VDEV MLME object 1459 * 1460 * API to perform operations on moving to STOP-PROGRESS substate 1461 * 1462 * Return: void 1463 */ 1464 static void mlme_vdev_subst_stop_stop_progress_entry(void *ctx) 1465 { 1466 struct vdev_mlme_obj *vdev_mlme = (struct vdev_mlme_obj *) ctx; 1467 struct wlan_objmgr_vdev *vdev; 1468 1469 vdev = vdev_mlme->vdev; 1470 1471 if (wlan_vdev_mlme_get_state(vdev) != WLAN_VDEV_S_STOP) 1472 QDF_BUG(0); 1473 1474 mlme_vdev_set_substate(vdev, WLAN_VDEV_SS_STOP_STOP_PROGRESS); 1475 } 1476 1477 /** 1478 * mlme_vdev_subst_stop_stop_progress_exit() - Exit API for Stop Progress 1479 * sub state 1480 * @ctx: VDEV MLME object 1481 * 1482 * API to perform operations on moving out of STOP-PROGRESS substate 1483 * 1484 * Return: void 1485 */ 1486 static void mlme_vdev_subst_stop_stop_progress_exit(void *ctx) 1487 { 1488 /* NONE */ 1489 } 1490 1491 /** 1492 * mlme_vdev_subst_stop_stop_progress_event() - Event handler API for Stop 1493 * Progress substate 1494 * @ctx: VDEV MLME object 1495 * 1496 * API to handle events in STOP-PROGRESS substate 1497 * 1498 * Return: SUCCESS: on handling event 1499 * FAILURE: on ignoring the event 1500 */ 1501 static bool mlme_vdev_subst_stop_stop_progress_event(void *ctx, 1502 uint16_t event, uint16_t event_data_len, void *event_data) 1503 { 1504 struct vdev_mlme_obj *vdev_mlme = (struct vdev_mlme_obj *)ctx; 1505 bool status; 1506 1507 /* Debug framework is required to hold the events */ 1508 1509 switch (event) { 1510 case WLAN_VDEV_SM_EV_STOP_REQ: 1511 /* send vdev stop command to FW and delete BSS peer*/ 1512 mlme_vdev_stop_send(vdev_mlme, event_data_len, event_data); 1513 status = true; 1514 break; 1515 1516 case WLAN_VDEV_SM_EV_STOP_RESP: 1517 /* Processes stop response, and checks BSS peer delete wait 1518 * is needed 1519 */ 1520 mlme_vdev_stop_continue(vdev_mlme, event_data_len, event_data); 1521 status = true; 1522 break; 1523 1524 /* This event should be given by MLME on stop complete and BSS 1525 * peer delete complete to move forward 1526 */ 1527 case WLAN_VDEV_SM_EV_MLME_DOWN_REQ: 1528 mlme_vdev_sm_transition_to(vdev_mlme, 1529 WLAN_VDEV_SS_STOP_DOWN_PROGRESS); 1530 mlme_vdev_sm_deliver_event(vdev_mlme, 1531 WLAN_VDEV_SM_EV_MLME_DOWN_REQ, 1532 event_data_len, event_data); 1533 status = true; 1534 break; 1535 1536 case WLAN_VDEV_SM_EV_STOP_FAIL: 1537 mlme_vdev_sm_transition_to(vdev_mlme, 1538 WLAN_VDEV_SS_STOP_DOWN_PROGRESS); 1539 mlme_vdev_sm_deliver_event(vdev_mlme, 1540 WLAN_VDEV_SM_EV_MLME_DOWN_REQ, 1541 event_data_len, event_data); 1542 status = true; 1543 break; 1544 1545 default: 1546 status = false; 1547 break; 1548 } 1549 1550 return status; 1551 } 1552 1553 /** 1554 * mlme_vdev_subst_stop_down_progress_entry() - Entry API for Down Progress 1555 * sub state 1556 * @ctx: VDEV MLME object 1557 * 1558 * API to perform operations on moving to DOWN-PROGRESS substate 1559 * 1560 * Return: void 1561 */ 1562 static void mlme_vdev_subst_stop_down_progress_entry(void *ctx) 1563 { 1564 struct vdev_mlme_obj *vdev_mlme = (struct vdev_mlme_obj *)ctx; 1565 struct wlan_objmgr_vdev *vdev; 1566 1567 vdev = vdev_mlme->vdev; 1568 1569 if (wlan_vdev_mlme_get_state(vdev) != WLAN_VDEV_S_STOP) 1570 QDF_BUG(0); 1571 1572 mlme_vdev_set_substate(vdev, WLAN_VDEV_SS_STOP_DOWN_PROGRESS); 1573 } 1574 1575 /** 1576 * mlme_vdev_subst_stop_down_progress_exit() - Exit API for Down Progress 1577 * sub state 1578 * @ctx: VDEV MLME object 1579 * 1580 * API to perform operations on moving out of DOWN-PROGRESS substate 1581 * 1582 * Return: void 1583 */ 1584 static void mlme_vdev_subst_stop_down_progress_exit(void *ctx) 1585 { 1586 /* NONE */ 1587 } 1588 1589 /** 1590 * mlme_vdev_subst_stop_down_progress_event() - Event handler API for Down 1591 * Progress substate 1592 * @ctx: VDEV MLME object 1593 * 1594 * API to handle events in DOWN-PROGRESS substate 1595 * 1596 * Return: SUCCESS: on handling event 1597 * FAILURE: on ignoring the event 1598 */ 1599 static bool mlme_vdev_subst_stop_down_progress_event(void *ctx, 1600 uint16_t event, uint16_t event_data_len, void *event_data) 1601 { 1602 struct vdev_mlme_obj *vdev_mlme = (struct vdev_mlme_obj *)ctx; 1603 bool status; 1604 1605 switch (event) { 1606 case WLAN_VDEV_SM_EV_DOWN: 1607 status = true; 1608 break; 1609 1610 case WLAN_VDEV_SM_EV_MLME_DOWN_REQ: 1611 /* send vdev down command to FW, if send is successful, sends 1612 * DOWN_COMPLETE event 1613 */ 1614 mlme_vdev_down_send(vdev_mlme, event_data_len, event_data); 1615 status = true; 1616 break; 1617 1618 case WLAN_VDEV_SM_EV_DOWN_COMPLETE: 1619 mlme_vdev_sm_transition_to(vdev_mlme, WLAN_VDEV_S_INIT); 1620 mlme_vdev_sm_deliver_event(vdev_mlme, 1621 WLAN_VDEV_SM_EV_DOWN_COMPLETE, 1622 event_data_len, event_data); 1623 status = true; 1624 break; 1625 1626 case WLAN_VDEV_SM_EV_DOWN_FAIL: 1627 mlme_vdev_sm_transition_to(vdev_mlme, WLAN_VDEV_S_INIT); 1628 mlme_vdev_sm_deliver_event(vdev_mlme, 1629 WLAN_VDEV_SM_EV_DOWN_COMPLETE, 1630 event_data_len, event_data); 1631 status = true; 1632 break; 1633 1634 default: 1635 status = false; 1636 break; 1637 } 1638 1639 return status; 1640 } 1641 1642 /** 1643 * mlme_vdev_subst_mlo_sync_wait_entry() - Entry API for mlo sync wait sub state 1644 * @ctx: VDEV MLME object 1645 * 1646 * API to perform operations on moving to MLO-SYNC-WAIT substate 1647 * 1648 * Return: void 1649 */ 1650 static void mlme_vdev_subst_mlo_sync_wait_entry(void *ctx) 1651 { 1652 struct vdev_mlme_obj *vdev_mlme = (struct vdev_mlme_obj *)ctx; 1653 struct wlan_objmgr_vdev *vdev; 1654 1655 vdev = vdev_mlme->vdev; 1656 1657 if (wlan_vdev_mlme_get_state(vdev) != WLAN_VDEV_S_UP) 1658 QDF_BUG(0); 1659 1660 mlme_vdev_set_substate(vdev, WLAN_VDEV_SS_MLO_SYNC_WAIT); 1661 mlme_vdev_notify_mlo_sync_wait_entry(vdev_mlme); 1662 } 1663 1664 /** 1665 * mlme_vdev_subst_mlo_sync_wait_exit() - Exit API for mlo sync wait sub state 1666 * @ctx: VDEV MLME object 1667 * 1668 * API to perform operations on moving out of MLO-SYNC-WAIT substate 1669 * 1670 * Return: void 1671 */ 1672 static void mlme_vdev_subst_mlo_sync_wait_exit(void *ctx) 1673 { 1674 /* NONE */ 1675 } 1676 1677 /** 1678 * mlme_vdev_subst_mlo_sync_wait_event() - Event handler API for mlo sync wait 1679 * substate 1680 * @ctx: VDEV MLME object 1681 * 1682 * API to handle events in MLO-SYNC-WAIT substate 1683 * 1684 * Return: SUCCESS: on handling event 1685 * FAILURE: on ignoring the event 1686 */ 1687 static bool mlme_vdev_subst_mlo_sync_wait_event(void *ctx, uint16_t event, 1688 uint16_t event_data_len, 1689 void *event_data) 1690 { 1691 struct vdev_mlme_obj *vdev_mlme = (struct vdev_mlme_obj *)ctx; 1692 bool status; 1693 1694 switch (event) { 1695 case WLAN_VDEV_SM_EV_START_SUCCESS: 1696 if (mlme_vdev_up_notify_mlo_mgr(vdev_mlme)) 1697 mlme_vdev_sm_deliver_event( 1698 vdev_mlme, 1699 WLAN_VDEV_SM_EV_MLO_SYNC_COMPLETE, 1700 event_data_len, event_data); 1701 status = true; 1702 break; 1703 1704 case WLAN_VDEV_SM_EV_MLO_SYNC_COMPLETE: 1705 mlme_vdev_sm_transition_to(vdev_mlme, WLAN_VDEV_SS_UP_ACTIVE); 1706 mlme_vdev_sm_deliver_event(vdev_mlme, event, 1707 event_data_len, event_data); 1708 status = true; 1709 break; 1710 1711 case WLAN_VDEV_SM_EV_DOWN: 1712 mlme_vdev_sm_transition_to(vdev_mlme, WLAN_VDEV_S_SUSPEND); 1713 mlme_vdev_sm_deliver_event(vdev_mlme, event, 1714 event_data_len, event_data); 1715 status = true; 1716 break; 1717 1718 case WLAN_VDEV_SM_EV_RADAR_DETECTED: 1719 case WLAN_VDEV_SM_EV_CSA_RESTART: 1720 mlme_vdev_sm_transition_to(vdev_mlme, WLAN_VDEV_S_START); 1721 mlme_vdev_sm_deliver_event(vdev_mlme, 1722 WLAN_VDEV_SM_EV_RESTART_REQ, 1723 event_data_len, event_data); 1724 status = true; 1725 break; 1726 1727 default: 1728 status = false; 1729 break; 1730 } 1731 1732 return status; 1733 } 1734 1735 /** 1736 * mlme_vdev_subst_up_active_entry() - Entry API for up active sub state 1737 * @ctx: VDEV MLME object 1738 * 1739 * API to perform operations on moving to UP-ACTIVE substate 1740 * 1741 * Return: void 1742 */ 1743 static void mlme_vdev_subst_up_active_entry(void *ctx) 1744 { 1745 struct vdev_mlme_obj *vdev_mlme = (struct vdev_mlme_obj *)ctx; 1746 struct wlan_objmgr_vdev *vdev; 1747 1748 vdev = vdev_mlme->vdev; 1749 1750 if (wlan_vdev_mlme_get_state(vdev) != WLAN_VDEV_S_UP) 1751 QDF_BUG(0); 1752 1753 mlme_vdev_set_substate(vdev, WLAN_VDEV_SS_UP_ACTIVE); 1754 } 1755 1756 /** 1757 * mlme_vdev_subst_up_active_exit() - Exit API for up active sub state 1758 * @ctx: VDEV MLME object 1759 * 1760 * API to perform operations on moving out of UP-ACTIVE substate 1761 * 1762 * Return: void 1763 */ 1764 static void mlme_vdev_subst_up_active_exit(void *ctx) 1765 { 1766 /* NONE */ 1767 } 1768 1769 /** 1770 * mlme_vdev_subst_up_active_event() - Event handler API for up active substate 1771 * @ctx: VDEV MLME object 1772 * 1773 * API to handle events in UP-ACTIVE substate 1774 * 1775 * Return: SUCCESS: on handling event 1776 * FAILURE: on ignoring the event 1777 */ 1778 static bool mlme_vdev_subst_up_active_event(void *ctx, uint16_t event, 1779 uint16_t event_data_len, 1780 void *event_data) 1781 { 1782 struct vdev_mlme_obj *vdev_mlme = (struct vdev_mlme_obj *)ctx; 1783 enum QDF_OPMODE mode; 1784 struct wlan_objmgr_vdev *vdev; 1785 bool status; 1786 1787 vdev = vdev_mlme->vdev; 1788 mode = wlan_vdev_mlme_get_opmode(vdev); 1789 1790 switch (event) { 1791 case WLAN_VDEV_SM_EV_START_SUCCESS: 1792 if (wlan_vdev_mlme_is_mlo_ap(vdev)) 1793 QDF_BUG(0); 1794 fallthrough; 1795 case WLAN_VDEV_SM_EV_MLO_SYNC_COMPLETE: 1796 mlme_vdev_update_beacon(vdev_mlme, BEACON_INIT, 1797 event_data_len, event_data); 1798 if (mlme_vdev_up_send(vdev_mlme, event_data_len, 1799 event_data) != QDF_STATUS_SUCCESS) { 1800 mlme_vdev_sm_deliver_event(vdev_mlme, 1801 WLAN_VDEV_SM_EV_UP_FAIL, 1802 event_data_len, event_data); 1803 } else { 1804 mlme_vdev_notify_up_complete(vdev_mlme, event_data_len, 1805 event_data); 1806 mlme_vdev_up_active_notify_mlo_mgr(vdev_mlme); 1807 } 1808 status = true; 1809 break; 1810 1811 case WLAN_VDEV_SM_EV_SUSPEND_RESTART: 1812 case WLAN_VDEV_SM_EV_HOST_RESTART: 1813 case WLAN_VDEV_SM_EV_CSA_RESTART: 1814 /* These events are not supported in STA mode */ 1815 if (mode == QDF_STA_MODE) 1816 QDF_BUG(0); 1817 fallthrough; 1818 case WLAN_VDEV_SM_EV_DOWN: 1819 mlme_vdev_sm_transition_to(vdev_mlme, WLAN_VDEV_S_SUSPEND); 1820 mlme_vdev_sm_deliver_event(vdev_mlme, event, 1821 event_data_len, event_data); 1822 status = true; 1823 break; 1824 1825 case WLAN_VDEV_SM_EV_RADAR_DETECTED: 1826 /* These events are not supported in STA mode */ 1827 if (mode == QDF_STA_MODE) 1828 QDF_BUG(0); 1829 mlme_vdev_sm_transition_to(vdev_mlme, WLAN_VDEV_S_SUSPEND); 1830 mlme_vdev_sm_deliver_event(vdev_mlme, 1831 WLAN_VDEV_SM_EV_CSA_RESTART, 1832 event_data_len, event_data); 1833 status = true; 1834 break; 1835 1836 case WLAN_VDEV_SM_EV_UP_HOST_RESTART: 1837 /* Reinit beacon, send template to FW(use ping-pong buffer) */ 1838 mlme_vdev_update_beacon(vdev_mlme, BEACON_UPDATE, 1839 event_data_len, event_data); 1840 fallthrough; 1841 case WLAN_VDEV_SM_EV_START: 1842 /* notify that UP command is completed */ 1843 mlme_vdev_notify_up_complete(vdev_mlme, 1844 event_data_len, event_data); 1845 status = true; 1846 break; 1847 1848 case WLAN_VDEV_SM_EV_FW_VDEV_RESTART: 1849 mlme_vdev_sm_transition_to(vdev_mlme, WLAN_VDEV_S_START); 1850 mlme_vdev_sm_deliver_event(vdev_mlme, 1851 WLAN_VDEV_SM_EV_RESTART_REQ, 1852 event_data_len, event_data); 1853 status = true; 1854 break; 1855 1856 case WLAN_VDEV_SM_EV_UP_FAIL: 1857 mlme_vdev_sm_transition_to(vdev_mlme, WLAN_VDEV_S_SUSPEND); 1858 mlme_vdev_sm_deliver_event(vdev_mlme, event, 1859 event_data_len, event_data); 1860 status = true; 1861 break; 1862 1863 case WLAN_VDEV_SM_EV_ROAM: 1864 mlme_vdev_notify_roam_start(vdev_mlme, event_data_len, 1865 event_data); 1866 status = true; 1867 break; 1868 1869 default: 1870 status = false; 1871 break; 1872 } 1873 1874 return status; 1875 } 1876 1877 1878 static const char *vdev_sm_event_names[] = { 1879 "EV_START", 1880 "EV_START_REQ", 1881 "EV_RESTART_REQ", 1882 "EV_START_RESP", 1883 "EV_RESTART_RESP", 1884 "EV_START_REQ_FAIL", 1885 "EV_RESTART_REQ_FAIL", 1886 "EV_START_SUCCESS", 1887 "EV_CONN_PROGRESS", 1888 "EV_STA_CONN_START", 1889 "EV_DFS_CAC_WAIT", 1890 "EV_DFS_CAC_COMPLETED", 1891 "EV_DOWN", 1892 "EV_CONNECTION_FAIL", 1893 "EV_STOP_RESP", 1894 "EV_STOP_FAIL", 1895 "EV_DOWN_FAIL", 1896 "EV_DISCONNECT_COMPLETE", 1897 "EV_SUSPEND_RESTART", 1898 "EV_HOST_RESTART", 1899 "EV_UP_HOST_RESTART", 1900 "EV_FW_VDEV_RESTART", 1901 "EV_UP_FAIL", 1902 "EV_RADAR_DETECTED", 1903 "EV_CSA_RESTART", 1904 "EV_CSA_COMPLETE", 1905 "EV_MLME_DOWN_REQ", 1906 "EV_DOWN_COMPLETE", 1907 "EV_ROAM", 1908 "EV_STOP_REQ", 1909 "EV_CHAN_SWITCH_DISABLED", 1910 "EV_MLO_SYNC_COMPLETE", 1911 }; 1912 1913 struct wlan_sm_state_info sm_info[] = { 1914 { 1915 (uint8_t)WLAN_VDEV_S_INIT, 1916 (uint8_t)WLAN_SM_ENGINE_STATE_NONE, 1917 (uint8_t)WLAN_SM_ENGINE_STATE_NONE, 1918 true, 1919 "INIT", 1920 mlme_vdev_state_init_entry, 1921 mlme_vdev_state_init_exit, 1922 mlme_vdev_state_init_event 1923 }, 1924 { 1925 (uint8_t)WLAN_VDEV_S_START, 1926 (uint8_t)WLAN_SM_ENGINE_STATE_NONE, 1927 (uint8_t)WLAN_SM_ENGINE_STATE_NONE, 1928 true, 1929 "START", 1930 mlme_vdev_state_start_entry, 1931 mlme_vdev_state_start_exit, 1932 mlme_vdev_state_start_event 1933 }, 1934 { 1935 (uint8_t)WLAN_VDEV_S_DFS_CAC_WAIT, 1936 (uint8_t)WLAN_SM_ENGINE_STATE_NONE, 1937 (uint8_t)WLAN_SM_ENGINE_STATE_NONE, 1938 true, 1939 "DFS_CAC_WAIT", 1940 mlme_vdev_state_dfs_cac_wait_entry, 1941 mlme_vdev_state_dfs_cac_wait_exit, 1942 mlme_vdev_state_dfs_cac_wait_event 1943 }, 1944 { 1945 (uint8_t)WLAN_VDEV_S_UP, 1946 (uint8_t)WLAN_SM_ENGINE_STATE_NONE, 1947 (uint8_t)WLAN_SM_ENGINE_STATE_NONE, 1948 true, 1949 "UP", 1950 mlme_vdev_state_up_entry, 1951 mlme_vdev_state_up_exit, 1952 mlme_vdev_state_up_event 1953 }, 1954 { 1955 (uint8_t)WLAN_VDEV_S_SUSPEND, 1956 (uint8_t)WLAN_SM_ENGINE_STATE_NONE, 1957 (uint8_t)WLAN_SM_ENGINE_STATE_NONE, 1958 true, 1959 "SUSPEND", 1960 mlme_vdev_state_suspend_entry, 1961 mlme_vdev_state_suspend_exit, 1962 mlme_vdev_state_suspend_event 1963 }, 1964 { 1965 (uint8_t)WLAN_VDEV_S_STOP, 1966 (uint8_t)WLAN_SM_ENGINE_STATE_NONE, 1967 (uint8_t)WLAN_VDEV_SS_STOP_STOP_PROGRESS, 1968 true, 1969 "STOP", 1970 mlme_vdev_state_stop_entry, 1971 mlme_vdev_state_stop_exit, 1972 mlme_vdev_state_stop_event 1973 }, 1974 { 1975 (uint8_t)WLAN_VDEV_S_MAX, 1976 (uint8_t)WLAN_SM_ENGINE_STATE_NONE, 1977 (uint8_t)WLAN_SM_ENGINE_STATE_NONE, 1978 false, 1979 "INVALID", 1980 NULL, 1981 NULL, 1982 NULL 1983 }, 1984 { 1985 (uint8_t)WLAN_VDEV_SS_START_START_PROGRESS, 1986 (uint8_t)WLAN_VDEV_S_START, 1987 (uint8_t)WLAN_SM_ENGINE_STATE_NONE, 1988 false, 1989 "ST-START_PROG", 1990 mlme_vdev_subst_start_start_progress_entry, 1991 mlme_vdev_subst_start_start_progress_exit, 1992 mlme_vdev_subst_start_start_progress_event 1993 }, 1994 { 1995 (uint8_t)WLAN_VDEV_SS_START_RESTART_PROGRESS, 1996 (uint8_t)WLAN_VDEV_S_START, 1997 (uint8_t)WLAN_SM_ENGINE_STATE_NONE, 1998 false, 1999 "ST-RESTART_PROG", 2000 mlme_vdev_subst_start_restart_progress_entry, 2001 mlme_vdev_subst_start_restart_progress_exit, 2002 mlme_vdev_subst_start_restart_progress_event 2003 }, 2004 { 2005 (uint8_t)WLAN_VDEV_SS_START_CONN_PROGRESS, 2006 (uint8_t)WLAN_VDEV_S_START, 2007 (uint8_t)WLAN_SM_ENGINE_STATE_NONE, 2008 false, 2009 "ST-CONN_PROG", 2010 mlme_vdev_subst_start_conn_progress_entry, 2011 mlme_vdev_subst_start_conn_progress_exit, 2012 mlme_vdev_subst_start_conn_progress_event 2013 }, 2014 { 2015 (uint8_t)WLAN_VDEV_SS_START_DISCONN_PROGRESS, 2016 (uint8_t)WLAN_VDEV_S_START, 2017 (uint8_t)WLAN_SM_ENGINE_STATE_NONE, 2018 false, 2019 "ST-DISCONN_PROG", 2020 mlme_vdev_subst_start_disconn_progress_entry, 2021 mlme_vdev_subst_start_disconn_progress_exit, 2022 mlme_vdev_subst_start_disconn_progress_event 2023 }, 2024 { 2025 (uint8_t)WLAN_VDEV_SS_SUSPEND_SUSPEND_DOWN, 2026 (uint8_t)WLAN_VDEV_S_SUSPEND, 2027 (uint8_t)WLAN_SM_ENGINE_STATE_NONE, 2028 false, 2029 "SP-SUSPEND_DOWN", 2030 mlme_vdev_subst_suspend_suspend_down_entry, 2031 mlme_vdev_subst_suspend_suspend_down_exit, 2032 mlme_vdev_subst_suspend_suspend_down_event 2033 }, 2034 { 2035 (uint8_t)WLAN_VDEV_SS_SUSPEND_SUSPEND_RESTART, 2036 (uint8_t)WLAN_VDEV_S_SUSPEND, 2037 (uint8_t)WLAN_SM_ENGINE_STATE_NONE, 2038 false, 2039 "SP-SUSPEND_RESTART", 2040 mlme_vdev_subst_suspend_suspend_restart_entry, 2041 mlme_vdev_subst_suspend_suspend_restart_exit, 2042 mlme_vdev_subst_suspend_suspend_restart_event 2043 }, 2044 { 2045 (uint8_t)WLAN_VDEV_SS_SUSPEND_HOST_RESTART, 2046 (uint8_t)WLAN_VDEV_S_SUSPEND, 2047 (uint8_t)WLAN_SM_ENGINE_STATE_NONE, 2048 false, 2049 "SP-HOST_RESTART", 2050 mlme_vdev_subst_suspend_host_restart_entry, 2051 mlme_vdev_subst_suspend_host_restart_exit, 2052 mlme_vdev_subst_suspend_host_restart_event 2053 }, 2054 { 2055 (uint8_t)WLAN_VDEV_SS_SUSPEND_CSA_RESTART, 2056 (uint8_t)WLAN_VDEV_S_SUSPEND, 2057 (uint8_t)WLAN_SM_ENGINE_STATE_NONE, 2058 false, 2059 "SP-CSA_RESTART", 2060 mlme_vdev_subst_suspend_csa_restart_entry, 2061 mlme_vdev_subst_suspend_csa_restart_exit, 2062 mlme_vdev_subst_suspend_csa_restart_event 2063 }, 2064 { 2065 (uint8_t)WLAN_VDEV_SS_STOP_STOP_PROGRESS, 2066 (uint8_t)WLAN_VDEV_S_STOP, 2067 (uint8_t)WLAN_SM_ENGINE_STATE_NONE, 2068 false, 2069 "STOP-STOP_PROG", 2070 mlme_vdev_subst_stop_stop_progress_entry, 2071 mlme_vdev_subst_stop_stop_progress_exit, 2072 mlme_vdev_subst_stop_stop_progress_event 2073 }, 2074 { 2075 (uint8_t)WLAN_VDEV_SS_STOP_DOWN_PROGRESS, 2076 (uint8_t)WLAN_VDEV_S_STOP, 2077 (uint8_t)WLAN_SM_ENGINE_STATE_NONE, 2078 false, 2079 "STOP-DOWN_PROG", 2080 mlme_vdev_subst_stop_down_progress_entry, 2081 mlme_vdev_subst_stop_down_progress_exit, 2082 mlme_vdev_subst_stop_down_progress_event 2083 }, 2084 { 2085 (uint8_t)WLAN_VDEV_SS_IDLE, 2086 (uint8_t)WLAN_SM_ENGINE_STATE_NONE, 2087 (uint8_t)WLAN_SM_ENGINE_STATE_NONE, 2088 false, 2089 "IDLE", 2090 NULL, 2091 NULL, 2092 NULL, 2093 }, 2094 { 2095 (uint8_t)WLAN_VDEV_SS_MLO_SYNC_WAIT, 2096 (uint8_t)WLAN_VDEV_S_UP, 2097 (uint8_t)WLAN_SM_ENGINE_STATE_NONE, 2098 false, 2099 "UP-MLO_SYNC_WAIT", 2100 mlme_vdev_subst_mlo_sync_wait_entry, 2101 mlme_vdev_subst_mlo_sync_wait_exit, 2102 mlme_vdev_subst_mlo_sync_wait_event 2103 }, 2104 { 2105 (uint8_t)WLAN_VDEV_SS_UP_ACTIVE, 2106 (uint8_t)WLAN_VDEV_S_UP, 2107 (uint8_t)WLAN_SM_ENGINE_STATE_NONE, 2108 false, 2109 "UP-UP_ACTIVE", 2110 mlme_vdev_subst_up_active_entry, 2111 mlme_vdev_subst_up_active_exit, 2112 mlme_vdev_subst_up_active_event 2113 }, 2114 { 2115 (uint8_t)WLAN_VDEV_SS_MAX, 2116 (uint8_t)WLAN_SM_ENGINE_STATE_NONE, 2117 (uint8_t)WLAN_SM_ENGINE_STATE_NONE, 2118 false, 2119 "INVALID", 2120 NULL, 2121 NULL, 2122 NULL, 2123 }, 2124 }; 2125 2126 QDF_STATUS mlme_vdev_sm_deliver_event(struct vdev_mlme_obj *vdev_mlme, 2127 enum wlan_vdev_sm_evt event, 2128 uint16_t event_data_len, void *event_data) 2129 { 2130 return wlan_sm_dispatch(vdev_mlme->sm_hdl, event, 2131 event_data_len, event_data); 2132 } 2133 2134 void mlme_vdev_sm_print_state_event(struct vdev_mlme_obj *vdev_mlme, 2135 enum wlan_vdev_sm_evt event) 2136 { 2137 enum wlan_vdev_state state; 2138 enum wlan_vdev_state substate; 2139 struct wlan_objmgr_vdev *vdev; 2140 2141 vdev = vdev_mlme->vdev; 2142 2143 state = wlan_vdev_mlme_get_state(vdev); 2144 substate = wlan_vdev_mlme_get_substate(vdev); 2145 2146 mlme_nofl_debug("[%s]%s - %s, %s", vdev_mlme->sm_hdl->name, 2147 sm_info[state].name, sm_info[substate].name, 2148 vdev_sm_event_names[event]); 2149 } 2150 2151 void mlme_vdev_sm_print_state(struct vdev_mlme_obj *vdev_mlme) 2152 { 2153 enum wlan_vdev_state state; 2154 enum wlan_vdev_state substate; 2155 struct wlan_objmgr_vdev *vdev; 2156 2157 vdev = vdev_mlme->vdev; 2158 2159 state = wlan_vdev_mlme_get_state(vdev); 2160 substate = wlan_vdev_mlme_get_substate(vdev); 2161 2162 mlme_nofl_debug("[%s]%s - %s", vdev_mlme->sm_hdl->name, 2163 sm_info[state].name, sm_info[substate].name); 2164 } 2165 2166 #ifdef SM_ENG_HIST_ENABLE 2167 void mlme_vdev_sm_history_print(struct vdev_mlme_obj *vdev_mlme) 2168 { 2169 return wlan_sm_print_history(vdev_mlme->sm_hdl); 2170 } 2171 #endif 2172 2173 QDF_STATUS mlme_vdev_sm_create(struct vdev_mlme_obj *vdev_mlme) 2174 { 2175 struct wlan_sm *sm; 2176 uint8_t name[WLAN_SM_ENGINE_MAX_NAME]; 2177 struct wlan_objmgr_vdev *vdev = vdev_mlme->vdev; 2178 2179 qdf_scnprintf(name, sizeof(name), "VM-PS_%d-VD_%d", 2180 wlan_psoc_get_id(wlan_vdev_get_psoc(vdev)), 2181 wlan_vdev_get_id(vdev)); 2182 sm = wlan_sm_create(name, vdev_mlme, 2183 WLAN_VDEV_S_INIT, 2184 sm_info, 2185 QDF_ARRAY_SIZE(sm_info), 2186 vdev_sm_event_names, 2187 QDF_ARRAY_SIZE(vdev_sm_event_names)); 2188 if (!sm) { 2189 mlme_err("VDEV MLME SM allocation failed"); 2190 return QDF_STATUS_E_FAILURE; 2191 } 2192 vdev_mlme->sm_hdl = sm; 2193 wlan_minidump_log((void *)sm, sizeof(*sm), 2194 wlan_vdev_get_psoc(vdev), 2195 WLAN_MD_OBJMGR_VDEV_SM, "wlan_sm"); 2196 2197 mlme_vdev_sm_spinlock_create(vdev_mlme); 2198 2199 mlme_vdev_cmd_mutex_create(vdev_mlme); 2200 2201 return QDF_STATUS_SUCCESS; 2202 } 2203 2204 QDF_STATUS mlme_vdev_sm_destroy(struct vdev_mlme_obj *vdev_mlme) 2205 { 2206 struct wlan_objmgr_vdev *vdev = vdev_mlme->vdev; 2207 2208 mlme_vdev_cmd_mutex_destroy(vdev_mlme); 2209 2210 mlme_vdev_sm_spinlock_destroy(vdev_mlme); 2211 2212 wlan_minidump_remove(vdev_mlme->sm_hdl, 2213 sizeof(*vdev_mlme->sm_hdl), 2214 wlan_vdev_get_psoc(vdev), 2215 WLAN_MD_OBJMGR_VDEV_SM, "wlan_sm"); 2216 2217 wlan_sm_delete(vdev_mlme->sm_hdl); 2218 2219 return QDF_STATUS_SUCCESS; 2220 } 2221