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