aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/host/whci/whci-hc.h
diff options
context:
space:
mode:
authorDavid Vrabel <david.vrabel@csr.com>2008-09-17 11:34:28 -0400
committerDavid Vrabel <dv02@dv02pc01.europe.root.pri>2008-09-17 11:54:31 -0400
commit7e6133aa42920ea87ad9791a0fb2b95d1a23b8f9 (patch)
treeaa686de823ea3246b6c5cd2e4ef0e54e3797c3e3 /drivers/usb/host/whci/whci-hc.h
parent870d5395045bfe8e5213525152682c863a10f8d2 (diff)
wusb: WHCI host controller driver
A driver for Wireless USB host controllers that comply with the Wireless Host Controller Interface (HCI) specification as published by Intel. The latest publically available version of the specification (0.95) is supported (except for isochronous transfers). Build fixes by Randy Dunlap <rdunlap@xenotime.net> Signed-off-by: David Vrabel <david.vrabel@csr.com>
Diffstat (limited to 'drivers/usb/host/whci/whci-hc.h')
-rw-r--r--drivers/usb/host/whci/whci-hc.h416
1 files changed, 416 insertions, 0 deletions
diff --git a/drivers/usb/host/whci/whci-hc.h b/drivers/usb/host/whci/whci-hc.h
new file mode 100644
index 000000000000..bff1eb7a35cf
--- /dev/null
+++ b/drivers/usb/host/whci/whci-hc.h
@@ -0,0 +1,416 @@
1/*
2 * Wireless Host Controller (WHC) data structures.
3 *
4 * Copyright (C) 2007 Cambridge Silicon Radio Ltd.
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License version
8 * 2 as published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
18 * 02110-1301, USA.
19 */
20#ifndef _WHCI_WHCI_HC_H
21#define _WHCI_WHCI_HC_H
22
23#include <linux/list.h>
24
25/**
26 * WHCI_PAGE_SIZE - page size use by WHCI
27 *
28 * WHCI assumes that host system uses pages of 4096 octets.
29 */
30#define WHCI_PAGE_SIZE 4096
31
32
33/**
34 * QTD_MAX_TXFER_SIZE - max number of bytes to transfer with a single
35 * qtd.
36 *
37 * This is 2^20 - 1.
38 */
39#define QTD_MAX_XFER_SIZE 1048575
40
41
42/**
43 * struct whc_qtd - Queue Element Transfer Descriptors (qTD)
44 *
45 * This describes the data for a bulk, control or interrupt transfer.
46 *
47 * [WHCI] section 3.2.4
48 */
49struct whc_qtd {
50 __le32 status; /*< remaining transfer len and transfer status */
51 __le32 options;
52 __le64 page_list_ptr; /*< physical pointer to data buffer page list*/
53 __u8 setup[8]; /*< setup data for control transfers */
54} __attribute__((packed));
55
56#define QTD_STS_ACTIVE (1 << 31) /* enable execution of transaction */
57#define QTD_STS_HALTED (1 << 30) /* transfer halted */
58#define QTD_STS_DBE (1 << 29) /* data buffer error */
59#define QTD_STS_BABBLE (1 << 28) /* babble detected */
60#define QTD_STS_RCE (1 << 27) /* retry count exceeded */
61#define QTD_STS_LAST_PKT (1 << 26) /* set Last Packet Flag in WUSB header */
62#define QTD_STS_INACTIVE (1 << 25) /* queue set is marked inactive */
63#define QTD_STS_IALT_VALID (1 << 23) /* iAlt field is valid */
64#define QTD_STS_IALT(i) (QTD_STS_IALT_VALID | ((i) << 20)) /* iAlt field */
65#define QTD_STS_LEN(l) ((l) << 0) /* transfer length */
66#define QTD_STS_TO_LEN(s) ((s) & 0x000fffff)
67
68#define QTD_OPT_IOC (1 << 1) /* page_list_ptr points to buffer directly */
69#define QTD_OPT_SMALL (1 << 0) /* interrupt on complete */
70
71/**
72 * struct whc_itd - Isochronous Queue Element Transfer Descriptors (iTD)
73 *
74 * This describes the data and other parameters for an isochronous
75 * transfer.
76 *
77 * [WHCI] section 3.2.5
78 */
79struct whc_itd {
80 __le16 presentation_time; /*< presentation time for OUT transfers */
81 __u8 num_segments; /*< number of data segments in segment list */
82 __u8 status; /*< command execution status */
83 __le32 options; /*< misc transfer options */
84 __le64 page_list_ptr; /*< physical pointer to data buffer page list */
85 __le64 seg_list_ptr; /*< physical pointer to segment list */
86} __attribute__((packed));
87
88#define ITD_STS_ACTIVE (1 << 7) /* enable execution of transaction */
89#define ITD_STS_DBE (1 << 5) /* data buffer error */
90#define ITD_STS_BABBLE (1 << 4) /* babble detected */
91#define ITD_STS_INACTIVE (1 << 1) /* queue set is marked inactive */
92
93#define ITD_OPT_IOC (1 << 1) /* interrupt on complete */
94#define ITD_OPT_SMALL (1 << 0) /* page_list_ptr points to buffer directly */
95
96/**
97 * Page list entry.
98 *
99 * A TD's page list must contain sufficient page list entries for the
100 * total data length in the TD.
101 *
102 * [WHCI] section 3.2.4.3
103 */
104struct whc_page_list_entry {
105 __le64 buf_ptr; /*< physical pointer to buffer */
106} __attribute__((packed));
107
108/**
109 * struct whc_seg_list_entry - Segment list entry.
110 *
111 * Describes a portion of the data buffer described in the containing
112 * qTD's page list.
113 *
114 * seg_ptr = qtd->page_list_ptr[qtd->seg_list_ptr[seg].idx].buf_ptr
115 * + qtd->seg_list_ptr[seg].offset;
116 *
117 * Segments can't cross page boundries.
118 *
119 * [WHCI] section 3.2.5.5
120 */
121struct whc_seg_list_entry {
122 __le16 len; /*< segment length */
123 __u8 idx; /*< index into page list */
124 __u8 status; /*< segment status */
125 __le16 offset; /*< 12 bit offset into page */
126} __attribute__((packed));
127
128/**
129 * struct whc_qhead - endpoint and status information for a qset.
130 *
131 * [WHCI] section 3.2.6
132 */
133struct whc_qhead {
134 __le64 link; /*< next qset in list */
135 __le32 info1;
136 __le32 info2;
137 __le32 info3;
138 __le16 status;
139 __le16 err_count; /*< transaction error count */
140 __le32 cur_window;
141 __le32 scratch[3]; /*< h/w scratch area */
142 union {
143 struct whc_qtd qtd;
144 struct whc_itd itd;
145 } overlay;
146} __attribute__((packed));
147
148#define QH_LINK_PTR_MASK (~0x03Full)
149#define QH_LINK_PTR(ptr) ((ptr) & QH_LINK_PTR_MASK)
150#define QH_LINK_IQS (1 << 4) /* isochronous queue set */
151#define QH_LINK_NTDS(n) (((n) - 1) << 1) /* number of TDs in queue set */
152#define QH_LINK_T (1 << 0) /* last queue set in periodic schedule list */
153
154#define QH_INFO1_EP(e) ((e) << 0) /* endpoint number */
155#define QH_INFO1_DIR_IN (1 << 4) /* IN transfer */
156#define QH_INFO1_DIR_OUT (0 << 4) /* OUT transfer */
157#define QH_INFO1_TR_TYPE_CTRL (0x0 << 5) /* control transfer */
158#define QH_INFO1_TR_TYPE_ISOC (0x1 << 5) /* isochronous transfer */
159#define QH_INFO1_TR_TYPE_BULK (0x2 << 5) /* bulk transfer */
160#define QH_INFO1_TR_TYPE_INT (0x3 << 5) /* interrupt */
161#define QH_INFO1_TR_TYPE_LP_INT (0x7 << 5) /* low power interrupt */
162#define QH_INFO1_DEV_INFO_IDX(i) ((i) << 8) /* index into device info buffer */
163#define QH_INFO1_SET_INACTIVE (1 << 15) /* set inactive after transfer */
164#define QH_INFO1_MAX_PKT_LEN(l) ((l) << 16) /* maximum packet length */
165
166#define QH_INFO2_BURST(b) ((b) << 0) /* maximum burst length */
167#define QH_INFO2_DBP(p) ((p) << 5) /* data burst policy (see [WUSB] table 5-7) */
168#define QH_INFO2_MAX_COUNT(c) ((c) << 8) /* max isoc/int pkts per zone */
169#define QH_INFO2_RQS (1 << 15) /* reactivate queue set */
170#define QH_INFO2_MAX_RETRY(r) ((r) << 16) /* maximum transaction retries */
171#define QH_INFO2_MAX_SEQ(s) ((s) << 20) /* maximum sequence number */
172#define QH_INFO3_MAX_DELAY(d) ((d) << 0) /* maximum stream delay in 125 us units (isoc only) */
173#define QH_INFO3_INTERVAL(i) ((i) << 16) /* segment interval in 125 us units (isoc only) */
174
175#define QH_INFO3_TX_RATE_53_3 (0 << 24)
176#define QH_INFO3_TX_RATE_80 (1 << 24)
177#define QH_INFO3_TX_RATE_106_7 (2 << 24)
178#define QH_INFO3_TX_RATE_160 (3 << 24)
179#define QH_INFO3_TX_RATE_200 (4 << 24)
180#define QH_INFO3_TX_RATE_320 (5 << 24)
181#define QH_INFO3_TX_RATE_400 (6 << 24)
182#define QH_INFO3_TX_RATE_480 (7 << 24)
183#define QH_INFO3_TX_PWR(p) ((p) << 29) /* transmit power (see [WUSB] section 5.2.1.2) */
184
185#define QH_STATUS_FLOW_CTRL (1 << 15)
186#define QH_STATUS_ICUR(i) ((i) << 5)
187#define QH_STATUS_TO_ICUR(s) (((s) >> 5) & 0x7)
188
189/**
190 * usb_pipe_to_qh_type - USB core pipe type to QH transfer type
191 *
192 * Returns the QH type field for a USB core pipe type.
193 */
194static inline unsigned usb_pipe_to_qh_type(unsigned pipe)
195{
196 static const unsigned type[] = {
197 [PIPE_ISOCHRONOUS] = QH_INFO1_TR_TYPE_ISOC,
198 [PIPE_INTERRUPT] = QH_INFO1_TR_TYPE_INT,
199 [PIPE_CONTROL] = QH_INFO1_TR_TYPE_CTRL,
200 [PIPE_BULK] = QH_INFO1_TR_TYPE_BULK,
201 };
202 return type[usb_pipetype(pipe)];
203}
204
205/**
206 * Maxiumum number of TDs in a qset.
207 */
208#define WHCI_QSET_TD_MAX 8
209
210/**
211 * struct whc_qset - WUSB data transfers to a specific endpoint
212 * @qh: the QHead of this qset
213 * @qtd: up to 8 qTDs (for qsets for control, bulk and interrupt
214 * transfers)
215 * @itd: up to 8 iTDs (for qsets for isochronous transfers)
216 * @qset_dma: DMA address for this qset
217 * @whc: WHCI HC this qset is for
218 * @ep: endpoint
219 * @stds: list of sTDs queued to this qset
220 * @ntds: number of qTDs queued (not necessarily the same as nTDs
221 * field in the QH)
222 * @td_start: index of the first qTD in the list
223 * @td_end: index of next free qTD in the list (provided
224 * ntds < WHCI_QSET_TD_MAX)
225 *
226 * Queue Sets (qsets) are added to the asynchronous schedule list
227 * (ASL) or the periodic zone list (PZL).
228 *
229 * qsets may contain up to 8 TDs (either qTDs or iTDs as appropriate).
230 * Each TD may refer to at most 1 MiB of data. If a single transfer
231 * has > 8MiB of data, TDs can be reused as they are completed since
232 * the TD list is used as a circular buffer. Similarly, several
233 * (smaller) transfers may be queued in a qset.
234 *
235 * WHCI controllers may cache portions of the qsets in the ASL and
236 * PZL, requiring the WHCD to inform the WHC that the lists have been
237 * updated (fields changed or qsets inserted or removed). For safe
238 * insertion and removal of qsets from the lists the schedule must be
239 * stopped to avoid races in updating the QH link pointers.
240 *
241 * Since the HC is free to execute qsets in any order, all transfers
242 * to an endpoint should use the same qset to ensure transfers are
243 * executed in the order they're submitted.
244 *
245 * [WHCI] section 3.2.3
246 */
247struct whc_qset {
248 struct whc_qhead qh;
249 union {
250 struct whc_qtd qtd[WHCI_QSET_TD_MAX];
251 struct whc_itd itd[WHCI_QSET_TD_MAX];
252 };
253
254 /* private data for WHCD */
255 dma_addr_t qset_dma;
256 struct whc *whc;
257 struct usb_host_endpoint *ep;
258 struct list_head stds;
259 int ntds;
260 int td_start;
261 int td_end;
262 struct list_head list_node;
263 unsigned in_sw_list:1;
264 unsigned in_hw_list:1;
265 unsigned remove:1;
266 struct urb *pause_after_urb;
267 struct completion remove_complete;
268 int max_burst;
269 int max_seq;
270};
271
272static inline void whc_qset_set_link_ptr(u64 *ptr, u64 target)
273{
274 if (target)
275 *ptr = (*ptr & ~(QH_LINK_PTR_MASK | QH_LINK_T)) | QH_LINK_PTR(target);
276 else
277 *ptr = QH_LINK_T;
278}
279
280/**
281 * struct di_buf_entry - Device Information (DI) buffer entry.
282 *
283 * There's one of these per connected device.
284 */
285struct di_buf_entry {
286 __le32 availability_info[8]; /*< MAS availability information, one MAS per bit */
287 __le32 addr_sec_info; /*< addressing and security info */
288 __le32 reserved[7];
289} __attribute__((packed));
290
291#define WHC_DI_SECURE (1 << 31)
292#define WHC_DI_DISABLE (1 << 30)
293#define WHC_DI_KEY_IDX(k) ((k) << 8)
294#define WHC_DI_KEY_IDX_MASK 0x0000ff00
295#define WHC_DI_DEV_ADDR(a) ((a) << 0)
296#define WHC_DI_DEV_ADDR_MASK 0x000000ff
297
298/**
299 * struct dn_buf_entry - Device Notification (DN) buffer entry.
300 *
301 * [WHCI] section 3.2.8
302 */
303struct dn_buf_entry {
304 __u8 msg_size; /*< number of octets of valid DN data */
305 __u8 reserved1;
306 __u8 src_addr; /*< source address */
307 __u8 status; /*< buffer entry status */
308 __le32 tkid; /*< TKID for source device, valid if secure bit is set */
309 __u8 dn_data[56]; /*< up to 56 octets of DN data */
310} __attribute__((packed));
311
312#define WHC_DN_STATUS_VALID (1 << 7) /* buffer entry is valid */
313#define WHC_DN_STATUS_SECURE (1 << 6) /* notification received using secure frame */
314
315#define WHC_N_DN_ENTRIES (4096 / sizeof(struct dn_buf_entry))
316
317/* The Add MMC IE WUSB Generic Command may take up to 256 bytes of
318 data. [WHCI] section 2.4.7. */
319#define WHC_GEN_CMD_DATA_LEN 256
320
321/*
322 * HC registers.
323 *
324 * [WHCI] section 2.4
325 */
326
327#define WHCIVERSION 0x00
328
329#define WHCSPARAMS 0x04
330# define WHCSPARAMS_TO_N_MMC_IES(p) (((p) >> 16) & 0xff)
331# define WHCSPARAMS_TO_N_KEYS(p) (((p) >> 8) & 0xff)
332# define WHCSPARAMS_TO_N_DEVICES(p) (((p) >> 0) & 0x7f)
333
334#define WUSBCMD 0x08
335# define WUSBCMD_BCID(b) ((b) << 16)
336# define WUSBCMD_BCID_MASK (0xff << 16)
337# define WUSBCMD_ASYNC_QSET_RM (1 << 12)
338# define WUSBCMD_PERIODIC_QSET_RM (1 << 11)
339# define WUSBCMD_WUSBSI(s) ((s) << 8)
340# define WUSBCMD_WUSBSI_MASK (0x7 << 8)
341# define WUSBCMD_ASYNC_SYNCED_DB (1 << 7)
342# define WUSBCMD_PERIODIC_SYNCED_DB (1 << 6)
343# define WUSBCMD_ASYNC_UPDATED (1 << 5)
344# define WUSBCMD_PERIODIC_UPDATED (1 << 4)
345# define WUSBCMD_ASYNC_EN (1 << 3)
346# define WUSBCMD_PERIODIC_EN (1 << 2)
347# define WUSBCMD_WHCRESET (1 << 1)
348# define WUSBCMD_RUN (1 << 0)
349
350#define WUSBSTS 0x0c
351# define WUSBSTS_ASYNC_SCHED (1 << 15)
352# define WUSBSTS_PERIODIC_SCHED (1 << 14)
353# define WUSBSTS_DNTS_SCHED (1 << 13)
354# define WUSBSTS_HCHALTED (1 << 12)
355# define WUSBSTS_GEN_CMD_DONE (1 << 9)
356# define WUSBSTS_CHAN_TIME_ROLLOVER (1 << 8)
357# define WUSBSTS_DNTS_OVERFLOW (1 << 7)
358# define WUSBSTS_BPST_ADJUSTMENT_CHANGED (1 << 6)
359# define WUSBSTS_HOST_ERR (1 << 5)
360# define WUSBSTS_ASYNC_SCHED_SYNCED (1 << 4)
361# define WUSBSTS_PERIODIC_SCHED_SYNCED (1 << 3)
362# define WUSBSTS_DNTS_INT (1 << 2)
363# define WUSBSTS_ERR_INT (1 << 1)
364# define WUSBSTS_INT (1 << 0)
365# define WUSBSTS_INT_MASK 0x3ff
366
367#define WUSBINTR 0x10
368# define WUSBINTR_GEN_CMD_DONE (1 << 9)
369# define WUSBINTR_CHAN_TIME_ROLLOVER (1 << 8)
370# define WUSBINTR_DNTS_OVERFLOW (1 << 7)
371# define WUSBINTR_BPST_ADJUSTMENT_CHANGED (1 << 6)
372# define WUSBINTR_HOST_ERR (1 << 5)
373# define WUSBINTR_ASYNC_SCHED_SYNCED (1 << 4)
374# define WUSBINTR_PERIODIC_SCHED_SYNCED (1 << 3)
375# define WUSBINTR_DNTS_INT (1 << 2)
376# define WUSBINTR_ERR_INT (1 << 1)
377# define WUSBINTR_INT (1 << 0)
378# define WUSBINTR_ALL 0x3ff
379
380#define WUSBGENCMDSTS 0x14
381# define WUSBGENCMDSTS_ACTIVE (1 << 31)
382# define WUSBGENCMDSTS_ERROR (1 << 24)
383# define WUSBGENCMDSTS_IOC (1 << 23)
384# define WUSBGENCMDSTS_MMCIE_ADD 0x01
385# define WUSBGENCMDSTS_MMCIE_RM 0x02
386# define WUSBGENCMDSTS_SET_MAS 0x03
387# define WUSBGENCMDSTS_CHAN_STOP 0x04
388# define WUSBGENCMDSTS_RWP_EN 0x05
389
390#define WUSBGENCMDPARAMS 0x18
391#define WUSBGENADDR 0x20
392#define WUSBASYNCLISTADDR 0x28
393#define WUSBDNTSBUFADDR 0x30
394#define WUSBDEVICEINFOADDR 0x38
395
396#define WUSBSETSECKEYCMD 0x40
397# define WUSBSETSECKEYCMD_SET (1 << 31)
398# define WUSBSETSECKEYCMD_ERASE (1 << 30)
399# define WUSBSETSECKEYCMD_GTK (1 << 8)
400# define WUSBSETSECKEYCMD_IDX(i) ((i) << 0)
401
402#define WUSBTKID 0x44
403#define WUSBSECKEY 0x48
404#define WUSBPERIODICLISTBASE 0x58
405#define WUSBMASINDEX 0x60
406
407#define WUSBDNTSCTRL 0x64
408# define WUSBDNTSCTRL_ACTIVE (1 << 31)
409# define WUSBDNTSCTRL_INTERVAL(i) ((i) << 8)
410# define WUSBDNTSCTRL_SLOTS(s) ((s) << 0)
411
412#define WUSBTIME 0x68
413#define WUSBBPST 0x6c
414#define WUSBDIBUPDATED 0x70
415
416#endif /* #ifndef _WHCI_WHCI_HC_H */