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, 0 - 1, 307 UCDC_NCM_FUNC_DESC_SUBTYPE, 0 - 1); 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, 0 - 1, UDESCSUB_CDC_UNION, 0 - 1); 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, 0 - 1, UDESCSUB_CDC_ENF, 0 - 1); 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, aframes, len; 896 897 usbd_xfer_status(xfer, &actlen, NULL, &aframes, NULL); 898 899 switch (USB_GET_STATE(xfer)) { 900 case USB_ST_TRANSFERRED: 901 902 DPRINTF("received %u bytes in %u frames\n", actlen, aframes); 903 904 for (x = 0; x != aframes; x++) { 905 906 m = sc->sc_rx_buf[x]; 907 sc->sc_rx_buf[x] = NULL; 908 len = usbd_xfer_frame_len(xfer, x); 909 910 /* Strip off CRC added by Zaurus, if any */ 911 if ((sc->sc_flags & CDCE_FLAG_ZAURUS) && len >= 14) 912 len -= 4; 913 914 if (len < sizeof(struct ether_header)) { 915 m_freem(m); 916 continue; 917 } 918 /* queue up mbuf */ 919 uether_rxmbuf(&sc->sc_ue, m, len); 920 } 921 922 /* FALLTHROUGH */ 923 case USB_ST_SETUP: 924 /* 925 * TODO: Implement support for multi frame transfers, 926 * when the USB hardware supports it. 927 */ 928 for (x = 0; x != 1; x++) { 929 if (sc->sc_rx_buf[x] == NULL) { 930 m = uether_newbuf(); 931 if (m == NULL) 932 goto tr_stall; 933 sc->sc_rx_buf[x] = m; 934 } else { 935 m = sc->sc_rx_buf[x]; 936 } 937 938 usbd_xfer_set_frame_data(xfer, x, m->m_data, m->m_len); 939 } 940 /* set number of frames and start hardware */ 941 usbd_xfer_set_frames(xfer, x); 942 usbd_transfer_submit(xfer); 943 /* flush any received frames */ 944 uether_rxflush(&sc->sc_ue); 945 break; 946 947 default: /* Error */ 948 DPRINTF("error = %s\n", 949 usbd_errstr(error)); 950 951 if (error != USB_ERR_CANCELLED) { 952 tr_stall: 953 /* try to clear stall first */ 954 usbd_xfer_set_stall(xfer); 955 usbd_xfer_set_frames(xfer, 0); 956 usbd_transfer_submit(xfer); 957 break; 958 } 959 960 /* need to free the RX-mbufs when we are cancelled */ 961 cdce_free_queue(sc->sc_rx_buf, CDCE_FRAMES_MAX); 962 break; 963 } 964 } 965 966 static void 967 cdce_intr_read_callback(struct usb_xfer *xfer, usb_error_t error) 968 { 969 int actlen; 970 971 usbd_xfer_status(xfer, &actlen, NULL, NULL, NULL); 972 973 switch (USB_GET_STATE(xfer)) { 974 case USB_ST_TRANSFERRED: 975 976 DPRINTF("Received %d bytes\n", actlen); 977 978 /* TODO: decode some indications */ 979 980 /* FALLTHROUGH */ 981 case USB_ST_SETUP: 982 tr_setup: 983 usbd_xfer_set_frame_len(xfer, 0, usbd_xfer_max_len(xfer)); 984 usbd_transfer_submit(xfer); 985 break; 986 987 default: /* Error */ 988 if (error != USB_ERR_CANCELLED) { 989 /* start clear stall */ 990 usbd_xfer_set_stall(xfer); 991 goto tr_setup; 992 } 993 break; 994 } 995 } 996 997 static void 998 cdce_intr_write_callback(struct usb_xfer *xfer, usb_error_t error) 999 { 1000 int actlen; 1001 1002 usbd_xfer_status(xfer, &actlen, NULL, NULL, NULL); 1003 1004 switch (USB_GET_STATE(xfer)) { 1005 case USB_ST_TRANSFERRED: 1006 1007 DPRINTF("Transferred %d bytes\n", actlen); 1008 1009 /* FALLTHROUGH */ 1010 case USB_ST_SETUP: 1011 tr_setup: 1012 #if 0 1013 usbd_xfer_set_frame_len(xfer, 0, XXX); 1014 usbd_transfer_submit(xfer); 1015 #endif 1016 break; 1017 1018 default: /* Error */ 1019 if (error != USB_ERR_CANCELLED) { 1020 /* start clear stall */ 1021 usbd_xfer_set_stall(xfer); 1022 goto tr_setup; 1023 } 1024 break; 1025 } 1026 } 1027 1028 static int 1029 cdce_handle_request(device_t dev, 1030 const void *req, void **pptr, uint16_t *plen, 1031 uint16_t offset, uint8_t *pstate) 1032 { 1033 return (ENXIO); /* use builtin handler */ 1034 } 1035 1036 #if CDCE_HAVE_NCM 1037 static void 1038 cdce_ncm_tx_zero(struct usb_page_cache *pc, 1039 uint32_t start, uint32_t end) 1040 { 1041 if (start >= CDCE_NCM_TX_MAXLEN) 1042 return; 1043 if (end > CDCE_NCM_TX_MAXLEN) 1044 end = CDCE_NCM_TX_MAXLEN; 1045 1046 usbd_frame_zero(pc, start, end - start); 1047 } 1048 1049 static uint8_t 1050 cdce_ncm_fill_tx_frames(struct usb_xfer *xfer, uint8_t index) 1051 { 1052 struct cdce_softc *sc = usbd_xfer_softc(xfer); 1053 struct ifnet *ifp = uether_getifp(&sc->sc_ue); 1054 struct usb_page_cache *pc = usbd_xfer_get_frame(xfer, index); 1055 struct mbuf *m; 1056 uint32_t rem; 1057 uint32_t offset; 1058 uint32_t last_offset; 1059 uint16_t n; 1060 uint8_t retval; 1061 1062 usbd_xfer_set_frame_offset(xfer, index * CDCE_NCM_TX_MAXLEN, index); 1063 1064 offset = sizeof(sc->sc_ncm.hdr) + 1065 sizeof(sc->sc_ncm.dpt) + sizeof(sc->sc_ncm.dp); 1066 1067 /* Store last valid offset before alignment */ 1068 last_offset = offset; 1069 1070 /* Align offset */ 1071 offset = CDCE_NCM_ALIGN(sc->sc_ncm.tx_remainder, 1072 offset, sc->sc_ncm.tx_modulus); 1073 1074 /* Zero pad */ 1075 cdce_ncm_tx_zero(pc, last_offset, offset); 1076 1077 /* buffer full */ 1078 retval = 2; 1079 1080 for (n = 0; n != sc->sc_ncm.tx_nframe; n++) { 1081 1082 /* check if end of transmit buffer is reached */ 1083 1084 if (offset >= sc->sc_ncm.tx_max) 1085 break; 1086 1087 /* compute maximum buffer size */ 1088 1089 rem = sc->sc_ncm.tx_max - offset; 1090 1091 IFQ_DRV_DEQUEUE(&(ifp->if_snd), m); 1092 1093 if (m == NULL) { 1094 /* buffer not full */ 1095 retval = 1; 1096 break; 1097 } 1098 1099 if (m->m_pkthdr.len > rem) { 1100 if (n == 0) { 1101 /* The frame won't fit in our buffer */ 1102 DPRINTFN(1, "Frame too big to be transmitted!\n"); 1103 m_freem(m); 1104 ifp->if_oerrors++; 1105 n--; 1106 continue; 1107 } 1108 /* Wait till next buffer becomes ready */ 1109 IFQ_DRV_PREPEND(&(ifp->if_snd), m); 1110 break; 1111 } 1112 usbd_m_copy_in(pc, offset, m, 0, m->m_pkthdr.len); 1113 1114 USETW(sc->sc_ncm.dp[n].wFrameLength, m->m_pkthdr.len); 1115 USETW(sc->sc_ncm.dp[n].wFrameIndex, offset); 1116 1117 /* Update offset */ 1118 offset += m->m_pkthdr.len; 1119 1120 /* Store last valid offset before alignment */ 1121 last_offset = offset; 1122 1123 /* Align offset */ 1124 offset = CDCE_NCM_ALIGN(sc->sc_ncm.tx_remainder, 1125 offset, sc->sc_ncm.tx_modulus); 1126 1127 /* Zero pad */ 1128 cdce_ncm_tx_zero(pc, last_offset, offset); 1129 1130 /* 1131 * If there's a BPF listener, bounce a copy 1132 * of this frame to him: 1133 */ 1134 BPF_MTAP(ifp, m); 1135 1136 /* Free mbuf */ 1137 1138 m_freem(m); 1139 1140 /* Pre-increment interface counter */ 1141 1142 ifp->if_opackets++; 1143 } 1144 1145 if (n == 0) 1146 return (0); 1147 1148 rem = (sizeof(sc->sc_ncm.dpt) + (4 * n) + 4); 1149 1150 USETW(sc->sc_ncm.dpt.wLength, rem); 1151 1152 /* zero the rest of the data pointer entries */ 1153 for (; n != CDCE_NCM_SUBFRAMES_MAX; n++) { 1154 USETW(sc->sc_ncm.dp[n].wFrameLength, 0); 1155 USETW(sc->sc_ncm.dp[n].wFrameIndex, 0); 1156 } 1157 1158 offset = last_offset; 1159 1160 /* Align offset */ 1161 offset = CDCE_NCM_ALIGN(0, offset, CDCE_NCM_TX_MINLEN); 1162 1163 /* Optimise, save bandwidth and force short termination */ 1164 if (offset >= sc->sc_ncm.tx_max) 1165 offset = sc->sc_ncm.tx_max; 1166 else 1167 offset ++; 1168 1169 /* Zero pad */ 1170 cdce_ncm_tx_zero(pc, last_offset, offset); 1171 1172 /* set frame length */ 1173 usbd_xfer_set_frame_len(xfer, index, offset); 1174 1175 /* Fill out 16-bit header */ 1176 sc->sc_ncm.hdr.dwSignature[0] = 'N'; 1177 sc->sc_ncm.hdr.dwSignature[1] = 'C'; 1178 sc->sc_ncm.hdr.dwSignature[2] = 'M'; 1179 sc->sc_ncm.hdr.dwSignature[3] = 'H'; 1180 USETW(sc->sc_ncm.hdr.wHeaderLength, sizeof(sc->sc_ncm.hdr)); 1181 USETW(sc->sc_ncm.hdr.wBlockLength, offset); 1182 USETW(sc->sc_ncm.hdr.wSequence, sc->sc_ncm.tx_seq); 1183 USETW(sc->sc_ncm.hdr.wDptIndex, sizeof(sc->sc_ncm.hdr)); 1184 1185 sc->sc_ncm.tx_seq++; 1186 1187 /* Fill out 16-bit frame table header */ 1188 sc->sc_ncm.dpt.dwSignature[0] = 'N'; 1189 sc->sc_ncm.dpt.dwSignature[1] = 'C'; 1190 sc->sc_ncm.dpt.dwSignature[2] = 'M'; 1191 sc->sc_ncm.dpt.dwSignature[3] = '0'; 1192 USETW(sc->sc_ncm.dpt.wNextNdpIndex, 0); /* reserved */ 1193 1194 usbd_copy_in(pc, 0, &(sc->sc_ncm.hdr), sizeof(sc->sc_ncm.hdr)); 1195 usbd_copy_in(pc, sizeof(sc->sc_ncm.hdr), &(sc->sc_ncm.dpt), 1196 sizeof(sc->sc_ncm.dpt)); 1197 usbd_copy_in(pc, sizeof(sc->sc_ncm.hdr) + sizeof(sc->sc_ncm.dpt), 1198 &(sc->sc_ncm.dp), sizeof(sc->sc_ncm.dp)); 1199 return (retval); 1200 } 1201 1202 static void 1203 cdce_ncm_bulk_write_callback(struct usb_xfer *xfer, usb_error_t error) 1204 { 1205 struct cdce_softc *sc = usbd_xfer_softc(xfer); 1206 struct ifnet *ifp = uether_getifp(&sc->sc_ue); 1207 uint16_t x; 1208 uint8_t temp; 1209 int actlen; 1210 int aframes; 1211 1212 switch (USB_GET_STATE(xfer)) { 1213 case USB_ST_TRANSFERRED: 1214 1215 usbd_xfer_status(xfer, &actlen, NULL, &aframes, NULL); 1216 1217 DPRINTFN(10, "transfer complete: " 1218 "%u bytes in %u frames\n", actlen, aframes); 1219 1220 case USB_ST_SETUP: 1221 for (x = 0; x != CDCE_NCM_TX_FRAMES_MAX; x++) { 1222 temp = cdce_ncm_fill_tx_frames(xfer, x); 1223 if (temp == 0) 1224 break; 1225 if (temp == 1) { 1226 x++; 1227 break; 1228 } 1229 } 1230 1231 if (x != 0) { 1232 #ifdef USB_DEBUG 1233 usbd_xfer_set_interval(xfer, cdce_tx_interval); 1234 #endif 1235 usbd_xfer_set_frames(xfer, x); 1236 usbd_transfer_submit(xfer); 1237 } 1238 break; 1239 1240 default: /* Error */ 1241 DPRINTFN(10, "Transfer error: %s\n", 1242 usbd_errstr(error)); 1243 1244 /* update error counter */ 1245 ifp->if_oerrors += 1; 1246 1247 if (error != USB_ERR_CANCELLED) { 1248 /* try to clear stall first */ 1249 usbd_xfer_set_stall(xfer); 1250 usbd_xfer_set_frames(xfer, 0); 1251 usbd_transfer_submit(xfer); 1252 } 1253 break; 1254 } 1255 } 1256 1257 static void 1258 cdce_ncm_bulk_read_callback(struct usb_xfer *xfer, usb_error_t error) 1259 { 1260 struct cdce_softc *sc = usbd_xfer_softc(xfer); 1261 struct usb_page_cache *pc = usbd_xfer_get_frame(xfer, 0); 1262 struct ifnet *ifp = uether_getifp(&sc->sc_ue); 1263 struct mbuf *m; 1264 int sumdata; 1265 int sumlen; 1266 int actlen; 1267 int aframes; 1268 int temp; 1269 int nframes; 1270 int x; 1271 int offset; 1272 1273 switch (USB_GET_STATE(xfer)) { 1274 case USB_ST_TRANSFERRED: 1275 1276 usbd_xfer_status(xfer, &actlen, &sumlen, &aframes, NULL); 1277 1278 DPRINTFN(1, "received %u bytes in %u frames\n", 1279 actlen, aframes); 1280 1281 if (actlen < (sizeof(sc->sc_ncm.hdr) + 1282 sizeof(sc->sc_ncm.dpt))) { 1283 DPRINTFN(1, "frame too short\n"); 1284 goto tr_setup; 1285 } 1286 usbd_copy_out(pc, 0, &(sc->sc_ncm.hdr), 1287 sizeof(sc->sc_ncm.hdr)); 1288 1289 if ((sc->sc_ncm.hdr.dwSignature[0] != 'N') || 1290 (sc->sc_ncm.hdr.dwSignature[1] != 'C') || 1291 (sc->sc_ncm.hdr.dwSignature[2] != 'M') || 1292 (sc->sc_ncm.hdr.dwSignature[3] != 'H')) { 1293 DPRINTFN(1, "invalid HDR signature: " 1294 "0x%02x:0x%02x:0x%02x:0x%02x\n", 1295 sc->sc_ncm.hdr.dwSignature[0], 1296 sc->sc_ncm.hdr.dwSignature[1], 1297 sc->sc_ncm.hdr.dwSignature[2], 1298 sc->sc_ncm.hdr.dwSignature[3]); 1299 goto tr_stall; 1300 } 1301 temp = UGETW(sc->sc_ncm.hdr.wBlockLength); 1302 if (temp > sumlen) { 1303 DPRINTFN(1, "unsupported block length %u/%u\n", 1304 temp, sumlen); 1305 goto tr_stall; 1306 } 1307 temp = UGETW(sc->sc_ncm.hdr.wDptIndex); 1308 if ((temp + sizeof(sc->sc_ncm.dpt)) > actlen) { 1309 DPRINTFN(1, "invalid DPT index: 0x%04x\n", temp); 1310 goto tr_stall; 1311 } 1312 usbd_copy_out(pc, temp, &(sc->sc_ncm.dpt), 1313 sizeof(sc->sc_ncm.dpt)); 1314 1315 if ((sc->sc_ncm.dpt.dwSignature[0] != 'N') || 1316 (sc->sc_ncm.dpt.dwSignature[1] != 'C') || 1317 (sc->sc_ncm.dpt.dwSignature[2] != 'M') || 1318 (sc->sc_ncm.dpt.dwSignature[3] != '0')) { 1319 DPRINTFN(1, "invalid DPT signature" 1320 "0x%02x:0x%02x:0x%02x:0x%02x\n", 1321 sc->sc_ncm.dpt.dwSignature[0], 1322 sc->sc_ncm.dpt.dwSignature[1], 1323 sc->sc_ncm.dpt.dwSignature[2], 1324 sc->sc_ncm.dpt.dwSignature[3]); 1325 goto tr_stall; 1326 } 1327 nframes = UGETW(sc->sc_ncm.dpt.wLength) / 4; 1328 1329 /* Subtract size of header and last zero padded entry */ 1330 if (nframes >= (2 + 1)) 1331 nframes -= (2 + 1); 1332 else 1333 nframes = 0; 1334 1335 DPRINTFN(1, "nframes = %u\n", nframes); 1336 1337 temp += sizeof(sc->sc_ncm.dpt); 1338 1339 if ((temp + (4 * nframes)) > actlen) 1340 goto tr_stall; 1341 1342 if (nframes > CDCE_NCM_SUBFRAMES_MAX) { 1343 DPRINTFN(1, "Truncating number of frames from %u to %u\n", 1344 nframes, CDCE_NCM_SUBFRAMES_MAX); 1345 nframes = CDCE_NCM_SUBFRAMES_MAX; 1346 } 1347 usbd_copy_out(pc, temp, &(sc->sc_ncm.dp), (4 * nframes)); 1348 1349 sumdata = 0; 1350 1351 for (x = 0; x != nframes; x++) { 1352 1353 offset = UGETW(sc->sc_ncm.dp[x].wFrameIndex); 1354 temp = UGETW(sc->sc_ncm.dp[x].wFrameLength); 1355 1356 if ((offset == 0) || 1357 (temp < sizeof(struct ether_header)) || 1358 (temp > (MCLBYTES - ETHER_ALIGN))) { 1359 DPRINTFN(1, "NULL frame detected at %d\n", x); 1360 m = NULL; 1361 /* silently ignore this frame */ 1362 continue; 1363 } else if ((offset + temp) > actlen) { 1364 DPRINTFN(1, "invalid frame " 1365 "detected at %d\n", x); 1366 m = NULL; 1367 /* silently ignore this frame */ 1368 continue; 1369 } else if (temp > (MHLEN - ETHER_ALIGN)) { 1370 m = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR); 1371 } else { 1372 m = m_gethdr(M_DONTWAIT, MT_DATA); 1373 } 1374 1375 DPRINTFN(16, "frame %u, offset = %u, length = %u \n", 1376 x, offset, temp); 1377 1378 /* check if we have a buffer */ 1379 if (m) { 1380 m_adj(m, ETHER_ALIGN); 1381 1382 usbd_copy_out(pc, offset, m->m_data, temp); 1383 1384 /* enqueue */ 1385 uether_rxmbuf(&sc->sc_ue, m, temp); 1386 1387 sumdata += temp; 1388 } else { 1389 ifp->if_ierrors++; 1390 } 1391 } 1392 1393 DPRINTFN(1, "Efficiency: %u/%u bytes\n", sumdata, actlen); 1394 1395 case USB_ST_SETUP: 1396 tr_setup: 1397 usbd_xfer_set_frame_len(xfer, 0, sc->sc_ncm.rx_max); 1398 usbd_xfer_set_frames(xfer, 1); 1399 usbd_transfer_submit(xfer); 1400 uether_rxflush(&sc->sc_ue); /* must be last */ 1401 break; 1402 1403 default: /* Error */ 1404 DPRINTFN(1, "error = %s\n", 1405 usbd_errstr(error)); 1406 1407 if (error != USB_ERR_CANCELLED) { 1408 tr_stall: 1409 /* try to clear stall first */ 1410 usbd_xfer_set_stall(xfer); 1411 usbd_xfer_set_frames(xfer, 0); 1412 usbd_transfer_submit(xfer); 1413 } 1414 break; 1415 } 1416 } 1417 #endif 1418