xref: /wlan-dirver/qca-wifi-host-cmn/umac/mlme/connection_mgr/core/src/wlan_cm_sm.c (revision a86b23ee68a2491aede2e03991f3fb37046f4e41)
1 /*
2  * Copyright (c) 2020, The Linux Foundation. All rights reserved.
3  *
4  * Permission to use, copy, modify, and/or distribute this software for any
5  * purpose with or without fee is hereby granted, provided that the above
6  * copyright notice and this permission notice appear in all copies.
7  *
8  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15  */
16 
17 /**
18  * DOC: Implements general SM framework for connection manager
19  */
20 
21 #include "wlan_cm_main.h"
22 #include "wlan_cm_sm.h"
23 #include "wlan_cm_roam_sm.h"
24 
25 void mlme_cm_set_state(struct cnx_mgr *cm_ctx, enum wlan_cm_sm_state state)
26 {
27 	if (state < WLAN_CM_S_MAX)
28 		cm_ctx->sm.cm_state = state;
29 	else
30 		mlme_err("mlme state (%d) is invalid", state);
31 }
32 
33 void mlme_cm_set_substate(struct cnx_mgr *cm_ctx,
34 			  enum wlan_cm_sm_state substate)
35 {
36 	if ((substate > WLAN_CM_S_MAX) && (substate < WLAN_CM_SS_MAX))
37 		cm_ctx->sm.cm_substate = substate;
38 	else
39 		mlme_err(" mlme sub state (%d) is invalid", substate);
40 }
41 
42 void mlme_cm_sm_state_update(struct cnx_mgr *cm_ctx,
43 			     enum wlan_cm_sm_state state,
44 			     enum wlan_cm_sm_state substate)
45 {
46 	if (!cm_ctx) {
47 		mlme_err("cm_ctx is NULL");
48 		return;
49 	}
50 
51 	mlme_cm_set_state(cm_ctx, state);
52 	mlme_cm_set_substate(cm_ctx, substate);
53 }
54 
55 /**
56  * mlme_cm_state_init_entry() - Entry API for init state for connection mgr
57  * @ctx: connection manager ctx
58  *
59  * API to perform operations on moving to init state
60  *
61  * Return: void
62  */
63 static void mlme_cm_state_init_entry(void *ctx)
64 {
65 	struct cnx_mgr *cm_ctx = (struct cnx_mgr *)ctx;
66 
67 	mlme_cm_sm_state_update(cm_ctx, WLAN_CM_S_INIT, WLAN_CM_SS_IDLE);
68 }
69 
70 /**
71  * mlme_cm_state_init_exit() - Exit API for init state for connection mgr
72  * @ctx: connection manager ctx
73  *
74  * API to perform operations on exiting from init state
75  *
76  * Return: void
77  */
78 static void mlme_cm_state_init_exit(void *ctx)
79 {
80 }
81 
82 /**
83  * mlme_cm_state_init_event() - Init State event handler for connection mgr
84  * @ctx: connection manager ctx
85  *
86  * API to handle events in INIT state
87  *
88  * Return: bool
89  */
90 static bool mlme_cm_state_init_event(void *ctx, uint16_t event,
91 				     uint16_t event_data_len,
92 				     void *event_data)
93 {
94 //	struct cnx_mgr *cm_ctx = (struct cnx_mgr *)ctx;
95 	bool status;
96 
97 	switch (event) {
98 	default:
99 		status = false;
100 		break;
101 	}
102 
103 	return status;
104 }
105 
106 /**
107  * mlme_cm_state_connecting_entry() - Entry API for connecting state for
108  * connection mgr
109  * @ctx: connection manager ctx
110  *
111  * API to perform operations on moving to connecting state
112  *
113  * Return: void
114  */
115 static void mlme_cm_state_connecting_entry(void *ctx)
116 {
117 	struct cnx_mgr *cm_ctx = (struct cnx_mgr *)ctx;
118 
119 	mlme_cm_sm_state_update(cm_ctx, WLAN_CM_S_CONNECTING, WLAN_CM_SS_IDLE);
120 }
121 
122 /**
123  * mlme_cm_state_connecting_exit() - Exit API for connecting state for
124  * connection mgr
125  * @ctx: connection manager ctx
126  *
127  * API to perform operations on exiting from connecting state
128  *
129  * Return: void
130  */
131 static void mlme_cm_state_connecting_exit(void *ctx)
132 {
133 }
134 
135 /**
136  * mlme_cm_state_connecting_event() - Connecting State event handler for
137  * connection mgr
138  * @ctx: connection manager ctx
139  *
140  * API to handle events in CONNECTING state
141  *
142  * Return: bool
143  */
144 static bool mlme_cm_state_connecting_event(void *ctx, uint16_t event,
145 					   uint16_t event_data_len,
146 					   void *event_data)
147 {
148 //	struct cnx_mgr *cm_ctx = (struct cnx_mgr *)ctx;
149 	bool status;
150 
151 	switch (event) {
152 	default:
153 		status = false;
154 		break;
155 	}
156 
157 	return status;
158 }
159 
160 /**
161  * mlme_cm_state_connected_entry() - Entry API for connected state for
162  * connection mgr
163  * @ctx: connection manager ctx
164  *
165  * API to perform operations on moving to connected state
166  *
167  * Return: void
168  */
169 static void mlme_cm_state_connected_entry(void *ctx)
170 {
171 	struct cnx_mgr *cm_ctx = (struct cnx_mgr *)ctx;
172 
173 	mlme_cm_sm_state_update(cm_ctx, WLAN_CM_S_CONNECTED, WLAN_CM_SS_IDLE);
174 }
175 
176 /**
177  * mlme_cm_state_connected_exit() - Exit API for connected state for
178  * connection mgr
179  * @ctx: connection manager ctx
180  *
181  * API to perform operations on exiting from connected state
182  *
183  * Return: void
184  */
185 static void mlme_cm_state_connected_exit(void *ctx)
186 {
187 }
188 
189 /**
190  * mlme_cm_state_connected_event() - Connected State event handler for
191  * connection mgr
192  * @ctx: connection manager ctx
193  *
194  * API to handle events in CONNECTED state
195  *
196  * Return: bool
197  */
198 static bool mlme_cm_state_connected_event(void *ctx, uint16_t event,
199 					  uint16_t event_data_len,
200 					  void *event_data)
201 {
202 //	struct cnx_mgr *cm_ctx = (struct cnx_mgr *)ctx;
203 	bool status;
204 
205 	switch (event) {
206 	default:
207 		status = false;
208 		break;
209 	}
210 
211 	return status;
212 }
213 
214 /**
215  * mlme_cm_state_disconnecting_entry() - Entry API for disconnecting state for
216  * connection mgr
217  * @ctx: connection manager ctx
218  *
219  * API to perform operations on moving to disconnecting state
220  *
221  * Return: void
222  */
223 static void mlme_cm_state_disconnecting_entry(void *ctx)
224 {
225 	struct cnx_mgr *cm_ctx = (struct cnx_mgr *)ctx;
226 
227 	mlme_cm_sm_state_update(cm_ctx, WLAN_CM_S_DISCONNECTING,
228 				WLAN_CM_SS_IDLE);
229 }
230 
231 /**
232  * mlme_cm_state_disconnecting_exit() - Exit API for disconnecting state for
233  * connection mgr
234  * @ctx: connection manager ctx
235  *
236  * API to perform operations on exiting from disconnecting state
237  *
238  * Return: void
239  */
240 static void mlme_cm_state_disconnecting_exit(void *ctx)
241 {
242 }
243 
244 /**
245  * mlme_cm_state_connected_event() - Disconnecting State event handler for
246  * connection mgr
247  * @ctx: connection manager ctx
248  *
249  * API to handle events in Disconnecting state
250  *
251  * Return: bool
252  */
253 static bool mlme_cm_state_disconnecting_event(void *ctx, uint16_t event,
254 					      uint16_t event_data_len,
255 					      void *event_data)
256 {
257 //	struct cnx_mgr *cm_ctx = (struct cnx_mgr *)ctx;
258 	bool status;
259 
260 	switch (event) {
261 	default:
262 		status = false;
263 		break;
264 	}
265 
266 	return status;
267 }
268 
269 /**
270  * mlme_cm_subst_join_pending_entry() - Entry API for join pending sub-state for
271  * connection mgr
272  * @ctx: connection manager ctx
273  *
274  * API to perform operations on moving to join pending sub-state
275  *
276  * Return: void
277  */
278 static void mlme_cm_subst_join_pending_entry(void *ctx)
279 {
280 	struct cnx_mgr *cm_ctx = (struct cnx_mgr *)ctx;
281 
282 	if (mlme_cm_get_state(cm_ctx) != WLAN_CM_S_CONNECTING)
283 		QDF_BUG(0);
284 
285 	mlme_cm_set_substate(cm_ctx, WLAN_CM_SS_JOIN_PENDING);
286 }
287 
288 /**
289  * mlme_cm_subst_join_pending_exit() - Exit API for join pending sub-state for
290  * connection mgr
291  * @ctx: connection manager ctx
292  *
293  * API to perform operations on exiting from join pending sub-state
294  *
295  * Return: void
296  */
297 static void mlme_cm_subst_join_pending_exit(void *ctx)
298 {
299 }
300 
301 /**
302  * mlme_cm_subst_join_pending_event() - Join pending sub-state event handler for
303  * connection mgr
304  * @ctx: connection manager ctx
305  *
306  * API to handle events in Join pending sub-state
307  *
308  * Return: bool
309  */
310 static bool mlme_cm_subst_join_pending_event(void *ctx, uint16_t event,
311 					     uint16_t event_data_len,
312 					     void *event_data)
313 {
314 //	struct cnx_mgr *cm_ctx = (struct cnx_mgr *)ctx;
315 	bool status;
316 
317 	switch (event) {
318 	default:
319 		status = false;
320 		break;
321 	}
322 
323 	return status;
324 }
325 
326 /**
327  * mlme_cm_subst_scan_entry() - Entry API for scan sub-state for
328  * connection mgr
329  * @ctx: connection manager ctx
330  *
331  * API to perform operations on moving to scan sub-state
332  *
333  * Return: void
334  */
335 static void mlme_cm_subst_scan_entry(void *ctx)
336 {
337 	struct cnx_mgr *cm_ctx = (struct cnx_mgr *)ctx;
338 
339 	if (mlme_cm_get_state(cm_ctx) != WLAN_CM_S_CONNECTING)
340 		QDF_BUG(0);
341 
342 	mlme_cm_set_substate(cm_ctx, WLAN_CM_SS_SCAN);
343 }
344 
345 /**
346  * mlme_cm_subst_scan_exit() - Exit API for scan sub-state for
347  * connection mgr
348  * @ctx: connection manager ctx
349  *
350  * API to perform operations on exiting from scan sub-state
351  *
352  * Return: void
353  */
354 static void mlme_cm_subst_scan_exit(void *ctx)
355 {
356 }
357 
358 /**
359  * mlme_cm_subst_scan_event() - Scan sub-state event handler for
360  * connection mgr
361  * @ctx: connection manager ctx
362  *
363  * API to handle events in scan sub-state
364  *
365  * Return: bool
366  */
367 static bool mlme_cm_subst_scan_event(void *ctx, uint16_t event,
368 				     uint16_t event_data_len, void *event_data)
369 {
370 //	struct cnx_mgr *cm_ctx = (struct cnx_mgr *)ctx;
371 	bool status;
372 
373 	switch (event) {
374 	default:
375 		status = false;
376 		break;
377 	}
378 
379 	return status;
380 }
381 
382 /**
383  * mlme_cm_subst_join_active_entry() - Entry API for join active sub-state for
384  * connection mgr
385  * @ctx: connection manager ctx
386  *
387  * API to perform operations on moving to join active sub-state
388  *
389  * Return: void
390  */
391 static void mlme_cm_subst_join_active_entry(void *ctx)
392 {
393 	struct cnx_mgr *cm_ctx = (struct cnx_mgr *)ctx;
394 
395 	if (mlme_cm_get_state(cm_ctx) != WLAN_CM_S_CONNECTING)
396 		QDF_BUG(0);
397 
398 	mlme_cm_set_substate(cm_ctx, WLAN_CM_SS_JOIN_ACTIVE);
399 }
400 
401 /**
402  * mlme_cm_subst_join_active_exit() - Exit API for join active sub-state for
403  * connection mgr
404  * @ctx: connection manager ctx
405  *
406  * API to perform operations on exiting from join active sub-state
407  *
408  * Return: void
409  */
410 static void mlme_cm_subst_join_active_exit(void *ctx)
411 {
412 }
413 
414 /**
415  * mlme_cm_subst_join_active_event() - Join active sub-state event handler for
416  * connection mgr
417  * @ctx: connection manager ctx
418  *
419  * API to handle events in join active sub-state
420  *
421  * Return: bool
422  */
423 static bool mlme_cm_subst_join_active_event(void *ctx, uint16_t event,
424 					    uint16_t event_data_len,
425 					    void *event_data)
426 {
427 //	struct cnx_mgr *cm_ctx = (struct cnx_mgr *)ctx;
428 	bool status;
429 
430 	switch (event) {
431 	default:
432 		status = false;
433 		break;
434 	}
435 
436 	return status;
437 }
438 
439 struct wlan_sm_state_info cm_sm_info[] = {
440 	{
441 		(uint8_t)WLAN_CM_S_INIT,
442 		(uint8_t)WLAN_SM_ENGINE_STATE_NONE,
443 		(uint8_t)WLAN_SM_ENGINE_STATE_NONE,
444 		true,
445 		"INIT",
446 		mlme_cm_state_init_entry,
447 		mlme_cm_state_init_exit,
448 		mlme_cm_state_init_event
449 	},
450 	{
451 		(uint8_t)WLAN_CM_S_CONNECTING,
452 		(uint8_t)WLAN_SM_ENGINE_STATE_NONE,
453 		(uint8_t)WLAN_SM_ENGINE_STATE_NONE,
454 		true,
455 		"CONNECTING",
456 		mlme_cm_state_connecting_entry,
457 		mlme_cm_state_connecting_exit,
458 		mlme_cm_state_connecting_event
459 	},
460 	{
461 		(uint8_t)WLAN_CM_S_CONNECTED,
462 		(uint8_t)WLAN_SM_ENGINE_STATE_NONE,
463 		(uint8_t)WLAN_SM_ENGINE_STATE_NONE,
464 		true,
465 		"CONNECTED",
466 		mlme_cm_state_connected_entry,
467 		mlme_cm_state_connected_exit,
468 		mlme_cm_state_connected_event
469 	},
470 	{
471 		(uint8_t)WLAN_CM_S_DISCONNECTING,
472 		(uint8_t)WLAN_SM_ENGINE_STATE_NONE,
473 		(uint8_t)WLAN_SM_ENGINE_STATE_NONE,
474 		true,
475 		"DISCONNECTING",
476 		mlme_cm_state_disconnecting_entry,
477 		mlme_cm_state_disconnecting_exit,
478 		mlme_cm_state_disconnecting_event
479 	},
480 	{
481 		(uint8_t)WLAN_CM_S_ROAMING,
482 		(uint8_t)WLAN_SM_ENGINE_STATE_NONE,
483 		(uint8_t)WLAN_SM_ENGINE_STATE_NONE,
484 		true,
485 		"ROAMING",
486 		mlme_cm_state_roaming_entry,
487 		mlme_cm_state_roaming_exit,
488 		mlme_cm_state_roaming_event
489 	},
490 	{
491 		(uint8_t)WLAN_CM_S_MAX,
492 		(uint8_t)WLAN_SM_ENGINE_STATE_NONE,
493 		(uint8_t)WLAN_SM_ENGINE_STATE_NONE,
494 		false,
495 		"INVALID",
496 		NULL,
497 		NULL,
498 		NULL
499 	},
500 	{
501 		(uint8_t)WLAN_CM_SS_IDLE,
502 		(uint8_t)WLAN_SM_ENGINE_STATE_NONE,
503 		(uint8_t)WLAN_SM_ENGINE_STATE_NONE,
504 		false,
505 		"IDLE",
506 		NULL,
507 		NULL,
508 		NULL
509 	},
510 	{
511 		(uint8_t)WLAN_CM_SS_JOIN_PENDING,
512 		(uint8_t)WLAN_CM_S_CONNECTING,
513 		(uint8_t)WLAN_SM_ENGINE_STATE_NONE,
514 		false,
515 		"JOIN_PENDING",
516 		mlme_cm_subst_join_pending_entry,
517 		mlme_cm_subst_join_pending_exit,
518 		mlme_cm_subst_join_pending_event
519 	},
520 	{
521 		(uint8_t)WLAN_CM_SS_SCAN,
522 		(uint8_t)WLAN_CM_S_CONNECTING,
523 		(uint8_t)WLAN_SM_ENGINE_STATE_NONE,
524 		false,
525 		"SCAN",
526 		mlme_cm_subst_scan_entry,
527 		mlme_cm_subst_scan_exit,
528 		mlme_cm_subst_scan_event
529 	},
530 	{
531 		(uint8_t)WLAN_CM_SS_JOIN_ACTIVE,
532 		(uint8_t)WLAN_CM_S_CONNECTING,
533 		(uint8_t)WLAN_SM_ENGINE_STATE_NONE,
534 		false,
535 		"JOIN_ACTIVE",
536 		mlme_cm_subst_join_active_entry,
537 		mlme_cm_subst_join_active_exit,
538 		mlme_cm_subst_join_active_event
539 	},
540 #ifdef WLAN_FEATURE_HOST_ROAM
541 	{
542 		(uint8_t)WLAN_CM_SS_PREAUTH,
543 		(uint8_t)WLAN_CM_S_ROAMING,
544 		(uint8_t)WLAN_SM_ENGINE_STATE_NONE,
545 		false,
546 		"PREAUTH",
547 		mlme_cm_subst_preauth_entry,
548 		mlme_cm_subst_preauth_exit,
549 		mlme_cm_subst_preauth_event
550 	},
551 	{
552 		(uint8_t)WLAN_CM_SS_REASSOC,
553 		(uint8_t)WLAN_CM_S_ROAMING,
554 		(uint8_t)WLAN_SM_ENGINE_STATE_NONE,
555 		false,
556 		"REASSOC",
557 		mlme_cm_subst_reassoc_entry,
558 		mlme_cm_subst_reassoc_exit,
559 		mlme_cm_subst_reassoc_event
560 	},
561 #endif
562 #ifdef WLAN_FEATURE_ROAM_OFFLOAD
563 	{
564 		(uint8_t)WLAN_CM_SS_ROAM_STARTED,
565 		(uint8_t)WLAN_CM_S_ROAMING,
566 		(uint8_t)WLAN_SM_ENGINE_STATE_NONE,
567 		false,
568 		"ROAM_START",
569 		mlme_cm_subst_roam_start_entry,
570 		mlme_cm_subst_roam_start_exit,
571 		mlme_cm_subst_roam_start_event
572 	},
573 	{
574 		(uint8_t)WLAN_CM_SS_ROAM_SYNC,
575 		(uint8_t)WLAN_CM_S_ROAMING,
576 		(uint8_t)WLAN_SM_ENGINE_STATE_NONE,
577 		false,
578 		"ROAM_SYNC",
579 		mlme_cm_subst_roam_sync_entry,
580 		mlme_cm_subst_roam_sync_exit,
581 		mlme_cm_subst_roam_sync_event
582 	},
583 #endif
584 	{
585 		(uint8_t)WLAN_CM_SS_MAX,
586 		(uint8_t)WLAN_SM_ENGINE_STATE_NONE,
587 		(uint8_t)WLAN_SM_ENGINE_STATE_NONE,
588 		false,
589 		"INVALID",
590 		NULL,
591 		NULL,
592 		NULL
593 	},
594 };
595 
596 static const char *cm_sm_event_names[] = {
597 	"EV_CONNECT_REQ",
598 	"EV_SCAN_FOR_SSID",
599 	"EV_SCAN_FOR_SSID_SUCCESS",
600 	"EV_SCAN_FOR_SSID_FAILURE",
601 	"EV_CONNECT_START_REQ",
602 	"EV_CONNECT_START",
603 	"EV_CONNECT_SUCCESS",
604 	"EV_CONNECT_NEXT_CANDIDATE",
605 	"EV_CONNECT_FAILURE",
606 	"EV_DISCONNECT_REQ",
607 	"EV_DISCONNECT_START_REQ",
608 	"EV_DISCONNECT_START",
609 	"EV_DISCONNECT_DONE",
610 	"EV_ROAM_START",
611 	"EV_ROAM_SYNC",
612 	"EV_ROAM_INVOKE_FAIL",
613 	"EV_ROAM_HO_FAIL",
614 	"EV_PREAUTH_DONE",
615 	"EV_GET_NEXT_PREAUTH_AP",
616 	"EV_PREAUTH_FAIL",
617 	"EV_START_REASSOC",
618 	"EV_REASSOC_DONE",
619 	"EV_REASSOC_FAILURE",
620 	"EV_ROAM_COMPLETE",
621 	"EV_CONNECT_TIMEOUT",
622 	"EV_CONNECT_SER_FAIL",
623 	"EV_HW_MODE_CHANGE_FAIL",
624 };
625 
626 enum wlan_cm_sm_state mlme_cm_get_state(struct cnx_mgr *cm_ctx)
627 {
628 	enum QDF_OPMODE op_mode;
629 
630 	if (!cm_ctx || !cm_ctx->vdev)
631 		return WLAN_CM_S_MAX;
632 
633 	op_mode = wlan_vdev_mlme_get_opmode(cm_ctx->vdev);
634 
635 	if (op_mode != QDF_STA_MODE && op_mode != QDF_P2P_CLIENT_MODE)
636 		return WLAN_CM_S_MAX;
637 
638 	return cm_ctx->sm.cm_state;
639 }
640 
641 enum wlan_cm_sm_state mlme_cm_get_sub_state(struct cnx_mgr *cm_ctx)
642 {
643 	enum QDF_OPMODE op_mode;
644 
645 	if (!cm_ctx || !cm_ctx->vdev)
646 		return WLAN_CM_SS_MAX;
647 
648 	op_mode = wlan_vdev_mlme_get_opmode(cm_ctx->vdev);
649 
650 	if (op_mode != QDF_STA_MODE && op_mode != QDF_P2P_CLIENT_MODE)
651 		return WLAN_CM_SS_MAX;
652 
653 	return cm_ctx->sm.cm_substate;
654 }
655 
656 static inline
657 QDF_STATUS mlme_cm_sm_deliver_event(struct cnx_mgr *cm_ctx,
658 				    enum wlan_cm_sm_evt event,
659 				    uint16_t event_data_len, void *event_data)
660 {
661 	return wlan_sm_dispatch(cm_ctx->sm.sm_hdl, event,
662 				event_data_len, event_data);
663 }
664 
665 static void mlme_cm_sm_print_state_event(struct cnx_mgr *cm_ctx,
666 					 enum wlan_cm_sm_evt event)
667 {
668 	enum wlan_cm_sm_state state;
669 	enum wlan_cm_sm_state substate;
670 
671 	state = mlme_cm_get_state(cm_ctx);
672 	substate = mlme_cm_get_sub_state(cm_ctx);
673 
674 	mlme_nofl_debug("[%s]%s - %s, %s", cm_ctx->sm.sm_hdl->name,
675 			cm_sm_info[state].name, cm_sm_info[substate].name,
676 			cm_sm_event_names[event]);
677 }
678 
679 static void mlme_cm_sm_print_state(struct cnx_mgr *cm_ctx)
680 {
681 	enum wlan_cm_sm_state state;
682 	enum wlan_cm_sm_state substate;
683 
684 	state = mlme_cm_get_state(cm_ctx);
685 	substate = mlme_cm_get_sub_state(cm_ctx);
686 
687 	mlme_nofl_debug("[%s]%s - %s", cm_ctx->sm.sm_hdl->name,
688 			cm_sm_info[state].name, cm_sm_info[substate].name);
689 }
690 
691 QDF_STATUS mlme_cm_sm_deliver_evt(struct wlan_objmgr_vdev *vdev,
692 				  enum wlan_cm_sm_evt event,
693 				  uint16_t event_data_len,
694 				  void *event_data)
695 {
696 	struct vdev_mlme_obj *vdev_mlme;
697 	QDF_STATUS status;
698 	enum wlan_cm_sm_state state_entry, state_exit;
699 	enum wlan_cm_sm_state substate_entry, substate_exit;
700 	enum QDF_OPMODE op_mode = wlan_vdev_mlme_get_opmode(vdev);
701 	struct cnx_mgr *cm_ctx;
702 
703 	if (op_mode != QDF_STA_MODE && op_mode != QDF_P2P_CLIENT_MODE) {
704 		mlme_err("Invalid mode %d", op_mode);
705 		return QDF_STATUS_E_NOSUPPORT;
706 	}
707 
708 	vdev_mlme = wlan_vdev_mlme_get_cmpt_obj(vdev);
709 	if (!vdev_mlme || !vdev_mlme->cnx_mgr_ctx) {
710 		mlme_err("vdev mlme or cm ctx is NULL");
711 		return QDF_STATUS_E_FAILURE;
712 	}
713 	cm_ctx = vdev_mlme->cnx_mgr_ctx;
714 	mlme_cm_lock_acquire(cm_ctx);
715 
716 	/* store entry state and sub state for prints */
717 	state_entry = mlme_cm_get_state(cm_ctx);
718 	substate_entry = mlme_cm_get_sub_state(cm_ctx);
719 	mlme_cm_sm_print_state_event(cm_ctx, event);
720 
721 	status = mlme_cm_sm_deliver_event(cm_ctx, event, event_data_len,
722 					  event_data);
723 	/* Take exit state, exit substate for prints */
724 	state_exit = mlme_cm_get_state(cm_ctx);
725 	substate_exit = mlme_cm_get_sub_state(cm_ctx);
726 	/* If no state and substate change, don't print */
727 	if (!((state_entry == state_exit) && (substate_entry == substate_exit)))
728 		mlme_cm_sm_print_state(cm_ctx);
729 	mlme_cm_lock_release(cm_ctx);
730 
731 	return status;
732 }
733 
734 QDF_STATUS mlme_cm_sm_create(struct cnx_mgr *cm_ctx)
735 {
736 	struct wlan_sm *sm;
737 	uint8_t name[WLAN_SM_ENGINE_MAX_NAME];
738 
739 	qdf_snprintf(name, sizeof(name), "CM-VDEV-%d",
740 		     wlan_vdev_get_id(cm_ctx->vdev));
741 	sm = wlan_sm_create(name, cm_ctx,
742 			    WLAN_CM_S_INIT,
743 			    cm_sm_info,
744 			    QDF_ARRAY_SIZE(cm_sm_info),
745 			    cm_sm_event_names,
746 			    QDF_ARRAY_SIZE(cm_sm_event_names));
747 	if (!sm) {
748 		mlme_err("CM MLME SM allocation failed");
749 		return QDF_STATUS_E_NOMEM;
750 	}
751 	cm_ctx->sm.sm_hdl = sm;
752 
753 	mlme_cm_lock_create(cm_ctx);
754 
755 	return QDF_STATUS_SUCCESS;
756 }
757 
758 QDF_STATUS mlme_cm_sm_destroy(struct cnx_mgr *cm_ctx)
759 {
760 	mlme_cm_lock_destroy(cm_ctx);
761 	wlan_sm_delete(cm_ctx->sm.sm_hdl);
762 
763 	return QDF_STATUS_SUCCESS;
764 }
765