]> CyberLeo.Net >> Repos - FreeBSD/releng/8.1.git/blob - sys/dev/usb/net/if_cdce.c
Copy stable/8 to releng/8.1 in preparation for 8.1-RC1.
[FreeBSD/releng/8.1.git] / sys / dev / usb / net / if_cdce.c
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 /*
44  * USB Network Control Model (NCM)
45  * http://www.usb.org/developers/devclass_docs/NCM10.zip
46  */
47
48 #include <sys/cdefs.h>
49 __FBSDID("$FreeBSD$");
50
51 #include <sys/stdint.h>
52 #include <sys/stddef.h>
53 #include <sys/param.h>
54 #include <sys/queue.h>
55 #include <sys/types.h>
56 #include <sys/systm.h>
57 #include <sys/kernel.h>
58 #include <sys/bus.h>
59 #include <sys/linker_set.h>
60 #include <sys/module.h>
61 #include <sys/lock.h>
62 #include <sys/mutex.h>
63 #include <sys/condvar.h>
64 #include <sys/sysctl.h>
65 #include <sys/sx.h>
66 #include <sys/unistd.h>
67 #include <sys/callout.h>
68 #include <sys/malloc.h>
69 #include <sys/priv.h>
70
71 #include <dev/usb/usb.h>
72 #include <dev/usb/usbdi.h>
73 #include <dev/usb/usbdi_util.h>
74 #include <dev/usb/usb_cdc.h>
75 #include "usbdevs.h"
76
77 #define USB_DEBUG_VAR cdce_debug
78 #include <dev/usb/usb_debug.h>
79 #include <dev/usb/usb_process.h>
80 #include "usb_if.h"
81
82 #include <dev/usb/net/usb_ethernet.h>
83 #include <dev/usb/net/if_cdcereg.h>
84
85 static device_probe_t cdce_probe;
86 static device_attach_t cdce_attach;
87 static device_detach_t cdce_detach;
88 static device_suspend_t cdce_suspend;
89 static device_resume_t cdce_resume;
90 static usb_handle_request_t cdce_handle_request;
91
92 static usb_callback_t cdce_bulk_write_callback;
93 static usb_callback_t cdce_bulk_read_callback;
94 static usb_callback_t cdce_intr_read_callback;
95 static usb_callback_t cdce_intr_write_callback;
96
97 #if CDCE_HAVE_NCM
98 static usb_callback_t cdce_ncm_bulk_write_callback;
99 static usb_callback_t cdce_ncm_bulk_read_callback;
100 #endif
101
102 static uether_fn_t cdce_attach_post;
103 static uether_fn_t cdce_init;
104 static uether_fn_t cdce_stop;
105 static uether_fn_t cdce_start;
106 static uether_fn_t cdce_setmulti;
107 static uether_fn_t cdce_setpromisc;
108
109 static uint32_t cdce_m_crc32(struct mbuf *, uint32_t, uint32_t);
110
111 #ifdef USB_DEBUG
112 static int cdce_debug = 0;
113
114 SYSCTL_NODE(_hw_usb, OID_AUTO, cdce, CTLFLAG_RW, 0, "USB CDC-Ethernet");
115 SYSCTL_INT(_hw_usb_cdce, OID_AUTO, debug, CTLFLAG_RW, &cdce_debug, 0,
116     "Debug level");
117 #endif
118
119 static const struct usb_config cdce_config[CDCE_N_TRANSFER] = {
120
121         [CDCE_BULK_RX] = {
122                 .type = UE_BULK,
123                 .endpoint = UE_ADDR_ANY,
124                 .direction = UE_DIR_RX,
125                 .if_index = 0,
126                 .frames = CDCE_FRAMES_MAX,
127                 .bufsize = (CDCE_FRAMES_MAX * MCLBYTES),
128                 .flags = {.pipe_bof = 1,.short_frames_ok = 1,.short_xfer_ok = 1,.ext_buffer = 1,},
129                 .callback = cdce_bulk_read_callback,
130                 .timeout = 0,   /* no timeout */
131                 .usb_mode = USB_MODE_DUAL,      /* both modes */
132         },
133
134         [CDCE_BULK_TX] = {
135                 .type = UE_BULK,
136                 .endpoint = UE_ADDR_ANY,
137                 .direction = UE_DIR_TX,
138                 .if_index = 0,
139                 .frames = CDCE_FRAMES_MAX,
140                 .bufsize = (CDCE_FRAMES_MAX * MCLBYTES),
141                 .flags = {.pipe_bof = 1,.force_short_xfer = 1,.ext_buffer = 1,},
142                 .callback = cdce_bulk_write_callback,
143                 .timeout = 10000,       /* 10 seconds */
144                 .usb_mode = USB_MODE_DUAL,      /* both modes */
145         },
146
147         [CDCE_INTR_RX] = {
148                 .type = UE_INTERRUPT,
149                 .endpoint = UE_ADDR_ANY,
150                 .direction = UE_DIR_RX,
151                 .if_index = 1,
152                 .bufsize = CDCE_IND_SIZE_MAX,
153                 .flags = {.pipe_bof = 1,.short_xfer_ok = 1,.no_pipe_ok = 1,},
154                 .callback = cdce_intr_read_callback,
155                 .timeout = 0,
156                 .usb_mode = USB_MODE_HOST,
157         },
158
159         [CDCE_INTR_TX] = {
160                 .type = UE_INTERRUPT,
161                 .endpoint = UE_ADDR_ANY,
162                 .direction = UE_DIR_TX,
163                 .if_index = 1,
164                 .bufsize = CDCE_IND_SIZE_MAX,
165                 .flags = {.pipe_bof = 1,.force_short_xfer = 1,.no_pipe_ok = 1,},
166                 .callback = cdce_intr_write_callback,
167                 .timeout = 10000,       /* 10 seconds */
168                 .usb_mode = USB_MODE_DEVICE,
169         },
170 };
171
172 #if CDCE_HAVE_NCM
173 static const struct usb_config cdce_ncm_config[CDCE_N_TRANSFER] = {
174
175         [CDCE_BULK_RX] = {
176                 .type = UE_BULK,
177                 .endpoint = UE_ADDR_ANY,
178                 .direction = UE_DIR_RX,
179                 .if_index = 0,
180                 .frames = CDCE_NCM_RX_FRAMES_MAX,
181                 .bufsize = (CDCE_NCM_RX_FRAMES_MAX * CDCE_NCM_RX_MAXLEN),
182                 .flags = {.pipe_bof = 1,.short_frames_ok = 1,.short_xfer_ok = 1,},
183                 .callback = cdce_ncm_bulk_read_callback,
184                 .timeout = 0,   /* no timeout */
185                 .usb_mode = USB_MODE_DUAL,      /* both modes */
186         },
187
188         [CDCE_BULK_TX] = {
189                 .type = UE_BULK,
190                 .endpoint = UE_ADDR_ANY,
191                 .direction = UE_DIR_TX,
192                 .if_index = 0,
193                 .frames = CDCE_NCM_TX_FRAMES_MAX,
194                 .bufsize = (CDCE_NCM_TX_FRAMES_MAX * CDCE_NCM_TX_MAXLEN),
195                 .flags = {.pipe_bof = 1,.force_short_xfer = 1,},
196                 .callback = cdce_ncm_bulk_write_callback,
197                 .timeout = 10000,       /* 10 seconds */
198                 .usb_mode = USB_MODE_DUAL,      /* both modes */
199         },
200
201         [CDCE_INTR_RX] = {
202                 .type = UE_INTERRUPT,
203                 .endpoint = UE_ADDR_ANY,
204                 .direction = UE_DIR_RX,
205                 .if_index = 1,
206                 .bufsize = CDCE_IND_SIZE_MAX,
207                 .flags = {.pipe_bof = 1,.short_xfer_ok = 1,.no_pipe_ok = 1,},
208                 .callback = cdce_intr_read_callback,
209                 .timeout = 0,
210                 .usb_mode = USB_MODE_HOST,
211         },
212
213         [CDCE_INTR_TX] = {
214                 .type = UE_INTERRUPT,
215                 .endpoint = UE_ADDR_ANY,
216                 .direction = UE_DIR_TX,
217                 .if_index = 1,
218                 .bufsize = CDCE_IND_SIZE_MAX,
219                 .flags = {.pipe_bof = 1,.force_short_xfer = 1,.no_pipe_ok = 1,},
220                 .callback = cdce_intr_write_callback,
221                 .timeout = 10000,       /* 10 seconds */
222                 .usb_mode = USB_MODE_DEVICE,
223         },
224 };
225 #endif
226
227 static device_method_t cdce_methods[] = {
228         /* USB interface */
229         DEVMETHOD(usb_handle_request, cdce_handle_request),
230
231         /* Device interface */
232         DEVMETHOD(device_probe, cdce_probe),
233         DEVMETHOD(device_attach, cdce_attach),
234         DEVMETHOD(device_detach, cdce_detach),
235         DEVMETHOD(device_suspend, cdce_suspend),
236         DEVMETHOD(device_resume, cdce_resume),
237
238         {0, 0}
239 };
240
241 static driver_t cdce_driver = {
242         .name = "cdce",
243         .methods = cdce_methods,
244         .size = sizeof(struct cdce_softc),
245 };
246
247 static devclass_t cdce_devclass;
248
249 DRIVER_MODULE(cdce, uhub, cdce_driver, cdce_devclass, NULL, 0);
250 MODULE_VERSION(cdce, 1);
251 MODULE_DEPEND(cdce, uether, 1, 1, 1);
252 MODULE_DEPEND(cdce, usb, 1, 1, 1);
253 MODULE_DEPEND(cdce, ether, 1, 1, 1);
254
255 static const struct usb_ether_methods cdce_ue_methods = {
256         .ue_attach_post = cdce_attach_post,
257         .ue_start = cdce_start,
258         .ue_init = cdce_init,
259         .ue_stop = cdce_stop,
260         .ue_setmulti = cdce_setmulti,
261         .ue_setpromisc = cdce_setpromisc,
262 };
263
264 static const struct usb_device_id cdce_devs[] = {
265         {USB_VPI(USB_VENDOR_ACERLABS, USB_PRODUCT_ACERLABS_M5632, CDCE_FLAG_NO_UNION)},
266         {USB_VPI(USB_VENDOR_AMBIT, USB_PRODUCT_AMBIT_NTL_250, CDCE_FLAG_NO_UNION)},
267         {USB_VPI(USB_VENDOR_COMPAQ, USB_PRODUCT_COMPAQ_IPAQLINUX, CDCE_FLAG_NO_UNION)},
268         {USB_VPI(USB_VENDOR_GMATE, USB_PRODUCT_GMATE_YP3X00, CDCE_FLAG_NO_UNION)},
269         {USB_VPI(USB_VENDOR_MOTOROLA2, USB_PRODUCT_MOTOROLA2_USBLAN, CDCE_FLAG_ZAURUS | CDCE_FLAG_NO_UNION)},
270         {USB_VPI(USB_VENDOR_MOTOROLA2, USB_PRODUCT_MOTOROLA2_USBLAN2, CDCE_FLAG_ZAURUS | CDCE_FLAG_NO_UNION)},
271         {USB_VPI(USB_VENDOR_NETCHIP, USB_PRODUCT_NETCHIP_ETHERNETGADGET, CDCE_FLAG_NO_UNION)},
272         {USB_VPI(USB_VENDOR_PROLIFIC, USB_PRODUCT_PROLIFIC_PL2501, CDCE_FLAG_NO_UNION)},
273         {USB_VPI(USB_VENDOR_SHARP, USB_PRODUCT_SHARP_SL5500, CDCE_FLAG_ZAURUS)},
274         {USB_VPI(USB_VENDOR_SHARP, USB_PRODUCT_SHARP_SL5600, CDCE_FLAG_ZAURUS | CDCE_FLAG_NO_UNION)},
275         {USB_VPI(USB_VENDOR_SHARP, USB_PRODUCT_SHARP_SLA300, CDCE_FLAG_ZAURUS | CDCE_FLAG_NO_UNION)},
276         {USB_VPI(USB_VENDOR_SHARP, USB_PRODUCT_SHARP_SLC700, CDCE_FLAG_ZAURUS | CDCE_FLAG_NO_UNION)},
277         {USB_VPI(USB_VENDOR_SHARP, USB_PRODUCT_SHARP_SLC750, CDCE_FLAG_ZAURUS | CDCE_FLAG_NO_UNION)},
278
279         {USB_IF_CSI(UICLASS_CDC, UISUBCLASS_ETHERNET_NETWORKING_CONTROL_MODEL, 0)},
280         {USB_IF_CSI(UICLASS_CDC, UISUBCLASS_MOBILE_DIRECT_LINE_MODEL, 0)},
281         {USB_IF_CSI(UICLASS_CDC, UISUBCLASS_NETWORK_CONTROL_MODEL, 0)},
282 };
283
284 #if CDCE_HAVE_NCM
285 /*------------------------------------------------------------------------*
286  *      cdce_ncm_init
287  *
288  * Return values:
289  * 0: Success
290  * Else: Failure
291  *------------------------------------------------------------------------*/
292 static uint8_t
293 cdce_ncm_init(struct cdce_softc *sc)
294 {
295         struct usb_ncm_parameters temp;
296         struct usb_device_request req;
297         uDWord value;
298         int err;
299
300         req.bmRequestType = UT_READ_CLASS_INTERFACE;
301         req.bRequest = UCDC_NCM_GET_NTB_PARAMETERS;
302         USETW(req.wValue, 0);
303         req.wIndex[0] = sc->sc_ifaces_index[1];
304         req.wIndex[1] = 0;
305         USETW(req.wLength, sizeof(temp));
306
307         err = usbd_do_request_flags(sc->sc_ue.ue_udev, NULL, &req,
308             &temp, 0, NULL, 1000 /* ms */);
309         if (err)
310                 return (1);
311
312         /* Read correct set of parameters according to device mode */
313
314         if (usbd_get_mode(sc->sc_ue.ue_udev) == USB_MODE_HOST) {
315                 sc->sc_ncm.rx_max = UGETW(temp.dwNtbInMaxSize);
316                 sc->sc_ncm.tx_max = UGETW(temp.dwNtbOutMaxSize);
317                 sc->sc_ncm.tx_remainder = UGETW(temp.wNdpOutPayloadRemainder);
318                 sc->sc_ncm.tx_modulus = UGETW(temp.wNdpOutDivisor);
319                 sc->sc_ncm.tx_struct_align = UGETW(temp.wNdpOutAlignment);
320         } else {
321                 sc->sc_ncm.rx_max = UGETW(temp.dwNtbOutMaxSize);
322                 sc->sc_ncm.tx_max = UGETW(temp.dwNtbInMaxSize);
323                 sc->sc_ncm.tx_remainder = UGETW(temp.wNdpInPayloadRemainder);
324                 sc->sc_ncm.tx_modulus = UGETW(temp.wNdpInDivisor);
325                 sc->sc_ncm.tx_struct_align = UGETW(temp.wNdpInAlignment);
326         }
327
328         /* Verify maximum receive length */
329
330         if (err || (sc->sc_ncm.rx_max < 32) || 
331             (sc->sc_ncm.rx_max > CDCE_NCM_RX_MAXLEN)) {
332                 DPRINTFN(1, "Using default maximum receive length\n");
333                 sc->sc_ncm.rx_max = CDCE_NCM_RX_MAXLEN;
334         }
335
336         /* Verify maximum transmit length */
337
338         if (err || (sc->sc_ncm.tx_max < 32) ||
339             (sc->sc_ncm.tx_max > CDCE_NCM_TX_MAXLEN)) {
340                 DPRINTFN(1, "Using default maximum transmit length\n");
341                 sc->sc_ncm.tx_max = CDCE_NCM_TX_MAXLEN;
342         }
343
344         /* 
345          * Verify that the structure alignment is:
346          * - power of two
347          * - not greater than the maximum transmit length
348          * - not less than four bytes
349          */
350         if (err || (sc->sc_ncm.tx_struct_align < 4) ||
351             (sc->sc_ncm.tx_struct_align != 
352              ((-sc->sc_ncm.tx_struct_align) & sc->sc_ncm.tx_struct_align)) ||
353             (sc->sc_ncm.tx_struct_align >= sc->sc_ncm.tx_max)) {
354                 DPRINTFN(1, "Using default other alignment: 4 bytes\n");
355                 sc->sc_ncm.tx_struct_align = 4;
356         }
357
358         /* 
359          * Verify that the payload alignment is:
360          * - power of two
361          * - not greater than the maximum transmit length
362          * - not less than four bytes
363          */
364         if (err || (sc->sc_ncm.tx_modulus < 4) ||
365             (sc->sc_ncm.tx_modulus !=
366              ((-sc->sc_ncm.tx_modulus) & sc->sc_ncm.tx_modulus)) ||
367             (sc->sc_ncm.tx_modulus >= sc->sc_ncm.tx_max)) {
368                 DPRINTFN(1, "Using default transmit modulus: 4 bytes\n");
369                 sc->sc_ncm.tx_modulus = 4;
370         }
371
372         /* Verify that the payload remainder */
373
374         if (err || (sc->sc_ncm.tx_remainder >= sc->sc_ncm.tx_modulus)) {
375                 DPRINTFN(1, "Using default transmit remainder: 0 bytes\n");
376                 sc->sc_ncm.tx_remainder = 0;
377         }
378
379         /* Additional configuration, will fail in device side mode, which is OK. */
380
381         req.bmRequestType = UT_WRITE_CLASS_INTERFACE;
382         req.bRequest = UCDC_NCM_SET_NTB_INPUT_SIZE;
383         USETW(req.wValue, 0);
384         req.wIndex[0] = sc->sc_ifaces_index[1];
385         req.wIndex[1] = 0;
386         USETW(req.wLength, 4);
387         USETDW(value, sc->sc_ncm.rx_max);
388
389         err = usbd_do_request_flags(sc->sc_ue.ue_udev, NULL, &req,
390             &value, 0, NULL, 1000 /* ms */);
391         if (err) {
392                 DPRINTFN(1, "Setting input size "
393                     "to %u failed.\n", sc->sc_ncm.rx_max);
394         }
395
396         req.bmRequestType = UT_WRITE_CLASS_INTERFACE;
397         req.bRequest = UCDC_NCM_SET_CRC_MODE;
398         USETW(req.wValue, 0);   /* no CRC */
399         req.wIndex[0] = sc->sc_ifaces_index[1];
400         req.wIndex[1] = 0;
401         USETW(req.wLength, 0);
402
403         err = usbd_do_request_flags(sc->sc_ue.ue_udev, NULL, &req,
404             NULL, 0, NULL, 1000 /* ms */);
405         if (err) {
406                 DPRINTFN(1, "Setting CRC mode to off failed.\n");
407         }
408
409         req.bmRequestType = UT_WRITE_CLASS_INTERFACE;
410         req.bRequest = UCDC_NCM_SET_NTB_FORMAT;
411         USETW(req.wValue, 0);   /* NTB-16 */
412         req.wIndex[0] = sc->sc_ifaces_index[1];
413         req.wIndex[1] = 0;
414         USETW(req.wLength, 0);
415
416         err = usbd_do_request_flags(sc->sc_ue.ue_udev, NULL, &req,
417             NULL, 0, NULL, 1000 /* ms */);
418         if (err) {
419                 DPRINTFN(1, "Setting NTB format to 16-bit failed.\n");
420         }
421
422         return (0);             /* success */
423 }
424 #endif
425
426 static int
427 cdce_probe(device_t dev)
428 {
429         struct usb_attach_arg *uaa = device_get_ivars(dev);
430
431         return (usbd_lookup_id_by_uaa(cdce_devs, sizeof(cdce_devs), uaa));
432 }
433
434 static void
435 cdce_attach_post(struct usb_ether *ue)
436 {
437         /* no-op */
438         return;
439 }
440
441 static int
442 cdce_attach(device_t dev)
443 {
444         struct cdce_softc *sc = device_get_softc(dev);
445         struct usb_ether *ue = &sc->sc_ue;
446         struct usb_attach_arg *uaa = device_get_ivars(dev);
447         struct usb_interface *iface;
448         const struct usb_cdc_union_descriptor *ud;
449         const struct usb_interface_descriptor *id;
450         const struct usb_cdc_ethernet_descriptor *ued;
451         const struct usb_config *pcfg;
452         int error;
453         uint8_t i;
454         uint8_t data_iface_no;
455         char eaddr_str[5 * ETHER_ADDR_LEN];     /* approx */
456
457         sc->sc_flags = USB_GET_DRIVER_INFO(uaa);
458         sc->sc_ue.ue_udev = uaa->device;
459
460         device_set_usb_desc(dev);
461
462         mtx_init(&sc->sc_mtx, device_get_nameunit(dev), NULL, MTX_DEF);
463
464         ud = usbd_find_descriptor
465             (uaa->device, NULL, uaa->info.bIfaceIndex,
466             UDESC_CS_INTERFACE, 0 - 1, UDESCSUB_CDC_UNION, 0 - 1);
467
468         if ((ud == NULL) || (ud->bLength < sizeof(*ud)) ||
469             (sc->sc_flags & CDCE_FLAG_NO_UNION)) {
470                 DPRINTFN(1, "No union descriptor!\n");
471                 sc->sc_ifaces_index[0] = uaa->info.bIfaceIndex;
472                 sc->sc_ifaces_index[1] = uaa->info.bIfaceIndex;
473                 goto alloc_transfers;
474         }
475         data_iface_no = ud->bSlaveInterface[0];
476
477         for (i = 0;; i++) {
478
479                 iface = usbd_get_iface(uaa->device, i);
480
481                 if (iface) {
482
483                         id = usbd_get_interface_descriptor(iface);
484
485                         if (id && (id->bInterfaceNumber == data_iface_no)) {
486                                 sc->sc_ifaces_index[0] = i;
487                                 sc->sc_ifaces_index[1] = uaa->info.bIfaceIndex;
488                                 usbd_set_parent_iface(uaa->device, i, uaa->info.bIfaceIndex);
489                                 break;
490                         }
491                 } else {
492                         device_printf(dev, "no data interface found\n");
493                         goto detach;
494                 }
495         }
496
497         /*
498          * <quote>
499          *
500          *  The Data Class interface of a networking device shall have
501          *  a minimum of two interface settings. The first setting
502          *  (the default interface setting) includes no endpoints and
503          *  therefore no networking traffic is exchanged whenever the
504          *  default interface setting is selected. One or more
505          *  additional interface settings are used for normal
506          *  operation, and therefore each includes a pair of endpoints
507          *  (one IN, and one OUT) to exchange network traffic. Select
508          *  an alternate interface setting to initialize the network
509          *  aspects of the device and to enable the exchange of
510          *  network traffic.
511          *
512          * </quote>
513          *
514          * Some devices, most notably cable modems, include interface
515          * settings that have no IN or OUT endpoint, therefore loop
516          * through the list of all available interface settings
517          * looking for one with both IN and OUT endpoints.
518          */
519
520 alloc_transfers:
521
522         pcfg = cdce_config;     /* Default Configuration */
523
524         for (i = 0; i != 32; i++) {
525
526                 error = usbd_set_alt_interface_index(uaa->device,
527                     sc->sc_ifaces_index[0], i);
528                 if (error)
529                         break;
530 #if CDCE_HAVE_NCM
531                 if ((i == 0) && (cdce_ncm_init(sc) == 0))
532                         pcfg = cdce_ncm_config;
533 #endif
534                 error = usbd_transfer_setup(uaa->device,
535                     sc->sc_ifaces_index, sc->sc_xfer,
536                     pcfg, CDCE_N_TRANSFER, sc, &sc->sc_mtx);
537
538                 if (error == 0)
539                         break;
540         }
541
542         if (error || (i == 32)) {
543                 device_printf(dev, "No valid alternate "
544                     "setting found\n");
545                 goto detach;
546         }
547
548         ued = usbd_find_descriptor
549             (uaa->device, NULL, uaa->info.bIfaceIndex,
550             UDESC_CS_INTERFACE, 0 - 1, UDESCSUB_CDC_ENF, 0 - 1);
551
552         if ((ued == NULL) || (ued->bLength < sizeof(*ued))) {
553                 error = USB_ERR_INVAL;
554         } else {
555                 error = usbd_req_get_string_any(uaa->device, NULL, 
556                     eaddr_str, sizeof(eaddr_str), ued->iMacAddress);
557         }
558
559         if (error) {
560
561                 /* fake MAC address */
562
563                 device_printf(dev, "faking MAC address\n");
564                 sc->sc_ue.ue_eaddr[0] = 0x2a;
565                 memcpy(&sc->sc_ue.ue_eaddr[1], &ticks, sizeof(uint32_t));
566                 sc->sc_ue.ue_eaddr[5] = device_get_unit(dev);
567
568         } else {
569
570                 bzero(sc->sc_ue.ue_eaddr, sizeof(sc->sc_ue.ue_eaddr));
571
572                 for (i = 0; i != (ETHER_ADDR_LEN * 2); i++) {
573
574                         char c = eaddr_str[i];
575
576                         if ('0' <= c && c <= '9')
577                                 c -= '0';
578                         else if (c != 0)
579                                 c -= 'A' - 10;
580                         else
581                                 break;
582
583                         c &= 0xf;
584
585                         if ((i & 1) == 0)
586                                 c <<= 4;
587                         sc->sc_ue.ue_eaddr[i / 2] |= c;
588                 }
589
590                 if (uaa->usb_mode == USB_MODE_DEVICE) {
591                         /*
592                          * Do not use the same MAC address like the peer !
593                          */
594                         sc->sc_ue.ue_eaddr[5] ^= 0xFF;
595                 }
596         }
597
598         ue->ue_sc = sc;
599         ue->ue_dev = dev;
600         ue->ue_udev = uaa->device;
601         ue->ue_mtx = &sc->sc_mtx;
602         ue->ue_methods = &cdce_ue_methods;
603
604         error = uether_ifattach(ue);
605         if (error) {
606                 device_printf(dev, "could not attach interface\n");
607                 goto detach;
608         }
609         return (0);                     /* success */
610
611 detach:
612         cdce_detach(dev);
613         return (ENXIO);                 /* failure */
614 }
615
616 static int
617 cdce_detach(device_t dev)
618 {
619         struct cdce_softc *sc = device_get_softc(dev);
620         struct usb_ether *ue = &sc->sc_ue;
621
622         /* stop all USB transfers first */
623         usbd_transfer_unsetup(sc->sc_xfer, CDCE_N_TRANSFER);
624         uether_ifdetach(ue);
625         mtx_destroy(&sc->sc_mtx);
626
627         return (0);
628 }
629
630 static void
631 cdce_start(struct usb_ether *ue)
632 {
633         struct cdce_softc *sc = uether_getsc(ue);
634
635         /*
636          * Start the USB transfers, if not already started:
637          */
638         usbd_transfer_start(sc->sc_xfer[CDCE_BULK_TX]);
639         usbd_transfer_start(sc->sc_xfer[CDCE_BULK_RX]);
640 }
641
642 static void
643 cdce_free_queue(struct mbuf **ppm, uint8_t n)
644 {
645         uint8_t x;
646         for (x = 0; x != n; x++) {
647                 if (ppm[x] != NULL) {
648                         m_freem(ppm[x]);
649                         ppm[x] = NULL;
650                 }
651         }
652 }
653
654 static void
655 cdce_bulk_write_callback(struct usb_xfer *xfer, usb_error_t error)
656 {
657         struct cdce_softc *sc = usbd_xfer_softc(xfer);
658         struct ifnet *ifp = uether_getifp(&sc->sc_ue);
659         struct mbuf *m;
660         struct mbuf *mt;
661         uint32_t crc;
662         uint8_t x;
663         int actlen, aframes;
664
665         usbd_xfer_status(xfer, &actlen, NULL, &aframes, NULL);
666
667         DPRINTFN(1, "\n");
668
669         switch (USB_GET_STATE(xfer)) {
670         case USB_ST_TRANSFERRED:
671                 DPRINTFN(11, "transfer complete: %u bytes in %u frames\n",
672                     actlen, aframes);
673
674                 ifp->if_opackets++;
675
676                 /* free all previous TX buffers */
677                 cdce_free_queue(sc->sc_tx_buf, CDCE_FRAMES_MAX);
678
679                 /* FALLTHROUGH */
680         case USB_ST_SETUP:
681 tr_setup:
682                 for (x = 0; x != CDCE_FRAMES_MAX; x++) {
683
684                         IFQ_DRV_DEQUEUE(&ifp->if_snd, m);
685
686                         if (m == NULL)
687                                 break;
688
689                         if (sc->sc_flags & CDCE_FLAG_ZAURUS) {
690                                 /*
691                                  * Zaurus wants a 32-bit CRC appended
692                                  * to every frame
693                                  */
694
695                                 crc = cdce_m_crc32(m, 0, m->m_pkthdr.len);
696                                 crc = htole32(crc);
697
698                                 if (!m_append(m, 4, (void *)&crc)) {
699                                         m_freem(m);
700                                         ifp->if_oerrors++;
701                                         continue;
702                                 }
703                         }
704                         if (m->m_len != m->m_pkthdr.len) {
705                                 mt = m_defrag(m, M_DONTWAIT);
706                                 if (mt == NULL) {
707                                         m_freem(m);
708                                         ifp->if_oerrors++;
709                                         continue;
710                                 }
711                                 m = mt;
712                         }
713                         if (m->m_pkthdr.len > MCLBYTES) {
714                                 m->m_pkthdr.len = MCLBYTES;
715                         }
716                         sc->sc_tx_buf[x] = m;
717                         usbd_xfer_set_frame_data(xfer, x, m->m_data, m->m_len);
718
719                         /*
720                          * If there's a BPF listener, bounce a copy of
721                          * this frame to him:
722                          */
723                         BPF_MTAP(ifp, m);
724                 }
725                 if (x != 0) {
726                         usbd_xfer_set_frames(xfer, x);
727
728                         usbd_transfer_submit(xfer);
729                 }
730                 break;
731
732         default:                        /* Error */
733                 DPRINTFN(11, "transfer error, %s\n",
734                     usbd_errstr(error));
735
736                 /* free all previous TX buffers */
737                 cdce_free_queue(sc->sc_tx_buf, CDCE_FRAMES_MAX);
738
739                 /* count output errors */
740                 ifp->if_oerrors++;
741
742                 if (error != USB_ERR_CANCELLED) {
743                         /* try to clear stall first */
744                         usbd_xfer_set_stall(xfer);
745                         goto tr_setup;
746                 }
747                 break;
748         }
749 }
750
751 static int32_t
752 cdce_m_crc32_cb(void *arg, void *src, uint32_t count)
753 {
754         uint32_t *p_crc = arg;
755
756         *p_crc = crc32_raw(src, count, *p_crc);
757         return (0);
758 }
759
760 static uint32_t
761 cdce_m_crc32(struct mbuf *m, uint32_t src_offset, uint32_t src_len)
762 {
763         uint32_t crc = 0xFFFFFFFF;
764         int error;
765
766         error = m_apply(m, src_offset, src_len, cdce_m_crc32_cb, &crc);
767         return (crc ^ 0xFFFFFFFF);
768 }
769
770 static void
771 cdce_init(struct usb_ether *ue)
772 {
773         struct cdce_softc *sc = uether_getsc(ue);
774         struct ifnet *ifp = uether_getifp(ue);
775
776         CDCE_LOCK_ASSERT(sc, MA_OWNED);
777
778         ifp->if_drv_flags |= IFF_DRV_RUNNING;
779
780         /* start interrupt transfer */
781         usbd_transfer_start(sc->sc_xfer[CDCE_INTR_RX]);
782         usbd_transfer_start(sc->sc_xfer[CDCE_INTR_TX]);
783
784         /* stall data write direction, which depends on USB mode */
785         usbd_xfer_set_stall(sc->sc_xfer[CDCE_BULK_TX]);
786
787         /* start data transfers */
788         cdce_start(ue);
789 }
790
791 static void
792 cdce_stop(struct usb_ether *ue)
793 {
794         struct cdce_softc *sc = uether_getsc(ue);
795         struct ifnet *ifp = uether_getifp(ue);
796
797         CDCE_LOCK_ASSERT(sc, MA_OWNED);
798
799         ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
800
801         /*
802          * stop all the transfers, if not already stopped:
803          */
804         usbd_transfer_stop(sc->sc_xfer[CDCE_BULK_RX]);
805         usbd_transfer_stop(sc->sc_xfer[CDCE_BULK_TX]);
806         usbd_transfer_stop(sc->sc_xfer[CDCE_INTR_RX]);
807         usbd_transfer_stop(sc->sc_xfer[CDCE_INTR_TX]);
808 }
809
810 static void
811 cdce_setmulti(struct usb_ether *ue)
812 {
813         /* no-op */
814         return;
815 }
816
817 static void
818 cdce_setpromisc(struct usb_ether *ue)
819 {
820         /* no-op */
821         return;
822 }
823
824 static int
825 cdce_suspend(device_t dev)
826 {
827         device_printf(dev, "Suspending\n");
828         return (0);
829 }
830
831 static int
832 cdce_resume(device_t dev)
833 {
834         device_printf(dev, "Resuming\n");
835         return (0);
836 }
837
838 static void
839 cdce_bulk_read_callback(struct usb_xfer *xfer, usb_error_t error)
840 {
841         struct cdce_softc *sc = usbd_xfer_softc(xfer);
842         struct mbuf *m;
843         uint8_t x;
844         int actlen, aframes, len;
845
846         usbd_xfer_status(xfer, &actlen, NULL, &aframes, NULL);
847
848         switch (USB_GET_STATE(xfer)) {
849         case USB_ST_TRANSFERRED:
850
851                 DPRINTF("received %u bytes in %u frames\n", actlen, aframes);
852
853                 for (x = 0; x != aframes; x++) {
854
855                         m = sc->sc_rx_buf[x];
856                         sc->sc_rx_buf[x] = NULL;
857                         len = usbd_xfer_frame_len(xfer, x);
858
859                         /* Strip off CRC added by Zaurus, if any */
860                         if ((sc->sc_flags & CDCE_FLAG_ZAURUS) && len >= 14)
861                                 len -= 4;
862
863                         if (len < sizeof(struct ether_header)) {
864                                 m_freem(m);
865                                 continue;
866                         }
867                         /* queue up mbuf */
868                         uether_rxmbuf(&sc->sc_ue, m, len);
869                 }
870
871                 /* FALLTHROUGH */
872         case USB_ST_SETUP:
873                 /* 
874                  * TODO: Implement support for multi frame transfers,
875                  * when the USB hardware supports it.
876                  */
877                 for (x = 0; x != 1; x++) {
878                         if (sc->sc_rx_buf[x] == NULL) {
879                                 m = uether_newbuf();
880                                 if (m == NULL)
881                                         goto tr_stall;
882                                 sc->sc_rx_buf[x] = m;
883                         } else {
884                                 m = sc->sc_rx_buf[x];
885                         }
886
887                         usbd_xfer_set_frame_data(xfer, x, m->m_data, m->m_len);
888                 }
889                 /* set number of frames and start hardware */
890                 usbd_xfer_set_frames(xfer, x);
891                 usbd_transfer_submit(xfer);
892                 /* flush any received frames */
893                 uether_rxflush(&sc->sc_ue);
894                 break;
895
896         default:                        /* Error */
897                 DPRINTF("error = %s\n",
898                     usbd_errstr(error));
899
900                 if (error != USB_ERR_CANCELLED) {
901 tr_stall:
902                         /* try to clear stall first */
903                         usbd_xfer_set_stall(xfer);
904                         usbd_xfer_set_frames(xfer, 0);
905                         usbd_transfer_submit(xfer);
906                         break;
907                 }
908
909                 /* need to free the RX-mbufs when we are cancelled */
910                 cdce_free_queue(sc->sc_rx_buf, CDCE_FRAMES_MAX);
911                 break;
912         }
913 }
914
915 static void
916 cdce_intr_read_callback(struct usb_xfer *xfer, usb_error_t error)
917 {
918         int actlen;
919
920         usbd_xfer_status(xfer, &actlen, NULL, NULL, NULL);
921
922         switch (USB_GET_STATE(xfer)) {
923         case USB_ST_TRANSFERRED:
924
925                 DPRINTF("Received %d bytes\n", actlen);
926
927                 /* TODO: decode some indications */
928
929                 /* FALLTHROUGH */
930         case USB_ST_SETUP:
931 tr_setup:
932                 usbd_xfer_set_frame_len(xfer, 0, usbd_xfer_max_len(xfer));
933                 usbd_transfer_submit(xfer);
934                 break;
935
936         default:                        /* Error */
937                 if (error != USB_ERR_CANCELLED) {
938                         /* start clear stall */
939                         usbd_xfer_set_stall(xfer);
940                         goto tr_setup;
941                 }
942                 break;
943         }
944 }
945
946 static void
947 cdce_intr_write_callback(struct usb_xfer *xfer, usb_error_t error)
948 {
949         int actlen;
950
951         usbd_xfer_status(xfer, &actlen, NULL, NULL, NULL);
952
953         switch (USB_GET_STATE(xfer)) {
954         case USB_ST_TRANSFERRED:
955
956                 DPRINTF("Transferred %d bytes\n", actlen);
957
958                 /* FALLTHROUGH */
959         case USB_ST_SETUP:
960 tr_setup:
961 #if 0
962                 usbd_xfer_set_frame_len(xfer, 0, XXX);
963                 usbd_transfer_submit(xfer);
964 #endif
965                 break;
966
967         default:                        /* Error */
968                 if (error != USB_ERR_CANCELLED) {
969                         /* start clear stall */
970                         usbd_xfer_set_stall(xfer);
971                         goto tr_setup;
972                 }
973                 break;
974         }
975 }
976
977 static int
978 cdce_handle_request(device_t dev,
979     const void *req, void **pptr, uint16_t *plen,
980     uint16_t offset, uint8_t *pstate)
981 {
982         return (ENXIO);                 /* use builtin handler */
983 }
984
985 #if CDCE_HAVE_NCM
986 static uint8_t
987 cdce_ncm_fill_tx_frames(struct usb_xfer *xfer, uint8_t index)
988 {
989         struct cdce_softc *sc = usbd_xfer_softc(xfer);
990         struct ifnet *ifp = uether_getifp(&sc->sc_ue);
991         struct usb_page_cache *pc = usbd_xfer_get_frame(xfer, index);
992         struct mbuf *m;
993         uint32_t rem;
994         uint32_t offset;
995         uint32_t last_offset;
996         uint32_t n;
997
998         usbd_xfer_set_frame_offset(xfer, index * CDCE_NCM_TX_MAXLEN, index);
999
1000         offset = sizeof(sc->sc_ncm.hdr) +
1001             sizeof(sc->sc_ncm.dpt) + sizeof(sc->sc_ncm.dp);
1002
1003         /* Store last valid offset before alignment */
1004         last_offset = offset;
1005
1006         /* Align offset correctly */
1007         offset = sc->sc_ncm.tx_remainder -
1008             ((0UL - offset) & (0UL - sc->sc_ncm.tx_modulus));
1009
1010         for (n = 0; n != CDCE_NCM_SUBFRAMES_MAX; n++) {
1011
1012                 /* check if end of transmit buffer is reached */
1013
1014                 if (offset >= sc->sc_ncm.tx_max)
1015                         break;
1016
1017                 /* compute maximum buffer size */
1018
1019                 rem = sc->sc_ncm.tx_max - offset;
1020
1021                 IFQ_DRV_DEQUEUE(&(ifp->if_snd), m);
1022
1023                 if (m == NULL)
1024                         break;
1025
1026                 if (m->m_pkthdr.len > rem) {
1027                         if (n == 0) {
1028                                 /* The frame won't fit in our buffer */
1029                                 DPRINTFN(1, "Frame too big to be transmitted!\n");
1030                                 m_freem(m);
1031                                 ifp->if_oerrors++;
1032                                 n--;
1033                                 continue;
1034                         }
1035                         /* Wait till next buffer becomes ready */
1036                         IFQ_DRV_PREPEND(&(ifp->if_snd), m);
1037                         break;
1038                 }
1039                 usbd_m_copy_in(pc, offset, m, 0, m->m_pkthdr.len);
1040
1041                 USETW(sc->sc_ncm.dp[n].wFrameLength, m->m_pkthdr.len);
1042                 USETW(sc->sc_ncm.dp[n].wFrameIndex, offset);
1043
1044                 /* Update offset */
1045                 offset += m->m_pkthdr.len;
1046
1047                 /* Store last valid offset before alignment */
1048                 last_offset = offset;
1049
1050                 /* Align offset correctly */
1051                 offset = sc->sc_ncm.tx_remainder - 
1052                     ((0UL - offset) & (0UL - sc->sc_ncm.tx_modulus));
1053
1054                 /*
1055                  * If there's a BPF listener, bounce a copy
1056                  * of this frame to him:
1057                  */
1058                 BPF_MTAP(ifp, m);
1059
1060                 /* Free mbuf */
1061
1062                 m_freem(m);
1063
1064                 /* Pre-increment interface counter */
1065
1066                 ifp->if_opackets++;
1067         }
1068
1069         if (n == 0)
1070                 return (1);
1071
1072         rem = (sizeof(sc->sc_ncm.dpt) + (4 * n) + 4);
1073
1074         USETW(sc->sc_ncm.dpt.wLength, rem);
1075
1076         /* zero the rest of the data pointer entries */
1077         for (; n != CDCE_NCM_SUBFRAMES_MAX; n++) {
1078                 USETW(sc->sc_ncm.dp[n].wFrameLength, 0);
1079                 USETW(sc->sc_ncm.dp[n].wFrameIndex, 0);
1080         }
1081
1082         /* set frame length */
1083         usbd_xfer_set_frame_len(xfer, index, last_offset);
1084
1085         /* Fill out 16-bit header */
1086         sc->sc_ncm.hdr.dwSignature[0] = 'N';
1087         sc->sc_ncm.hdr.dwSignature[1] = 'C';
1088         sc->sc_ncm.hdr.dwSignature[2] = 'M';
1089         sc->sc_ncm.hdr.dwSignature[3] = 'H';
1090         USETW(sc->sc_ncm.hdr.wHeaderLength, sizeof(sc->sc_ncm.hdr));
1091         USETW(sc->sc_ncm.hdr.wBlockLength, last_offset);
1092         USETW(sc->sc_ncm.hdr.wSequence, sc->sc_ncm.tx_seq);
1093         USETW(sc->sc_ncm.hdr.wDptIndex, sizeof(sc->sc_ncm.hdr));
1094
1095         sc->sc_ncm.tx_seq++;
1096
1097         /* Fill out 16-bit frame table header */
1098         sc->sc_ncm.dpt.dwSignature[0] = 'N';
1099         sc->sc_ncm.dpt.dwSignature[1] = 'C';
1100         sc->sc_ncm.dpt.dwSignature[2] = 'M';
1101         sc->sc_ncm.dpt.dwSignature[3] = '0';
1102         USETW(sc->sc_ncm.dpt.wNextNdpIndex, 0);         /* reserved */
1103
1104         usbd_copy_in(pc, 0, &(sc->sc_ncm.hdr), sizeof(sc->sc_ncm.hdr));
1105         usbd_copy_in(pc, sizeof(sc->sc_ncm.hdr), &(sc->sc_ncm.dpt),
1106             sizeof(sc->sc_ncm.dpt));
1107         usbd_copy_in(pc, sizeof(sc->sc_ncm.hdr) + sizeof(sc->sc_ncm.dpt),
1108             &(sc->sc_ncm.dp), sizeof(sc->sc_ncm.dp));
1109         return (0);
1110 }
1111
1112 static void
1113 cdce_ncm_bulk_write_callback(struct usb_xfer *xfer, usb_error_t error)
1114 {
1115         struct cdce_softc *sc = usbd_xfer_softc(xfer);
1116         struct ifnet *ifp = uether_getifp(&sc->sc_ue);
1117         uint16_t x;
1118         int actlen;
1119         int aframes;
1120
1121         switch (USB_GET_STATE(xfer)) {
1122         case USB_ST_TRANSFERRED:
1123
1124                 usbd_xfer_status(xfer, &actlen, NULL, &aframes, NULL);
1125
1126                 DPRINTFN(10, "transfer complete: "
1127                     "%u bytes in %u frames\n", actlen, aframes);
1128
1129         case USB_ST_SETUP:
1130                 for (x = 0; x != CDCE_NCM_TX_FRAMES_MAX; x++) {
1131                         if (cdce_ncm_fill_tx_frames(xfer, x))
1132                                 break;
1133                 }
1134
1135                 if (x != 0) {
1136                         usbd_xfer_set_frames(xfer, x);
1137                         usbd_transfer_submit(xfer);
1138                 }
1139                 break;
1140
1141         default:                        /* Error */
1142                 DPRINTFN(10, "Transfer error: %s\n",
1143                     usbd_errstr(error));
1144
1145                 /* update error counter */
1146                 ifp->if_oerrors += 1;
1147
1148                 if (error != USB_ERR_CANCELLED) {
1149                         /* try to clear stall first */
1150                         usbd_xfer_set_stall(xfer);
1151                         usbd_xfer_set_frames(xfer, 0);
1152                         usbd_transfer_submit(xfer);
1153                 }
1154                 break;
1155         }
1156 }
1157
1158 static void
1159 cdce_ncm_bulk_read_callback(struct usb_xfer *xfer, usb_error_t error)
1160 {
1161         struct cdce_softc *sc = usbd_xfer_softc(xfer);
1162         struct usb_page_cache *pc = usbd_xfer_get_frame(xfer, 0);
1163         struct ifnet *ifp = uether_getifp(&sc->sc_ue);
1164         struct mbuf *m;
1165         int sumdata;
1166         int sumlen;
1167         int actlen;
1168         int aframes;
1169         int temp;
1170         int nframes;
1171         int x;
1172         int offset;
1173
1174         switch (USB_GET_STATE(xfer)) {
1175         case USB_ST_TRANSFERRED:
1176
1177                 usbd_xfer_status(xfer, &actlen, &sumlen, &aframes, NULL);
1178
1179                 DPRINTFN(1, "received %u bytes in %u frames\n",
1180                     actlen, aframes);
1181
1182                 if (actlen < (sizeof(sc->sc_ncm.hdr) +
1183                     sizeof(sc->sc_ncm.dpt))) {
1184                         DPRINTFN(1, "frame too short\n");
1185                         goto tr_setup;
1186                 }
1187                 usbd_copy_out(pc, 0, &(sc->sc_ncm.hdr),
1188                     sizeof(sc->sc_ncm.hdr));
1189
1190                 if ((sc->sc_ncm.hdr.dwSignature[0] != 'N') ||
1191                     (sc->sc_ncm.hdr.dwSignature[1] != 'C') ||
1192                     (sc->sc_ncm.hdr.dwSignature[2] != 'M') ||
1193                     (sc->sc_ncm.hdr.dwSignature[3] != 'H')) {
1194                         DPRINTFN(1, "invalid HDR signature: "
1195                             "0x%02x:0x%02x:0x%02x:0x%02x\n",
1196                             sc->sc_ncm.hdr.dwSignature[0],
1197                             sc->sc_ncm.hdr.dwSignature[1],
1198                             sc->sc_ncm.hdr.dwSignature[2],
1199                             sc->sc_ncm.hdr.dwSignature[3]);
1200                         goto tr_stall;
1201                 }
1202                 temp = UGETW(sc->sc_ncm.hdr.wBlockLength);
1203                 if (temp > sumlen) {
1204                         DPRINTFN(1, "unsupported block length %u/%u\n",
1205                             temp, sumlen);
1206                         goto tr_stall;
1207                 }
1208                 temp = UGETW(sc->sc_ncm.hdr.wDptIndex);
1209                 if ((temp + sizeof(sc->sc_ncm.dpt)) > actlen) {
1210                         DPRINTFN(1, "invalid DPT index: 0x%04x\n", temp);
1211                         goto tr_stall;
1212                 }
1213                 usbd_copy_out(pc, temp, &(sc->sc_ncm.dpt),
1214                     sizeof(sc->sc_ncm.dpt));
1215
1216                 if ((sc->sc_ncm.dpt.dwSignature[0] != 'N') ||
1217                     (sc->sc_ncm.dpt.dwSignature[1] != 'C') ||
1218                     (sc->sc_ncm.dpt.dwSignature[2] != 'M') ||
1219                     (sc->sc_ncm.dpt.dwSignature[3] != '0')) {
1220                         DPRINTFN(1, "invalid DPT signature"
1221                             "0x%02x:0x%02x:0x%02x:0x%02x\n",
1222                             sc->sc_ncm.dpt.dwSignature[0],
1223                             sc->sc_ncm.dpt.dwSignature[1],
1224                             sc->sc_ncm.dpt.dwSignature[2],
1225                             sc->sc_ncm.dpt.dwSignature[3]);
1226                         goto tr_stall;
1227                 }
1228                 nframes = UGETW(sc->sc_ncm.dpt.wLength) / 4;
1229
1230                 /* Subtract size of header and last zero padded entry */
1231                 if (nframes >= (2 + 1))
1232                         nframes -= (2 + 1);
1233                 else
1234                         nframes = 0;
1235
1236                 DPRINTFN(1, "nframes = %u\n", nframes);
1237
1238                 temp += sizeof(sc->sc_ncm.dpt);
1239
1240                 if ((temp + (4 * nframes)) > actlen)
1241                         goto tr_stall;
1242
1243                 if (nframes > CDCE_NCM_SUBFRAMES_MAX) {
1244                         DPRINTFN(1, "Truncating number of frames from %u to %u\n",
1245                             nframes, CDCE_NCM_SUBFRAMES_MAX);
1246                         nframes = CDCE_NCM_SUBFRAMES_MAX;
1247                 }
1248                 usbd_copy_out(pc, temp, &(sc->sc_ncm.dp), (4 * nframes));
1249
1250                 sumdata = 0;
1251
1252                 for (x = 0; x != nframes; x++) {
1253
1254                         offset = UGETW(sc->sc_ncm.dp[x].wFrameIndex);
1255                         temp = UGETW(sc->sc_ncm.dp[x].wFrameLength);
1256
1257                         if ((offset == 0) ||
1258                             (temp < sizeof(struct ether_header)) ||
1259                             (temp > (MCLBYTES - ETHER_ALIGN))) {
1260                                 DPRINTFN(1, "NULL frame detected at %d\n", x);
1261                                 m = NULL;
1262                                 /* silently ignore this frame */
1263                                 continue;
1264                         } else if ((offset + temp) > actlen) {
1265                                 DPRINTFN(1, "invalid frame "
1266                                     "detected at %d\n", x);
1267                                 m = NULL;
1268                                 /* silently ignore this frame */
1269                                 continue;
1270                         } else if (temp > (MHLEN - ETHER_ALIGN)) {
1271                                 m = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR);
1272                         } else {
1273                                 m = m_gethdr(M_DONTWAIT, MT_DATA);
1274                         }
1275
1276                         DPRINTFN(16, "frame %u, offset = %u, length = %u \n",
1277                             x, offset, temp);
1278
1279                         /* check if we have a buffer */
1280                         if (m) {
1281                                 m_adj(m, ETHER_ALIGN);
1282
1283                                 usbd_copy_out(pc, offset, m->m_data, temp);
1284
1285                                 /* enqueue */
1286                                 uether_rxmbuf(&sc->sc_ue, m, temp);
1287
1288                                 sumdata += temp;
1289                         } else {
1290                                 ifp->if_ierrors++;
1291                         }
1292                 }
1293
1294                 DPRINTFN(1, "Efficiency: %u/%u bytes\n", sumdata, actlen);
1295
1296         case USB_ST_SETUP:
1297 tr_setup:
1298                 usbd_xfer_set_frame_len(xfer, 0, sc->sc_ncm.rx_max);
1299                 usbd_xfer_set_frames(xfer, 1);
1300                 usbd_transfer_submit(xfer);
1301                 uether_rxflush(&sc->sc_ue);     /* must be last */
1302                 break;
1303
1304         default:                        /* Error */
1305                 DPRINTFN(1, "error = %s\n",
1306                     usbd_errstr(error));
1307
1308                 if (error != USB_ERR_CANCELLED) {
1309 tr_stall:
1310                         /* try to clear stall first */
1311                         usbd_xfer_set_stall(xfer);
1312                         usbd_xfer_set_frames(xfer, 0);
1313                         usbd_transfer_submit(xfer);
1314                 }
1315                 break;
1316         }
1317 }
1318 #endif