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
|
/*
* 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 2010 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#ifndef _SYS_USB_USBETH_H
#define _SYS_USB_USBETH_H
#include <sys/types.h>
#include <sys/dditypes.h>
#include <sys/mac.h>
#include <sys/note.h>
#ifdef __cplusplus
extern "C" {
#endif
typedef struct usbecm_state usbecm_state_t;
/*
* PM support
*/
typedef struct usbecm_power {
uint8_t pm_wakeup_enabled; /* remote wakeup enabled */
uint8_t pm_pwr_states; /* bit mask of power states */
boolean_t pm_raise_power; /* driver is about to raise power */
uint8_t pm_cur_power; /* current power level */
uint_t pm_busy_cnt; /* number of set_busy requests */
} usbecm_pm_t;
struct usbecm_statistics {
uint32_t es_upspeed; /* Upstream bit rate, bps */
uint32_t es_downspeed; /* Downstream bit rate, bps */
int es_linkstate; /* link state */
uint64_t es_ipackets;
uint64_t es_opackets;
uint64_t es_ibytes;
uint64_t es_obytes;
uint64_t es_ierrors; /* received frames with errors */
uint64_t es_oerrors; /* transmitted frames with errors */
uint64_t es_multircv; /* received multicast frames */
uint64_t es_multixmt; /* transmitted multicast frames */
uint64_t es_brdcstrcv;
uint64_t es_brdcstxmt;
uint64_t es_macxmt_err;
};
struct usbecm_ds_ops {
/* Device specific initialization and deinitialization */
int (*ecm_ds_init)(usbecm_state_t *);
int (*ecm_ds_fini)(usbecm_state_t *);
int (*ecm_ds_start)(usbecm_state_t *);
int (*ecm_ds_stop)(usbecm_state_t *);
int (*ecm_ds_unicst)(usbecm_state_t *);
int (*ecm_ds_promisc)(usbecm_state_t *);
int (*ecm_ds_multicst)(usbecm_state_t *);
mblk_t *(*ecm_ds_tx)(usbecm_state_t *, mblk_t *);
int (*ecm_ds_intr_cb)(usbecm_state_t *, mblk_t *);
int (*ecm_ds_bulkin_cb)(usbecm_state_t *, mblk_t *);
int (*ecm_ds_bulkout_cb)(usbecm_state_t *, mblk_t *);
};
/*
* per bulk in/out structure
*/
struct usbecm_state {
kmutex_t ecm_mutex; /* structure lock */
dev_info_t *ecm_dip; /* device info */
usb_client_dev_data_t *ecm_dev_data; /* registration data */
usb_pipe_handle_t ecm_def_ph; /* default pipe hdl */
usb_log_handle_t ecm_lh; /* USBA log handle */
int ecm_dev_state; /* USB device state */
size_t ecm_xfer_sz; /* bulk xfer size */
size_t ecm_bulkin_sz;
usbecm_pm_t *ecm_pm; /* PM support */
mac_handle_t ecm_mh; /* mac handle */
usb_serialization_t ecm_ser_acc; /* serialization object */
uint_t ecm_cfg_index; /* config contains ECM ifc */
uint16_t ecm_ctrl_if_no;
uint16_t ecm_data_if_no;
uint16_t ecm_data_if_alt; /* non-compatible device */
usb_ep_data_t *ecm_intr_ep;
usb_ep_data_t *ecm_bulk_in_ep;
usb_ep_data_t *ecm_bulk_out_ep;
boolean_t ecm_compatibility; /* if conform to spec */
usb_cdc_ecm_descr_t ecm_desc; /* if conform to spec */
uint8_t ecm_srcaddr[6]; /* source MAC addr */
uint16_t ecm_pkt_flt; /* pkt flt bitmap ECM1.2 T.8 */
usb_pipe_handle_t ecm_bulkout_ph;
int ecm_bulkout_state;
usb_pipe_handle_t ecm_bulkin_ph;
int ecm_bulkin_state;
usb_pipe_handle_t ecm_intr_ph;
int ecm_intr_state;
struct usbecm_statistics ecm_stat;
uint32_t ecm_init_flags;
int ecm_mac_state;
mblk_t *ecm_rcv_queue; /* receive queue */
int ecm_tx_cnt;
void *ecm_priv; /* device private data */
struct usbecm_ds_ops *ecm_ds_ops;
};
_NOTE(MUTEX_PROTECTS_DATA(usbecm_state::ecm_mutex, usbecm_state))
_NOTE(MUTEX_PROTECTS_DATA(usbecm_state::ecm_mutex, usbecm_statistics))
_NOTE(DATA_READABLE_WITHOUT_LOCK(usbecm_state::{
ecm_dip
ecm_dev_data
ecm_def_ph
ecm_lh
ecm_dev_state
ecm_xfer_sz
ecm_compatibility
ecm_pm
ecm_mh
ecm_bulkin_ph
ecm_bulkout_ph
ecm_intr_ph
ecm_ser_acc
ecm_ctrl_if_no
ecm_data_if_no
ecm_data_if_alt
ecm_desc
ecm_bulk_in_ep
ecm_intr_ep
ecm_bulk_out_ep
ecm_bulkin_sz
ecm_priv
ecm_ds_ops
}))
_NOTE(SCHEME_PROTECTS_DATA("unshared data", mblk_t iocblk))
_NOTE(SCHEME_PROTECTS_DATA("unshared data", usb_bulk_req_t usb_intr_req_t))
/* pipe state */
enum {
USBECM_PIPE_CLOSED, /* pipe is closed */
USBECM_PIPE_IDLE, /* open but no requests */
USBECM_PIPE_BUSY, /* servicing request */
USBECM_PIPE_CLOSING /* pipe is closing */
};
enum {
USBECM_MAC_STOPPED = 0,
USBECM_MAC_STARTED,
};
/* various tunables */
enum {
USBECM_BULKOUT_TIMEOUT = 15, /* bulkout timeout */
USBECM_BULKIN_TIMEOUT = 0 /* bulkin timeout */
};
/* hardware definitions */
enum {
USBSACM_REQ_OUT = USB_DEV_REQ_TYPE_CLASS| USB_DEV_REQ_HOST_TO_DEV,
USBSACM_REQ_IN = USB_DEV_REQ_TYPE_CLASS | USB_DEV_REQ_DEV_TO_HOST,
USBSACM_REQ_WRITE_IF = USBSACM_REQ_OUT | USB_DEV_REQ_RCPT_IF,
USBSACM_REQ_READ_IF = USBSACM_REQ_IN | USB_DEV_REQ_RCPT_IF
};
#define USBECM_INIT_EVENTS (0x01 << 0)
#define USBECM_INIT_SER (0x01 << 1)
#define USBECM_INIT_MAC (0x01 << 2)
/* Bit offset for ECM statistics capabilities, CDC ECM Rev 1.2, Table 4 */
#define ECM_XMIT_OK 0
#define ECM_RCV_OK 1
#define ECM_XMIT_ERROR 2
#define ECM_RCV_ERROR 3
#define ECM_RCV_NO_BUFFER 4
#define ECM_DIRECTED_BYTES_XMIT 5
#define ECM_DIRECTED_FRAMES_XMIT 6
#define ECM_MULTICAST_BYTES_XMIT 7
#define ECM_MULTICAST_FRAMES_XMIT 8
#define ECM_BROADCAST_BYTES_XMIT 9
#define ECM_BROADCAST_FRAMES_XMIT 10
#define ECM_DIRECTED_BYTES_RCV 11
#define ECM_DIRECTED_FRAMES_RCV 12
#define ECM_MULTICAST_BYTES_RCV 13
#define ECM_MULTICAST_FRAMES_RCV 14
#define ECM_BROADCAST_BYTES_RCV 15
#define ECM_BROADCAST_FRAMES_RCV 16
#define ECM_RCV_CRC_ERROR 17
#define ECM_TRANSMIT_QUEUE_LENGTH 18
#define ECM_RCV_ERROR_ALIGNMENT 19
#define ECM_XMIT_ONE_COLLISION 20
#define ECM_XMIT_MORE_COLLISIONS 21
#define ECM_XMIT_DEFERRED 22
#define ECM_XMIT_MAX_COLLISIONS 23
#define ECM_RCV_OVERRUN 24
#define ECM_XMIT_UNDERRUN 25
#define ECM_XMIT_HEARTBEAT_FAILURE 26
#define ECM_XMIT_TIMES_CRS_LOST 27
#define ECM_XMIT_LATE_COLLISIONS 28
#define ECM_STAT_CAP_MASK(x) (1UL << (x)) /* Table 4 */
#define ECM_STAT_SELECTOR(x) ((x) + 1) /* Table 9 */
/* ECM class-specific request codes, Table 6 */
#define CDC_ECM_SET_ETH_MCAST_FLT 0x40
#define CDC_ECM_SET_ETH_PM_FLT 0x41
#define CDC_ECM_GET_ETH_PM_FLT 0x42
#define CDC_ECM_SET_ETH_PKT_FLT 0x43
#define CDC_ECM_GET_ETH_STAT 0x44
/* ECM Ethernet Pakcet Filter Bitmap, Table 8 */
#define CDC_ECM_PKT_TYPE_PROMISC (1<<0)
#define CDC_ECM_PKT_TYPE_ALL_MCAST (1<<1) /* all multicast */
#define CDC_ECM_PKT_TYPE_DIRECTED (1<<2)
#define CDC_ECM_PKT_TYPE_BCAST (1<<3) /* broadcast */
#define CDC_ECM_PKT_TYPE_MCAST (1<<4) /* multicast */
#define PRINT_MASK_ATTA 0x00000001
#define PRINT_MASK_CLOSE 0x00000002
#define PRINT_MASK_OPEN 0x00000004
#define PRINT_MASK_EVENTS 0x00000008
#define PRINT_MASK_PM 0x00000010
#define PRINT_MASK_CB 0x00000020
#define PRINT_MASK_OPS 0x00000040
#define PRINT_MASK_ALL 0xFFFFFFFF
/* Turn a little endian byte array to a uint32_t */
#define LE_TO_UINT32(src, des) { \
uint32_t tmp; \
des = src[3]; \
des = des << 24; \
tmp = src[2]; \
des |= tmp << 16; \
tmp = src[1]; \
des |= tmp << 8; \
des |= src[0]; \
}
#define isdigit(c) ((c) >= '0' && c <= '9')
#define toupper(C) (((C) >= 'a' && (C) <= 'z')? ((C) - 'a' + 'A'): (C))
/* #define NELEM(a) (sizeof (a) / sizeof (*(a))) */
#ifdef __cplusplus
}
#endif
#endif /* _SYS_USB_USBETH_H */
|