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