diff options
| author | Inaky Perez-Gonzalez <inaky.perez-gonzalez@intel.com> | 2008-09-17 11:34:22 -0400 |
|---|---|---|
| committer | David Vrabel <dv02@dv02pc01.europe.root.pri> | 2008-09-17 11:54:29 -0400 |
| commit | c7f736484f8ecde4dc1bc8459179c4d65f2ccbe4 (patch) | |
| tree | bcb16ec170c9279ed580cad778cc481a7ebb435c /include/linux/usb | |
| parent | a21b963aa4a98c645b1fa3799f2e4a6ebb6c974a (diff) | |
wusb: add the Wireless USB include files.
Common header files derived from the WUSB 1.0 specification.
Signed-off-by: David Vrabel <david.vrabel@csr.com>
Diffstat (limited to 'include/linux/usb')
| -rw-r--r-- | include/linux/usb/wusb-wa.h | 271 | ||||
| -rw-r--r-- | include/linux/usb/wusb.h | 376 |
2 files changed, 647 insertions, 0 deletions
diff --git a/include/linux/usb/wusb-wa.h b/include/linux/usb/wusb-wa.h new file mode 100644 index 000000000000..a102561e7026 --- /dev/null +++ b/include/linux/usb/wusb-wa.h | |||
| @@ -0,0 +1,271 @@ | |||
| 1 | /* | ||
| 2 | * Wireless USB Wire Adapter constants and structures. | ||
| 3 | * | ||
| 4 | * Copyright (C) 2005-2006 Intel Corporation. | ||
| 5 | * Inaky Perez-Gonzalez <inaky.perez-gonzalez@intel.com> | ||
| 6 | * | ||
| 7 | * This program is free software; you can redistribute it and/or | ||
| 8 | * modify it under the terms of the GNU General Public License version | ||
| 9 | * 2 as published by the Free Software Foundation. | ||
| 10 | * | ||
| 11 | * This program is distributed in the hope that it will be useful, | ||
| 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 14 | * GNU General Public License for more details. | ||
| 15 | * | ||
| 16 | * You should have received a copy of the GNU General Public License | ||
| 17 | * along with this program; if not, write to the Free Software | ||
| 18 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA | ||
| 19 | * 02110-1301, USA. | ||
| 20 | * | ||
| 21 | * | ||
| 22 | * FIXME: docs | ||
| 23 | * FIXME: organize properly, group logically | ||
| 24 | * | ||
| 25 | * All the event structures are defined in uwb/spec.h, as they are | ||
| 26 | * common to the WHCI and WUSB radio control interfaces. | ||
| 27 | * | ||
| 28 | * References: | ||
| 29 | * [WUSB] Wireless Universal Serial Bus Specification, revision 1.0, ch8 | ||
| 30 | */ | ||
| 31 | #ifndef __LINUX_USB_WUSB_WA_H | ||
| 32 | #define __LINUX_USB_WUSB_WA_H | ||
| 33 | |||
| 34 | /** | ||
| 35 | * Radio Command Request for the Radio Control Interface | ||
| 36 | * | ||
| 37 | * Radio Control Interface command and event codes are the same as | ||
| 38 | * WHCI, and listed in include/linux/uwb.h:UWB_RC_{CMD,EVT}_* | ||
| 39 | */ | ||
| 40 | enum { | ||
| 41 | WA_EXEC_RC_CMD = 40, /* Radio Control command Request */ | ||
| 42 | }; | ||
| 43 | |||
| 44 | /* Wireless Adapter Requests ([WUSB] table 8-51) */ | ||
| 45 | enum { | ||
| 46 | WUSB_REQ_ADD_MMC_IE = 20, | ||
| 47 | WUSB_REQ_REMOVE_MMC_IE = 21, | ||
| 48 | WUSB_REQ_SET_NUM_DNTS = 22, | ||
| 49 | WUSB_REQ_SET_CLUSTER_ID = 23, | ||
| 50 | WUSB_REQ_SET_DEV_INFO = 24, | ||
| 51 | WUSB_REQ_GET_TIME = 25, | ||
| 52 | WUSB_REQ_SET_STREAM_IDX = 26, | ||
| 53 | WUSB_REQ_SET_WUSB_MAS = 27, | ||
| 54 | }; | ||
| 55 | |||
| 56 | |||
| 57 | /* Wireless Adapter WUSB Channel Time types ([WUSB] table 8-52) */ | ||
| 58 | enum { | ||
| 59 | WUSB_TIME_ADJ = 0, | ||
| 60 | WUSB_TIME_BPST = 1, | ||
| 61 | WUSB_TIME_WUSB = 2, | ||
| 62 | }; | ||
| 63 | |||
| 64 | enum { | ||
| 65 | WA_ENABLE = 0x01, | ||
| 66 | WA_RESET = 0x02, | ||
| 67 | RPIPE_PAUSE = 0x1, | ||
| 68 | }; | ||
| 69 | |||
| 70 | /* Responses from Get Status request ([WUSB] section 8.3.1.6) */ | ||
| 71 | enum { | ||
| 72 | WA_STATUS_ENABLED = 0x01, | ||
| 73 | WA_STATUS_RESETTING = 0x02 | ||
| 74 | }; | ||
| 75 | |||
| 76 | enum rpipe_crs { | ||
| 77 | RPIPE_CRS_CTL = 0x01, | ||
| 78 | RPIPE_CRS_ISO = 0x02, | ||
| 79 | RPIPE_CRS_BULK = 0x04, | ||
| 80 | RPIPE_CRS_INTR = 0x08 | ||
| 81 | }; | ||
| 82 | |||
| 83 | /** | ||
| 84 | * RPipe descriptor ([WUSB] section 8.5.2.11) | ||
| 85 | * | ||
| 86 | * FIXME: explain rpipes | ||
| 87 | */ | ||
| 88 | struct usb_rpipe_descriptor { | ||
| 89 | u8 bLength; | ||
| 90 | u8 bDescriptorType; | ||
| 91 | __le16 wRPipeIndex; | ||
| 92 | __le16 wRequests; | ||
| 93 | __le16 wBlocks; /* rw if 0 */ | ||
| 94 | __le16 wMaxPacketSize; /* rw? */ | ||
| 95 | u8 bHSHubAddress; /* reserved: 0 */ | ||
| 96 | u8 bHSHubPort; /* ??? FIXME ??? */ | ||
| 97 | u8 bSpeed; /* rw: xfer rate 'enum uwb_phy_rate' */ | ||
| 98 | u8 bDeviceAddress; /* rw: Target device address */ | ||
| 99 | u8 bEndpointAddress; /* rw: Target EP address */ | ||
| 100 | u8 bDataSequence; /* ro: Current Data sequence */ | ||
| 101 | __le32 dwCurrentWindow; /* ro */ | ||
| 102 | u8 bMaxDataSequence; /* ro?: max supported seq */ | ||
| 103 | u8 bInterval; /* rw: */ | ||
| 104 | u8 bOverTheAirInterval; /* rw: */ | ||
| 105 | u8 bmAttribute; /* ro? */ | ||
| 106 | u8 bmCharacteristics; /* ro? enum rpipe_attr, supported xsactions */ | ||
| 107 | u8 bmRetryOptions; /* rw? */ | ||
| 108 | __le16 wNumTransactionErrors; /* rw */ | ||
| 109 | } __attribute__ ((packed)); | ||
| 110 | |||
| 111 | /** | ||
| 112 | * Wire Adapter Notification types ([WUSB] sections 8.4.5 & 8.5.4) | ||
| 113 | * | ||
| 114 | * These are the notifications coming on the notification endpoint of | ||
| 115 | * an HWA and a DWA. | ||
| 116 | */ | ||
| 117 | enum wa_notif_type { | ||
| 118 | DWA_NOTIF_RWAKE = 0x91, | ||
| 119 | DWA_NOTIF_PORTSTATUS = 0x92, | ||
| 120 | WA_NOTIF_TRANSFER = 0x93, | ||
| 121 | HWA_NOTIF_BPST_ADJ = 0x94, | ||
| 122 | HWA_NOTIF_DN = 0x95, | ||
| 123 | }; | ||
| 124 | |||
| 125 | /** | ||
| 126 | * Wire Adapter notification header | ||
| 127 | * | ||
| 128 | * Notifications coming from a wire adapter use a common header | ||
| 129 | * defined in [WUSB] sections 8.4.5 & 8.5.4. | ||
| 130 | */ | ||
| 131 | struct wa_notif_hdr { | ||
| 132 | u8 bLength; | ||
| 133 | u8 bNotifyType; /* enum wa_notif_type */ | ||
| 134 | } __attribute__((packed)); | ||
| 135 | |||
| 136 | /** | ||
| 137 | * HWA DN Received notification [(WUSB] section 8.5.4.2) | ||
| 138 | * | ||
| 139 | * The DNData is specified in WUSB1.0[7.6]. For each device | ||
| 140 | * notification we received, we just need to dispatch it. | ||
| 141 | * | ||
| 142 | * @dndata: this is really an array of notifications, but all start | ||
| 143 | * with the same header. | ||
| 144 | */ | ||
| 145 | struct hwa_notif_dn { | ||
| 146 | struct wa_notif_hdr hdr; | ||
| 147 | u8 bSourceDeviceAddr; /* from errata 2005/07 */ | ||
| 148 | u8 bmAttributes; | ||
| 149 | struct wusb_dn_hdr dndata[]; | ||
| 150 | } __attribute__((packed)); | ||
| 151 | |||
| 152 | /* [WUSB] section 8.3.3 */ | ||
| 153 | enum wa_xfer_type { | ||
| 154 | WA_XFER_TYPE_CTL = 0x80, | ||
| 155 | WA_XFER_TYPE_BI = 0x81, /* bulk/interrupt */ | ||
| 156 | WA_XFER_TYPE_ISO = 0x82, | ||
| 157 | WA_XFER_RESULT = 0x83, | ||
| 158 | WA_XFER_ABORT = 0x84, | ||
| 159 | }; | ||
| 160 | |||
| 161 | /* [WUSB] section 8.3.3 */ | ||
| 162 | struct wa_xfer_hdr { | ||
| 163 | u8 bLength; /* 0x18 */ | ||
| 164 | u8 bRequestType; /* 0x80 WA_REQUEST_TYPE_CTL */ | ||
| 165 | __le16 wRPipe; /* RPipe index */ | ||
| 166 | __le32 dwTransferID; /* Host-assigned ID */ | ||
| 167 | __le32 dwTransferLength; /* Length of data to xfer */ | ||
| 168 | u8 bTransferSegment; | ||
| 169 | } __attribute__((packed)); | ||
| 170 | |||
| 171 | struct wa_xfer_ctl { | ||
| 172 | struct wa_xfer_hdr hdr; | ||
| 173 | u8 bmAttribute; | ||
| 174 | __le16 wReserved; | ||
| 175 | struct usb_ctrlrequest baSetupData; | ||
| 176 | } __attribute__((packed)); | ||
| 177 | |||
| 178 | struct wa_xfer_bi { | ||
| 179 | struct wa_xfer_hdr hdr; | ||
| 180 | u8 bReserved; | ||
| 181 | __le16 wReserved; | ||
| 182 | } __attribute__((packed)); | ||
| 183 | |||
| 184 | struct wa_xfer_hwaiso { | ||
| 185 | struct wa_xfer_hdr hdr; | ||
| 186 | u8 bReserved; | ||
| 187 | __le16 wPresentationTime; | ||
| 188 | __le32 dwNumOfPackets; | ||
| 189 | /* FIXME: u8 pktdata[]? */ | ||
| 190 | } __attribute__((packed)); | ||
| 191 | |||
| 192 | /* [WUSB] section 8.3.3.5 */ | ||
| 193 | struct wa_xfer_abort { | ||
| 194 | u8 bLength; | ||
| 195 | u8 bRequestType; | ||
| 196 | __le16 wRPipe; /* RPipe index */ | ||
| 197 | __le32 dwTransferID; /* Host-assigned ID */ | ||
| 198 | } __attribute__((packed)); | ||
| 199 | |||
| 200 | /** | ||
| 201 | * WA Transfer Complete notification ([WUSB] section 8.3.3.3) | ||
| 202 | * | ||
| 203 | */ | ||
| 204 | struct wa_notif_xfer { | ||
| 205 | struct wa_notif_hdr hdr; | ||
| 206 | u8 bEndpoint; | ||
| 207 | u8 Reserved; | ||
| 208 | } __attribute__((packed)); | ||
| 209 | |||
| 210 | /** Transfer result basic codes [WUSB] table 8-15 */ | ||
| 211 | enum { | ||
| 212 | WA_XFER_STATUS_SUCCESS, | ||
| 213 | WA_XFER_STATUS_HALTED, | ||
| 214 | WA_XFER_STATUS_DATA_BUFFER_ERROR, | ||
| 215 | WA_XFER_STATUS_BABBLE, | ||
| 216 | WA_XFER_RESERVED, | ||
| 217 | WA_XFER_STATUS_NOT_FOUND, | ||
| 218 | WA_XFER_STATUS_INSUFFICIENT_RESOURCE, | ||
| 219 | WA_XFER_STATUS_TRANSACTION_ERROR, | ||
| 220 | WA_XFER_STATUS_ABORTED, | ||
| 221 | WA_XFER_STATUS_RPIPE_NOT_READY, | ||
| 222 | WA_XFER_INVALID_FORMAT, | ||
| 223 | WA_XFER_UNEXPECTED_SEGMENT_NUMBER, | ||
| 224 | WA_XFER_STATUS_RPIPE_TYPE_MISMATCH, | ||
| 225 | }; | ||
| 226 | |||
| 227 | /** [WUSB] section 8.3.3.4 */ | ||
| 228 | struct wa_xfer_result { | ||
| 229 | struct wa_notif_hdr hdr; | ||
| 230 | __le32 dwTransferID; | ||
| 231 | __le32 dwTransferLength; | ||
| 232 | u8 bTransferSegment; | ||
| 233 | u8 bTransferStatus; | ||
| 234 | __le32 dwNumOfPackets; | ||
| 235 | } __attribute__((packed)); | ||
| 236 | |||
| 237 | /** | ||
| 238 | * Wire Adapter Class Descriptor ([WUSB] section 8.5.2.7). | ||
| 239 | * | ||
| 240 | * NOTE: u16 fields are read Little Endian from the hardware. | ||
| 241 | * | ||
| 242 | * @bNumPorts is the original max number of devices that the host can | ||
| 243 | * connect; we might chop this so the stack can handle | ||
| 244 | * it. In case you need to access it, use wusbhc->ports_max | ||
| 245 | * if it is a Wireless USB WA. | ||
| 246 | */ | ||
| 247 | struct usb_wa_descriptor { | ||
| 248 | u8 bLength; | ||
| 249 | u8 bDescriptorType; | ||
| 250 | u16 bcdWAVersion; | ||
| 251 | u8 bNumPorts; /* don't use!! */ | ||
| 252 | u8 bmAttributes; /* Reserved == 0 */ | ||
| 253 | u16 wNumRPipes; | ||
| 254 | u16 wRPipeMaxBlock; | ||
| 255 | u8 bRPipeBlockSize; | ||
| 256 | u8 bPwrOn2PwrGood; | ||
| 257 | u8 bNumMMCIEs; | ||
| 258 | u8 DeviceRemovable; /* FIXME: in DWA this is up to 16 bytes */ | ||
| 259 | } __attribute__((packed)); | ||
| 260 | |||
| 261 | /** | ||
| 262 | * HWA Device Information Buffer (WUSB1.0[T8.54]) | ||
| 263 | */ | ||
| 264 | struct hwa_dev_info { | ||
| 265 | u8 bmDeviceAvailability[32]; /* FIXME: ignored for now */ | ||
| 266 | u8 bDeviceAddress; | ||
| 267 | __le16 wPHYRates; | ||
| 268 | u8 bmDeviceAttribute; | ||
| 269 | } __attribute__((packed)); | ||
| 270 | |||
| 271 | #endif /* #ifndef __LINUX_USB_WUSB_WA_H */ | ||
diff --git a/include/linux/usb/wusb.h b/include/linux/usb/wusb.h new file mode 100644 index 000000000000..5f401b644ed5 --- /dev/null +++ b/include/linux/usb/wusb.h | |||
| @@ -0,0 +1,376 @@ | |||
| 1 | /* | ||
| 2 | * Wireless USB Standard Definitions | ||
| 3 | * Event Size Tables | ||
| 4 | * | ||
| 5 | * Copyright (C) 2005-2006 Intel Corporation | ||
| 6 | * Inaky Perez-Gonzalez <inaky.perez-gonzalez@intel.com> | ||
| 7 | * | ||
| 8 | * This program is free software; you can redistribute it and/or | ||
| 9 | * modify it under the terms of the GNU General Public License version | ||
| 10 | * 2 as published by the Free Software Foundation. | ||
| 11 | * | ||
| 12 | * This program is distributed in the hope that it will be useful, | ||
| 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 15 | * GNU General Public License for more details. | ||
| 16 | * | ||
| 17 | * You should have received a copy of the GNU General Public License | ||
| 18 | * along with this program; if not, write to the Free Software | ||
| 19 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA | ||
| 20 | * 02110-1301, USA. | ||
| 21 | * | ||
| 22 | * | ||
| 23 | * FIXME: docs | ||
| 24 | * FIXME: organize properly, group logically | ||
| 25 | * | ||
| 26 | * All the event structures are defined in uwb/spec.h, as they are | ||
| 27 | * common to the WHCI and WUSB radio control interfaces. | ||
| 28 | */ | ||
| 29 | |||
| 30 | #ifndef __WUSB_H__ | ||
| 31 | #define __WUSB_H__ | ||
| 32 | |||
| 33 | #include <linux/types.h> | ||
| 34 | #include <linux/kernel.h> | ||
| 35 | #include <linux/uwb/spec.h> | ||
| 36 | #include <linux/usb/ch9.h> | ||
| 37 | #include <linux/param.h> | ||
| 38 | |||
| 39 | /** | ||
| 40 | * WUSB Information Element header | ||
| 41 | * | ||
| 42 | * I don't know why, they decided to make it different to the MBOA MAC | ||
| 43 | * IE Header; beats me. | ||
| 44 | */ | ||
| 45 | struct wuie_hdr { | ||
| 46 | u8 bLength; | ||
| 47 | u8 bIEIdentifier; | ||
| 48 | } __attribute__((packed)); | ||
| 49 | |||
| 50 | enum { | ||
| 51 | WUIE_ID_WCTA = 0x80, | ||
| 52 | WUIE_ID_CONNECTACK, | ||
| 53 | WUIE_ID_HOST_INFO, | ||
| 54 | WUIE_ID_CHANGE_ANNOUNCE, | ||
| 55 | WUIE_ID_DEVICE_DISCONNECT, | ||
| 56 | WUIE_ID_HOST_DISCONNECT, | ||
| 57 | WUIE_ID_KEEP_ALIVE = 0x89, | ||
| 58 | WUIE_ID_ISOCH_DISCARD, | ||
| 59 | WUIE_ID_RESET_DEVICE, | ||
| 60 | }; | ||
| 61 | |||
| 62 | /** | ||
| 63 | * Maximum number of array elements in a WUSB IE. | ||
| 64 | * | ||
| 65 | * WUSB1.0[7.5 before table 7-38] says that in WUSB IEs that | ||
| 66 | * are "arrays" have to limited to 4 elements. So we define it | ||
| 67 | * like that to ease up and submit only the neeed size. | ||
| 68 | */ | ||
| 69 | #define WUIE_ELT_MAX 4 | ||
| 70 | |||
| 71 | /** | ||
| 72 | * Wrapper for the data that defines a CHID, a CDID or a CK | ||
| 73 | * | ||
| 74 | * WUSB defines that CHIDs, CDIDs and CKs are a 16 byte string of | ||
| 75 | * data. In order to avoid confusion and enforce types, we wrap it. | ||
| 76 | * | ||
| 77 | * Make it packed, as we use it in some hw defintions. | ||
| 78 | */ | ||
| 79 | struct wusb_ckhdid { | ||
| 80 | u8 data[16]; | ||
| 81 | } __attribute__((packed)); | ||
| 82 | |||
| 83 | const static | ||
| 84 | struct wusb_ckhdid wusb_ckhdid_zero = { .data = { 0 } }; | ||
| 85 | |||
| 86 | #define WUSB_CKHDID_STRSIZE (3 * sizeof(struct wusb_ckhdid) + 1) | ||
| 87 | |||
| 88 | /** | ||
| 89 | * WUSB IE: Host Information (WUSB1.0[7.5.2]) | ||
| 90 | * | ||
| 91 | * Used to provide information about the host to the Wireless USB | ||
| 92 | * devices in range (CHID can be used as an ASCII string). | ||
| 93 | */ | ||
| 94 | struct wuie_host_info { | ||
| 95 | struct wuie_hdr hdr; | ||
| 96 | __le16 attributes; | ||
| 97 | struct wusb_ckhdid CHID; | ||
| 98 | } __attribute__((packed)); | ||
| 99 | |||
| 100 | /** | ||
| 101 | * WUSB IE: Connect Ack (WUSB1.0[7.5.1]) | ||
| 102 | * | ||
| 103 | * Used to acknowledge device connect requests. See note for | ||
| 104 | * WUIE_ELT_MAX. | ||
| 105 | */ | ||
| 106 | struct wuie_connect_ack { | ||
| 107 | struct wuie_hdr hdr; | ||
| 108 | struct { | ||
| 109 | struct wusb_ckhdid CDID; | ||
| 110 | u8 bDeviceAddress; /* 0 means unused */ | ||
| 111 | u8 bReserved; | ||
| 112 | } blk[WUIE_ELT_MAX]; | ||
| 113 | } __attribute__((packed)); | ||
| 114 | |||
| 115 | /** | ||
| 116 | * WUSB IE Host Information Element, Connect Availability | ||
| 117 | * | ||
| 118 | * WUSB1.0[7.5.2], bmAttributes description | ||
| 119 | */ | ||
| 120 | enum { | ||
| 121 | WUIE_HI_CAP_RECONNECT = 0, | ||
| 122 | WUIE_HI_CAP_LIMITED, | ||
| 123 | WUIE_HI_CAP_RESERVED, | ||
| 124 | WUIE_HI_CAP_ALL, | ||
| 125 | }; | ||
| 126 | |||
| 127 | /** | ||
| 128 | * WUSB IE: Channel Stop (WUSB1.0[7.5.8]) | ||
| 129 | * | ||
| 130 | * Tells devices the host is going to stop sending MMCs and will dissapear. | ||
| 131 | */ | ||
| 132 | struct wuie_channel_stop { | ||
| 133 | struct wuie_hdr hdr; | ||
| 134 | u8 attributes; | ||
| 135 | u8 timestamp[3]; | ||
| 136 | } __attribute__((packed)); | ||
| 137 | |||
| 138 | /** | ||
| 139 | * WUSB IE: Keepalive (WUSB1.0[7.5.9]) | ||
| 140 | * | ||
| 141 | * Ask device(s) to send keepalives. | ||
| 142 | */ | ||
| 143 | struct wuie_keep_alive { | ||
| 144 | struct wuie_hdr hdr; | ||
| 145 | u8 bDeviceAddress[WUIE_ELT_MAX]; | ||
| 146 | } __attribute__((packed)); | ||
| 147 | |||
| 148 | /** | ||
| 149 | * WUSB IE: Reset device (WUSB1.0[7.5.11]) | ||
| 150 | * | ||
| 151 | * Tell device to reset; in all truth, we can fit 4 CDIDs, but we only | ||
| 152 | * use it for one at the time... | ||
| 153 | * | ||
| 154 | * In any case, this request is a wee bit silly: why don't they target | ||
| 155 | * by address?? | ||
| 156 | */ | ||
| 157 | struct wuie_reset { | ||
| 158 | struct wuie_hdr hdr; | ||
| 159 | struct wusb_ckhdid CDID; | ||
| 160 | } __attribute__((packed)); | ||
| 161 | |||
| 162 | /** | ||
| 163 | * WUSB IE: Disconnect device (WUSB1.0[7.5.11]) | ||
| 164 | * | ||
| 165 | * Tell device to disconnect; we can fit 4 addresses, but we only use | ||
| 166 | * it for one at the time... | ||
| 167 | */ | ||
| 168 | struct wuie_disconnect { | ||
| 169 | struct wuie_hdr hdr; | ||
| 170 | u8 bDeviceAddress; | ||
| 171 | u8 padding; | ||
| 172 | } __attribute__((packed)); | ||
| 173 | |||
| 174 | /** | ||
| 175 | * WUSB IE: Host disconnect ([WUSB] section 7.5.5) | ||
| 176 | * | ||
| 177 | * Tells all connected devices to disconnect. | ||
| 178 | */ | ||
| 179 | struct wuie_host_disconnect { | ||
| 180 | struct wuie_hdr hdr; | ||
| 181 | } __attribute__((packed)); | ||
| 182 | |||
| 183 | /** | ||
| 184 | * WUSB Device Notification header (WUSB1.0[7.6]) | ||
| 185 | */ | ||
| 186 | struct wusb_dn_hdr { | ||
| 187 | u8 bType; | ||
| 188 | u8 notifdata[]; | ||
| 189 | } __attribute__((packed)); | ||
| 190 | |||
| 191 | /** Device Notification codes (WUSB1.0[Table 7-54]) */ | ||
| 192 | enum WUSB_DN { | ||
| 193 | WUSB_DN_CONNECT = 0x01, | ||
| 194 | WUSB_DN_DISCONNECT = 0x02, | ||
| 195 | WUSB_DN_EPRDY = 0x03, | ||
| 196 | WUSB_DN_MASAVAILCHANGED = 0x04, | ||
| 197 | WUSB_DN_RWAKE = 0x05, | ||
| 198 | WUSB_DN_SLEEP = 0x06, | ||
| 199 | WUSB_DN_ALIVE = 0x07, | ||
| 200 | }; | ||
| 201 | |||
| 202 | /** WUSB Device Notification Connect */ | ||
| 203 | struct wusb_dn_connect { | ||
| 204 | struct wusb_dn_hdr hdr; | ||
| 205 | __le16 attributes; | ||
| 206 | struct wusb_ckhdid CDID; | ||
| 207 | } __attribute__((packed)); | ||
| 208 | |||
| 209 | static inline int wusb_dn_connect_prev_dev_addr(const struct wusb_dn_connect *dn) | ||
| 210 | { | ||
| 211 | return le16_to_cpu(dn->attributes) & 0xff; | ||
| 212 | } | ||
| 213 | |||
| 214 | static inline int wusb_dn_connect_new_connection(const struct wusb_dn_connect *dn) | ||
| 215 | { | ||
| 216 | return (le16_to_cpu(dn->attributes) >> 8) & 0x1; | ||
| 217 | } | ||
| 218 | |||
| 219 | static inline int wusb_dn_connect_beacon_behavior(const struct wusb_dn_connect *dn) | ||
| 220 | { | ||
| 221 | return (le16_to_cpu(dn->attributes) >> 9) & 0x03; | ||
| 222 | } | ||
| 223 | |||
| 224 | /** Device is alive (aka: pong) (WUSB1.0[7.6.7]) */ | ||
| 225 | struct wusb_dn_alive { | ||
| 226 | struct wusb_dn_hdr hdr; | ||
| 227 | } __attribute__((packed)); | ||
| 228 | |||
| 229 | /** Device is disconnecting (WUSB1.0[7.6.2]) */ | ||
| 230 | struct wusb_dn_disconnect { | ||
| 231 | struct wusb_dn_hdr hdr; | ||
| 232 | } __attribute__((packed)); | ||
| 233 | |||
| 234 | /* General constants */ | ||
| 235 | enum { | ||
| 236 | WUSB_TRUST_TIMEOUT_MS = 4000, /* [WUSB] section 4.15.1 */ | ||
| 237 | }; | ||
| 238 | |||
| 239 | static inline size_t ckhdid_printf(char *pr_ckhdid, size_t size, | ||
| 240 | const struct wusb_ckhdid *ckhdid) | ||
| 241 | { | ||
| 242 | return scnprintf(pr_ckhdid, size, | ||
| 243 | "%02hx %02hx %02hx %02hx %02hx %02hx %02hx %02hx " | ||
| 244 | "%02hx %02hx %02hx %02hx %02hx %02hx %02hx %02hx", | ||
| 245 | ckhdid->data[0], ckhdid->data[1], | ||
| 246 | ckhdid->data[2], ckhdid->data[3], | ||
| 247 | ckhdid->data[4], ckhdid->data[5], | ||
| 248 | ckhdid->data[6], ckhdid->data[7], | ||
| 249 | ckhdid->data[8], ckhdid->data[9], | ||
| 250 | ckhdid->data[10], ckhdid->data[11], | ||
| 251 | ckhdid->data[12], ckhdid->data[13], | ||
| 252 | ckhdid->data[14], ckhdid->data[15]); | ||
| 253 | } | ||
| 254 | |||
| 255 | /* | ||
| 256 | * WUSB Crypto stuff (WUSB1.0[6]) | ||
| 257 | */ | ||
| 258 | |||
| 259 | extern const char *wusb_et_name(u8); | ||
| 260 | |||
| 261 | /** | ||
| 262 | * WUSB key index WUSB1.0[7.3.2.4], for usage when setting keys for | ||
| 263 | * the host or the device. | ||
| 264 | */ | ||
| 265 | static inline u8 wusb_key_index(int index, int type, int originator) | ||
| 266 | { | ||
| 267 | return (originator << 6) | (type << 4) | index; | ||
| 268 | } | ||
| 269 | |||
| 270 | #define WUSB_KEY_INDEX_TYPE_PTK 0 /* for HWA only */ | ||
| 271 | #define WUSB_KEY_INDEX_TYPE_ASSOC 1 | ||
| 272 | #define WUSB_KEY_INDEX_TYPE_GTK 2 | ||
| 273 | #define WUSB_KEY_INDEX_ORIGINATOR_HOST 0 | ||
| 274 | #define WUSB_KEY_INDEX_ORIGINATOR_DEVICE 1 | ||
| 275 | |||
| 276 | /* A CCM Nonce, defined in WUSB1.0[6.4.1] */ | ||
| 277 | struct aes_ccm_nonce { | ||
| 278 | u8 sfn[6]; /* Little Endian */ | ||
| 279 | u8 tkid[3]; /* LE */ | ||
| 280 | struct uwb_dev_addr dest_addr; | ||
| 281 | struct uwb_dev_addr src_addr; | ||
| 282 | } __attribute__((packed)); | ||
| 283 | |||
| 284 | /* A CCM operation label, defined on WUSB1.0[6.5.x] */ | ||
| 285 | struct aes_ccm_label { | ||
| 286 | u8 data[14]; | ||
| 287 | } __attribute__((packed)); | ||
| 288 | |||
| 289 | /* | ||
| 290 | * Input to the key derivation sequence defined in | ||
| 291 | * WUSB1.0[6.5.1]. Rest of the data is in the CCM Nonce passed to the | ||
| 292 | * PRF function. | ||
| 293 | */ | ||
| 294 | struct wusb_keydvt_in { | ||
| 295 | u8 hnonce[16]; | ||
| 296 | u8 dnonce[16]; | ||
| 297 | } __attribute__((packed)); | ||
| 298 | |||
| 299 | /* | ||
| 300 | * Output from the key derivation sequence defined in | ||
| 301 | * WUSB1.0[6.5.1]. | ||
| 302 | */ | ||
| 303 | struct wusb_keydvt_out { | ||
| 304 | u8 kck[16]; | ||
| 305 | u8 ptk[16]; | ||
| 306 | } __attribute__((packed)); | ||
| 307 | |||
| 308 | /* Pseudo Random Function WUSB1.0[6.5] */ | ||
| 309 | extern int wusb_crypto_init(void); | ||
| 310 | extern void wusb_crypto_exit(void); | ||
| 311 | extern ssize_t wusb_prf(void *out, size_t out_size, | ||
| 312 | const u8 key[16], const struct aes_ccm_nonce *_n, | ||
| 313 | const struct aes_ccm_label *a, | ||
| 314 | const void *b, size_t blen, size_t len); | ||
| 315 | |||
| 316 | static inline int wusb_prf_64(void *out, size_t out_size, const u8 key[16], | ||
| 317 | const struct aes_ccm_nonce *n, | ||
| 318 | const struct aes_ccm_label *a, | ||
| 319 | const void *b, size_t blen) | ||
| 320 | { | ||
| 321 | return wusb_prf(out, out_size, key, n, a, b, blen, 64); | ||
| 322 | } | ||
| 323 | |||
| 324 | static inline int wusb_prf_128(void *out, size_t out_size, const u8 key[16], | ||
| 325 | const struct aes_ccm_nonce *n, | ||
| 326 | const struct aes_ccm_label *a, | ||
| 327 | const void *b, size_t blen) | ||
| 328 | { | ||
| 329 | return wusb_prf(out, out_size, key, n, a, b, blen, 128); | ||
| 330 | } | ||
| 331 | |||
| 332 | static inline int wusb_prf_256(void *out, size_t out_size, const u8 key[16], | ||
| 333 | const struct aes_ccm_nonce *n, | ||
| 334 | const struct aes_ccm_label *a, | ||
| 335 | const void *b, size_t blen) | ||
| 336 | { | ||
| 337 | return wusb_prf(out, out_size, key, n, a, b, blen, 256); | ||
| 338 | } | ||
| 339 | |||
| 340 | /* Key derivation WUSB1.0[6.5.1] */ | ||
| 341 | static inline int wusb_key_derive(struct wusb_keydvt_out *keydvt_out, | ||
| 342 | const u8 key[16], | ||
| 343 | const struct aes_ccm_nonce *n, | ||
| 344 | const struct wusb_keydvt_in *keydvt_in) | ||
| 345 | { | ||
| 346 | const struct aes_ccm_label a = { .data = "Pair-wise keys" }; | ||
| 347 | return wusb_prf_256(keydvt_out, sizeof(*keydvt_out), key, n, &a, | ||
| 348 | keydvt_in, sizeof(*keydvt_in)); | ||
| 349 | } | ||
| 350 | |||
| 351 | /* | ||
| 352 | * Out-of-band MIC Generation WUSB1.0[6.5.2] | ||
| 353 | * | ||
| 354 | * Compute the MIC over @key, @n and @hs and place it in @mic_out. | ||
| 355 | * | ||
| 356 | * @mic_out: Where to place the 8 byte MIC tag | ||
| 357 | * @key: KCK from the derivation process | ||
| 358 | * @n: CCM nonce, n->sfn == 0, TKID as established in the | ||
| 359 | * process. | ||
| 360 | * @hs: Handshake struct for phase 2 of the 4-way. | ||
| 361 | * hs->bStatus and hs->bReserved are zero. | ||
| 362 | * hs->bMessageNumber is 2 (WUSB1.0[7.3.2.5.2] | ||
| 363 | * hs->dest_addr is the device's USB address padded with 0 | ||
| 364 | * hs->src_addr is the hosts's UWB device address | ||
| 365 | * hs->mic is ignored (as we compute that value). | ||
| 366 | */ | ||
| 367 | static inline int wusb_oob_mic(u8 mic_out[8], const u8 key[16], | ||
| 368 | const struct aes_ccm_nonce *n, | ||
| 369 | const struct usb_handshake *hs) | ||
| 370 | { | ||
| 371 | const struct aes_ccm_label a = { .data = "out-of-bandMIC" }; | ||
| 372 | return wusb_prf_64(mic_out, 8, key, n, &a, | ||
| 373 | hs, sizeof(*hs) - sizeof(hs->MIC)); | ||
| 374 | } | ||
| 375 | |||
| 376 | #endif /* #ifndef __WUSB_H__ */ | ||
