1 /*
2  * Copyright (c) 2010 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 
21 struct wmi_event_txrate {
22 	__be32 txrate;
23 	struct {
24 		u8 rssi_thresh;
25 		u8 per;
26 	} rc_stats;
27 } __packed;
28 
29 struct wmi_cmd_hdr {
30 	__be16 command_id;
31 	__be16 seq_no;
32 } __packed;
33 
34 enum wmi_cmd_id {
35 	WMI_ECHO_CMDID = 0x0001,
36 	WMI_ACCESS_MEMORY_CMDID,
37 
38 	/* Commands to Target */
39 	WMI_DISABLE_INTR_CMDID,
40 	WMI_ENABLE_INTR_CMDID,
41 	WMI_RX_LINK_CMDID,
42 	WMI_ATH_INIT_CMDID,
43 	WMI_ABORT_TXQ_CMDID,
44 	WMI_STOP_TX_DMA_CMDID,
45 	WMI_STOP_DMA_RECV_CMDID,
46 	WMI_ABORT_TX_DMA_CMDID,
47 	WMI_DRAIN_TXQ_CMDID,
48 	WMI_DRAIN_TXQ_ALL_CMDID,
49 	WMI_START_RECV_CMDID,
50 	WMI_STOP_RECV_CMDID,
51 	WMI_FLUSH_RECV_CMDID,
52 	WMI_SET_MODE_CMDID,
53 	WMI_RESET_CMDID,
54 	WMI_NODE_CREATE_CMDID,
55 	WMI_NODE_REMOVE_CMDID,
56 	WMI_VAP_REMOVE_CMDID,
57 	WMI_VAP_CREATE_CMDID,
58 	WMI_BEACON_UPDATE_CMDID,
59 	WMI_REG_READ_CMDID,
60 	WMI_REG_WRITE_CMDID,
61 	WMI_RC_STATE_CHANGE_CMDID,
62 	WMI_RC_RATE_UPDATE_CMDID,
63 	WMI_DEBUG_INFO_CMDID,
64 	WMI_HOST_ATTACH,
65 	WMI_TARGET_IC_UPDATE_CMDID,
66 	WMI_TGT_STATS_CMDID,
67 	WMI_TX_AGGR_ENABLE_CMDID,
68 	WMI_TGT_DETACH_CMDID,
69 	WMI_TGT_TXQ_ENABLE_CMDID,
70 	WMI_AGGR_LIMIT_CMD = 0x0026,
71 };
72 
73 enum wmi_event_id {
74 	WMI_TGT_RDY_EVENTID = 0x1001,
75 	WMI_SWBA_EVENTID,
76 	WMI_FATAL_EVENTID,
77 	WMI_TXTO_EVENTID,
78 	WMI_BMISS_EVENTID,
79 	WMI_WLAN_TXCOMP_EVENTID,
80 	WMI_DELBA_EVENTID,
81 	WMI_TXRATE_EVENTID,
82 };
83 
84 #define MAX_CMD_NUMBER 62
85 
86 struct register_write {
87 	__be32 reg;
88 	__be32 val;
89 };
90 
91 struct wmi {
92 	struct ath9k_htc_priv *drv_priv;
93 	struct htc_target *htc;
94 	enum htc_endpoint_id ctrl_epid;
95 	struct mutex op_mutex;
96 	struct completion cmd_wait;
97 	enum wmi_cmd_id last_cmd_id;
98 	u16 tx_seq_id;
99 	u8 *cmd_rsp_buf;
100 	u32 cmd_rsp_len;
101 	bool stopped;
102 
103 	u8 beacon_pending;
104 	spinlock_t wmi_lock;
105 
106 	atomic_t mwrite_cnt;
107 	struct register_write multi_write[MAX_CMD_NUMBER];
108 	u32 multi_write_idx;
109 	struct mutex multi_write_mutex;
110 };
111 
112 struct wmi *ath9k_init_wmi(struct ath9k_htc_priv *priv);
113 void ath9k_deinit_wmi(struct ath9k_htc_priv *priv);
114 int ath9k_wmi_connect(struct htc_target *htc, struct wmi *wmi,
115 		      enum htc_endpoint_id *wmi_ctrl_epid);
116 int ath9k_wmi_cmd(struct wmi *wmi, enum wmi_cmd_id cmd_id,
117 		  u8 *cmd_buf, u32 cmd_len,
118 		  u8 *rsp_buf, u32 rsp_len,
119 		  u32 timeout);
120 void ath9k_swba_tasklet(unsigned long data);
121 void ath9k_fatal_work(struct work_struct *work);
122 
123 #define WMI_CMD(_wmi_cmd)						\
124 	do {								\
125 		ret = ath9k_wmi_cmd(priv->wmi, _wmi_cmd, NULL, 0,	\
126 				    (u8 *) &cmd_rsp,			\
127 				    sizeof(cmd_rsp), HZ*2);		\
128 	} while (0)
129 
130 #define WMI_CMD_BUF(_wmi_cmd, _buf)					\
131 	do {								\
132 		ret = ath9k_wmi_cmd(priv->wmi, _wmi_cmd,		\
133 				    (u8 *) _buf, sizeof(*_buf),		\
134 				    &cmd_rsp, sizeof(cmd_rsp), HZ*2);	\
135 	} while (0)
136 
137 #endif /* WMI_H */
138