xref: /wlan-dirver/qca-wifi-host-cmn/umac/mlme/vdev_mgr/core/src/vdev_mlme_sm.c (revision 97f44cd39e4ff816eaa1710279d28cf6b9e65ad9)
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 		/* fallthrough */
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 		/* fallthrough */
484 	case WLAN_VDEV_SM_EV_START:
485 		/* notify that UP command is completed */
486 		mlme_vdev_notify_up_complete(vdev_mlme,
487 					     event_data_len, event_data);
488 		status = true;
489 		break;
490 
491 	case WLAN_VDEV_SM_EV_FW_VDEV_RESTART:
492 		mlme_vdev_sm_transition_to(vdev_mlme, WLAN_VDEV_S_START);
493 		mlme_vdev_sm_deliver_event(vdev_mlme,
494 					   WLAN_VDEV_SM_EV_RESTART_REQ,
495 					   event_data_len, event_data);
496 		status = true;
497 		break;
498 
499 	case WLAN_VDEV_SM_EV_UP_FAIL:
500 		mlme_vdev_sm_transition_to(vdev_mlme, WLAN_VDEV_S_SUSPEND);
501 		mlme_vdev_sm_deliver_event(vdev_mlme, event,
502 					   event_data_len, event_data);
503 		status = true;
504 		break;
505 
506 	case WLAN_VDEV_SM_EV_ROAM:
507 		mlme_vdev_notify_roam_start(vdev_mlme, event_data_len,
508 					    event_data);
509 		status = true;
510 		break;
511 
512 	default:
513 		status = false;
514 		break;
515 	}
516 
517 	return status;
518 }
519 
520 /**
521  * mlme_vdev_state_suspend_entry() - Entry API for Suspend state
522  * @ctx: VDEV MLME object
523  *
524  * API to perform operations on moving to SUSPEND state
525  *
526  * Return: void
527  */
528 static void mlme_vdev_state_suspend_entry(void *ctx)
529 {
530 	struct vdev_mlme_obj *vdev_mlme = (struct vdev_mlme_obj *)ctx;
531 
532 	mlme_vdev_sm_state_update(vdev_mlme, WLAN_VDEV_S_SUSPEND,
533 				  WLAN_VDEV_SS_IDLE);
534 }
535 
536 /**
537  * mlme_vdev_state_suspend_exit() - Exit API for Suspend state
538  * @ctx: VDEV MLME object
539  *
540  * API to perform operations on moving out of SUSPEND state
541  *
542  * Return: void
543  */
544 static void mlme_vdev_state_suspend_exit(void *ctx)
545 {
546 	/* NONE */
547 }
548 
549 /**
550  * mlme_vdev_state_suspend_event() - Suspend State event handler
551  * @ctx: VDEV MLME object
552  *
553  * API to handle events in SUSPEND state
554  *
555  * Return: SUCCESS: on handling event
556  *         FAILURE: on ignoring the event
557  */
558 static bool mlme_vdev_state_suspend_event(void *ctx, uint16_t event,
559 					  uint16_t event_data_len,
560 					  void *event_data)
561 {
562 	struct vdev_mlme_obj *vdev_mlme = (struct vdev_mlme_obj *)ctx;
563 	bool status;
564 
565 	switch (event) {
566 	case WLAN_VDEV_SM_EV_DOWN:
567 	case WLAN_VDEV_SM_EV_RESTART_REQ_FAIL:
568 		mlme_vdev_sm_transition_to(vdev_mlme,
569 					   WLAN_VDEV_SS_SUSPEND_SUSPEND_DOWN);
570 		mlme_vdev_sm_deliver_event(vdev_mlme, event,
571 					   event_data_len, event_data);
572 		status = true;
573 		break;
574 
575 	case WLAN_VDEV_SM_EV_SUSPEND_RESTART:
576 		mlme_vdev_sm_transition_to(vdev_mlme,
577 					  WLAN_VDEV_SS_SUSPEND_SUSPEND_RESTART);
578 		mlme_vdev_sm_deliver_event(vdev_mlme, event,
579 					   event_data_len, event_data);
580 		status = true;
581 		break;
582 
583 	case WLAN_VDEV_SM_EV_HOST_RESTART:
584 		mlme_vdev_sm_transition_to(vdev_mlme,
585 					   WLAN_VDEV_SS_SUSPEND_HOST_RESTART);
586 		mlme_vdev_sm_deliver_event(vdev_mlme, event,
587 					   event_data_len, event_data);
588 		status = true;
589 		break;
590 
591 	case WLAN_VDEV_SM_EV_CSA_RESTART:
592 		mlme_vdev_sm_transition_to(vdev_mlme,
593 					   WLAN_VDEV_SS_SUSPEND_CSA_RESTART);
594 		mlme_vdev_sm_deliver_event(vdev_mlme, event,
595 					   event_data_len, event_data);
596 		status = true;
597 		break;
598 
599 	case WLAN_VDEV_SM_EV_UP_FAIL:
600 		mlme_vdev_sm_transition_to(vdev_mlme,
601 					   WLAN_VDEV_SS_SUSPEND_SUSPEND_DOWN);
602 		mlme_vdev_sm_deliver_event(vdev_mlme, WLAN_VDEV_SM_EV_DOWN,
603 					   event_data_len, event_data);
604 		status = true;
605 		break;
606 
607 	default:
608 		status = false;
609 		break;
610 	}
611 
612 	return status;
613 }
614 
615 /**
616  * mlme_vdev_state_stop_entry() - Entry API for Stop state
617  * @ctx: VDEV MLME object
618  *
619  * API to perform operations on moving to STOP state
620  *
621  * Return: void
622  */
623 static void mlme_vdev_state_stop_entry(void *ctx)
624 {
625 	struct vdev_mlme_obj *vdev_mlme = (struct vdev_mlme_obj *) ctx;
626 
627 	mlme_vdev_sm_state_update(vdev_mlme, WLAN_VDEV_S_STOP,
628 				  WLAN_VDEV_SS_IDLE);
629 }
630 
631 /**
632  * mlme_vdev_state_stop_exit() - Exit API for Stop state
633  * @ctx: VDEV MLME object
634  *
635  * API to perform operations on moving out of STOP state
636  *
637  * Return: void
638  */
639 static void mlme_vdev_state_stop_exit(void *ctx)
640 {
641 	/* NONE */
642 }
643 
644 /**
645  * mlme_vdev_state_stop_event() - Stop State event handler
646  * @ctx: VDEV MLME object
647  *
648  * API to handle events in STOP state
649  *
650  * Return: SUCCESS: on handling event
651  *         FAILURE: on ignoring the event
652  */
653 static bool mlme_vdev_state_stop_event(void *ctx, uint16_t event,
654 				       uint16_t event_data_len,
655 				       void *event_data)
656 {
657 	QDF_BUG(0);
658 	return false;
659 }
660 
661 /**
662  * mlme_vdev_subst_start_start_progress_entry() - Entry API for Start Progress
663  *                                                sub state
664  * @ctx: VDEV MLME object
665  *
666  * API to perform operations on moving to START-PROGRESS substate
667  *
668  * Return: void
669  */
670 static void mlme_vdev_subst_start_start_progress_entry(void *ctx)
671 {
672 	struct vdev_mlme_obj *vdev_mlme = (struct vdev_mlme_obj *)ctx;
673 	struct wlan_objmgr_vdev *vdev;
674 
675 	vdev = vdev_mlme->vdev;
676 
677 	if (wlan_vdev_mlme_get_state(vdev) != WLAN_VDEV_S_START)
678 		QDF_BUG(0);
679 
680 	mlme_vdev_set_substate(vdev, WLAN_VDEV_SS_START_START_PROGRESS);
681 }
682 
683 /**
684  * mlme_vdev_subst_start_start_progress_exit() - Exit API for Start Progress
685  *                                                sub state
686  * @ctx: VDEV MLME object
687  *
688  * API to perform operations on moving out of START-PROGRESS substate
689  *
690  * Return: void
691  */
692 static void mlme_vdev_subst_start_start_progress_exit(void *ctx)
693 {
694 	/* NONE */
695 }
696 
697 /**
698  * mlme_vdev_subst_start_start_progress_event() - Event handler API for Start
699  *                                                Progress substate
700  * @ctx: VDEV MLME object
701  *
702  * API to handle events in START-PROGRESS substate
703  *
704  * Return: SUCCESS: on handling event
705  *         FAILURE: on ignoring the event
706  */
707 static bool mlme_vdev_subst_start_start_progress_event(void *ctx,
708 		uint16_t event, uint16_t event_data_len, void *event_data)
709 {
710 	struct vdev_mlme_obj *vdev_mlme = (struct vdev_mlme_obj *)ctx;
711 	struct wlan_objmgr_vdev *vdev;
712 	bool status;
713 
714 	vdev = vdev_mlme->vdev;
715 
716 	switch (event) {
717 	case WLAN_VDEV_SM_EV_START_REQ:
718 		/* send vdev start req command to FW */
719 		mlme_vdev_start_send(vdev_mlme,	event_data_len, event_data);
720 		status = true;
721 		break;
722 	/* While waiting for START response, move to RESTART_PROGRESS,
723 	 * wait for START response to send RESTART req */
724 	case WLAN_VDEV_SM_EV_RADAR_DETECTED:
725 		mlme_vdev_sm_transition_to(vdev_mlme,
726 					   WLAN_VDEV_SS_START_RESTART_PROGRESS);
727 		status = true;
728 		break;
729 	case WLAN_VDEV_SM_EV_START_RESP:
730 	case WLAN_VDEV_SM_EV_RESTART_RESP:
731 		mlme_vdev_sm_transition_to(vdev_mlme,
732 					   WLAN_VDEV_SS_START_CONN_PROGRESS);
733 		mlme_vdev_sm_deliver_event(vdev_mlme,
734 					   WLAN_VDEV_SM_EV_CONN_PROGRESS,
735 					   event_data_len, event_data);
736 		status = true;
737 		break;
738 
739 	case WLAN_VDEV_SM_EV_START_REQ_FAIL:
740 		mlme_vdev_start_req_failed(vdev_mlme,
741 					   event_data_len, event_data);
742 		mlme_vdev_sm_transition_to(vdev_mlme, WLAN_VDEV_S_INIT);
743 		mlme_vdev_sm_deliver_event(vdev_mlme, event,
744 					   event_data_len, event_data);
745 		status = true;
746 		break;
747 
748 	case WLAN_VDEV_SM_EV_DOWN:
749 		mlme_vdev_sm_transition_to(vdev_mlme,
750 					   WLAN_VDEV_SS_START_DISCONN_PROGRESS);
751 		/* block start request, if it is pending */
752 		mlme_vdev_stop_start_send(vdev_mlme, START_REQ,
753 					  event_data_len, event_data);
754 		status = true;
755 		break;
756 
757 	default:
758 		status = false;
759 		break;
760 	}
761 
762 	return status;
763 }
764 
765 /**
766  * mlme_vdev_subst_start_restart_progress_entry() - Entry API for Restart
767  *                                                  progress sub state
768  * @ctx: VDEV MLME object
769  *
770  * API to perform operations on moving to RESTART-PROGRESS substate
771  *
772  * Return: void
773  */
774 static void mlme_vdev_subst_start_restart_progress_entry(void *ctx)
775 {
776 	struct vdev_mlme_obj *vdev_mlme = (struct vdev_mlme_obj *)ctx;
777 	struct wlan_objmgr_vdev *vdev;
778 
779 	vdev = vdev_mlme->vdev;
780 
781 	if (wlan_vdev_mlme_get_state(vdev) != WLAN_VDEV_S_START)
782 		QDF_BUG(0);
783 
784 	mlme_vdev_set_substate(vdev, WLAN_VDEV_SS_START_RESTART_PROGRESS);
785 }
786 
787 /**
788  * mlme_vdev_subst_start_restart_progress_exit() - Exit API for Restart Progress
789  *                                                 sub state
790  * @ctx: VDEV MLME object
791  *
792  * API to perform operations on moving out of RESTART-PROGRESS substate
793  *
794  * Return: void
795  */
796 static void mlme_vdev_subst_start_restart_progress_exit(void *ctx)
797 {
798 	/* NONE */
799 }
800 
801 /**
802  * mlme_vdev_subst_start_restart_progress_event() - Event handler API for
803  *                                                  Restart Progress substate
804  * @ctx: VDEV MLME object
805  *
806  * API to handle events in RESTART-PROGRESS substate
807  *
808  * Return: SUCCESS: on handling event
809  *         FAILURE: on ignoring the event
810  */
811 static bool mlme_vdev_subst_start_restart_progress_event(void *ctx,
812 		uint16_t event, uint16_t event_data_len, void *event_data)
813 {
814 	struct vdev_mlme_obj *vdev_mlme = (struct vdev_mlme_obj *)ctx;
815 	struct wlan_objmgr_vdev *vdev;
816 	bool status;
817 
818 	vdev = vdev_mlme->vdev;
819 
820 	switch (event) {
821 	case WLAN_VDEV_SM_EV_RESTART_REQ:
822 	/* If Start resp is pending, send restart after start response */
823 	case WLAN_VDEV_SM_EV_START_RESP:
824 		/* send vdev restart req command to FW */
825 		mlme_vdev_restart_send(vdev_mlme, event_data_len, event_data);
826 		status = true;
827 		break;
828 	case WLAN_VDEV_SM_EV_RESTART_RESP:
829 		mlme_vdev_sm_transition_to(vdev_mlme,
830 					   WLAN_VDEV_SS_START_CONN_PROGRESS);
831 		mlme_vdev_sm_deliver_event(vdev_mlme,
832 					   WLAN_VDEV_SM_EV_CONN_PROGRESS,
833 					   event_data_len, event_data);
834 		status = true;
835 		break;
836 
837 	case WLAN_VDEV_SM_EV_RESTART_REQ_FAIL:
838 		mlme_vdev_sm_transition_to(vdev_mlme, WLAN_VDEV_S_SUSPEND);
839 		mlme_vdev_sm_deliver_event(vdev_mlme, event,
840 					   event_data_len, event_data);
841 		status = true;
842 		break;
843 
844 	case WLAN_VDEV_SM_EV_DOWN:
845 		mlme_vdev_sm_transition_to(vdev_mlme,
846 					   WLAN_VDEV_SS_START_DISCONN_PROGRESS);
847 		/* block restart request, if it is pending */
848 		mlme_vdev_stop_start_send(vdev_mlme, RESTART_REQ,
849 					  event_data_len, event_data);
850 		status = true;
851 		break;
852 
853 	case WLAN_VDEV_SM_EV_RADAR_DETECTED:
854 		/* It is complicated to handle RADAR detected in this substate,
855 		 * as vdev updates des channels as bss channel on response,
856 		 * it would be easily handled, if it is deferred by DFS module
857 		 */
858 		QDF_BUG(0);
859 		status = true;
860 		break;
861 
862 	default:
863 		status = false;
864 		break;
865 	}
866 
867 	return status;
868 }
869 
870 /**
871  * mlme_vdev_subst_start_conn_progress_entry() - Entry API for Conn. Progress
872  *                                                sub state
873  * @ctx: VDEV MLME object
874  *
875  * API to perform operations on moving to CONN-PROGRESS substate
876  *
877  * Return: void
878  */
879 static void mlme_vdev_subst_start_conn_progress_entry(void *ctx)
880 {
881 	struct vdev_mlme_obj *vdev_mlme = (struct vdev_mlme_obj *)ctx;
882 	struct wlan_objmgr_vdev *vdev;
883 
884 	vdev = vdev_mlme->vdev;
885 
886 	if (wlan_vdev_mlme_get_state(vdev) != WLAN_VDEV_S_START)
887 		QDF_BUG(0);
888 
889 	mlme_vdev_set_substate(vdev, WLAN_VDEV_SS_START_CONN_PROGRESS);
890 }
891 
892 /**
893  * mlme_vdev_subst_start_conn_progress_exit() - Exit API for Conn. Progress
894  *                                              sub state
895  * @ctx: VDEV MLME object
896  *
897  * API to perform operations on moving out of CONN-PROGRESS substate
898  *
899  * Return: void
900  */
901 static void mlme_vdev_subst_start_conn_progress_exit(void *ctx)
902 {
903 	struct vdev_mlme_obj *vdev_mlme = (struct vdev_mlme_obj *)ctx;
904 
905 	mlme_vdev_notify_start_state_exit(vdev_mlme);
906 }
907 
908 /**
909  * mlme_vdev_subst_start_conn_progress_event() - Event handler API for Conn.
910  *                                                Progress substate
911  * @ctx: VDEV MLME object
912  *
913  * API to handle events in CONN-PROGRESS substate
914  *
915  * Return: SUCCESS: on handling event
916  *         FAILURE: on ignoring the event
917  */
918 static bool mlme_vdev_subst_start_conn_progress_event(void *ctx,
919 						      uint16_t event,
920 						      uint16_t event_data_len,
921 						      void *event_data)
922 {
923 	struct vdev_mlme_obj *vdev_mlme = (struct vdev_mlme_obj *)ctx;
924 	enum QDF_OPMODE mode;
925 	struct wlan_objmgr_vdev *vdev;
926 	bool status;
927 
928 	vdev = vdev_mlme->vdev;
929 
930 	mode = wlan_vdev_mlme_get_opmode(vdev);
931 
932 	switch (event) {
933 	case WLAN_VDEV_SM_EV_CONN_PROGRESS:
934 		/* This API decides to move to DFS CAC WAIT or UP state,
935 		 * for station notify connection state machine */
936 		if (mlme_vdev_start_continue(vdev_mlme, event_data_len,
937 					     event_data) != QDF_STATUS_SUCCESS)
938 			mlme_vdev_sm_deliver_event(
939 					vdev_mlme,
940 					WLAN_VDEV_SM_EV_CONNECTION_FAIL,
941 					event_data_len, event_data);
942 		status = true;
943 		break;
944 
945 	case WLAN_VDEV_SM_EV_DFS_CAC_WAIT:
946 		mlme_vdev_sm_transition_to(vdev_mlme, WLAN_VDEV_S_DFS_CAC_WAIT);
947 		mlme_vdev_sm_deliver_event(vdev_mlme, event,
948 					   event_data_len, event_data);
949 		status = true;
950 		break;
951 
952 	case WLAN_VDEV_SM_EV_START_SUCCESS:
953 		mlme_vdev_sm_transition_to(vdev_mlme, WLAN_VDEV_S_UP);
954 		mlme_vdev_sm_deliver_event(vdev_mlme, event,
955 					   event_data_len, event_data);
956 		status = true;
957 		break;
958 
959 	case WLAN_VDEV_SM_EV_STA_CONN_START:
960 		/* This event triggers station connection, if it is blocked for
961 		 * CAC WAIT
962 		 */
963 		if (mode != QDF_STA_MODE)
964 			QDF_BUG(0);
965 
966 		mlme_vdev_sta_conn_start(vdev_mlme, event_data_len, event_data);
967 		status = true;
968 		break;
969 
970 	case WLAN_VDEV_SM_EV_RADAR_DETECTED:
971 		if (mode != QDF_STA_MODE)
972 			QDF_BUG(0);
973 
974 		status = true;
975 		break;
976 
977 	case WLAN_VDEV_SM_EV_DOWN:
978 	case WLAN_VDEV_SM_EV_CONNECTION_FAIL:
979 		mlme_vdev_sm_transition_to(vdev_mlme,
980 					   WLAN_VDEV_SS_START_DISCONN_PROGRESS);
981 		mlme_vdev_sm_deliver_event(vdev_mlme, event,
982 					   event_data_len, event_data);
983 		status = true;
984 		break;
985 
986 	default:
987 		status = false;
988 		break;
989 	}
990 
991 	return status;
992 }
993 
994 /**
995  * mlme_vdev_subst_start_disconn_progress_entry() - Entry API for Disconn
996  *                                                  progress sub state
997  * @ctx: VDEV MLME object
998  *
999  * API to perform operations on moving to DISCONN-PROGRESS substate
1000  *
1001  * Return: SUCCESS: on handling event
1002  *         FAILURE: on ignoring the event
1003  */
1004 static void mlme_vdev_subst_start_disconn_progress_entry(void *ctx)
1005 {
1006 	struct vdev_mlme_obj *vdev_mlme = (struct vdev_mlme_obj *)ctx;
1007 	struct wlan_objmgr_vdev *vdev;
1008 
1009 	vdev = vdev_mlme->vdev;
1010 
1011 	if (wlan_vdev_mlme_get_state(vdev) != WLAN_VDEV_S_START)
1012 		QDF_BUG(0);
1013 
1014 	mlme_vdev_set_substate(vdev, WLAN_VDEV_SS_START_DISCONN_PROGRESS);
1015 }
1016 
1017 /**
1018  * mlme_vdev_subst_start_disconn_progress_exit() - Exit API for Disconn Progress
1019  *                                                sub state
1020  * @ctx: VDEV MLME object
1021  *
1022  * API to perform operations on moving out of DISCONN-PROGRESS substate
1023  *
1024  * Return: void
1025  */
1026 static void mlme_vdev_subst_start_disconn_progress_exit(void *ctx)
1027 {
1028 	/* NONE */
1029 }
1030 
1031 /**
1032  * mlme_vdev_subst_start_disconn_progress_event() - Event handler API for Discon
1033  *                                                Progress substate
1034  * @ctx: VDEV MLME object
1035  *
1036  * API to handle events in DISCONN-PROGRESS substate
1037  *
1038  * Return: SUCCESS: on handling event
1039  *         FAILURE: on ignoring the event
1040  */
1041 static bool mlme_vdev_subst_start_disconn_progress_event(void *ctx,
1042 		uint16_t event, uint16_t event_data_len, void *event_data)
1043 {
1044 	struct vdev_mlme_obj *vdev_mlme = (struct vdev_mlme_obj *)ctx;
1045 	bool status;
1046 
1047 	switch (event) {
1048 	case WLAN_VDEV_SM_EV_START_RESP:
1049 	/* clean up, if any needs to be cleaned up */
1050 	case WLAN_VDEV_SM_EV_CONNECTION_FAIL:
1051 		mlme_vdev_sm_transition_to(vdev_mlme, WLAN_VDEV_S_STOP);
1052 		mlme_vdev_sm_deliver_event(vdev_mlme, WLAN_VDEV_SM_EV_STOP_REQ,
1053 					   event_data_len, event_data);
1054 		status = true;
1055 		break;
1056 
1057 	case WLAN_VDEV_SM_EV_RESTART_RESP:
1058 	case WLAN_VDEV_SM_EV_RESTART_REQ_FAIL:
1059 		mlme_vdev_sm_transition_to(vdev_mlme, WLAN_VDEV_S_SUSPEND);
1060 		mlme_vdev_sm_deliver_event(vdev_mlme, WLAN_VDEV_SM_EV_DOWN,
1061 					   event_data_len, event_data);
1062 		status = true;
1063 		break;
1064 
1065 	case WLAN_VDEV_SM_EV_START_REQ_FAIL:
1066 		mlme_vdev_sm_transition_to(vdev_mlme, WLAN_VDEV_S_INIT);
1067 		mlme_vdev_sm_deliver_event(vdev_mlme, event,
1068 					   event_data_len, event_data);
1069 		status = true;
1070 		break;
1071 
1072 	default:
1073 		status = false;
1074 		break;
1075 	}
1076 
1077 	return status;
1078 }
1079 
1080 /**
1081  * mlme_vdev_subst_suspend_suspend_down_entry() - Entry API for Suspend down
1082  *                                                sub state
1083  * @ctx: VDEV MLME object
1084  *
1085  * API to perform operations on moving to SUSPEND-DOWN substate
1086  *
1087  * Return: void
1088  */
1089 static void mlme_vdev_subst_suspend_suspend_down_entry(void *ctx)
1090 {
1091 	struct vdev_mlme_obj *vdev_mlme = (struct vdev_mlme_obj *)ctx;
1092 	struct wlan_objmgr_vdev *vdev;
1093 
1094 	vdev = vdev_mlme->vdev;
1095 
1096 	if (wlan_vdev_mlme_get_state(vdev) != WLAN_VDEV_S_SUSPEND)
1097 		QDF_BUG(0);
1098 
1099 	mlme_vdev_set_substate(vdev, WLAN_VDEV_SS_SUSPEND_SUSPEND_DOWN);
1100 }
1101 
1102 /**
1103  * mlme_vdev_subst_suspend_suspend_down_exit() - Exit API for Suspend down
1104  *                                                sub state
1105  * @ctx: VDEV MLME object
1106  *
1107  * API to perform operations on moving out of SUSPEND-DOWN substate
1108  *
1109  * Return: void
1110  */
1111 static void mlme_vdev_subst_suspend_suspend_down_exit(void *ctx)
1112 {
1113 	/* NONE */
1114 }
1115 
1116 /**
1117  * mlme_vdev_subst_suspend_suspend_down_event() - Event handler API for Suspend
1118  *                                                down substate
1119  * @ctx: VDEV MLME object
1120  *
1121  * API to handle events in SUSPEND-DOWN substate
1122  *
1123  * Return: SUCCESS: on handling event
1124  *         FAILURE: on ignoring the event
1125  */
1126 static bool mlme_vdev_subst_suspend_suspend_down_event(void *ctx,
1127 		uint16_t event, uint16_t event_data_len, void *event_data)
1128 {
1129 	struct vdev_mlme_obj *vdev_mlme = (struct vdev_mlme_obj *)ctx;
1130 	bool status;
1131 
1132 	switch (event) {
1133 	case WLAN_VDEV_SM_EV_DOWN:
1134 	case WLAN_VDEV_SM_EV_RESTART_REQ_FAIL:
1135 		mlme_vdev_disconnect_peers(vdev_mlme,
1136 					   event_data_len, event_data);
1137 		status = true;
1138 		break;
1139 
1140 	case WLAN_VDEV_SM_EV_DISCONNECT_COMPLETE:
1141 		/* clean up, if any needs to be cleaned up */
1142 		mlme_vdev_sm_transition_to(vdev_mlme, WLAN_VDEV_S_STOP);
1143 		mlme_vdev_sm_deliver_event(vdev_mlme, WLAN_VDEV_SM_EV_STOP_REQ,
1144 					   event_data_len, event_data);
1145 		status = true;
1146 		break;
1147 
1148 	default:
1149 		status = false;
1150 		break;
1151 	}
1152 
1153 	return status;
1154 }
1155 
1156 /**
1157  * mlme_vdev_subst_suspend_suspend_restart_entry() - Entry API for Suspend
1158  *                                                   restart substate
1159  * @ctx: VDEV MLME object
1160  *
1161  * API to perform operations on moving to SUSPEND-RESTART substate
1162  *
1163  * Return: void
1164  */
1165 static void mlme_vdev_subst_suspend_suspend_restart_entry(void *ctx)
1166 {
1167 	struct vdev_mlme_obj *vdev_mlme = (struct vdev_mlme_obj *)ctx;
1168 	struct wlan_objmgr_vdev *vdev;
1169 
1170 	vdev = vdev_mlme->vdev;
1171 
1172 	if (wlan_vdev_mlme_get_state(vdev) != WLAN_VDEV_S_SUSPEND)
1173 		QDF_BUG(0);
1174 
1175 	mlme_vdev_set_substate(vdev, WLAN_VDEV_SS_SUSPEND_SUSPEND_RESTART);
1176 }
1177 
1178 /**
1179  * mlme_vdev_subst_suspend_suspend_restart_exit() - Exit API for Suspend restart
1180  *                                                sub state
1181  * @ctx: VDEV MLME object
1182  *
1183  * API to perform operations on moving out of SUSPEND-RESTART substate
1184  *
1185  * Return: void
1186  */
1187 static void mlme_vdev_subst_suspend_suspend_restart_exit(void *ctx)
1188 {
1189 	/* NONE */
1190 }
1191 
1192 /**
1193  * mlme_vdev_subst_suspend_suspend_restart_event() - Event handler API for
1194  *                                                   Suspend restart substate
1195  * @ctx: VDEV MLME object
1196  *
1197  * API to handle events in SUSPEND-RESTART substate
1198  *
1199  * Return: SUCCESS: on handling event
1200  *         FAILURE: on ignoring the event
1201  */
1202 static bool mlme_vdev_subst_suspend_suspend_restart_event(void *ctx,
1203 		uint16_t event, uint16_t event_data_len, void *event_data)
1204 {
1205 	struct vdev_mlme_obj *vdev_mlme = (struct vdev_mlme_obj *)ctx;
1206 	bool status;
1207 
1208 	switch (event) {
1209 	case WLAN_VDEV_SM_EV_SUSPEND_RESTART:
1210 		mlme_vdev_disconnect_peers(vdev_mlme,
1211 					   event_data_len, event_data);
1212 		status = true;
1213 		break;
1214 
1215 	case WLAN_VDEV_SM_EV_DISCONNECT_COMPLETE:
1216 		/* clean up, if any needs to be cleaned up */
1217 		mlme_vdev_sm_transition_to(vdev_mlme, WLAN_VDEV_S_START);
1218 		mlme_vdev_sm_deliver_event(vdev_mlme,
1219 					   WLAN_VDEV_SM_EV_RESTART_REQ,
1220 					   event_data_len, event_data);
1221 		status = true;
1222 		break;
1223 
1224 	case WLAN_VDEV_SM_EV_DOWN:
1225 		mlme_vdev_sm_transition_to(vdev_mlme,
1226 					   WLAN_VDEV_SS_SUSPEND_SUSPEND_DOWN);
1227 		status = true;
1228 		break;
1229 
1230 	case WLAN_VDEV_SM_EV_RADAR_DETECTED:
1231 		mlme_vdev_sm_transition_to(vdev_mlme,
1232 					   WLAN_VDEV_SS_SUSPEND_CSA_RESTART);
1233 		mlme_vdev_sm_deliver_event(vdev_mlme,
1234 					   WLAN_VDEV_SM_EV_CSA_RESTART,
1235 					   event_data_len, event_data);
1236 		status = true;
1237 		break;
1238 
1239 	default:
1240 		status = false;
1241 		break;
1242 	}
1243 
1244 	return status;
1245 }
1246 
1247 /**
1248  * mlme_vdev_subst_suspend_host_restart_entry() - Entry API for Host restart
1249  *                                                substate
1250  * @ctx: VDEV MLME object
1251  *
1252  * API to perform operations on moving to HOST-RESTART substate
1253  *
1254  * Return: void
1255  */
1256 static void mlme_vdev_subst_suspend_host_restart_entry(void *ctx)
1257 {
1258 	struct vdev_mlme_obj *vdev_mlme = (struct vdev_mlme_obj *)ctx;
1259 	struct wlan_objmgr_vdev *vdev;
1260 
1261 	vdev = vdev_mlme->vdev;
1262 
1263 	if (wlan_vdev_mlme_get_state(vdev) != WLAN_VDEV_S_SUSPEND)
1264 		QDF_BUG(0);
1265 
1266 	mlme_vdev_set_substate(vdev, WLAN_VDEV_SS_SUSPEND_HOST_RESTART);
1267 }
1268 
1269 /**
1270  * mlme_vdev_subst_suspend_host_restart_exit() - Exit API for host restart
1271  *                                                sub state
1272  * @ctx: VDEV MLME object
1273  *
1274  * API to perform operations on moving out of HOST-RESTART substate
1275  *
1276  * Return: void
1277  */
1278 static void mlme_vdev_subst_suspend_host_restart_exit(void *ctx)
1279 {
1280     /* NONE */
1281 }
1282 
1283 /**
1284  * mlme_vdev_subst_suspend_host_restart_entry() - Event handler API for Host
1285  *                                                restart substate
1286  * @ctx: VDEV MLME object
1287  *
1288  * API to handle events in HOST-RESTART substate
1289  *
1290  * Return: void
1291  */
1292 static bool mlme_vdev_subst_suspend_host_restart_event(void *ctx,
1293 		uint16_t event, uint16_t event_data_len, void *event_data)
1294 {
1295 	struct vdev_mlme_obj *vdev_mlme = (struct vdev_mlme_obj *)ctx;
1296 	bool status;
1297 
1298 	switch (event) {
1299 	case WLAN_VDEV_SM_EV_HOST_RESTART:
1300 		mlme_vdev_disconnect_peers(vdev_mlme,
1301 					   event_data_len, event_data);
1302 		status = true;
1303 		break;
1304 
1305 	case WLAN_VDEV_SM_EV_DISCONNECT_COMPLETE:
1306 		/* VDEV up command need not be sent */
1307 		mlme_vdev_sm_transition_to(vdev_mlme, WLAN_VDEV_S_UP);
1308 		mlme_vdev_sm_deliver_event(vdev_mlme,
1309 					   WLAN_VDEV_SM_EV_UP_HOST_RESTART,
1310 					   event_data_len, event_data);
1311 		status = true;
1312 		break;
1313 
1314 	case WLAN_VDEV_SM_EV_DOWN:
1315 		mlme_vdev_sm_transition_to(vdev_mlme,
1316 					   WLAN_VDEV_SS_SUSPEND_SUSPEND_DOWN);
1317 		status = true;
1318 		break;
1319 
1320 	case WLAN_VDEV_SM_EV_RADAR_DETECTED:
1321 		mlme_vdev_sm_transition_to(vdev_mlme,
1322 					   WLAN_VDEV_SS_SUSPEND_CSA_RESTART);
1323 		mlme_vdev_sm_deliver_event(vdev_mlme,
1324 					   WLAN_VDEV_SM_EV_CSA_RESTART,
1325 					   event_data_len, event_data);
1326 		status = true;
1327 		break;
1328 
1329 	default:
1330 		status = false;
1331 		break;
1332 	}
1333 
1334 	return status;
1335 }
1336 
1337 /**
1338  * mlme_vdev_subst_suspend_csa_restart_entry() - Entry API for CSA restart
1339  *                                               substate
1340  * @ctx: VDEV MLME object
1341  *
1342  * API to perform operations on moving to CSA-RESTART substate
1343  *
1344  * Return: void
1345  */
1346 static void mlme_vdev_subst_suspend_csa_restart_entry(void *ctx)
1347 {
1348 	struct vdev_mlme_obj *vdev_mlme = (struct vdev_mlme_obj *)ctx;
1349 	struct wlan_objmgr_vdev *vdev;
1350 
1351 	vdev = vdev_mlme->vdev;
1352 
1353 	if (wlan_vdev_mlme_get_state(vdev) != WLAN_VDEV_S_SUSPEND)
1354 		QDF_BUG(0);
1355 
1356 	mlme_vdev_set_substate(vdev, WLAN_VDEV_SS_SUSPEND_CSA_RESTART);
1357 }
1358 
1359 /**
1360  * mlme_vdev_subst_suspend_csa_restart_exit() - Exit API for CSA restart
1361  *                                                sub state
1362  * @ctx: VDEV MLME object
1363  *
1364  * API to perform operations on moving out of CSA-RESTART substate
1365  *
1366  * Return: void
1367  */
1368 static void mlme_vdev_subst_suspend_csa_restart_exit(void *ctx)
1369 {
1370     /* NONE */
1371 }
1372 
1373 /**
1374  * mlme_vdev_subst_suspend_csa_restart_event() - Event handler API for CSA
1375  *                                               restart substate
1376  * @ctx: VDEV MLME object
1377  *
1378  * API to handle events in CSA-RESTART substate
1379  *
1380  * Return: SUCCESS: on handling event
1381  *         FAILURE: on ignoring the event
1382  */
1383 static bool mlme_vdev_subst_suspend_csa_restart_event(void *ctx,
1384 		uint16_t event, uint16_t event_data_len, void *event_data)
1385 {
1386 	struct vdev_mlme_obj *vdev_mlme = (struct vdev_mlme_obj *)ctx;
1387 	bool status;
1388 
1389 	switch (event) {
1390 	case WLAN_VDEV_SM_EV_CHAN_SWITCH_DISABLED:
1391 	/**
1392 	 * This event is sent when CSA count becomes 0 without
1393 	 * change in channel i.e. only Beacon Probe response template
1394 	 * is updated (CSA / ECSA IE is removed).
1395 	 */
1396 
1397 		mlme_vdev_sm_transition_to(vdev_mlme, WLAN_VDEV_S_UP);
1398 		mlme_vdev_sm_deliver_event(vdev_mlme,
1399 					   WLAN_VDEV_SM_EV_UP_HOST_RESTART,
1400 					   event_data_len, event_data);
1401 		status = true;
1402 		break;
1403 	case WLAN_VDEV_SM_EV_CSA_RESTART:
1404 		mlme_vdev_update_beacon(vdev_mlme, BEACON_CSA,
1405 					event_data_len, event_data);
1406 		status = true;
1407 		break;
1408 	case WLAN_VDEV_SM_EV_CSA_COMPLETE:
1409 		if (mlme_vdev_is_newchan_no_cac(vdev_mlme) ==
1410 						QDF_STATUS_SUCCESS) {
1411 			mlme_vdev_sm_transition_to(vdev_mlme,
1412 						   WLAN_VDEV_S_START);
1413 			mlme_vdev_sm_deliver_event(vdev_mlme,
1414 						   WLAN_VDEV_SM_EV_RESTART_REQ,
1415 						   event_data_len, event_data);
1416 		} else if (mlme_vdev_replace_csa_with_stop_start(vdev_mlme) ==
1417 						QDF_STATUS_E_NOSUPPORT) {
1418 			mlme_vdev_sm_transition_to
1419 				(vdev_mlme,
1420 				 WLAN_VDEV_SS_SUSPEND_SUSPEND_RESTART);
1421 			mlme_vdev_sm_deliver_event
1422 				(vdev_mlme, WLAN_VDEV_SM_EV_SUSPEND_RESTART,
1423 				 event_data_len, event_data);
1424 		}
1425 		status = true;
1426 		break;
1427 
1428 	case WLAN_VDEV_SM_EV_DOWN:
1429 		mlme_vdev_sm_transition_to(vdev_mlme,
1430 					   WLAN_VDEV_SS_SUSPEND_SUSPEND_DOWN);
1431 		mlme_vdev_sm_deliver_event(vdev_mlme, event,
1432 					   event_data_len, event_data);
1433 		status = true;
1434 		break;
1435 
1436 	case WLAN_VDEV_SM_EV_RADAR_DETECTED:
1437 		/* since channel change is already in progress,
1438 		 * dfs ignore radar detected event
1439 		 */
1440 		status = true;
1441 		break;
1442 
1443 	default:
1444 		status = false;
1445 		break;
1446 	}
1447 
1448 	return status;
1449 }
1450 
1451 /**
1452  * mlme_vdev_subst_stop_stop_progress_entry() - Entry API for Stop Progress
1453  *                                                sub state
1454  * @ctx: VDEV MLME object
1455  *
1456  * API to perform operations on moving to STOP-PROGRESS substate
1457  *
1458  * Return: void
1459  */
1460 static void mlme_vdev_subst_stop_stop_progress_entry(void *ctx)
1461 {
1462 	struct vdev_mlme_obj *vdev_mlme = (struct vdev_mlme_obj *) ctx;
1463 	struct wlan_objmgr_vdev *vdev;
1464 
1465 	vdev = vdev_mlme->vdev;
1466 
1467 	if (wlan_vdev_mlme_get_state(vdev) != WLAN_VDEV_S_STOP)
1468 		QDF_BUG(0);
1469 
1470 	mlme_vdev_set_substate(vdev, WLAN_VDEV_SS_STOP_STOP_PROGRESS);
1471 }
1472 
1473 /**
1474  * mlme_vdev_subst_stop_stop_progress_exit() - Exit API for Stop Progress
1475  *                                                sub state
1476  * @ctx: VDEV MLME object
1477  *
1478  * API to perform operations on moving out of STOP-PROGRESS substate
1479  *
1480  * Return: void
1481  */
1482 static void mlme_vdev_subst_stop_stop_progress_exit(void *ctx)
1483 {
1484     /* NONE */
1485 }
1486 
1487 /**
1488  * mlme_vdev_subst_stop_stop_progress_event() - Event handler API for Stop
1489  *                                                Progress substate
1490  * @ctx: VDEV MLME object
1491  *
1492  * API to handle events in STOP-PROGRESS substate
1493  *
1494  * Return: SUCCESS: on handling event
1495  *         FAILURE: on ignoring the event
1496  */
1497 static bool mlme_vdev_subst_stop_stop_progress_event(void *ctx,
1498 		uint16_t event, uint16_t event_data_len, void *event_data)
1499 {
1500 	struct vdev_mlme_obj *vdev_mlme = (struct vdev_mlme_obj *)ctx;
1501 	bool status;
1502 
1503 	/* Debug framework is required to hold the events */
1504 
1505 	switch (event) {
1506 	case WLAN_VDEV_SM_EV_STOP_REQ:
1507 		/* send vdev stop command to FW and delete BSS peer*/
1508 		mlme_vdev_stop_send(vdev_mlme, event_data_len, event_data);
1509 		status = true;
1510 		break;
1511 
1512 	case WLAN_VDEV_SM_EV_STOP_RESP:
1513 		/* Processes stop response, and checks BSS peer delete wait
1514 		 * is needed
1515 		 */
1516 		mlme_vdev_stop_continue(vdev_mlme, event_data_len, event_data);
1517 		status = true;
1518 		break;
1519 
1520 	/* This event should be given by MLME on stop complete and BSS
1521 	 * peer delete complete to move forward
1522 	 */
1523 	case WLAN_VDEV_SM_EV_MLME_DOWN_REQ:
1524 		mlme_vdev_sm_transition_to(vdev_mlme,
1525 					   WLAN_VDEV_SS_STOP_DOWN_PROGRESS);
1526 		mlme_vdev_sm_deliver_event(vdev_mlme,
1527 					   WLAN_VDEV_SM_EV_MLME_DOWN_REQ,
1528 					   event_data_len, event_data);
1529 		status = true;
1530 		break;
1531 
1532 	case WLAN_VDEV_SM_EV_STOP_FAIL:
1533 		mlme_vdev_sm_transition_to(vdev_mlme,
1534 					   WLAN_VDEV_SS_STOP_DOWN_PROGRESS);
1535 		mlme_vdev_sm_deliver_event(vdev_mlme,
1536 					   WLAN_VDEV_SM_EV_MLME_DOWN_REQ,
1537 					   event_data_len, event_data);
1538 		status = true;
1539 		break;
1540 
1541 	default:
1542 		status = false;
1543 		break;
1544 	}
1545 
1546 	return status;
1547 }
1548 
1549 /**
1550  * mlme_vdev_subst_stop_down_progress_entry() - Entry API for Down Progress
1551  *                                                sub state
1552  * @ctx: VDEV MLME object
1553  *
1554  * API to perform operations on moving to DOWN-PROGRESS substate
1555  *
1556  * Return: void
1557  */
1558 static void mlme_vdev_subst_stop_down_progress_entry(void *ctx)
1559 {
1560 	struct vdev_mlme_obj *vdev_mlme = (struct vdev_mlme_obj *)ctx;
1561 	struct wlan_objmgr_vdev *vdev;
1562 
1563 	vdev = vdev_mlme->vdev;
1564 
1565 	if (wlan_vdev_mlme_get_state(vdev) != WLAN_VDEV_S_STOP)
1566 		QDF_BUG(0);
1567 
1568 	mlme_vdev_set_substate(vdev, WLAN_VDEV_SS_STOP_DOWN_PROGRESS);
1569 }
1570 
1571 /**
1572  * mlme_vdev_subst_stop_down_progress_exit() - Exit API for Down Progress
1573  *                                                sub state
1574  * @ctx: VDEV MLME object
1575  *
1576  * API to perform operations on moving out of DOWN-PROGRESS substate
1577  *
1578  * Return: void
1579  */
1580 static void mlme_vdev_subst_stop_down_progress_exit(void *ctx)
1581 {
1582 	/* NONE */
1583 }
1584 
1585 /**
1586  * mlme_vdev_subst_stop_down_progress_event() - Event handler API for Down
1587  *                                                Progress substate
1588  * @ctx: VDEV MLME object
1589  *
1590  * API to handle events in DOWN-PROGRESS substate
1591  *
1592  * Return: SUCCESS: on handling event
1593  *         FAILURE: on ignoring the event
1594  */
1595 static bool mlme_vdev_subst_stop_down_progress_event(void *ctx,
1596 		uint16_t event, uint16_t event_data_len, void *event_data)
1597 {
1598 	struct vdev_mlme_obj *vdev_mlme = (struct vdev_mlme_obj *)ctx;
1599 	bool status;
1600 
1601 	switch (event) {
1602 	case WLAN_VDEV_SM_EV_DOWN:
1603 		status = true;
1604 		break;
1605 
1606 	case WLAN_VDEV_SM_EV_MLME_DOWN_REQ:
1607 		/* send vdev down command to FW, if send is successful, sends
1608 		 * DOWN_COMPLETE event
1609 		 */
1610 		mlme_vdev_down_send(vdev_mlme, event_data_len, event_data);
1611 		status = true;
1612 		break;
1613 
1614 	case WLAN_VDEV_SM_EV_DOWN_COMPLETE:
1615 		mlme_vdev_sm_transition_to(vdev_mlme, WLAN_VDEV_S_INIT);
1616 		mlme_vdev_sm_deliver_event(vdev_mlme,
1617 					   WLAN_VDEV_SM_EV_DOWN_COMPLETE,
1618 					   event_data_len, event_data);
1619 		status = true;
1620 		break;
1621 
1622 	case WLAN_VDEV_SM_EV_DOWN_FAIL:
1623 		mlme_vdev_sm_transition_to(vdev_mlme, WLAN_VDEV_S_INIT);
1624 		mlme_vdev_sm_deliver_event(vdev_mlme,
1625 					   WLAN_VDEV_SM_EV_DOWN_COMPLETE,
1626 					   event_data_len, event_data);
1627 		status = true;
1628 		break;
1629 
1630 	default:
1631 		status = false;
1632 		break;
1633 	}
1634 
1635 	return status;
1636 }
1637 
1638 
1639 static const char *vdev_sm_event_names[] = {
1640 	"EV_START",
1641 	"EV_START_REQ",
1642 	"EV_RESTART_REQ",
1643 	"EV_START_RESP",
1644 	"EV_RESTART_RESP",
1645 	"EV_START_REQ_FAIL",
1646 	"EV_RESTART_REQ_FAIL",
1647 	"EV_START_SUCCESS",
1648 	"EV_CONN_PROGRESS",
1649 	"EV_STA_CONN_START",
1650 	"EV_DFS_CAC_WAIT",
1651 	"EV_DFS_CAC_COMPLETED",
1652 	"EV_DOWN",
1653 	"EV_CONNECTION_FAIL",
1654 	"EV_STOP_RESP",
1655 	"EV_STOP_FAIL",
1656 	"EV_DOWN_FAIL",
1657 	"EV_DISCONNECT_COMPLETE",
1658 	"EV_SUSPEND_RESTART",
1659 	"EV_HOST_RESTART",
1660 	"EV_UP_HOST_RESTART",
1661 	"EV_FW_VDEV_RESTART",
1662 	"EV_UP_FAIL",
1663 	"EV_RADAR_DETECTED",
1664 	"EV_CSA_RESTART",
1665 	"EV_CSA_COMPLETE",
1666 	"EV_MLME_DOWN_REQ",
1667 	"EV_DOWN_COMPLETE",
1668 	"EV_ROAM",
1669 	"EV_STOP_REQ",
1670 	"EV_CHAN_SWITCH_DISABLED",
1671 };
1672 
1673 struct wlan_sm_state_info sm_info[] = {
1674 	{
1675 		(uint8_t)WLAN_VDEV_S_INIT,
1676 		(uint8_t)WLAN_SM_ENGINE_STATE_NONE,
1677 		(uint8_t)WLAN_SM_ENGINE_STATE_NONE,
1678 		true,
1679 		"INIT",
1680 		mlme_vdev_state_init_entry,
1681 		mlme_vdev_state_init_exit,
1682 		mlme_vdev_state_init_event
1683 	},
1684 	{
1685 		(uint8_t)WLAN_VDEV_S_START,
1686 		(uint8_t)WLAN_SM_ENGINE_STATE_NONE,
1687 		(uint8_t)WLAN_SM_ENGINE_STATE_NONE,
1688 		true,
1689 		"START",
1690 		mlme_vdev_state_start_entry,
1691 		mlme_vdev_state_start_exit,
1692 		mlme_vdev_state_start_event
1693 	},
1694 	{
1695 		(uint8_t)WLAN_VDEV_S_DFS_CAC_WAIT,
1696 		(uint8_t)WLAN_SM_ENGINE_STATE_NONE,
1697 		(uint8_t)WLAN_SM_ENGINE_STATE_NONE,
1698 		true,
1699 		"DFS_CAC_WAIT",
1700 		mlme_vdev_state_dfs_cac_wait_entry,
1701 		mlme_vdev_state_dfs_cac_wait_exit,
1702 		mlme_vdev_state_dfs_cac_wait_event
1703 	},
1704 	{
1705 		(uint8_t)WLAN_VDEV_S_UP,
1706 		(uint8_t)WLAN_SM_ENGINE_STATE_NONE,
1707 		(uint8_t)WLAN_SM_ENGINE_STATE_NONE,
1708 		true,
1709 		"UP",
1710 		mlme_vdev_state_up_entry,
1711 		mlme_vdev_state_up_exit,
1712 		mlme_vdev_state_up_event
1713 	},
1714 	{
1715 		(uint8_t)WLAN_VDEV_S_SUSPEND,
1716 		(uint8_t)WLAN_SM_ENGINE_STATE_NONE,
1717 		(uint8_t)WLAN_SM_ENGINE_STATE_NONE,
1718 		true,
1719 		"SUSPEND",
1720 		mlme_vdev_state_suspend_entry,
1721 		mlme_vdev_state_suspend_exit,
1722 		mlme_vdev_state_suspend_event
1723 	},
1724 	{
1725 		(uint8_t)WLAN_VDEV_S_STOP,
1726 		(uint8_t)WLAN_SM_ENGINE_STATE_NONE,
1727 		(uint8_t)WLAN_VDEV_SS_STOP_STOP_PROGRESS,
1728 		true,
1729 		"STOP",
1730 		mlme_vdev_state_stop_entry,
1731 		mlme_vdev_state_stop_exit,
1732 		mlme_vdev_state_stop_event
1733 	},
1734 	{
1735 		(uint8_t)WLAN_VDEV_S_MAX,
1736 		(uint8_t)WLAN_SM_ENGINE_STATE_NONE,
1737 		(uint8_t)WLAN_SM_ENGINE_STATE_NONE,
1738 		false,
1739 		"INVALID",
1740 		NULL,
1741 		NULL,
1742 		NULL
1743 	},
1744 	{
1745 		(uint8_t)WLAN_VDEV_SS_START_START_PROGRESS,
1746 		(uint8_t)WLAN_VDEV_S_START,
1747 		(uint8_t)WLAN_SM_ENGINE_STATE_NONE,
1748 		false,
1749 		"ST-START_PROG",
1750 		mlme_vdev_subst_start_start_progress_entry,
1751 		mlme_vdev_subst_start_start_progress_exit,
1752 		mlme_vdev_subst_start_start_progress_event
1753 	},
1754 	{
1755 		(uint8_t)WLAN_VDEV_SS_START_RESTART_PROGRESS,
1756 		(uint8_t)WLAN_VDEV_S_START,
1757 		(uint8_t)WLAN_SM_ENGINE_STATE_NONE,
1758 		false,
1759 		"ST-RESTART_PROG",
1760 		mlme_vdev_subst_start_restart_progress_entry,
1761 		mlme_vdev_subst_start_restart_progress_exit,
1762 		mlme_vdev_subst_start_restart_progress_event
1763 	},
1764 	{
1765 		(uint8_t)WLAN_VDEV_SS_START_CONN_PROGRESS,
1766 		(uint8_t)WLAN_VDEV_S_START,
1767 		(uint8_t)WLAN_SM_ENGINE_STATE_NONE,
1768 		false,
1769 		"ST-CONN_PROG",
1770 		mlme_vdev_subst_start_conn_progress_entry,
1771 		mlme_vdev_subst_start_conn_progress_exit,
1772 		mlme_vdev_subst_start_conn_progress_event
1773 	},
1774 	{
1775 		(uint8_t)WLAN_VDEV_SS_START_DISCONN_PROGRESS,
1776 		(uint8_t)WLAN_VDEV_S_START,
1777 		(uint8_t)WLAN_SM_ENGINE_STATE_NONE,
1778 		false,
1779 		"ST-DISCONN_PROG",
1780 		mlme_vdev_subst_start_disconn_progress_entry,
1781 		mlme_vdev_subst_start_disconn_progress_exit,
1782 		mlme_vdev_subst_start_disconn_progress_event
1783 	},
1784 	{
1785 		(uint8_t)WLAN_VDEV_SS_SUSPEND_SUSPEND_DOWN,
1786 		(uint8_t)WLAN_VDEV_S_SUSPEND,
1787 		(uint8_t)WLAN_SM_ENGINE_STATE_NONE,
1788 		false,
1789 		"SP-SUSPEND_DOWN",
1790 		mlme_vdev_subst_suspend_suspend_down_entry,
1791 		mlme_vdev_subst_suspend_suspend_down_exit,
1792 		mlme_vdev_subst_suspend_suspend_down_event
1793 	},
1794 	{
1795 		(uint8_t)WLAN_VDEV_SS_SUSPEND_SUSPEND_RESTART,
1796 		(uint8_t)WLAN_VDEV_S_SUSPEND,
1797 		(uint8_t)WLAN_SM_ENGINE_STATE_NONE,
1798 		false,
1799 		"SP-SUSPEND_RESTART",
1800 		mlme_vdev_subst_suspend_suspend_restart_entry,
1801 		mlme_vdev_subst_suspend_suspend_restart_exit,
1802 		mlme_vdev_subst_suspend_suspend_restart_event
1803 	},
1804 	{
1805 		(uint8_t)WLAN_VDEV_SS_SUSPEND_HOST_RESTART,
1806 		(uint8_t)WLAN_VDEV_S_SUSPEND,
1807 		(uint8_t)WLAN_SM_ENGINE_STATE_NONE,
1808 		false,
1809 		"SP-HOST_RESTART",
1810 		mlme_vdev_subst_suspend_host_restart_entry,
1811 		mlme_vdev_subst_suspend_host_restart_exit,
1812 		mlme_vdev_subst_suspend_host_restart_event
1813 	},
1814 	{
1815 		(uint8_t)WLAN_VDEV_SS_SUSPEND_CSA_RESTART,
1816 		(uint8_t)WLAN_VDEV_S_SUSPEND,
1817 		(uint8_t)WLAN_SM_ENGINE_STATE_NONE,
1818 		false,
1819 		"SP-CSA_RESTART",
1820 		mlme_vdev_subst_suspend_csa_restart_entry,
1821 		mlme_vdev_subst_suspend_csa_restart_exit,
1822 		mlme_vdev_subst_suspend_csa_restart_event
1823 	},
1824 	{
1825 		(uint8_t)WLAN_VDEV_SS_STOP_STOP_PROGRESS,
1826 		(uint8_t)WLAN_VDEV_S_STOP,
1827 		(uint8_t)WLAN_SM_ENGINE_STATE_NONE,
1828 		false,
1829 		"STOP-STOP_PROG",
1830 		mlme_vdev_subst_stop_stop_progress_entry,
1831 		mlme_vdev_subst_stop_stop_progress_exit,
1832 		mlme_vdev_subst_stop_stop_progress_event
1833 	},
1834 	{
1835 		(uint8_t)WLAN_VDEV_SS_STOP_DOWN_PROGRESS,
1836 		(uint8_t)WLAN_VDEV_S_STOP,
1837 		(uint8_t)WLAN_SM_ENGINE_STATE_NONE,
1838 		false,
1839 		"STOP-DOWN_PROG",
1840 		mlme_vdev_subst_stop_down_progress_entry,
1841 		mlme_vdev_subst_stop_down_progress_exit,
1842 		mlme_vdev_subst_stop_down_progress_event
1843 	},
1844 	{
1845 		(uint8_t)WLAN_VDEV_SS_IDLE,
1846 		(uint8_t)WLAN_SM_ENGINE_STATE_NONE,
1847 		(uint8_t)WLAN_SM_ENGINE_STATE_NONE,
1848 		false,
1849 		"IDLE",
1850 		NULL,
1851 		NULL,
1852 		NULL,
1853 	},
1854 	{
1855 		(uint8_t)WLAN_VDEV_SS_MAX,
1856 		(uint8_t)WLAN_SM_ENGINE_STATE_NONE,
1857 		(uint8_t)WLAN_SM_ENGINE_STATE_NONE,
1858 		false,
1859 		"INVALID",
1860 		NULL,
1861 		NULL,
1862 		NULL,
1863 	},
1864 };
1865 
1866 QDF_STATUS mlme_vdev_sm_deliver_event(struct vdev_mlme_obj *vdev_mlme,
1867 				      enum wlan_vdev_sm_evt event,
1868 				      uint16_t event_data_len, void *event_data)
1869 {
1870 	return wlan_sm_dispatch(vdev_mlme->sm_hdl, event,
1871 				event_data_len, event_data);
1872 }
1873 
1874 void mlme_vdev_sm_print_state_event(struct vdev_mlme_obj *vdev_mlme,
1875 				    enum wlan_vdev_sm_evt event)
1876 {
1877 	enum wlan_vdev_state state;
1878 	enum wlan_vdev_state substate;
1879 	struct wlan_objmgr_vdev *vdev;
1880 
1881 	vdev = vdev_mlme->vdev;
1882 
1883 	state = wlan_vdev_mlme_get_state(vdev);
1884 	substate = wlan_vdev_mlme_get_substate(vdev);
1885 
1886 	mlme_nofl_debug("[%s]%s - %s, %s", vdev_mlme->sm_hdl->name,
1887 			sm_info[state].name, sm_info[substate].name,
1888 			vdev_sm_event_names[event]);
1889 }
1890 
1891 void mlme_vdev_sm_print_state(struct vdev_mlme_obj *vdev_mlme)
1892 {
1893 	enum wlan_vdev_state state;
1894 	enum wlan_vdev_state substate;
1895 	struct wlan_objmgr_vdev *vdev;
1896 
1897 	vdev = vdev_mlme->vdev;
1898 
1899 	state = wlan_vdev_mlme_get_state(vdev);
1900 	substate = wlan_vdev_mlme_get_substate(vdev);
1901 
1902 	mlme_nofl_debug("[%s]%s - %s", vdev_mlme->sm_hdl->name,
1903 			sm_info[state].name, sm_info[substate].name);
1904 }
1905 
1906 #ifdef SM_ENG_HIST_ENABLE
1907 void mlme_vdev_sm_history_print(struct vdev_mlme_obj *vdev_mlme)
1908 {
1909 	return wlan_sm_print_history(vdev_mlme->sm_hdl);
1910 }
1911 #endif
1912 
1913 QDF_STATUS mlme_vdev_sm_create(struct vdev_mlme_obj *vdev_mlme)
1914 {
1915 	struct wlan_sm *sm;
1916 	uint8_t name[WLAN_SM_ENGINE_MAX_NAME];
1917 	struct wlan_objmgr_vdev *vdev = vdev_mlme->vdev;
1918 
1919 	qdf_scnprintf(name, sizeof(name), "VDEV%d-MLME",
1920 		      wlan_vdev_get_id(vdev_mlme->vdev));
1921 	sm = wlan_sm_create(name, vdev_mlme,
1922 			    WLAN_VDEV_S_INIT,
1923 			    sm_info,
1924 			    QDF_ARRAY_SIZE(sm_info),
1925 			    vdev_sm_event_names,
1926 			    QDF_ARRAY_SIZE(vdev_sm_event_names));
1927 	if (!sm) {
1928 		mlme_err("VDEV MLME SM allocation failed");
1929 		return QDF_STATUS_E_FAILURE;
1930 	}
1931 	vdev_mlme->sm_hdl = sm;
1932 	wlan_minidump_log((void *)sm, sizeof(*sm),
1933 			  wlan_vdev_get_psoc(vdev),
1934 			  WLAN_MD_OBJMGR_VDEV_SM, "wlan_sm");
1935 
1936 	mlme_vdev_sm_spinlock_create(vdev_mlme);
1937 
1938 	mlme_vdev_cmd_mutex_create(vdev_mlme);
1939 
1940 	return QDF_STATUS_SUCCESS;
1941 }
1942 
1943 QDF_STATUS mlme_vdev_sm_destroy(struct vdev_mlme_obj *vdev_mlme)
1944 {
1945 	mlme_vdev_cmd_mutex_destroy(vdev_mlme);
1946 
1947 	mlme_vdev_sm_spinlock_destroy(vdev_mlme);
1948 
1949 	wlan_minidump_remove(vdev_mlme->sm_hdl);
1950 	wlan_sm_delete(vdev_mlme->sm_hdl);
1951 
1952 	return QDF_STATUS_SUCCESS;
1953 }
1954