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 rssi_thresh; 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 void ath9k_deinit_wmi(struct ath9k_htc_priv *priv); 183 int ath9k_wmi_connect(struct htc_target *htc, struct wmi *wmi, 184 enum htc_endpoint_id *wmi_ctrl_epid); 185 int ath9k_wmi_cmd(struct wmi *wmi, enum wmi_cmd_id cmd_id, 186 u8 *cmd_buf, u32 cmd_len, 187 u8 *rsp_buf, u32 rsp_len, 188 u32 timeout); 189 void ath9k_wmi_event_tasklet(unsigned long data); 190 void ath9k_fatal_work(struct work_struct *work); 191 void ath9k_wmi_event_drain(struct ath9k_htc_priv *priv); 192 193 #define WMI_CMD(_wmi_cmd) \ 194 do { \ 195 ret = ath9k_wmi_cmd(priv->wmi, _wmi_cmd, NULL, 0, \ 196 (u8 *) &cmd_rsp, \ 197 sizeof(cmd_rsp), HZ*2); \ 198 } while (0) 199 200 #define WMI_CMD_BUF(_wmi_cmd, _buf) \ 201 do { \ 202 ret = ath9k_wmi_cmd(priv->wmi, _wmi_cmd, \ 203 (u8 *) _buf, sizeof(*_buf), \ 204 &cmd_rsp, sizeof(cmd_rsp), HZ*2); \ 205 } while (0) 206 207 #endif /* WMI_H */ 208