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