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