Back to home page

OSCL-LXR

 
 

    


0001 /*
0002  * Copyright (c) 2010-2011 Atheros Communications Inc.
0003  *
0004  * Permission to use, copy, modify, and/or distribute this software for any
0005  * purpose with or without fee is hereby granted, provided that the above
0006  * copyright notice and this permission notice appear in all copies.
0007  *
0008  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
0009  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
0010  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
0011  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
0012  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
0013  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
0014  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
0015  */
0016 
0017 #ifndef WMI_H
0018 #define WMI_H
0019 
0020 struct wmi_event_txrate {
0021     __be32 txrate;
0022     struct {
0023         u8 rssi_thresh;
0024         u8 per;
0025     } rc_stats;
0026 } __packed;
0027 
0028 struct wmi_cmd_hdr {
0029     __be16 command_id;
0030     __be16 seq_no;
0031 } __packed;
0032 
0033 struct wmi_fw_version {
0034     __be16 major;
0035     __be16 minor;
0036 
0037 } __packed;
0038 
0039 struct wmi_event_swba {
0040     __be64 tsf;
0041     u8 beacon_pending;
0042 } __packed;
0043 
0044 /*
0045  * 64 - HTC header - WMI header - 1 / txstatus
0046  * And some other hdr. space is also accounted for.
0047  * 12 seems to be the magic number.
0048  */
0049 #define HTC_MAX_TX_STATUS 12
0050 
0051 #define ATH9K_HTC_TXSTAT_ACK        BIT(0)
0052 #define ATH9K_HTC_TXSTAT_FILT       BIT(1)
0053 #define ATH9K_HTC_TXSTAT_RTC_CTS    BIT(2)
0054 #define ATH9K_HTC_TXSTAT_MCS        BIT(3)
0055 #define ATH9K_HTC_TXSTAT_CW40       BIT(4)
0056 #define ATH9K_HTC_TXSTAT_SGI        BIT(5)
0057 
0058 /*
0059  * Legacy rates are indicated as indices.
0060  * HT rates are indicated as dot11 numbers.
0061  * This allows us to resrict the rate field
0062  * to 4 bits.
0063  */
0064 #define ATH9K_HTC_TXSTAT_RATE       0x0f
0065 #define ATH9K_HTC_TXSTAT_RATE_S     0
0066 
0067 #define ATH9K_HTC_TXSTAT_EPID       0xf0
0068 #define ATH9K_HTC_TXSTAT_EPID_S     4
0069 
0070 struct __wmi_event_txstatus {
0071     u8 cookie;
0072     u8 ts_rate; /* Also holds EP ID */
0073     u8 ts_flags;
0074 };
0075 
0076 struct wmi_event_txstatus {
0077     u8 cnt;
0078     struct __wmi_event_txstatus txstatus[HTC_MAX_TX_STATUS];
0079 } __packed;
0080 
0081 enum wmi_cmd_id {
0082     WMI_ECHO_CMDID = 0x0001,
0083     WMI_ACCESS_MEMORY_CMDID,
0084 
0085     /* Commands to Target */
0086     WMI_GET_FW_VERSION,
0087     WMI_DISABLE_INTR_CMDID,
0088     WMI_ENABLE_INTR_CMDID,
0089     WMI_ATH_INIT_CMDID,
0090     WMI_ABORT_TXQ_CMDID,
0091     WMI_STOP_TX_DMA_CMDID,
0092     WMI_ABORT_TX_DMA_CMDID,
0093     WMI_DRAIN_TXQ_CMDID,
0094     WMI_DRAIN_TXQ_ALL_CMDID,
0095     WMI_START_RECV_CMDID,
0096     WMI_STOP_RECV_CMDID,
0097     WMI_FLUSH_RECV_CMDID,
0098     WMI_SET_MODE_CMDID,
0099     WMI_NODE_CREATE_CMDID,
0100     WMI_NODE_REMOVE_CMDID,
0101     WMI_VAP_REMOVE_CMDID,
0102     WMI_VAP_CREATE_CMDID,
0103     WMI_REG_READ_CMDID,
0104     WMI_REG_WRITE_CMDID,
0105     WMI_RC_STATE_CHANGE_CMDID,
0106     WMI_RC_RATE_UPDATE_CMDID,
0107     WMI_TARGET_IC_UPDATE_CMDID,
0108     WMI_TX_AGGR_ENABLE_CMDID,
0109     WMI_TGT_DETACH_CMDID,
0110     WMI_NODE_UPDATE_CMDID,
0111     WMI_INT_STATS_CMDID,
0112     WMI_TX_STATS_CMDID,
0113     WMI_RX_STATS_CMDID,
0114     WMI_BITRATE_MASK_CMDID,
0115     WMI_REG_RMW_CMDID,
0116 };
0117 
0118 enum wmi_event_id {
0119     WMI_TGT_RDY_EVENTID = 0x1001,
0120     WMI_SWBA_EVENTID,
0121     WMI_FATAL_EVENTID,
0122     WMI_TXTO_EVENTID,
0123     WMI_BMISS_EVENTID,
0124     WMI_DELBA_EVENTID,
0125     WMI_TXSTATUS_EVENTID,
0126 };
0127 
0128 #define MAX_CMD_NUMBER 62
0129 #define MAX_RMW_CMD_NUMBER 15
0130 
0131 struct register_write {
0132     __be32 reg;
0133     __be32 val;
0134 };
0135 
0136 struct register_rmw {
0137     __be32 reg;
0138     __be32 set;
0139     __be32 clr;
0140 } __packed;
0141 
0142 struct ath9k_htc_tx_event {
0143     int count;
0144     struct __wmi_event_txstatus txs;
0145     struct list_head list;
0146 };
0147 
0148 struct wmi {
0149     struct ath9k_htc_priv *drv_priv;
0150     struct htc_target *htc;
0151     enum htc_endpoint_id ctrl_epid;
0152     struct mutex op_mutex;
0153     struct completion cmd_wait;
0154     u16 last_seq_id;
0155     struct sk_buff_head wmi_event_queue;
0156     struct tasklet_struct wmi_event_tasklet;
0157     u16 tx_seq_id;
0158     u8 *cmd_rsp_buf;
0159     u32 cmd_rsp_len;
0160     bool stopped;
0161 
0162     struct list_head pending_tx_events;
0163     spinlock_t event_lock;
0164 
0165     spinlock_t wmi_lock;
0166 
0167     /* multi write section */
0168     atomic_t mwrite_cnt;
0169     struct register_write multi_write[MAX_CMD_NUMBER];
0170     u32 multi_write_idx;
0171     struct mutex multi_write_mutex;
0172 
0173     /* multi rmw section */
0174     atomic_t m_rmw_cnt;
0175     struct register_rmw multi_rmw[MAX_RMW_CMD_NUMBER];
0176     u32 multi_rmw_idx;
0177     struct mutex multi_rmw_mutex;
0178 
0179 };
0180 
0181 struct wmi *ath9k_init_wmi(struct ath9k_htc_priv *priv);
0182 int ath9k_wmi_connect(struct htc_target *htc, struct wmi *wmi,
0183               enum htc_endpoint_id *wmi_ctrl_epid);
0184 int ath9k_wmi_cmd(struct wmi *wmi, enum wmi_cmd_id cmd_id,
0185           u8 *cmd_buf, u32 cmd_len,
0186           u8 *rsp_buf, u32 rsp_len,
0187           u32 timeout);
0188 void ath9k_wmi_event_tasklet(struct tasklet_struct *t);
0189 void ath9k_fatal_work(struct work_struct *work);
0190 void ath9k_wmi_event_drain(struct ath9k_htc_priv *priv);
0191 void ath9k_stop_wmi(struct ath9k_htc_priv *priv);
0192 void ath9k_destroy_wmi(struct ath9k_htc_priv *priv);
0193 
0194 #define WMI_CMD(_wmi_cmd)                       \
0195     do {                                \
0196         ret = ath9k_wmi_cmd(priv->wmi, _wmi_cmd, NULL, 0,   \
0197                     (u8 *) &cmd_rsp,            \
0198                     sizeof(cmd_rsp), HZ*2);     \
0199     } while (0)
0200 
0201 #define WMI_CMD_BUF(_wmi_cmd, _buf)                 \
0202     do {                                \
0203         ret = ath9k_wmi_cmd(priv->wmi, _wmi_cmd,        \
0204                     (u8 *) _buf, sizeof(*_buf),     \
0205                     &cmd_rsp, sizeof(cmd_rsp), HZ*2);   \
0206     } while (0)
0207 
0208 #endif /* WMI_H */