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 */
mlme_vdev_set_state(struct wlan_objmgr_vdev * vdev,enum wlan_vdev_state state)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 */
mlme_vdev_set_substate(struct wlan_objmgr_vdev * vdev,enum wlan_vdev_state substate)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 */
mlme_vdev_sm_state_update(struct vdev_mlme_obj * vdev_mlme,enum wlan_vdev_state state,enum wlan_vdev_state substate)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 */
mlme_vdev_sm_transition_to(struct vdev_mlme_obj * vdev_mlme,enum wlan_vdev_state state)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 */
mlme_vdev_state_init_entry(void * ctx)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 */
mlme_vdev_state_init_exit(void * ctx)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 */
mlme_vdev_state_init_event(void * ctx,uint16_t event,uint16_t event_data_len,void * event_data)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 */
mlme_vdev_state_start_entry(void * ctx)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 */
mlme_vdev_state_start_exit(void * ctx)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 */
mlme_vdev_state_start_event(void * ctx,uint16_t event,uint16_t event_data_len,void * event_data)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 */
mlme_vdev_state_dfs_cac_wait_entry(void * ctx)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 */
mlme_vdev_state_dfs_cac_wait_exit(void * ctx)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 */
mlme_vdev_state_dfs_cac_wait_event(void * ctx,uint16_t event,uint16_t event_data_len,void * event_data)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 */
mlme_vdev_state_up_entry(void * ctx)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 */
mlme_vdev_state_up_exit(void * ctx)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 */
mlme_vdev_state_up_event(void * ctx,uint16_t event,uint16_t event_data_len,void * event_data)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 */
mlme_vdev_state_suspend_entry(void * ctx)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 */
mlme_vdev_state_suspend_exit(void * ctx)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 */
mlme_vdev_state_suspend_event(void * ctx,uint16_t event,uint16_t event_data_len,void * event_data)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 */
mlme_vdev_state_stop_entry(void * ctx)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 */
mlme_vdev_state_stop_exit(void * ctx)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 */
mlme_vdev_state_stop_event(void * ctx,uint16_t event,uint16_t event_data_len,void * event_data)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 */
mlme_vdev_subst_start_start_progress_entry(void * ctx)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 */
mlme_vdev_subst_start_start_progress_exit(void * ctx)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 */
mlme_vdev_subst_start_start_progress_event(void * ctx,uint16_t event,uint16_t event_data_len,void * event_data)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 */
mlme_vdev_subst_start_restart_progress_entry(void * ctx)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 */
mlme_vdev_subst_start_restart_progress_exit(void * ctx)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 */
mlme_vdev_subst_start_restart_progress_event(void * ctx,uint16_t event,uint16_t event_data_len,void * event_data)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 */
mlme_vdev_subst_start_conn_progress_entry(void * ctx)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 */
mlme_vdev_subst_start_conn_progress_exit(void * ctx)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 */
mlme_vdev_subst_start_conn_progress_event(void * ctx,uint16_t event,uint16_t event_data_len,void * event_data)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 */
mlme_vdev_subst_start_disconn_progress_entry(void * ctx)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 */
mlme_vdev_subst_start_disconn_progress_exit(void * ctx)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 */
mlme_vdev_subst_start_disconn_progress_event(void * ctx,uint16_t event,uint16_t event_data_len,void * event_data)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 */
mlme_vdev_subst_suspend_suspend_down_entry(void * ctx)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 */
mlme_vdev_subst_suspend_suspend_down_exit(void * ctx)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 */
mlme_vdev_subst_suspend_suspend_down_event(void * ctx,uint16_t event,uint16_t event_data_len,void * event_data)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 */
mlme_vdev_subst_suspend_suspend_restart_entry(void * ctx)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 */
mlme_vdev_subst_suspend_suspend_restart_exit(void * ctx)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 */
mlme_vdev_subst_suspend_suspend_restart_event(void * ctx,uint16_t event,uint16_t event_data_len,void * event_data)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 */
mlme_vdev_subst_suspend_host_restart_entry(void * ctx)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 */
mlme_vdev_subst_suspend_host_restart_exit(void * ctx)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 */
mlme_vdev_subst_suspend_host_restart_event(void * ctx,uint16_t event,uint16_t event_data_len,void * event_data)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 */
mlme_vdev_subst_suspend_csa_restart_entry(void * ctx)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 */
mlme_vdev_subst_suspend_csa_restart_exit(void * ctx)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 */
mlme_vdev_subst_suspend_csa_restart_event(void * ctx,uint16_t event,uint16_t event_data_len,void * event_data)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 */
mlme_vdev_subst_stop_stop_progress_entry(void * ctx)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 */
mlme_vdev_subst_stop_stop_progress_exit(void * ctx)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 */
mlme_vdev_subst_stop_stop_progress_event(void * ctx,uint16_t event,uint16_t event_data_len,void * event_data)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 */
mlme_vdev_subst_stop_down_progress_entry(void * ctx)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 */
mlme_vdev_subst_stop_down_progress_exit(void * ctx)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 */
mlme_vdev_subst_stop_down_progress_event(void * ctx,uint16_t event,uint16_t event_data_len,void * event_data)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 */
mlme_vdev_subst_mlo_sync_wait_entry(void * ctx)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
mlme_vdev_subst_mlo_sync_wait_exit(void * ctx)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
mlme_vdev_subst_mlo_sync_wait_exit(void * ctx)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 */
mlme_vdev_subst_mlo_sync_wait_event(void * ctx,uint16_t event,uint16_t event_data_len,void * event_data)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 */
mlme_vdev_subst_up_active_entry(void * ctx)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 */
mlme_vdev_subst_up_active_exit(void * ctx)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 */
mlme_vdev_subst_up_active_event(void * ctx,uint16_t event,uint16_t event_data_len,void * event_data)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
mlme_vdev_sm_deliver_event(struct vdev_mlme_obj * vdev_mlme,enum wlan_vdev_sm_evt event,uint16_t event_data_len,void * event_data)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
mlme_vdev_sm_print_state_event(struct vdev_mlme_obj * vdev_mlme,enum wlan_vdev_sm_evt event)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
mlme_vdev_sm_print_state(struct vdev_mlme_obj * vdev_mlme)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
mlme_vdev_sm_history_print(struct vdev_mlme_obj * vdev_mlme)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
mlme_vdev_sm_create(struct vdev_mlme_obj * vdev_mlme)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
mlme_vdev_sm_destroy(struct vdev_mlme_obj * vdev_mlme)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