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