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