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