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