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