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 #include <sys/cdefs.h> 44 __FBSDID("$FreeBSD$"); 45 46 #include "usbdevs.h" 47 #include <dev/usb/usb.h> 48 #include <dev/usb/usb_mfunc.h> 49 #include <dev/usb/usb_error.h> 50 #include <dev/usb/usb_cdc.h> 51 #include <dev/usb/usb_defs.h> 52 53 #define USB_DEBUG_VAR cdce_debug 54 55 #include <dev/usb/usb_core.h> 56 #include <dev/usb/usb_lookup.h> 57 #include <dev/usb/usb_process.h> 58 #include <dev/usb/usb_debug.h> 59 #include <dev/usb/usb_request.h> 60 #include <dev/usb/usb_busdma.h> 61 #include <dev/usb/usb_util.h> 62 #include <dev/usb/usb_parse.h> 63 #include <dev/usb/usb_device.h> 64 65 #include <dev/usb/net/usb_ethernet.h> 66 #include <dev/usb/net/if_cdcereg.h> 67 68 static device_probe_t cdce_probe; 69 static device_attach_t cdce_attach; 70 static device_detach_t cdce_detach; 71 static device_shutdown_t cdce_shutdown; 72 static device_suspend_t cdce_suspend; 73 static device_resume_t cdce_resume; 74 static usb_handle_request_t cdce_handle_request; 75 76 static usb2_callback_t cdce_bulk_write_callback; 77 static usb2_callback_t cdce_bulk_read_callback; 78 static usb2_callback_t cdce_intr_read_callback; 79 static usb2_callback_t cdce_intr_write_callback; 80 81 static usb2_ether_fn_t cdce_attach_post; 82 static usb2_ether_fn_t cdce_init; 83 static usb2_ether_fn_t cdce_stop; 84 static usb2_ether_fn_t cdce_start; 85 static usb2_ether_fn_t cdce_setmulti; 86 static usb2_ether_fn_t cdce_setpromisc; 87 88 static uint32_t cdce_m_crc32(struct mbuf *, uint32_t, uint32_t); 89 90 #if USB_DEBUG 91 static int cdce_debug = 0; 92 93 SYSCTL_NODE(_hw_usb2, OID_AUTO, cdce, CTLFLAG_RW, 0, "USB CDC-Ethernet"); 94 SYSCTL_INT(_hw_usb2_cdce, OID_AUTO, debug, CTLFLAG_RW, &cdce_debug, 0, 95 "Debug level"); 96 #endif 97 98 static const struct usb2_config cdce_config[CDCE_N_TRANSFER] = { 99 100 [CDCE_BULK_A] = { 101 .type = UE_BULK, 102 .endpoint = UE_ADDR_ANY, 103 .direction = UE_DIR_OUT, 104 .if_index = 0, 105 /* Host Mode */ 106 .mh.frames = CDCE_FRAMES_MAX, 107 .mh.bufsize = (CDCE_FRAMES_MAX * MCLBYTES), 108 .mh.flags = {.pipe_bof = 1,.force_short_xfer = 1,.ext_buffer = 1,}, 109 .mh.callback = cdce_bulk_write_callback, 110 .mh.timeout = 10000, /* 10 seconds */ 111 /* Device Mode */ 112 .md.frames = CDCE_FRAMES_MAX, 113 .md.bufsize = (CDCE_FRAMES_MAX * MCLBYTES), 114 .md.flags = {.pipe_bof = 1,.short_frames_ok = 1,.short_xfer_ok = 1,.ext_buffer = 1,}, 115 .md.callback = cdce_bulk_read_callback, 116 .md.timeout = 0, /* no timeout */ 117 }, 118 119 [CDCE_BULK_B] = { 120 .type = UE_BULK, 121 .endpoint = UE_ADDR_ANY, 122 .direction = UE_DIR_IN, 123 .if_index = 0, 124 /* Host Mode */ 125 .mh.frames = CDCE_FRAMES_MAX, 126 .mh.bufsize = (CDCE_FRAMES_MAX * MCLBYTES), 127 .mh.flags = {.pipe_bof = 1,.short_frames_ok = 1,.short_xfer_ok = 1,.ext_buffer = 1,}, 128 .mh.callback = cdce_bulk_read_callback, 129 .mh.timeout = 0, /* no timeout */ 130 /* Device Mode */ 131 .md.frames = CDCE_FRAMES_MAX, 132 .md.bufsize = (CDCE_FRAMES_MAX * MCLBYTES), 133 .md.flags = {.pipe_bof = 1,.force_short_xfer = 1,.ext_buffer = 1,}, 134 .md.callback = cdce_bulk_write_callback, 135 .md.timeout = 10000, /* 10 seconds */ 136 }, 137 138 [CDCE_INTR] = { 139 .type = UE_INTERRUPT, 140 .endpoint = UE_ADDR_ANY, 141 .direction = UE_DIR_IN, 142 .if_index = 1, 143 /* Host Mode */ 144 .mh.bufsize = CDCE_IND_SIZE_MAX, 145 .mh.flags = {.pipe_bof = 1,.short_xfer_ok = 1,.no_pipe_ok = 1,}, 146 .mh.callback = cdce_intr_read_callback, 147 .mh.timeout = 0, 148 /* Device Mode */ 149 .md.bufsize = CDCE_IND_SIZE_MAX, 150 .md.flags = {.pipe_bof = 1,.force_short_xfer = 1,.no_pipe_ok = 1,}, 151 .md.callback = cdce_intr_write_callback, 152 .md.timeout = 10000, /* 10 seconds */ 153 }, 154 }; 155 156 static device_method_t cdce_methods[] = { 157 /* USB interface */ 158 DEVMETHOD(usb_handle_request, cdce_handle_request), 159 160 /* Device interface */ 161 DEVMETHOD(device_probe, cdce_probe), 162 DEVMETHOD(device_attach, cdce_attach), 163 DEVMETHOD(device_detach, cdce_detach), 164 DEVMETHOD(device_suspend, cdce_suspend), 165 DEVMETHOD(device_resume, cdce_resume), 166 DEVMETHOD(device_shutdown, cdce_shutdown), 167 168 {0, 0} 169 }; 170 171 static driver_t cdce_driver = { 172 .name = "cdce", 173 .methods = cdce_methods, 174 .size = sizeof(struct cdce_softc), 175 }; 176 177 static devclass_t cdce_devclass; 178 179 DRIVER_MODULE(cdce, ushub, cdce_driver, cdce_devclass, NULL, 0); 180 MODULE_VERSION(cdce, 1); 181 MODULE_DEPEND(cdce, uether, 1, 1, 1); 182 MODULE_DEPEND(cdce, usb, 1, 1, 1); 183 MODULE_DEPEND(cdce, ether, 1, 1, 1); 184 185 static const struct usb2_ether_methods cdce_ue_methods = { 186 .ue_attach_post = cdce_attach_post, 187 .ue_start = cdce_start, 188 .ue_init = cdce_init, 189 .ue_stop = cdce_stop, 190 .ue_setmulti = cdce_setmulti, 191 .ue_setpromisc = cdce_setpromisc, 192 }; 193 194 static const struct usb2_device_id cdce_devs[] = { 195 {USB_IF_CSI(UICLASS_CDC, UISUBCLASS_ETHERNET_NETWORKING_CONTROL_MODEL, 0)}, 196 {USB_IF_CSI(UICLASS_CDC, UISUBCLASS_MOBILE_DIRECT_LINE_MODEL, 0)}, 197 198 {USB_VPI(USB_VENDOR_ACERLABS, USB_PRODUCT_ACERLABS_M5632, CDCE_FLAG_NO_UNION)}, 199 {USB_VPI(USB_VENDOR_AMBIT, USB_PRODUCT_AMBIT_NTL_250, CDCE_FLAG_NO_UNION)}, 200 {USB_VPI(USB_VENDOR_COMPAQ, USB_PRODUCT_COMPAQ_IPAQLINUX, CDCE_FLAG_NO_UNION)}, 201 {USB_VPI(USB_VENDOR_GMATE, USB_PRODUCT_GMATE_YP3X00, CDCE_FLAG_NO_UNION)}, 202 {USB_VPI(USB_VENDOR_MOTOROLA2, USB_PRODUCT_MOTOROLA2_USBLAN, CDCE_FLAG_ZAURUS | CDCE_FLAG_NO_UNION)}, 203 {USB_VPI(USB_VENDOR_MOTOROLA2, USB_PRODUCT_MOTOROLA2_USBLAN2, CDCE_FLAG_ZAURUS | CDCE_FLAG_NO_UNION)}, 204 {USB_VPI(USB_VENDOR_NETCHIP, USB_PRODUCT_NETCHIP_ETHERNETGADGET, CDCE_FLAG_NO_UNION)}, 205 {USB_VPI(USB_VENDOR_PROLIFIC, USB_PRODUCT_PROLIFIC_PL2501, CDCE_FLAG_NO_UNION)}, 206 {USB_VPI(USB_VENDOR_SHARP, USB_PRODUCT_SHARP_SL5500, CDCE_FLAG_ZAURUS)}, 207 {USB_VPI(USB_VENDOR_SHARP, USB_PRODUCT_SHARP_SL5600, CDCE_FLAG_ZAURUS | CDCE_FLAG_NO_UNION)}, 208 {USB_VPI(USB_VENDOR_SHARP, USB_PRODUCT_SHARP_SLA300, CDCE_FLAG_ZAURUS | CDCE_FLAG_NO_UNION)}, 209 {USB_VPI(USB_VENDOR_SHARP, USB_PRODUCT_SHARP_SLC700, CDCE_FLAG_ZAURUS | CDCE_FLAG_NO_UNION)}, 210 {USB_VPI(USB_VENDOR_SHARP, USB_PRODUCT_SHARP_SLC750, CDCE_FLAG_ZAURUS | CDCE_FLAG_NO_UNION)}, 211 }; 212 213 static int 214 cdce_probe(device_t dev) 215 { 216 struct usb2_attach_arg *uaa = device_get_ivars(dev); 217 218 return (usb2_lookup_id_by_uaa(cdce_devs, sizeof(cdce_devs), uaa)); 219 } 220 221 static void 222 cdce_attach_post(struct usb2_ether *ue) 223 { 224 /* no-op */ 225 return; 226 } 227 228 static int 229 cdce_attach(device_t dev) 230 { 231 struct cdce_softc *sc = device_get_softc(dev); 232 struct usb2_ether *ue = &sc->sc_ue; 233 struct usb2_attach_arg *uaa = device_get_ivars(dev); 234 struct usb2_interface *iface; 235 const struct usb2_cdc_union_descriptor *ud; 236 const struct usb2_interface_descriptor *id; 237 const struct usb2_cdc_ethernet_descriptor *ued; 238 int error; 239 uint8_t i; 240 char eaddr_str[5 * ETHER_ADDR_LEN]; /* approx */ 241 242 sc->sc_flags = USB_GET_DRIVER_INFO(uaa); 243 244 device_set_usb2_desc(dev); 245 246 mtx_init(&sc->sc_mtx, device_get_nameunit(dev), NULL, MTX_DEF); 247 248 if (sc->sc_flags & CDCE_FLAG_NO_UNION) { 249 sc->sc_ifaces_index[0] = uaa->info.bIfaceIndex; 250 sc->sc_ifaces_index[1] = uaa->info.bIfaceIndex; 251 sc->sc_data_iface_no = 0; /* not used */ 252 goto alloc_transfers; 253 } 254 ud = usb2_find_descriptor 255 (uaa->device, NULL, uaa->info.bIfaceIndex, 256 UDESC_CS_INTERFACE, 0 - 1, UDESCSUB_CDC_UNION, 0 - 1); 257 258 if ((ud == NULL) || (ud->bLength < sizeof(*ud))) { 259 device_printf(dev, "no union descriptor!\n"); 260 goto detach; 261 } 262 sc->sc_data_iface_no = ud->bSlaveInterface[0]; 263 264 for (i = 0;; i++) { 265 266 iface = usb2_get_iface(uaa->device, i); 267 268 if (iface) { 269 270 id = usb2_get_interface_descriptor(iface); 271 272 if (id && (id->bInterfaceNumber == 273 sc->sc_data_iface_no)) { 274 sc->sc_ifaces_index[0] = i; 275 sc->sc_ifaces_index[1] = uaa->info.bIfaceIndex; 276 usb2_set_parent_iface(uaa->device, i, uaa->info.bIfaceIndex); 277 break; 278 } 279 } else { 280 device_printf(dev, "no data interface found!\n"); 281 goto detach; 282 } 283 } 284 285 /* 286 * <quote> 287 * 288 * The Data Class interface of a networking device shall have 289 * a minimum of two interface settings. The first setting 290 * (the default interface setting) includes no endpoints and 291 * therefore no networking traffic is exchanged whenever the 292 * default interface setting is selected. One or more 293 * additional interface settings are used for normal 294 * operation, and therefore each includes a pair of endpoints 295 * (one IN, and one OUT) to exchange network traffic. Select 296 * an alternate interface setting to initialize the network 297 * aspects of the device and to enable the exchange of 298 * network traffic. 299 * 300 * </quote> 301 * 302 * Some devices, most notably cable modems, include interface 303 * settings that have no IN or OUT endpoint, therefore loop 304 * through the list of all available interface settings 305 * looking for one with both IN and OUT endpoints. 306 */ 307 308 alloc_transfers: 309 310 for (i = 0; i != 32; i++) { 311 312 error = usb2_set_alt_interface_index 313 (uaa->device, sc->sc_ifaces_index[0], i); 314 315 if (error) { 316 device_printf(dev, "no valid alternate " 317 "setting found!\n"); 318 goto detach; 319 } 320 error = usb2_transfer_setup 321 (uaa->device, sc->sc_ifaces_index, 322 sc->sc_xfer, cdce_config, CDCE_N_TRANSFER, 323 sc, &sc->sc_mtx); 324 325 if (error == 0) { 326 break; 327 } 328 } 329 330 ued = usb2_find_descriptor 331 (uaa->device, NULL, uaa->info.bIfaceIndex, 332 UDESC_CS_INTERFACE, 0 - 1, UDESCSUB_CDC_ENF, 0 - 1); 333 334 if ((ued == NULL) || (ued->bLength < sizeof(*ued))) { 335 error = USB_ERR_INVAL; 336 } else { 337 error = usb2_req_get_string_any(uaa->device, NULL, 338 eaddr_str, sizeof(eaddr_str), ued->iMacAddress); 339 } 340 341 if (error) { 342 343 /* fake MAC address */ 344 345 device_printf(dev, "faking MAC address\n"); 346 sc->sc_ue.ue_eaddr[0] = 0x2a; 347 memcpy(&sc->sc_ue.ue_eaddr[1], &ticks, sizeof(uint32_t)); 348 sc->sc_ue.ue_eaddr[5] = device_get_unit(dev); 349 350 } else { 351 352 bzero(sc->sc_ue.ue_eaddr, sizeof(sc->sc_ue.ue_eaddr)); 353 354 for (i = 0; i != (ETHER_ADDR_LEN * 2); i++) { 355 356 char c = eaddr_str[i]; 357 358 if ('0' <= c && c <= '9') 359 c -= '0'; 360 else if (c != 0) 361 c -= 'A' - 10; 362 else 363 break; 364 365 c &= 0xf; 366 367 if ((i & 1) == 0) 368 c <<= 4; 369 sc->sc_ue.ue_eaddr[i / 2] |= c; 370 } 371 372 if (uaa->usb2_mode == USB_MODE_DEVICE) { 373 /* 374 * Do not use the same MAC address like the peer ! 375 */ 376 sc->sc_ue.ue_eaddr[5] ^= 0xFF; 377 } 378 } 379 380 ue->ue_sc = sc; 381 ue->ue_dev = dev; 382 ue->ue_udev = uaa->device; 383 ue->ue_mtx = &sc->sc_mtx; 384 ue->ue_methods = &cdce_ue_methods; 385 386 error = usb2_ether_ifattach(ue); 387 if (error) { 388 device_printf(dev, "could not attach interface\n"); 389 goto detach; 390 } 391 return (0); /* success */ 392 393 detach: 394 cdce_detach(dev); 395 return (ENXIO); /* failure */ 396 } 397 398 static int 399 cdce_detach(device_t dev) 400 { 401 struct cdce_softc *sc = device_get_softc(dev); 402 struct usb2_ether *ue = &sc->sc_ue; 403 404 /* stop all USB transfers first */ 405 usb2_transfer_unsetup(sc->sc_xfer, CDCE_N_TRANSFER); 406 usb2_ether_ifdetach(ue); 407 mtx_destroy(&sc->sc_mtx); 408 409 return (0); 410 } 411 412 static void 413 cdce_start(struct usb2_ether *ue) 414 { 415 struct cdce_softc *sc = usb2_ether_getsc(ue); 416 417 /* 418 * Start the USB transfers, if not already started: 419 */ 420 usb2_transfer_start(sc->sc_xfer[CDCE_BULK_B]); 421 usb2_transfer_start(sc->sc_xfer[CDCE_BULK_A]); 422 } 423 424 static void 425 cdce_free_queue(struct mbuf **ppm, uint8_t n) 426 { 427 uint8_t x; 428 for (x = 0; x != n; x++) { 429 if (ppm[x] != NULL) { 430 m_freem(ppm[x]); 431 ppm[x] = NULL; 432 } 433 } 434 } 435 436 static void 437 cdce_bulk_write_callback(struct usb2_xfer *xfer) 438 { 439 struct cdce_softc *sc = xfer->priv_sc; 440 struct ifnet *ifp = usb2_ether_getifp(&sc->sc_ue); 441 struct mbuf *m; 442 struct mbuf *mt; 443 uint32_t crc; 444 uint8_t x; 445 446 DPRINTFN(1, "\n"); 447 448 switch (USB_GET_STATE(xfer)) { 449 case USB_ST_TRANSFERRED: 450 DPRINTFN(11, "transfer complete: " 451 "%u bytes in %u frames\n", xfer->actlen, 452 xfer->aframes); 453 454 ifp->if_opackets++; 455 456 /* free all previous TX buffers */ 457 cdce_free_queue(sc->sc_tx_buf, CDCE_FRAMES_MAX); 458 459 /* FALLTHROUGH */ 460 case USB_ST_SETUP: 461 tr_setup: 462 for (x = 0; x != CDCE_FRAMES_MAX; x++) { 463 464 IFQ_DRV_DEQUEUE(&ifp->if_snd, m); 465 466 if (m == NULL) 467 break; 468 469 if (sc->sc_flags & CDCE_FLAG_ZAURUS) { 470 /* 471 * Zaurus wants a 32-bit CRC appended 472 * to every frame 473 */ 474 475 crc = cdce_m_crc32(m, 0, m->m_pkthdr.len); 476 crc = htole32(crc); 477 478 if (!m_append(m, 4, (void *)&crc)) { 479 m_freem(m); 480 ifp->if_oerrors++; 481 continue; 482 } 483 } 484 if (m->m_len != m->m_pkthdr.len) { 485 mt = m_defrag(m, M_DONTWAIT); 486 if (mt == NULL) { 487 m_freem(m); 488 ifp->if_oerrors++; 489 continue; 490 } 491 m = mt; 492 } 493 if (m->m_pkthdr.len > MCLBYTES) { 494 m->m_pkthdr.len = MCLBYTES; 495 } 496 sc->sc_tx_buf[x] = m; 497 xfer->frlengths[x] = m->m_len; 498 usb2_set_frame_data(xfer, m->m_data, x); 499 500 /* 501 * If there's a BPF listener, bounce a copy of 502 * this frame to him: 503 */ 504 BPF_MTAP(ifp, m); 505 } 506 if (x != 0) { 507 xfer->nframes = x; 508 usb2_start_hardware(xfer); 509 } 510 break; 511 512 default: /* Error */ 513 DPRINTFN(11, "transfer error, %s\n", 514 usb2_errstr(xfer->error)); 515 516 /* free all previous TX buffers */ 517 cdce_free_queue(sc->sc_tx_buf, CDCE_FRAMES_MAX); 518 519 /* count output errors */ 520 ifp->if_oerrors++; 521 522 if (xfer->error != USB_ERR_CANCELLED) { 523 /* try to clear stall first */ 524 xfer->flags.stall_pipe = 1; 525 goto tr_setup; 526 } 527 break; 528 } 529 } 530 531 static int32_t 532 cdce_m_crc32_cb(void *arg, void *src, uint32_t count) 533 { 534 uint32_t *p_crc = arg; 535 536 *p_crc = crc32_raw(src, count, *p_crc); 537 return (0); 538 } 539 540 static uint32_t 541 cdce_m_crc32(struct mbuf *m, uint32_t src_offset, uint32_t src_len) 542 { 543 uint32_t crc = 0xFFFFFFFF; 544 int error; 545 546 error = m_apply(m, src_offset, src_len, cdce_m_crc32_cb, &crc); 547 return (crc ^ 0xFFFFFFFF); 548 } 549 550 static void 551 cdce_init(struct usb2_ether *ue) 552 { 553 struct cdce_softc *sc = usb2_ether_getsc(ue); 554 struct ifnet *ifp = usb2_ether_getifp(ue); 555 556 CDCE_LOCK_ASSERT(sc, MA_OWNED); 557 558 ifp->if_drv_flags |= IFF_DRV_RUNNING; 559 560 /* start interrupt transfer */ 561 usb2_transfer_start(sc->sc_xfer[CDCE_INTR]); 562 563 /* stall data write direction, which depends on USB mode */ 564 if (usb2_get_mode(sc->sc_ue.ue_udev) == USB_MODE_HOST) 565 usb2_transfer_set_stall(sc->sc_xfer[CDCE_BULK_A]); 566 else 567 usb2_transfer_set_stall(sc->sc_xfer[CDCE_BULK_B]); 568 569 /* start data transfers */ 570 cdce_start(ue); 571 } 572 573 static void 574 cdce_stop(struct usb2_ether *ue) 575 { 576 struct cdce_softc *sc = usb2_ether_getsc(ue); 577 struct ifnet *ifp = usb2_ether_getifp(ue); 578 579 CDCE_LOCK_ASSERT(sc, MA_OWNED); 580 581 ifp->if_drv_flags &= ~IFF_DRV_RUNNING; 582 583 /* 584 * stop all the transfers, if not already stopped: 585 */ 586 usb2_transfer_stop(sc->sc_xfer[CDCE_BULK_A]); 587 usb2_transfer_stop(sc->sc_xfer[CDCE_BULK_B]); 588 usb2_transfer_stop(sc->sc_xfer[CDCE_INTR]); 589 } 590 591 static void 592 cdce_setmulti(struct usb2_ether *ue) 593 { 594 /* no-op */ 595 return; 596 } 597 598 static void 599 cdce_setpromisc(struct usb2_ether *ue) 600 { 601 /* no-op */ 602 return; 603 } 604 605 static int 606 cdce_shutdown(device_t dev) 607 { 608 struct cdce_softc *sc = device_get_softc(dev); 609 610 usb2_ether_ifshutdown(&sc->sc_ue); 611 612 return (0); 613 } 614 615 static int 616 cdce_suspend(device_t dev) 617 { 618 device_printf(dev, "Suspending\n"); 619 return (0); 620 } 621 622 static int 623 cdce_resume(device_t dev) 624 { 625 device_printf(dev, "Resuming\n"); 626 return (0); 627 } 628 629 static void 630 cdce_bulk_read_callback(struct usb2_xfer *xfer) 631 { 632 struct cdce_softc *sc = xfer->priv_sc; 633 struct mbuf *m; 634 uint8_t x; 635 636 switch (USB_GET_STATE(xfer)) { 637 case USB_ST_TRANSFERRED: 638 639 DPRINTF("received %u bytes in %u frames\n", 640 xfer->actlen, xfer->aframes); 641 642 for (x = 0; x != xfer->aframes; x++) { 643 644 m = sc->sc_rx_buf[x]; 645 sc->sc_rx_buf[x] = NULL; 646 647 /* Strip off CRC added by Zaurus, if any */ 648 if ((sc->sc_flags & CDCE_FLAG_ZAURUS) && 649 (xfer->frlengths[x] >= 14)) 650 xfer->frlengths[x] -= 4; 651 652 if (xfer->frlengths[x] < sizeof(struct ether_header)) { 653 m_freem(m); 654 continue; 655 } 656 /* queue up mbuf */ 657 usb2_ether_rxmbuf(&sc->sc_ue, m, xfer->frlengths[x]); 658 } 659 660 /* FALLTHROUGH */ 661 case USB_ST_SETUP: 662 /* 663 * TODO: Implement support for multi frame transfers, 664 * when the USB hardware supports it. 665 */ 666 for (x = 0; x != 1; x++) { 667 if (sc->sc_rx_buf[x] == NULL) { 668 m = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR); 669 if (m == NULL) 670 goto tr_stall; 671 sc->sc_rx_buf[x] = m; 672 /* adjust for ethernet */ 673 m->m_len = m->m_pkthdr.len = MCLBYTES; 674 m_adj(m, ETHER_ALIGN); 675 } else { 676 m = sc->sc_rx_buf[x]; 677 } 678 679 usb2_set_frame_data(xfer, m->m_data, x); 680 xfer->frlengths[x] = m->m_len; 681 } 682 /* set number of frames and start hardware */ 683 xfer->nframes = x; 684 usb2_start_hardware(xfer); 685 /* flush any received frames */ 686 usb2_ether_rxflush(&sc->sc_ue); 687 break; 688 689 default: /* Error */ 690 DPRINTF("error = %s\n", 691 usb2_errstr(xfer->error)); 692 693 if (xfer->error != USB_ERR_CANCELLED) { 694 tr_stall: 695 /* try to clear stall first */ 696 xfer->flags.stall_pipe = 1; 697 xfer->nframes = 0; 698 usb2_start_hardware(xfer); 699 break; 700 } 701 702 /* need to free the RX-mbufs when we are cancelled */ 703 cdce_free_queue(sc->sc_rx_buf, CDCE_FRAMES_MAX); 704 break; 705 } 706 } 707 708 static void 709 cdce_intr_read_callback(struct usb2_xfer *xfer) 710 { 711 ; /* style fix */ 712 switch (USB_GET_STATE(xfer)) { 713 case USB_ST_TRANSFERRED: 714 715 DPRINTF("Received %d bytes\n", 716 xfer->actlen); 717 718 /* TODO: decode some indications */ 719 720 /* FALLTHROUGH */ 721 case USB_ST_SETUP: 722 tr_setup: 723 xfer->frlengths[0] = xfer->max_data_length; 724 usb2_start_hardware(xfer); 725 break; 726 727 default: /* Error */ 728 if (xfer->error != USB_ERR_CANCELLED) { 729 /* start clear stall */ 730 xfer->flags.stall_pipe = 1; 731 goto tr_setup; 732 } 733 break; 734 } 735 } 736 737 static void 738 cdce_intr_write_callback(struct usb2_xfer *xfer) 739 { 740 ; /* style fix */ 741 switch (USB_GET_STATE(xfer)) { 742 case USB_ST_TRANSFERRED: 743 744 DPRINTF("Transferred %d bytes\n", xfer->actlen); 745 746 /* FALLTHROUGH */ 747 case USB_ST_SETUP: 748 tr_setup: 749 #if 0 750 xfer->frlengths[0] = XXX; 751 usb2_start_hardware(xfer); 752 #endif 753 break; 754 755 default: /* Error */ 756 if (xfer->error != USB_ERR_CANCELLED) { 757 /* start clear stall */ 758 xfer->flags.stall_pipe = 1; 759 goto tr_setup; 760 } 761 break; 762 } 763 } 764 765 static int 766 cdce_handle_request(device_t dev, 767 const void *req, void **pptr, uint16_t *plen, 768 uint16_t offset, uint8_t is_complete) 769 { 770 return (ENXIO); /* use builtin handler */ 771 } 772