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