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