1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
|
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#ifndef _SYS_USB_WHCDI_H
#define _SYS_USB_WHCDI_H
#ifdef __cplusplus
extern "C" {
#endif
#include <sys/usb/usba/usba_types.h>
#include <sys/usb/usba/wusba.h>
#include <sys/usb/usba/wusba_io.h>
#include <sys/usb/usba/wa.h> /* for wusb_secrt_data_t */
/*
* This file contains data structures and functions that might be
* shared by HWA and WHCI drivers.
*/
typedef struct wusb_hc_cc_list {
wusb_cc_t cc;
struct wusb_hc_cc_list *next;
} wusb_hc_cc_list_t;
struct wusb_hc_data;
typedef struct wusb_dev_info {
struct wusb_hc_data *wdev_hc; /* the HC this device attaches */
uint8_t wdev_cdid[16];
uint16_t wdev_addr;
uint16_t wdev_state;
uint8_t wdev_is_newconn;
uint8_t wdev_beacon_attr;
usb_pipe_handle_t wdev_ph; /* used before authenticated */
wusb_secrt_data_t wdev_secrt_data;
usb_uwb_cap_descr_t *wdev_uwb_descr;
wusb_cc_t *wdev_cc;
uint8_t wdev_ptk[16];
uint8_t wdev_tkid[3];
timeout_id_t wdev_trust_timer; /* TrustTimeout timer */
uint8_t wdev_active;
} wusb_dev_info_t;
_NOTE(DATA_READABLE_WITHOUT_LOCK(wusb_dev_info::wdev_addr))
_NOTE(DATA_READABLE_WITHOUT_LOCK(wusb_dev_info::wdev_uwb_descr))
_NOTE(DATA_READABLE_WITHOUT_LOCK(wusb_dev_info::wdev_hc))
_NOTE(DATA_READABLE_WITHOUT_LOCK(wusb_dev_info::wdev_secrt_data))
/*
* According to WUSB 1.0 spec, WUSB hosts can support up to 127 devices.
* To comply with USB bus convention that bus address 1 is assigned
* to the host controller device, the addresses assigned to WUSB devices
* would start from 2. So the max device number is reduced to 126.
*/
#define WUSB_MAX_PORTS 126
#define WUSB_CHILD_ZAP 0x1
typedef struct wusb_hc_data {
dev_info_t *hc_dip;
void *hc_private_data;
uint8_t hc_chid[16];
uint8_t hc_cluster_id;
uint8_t hc_num_mmcies;
kmutex_t hc_mutex;
wusb_ie_header_t **hc_mmcie_list;
boolean_t hc_newcon_enabled;
/* save the often used IEs so as not to allocate them each time */
wusb_ie_keepalive_t hc_alive_ie;
/* children info structures */
uint8_t hc_num_ports;
wusb_dev_info_t **hc_dev_infos;
dev_info_t **hc_children_dips;
size_t hc_cd_list_length;
usba_device_t **hc_usba_devices;
/* for bus unconfig */
uint8_t hc_children_state[WUSB_MAX_PORTS + 1];
/* child connection functions */
void (*disconnect_dev)(dev_info_t *, usb_port_t);
void (*reconnect_dev)(dev_info_t *, usb_port_t);
int (*create_child)(dev_info_t *, usb_port_t);
int (*destroy_child)(dev_info_t *, usb_port_t);
/*
* some necessary host functions:
* Both HWA and HCI must implement these entries to support basic
* host controller operations.
*/
int (*set_encrypt)(dev_info_t *, usb_port_t, uint8_t);
int (*set_ptk)(dev_info_t *, usb_key_descr_t *, size_t, usb_port_t);
int (*set_gtk)(dev_info_t *, usb_key_descr_t *, size_t);
int (*set_device_info)(dev_info_t *, wusb_dev_info_t *, usb_port_t);
int (*set_cluster_id) (dev_info_t *, uint8_t id);
int (*set_stream_idx) (dev_info_t *, uint8_t idx);
int (*set_wusb_mas) (dev_info_t *, uint8_t *data);
int (*add_mmc_ie) (dev_info_t *, uint8_t interval, uint8_t rcnt,
uint8_t iehdl, uint16_t len, uint8_t *data);
int (*rem_mmc_ie) (dev_info_t *, uint8_t iehdl);
int (*stop_ch) (dev_info_t *, uint32_t time);
int (*set_num_dnts) (dev_info_t *, uint8_t interval, uint8_t nslot);
int (*get_time) (dev_info_t *, uint8_t timetype,
uint16_t timelen, uint32_t *time);
/* host addr in MAC layer */
uint16_t hc_addr;
/* beaconing channel */
uint8_t hc_channel;
/* reserved MASes. bitmaps */
uint8_t hc_mas[WUSB_SET_WUSB_MAS_LEN];
/* connection context list for the host */
wusb_hc_cc_list_t *hc_cc_list;
/* group temporal key */
usb_key_descr_t hc_gtk;
uint8_t hc_gtk_padding[15];
} wusb_hc_data_t;
_NOTE(MUTEX_PROTECTS_DATA(wusb_hc_data_t::hc_mutex, wusb_dev_info_t))
_NOTE(MUTEX_PROTECTS_DATA(wusb_hc_data_t::hc_mutex, wusb_hc_data_t))
_NOTE(DATA_READABLE_WITHOUT_LOCK(wusb_hc_data_t::hc_num_ports))
_NOTE(DATA_READABLE_WITHOUT_LOCK(wusb_hc_data_t::hc_num_mmcies))
_NOTE(DATA_READABLE_WITHOUT_LOCK(wusb_hc_data_t::hc_dip))
_NOTE(DATA_READABLE_WITHOUT_LOCK(wusb_hc_data_t::hc_gtk))
_NOTE(DATA_READABLE_WITHOUT_LOCK(wusb_hc_data_t::add_mmc_ie))
_NOTE(DATA_READABLE_WITHOUT_LOCK(wusb_hc_data_t::rem_mmc_ie))
_NOTE(DATA_READABLE_WITHOUT_LOCK(wusb_hc_data_t::set_cluster_id))
_NOTE(DATA_READABLE_WITHOUT_LOCK(wusb_hc_data_t::set_encrypt))
_NOTE(DATA_READABLE_WITHOUT_LOCK(wusb_hc_data_t::set_gtk))
_NOTE(DATA_READABLE_WITHOUT_LOCK(wusb_hc_data_t::set_ptk))
_NOTE(DATA_READABLE_WITHOUT_LOCK(wusb_hc_data_t::set_num_dnts))
_NOTE(DATA_READABLE_WITHOUT_LOCK(wusb_hc_data_t::set_stream_idx))
_NOTE(DATA_READABLE_WITHOUT_LOCK(wusb_hc_data_t::set_wusb_mas))
_NOTE(DATA_READABLE_WITHOUT_LOCK(wusb_hc_data_t::stop_ch))
_NOTE(DATA_READABLE_WITHOUT_LOCK(wusb_hc_data_t::create_child))
_NOTE(DATA_READABLE_WITHOUT_LOCK(wusb_hc_data_t::destroy_child))
_NOTE(DATA_READABLE_WITHOUT_LOCK(wusb_hc_data_t::disconnect_dev))
_NOTE(DATA_READABLE_WITHOUT_LOCK(wusb_hc_data_t::reconnect_dev))
_NOTE(DATA_READABLE_WITHOUT_LOCK(wusb_hc_data_t::get_time))
_NOTE(SCHEME_PROTECTS_DATA("local use only",
wusb_ie_host_disconnect::bLength))
_NOTE(SCHEME_PROTECTS_DATA("local use only",
wusb_ie_host_disconnect::bIEIdentifier))
_NOTE(SCHEME_PROTECTS_DATA("local use only",
wusb_ccm_nonce::sfn))
/*
* WUSB 1.0 4.3.8.5 says the range of cluster id is in 0x80-0xfe,
* we limit the maximum WUSB host controller numbers to 31 now,
* and take the upper portion of this range as the broadcast
* cluster id
*/
#define WUSB_CLUSTER_ID_COUNT 31
#define WUSB_MIN_CLUSTER_ID 0xe0
#define WUSB_TRUST_TIMEOUT 4 /* WUSB 4.15.1 TrustTimeout = 4s */
#define WUSB_TRUST_TIMEOUT_US WUSB_TRUST_TIMEOUT * MICROSEC
#define WUSB_PERIODIC_ENDPOINT(endpoint) (((endpoint->bmAttributes & \
USB_EP_ATTR_MASK) == USB_EP_ATTR_INTR) ||\
((endpoint->bmAttributes &\
USB_EP_ATTR_MASK) == USB_EP_ATTR_ISOCH))
#define WUSB_ISOC_ENDPOINT(endpoint) (((endpoint->bmAttributes &\
USB_EP_ATTR_MASK) == USB_EP_ATTR_ISOCH))
#define WUSB_INTR_ENDPOINT(endpoint) (((endpoint->bmAttributes &\
USB_EP_ATTR_MASK) == USB_EP_ATTR_INTR))
/* helper functions */
uint8_t wusb_hc_get_cluster_id();
void wusb_hc_free_cluster_id(uint8_t id);
int wusb_hc_get_iehdl(wusb_hc_data_t *hc_data, wusb_ie_header_t *hdr,
uint8_t *iehdl);
void wusb_hc_free_iehdl(wusb_hc_data_t *hc_data, uint8_t iehdl);
uint_t wusb_hc_is_dev_connected(wusb_hc_data_t *hc_data, uint8_t *cdid,
usb_port_t *port);
uint_t wusb_hc_is_addr_valid(wusb_hc_data_t *hc_data, uint8_t addr,
usb_port_t *port);
usb_port_t wusb_hc_get_free_port(wusb_hc_data_t *hc_data);
/* device notification support */
int wusb_hc_ack_conn(wusb_hc_data_t *hc_data, usb_port_t port);
int wusb_hc_ack_disconn(wusb_hc_data_t *hc_data, uint8_t addr);
void wusb_hc_rm_ack(wusb_hc_data_t *hc_data);
int wusb_hc_send_keepalive_ie(wusb_hc_data_t *hc_data, uint8_t addr);
int wusb_hc_auth_dev(wusb_hc_data_t *hc_data, usb_port_t port,
usb_pipe_handle_t ph, uint8_t ifc, wusb_secrt_data_t *secrt_data);
int wusb_hc_handle_port_connect(wusb_hc_data_t *hc_data, usb_port_t port,
usb_pipe_handle_t ph, uint8_t ifc, wusb_secrt_data_t *secrt_data);
void wusb_hc_handle_dn_connect(wusb_hc_data_t *hc_data,
usb_pipe_handle_t ph, uint8_t ifc, uint8_t *data, size_t len,
wusb_secrt_data_t *secrt_data);
void wusb_hc_handle_dn_disconnect(wusb_hc_data_t *hc_data, uint8_t addr,
uint8_t *data, size_t len);
/* wusb common device function */
int wusb_create_child_devi(dev_info_t *dip, char *node_name,
usba_hcdi_ops_t *usba_hcdi_ops, dev_info_t *usb_root_hub_dip,
usb_port_status_t port_status, usba_device_t *usba_device,
dev_info_t **child_dip);
int wusb_get_dev_security_descr(usb_pipe_handle_t ph,
wusb_secrt_data_t *secrt_data);
int wusb_get_bos_cloud(dev_info_t *child_dip, usba_device_t *child_ud);
int wusb_get_rc_dev_by_hc(dev_info_t *dip, dev_t *dev);
int16_t wusb_get_ccm_encryption_value(wusb_secrt_data_t *secrt_data);
/* device dynamical configuration functions */
void wusb_hc_disconnect_dev(wusb_hc_data_t *hc_data, usb_port_t port);
void wusb_hc_reconnect_dev(wusb_hc_data_t *hc_data, usb_port_t port);
int wusb_hc_create_child(wusb_hc_data_t *hc_data, usb_port_t port);
int wusb_hc_destroy_child(wusb_hc_data_t *hc_data, usb_port_t port);
/* WUSB HC common requests */
int wusb_hc_set_cluster_id(wusb_hc_data_t *hc_data, uint8_t cluster_id);
int wusb_hc_set_stream_idx(wusb_hc_data_t *hc_data, uint8_t stream_idx);
int wusb_hc_set_wusb_mas(wusb_hc_data_t *hc_data, uint8_t *data);
int wusb_hc_add_mmc_ie(wusb_hc_data_t *hc_data, uint8_t interval,
uint8_t rcnt, uint8_t iehdl, uint16_t len, uint8_t *data);
int wusb_hc_remove_mmc_ie(wusb_hc_data_t *hc_data, uint8_t iehdl);
void wusb_hc_rem_ie(wusb_hc_data_t *hc_data, wusb_ie_header_t *ieh);
int wusb_hc_stop_ch(wusb_hc_data_t *hc_data, uint32_t timeoff);
int wusb_hc_set_num_dnts(wusb_hc_data_t *hc_data, uint8_t interval,
uint8_t nslots);
int wusb_hc_get_time(wusb_hc_data_t *hc_data, uint8_t time_type,
uint16_t len, uint32_t *time);
int wusb_hc_add_host_info(wusb_hc_data_t *hc_data, uint8_t stream_idx);
void wusb_hc_rem_host_info(wusb_hc_data_t *hc_data);
int wusb_hc_send_host_disconnect(wusb_hc_data_t *hc_data);
int wusb_hc_set_device_info(wusb_hc_data_t *hc_data, usb_port_t port);
/* WUSB HC connection context list operations */
void wusb_hc_add_cc(wusb_hc_cc_list_t **cc_list, wusb_hc_cc_list_t *new_cc);
void wusb_hc_rem_cc(wusb_hc_cc_list_t **cc_list, wusb_cc_t *old_cc);
void wusb_hc_free_cc_list(wusb_hc_cc_list_t *cc_list);
wusb_cc_t *wusb_hc_cc_matched(wusb_hc_cc_list_t *cc_list, uint8_t *cdid);
/* security functions */
int wusb_dev_set_encrypt(usb_pipe_handle_t ph, uint8_t value);
int wusb_enable_dev_encrypt(wusb_hc_data_t *hc, wusb_dev_info_t *dev_info);
int wusb_dev_set_key(usb_pipe_handle_t ph, uint8_t key_index,
usb_key_descr_t *key, size_t klen);
int wusb_hc_set_encrypt(wusb_hc_data_t *hc_data, usb_port_t port,
uint8_t type);
int wusb_hc_set_ptk(wusb_hc_data_t *hc_data, uint8_t *key_data,
usb_port_t port);
int wusb_hc_set_gtk(wusb_hc_data_t *hc_data, uint8_t *key_data,
uint8_t *tkid);
/* crypto functions */
int PRF(const uchar_t *key, size_t klen, wusb_ccm_nonce_t *nonce,
const uchar_t *adata, size_t alen,
const uchar_t *bdata, size_t blen,
uchar_t *out, size_t bitlen);
#define PRF_64(key, klen, nonce, adata, alen, bdata, blen, out) \
PRF(key, klen, nonce, adata, alen, bdata, blen, out, 64)
#define PRF_128(key, klen, nonce, adata, alen, bdata, blen, out) \
PRF(key, klen, nonce, adata, alen, bdata, blen, out, 128)
#define PRF_256(key, klen, nonce, adata, alen, bdata, blen, out) \
PRF(key, klen, nonce, adata, alen, bdata, blen, out, 256)
int wusb_gen_random_nonce(wusb_hc_data_t *hc_data,
wusb_dev_info_t *dev_info, uchar_t *rbuf);
int wusb_4way_handshake(wusb_hc_data_t *hc_data, usb_port_t port,
usb_pipe_handle_t ph, uint8_t ifc);
#ifdef __cplusplus
}
#endif
#endif /* _SYS_USB_WHCDI_H */
|