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