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