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