xref: /linux/drivers/net/wireless/ath/ath9k/htc_hst.h (revision e5451c8f8330e03ad3cfa16048b4daf961af434f)
1fb9987d0SSujith /*
25b68138eSSujith Manoharan  * Copyright (c) 2010-2011 Atheros Communications Inc.
3fb9987d0SSujith  *
4fb9987d0SSujith  * Permission to use, copy, modify, and/or distribute this software for any
5fb9987d0SSujith  * purpose with or without fee is hereby granted, provided that the above
6fb9987d0SSujith  * copyright notice and this permission notice appear in all copies.
7fb9987d0SSujith  *
8fb9987d0SSujith  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9fb9987d0SSujith  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10fb9987d0SSujith  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11fb9987d0SSujith  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12fb9987d0SSujith  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13fb9987d0SSujith  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14fb9987d0SSujith  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15fb9987d0SSujith  */
16fb9987d0SSujith 
17fb9987d0SSujith #ifndef HTC_HST_H
18fb9987d0SSujith #define HTC_HST_H
19fb9987d0SSujith 
20fb9987d0SSujith struct ath9k_htc_priv;
21fb9987d0SSujith struct htc_target;
22fb9987d0SSujith struct ath9k_htc_tx_ctl;
23fb9987d0SSujith 
24fb9987d0SSujith enum ath9k_hif_transports {
25fb9987d0SSujith 	ATH9K_HIF_USB,
26fb9987d0SSujith };
27fb9987d0SSujith 
28fb9987d0SSujith struct ath9k_htc_hif {
29fb9987d0SSujith 	struct list_head list;
30fb9987d0SSujith 	const enum ath9k_hif_transports transport;
31fb9987d0SSujith 	const char *name;
32fb9987d0SSujith 
33fb9987d0SSujith 	u8 control_dl_pipe;
34fb9987d0SSujith 	u8 control_ul_pipe;
35fb9987d0SSujith 
36e1fe7c38SSujith Manoharan 	void (*start) (void *hif_handle);
37e1fe7c38SSujith Manoharan 	void (*stop) (void *hif_handle);
3884c9e164SSujith Manoharan 	void (*sta_drain) (void *hif_handle, u8 idx);
3940dc9e4bSSujith Manoharan 	int (*send) (void *hif_handle, u8 pipe, struct sk_buff *buf);
40fb9987d0SSujith };
41fb9987d0SSujith 
42fb9987d0SSujith enum htc_endpoint_id {
43fb9987d0SSujith 	ENDPOINT_UNUSED = -1,
44fb9987d0SSujith 	ENDPOINT0 = 0,
45fb9987d0SSujith 	ENDPOINT1 = 1,
46fb9987d0SSujith 	ENDPOINT2 = 2,
47fb9987d0SSujith 	ENDPOINT3 = 3,
48fb9987d0SSujith 	ENDPOINT4 = 4,
49fb9987d0SSujith 	ENDPOINT5 = 5,
50fb9987d0SSujith 	ENDPOINT6 = 6,
51fb9987d0SSujith 	ENDPOINT7 = 7,
52fb9987d0SSujith 	ENDPOINT8 = 8,
53fb9987d0SSujith 	ENDPOINT_MAX = 22
54fb9987d0SSujith };
55fb9987d0SSujith 
56fb9987d0SSujith /* Htc frame hdr flags */
57fb9987d0SSujith #define HTC_FLAGS_RECV_TRAILER (1 << 1)
58fb9987d0SSujith 
59fb9987d0SSujith struct htc_frame_hdr {
60fb9987d0SSujith 	u8 endpoint_id;
61fb9987d0SSujith 	u8 flags;
627f1f5a00SSujith 	__be16 payload_len;
63fb9987d0SSujith 	u8 control[4];
64fb9987d0SSujith } __packed;
65fb9987d0SSujith 
66fb9987d0SSujith struct htc_ready_msg {
677f1f5a00SSujith 	__be16 message_id;
687f1f5a00SSujith 	__be16 credits;
697f1f5a00SSujith 	__be16 credit_size;
70fb9987d0SSujith 	u8 max_endpoints;
71fb9987d0SSujith 	u8 pad;
72fb9987d0SSujith } __packed;
73fb9987d0SSujith 
74fb9987d0SSujith struct htc_config_pipe_msg {
757f1f5a00SSujith 	__be16 message_id;
76fb9987d0SSujith 	u8 pipe_id;
77fb9987d0SSujith 	u8 credits;
78fb9987d0SSujith } __packed;
79fb9987d0SSujith 
80*482b30b6SOleksij Rempel struct htc_panic_bad_vaddr {
81*482b30b6SOleksij Rempel 	__be32 pattern;
82*482b30b6SOleksij Rempel 	__be32 exccause;
83*482b30b6SOleksij Rempel 	__be32 pc;
84*482b30b6SOleksij Rempel 	__be32 badvaddr;
85*482b30b6SOleksij Rempel } __packed;
86*482b30b6SOleksij Rempel 
87*482b30b6SOleksij Rempel struct htc_panic_bad_epid {
88*482b30b6SOleksij Rempel 	__be32 pattern;
89*482b30b6SOleksij Rempel 	__be32 epid;
90*482b30b6SOleksij Rempel } __packed;
91*482b30b6SOleksij Rempel 
92fb9987d0SSujith struct htc_ep_callbacks {
93fb9987d0SSujith 	void *priv;
94fb9987d0SSujith 	void (*tx) (void *, struct sk_buff *, enum htc_endpoint_id, bool txok);
95fb9987d0SSujith 	void (*rx) (void *, struct sk_buff *, enum htc_endpoint_id);
96fb9987d0SSujith };
97fb9987d0SSujith 
98fb9987d0SSujith struct htc_endpoint {
99fb9987d0SSujith 	u16 service_id;
100fb9987d0SSujith 
101fb9987d0SSujith 	struct htc_ep_callbacks ep_callbacks;
102fb9987d0SSujith 	u32 max_txqdepth;
103fb9987d0SSujith 	int max_msglen;
104fb9987d0SSujith 
105fb9987d0SSujith 	u8 ul_pipeid;
106fb9987d0SSujith 	u8 dl_pipeid;
107fb9987d0SSujith };
108fb9987d0SSujith 
109fb9987d0SSujith #define HTC_MAX_CONTROL_MESSAGE_LENGTH 255
110fb9987d0SSujith #define HTC_CONTROL_BUFFER_SIZE	\
111fb9987d0SSujith 	(HTC_MAX_CONTROL_MESSAGE_LENGTH + sizeof(struct htc_frame_hdr))
112fb9987d0SSujith 
113fb9987d0SSujith #define HTC_OP_START_WAIT           BIT(0)
114fb9987d0SSujith #define HTC_OP_CONFIG_PIPE_CREDITS  BIT(1)
115fb9987d0SSujith 
116fb9987d0SSujith struct htc_target {
117fb9987d0SSujith 	void *hif_dev;
118fb9987d0SSujith 	struct ath9k_htc_priv *drv_priv;
119fb9987d0SSujith 	struct device *dev;
120fb9987d0SSujith 	struct ath9k_htc_hif *hif;
1218116daf2SSujith.Manoharan@atheros.com 	struct htc_endpoint endpoint[ENDPOINT_MAX];
122fb9987d0SSujith 	struct completion target_wait;
123fb9987d0SSujith 	struct completion cmd_wait;
124fb9987d0SSujith 	struct list_head list;
125fb9987d0SSujith 	enum htc_endpoint_id conn_rsp_epid;
126fb9987d0SSujith 	u16 credits;
127fb9987d0SSujith 	u16 credit_size;
128fb9987d0SSujith 	u8 htc_flags;
129d8c49ffbSSujith.Manoharan@atheros.com 	atomic_t tgt_ready;
130fb9987d0SSujith };
131fb9987d0SSujith 
132fb9987d0SSujith enum htc_msg_id {
133fb9987d0SSujith 	HTC_MSG_READY_ID = 1,
134fb9987d0SSujith 	HTC_MSG_CONNECT_SERVICE_ID,
135fb9987d0SSujith 	HTC_MSG_CONNECT_SERVICE_RESPONSE_ID,
136fb9987d0SSujith 	HTC_MSG_SETUP_COMPLETE_ID,
137fb9987d0SSujith 	HTC_MSG_CONFIG_PIPE_ID,
138fb9987d0SSujith 	HTC_MSG_CONFIG_PIPE_RESPONSE_ID,
139fb9987d0SSujith };
140fb9987d0SSujith 
141fb9987d0SSujith struct htc_service_connreq {
142fb9987d0SSujith 	u16 service_id;
143fb9987d0SSujith 	u16 con_flags;
144fb9987d0SSujith 	u32 max_send_qdepth;
145fb9987d0SSujith 	struct htc_ep_callbacks ep_callbacks;
146fb9987d0SSujith };
147fb9987d0SSujith 
148fb9987d0SSujith /* Current service IDs */
149fb9987d0SSujith 
150fb9987d0SSujith enum htc_service_group_ids{
151fb9987d0SSujith 	RSVD_SERVICE_GROUP = 0,
152fb9987d0SSujith 	WMI_SERVICE_GROUP = 1,
153fb9987d0SSujith 
154fb9987d0SSujith 	HTC_SERVICE_GROUP_LAST = 255
155fb9987d0SSujith };
156fb9987d0SSujith 
157fb9987d0SSujith #define MAKE_SERVICE_ID(group, index)		\
158fb9987d0SSujith 	(int)(((int)group << 8) | (int)(index))
159fb9987d0SSujith 
160fb9987d0SSujith /* NOTE: service ID of 0x0000 is reserved and should never be used */
161fb9987d0SSujith #define HTC_CTRL_RSVD_SVC MAKE_SERVICE_ID(RSVD_SERVICE_GROUP, 1)
162fb9987d0SSujith #define HTC_LOOPBACK_RSVD_SVC MAKE_SERVICE_ID(RSVD_SERVICE_GROUP, 2)
163fb9987d0SSujith 
164fb9987d0SSujith #define WMI_CONTROL_SVC   MAKE_SERVICE_ID(WMI_SERVICE_GROUP, 0)
165fb9987d0SSujith #define WMI_BEACON_SVC	  MAKE_SERVICE_ID(WMI_SERVICE_GROUP, 1)
166fb9987d0SSujith #define WMI_CAB_SVC	  MAKE_SERVICE_ID(WMI_SERVICE_GROUP, 2)
167fb9987d0SSujith #define WMI_UAPSD_SVC	  MAKE_SERVICE_ID(WMI_SERVICE_GROUP, 3)
168fb9987d0SSujith #define WMI_MGMT_SVC	  MAKE_SERVICE_ID(WMI_SERVICE_GROUP, 4)
169fb9987d0SSujith #define WMI_DATA_VO_SVC   MAKE_SERVICE_ID(WMI_SERVICE_GROUP, 5)
170fb9987d0SSujith #define WMI_DATA_VI_SVC   MAKE_SERVICE_ID(WMI_SERVICE_GROUP, 6)
171fb9987d0SSujith #define WMI_DATA_BE_SVC   MAKE_SERVICE_ID(WMI_SERVICE_GROUP, 7)
172fb9987d0SSujith #define WMI_DATA_BK_SVC   MAKE_SERVICE_ID(WMI_SERVICE_GROUP, 8)
173fb9987d0SSujith 
174fb9987d0SSujith struct htc_conn_svc_msg {
1757f1f5a00SSujith 	__be16 msg_id;
1767f1f5a00SSujith 	__be16 service_id;
1777f1f5a00SSujith 	__be16 con_flags;
178fb9987d0SSujith 	u8 dl_pipeid;
179fb9987d0SSujith 	u8 ul_pipeid;
180fb9987d0SSujith 	u8 svc_meta_len;
181fb9987d0SSujith 	u8 pad;
182fb9987d0SSujith } __packed;
183fb9987d0SSujith 
184fb9987d0SSujith /* connect response status codes */
185fb9987d0SSujith #define HTC_SERVICE_SUCCESS      0
186fb9987d0SSujith #define HTC_SERVICE_NOT_FOUND    1
187fb9987d0SSujith #define HTC_SERVICE_FAILED       2
188fb9987d0SSujith #define HTC_SERVICE_NO_RESOURCES 3
189fb9987d0SSujith #define HTC_SERVICE_NO_MORE_EP   4
190fb9987d0SSujith 
191fb9987d0SSujith struct htc_conn_svc_rspmsg {
1927f1f5a00SSujith 	__be16 msg_id;
1937f1f5a00SSujith 	__be16 service_id;
194fb9987d0SSujith 	u8 status;
195fb9987d0SSujith 	u8 endpoint_id;
1967f1f5a00SSujith 	__be16 max_msg_len;
197fb9987d0SSujith 	u8 svc_meta_len;
198fb9987d0SSujith 	u8 pad;
199fb9987d0SSujith } __packed;
200fb9987d0SSujith 
201fb9987d0SSujith struct htc_comp_msg {
2027f1f5a00SSujith 	__be16 msg_id;
203fb9987d0SSujith } __packed;
204fb9987d0SSujith 
205fb9987d0SSujith int htc_init(struct htc_target *target);
206fb9987d0SSujith int htc_connect_service(struct htc_target *target,
207fb9987d0SSujith 			  struct htc_service_connreq *service_connreq,
208fb9987d0SSujith 			  enum htc_endpoint_id *conn_rsp_eid);
209d67ee533SSujith Manoharan int htc_send(struct htc_target *target, struct sk_buff *skb);
210d67ee533SSujith Manoharan int htc_send_epid(struct htc_target *target, struct sk_buff *skb,
211d67ee533SSujith Manoharan 		  enum htc_endpoint_id epid);
212fb9987d0SSujith void htc_stop(struct htc_target *target);
213fb9987d0SSujith void htc_start(struct htc_target *target);
21484c9e164SSujith Manoharan void htc_sta_drain(struct htc_target *target, u8 idx);
215fb9987d0SSujith 
216fb9987d0SSujith void ath9k_htc_rx_msg(struct htc_target *htc_handle,
217fb9987d0SSujith 		      struct sk_buff *skb, u32 len, u8 pipe_id);
218fb9987d0SSujith void ath9k_htc_txcompletion_cb(struct htc_target *htc_handle,
219fb9987d0SSujith 			       struct sk_buff *skb, bool txok);
220fb9987d0SSujith 
22147fce026SSujith.Manoharan@atheros.com struct htc_target *ath9k_htc_hw_alloc(void *hif_handle,
22247fce026SSujith.Manoharan@atheros.com 				      struct ath9k_htc_hif *hif,
22347fce026SSujith.Manoharan@atheros.com 				      struct device *dev);
224fb9987d0SSujith void ath9k_htc_hw_free(struct htc_target *htc);
22547fce026SSujith.Manoharan@atheros.com int ath9k_htc_hw_init(struct htc_target *target,
226fa6e15e0SRajkumar Manoharan 		      struct device *dev, u16 devid, char *product,
227fa6e15e0SRajkumar Manoharan 		      u32 drv_info);
228fb9987d0SSujith void ath9k_htc_hw_deinit(struct htc_target *target, bool hot_unplug);
229fb9987d0SSujith 
230fb9987d0SSujith #endif /* HTC_HST_H */
231