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