1 /* $OpenBSD: if_urndis.c,v 1.46 2013/12/09 15:45:29 pirofti Exp $ */ 2 3 /* 4 * Copyright (c) 2010 Jonathan Armani <armani@openbsd.org> 5 * Copyright (c) 2010 Fabien Romano <fabien@openbsd.org> 6 * Copyright (c) 2010 Michael Knudsen <mk@openbsd.org> 7 * Copyright (c) 2014 Hans Petter Selasky <hselasky@freebsd.org> 8 * All rights reserved. 9 * 10 * Permission to use, copy, modify, and distribute this software for any 11 * purpose with or without fee is hereby granted, provided that the above 12 * copyright notice and this permission notice appear in all copies. 13 * 14 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 15 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 16 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 17 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 18 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 19 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 20 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 21 */ 22 23 #include <sys/cdefs.h> 24 __FBSDID("$FreeBSD: releng/12.2/sys/dev/usb/net/if_urndis.c 365748 2020-09-15 12:34:01Z lwhsu $"); 25 26 #include <lwip/netif.h> 27 #include <lwip/dhcp.h> 28 #include <lwip/netifapi.h> 29 #include <lwip/inet.h> 30 31 #include "if_urndisreg.h" 32 33 static device_probe_t urndis_probe; 34 static device_attach_t urndis_attach; 35 static device_detach_t urndis_detach; 36 static device_suspend_t urndis_suspend; 37 static device_resume_t urndis_resume; 38 39 static usb_callback_t urndis_bulk_write_callback; 40 static usb_callback_t urndis_bulk_read_callback; 41 static usb_callback_t urndis_intr_read_callback; 42 43 static uether_fn_t urndis_attach_post; 44 static uether_fn_t urndis_init; 45 static uether_fn_t urndis_stop; 46 static uether_fn_t urndis_start; 47 static uether_fn_t urndis_setmulti; 48 static uether_fn_t urndis_setpromisc; 49 50 static uint32_t urndis_ctrl_query(struct urndis_softc *sc, uint32_t oid, 51 struct urndis_query_req *msg, uint16_t len, 52 const void **rbuf, uint16_t *rbufsz); 53 static uint32_t urndis_ctrl_set(struct urndis_softc *sc, uint32_t oid, 54 struct urndis_set_req *msg, uint16_t len); 55 static uint32_t urndis_ctrl_handle_init(struct urndis_softc *sc, 56 const struct urndis_comp_hdr *hdr); 57 static uint32_t urndis_ctrl_handle_query(struct urndis_softc *sc, 58 const struct urndis_comp_hdr *hdr, const void **buf, 59 uint16_t *bufsz); 60 static uint32_t urndis_ctrl_handle_reset(struct urndis_softc *sc, 61 const struct urndis_comp_hdr *hdr); 62 static uint32_t urndis_ctrl_init(struct urndis_softc *sc); 63 static uint32_t urndis_ctrl_halt(struct urndis_softc *sc); 64 65 #undef USB_DEBUG_VAR 66 #define USB_DEBUG_VAR urndis_debug 67 #ifdef LOSCFG_USB_DEBUG 68 static int urndis_debug = 0; 69 void 70 usb_urndis_debug_func(int level) 71 { 72 urndis_debug = level; 73 PRINTK("The level of usb urndis debug is %d\n", level); 74 } 75 DEBUG_MODULE(urndis, usb_urndis_debug_func); 76 #endif 77 78 static const struct usb_config urndis_config[URNDIS_N_TRANSFER] = { 79 { /* [URNDIS_BULK_RX] = */ 80 .type = UE_BULK, 81 .endpoint = UE_ADDR_ANY, 82 .direction = UE_DIR_RX, 83 .if_index = 0, 84 .frames = 1, 85 .bufsize = RNDIS_RX_MAXLEN, 86 .flags = {.short_xfer_ok = 1,}, 87 .callback = urndis_bulk_read_callback, 88 .timeout = 0, /* no timeout */ 89 .usb_mode = USB_MODE_HOST, 90 }, 91 92 { /* [URNDIS_BULK_TX] = */ 93 .type = UE_BULK, 94 .endpoint = UE_ADDR_ANY, 95 .direction = UE_DIR_TX, 96 .if_index = 0, 97 .frames = RNDIS_TX_FRAMES_MAX, 98 .bufsize = (RNDIS_TX_FRAMES_MAX * RNDIS_TX_MAXLEN), 99 .flags = { 100 .force_short_xfer = 1, 101 }, 102 .callback = urndis_bulk_write_callback, 103 .timeout = 10000, /* 10 seconds */ 104 .usb_mode = USB_MODE_HOST, 105 }, 106 107 { /* [URNDIS_INTR_RX] = */ 108 .type = UE_INTERRUPT, 109 .endpoint = UE_ADDR_ANY, 110 .direction = UE_DIR_RX, 111 .if_index = 1, 112 .bufsize = 0, /* use wMaxPacketSize */ 113 .flags = {.short_xfer_ok = 1,.no_pipe_ok = 1,}, 114 .callback = urndis_intr_read_callback, 115 .timeout = 0, 116 .usb_mode = USB_MODE_HOST, 117 }, 118 }; 119 120 static device_method_t urndis_methods[] = { 121 /* Device interface */ 122 DEVMETHOD(device_probe, urndis_probe), 123 DEVMETHOD(device_attach, urndis_attach), 124 DEVMETHOD(device_detach, urndis_detach), 125 DEVMETHOD(device_suspend, urndis_suspend), 126 DEVMETHOD(device_resume, urndis_resume), 127 128 DEVMETHOD_END 129 }; 130 131 static driver_t urndis_driver = { 132 .name = "urndis", 133 .methods = urndis_methods, 134 .size = sizeof(struct urndis_softc), 135 }; 136 137 static devclass_t urndis_devclass; 138 139 DRIVER_MODULE(urndis, uhub, urndis_driver, urndis_devclass, NULL, NULL); 140 141 static const struct usb_ether_methods urndis_ue_methods = { 142 .ue_attach_post = urndis_attach_post, 143 .ue_start = urndis_start, 144 .ue_init = urndis_init, 145 .ue_stop = urndis_stop, 146 .ue_setmulti = urndis_setmulti, 147 .ue_setpromisc = urndis_setpromisc, 148 }; 149 150 static const STRUCT_USB_HOST_ID urndis_host_devs[] = { 151 /* Generic RNDIS class match */ 152 {USB_IFACE_CLASS(UICLASS_CDC), 153 USB_IFACE_SUBCLASS(UISUBCLASS_ABSTRACT_CONTROL_MODEL), 154 USB_IFACE_PROTOCOL(0xff)}, 155 {USB_IFACE_CLASS(UICLASS_WIRELESS), USB_IFACE_SUBCLASS(UISUBCLASS_RF), 156 USB_IFACE_PROTOCOL(UIPROTO_RNDIS)}, 157 {USB_IFACE_CLASS(UICLASS_IAD), USB_IFACE_SUBCLASS(UISUBCLASS_SYNC), 158 USB_IFACE_PROTOCOL(UIPROTO_ACTIVESYNC)}, 159 }; 160 161 static int 162 urndis_probe(device_t dev) 163 { 164 struct usb_attach_arg *uaa = device_get_ivars(dev); 165 166 return (usbd_lookup_id_by_uaa(urndis_host_devs, sizeof(urndis_host_devs), uaa)); 167 } 168 169 static void 170 urndis_attach_post(struct usb_ether *ue) 171 { 172 /* no-op */ 173 } 174 175 static int 176 urndis_attach(device_t dev) 177 { 178 static struct { 179 union { 180 struct urndis_query_req query; 181 struct urndis_set_req set; 182 } hdr; 183 union { 184 uint8_t eaddr[NETIF_MAX_HWADDR_LEN]; 185 uint32_t filter; 186 } ibuf; 187 } msg; 188 struct urndis_softc *sc = device_get_softc(dev); 189 struct usb_ether *ue = &sc->sc_ue; 190 struct usb_attach_arg *uaa = device_get_ivars(dev); 191 struct usb_cdc_cm_descriptor *cmd; 192 const void *buf; 193 struct netif *netif; 194 195 uint16_t bufsz; 196 uint8_t iface_index[2] = {0}; 197 int error; 198 uint8_t i; 199 200 sc->sc_ue.ue_udev = uaa->device; 201 sc->sc_ifaceno_ctl = uaa->info.bIfaceNum; 202 iface_index[0] = uaa->info.bIfaceIndex + 1; 203 iface_index[1] = uaa->info.bIfaceIndex; 204 205 cmd = usbd_find_descriptor(uaa->device, NULL, uaa->info.bIfaceIndex, 206 UDESC_CS_INTERFACE, 0xFF, UDESCSUB_CDC_CM, 0xFF); 207 if (cmd != 0) { 208 DPRINTF("Call Mode Descriptor found, dataif=%d\n", cmd->bDataInterface); 209 iface_index[0] = cmd->bDataInterface; 210 } 211 212 device_set_usb_desc(dev); 213 214 mtx_init(&sc->sc_mtx, device_get_nameunit(dev), NULL, MTX_RECURSE); 215 216 /* scan the alternate settings looking for a valid one */ 217 for (i = 0; i != 32; i++) { 218 error = usbd_set_alt_interface_index(uaa->device, 219 iface_index[0], i); 220 221 if (error != 0) 222 break; 223 224 error = usbd_transfer_setup(uaa->device, 225 iface_index, sc->sc_xfer, urndis_config, 226 URNDIS_N_TRANSFER, sc, &sc->sc_mtx); 227 228 if (error == 0) 229 break; 230 } 231 if ((error != 0) || (i == 32)) { 232 device_printf(dev, "No valid alternate setting found\n"); 233 goto detach; 234 } 235 236 URNDIS_LOCK(sc); 237 /* start interrupt endpoint, if any */ 238 usbd_transfer_start(sc->sc_xfer[URNDIS_INTR_RX]); 239 URNDIS_UNLOCK(sc); 240 241 /* Initialize device - must be done before even querying it */ 242 URNDIS_LOCK(sc); 243 error = urndis_ctrl_init(sc); 244 URNDIS_UNLOCK(sc); 245 if (error != (int)RNDIS_STATUS_SUCCESS) { 246 device_printf(dev, "Unable to initialize hardware\n"); 247 goto detach; 248 } 249 250 /* Determine MAC address */ 251 (void)memset_s(msg.ibuf.eaddr, sizeof(msg.ibuf.eaddr), 0, sizeof(msg.ibuf.eaddr)); 252 URNDIS_LOCK(sc); 253 error = urndis_ctrl_query(sc, OID_802_3_PERMANENT_ADDRESS, 254 &msg.hdr.query, sizeof(msg.hdr.query) + sizeof(msg.ibuf.eaddr), 255 &buf, &bufsz); 256 URNDIS_UNLOCK(sc); 257 if (error != (int)RNDIS_STATUS_SUCCESS) { 258 device_printf(dev, "Unable to get hardware address\n"); 259 goto detach; 260 } 261 if (bufsz != NETIF_MAX_HWADDR_LEN) { 262 device_printf(dev, "Invalid address length: %d bytes\n", bufsz); 263 goto detach; 264 } 265 (void)memcpy_s(&sc->sc_ue.ue_eaddr, NETIF_MAX_HWADDR_LEN, buf, NETIF_MAX_HWADDR_LEN); 266 267 /* Initialize packet filter */ 268 sc->sc_filter = RNDIS_PACKET_TYPE_BROADCAST | 269 RNDIS_PACKET_TYPE_ALL_MULTICAST; 270 msg.ibuf.filter = htole32(sc->sc_filter); 271 URNDIS_LOCK(sc); 272 error = urndis_ctrl_set(sc, OID_GEN_CURRENT_PACKET_FILTER, 273 &msg.hdr.set, sizeof(msg.hdr.set) + sizeof(msg.ibuf.filter)); 274 URNDIS_UNLOCK(sc); 275 if (error != (int)RNDIS_STATUS_SUCCESS) { 276 device_printf(dev, "Unable to set data filters\n"); 277 goto detach; 278 } 279 280 ue->ue_sc = sc; 281 ue->ue_dev = dev; 282 ue->ue_udev = uaa->device; 283 ue->ue_mtx = &sc->sc_mtx; 284 ue->ue_methods = &urndis_ue_methods; 285 error = uether_ifattach(ue); 286 if (error) { 287 device_printf(dev, "Could not attach interface\n"); 288 goto detach; 289 } 290 291 error = (int)LOS_EventRead(&ue->ue_event, 0x01, LOS_WAITMODE_OR | LOS_WAITMODE_CLR, 1000); 292 if (error == (int)LOS_ERRNO_EVENT_READ_TIMEOUT) { 293 device_printf(dev, "read sc_event fail , %x\n", error); 294 goto detach; 295 } 296 297 netif = &(ue->ue_drv_sc->ac_if); 298 if (!netif_is_up(netif)) { 299 (void)netifapi_netif_set_up(netif); 300 } 301 302 return (0); /* success */ 303 304 detach: 305 306 (void)urndis_detach(dev); 307 return (ENXIO); /* failure */ 308 } 309 310 static int 311 urndis_detach(device_t dev) 312 { 313 struct urndis_softc *sc = device_get_softc(dev); 314 struct usb_ether *ue = &sc->sc_ue; 315 316 /* stop all USB transfers first */ 317 usbd_transfer_unsetup(sc->sc_xfer, URNDIS_N_TRANSFER); 318 319 uether_ifdetach(ue); 320 321 URNDIS_LOCK(sc); 322 (void)urndis_ctrl_halt(sc); 323 URNDIS_UNLOCK(sc); 324 325 mtx_destroy(&sc->sc_mtx); 326 327 return (0); 328 } 329 330 static void 331 urndis_start(struct usb_ether *ue) 332 { 333 struct urndis_softc *sc = uether_getsc(ue); 334 335 /* 336 * Start the USB transfers, if not already started: 337 */ 338 usbd_transfer_start(sc->sc_xfer[URNDIS_BULK_TX]); 339 usbd_transfer_start(sc->sc_xfer[URNDIS_BULK_RX]); 340 } 341 342 static void 343 urndis_init(struct usb_ether *ue) 344 { 345 struct urndis_softc *sc = uether_getsc(ue); 346 struct los_eth_driver *ifp = ue->ue_drv_sc; 347 struct eth_drv_sc *drv_sc = (struct eth_drv_sc *)ifp->driver_context; 348 349 URNDIS_LOCK_ASSERT(sc, MA_OWNED); 350 351 drv_sc->state |= IFF_DRV_RUNNING; 352 353 /* stall data write direction, which depends on USB mode */ 354 usbd_xfer_set_stall(sc->sc_xfer[URNDIS_BULK_TX]); 355 356 /* start data transfers */ 357 urndis_start(ue); 358 } 359 360 static void 361 urndis_stop(struct usb_ether *ue) 362 { 363 struct urndis_softc *sc = uether_getsc(ue); 364 struct los_eth_driver *ifp = ue->ue_drv_sc; 365 struct eth_drv_sc *drv_sc = (struct eth_drv_sc *)ifp->driver_context; 366 367 URNDIS_LOCK_ASSERT(sc, MA_OWNED); 368 369 drv_sc->state &= ~IFF_DRV_RUNNING; 370 371 /* 372 * stop all the transfers, if not already stopped: 373 */ 374 usbd_transfer_stop(sc->sc_xfer[URNDIS_BULK_RX]); 375 usbd_transfer_stop(sc->sc_xfer[URNDIS_BULK_TX]); 376 } 377 378 static void 379 urndis_setmulti(struct usb_ether *ue) 380 { 381 /* no-op */ 382 } 383 384 static void 385 urndis_setpromisc(struct usb_ether *ue) 386 { 387 /* no-op */ 388 } 389 390 static int 391 urndis_suspend(device_t dev) 392 { 393 device_printf(dev, "Suspending\n"); 394 return (0); 395 } 396 397 static int 398 urndis_resume(device_t dev) 399 { 400 device_printf(dev, "Resuming\n"); 401 return (0); 402 } 403 404 static usb_error_t 405 urndis_ctrl_msg(struct urndis_softc *sc, uint8_t rt, uint8_t r, 406 uint16_t index, uint16_t value, void *buf, uint16_t buflen) 407 { 408 usb_device_request_t req; 409 410 req.bmRequestType = rt; 411 req.bRequest = r; 412 USETW(req.wValue, value); 413 USETW(req.wIndex, index); 414 USETW(req.wLength, buflen); 415 416 return (usbd_do_request_flags(sc->sc_ue.ue_udev, 417 &sc->sc_mtx, &req, buf, (rt & UT_READ) ? 418 USB_SHORT_XFER_OK : 0, NULL, 2000 /* ms */ )); 419 } 420 421 static usb_error_t 422 urndis_ctrl_send(struct urndis_softc *sc, void *buf, uint16_t len) 423 { 424 usb_error_t err; 425 426 err = urndis_ctrl_msg(sc, UT_WRITE_CLASS_INTERFACE, 427 UCDC_SEND_ENCAPSULATED_COMMAND, sc->sc_ifaceno_ctl, 0, buf, len); 428 429 DPRINTF("%s\n", usbd_errstr(err)); 430 431 return (err); 432 } 433 434 static struct urndis_comp_hdr * 435 urndis_ctrl_recv(struct urndis_softc *sc) 436 { 437 struct urndis_comp_hdr *hdr; 438 usb_error_t err; 439 440 err = urndis_ctrl_msg(sc, UT_READ_CLASS_INTERFACE, 441 UCDC_GET_ENCAPSULATED_RESPONSE, sc->sc_ifaceno_ctl, 0, 442 sc->sc_response_buf, RNDIS_RESPONSE_LEN); 443 444 if (err != USB_ERR_NORMAL_COMPLETION) 445 return (NULL); 446 447 hdr = (struct urndis_comp_hdr *)sc->sc_response_buf; 448 449 DPRINTF("type 0x%x len %u\n", le32toh(hdr->rm_type), 450 le32toh(hdr->rm_len)); 451 452 if (le32toh(hdr->rm_len) > RNDIS_RESPONSE_LEN) { 453 DPRINTF("ctrl message error: wrong size %u > %u\n", 454 le32toh(hdr->rm_len), RNDIS_RESPONSE_LEN); 455 return (NULL); 456 } 457 return (hdr); 458 } 459 460 static uint32_t 461 urndis_ctrl_handle(struct urndis_softc *sc, struct urndis_comp_hdr *hdr, 462 const void **buf, uint16_t *bufsz) 463 { 464 uint32_t rval; 465 466 DPRINTF("\n"); 467 468 if (buf != NULL && bufsz != NULL) { 469 *buf = NULL; 470 *bufsz = 0; 471 } 472 switch (le32toh(hdr->rm_type)) { 473 case REMOTE_NDIS_INITIALIZE_CMPLT: 474 rval = urndis_ctrl_handle_init(sc, hdr); 475 break; 476 477 case REMOTE_NDIS_QUERY_CMPLT: 478 rval = urndis_ctrl_handle_query(sc, hdr, buf, bufsz); 479 break; 480 481 case REMOTE_NDIS_RESET_CMPLT: 482 rval = urndis_ctrl_handle_reset(sc, hdr); 483 break; 484 485 case REMOTE_NDIS_KEEPALIVE_CMPLT: 486 /* FALLTHROUGH */ 487 case REMOTE_NDIS_SET_CMPLT: 488 rval = le32toh(hdr->rm_status); 489 break; 490 491 default: 492 device_printf(sc->sc_ue.ue_dev, 493 "ctrl message error: unknown event 0x%x\n", 494 le32toh(hdr->rm_type)); 495 rval = RNDIS_STATUS_FAILURE; 496 break; 497 } 498 return (rval); 499 } 500 501 static uint32_t 502 urndis_ctrl_handle_init(struct urndis_softc *sc, 503 const struct urndis_comp_hdr *hdr) 504 { 505 const struct urndis_init_comp *msg; 506 507 msg = (const struct urndis_init_comp *)hdr; 508 509 DPRINTF("len %u rid %u status 0x%x " 510 "ver_major %u ver_minor %u devflags 0x%x medium 0x%x pktmaxcnt %u " 511 "pktmaxsz %u align %u aflistoffset %u aflistsz %u\n", 512 le32toh(msg->rm_len), 513 le32toh(msg->rm_rid), 514 le32toh(msg->rm_status), 515 le32toh(msg->rm_ver_major), 516 le32toh(msg->rm_ver_minor), 517 le32toh(msg->rm_devflags), 518 le32toh(msg->rm_medium), 519 le32toh(msg->rm_pktmaxcnt), 520 le32toh(msg->rm_pktmaxsz), 521 le32toh(msg->rm_align), 522 le32toh(msg->rm_aflistoffset), 523 le32toh(msg->rm_aflistsz)); 524 525 if (le32toh(msg->rm_status) != RNDIS_STATUS_SUCCESS) { 526 DPRINTF("init failed 0x%x\n", le32toh(msg->rm_status)); 527 return (le32toh(msg->rm_status)); 528 } 529 if (le32toh(msg->rm_devflags) != RNDIS_DF_CONNECTIONLESS) { 530 DPRINTF("wrong device type (current type: 0x%x)\n", 531 le32toh(msg->rm_devflags)); 532 return (RNDIS_STATUS_FAILURE); 533 } 534 if (le32toh(msg->rm_medium) != RNDIS_MEDIUM_802_3) { 535 DPRINTF("medium not 802.3 (current medium: 0x%x)\n", 536 le32toh(msg->rm_medium)); 537 return (RNDIS_STATUS_FAILURE); 538 } 539 sc->sc_lim_pktsz = le32toh(msg->rm_pktmaxsz); 540 541 return (le32toh(msg->rm_status)); 542 } 543 544 static uint32_t 545 urndis_ctrl_handle_query(struct urndis_softc *sc, 546 const struct urndis_comp_hdr *hdr, const void **buf, uint16_t *bufsz) 547 { 548 const struct urndis_query_comp *msg; 549 uint64_t limit; 550 if (hdr == NULL || buf == NULL || bufsz == NULL) { 551 return RNDIS_STATUS_FAILURE; 552 } 553 554 msg = (const struct urndis_query_comp *)hdr; 555 556 DPRINTF("len %u rid %u status 0x%x " 557 "buflen %u bufoff %u\n", 558 le32toh(msg->rm_len), 559 le32toh(msg->rm_rid), 560 le32toh(msg->rm_status), 561 le32toh(msg->rm_infobuflen), 562 le32toh(msg->rm_infobufoffset)); 563 564 *buf = NULL; 565 *bufsz = 0; 566 if (le32toh(msg->rm_status) != RNDIS_STATUS_SUCCESS) { 567 DPRINTF("query failed 0x%x\n", le32toh(msg->rm_status)); 568 return (le32toh(msg->rm_status)); 569 } 570 limit = le32toh(msg->rm_infobuflen); 571 limit += le32toh(msg->rm_infobufoffset); 572 limit += RNDIS_HEADER_OFFSET; 573 574 if (limit > (uint64_t)le32toh(msg->rm_len)) { 575 DPRINTF("ctrl message error: invalid query info " 576 "len/offset/end_position(%u/%u/%u) -> " 577 "go out of buffer limit %u\n", 578 le32toh(msg->rm_infobuflen), 579 le32toh(msg->rm_infobufoffset), 580 le32toh(msg->rm_infobuflen) + 581 le32toh(msg->rm_infobufoffset) + RNDIS_HEADER_OFFSET, 582 le32toh(msg->rm_len)); 583 return (RNDIS_STATUS_FAILURE); 584 } 585 *buf = ((const uint8_t *)msg) + RNDIS_HEADER_OFFSET + 586 le32toh(msg->rm_infobufoffset); 587 *bufsz = le32toh(msg->rm_infobuflen); 588 589 return (le32toh(msg->rm_status)); 590 } 591 592 static uint32_t 593 urndis_ctrl_handle_reset(struct urndis_softc *sc, 594 const struct urndis_comp_hdr *hdr) 595 { 596 const struct urndis_reset_comp *msg; 597 uint32_t rval; 598 599 msg = (const struct urndis_reset_comp *)hdr; 600 601 rval = le32toh(msg->rm_status); 602 603 DPRINTF("len %u status 0x%x " 604 "adrreset %u\n", 605 le32toh(msg->rm_len), 606 rval, 607 le32toh(msg->rm_adrreset)); 608 609 if (rval != RNDIS_STATUS_SUCCESS) { 610 DPRINTF("reset failed 0x%x\n", rval); 611 return (rval); 612 } 613 if (msg->rm_adrreset != 0) { 614 struct { 615 struct urndis_set_req hdr; 616 uint32_t filter; 617 } msg_filter; 618 619 msg_filter.filter = htole32(sc->sc_filter); 620 621 rval = urndis_ctrl_set(sc, OID_GEN_CURRENT_PACKET_FILTER, 622 &msg_filter.hdr, sizeof(msg_filter)); 623 624 if (rval != RNDIS_STATUS_SUCCESS) { 625 DPRINTF("unable to reset data filters\n"); 626 return (rval); 627 } 628 } 629 return (rval); 630 } 631 632 static uint32_t 633 urndis_ctrl_init(struct urndis_softc *sc) 634 { 635 struct urndis_init_req msg; 636 struct urndis_comp_hdr *hdr; 637 uint32_t rval; 638 639 msg.rm_type = htole32(REMOTE_NDIS_INITIALIZE_MSG); 640 msg.rm_len = htole32(sizeof(msg)); 641 msg.rm_rid = 0; 642 msg.rm_ver_major = htole32(1); 643 msg.rm_ver_minor = htole32(1); 644 msg.rm_max_xfersz = htole32(RNDIS_RX_MAXLEN); 645 646 DPRINTF("type %u len %u rid %u ver_major %u " 647 "ver_minor %u max_xfersz %u\n", 648 le32toh(msg.rm_type), 649 le32toh(msg.rm_len), 650 le32toh(msg.rm_rid), 651 le32toh(msg.rm_ver_major), 652 le32toh(msg.rm_ver_minor), 653 le32toh(msg.rm_max_xfersz)); 654 655 rval = urndis_ctrl_send(sc, &msg, sizeof(msg)); 656 657 if (rval != RNDIS_STATUS_SUCCESS) { 658 DPRINTF("init failed\n"); 659 return (rval); 660 } 661 if ((hdr = urndis_ctrl_recv(sc)) == NULL) { 662 DPRINTF("unable to get init response\n"); 663 return (RNDIS_STATUS_FAILURE); 664 } 665 rval = urndis_ctrl_handle(sc, hdr, NULL, NULL); 666 667 return (rval); 668 } 669 670 static uint32_t 671 urndis_ctrl_halt(struct urndis_softc *sc) 672 { 673 struct urndis_halt_req msg; 674 uint32_t rval; 675 676 msg.rm_type = htole32(REMOTE_NDIS_HALT_MSG); 677 msg.rm_len = htole32(sizeof(msg)); 678 msg.rm_rid = 0; 679 680 DPRINTF("type %u len %u rid %u\n", 681 le32toh(msg.rm_type), 682 le32toh(msg.rm_len), 683 le32toh(msg.rm_rid)); 684 685 rval = urndis_ctrl_send(sc, &msg, sizeof(msg)); 686 687 if (rval != RNDIS_STATUS_SUCCESS) 688 DPRINTF("halt failed\n"); 689 690 return (rval); 691 } 692 693 /* 694 * NB: Querying a device has the requirment of using an input buffer the size 695 * of the expected reply or larger, except for variably sized replies. 696 */ 697 static uint32_t 698 urndis_ctrl_query(struct urndis_softc *sc, uint32_t oid, 699 struct urndis_query_req *msg, uint16_t len, const void **rbuf, 700 uint16_t *rbufsz) 701 { 702 struct urndis_comp_hdr *hdr; 703 uint32_t datalen, rval; 704 705 msg->rm_type = htole32(REMOTE_NDIS_QUERY_MSG); 706 msg->rm_len = htole32(len); 707 msg->rm_rid = 0; /* XXX */ 708 msg->rm_oid = htole32(oid); 709 datalen = len - sizeof(*msg); 710 msg->rm_infobuflen = htole32(datalen); 711 if (datalen != 0) { 712 msg->rm_infobufoffset = htole32(sizeof(*msg) - 713 RNDIS_HEADER_OFFSET); 714 } else { 715 msg->rm_infobufoffset = 0; 716 } 717 msg->rm_devicevchdl = 0; 718 719 DPRINTF("type %u len %u rid %u oid 0x%x " 720 "infobuflen %u infobufoffset %u devicevchdl %u\n", 721 le32toh(msg->rm_type), 722 le32toh(msg->rm_len), 723 le32toh(msg->rm_rid), 724 le32toh(msg->rm_oid), 725 le32toh(msg->rm_infobuflen), 726 le32toh(msg->rm_infobufoffset), 727 le32toh(msg->rm_devicevchdl)); 728 729 rval = urndis_ctrl_send(sc, msg, len); 730 731 if (rval != RNDIS_STATUS_SUCCESS) { 732 DPRINTF("query failed\n"); 733 return (rval); 734 } 735 if ((hdr = urndis_ctrl_recv(sc)) == NULL) { 736 DPRINTF("unable to get query response\n"); 737 return (RNDIS_STATUS_FAILURE); 738 } 739 rval = urndis_ctrl_handle(sc, hdr, rbuf, rbufsz); 740 741 return (rval); 742 } 743 744 static uint32_t 745 urndis_ctrl_set(struct urndis_softc *sc, uint32_t oid, 746 struct urndis_set_req *msg, uint16_t len) 747 { 748 struct urndis_comp_hdr *hdr; 749 uint32_t datalen, rval; 750 751 msg->rm_type = htole32(REMOTE_NDIS_SET_MSG); 752 msg->rm_len = htole32(len); 753 msg->rm_rid = 0; /* XXX */ 754 msg->rm_oid = htole32(oid); 755 datalen = len - sizeof(*msg); 756 msg->rm_infobuflen = htole32(datalen); 757 if (datalen != 0) { 758 msg->rm_infobufoffset = htole32(sizeof(*msg) - 759 RNDIS_HEADER_OFFSET); 760 } else { 761 msg->rm_infobufoffset = 0; 762 } 763 msg->rm_devicevchdl = 0; 764 765 DPRINTF("type %u len %u rid %u oid 0x%x " 766 "infobuflen %u infobufoffset %u devicevchdl %u\n", 767 le32toh(msg->rm_type), 768 le32toh(msg->rm_len), 769 le32toh(msg->rm_rid), 770 le32toh(msg->rm_oid), 771 le32toh(msg->rm_infobuflen), 772 le32toh(msg->rm_infobufoffset), 773 le32toh(msg->rm_devicevchdl)); 774 775 rval = urndis_ctrl_send(sc, msg, len); 776 777 if (rval != RNDIS_STATUS_SUCCESS) { 778 DPRINTF("set failed\n"); 779 return (rval); 780 } 781 if ((hdr = urndis_ctrl_recv(sc)) == NULL) { 782 DPRINTF("unable to get set response\n"); 783 return (RNDIS_STATUS_FAILURE); 784 } 785 rval = urndis_ctrl_handle(sc, hdr, NULL, NULL); 786 if (rval != RNDIS_STATUS_SUCCESS) 787 DPRINTF("set failed 0x%x\n", rval); 788 789 return (rval); 790 } 791 792 #define OFFSET_OF(type, field) \ 793 ((size_t)(uintptr_t)((const volatile void *)&((type *)0)->field)) 794 795 static int urndis_bulk_read(struct usb_xfer *xfer, struct urndis_packet_msg *msg, int offset) 796 { 797 struct urndis_softc *sc = usbd_xfer_softc(xfer); 798 struct usb_page_cache *pc = usbd_xfer_get_frame(xfer, 0); 799 struct usb_ether *ue = &sc->sc_ue; 800 struct los_eth_driver *ifp = ue->ue_drv_sc; 801 struct pbuf *m; 802 803 m = pbuf_alloc(PBUF_RAW, msg->rm_datalen + ETH_PAD_SIZE, PBUF_RAM); 804 if (m == NULL){ 805 DPRINTF("pbuf_alloc failed\n"); 806 return (-1); 807 } 808 809 #if ETH_PAD_SIZE 810 /* drop the padding word */ 811 if (pbuf_header(m, -ETH_PAD_SIZE)) { 812 PRINTK("[URNDIS_ERROR]urndis_rxeof : pbuf_header drop failed\n"); 813 (void) pbuf_free(m); 814 return (-1); 815 } 816 #endif 817 818 usbd_copy_out(pc, offset + msg->rm_dataoffset + 819 OFFSET_OF(struct urndis_packet_msg, rm_dataoffset), m->payload, msg->rm_datalen); 820 821 #if ETH_PAD_SIZE 822 /* reclaim the padding word */ 823 if (pbuf_header(m, ETH_PAD_SIZE)) { 824 PRINTK("[URNDIS_ERROR]urndis_rxeof : pbuf_header drop failed\n"); 825 (void) pbuf_free(m); 826 return (-1); 827 } 828 #endif 829 830 /* enqueue */ 831 driverif_input(&ifp->ac_if, m); 832 833 return (0); 834 } 835 836 static void 837 urndis_bulk_read_callback(struct usb_xfer *xfer, usb_error_t error) 838 { 839 struct urndis_softc *sc = usbd_xfer_softc(xfer); 840 struct usb_page_cache *pc = usbd_xfer_get_frame(xfer, 0); 841 struct urndis_packet_msg msg; 842 int actlen; 843 int aframes; 844 int offset; 845 846 switch (USB_GET_STATE(xfer)) { 847 case USB_ST_TRANSFERRED: 848 usbd_xfer_status(xfer, &actlen, NULL, &aframes, NULL); 849 850 DPRINTFN(1, "received %u bytes in %u frames\n", actlen, aframes); 851 852 for (offset = 0; actlen >= (int)sizeof(msg);) { 853 /* copy out header */ 854 usbd_copy_out(pc, offset, &msg, sizeof(msg)); 855 856 if (le32toh(0x1234567U) != 0x1234567U) { 857 /* swap endianness */ 858 msg.rm_type = le32toh(msg.rm_type); 859 msg.rm_len = le32toh(msg.rm_len); 860 msg.rm_dataoffset = le32toh(msg.rm_dataoffset); 861 msg.rm_datalen = le32toh(msg.rm_datalen); 862 msg.rm_oobdataoffset = le32toh(msg.rm_oobdataoffset); 863 msg.rm_oobdatalen = le32toh(msg.rm_oobdatalen); 864 msg.rm_oobdataelements = le32toh(msg.rm_oobdataelements); 865 msg.rm_pktinfooffset = le32toh(msg.rm_pktinfooffset); 866 msg.rm_pktinfolen = le32toh(msg.rm_pktinfolen); 867 msg.rm_vchandle = le32toh(msg.rm_vchandle); 868 msg.rm_reserved = le32toh(msg.rm_reserved); 869 } 870 871 DPRINTF("len %u data(off:%u len:%u) " 872 "oobdata(off:%u len:%u nb:%u) perpacket(off:%u len:%u)\n", 873 msg.rm_len, msg.rm_dataoffset, msg.rm_datalen, 874 msg.rm_oobdataoffset, msg.rm_oobdatalen, 875 msg.rm_oobdataelements, msg.rm_pktinfooffset, 876 msg.rm_pktinfooffset); 877 878 /* sanity check the RNDIS header */ 879 if (msg.rm_type != REMOTE_NDIS_PACKET_MSG) { 880 DPRINTF("invalid type 0x%x != 0x%x\n", 881 msg.rm_type, REMOTE_NDIS_PACKET_MSG); 882 goto tr_setup; 883 } else if (msg.rm_len < (uint32_t)sizeof(msg)) { 884 DPRINTF("invalid msg len %u < %u\n", 885 msg.rm_len, (unsigned)sizeof(msg)); 886 goto tr_setup; 887 } else if (msg.rm_len > (uint32_t)actlen) { 888 DPRINTF("invalid msg len %u > buffer " 889 "len %u\n", msg.rm_len, actlen); 890 goto tr_setup; 891 } else if (msg.rm_dataoffset >= (uint32_t)actlen) { 892 DPRINTF("invalid msg dataoffset %u > buffer " 893 "dataoffset %u\n", msg.rm_dataoffset, actlen); 894 goto tr_setup; 895 } else if (msg.rm_datalen > (uint32_t)actlen) { 896 DPRINTF("invalid msg datalen %u > buffer " 897 "datalen %u\n", msg.rm_datalen, actlen); 898 goto tr_setup; 899 } else if (msg.rm_datalen < (uint32_t)sizeof(struct ether_header)) { 900 DPRINTF("invalid ethernet size " 901 "%u < %u\n", msg.rm_datalen, (unsigned)sizeof(struct ether_header)); 902 goto tr_setup; 903 } else if (msg.rm_datalen > (uint32_t)(MCLBYTES - ETHER_ALIGN)) { 904 DPRINTF("invalid ethernet size " 905 "%u > %u\n", 906 msg.rm_datalen, (unsigned)MCLBYTES); 907 goto tr_setup; 908 } else { 909 if (0 != urndis_bulk_read(xfer, &msg, offset)) { 910 return; 911 } 912 } 913 914 offset += msg.rm_len; 915 actlen -= msg.rm_len; 916 } 917 /* FALLTHROUGH */ 918 919 case USB_ST_SETUP: 920 tr_setup: 921 922 usbd_xfer_set_frame_len(xfer, 0, RNDIS_RX_MAXLEN); 923 usbd_xfer_set_frames(xfer, 1); 924 usbd_transfer_submit(xfer); 925 uether_rxflush(&sc->sc_ue); /* must be last */ 926 break; 927 928 default: /* Error */ 929 DPRINTFN(1, "error = %s\n", usbd_errstr(error)); 930 931 if (error != USB_ERR_CANCELLED) { 932 /* try to clear stall first */ 933 usbd_xfer_set_stall(xfer); 934 usbd_xfer_set_frames(xfer, 0); 935 usbd_transfer_submit(xfer); 936 } 937 break; 938 } 939 } 940 941 static void 942 urndis_bulk_write_callback(struct usb_xfer *xfer, usb_error_t error) 943 { 944 struct urndis_packet_msg msg; 945 struct urndis_softc *sc = usbd_xfer_softc(xfer); 946 struct usb_ether *ue = &sc->sc_ue; 947 struct pbuf *m; 948 unsigned x; 949 int actlen; 950 int aframes; 951 952 usbd_xfer_status(xfer, &actlen, NULL, &aframes, NULL); 953 954 DPRINTFN(1, "\n"); 955 956 switch (USB_GET_STATE(xfer)) { 957 case USB_ST_TRANSFERRED: 958 DPRINTFN(11, "%u bytes in %u frames\n", actlen, aframes); 959 960 /* FALLTHROUGH */ 961 case USB_ST_SETUP: 962 tr_setup: 963 (void)memset_s(&msg, sizeof(msg), 0, sizeof(msg)); 964 965 for (x = 0; x != RNDIS_TX_FRAMES_MAX; x++) { 966 struct usb_page_cache *pc = usbd_xfer_get_frame(xfer, x); 967 968 usbd_xfer_set_frame_offset(xfer, x * RNDIS_TX_MAXLEN, x); 969 970 next_pkt: 971 UE_LOCK(ue); 972 IF_DEQUEUE(&(ue->ue_txq), m); 973 UE_UNLOCK(ue); 974 975 if (m == NULL) 976 break; 977 978 if ((m->len + sizeof(msg)) > RNDIS_TX_MAXLEN) { 979 DPRINTF("Too big packet\n"); 980 981 /* Free buffer */ 982 uether_freebuf(m); 983 goto next_pkt; 984 } 985 msg.rm_type = htole32(REMOTE_NDIS_PACKET_MSG); 986 msg.rm_len = htole32(sizeof(msg) + m->len); 987 988 msg.rm_dataoffset = htole32(RNDIS_DATA_OFFSET); 989 msg.rm_datalen = htole32(m->len); 990 991 /* copy in all data */ 992 usbd_copy_in(pc, 0, &msg, sizeof(msg)); 993 usbd_copy_in(pc, sizeof(msg), m->payload, m->len); 994 usbd_xfer_set_frame_len(xfer, x, sizeof(msg) + m->len); 995 996 /* Free buffer */ 997 uether_freebuf(m); 998 } 999 if (x != 0) { 1000 usbd_xfer_set_frames(xfer, x); 1001 usbd_transfer_submit(xfer); 1002 } 1003 break; 1004 1005 default: /* Error */ 1006 DPRINTFN(11, "transfer error, %s\n", usbd_errstr(error)); 1007 1008 if (error != USB_ERR_CANCELLED) { 1009 /* try to clear stall first */ 1010 usbd_xfer_set_stall(xfer); 1011 goto tr_setup; 1012 } 1013 break; 1014 } 1015 } 1016 1017 static void 1018 urndis_intr_read_callback(struct usb_xfer *xfer, usb_error_t error) 1019 { 1020 int actlen; 1021 1022 usbd_xfer_status(xfer, &actlen, NULL, NULL, NULL); 1023 1024 switch (USB_GET_STATE(xfer)) { 1025 case USB_ST_TRANSFERRED: 1026 1027 DPRINTF("Received %d bytes\n", actlen); 1028 1029 /* TODO: decode some indications */ 1030 1031 /* FALLTHROUGH */ 1032 case USB_ST_SETUP: 1033 tr_setup: 1034 usbd_xfer_set_frame_len(xfer, 0, usbd_xfer_max_len(xfer)); 1035 usbd_transfer_submit(xfer); 1036 break; 1037 1038 default: /* Error */ 1039 if (error != USB_ERR_CANCELLED) { 1040 /* start clear stall */ 1041 usbd_xfer_set_stall(xfer); 1042 goto tr_setup; 1043 } 1044 break; 1045 } 1046 } 1047 1048 #undef USB_DEBUG_VAR 1049