xref: /wlan-dirver/qca-wifi-host-cmn/umac/mlme/vdev_mgr/core/src/vdev_mlme_sm.c (revision dd4dc88b837a295134aa9869114a2efee0f4894b)
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 		mlme_vdev_start_continue(vdev_mlme, event_data_len, event_data);
924 		status = true;
925 		break;
926 
927 	case WLAN_VDEV_SM_EV_DFS_CAC_WAIT:
928 		mlme_vdev_sm_transition_to(vdev_mlme, WLAN_VDEV_S_DFS_CAC_WAIT);
929 		mlme_vdev_sm_deliver_event(vdev_mlme, event,
930 					   event_data_len, event_data);
931 		status = true;
932 		break;
933 
934 	case WLAN_VDEV_SM_EV_START_SUCCESS:
935 		mlme_vdev_sm_transition_to(vdev_mlme, WLAN_VDEV_S_UP);
936 		mlme_vdev_sm_deliver_event(vdev_mlme, event,
937 					   event_data_len, event_data);
938 		status = true;
939 		break;
940 
941 	case WLAN_VDEV_SM_EV_STA_CONN_START:
942 		/* This event triggers station connection, if it is blocked for
943 		 * CAC WAIT
944 		 */
945 		if (mode != QDF_STA_MODE)
946 			QDF_BUG(0);
947 
948 		mlme_vdev_sta_conn_start(vdev_mlme, event_data_len, event_data);
949 		status = true;
950 		break;
951 
952 	case WLAN_VDEV_SM_EV_RADAR_DETECTED:
953 		if (mode != QDF_STA_MODE)
954 			QDF_BUG(0);
955 
956 		status = true;
957 		break;
958 
959 	case WLAN_VDEV_SM_EV_DOWN:
960 	case WLAN_VDEV_SM_EV_CONNECTION_FAIL:
961 		mlme_vdev_sm_transition_to(vdev_mlme,
962 					   WLAN_VDEV_SS_START_DISCONN_PROGRESS);
963 		mlme_vdev_sm_deliver_event(vdev_mlme, event,
964 					   event_data_len, event_data);
965 		status = true;
966 		break;
967 
968 	default:
969 		status = false;
970 		break;
971 	}
972 
973 	return status;
974 }
975 
976 /**
977  * mlme_vdev_subst_start_disconn_progress_entry() - Entry API for Disconn
978  *                                                  progress sub state
979  * @ctx: VDEV MLME object
980  *
981  * API to perform operations on moving to DISCONN-PROGRESS substate
982  *
983  * Return: SUCCESS: on handling event
984  *         FAILURE: on ignoring the event
985  */
986 static void mlme_vdev_subst_start_disconn_progress_entry(void *ctx)
987 {
988 	struct vdev_mlme_obj *vdev_mlme = (struct vdev_mlme_obj *)ctx;
989 	struct wlan_objmgr_vdev *vdev;
990 
991 	vdev = vdev_mlme->vdev;
992 
993 	if (wlan_vdev_mlme_get_state(vdev) != WLAN_VDEV_S_START)
994 		QDF_BUG(0);
995 
996 	mlme_vdev_set_substate(vdev, WLAN_VDEV_SS_START_DISCONN_PROGRESS);
997 }
998 
999 /**
1000  * mlme_vdev_subst_start_disconn_progress_exit() - Exit API for Disconn Progress
1001  *                                                sub state
1002  * @ctx: VDEV MLME object
1003  *
1004  * API to perform operations on moving out of DISCONN-PROGRESS substate
1005  *
1006  * Return: void
1007  */
1008 static void mlme_vdev_subst_start_disconn_progress_exit(void *ctx)
1009 {
1010 	/* NONE */
1011 }
1012 
1013 /**
1014  * mlme_vdev_subst_start_disconn_progress_event() - Event handler API for Discon
1015  *                                                Progress substate
1016  * @ctx: VDEV MLME object
1017  *
1018  * API to handle events in DISCONN-PROGRESS substate
1019  *
1020  * Return: SUCCESS: on handling event
1021  *         FAILURE: on ignoring the event
1022  */
1023 static bool mlme_vdev_subst_start_disconn_progress_event(void *ctx,
1024 		uint16_t event, uint16_t event_data_len, void *event_data)
1025 {
1026 	struct vdev_mlme_obj *vdev_mlme = (struct vdev_mlme_obj *)ctx;
1027 	bool status;
1028 
1029 	switch (event) {
1030 	case WLAN_VDEV_SM_EV_START_RESP:
1031 	/* clean up, if any needs to be cleaned up */
1032 	case WLAN_VDEV_SM_EV_CONNECTION_FAIL:
1033 		mlme_vdev_sm_transition_to(vdev_mlme, WLAN_VDEV_S_STOP);
1034 		mlme_vdev_sm_deliver_event(vdev_mlme, WLAN_VDEV_SM_EV_STOP_REQ,
1035 					   event_data_len, event_data);
1036 		status = true;
1037 		break;
1038 
1039 	case WLAN_VDEV_SM_EV_RESTART_RESP:
1040 	case WLAN_VDEV_SM_EV_RESTART_REQ_FAIL:
1041 		mlme_vdev_sm_transition_to(vdev_mlme, WLAN_VDEV_S_SUSPEND);
1042 		mlme_vdev_sm_deliver_event(vdev_mlme, WLAN_VDEV_SM_EV_DOWN,
1043 					   event_data_len, event_data);
1044 		status = true;
1045 		break;
1046 
1047 	case WLAN_VDEV_SM_EV_START_REQ_FAIL:
1048 		mlme_vdev_sm_transition_to(vdev_mlme, WLAN_VDEV_S_INIT);
1049 		mlme_vdev_sm_deliver_event(vdev_mlme, event,
1050 					   event_data_len, event_data);
1051 		status = true;
1052 		break;
1053 
1054 	default:
1055 		status = false;
1056 		break;
1057 	}
1058 
1059 	return status;
1060 }
1061 
1062 /**
1063  * mlme_vdev_subst_suspend_suspend_down_entry() - Entry API for Suspend down
1064  *                                                sub state
1065  * @ctx: VDEV MLME object
1066  *
1067  * API to perform operations on moving to SUSPEND-DOWN substate
1068  *
1069  * Return: void
1070  */
1071 static void mlme_vdev_subst_suspend_suspend_down_entry(void *ctx)
1072 {
1073 	struct vdev_mlme_obj *vdev_mlme = (struct vdev_mlme_obj *)ctx;
1074 	struct wlan_objmgr_vdev *vdev;
1075 
1076 	vdev = vdev_mlme->vdev;
1077 
1078 	if (wlan_vdev_mlme_get_state(vdev) != WLAN_VDEV_S_SUSPEND)
1079 		QDF_BUG(0);
1080 
1081 	mlme_vdev_set_substate(vdev, WLAN_VDEV_SS_SUSPEND_SUSPEND_DOWN);
1082 }
1083 
1084 /**
1085  * mlme_vdev_subst_suspend_suspend_down_exit() - Exit API for Suspend down
1086  *                                                sub state
1087  * @ctx: VDEV MLME object
1088  *
1089  * API to perform operations on moving out of SUSPEND-DOWN substate
1090  *
1091  * Return: void
1092  */
1093 static void mlme_vdev_subst_suspend_suspend_down_exit(void *ctx)
1094 {
1095 	/* NONE */
1096 }
1097 
1098 /**
1099  * mlme_vdev_subst_suspend_suspend_down_event() - Event handler API for Suspend
1100  *                                                down substate
1101  * @ctx: VDEV MLME object
1102  *
1103  * API to handle events in SUSPEND-DOWN substate
1104  *
1105  * Return: SUCCESS: on handling event
1106  *         FAILURE: on ignoring the event
1107  */
1108 static bool mlme_vdev_subst_suspend_suspend_down_event(void *ctx,
1109 		uint16_t event, uint16_t event_data_len, void *event_data)
1110 {
1111 	struct vdev_mlme_obj *vdev_mlme = (struct vdev_mlme_obj *)ctx;
1112 	bool status;
1113 
1114 	switch (event) {
1115 	case WLAN_VDEV_SM_EV_DOWN:
1116 	case WLAN_VDEV_SM_EV_RESTART_REQ_FAIL:
1117 		mlme_vdev_disconnect_peers(vdev_mlme,
1118 					   event_data_len, event_data);
1119 		status = true;
1120 		break;
1121 
1122 	case WLAN_VDEV_SM_EV_DISCONNECT_COMPLETE:
1123 		/* clean up, if any needs to be cleaned up */
1124 		mlme_vdev_sm_transition_to(vdev_mlme, WLAN_VDEV_S_STOP);
1125 		mlme_vdev_sm_deliver_event(vdev_mlme, WLAN_VDEV_SM_EV_STOP_REQ,
1126 					   event_data_len, event_data);
1127 		status = true;
1128 		break;
1129 
1130 	default:
1131 		status = false;
1132 		break;
1133 	}
1134 
1135 	return status;
1136 }
1137 
1138 /**
1139  * mlme_vdev_subst_suspend_suspend_restart_entry() - Entry API for Suspend
1140  *                                                   restart substate
1141  * @ctx: VDEV MLME object
1142  *
1143  * API to perform operations on moving to SUSPEND-RESTART substate
1144  *
1145  * Return: void
1146  */
1147 static void mlme_vdev_subst_suspend_suspend_restart_entry(void *ctx)
1148 {
1149 	struct vdev_mlme_obj *vdev_mlme = (struct vdev_mlme_obj *)ctx;
1150 	struct wlan_objmgr_vdev *vdev;
1151 
1152 	vdev = vdev_mlme->vdev;
1153 
1154 	if (wlan_vdev_mlme_get_state(vdev) != WLAN_VDEV_S_SUSPEND)
1155 		QDF_BUG(0);
1156 
1157 	mlme_vdev_set_substate(vdev, WLAN_VDEV_SS_SUSPEND_SUSPEND_RESTART);
1158 }
1159 
1160 /**
1161  * mlme_vdev_subst_suspend_suspend_restart_exit() - Exit API for Suspend restart
1162  *                                                sub state
1163  * @ctx: VDEV MLME object
1164  *
1165  * API to perform operations on moving out of SUSPEND-RESTART substate
1166  *
1167  * Return: void
1168  */
1169 static void mlme_vdev_subst_suspend_suspend_restart_exit(void *ctx)
1170 {
1171 	/* NONE */
1172 }
1173 
1174 /**
1175  * mlme_vdev_subst_suspend_suspend_restart_event() - Event handler API for
1176  *                                                   Suspend restart substate
1177  * @ctx: VDEV MLME object
1178  *
1179  * API to handle events in SUSPEND-RESTART substate
1180  *
1181  * Return: SUCCESS: on handling event
1182  *         FAILURE: on ignoring the event
1183  */
1184 static bool mlme_vdev_subst_suspend_suspend_restart_event(void *ctx,
1185 		uint16_t event, uint16_t event_data_len, void *event_data)
1186 {
1187 	struct vdev_mlme_obj *vdev_mlme = (struct vdev_mlme_obj *)ctx;
1188 	bool status;
1189 
1190 	switch (event) {
1191 	case WLAN_VDEV_SM_EV_SUSPEND_RESTART:
1192 		mlme_vdev_disconnect_peers(vdev_mlme,
1193 					   event_data_len, event_data);
1194 		status = true;
1195 		break;
1196 
1197 	case WLAN_VDEV_SM_EV_DISCONNECT_COMPLETE:
1198 		/* clean up, if any needs to be cleaned up */
1199 		mlme_vdev_sm_transition_to(vdev_mlme, WLAN_VDEV_S_START);
1200 		mlme_vdev_sm_deliver_event(vdev_mlme,
1201 					   WLAN_VDEV_SM_EV_RESTART_REQ,
1202 					   event_data_len, event_data);
1203 		status = true;
1204 		break;
1205 
1206 	case WLAN_VDEV_SM_EV_DOWN:
1207 		mlme_vdev_sm_transition_to(vdev_mlme,
1208 					   WLAN_VDEV_SS_SUSPEND_SUSPEND_DOWN);
1209 		status = true;
1210 		break;
1211 
1212 	case WLAN_VDEV_SM_EV_RADAR_DETECTED:
1213 		mlme_vdev_sm_transition_to(vdev_mlme,
1214 					   WLAN_VDEV_SS_SUSPEND_CSA_RESTART);
1215 		mlme_vdev_sm_deliver_event(vdev_mlme,
1216 					   WLAN_VDEV_SM_EV_CSA_RESTART,
1217 					   event_data_len, event_data);
1218 		status = true;
1219 		break;
1220 
1221 	default:
1222 		status = false;
1223 		break;
1224 	}
1225 
1226 	return status;
1227 }
1228 
1229 /**
1230  * mlme_vdev_subst_suspend_host_restart_entry() - Entry API for Host restart
1231  *                                                substate
1232  * @ctx: VDEV MLME object
1233  *
1234  * API to perform operations on moving to HOST-RESTART substate
1235  *
1236  * Return: void
1237  */
1238 static void mlme_vdev_subst_suspend_host_restart_entry(void *ctx)
1239 {
1240 	struct vdev_mlme_obj *vdev_mlme = (struct vdev_mlme_obj *)ctx;
1241 	struct wlan_objmgr_vdev *vdev;
1242 
1243 	vdev = vdev_mlme->vdev;
1244 
1245 	if (wlan_vdev_mlme_get_state(vdev) != WLAN_VDEV_S_SUSPEND)
1246 		QDF_BUG(0);
1247 
1248 	mlme_vdev_set_substate(vdev, WLAN_VDEV_SS_SUSPEND_HOST_RESTART);
1249 }
1250 
1251 /**
1252  * mlme_vdev_subst_suspend_host_restart_exit() - Exit API for host restart
1253  *                                                sub state
1254  * @ctx: VDEV MLME object
1255  *
1256  * API to perform operations on moving out of HOST-RESTART substate
1257  *
1258  * Return: void
1259  */
1260 static void mlme_vdev_subst_suspend_host_restart_exit(void *ctx)
1261 {
1262     /* NONE */
1263 }
1264 
1265 /**
1266  * mlme_vdev_subst_suspend_host_restart_entry() - Event handler API for Host
1267  *                                                restart substate
1268  * @ctx: VDEV MLME object
1269  *
1270  * API to handle events in HOST-RESTART substate
1271  *
1272  * Return: void
1273  */
1274 static bool mlme_vdev_subst_suspend_host_restart_event(void *ctx,
1275 		uint16_t event, uint16_t event_data_len, void *event_data)
1276 {
1277 	struct vdev_mlme_obj *vdev_mlme = (struct vdev_mlme_obj *)ctx;
1278 	bool status;
1279 
1280 	switch (event) {
1281 	case WLAN_VDEV_SM_EV_HOST_RESTART:
1282 		mlme_vdev_disconnect_peers(vdev_mlme,
1283 					   event_data_len, event_data);
1284 		status = true;
1285 		break;
1286 
1287 	case WLAN_VDEV_SM_EV_DISCONNECT_COMPLETE:
1288 		/* VDEV up command need not be sent */
1289 		mlme_vdev_sm_transition_to(vdev_mlme, WLAN_VDEV_S_UP);
1290 		mlme_vdev_sm_deliver_event(vdev_mlme,
1291 					   WLAN_VDEV_SM_EV_UP_HOST_RESTART,
1292 					   event_data_len, event_data);
1293 		status = true;
1294 		break;
1295 
1296 	case WLAN_VDEV_SM_EV_DOWN:
1297 		mlme_vdev_sm_transition_to(vdev_mlme,
1298 					   WLAN_VDEV_SS_SUSPEND_SUSPEND_DOWN);
1299 		status = true;
1300 		break;
1301 
1302 	case WLAN_VDEV_SM_EV_RADAR_DETECTED:
1303 		mlme_vdev_sm_transition_to(vdev_mlme,
1304 					   WLAN_VDEV_SS_SUSPEND_CSA_RESTART);
1305 		mlme_vdev_sm_deliver_event(vdev_mlme,
1306 					   WLAN_VDEV_SM_EV_CSA_RESTART,
1307 					   event_data_len, event_data);
1308 		status = true;
1309 		break;
1310 
1311 	default:
1312 		status = false;
1313 		break;
1314 	}
1315 
1316 	return status;
1317 }
1318 
1319 /**
1320  * mlme_vdev_subst_suspend_csa_restart_entry() - Entry API for CSA restart
1321  *                                               substate
1322  * @ctx: VDEV MLME object
1323  *
1324  * API to perform operations on moving to CSA-RESTART substate
1325  *
1326  * Return: void
1327  */
1328 static void mlme_vdev_subst_suspend_csa_restart_entry(void *ctx)
1329 {
1330 	struct vdev_mlme_obj *vdev_mlme = (struct vdev_mlme_obj *)ctx;
1331 	struct wlan_objmgr_vdev *vdev;
1332 
1333 	vdev = vdev_mlme->vdev;
1334 
1335 	if (wlan_vdev_mlme_get_state(vdev) != WLAN_VDEV_S_SUSPEND)
1336 		QDF_BUG(0);
1337 
1338 	mlme_vdev_set_substate(vdev, WLAN_VDEV_SS_SUSPEND_CSA_RESTART);
1339 }
1340 
1341 /**
1342  * mlme_vdev_subst_suspend_csa_restart_exit() - Exit API for CSA restart
1343  *                                                sub state
1344  * @ctx: VDEV MLME object
1345  *
1346  * API to perform operations on moving out of CSA-RESTART substate
1347  *
1348  * Return: void
1349  */
1350 static void mlme_vdev_subst_suspend_csa_restart_exit(void *ctx)
1351 {
1352     /* NONE */
1353 }
1354 
1355 /**
1356  * mlme_vdev_subst_suspend_csa_restart_event() - Event handler API for CSA
1357  *                                               restart substate
1358  * @ctx: VDEV MLME object
1359  *
1360  * API to handle events in CSA-RESTART substate
1361  *
1362  * Return: SUCCESS: on handling event
1363  *         FAILURE: on ignoring the event
1364  */
1365 static bool mlme_vdev_subst_suspend_csa_restart_event(void *ctx,
1366 		uint16_t event, uint16_t event_data_len, void *event_data)
1367 {
1368 	struct vdev_mlme_obj *vdev_mlme = (struct vdev_mlme_obj *)ctx;
1369 	bool status;
1370 
1371 	switch (event) {
1372 	case WLAN_VDEV_SM_EV_CSA_RESTART:
1373 		mlme_vdev_update_beacon(vdev_mlme, BEACON_CSA,
1374 					event_data_len, event_data);
1375 		status = true;
1376 		break;
1377 	case WLAN_VDEV_SM_EV_CSA_COMPLETE:
1378 		if (mlme_vdev_is_newchan_no_cac(vdev_mlme) ==
1379 						QDF_STATUS_SUCCESS) {
1380 			mlme_vdev_sm_transition_to(vdev_mlme,
1381 						   WLAN_VDEV_S_START);
1382 			mlme_vdev_sm_deliver_event(vdev_mlme,
1383 						   WLAN_VDEV_SM_EV_RESTART_REQ,
1384 						   event_data_len, event_data);
1385 		} else {
1386 			mlme_vdev_sm_transition_to
1387 				(vdev_mlme,
1388 				 WLAN_VDEV_SS_SUSPEND_SUSPEND_RESTART);
1389 			mlme_vdev_sm_deliver_event
1390 				(vdev_mlme, WLAN_VDEV_SM_EV_SUSPEND_RESTART,
1391 				 event_data_len, event_data);
1392 		}
1393 		status = true;
1394 		break;
1395 
1396 	case WLAN_VDEV_SM_EV_DOWN:
1397 		mlme_vdev_sm_transition_to(vdev_mlme,
1398 					   WLAN_VDEV_SS_SUSPEND_SUSPEND_DOWN);
1399 		mlme_vdev_sm_deliver_event(vdev_mlme, event,
1400 					   event_data_len, event_data);
1401 		status = true;
1402 		break;
1403 
1404 	case WLAN_VDEV_SM_EV_RADAR_DETECTED:
1405 		/* since channel change is already in progress,
1406 		 * dfs ignore radar detected event
1407 		 */
1408 		status = true;
1409 		break;
1410 
1411 	default:
1412 		status = false;
1413 		break;
1414 	}
1415 
1416 	return status;
1417 }
1418 
1419 /**
1420  * mlme_vdev_subst_stop_stop_progress_entry() - Entry API for Stop Progress
1421  *                                                sub state
1422  * @ctx: VDEV MLME object
1423  *
1424  * API to perform operations on moving to STOP-PROGRESS substate
1425  *
1426  * Return: void
1427  */
1428 static void mlme_vdev_subst_stop_stop_progress_entry(void *ctx)
1429 {
1430 	struct vdev_mlme_obj *vdev_mlme = (struct vdev_mlme_obj *) ctx;
1431 	struct wlan_objmgr_vdev *vdev;
1432 
1433 	vdev = vdev_mlme->vdev;
1434 
1435 	if (wlan_vdev_mlme_get_state(vdev) != WLAN_VDEV_S_STOP)
1436 		QDF_BUG(0);
1437 
1438 	mlme_vdev_set_substate(vdev, WLAN_VDEV_SS_STOP_STOP_PROGRESS);
1439 }
1440 
1441 /**
1442  * mlme_vdev_subst_stop_stop_progress_exit() - Exit API for Stop Progress
1443  *                                                sub state
1444  * @ctx: VDEV MLME object
1445  *
1446  * API to perform operations on moving out of STOP-PROGRESS substate
1447  *
1448  * Return: void
1449  */
1450 static void mlme_vdev_subst_stop_stop_progress_exit(void *ctx)
1451 {
1452     /* NONE */
1453 }
1454 
1455 /**
1456  * mlme_vdev_subst_stop_stop_progress_event() - Event handler API for Stop
1457  *                                                Progress substate
1458  * @ctx: VDEV MLME object
1459  *
1460  * API to handle events in STOP-PROGRESS substate
1461  *
1462  * Return: SUCCESS: on handling event
1463  *         FAILURE: on ignoring the event
1464  */
1465 static bool mlme_vdev_subst_stop_stop_progress_event(void *ctx,
1466 		uint16_t event, uint16_t event_data_len, void *event_data)
1467 {
1468 	struct vdev_mlme_obj *vdev_mlme = (struct vdev_mlme_obj *)ctx;
1469 	bool status;
1470 
1471 	/* Debug framework is required to hold the events */
1472 
1473 	switch (event) {
1474 	case WLAN_VDEV_SM_EV_STOP_REQ:
1475 		/* send vdev stop command to FW and delete BSS peer*/
1476 		mlme_vdev_stop_send(vdev_mlme, event_data_len, event_data);
1477 		status = true;
1478 		break;
1479 
1480 	case WLAN_VDEV_SM_EV_STOP_RESP:
1481 		/* Processes stop response, and checks BSS peer delete wait
1482 		 * is needed
1483 		 */
1484 		mlme_vdev_stop_continue(vdev_mlme, event_data_len, event_data);
1485 		status = true;
1486 		break;
1487 
1488 	/* This event should be given by MLME on stop complete and BSS
1489 	 * peer delete complete to move forward
1490 	 */
1491 	case WLAN_VDEV_SM_EV_MLME_DOWN_REQ:
1492 		mlme_vdev_sm_transition_to(vdev_mlme,
1493 					   WLAN_VDEV_SS_STOP_DOWN_PROGRESS);
1494 		mlme_vdev_sm_deliver_event(vdev_mlme,
1495 					   WLAN_VDEV_SM_EV_MLME_DOWN_REQ,
1496 					   event_data_len, event_data);
1497 		status = true;
1498 		break;
1499 
1500 	case WLAN_VDEV_SM_EV_STOP_FAIL:
1501 		mlme_vdev_sm_transition_to(vdev_mlme,
1502 					   WLAN_VDEV_SS_STOP_DOWN_PROGRESS);
1503 		mlme_vdev_sm_deliver_event(vdev_mlme,
1504 					   WLAN_VDEV_SM_EV_MLME_DOWN_REQ,
1505 					   event_data_len, event_data);
1506 		status = true;
1507 		break;
1508 
1509 	default:
1510 		status = false;
1511 		break;
1512 	}
1513 
1514 	return status;
1515 }
1516 
1517 /**
1518  * mlme_vdev_subst_stop_down_progress_entry() - Entry API for Down Progress
1519  *                                                sub state
1520  * @ctx: VDEV MLME object
1521  *
1522  * API to perform operations on moving to DOWN-PROGRESS substate
1523  *
1524  * Return: void
1525  */
1526 static void mlme_vdev_subst_stop_down_progress_entry(void *ctx)
1527 {
1528 	struct vdev_mlme_obj *vdev_mlme = (struct vdev_mlme_obj *)ctx;
1529 	struct wlan_objmgr_vdev *vdev;
1530 
1531 	vdev = vdev_mlme->vdev;
1532 
1533 	if (wlan_vdev_mlme_get_state(vdev) != WLAN_VDEV_S_STOP)
1534 		QDF_BUG(0);
1535 
1536 	mlme_vdev_set_substate(vdev, WLAN_VDEV_SS_STOP_DOWN_PROGRESS);
1537 }
1538 
1539 /**
1540  * mlme_vdev_subst_stop_down_progress_exit() - Exit API for Down Progress
1541  *                                                sub state
1542  * @ctx: VDEV MLME object
1543  *
1544  * API to perform operations on moving out of DOWN-PROGRESS substate
1545  *
1546  * Return: void
1547  */
1548 static void mlme_vdev_subst_stop_down_progress_exit(void *ctx)
1549 {
1550 	/* NONE */
1551 }
1552 
1553 /**
1554  * mlme_vdev_subst_stop_down_progress_event() - Event handler API for Down
1555  *                                                Progress substate
1556  * @ctx: VDEV MLME object
1557  *
1558  * API to handle events in DOWN-PROGRESS substate
1559  *
1560  * Return: SUCCESS: on handling event
1561  *         FAILURE: on ignoring the event
1562  */
1563 static bool mlme_vdev_subst_stop_down_progress_event(void *ctx,
1564 		uint16_t event, uint16_t event_data_len, void *event_data)
1565 {
1566 	struct vdev_mlme_obj *vdev_mlme = (struct vdev_mlme_obj *)ctx;
1567 	bool status;
1568 
1569 	switch (event) {
1570 	case WLAN_VDEV_SM_EV_DOWN:
1571 		status = true;
1572 		break;
1573 
1574 	case WLAN_VDEV_SM_EV_MLME_DOWN_REQ:
1575 		/* send vdev down command to FW, if send is successful, sends
1576 		 * DOWN_COMPLETE event
1577 		 */
1578 		mlme_vdev_down_send(vdev_mlme, event_data_len, event_data);
1579 		status = true;
1580 		break;
1581 
1582 	case WLAN_VDEV_SM_EV_DOWN_COMPLETE:
1583 		mlme_vdev_sm_transition_to(vdev_mlme, WLAN_VDEV_S_INIT);
1584 		mlme_vdev_sm_deliver_event(vdev_mlme,
1585 					   WLAN_VDEV_SM_EV_DOWN_COMPLETE,
1586 					   event_data_len, event_data);
1587 		status = true;
1588 		break;
1589 
1590 	case WLAN_VDEV_SM_EV_DOWN_FAIL:
1591 		mlme_vdev_sm_transition_to(vdev_mlme, WLAN_VDEV_S_INIT);
1592 		mlme_vdev_sm_deliver_event(vdev_mlme,
1593 					   WLAN_VDEV_SM_EV_DOWN_COMPLETE,
1594 					   event_data_len, event_data);
1595 		status = true;
1596 		break;
1597 
1598 	default:
1599 		status = false;
1600 		break;
1601 	}
1602 
1603 	return status;
1604 }
1605 
1606 
1607 static const char *vdev_sm_event_names[] = {
1608 	"EV_START",
1609 	"EV_START_REQ",
1610 	"EV_RESTART_REQ",
1611 	"EV_START_RESP",
1612 	"EV_RESTART_RESP",
1613 	"EV_START_REQ_FAIL",
1614 	"EV_RESTART_REQ_FAIL",
1615 	"EV_START_SUCCESS",
1616 	"EV_CONN_PROGRESS",
1617 	"EV_STA_CONN_START",
1618 	"EV_DFS_CAC_WAIT",
1619 	"EV_DFS_CAC_COMPLETED",
1620 	"EV_DOWN",
1621 	"EV_CONNECTION_FAIL",
1622 	"EV_STOP_RESP",
1623 	"EV_STOP_FAIL",
1624 	"EV_DOWN_FAIL",
1625 	"EV_DISCONNECT_COMPLETE",
1626 	"EV_SUSPEND_RESTART",
1627 	"EV_HOST_RESTART",
1628 	"EV_UP_HOST_RESTART",
1629 	"EV_FW_VDEV_RESTART",
1630 	"EV_UP_FAIL",
1631 	"EV_RADAR_DETECTED",
1632 	"EV_CSA_RESTART",
1633 	"EV_CSA_COMPLETE",
1634 	"EV_MLME_DOWN_REQ",
1635 	"EV_DOWN_COMPLETE",
1636 	"EV_ROAM",
1637 	"EV_STOP_REQ",
1638 };
1639 
1640 struct wlan_sm_state_info sm_info[] = {
1641 	{
1642 		(uint8_t)WLAN_VDEV_S_INIT,
1643 		(uint8_t)WLAN_SM_ENGINE_STATE_NONE,
1644 		(uint8_t)WLAN_SM_ENGINE_STATE_NONE,
1645 		true,
1646 		"INIT",
1647 		mlme_vdev_state_init_entry,
1648 		mlme_vdev_state_init_exit,
1649 		mlme_vdev_state_init_event
1650 	},
1651 	{
1652 		(uint8_t)WLAN_VDEV_S_START,
1653 		(uint8_t)WLAN_SM_ENGINE_STATE_NONE,
1654 		(uint8_t)WLAN_SM_ENGINE_STATE_NONE,
1655 		true,
1656 		"START",
1657 		mlme_vdev_state_start_entry,
1658 		mlme_vdev_state_start_exit,
1659 		mlme_vdev_state_start_event
1660 	},
1661 	{
1662 		(uint8_t)WLAN_VDEV_S_DFS_CAC_WAIT,
1663 		(uint8_t)WLAN_SM_ENGINE_STATE_NONE,
1664 		(uint8_t)WLAN_SM_ENGINE_STATE_NONE,
1665 		true,
1666 		"DFS_CAC_WAIT",
1667 		mlme_vdev_state_dfs_cac_wait_entry,
1668 		mlme_vdev_state_dfs_cac_wait_exit,
1669 		mlme_vdev_state_dfs_cac_wait_event
1670 	},
1671 	{
1672 		(uint8_t)WLAN_VDEV_S_UP,
1673 		(uint8_t)WLAN_SM_ENGINE_STATE_NONE,
1674 		(uint8_t)WLAN_SM_ENGINE_STATE_NONE,
1675 		true,
1676 		"UP",
1677 		mlme_vdev_state_up_entry,
1678 		mlme_vdev_state_up_exit,
1679 		mlme_vdev_state_up_event
1680 	},
1681 	{
1682 		(uint8_t)WLAN_VDEV_S_SUSPEND,
1683 		(uint8_t)WLAN_SM_ENGINE_STATE_NONE,
1684 		(uint8_t)WLAN_SM_ENGINE_STATE_NONE,
1685 		true,
1686 		"SUSPEND",
1687 		mlme_vdev_state_suspend_entry,
1688 		mlme_vdev_state_suspend_exit,
1689 		mlme_vdev_state_suspend_event
1690 	},
1691 	{
1692 		(uint8_t)WLAN_VDEV_S_STOP,
1693 		(uint8_t)WLAN_SM_ENGINE_STATE_NONE,
1694 		(uint8_t)WLAN_VDEV_SS_STOP_STOP_PROGRESS,
1695 		true,
1696 		"STOP",
1697 		mlme_vdev_state_stop_entry,
1698 		mlme_vdev_state_stop_exit,
1699 		mlme_vdev_state_stop_event
1700 	},
1701 	{
1702 		(uint8_t)WLAN_VDEV_S_MAX,
1703 		(uint8_t)WLAN_SM_ENGINE_STATE_NONE,
1704 		(uint8_t)WLAN_SM_ENGINE_STATE_NONE,
1705 		false,
1706 		"INVALID",
1707 		NULL,
1708 		NULL,
1709 		NULL
1710 	},
1711 	{
1712 		(uint8_t)WLAN_VDEV_SS_START_START_PROGRESS,
1713 		(uint8_t)WLAN_VDEV_S_START,
1714 		(uint8_t)WLAN_SM_ENGINE_STATE_NONE,
1715 		false,
1716 		"ST-START_PROG",
1717 		mlme_vdev_subst_start_start_progress_entry,
1718 		mlme_vdev_subst_start_start_progress_exit,
1719 		mlme_vdev_subst_start_start_progress_event
1720 	},
1721 	{
1722 		(uint8_t)WLAN_VDEV_SS_START_RESTART_PROGRESS,
1723 		(uint8_t)WLAN_VDEV_S_START,
1724 		(uint8_t)WLAN_SM_ENGINE_STATE_NONE,
1725 		false,
1726 		"ST-RESTART_PROG",
1727 		mlme_vdev_subst_start_restart_progress_entry,
1728 		mlme_vdev_subst_start_restart_progress_exit,
1729 		mlme_vdev_subst_start_restart_progress_event
1730 	},
1731 	{
1732 		(uint8_t)WLAN_VDEV_SS_START_CONN_PROGRESS,
1733 		(uint8_t)WLAN_VDEV_S_START,
1734 		(uint8_t)WLAN_SM_ENGINE_STATE_NONE,
1735 		false,
1736 		"ST-CONN_PROG",
1737 		mlme_vdev_subst_start_conn_progress_entry,
1738 		mlme_vdev_subst_start_conn_progress_exit,
1739 		mlme_vdev_subst_start_conn_progress_event
1740 	},
1741 	{
1742 		(uint8_t)WLAN_VDEV_SS_START_DISCONN_PROGRESS,
1743 		(uint8_t)WLAN_VDEV_S_START,
1744 		(uint8_t)WLAN_SM_ENGINE_STATE_NONE,
1745 		false,
1746 		"ST-DISCONN_PROG",
1747 		mlme_vdev_subst_start_disconn_progress_entry,
1748 		mlme_vdev_subst_start_disconn_progress_exit,
1749 		mlme_vdev_subst_start_disconn_progress_event
1750 	},
1751 	{
1752 		(uint8_t)WLAN_VDEV_SS_SUSPEND_SUSPEND_DOWN,
1753 		(uint8_t)WLAN_VDEV_S_SUSPEND,
1754 		(uint8_t)WLAN_SM_ENGINE_STATE_NONE,
1755 		false,
1756 		"SP-SUSPEND_DOWN",
1757 		mlme_vdev_subst_suspend_suspend_down_entry,
1758 		mlme_vdev_subst_suspend_suspend_down_exit,
1759 		mlme_vdev_subst_suspend_suspend_down_event
1760 	},
1761 	{
1762 		(uint8_t)WLAN_VDEV_SS_SUSPEND_SUSPEND_RESTART,
1763 		(uint8_t)WLAN_VDEV_S_SUSPEND,
1764 		(uint8_t)WLAN_SM_ENGINE_STATE_NONE,
1765 		false,
1766 		"SP-SUSPEND_RESTART",
1767 		mlme_vdev_subst_suspend_suspend_restart_entry,
1768 		mlme_vdev_subst_suspend_suspend_restart_exit,
1769 		mlme_vdev_subst_suspend_suspend_restart_event
1770 	},
1771 	{
1772 		(uint8_t)WLAN_VDEV_SS_SUSPEND_HOST_RESTART,
1773 		(uint8_t)WLAN_VDEV_S_SUSPEND,
1774 		(uint8_t)WLAN_SM_ENGINE_STATE_NONE,
1775 		false,
1776 		"SP-HOST_RESTART",
1777 		mlme_vdev_subst_suspend_host_restart_entry,
1778 		mlme_vdev_subst_suspend_host_restart_exit,
1779 		mlme_vdev_subst_suspend_host_restart_event
1780 	},
1781 	{
1782 		(uint8_t)WLAN_VDEV_SS_SUSPEND_CSA_RESTART,
1783 		(uint8_t)WLAN_VDEV_S_SUSPEND,
1784 		(uint8_t)WLAN_SM_ENGINE_STATE_NONE,
1785 		false,
1786 		"SP-CSA_RESTART",
1787 		mlme_vdev_subst_suspend_csa_restart_entry,
1788 		mlme_vdev_subst_suspend_csa_restart_exit,
1789 		mlme_vdev_subst_suspend_csa_restart_event
1790 	},
1791 	{
1792 		(uint8_t)WLAN_VDEV_SS_STOP_STOP_PROGRESS,
1793 		(uint8_t)WLAN_VDEV_S_STOP,
1794 		(uint8_t)WLAN_SM_ENGINE_STATE_NONE,
1795 		false,
1796 		"STOP-STOP_PROG",
1797 		mlme_vdev_subst_stop_stop_progress_entry,
1798 		mlme_vdev_subst_stop_stop_progress_exit,
1799 		mlme_vdev_subst_stop_stop_progress_event
1800 	},
1801 	{
1802 		(uint8_t)WLAN_VDEV_SS_STOP_DOWN_PROGRESS,
1803 		(uint8_t)WLAN_VDEV_S_STOP,
1804 		(uint8_t)WLAN_SM_ENGINE_STATE_NONE,
1805 		false,
1806 		"STOP-DOWN_PROG",
1807 		mlme_vdev_subst_stop_down_progress_entry,
1808 		mlme_vdev_subst_stop_down_progress_exit,
1809 		mlme_vdev_subst_stop_down_progress_event
1810 	},
1811 	{
1812 		(uint8_t)WLAN_VDEV_SS_IDLE,
1813 		(uint8_t)WLAN_SM_ENGINE_STATE_NONE,
1814 		(uint8_t)WLAN_SM_ENGINE_STATE_NONE,
1815 		false,
1816 		"IDLE",
1817 		NULL,
1818 		NULL,
1819 		NULL,
1820 	},
1821 	{
1822 		(uint8_t)WLAN_VDEV_SS_MAX,
1823 		(uint8_t)WLAN_SM_ENGINE_STATE_NONE,
1824 		(uint8_t)WLAN_SM_ENGINE_STATE_NONE,
1825 		false,
1826 		"INVALID",
1827 		NULL,
1828 		NULL,
1829 		NULL,
1830 	},
1831 };
1832 
1833 QDF_STATUS mlme_vdev_sm_deliver_event(struct vdev_mlme_obj *vdev_mlme,
1834 				      enum wlan_vdev_sm_evt event,
1835 				      uint16_t event_data_len, void *event_data)
1836 {
1837 	return wlan_sm_dispatch(vdev_mlme->sm_hdl, event,
1838 				event_data_len, event_data);
1839 }
1840 
1841 void mlme_vdev_sm_print_state_event(struct vdev_mlme_obj *vdev_mlme,
1842 				    enum wlan_vdev_sm_evt event)
1843 {
1844 	enum wlan_vdev_state state;
1845 	enum wlan_vdev_state substate;
1846 	struct wlan_objmgr_vdev *vdev;
1847 
1848 	vdev = vdev_mlme->vdev;
1849 
1850 	state = wlan_vdev_mlme_get_state(vdev);
1851 	substate = wlan_vdev_mlme_get_substate(vdev);
1852 
1853 	mlme_nofl_debug("[%s]%s - %s, %s", vdev_mlme->sm_hdl->name,
1854 			sm_info[state].name, sm_info[substate].name,
1855 			vdev_sm_event_names[event]);
1856 }
1857 
1858 void mlme_vdev_sm_print_state(struct vdev_mlme_obj *vdev_mlme)
1859 {
1860 	enum wlan_vdev_state state;
1861 	enum wlan_vdev_state substate;
1862 	struct wlan_objmgr_vdev *vdev;
1863 
1864 	vdev = vdev_mlme->vdev;
1865 
1866 	state = wlan_vdev_mlme_get_state(vdev);
1867 	substate = wlan_vdev_mlme_get_substate(vdev);
1868 
1869 	mlme_nofl_debug("[%s]%s - %s", vdev_mlme->sm_hdl->name,
1870 			sm_info[state].name, sm_info[substate].name);
1871 }
1872 
1873 #ifdef SM_ENG_HIST_ENABLE
1874 void mlme_vdev_sm_history_print(struct vdev_mlme_obj *vdev_mlme)
1875 {
1876 	return wlan_sm_print_history(vdev_mlme->sm_hdl);
1877 }
1878 #endif
1879 
1880 QDF_STATUS mlme_vdev_sm_create(struct vdev_mlme_obj *vdev_mlme)
1881 {
1882 	struct wlan_sm *sm;
1883 	uint8_t name[WLAN_SM_ENGINE_MAX_NAME];
1884 
1885 	qdf_snprintf(name, sizeof(name), "VDEV%d-MLME",
1886 		     wlan_vdev_get_id(vdev_mlme->vdev));
1887 	sm = wlan_sm_create(name, vdev_mlme,
1888 			    WLAN_VDEV_S_INIT,
1889 			    sm_info,
1890 			    QDF_ARRAY_SIZE(sm_info),
1891 			    vdev_sm_event_names,
1892 			    QDF_ARRAY_SIZE(vdev_sm_event_names));
1893 	if (!sm) {
1894 		mlme_err("VDEV MLME SM allocation failed");
1895 		return QDF_STATUS_E_FAILURE;
1896 	}
1897 	vdev_mlme->sm_hdl = sm;
1898 
1899 	mlme_vdev_sm_spinlock_create(vdev_mlme);
1900 
1901 	mlme_vdev_cmd_mutex_create(vdev_mlme);
1902 
1903 	return QDF_STATUS_SUCCESS;
1904 }
1905 
1906 QDF_STATUS mlme_vdev_sm_destroy(struct vdev_mlme_obj *vdev_mlme)
1907 {
1908 	mlme_vdev_cmd_mutex_destroy(vdev_mlme);
1909 
1910 	mlme_vdev_sm_spinlock_destroy(vdev_mlme);
1911 
1912 	wlan_sm_delete(vdev_mlme->sm_hdl);
1913 
1914 	return QDF_STATUS_SUCCESS;
1915 }
1916