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