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