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