1 /* $NetBSD: if_urndis.c,v 1.3 2011/12/23 00:51:44 jakllsch 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.3 2011/12/23 00:51:44 jakllsch 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(usbd_xfer_handle, usbd_private_handle, usbd_status); 75 static void urndis_txeof(usbd_xfer_handle, usbd_private_handle, 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 void 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 *, size_t); 103 #if 0 104 static uint32_t urndis_ctrl_set_param(struct urndis_softc *, const char *, 105 uint32_t, void *, size_t); 106 static uint32_t urndis_ctrl_reset(struct urndis_softc *); 107 static uint32_t urndis_ctrl_keepalive(struct urndis_softc *); 108 #endif 109 110 static int urndis_encap(struct urndis_softc *, struct mbuf *, int); 111 static void urndis_decap(struct urndis_softc *, struct urndis_chain *, uint32_t); 112 113 static int urndis_match(device_t, cfdata_t, void *); 114 static void urndis_attach(device_t, device_t, void *); 115 static int urndis_detach(device_t, int); 116 static int urndis_activate(device_t, enum devact); 117 118 CFATTACH_DECL_NEW(urndis, sizeof(struct urndis_softc), 119 urndis_match, urndis_attach, urndis_detach, urndis_activate); 120 121 /* 122 * Supported devices that we can't match by class IDs. 123 */ 124 static const struct usb_devno urndis_devs[] = { 125 { USB_VENDOR_HTC, USB_PRODUCT_HTC_ANDROID }, 126 { USB_VENDOR_SAMSUNG, USB_PRODUCT_SAMSUNG_ANDROID2 }, 127 { 0, 0 } 128 }; 129 130 static usbd_status 131 urndis_ctrl_msg(struct urndis_softc *sc, uint8_t rt, uint8_t r, 132 uint16_t index, uint16_t value, void *buf, size_t buflen) 133 { 134 usb_device_request_t req; 135 136 req.bmRequestType = rt; 137 req.bRequest = r; 138 USETW(req.wValue, value); 139 USETW(req.wIndex, index); 140 USETW(req.wLength, buflen); 141 142 return usbd_do_request(sc->sc_udev, &req, buf); 143 } 144 145 static usbd_status 146 urndis_ctrl_send(struct urndis_softc *sc, void *buf, size_t len) 147 { 148 usbd_status err; 149 150 if (sc->sc_dying) 151 return(0); 152 153 err = urndis_ctrl_msg(sc, UT_WRITE_CLASS_INTERFACE, UR_GET_STATUS, 154 sc->sc_ifaceno_ctl, 0, buf, len); 155 156 if (err != USBD_NORMAL_COMPLETION) 157 printf("%s: %s\n", DEVNAME(sc), usbd_errstr(err)); 158 159 return err; 160 } 161 162 static struct urndis_comp_hdr * 163 urndis_ctrl_recv(struct urndis_softc *sc) 164 { 165 struct urndis_comp_hdr *hdr; 166 char *buf; 167 usbd_status err; 168 169 buf = kmem_alloc(URNDIS_RESPONSE_LEN, KM_SLEEP); 170 if (buf == NULL) { 171 printf("%s: out of memory\n", DEVNAME(sc)); 172 return NULL; 173 } 174 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 *buf = kmem_alloc(le32toh(msg->rm_infobuflen), KM_SLEEP); 343 if (*buf == NULL) { 344 printf("%s: out of memory\n", DEVNAME(sc)); 345 return RNDIS_STATUS_FAILURE; 346 } else { 347 const char *p; 348 *bufsz = le32toh(msg->rm_infobuflen); 349 350 p = (const char *)&msg->rm_rid; 351 p += le32toh(msg->rm_infobufoffset); 352 memcpy(*buf, p, le32toh(msg->rm_infobuflen)); 353 } 354 } 355 356 return le32toh(msg->rm_status); 357 } 358 359 static uint32_t 360 urndis_ctrl_handle_reset(struct urndis_softc *sc, 361 const struct urndis_comp_hdr *hdr) 362 { 363 const struct urndis_reset_comp *msg; 364 uint32_t rval; 365 366 msg = (const struct urndis_reset_comp *) hdr; 367 368 rval = le32toh(msg->rm_status); 369 370 DPRINTF(("%s: urndis_ctrl_handle_reset: len %u status 0x%x " 371 "adrreset %u\n", 372 DEVNAME(sc), 373 le32toh(msg->rm_len), 374 rval, 375 le32toh(msg->rm_adrreset))); 376 377 if (rval != RNDIS_STATUS_SUCCESS) { 378 printf("%s: reset failed 0x%x\n", DEVNAME(sc), rval); 379 return rval; 380 } 381 382 if (le32toh(msg->rm_adrreset) != 0) { 383 uint32_t filter; 384 385 filter = htole32(sc->sc_filter); 386 rval = urndis_ctrl_set(sc, OID_GEN_CURRENT_PACKET_FILTER, 387 &filter, sizeof(filter)); 388 if (rval != RNDIS_STATUS_SUCCESS) { 389 printf("%s: unable to reset data filters\n", 390 DEVNAME(sc)); 391 return rval; 392 } 393 } 394 395 return rval; 396 } 397 398 static uint32_t 399 urndis_ctrl_init(struct urndis_softc *sc) 400 { 401 struct urndis_init_req *msg; 402 uint32_t rval; 403 struct urndis_comp_hdr *hdr; 404 405 msg = kmem_alloc(sizeof(*msg), KM_SLEEP); 406 if (msg == NULL) { 407 printf("%s: out of memory\n", DEVNAME(sc)); 408 return RNDIS_STATUS_FAILURE; 409 } 410 411 msg->rm_type = htole32(REMOTE_NDIS_INITIALIZE_MSG); 412 msg->rm_len = htole32(sizeof(*msg)); 413 msg->rm_rid = htole32(0); 414 msg->rm_ver_major = htole32(1); 415 msg->rm_ver_minor = htole32(1); 416 msg->rm_max_xfersz = htole32(RNDIS_BUFSZ); 417 418 DPRINTF(("%s: urndis_ctrl_init send: type %u len %u rid %u ver_major %u " 419 "ver_minor %u max_xfersz %u\n", 420 DEVNAME(sc), 421 le32toh(msg->rm_type), 422 le32toh(msg->rm_len), 423 le32toh(msg->rm_rid), 424 le32toh(msg->rm_ver_major), 425 le32toh(msg->rm_ver_minor), 426 le32toh(msg->rm_max_xfersz))); 427 428 rval = urndis_ctrl_send(sc, msg, sizeof(*msg)); 429 kmem_free(msg, sizeof(*msg)); 430 431 if (rval != RNDIS_STATUS_SUCCESS) { 432 printf("%s: init failed\n", DEVNAME(sc)); 433 return rval; 434 } 435 436 if ((hdr = urndis_ctrl_recv(sc)) == NULL) { 437 printf("%s: unable to get init response\n", DEVNAME(sc)); 438 return RNDIS_STATUS_FAILURE; 439 } 440 rval = urndis_ctrl_handle(sc, hdr, NULL, NULL); 441 442 return rval; 443 } 444 445 #if 0 446 static uint32_t 447 urndis_ctrl_halt(struct urndis_softc *sc) 448 { 449 struct urndis_halt_req *msg; 450 uint32_t rval; 451 452 msg = kmem_alloc(sizeof(*msg), KM_SLEEP); 453 if (msg == NULL) { 454 printf("%s: out of memory\n", DEVNAME(sc)); 455 return RNDIS_STATUS_FAILURE; 456 } 457 458 msg->rm_type = htole32(REMOTE_NDIS_HALT_MSG); 459 msg->rm_len = htole32(sizeof(*msg)); 460 msg->rm_rid = 0; 461 462 DPRINTF(("%s: urndis_ctrl_halt send: type %u len %u rid %u\n", 463 DEVNAME(sc), 464 le32toh(msg->rm_type), 465 le32toh(msg->rm_len), 466 le32toh(msg->rm_rid))); 467 468 rval = urndis_ctrl_send(sc, msg, sizeof(*msg)); 469 kmem_free(msg, sizeof(*msg)); 470 471 if (rval != RNDIS_STATUS_SUCCESS) 472 printf("%s: halt failed\n", DEVNAME(sc)); 473 474 return rval; 475 } 476 #endif 477 478 static uint32_t 479 urndis_ctrl_query(struct urndis_softc *sc, uint32_t oid, 480 void *qbuf, size_t qlen, 481 void **rbuf, size_t *rbufsz) 482 { 483 struct urndis_query_req *msg; 484 uint32_t rval; 485 struct urndis_comp_hdr *hdr; 486 487 msg = kmem_alloc(sizeof(*msg) + qlen, KM_SLEEP); 488 if (msg == NULL) { 489 printf("%s: out of memory\n", DEVNAME(sc)); 490 return RNDIS_STATUS_FAILURE; 491 } 492 493 msg->rm_type = htole32(REMOTE_NDIS_QUERY_MSG); 494 msg->rm_len = htole32(sizeof(*msg) + qlen); 495 msg->rm_rid = 0; /* XXX */ 496 msg->rm_oid = htole32(oid); 497 msg->rm_infobuflen = htole32(qlen); 498 if (qlen != 0) { 499 msg->rm_infobufoffset = htole32(20); 500 memcpy((char*)msg + 20, qbuf, qlen); 501 } else 502 msg->rm_infobufoffset = 0; 503 msg->rm_devicevchdl = 0; 504 505 DPRINTF(("%s: urndis_ctrl_query send: type %u len %u rid %u oid 0x%x " 506 "infobuflen %u infobufoffset %u devicevchdl %u\n", 507 DEVNAME(sc), 508 le32toh(msg->rm_type), 509 le32toh(msg->rm_len), 510 le32toh(msg->rm_rid), 511 le32toh(msg->rm_oid), 512 le32toh(msg->rm_infobuflen), 513 le32toh(msg->rm_infobufoffset), 514 le32toh(msg->rm_devicevchdl))); 515 516 rval = urndis_ctrl_send(sc, msg, sizeof(*msg)); 517 kmem_free(msg, sizeof(*msg)); 518 519 if (rval != RNDIS_STATUS_SUCCESS) { 520 printf("%s: query failed\n", DEVNAME(sc)); 521 return rval; 522 } 523 524 if ((hdr = urndis_ctrl_recv(sc)) == NULL) { 525 printf("%s: unable to get query response\n", DEVNAME(sc)); 526 return RNDIS_STATUS_FAILURE; 527 } 528 rval = urndis_ctrl_handle(sc, hdr, rbuf, rbufsz); 529 530 return rval; 531 } 532 533 static uint32_t 534 urndis_ctrl_set(struct urndis_softc *sc, uint32_t oid, void *buf, size_t len) 535 { 536 struct urndis_set_req *msg; 537 uint32_t rval; 538 struct urndis_comp_hdr *hdr; 539 540 msg = kmem_alloc(sizeof(*msg) + len, KM_SLEEP); 541 if (msg == NULL) { 542 printf("%s: out of memory\n", DEVNAME(sc)); 543 return RNDIS_STATUS_FAILURE; 544 } 545 546 msg->rm_type = htole32(REMOTE_NDIS_SET_MSG); 547 msg->rm_len = htole32(sizeof(*msg) + len); 548 msg->rm_rid = 0; /* XXX */ 549 msg->rm_oid = htole32(oid); 550 msg->rm_infobuflen = htole32(len); 551 if (len != 0) { 552 msg->rm_infobufoffset = htole32(20); 553 memcpy((char*)msg + 20, buf, len); 554 } else 555 msg->rm_infobufoffset = 0; 556 msg->rm_devicevchdl = 0; 557 558 DPRINTF(("%s: urndis_ctrl_set send: type %u len %u rid %u oid 0x%x " 559 "infobuflen %u infobufoffset %u devicevchdl %u\n", 560 DEVNAME(sc), 561 le32toh(msg->rm_type), 562 le32toh(msg->rm_len), 563 le32toh(msg->rm_rid), 564 le32toh(msg->rm_oid), 565 le32toh(msg->rm_infobuflen), 566 le32toh(msg->rm_infobufoffset), 567 le32toh(msg->rm_devicevchdl))); 568 569 rval = urndis_ctrl_send(sc, msg, sizeof(*msg)); 570 kmem_free(msg, sizeof(*msg)); 571 572 if (rval != RNDIS_STATUS_SUCCESS) { 573 printf("%s: set failed\n", DEVNAME(sc)); 574 return rval; 575 } 576 577 if ((hdr = urndis_ctrl_recv(sc)) == NULL) { 578 printf("%s: unable to get set response\n", DEVNAME(sc)); 579 return RNDIS_STATUS_FAILURE; 580 } 581 rval = urndis_ctrl_handle(sc, hdr, NULL, NULL); 582 if (rval != RNDIS_STATUS_SUCCESS) 583 printf("%s: set failed 0x%x\n", DEVNAME(sc), rval); 584 585 return rval; 586 } 587 588 #if 0 589 static uint32_t 590 urndis_ctrl_set_param(struct urndis_softc *sc, 591 const char *name, 592 uint32_t type, 593 void *buf, 594 size_t len) 595 { 596 struct urndis_set_parameter *param; 597 uint32_t rval; 598 size_t namelen, tlen; 599 600 if (name) 601 namelen = strlen(name); 602 else 603 namelen = 0; 604 tlen = sizeof(*param) + len + namelen; 605 param = kmem_alloc(tlen, KM_SLEEP); 606 if (param == NULL) { 607 printf("%s: out of memory\n", DEVNAME(sc)); 608 return RNDIS_STATUS_FAILURE; 609 } 610 611 param->rm_namelen = htole32(namelen); 612 param->rm_valuelen = htole32(len); 613 param->rm_type = htole32(type); 614 if (namelen != 0) { 615 param->rm_nameoffset = htole32(20); 616 memcpy(param + 20, name, namelen); 617 } else 618 param->rm_nameoffset = 0; 619 if (len != 0) { 620 param->rm_valueoffset = htole32(20 + namelen); 621 memcpy(param + 20 + namelen, buf, len); 622 } else 623 param->rm_valueoffset = 0; 624 625 DPRINTF(("%s: urndis_ctrl_set_param send: nameoffset %u namelen %u " 626 "type 0x%x valueoffset %u valuelen %u\n", 627 DEVNAME(sc), 628 le32toh(param->rm_nameoffset), 629 le32toh(param->rm_namelen), 630 le32toh(param->rm_type), 631 le32toh(param->rm_valueoffset), 632 le32toh(param->rm_valuelen))); 633 634 rval = urndis_ctrl_set(sc, OID_GEN_RNDIS_CONFIG_PARAMETER, param, tlen); 635 kmem_free(param, tlen); 636 if (rval != RNDIS_STATUS_SUCCESS) 637 printf("%s: set param failed 0x%x\n", DEVNAME(sc), rval); 638 639 return rval; 640 } 641 642 /* XXX : adrreset, get it from response */ 643 static uint32_t 644 urndis_ctrl_reset(struct urndis_softc *sc) 645 { 646 struct urndis_reset_req *reset; 647 uint32_t rval; 648 struct urndis_comp_hdr *hdr; 649 650 reset = kmem_alloc(sizeof(*reset), KM_SLEEP); 651 if (reset == NULL) { 652 printf("%s: out of memory\n", DEVNAME(sc)); 653 return RNDIS_STATUS_FAILURE; 654 } 655 656 reset->rm_type = htole32(REMOTE_NDIS_RESET_MSG); 657 reset->rm_len = htole32(sizeof(*reset)); 658 reset->rm_rid = 0; /* XXX rm_rid == reserved ... remove ? */ 659 660 DPRINTF(("%s: urndis_ctrl_reset send: type %u len %u rid %u\n", 661 DEVNAME(sc), 662 le32toh(reset->rm_type), 663 le32toh(reset->rm_len), 664 le32toh(reset->rm_rid))); 665 666 rval = urndis_ctrl_send(sc, reset, sizeof(*reset)); 667 kmem_free(reset, sizeof(*reset)); 668 669 if (rval != RNDIS_STATUS_SUCCESS) { 670 printf("%s: reset failed\n", DEVNAME(sc)); 671 return rval; 672 } 673 674 if ((hdr = urndis_ctrl_recv(sc)) == NULL) { 675 printf("%s: unable to get reset response\n", DEVNAME(sc)); 676 return RNDIS_STATUS_FAILURE; 677 } 678 rval = urndis_ctrl_handle(sc, hdr, NULL, NULL); 679 680 return rval; 681 } 682 683 static uint32_t 684 urndis_ctrl_keepalive(struct urndis_softc *sc) 685 { 686 struct urndis_keepalive_req *keep; 687 uint32_t rval; 688 struct urndis_comp_hdr *hdr; 689 690 keep = kmem_alloc(sizeof(*keep), KM_SLEEP); 691 if (keep == NULL) { 692 printf("%s: out of memory\n", DEVNAME(sc)); 693 return RNDIS_STATUS_FAILURE; 694 } 695 696 keep->rm_type = htole32(REMOTE_NDIS_KEEPALIVE_MSG); 697 keep->rm_len = htole32(sizeof(*keep)); 698 keep->rm_rid = 0; /* XXX rm_rid == reserved ... remove ? */ 699 700 DPRINTF(("%s: urndis_ctrl_keepalive: type %u len %u rid %u\n", 701 DEVNAME(sc), 702 le32toh(keep->rm_type), 703 le32toh(keep->rm_len), 704 le32toh(keep->rm_rid))); 705 706 rval = urndis_ctrl_send(sc, keep, sizeof(*keep)); 707 kmem_free(keep, sizeof(*keep)); 708 709 if (rval != RNDIS_STATUS_SUCCESS) { 710 printf("%s: keepalive failed\n", DEVNAME(sc)); 711 return rval; 712 } 713 714 if ((hdr = urndis_ctrl_recv(sc)) == NULL) { 715 printf("%s: unable to get keepalive response\n", DEVNAME(sc)); 716 return RNDIS_STATUS_FAILURE; 717 } 718 rval = urndis_ctrl_handle(sc, hdr, NULL, NULL); 719 if (rval != RNDIS_STATUS_SUCCESS) { 720 printf("%s: keepalive failed 0x%x\n", DEVNAME(sc), rval); 721 urndis_ctrl_reset(sc); 722 } 723 724 return rval; 725 } 726 #endif 727 728 static int 729 urndis_encap(struct urndis_softc *sc, struct mbuf *m, int idx) 730 { 731 struct urndis_chain *c; 732 usbd_status err; 733 struct urndis_packet_msg *msg; 734 735 c = &sc->sc_data.sc_tx_chain[idx]; 736 737 msg = (struct urndis_packet_msg *)c->sc_buf; 738 739 memset(msg, 0, sizeof(*msg)); 740 msg->rm_type = htole32(REMOTE_NDIS_PACKET_MSG); 741 msg->rm_len = htole32(sizeof(*msg) + m->m_pkthdr.len); 742 743 msg->rm_dataoffset = htole32(RNDIS_DATA_OFFSET); 744 msg->rm_datalen = htole32(m->m_pkthdr.len); 745 746 m_copydata(m, 0, m->m_pkthdr.len, 747 ((char*)msg + RNDIS_DATA_OFFSET + RNDIS_HEADER_OFFSET)); 748 749 DPRINTF(("%s: urndis_encap type 0x%x len %u data(off %u len %u)\n", 750 DEVNAME(sc), 751 le32toh(msg->rm_type), 752 le32toh(msg->rm_len), 753 le32toh(msg->rm_dataoffset), 754 le32toh(msg->rm_datalen))); 755 756 c->sc_mbuf = m; 757 758 usbd_setup_xfer(c->sc_xfer, sc->sc_bulkout_pipe, c, c->sc_buf, 759 le32toh(msg->rm_len), USBD_FORCE_SHORT_XFER | USBD_NO_COPY, 10000, 760 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->m_pkthdr.rcvif = 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 (*(ifp)->if_input)((ifp), (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 c->sc_xfer = usbd_alloc_xfer(sc->sc_udev); 930 if (c->sc_xfer == NULL) 931 return (ENOBUFS); 932 c->sc_buf = usbd_alloc_buffer(c->sc_xfer, 933 RNDIS_BUFSZ); 934 if (c->sc_buf == NULL) 935 return (ENOBUFS); 936 } 937 } 938 939 return (0); 940 } 941 942 static int 943 urndis_tx_list_init(struct urndis_softc *sc) 944 { 945 struct urndis_cdata *cd; 946 struct urndis_chain *c; 947 int i; 948 949 cd = &sc->sc_data; 950 for (i = 0; i < RNDIS_TX_LIST_CNT; i++) { 951 c = &cd->sc_tx_chain[i]; 952 c->sc_softc = sc; 953 c->sc_idx = i; 954 c->sc_mbuf = NULL; 955 if (c->sc_xfer == NULL) { 956 c->sc_xfer = usbd_alloc_xfer(sc->sc_udev); 957 if (c->sc_xfer == NULL) 958 return (ENOBUFS); 959 c->sc_buf = usbd_alloc_buffer(c->sc_xfer, 960 RNDIS_BUFSZ); 961 if (c->sc_buf == NULL) 962 return (ENOBUFS); 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 struct ifaddr *ifa; 973 int s, error; 974 975 sc = ifp->if_softc; 976 ifa = (struct ifaddr *)data; 977 error = 0; 978 979 if (sc->sc_dying) 980 return (EIO); 981 982 s = splnet(); 983 984 switch(command) { 985 case SIOCSIFFLAGS: 986 if ((error = ifioctl_common(ifp, command, data)) != 0) 987 break; 988 if (ifp->if_flags & IFF_UP) { 989 if (!(ifp->if_flags & IFF_RUNNING)) 990 urndis_init(ifp); 991 } else { 992 if (ifp->if_flags & IFF_RUNNING) 993 urndis_stop(ifp); 994 } 995 error = 0; 996 break; 997 998 default: 999 error = ether_ioctl(ifp, command, data); 1000 break; 1001 } 1002 1003 if (error == ENETRESET) 1004 error = 0; 1005 1006 splx(s); 1007 return (error); 1008 } 1009 1010 #if 0 1011 static void 1012 urndis_watchdog(struct ifnet *ifp) 1013 { 1014 struct urndis_softc *sc; 1015 1016 sc = ifp->if_softc; 1017 1018 if (sc->sc_dying) 1019 return; 1020 1021 ifp->if_oerrors++; 1022 printf("%s: watchdog timeout\n", DEVNAME(sc)); 1023 1024 urndis_ctrl_keepalive(sc); 1025 } 1026 #endif 1027 1028 static void 1029 urndis_init(struct ifnet *ifp) 1030 { 1031 struct urndis_softc *sc; 1032 int i, s; 1033 usbd_status err; 1034 1035 sc = ifp->if_softc; 1036 1037 if (ifp->if_flags & IFF_RUNNING) 1038 return; 1039 1040 if (urndis_ctrl_init(sc) != RNDIS_STATUS_SUCCESS) 1041 return; 1042 1043 s = splnet(); 1044 1045 if (urndis_tx_list_init(sc) == ENOBUFS) { 1046 printf("%s: tx list init failed\n", 1047 DEVNAME(sc)); 1048 splx(s); 1049 return; 1050 } 1051 1052 if (urndis_rx_list_init(sc) == ENOBUFS) { 1053 printf("%s: rx list init failed\n", 1054 DEVNAME(sc)); 1055 splx(s); 1056 return; 1057 } 1058 1059 err = usbd_open_pipe(sc->sc_iface_data, sc->sc_bulkin_no, 1060 USBD_EXCLUSIVE_USE, &sc->sc_bulkin_pipe); 1061 if (err) { 1062 printf("%s: open rx pipe failed: %s\n", DEVNAME(sc), 1063 usbd_errstr(err)); 1064 splx(s); 1065 return; 1066 } 1067 1068 err = usbd_open_pipe(sc->sc_iface_data, sc->sc_bulkout_no, 1069 USBD_EXCLUSIVE_USE, &sc->sc_bulkout_pipe); 1070 if (err) { 1071 printf("%s: open tx pipe failed: %s\n", DEVNAME(sc), 1072 usbd_errstr(err)); 1073 splx(s); 1074 return; 1075 } 1076 1077 for (i = 0; i < RNDIS_RX_LIST_CNT; i++) { 1078 struct urndis_chain *c; 1079 1080 c = &sc->sc_data.sc_rx_chain[i]; 1081 usbd_setup_xfer(c->sc_xfer, sc->sc_bulkin_pipe, c, 1082 c->sc_buf, RNDIS_BUFSZ, 1083 USBD_SHORT_XFER_OK | USBD_NO_COPY, 1084 USBD_NO_TIMEOUT, urndis_rxeof); 1085 usbd_transfer(c->sc_xfer); 1086 } 1087 1088 ifp->if_flags |= IFF_RUNNING; 1089 ifp->if_flags &= ~IFF_OACTIVE; 1090 1091 splx(s); 1092 } 1093 1094 static void 1095 urndis_stop(struct ifnet *ifp) 1096 { 1097 struct urndis_softc *sc; 1098 usbd_status err; 1099 int i; 1100 1101 sc = ifp->if_softc; 1102 1103 ifp->if_timer = 0; 1104 ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE); 1105 1106 if (sc->sc_bulkin_pipe != NULL) { 1107 err = usbd_abort_pipe(sc->sc_bulkin_pipe); 1108 if (err) 1109 printf("%s: abort rx pipe failed: %s\n", 1110 DEVNAME(sc), usbd_errstr(err)); 1111 err = usbd_close_pipe(sc->sc_bulkin_pipe); 1112 if (err) 1113 printf("%s: close rx pipe failed: %s\n", 1114 DEVNAME(sc), usbd_errstr(err)); 1115 sc->sc_bulkin_pipe = NULL; 1116 } 1117 1118 if (sc->sc_bulkout_pipe != NULL) { 1119 err = usbd_abort_pipe(sc->sc_bulkout_pipe); 1120 if (err) 1121 printf("%s: abort tx pipe failed: %s\n", 1122 DEVNAME(sc), usbd_errstr(err)); 1123 err = usbd_close_pipe(sc->sc_bulkout_pipe); 1124 if (err) 1125 printf("%s: close tx pipe failed: %s\n", 1126 DEVNAME(sc), usbd_errstr(err)); 1127 sc->sc_bulkout_pipe = NULL; 1128 } 1129 1130 for (i = 0; i < RNDIS_RX_LIST_CNT; i++) { 1131 if (sc->sc_data.sc_rx_chain[i].sc_mbuf != NULL) { 1132 m_freem(sc->sc_data.sc_rx_chain[i].sc_mbuf); 1133 sc->sc_data.sc_rx_chain[i].sc_mbuf = NULL; 1134 } 1135 if (sc->sc_data.sc_rx_chain[i].sc_xfer != NULL) { 1136 usbd_free_xfer(sc->sc_data.sc_rx_chain[i].sc_xfer); 1137 sc->sc_data.sc_rx_chain[i].sc_xfer = NULL; 1138 } 1139 } 1140 1141 for (i = 0; i < RNDIS_TX_LIST_CNT; i++) { 1142 if (sc->sc_data.sc_tx_chain[i].sc_mbuf != NULL) { 1143 m_freem(sc->sc_data.sc_tx_chain[i].sc_mbuf); 1144 sc->sc_data.sc_tx_chain[i].sc_mbuf = NULL; 1145 } 1146 if (sc->sc_data.sc_tx_chain[i].sc_xfer != NULL) { 1147 usbd_free_xfer(sc->sc_data.sc_tx_chain[i].sc_xfer); 1148 sc->sc_data.sc_tx_chain[i].sc_xfer = NULL; 1149 } 1150 } 1151 } 1152 1153 static void 1154 urndis_start(struct ifnet *ifp) 1155 { 1156 struct urndis_softc *sc; 1157 struct mbuf *m_head = NULL; 1158 1159 sc = ifp->if_softc; 1160 1161 if (sc->sc_dying || (ifp->if_flags & IFF_OACTIVE)) 1162 return; 1163 1164 IFQ_POLL(&ifp->if_snd, m_head); 1165 if (m_head == NULL) 1166 return; 1167 1168 if (urndis_encap(sc, m_head, 0)) { 1169 ifp->if_flags |= IFF_OACTIVE; 1170 return; 1171 } 1172 IFQ_DEQUEUE(&ifp->if_snd, m_head); 1173 1174 /* 1175 * If there's a BPF listener, bounce a copy of this frame 1176 * to him. 1177 */ 1178 bpf_mtap(ifp, m_head); 1179 1180 ifp->if_flags |= IFF_OACTIVE; 1181 1182 /* 1183 * Set a timeout in case the chip goes out to lunch. 1184 */ 1185 ifp->if_timer = 5; 1186 1187 return; 1188 } 1189 1190 static void 1191 urndis_rxeof(usbd_xfer_handle xfer, 1192 usbd_private_handle priv, 1193 usbd_status status) 1194 { 1195 struct urndis_chain *c; 1196 struct urndis_softc *sc; 1197 struct ifnet *ifp; 1198 uint32_t total_len; 1199 1200 c = priv; 1201 sc = c->sc_softc; 1202 ifp = GET_IFP(sc); 1203 total_len = 0; 1204 1205 if (sc->sc_dying || !(ifp->if_flags & IFF_RUNNING)) 1206 return; 1207 1208 if (status != USBD_NORMAL_COMPLETION) { 1209 if (status == USBD_NOT_STARTED || status == USBD_CANCELLED) 1210 return; 1211 if (usbd_ratecheck(&sc->sc_rx_notice)) { 1212 printf("%s: usb errors on rx: %s\n", 1213 DEVNAME(sc), usbd_errstr(status)); 1214 } 1215 if (status == USBD_STALLED) 1216 usbd_clear_endpoint_stall_async(sc->sc_bulkin_pipe); 1217 1218 goto done; 1219 } 1220 1221 usbd_get_xfer_status(xfer, NULL, NULL, &total_len, NULL); 1222 urndis_decap(sc, c, total_len); 1223 1224 done: 1225 /* Setup new transfer. */ 1226 usbd_setup_xfer(c->sc_xfer, sc->sc_bulkin_pipe, c, c->sc_buf, 1227 RNDIS_BUFSZ, USBD_SHORT_XFER_OK | USBD_NO_COPY, USBD_NO_TIMEOUT, 1228 urndis_rxeof); 1229 usbd_transfer(c->sc_xfer); 1230 } 1231 1232 static void 1233 urndis_txeof(usbd_xfer_handle xfer, 1234 usbd_private_handle priv, 1235 usbd_status status) 1236 { 1237 struct urndis_chain *c; 1238 struct urndis_softc *sc; 1239 struct ifnet *ifp; 1240 usbd_status err; 1241 int s; 1242 1243 c = priv; 1244 sc = c->sc_softc; 1245 ifp = GET_IFP(sc); 1246 1247 DPRINTF(("%s: urndis_txeof\n", DEVNAME(sc))); 1248 1249 if (sc->sc_dying) 1250 return; 1251 1252 s = splnet(); 1253 1254 ifp->if_timer = 0; 1255 ifp->if_flags &= ~IFF_OACTIVE; 1256 1257 if (status != USBD_NORMAL_COMPLETION) { 1258 if (status == USBD_NOT_STARTED || status == USBD_CANCELLED) { 1259 splx(s); 1260 return; 1261 } 1262 ifp->if_oerrors++; 1263 printf("%s: usb error on tx: %s\n", DEVNAME(sc), 1264 usbd_errstr(status)); 1265 if (status == USBD_STALLED) 1266 usbd_clear_endpoint_stall_async(sc->sc_bulkout_pipe); 1267 splx(s); 1268 return; 1269 } 1270 1271 usbd_get_xfer_status(c->sc_xfer, NULL, NULL, NULL, &err); 1272 1273 if (c->sc_mbuf != NULL) { 1274 m_freem(c->sc_mbuf); 1275 c->sc_mbuf = NULL; 1276 } 1277 1278 if (err) 1279 ifp->if_oerrors++; 1280 else 1281 ifp->if_opackets++; 1282 1283 if (IFQ_IS_EMPTY(&ifp->if_snd) == 0) 1284 urndis_start(ifp); 1285 1286 splx(s); 1287 } 1288 1289 static int 1290 urndis_match(device_t parent, cfdata_t match, void *aux) 1291 { 1292 struct usbif_attach_arg *uaa; 1293 usb_interface_descriptor_t *id; 1294 1295 uaa = aux; 1296 1297 if (!uaa->iface) 1298 return (UMATCH_NONE); 1299 1300 id = usbd_get_interface_descriptor(uaa->iface); 1301 if (id == NULL) 1302 return (UMATCH_NONE); 1303 1304 if (id->bInterfaceClass == UICLASS_WIRELESS && 1305 id->bInterfaceSubClass == UISUBCLASS_RF && 1306 id->bInterfaceProtocol == UIPROTO_RNDIS) 1307 return (UMATCH_IFACECLASS_IFACESUBCLASS_IFACEPROTO); 1308 1309 return (usb_lookup(urndis_devs, uaa->vendor, uaa->product) != NULL) ? 1310 UMATCH_VENDOR_PRODUCT : UMATCH_NONE; 1311 } 1312 1313 static void 1314 urndis_attach(device_t parent, device_t self, void *aux) 1315 { 1316 struct urndis_softc *sc; 1317 struct usbif_attach_arg *uaa; 1318 struct ifnet *ifp; 1319 usb_interface_descriptor_t *id; 1320 usb_endpoint_descriptor_t *ed; 1321 usb_config_descriptor_t *cd; 1322 const usb_cdc_union_descriptor_t *ud; 1323 const usb_cdc_header_descriptor_t *desc; 1324 usbd_desc_iter_t iter; 1325 int if_ctl, if_data; 1326 int i, j, altcnt; 1327 int s; 1328 u_char eaddr[ETHER_ADDR_LEN]; 1329 void *buf; 1330 size_t bufsz; 1331 uint32_t filter; 1332 char *devinfop; 1333 1334 sc = device_private(self); 1335 uaa = aux; 1336 sc->sc_dev = self; 1337 sc->sc_udev = uaa->device; 1338 1339 aprint_naive("\n"); 1340 aprint_normal("\n"); 1341 1342 devinfop = usbd_devinfo_alloc(uaa->device, 0); 1343 aprint_normal_dev(self, "%s\n", devinfop); 1344 usbd_devinfo_free(devinfop); 1345 1346 sc->sc_iface_ctl = uaa->iface; 1347 id = usbd_get_interface_descriptor(sc->sc_iface_ctl); 1348 if_ctl = id->bInterfaceNumber; 1349 sc->sc_ifaceno_ctl = if_ctl; 1350 if_data = -1; 1351 1352 usb_desc_iter_init(sc->sc_udev, &iter); 1353 while ((desc = (const void *)usb_desc_iter_next(&iter)) != NULL) { 1354 1355 if (desc->bDescriptorType != UDESC_CS_INTERFACE) { 1356 continue; 1357 } 1358 switch (desc->bDescriptorSubtype) { 1359 case UDESCSUB_CDC_UNION: 1360 /* XXX bail out when found first? */ 1361 ud = (const usb_cdc_union_descriptor_t *)desc; 1362 if (if_data == -1) 1363 if_data = ud->bSlaveInterface[0]; 1364 break; 1365 } 1366 } 1367 1368 if (if_data == -1) { 1369 DPRINTF(("urndis_attach: no union interface\n")); 1370 sc->sc_iface_data = sc->sc_iface_ctl; 1371 } else { 1372 DPRINTF(("urndis_attach: union interface: ctl %u, data %u\n", 1373 if_ctl, if_data)); 1374 for (i = 0; i < uaa->nifaces; i++) { 1375 if (uaa->ifaces[i] != NULL) { 1376 id = usbd_get_interface_descriptor( 1377 uaa->ifaces[i]); 1378 if (id != NULL && id->bInterfaceNumber == 1379 if_data) { 1380 sc->sc_iface_data = uaa->ifaces[i]; 1381 uaa->ifaces[i] = NULL; 1382 } 1383 } 1384 } 1385 } 1386 1387 if (sc->sc_iface_data == NULL) { 1388 printf("%s: no data interface\n", DEVNAME(sc)); 1389 return; 1390 } 1391 1392 id = usbd_get_interface_descriptor(sc->sc_iface_data); 1393 cd = usbd_get_config_descriptor(sc->sc_udev); 1394 altcnt = usbd_get_no_alts(cd, id->bInterfaceNumber); 1395 1396 for (j = 0; j < altcnt; j++) { 1397 if (usbd_set_interface(sc->sc_iface_data, j)) { 1398 printf("%s: interface alternate setting %u failed\n", 1399 DEVNAME(sc), j); 1400 return; 1401 } 1402 /* Find endpoints. */ 1403 id = usbd_get_interface_descriptor(sc->sc_iface_data); 1404 sc->sc_bulkin_no = sc->sc_bulkout_no = -1; 1405 for (i = 0; i < id->bNumEndpoints; i++) { 1406 ed = usbd_interface2endpoint_descriptor( 1407 sc->sc_iface_data, i); 1408 if (!ed) { 1409 printf("%s: no descriptor for bulk endpoint " 1410 "%u\n", DEVNAME(sc), i); 1411 return; 1412 } 1413 if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN && 1414 UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) { 1415 sc->sc_bulkin_no = ed->bEndpointAddress; 1416 } 1417 else if ( 1418 UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT && 1419 UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) { 1420 sc->sc_bulkout_no = ed->bEndpointAddress; 1421 } 1422 } 1423 1424 if (sc->sc_bulkin_no != -1 && sc->sc_bulkout_no != -1) { 1425 DPRINTF(("%s: in=0x%x, out=0x%x\n", 1426 DEVNAME(sc), 1427 sc->sc_bulkin_no, 1428 sc->sc_bulkout_no)); 1429 goto found; 1430 } 1431 } 1432 1433 if (sc->sc_bulkin_no == -1) 1434 printf("%s: could not find data bulk in\n", DEVNAME(sc)); 1435 if (sc->sc_bulkout_no == -1 ) 1436 printf("%s: could not find data bulk out\n", DEVNAME(sc)); 1437 return; 1438 1439 found: 1440 1441 ifp = GET_IFP(sc); 1442 ifp->if_softc = sc; 1443 ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; 1444 ifp->if_start = urndis_start; 1445 ifp->if_ioctl = urndis_ioctl; 1446 #if 0 1447 ifp->if_watchdog = urndis_watchdog; 1448 #endif 1449 1450 strlcpy(ifp->if_xname, DEVNAME(sc), IFNAMSIZ); 1451 1452 IFQ_SET_READY(&ifp->if_snd); 1453 1454 urndis_init(ifp); 1455 1456 s = splnet(); 1457 1458 if (urndis_ctrl_query(sc, OID_802_3_PERMANENT_ADDRESS, NULL, 0, 1459 &buf, &bufsz) != RNDIS_STATUS_SUCCESS) { 1460 printf("%s: unable to get hardware address\n", DEVNAME(sc)); 1461 urndis_stop(ifp); 1462 splx(s); 1463 return; 1464 } 1465 1466 if (bufsz == ETHER_ADDR_LEN) { 1467 memcpy(eaddr, buf, ETHER_ADDR_LEN); 1468 printf("%s: address %s\n", DEVNAME(sc), ether_sprintf(eaddr)); 1469 kmem_free(buf, bufsz); 1470 } else { 1471 printf("%s: invalid address\n", DEVNAME(sc)); 1472 kmem_free(buf, bufsz); 1473 urndis_stop(ifp); 1474 splx(s); 1475 return; 1476 } 1477 1478 /* Initialize packet filter */ 1479 sc->sc_filter = RNDIS_PACKET_TYPE_BROADCAST; 1480 sc->sc_filter |= RNDIS_PACKET_TYPE_ALL_MULTICAST; 1481 filter = htole32(sc->sc_filter); 1482 if (urndis_ctrl_set(sc, OID_GEN_CURRENT_PACKET_FILTER, &filter, 1483 sizeof(filter)) != RNDIS_STATUS_SUCCESS) { 1484 printf("%s: unable to set data filters\n", DEVNAME(sc)); 1485 urndis_stop(ifp); 1486 splx(s); 1487 return; 1488 } 1489 1490 if_attach(ifp); 1491 ether_ifattach(ifp, eaddr); 1492 sc->sc_attached = 1; 1493 1494 splx(s); 1495 } 1496 1497 static int 1498 urndis_detach(device_t self, int flags) 1499 { 1500 struct urndis_softc *sc; 1501 struct ifnet *ifp; 1502 int s; 1503 1504 sc = device_private(self); 1505 1506 DPRINTF(("urndis_detach: %s flags %u\n", DEVNAME(sc), 1507 flags)); 1508 1509 if (!sc->sc_attached) 1510 return 0; 1511 1512 s = splusb(); 1513 1514 ifp = GET_IFP(sc); 1515 1516 if (ifp->if_softc != NULL) { 1517 ether_ifdetach(ifp); 1518 if_detach(ifp); 1519 } 1520 1521 urndis_stop(ifp); 1522 sc->sc_attached = 0; 1523 1524 splx(s); 1525 1526 return 0; 1527 } 1528 1529 static int 1530 urndis_activate(device_t self, enum devact act) 1531 { 1532 struct urndis_softc *sc; 1533 1534 sc = device_private(self); 1535 1536 switch (act) { 1537 case DVACT_DEACTIVATE: 1538 sc->sc_dying = 1; 1539 return 0; 1540 } 1541 1542 return EOPNOTSUPP; 1543 } 1544 1545