xref: /OK3568_Linux_fs/kernel/drivers/net/wireless/ath/ath9k/wmi.h (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun /*
2*4882a593Smuzhiyun  * Copyright (c) 2010-2011 Atheros Communications Inc.
3*4882a593Smuzhiyun  *
4*4882a593Smuzhiyun  * Permission to use, copy, modify, and/or distribute this software for any
5*4882a593Smuzhiyun  * purpose with or without fee is hereby granted, provided that the above
6*4882a593Smuzhiyun  * copyright notice and this permission notice appear in all copies.
7*4882a593Smuzhiyun  *
8*4882a593Smuzhiyun  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9*4882a593Smuzhiyun  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10*4882a593Smuzhiyun  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11*4882a593Smuzhiyun  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12*4882a593Smuzhiyun  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13*4882a593Smuzhiyun  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14*4882a593Smuzhiyun  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15*4882a593Smuzhiyun  */
16*4882a593Smuzhiyun 
17*4882a593Smuzhiyun #ifndef WMI_H
18*4882a593Smuzhiyun #define WMI_H
19*4882a593Smuzhiyun 
20*4882a593Smuzhiyun struct wmi_event_txrate {
21*4882a593Smuzhiyun 	__be32 txrate;
22*4882a593Smuzhiyun 	struct {
23*4882a593Smuzhiyun 		u8 rssi_thresh;
24*4882a593Smuzhiyun 		u8 per;
25*4882a593Smuzhiyun 	} rc_stats;
26*4882a593Smuzhiyun } __packed;
27*4882a593Smuzhiyun 
28*4882a593Smuzhiyun struct wmi_cmd_hdr {
29*4882a593Smuzhiyun 	__be16 command_id;
30*4882a593Smuzhiyun 	__be16 seq_no;
31*4882a593Smuzhiyun } __packed;
32*4882a593Smuzhiyun 
33*4882a593Smuzhiyun struct wmi_fw_version {
34*4882a593Smuzhiyun 	__be16 major;
35*4882a593Smuzhiyun 	__be16 minor;
36*4882a593Smuzhiyun 
37*4882a593Smuzhiyun } __packed;
38*4882a593Smuzhiyun 
39*4882a593Smuzhiyun struct wmi_event_swba {
40*4882a593Smuzhiyun 	__be64 tsf;
41*4882a593Smuzhiyun 	u8 beacon_pending;
42*4882a593Smuzhiyun } __packed;
43*4882a593Smuzhiyun 
44*4882a593Smuzhiyun /*
45*4882a593Smuzhiyun  * 64 - HTC header - WMI header - 1 / txstatus
46*4882a593Smuzhiyun  * And some other hdr. space is also accounted for.
47*4882a593Smuzhiyun  * 12 seems to be the magic number.
48*4882a593Smuzhiyun  */
49*4882a593Smuzhiyun #define HTC_MAX_TX_STATUS 12
50*4882a593Smuzhiyun 
51*4882a593Smuzhiyun #define ATH9K_HTC_TXSTAT_ACK        BIT(0)
52*4882a593Smuzhiyun #define ATH9K_HTC_TXSTAT_FILT       BIT(1)
53*4882a593Smuzhiyun #define ATH9K_HTC_TXSTAT_RTC_CTS    BIT(2)
54*4882a593Smuzhiyun #define ATH9K_HTC_TXSTAT_MCS        BIT(3)
55*4882a593Smuzhiyun #define ATH9K_HTC_TXSTAT_CW40       BIT(4)
56*4882a593Smuzhiyun #define ATH9K_HTC_TXSTAT_SGI        BIT(5)
57*4882a593Smuzhiyun 
58*4882a593Smuzhiyun /*
59*4882a593Smuzhiyun  * Legacy rates are indicated as indices.
60*4882a593Smuzhiyun  * HT rates are indicated as dot11 numbers.
61*4882a593Smuzhiyun  * This allows us to resrict the rate field
62*4882a593Smuzhiyun  * to 4 bits.
63*4882a593Smuzhiyun  */
64*4882a593Smuzhiyun #define ATH9K_HTC_TXSTAT_RATE       0x0f
65*4882a593Smuzhiyun #define ATH9K_HTC_TXSTAT_RATE_S     0
66*4882a593Smuzhiyun 
67*4882a593Smuzhiyun #define ATH9K_HTC_TXSTAT_EPID       0xf0
68*4882a593Smuzhiyun #define ATH9K_HTC_TXSTAT_EPID_S     4
69*4882a593Smuzhiyun 
70*4882a593Smuzhiyun struct __wmi_event_txstatus {
71*4882a593Smuzhiyun 	u8 cookie;
72*4882a593Smuzhiyun 	u8 ts_rate; /* Also holds EP ID */
73*4882a593Smuzhiyun 	u8 ts_flags;
74*4882a593Smuzhiyun };
75*4882a593Smuzhiyun 
76*4882a593Smuzhiyun struct wmi_event_txstatus {
77*4882a593Smuzhiyun 	u8 cnt;
78*4882a593Smuzhiyun 	struct __wmi_event_txstatus txstatus[HTC_MAX_TX_STATUS];
79*4882a593Smuzhiyun } __packed;
80*4882a593Smuzhiyun 
81*4882a593Smuzhiyun enum wmi_cmd_id {
82*4882a593Smuzhiyun 	WMI_ECHO_CMDID = 0x0001,
83*4882a593Smuzhiyun 	WMI_ACCESS_MEMORY_CMDID,
84*4882a593Smuzhiyun 
85*4882a593Smuzhiyun 	/* Commands to Target */
86*4882a593Smuzhiyun 	WMI_GET_FW_VERSION,
87*4882a593Smuzhiyun 	WMI_DISABLE_INTR_CMDID,
88*4882a593Smuzhiyun 	WMI_ENABLE_INTR_CMDID,
89*4882a593Smuzhiyun 	WMI_ATH_INIT_CMDID,
90*4882a593Smuzhiyun 	WMI_ABORT_TXQ_CMDID,
91*4882a593Smuzhiyun 	WMI_STOP_TX_DMA_CMDID,
92*4882a593Smuzhiyun 	WMI_ABORT_TX_DMA_CMDID,
93*4882a593Smuzhiyun 	WMI_DRAIN_TXQ_CMDID,
94*4882a593Smuzhiyun 	WMI_DRAIN_TXQ_ALL_CMDID,
95*4882a593Smuzhiyun 	WMI_START_RECV_CMDID,
96*4882a593Smuzhiyun 	WMI_STOP_RECV_CMDID,
97*4882a593Smuzhiyun 	WMI_FLUSH_RECV_CMDID,
98*4882a593Smuzhiyun 	WMI_SET_MODE_CMDID,
99*4882a593Smuzhiyun 	WMI_NODE_CREATE_CMDID,
100*4882a593Smuzhiyun 	WMI_NODE_REMOVE_CMDID,
101*4882a593Smuzhiyun 	WMI_VAP_REMOVE_CMDID,
102*4882a593Smuzhiyun 	WMI_VAP_CREATE_CMDID,
103*4882a593Smuzhiyun 	WMI_REG_READ_CMDID,
104*4882a593Smuzhiyun 	WMI_REG_WRITE_CMDID,
105*4882a593Smuzhiyun 	WMI_RC_STATE_CHANGE_CMDID,
106*4882a593Smuzhiyun 	WMI_RC_RATE_UPDATE_CMDID,
107*4882a593Smuzhiyun 	WMI_TARGET_IC_UPDATE_CMDID,
108*4882a593Smuzhiyun 	WMI_TX_AGGR_ENABLE_CMDID,
109*4882a593Smuzhiyun 	WMI_TGT_DETACH_CMDID,
110*4882a593Smuzhiyun 	WMI_NODE_UPDATE_CMDID,
111*4882a593Smuzhiyun 	WMI_INT_STATS_CMDID,
112*4882a593Smuzhiyun 	WMI_TX_STATS_CMDID,
113*4882a593Smuzhiyun 	WMI_RX_STATS_CMDID,
114*4882a593Smuzhiyun 	WMI_BITRATE_MASK_CMDID,
115*4882a593Smuzhiyun 	WMI_REG_RMW_CMDID,
116*4882a593Smuzhiyun };
117*4882a593Smuzhiyun 
118*4882a593Smuzhiyun enum wmi_event_id {
119*4882a593Smuzhiyun 	WMI_TGT_RDY_EVENTID = 0x1001,
120*4882a593Smuzhiyun 	WMI_SWBA_EVENTID,
121*4882a593Smuzhiyun 	WMI_FATAL_EVENTID,
122*4882a593Smuzhiyun 	WMI_TXTO_EVENTID,
123*4882a593Smuzhiyun 	WMI_BMISS_EVENTID,
124*4882a593Smuzhiyun 	WMI_DELBA_EVENTID,
125*4882a593Smuzhiyun 	WMI_TXSTATUS_EVENTID,
126*4882a593Smuzhiyun };
127*4882a593Smuzhiyun 
128*4882a593Smuzhiyun #define MAX_CMD_NUMBER 62
129*4882a593Smuzhiyun #define MAX_RMW_CMD_NUMBER 15
130*4882a593Smuzhiyun 
131*4882a593Smuzhiyun struct register_write {
132*4882a593Smuzhiyun 	__be32 reg;
133*4882a593Smuzhiyun 	__be32 val;
134*4882a593Smuzhiyun };
135*4882a593Smuzhiyun 
136*4882a593Smuzhiyun struct register_rmw {
137*4882a593Smuzhiyun 	__be32 reg;
138*4882a593Smuzhiyun 	__be32 set;
139*4882a593Smuzhiyun 	__be32 clr;
140*4882a593Smuzhiyun } __packed;
141*4882a593Smuzhiyun 
142*4882a593Smuzhiyun struct ath9k_htc_tx_event {
143*4882a593Smuzhiyun 	int count;
144*4882a593Smuzhiyun 	struct __wmi_event_txstatus txs;
145*4882a593Smuzhiyun 	struct list_head list;
146*4882a593Smuzhiyun };
147*4882a593Smuzhiyun 
148*4882a593Smuzhiyun struct wmi {
149*4882a593Smuzhiyun 	struct ath9k_htc_priv *drv_priv;
150*4882a593Smuzhiyun 	struct htc_target *htc;
151*4882a593Smuzhiyun 	enum htc_endpoint_id ctrl_epid;
152*4882a593Smuzhiyun 	struct mutex op_mutex;
153*4882a593Smuzhiyun 	struct completion cmd_wait;
154*4882a593Smuzhiyun 	u16 last_seq_id;
155*4882a593Smuzhiyun 	struct sk_buff_head wmi_event_queue;
156*4882a593Smuzhiyun 	struct tasklet_struct wmi_event_tasklet;
157*4882a593Smuzhiyun 	u16 tx_seq_id;
158*4882a593Smuzhiyun 	u8 *cmd_rsp_buf;
159*4882a593Smuzhiyun 	u32 cmd_rsp_len;
160*4882a593Smuzhiyun 	bool stopped;
161*4882a593Smuzhiyun 
162*4882a593Smuzhiyun 	struct list_head pending_tx_events;
163*4882a593Smuzhiyun 	spinlock_t event_lock;
164*4882a593Smuzhiyun 
165*4882a593Smuzhiyun 	spinlock_t wmi_lock;
166*4882a593Smuzhiyun 
167*4882a593Smuzhiyun 	/* multi write section */
168*4882a593Smuzhiyun 	atomic_t mwrite_cnt;
169*4882a593Smuzhiyun 	struct register_write multi_write[MAX_CMD_NUMBER];
170*4882a593Smuzhiyun 	u32 multi_write_idx;
171*4882a593Smuzhiyun 	struct mutex multi_write_mutex;
172*4882a593Smuzhiyun 
173*4882a593Smuzhiyun 	/* multi rmw section */
174*4882a593Smuzhiyun 	atomic_t m_rmw_cnt;
175*4882a593Smuzhiyun 	struct register_rmw multi_rmw[MAX_RMW_CMD_NUMBER];
176*4882a593Smuzhiyun 	u32 multi_rmw_idx;
177*4882a593Smuzhiyun 	struct mutex multi_rmw_mutex;
178*4882a593Smuzhiyun 
179*4882a593Smuzhiyun };
180*4882a593Smuzhiyun 
181*4882a593Smuzhiyun struct wmi *ath9k_init_wmi(struct ath9k_htc_priv *priv);
182*4882a593Smuzhiyun int ath9k_wmi_connect(struct htc_target *htc, struct wmi *wmi,
183*4882a593Smuzhiyun 		      enum htc_endpoint_id *wmi_ctrl_epid);
184*4882a593Smuzhiyun int ath9k_wmi_cmd(struct wmi *wmi, enum wmi_cmd_id cmd_id,
185*4882a593Smuzhiyun 		  u8 *cmd_buf, u32 cmd_len,
186*4882a593Smuzhiyun 		  u8 *rsp_buf, u32 rsp_len,
187*4882a593Smuzhiyun 		  u32 timeout);
188*4882a593Smuzhiyun void ath9k_wmi_event_tasklet(struct tasklet_struct *t);
189*4882a593Smuzhiyun void ath9k_fatal_work(struct work_struct *work);
190*4882a593Smuzhiyun void ath9k_wmi_event_drain(struct ath9k_htc_priv *priv);
191*4882a593Smuzhiyun void ath9k_stop_wmi(struct ath9k_htc_priv *priv);
192*4882a593Smuzhiyun void ath9k_destroy_wmi(struct ath9k_htc_priv *priv);
193*4882a593Smuzhiyun 
194*4882a593Smuzhiyun #define WMI_CMD(_wmi_cmd)						\
195*4882a593Smuzhiyun 	do {								\
196*4882a593Smuzhiyun 		ret = ath9k_wmi_cmd(priv->wmi, _wmi_cmd, NULL, 0,	\
197*4882a593Smuzhiyun 				    (u8 *) &cmd_rsp,			\
198*4882a593Smuzhiyun 				    sizeof(cmd_rsp), HZ*2);		\
199*4882a593Smuzhiyun 	} while (0)
200*4882a593Smuzhiyun 
201*4882a593Smuzhiyun #define WMI_CMD_BUF(_wmi_cmd, _buf)					\
202*4882a593Smuzhiyun 	do {								\
203*4882a593Smuzhiyun 		ret = ath9k_wmi_cmd(priv->wmi, _wmi_cmd,		\
204*4882a593Smuzhiyun 				    (u8 *) _buf, sizeof(*_buf),		\
205*4882a593Smuzhiyun 				    &cmd_rsp, sizeof(cmd_rsp), HZ*2);	\
206*4882a593Smuzhiyun 	} while (0)
207*4882a593Smuzhiyun 
208*4882a593Smuzhiyun #endif /* WMI_H */
209