summaryrefslogtreecommitdiff
path: root/usr/src/uts/common/sys/usb/clients/usbecm/usbecm.h
blob: 34a1ddae38f1481768a70ad2b85c754c101afa39 (plain)
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 */