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