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