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