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