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_SUSPEND); 392 mlme_vdev_sm_deliver_event(vdev_mlme, WLAN_VDEV_SM_EV_DOWN, 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, false); 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, false); 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 case WLAN_VDEV_SM_EV_SUSPEND_CSA_RESTART: 1290 mlme_vdev_disconnect_peers(vdev_mlme, 1291 event_data_len, event_data, true); 1292 status = true; 1293 break; 1294 1295 default: 1296 status = false; 1297 break; 1298 } 1299 1300 return status; 1301 } 1302 1303 /** 1304 * mlme_vdev_subst_suspend_host_restart_entry() - Entry API for Host restart 1305 * substate 1306 * @ctx: VDEV MLME object 1307 * 1308 * API to perform operations on moving to HOST-RESTART substate 1309 * 1310 * Return: void 1311 */ 1312 static void mlme_vdev_subst_suspend_host_restart_entry(void *ctx) 1313 { 1314 struct vdev_mlme_obj *vdev_mlme = (struct vdev_mlme_obj *)ctx; 1315 struct wlan_objmgr_vdev *vdev; 1316 1317 vdev = vdev_mlme->vdev; 1318 1319 if (wlan_vdev_mlme_get_state(vdev) != WLAN_VDEV_S_SUSPEND) 1320 QDF_BUG(0); 1321 1322 mlme_vdev_set_substate(vdev, WLAN_VDEV_SS_SUSPEND_HOST_RESTART); 1323 } 1324 1325 /** 1326 * mlme_vdev_subst_suspend_host_restart_exit() - Exit API for host restart 1327 * sub state 1328 * @ctx: VDEV MLME object 1329 * 1330 * API to perform operations on moving out of HOST-RESTART substate 1331 * 1332 * Return: void 1333 */ 1334 static void mlme_vdev_subst_suspend_host_restart_exit(void *ctx) 1335 { 1336 /* NONE */ 1337 } 1338 1339 /** 1340 * mlme_vdev_subst_suspend_host_restart_event() - Event handler API for Host 1341 * restart substate 1342 * @ctx: VDEV MLME object 1343 * @event: MLME event 1344 * @event_data_len: data size 1345 * @event_data: event data 1346 * 1347 * API to handle events in HOST-RESTART substate 1348 * 1349 * Return: void 1350 */ 1351 static bool mlme_vdev_subst_suspend_host_restart_event(void *ctx, 1352 uint16_t event, uint16_t event_data_len, void *event_data) 1353 { 1354 struct vdev_mlme_obj *vdev_mlme = (struct vdev_mlme_obj *)ctx; 1355 bool status; 1356 1357 switch (event) { 1358 case WLAN_VDEV_SM_EV_HOST_RESTART: 1359 mlme_vdev_disconnect_peers(vdev_mlme, 1360 event_data_len, event_data, false); 1361 status = true; 1362 break; 1363 1364 case WLAN_VDEV_SM_EV_DISCONNECT_COMPLETE: 1365 /* VDEV up command need not be sent */ 1366 mlme_vdev_sm_transition_to(vdev_mlme, WLAN_VDEV_S_UP); 1367 mlme_vdev_sm_deliver_event(vdev_mlme, 1368 WLAN_VDEV_SM_EV_UP_HOST_RESTART, 1369 event_data_len, event_data); 1370 status = true; 1371 break; 1372 1373 case WLAN_VDEV_SM_EV_DOWN: 1374 mlme_vdev_sm_transition_to(vdev_mlme, 1375 WLAN_VDEV_SS_SUSPEND_SUSPEND_DOWN); 1376 status = true; 1377 break; 1378 1379 case WLAN_VDEV_SM_EV_RADAR_DETECTED: 1380 mlme_vdev_sm_transition_to(vdev_mlme, 1381 WLAN_VDEV_SS_SUSPEND_CSA_RESTART); 1382 mlme_vdev_sm_deliver_event(vdev_mlme, 1383 WLAN_VDEV_SM_EV_CSA_RESTART, 1384 event_data_len, event_data); 1385 status = true; 1386 break; 1387 1388 default: 1389 status = false; 1390 break; 1391 } 1392 1393 return status; 1394 } 1395 1396 /** 1397 * mlme_vdev_subst_suspend_csa_restart_entry() - Entry API for CSA restart 1398 * substate 1399 * @ctx: VDEV MLME object 1400 * 1401 * API to perform operations on moving to CSA-RESTART substate 1402 * 1403 * Return: void 1404 */ 1405 static void mlme_vdev_subst_suspend_csa_restart_entry(void *ctx) 1406 { 1407 struct vdev_mlme_obj *vdev_mlme = (struct vdev_mlme_obj *)ctx; 1408 struct wlan_objmgr_vdev *vdev; 1409 1410 vdev = vdev_mlme->vdev; 1411 1412 if (wlan_vdev_mlme_get_state(vdev) != WLAN_VDEV_S_SUSPEND) 1413 QDF_BUG(0); 1414 1415 mlme_vdev_set_substate(vdev, WLAN_VDEV_SS_SUSPEND_CSA_RESTART); 1416 } 1417 1418 /** 1419 * mlme_vdev_subst_suspend_csa_restart_exit() - Exit API for CSA restart 1420 * sub state 1421 * @ctx: VDEV MLME object 1422 * 1423 * API to perform operations on moving out of CSA-RESTART substate 1424 * 1425 * Return: void 1426 */ 1427 static void mlme_vdev_subst_suspend_csa_restart_exit(void *ctx) 1428 { 1429 /* NONE */ 1430 } 1431 1432 /** 1433 * mlme_vdev_subst_suspend_csa_restart_event() - Event handler API for CSA 1434 * restart substate 1435 * @ctx: VDEV MLME object 1436 * @event: MLME event 1437 * @event_data_len: data size 1438 * @event_data: event data 1439 * 1440 * API to handle events in CSA-RESTART substate 1441 * 1442 * Return: SUCCESS: on handling event 1443 * FAILURE: on ignoring the event 1444 */ 1445 static bool mlme_vdev_subst_suspend_csa_restart_event(void *ctx, 1446 uint16_t event, uint16_t event_data_len, void *event_data) 1447 { 1448 struct vdev_mlme_obj *vdev_mlme = (struct vdev_mlme_obj *)ctx; 1449 struct wlan_objmgr_psoc *psoc = wlan_vdev_get_psoc(vdev_mlme->vdev); 1450 bool status; 1451 1452 switch (event) { 1453 case WLAN_VDEV_SM_EV_CHAN_SWITCH_DISABLED: 1454 /** 1455 * This event is sent when CSA count becomes 0 without 1456 * change in channel i.e. only Beacon Probe response template 1457 * is updated (CSA / ECSA IE is removed). 1458 */ 1459 mlme_vdev_chan_switch_disable_notify_dfs(vdev_mlme); 1460 mlme_vdev_sm_transition_to(vdev_mlme, WLAN_VDEV_S_UP); 1461 mlme_vdev_sm_deliver_event(vdev_mlme, 1462 WLAN_VDEV_SM_EV_UP_HOST_RESTART, 1463 event_data_len, event_data); 1464 status = true; 1465 break; 1466 case WLAN_VDEV_SM_EV_CSA_RESTART: 1467 mlme_vdev_update_beacon(vdev_mlme, BEACON_CSA, 1468 event_data_len, event_data); 1469 status = true; 1470 break; 1471 case WLAN_VDEV_SM_EV_CSA_COMPLETE: 1472 if ((mlme_vdev_is_newchan_no_cac(vdev_mlme) == 1473 QDF_STATUS_SUCCESS) || 1474 mlme_max_chan_switch_is_set(psoc)) { 1475 mlme_vdev_sm_transition_to(vdev_mlme, 1476 WLAN_VDEV_S_START); 1477 mlme_vdev_sm_deliver_event(vdev_mlme, 1478 WLAN_VDEV_SM_EV_RESTART_REQ, 1479 event_data_len, event_data); 1480 } else { 1481 mlme_vdev_sm_transition_to 1482 (vdev_mlme, 1483 WLAN_VDEV_SS_SUSPEND_SUSPEND_RESTART); 1484 mlme_vdev_sm_deliver_event 1485 (vdev_mlme, WLAN_VDEV_SM_EV_SUSPEND_CSA_RESTART, 1486 event_data_len, event_data); 1487 } 1488 status = true; 1489 break; 1490 1491 case WLAN_VDEV_SM_EV_DOWN: 1492 mlme_vdev_sm_transition_to(vdev_mlme, 1493 WLAN_VDEV_SS_SUSPEND_SUSPEND_DOWN); 1494 mlme_vdev_sm_deliver_event(vdev_mlme, event, 1495 event_data_len, event_data); 1496 status = true; 1497 break; 1498 1499 case WLAN_VDEV_SM_EV_RADAR_DETECTED: 1500 /* since channel change is already in progress, 1501 * dfs ignore radar detected event 1502 */ 1503 status = true; 1504 break; 1505 1506 default: 1507 status = false; 1508 break; 1509 } 1510 1511 return status; 1512 } 1513 1514 /** 1515 * mlme_vdev_subst_stop_stop_progress_entry() - Entry API for Stop Progress 1516 * sub state 1517 * @ctx: VDEV MLME object 1518 * 1519 * API to perform operations on moving to STOP-PROGRESS substate 1520 * 1521 * Return: void 1522 */ 1523 static void mlme_vdev_subst_stop_stop_progress_entry(void *ctx) 1524 { 1525 struct vdev_mlme_obj *vdev_mlme = (struct vdev_mlme_obj *) ctx; 1526 struct wlan_objmgr_vdev *vdev; 1527 1528 vdev = vdev_mlme->vdev; 1529 1530 if (wlan_vdev_mlme_get_state(vdev) != WLAN_VDEV_S_STOP) 1531 QDF_BUG(0); 1532 1533 mlme_vdev_set_substate(vdev, WLAN_VDEV_SS_STOP_STOP_PROGRESS); 1534 } 1535 1536 /** 1537 * mlme_vdev_subst_stop_stop_progress_exit() - Exit API for Stop Progress 1538 * sub state 1539 * @ctx: VDEV MLME object 1540 * 1541 * API to perform operations on moving out of STOP-PROGRESS substate 1542 * 1543 * Return: void 1544 */ 1545 static void mlme_vdev_subst_stop_stop_progress_exit(void *ctx) 1546 { 1547 /* NONE */ 1548 } 1549 1550 /** 1551 * mlme_vdev_subst_stop_stop_progress_event() - Event handler API for Stop 1552 * Progress substate 1553 * @ctx: VDEV MLME object 1554 * @event: MLME event 1555 * @event_data_len: data size 1556 * @event_data: event data 1557 * 1558 * API to handle events in STOP-PROGRESS substate 1559 * 1560 * Return: SUCCESS: on handling event 1561 * FAILURE: on ignoring the event 1562 */ 1563 static bool mlme_vdev_subst_stop_stop_progress_event(void *ctx, 1564 uint16_t event, uint16_t event_data_len, void *event_data) 1565 { 1566 struct vdev_mlme_obj *vdev_mlme = (struct vdev_mlme_obj *)ctx; 1567 bool status; 1568 1569 /* Debug framework is required to hold the events */ 1570 1571 switch (event) { 1572 case WLAN_VDEV_SM_EV_STOP_REQ: 1573 /* send vdev stop command to FW and delete BSS peer*/ 1574 mlme_vdev_stop_send(vdev_mlme, event_data_len, event_data); 1575 status = true; 1576 break; 1577 1578 case WLAN_VDEV_SM_EV_STOP_RESP: 1579 /* Processes stop response, and checks BSS peer delete wait 1580 * is needed 1581 */ 1582 mlme_vdev_stop_continue(vdev_mlme, event_data_len, event_data); 1583 status = true; 1584 break; 1585 1586 /* This event should be given by MLME on stop complete and BSS 1587 * peer delete complete to move forward 1588 */ 1589 case WLAN_VDEV_SM_EV_MLME_DOWN_REQ: 1590 mlme_vdev_sm_transition_to(vdev_mlme, 1591 WLAN_VDEV_SS_STOP_DOWN_PROGRESS); 1592 mlme_vdev_sm_deliver_event(vdev_mlme, 1593 WLAN_VDEV_SM_EV_MLME_DOWN_REQ, 1594 event_data_len, event_data); 1595 status = true; 1596 break; 1597 1598 case WLAN_VDEV_SM_EV_STOP_FAIL: 1599 mlme_vdev_sm_transition_to(vdev_mlme, 1600 WLAN_VDEV_SS_STOP_DOWN_PROGRESS); 1601 mlme_vdev_sm_deliver_event(vdev_mlme, 1602 WLAN_VDEV_SM_EV_MLME_DOWN_REQ, 1603 event_data_len, event_data); 1604 status = true; 1605 break; 1606 1607 default: 1608 status = false; 1609 break; 1610 } 1611 1612 return status; 1613 } 1614 1615 /** 1616 * mlme_vdev_subst_stop_down_progress_entry() - Entry API for Down Progress 1617 * sub state 1618 * @ctx: VDEV MLME object 1619 * 1620 * API to perform operations on moving to DOWN-PROGRESS substate 1621 * 1622 * Return: void 1623 */ 1624 static void mlme_vdev_subst_stop_down_progress_entry(void *ctx) 1625 { 1626 struct vdev_mlme_obj *vdev_mlme = (struct vdev_mlme_obj *)ctx; 1627 struct wlan_objmgr_vdev *vdev; 1628 1629 vdev = vdev_mlme->vdev; 1630 1631 if (wlan_vdev_mlme_get_state(vdev) != WLAN_VDEV_S_STOP) 1632 QDF_BUG(0); 1633 1634 mlme_vdev_set_substate(vdev, WLAN_VDEV_SS_STOP_DOWN_PROGRESS); 1635 } 1636 1637 /** 1638 * mlme_vdev_subst_stop_down_progress_exit() - Exit API for Down Progress 1639 * sub state 1640 * @ctx: VDEV MLME object 1641 * 1642 * API to perform operations on moving out of DOWN-PROGRESS substate 1643 * 1644 * Return: void 1645 */ 1646 static void mlme_vdev_subst_stop_down_progress_exit(void *ctx) 1647 { 1648 /* NONE */ 1649 } 1650 1651 /** 1652 * mlme_vdev_subst_stop_down_progress_event() - Event handler API for Down 1653 * Progress substate 1654 * @ctx: VDEV MLME object 1655 * @event: MLME event 1656 * @event_data_len: data size 1657 * @event_data: event data 1658 * 1659 * API to handle events in DOWN-PROGRESS substate 1660 * 1661 * Return: SUCCESS: on handling event 1662 * FAILURE: on ignoring the event 1663 */ 1664 static bool mlme_vdev_subst_stop_down_progress_event(void *ctx, 1665 uint16_t event, uint16_t event_data_len, void *event_data) 1666 { 1667 struct vdev_mlme_obj *vdev_mlme = (struct vdev_mlme_obj *)ctx; 1668 bool status; 1669 1670 switch (event) { 1671 case WLAN_VDEV_SM_EV_DOWN: 1672 status = true; 1673 break; 1674 1675 case WLAN_VDEV_SM_EV_MLME_DOWN_REQ: 1676 /* send vdev down command to FW, if send is successful, sends 1677 * DOWN_COMPLETE event 1678 */ 1679 mlme_vdev_down_send(vdev_mlme, event_data_len, event_data); 1680 status = true; 1681 break; 1682 1683 case WLAN_VDEV_SM_EV_DOWN_COMPLETE: 1684 mlme_vdev_sm_transition_to(vdev_mlme, WLAN_VDEV_S_INIT); 1685 mlme_vdev_sm_deliver_event(vdev_mlme, 1686 WLAN_VDEV_SM_EV_DOWN_COMPLETE, 1687 event_data_len, event_data); 1688 status = true; 1689 break; 1690 1691 case WLAN_VDEV_SM_EV_DOWN_FAIL: 1692 mlme_vdev_sm_transition_to(vdev_mlme, WLAN_VDEV_S_INIT); 1693 mlme_vdev_sm_deliver_event(vdev_mlme, 1694 WLAN_VDEV_SM_EV_DOWN_COMPLETE, 1695 event_data_len, event_data); 1696 status = true; 1697 break; 1698 1699 default: 1700 status = false; 1701 break; 1702 } 1703 1704 return status; 1705 } 1706 1707 /** 1708 * mlme_vdev_subst_mlo_sync_wait_entry() - Entry API for mlo sync wait sub state 1709 * @ctx: VDEV MLME object 1710 * 1711 * API to perform operations on moving to MLO-SYNC-WAIT substate 1712 * 1713 * Return: void 1714 */ 1715 static void mlme_vdev_subst_mlo_sync_wait_entry(void *ctx) 1716 { 1717 struct vdev_mlme_obj *vdev_mlme = (struct vdev_mlme_obj *)ctx; 1718 struct wlan_objmgr_vdev *vdev; 1719 1720 vdev = vdev_mlme->vdev; 1721 1722 if (wlan_vdev_mlme_get_state(vdev) != WLAN_VDEV_S_UP) 1723 QDF_BUG(0); 1724 1725 mlme_vdev_set_substate(vdev, WLAN_VDEV_SS_MLO_SYNC_WAIT); 1726 mlme_vdev_notify_mlo_sync_wait_entry(vdev_mlme); 1727 } 1728 1729 /** 1730 * mlme_vdev_subst_mlo_sync_wait_exit() - Exit API for mlo sync wait sub state 1731 * @ctx: VDEV MLME object 1732 * 1733 * API to perform operations on moving out of MLO-SYNC-WAIT substate 1734 * 1735 * Return: void 1736 */ 1737 #ifdef WLAN_FEATURE_11BE_MLO 1738 static void mlme_vdev_subst_mlo_sync_wait_exit(void *ctx) 1739 { 1740 struct vdev_mlme_obj *vdev_mlme = (struct vdev_mlme_obj *)ctx; 1741 struct wlan_objmgr_vdev *vdev = vdev_mlme->vdev; 1742 struct wlan_mlo_dev_context *mld_ctx = vdev->mlo_dev_ctx; 1743 enum QDF_OPMODE mode; 1744 uint8_t idx; 1745 1746 if (!vdev->mlo_dev_ctx) 1747 return; 1748 1749 idx = mlo_get_link_vdev_ix(mld_ctx, vdev); 1750 if (idx == MLO_INVALID_LINK_IDX) 1751 return; 1752 1753 mode = wlan_vdev_mlme_get_opmode(vdev); 1754 if (mode != QDF_SAP_MODE) 1755 return; 1756 1757 wlan_util_change_map_index(mld_ctx->ap_ctx->mlo_vdev_up_bmap, 1758 idx, 0); 1759 } 1760 #else 1761 static void mlme_vdev_subst_mlo_sync_wait_exit(void *ctx) 1762 { 1763 /* NONE */ 1764 } 1765 #endif 1766 1767 /** 1768 * mlme_vdev_subst_mlo_sync_wait_event() - Event handler API for mlo sync wait 1769 * substate 1770 * @ctx: VDEV MLME object 1771 * @event: MLME event 1772 * @event_data_len: data size 1773 * @event_data: event data 1774 * 1775 * API to handle events in MLO-SYNC-WAIT substate 1776 * 1777 * Return: SUCCESS: on handling event 1778 * FAILURE: on ignoring the event 1779 */ 1780 static bool mlme_vdev_subst_mlo_sync_wait_event(void *ctx, uint16_t event, 1781 uint16_t event_data_len, 1782 void *event_data) 1783 { 1784 struct vdev_mlme_obj *vdev_mlme = (struct vdev_mlme_obj *)ctx; 1785 bool status; 1786 1787 switch (event) { 1788 case WLAN_VDEV_SM_EV_START_SUCCESS: 1789 if (mlme_vdev_up_notify_mlo_mgr(vdev_mlme)) 1790 mlme_vdev_sm_deliver_event( 1791 vdev_mlme, 1792 WLAN_VDEV_SM_EV_MLO_SYNC_COMPLETE, 1793 event_data_len, event_data); 1794 status = true; 1795 break; 1796 1797 case WLAN_VDEV_SM_EV_MLO_SYNC_COMPLETE: 1798 mlme_vdev_sm_transition_to(vdev_mlme, WLAN_VDEV_SS_UP_ACTIVE); 1799 mlme_vdev_sm_deliver_event(vdev_mlme, event, 1800 event_data_len, event_data); 1801 status = true; 1802 break; 1803 1804 case WLAN_VDEV_SM_EV_DOWN: 1805 mlme_vdev_sm_transition_to(vdev_mlme, WLAN_VDEV_S_SUSPEND); 1806 mlme_vdev_sm_deliver_event(vdev_mlme, event, 1807 event_data_len, event_data); 1808 status = true; 1809 break; 1810 1811 case WLAN_VDEV_SM_EV_RADAR_DETECTED: 1812 case WLAN_VDEV_SM_EV_CSA_RESTART: 1813 case WLAN_VDEV_SM_EV_FW_VDEV_RESTART: 1814 mlme_vdev_sm_transition_to(vdev_mlme, WLAN_VDEV_S_START); 1815 mlme_vdev_sm_deliver_event(vdev_mlme, 1816 WLAN_VDEV_SM_EV_RESTART_REQ, 1817 event_data_len, event_data); 1818 status = true; 1819 break; 1820 1821 default: 1822 status = false; 1823 break; 1824 } 1825 1826 return status; 1827 } 1828 1829 /** 1830 * mlme_vdev_subst_up_active_entry() - Entry API for up active sub state 1831 * @ctx: VDEV MLME object 1832 * 1833 * API to perform operations on moving to UP-ACTIVE substate 1834 * 1835 * Return: void 1836 */ 1837 static void mlme_vdev_subst_up_active_entry(void *ctx) 1838 { 1839 struct vdev_mlme_obj *vdev_mlme = (struct vdev_mlme_obj *)ctx; 1840 struct wlan_objmgr_vdev *vdev; 1841 1842 vdev = vdev_mlme->vdev; 1843 1844 if (wlan_vdev_mlme_get_state(vdev) != WLAN_VDEV_S_UP) 1845 QDF_BUG(0); 1846 1847 mlme_vdev_set_substate(vdev, WLAN_VDEV_SS_UP_ACTIVE); 1848 } 1849 1850 /** 1851 * mlme_vdev_subst_up_active_exit() - Exit API for up active sub state 1852 * @ctx: VDEV MLME object 1853 * 1854 * API to perform operations on moving out of UP-ACTIVE substate 1855 * 1856 * Return: void 1857 */ 1858 static void mlme_vdev_subst_up_active_exit(void *ctx) 1859 { 1860 /* NONE */ 1861 } 1862 1863 /** 1864 * mlme_vdev_subst_up_active_event() - Event handler API for up active substate 1865 * @ctx: VDEV MLME object 1866 * @event: MLME event 1867 * @event_data_len: data size 1868 * @event_data: event data 1869 * 1870 * API to handle events in UP-ACTIVE substate 1871 * 1872 * Return: SUCCESS: on handling event 1873 * FAILURE: on ignoring the event 1874 */ 1875 static bool mlme_vdev_subst_up_active_event(void *ctx, uint16_t event, 1876 uint16_t event_data_len, 1877 void *event_data) 1878 { 1879 struct vdev_mlme_obj *vdev_mlme = (struct vdev_mlme_obj *)ctx; 1880 enum QDF_OPMODE mode; 1881 struct wlan_objmgr_vdev *vdev; 1882 bool status; 1883 QDF_STATUS sm_status; 1884 1885 vdev = vdev_mlme->vdev; 1886 mode = wlan_vdev_mlme_get_opmode(vdev); 1887 1888 switch (event) { 1889 case WLAN_VDEV_SM_EV_START_SUCCESS: 1890 if (wlan_vdev_mlme_is_mlo_ap(vdev)) 1891 QDF_BUG(0); 1892 fallthrough; 1893 case WLAN_VDEV_SM_EV_MLO_SYNC_COMPLETE: 1894 mlme_vdev_update_beacon(vdev_mlme, BEACON_INIT, 1895 event_data_len, event_data); 1896 if (mlme_vdev_up_send(vdev_mlme, event_data_len, 1897 event_data) != QDF_STATUS_SUCCESS) { 1898 mlme_vdev_sm_deliver_event(vdev_mlme, 1899 WLAN_VDEV_SM_EV_UP_FAIL, 1900 event_data_len, event_data); 1901 } else { 1902 mlme_vdev_notify_up_complete(vdev_mlme, event_data_len, 1903 event_data); 1904 mlme_vdev_up_active_notify_mlo_mgr(vdev_mlme); 1905 } 1906 status = true; 1907 break; 1908 1909 case WLAN_VDEV_SM_EV_SUSPEND_RESTART: 1910 case WLAN_VDEV_SM_EV_HOST_RESTART: 1911 case WLAN_VDEV_SM_EV_CSA_RESTART: 1912 /* These events are not supported in STA mode */ 1913 if (mode == QDF_STA_MODE) 1914 QDF_BUG(0); 1915 fallthrough; 1916 case WLAN_VDEV_SM_EV_DOWN: 1917 mlme_vdev_sm_transition_to(vdev_mlme, WLAN_VDEV_S_SUSPEND); 1918 mlme_vdev_sm_deliver_event(vdev_mlme, event, 1919 event_data_len, event_data); 1920 status = true; 1921 break; 1922 1923 case WLAN_VDEV_SM_EV_RADAR_DETECTED: 1924 /* These events are not supported in STA mode */ 1925 if (mode == QDF_STA_MODE) 1926 QDF_BUG(0); 1927 mlme_vdev_sm_transition_to(vdev_mlme, WLAN_VDEV_S_SUSPEND); 1928 mlme_vdev_sm_deliver_event(vdev_mlme, 1929 WLAN_VDEV_SM_EV_CSA_RESTART, 1930 event_data_len, event_data); 1931 status = true; 1932 break; 1933 1934 case WLAN_VDEV_SM_EV_UP_HOST_RESTART: 1935 /* Reinit beacon, send template to FW(use ping-pong buffer) */ 1936 mlme_vdev_update_beacon(vdev_mlme, BEACON_UPDATE, 1937 event_data_len, event_data); 1938 fallthrough; 1939 case WLAN_VDEV_SM_EV_START: 1940 /* notify that UP command is completed */ 1941 mlme_vdev_notify_up_complete(vdev_mlme, 1942 event_data_len, event_data); 1943 status = true; 1944 break; 1945 1946 case WLAN_VDEV_SM_EV_FW_VDEV_RESTART: 1947 mlme_vdev_sm_transition_to(vdev_mlme, WLAN_VDEV_S_START); 1948 mlme_vdev_sm_deliver_event(vdev_mlme, 1949 WLAN_VDEV_SM_EV_RESTART_REQ, 1950 event_data_len, event_data); 1951 status = true; 1952 break; 1953 1954 case WLAN_VDEV_SM_EV_UP_FAIL: 1955 mlme_vdev_sm_transition_to(vdev_mlme, WLAN_VDEV_S_SUSPEND); 1956 mlme_vdev_sm_deliver_event(vdev_mlme, event, 1957 event_data_len, event_data); 1958 status = true; 1959 break; 1960 1961 case WLAN_VDEV_SM_EV_ROAM: 1962 sm_status = mlme_vdev_notify_roam_start(vdev_mlme, 1963 event_data_len, 1964 event_data); 1965 status = !sm_status; 1966 break; 1967 1968 default: 1969 status = false; 1970 break; 1971 } 1972 1973 return status; 1974 } 1975 1976 1977 static const char *vdev_sm_event_names[] = { 1978 "EV_START", 1979 "EV_START_REQ", 1980 "EV_RESTART_REQ", 1981 "EV_START_RESP", 1982 "EV_RESTART_RESP", 1983 "EV_START_REQ_FAIL", 1984 "EV_RESTART_REQ_FAIL", 1985 "EV_START_SUCCESS", 1986 "EV_CONN_PROGRESS", 1987 "EV_STA_CONN_START", 1988 "EV_DFS_CAC_WAIT", 1989 "EV_DFS_CAC_COMPLETED", 1990 "EV_DOWN", 1991 "EV_CONNECTION_FAIL", 1992 "EV_STOP_RESP", 1993 "EV_STOP_FAIL", 1994 "EV_DOWN_FAIL", 1995 "EV_DISCONNECT_COMPLETE", 1996 "EV_SUSPEND_RESTART", 1997 "EV_HOST_RESTART", 1998 "EV_UP_HOST_RESTART", 1999 "EV_FW_VDEV_RESTART", 2000 "EV_UP_FAIL", 2001 "EV_RADAR_DETECTED", 2002 "EV_CSA_RESTART", 2003 "EV_CSA_COMPLETE", 2004 "EV_MLME_DOWN_REQ", 2005 "EV_DOWN_COMPLETE", 2006 "EV_ROAM", 2007 "EV_STOP_REQ", 2008 "EV_CHAN_SWITCH_DISABLED", 2009 "EV_MLO_SYNC_COMPLETE", 2010 "EV_SUSPEND_CSA_RESTART" 2011 }; 2012 2013 struct wlan_sm_state_info sm_info[] = { 2014 { 2015 (uint8_t)WLAN_VDEV_S_INIT, 2016 (uint8_t)WLAN_SM_ENGINE_STATE_NONE, 2017 (uint8_t)WLAN_SM_ENGINE_STATE_NONE, 2018 true, 2019 "INIT", 2020 mlme_vdev_state_init_entry, 2021 mlme_vdev_state_init_exit, 2022 mlme_vdev_state_init_event 2023 }, 2024 { 2025 (uint8_t)WLAN_VDEV_S_START, 2026 (uint8_t)WLAN_SM_ENGINE_STATE_NONE, 2027 (uint8_t)WLAN_SM_ENGINE_STATE_NONE, 2028 true, 2029 "START", 2030 mlme_vdev_state_start_entry, 2031 mlme_vdev_state_start_exit, 2032 mlme_vdev_state_start_event 2033 }, 2034 { 2035 (uint8_t)WLAN_VDEV_S_DFS_CAC_WAIT, 2036 (uint8_t)WLAN_SM_ENGINE_STATE_NONE, 2037 (uint8_t)WLAN_SM_ENGINE_STATE_NONE, 2038 true, 2039 "DFS_CAC_WAIT", 2040 mlme_vdev_state_dfs_cac_wait_entry, 2041 mlme_vdev_state_dfs_cac_wait_exit, 2042 mlme_vdev_state_dfs_cac_wait_event 2043 }, 2044 { 2045 (uint8_t)WLAN_VDEV_S_UP, 2046 (uint8_t)WLAN_SM_ENGINE_STATE_NONE, 2047 (uint8_t)WLAN_SM_ENGINE_STATE_NONE, 2048 true, 2049 "UP", 2050 mlme_vdev_state_up_entry, 2051 mlme_vdev_state_up_exit, 2052 mlme_vdev_state_up_event 2053 }, 2054 { 2055 (uint8_t)WLAN_VDEV_S_SUSPEND, 2056 (uint8_t)WLAN_SM_ENGINE_STATE_NONE, 2057 (uint8_t)WLAN_SM_ENGINE_STATE_NONE, 2058 true, 2059 "SUSPEND", 2060 mlme_vdev_state_suspend_entry, 2061 mlme_vdev_state_suspend_exit, 2062 mlme_vdev_state_suspend_event 2063 }, 2064 { 2065 (uint8_t)WLAN_VDEV_S_STOP, 2066 (uint8_t)WLAN_SM_ENGINE_STATE_NONE, 2067 (uint8_t)WLAN_VDEV_SS_STOP_STOP_PROGRESS, 2068 true, 2069 "STOP", 2070 mlme_vdev_state_stop_entry, 2071 mlme_vdev_state_stop_exit, 2072 mlme_vdev_state_stop_event 2073 }, 2074 { 2075 (uint8_t)WLAN_VDEV_S_MAX, 2076 (uint8_t)WLAN_SM_ENGINE_STATE_NONE, 2077 (uint8_t)WLAN_SM_ENGINE_STATE_NONE, 2078 false, 2079 "INVALID", 2080 NULL, 2081 NULL, 2082 NULL 2083 }, 2084 { 2085 (uint8_t)WLAN_VDEV_SS_START_START_PROGRESS, 2086 (uint8_t)WLAN_VDEV_S_START, 2087 (uint8_t)WLAN_SM_ENGINE_STATE_NONE, 2088 false, 2089 "ST-START_PROG", 2090 mlme_vdev_subst_start_start_progress_entry, 2091 mlme_vdev_subst_start_start_progress_exit, 2092 mlme_vdev_subst_start_start_progress_event 2093 }, 2094 { 2095 (uint8_t)WLAN_VDEV_SS_START_RESTART_PROGRESS, 2096 (uint8_t)WLAN_VDEV_S_START, 2097 (uint8_t)WLAN_SM_ENGINE_STATE_NONE, 2098 false, 2099 "ST-RESTART_PROG", 2100 mlme_vdev_subst_start_restart_progress_entry, 2101 mlme_vdev_subst_start_restart_progress_exit, 2102 mlme_vdev_subst_start_restart_progress_event 2103 }, 2104 { 2105 (uint8_t)WLAN_VDEV_SS_START_CONN_PROGRESS, 2106 (uint8_t)WLAN_VDEV_S_START, 2107 (uint8_t)WLAN_SM_ENGINE_STATE_NONE, 2108 false, 2109 "ST-CONN_PROG", 2110 mlme_vdev_subst_start_conn_progress_entry, 2111 mlme_vdev_subst_start_conn_progress_exit, 2112 mlme_vdev_subst_start_conn_progress_event 2113 }, 2114 { 2115 (uint8_t)WLAN_VDEV_SS_START_DISCONN_PROGRESS, 2116 (uint8_t)WLAN_VDEV_S_START, 2117 (uint8_t)WLAN_SM_ENGINE_STATE_NONE, 2118 false, 2119 "ST-DISCONN_PROG", 2120 mlme_vdev_subst_start_disconn_progress_entry, 2121 mlme_vdev_subst_start_disconn_progress_exit, 2122 mlme_vdev_subst_start_disconn_progress_event 2123 }, 2124 { 2125 (uint8_t)WLAN_VDEV_SS_SUSPEND_SUSPEND_DOWN, 2126 (uint8_t)WLAN_VDEV_S_SUSPEND, 2127 (uint8_t)WLAN_SM_ENGINE_STATE_NONE, 2128 false, 2129 "SP-SUSPEND_DOWN", 2130 mlme_vdev_subst_suspend_suspend_down_entry, 2131 mlme_vdev_subst_suspend_suspend_down_exit, 2132 mlme_vdev_subst_suspend_suspend_down_event 2133 }, 2134 { 2135 (uint8_t)WLAN_VDEV_SS_SUSPEND_SUSPEND_RESTART, 2136 (uint8_t)WLAN_VDEV_S_SUSPEND, 2137 (uint8_t)WLAN_SM_ENGINE_STATE_NONE, 2138 false, 2139 "SP-SUSPEND_RESTART", 2140 mlme_vdev_subst_suspend_suspend_restart_entry, 2141 mlme_vdev_subst_suspend_suspend_restart_exit, 2142 mlme_vdev_subst_suspend_suspend_restart_event 2143 }, 2144 { 2145 (uint8_t)WLAN_VDEV_SS_SUSPEND_HOST_RESTART, 2146 (uint8_t)WLAN_VDEV_S_SUSPEND, 2147 (uint8_t)WLAN_SM_ENGINE_STATE_NONE, 2148 false, 2149 "SP-HOST_RESTART", 2150 mlme_vdev_subst_suspend_host_restart_entry, 2151 mlme_vdev_subst_suspend_host_restart_exit, 2152 mlme_vdev_subst_suspend_host_restart_event 2153 }, 2154 { 2155 (uint8_t)WLAN_VDEV_SS_SUSPEND_CSA_RESTART, 2156 (uint8_t)WLAN_VDEV_S_SUSPEND, 2157 (uint8_t)WLAN_SM_ENGINE_STATE_NONE, 2158 false, 2159 "SP-CSA_RESTART", 2160 mlme_vdev_subst_suspend_csa_restart_entry, 2161 mlme_vdev_subst_suspend_csa_restart_exit, 2162 mlme_vdev_subst_suspend_csa_restart_event 2163 }, 2164 { 2165 (uint8_t)WLAN_VDEV_SS_STOP_STOP_PROGRESS, 2166 (uint8_t)WLAN_VDEV_S_STOP, 2167 (uint8_t)WLAN_SM_ENGINE_STATE_NONE, 2168 false, 2169 "STOP-STOP_PROG", 2170 mlme_vdev_subst_stop_stop_progress_entry, 2171 mlme_vdev_subst_stop_stop_progress_exit, 2172 mlme_vdev_subst_stop_stop_progress_event 2173 }, 2174 { 2175 (uint8_t)WLAN_VDEV_SS_STOP_DOWN_PROGRESS, 2176 (uint8_t)WLAN_VDEV_S_STOP, 2177 (uint8_t)WLAN_SM_ENGINE_STATE_NONE, 2178 false, 2179 "STOP-DOWN_PROG", 2180 mlme_vdev_subst_stop_down_progress_entry, 2181 mlme_vdev_subst_stop_down_progress_exit, 2182 mlme_vdev_subst_stop_down_progress_event 2183 }, 2184 { 2185 (uint8_t)WLAN_VDEV_SS_IDLE, 2186 (uint8_t)WLAN_SM_ENGINE_STATE_NONE, 2187 (uint8_t)WLAN_SM_ENGINE_STATE_NONE, 2188 false, 2189 "IDLE", 2190 NULL, 2191 NULL, 2192 NULL, 2193 }, 2194 { 2195 (uint8_t)WLAN_VDEV_SS_MLO_SYNC_WAIT, 2196 (uint8_t)WLAN_VDEV_S_UP, 2197 (uint8_t)WLAN_SM_ENGINE_STATE_NONE, 2198 false, 2199 "UP-MLO_SYNC_WAIT", 2200 mlme_vdev_subst_mlo_sync_wait_entry, 2201 mlme_vdev_subst_mlo_sync_wait_exit, 2202 mlme_vdev_subst_mlo_sync_wait_event 2203 }, 2204 { 2205 (uint8_t)WLAN_VDEV_SS_UP_ACTIVE, 2206 (uint8_t)WLAN_VDEV_S_UP, 2207 (uint8_t)WLAN_SM_ENGINE_STATE_NONE, 2208 false, 2209 "UP-UP_ACTIVE", 2210 mlme_vdev_subst_up_active_entry, 2211 mlme_vdev_subst_up_active_exit, 2212 mlme_vdev_subst_up_active_event 2213 }, 2214 { 2215 (uint8_t)WLAN_VDEV_SS_MAX, 2216 (uint8_t)WLAN_SM_ENGINE_STATE_NONE, 2217 (uint8_t)WLAN_SM_ENGINE_STATE_NONE, 2218 false, 2219 "INVALID", 2220 NULL, 2221 NULL, 2222 NULL, 2223 }, 2224 }; 2225 2226 QDF_STATUS mlme_vdev_sm_deliver_event(struct vdev_mlme_obj *vdev_mlme, 2227 enum wlan_vdev_sm_evt event, 2228 uint16_t event_data_len, void *event_data) 2229 { 2230 return wlan_sm_dispatch(vdev_mlme->sm_hdl, event, 2231 event_data_len, event_data); 2232 } 2233 2234 void mlme_vdev_sm_print_state_event(struct vdev_mlme_obj *vdev_mlme, 2235 enum wlan_vdev_sm_evt event) 2236 { 2237 enum wlan_vdev_state state; 2238 enum wlan_vdev_state substate; 2239 struct wlan_objmgr_vdev *vdev; 2240 2241 vdev = vdev_mlme->vdev; 2242 2243 state = wlan_vdev_mlme_get_state(vdev); 2244 substate = wlan_vdev_mlme_get_substate(vdev); 2245 2246 mlme_nofl_debug("[%s]%s - %s, %s", vdev_mlme->sm_hdl->name, 2247 sm_info[state].name, sm_info[substate].name, 2248 vdev_sm_event_names[event]); 2249 } 2250 2251 void mlme_vdev_sm_print_state(struct vdev_mlme_obj *vdev_mlme) 2252 { 2253 enum wlan_vdev_state state; 2254 enum wlan_vdev_state substate; 2255 struct wlan_objmgr_vdev *vdev; 2256 2257 vdev = vdev_mlme->vdev; 2258 2259 state = wlan_vdev_mlme_get_state(vdev); 2260 substate = wlan_vdev_mlme_get_substate(vdev); 2261 2262 mlme_nofl_debug("[%s]%s - %s", vdev_mlme->sm_hdl->name, 2263 sm_info[state].name, sm_info[substate].name); 2264 } 2265 2266 #ifdef SM_ENG_HIST_ENABLE 2267 void mlme_vdev_sm_history_print(struct vdev_mlme_obj *vdev_mlme) 2268 { 2269 return wlan_sm_print_history(vdev_mlme->sm_hdl); 2270 } 2271 #endif 2272 2273 QDF_STATUS mlme_vdev_sm_create(struct vdev_mlme_obj *vdev_mlme) 2274 { 2275 struct wlan_sm *sm; 2276 uint8_t name[WLAN_SM_ENGINE_MAX_NAME]; 2277 struct wlan_objmgr_vdev *vdev = vdev_mlme->vdev; 2278 2279 qdf_scnprintf(name, sizeof(name), "VM-PS_%d-VD_%d", 2280 wlan_psoc_get_id(wlan_vdev_get_psoc(vdev)), 2281 wlan_vdev_get_id(vdev)); 2282 sm = wlan_sm_create(name, vdev_mlme, 2283 WLAN_VDEV_S_INIT, 2284 sm_info, 2285 QDF_ARRAY_SIZE(sm_info), 2286 vdev_sm_event_names, 2287 QDF_ARRAY_SIZE(vdev_sm_event_names)); 2288 if (!sm) { 2289 mlme_err("VDEV MLME SM allocation failed"); 2290 return QDF_STATUS_E_FAILURE; 2291 } 2292 vdev_mlme->sm_hdl = sm; 2293 wlan_minidump_log((void *)sm, sizeof(*sm), 2294 wlan_vdev_get_psoc(vdev), 2295 WLAN_MD_OBJMGR_VDEV_SM, "wlan_sm"); 2296 2297 mlme_vdev_sm_spinlock_create(vdev_mlme); 2298 2299 mlme_vdev_cmd_mutex_create(vdev_mlme); 2300 2301 return QDF_STATUS_SUCCESS; 2302 } 2303 2304 QDF_STATUS mlme_vdev_sm_destroy(struct vdev_mlme_obj *vdev_mlme) 2305 { 2306 struct wlan_objmgr_vdev *vdev = vdev_mlme->vdev; 2307 2308 mlme_vdev_cmd_mutex_destroy(vdev_mlme); 2309 2310 mlme_vdev_sm_spinlock_destroy(vdev_mlme); 2311 2312 wlan_minidump_remove(vdev_mlme->sm_hdl, 2313 sizeof(*vdev_mlme->sm_hdl), 2314 wlan_vdev_get_psoc(vdev), 2315 WLAN_MD_OBJMGR_VDEV_SM, "wlan_sm"); 2316 2317 wlan_sm_delete(vdev_mlme->sm_hdl); 2318 2319 return QDF_STATUS_SUCCESS; 2320 } 2321