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