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