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