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