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