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 }; 116 117 enum wmi_event_id { 118 WMI_TGT_RDY_EVENTID = 0x1001, 119 WMI_SWBA_EVENTID, 120 WMI_FATAL_EVENTID, 121 WMI_TXTO_EVENTID, 122 WMI_BMISS_EVENTID, 123 WMI_DELBA_EVENTID, 124 WMI_TXSTATUS_EVENTID, 125 }; 126 127 #define MAX_CMD_NUMBER 62 128 129 struct register_write { 130 __be32 reg; 131 __be32 val; 132 }; 133 134 struct ath9k_htc_tx_event { 135 int count; 136 struct __wmi_event_txstatus txs; 137 struct list_head list; 138 }; 139 140 struct wmi { 141 struct ath9k_htc_priv *drv_priv; 142 struct htc_target *htc; 143 enum htc_endpoint_id ctrl_epid; 144 struct mutex op_mutex; 145 struct completion cmd_wait; 146 enum wmi_cmd_id last_cmd_id; 147 struct sk_buff_head wmi_event_queue; 148 struct tasklet_struct wmi_event_tasklet; 149 u16 tx_seq_id; 150 u8 *cmd_rsp_buf; 151 u32 cmd_rsp_len; 152 bool stopped; 153 154 struct list_head pending_tx_events; 155 spinlock_t event_lock; 156 157 spinlock_t wmi_lock; 158 159 atomic_t mwrite_cnt; 160 struct register_write multi_write[MAX_CMD_NUMBER]; 161 u32 multi_write_idx; 162 struct mutex multi_write_mutex; 163 }; 164 165 struct wmi *ath9k_init_wmi(struct ath9k_htc_priv *priv); 166 void ath9k_deinit_wmi(struct ath9k_htc_priv *priv); 167 int ath9k_wmi_connect(struct htc_target *htc, struct wmi *wmi, 168 enum htc_endpoint_id *wmi_ctrl_epid); 169 int ath9k_wmi_cmd(struct wmi *wmi, enum wmi_cmd_id cmd_id, 170 u8 *cmd_buf, u32 cmd_len, 171 u8 *rsp_buf, u32 rsp_len, 172 u32 timeout); 173 void ath9k_wmi_event_tasklet(unsigned long data); 174 void ath9k_fatal_work(struct work_struct *work); 175 void ath9k_wmi_event_drain(struct ath9k_htc_priv *priv); 176 177 #define WMI_CMD(_wmi_cmd) \ 178 do { \ 179 ret = ath9k_wmi_cmd(priv->wmi, _wmi_cmd, NULL, 0, \ 180 (u8 *) &cmd_rsp, \ 181 sizeof(cmd_rsp), HZ*2); \ 182 } while (0) 183 184 #define WMI_CMD_BUF(_wmi_cmd, _buf) \ 185 do { \ 186 ret = ath9k_wmi_cmd(priv->wmi, _wmi_cmd, \ 187 (u8 *) _buf, sizeof(*_buf), \ 188 &cmd_rsp, sizeof(cmd_rsp), HZ*2); \ 189 } while (0) 190 191 #endif /* WMI_H */ 192