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