xref: /wlan-dirver/qca-wifi-host-cmn/umac/mlme/vdev_mgr/core/src/vdev_mlme_sm.c (revision 70a19e16789e308182f63b15c75decec7bf0b342)
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  *
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 	mlme_vdev_notify_mlo_sync_wait_entry(vdev_mlme);
1662 }
1663 
1664 /**
1665  * mlme_vdev_subst_mlo_sync_wait_exit() - Exit API for mlo sync wait sub state
1666  * @ctx: VDEV MLME object
1667  *
1668  * API to perform operations on moving out of MLO-SYNC-WAIT substate
1669  *
1670  * Return: void
1671  */
1672 static void mlme_vdev_subst_mlo_sync_wait_exit(void *ctx)
1673 {
1674 	/* NONE */
1675 }
1676 
1677 /**
1678  * mlme_vdev_subst_mlo_sync_wait_event() - Event handler API for mlo sync wait
1679  *                                         substate
1680  * @ctx: VDEV MLME object
1681  *
1682  * API to handle events in MLO-SYNC-WAIT substate
1683  *
1684  * Return: SUCCESS: on handling event
1685  *         FAILURE: on ignoring the event
1686  */
1687 static bool mlme_vdev_subst_mlo_sync_wait_event(void *ctx, uint16_t event,
1688 						uint16_t event_data_len,
1689 						void *event_data)
1690 {
1691 	struct vdev_mlme_obj *vdev_mlme = (struct vdev_mlme_obj *)ctx;
1692 	bool status;
1693 
1694 	switch (event) {
1695 	case WLAN_VDEV_SM_EV_START_SUCCESS:
1696 		if (mlme_vdev_up_notify_mlo_mgr(vdev_mlme))
1697 			mlme_vdev_sm_deliver_event(
1698 					vdev_mlme,
1699 					WLAN_VDEV_SM_EV_MLO_SYNC_COMPLETE,
1700 					event_data_len, event_data);
1701 		status = true;
1702 		break;
1703 
1704 	case WLAN_VDEV_SM_EV_MLO_SYNC_COMPLETE:
1705 		mlme_vdev_sm_transition_to(vdev_mlme, WLAN_VDEV_SS_UP_ACTIVE);
1706 		mlme_vdev_sm_deliver_event(vdev_mlme, event,
1707 					   event_data_len, event_data);
1708 		status = true;
1709 		break;
1710 
1711 	case WLAN_VDEV_SM_EV_DOWN:
1712 		mlme_vdev_sm_transition_to(vdev_mlme, WLAN_VDEV_S_SUSPEND);
1713 		mlme_vdev_sm_deliver_event(vdev_mlme, event,
1714 					   event_data_len, event_data);
1715 		status = true;
1716 		break;
1717 
1718 	case WLAN_VDEV_SM_EV_RADAR_DETECTED:
1719 	case WLAN_VDEV_SM_EV_CSA_RESTART:
1720 		mlme_vdev_sm_transition_to(vdev_mlme, WLAN_VDEV_S_START);
1721 		mlme_vdev_sm_deliver_event(vdev_mlme,
1722 					   WLAN_VDEV_SM_EV_RESTART_REQ,
1723 					   event_data_len, event_data);
1724 		status = true;
1725 		break;
1726 
1727 	default:
1728 		status = false;
1729 		break;
1730 	}
1731 
1732 	return status;
1733 }
1734 
1735 /**
1736  * mlme_vdev_subst_up_active_entry() - Entry API for up active sub state
1737  * @ctx: VDEV MLME object
1738  *
1739  * API to perform operations on moving to UP-ACTIVE substate
1740  *
1741  * Return: void
1742  */
1743 static void mlme_vdev_subst_up_active_entry(void *ctx)
1744 {
1745 	struct vdev_mlme_obj *vdev_mlme = (struct vdev_mlme_obj *)ctx;
1746 	struct wlan_objmgr_vdev *vdev;
1747 
1748 	vdev = vdev_mlme->vdev;
1749 
1750 	if (wlan_vdev_mlme_get_state(vdev) != WLAN_VDEV_S_UP)
1751 		QDF_BUG(0);
1752 
1753 	mlme_vdev_set_substate(vdev, WLAN_VDEV_SS_UP_ACTIVE);
1754 }
1755 
1756 /**
1757  * mlme_vdev_subst_up_active_exit() - Exit API for up active sub state
1758  * @ctx: VDEV MLME object
1759  *
1760  * API to perform operations on moving out of UP-ACTIVE substate
1761  *
1762  * Return: void
1763  */
1764 static void mlme_vdev_subst_up_active_exit(void *ctx)
1765 {
1766 	/* NONE */
1767 }
1768 
1769 /**
1770  * mlme_vdev_subst_up_active_event() - Event handler API for up active substate
1771  * @ctx: VDEV MLME object
1772  *
1773  * API to handle events in UP-ACTIVE substate
1774  *
1775  * Return: SUCCESS: on handling event
1776  *         FAILURE: on ignoring the event
1777  */
1778 static bool mlme_vdev_subst_up_active_event(void *ctx, uint16_t event,
1779 					    uint16_t event_data_len,
1780 					    void *event_data)
1781 {
1782 	struct vdev_mlme_obj *vdev_mlme = (struct vdev_mlme_obj *)ctx;
1783 	enum QDF_OPMODE mode;
1784 	struct wlan_objmgr_vdev *vdev;
1785 	bool status;
1786 
1787 	vdev = vdev_mlme->vdev;
1788 	mode = wlan_vdev_mlme_get_opmode(vdev);
1789 
1790 	switch (event) {
1791 	case WLAN_VDEV_SM_EV_START_SUCCESS:
1792 		if (wlan_vdev_mlme_is_mlo_ap(vdev))
1793 			QDF_BUG(0);
1794 		fallthrough;
1795 	case WLAN_VDEV_SM_EV_MLO_SYNC_COMPLETE:
1796 		mlme_vdev_update_beacon(vdev_mlme, BEACON_INIT,
1797 					event_data_len, event_data);
1798 		if (mlme_vdev_up_send(vdev_mlme, event_data_len,
1799 				      event_data) != QDF_STATUS_SUCCESS) {
1800 			mlme_vdev_sm_deliver_event(vdev_mlme,
1801 						   WLAN_VDEV_SM_EV_UP_FAIL,
1802 						   event_data_len, event_data);
1803 		} else {
1804 			mlme_vdev_notify_up_complete(vdev_mlme, event_data_len,
1805 						     event_data);
1806 			mlme_vdev_up_active_notify_mlo_mgr(vdev_mlme);
1807 		}
1808 		status = true;
1809 		break;
1810 
1811 	case WLAN_VDEV_SM_EV_SUSPEND_RESTART:
1812 	case WLAN_VDEV_SM_EV_HOST_RESTART:
1813 	case WLAN_VDEV_SM_EV_CSA_RESTART:
1814 		/* These events are not supported in STA mode */
1815 		if (mode == QDF_STA_MODE)
1816 			QDF_BUG(0);
1817 		fallthrough;
1818 	case WLAN_VDEV_SM_EV_DOWN:
1819 		mlme_vdev_sm_transition_to(vdev_mlme, WLAN_VDEV_S_SUSPEND);
1820 		mlme_vdev_sm_deliver_event(vdev_mlme, event,
1821 					   event_data_len, event_data);
1822 		status = true;
1823 		break;
1824 
1825 	case WLAN_VDEV_SM_EV_RADAR_DETECTED:
1826 		/* These events are not supported in STA mode */
1827 		if (mode == QDF_STA_MODE)
1828 			QDF_BUG(0);
1829 		mlme_vdev_sm_transition_to(vdev_mlme, WLAN_VDEV_S_SUSPEND);
1830 		mlme_vdev_sm_deliver_event(vdev_mlme,
1831 					   WLAN_VDEV_SM_EV_CSA_RESTART,
1832 					   event_data_len, event_data);
1833 		status = true;
1834 		break;
1835 
1836 	case WLAN_VDEV_SM_EV_UP_HOST_RESTART:
1837 		/* Reinit beacon, send template to FW(use ping-pong buffer) */
1838 		mlme_vdev_update_beacon(vdev_mlme, BEACON_UPDATE,
1839 					event_data_len, event_data);
1840 		fallthrough;
1841 	case WLAN_VDEV_SM_EV_START:
1842 		/* notify that UP command is completed */
1843 		mlme_vdev_notify_up_complete(vdev_mlme,
1844 					     event_data_len, event_data);
1845 		status = true;
1846 		break;
1847 
1848 	case WLAN_VDEV_SM_EV_FW_VDEV_RESTART:
1849 		mlme_vdev_sm_transition_to(vdev_mlme, WLAN_VDEV_S_START);
1850 		mlme_vdev_sm_deliver_event(vdev_mlme,
1851 					   WLAN_VDEV_SM_EV_RESTART_REQ,
1852 					   event_data_len, event_data);
1853 		status = true;
1854 		break;
1855 
1856 	case WLAN_VDEV_SM_EV_UP_FAIL:
1857 		mlme_vdev_sm_transition_to(vdev_mlme, WLAN_VDEV_S_SUSPEND);
1858 		mlme_vdev_sm_deliver_event(vdev_mlme, event,
1859 					   event_data_len, event_data);
1860 		status = true;
1861 		break;
1862 
1863 	case WLAN_VDEV_SM_EV_ROAM:
1864 		mlme_vdev_notify_roam_start(vdev_mlme, event_data_len,
1865 					    event_data);
1866 		status = true;
1867 		break;
1868 
1869 	default:
1870 		status = false;
1871 		break;
1872 	}
1873 
1874 	return status;
1875 }
1876 
1877 
1878 static const char *vdev_sm_event_names[] = {
1879 	"EV_START",
1880 	"EV_START_REQ",
1881 	"EV_RESTART_REQ",
1882 	"EV_START_RESP",
1883 	"EV_RESTART_RESP",
1884 	"EV_START_REQ_FAIL",
1885 	"EV_RESTART_REQ_FAIL",
1886 	"EV_START_SUCCESS",
1887 	"EV_CONN_PROGRESS",
1888 	"EV_STA_CONN_START",
1889 	"EV_DFS_CAC_WAIT",
1890 	"EV_DFS_CAC_COMPLETED",
1891 	"EV_DOWN",
1892 	"EV_CONNECTION_FAIL",
1893 	"EV_STOP_RESP",
1894 	"EV_STOP_FAIL",
1895 	"EV_DOWN_FAIL",
1896 	"EV_DISCONNECT_COMPLETE",
1897 	"EV_SUSPEND_RESTART",
1898 	"EV_HOST_RESTART",
1899 	"EV_UP_HOST_RESTART",
1900 	"EV_FW_VDEV_RESTART",
1901 	"EV_UP_FAIL",
1902 	"EV_RADAR_DETECTED",
1903 	"EV_CSA_RESTART",
1904 	"EV_CSA_COMPLETE",
1905 	"EV_MLME_DOWN_REQ",
1906 	"EV_DOWN_COMPLETE",
1907 	"EV_ROAM",
1908 	"EV_STOP_REQ",
1909 	"EV_CHAN_SWITCH_DISABLED",
1910 	"EV_MLO_SYNC_COMPLETE",
1911 };
1912 
1913 struct wlan_sm_state_info sm_info[] = {
1914 	{
1915 		(uint8_t)WLAN_VDEV_S_INIT,
1916 		(uint8_t)WLAN_SM_ENGINE_STATE_NONE,
1917 		(uint8_t)WLAN_SM_ENGINE_STATE_NONE,
1918 		true,
1919 		"INIT",
1920 		mlme_vdev_state_init_entry,
1921 		mlme_vdev_state_init_exit,
1922 		mlme_vdev_state_init_event
1923 	},
1924 	{
1925 		(uint8_t)WLAN_VDEV_S_START,
1926 		(uint8_t)WLAN_SM_ENGINE_STATE_NONE,
1927 		(uint8_t)WLAN_SM_ENGINE_STATE_NONE,
1928 		true,
1929 		"START",
1930 		mlme_vdev_state_start_entry,
1931 		mlme_vdev_state_start_exit,
1932 		mlme_vdev_state_start_event
1933 	},
1934 	{
1935 		(uint8_t)WLAN_VDEV_S_DFS_CAC_WAIT,
1936 		(uint8_t)WLAN_SM_ENGINE_STATE_NONE,
1937 		(uint8_t)WLAN_SM_ENGINE_STATE_NONE,
1938 		true,
1939 		"DFS_CAC_WAIT",
1940 		mlme_vdev_state_dfs_cac_wait_entry,
1941 		mlme_vdev_state_dfs_cac_wait_exit,
1942 		mlme_vdev_state_dfs_cac_wait_event
1943 	},
1944 	{
1945 		(uint8_t)WLAN_VDEV_S_UP,
1946 		(uint8_t)WLAN_SM_ENGINE_STATE_NONE,
1947 		(uint8_t)WLAN_SM_ENGINE_STATE_NONE,
1948 		true,
1949 		"UP",
1950 		mlme_vdev_state_up_entry,
1951 		mlme_vdev_state_up_exit,
1952 		mlme_vdev_state_up_event
1953 	},
1954 	{
1955 		(uint8_t)WLAN_VDEV_S_SUSPEND,
1956 		(uint8_t)WLAN_SM_ENGINE_STATE_NONE,
1957 		(uint8_t)WLAN_SM_ENGINE_STATE_NONE,
1958 		true,
1959 		"SUSPEND",
1960 		mlme_vdev_state_suspend_entry,
1961 		mlme_vdev_state_suspend_exit,
1962 		mlme_vdev_state_suspend_event
1963 	},
1964 	{
1965 		(uint8_t)WLAN_VDEV_S_STOP,
1966 		(uint8_t)WLAN_SM_ENGINE_STATE_NONE,
1967 		(uint8_t)WLAN_VDEV_SS_STOP_STOP_PROGRESS,
1968 		true,
1969 		"STOP",
1970 		mlme_vdev_state_stop_entry,
1971 		mlme_vdev_state_stop_exit,
1972 		mlme_vdev_state_stop_event
1973 	},
1974 	{
1975 		(uint8_t)WLAN_VDEV_S_MAX,
1976 		(uint8_t)WLAN_SM_ENGINE_STATE_NONE,
1977 		(uint8_t)WLAN_SM_ENGINE_STATE_NONE,
1978 		false,
1979 		"INVALID",
1980 		NULL,
1981 		NULL,
1982 		NULL
1983 	},
1984 	{
1985 		(uint8_t)WLAN_VDEV_SS_START_START_PROGRESS,
1986 		(uint8_t)WLAN_VDEV_S_START,
1987 		(uint8_t)WLAN_SM_ENGINE_STATE_NONE,
1988 		false,
1989 		"ST-START_PROG",
1990 		mlme_vdev_subst_start_start_progress_entry,
1991 		mlme_vdev_subst_start_start_progress_exit,
1992 		mlme_vdev_subst_start_start_progress_event
1993 	},
1994 	{
1995 		(uint8_t)WLAN_VDEV_SS_START_RESTART_PROGRESS,
1996 		(uint8_t)WLAN_VDEV_S_START,
1997 		(uint8_t)WLAN_SM_ENGINE_STATE_NONE,
1998 		false,
1999 		"ST-RESTART_PROG",
2000 		mlme_vdev_subst_start_restart_progress_entry,
2001 		mlme_vdev_subst_start_restart_progress_exit,
2002 		mlme_vdev_subst_start_restart_progress_event
2003 	},
2004 	{
2005 		(uint8_t)WLAN_VDEV_SS_START_CONN_PROGRESS,
2006 		(uint8_t)WLAN_VDEV_S_START,
2007 		(uint8_t)WLAN_SM_ENGINE_STATE_NONE,
2008 		false,
2009 		"ST-CONN_PROG",
2010 		mlme_vdev_subst_start_conn_progress_entry,
2011 		mlme_vdev_subst_start_conn_progress_exit,
2012 		mlme_vdev_subst_start_conn_progress_event
2013 	},
2014 	{
2015 		(uint8_t)WLAN_VDEV_SS_START_DISCONN_PROGRESS,
2016 		(uint8_t)WLAN_VDEV_S_START,
2017 		(uint8_t)WLAN_SM_ENGINE_STATE_NONE,
2018 		false,
2019 		"ST-DISCONN_PROG",
2020 		mlme_vdev_subst_start_disconn_progress_entry,
2021 		mlme_vdev_subst_start_disconn_progress_exit,
2022 		mlme_vdev_subst_start_disconn_progress_event
2023 	},
2024 	{
2025 		(uint8_t)WLAN_VDEV_SS_SUSPEND_SUSPEND_DOWN,
2026 		(uint8_t)WLAN_VDEV_S_SUSPEND,
2027 		(uint8_t)WLAN_SM_ENGINE_STATE_NONE,
2028 		false,
2029 		"SP-SUSPEND_DOWN",
2030 		mlme_vdev_subst_suspend_suspend_down_entry,
2031 		mlme_vdev_subst_suspend_suspend_down_exit,
2032 		mlme_vdev_subst_suspend_suspend_down_event
2033 	},
2034 	{
2035 		(uint8_t)WLAN_VDEV_SS_SUSPEND_SUSPEND_RESTART,
2036 		(uint8_t)WLAN_VDEV_S_SUSPEND,
2037 		(uint8_t)WLAN_SM_ENGINE_STATE_NONE,
2038 		false,
2039 		"SP-SUSPEND_RESTART",
2040 		mlme_vdev_subst_suspend_suspend_restart_entry,
2041 		mlme_vdev_subst_suspend_suspend_restart_exit,
2042 		mlme_vdev_subst_suspend_suspend_restart_event
2043 	},
2044 	{
2045 		(uint8_t)WLAN_VDEV_SS_SUSPEND_HOST_RESTART,
2046 		(uint8_t)WLAN_VDEV_S_SUSPEND,
2047 		(uint8_t)WLAN_SM_ENGINE_STATE_NONE,
2048 		false,
2049 		"SP-HOST_RESTART",
2050 		mlme_vdev_subst_suspend_host_restart_entry,
2051 		mlme_vdev_subst_suspend_host_restart_exit,
2052 		mlme_vdev_subst_suspend_host_restart_event
2053 	},
2054 	{
2055 		(uint8_t)WLAN_VDEV_SS_SUSPEND_CSA_RESTART,
2056 		(uint8_t)WLAN_VDEV_S_SUSPEND,
2057 		(uint8_t)WLAN_SM_ENGINE_STATE_NONE,
2058 		false,
2059 		"SP-CSA_RESTART",
2060 		mlme_vdev_subst_suspend_csa_restart_entry,
2061 		mlme_vdev_subst_suspend_csa_restart_exit,
2062 		mlme_vdev_subst_suspend_csa_restart_event
2063 	},
2064 	{
2065 		(uint8_t)WLAN_VDEV_SS_STOP_STOP_PROGRESS,
2066 		(uint8_t)WLAN_VDEV_S_STOP,
2067 		(uint8_t)WLAN_SM_ENGINE_STATE_NONE,
2068 		false,
2069 		"STOP-STOP_PROG",
2070 		mlme_vdev_subst_stop_stop_progress_entry,
2071 		mlme_vdev_subst_stop_stop_progress_exit,
2072 		mlme_vdev_subst_stop_stop_progress_event
2073 	},
2074 	{
2075 		(uint8_t)WLAN_VDEV_SS_STOP_DOWN_PROGRESS,
2076 		(uint8_t)WLAN_VDEV_S_STOP,
2077 		(uint8_t)WLAN_SM_ENGINE_STATE_NONE,
2078 		false,
2079 		"STOP-DOWN_PROG",
2080 		mlme_vdev_subst_stop_down_progress_entry,
2081 		mlme_vdev_subst_stop_down_progress_exit,
2082 		mlme_vdev_subst_stop_down_progress_event
2083 	},
2084 	{
2085 		(uint8_t)WLAN_VDEV_SS_IDLE,
2086 		(uint8_t)WLAN_SM_ENGINE_STATE_NONE,
2087 		(uint8_t)WLAN_SM_ENGINE_STATE_NONE,
2088 		false,
2089 		"IDLE",
2090 		NULL,
2091 		NULL,
2092 		NULL,
2093 	},
2094 	{
2095 		(uint8_t)WLAN_VDEV_SS_MLO_SYNC_WAIT,
2096 		(uint8_t)WLAN_VDEV_S_UP,
2097 		(uint8_t)WLAN_SM_ENGINE_STATE_NONE,
2098 		false,
2099 		"UP-MLO_SYNC_WAIT",
2100 		mlme_vdev_subst_mlo_sync_wait_entry,
2101 		mlme_vdev_subst_mlo_sync_wait_exit,
2102 		mlme_vdev_subst_mlo_sync_wait_event
2103 	},
2104 	{
2105 		(uint8_t)WLAN_VDEV_SS_UP_ACTIVE,
2106 		(uint8_t)WLAN_VDEV_S_UP,
2107 		(uint8_t)WLAN_SM_ENGINE_STATE_NONE,
2108 		false,
2109 		"UP-UP_ACTIVE",
2110 		mlme_vdev_subst_up_active_entry,
2111 		mlme_vdev_subst_up_active_exit,
2112 		mlme_vdev_subst_up_active_event
2113 	},
2114 	{
2115 		(uint8_t)WLAN_VDEV_SS_MAX,
2116 		(uint8_t)WLAN_SM_ENGINE_STATE_NONE,
2117 		(uint8_t)WLAN_SM_ENGINE_STATE_NONE,
2118 		false,
2119 		"INVALID",
2120 		NULL,
2121 		NULL,
2122 		NULL,
2123 	},
2124 };
2125 
2126 QDF_STATUS mlme_vdev_sm_deliver_event(struct vdev_mlme_obj *vdev_mlme,
2127 				      enum wlan_vdev_sm_evt event,
2128 				      uint16_t event_data_len, void *event_data)
2129 {
2130 	return wlan_sm_dispatch(vdev_mlme->sm_hdl, event,
2131 				event_data_len, event_data);
2132 }
2133 
2134 void mlme_vdev_sm_print_state_event(struct vdev_mlme_obj *vdev_mlme,
2135 				    enum wlan_vdev_sm_evt event)
2136 {
2137 	enum wlan_vdev_state state;
2138 	enum wlan_vdev_state substate;
2139 	struct wlan_objmgr_vdev *vdev;
2140 
2141 	vdev = vdev_mlme->vdev;
2142 
2143 	state = wlan_vdev_mlme_get_state(vdev);
2144 	substate = wlan_vdev_mlme_get_substate(vdev);
2145 
2146 	mlme_nofl_debug("[%s]%s - %s, %s", vdev_mlme->sm_hdl->name,
2147 			sm_info[state].name, sm_info[substate].name,
2148 			vdev_sm_event_names[event]);
2149 }
2150 
2151 void mlme_vdev_sm_print_state(struct vdev_mlme_obj *vdev_mlme)
2152 {
2153 	enum wlan_vdev_state state;
2154 	enum wlan_vdev_state substate;
2155 	struct wlan_objmgr_vdev *vdev;
2156 
2157 	vdev = vdev_mlme->vdev;
2158 
2159 	state = wlan_vdev_mlme_get_state(vdev);
2160 	substate = wlan_vdev_mlme_get_substate(vdev);
2161 
2162 	mlme_nofl_debug("[%s]%s - %s", vdev_mlme->sm_hdl->name,
2163 			sm_info[state].name, sm_info[substate].name);
2164 }
2165 
2166 #ifdef SM_ENG_HIST_ENABLE
2167 void mlme_vdev_sm_history_print(struct vdev_mlme_obj *vdev_mlme)
2168 {
2169 	return wlan_sm_print_history(vdev_mlme->sm_hdl);
2170 }
2171 #endif
2172 
2173 QDF_STATUS mlme_vdev_sm_create(struct vdev_mlme_obj *vdev_mlme)
2174 {
2175 	struct wlan_sm *sm;
2176 	uint8_t name[WLAN_SM_ENGINE_MAX_NAME];
2177 	struct wlan_objmgr_vdev *vdev = vdev_mlme->vdev;
2178 
2179 	qdf_scnprintf(name, sizeof(name), "VM-PS_%d-VD_%d",
2180 		      wlan_psoc_get_id(wlan_vdev_get_psoc(vdev)),
2181 		      wlan_vdev_get_id(vdev));
2182 	sm = wlan_sm_create(name, vdev_mlme,
2183 			    WLAN_VDEV_S_INIT,
2184 			    sm_info,
2185 			    QDF_ARRAY_SIZE(sm_info),
2186 			    vdev_sm_event_names,
2187 			    QDF_ARRAY_SIZE(vdev_sm_event_names));
2188 	if (!sm) {
2189 		mlme_err("VDEV MLME SM allocation failed");
2190 		return QDF_STATUS_E_FAILURE;
2191 	}
2192 	vdev_mlme->sm_hdl = sm;
2193 	wlan_minidump_log((void *)sm, sizeof(*sm),
2194 			  wlan_vdev_get_psoc(vdev),
2195 			  WLAN_MD_OBJMGR_VDEV_SM, "wlan_sm");
2196 
2197 	mlme_vdev_sm_spinlock_create(vdev_mlme);
2198 
2199 	mlme_vdev_cmd_mutex_create(vdev_mlme);
2200 
2201 	return QDF_STATUS_SUCCESS;
2202 }
2203 
2204 QDF_STATUS mlme_vdev_sm_destroy(struct vdev_mlme_obj *vdev_mlme)
2205 {
2206 	struct wlan_objmgr_vdev *vdev = vdev_mlme->vdev;
2207 
2208 	mlme_vdev_cmd_mutex_destroy(vdev_mlme);
2209 
2210 	mlme_vdev_sm_spinlock_destroy(vdev_mlme);
2211 
2212 	wlan_minidump_remove(vdev_mlme->sm_hdl,
2213 			     sizeof(*vdev_mlme->sm_hdl),
2214 			     wlan_vdev_get_psoc(vdev),
2215 			     WLAN_MD_OBJMGR_VDEV_SM, "wlan_sm");
2216 
2217 	wlan_sm_delete(vdev_mlme->sm_hdl);
2218 
2219 	return QDF_STATUS_SUCCESS;
2220 }
2221