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