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 1319