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