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