xref: /freebsd/sys/dev/usb/net/if_cdce.c (revision f4f8f02054f3abb6ceb84aefcdecc78d5c8b462f)
1 /*	$NetBSD: if_cdce.c,v 1.4 2004/10/24 12:50:54 augustss Exp $ */
2 
3 /*-
4  * Copyright (c) 1997, 1998, 1999, 2000-2003 Bill Paul <wpaul@windriver.com>
5  * Copyright (c) 2003-2005 Craig Boston
6  * Copyright (c) 2004 Daniel Hartmeier
7  * Copyright (c) 2009 Hans Petter Selasky
8  * All rights reserved.
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions
12  * are met:
13  * 1. Redistributions of source code must retain the above copyright
14  *    notice, this list of conditions and the following disclaimer.
15  * 2. Redistributions in binary form must reproduce the above copyright
16  *    notice, this list of conditions and the following disclaimer in the
17  *    documentation and/or other materials provided with the distribution.
18  * 3. All advertising materials mentioning features or use of this software
19  *    must display the following acknowledgement:
20  *	This product includes software developed by Bill Paul.
21  * 4. Neither the name of the author nor the names of any co-contributors
22  *    may be used to endorse or promote products derived from this software
23  *    without specific prior written permission.
24  *
25  * THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND
26  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28  * ARE DISCLAIMED.  IN NO EVENT SHALL Bill Paul, THE VOICES IN HIS HEAD OR
29  * THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
30  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
31  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
32  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
33  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
34  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
35  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36  */
37 
38 /*
39  * USB Communication Device Class (Ethernet Networking Control Model)
40  * http://www.usb.org/developers/devclass_docs/usbcdc11.pdf
41  */
42 
43 #include <sys/cdefs.h>
44 __FBSDID("$FreeBSD$");
45 
46 #include "usbdevs.h"
47 #include <dev/usb/usb.h>
48 #include <dev/usb/usb_mfunc.h>
49 #include <dev/usb/usb_error.h>
50 #include <dev/usb/usb_cdc.h>
51 
52 #define	USB_DEBUG_VAR cdce_debug
53 
54 #include <dev/usb/usb_core.h>
55 #include <dev/usb/usb_lookup.h>
56 #include <dev/usb/usb_process.h>
57 #include <dev/usb/usb_debug.h>
58 #include <dev/usb/usb_request.h>
59 #include <dev/usb/usb_busdma.h>
60 #include <dev/usb/usb_util.h>
61 #include <dev/usb/usb_parse.h>
62 #include <dev/usb/usb_device.h>
63 
64 #include <dev/usb/net/usb_ethernet.h>
65 #include <dev/usb/net/if_cdcereg.h>
66 
67 static device_probe_t cdce_probe;
68 static device_attach_t cdce_attach;
69 static device_detach_t cdce_detach;
70 static device_suspend_t cdce_suspend;
71 static device_resume_t cdce_resume;
72 static usb_handle_request_t cdce_handle_request;
73 
74 static usb2_callback_t cdce_bulk_write_callback;
75 static usb2_callback_t cdce_bulk_read_callback;
76 static usb2_callback_t cdce_intr_read_callback;
77 static usb2_callback_t cdce_intr_write_callback;
78 
79 static usb2_ether_fn_t cdce_attach_post;
80 static usb2_ether_fn_t cdce_init;
81 static usb2_ether_fn_t cdce_stop;
82 static usb2_ether_fn_t cdce_start;
83 static usb2_ether_fn_t cdce_setmulti;
84 static usb2_ether_fn_t cdce_setpromisc;
85 
86 static uint32_t	cdce_m_crc32(struct mbuf *, uint32_t, uint32_t);
87 
88 #if USB_DEBUG
89 static int cdce_debug = 0;
90 
91 SYSCTL_NODE(_hw_usb2, OID_AUTO, cdce, CTLFLAG_RW, 0, "USB CDC-Ethernet");
92 SYSCTL_INT(_hw_usb2_cdce, OID_AUTO, debug, CTLFLAG_RW, &cdce_debug, 0,
93     "Debug level");
94 #endif
95 
96 static const struct usb2_config cdce_config[CDCE_N_TRANSFER] = {
97 
98 	[CDCE_BULK_RX] = {
99 		.type = UE_BULK,
100 		.endpoint = UE_ADDR_ANY,
101 		.direction = UE_DIR_RX,
102 		.if_index = 0,
103 		.frames = CDCE_FRAMES_MAX,
104 		.bufsize = (CDCE_FRAMES_MAX * MCLBYTES),
105 		.flags = {.pipe_bof = 1,.short_frames_ok = 1,.short_xfer_ok = 1,.ext_buffer = 1,},
106 		.callback = cdce_bulk_read_callback,
107 		.timeout = 0,	/* no timeout */
108 		.usb_mode = USB_MODE_MAX,	/* both modes */
109 	},
110 
111 	[CDCE_BULK_TX] = {
112 		.type = UE_BULK,
113 		.endpoint = UE_ADDR_ANY,
114 		.direction = UE_DIR_TX,
115 		.if_index = 0,
116 		.frames = CDCE_FRAMES_MAX,
117 		.bufsize = (CDCE_FRAMES_MAX * MCLBYTES),
118 		.flags = {.pipe_bof = 1,.force_short_xfer = 1,.ext_buffer = 1,},
119 		.callback = cdce_bulk_write_callback,
120 		.timeout = 10000,	/* 10 seconds */
121 		.usb_mode = USB_MODE_MAX,	/* both modes */
122 	},
123 
124 	[CDCE_INTR_RX] = {
125 		.type = UE_INTERRUPT,
126 		.endpoint = UE_ADDR_ANY,
127 		.direction = UE_DIR_RX,
128 		.if_index = 1,
129 		.bufsize = CDCE_IND_SIZE_MAX,
130 		.flags = {.pipe_bof = 1,.short_xfer_ok = 1,.no_pipe_ok = 1,},
131 		.callback = cdce_intr_read_callback,
132 		.timeout = 0,
133 		.usb_mode = USB_MODE_HOST,
134 	},
135 
136 	[CDCE_INTR_TX] = {
137 		.type = UE_INTERRUPT,
138 		.endpoint = UE_ADDR_ANY,
139 		.direction = UE_DIR_TX,
140 		.if_index = 1,
141 		.bufsize = CDCE_IND_SIZE_MAX,
142 		.flags = {.pipe_bof = 1,.force_short_xfer = 1,.no_pipe_ok = 1,},
143 		.callback = cdce_intr_write_callback,
144 		.timeout = 10000,	/* 10 seconds */
145 		.usb_mode = USB_MODE_DEVICE,
146 	},
147 };
148 
149 static device_method_t cdce_methods[] = {
150 	/* USB interface */
151 	DEVMETHOD(usb_handle_request, cdce_handle_request),
152 
153 	/* Device interface */
154 	DEVMETHOD(device_probe, cdce_probe),
155 	DEVMETHOD(device_attach, cdce_attach),
156 	DEVMETHOD(device_detach, cdce_detach),
157 	DEVMETHOD(device_suspend, cdce_suspend),
158 	DEVMETHOD(device_resume, cdce_resume),
159 
160 	{0, 0}
161 };
162 
163 static driver_t cdce_driver = {
164 	.name = "cdce",
165 	.methods = cdce_methods,
166 	.size = sizeof(struct cdce_softc),
167 };
168 
169 static devclass_t cdce_devclass;
170 
171 DRIVER_MODULE(cdce, uhub, cdce_driver, cdce_devclass, NULL, 0);
172 MODULE_VERSION(cdce, 1);
173 MODULE_DEPEND(cdce, uether, 1, 1, 1);
174 MODULE_DEPEND(cdce, usb, 1, 1, 1);
175 MODULE_DEPEND(cdce, ether, 1, 1, 1);
176 
177 static const struct usb2_ether_methods cdce_ue_methods = {
178 	.ue_attach_post = cdce_attach_post,
179 	.ue_start = cdce_start,
180 	.ue_init = cdce_init,
181 	.ue_stop = cdce_stop,
182 	.ue_setmulti = cdce_setmulti,
183 	.ue_setpromisc = cdce_setpromisc,
184 };
185 
186 static const struct usb2_device_id cdce_devs[] = {
187 	{USB_IF_CSI(UICLASS_CDC, UISUBCLASS_ETHERNET_NETWORKING_CONTROL_MODEL, 0)},
188 	{USB_IF_CSI(UICLASS_CDC, UISUBCLASS_MOBILE_DIRECT_LINE_MODEL, 0)},
189 
190 	{USB_VPI(USB_VENDOR_ACERLABS, USB_PRODUCT_ACERLABS_M5632, CDCE_FLAG_NO_UNION)},
191 	{USB_VPI(USB_VENDOR_AMBIT, USB_PRODUCT_AMBIT_NTL_250, CDCE_FLAG_NO_UNION)},
192 	{USB_VPI(USB_VENDOR_COMPAQ, USB_PRODUCT_COMPAQ_IPAQLINUX, CDCE_FLAG_NO_UNION)},
193 	{USB_VPI(USB_VENDOR_GMATE, USB_PRODUCT_GMATE_YP3X00, CDCE_FLAG_NO_UNION)},
194 	{USB_VPI(USB_VENDOR_MOTOROLA2, USB_PRODUCT_MOTOROLA2_USBLAN, CDCE_FLAG_ZAURUS | CDCE_FLAG_NO_UNION)},
195 	{USB_VPI(USB_VENDOR_MOTOROLA2, USB_PRODUCT_MOTOROLA2_USBLAN2, CDCE_FLAG_ZAURUS | CDCE_FLAG_NO_UNION)},
196 	{USB_VPI(USB_VENDOR_NETCHIP, USB_PRODUCT_NETCHIP_ETHERNETGADGET, CDCE_FLAG_NO_UNION)},
197 	{USB_VPI(USB_VENDOR_PROLIFIC, USB_PRODUCT_PROLIFIC_PL2501, CDCE_FLAG_NO_UNION)},
198 	{USB_VPI(USB_VENDOR_SHARP, USB_PRODUCT_SHARP_SL5500, CDCE_FLAG_ZAURUS)},
199 	{USB_VPI(USB_VENDOR_SHARP, USB_PRODUCT_SHARP_SL5600, CDCE_FLAG_ZAURUS | CDCE_FLAG_NO_UNION)},
200 	{USB_VPI(USB_VENDOR_SHARP, USB_PRODUCT_SHARP_SLA300, CDCE_FLAG_ZAURUS | CDCE_FLAG_NO_UNION)},
201 	{USB_VPI(USB_VENDOR_SHARP, USB_PRODUCT_SHARP_SLC700, CDCE_FLAG_ZAURUS | CDCE_FLAG_NO_UNION)},
202 	{USB_VPI(USB_VENDOR_SHARP, USB_PRODUCT_SHARP_SLC750, CDCE_FLAG_ZAURUS | CDCE_FLAG_NO_UNION)},
203 };
204 
205 static int
206 cdce_probe(device_t dev)
207 {
208 	struct usb2_attach_arg *uaa = device_get_ivars(dev);
209 
210 	return (usb2_lookup_id_by_uaa(cdce_devs, sizeof(cdce_devs), uaa));
211 }
212 
213 static void
214 cdce_attach_post(struct usb2_ether *ue)
215 {
216 	/* no-op */
217 	return;
218 }
219 
220 static int
221 cdce_attach(device_t dev)
222 {
223 	struct cdce_softc *sc = device_get_softc(dev);
224 	struct usb2_ether *ue = &sc->sc_ue;
225 	struct usb2_attach_arg *uaa = device_get_ivars(dev);
226 	struct usb2_interface *iface;
227 	const struct usb2_cdc_union_descriptor *ud;
228 	const struct usb2_interface_descriptor *id;
229 	const struct usb2_cdc_ethernet_descriptor *ued;
230 	int error;
231 	uint8_t i;
232 	char eaddr_str[5 * ETHER_ADDR_LEN];	/* approx */
233 
234 	sc->sc_flags = USB_GET_DRIVER_INFO(uaa);
235 
236 	device_set_usb2_desc(dev);
237 
238 	mtx_init(&sc->sc_mtx, device_get_nameunit(dev), NULL, MTX_DEF);
239 
240 	if (sc->sc_flags & CDCE_FLAG_NO_UNION) {
241 		sc->sc_ifaces_index[0] = uaa->info.bIfaceIndex;
242 		sc->sc_ifaces_index[1] = uaa->info.bIfaceIndex;
243 		sc->sc_data_iface_no = 0;	/* not used */
244 		goto alloc_transfers;
245 	}
246 	ud = usb2_find_descriptor
247 	    (uaa->device, NULL, uaa->info.bIfaceIndex,
248 	    UDESC_CS_INTERFACE, 0 - 1, UDESCSUB_CDC_UNION, 0 - 1);
249 
250 	if ((ud == NULL) || (ud->bLength < sizeof(*ud))) {
251 		device_printf(dev, "no union descriptor!\n");
252 		goto detach;
253 	}
254 	sc->sc_data_iface_no = ud->bSlaveInterface[0];
255 
256 	for (i = 0;; i++) {
257 
258 		iface = usb2_get_iface(uaa->device, i);
259 
260 		if (iface) {
261 
262 			id = usb2_get_interface_descriptor(iface);
263 
264 			if (id && (id->bInterfaceNumber ==
265 			    sc->sc_data_iface_no)) {
266 				sc->sc_ifaces_index[0] = i;
267 				sc->sc_ifaces_index[1] = uaa->info.bIfaceIndex;
268 				usb2_set_parent_iface(uaa->device, i, uaa->info.bIfaceIndex);
269 				break;
270 			}
271 		} else {
272 			device_printf(dev, "no data interface found!\n");
273 			goto detach;
274 		}
275 	}
276 
277 	/*
278 	 * <quote>
279 	 *
280 	 *  The Data Class interface of a networking device shall have
281 	 *  a minimum of two interface settings. The first setting
282 	 *  (the default interface setting) includes no endpoints and
283 	 *  therefore no networking traffic is exchanged whenever the
284 	 *  default interface setting is selected. One or more
285 	 *  additional interface settings are used for normal
286 	 *  operation, and therefore each includes a pair of endpoints
287 	 *  (one IN, and one OUT) to exchange network traffic. Select
288 	 *  an alternate interface setting to initialize the network
289 	 *  aspects of the device and to enable the exchange of
290 	 *  network traffic.
291 	 *
292 	 * </quote>
293 	 *
294 	 * Some devices, most notably cable modems, include interface
295 	 * settings that have no IN or OUT endpoint, therefore loop
296 	 * through the list of all available interface settings
297 	 * looking for one with both IN and OUT endpoints.
298 	 */
299 
300 alloc_transfers:
301 
302 	for (i = 0; i != 32; i++) {
303 
304 		error = usb2_set_alt_interface_index
305 		    (uaa->device, sc->sc_ifaces_index[0], i);
306 
307 		if (error) {
308 			device_printf(dev, "no valid alternate "
309 			    "setting found!\n");
310 			goto detach;
311 		}
312 		error = usb2_transfer_setup
313 		    (uaa->device, sc->sc_ifaces_index,
314 		    sc->sc_xfer, cdce_config, CDCE_N_TRANSFER,
315 		    sc, &sc->sc_mtx);
316 
317 		if (error == 0) {
318 			break;
319 		}
320 	}
321 
322 	ued = usb2_find_descriptor
323 	    (uaa->device, NULL, uaa->info.bIfaceIndex,
324 	    UDESC_CS_INTERFACE, 0 - 1, UDESCSUB_CDC_ENF, 0 - 1);
325 
326 	if ((ued == NULL) || (ued->bLength < sizeof(*ued))) {
327 		error = USB_ERR_INVAL;
328 	} else {
329 		error = usb2_req_get_string_any(uaa->device, NULL,
330 		    eaddr_str, sizeof(eaddr_str), ued->iMacAddress);
331 	}
332 
333 	if (error) {
334 
335 		/* fake MAC address */
336 
337 		device_printf(dev, "faking MAC address\n");
338 		sc->sc_ue.ue_eaddr[0] = 0x2a;
339 		memcpy(&sc->sc_ue.ue_eaddr[1], &ticks, sizeof(uint32_t));
340 		sc->sc_ue.ue_eaddr[5] = device_get_unit(dev);
341 
342 	} else {
343 
344 		bzero(sc->sc_ue.ue_eaddr, sizeof(sc->sc_ue.ue_eaddr));
345 
346 		for (i = 0; i != (ETHER_ADDR_LEN * 2); i++) {
347 
348 			char c = eaddr_str[i];
349 
350 			if ('0' <= c && c <= '9')
351 				c -= '0';
352 			else if (c != 0)
353 				c -= 'A' - 10;
354 			else
355 				break;
356 
357 			c &= 0xf;
358 
359 			if ((i & 1) == 0)
360 				c <<= 4;
361 			sc->sc_ue.ue_eaddr[i / 2] |= c;
362 		}
363 
364 		if (uaa->usb2_mode == USB_MODE_DEVICE) {
365 			/*
366 			 * Do not use the same MAC address like the peer !
367 			 */
368 			sc->sc_ue.ue_eaddr[5] ^= 0xFF;
369 		}
370 	}
371 
372 	ue->ue_sc = sc;
373 	ue->ue_dev = dev;
374 	ue->ue_udev = uaa->device;
375 	ue->ue_mtx = &sc->sc_mtx;
376 	ue->ue_methods = &cdce_ue_methods;
377 
378 	error = usb2_ether_ifattach(ue);
379 	if (error) {
380 		device_printf(dev, "could not attach interface\n");
381 		goto detach;
382 	}
383 	return (0);			/* success */
384 
385 detach:
386 	cdce_detach(dev);
387 	return (ENXIO);			/* failure */
388 }
389 
390 static int
391 cdce_detach(device_t dev)
392 {
393 	struct cdce_softc *sc = device_get_softc(dev);
394 	struct usb2_ether *ue = &sc->sc_ue;
395 
396 	/* stop all USB transfers first */
397 	usb2_transfer_unsetup(sc->sc_xfer, CDCE_N_TRANSFER);
398 	usb2_ether_ifdetach(ue);
399 	mtx_destroy(&sc->sc_mtx);
400 
401 	return (0);
402 }
403 
404 static void
405 cdce_start(struct usb2_ether *ue)
406 {
407 	struct cdce_softc *sc = usb2_ether_getsc(ue);
408 
409 	/*
410 	 * Start the USB transfers, if not already started:
411 	 */
412 	usb2_transfer_start(sc->sc_xfer[CDCE_BULK_TX]);
413 	usb2_transfer_start(sc->sc_xfer[CDCE_BULK_RX]);
414 }
415 
416 static void
417 cdce_free_queue(struct mbuf **ppm, uint8_t n)
418 {
419 	uint8_t x;
420 	for (x = 0; x != n; x++) {
421 		if (ppm[x] != NULL) {
422 			m_freem(ppm[x]);
423 			ppm[x] = NULL;
424 		}
425 	}
426 }
427 
428 static void
429 cdce_bulk_write_callback(struct usb2_xfer *xfer)
430 {
431 	struct cdce_softc *sc = xfer->priv_sc;
432 	struct ifnet *ifp = usb2_ether_getifp(&sc->sc_ue);
433 	struct mbuf *m;
434 	struct mbuf *mt;
435 	uint32_t crc;
436 	uint8_t x;
437 
438 	DPRINTFN(1, "\n");
439 
440 	switch (USB_GET_STATE(xfer)) {
441 	case USB_ST_TRANSFERRED:
442 		DPRINTFN(11, "transfer complete: "
443 		    "%u bytes in %u frames\n", xfer->actlen,
444 		    xfer->aframes);
445 
446 		ifp->if_opackets++;
447 
448 		/* free all previous TX buffers */
449 		cdce_free_queue(sc->sc_tx_buf, CDCE_FRAMES_MAX);
450 
451 		/* FALLTHROUGH */
452 	case USB_ST_SETUP:
453 tr_setup:
454 		for (x = 0; x != CDCE_FRAMES_MAX; x++) {
455 
456 			IFQ_DRV_DEQUEUE(&ifp->if_snd, m);
457 
458 			if (m == NULL)
459 				break;
460 
461 			if (sc->sc_flags & CDCE_FLAG_ZAURUS) {
462 				/*
463 				 * Zaurus wants a 32-bit CRC appended
464 				 * to every frame
465 				 */
466 
467 				crc = cdce_m_crc32(m, 0, m->m_pkthdr.len);
468 				crc = htole32(crc);
469 
470 				if (!m_append(m, 4, (void *)&crc)) {
471 					m_freem(m);
472 					ifp->if_oerrors++;
473 					continue;
474 				}
475 			}
476 			if (m->m_len != m->m_pkthdr.len) {
477 				mt = m_defrag(m, M_DONTWAIT);
478 				if (mt == NULL) {
479 					m_freem(m);
480 					ifp->if_oerrors++;
481 					continue;
482 				}
483 				m = mt;
484 			}
485 			if (m->m_pkthdr.len > MCLBYTES) {
486 				m->m_pkthdr.len = MCLBYTES;
487 			}
488 			sc->sc_tx_buf[x] = m;
489 			xfer->frlengths[x] = m->m_len;
490 			usb2_set_frame_data(xfer, m->m_data, x);
491 
492 			/*
493 			 * If there's a BPF listener, bounce a copy of
494 			 * this frame to him:
495 			 */
496 			BPF_MTAP(ifp, m);
497 		}
498 		if (x != 0) {
499 			xfer->nframes = x;
500 			usb2_start_hardware(xfer);
501 		}
502 		break;
503 
504 	default:			/* Error */
505 		DPRINTFN(11, "transfer error, %s\n",
506 		    usb2_errstr(xfer->error));
507 
508 		/* free all previous TX buffers */
509 		cdce_free_queue(sc->sc_tx_buf, CDCE_FRAMES_MAX);
510 
511 		/* count output errors */
512 		ifp->if_oerrors++;
513 
514 		if (xfer->error != USB_ERR_CANCELLED) {
515 			/* try to clear stall first */
516 			xfer->flags.stall_pipe = 1;
517 			goto tr_setup;
518 		}
519 		break;
520 	}
521 }
522 
523 static int32_t
524 cdce_m_crc32_cb(void *arg, void *src, uint32_t count)
525 {
526 	uint32_t *p_crc = arg;
527 
528 	*p_crc = crc32_raw(src, count, *p_crc);
529 	return (0);
530 }
531 
532 static uint32_t
533 cdce_m_crc32(struct mbuf *m, uint32_t src_offset, uint32_t src_len)
534 {
535 	uint32_t crc = 0xFFFFFFFF;
536 	int error;
537 
538 	error = m_apply(m, src_offset, src_len, cdce_m_crc32_cb, &crc);
539 	return (crc ^ 0xFFFFFFFF);
540 }
541 
542 static void
543 cdce_init(struct usb2_ether *ue)
544 {
545 	struct cdce_softc *sc = usb2_ether_getsc(ue);
546 	struct ifnet *ifp = usb2_ether_getifp(ue);
547 
548 	CDCE_LOCK_ASSERT(sc, MA_OWNED);
549 
550 	ifp->if_drv_flags |= IFF_DRV_RUNNING;
551 
552 	/* start interrupt transfer */
553 	usb2_transfer_start(sc->sc_xfer[CDCE_INTR_RX]);
554 	usb2_transfer_start(sc->sc_xfer[CDCE_INTR_TX]);
555 
556 	/* stall data write direction, which depends on USB mode */
557 	usb2_transfer_set_stall(sc->sc_xfer[CDCE_BULK_TX]);
558 
559 	/* start data transfers */
560 	cdce_start(ue);
561 }
562 
563 static void
564 cdce_stop(struct usb2_ether *ue)
565 {
566 	struct cdce_softc *sc = usb2_ether_getsc(ue);
567 	struct ifnet *ifp = usb2_ether_getifp(ue);
568 
569 	CDCE_LOCK_ASSERT(sc, MA_OWNED);
570 
571 	ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
572 
573 	/*
574 	 * stop all the transfers, if not already stopped:
575 	 */
576 	usb2_transfer_stop(sc->sc_xfer[CDCE_BULK_RX]);
577 	usb2_transfer_stop(sc->sc_xfer[CDCE_BULK_TX]);
578 	usb2_transfer_stop(sc->sc_xfer[CDCE_INTR_RX]);
579 	usb2_transfer_stop(sc->sc_xfer[CDCE_INTR_TX]);
580 }
581 
582 static void
583 cdce_setmulti(struct usb2_ether *ue)
584 {
585 	/* no-op */
586 	return;
587 }
588 
589 static void
590 cdce_setpromisc(struct usb2_ether *ue)
591 {
592 	/* no-op */
593 	return;
594 }
595 
596 static int
597 cdce_suspend(device_t dev)
598 {
599 	device_printf(dev, "Suspending\n");
600 	return (0);
601 }
602 
603 static int
604 cdce_resume(device_t dev)
605 {
606 	device_printf(dev, "Resuming\n");
607 	return (0);
608 }
609 
610 static void
611 cdce_bulk_read_callback(struct usb2_xfer *xfer)
612 {
613 	struct cdce_softc *sc = xfer->priv_sc;
614 	struct mbuf *m;
615 	uint8_t x;
616 
617 	switch (USB_GET_STATE(xfer)) {
618 	case USB_ST_TRANSFERRED:
619 
620 		DPRINTF("received %u bytes in %u frames\n",
621 		    xfer->actlen, xfer->aframes);
622 
623 		for (x = 0; x != xfer->aframes; x++) {
624 
625 			m = sc->sc_rx_buf[x];
626 			sc->sc_rx_buf[x] = NULL;
627 
628 			/* Strip off CRC added by Zaurus, if any */
629 			if ((sc->sc_flags & CDCE_FLAG_ZAURUS) &&
630 			    (xfer->frlengths[x] >= 14))
631 				xfer->frlengths[x] -= 4;
632 
633 			if (xfer->frlengths[x] < sizeof(struct ether_header)) {
634 				m_freem(m);
635 				continue;
636 			}
637 			/* queue up mbuf */
638 			usb2_ether_rxmbuf(&sc->sc_ue, m, xfer->frlengths[x]);
639 		}
640 
641 		/* FALLTHROUGH */
642 	case USB_ST_SETUP:
643 		/*
644 		 * TODO: Implement support for multi frame transfers,
645 		 * when the USB hardware supports it.
646 		 */
647 		for (x = 0; x != 1; x++) {
648 			if (sc->sc_rx_buf[x] == NULL) {
649 				m = usb2_ether_newbuf();
650 				if (m == NULL)
651 					goto tr_stall;
652 				sc->sc_rx_buf[x] = m;
653 			} else {
654 				m = sc->sc_rx_buf[x];
655 			}
656 
657 			usb2_set_frame_data(xfer, m->m_data, x);
658 			xfer->frlengths[x] = m->m_len;
659 		}
660 		/* set number of frames and start hardware */
661 		xfer->nframes = x;
662 		usb2_start_hardware(xfer);
663 		/* flush any received frames */
664 		usb2_ether_rxflush(&sc->sc_ue);
665 		break;
666 
667 	default:			/* Error */
668 		DPRINTF("error = %s\n",
669 		    usb2_errstr(xfer->error));
670 
671 		if (xfer->error != USB_ERR_CANCELLED) {
672 tr_stall:
673 			/* try to clear stall first */
674 			xfer->flags.stall_pipe = 1;
675 			xfer->nframes = 0;
676 			usb2_start_hardware(xfer);
677 			break;
678 		}
679 
680 		/* need to free the RX-mbufs when we are cancelled */
681 		cdce_free_queue(sc->sc_rx_buf, CDCE_FRAMES_MAX);
682 		break;
683 	}
684 }
685 
686 static void
687 cdce_intr_read_callback(struct usb2_xfer *xfer)
688 {
689 	;				/* style fix */
690 	switch (USB_GET_STATE(xfer)) {
691 	case USB_ST_TRANSFERRED:
692 
693 		DPRINTF("Received %d bytes\n",
694 		    xfer->actlen);
695 
696 		/* TODO: decode some indications */
697 
698 		/* FALLTHROUGH */
699 	case USB_ST_SETUP:
700 tr_setup:
701 		xfer->frlengths[0] = xfer->max_data_length;
702 		usb2_start_hardware(xfer);
703 		break;
704 
705 	default:			/* Error */
706 		if (xfer->error != USB_ERR_CANCELLED) {
707 			/* start clear stall */
708 			xfer->flags.stall_pipe = 1;
709 			goto tr_setup;
710 		}
711 		break;
712 	}
713 }
714 
715 static void
716 cdce_intr_write_callback(struct usb2_xfer *xfer)
717 {
718 	;				/* style fix */
719 	switch (USB_GET_STATE(xfer)) {
720 	case USB_ST_TRANSFERRED:
721 
722 		DPRINTF("Transferred %d bytes\n", xfer->actlen);
723 
724 		/* FALLTHROUGH */
725 	case USB_ST_SETUP:
726 tr_setup:
727 #if 0
728 		xfer->frlengths[0] = XXX;
729 		usb2_start_hardware(xfer);
730 #endif
731 		break;
732 
733 	default:			/* Error */
734 		if (xfer->error != USB_ERR_CANCELLED) {
735 			/* start clear stall */
736 			xfer->flags.stall_pipe = 1;
737 			goto tr_setup;
738 		}
739 		break;
740 	}
741 }
742 
743 static int
744 cdce_handle_request(device_t dev,
745     const void *req, void **pptr, uint16_t *plen,
746     uint16_t offset, uint8_t is_complete)
747 {
748 	return (ENXIO);			/* use builtin handler */
749 }
750