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