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