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