android13/external/wifi_driver/rtl8852be/phl/phl_fsm.h

283 lines
8.0 KiB
C

/******************************************************************************
*
* 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__ */