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