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