xref: /wlan-dirver/qca-wifi-host-cmn/umac/cmn_services/sm_engine/inc/wlan_sm_engine.h (revision 0626a4da6c07f30da06dd6747e8cc290a60371d8)
1 /*
2  * Copyright (c) 2018 The Linux Foundation. All rights reserved.
3  *
4  * Permission to use, copy, modify, and/or distribute this software for
5  * any purpose with or without fee is hereby granted, provided that the
6  * above copyright notice and this permission notice appear in all
7  * copies.
8  *
9  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
10  * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
11  * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
12  * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
13  * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
14  * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
15  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
16  * PERFORMANCE OF THIS SOFTWARE.
17  */
18 
19 /**
20  * DOC: Define general SM framework, The modules can implement state machine
21  * using framework, it provides framework for state, event, state transition,
22  * event handling
23  *
24  * The module, whoever implement SM using this framework need to define an array
25  * of structures (of type struct wlan_sm_state_info) as below,
26  * for example, sample state array definition
27  *
28  * struct wlan_sm_state_info sm_info[] = {
29  *     {
30  *         (uint8_t) WLAN_VDEV_S_INIT,
31  *         (uint8_t) WLAN_SM_ENGINE_STATE_NONE,
32  *         (uint8_t) WLAN_SM_ENGINE_STATE_NONE,
33  *         true,
34  *         "INIT",
35  *         mlme_vdev_state_init_entry, --> gets invoked on entering the state
36  *         mlme_vdev_state_init_exit, --> gets invoked before exiting the state
37  *         mlme_vdev_state_init_event  --> gets invoked on event dispatch
38  *     },
39  *     {
40  *         (uint8_t) WLAN_VDEV_S_START,
41  *         (uint8_t) WLAN_SM_ENGINE_STATE_NONE,
42  *         (uint8_t) WLAN_SM_ENGINE_STATE_NONE,
43  *         true,
44  *         "START",
45  *         mlme_vdev_state_start_entry,
46  *         mlme_vdev_state_start_exit,
47  *         mlme_vdev_state_start_event
48  *     },
49  *     {
50  *        (uint8_t) WLAN_VDEV_S_DFS_CAC_WAIT,
51  *        (uint8_t) WLAN_SM_ENGINE_STATE_NONE,
52  *        (uint8_t) WLAN_SM_ENGINE_STATE_NONE,
53  *        true,
54  *        "DFS_CAC_WAIT",
55  *        mlme_vdev_state_dfs_cac_wait_entry,
56  *        mlme_vdev_state_dfs_cac_wait_exit,
57  *        mlme_vdev_state_dfs_cac_wait_event
58  *     },
59  *     ...
60  *  };
61  *
62  *  Invoke wlan_sm_create() with this state array as below
63  *
64  *  sm = wlan_sm_create("VDEV_SM", vdev_obj, WLAN_VDEV_S_INIT, sm_info, 3,
65  *                       event_names[], num_events);
66  *
67  *  on successful creation, invoke below functions to dispatch events and state
68  *  transition
69  *
70  *  Event dispatch:
71  *    wlan_sm_dispatch(sm, start_event_id, 0, NULL);
72  *
73  *  State transition:
74  *     wlan_sm_transition_to(sm, WLAN_VDEV_S_INIT);
75  *
76  *
77  */
78 #ifndef _WLAN_SM_ENGINE_H_
79 #define _WLAN_SM_ENGINE_H_
80 
81 #include <qdf_types.h>
82 #include <qdf_atomic.h>
83 #include <wlan_sm_engine_dbg.h>
84 
85 /* invalid state */
86 #define WLAN_SM_ENGINE_STATE_NONE 255
87 /* invalid event */
88 #define WLAN_SM_ENGINE_EVENT_NONE 255
89 
90 #define WLAN_SM_ENGINE_MAX_STATE_NAME 128
91 #define WLAN_SM_ENGINE_MAX_NAME   64
92 #define WLAN_SM_ENGINE_MAX_STATES 200
93 #define WLAN_SM_ENGINE_MAX_EVENTS 200
94 
95 /**
96  * struct wlan_sm_state_info - state structure definition
97  * @state:             State id
98  * @parent_state:      Parent state id (optional)
99  * @initial_substate:  Initial sub state of this state
100  * @has_substates:     flag to specify, whether it has sub states
101  * @name:              Name of the state
102  * @wlan_sm_entry:    State entry callback poitner
103  * @wlan_sm_exit:     State exit callback poitner
104  * @wlan_sm_event:    State event callback poitner
105  */
106 struct wlan_sm_state_info {
107 	uint8_t state;
108 	uint8_t parent_state;
109 	uint8_t initial_substate;
110 	uint8_t has_substates;
111 	const char *name;
112 	void (*wlan_sm_entry) (void *ctx);
113 	void (*wlan_sm_exit) (void *ctx);
114 	bool (*wlan_sm_event) (void *ctx, uint16_t event,
115 			       uint16_t event_data_len, void *event_data);
116 };
117 
118 /**
119  * struct wlan_sm - state machine structure
120  * @name:                 Name of the statemachine
121  * @cur_state:            Current state (state/sub-state)
122  * @num_states:           Number of states
123  * @last_event:           Holds the last handled event of SM
124  * @state_info:           Initialized States' table
125  * @ctx:                  Holds the caller's context
126  * @in_state_transition:  Flag to check whether state transition is in progress
127  * @event_names:          Array of event names
128  * @num_event_names:      Number of event names
129  * @history:              Holds the SM history pointer
130  */
131 struct wlan_sm {
132 	uint8_t name[WLAN_SM_ENGINE_MAX_NAME];
133 	uint8_t cur_state;
134 	uint8_t num_states;
135 	uint8_t last_event;
136 	struct wlan_sm_state_info *state_info;
137 	void *ctx;
138 	qdf_atomic_t in_state_transition;
139 	const char **event_names;
140 	uint32_t num_event_names;
141 #ifdef SM_ENG_HIST_ENABLE
142 	struct wlan_sm_history history;
143 #endif
144 };
145 
146 #define WLAN_SM_ENGINE_ENTRY(name, state, parent, initsubstate, has_substates) \
147 	{ state, parent, initsubstate, has_substates, \
148 	"##name", wlan_sm_##name_entry, wlan_sm_##name_exit,\
149 	wlan_sm_##name_event }
150 
151 /*
152  * flag definitions
153  */
154 #define WLAN_SM_ENGINE_ASYNCHRONOUS  0x0  /* run SM asynchronously */
155 #define WLAN_SM_ENGINE_SYNCHRONOUS   0x1  /* run SM synchronously */
156 
157 /**
158  * wlan_sm_create() - SM create
159  * @name: Name of SM owner module
160  * @ctx: caller pointer, used on invoking callbacks
161  * @init_state: Default state of the SM
162  * @state_info: States' definitions
163  * @num_state: Number of states
164  * @event_names: Event name table
165  * @num_event_names: Number of events
166  *
167  * Creates SM object, intializes with init_state, stores the name and owner
168  * module pointer, states definition table, and event name table
169  *
170  * Return: Handle to struct wlan_sm on successful creation,
171  *         NULL on Failure
172  */
173 struct wlan_sm *wlan_sm_create(const char *name, void *ctx,
174 			       uint8_t init_state,
175 			       struct wlan_sm_state_info *state_info,
176 			       uint8_t num_states,
177 			       const char **event_names,
178 			       uint32_t num_event_names);
179 
180 /**
181  * wlan_sm_delete() - SM delete
182  * @sm: state machine handle
183  *
184  * Delete SM object
185  *
186  * Return: void
187  */
188 void wlan_sm_delete(struct wlan_sm *sm);
189 
190 /**
191  * wlan_sm_dispatch() - API to notify event to SM
192  * @sm: state machine handle
193  * @event: event id
194  * @event_data_len: Size of event data
195  * @event_data: Event data
196  *
197  * Notifies event to SM, it invokes event callback of the current state of SM
198  *
199  * Return: QDF_STATUS_SUCCESS for handling
200  *         QDF_STATUS_E_INVAL for not handling
201  */
202 QDF_STATUS wlan_sm_dispatch(struct wlan_sm *sm, uint16_t event,
203 			    uint16_t event_data_len, void *event_data);
204 
205 /**
206  * wlan_sm_transition_to() - API to move the state of SM
207  * @sm: state machine handle
208  * @state: State id
209  *
210  * Moves the SM's state
211  *
212  * Return: void
213  */
214 void wlan_sm_transition_to(struct wlan_sm *sm, uint8_t state);
215 
216 /**
217  * wlan_sm_get_lastevent() - API to get last dispatched event
218  * @sm: state machine handle
219  *
220  * Gets the last dispatched event
221  *
222  * Return: event id
223  */
224 uint8_t wlan_sm_get_lastevent(struct wlan_sm *sm);
225 
226 /**
227  * wlan_sm_get_current_state() - API to get current state of SM
228  * @sm: state machine handle
229  *
230  * Gets the current state of SM
231  *
232  * Return: state id
233  */
234 uint8_t wlan_sm_get_current_state(struct wlan_sm *sm);
235 
236 /**
237  * wlan_sm_get_current_state_name() - API to get current state's name of SM
238  * @sm: state machine handle
239  *
240  * Gets the current state name of SM
241  *
242  * Return: name of the state
243  */
244 const char *wlan_sm_get_current_state_name(struct wlan_sm *sm);
245 
246 /**
247  * wlan_sm_get_state_name() - API to get state's name
248  * @sm: state machine handle
249  * @state: state id
250  *
251  * Gets the given state name of SM
252  *
253  * Return: name of the state
254  */
255 const char *wlan_sm_get_state_name(struct wlan_sm *sm, uint8_t state);
256 
257 /**
258  * wlan_sm_reset() - API to reset SM state
259  * @sm: state machine handle
260  * @init_state: state to reset SM
261  *
262  * Resets the SM to given state
263  *
264  * Return: void
265  */
266 void wlan_sm_reset(struct wlan_sm *sm, uint8_t init_state);
267 
268 #endif
269