1 /* $NetBSD: if_urndis.c,v 1.15 2016/12/15 09:28:06 ozaki-r 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.15 2016/12/15 09:28:06 ozaki-r 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 m_set_rcvif(m, ifp); 872 873 s = splnet(); 874 875 if (urndis_newbuf(sc, c) == ENOBUFS) { 876 ifp->if_ierrors++; 877 } else { 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