1 /* $NetBSD: if_urndis.c,v 1.18 2018/06/26 06:48:02 msaitoh Exp $ */ 2 /* $OpenBSD: if_urndis.c,v 1.31 2011/07/03 15:47:17 matthew Exp $ */ 3 4 /* 5 * Copyright (c) 2010 Jonathan Armani <armani@openbsd.org> 6 * Copyright (c) 2010 Fabien Romano <fabien@openbsd.org> 7 * Copyright (c) 2010 Michael Knudsen <mk@openbsd.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 __KERNEL_RCSID(0, "$NetBSD: if_urndis.c,v 1.18 2018/06/26 06:48:02 msaitoh Exp $"); 25 26 #ifdef _KERNEL_OPT 27 #include "opt_usb.h" 28 #endif 29 30 #include <sys/param.h> 31 #include <sys/systm.h> 32 #include <sys/sockio.h> 33 #include <sys/rwlock.h> 34 #include <sys/mbuf.h> 35 #include <sys/kmem.h> 36 #include <sys/kernel.h> 37 #include <sys/proc.h> 38 #include <sys/socket.h> 39 #include <sys/device.h> 40 41 #include <net/if.h> 42 #include <net/if_dl.h> 43 #include <net/if_media.h> 44 #include <net/if_ether.h> 45 46 #include <net/bpf.h> 47 48 #include <sys/bus.h> 49 #include <dev/usb/usb.h> 50 #include <dev/usb/usbdi.h> 51 #include <dev/usb/usbdi_util.h> 52 #include <dev/usb/usbdivar.h> 53 #include <dev/usb/usbdevs.h> 54 #include <dev/usb/usbcdc.h> 55 56 #include <dev/usb/if_urndisreg.h> 57 58 #ifdef URNDIS_DEBUG 59 #define DPRINTF(x) do { printf x; } while (0) 60 #else 61 #define DPRINTF(x) 62 #endif 63 64 #define DEVNAME(sc) (device_xname(sc->sc_dev)) 65 66 #define ETHER_ALIGN 2 67 #define URNDIS_RESPONSE_LEN 0x400 68 69 70 static int urndis_newbuf(struct urndis_softc *, struct urndis_chain *); 71 72 static int urndis_ioctl(struct ifnet *, unsigned long, void *); 73 #if 0 74 static void urndis_watchdog(struct ifnet *); 75 #endif 76 77 static void urndis_start(struct ifnet *); 78 static void urndis_rxeof(struct usbd_xfer *, void *, usbd_status); 79 static void urndis_txeof(struct usbd_xfer *, void *, usbd_status); 80 static int urndis_rx_list_init(struct urndis_softc *); 81 static int urndis_tx_list_init(struct urndis_softc *); 82 83 static int urndis_init(struct ifnet *); 84 static void urndis_stop(struct ifnet *); 85 86 static usbd_status urndis_ctrl_msg(struct urndis_softc *, uint8_t, uint8_t, 87 uint16_t, uint16_t, void *, size_t); 88 static usbd_status urndis_ctrl_send(struct urndis_softc *, void *, size_t); 89 static struct urndis_comp_hdr *urndis_ctrl_recv(struct urndis_softc *); 90 91 static uint32_t urndis_ctrl_handle(struct urndis_softc *, 92 struct urndis_comp_hdr *, void **, size_t *); 93 static uint32_t urndis_ctrl_handle_init(struct urndis_softc *, 94 const struct urndis_comp_hdr *); 95 static uint32_t urndis_ctrl_handle_query(struct urndis_softc *, 96 const struct urndis_comp_hdr *, void **, size_t *); 97 static uint32_t urndis_ctrl_handle_reset(struct urndis_softc *, 98 const struct urndis_comp_hdr *); 99 100 static uint32_t urndis_ctrl_init(struct urndis_softc *); 101 #if 0 102 static uint32_t urndis_ctrl_halt(struct urndis_softc *); 103 #endif 104 static uint32_t urndis_ctrl_query(struct urndis_softc *, uint32_t, void *, 105 size_t, void **, size_t *); 106 static uint32_t urndis_ctrl_set(struct urndis_softc *, uint32_t, void *, 107 size_t); 108 #if 0 109 static uint32_t urndis_ctrl_set_param(struct urndis_softc *, const char *, 110 uint32_t, void *, size_t); 111 static uint32_t urndis_ctrl_reset(struct urndis_softc *); 112 static uint32_t urndis_ctrl_keepalive(struct urndis_softc *); 113 #endif 114 115 static int urndis_encap(struct urndis_softc *, struct mbuf *, int); 116 static void urndis_decap(struct urndis_softc *, struct urndis_chain *, 117 uint32_t); 118 119 static int urndis_match(device_t, cfdata_t, void *); 120 static void urndis_attach(device_t, device_t, void *); 121 static int urndis_detach(device_t, int); 122 static int urndis_activate(device_t, enum devact); 123 124 CFATTACH_DECL_NEW(urndis, sizeof(struct urndis_softc), 125 urndis_match, urndis_attach, urndis_detach, urndis_activate); 126 127 /* 128 * Supported devices that we can't match by class IDs. 129 */ 130 static const struct usb_devno urndis_devs[] = { 131 { USB_VENDOR_HTC, USB_PRODUCT_HTC_ANDROID }, 132 { USB_VENDOR_SAMSUNG, USB_PRODUCT_SAMSUNG_ANDROID2 }, 133 }; 134 135 static usbd_status 136 urndis_ctrl_msg(struct urndis_softc *sc, uint8_t rt, uint8_t r, 137 uint16_t index, uint16_t value, void *buf, size_t buflen) 138 { 139 usb_device_request_t req; 140 141 req.bmRequestType = rt; 142 req.bRequest = r; 143 USETW(req.wValue, value); 144 USETW(req.wIndex, index); 145 USETW(req.wLength, buflen); 146 147 return usbd_do_request(sc->sc_udev, &req, buf); 148 } 149 150 static usbd_status 151 urndis_ctrl_send(struct urndis_softc *sc, void *buf, size_t len) 152 { 153 usbd_status err; 154 155 if (sc->sc_dying) 156 return(0); 157 158 err = urndis_ctrl_msg(sc, UT_WRITE_CLASS_INTERFACE, UR_GET_STATUS, 159 sc->sc_ifaceno_ctl, 0, buf, len); 160 161 if (err != USBD_NORMAL_COMPLETION) 162 printf("%s: %s\n", DEVNAME(sc), usbd_errstr(err)); 163 164 return err; 165 } 166 167 static struct urndis_comp_hdr * 168 urndis_ctrl_recv(struct urndis_softc *sc) 169 { 170 struct urndis_comp_hdr *hdr; 171 char *buf; 172 usbd_status err; 173 174 buf = kmem_alloc(URNDIS_RESPONSE_LEN, KM_SLEEP); 175 err = urndis_ctrl_msg(sc, UT_READ_CLASS_INTERFACE, UR_CLEAR_FEATURE, 176 sc->sc_ifaceno_ctl, 0, buf, URNDIS_RESPONSE_LEN); 177 178 if (err != USBD_NORMAL_COMPLETION && err != USBD_SHORT_XFER) { 179 printf("%s: %s\n", DEVNAME(sc), usbd_errstr(err)); 180 kmem_free(buf, URNDIS_RESPONSE_LEN); 181 return NULL; 182 } 183 184 hdr = (struct urndis_comp_hdr *)buf; 185 DPRINTF(("%s: urndis_ctrl_recv: type 0x%x len %u\n", 186 DEVNAME(sc), 187 le32toh(hdr->rm_type), 188 le32toh(hdr->rm_len))); 189 190 if (le32toh(hdr->rm_len) > URNDIS_RESPONSE_LEN) { 191 printf("%s: ctrl message error: wrong size %u > %u\n", 192 DEVNAME(sc), 193 le32toh(hdr->rm_len), 194 URNDIS_RESPONSE_LEN); 195 kmem_free(buf, URNDIS_RESPONSE_LEN); 196 return NULL; 197 } 198 199 return hdr; 200 } 201 202 static uint32_t 203 urndis_ctrl_handle(struct urndis_softc *sc, struct urndis_comp_hdr *hdr, 204 void **buf, size_t *bufsz) 205 { 206 uint32_t rval; 207 208 DPRINTF(("%s: urndis_ctrl_handle\n", DEVNAME(sc))); 209 210 if (buf && bufsz) { 211 *buf = NULL; 212 *bufsz = 0; 213 } 214 215 switch (le32toh(hdr->rm_type)) { 216 case REMOTE_NDIS_INITIALIZE_CMPLT: 217 rval = urndis_ctrl_handle_init(sc, hdr); 218 break; 219 220 case REMOTE_NDIS_QUERY_CMPLT: 221 rval = urndis_ctrl_handle_query(sc, hdr, buf, bufsz); 222 break; 223 224 case REMOTE_NDIS_RESET_CMPLT: 225 rval = urndis_ctrl_handle_reset(sc, hdr); 226 break; 227 228 case REMOTE_NDIS_KEEPALIVE_CMPLT: 229 case REMOTE_NDIS_SET_CMPLT: 230 rval = le32toh(hdr->rm_status); 231 break; 232 233 default: 234 printf("%s: ctrl message error: unknown event 0x%x\n", 235 DEVNAME(sc), le32toh(hdr->rm_type)); 236 rval = RNDIS_STATUS_FAILURE; 237 } 238 239 kmem_free(hdr, URNDIS_RESPONSE_LEN); 240 241 return rval; 242 } 243 244 static uint32_t 245 urndis_ctrl_handle_init(struct urndis_softc *sc, 246 const struct urndis_comp_hdr *hdr) 247 { 248 const struct urndis_init_comp *msg; 249 250 msg = (const struct urndis_init_comp *) hdr; 251 252 DPRINTF(("%s: urndis_ctrl_handle_init: len %u rid %u status 0x%x " 253 "ver_major %u ver_minor %u devflags 0x%x medium 0x%x pktmaxcnt %u " 254 "pktmaxsz %u align %u aflistoffset %u aflistsz %u\n", 255 DEVNAME(sc), 256 le32toh(msg->rm_len), 257 le32toh(msg->rm_rid), 258 le32toh(msg->rm_status), 259 le32toh(msg->rm_ver_major), 260 le32toh(msg->rm_ver_minor), 261 le32toh(msg->rm_devflags), 262 le32toh(msg->rm_medium), 263 le32toh(msg->rm_pktmaxcnt), 264 le32toh(msg->rm_pktmaxsz), 265 le32toh(msg->rm_align), 266 le32toh(msg->rm_aflistoffset), 267 le32toh(msg->rm_aflistsz))); 268 269 if (le32toh(msg->rm_status) != RNDIS_STATUS_SUCCESS) { 270 printf("%s: init failed 0x%x\n", 271 DEVNAME(sc), 272 le32toh(msg->rm_status)); 273 274 return le32toh(msg->rm_status); 275 } 276 277 if (le32toh(msg->rm_devflags) != RNDIS_DF_CONNECTIONLESS) { 278 printf("%s: wrong device type (current type: 0x%x)\n", 279 DEVNAME(sc), 280 le32toh(msg->rm_devflags)); 281 282 return RNDIS_STATUS_FAILURE; 283 } 284 285 if (le32toh(msg->rm_medium) != RNDIS_MEDIUM_802_3) { 286 printf("%s: medium not 802.3 (current medium: 0x%x)\n", 287 DEVNAME(sc), le32toh(msg->rm_medium)); 288 289 return RNDIS_STATUS_FAILURE; 290 } 291 292 sc->sc_lim_pktsz = le32toh(msg->rm_pktmaxsz); 293 294 return le32toh(msg->rm_status); 295 } 296 297 static uint32_t 298 urndis_ctrl_handle_query(struct urndis_softc *sc, 299 const struct urndis_comp_hdr *hdr, void **buf, size_t *bufsz) 300 { 301 const struct urndis_query_comp *msg; 302 303 msg = (const struct urndis_query_comp *) hdr; 304 305 DPRINTF(("%s: urndis_ctrl_handle_query: len %u rid %u status 0x%x " 306 "buflen %u bufoff %u\n", 307 DEVNAME(sc), 308 le32toh(msg->rm_len), 309 le32toh(msg->rm_rid), 310 le32toh(msg->rm_status), 311 le32toh(msg->rm_infobuflen), 312 le32toh(msg->rm_infobufoffset))); 313 314 if (buf && bufsz) { 315 *buf = NULL; 316 *bufsz = 0; 317 } 318 319 if (le32toh(msg->rm_status) != RNDIS_STATUS_SUCCESS) { 320 printf("%s: query failed 0x%x\n", 321 DEVNAME(sc), 322 le32toh(msg->rm_status)); 323 324 return le32toh(msg->rm_status); 325 } 326 327 if (le32toh(msg->rm_infobuflen) + le32toh(msg->rm_infobufoffset) + 328 RNDIS_HEADER_OFFSET > le32toh(msg->rm_len)) { 329 printf("%s: ctrl message error: invalid query info " 330 "len/offset/end_position(%u/%u/%u) -> " 331 "go out of buffer limit %u\n", 332 DEVNAME(sc), 333 le32toh(msg->rm_infobuflen), 334 le32toh(msg->rm_infobufoffset), 335 le32toh(msg->rm_infobuflen) + 336 le32toh(msg->rm_infobufoffset) + (uint32_t)RNDIS_HEADER_OFFSET, 337 le32toh(msg->rm_len)); 338 return RNDIS_STATUS_FAILURE; 339 } 340 341 if (buf && bufsz) { 342 const char *p; 343 344 *buf = kmem_alloc(le32toh(msg->rm_infobuflen), KM_SLEEP); 345 *bufsz = le32toh(msg->rm_infobuflen); 346 347 p = (const char *)&msg->rm_rid; 348 p += le32toh(msg->rm_infobufoffset); 349 memcpy(*buf, p, le32toh(msg->rm_infobuflen)); 350 } 351 352 return le32toh(msg->rm_status); 353 } 354 355 static uint32_t 356 urndis_ctrl_handle_reset(struct urndis_softc *sc, 357 const struct urndis_comp_hdr *hdr) 358 { 359 const struct urndis_reset_comp *msg; 360 uint32_t rval; 361 362 msg = (const struct urndis_reset_comp *) hdr; 363 364 rval = le32toh(msg->rm_status); 365 366 DPRINTF(("%s: urndis_ctrl_handle_reset: len %u status 0x%x " 367 "adrreset %u\n", 368 DEVNAME(sc), 369 le32toh(msg->rm_len), 370 rval, 371 le32toh(msg->rm_adrreset))); 372 373 if (rval != RNDIS_STATUS_SUCCESS) { 374 printf("%s: reset failed 0x%x\n", DEVNAME(sc), rval); 375 return rval; 376 } 377 378 if (le32toh(msg->rm_adrreset) != 0) { 379 uint32_t filter; 380 381 filter = htole32(sc->sc_filter); 382 rval = urndis_ctrl_set(sc, OID_GEN_CURRENT_PACKET_FILTER, 383 &filter, sizeof(filter)); 384 if (rval != RNDIS_STATUS_SUCCESS) { 385 printf("%s: unable to reset data filters\n", 386 DEVNAME(sc)); 387 return rval; 388 } 389 } 390 391 return rval; 392 } 393 394 static uint32_t 395 urndis_ctrl_init(struct urndis_softc *sc) 396 { 397 struct urndis_init_req *msg; 398 uint32_t rval; 399 struct urndis_comp_hdr *hdr; 400 401 msg = kmem_alloc(sizeof(*msg), KM_SLEEP); 402 msg->rm_type = htole32(REMOTE_NDIS_INITIALIZE_MSG); 403 msg->rm_len = htole32(sizeof(*msg)); 404 msg->rm_rid = htole32(0); 405 msg->rm_ver_major = htole32(1); 406 msg->rm_ver_minor = htole32(1); 407 msg->rm_max_xfersz = htole32(RNDIS_BUFSZ); 408 409 DPRINTF(("%s: urndis_ctrl_init send: type %u len %u rid %u ver_major %u " 410 "ver_minor %u max_xfersz %u\n", 411 DEVNAME(sc), 412 le32toh(msg->rm_type), 413 le32toh(msg->rm_len), 414 le32toh(msg->rm_rid), 415 le32toh(msg->rm_ver_major), 416 le32toh(msg->rm_ver_minor), 417 le32toh(msg->rm_max_xfersz))); 418 419 rval = urndis_ctrl_send(sc, msg, sizeof(*msg)); 420 kmem_free(msg, sizeof(*msg)); 421 422 if (rval != RNDIS_STATUS_SUCCESS) { 423 printf("%s: init failed\n", DEVNAME(sc)); 424 return rval; 425 } 426 427 if ((hdr = urndis_ctrl_recv(sc)) == NULL) { 428 printf("%s: unable to get init response\n", DEVNAME(sc)); 429 return RNDIS_STATUS_FAILURE; 430 } 431 rval = urndis_ctrl_handle(sc, hdr, NULL, NULL); 432 433 return rval; 434 } 435 436 #if 0 437 static uint32_t 438 urndis_ctrl_halt(struct urndis_softc *sc) 439 { 440 struct urndis_halt_req *msg; 441 uint32_t rval; 442 443 msg = kmem_alloc(sizeof(*msg), KM_SLEEP); 444 msg->rm_type = htole32(REMOTE_NDIS_HALT_MSG); 445 msg->rm_len = htole32(sizeof(*msg)); 446 msg->rm_rid = 0; 447 448 DPRINTF(("%s: urndis_ctrl_halt send: type %u len %u rid %u\n", 449 DEVNAME(sc), 450 le32toh(msg->rm_type), 451 le32toh(msg->rm_len), 452 le32toh(msg->rm_rid))); 453 454 rval = urndis_ctrl_send(sc, msg, sizeof(*msg)); 455 kmem_free(msg, sizeof(*msg)); 456 457 if (rval != RNDIS_STATUS_SUCCESS) 458 printf("%s: halt failed\n", DEVNAME(sc)); 459 460 return rval; 461 } 462 #endif 463 464 static uint32_t 465 urndis_ctrl_query(struct urndis_softc *sc, uint32_t oid, 466 void *qbuf, size_t qlen, 467 void **rbuf, size_t *rbufsz) 468 { 469 struct urndis_query_req *msg; 470 uint32_t rval; 471 struct urndis_comp_hdr *hdr; 472 473 msg = kmem_alloc(sizeof(*msg) + qlen, KM_SLEEP); 474 msg->rm_type = htole32(REMOTE_NDIS_QUERY_MSG); 475 msg->rm_len = htole32(sizeof(*msg) + qlen); 476 msg->rm_rid = 0; /* XXX */ 477 msg->rm_oid = htole32(oid); 478 msg->rm_infobuflen = htole32(qlen); 479 if (qlen != 0) { 480 msg->rm_infobufoffset = htole32(20); 481 memcpy((char*)msg + 20, qbuf, qlen); 482 } else 483 msg->rm_infobufoffset = 0; 484 msg->rm_devicevchdl = 0; 485 486 DPRINTF(("%s: urndis_ctrl_query send: type %u len %u rid %u oid 0x%x " 487 "infobuflen %u infobufoffset %u devicevchdl %u\n", 488 DEVNAME(sc), 489 le32toh(msg->rm_type), 490 le32toh(msg->rm_len), 491 le32toh(msg->rm_rid), 492 le32toh(msg->rm_oid), 493 le32toh(msg->rm_infobuflen), 494 le32toh(msg->rm_infobufoffset), 495 le32toh(msg->rm_devicevchdl))); 496 497 rval = urndis_ctrl_send(sc, msg, sizeof(*msg)); 498 kmem_free(msg, sizeof(*msg) + qlen); 499 500 if (rval != RNDIS_STATUS_SUCCESS) { 501 printf("%s: query failed\n", DEVNAME(sc)); 502 return rval; 503 } 504 505 if ((hdr = urndis_ctrl_recv(sc)) == NULL) { 506 printf("%s: unable to get query response\n", DEVNAME(sc)); 507 return RNDIS_STATUS_FAILURE; 508 } 509 rval = urndis_ctrl_handle(sc, hdr, rbuf, rbufsz); 510 511 return rval; 512 } 513 514 static uint32_t 515 urndis_ctrl_set(struct urndis_softc *sc, uint32_t oid, void *buf, size_t len) 516 { 517 struct urndis_set_req *msg; 518 uint32_t rval; 519 struct urndis_comp_hdr *hdr; 520 521 msg = kmem_alloc(sizeof(*msg) + len, KM_SLEEP); 522 msg->rm_type = htole32(REMOTE_NDIS_SET_MSG); 523 msg->rm_len = htole32(sizeof(*msg) + len); 524 msg->rm_rid = 0; /* XXX */ 525 msg->rm_oid = htole32(oid); 526 msg->rm_infobuflen = htole32(len); 527 if (len != 0) { 528 msg->rm_infobufoffset = htole32(20); 529 memcpy((char*)msg + 20, buf, len); 530 } else 531 msg->rm_infobufoffset = 0; 532 msg->rm_devicevchdl = 0; 533 534 DPRINTF(("%s: urndis_ctrl_set send: type %u len %u rid %u oid 0x%x " 535 "infobuflen %u infobufoffset %u devicevchdl %u\n", 536 DEVNAME(sc), 537 le32toh(msg->rm_type), 538 le32toh(msg->rm_len), 539 le32toh(msg->rm_rid), 540 le32toh(msg->rm_oid), 541 le32toh(msg->rm_infobuflen), 542 le32toh(msg->rm_infobufoffset), 543 le32toh(msg->rm_devicevchdl))); 544 545 rval = urndis_ctrl_send(sc, msg, sizeof(*msg)); 546 kmem_free(msg, sizeof(*msg) + len); 547 548 if (rval != RNDIS_STATUS_SUCCESS) { 549 printf("%s: set failed\n", DEVNAME(sc)); 550 return rval; 551 } 552 553 if ((hdr = urndis_ctrl_recv(sc)) == NULL) { 554 printf("%s: unable to get set response\n", DEVNAME(sc)); 555 return RNDIS_STATUS_FAILURE; 556 } 557 rval = urndis_ctrl_handle(sc, hdr, NULL, NULL); 558 if (rval != RNDIS_STATUS_SUCCESS) 559 printf("%s: set failed 0x%x\n", DEVNAME(sc), rval); 560 561 return rval; 562 } 563 564 #if 0 565 static uint32_t 566 urndis_ctrl_set_param(struct urndis_softc *sc, 567 const char *name, 568 uint32_t type, 569 void *buf, 570 size_t len) 571 { 572 struct urndis_set_parameter *param; 573 uint32_t rval; 574 size_t namelen, tlen; 575 576 if (name) 577 namelen = strlen(name); 578 else 579 namelen = 0; 580 tlen = sizeof(*param) + len + namelen; 581 param = kmem_alloc(tlen, KM_SLEEP); 582 param->rm_namelen = htole32(namelen); 583 param->rm_valuelen = htole32(len); 584 param->rm_type = htole32(type); 585 if (namelen != 0) { 586 param->rm_nameoffset = htole32(20); 587 memcpy(param + 20, name, namelen); 588 } else 589 param->rm_nameoffset = 0; 590 if (len != 0) { 591 param->rm_valueoffset = htole32(20 + namelen); 592 memcpy(param + 20 + namelen, buf, len); 593 } else 594 param->rm_valueoffset = 0; 595 596 DPRINTF(("%s: urndis_ctrl_set_param send: nameoffset %u namelen %u " 597 "type 0x%x valueoffset %u valuelen %u\n", 598 DEVNAME(sc), 599 le32toh(param->rm_nameoffset), 600 le32toh(param->rm_namelen), 601 le32toh(param->rm_type), 602 le32toh(param->rm_valueoffset), 603 le32toh(param->rm_valuelen))); 604 605 rval = urndis_ctrl_set(sc, OID_GEN_RNDIS_CONFIG_PARAMETER, param, tlen); 606 kmem_free(param, tlen); 607 if (rval != RNDIS_STATUS_SUCCESS) 608 printf("%s: set param failed 0x%x\n", DEVNAME(sc), rval); 609 610 return rval; 611 } 612 613 /* XXX : adrreset, get it from response */ 614 static uint32_t 615 urndis_ctrl_reset(struct urndis_softc *sc) 616 { 617 struct urndis_reset_req *reset; 618 uint32_t rval; 619 struct urndis_comp_hdr *hdr; 620 621 reset = kmem_alloc(sizeof(*reset), KM_SLEEP); 622 reset->rm_type = htole32(REMOTE_NDIS_RESET_MSG); 623 reset->rm_len = htole32(sizeof(*reset)); 624 reset->rm_rid = 0; /* XXX rm_rid == reserved ... remove ? */ 625 626 DPRINTF(("%s: urndis_ctrl_reset send: type %u len %u rid %u\n", 627 DEVNAME(sc), 628 le32toh(reset->rm_type), 629 le32toh(reset->rm_len), 630 le32toh(reset->rm_rid))); 631 632 rval = urndis_ctrl_send(sc, reset, sizeof(*reset)); 633 kmem_free(reset, sizeof(*reset)); 634 635 if (rval != RNDIS_STATUS_SUCCESS) { 636 printf("%s: reset failed\n", DEVNAME(sc)); 637 return rval; 638 } 639 640 if ((hdr = urndis_ctrl_recv(sc)) == NULL) { 641 printf("%s: unable to get reset response\n", DEVNAME(sc)); 642 return RNDIS_STATUS_FAILURE; 643 } 644 rval = urndis_ctrl_handle(sc, hdr, NULL, NULL); 645 646 return rval; 647 } 648 649 static uint32_t 650 urndis_ctrl_keepalive(struct urndis_softc *sc) 651 { 652 struct urndis_keepalive_req *keep; 653 uint32_t rval; 654 struct urndis_comp_hdr *hdr; 655 656 keep = kmem_alloc(sizeof(*keep), KM_SLEEP); 657 keep->rm_type = htole32(REMOTE_NDIS_KEEPALIVE_MSG); 658 keep->rm_len = htole32(sizeof(*keep)); 659 keep->rm_rid = 0; /* XXX rm_rid == reserved ... remove ? */ 660 661 DPRINTF(("%s: urndis_ctrl_keepalive: type %u len %u rid %u\n", 662 DEVNAME(sc), 663 le32toh(keep->rm_type), 664 le32toh(keep->rm_len), 665 le32toh(keep->rm_rid))); 666 667 rval = urndis_ctrl_send(sc, keep, sizeof(*keep)); 668 kmem_free(keep, sizeof(*keep)); 669 670 if (rval != RNDIS_STATUS_SUCCESS) { 671 printf("%s: keepalive failed\n", DEVNAME(sc)); 672 return rval; 673 } 674 675 if ((hdr = urndis_ctrl_recv(sc)) == NULL) { 676 printf("%s: unable to get keepalive response\n", DEVNAME(sc)); 677 return RNDIS_STATUS_FAILURE; 678 } 679 rval = urndis_ctrl_handle(sc, hdr, NULL, NULL); 680 if (rval != RNDIS_STATUS_SUCCESS) { 681 printf("%s: keepalive failed 0x%x\n", DEVNAME(sc), rval); 682 urndis_ctrl_reset(sc); 683 } 684 685 return rval; 686 } 687 #endif 688 689 static int 690 urndis_encap(struct urndis_softc *sc, struct mbuf *m, int idx) 691 { 692 struct urndis_chain *c; 693 usbd_status err; 694 struct urndis_packet_msg *msg; 695 696 c = &sc->sc_data.sc_tx_chain[idx]; 697 698 msg = (struct urndis_packet_msg *)c->sc_buf; 699 700 memset(msg, 0, sizeof(*msg)); 701 msg->rm_type = htole32(REMOTE_NDIS_PACKET_MSG); 702 msg->rm_len = htole32(sizeof(*msg) + m->m_pkthdr.len); 703 704 msg->rm_dataoffset = htole32(RNDIS_DATA_OFFSET); 705 msg->rm_datalen = htole32(m->m_pkthdr.len); 706 707 m_copydata(m, 0, m->m_pkthdr.len, 708 ((char*)msg + RNDIS_DATA_OFFSET + RNDIS_HEADER_OFFSET)); 709 710 DPRINTF(("%s: urndis_encap type 0x%x len %u data(off %u len %u)\n", 711 DEVNAME(sc), 712 le32toh(msg->rm_type), 713 le32toh(msg->rm_len), 714 le32toh(msg->rm_dataoffset), 715 le32toh(msg->rm_datalen))); 716 717 c->sc_mbuf = m; 718 719 usbd_setup_xfer(c->sc_xfer, c, c->sc_buf, le32toh(msg->rm_len), 720 USBD_FORCE_SHORT_XFER, 10000, urndis_txeof); 721 722 /* Transmit */ 723 err = usbd_transfer(c->sc_xfer); 724 if (err != USBD_IN_PROGRESS) { 725 urndis_stop(GET_IFP(sc)); 726 return(EIO); 727 } 728 729 sc->sc_data.sc_tx_cnt++; 730 731 return(0); 732 } 733 734 static void 735 urndis_decap(struct urndis_softc *sc, struct urndis_chain *c, uint32_t len) 736 { 737 struct mbuf *m; 738 struct urndis_packet_msg *msg; 739 struct ifnet *ifp; 740 int s; 741 int offset; 742 743 ifp = GET_IFP(sc); 744 offset = 0; 745 746 while (len > 0) { 747 msg = (struct urndis_packet_msg *)((char*)c->sc_buf + offset); 748 m = c->sc_mbuf; 749 750 DPRINTF(("%s: urndis_decap buffer size left %u\n", DEVNAME(sc), 751 len)); 752 753 if (len < sizeof(*msg)) { 754 printf("%s: urndis_decap invalid buffer len %u < " 755 "minimum header %zu\n", 756 DEVNAME(sc), 757 len, 758 sizeof(*msg)); 759 return; 760 } 761 762 DPRINTF(("%s: urndis_decap len %u data(off:%u len:%u) " 763 "oobdata(off:%u len:%u nb:%u) perpacket(off:%u len:%u)\n", 764 DEVNAME(sc), 765 le32toh(msg->rm_len), 766 le32toh(msg->rm_dataoffset), 767 le32toh(msg->rm_datalen), 768 le32toh(msg->rm_oobdataoffset), 769 le32toh(msg->rm_oobdatalen), 770 le32toh(msg->rm_oobdataelements), 771 le32toh(msg->rm_pktinfooffset), 772 le32toh(msg->rm_pktinfooffset))); 773 774 if (le32toh(msg->rm_type) != REMOTE_NDIS_PACKET_MSG) { 775 printf("%s: urndis_decap invalid type 0x%x != 0x%x\n", 776 DEVNAME(sc), 777 le32toh(msg->rm_type), 778 REMOTE_NDIS_PACKET_MSG); 779 return; 780 } 781 if (le32toh(msg->rm_len) < sizeof(*msg)) { 782 printf("%s: urndis_decap invalid msg len %u < %zu\n", 783 DEVNAME(sc), 784 le32toh(msg->rm_len), 785 sizeof(*msg)); 786 return; 787 } 788 if (le32toh(msg->rm_len) > len) { 789 printf("%s: urndis_decap invalid msg len %u > buffer " 790 "len %u\n", 791 DEVNAME(sc), 792 le32toh(msg->rm_len), 793 len); 794 return; 795 } 796 797 if (le32toh(msg->rm_dataoffset) + 798 le32toh(msg->rm_datalen) + RNDIS_HEADER_OFFSET 799 > le32toh(msg->rm_len)) { 800 printf("%s: urndis_decap invalid data " 801 "len/offset/end_position(%u/%u/%u) -> " 802 "go out of receive buffer limit %u\n", 803 DEVNAME(sc), 804 le32toh(msg->rm_datalen), 805 le32toh(msg->rm_dataoffset), 806 le32toh(msg->rm_dataoffset) + 807 le32toh(msg->rm_datalen) + (uint32_t)RNDIS_HEADER_OFFSET, 808 le32toh(msg->rm_len)); 809 return; 810 } 811 812 if (le32toh(msg->rm_datalen) < sizeof(struct ether_header)) { 813 ifp->if_ierrors++; 814 printf("%s: urndis_decap invalid ethernet size " 815 "%d < %zu\n", 816 DEVNAME(sc), 817 le32toh(msg->rm_datalen), 818 sizeof(struct ether_header)); 819 return; 820 } 821 822 memcpy(mtod(m, char*), 823 ((char*)&msg->rm_dataoffset + le32toh(msg->rm_dataoffset)), 824 le32toh(msg->rm_datalen)); 825 m->m_pkthdr.len = m->m_len = le32toh(msg->rm_datalen); 826 827 m_set_rcvif(m, ifp); 828 829 s = splnet(); 830 831 if (urndis_newbuf(sc, c) == ENOBUFS) { 832 ifp->if_ierrors++; 833 } else { 834 if_percpuq_enqueue(ifp->if_percpuq, m); 835 } 836 splx(s); 837 838 offset += le32toh(msg->rm_len); 839 len -= le32toh(msg->rm_len); 840 } 841 } 842 843 static int 844 urndis_newbuf(struct urndis_softc *sc, struct urndis_chain *c) 845 { 846 struct mbuf *m_new = NULL; 847 848 MGETHDR(m_new, M_DONTWAIT, MT_DATA); 849 if (m_new == NULL) { 850 printf("%s: no memory for rx list -- packet dropped!\n", 851 DEVNAME(sc)); 852 return ENOBUFS; 853 } 854 MCLGET(m_new, M_DONTWAIT); 855 if (!(m_new->m_flags & M_EXT)) { 856 printf("%s: no memory for rx list -- packet dropped!\n", 857 DEVNAME(sc)); 858 m_freem(m_new); 859 return ENOBUFS; 860 } 861 m_new->m_len = m_new->m_pkthdr.len = MCLBYTES; 862 863 m_adj(m_new, ETHER_ALIGN); 864 c->sc_mbuf = m_new; 865 return 0; 866 } 867 868 static int 869 urndis_rx_list_init(struct urndis_softc *sc) 870 { 871 struct urndis_cdata *cd; 872 struct urndis_chain *c; 873 int i; 874 875 cd = &sc->sc_data; 876 for (i = 0; i < RNDIS_RX_LIST_CNT; i++) { 877 c = &cd->sc_rx_chain[i]; 878 c->sc_softc = sc; 879 c->sc_idx = i; 880 881 if (urndis_newbuf(sc, c) == ENOBUFS) 882 return ENOBUFS; 883 884 if (c->sc_xfer == NULL) { 885 int err = usbd_create_xfer(sc->sc_bulkin_pipe, 886 RNDIS_BUFSZ, 0, 0, &c->sc_xfer); 887 if (err) 888 return err; 889 c->sc_buf = usbd_get_buffer(c->sc_xfer); 890 } 891 } 892 893 return 0; 894 } 895 896 static int 897 urndis_tx_list_init(struct urndis_softc *sc) 898 { 899 struct urndis_cdata *cd; 900 struct urndis_chain *c; 901 int i; 902 903 cd = &sc->sc_data; 904 for (i = 0; i < RNDIS_TX_LIST_CNT; i++) { 905 c = &cd->sc_tx_chain[i]; 906 c->sc_softc = sc; 907 c->sc_idx = i; 908 c->sc_mbuf = NULL; 909 if (c->sc_xfer == NULL) { 910 int err = usbd_create_xfer(sc->sc_bulkout_pipe, 911 RNDIS_BUFSZ, USBD_FORCE_SHORT_XFER, 0, &c->sc_xfer); 912 if (err) 913 return err; 914 c->sc_buf = usbd_get_buffer(c->sc_xfer); 915 } 916 } 917 return 0; 918 } 919 920 static int 921 urndis_ioctl(struct ifnet *ifp, unsigned long command, void *data) 922 { 923 struct urndis_softc *sc; 924 int s, error; 925 926 sc = ifp->if_softc; 927 error = 0; 928 929 if (sc->sc_dying) 930 return EIO; 931 932 s = splnet(); 933 934 switch(command) { 935 case SIOCSIFFLAGS: 936 if ((error = ifioctl_common(ifp, command, data)) != 0) 937 break; 938 if (ifp->if_flags & IFF_UP) { 939 if (!(ifp->if_flags & IFF_RUNNING)) 940 urndis_init(ifp); 941 } else { 942 if (ifp->if_flags & IFF_RUNNING) 943 urndis_stop(ifp); 944 } 945 error = 0; 946 break; 947 948 default: 949 error = ether_ioctl(ifp, command, data); 950 break; 951 } 952 953 if (error == ENETRESET) 954 error = 0; 955 956 splx(s); 957 return error; 958 } 959 960 #if 0 961 static void 962 urndis_watchdog(struct ifnet *ifp) 963 { 964 struct urndis_softc *sc; 965 966 sc = ifp->if_softc; 967 968 if (sc->sc_dying) 969 return; 970 971 ifp->if_oerrors++; 972 printf("%s: watchdog timeout\n", DEVNAME(sc)); 973 974 urndis_ctrl_keepalive(sc); 975 } 976 #endif 977 978 static int 979 urndis_init(struct ifnet *ifp) 980 { 981 struct urndis_softc *sc; 982 int i, s; 983 int err; 984 usbd_status usberr; 985 986 sc = ifp->if_softc; 987 988 if (ifp->if_flags & IFF_RUNNING) 989 return 0; 990 991 err = urndis_ctrl_init(sc); 992 if (err != RNDIS_STATUS_SUCCESS) 993 return EIO; 994 995 s = splnet(); 996 997 usberr = usbd_open_pipe(sc->sc_iface_data, sc->sc_bulkin_no, 998 USBD_EXCLUSIVE_USE, &sc->sc_bulkin_pipe); 999 if (usberr) { 1000 printf("%s: open rx pipe failed: %s\n", DEVNAME(sc), 1001 usbd_errstr(err)); 1002 splx(s); 1003 return EIO; 1004 } 1005 1006 usberr = usbd_open_pipe(sc->sc_iface_data, sc->sc_bulkout_no, 1007 USBD_EXCLUSIVE_USE, &sc->sc_bulkout_pipe); 1008 if (usberr) { 1009 printf("%s: open tx pipe failed: %s\n", DEVNAME(sc), 1010 usbd_errstr(err)); 1011 splx(s); 1012 return EIO; 1013 } 1014 1015 err = urndis_tx_list_init(sc); 1016 if (err) { 1017 printf("%s: tx list init failed\n", 1018 DEVNAME(sc)); 1019 splx(s); 1020 return err; 1021 } 1022 1023 err = urndis_rx_list_init(sc); 1024 if (err) { 1025 printf("%s: rx list init failed\n", 1026 DEVNAME(sc)); 1027 splx(s); 1028 return err; 1029 } 1030 1031 for (i = 0; i < RNDIS_RX_LIST_CNT; i++) { 1032 struct urndis_chain *c; 1033 1034 c = &sc->sc_data.sc_rx_chain[i]; 1035 1036 usbd_setup_xfer(c->sc_xfer, c, c->sc_buf, RNDIS_BUFSZ, 1037 USBD_SHORT_XFER_OK, USBD_NO_TIMEOUT, urndis_rxeof); 1038 usbd_transfer(c->sc_xfer); 1039 } 1040 1041 ifp->if_flags |= IFF_RUNNING; 1042 ifp->if_flags &= ~IFF_OACTIVE; 1043 1044 splx(s); 1045 return 0; 1046 } 1047 1048 static void 1049 urndis_stop(struct ifnet *ifp) 1050 { 1051 struct urndis_softc *sc; 1052 usbd_status err; 1053 int i; 1054 1055 sc = ifp->if_softc; 1056 1057 ifp->if_timer = 0; 1058 ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE); 1059 1060 if (sc->sc_bulkin_pipe != NULL) { 1061 err = usbd_abort_pipe(sc->sc_bulkin_pipe); 1062 if (err) 1063 printf("%s: abort rx pipe failed: %s\n", 1064 DEVNAME(sc), usbd_errstr(err)); 1065 } 1066 1067 if (sc->sc_bulkout_pipe != NULL) { 1068 err = usbd_abort_pipe(sc->sc_bulkout_pipe); 1069 if (err) 1070 printf("%s: abort tx pipe failed: %s\n", 1071 DEVNAME(sc), usbd_errstr(err)); 1072 } 1073 1074 for (i = 0; i < RNDIS_RX_LIST_CNT; i++) { 1075 if (sc->sc_data.sc_rx_chain[i].sc_mbuf != NULL) { 1076 m_freem(sc->sc_data.sc_rx_chain[i].sc_mbuf); 1077 sc->sc_data.sc_rx_chain[i].sc_mbuf = NULL; 1078 } 1079 if (sc->sc_data.sc_rx_chain[i].sc_xfer != NULL) { 1080 usbd_destroy_xfer(sc->sc_data.sc_rx_chain[i].sc_xfer); 1081 sc->sc_data.sc_rx_chain[i].sc_xfer = NULL; 1082 } 1083 } 1084 1085 for (i = 0; i < RNDIS_TX_LIST_CNT; i++) { 1086 if (sc->sc_data.sc_tx_chain[i].sc_mbuf != NULL) { 1087 m_freem(sc->sc_data.sc_tx_chain[i].sc_mbuf); 1088 sc->sc_data.sc_tx_chain[i].sc_mbuf = NULL; 1089 } 1090 if (sc->sc_data.sc_tx_chain[i].sc_xfer != NULL) { 1091 usbd_destroy_xfer(sc->sc_data.sc_tx_chain[i].sc_xfer); 1092 sc->sc_data.sc_tx_chain[i].sc_xfer = NULL; 1093 } 1094 } 1095 1096 /* Close pipes. */ 1097 if (sc->sc_bulkin_pipe != NULL) { 1098 err = usbd_close_pipe(sc->sc_bulkin_pipe); 1099 if (err) 1100 printf("%s: close rx pipe failed: %s\n", 1101 DEVNAME(sc), usbd_errstr(err)); 1102 sc->sc_bulkin_pipe = NULL; 1103 } 1104 1105 if (sc->sc_bulkout_pipe != NULL) { 1106 err = usbd_close_pipe(sc->sc_bulkout_pipe); 1107 if (err) 1108 printf("%s: close tx pipe failed: %s\n", 1109 DEVNAME(sc), usbd_errstr(err)); 1110 sc->sc_bulkout_pipe = NULL; 1111 } 1112 } 1113 1114 static void 1115 urndis_start(struct ifnet *ifp) 1116 { 1117 struct urndis_softc *sc; 1118 struct mbuf *m_head = NULL; 1119 1120 sc = ifp->if_softc; 1121 1122 if (sc->sc_dying || (ifp->if_flags & IFF_OACTIVE)) 1123 return; 1124 1125 IFQ_POLL(&ifp->if_snd, m_head); 1126 if (m_head == NULL) 1127 return; 1128 1129 if (urndis_encap(sc, m_head, 0)) { 1130 ifp->if_flags |= IFF_OACTIVE; 1131 return; 1132 } 1133 IFQ_DEQUEUE(&ifp->if_snd, m_head); 1134 1135 /* 1136 * If there's a BPF listener, bounce a copy of this frame 1137 * to him. 1138 */ 1139 bpf_mtap(ifp, m_head, BPF_D_OUT); 1140 1141 ifp->if_flags |= IFF_OACTIVE; 1142 1143 /* 1144 * Set a timeout in case the chip goes out to lunch. 1145 */ 1146 ifp->if_timer = 5; 1147 1148 return; 1149 } 1150 1151 static void 1152 urndis_rxeof(struct usbd_xfer *xfer, 1153 void *priv, 1154 usbd_status status) 1155 { 1156 struct urndis_chain *c; 1157 struct urndis_softc *sc; 1158 struct ifnet *ifp; 1159 uint32_t total_len; 1160 1161 c = priv; 1162 sc = c->sc_softc; 1163 ifp = GET_IFP(sc); 1164 total_len = 0; 1165 1166 if (sc->sc_dying || !(ifp->if_flags & IFF_RUNNING)) 1167 return; 1168 1169 if (status != USBD_NORMAL_COMPLETION) { 1170 if (status == USBD_NOT_STARTED || status == USBD_CANCELLED) 1171 return; 1172 if (usbd_ratecheck(&sc->sc_rx_notice)) { 1173 printf("%s: usb errors on rx: %s\n", 1174 DEVNAME(sc), usbd_errstr(status)); 1175 } 1176 if (status == USBD_STALLED) 1177 usbd_clear_endpoint_stall_async(sc->sc_bulkin_pipe); 1178 1179 goto done; 1180 } 1181 1182 usbd_get_xfer_status(xfer, NULL, NULL, &total_len, NULL); 1183 urndis_decap(sc, c, total_len); 1184 1185 done: 1186 /* Setup new transfer. */ 1187 usbd_setup_xfer(c->sc_xfer, c, c->sc_buf, RNDIS_BUFSZ, 1188 USBD_SHORT_XFER_OK, USBD_NO_TIMEOUT, urndis_rxeof); 1189 usbd_transfer(c->sc_xfer); 1190 } 1191 1192 static void 1193 urndis_txeof(struct usbd_xfer *xfer, 1194 void *priv, 1195 usbd_status status) 1196 { 1197 struct urndis_chain *c; 1198 struct urndis_softc *sc; 1199 struct ifnet *ifp; 1200 usbd_status err; 1201 int s; 1202 1203 c = priv; 1204 sc = c->sc_softc; 1205 ifp = GET_IFP(sc); 1206 1207 DPRINTF(("%s: urndis_txeof\n", DEVNAME(sc))); 1208 1209 if (sc->sc_dying) 1210 return; 1211 1212 s = splnet(); 1213 1214 ifp->if_timer = 0; 1215 ifp->if_flags &= ~IFF_OACTIVE; 1216 1217 if (status != USBD_NORMAL_COMPLETION) { 1218 if (status == USBD_NOT_STARTED || status == USBD_CANCELLED) { 1219 splx(s); 1220 return; 1221 } 1222 ifp->if_oerrors++; 1223 printf("%s: usb error on tx: %s\n", DEVNAME(sc), 1224 usbd_errstr(status)); 1225 if (status == USBD_STALLED) 1226 usbd_clear_endpoint_stall_async(sc->sc_bulkout_pipe); 1227 splx(s); 1228 return; 1229 } 1230 1231 usbd_get_xfer_status(c->sc_xfer, NULL, NULL, NULL, &err); 1232 1233 if (c->sc_mbuf != NULL) { 1234 m_freem(c->sc_mbuf); 1235 c->sc_mbuf = NULL; 1236 } 1237 1238 if (err) 1239 ifp->if_oerrors++; 1240 else 1241 ifp->if_opackets++; 1242 1243 if (IFQ_IS_EMPTY(&ifp->if_snd) == 0) 1244 urndis_start(ifp); 1245 1246 splx(s); 1247 } 1248 1249 static int 1250 urndis_match(device_t parent, cfdata_t match, void *aux) 1251 { 1252 struct usbif_attach_arg *uiaa = aux; 1253 usb_interface_descriptor_t *id; 1254 1255 if (!uiaa->uiaa_iface) 1256 return UMATCH_NONE; 1257 1258 id = usbd_get_interface_descriptor(uiaa->uiaa_iface); 1259 if (id == NULL) 1260 return UMATCH_NONE; 1261 1262 if (id->bInterfaceClass == UICLASS_WIRELESS && 1263 id->bInterfaceSubClass == UISUBCLASS_RF && 1264 id->bInterfaceProtocol == UIPROTO_RNDIS) 1265 return UMATCH_IFACECLASS_IFACESUBCLASS_IFACEPROTO; 1266 1267 return usb_lookup(urndis_devs, uiaa->uiaa_vendor, uiaa->uiaa_product) != NULL ? 1268 UMATCH_VENDOR_PRODUCT : UMATCH_NONE; 1269 } 1270 1271 static void 1272 urndis_attach(device_t parent, device_t self, void *aux) 1273 { 1274 struct urndis_softc *sc; 1275 struct usbif_attach_arg *uiaa; 1276 struct ifnet *ifp; 1277 usb_interface_descriptor_t *id; 1278 usb_endpoint_descriptor_t *ed; 1279 usb_config_descriptor_t *cd; 1280 const usb_cdc_union_descriptor_t *ud; 1281 const usb_cdc_header_descriptor_t *desc; 1282 usbd_desc_iter_t iter; 1283 int if_ctl, if_data; 1284 int i, j, altcnt; 1285 int s; 1286 u_char eaddr[ETHER_ADDR_LEN]; 1287 void *buf; 1288 size_t bufsz; 1289 uint32_t filter; 1290 char *devinfop; 1291 1292 sc = device_private(self); 1293 uiaa = aux; 1294 sc->sc_dev = self; 1295 sc->sc_udev = uiaa->uiaa_device; 1296 1297 aprint_naive("\n"); 1298 aprint_normal("\n"); 1299 1300 devinfop = usbd_devinfo_alloc(uiaa->uiaa_device, 0); 1301 aprint_normal_dev(self, "%s\n", devinfop); 1302 usbd_devinfo_free(devinfop); 1303 1304 sc->sc_iface_ctl = uiaa->uiaa_iface; 1305 id = usbd_get_interface_descriptor(sc->sc_iface_ctl); 1306 if_ctl = id->bInterfaceNumber; 1307 sc->sc_ifaceno_ctl = if_ctl; 1308 if_data = -1; 1309 1310 usb_desc_iter_init(sc->sc_udev, &iter); 1311 while ((desc = (const void *)usb_desc_iter_next(&iter)) != NULL) { 1312 1313 if (desc->bDescriptorType != UDESC_CS_INTERFACE) { 1314 continue; 1315 } 1316 switch (desc->bDescriptorSubtype) { 1317 case UDESCSUB_CDC_UNION: 1318 /* XXX bail out when found first? */ 1319 ud = (const usb_cdc_union_descriptor_t *)desc; 1320 if (if_data == -1) 1321 if_data = ud->bSlaveInterface[0]; 1322 break; 1323 } 1324 } 1325 1326 if (if_data == -1) { 1327 DPRINTF(("urndis_attach: no union interface\n")); 1328 sc->sc_iface_data = sc->sc_iface_ctl; 1329 } else { 1330 DPRINTF(("urndis_attach: union interface: ctl %u, data %u\n", 1331 if_ctl, if_data)); 1332 for (i = 0; i < uiaa->uiaa_nifaces; i++) { 1333 if (uiaa->uiaa_ifaces[i] != NULL) { 1334 id = usbd_get_interface_descriptor( 1335 uiaa->uiaa_ifaces[i]); 1336 if (id != NULL && id->bInterfaceNumber == 1337 if_data) { 1338 sc->sc_iface_data = uiaa->uiaa_ifaces[i]; 1339 uiaa->uiaa_ifaces[i] = NULL; 1340 } 1341 } 1342 } 1343 } 1344 1345 if (sc->sc_iface_data == NULL) { 1346 aprint_error("%s: no data interface\n", DEVNAME(sc)); 1347 return; 1348 } 1349 1350 id = usbd_get_interface_descriptor(sc->sc_iface_data); 1351 cd = usbd_get_config_descriptor(sc->sc_udev); 1352 altcnt = usbd_get_no_alts(cd, id->bInterfaceNumber); 1353 1354 for (j = 0; j < altcnt; j++) { 1355 if (usbd_set_interface(sc->sc_iface_data, j)) { 1356 aprint_error("%s: interface alternate setting %u " 1357 "failed\n", DEVNAME(sc), j); 1358 return; 1359 } 1360 /* Find endpoints. */ 1361 id = usbd_get_interface_descriptor(sc->sc_iface_data); 1362 sc->sc_bulkin_no = sc->sc_bulkout_no = -1; 1363 for (i = 0; i < id->bNumEndpoints; i++) { 1364 ed = usbd_interface2endpoint_descriptor( 1365 sc->sc_iface_data, i); 1366 if (!ed) { 1367 aprint_error("%s: no descriptor for bulk " 1368 "endpoint %u\n", DEVNAME(sc), i); 1369 return; 1370 } 1371 if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN && 1372 UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) { 1373 sc->sc_bulkin_no = ed->bEndpointAddress; 1374 } 1375 else if ( 1376 UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT && 1377 UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) { 1378 sc->sc_bulkout_no = ed->bEndpointAddress; 1379 } 1380 } 1381 1382 if (sc->sc_bulkin_no != -1 && sc->sc_bulkout_no != -1) { 1383 DPRINTF(("%s: in=0x%x, out=0x%x\n", 1384 DEVNAME(sc), 1385 sc->sc_bulkin_no, 1386 sc->sc_bulkout_no)); 1387 goto found; 1388 } 1389 } 1390 1391 if (sc->sc_bulkin_no == -1) 1392 aprint_error("%s: could not find data bulk in\n", DEVNAME(sc)); 1393 if (sc->sc_bulkout_no == -1 ) 1394 aprint_error("%s: could not find data bulk out\n",DEVNAME(sc)); 1395 return; 1396 1397 found: 1398 1399 ifp = GET_IFP(sc); 1400 ifp->if_softc = sc; 1401 ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; 1402 ifp->if_start = urndis_start; 1403 ifp->if_ioctl = urndis_ioctl; 1404 ifp->if_init = urndis_init; 1405 #if 0 1406 ifp->if_watchdog = urndis_watchdog; 1407 #endif 1408 1409 strlcpy(ifp->if_xname, DEVNAME(sc), IFNAMSIZ); 1410 1411 IFQ_SET_READY(&ifp->if_snd); 1412 1413 urndis_init(ifp); 1414 1415 s = splnet(); 1416 1417 if (urndis_ctrl_query(sc, OID_802_3_PERMANENT_ADDRESS, NULL, 0, 1418 &buf, &bufsz) != RNDIS_STATUS_SUCCESS) { 1419 aprint_error("%s: unable to get hardware address\n", 1420 DEVNAME(sc)); 1421 urndis_stop(ifp); 1422 splx(s); 1423 return; 1424 } 1425 1426 if (bufsz == ETHER_ADDR_LEN) { 1427 memcpy(eaddr, buf, ETHER_ADDR_LEN); 1428 aprint_normal("%s: address %s\n", DEVNAME(sc), 1429 ether_sprintf(eaddr)); 1430 kmem_free(buf, bufsz); 1431 } else { 1432 aprint_error("%s: invalid address\n", DEVNAME(sc)); 1433 kmem_free(buf, bufsz); 1434 urndis_stop(ifp); 1435 splx(s); 1436 return; 1437 } 1438 1439 /* Initialize packet filter */ 1440 sc->sc_filter = RNDIS_PACKET_TYPE_BROADCAST; 1441 sc->sc_filter |= RNDIS_PACKET_TYPE_ALL_MULTICAST; 1442 filter = htole32(sc->sc_filter); 1443 if (urndis_ctrl_set(sc, OID_GEN_CURRENT_PACKET_FILTER, &filter, 1444 sizeof(filter)) != RNDIS_STATUS_SUCCESS) { 1445 aprint_error("%s: unable to set data filters\n", DEVNAME(sc)); 1446 urndis_stop(ifp); 1447 splx(s); 1448 return; 1449 } 1450 1451 if_attach(ifp); 1452 ether_ifattach(ifp, eaddr); 1453 sc->sc_attached = 1; 1454 1455 splx(s); 1456 } 1457 1458 static int 1459 urndis_detach(device_t self, int flags) 1460 { 1461 struct urndis_softc *sc; 1462 struct ifnet *ifp; 1463 int s; 1464 1465 sc = device_private(self); 1466 1467 DPRINTF(("urndis_detach: %s flags %u\n", DEVNAME(sc), 1468 flags)); 1469 1470 if (!sc->sc_attached) 1471 return 0; 1472 1473 s = splusb(); 1474 1475 ifp = GET_IFP(sc); 1476 1477 if (ifp->if_softc != NULL) { 1478 ether_ifdetach(ifp); 1479 if_detach(ifp); 1480 } 1481 1482 urndis_stop(ifp); 1483 sc->sc_attached = 0; 1484 1485 splx(s); 1486 1487 return 0; 1488 } 1489 1490 static int 1491 urndis_activate(device_t self, enum devact act) 1492 { 1493 struct urndis_softc *sc; 1494 1495 sc = device_private(self); 1496 1497 switch (act) { 1498 case DVACT_DEACTIVATE: 1499 sc->sc_dying = 1; 1500 return 0; 1501 } 1502 1503 return EOPNOTSUPP; 1504 } 1505