xref: /OK3568_Linux_fs/external/rkwifibt/drivers/rtl8852bs/phl/phl_fsm.h (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1 /******************************************************************************
2  *
3  * Copyright(c) 2019 - 2020 Realtek Corporation.
4  *
5  * This program is free software; you can redistribute it and/or modify it
6  * under the terms of version 2 of the GNU General Public License as
7  * published by the Free Software Foundation.
8  *
9  * This program is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12  * more details.
13  *
14  *****************************************************************************/
15 #ifndef __PHL_FSM_H__
16 #define __PHL_FSM_H__
17 
18 #define PHL_INCLUDE_FSM
19 
20 /* #define PHL_DEBUG_FSM */
21 /* #define FSM_DBG_MEM_OVERWRITE */
22 
23 #ifdef FSM_DBG_MEM_OVERWRITE
24 void *fsm_kmalloc(u32 sz);
25 void fsm_kfree(void *ptr, u32 sz);
26 #endif
27 #define FSM_NAME_LEN		32
28 #define CLOCK_UNIT              10 /* ms */
29 
30 struct fsm_root;
31 struct fsm_main;
32 struct fsm_obj;
33 
34 /* event map
35  */
36 #define FSM_EV_MASK	0xff00
37 #define FSM_USR_EV_MASK	0x0100
38 #define FSM_INT_EV_MASK	0x0200
39 #define FSM_GBL_EV_MASK	0x0400
40 #define FSM_EV_UNKNOWN	0xffff
41 
42 /* FSM EVENT */
43 enum FSM_EV_ID {
44 	/* Expose to all FSM service */
45 	FSM_INT_EV_MASK_ = FSM_INT_EV_MASK,
46 	FSM_EV_CANCEL,
47 	FSM_EV_TIMER_EXPIRE,
48 	FSM_EV_END, /* for reference */
49 
50 	FSM_EV_SWITCH_IN,
51 	FSM_EV_SWITCH_OUT,
52 	FSM_EV_STATE_IN,
53 	FSM_EV_STATE_OUT,
54 
55 	/* Global Events for announcement */
56 	/* BE CAUREFUL the EVENT ORDER
57 	 * please also modify int_event_tbl[] in phl_fsm.c
58 	 */
59 	FSM_GB_SCAN_START,
60 	FSM_GB_SCAN_COMPLETE,
61 
62 	FSM_EV_MAX
63 };
64 
65 enum fsm_mode {
66 	FSM_SHARE_THREAD, /* fsm shares root_fsm thread */
67 	FSM_ALONE_THREAD /* fsm has its own thread */
68 };
69 
70 enum fsm_run_rtn {
71 	FSM_FREE_PARAM,
72 	FSM_KEEP_PARAM
73 };
74 
75 /* @oid: object id
76  * @event: event id
77  * @msg: additional message of the event
78  * @msg_sz: message size
79  */
80 struct fsm_msg {
81 	_os_list list;
82 	u8 oid; /* receiver */
83 	u16 event; /* event id */
84 	struct fsm_main *fsm;
85 
86 	void *param;
87 	int param_sz;
88 };
89 
90 enum fsm_dbg_level {
91 	FSM_DBG_NONE,
92 	FSM_DBG_PRINT,
93 	FSM_DBG_ERR,
94 	FSM_DBG_WARN,
95 	FSM_DBG_INFO, /* dbg_level: dump normal info msg */
96 	FSM_DBG_DBG, /* dbg_level: dump state change info */
97 	FSM_DBG_MAX
98 };
99 
100 #define EV_ENT(ev) {ev, #ev, FSM_DBG_INFO}
101 #define EV_WRN(ev) {ev, #ev, FSM_DBG_WARN}
102 #define EV_INF(ev) {ev, #ev, FSM_DBG_INFO}
103 #define EV_DBG(ev) {ev, #ev, FSM_DBG_DBG}
104 
105 struct fsm_event_ent {
106 	u16 event;
107 	char *name;
108 	u8 evt_level;
109 };
110 
111 #define ST_ENT(st, hdl) {st, #st, hdl}
112 struct fsm_state_ent {
113 	u8 state;
114 	char *name;
115 	int (*fsm_func)(void *priv, u16 event, void *param);
116 };
117 
118 /* struct of phl_fsm_init_fsm() */
119 struct rtw_phl_fsm_tb {
120 	u8 mode; /* 0/1: Share/Standalone thread mode */
121 	u8 dbg_level;
122 	u8 evt_level;
123 	u8 max_state;
124 	u16 max_event;
125 	struct fsm_state_ent *state_tbl;
126 	struct fsm_event_ent *evt_tbl;
127 
128 	/* debug function */
129 	void (*dump_obj)(void *obj, char *p, int *sz); /* optional */
130 	void (*dump_fsm)(void *fsm, char *p, int *sz); /* optional */
131 	void (*debug)(void *custom_obj, char input[][MAX_ARGV],
132 		      u32 input_num, char *output, u32 *out_len);
133 };
134 
135 enum gbl_evt_result {
136 	GBL_ST_NOT_FINISH,
137 	GBL_ST_SUCCESS,
138 	GBL_ST_ABORT,
139 	GBL_ST_FAIL,
140 	GBL_ST_WAIT_REACH_MAX,
141 	GBL_ST_REPLY_REACH_MAX,
142 	GBL_ST_ALLOC_MEM_FAIL
143 };
144 
145 #define PHL_FSM_MAX_WAIT_OCUNT 16
146 struct gbl_param {
147 	struct list_head list;
148 	u16 event;
149 	u16 cb_evt;
150 	u16 count;
151 	u32 wait_ms;
152 	u32 seq;
153 	struct fsm_obj *obj_from; /* GBL event original issuer */
154 	struct fsm_obj *obj_to; /* GBL event original receiver */
155 	struct fsm_obj *wait_list[PHL_FSM_MAX_WAIT_OCUNT];
156 	int result;
157 };
158 
159 /* GBL event caller use */
160 int phl_fsm_gbl_msg_announce(struct fsm_obj *obj, u16 gbl_evt, u16 cb_evt);
161 int phl_fsm_gbl_not_reply_num(struct fsm_obj *obj, struct gbl_param *param);
162 enum rtw_phl_status phl_fsm_flush_gbl(struct fsm_obj *obj);
163 
164 /* GBL event callee use */
165 int phl_fsm_gbl_msg_hold(struct fsm_obj *obj,
166 	struct gbl_param *param, u32 ms);
167 enum rtw_phl_status phl_fsm_gbl_msg_release(struct fsm_obj *obj,
168 	u16 event, u32 seq, enum gbl_evt_result result);
169 
170 /* fsm init funciton */
171 struct fsm_root *phl_fsm_init_root(void *phl_info);
172 void phl_fsm_deinit_root(struct fsm_root *root);
173 enum rtw_phl_status phl_fsm_start_root(struct fsm_root *root);
174 enum rtw_phl_status phl_fsm_stop_root(struct fsm_root *root);
175 
176 
177 struct fsm_main *phl_fsm_init_fsm(struct fsm_root *root,
178 	const char *name, void *phl_info, struct rtw_phl_fsm_tb *tb);
179 enum rtw_phl_status phl_fsm_deinit_fsm(struct fsm_main *fsm);
180 
181 enum rtw_phl_status phl_fsm_start_fsm(struct fsm_main *fsm);
182 enum rtw_phl_status phl_fsm_stop_fsm(struct fsm_main *fsm);
183 void *phl_fsm_new_obj(struct fsm_main *fsm, void **fsm_obj, int obj_sz);
184 void phl_fsm_destory_obj(struct fsm_obj *obj);
185 void phl_fsm_dbg(struct phl_info_t *phl_info, char input[][MAX_ARGV],
186 		      u32 input_num, char *output, u32 out_len);
187 
188 /* fsm operating funciton */
189 struct fsm_msg *phl_fsm_new_msg(struct fsm_obj *obj, u16 event);
190 enum rtw_phl_status phl_fsm_sent_msg(struct fsm_obj *obj, struct fsm_msg *msg);
191 enum rtw_phl_status phl_fsm_cancel_obj(struct fsm_obj *obj);
192 void phl_fsm_state_goto(struct fsm_obj *obj, u8 new_state);
193 void phl_fsm_set_alarm(struct fsm_obj *obj, int ms, u16 event);
194 void phl_fsm_set_alarm_ext(struct fsm_obj *obj,
195 	int ms, u16 event, u8 id, void *priv);
196 void phl_fsm_cancel_alarm(struct fsm_obj *obj);
197 void phl_fsm_cancel_alarm_ext(struct fsm_obj *obj, u8 id);
198 void phl_fsm_pause_alarm(struct fsm_obj *obj);
199 void phl_fsm_pause_alarm_ext(struct fsm_obj *obj, u8 id);
200 void phl_fsm_resume_alarm(struct fsm_obj *obj);
201 void phl_fsm_resume_alarm_ext(struct fsm_obj *obj, u8 id);
202 bool phl_fsm_is_alarm_off(struct fsm_obj *obj);
203 bool phl_fsm_is_alarm_off_ext(struct fsm_obj *obj, u8 id);
204 void phl_fsm_extend_alarm_ext(struct fsm_obj *obj, int ms, u8 id);
205 u8 phl_fsm_dbg_level(struct fsm_main *fsm, u8 level);
206 u8 phl_fsm_evt_level(struct fsm_main *fsm, u8 level);
207 enum rtw_phl_status phl_fsm_gen_msg(void *phl, struct fsm_obj *obj,
208 	void *pbuf, u32 sz, u16 event);
209 
210 /* function to manipulate extra queue */
211 int phl_fsm_enqueue_ext(struct fsm_main *fsm, struct fsm_msg *msg, u8 to_head);
212 struct fsm_msg *phl_fsm_dequeue_ext(struct fsm_main *fsm);
213 int phl_fsm_is_ext_queue_empty(struct fsm_main *fsm);
214 
215 /* util function */
216 u8 phl_fsm_state_id(struct fsm_obj *obj);
217 char *phl_fsm_obj_name(struct fsm_obj *obj);
218 char *phl_fsm_evt_name(struct fsm_obj *obj, u16 event);
219 u32 phl_fsm_time_pass(u32 start);
220 u32 phl_fsm_time_left(u32 start, u32 end);
221 
222 
223 #ifndef CONFIG_PHL_WPP
224 #define FSM_PRINT(fsm, fmt, ...) \
225 	do {\
226 		if (!fsm || phl_fsm_dbg_level(fsm, FSM_DBG_PRINT)) \
227 			PHL_TRACE(COMP_PHL_FSM, _PHL_ALWAYS_, fmt, ##__VA_ARGS__); \
228 	} while (0)
229 
230 #define FSM_ERR(fsm, fmt, ...) \
231 	do {\
232 		if (!fsm || phl_fsm_dbg_level(fsm, FSM_DBG_ERR)) \
233 			PHL_TRACE(COMP_PHL_FSM, _PHL_ERR_, fmt, ##__VA_ARGS__); \
234 	} while (0)
235 
236 #define FSM_WARN(fsm, fmt, ...) \
237 	do {\
238 		if (!fsm || phl_fsm_dbg_level(fsm, FSM_DBG_WARN)) \
239 			PHL_TRACE(COMP_PHL_FSM, _PHL_WARNING_, fmt, ##__VA_ARGS__); \
240 	} while (0)
241 
242 #define FSM_INFO(fsm, fmt, ...) \
243 	do {\
244 		if (!fsm || phl_fsm_dbg_level(fsm, FSM_DBG_INFO)) \
245 			PHL_TRACE(COMP_PHL_FSM, _PHL_INFO_, fmt, ##__VA_ARGS__); \
246 	} while (0)
247 
248 #define FSM_DBG(fsm, fmt, ...) \
249 	do {\
250 		if (!fsm || phl_fsm_dbg_level(fsm, FSM_DBG_DBG)) \
251 			PHL_TRACE(COMP_PHL_FSM, _PHL_DEBUG_, fmt, ##__VA_ARGS__); \
252 	} while (0)
253 
254 #define FSM_MSG(fsm, level_, fmt, ...) \
255 	do {\
256 		if (!fsm || phl_fsm_dbg_level(fsm, level_)) \
257 			PHL_TRACE(COMP_PHL_FSM, _PHL_INFO_, fmt, ##__VA_ARGS__); \
258 	} while (0)
259 
260 #define FSM_EV_MSG(fsm, level_, fmt, ...) \
261 	do {\
262 		if (!fsm || phl_fsm_evt_level(fsm, level_)) \
263 			PHL_TRACE(COMP_PHL_FSM, _PHL_INFO_, fmt, ##__VA_ARGS__); \
264 	} while (0)
265 #else
266 #undef FSM_PRINT
267 #define FSM_PRINT(fsm, fmt, ...)
268 #undef FSM_ERR
269 #define FSM_ERR(fsm, fmt, ...)
270 #undef FSM_WARN
271 #define FSM_WARN(fsm, fmt, ...)
272 #undef FSM_INFO
273 #define FSM_INFO(fsm, fmt, ...)
274 #undef FSM_DBG
275 #define FSM_DBG(fsm, fmt, ...)
276 #undef FSM_MSG
277 #define FSM_MSG(fsm, level, fmt, ...)
278 #undef FSM_EV_MSG
279 #define FSM_EV_MSG(fsm, level, fmt, ...)
280 #endif  /* CONFIG_PHL_WPP */
281 
282 #endif /* __PHL_FSM_H__ */
283