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