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