1/* SPDX-License-Identifier: GPL-2.0-only
2 *
3 * Copyright (c) 2021, MediaTek Inc.
4 * Copyright (c) 2021-2022, Intel Corporation.
5 *
6 * Authors:
7 * Amir Hanania <amir.hanania@intel.com>
8 * Haijun Liu <haijun.liu@mediatek.com>
9 * Moises Veleta <moises.veleta@intel.com>
10 *
11 * Contributors:
12 * Eliot Lee <eliot.lee@intel.com>
13 * Ricardo Martinez <ricardo.martinez@linux.intel.com>
14 * Sreehari Kancharla <sreehari.kancharla@intel.com>
15 */
16
17#ifndef __T7XX_MONITOR_H__
18#define __T7XX_MONITOR_H__
19
20#include <linux/bits.h>
21#include <linux/sched.h>
22#include <linux/spinlock.h>
23#include <linux/types.h>
24#include <linux/wait.h>
25
26#include "t7xx_modem_ops.h"
27
28enum t7xx_fsm_state {
29 FSM_STATE_INIT,
30 FSM_STATE_PRE_START,
31 FSM_STATE_STARTING,
32 FSM_STATE_READY,
33 FSM_STATE_EXCEPTION,
34 FSM_STATE_STOPPING,
35 FSM_STATE_STOPPED,
36};
37
38enum t7xx_fsm_event_state {
39 FSM_EVENT_INVALID,
40 FSM_EVENT_MD_HS2,
41 FSM_EVENT_AP_HS2,
42 FSM_EVENT_MD_EX,
43 FSM_EVENT_MD_EX_REC_OK,
44 FSM_EVENT_MD_EX_PASS,
45 FSM_EVENT_MD_HS2_EXIT,
46 FSM_EVENT_AP_HS2_EXIT,
47 FSM_EVENT_MAX
48};
49
50enum t7xx_fsm_cmd_state {
51 FSM_CMD_INVALID,
52 FSM_CMD_START,
53 FSM_CMD_EXCEPTION,
54 FSM_CMD_PRE_STOP,
55 FSM_CMD_STOP,
56};
57
58enum t7xx_ex_reason {
59 EXCEPTION_HS_TIMEOUT,
60 EXCEPTION_EVENT,
61};
62
63enum t7xx_md_irq_type {
64 MD_IRQ_WDT,
65 MD_IRQ_CCIF_EX,
66 MD_IRQ_PORT_ENUM,
67};
68
69enum md_state {
70 MD_STATE_INVALID,
71 MD_STATE_WAITING_FOR_HS1,
72 MD_STATE_WAITING_FOR_HS2,
73 MD_STATE_READY,
74 MD_STATE_EXCEPTION,
75 MD_STATE_WAITING_TO_STOP,
76 MD_STATE_STOPPED,
77};
78
79#define FSM_CMD_FLAG_WAIT_FOR_COMPLETION BIT(0)
80#define FSM_CMD_FLAG_FLIGHT_MODE BIT(1)
81#define FSM_CMD_FLAG_IN_INTERRUPT BIT(2)
82#define FSM_CMD_EX_REASON GENMASK(23, 16)
83
84struct t7xx_fsm_ctl {
85 struct t7xx_modem *md;
86 enum md_state md_state;
87 unsigned int curr_state;
88 struct list_head command_queue;
89 struct list_head event_queue;
90 wait_queue_head_t command_wq;
91 wait_queue_head_t event_wq;
92 wait_queue_head_t async_hk_wq;
93 spinlock_t event_lock; /* Protects event queue */
94 spinlock_t command_lock; /* Protects command queue */
95 struct task_struct *fsm_thread;
96 bool exp_flg;
97 spinlock_t notifier_lock; /* Protects notifier list */
98 struct list_head notifier_list;
99 u32 status; /* Device boot stage */
100};
101
102struct t7xx_fsm_event {
103 struct list_head entry;
104 enum t7xx_fsm_event_state event_id;
105 unsigned int length;
106 unsigned char data[] __counted_by(length);
107};
108
109struct t7xx_fsm_command {
110 struct list_head entry;
111 enum t7xx_fsm_cmd_state cmd_id;
112 unsigned int flag;
113 struct completion *done;
114 int *ret;
115};
116
117struct t7xx_fsm_notifier {
118 struct list_head entry;
119 int (*notifier_fn)(enum md_state state, void *data);
120 void *data;
121};
122
123int t7xx_fsm_append_cmd(struct t7xx_fsm_ctl *ctl, enum t7xx_fsm_cmd_state cmd_id,
124 unsigned int flag);
125int t7xx_fsm_append_event(struct t7xx_fsm_ctl *ctl, enum t7xx_fsm_event_state event_id,
126 unsigned char *data, unsigned int length);
127void t7xx_fsm_clr_event(struct t7xx_fsm_ctl *ctl, enum t7xx_fsm_event_state event_id);
128void t7xx_fsm_broadcast_state(struct t7xx_fsm_ctl *ctl, enum md_state state);
129void t7xx_fsm_reset(struct t7xx_modem *md);
130int t7xx_fsm_init(struct t7xx_modem *md);
131void t7xx_fsm_uninit(struct t7xx_modem *md);
132int t7xx_fsm_recv_md_intr(struct t7xx_fsm_ctl *ctl, enum t7xx_md_irq_type type);
133enum md_state t7xx_fsm_get_md_state(struct t7xx_fsm_ctl *ctl);
134unsigned int t7xx_fsm_get_ctl_state(struct t7xx_fsm_ctl *ctl);
135void t7xx_fsm_notifier_register(struct t7xx_modem *md, struct t7xx_fsm_notifier *notifier);
136void t7xx_fsm_notifier_unregister(struct t7xx_modem *md, struct t7xx_fsm_notifier *notifier);
137
138#endif /* __T7XX_MONITOR_H__ */
139

source code of linux/drivers/net/wwan/t7xx/t7xx_state_monitor.h