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