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