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