1 /* 2 * Copyright (c) 2020, The Linux Foundation. All rights reserved. 3 * 4 * Permission to use, copy, modify, and/or distribute this software for any 5 * purpose with or without fee is hereby granted, provided that the above 6 * copyright notice and this permission notice appear in all copies. 7 * 8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 */ 16 17 /** 18 * DOC: Implements general SM framework for connection manager 19 */ 20 21 #include "wlan_cm_main.h" 22 #include "wlan_cm_sm.h" 23 #include "wlan_cm_roam_sm.h" 24 25 void mlme_cm_set_state(struct cnx_mgr *cm_ctx, enum wlan_cm_sm_state state) 26 { 27 if (state < WLAN_CM_S_MAX) 28 cm_ctx->sm.cm_state = state; 29 else 30 mlme_err("mlme state (%d) is invalid", state); 31 } 32 33 void mlme_cm_set_substate(struct cnx_mgr *cm_ctx, 34 enum wlan_cm_sm_state substate) 35 { 36 if ((substate > WLAN_CM_S_MAX) && (substate < WLAN_CM_SS_MAX)) 37 cm_ctx->sm.cm_substate = substate; 38 else 39 mlme_err(" mlme sub state (%d) is invalid", substate); 40 } 41 42 void mlme_cm_sm_state_update(struct cnx_mgr *cm_ctx, 43 enum wlan_cm_sm_state state, 44 enum wlan_cm_sm_state substate) 45 { 46 if (!cm_ctx) { 47 mlme_err("cm_ctx is NULL"); 48 return; 49 } 50 51 mlme_cm_set_state(cm_ctx, state); 52 mlme_cm_set_substate(cm_ctx, substate); 53 } 54 55 /** 56 * mlme_cm_state_init_entry() - Entry API for init state for connection mgr 57 * @ctx: connection manager ctx 58 * 59 * API to perform operations on moving to init state 60 * 61 * Return: void 62 */ 63 static void mlme_cm_state_init_entry(void *ctx) 64 { 65 struct cnx_mgr *cm_ctx = (struct cnx_mgr *)ctx; 66 67 mlme_cm_sm_state_update(cm_ctx, WLAN_CM_S_INIT, WLAN_CM_SS_IDLE); 68 } 69 70 /** 71 * mlme_cm_state_init_exit() - Exit API for init state for connection mgr 72 * @ctx: connection manager ctx 73 * 74 * API to perform operations on exiting from init state 75 * 76 * Return: void 77 */ 78 static void mlme_cm_state_init_exit(void *ctx) 79 { 80 } 81 82 /** 83 * mlme_cm_state_init_event() - Init State event handler for connection mgr 84 * @ctx: connection manager ctx 85 * 86 * API to handle events in INIT state 87 * 88 * Return: bool 89 */ 90 static bool mlme_cm_state_init_event(void *ctx, uint16_t event, 91 uint16_t event_data_len, 92 void *event_data) 93 { 94 // struct cnx_mgr *cm_ctx = (struct cnx_mgr *)ctx; 95 bool status; 96 97 switch (event) { 98 default: 99 status = false; 100 break; 101 } 102 103 return status; 104 } 105 106 /** 107 * mlme_cm_state_connecting_entry() - Entry API for connecting state for 108 * connection mgr 109 * @ctx: connection manager ctx 110 * 111 * API to perform operations on moving to connecting state 112 * 113 * Return: void 114 */ 115 static void mlme_cm_state_connecting_entry(void *ctx) 116 { 117 struct cnx_mgr *cm_ctx = (struct cnx_mgr *)ctx; 118 119 mlme_cm_sm_state_update(cm_ctx, WLAN_CM_S_CONNECTING, WLAN_CM_SS_IDLE); 120 } 121 122 /** 123 * mlme_cm_state_connecting_exit() - Exit API for connecting state for 124 * connection mgr 125 * @ctx: connection manager ctx 126 * 127 * API to perform operations on exiting from connecting state 128 * 129 * Return: void 130 */ 131 static void mlme_cm_state_connecting_exit(void *ctx) 132 { 133 } 134 135 /** 136 * mlme_cm_state_connecting_event() - Connecting State event handler for 137 * connection mgr 138 * @ctx: connection manager ctx 139 * 140 * API to handle events in CONNECTING state 141 * 142 * Return: bool 143 */ 144 static bool mlme_cm_state_connecting_event(void *ctx, uint16_t event, 145 uint16_t event_data_len, 146 void *event_data) 147 { 148 // struct cnx_mgr *cm_ctx = (struct cnx_mgr *)ctx; 149 bool status; 150 151 switch (event) { 152 default: 153 status = false; 154 break; 155 } 156 157 return status; 158 } 159 160 /** 161 * mlme_cm_state_connected_entry() - Entry API for connected state for 162 * connection mgr 163 * @ctx: connection manager ctx 164 * 165 * API to perform operations on moving to connected state 166 * 167 * Return: void 168 */ 169 static void mlme_cm_state_connected_entry(void *ctx) 170 { 171 struct cnx_mgr *cm_ctx = (struct cnx_mgr *)ctx; 172 173 mlme_cm_sm_state_update(cm_ctx, WLAN_CM_S_CONNECTED, WLAN_CM_SS_IDLE); 174 } 175 176 /** 177 * mlme_cm_state_connected_exit() - Exit API for connected state for 178 * connection mgr 179 * @ctx: connection manager ctx 180 * 181 * API to perform operations on exiting from connected state 182 * 183 * Return: void 184 */ 185 static void mlme_cm_state_connected_exit(void *ctx) 186 { 187 } 188 189 /** 190 * mlme_cm_state_connected_event() - Connected State event handler for 191 * connection mgr 192 * @ctx: connection manager ctx 193 * 194 * API to handle events in CONNECTED state 195 * 196 * Return: bool 197 */ 198 static bool mlme_cm_state_connected_event(void *ctx, uint16_t event, 199 uint16_t event_data_len, 200 void *event_data) 201 { 202 // struct cnx_mgr *cm_ctx = (struct cnx_mgr *)ctx; 203 bool status; 204 205 switch (event) { 206 default: 207 status = false; 208 break; 209 } 210 211 return status; 212 } 213 214 /** 215 * mlme_cm_state_disconnecting_entry() - Entry API for disconnecting state for 216 * connection mgr 217 * @ctx: connection manager ctx 218 * 219 * API to perform operations on moving to disconnecting state 220 * 221 * Return: void 222 */ 223 static void mlme_cm_state_disconnecting_entry(void *ctx) 224 { 225 struct cnx_mgr *cm_ctx = (struct cnx_mgr *)ctx; 226 227 mlme_cm_sm_state_update(cm_ctx, WLAN_CM_S_DISCONNECTING, 228 WLAN_CM_SS_IDLE); 229 } 230 231 /** 232 * mlme_cm_state_disconnecting_exit() - Exit API for disconnecting state for 233 * connection mgr 234 * @ctx: connection manager ctx 235 * 236 * API to perform operations on exiting from disconnecting state 237 * 238 * Return: void 239 */ 240 static void mlme_cm_state_disconnecting_exit(void *ctx) 241 { 242 } 243 244 /** 245 * mlme_cm_state_connected_event() - Disconnecting State event handler for 246 * connection mgr 247 * @ctx: connection manager ctx 248 * 249 * API to handle events in Disconnecting state 250 * 251 * Return: bool 252 */ 253 static bool mlme_cm_state_disconnecting_event(void *ctx, uint16_t event, 254 uint16_t event_data_len, 255 void *event_data) 256 { 257 // struct cnx_mgr *cm_ctx = (struct cnx_mgr *)ctx; 258 bool status; 259 260 switch (event) { 261 default: 262 status = false; 263 break; 264 } 265 266 return status; 267 } 268 269 /** 270 * mlme_cm_subst_join_pending_entry() - Entry API for join pending sub-state for 271 * connection mgr 272 * @ctx: connection manager ctx 273 * 274 * API to perform operations on moving to join pending sub-state 275 * 276 * Return: void 277 */ 278 static void mlme_cm_subst_join_pending_entry(void *ctx) 279 { 280 struct cnx_mgr *cm_ctx = (struct cnx_mgr *)ctx; 281 282 if (mlme_cm_get_state(cm_ctx) != WLAN_CM_S_CONNECTING) 283 QDF_BUG(0); 284 285 mlme_cm_set_substate(cm_ctx, WLAN_CM_SS_JOIN_PENDING); 286 } 287 288 /** 289 * mlme_cm_subst_join_pending_exit() - Exit API for join pending sub-state for 290 * connection mgr 291 * @ctx: connection manager ctx 292 * 293 * API to perform operations on exiting from join pending sub-state 294 * 295 * Return: void 296 */ 297 static void mlme_cm_subst_join_pending_exit(void *ctx) 298 { 299 } 300 301 /** 302 * mlme_cm_subst_join_pending_event() - Join pending sub-state event handler for 303 * connection mgr 304 * @ctx: connection manager ctx 305 * 306 * API to handle events in Join pending sub-state 307 * 308 * Return: bool 309 */ 310 static bool mlme_cm_subst_join_pending_event(void *ctx, uint16_t event, 311 uint16_t event_data_len, 312 void *event_data) 313 { 314 // struct cnx_mgr *cm_ctx = (struct cnx_mgr *)ctx; 315 bool status; 316 317 switch (event) { 318 default: 319 status = false; 320 break; 321 } 322 323 return status; 324 } 325 326 /** 327 * mlme_cm_subst_scan_entry() - Entry API for scan sub-state for 328 * connection mgr 329 * @ctx: connection manager ctx 330 * 331 * API to perform operations on moving to scan sub-state 332 * 333 * Return: void 334 */ 335 static void mlme_cm_subst_scan_entry(void *ctx) 336 { 337 struct cnx_mgr *cm_ctx = (struct cnx_mgr *)ctx; 338 339 if (mlme_cm_get_state(cm_ctx) != WLAN_CM_S_CONNECTING) 340 QDF_BUG(0); 341 342 mlme_cm_set_substate(cm_ctx, WLAN_CM_SS_SCAN); 343 } 344 345 /** 346 * mlme_cm_subst_scan_exit() - Exit API for scan sub-state for 347 * connection mgr 348 * @ctx: connection manager ctx 349 * 350 * API to perform operations on exiting from scan sub-state 351 * 352 * Return: void 353 */ 354 static void mlme_cm_subst_scan_exit(void *ctx) 355 { 356 } 357 358 /** 359 * mlme_cm_subst_scan_event() - Scan sub-state event handler for 360 * connection mgr 361 * @ctx: connection manager ctx 362 * 363 * API to handle events in scan sub-state 364 * 365 * Return: bool 366 */ 367 static bool mlme_cm_subst_scan_event(void *ctx, uint16_t event, 368 uint16_t event_data_len, void *event_data) 369 { 370 // struct cnx_mgr *cm_ctx = (struct cnx_mgr *)ctx; 371 bool status; 372 373 switch (event) { 374 default: 375 status = false; 376 break; 377 } 378 379 return status; 380 } 381 382 /** 383 * mlme_cm_subst_join_active_entry() - Entry API for join active sub-state for 384 * connection mgr 385 * @ctx: connection manager ctx 386 * 387 * API to perform operations on moving to join active sub-state 388 * 389 * Return: void 390 */ 391 static void mlme_cm_subst_join_active_entry(void *ctx) 392 { 393 struct cnx_mgr *cm_ctx = (struct cnx_mgr *)ctx; 394 395 if (mlme_cm_get_state(cm_ctx) != WLAN_CM_S_CONNECTING) 396 QDF_BUG(0); 397 398 mlme_cm_set_substate(cm_ctx, WLAN_CM_SS_JOIN_ACTIVE); 399 } 400 401 /** 402 * mlme_cm_subst_join_active_exit() - Exit API for join active sub-state for 403 * connection mgr 404 * @ctx: connection manager ctx 405 * 406 * API to perform operations on exiting from join active sub-state 407 * 408 * Return: void 409 */ 410 static void mlme_cm_subst_join_active_exit(void *ctx) 411 { 412 } 413 414 /** 415 * mlme_cm_subst_join_active_event() - Join active sub-state event handler for 416 * connection mgr 417 * @ctx: connection manager ctx 418 * 419 * API to handle events in join active sub-state 420 * 421 * Return: bool 422 */ 423 static bool mlme_cm_subst_join_active_event(void *ctx, uint16_t event, 424 uint16_t event_data_len, 425 void *event_data) 426 { 427 // struct cnx_mgr *cm_ctx = (struct cnx_mgr *)ctx; 428 bool status; 429 430 switch (event) { 431 default: 432 status = false; 433 break; 434 } 435 436 return status; 437 } 438 439 struct wlan_sm_state_info cm_sm_info[] = { 440 { 441 (uint8_t)WLAN_CM_S_INIT, 442 (uint8_t)WLAN_SM_ENGINE_STATE_NONE, 443 (uint8_t)WLAN_SM_ENGINE_STATE_NONE, 444 true, 445 "INIT", 446 mlme_cm_state_init_entry, 447 mlme_cm_state_init_exit, 448 mlme_cm_state_init_event 449 }, 450 { 451 (uint8_t)WLAN_CM_S_CONNECTING, 452 (uint8_t)WLAN_SM_ENGINE_STATE_NONE, 453 (uint8_t)WLAN_SM_ENGINE_STATE_NONE, 454 true, 455 "CONNECTING", 456 mlme_cm_state_connecting_entry, 457 mlme_cm_state_connecting_exit, 458 mlme_cm_state_connecting_event 459 }, 460 { 461 (uint8_t)WLAN_CM_S_CONNECTED, 462 (uint8_t)WLAN_SM_ENGINE_STATE_NONE, 463 (uint8_t)WLAN_SM_ENGINE_STATE_NONE, 464 true, 465 "CONNECTED", 466 mlme_cm_state_connected_entry, 467 mlme_cm_state_connected_exit, 468 mlme_cm_state_connected_event 469 }, 470 { 471 (uint8_t)WLAN_CM_S_DISCONNECTING, 472 (uint8_t)WLAN_SM_ENGINE_STATE_NONE, 473 (uint8_t)WLAN_SM_ENGINE_STATE_NONE, 474 true, 475 "DISCONNECTING", 476 mlme_cm_state_disconnecting_entry, 477 mlme_cm_state_disconnecting_exit, 478 mlme_cm_state_disconnecting_event 479 }, 480 { 481 (uint8_t)WLAN_CM_S_ROAMING, 482 (uint8_t)WLAN_SM_ENGINE_STATE_NONE, 483 (uint8_t)WLAN_SM_ENGINE_STATE_NONE, 484 true, 485 "ROAMING", 486 mlme_cm_state_roaming_entry, 487 mlme_cm_state_roaming_exit, 488 mlme_cm_state_roaming_event 489 }, 490 { 491 (uint8_t)WLAN_CM_S_MAX, 492 (uint8_t)WLAN_SM_ENGINE_STATE_NONE, 493 (uint8_t)WLAN_SM_ENGINE_STATE_NONE, 494 false, 495 "INVALID", 496 NULL, 497 NULL, 498 NULL 499 }, 500 { 501 (uint8_t)WLAN_CM_SS_IDLE, 502 (uint8_t)WLAN_SM_ENGINE_STATE_NONE, 503 (uint8_t)WLAN_SM_ENGINE_STATE_NONE, 504 false, 505 "IDLE", 506 NULL, 507 NULL, 508 NULL 509 }, 510 { 511 (uint8_t)WLAN_CM_SS_JOIN_PENDING, 512 (uint8_t)WLAN_CM_S_CONNECTING, 513 (uint8_t)WLAN_SM_ENGINE_STATE_NONE, 514 false, 515 "JOIN_PENDING", 516 mlme_cm_subst_join_pending_entry, 517 mlme_cm_subst_join_pending_exit, 518 mlme_cm_subst_join_pending_event 519 }, 520 { 521 (uint8_t)WLAN_CM_SS_SCAN, 522 (uint8_t)WLAN_CM_S_CONNECTING, 523 (uint8_t)WLAN_SM_ENGINE_STATE_NONE, 524 false, 525 "SCAN", 526 mlme_cm_subst_scan_entry, 527 mlme_cm_subst_scan_exit, 528 mlme_cm_subst_scan_event 529 }, 530 { 531 (uint8_t)WLAN_CM_SS_JOIN_ACTIVE, 532 (uint8_t)WLAN_CM_S_CONNECTING, 533 (uint8_t)WLAN_SM_ENGINE_STATE_NONE, 534 false, 535 "JOIN_ACTIVE", 536 mlme_cm_subst_join_active_entry, 537 mlme_cm_subst_join_active_exit, 538 mlme_cm_subst_join_active_event 539 }, 540 #ifdef WLAN_FEATURE_HOST_ROAM 541 { 542 (uint8_t)WLAN_CM_SS_PREAUTH, 543 (uint8_t)WLAN_CM_S_ROAMING, 544 (uint8_t)WLAN_SM_ENGINE_STATE_NONE, 545 false, 546 "PREAUTH", 547 mlme_cm_subst_preauth_entry, 548 mlme_cm_subst_preauth_exit, 549 mlme_cm_subst_preauth_event 550 }, 551 { 552 (uint8_t)WLAN_CM_SS_REASSOC, 553 (uint8_t)WLAN_CM_S_ROAMING, 554 (uint8_t)WLAN_SM_ENGINE_STATE_NONE, 555 false, 556 "REASSOC", 557 mlme_cm_subst_reassoc_entry, 558 mlme_cm_subst_reassoc_exit, 559 mlme_cm_subst_reassoc_event 560 }, 561 #endif 562 #ifdef WLAN_FEATURE_ROAM_OFFLOAD 563 { 564 (uint8_t)WLAN_CM_SS_ROAM_STARTED, 565 (uint8_t)WLAN_CM_S_ROAMING, 566 (uint8_t)WLAN_SM_ENGINE_STATE_NONE, 567 false, 568 "ROAM_START", 569 mlme_cm_subst_roam_start_entry, 570 mlme_cm_subst_roam_start_exit, 571 mlme_cm_subst_roam_start_event 572 }, 573 { 574 (uint8_t)WLAN_CM_SS_ROAM_SYNC, 575 (uint8_t)WLAN_CM_S_ROAMING, 576 (uint8_t)WLAN_SM_ENGINE_STATE_NONE, 577 false, 578 "ROAM_SYNC", 579 mlme_cm_subst_roam_sync_entry, 580 mlme_cm_subst_roam_sync_exit, 581 mlme_cm_subst_roam_sync_event 582 }, 583 #endif 584 { 585 (uint8_t)WLAN_CM_SS_MAX, 586 (uint8_t)WLAN_SM_ENGINE_STATE_NONE, 587 (uint8_t)WLAN_SM_ENGINE_STATE_NONE, 588 false, 589 "INVALID", 590 NULL, 591 NULL, 592 NULL 593 }, 594 }; 595 596 static const char *cm_sm_event_names[] = { 597 "EV_CONNECT_REQ", 598 "EV_SCAN_FOR_SSID", 599 "EV_SCAN_FOR_SSID_SUCCESS", 600 "EV_SCAN_FOR_SSID_FAILURE", 601 "EV_CONNECT_START_REQ", 602 "EV_CONNECT_START", 603 "EV_CONNECT_SUCCESS", 604 "EV_CONNECT_NEXT_CANDIDATE", 605 "EV_CONNECT_FAILURE", 606 "EV_DISCONNECT_REQ", 607 "EV_DISCONNECT_START_REQ", 608 "EV_DISCONNECT_START", 609 "EV_DISCONNECT_DONE", 610 "EV_ROAM_START", 611 "EV_ROAM_SYNC", 612 "EV_ROAM_INVOKE_FAIL", 613 "EV_ROAM_HO_FAIL", 614 "EV_PREAUTH_DONE", 615 "EV_GET_NEXT_PREAUTH_AP", 616 "EV_PREAUTH_FAIL", 617 "EV_START_REASSOC", 618 "EV_REASSOC_DONE", 619 "EV_REASSOC_FAILURE", 620 "EV_ROAM_COMPLETE", 621 "EV_CONNECT_TIMEOUT", 622 "EV_CONNECT_SER_FAIL", 623 "EV_HW_MODE_CHANGE_FAIL", 624 }; 625 626 enum wlan_cm_sm_state mlme_cm_get_state(struct cnx_mgr *cm_ctx) 627 { 628 enum QDF_OPMODE op_mode; 629 630 if (!cm_ctx || !cm_ctx->vdev) 631 return WLAN_CM_S_MAX; 632 633 op_mode = wlan_vdev_mlme_get_opmode(cm_ctx->vdev); 634 635 if (op_mode != QDF_STA_MODE && op_mode != QDF_P2P_CLIENT_MODE) 636 return WLAN_CM_S_MAX; 637 638 return cm_ctx->sm.cm_state; 639 } 640 641 enum wlan_cm_sm_state mlme_cm_get_sub_state(struct cnx_mgr *cm_ctx) 642 { 643 enum QDF_OPMODE op_mode; 644 645 if (!cm_ctx || !cm_ctx->vdev) 646 return WLAN_CM_SS_MAX; 647 648 op_mode = wlan_vdev_mlme_get_opmode(cm_ctx->vdev); 649 650 if (op_mode != QDF_STA_MODE && op_mode != QDF_P2P_CLIENT_MODE) 651 return WLAN_CM_SS_MAX; 652 653 return cm_ctx->sm.cm_substate; 654 } 655 656 static inline 657 QDF_STATUS mlme_cm_sm_deliver_event(struct cnx_mgr *cm_ctx, 658 enum wlan_cm_sm_evt event, 659 uint16_t event_data_len, void *event_data) 660 { 661 return wlan_sm_dispatch(cm_ctx->sm.sm_hdl, event, 662 event_data_len, event_data); 663 } 664 665 static void mlme_cm_sm_print_state_event(struct cnx_mgr *cm_ctx, 666 enum wlan_cm_sm_evt event) 667 { 668 enum wlan_cm_sm_state state; 669 enum wlan_cm_sm_state substate; 670 671 state = mlme_cm_get_state(cm_ctx); 672 substate = mlme_cm_get_sub_state(cm_ctx); 673 674 mlme_nofl_debug("[%s]%s - %s, %s", cm_ctx->sm.sm_hdl->name, 675 cm_sm_info[state].name, cm_sm_info[substate].name, 676 cm_sm_event_names[event]); 677 } 678 679 static void mlme_cm_sm_print_state(struct cnx_mgr *cm_ctx) 680 { 681 enum wlan_cm_sm_state state; 682 enum wlan_cm_sm_state substate; 683 684 state = mlme_cm_get_state(cm_ctx); 685 substate = mlme_cm_get_sub_state(cm_ctx); 686 687 mlme_nofl_debug("[%s]%s - %s", cm_ctx->sm.sm_hdl->name, 688 cm_sm_info[state].name, cm_sm_info[substate].name); 689 } 690 691 QDF_STATUS mlme_cm_sm_deliver_evt(struct wlan_objmgr_vdev *vdev, 692 enum wlan_cm_sm_evt event, 693 uint16_t event_data_len, 694 void *event_data) 695 { 696 struct vdev_mlme_obj *vdev_mlme; 697 QDF_STATUS status; 698 enum wlan_cm_sm_state state_entry, state_exit; 699 enum wlan_cm_sm_state substate_entry, substate_exit; 700 enum QDF_OPMODE op_mode = wlan_vdev_mlme_get_opmode(vdev); 701 struct cnx_mgr *cm_ctx; 702 703 if (op_mode != QDF_STA_MODE && op_mode != QDF_P2P_CLIENT_MODE) { 704 mlme_err("Invalid mode %d", op_mode); 705 return QDF_STATUS_E_NOSUPPORT; 706 } 707 708 vdev_mlme = wlan_vdev_mlme_get_cmpt_obj(vdev); 709 if (!vdev_mlme || !vdev_mlme->cnx_mgr_ctx) { 710 mlme_err("vdev mlme or cm ctx is NULL"); 711 return QDF_STATUS_E_FAILURE; 712 } 713 cm_ctx = vdev_mlme->cnx_mgr_ctx; 714 mlme_cm_lock_acquire(cm_ctx); 715 716 /* store entry state and sub state for prints */ 717 state_entry = mlme_cm_get_state(cm_ctx); 718 substate_entry = mlme_cm_get_sub_state(cm_ctx); 719 mlme_cm_sm_print_state_event(cm_ctx, event); 720 721 status = mlme_cm_sm_deliver_event(cm_ctx, event, event_data_len, 722 event_data); 723 /* Take exit state, exit substate for prints */ 724 state_exit = mlme_cm_get_state(cm_ctx); 725 substate_exit = mlme_cm_get_sub_state(cm_ctx); 726 /* If no state and substate change, don't print */ 727 if (!((state_entry == state_exit) && (substate_entry == substate_exit))) 728 mlme_cm_sm_print_state(cm_ctx); 729 mlme_cm_lock_release(cm_ctx); 730 731 return status; 732 } 733 734 QDF_STATUS mlme_cm_sm_create(struct cnx_mgr *cm_ctx) 735 { 736 struct wlan_sm *sm; 737 uint8_t name[WLAN_SM_ENGINE_MAX_NAME]; 738 739 qdf_snprintf(name, sizeof(name), "CM-VDEV-%d", 740 wlan_vdev_get_id(cm_ctx->vdev)); 741 sm = wlan_sm_create(name, cm_ctx, 742 WLAN_CM_S_INIT, 743 cm_sm_info, 744 QDF_ARRAY_SIZE(cm_sm_info), 745 cm_sm_event_names, 746 QDF_ARRAY_SIZE(cm_sm_event_names)); 747 if (!sm) { 748 mlme_err("CM MLME SM allocation failed"); 749 return QDF_STATUS_E_NOMEM; 750 } 751 cm_ctx->sm.sm_hdl = sm; 752 753 mlme_cm_lock_create(cm_ctx); 754 755 return QDF_STATUS_SUCCESS; 756 } 757 758 QDF_STATUS mlme_cm_sm_destroy(struct cnx_mgr *cm_ctx) 759 { 760 mlme_cm_lock_destroy(cm_ctx); 761 wlan_sm_delete(cm_ctx->sm.sm_hdl); 762 763 return QDF_STATUS_SUCCESS; 764 } 765