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