1*0035018cSRaymond Chen /*
2*0035018cSRaymond Chen  * CDDL HEADER START
3*0035018cSRaymond Chen  *
4*0035018cSRaymond Chen  * The contents of this file are subject to the terms of the
5*0035018cSRaymond Chen  * Common Development and Distribution License (the "License").
6*0035018cSRaymond Chen  * You may not use this file except in compliance with the License.
7*0035018cSRaymond Chen  *
8*0035018cSRaymond Chen  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*0035018cSRaymond Chen  * or http://www.opensolaris.org/os/licensing.
10*0035018cSRaymond Chen  * See the License for the specific language governing permissions
11*0035018cSRaymond Chen  * and limitations under the License.
12*0035018cSRaymond Chen  *
13*0035018cSRaymond Chen  * When distributing Covered Code, include this CDDL HEADER in each
14*0035018cSRaymond Chen  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*0035018cSRaymond Chen  * If applicable, add the following below this CDDL HEADER, with the
16*0035018cSRaymond Chen  * fields enclosed by brackets "[]" replaced with your own identifying
17*0035018cSRaymond Chen  * information: Portions Copyright [yyyy] [name of copyright owner]
18*0035018cSRaymond Chen  *
19*0035018cSRaymond Chen  * CDDL HEADER END
20*0035018cSRaymond Chen  */
21*0035018cSRaymond Chen /*
22*0035018cSRaymond Chen  * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
23*0035018cSRaymond Chen  * Use is subject to license terms.
24*0035018cSRaymond Chen  */
25*0035018cSRaymond Chen 
26*0035018cSRaymond Chen #ifndef _SYS_USB_USBETH_H
27*0035018cSRaymond Chen #define	_SYS_USB_USBETH_H
28*0035018cSRaymond Chen 
29*0035018cSRaymond Chen 
30*0035018cSRaymond Chen #include <sys/types.h>
31*0035018cSRaymond Chen #include <sys/dditypes.h>
32*0035018cSRaymond Chen #include <sys/mac.h>
33*0035018cSRaymond Chen #include <sys/note.h>
34*0035018cSRaymond Chen 
35*0035018cSRaymond Chen #ifdef	__cplusplus
36*0035018cSRaymond Chen extern "C" {
37*0035018cSRaymond Chen #endif
38*0035018cSRaymond Chen 
39*0035018cSRaymond Chen typedef struct usbecm_state usbecm_state_t;
40*0035018cSRaymond Chen 
41*0035018cSRaymond Chen 
42*0035018cSRaymond Chen /*
43*0035018cSRaymond Chen  * PM support
44*0035018cSRaymond Chen  */
45*0035018cSRaymond Chen typedef struct usbecm_power {
46*0035018cSRaymond Chen 	uint8_t		pm_wakeup_enabled;	/* remote wakeup enabled */
47*0035018cSRaymond Chen 	uint8_t		pm_pwr_states;	/* bit mask of power states */
48*0035018cSRaymond Chen 	boolean_t	pm_raise_power;	/* driver is about to raise power */
49*0035018cSRaymond Chen 	uint8_t		pm_cur_power;	/* current power level */
50*0035018cSRaymond Chen 	uint_t		pm_busy_cnt;	/* number of set_busy requests */
51*0035018cSRaymond Chen } usbecm_pm_t;
52*0035018cSRaymond Chen 
53*0035018cSRaymond Chen struct usbecm_statistics {
54*0035018cSRaymond Chen 	uint32_t	es_upspeed;	/* Upstream bit rate, bps */
55*0035018cSRaymond Chen 	uint32_t	es_downspeed;	/* Downstream bit rate, bps */
56*0035018cSRaymond Chen 	int		es_linkstate;	/* link state */
57*0035018cSRaymond Chen 	uint64_t	es_ipackets;
58*0035018cSRaymond Chen 	uint64_t	es_opackets;
59*0035018cSRaymond Chen 	uint64_t	es_ibytes;
60*0035018cSRaymond Chen 	uint64_t	es_obytes;
61*0035018cSRaymond Chen 	uint64_t	es_ierrors;	/* received frames with errors */
62*0035018cSRaymond Chen 	uint64_t	es_oerrors;	/* transmitted frames with errors */
63*0035018cSRaymond Chen 	uint64_t	es_multircv;	/* received multicast frames */
64*0035018cSRaymond Chen 	uint64_t	es_multixmt;	/* transmitted multicast frames */
65*0035018cSRaymond Chen 	uint64_t	es_brdcstrcv;
66*0035018cSRaymond Chen 	uint64_t	es_brdcstxmt;
67*0035018cSRaymond Chen 	uint64_t	es_macxmt_err;
68*0035018cSRaymond Chen };
69*0035018cSRaymond Chen 
70*0035018cSRaymond Chen struct usbecm_ds_ops {
71*0035018cSRaymond Chen 	/* Device specific initialization and deinitialization */
72*0035018cSRaymond Chen 	int (*ecm_ds_init)(usbecm_state_t *);
73*0035018cSRaymond Chen 	int (*ecm_ds_fini)(usbecm_state_t *);
74*0035018cSRaymond Chen 
75*0035018cSRaymond Chen 	int (*ecm_ds_start)(usbecm_state_t *);
76*0035018cSRaymond Chen 	int (*ecm_ds_stop)(usbecm_state_t *);
77*0035018cSRaymond Chen 	int (*ecm_ds_unicst)(usbecm_state_t *);
78*0035018cSRaymond Chen 	int (*ecm_ds_promisc)(usbecm_state_t *);
79*0035018cSRaymond Chen 	int (*ecm_ds_multicst)(usbecm_state_t *);
80*0035018cSRaymond Chen 	mblk_t *(*ecm_ds_tx)(usbecm_state_t *, mblk_t *);
81*0035018cSRaymond Chen 
82*0035018cSRaymond Chen 	int (*ecm_ds_intr_cb)(usbecm_state_t *, mblk_t *);
83*0035018cSRaymond Chen 	int (*ecm_ds_bulkin_cb)(usbecm_state_t *, mblk_t *);
84*0035018cSRaymond Chen 	int (*ecm_ds_bulkout_cb)(usbecm_state_t *, mblk_t *);
85*0035018cSRaymond Chen };
86*0035018cSRaymond Chen 
87*0035018cSRaymond Chen /*
88*0035018cSRaymond Chen  * per bulk in/out structure
89*0035018cSRaymond Chen  */
90*0035018cSRaymond Chen struct usbecm_state {
91*0035018cSRaymond Chen 	kmutex_t		ecm_mutex;		/* structure lock */
92*0035018cSRaymond Chen 	dev_info_t		*ecm_dip;		/* device info */
93*0035018cSRaymond Chen 	usb_client_dev_data_t	*ecm_dev_data;		/* registration data */
94*0035018cSRaymond Chen 	usb_pipe_handle_t	ecm_def_ph;		/* default pipe hdl */
95*0035018cSRaymond Chen 	usb_log_handle_t	ecm_lh;			/* USBA log handle */
96*0035018cSRaymond Chen 	int			ecm_dev_state;		/* USB device state */
97*0035018cSRaymond Chen 	size_t			ecm_xfer_sz;		/* bulk xfer size */
98*0035018cSRaymond Chen 	size_t			ecm_bulkin_sz;
99*0035018cSRaymond Chen 	usbecm_pm_t		*ecm_pm;		/* PM support */
100*0035018cSRaymond Chen 	mac_handle_t		ecm_mh;			/* mac handle */
101*0035018cSRaymond Chen 	usb_serialization_t	ecm_ser_acc;	/* serialization object */
102*0035018cSRaymond Chen 
103*0035018cSRaymond Chen 	uint_t			ecm_cfg_index;	/* config contains ECM ifc */
104*0035018cSRaymond Chen 	uint16_t		ecm_ctrl_if_no;
105*0035018cSRaymond Chen 	uint16_t		ecm_data_if_no;
106*0035018cSRaymond Chen 	uint16_t		ecm_data_if_alt; /* non-compatible device */
107*0035018cSRaymond Chen 
108*0035018cSRaymond Chen 	usb_ep_data_t		*ecm_intr_ep;
109*0035018cSRaymond Chen 	usb_ep_data_t		*ecm_bulk_in_ep;
110*0035018cSRaymond Chen 	usb_ep_data_t		*ecm_bulk_out_ep;
111*0035018cSRaymond Chen 
112*0035018cSRaymond Chen 	boolean_t		ecm_compatibility;	/* if conform to spec */
113*0035018cSRaymond Chen 	usb_cdc_ecm_descr_t	ecm_desc;	/* if conform to spec */
114*0035018cSRaymond Chen 
115*0035018cSRaymond Chen 	uint8_t			ecm_srcaddr[6];	/* source MAC addr */
116*0035018cSRaymond Chen 	uint16_t		ecm_pkt_flt;	/* pkt flt bitmap ECM1.2 T.8 */
117*0035018cSRaymond Chen 
118*0035018cSRaymond Chen 	usb_pipe_handle_t	ecm_bulkout_ph;
119*0035018cSRaymond Chen 	int			ecm_bulkout_state;
120*0035018cSRaymond Chen 	usb_pipe_handle_t	ecm_bulkin_ph;
121*0035018cSRaymond Chen 	int			ecm_bulkin_state;
122*0035018cSRaymond Chen 	usb_pipe_handle_t	ecm_intr_ph;
123*0035018cSRaymond Chen 	int			ecm_intr_state;
124*0035018cSRaymond Chen 	struct usbecm_statistics	ecm_stat;
125*0035018cSRaymond Chen 	uint32_t		ecm_init_flags;
126*0035018cSRaymond Chen 	int			ecm_mac_state;
127*0035018cSRaymond Chen 	mblk_t			*ecm_rcv_queue; /* receive queue */
128*0035018cSRaymond Chen 	int			ecm_tx_cnt;
129*0035018cSRaymond Chen 
130*0035018cSRaymond Chen 	void			*ecm_priv; /* device private data */
131*0035018cSRaymond Chen 	struct usbecm_ds_ops    *ecm_ds_ops;
132*0035018cSRaymond Chen };
133*0035018cSRaymond Chen 
134*0035018cSRaymond Chen 
135*0035018cSRaymond Chen _NOTE(MUTEX_PROTECTS_DATA(usbecm_state::ecm_mutex, usbecm_state))
136*0035018cSRaymond Chen _NOTE(MUTEX_PROTECTS_DATA(usbecm_state::ecm_mutex, usbecm_statistics))
137*0035018cSRaymond Chen 
138*0035018cSRaymond Chen _NOTE(DATA_READABLE_WITHOUT_LOCK(usbecm_state::{
139*0035018cSRaymond Chen 	ecm_dip
140*0035018cSRaymond Chen 	ecm_dev_data
141*0035018cSRaymond Chen 	ecm_def_ph
142*0035018cSRaymond Chen 	ecm_lh
143*0035018cSRaymond Chen 	ecm_dev_state
144*0035018cSRaymond Chen 	ecm_xfer_sz
145*0035018cSRaymond Chen 	ecm_compatibility
146*0035018cSRaymond Chen 	ecm_pm
147*0035018cSRaymond Chen 	ecm_mh
148*0035018cSRaymond Chen 	ecm_bulkin_ph
149*0035018cSRaymond Chen 	ecm_bulkout_ph
150*0035018cSRaymond Chen 	ecm_intr_ph
151*0035018cSRaymond Chen 	ecm_ser_acc
152*0035018cSRaymond Chen 	ecm_ctrl_if_no
153*0035018cSRaymond Chen 	ecm_data_if_no
154*0035018cSRaymond Chen 	ecm_data_if_alt
155*0035018cSRaymond Chen 	ecm_desc
156*0035018cSRaymond Chen 	ecm_bulk_in_ep
157*0035018cSRaymond Chen 	ecm_intr_ep
158*0035018cSRaymond Chen 	ecm_bulk_out_ep
159*0035018cSRaymond Chen 	ecm_bulkin_sz
160*0035018cSRaymond Chen 	ecm_priv
161*0035018cSRaymond Chen 	ecm_ds_ops
162*0035018cSRaymond Chen }))
163*0035018cSRaymond Chen 
164*0035018cSRaymond Chen _NOTE(SCHEME_PROTECTS_DATA("unshared data", mblk_t iocblk))
165*0035018cSRaymond Chen _NOTE(SCHEME_PROTECTS_DATA("unshared data", usb_bulk_req_t usb_intr_req_t))
166*0035018cSRaymond Chen 
167*0035018cSRaymond Chen /* pipe state */
168*0035018cSRaymond Chen enum {
169*0035018cSRaymond Chen 	USBECM_PIPE_CLOSED,			/* pipe is closed */
170*0035018cSRaymond Chen 	USBECM_PIPE_IDLE,			/* open but no requests */
171*0035018cSRaymond Chen 	USBECM_PIPE_BUSY,			/* servicing request */
172*0035018cSRaymond Chen 	USBECM_PIPE_CLOSING			/* pipe is closing */
173*0035018cSRaymond Chen };
174*0035018cSRaymond Chen 
175*0035018cSRaymond Chen enum {
176*0035018cSRaymond Chen 	USBECM_MAC_STOPPED = 0,
177*0035018cSRaymond Chen 	USBECM_MAC_STARTED,
178*0035018cSRaymond Chen };
179*0035018cSRaymond Chen 
180*0035018cSRaymond Chen /* various tunables */
181*0035018cSRaymond Chen enum {
182*0035018cSRaymond Chen 	USBECM_BULKOUT_TIMEOUT		= 15,	/* bulkout timeout */
183*0035018cSRaymond Chen 	USBECM_BULKIN_TIMEOUT		= 0	/* bulkin timeout */
184*0035018cSRaymond Chen };
185*0035018cSRaymond Chen 
186*0035018cSRaymond Chen /* hardware definitions */
187*0035018cSRaymond Chen enum {
188*0035018cSRaymond Chen 	USBSACM_REQ_OUT	= USB_DEV_REQ_TYPE_CLASS| USB_DEV_REQ_HOST_TO_DEV,
189*0035018cSRaymond Chen 	USBSACM_REQ_IN	= USB_DEV_REQ_TYPE_CLASS | USB_DEV_REQ_DEV_TO_HOST,
190*0035018cSRaymond Chen 	USBSACM_REQ_WRITE_IF		= USBSACM_REQ_OUT | USB_DEV_REQ_RCPT_IF,
191*0035018cSRaymond Chen 	USBSACM_REQ_READ_IF		= USBSACM_REQ_IN | USB_DEV_REQ_RCPT_IF
192*0035018cSRaymond Chen };
193*0035018cSRaymond Chen 
194*0035018cSRaymond Chen #define	USBECM_INIT_EVENTS	(0x01 << 0)
195*0035018cSRaymond Chen #define	USBECM_INIT_SER		(0x01 << 1)
196*0035018cSRaymond Chen #define	USBECM_INIT_MAC		(0x01 << 2)
197*0035018cSRaymond Chen 
198*0035018cSRaymond Chen /* Bit offset for ECM statistics capabilities, CDC ECM Rev 1.2, Table 4 */
199*0035018cSRaymond Chen #define	ECM_XMIT_OK			0
200*0035018cSRaymond Chen #define	ECM_RCV_OK			1
201*0035018cSRaymond Chen #define	ECM_XMIT_ERROR			2
202*0035018cSRaymond Chen #define	ECM_RCV_ERROR			3
203*0035018cSRaymond Chen #define	ECM_RCV_NO_BUFFER		4
204*0035018cSRaymond Chen #define	ECM_DIRECTED_BYTES_XMIT		5
205*0035018cSRaymond Chen #define	ECM_DIRECTED_FRAMES_XMIT	6
206*0035018cSRaymond Chen #define	ECM_MULTICAST_BYTES_XMIT	7
207*0035018cSRaymond Chen #define	ECM_MULTICAST_FRAMES_XMIT	8
208*0035018cSRaymond Chen #define	ECM_BROADCAST_BYTES_XMIT	9
209*0035018cSRaymond Chen #define	ECM_BROADCAST_FRAMES_XMIT	10
210*0035018cSRaymond Chen #define	ECM_DIRECTED_BYTES_RCV		11
211*0035018cSRaymond Chen #define	ECM_DIRECTED_FRAMES_RCV		12
212*0035018cSRaymond Chen #define	ECM_MULTICAST_BYTES_RCV		13
213*0035018cSRaymond Chen #define	ECM_MULTICAST_FRAMES_RCV	14
214*0035018cSRaymond Chen #define	ECM_BROADCAST_BYTES_RCV		15
215*0035018cSRaymond Chen #define	ECM_BROADCAST_FRAMES_RCV	16
216*0035018cSRaymond Chen #define	ECM_RCV_CRC_ERROR		17
217*0035018cSRaymond Chen #define	ECM_TRANSMIT_QUEUE_LENGTH	18
218*0035018cSRaymond Chen #define	ECM_RCV_ERROR_ALIGNMENT		19
219*0035018cSRaymond Chen #define	ECM_XMIT_ONE_COLLISION		20
220*0035018cSRaymond Chen #define	ECM_XMIT_MORE_COLLISIONS	21
221*0035018cSRaymond Chen #define	ECM_XMIT_DEFERRED		22
222*0035018cSRaymond Chen #define	ECM_XMIT_MAX_COLLISIONS		23
223*0035018cSRaymond Chen #define	ECM_RCV_OVERRUN			24
224*0035018cSRaymond Chen #define	ECM_XMIT_UNDERRUN		25
225*0035018cSRaymond Chen #define	ECM_XMIT_HEARTBEAT_FAILURE	26
226*0035018cSRaymond Chen #define	ECM_XMIT_TIMES_CRS_LOST		27
227*0035018cSRaymond Chen #define	ECM_XMIT_LATE_COLLISIONS	28
228*0035018cSRaymond Chen 
229*0035018cSRaymond Chen #define	ECM_STAT_CAP_MASK(x)	(1UL << (x))		/* Table 4 */
230*0035018cSRaymond Chen #define	ECM_STAT_SELECTOR(x)	((x) + 1)	/* Table 9 */
231*0035018cSRaymond Chen 
232*0035018cSRaymond Chen /* ECM class-specific request codes, Table 6 */
233*0035018cSRaymond Chen #define	CDC_ECM_SET_ETH_MCAST_FLT	0x40
234*0035018cSRaymond Chen #define	CDC_ECM_SET_ETH_PM_FLT		0x41
235*0035018cSRaymond Chen #define	CDC_ECM_GET_ETH_PM_FLT		0x42
236*0035018cSRaymond Chen #define	CDC_ECM_SET_ETH_PKT_FLT		0x43
237*0035018cSRaymond Chen #define	CDC_ECM_GET_ETH_STAT		0x44
238*0035018cSRaymond Chen 
239*0035018cSRaymond Chen /* ECM Ethernet Pakcet Filter Bitmap, Table 8 */
240*0035018cSRaymond Chen #define	CDC_ECM_PKT_TYPE_PROMISC	(1<<0)
241*0035018cSRaymond Chen #define	CDC_ECM_PKT_TYPE_ALL_MCAST	(1<<1) /* all multicast */
242*0035018cSRaymond Chen #define	CDC_ECM_PKT_TYPE_DIRECTED	(1<<2)
243*0035018cSRaymond Chen #define	CDC_ECM_PKT_TYPE_BCAST		(1<<3) /* broadcast */
244*0035018cSRaymond Chen #define	CDC_ECM_PKT_TYPE_MCAST		(1<<4) /* multicast */
245*0035018cSRaymond Chen 
246*0035018cSRaymond Chen #define	PRINT_MASK_ATTA		0x00000001
247*0035018cSRaymond Chen #define	PRINT_MASK_CLOSE	0x00000002
248*0035018cSRaymond Chen #define	PRINT_MASK_OPEN		0x00000004
249*0035018cSRaymond Chen #define	PRINT_MASK_EVENTS	0x00000008
250*0035018cSRaymond Chen #define	PRINT_MASK_PM		0x00000010
251*0035018cSRaymond Chen #define	PRINT_MASK_CB		0x00000020
252*0035018cSRaymond Chen #define	PRINT_MASK_OPS		0x00000040
253*0035018cSRaymond Chen #define	PRINT_MASK_ALL		0xFFFFFFFF
254*0035018cSRaymond Chen 
255*0035018cSRaymond Chen /* Turn a little endian byte array to a uint32_t */
256*0035018cSRaymond Chen #define	LE_TO_UINT32(src, des)	{ \
257*0035018cSRaymond Chen 	uint32_t tmp; \
258*0035018cSRaymond Chen 	des = src[3]; \
259*0035018cSRaymond Chen 	des = des << 24; \
260*0035018cSRaymond Chen 	tmp = src[2]; \
261*0035018cSRaymond Chen 	des |= tmp << 16; \
262*0035018cSRaymond Chen 	tmp = src[1]; \
263*0035018cSRaymond Chen 	des |= tmp << 8; \
264*0035018cSRaymond Chen 	des |= src[0]; \
265*0035018cSRaymond Chen }
266*0035018cSRaymond Chen 
267*0035018cSRaymond Chen #define	isdigit(c)	((c) >= '0' && c <= '9')
268*0035018cSRaymond Chen #define	toupper(C)	(((C) >= 'a' && (C) <= 'z')? ((C) - 'a' + 'A'): (C))
269*0035018cSRaymond Chen 
270*0035018cSRaymond Chen /* #define	NELEM(a)	(sizeof (a) / sizeof (*(a))) */
271*0035018cSRaymond Chen 
272*0035018cSRaymond Chen 
273*0035018cSRaymond Chen #ifdef	__cplusplus
274*0035018cSRaymond Chen }
275*0035018cSRaymond Chen #endif
276*0035018cSRaymond Chen 
277*0035018cSRaymond Chen #endif	/* _SYS_USB_USBETH_H */
278