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