FreeBSD/Linux Kernel Cross Reference
sys/dev/usb/if_udav.c
1 /* $NetBSD: if_udav.c,v 1.2 2003/09/04 15:17:38 tsutsui Exp $ */
2 /* $nabe: if_udav.c,v 1.3 2003/08/21 16:57:19 nabe Exp $ */
3 /* $FreeBSD: src/sys/dev/usb/if_udav.c,v 1.14.2.5 2007/05/21 18:10:48 brueffer Exp $ */
4 /*-
5 * Copyright (c) 2003
6 * Shingo WATANABE <nabe@nabechan.org>. All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. Neither the name of the author nor the names of any co-contributors
17 * may be used to endorse or promote products derived from this software
18 * without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30 * SUCH DAMAGE.
31 *
32 */
33
34 /*
35 * DM9601(DAVICOM USB to Ethernet MAC Controller with Integrated 10/100 PHY)
36 * The spec can be found at the following url.
37 * http://www.davicom.com.tw/big5/download/Data%20Sheet/DM9601-DS-P01-930914.pdf
38 */
39
40 /*
41 * TODO:
42 * Interrupt Endpoint support
43 * External PHYs
44 * powerhook() support?
45 */
46
47 #include <sys/cdefs.h>
48 __FBSDID("$FreeBSD: src/sys/dev/usb/if_udav.c,v 1.14.2.5 2007/05/21 18:10:48 brueffer Exp $");
49
50 #include "opt_inet.h"
51 #if defined(__NetBSD__)
52 #include "opt_ns.h"
53 #endif
54 #if defined(__NetBSD__)
55 #include "bpfilter.h"
56 #endif
57 #if defined(__FreeBSD__)
58 #define NBPFILTER 1
59 #endif
60 #if defined(__NetBSD__)
61 #include "rnd.h"
62 #endif
63
64 #include <sys/param.h>
65 #include <sys/systm.h>
66 #include <sys/lock.h>
67 #include <sys/mbuf.h>
68 #include <sys/kernel.h>
69 #include <sys/module.h>
70 #include <sys/socket.h>
71 #if defined(__FreeBSD__)
72 #include <sys/types.h>
73 #include <sys/lockmgr.h>
74 #include <sys/sockio.h>
75 #endif
76
77 #if defined(__NetBSD__)
78 #include <sys/device.h>
79 #endif
80
81 #if NRND > 0
82 #include <sys/rnd.h>
83 #endif
84
85 #include <net/if.h>
86 #include <net/if_arp.h>
87 #include <net/if_dl.h>
88 #include <net/if_media.h>
89 #include <net/ethernet.h>
90 #include <net/if_types.h>
91
92 #if NBPFILTER > 0
93 #include <net/bpf.h>
94 #endif
95 #if defined(__NetBSD__)
96 #ifndef BPF_MTAP
97 #define BPF_MTAP(_ifp, _m) do { \
98 if ((_ifp)->if_bpf)) { \
99 bpf_mtap((_ifp)->if_bpf, (_m)) ; \
100 } \
101 } while (0)
102 #endif
103 #endif
104
105 #if defined(__NetBSD__)
106 #include <net/if_ether.h>
107 #ifdef INET
108 #include <netinet/in.h>
109 #include <netinet/if_inarp.h>
110 #endif /* INET */
111 #elif defined(__FreeBSD__) /* defined(__NetBSD__) */
112 #include <netinet/in.h>
113 #include <netinet/if_ether.h>
114 #endif /* defined(__FreeBSD__) */
115
116 #if defined(__NetBSD__)
117 #ifdef NS
118 #include <netns/ns.h>
119 #include <netns/ns_if.h>
120 #endif
121 #endif /* defined (__NetBSD__) */
122
123 #include <sys/bus.h>
124 #include <machine/bus.h>
125
126 #include <dev/mii/mii.h>
127 #include <dev/mii/miivar.h>
128
129 #include <dev/usb/usb.h>
130 #include <dev/usb/usbdi.h>
131 #include <dev/usb/usbdi_util.h>
132 #include "usbdevs.h"
133 #include <dev/usb/usbdivar.h>
134 #include <dev/usb/usb_ethersubr.h>
135
136 #include <dev/usb/if_udavreg.h>
137
138 #if defined(__FreeBSD__)
139 MODULE_DEPEND(udav, usb, 1, 1, 1);
140 MODULE_DEPEND(udav, ether, 1, 1, 1);
141 MODULE_DEPEND(udav, miibus, 1, 1, 1);
142 #endif
143
144 /* "controller miibus0" required. See GENERIC if you get errors here. */
145 #include "miibus_if.h"
146
147 #if !defined(__FreeBSD__)
148 /* Function declarations */
149 USB_DECLARE_DRIVER(udav);
150 #endif
151
152 #if defined(__FreeBSD__)
153 Static int udav_match(device_ptr_t);
154 Static int udav_attach(device_ptr_t);
155 Static int udav_detach(device_ptr_t);
156 Static void udav_shutdown(device_ptr_t);
157 #endif
158
159 Static int udav_openpipes(struct udav_softc *);
160 Static void udav_start(struct ifnet *);
161 Static int udav_send(struct udav_softc *, struct mbuf *, int);
162 Static void udav_txeof(usbd_xfer_handle, usbd_private_handle, usbd_status);
163 #if defined(__FreeBSD__)
164 Static void udav_rxstart(struct ifnet *ifp);
165 #endif
166 Static void udav_rxeof(usbd_xfer_handle, usbd_private_handle, usbd_status);
167 Static void udav_tick(void *);
168 Static void udav_tick_task(void *);
169 Static int udav_ioctl(struct ifnet *, u_long, caddr_t);
170 Static void udav_stop_task(struct udav_softc *);
171 Static void udav_stop(struct ifnet *, int);
172 Static void udav_watchdog(struct ifnet *);
173 Static int udav_ifmedia_change(struct ifnet *);
174 Static void udav_ifmedia_status(struct ifnet *, struct ifmediareq *);
175 Static void udav_lock_mii(struct udav_softc *);
176 Static void udav_unlock_mii(struct udav_softc *);
177 Static int udav_miibus_readreg(device_ptr_t, int, int);
178 Static void udav_miibus_writereg(device_ptr_t, int, int, int);
179 Static void udav_miibus_statchg(device_ptr_t);
180 #if defined(__NetBSD__)
181 Static int udav_init(struct ifnet *);
182 #elif defined(__FreeBSD__)
183 Static void udav_init(void *);
184 #endif
185 Static void udav_setmulti(struct udav_softc *);
186 Static void udav_reset(struct udav_softc *);
187
188 Static int udav_csr_read(struct udav_softc *, int, void *, int);
189 Static int udav_csr_write(struct udav_softc *, int, void *, int);
190 Static int udav_csr_read1(struct udav_softc *, int);
191 Static int udav_csr_write1(struct udav_softc *, int, unsigned char);
192
193 #if 0
194 Static int udav_mem_read(struct udav_softc *, int, void *, int);
195 Static int udav_mem_write(struct udav_softc *, int, void *, int);
196 Static int udav_mem_write1(struct udav_softc *, int, unsigned char);
197 #endif
198
199 #if defined(__FreeBSD__)
200 Static device_method_t udav_methods[] = {
201 /* Device interface */
202 DEVMETHOD(device_probe, udav_match),
203 DEVMETHOD(device_attach, udav_attach),
204 DEVMETHOD(device_detach, udav_detach),
205 DEVMETHOD(device_shutdown, udav_shutdown),
206
207 /* bus interface */
208 DEVMETHOD(bus_print_child, bus_generic_print_child),
209 DEVMETHOD(bus_driver_added, bus_generic_driver_added),
210
211 /* MII interface */
212 DEVMETHOD(miibus_readreg, udav_miibus_readreg),
213 DEVMETHOD(miibus_writereg, udav_miibus_writereg),
214 DEVMETHOD(miibus_statchg, udav_miibus_statchg),
215
216 { 0, 0 }
217 };
218
219 Static driver_t udav_driver = {
220 "udav",
221 udav_methods,
222 sizeof(struct udav_softc)
223 };
224
225 Static devclass_t udav_devclass;
226
227 DRIVER_MODULE(udav, uhub, udav_driver, udav_devclass, usbd_driver_load, 0);
228 DRIVER_MODULE(miibus, udav, miibus_driver, miibus_devclass, 0, 0);
229
230 #endif /* defined(__FreeBSD__) */
231
232 /* Macros */
233 #ifdef UDAV_DEBUG
234 #define DPRINTF(x) if (udavdebug) logprintf x
235 #define DPRINTFN(n,x) if (udavdebug >= (n)) logprintf x
236 int udavdebug = 0;
237 #else
238 #define DPRINTF(x)
239 #define DPRINTFN(n,x)
240 #endif
241
242 #define delay(d) DELAY(d)
243
244 #define UDAV_SETBIT(sc, reg, x) \
245 udav_csr_write1(sc, reg, udav_csr_read1(sc, reg) | (x))
246
247 #define UDAV_CLRBIT(sc, reg, x) \
248 udav_csr_write1(sc, reg, udav_csr_read1(sc, reg) & ~(x))
249
250 static const struct udav_type {
251 struct usb_devno udav_dev;
252 u_int16_t udav_flags;
253 #define UDAV_EXT_PHY 0x0001
254 } udav_devs [] = {
255 /* Corega USB-TXC */
256 {{ USB_VENDOR_COREGA, USB_PRODUCT_COREGA_FETHER_USB_TXC }, 0},
257 #if 0
258 /* DAVICOM DM9601 Generic? */
259 /* XXX: The following ids was obtained from the data sheet. */
260 {{ 0x0a46, 0x9601 }, 0},
261 #endif
262 };
263 #define udav_lookup(v, p) ((const struct udav_type *)usb_lookup(udav_devs, v, p))
264
265
266 /* Probe */
267 USB_MATCH(udav)
268 {
269 USB_MATCH_START(udav, uaa);
270
271 if (uaa->iface != NULL)
272 return (UMATCH_NONE);
273
274 return (udav_lookup(uaa->vendor, uaa->product) != NULL ?
275 UMATCH_VENDOR_PRODUCT : UMATCH_NONE);
276 }
277
278 /* Attach */
279 USB_ATTACH(udav)
280 {
281 USB_ATTACH_START(udav, sc, uaa);
282 usbd_device_handle dev = uaa->device;
283 usbd_interface_handle iface;
284 usbd_status err;
285 usb_interface_descriptor_t *id;
286 usb_endpoint_descriptor_t *ed;
287 char devinfo[1024];
288 const char *devname ;
289 struct ifnet *ifp;
290 #if defined(__NetBSD__)
291 struct mii_data *mii;
292 #endif
293 u_char eaddr[ETHER_ADDR_LEN];
294 int i;
295 #if defined(__NetBSD__)
296 int s;
297 #endif
298
299 bzero(sc, sizeof(struct udav_softc));
300
301 usbd_devinfo(dev, 0, devinfo);
302 USB_ATTACH_SETUP;
303 devname = USBDEVNAME(sc->sc_dev);
304 printf("%s: %s\n", devname, devinfo);
305
306 /* Move the device into the configured state. */
307 err = usbd_set_config_no(dev, UDAV_CONFIG_NO, 1);
308 if (err) {
309 printf("%s: setting config no failed\n", devname);
310 goto bad;
311 }
312
313 usb_init_task(&sc->sc_tick_task, udav_tick_task, sc);
314 lockinit(&sc->sc_mii_lock, PZERO, "udavmii", 0, 0);
315 usb_init_task(&sc->sc_stop_task, (void (*)(void *)) udav_stop_task, sc);
316
317 /* get control interface */
318 err = usbd_device2interface_handle(dev, UDAV_IFACE_INDEX, &iface);
319 if (err) {
320 printf("%s: failed to get interface, err=%s\n", devname,
321 usbd_errstr(err));
322 goto bad;
323 }
324
325 sc->sc_udev = dev;
326 sc->sc_ctl_iface = iface;
327 sc->sc_flags = udav_lookup(uaa->vendor, uaa->product)->udav_flags;
328
329 /* get interface descriptor */
330 id = usbd_get_interface_descriptor(sc->sc_ctl_iface);
331
332 /* find endpoints */
333 sc->sc_bulkin_no = sc->sc_bulkout_no = sc->sc_intrin_no = -1;
334 for (i = 0; i < id->bNumEndpoints; i++) {
335 ed = usbd_interface2endpoint_descriptor(sc->sc_ctl_iface, i);
336 if (ed == NULL) {
337 printf("%s: couldn't get endpoint %d\n", devname, i);
338 goto bad;
339 }
340 if ((ed->bmAttributes & UE_XFERTYPE) == UE_BULK &&
341 UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN)
342 sc->sc_bulkin_no = ed->bEndpointAddress; /* RX */
343 else if ((ed->bmAttributes & UE_XFERTYPE) == UE_BULK &&
344 UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT)
345 sc->sc_bulkout_no = ed->bEndpointAddress; /* TX */
346 else if ((ed->bmAttributes & UE_XFERTYPE) == UE_INTERRUPT &&
347 UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN)
348 sc->sc_intrin_no = ed->bEndpointAddress; /* Status */
349 }
350
351 if (sc->sc_bulkin_no == -1 || sc->sc_bulkout_no == -1 ||
352 sc->sc_intrin_no == -1) {
353 printf("%s: missing endpoint\n", devname);
354 goto bad;
355 }
356
357 #if defined(__FreeBSD__)
358 mtx_init(&sc->sc_mtx, device_get_nameunit(self), MTX_NETWORK_LOCK,
359 MTX_DEF | MTX_RECURSE);
360 #endif
361 #if defined(__NetBSD__)
362 s = splnet();
363 #elif defined(__FreeBSD__)
364 UDAV_LOCK(sc);
365 #endif
366
367 /* reset the adapter */
368 udav_reset(sc);
369
370 /* Get Ethernet Address */
371 err = udav_csr_read(sc, UDAV_PAR, (void *)eaddr, ETHER_ADDR_LEN);
372 if (err) {
373 printf("%s: read MAC address failed\n", devname);
374 #if defined(__NetBSD__)
375 splx(s);
376 #elif defined(__FreeBSD__)
377 UDAV_UNLOCK(sc);
378 mtx_destroy(&sc->sc_mtx);
379 #endif
380 goto bad;
381 }
382
383 /* Print Ethernet Address */
384 printf("%s: Ethernet address %s\n", devname, ether_sprintf(eaddr));
385
386 /* initialize interface infomation */
387 #if defined(__FreeBSD__)
388 ifp = GET_IFP(sc) = if_alloc(IFT_ETHER);
389 if (ifp == NULL) {
390 printf("%s: can not if_alloc\n", devname);
391 UDAV_UNLOCK(sc);
392 mtx_destroy(&sc->sc_mtx);
393 goto bad;
394 }
395 #else
396 ifp = GET_IFP(sc);
397 #endif
398 ifp->if_softc = sc;
399 ifp->if_mtu = ETHERMTU;
400 #if defined(__NetBSD__)
401 strncpy(ifp->if_xname, devname, IFNAMSIZ);
402 #elif defined(__FreeBSD__)
403 if_initname(ifp, "udav", device_get_unit(self));
404 #endif
405 ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST |
406 IFF_NEEDSGIANT;
407 ifp->if_start = udav_start;
408 ifp->if_ioctl = udav_ioctl;
409 ifp->if_watchdog = udav_watchdog;
410 ifp->if_init = udav_init;
411 #if defined(__NetBSD__)
412 ifp->if_stop = udav_stop;
413 #endif
414 #if defined(__FreeBSD__)
415 ifp->if_snd.ifq_maxlen = IFQ_MAXLEN;
416 #endif
417 #if defined(__NetBSD__)
418 IFQ_SET_READY(&ifp->if_snd);
419 #endif
420
421
422 #if defined(__NetBSD__)
423 /*
424 * Do ifmedia setup.
425 */
426 mii = &sc->sc_mii;
427 mii->mii_ifp = ifp;
428 mii->mii_readreg = udav_miibus_readreg;
429 mii->mii_writereg = udav_miibus_writereg;
430 mii->mii_statchg = udav_miibus_statchg;
431 mii->mii_flags = MIIF_AUTOTSLEEP;
432 ifmedia_init(&mii->mii_media, 0,
433 udav_ifmedia_change, udav_ifmedia_status);
434 mii_attach(self, mii, 0xffffffff, MII_PHY_ANY, MII_OFFSET_ANY, 0);
435 if (LIST_FIRST(&mii->mii_phys) == NULL) {
436 ifmedia_add(&mii->mii_media, IFM_ETHER | IFM_NONE, 0, NULL);
437 ifmedia_set(&mii->mii_media, IFM_ETHER | IFM_NONE);
438 } else
439 ifmedia_set(&mii->mii_media, IFM_ETHER | IFM_AUTO);
440
441 /* attach the interface */
442 if_attach(ifp);
443 Ether_ifattach(ifp, eaddr);
444 #elif defined(__FreeBSD__)
445 if (mii_phy_probe(self, &sc->sc_miibus,
446 udav_ifmedia_change, udav_ifmedia_status)) {
447 printf("%s: MII without any PHY!\n", USBDEVNAME(sc->sc_dev));
448 if_free(ifp);
449 UDAV_UNLOCK(sc);
450 mtx_destroy(&sc->sc_mtx);
451 USB_ATTACH_ERROR_RETURN;
452 }
453
454 sc->sc_qdat.ifp = ifp;
455 sc->sc_qdat.if_rxstart = udav_rxstart;
456
457 /*
458 * Call MI attach routine.
459 */
460
461 ether_ifattach(ifp, eaddr);
462 #endif
463
464 #if NRND > 0
465 rnd_attach_source(&sc->rnd_source, devname, RND_TYPE_NET, 0);
466 #endif
467
468 usb_callout_init(sc->sc_stat_ch);
469 #if defined(__FreeBSD__)
470 usb_register_netisr();
471 #endif
472 sc->sc_attached = 1;
473 #if defined(__NetBSD__)
474 splx(s);
475 #elif defined(__FreeBSD__)
476 UDAV_UNLOCK(sc);
477 #endif
478
479 usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, dev, USBDEV(sc->sc_dev));
480
481 USB_ATTACH_SUCCESS_RETURN;
482
483 bad:
484 sc->sc_dying = 1;
485 USB_ATTACH_ERROR_RETURN;
486 }
487
488 /* detach */
489 USB_DETACH(udav)
490 {
491 USB_DETACH_START(udav, sc);
492 struct ifnet *ifp = GET_IFP(sc);
493 #if defined(__NetBSD__)
494 int s;
495 #endif
496
497 DPRINTF(("%s: %s: enter\n", USBDEVNAME(sc->sc_dev), __func__));
498
499 /* Detached before attached finished */
500 if (!sc->sc_attached)
501 return (0);
502
503 UDAV_LOCK(sc);
504
505 usb_uncallout(sc->sc_stat_ch, udav_tick, sc);
506
507 /* Remove any pending tasks */
508 usb_rem_task(sc->sc_udev, &sc->sc_tick_task);
509 usb_rem_task(sc->sc_udev, &sc->sc_stop_task);
510
511 #if defined(__NetBSD__)
512 s = splusb();
513 #elif defined(__FreeBSD__)
514 UDAV_LOCK(sc);
515 #endif
516
517 if (--sc->sc_refcnt >= 0) {
518 /* Wait for processes to go away */
519 usb_detach_wait(USBDEV(sc->sc_dev));
520 }
521 #if defined(__FreeBSD__)
522 if (ifp->if_drv_flags & IFF_DRV_RUNNING)
523 #else
524 if (ifp->if_flags & IFF_RUNNING)
525 #endif
526 udav_stop(GET_IFP(sc), 1);
527
528 #if NRND > 0
529 rnd_detach_source(&sc->rnd_source);
530 #endif
531 #if defined(__NetBSD__)
532 mii_detach(&sc->sc_mii, MII_PHY_ANY, MII_OFFSET_ANY);
533 ifmedia_delete_instance(&sc->sc_mii.mii_media, IFM_INST_ANY);
534 #endif
535 ether_ifdetach(ifp);
536 #if defined(__NetBSD__)
537 if_detach(ifp);
538 #endif
539 #if defined(__FreeBSD__)
540 if_free(ifp);
541 #endif
542
543 #ifdef DIAGNOSTIC
544 if (sc->sc_pipe_tx != NULL)
545 printf("%s: detach has active tx endpoint.\n",
546 USBDEVNAME(sc->sc_dev));
547 if (sc->sc_pipe_rx != NULL)
548 printf("%s: detach has active rx endpoint.\n",
549 USBDEVNAME(sc->sc_dev));
550 if (sc->sc_pipe_intr != NULL)
551 printf("%s: detach has active intr endpoint.\n",
552 USBDEVNAME(sc->sc_dev));
553 #endif
554 sc->sc_attached = 0;
555
556 #if defined(__NetBSD__)
557 splx(s);
558 #elif defined(__FreeBSD__)
559 UDAV_UNLOCK(sc);
560 #endif
561
562 #if defined(__FreeBSD__)
563 mtx_destroy(&sc->sc_mtx);
564 #endif
565
566 usbd_add_drv_event(USB_EVENT_DRIVER_DETACH, sc->sc_udev,
567 USBDEV(sc->sc_dev));
568 return (0);
569 }
570
571 #if 0
572 /* read memory */
573 Static int
574 udav_mem_read(struct udav_softc *sc, int offset, void *buf, int len)
575 {
576 usb_device_request_t req;
577 usbd_status err;
578
579 if (sc == NULL)
580 return (0);
581
582 DPRINTFN(0x200,
583 ("%s: %s: enter\n", USBDEVNAME(sc->sc_dev), __func__));
584
585 if (sc->sc_dying)
586 return (0);
587
588 offset &= 0xffff;
589 len &= 0xff;
590
591 req.bmRequestType = UT_READ_VENDOR_DEVICE;
592 req.bRequest = UDAV_REQ_MEM_READ;
593 USETW(req.wValue, 0x0000);
594 USETW(req.wIndex, offset);
595 USETW(req.wLength, len);
596
597 sc->sc_refcnt++;
598 err = usbd_do_request(sc->sc_udev, &req, buf);
599 if (--sc->sc_refcnt < 0)
600 usb_detach_wakeup(USBDEV(sc->sc_dev));
601 if (err) {
602 DPRINTF(("%s: %s: read failed. off=%04x, err=%d\n",
603 USBDEVNAME(sc->sc_dev), __func__, offset, err));
604 }
605
606 return (err);
607 }
608
609 /* write memory */
610 Static int
611 udav_mem_write(struct udav_softc *sc, int offset, void *buf, int len)
612 {
613 usb_device_request_t req;
614 usbd_status err;
615
616 if (sc == NULL)
617 return (0);
618
619 DPRINTFN(0x200,
620 ("%s: %s: enter\n", USBDEVNAME(sc->sc_dev), __func__));
621
622 if (sc->sc_dying)
623 return (0);
624
625 offset &= 0xffff;
626 len &= 0xff;
627
628 req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
629 req.bRequest = UDAV_REQ_MEM_WRITE;
630 USETW(req.wValue, 0x0000);
631 USETW(req.wIndex, offset);
632 USETW(req.wLength, len);
633
634 sc->sc_refcnt++;
635 err = usbd_do_request(sc->sc_udev, &req, buf);
636 if (--sc->sc_refcnt < 0)
637 usb_detach_wakeup(USBDEV(sc->sc_dev));
638 if (err) {
639 DPRINTF(("%s: %s: write failed. off=%04x, err=%d\n",
640 USBDEVNAME(sc->sc_dev), __func__, offset, err));
641 }
642
643 return (err);
644 }
645
646 /* write memory */
647 Static int
648 udav_mem_write1(struct udav_softc *sc, int offset, unsigned char ch)
649 {
650 usb_device_request_t req;
651 usbd_status err;
652
653 if (sc == NULL)
654 return (0);
655
656 DPRINTFN(0x200,
657 ("%s: %s: enter\n", USBDEVNAME(sc->sc_dev), __func__));
658
659 if (sc->sc_dying)
660 return (0);
661
662 offset &= 0xffff;
663
664 req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
665 req.bRequest = UDAV_REQ_MEM_WRITE1;
666 USETW(req.wValue, ch);
667 USETW(req.wIndex, offset);
668 USETW(req.wLength, 0x0000);
669
670 sc->sc_refcnt++;
671 err = usbd_do_request(sc->sc_udev, &req, NULL);
672 if (--sc->sc_refcnt < 0)
673 usb_detach_wakeup(USBDEV(sc->sc_dev));
674 if (err) {
675 DPRINTF(("%s: %s: write failed. off=%04x, err=%d\n",
676 USBDEVNAME(sc->sc_dev), __func__, offset, err));
677 }
678
679 return (err);
680 }
681 #endif
682
683 /* read register(s) */
684 Static int
685 udav_csr_read(struct udav_softc *sc, int offset, void *buf, int len)
686 {
687 usb_device_request_t req;
688 usbd_status err;
689
690 if (sc == NULL)
691 return (0);
692
693 DPRINTFN(0x200,
694 ("%s: %s: enter\n", USBDEVNAME(sc->sc_dev), __func__));
695
696 if (sc->sc_dying)
697 return (0);
698
699 offset &= 0xff;
700 len &= 0xff;
701
702 req.bmRequestType = UT_READ_VENDOR_DEVICE;
703 req.bRequest = UDAV_REQ_REG_READ;
704 USETW(req.wValue, 0x0000);
705 USETW(req.wIndex, offset);
706 USETW(req.wLength, len);
707
708 sc->sc_refcnt++;
709 err = usbd_do_request(sc->sc_udev, &req, buf);
710 if (--sc->sc_refcnt < 0)
711 usb_detach_wakeup(USBDEV(sc->sc_dev));
712 if (err) {
713 DPRINTF(("%s: %s: read failed. off=%04x, err=%d\n",
714 USBDEVNAME(sc->sc_dev), __func__, offset, err));
715 }
716
717 return (err);
718 }
719
720 /* write register(s) */
721 Static int
722 udav_csr_write(struct udav_softc *sc, int offset, void *buf, int len)
723 {
724 usb_device_request_t req;
725 usbd_status err;
726
727 if (sc == NULL)
728 return (0);
729
730 DPRINTFN(0x200,
731 ("%s: %s: enter\n", USBDEVNAME(sc->sc_dev), __func__));
732
733 if (sc->sc_dying)
734 return (0);
735
736 offset &= 0xff;
737 len &= 0xff;
738
739 req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
740 req.bRequest = UDAV_REQ_REG_WRITE;
741 USETW(req.wValue, 0x0000);
742 USETW(req.wIndex, offset);
743 USETW(req.wLength, len);
744
745 sc->sc_refcnt++;
746 err = usbd_do_request(sc->sc_udev, &req, buf);
747 if (--sc->sc_refcnt < 0)
748 usb_detach_wakeup(USBDEV(sc->sc_dev));
749 if (err) {
750 DPRINTF(("%s: %s: write failed. off=%04x, err=%d\n",
751 USBDEVNAME(sc->sc_dev), __func__, offset, err));
752 }
753
754 return (err);
755 }
756
757 Static int
758 udav_csr_read1(struct udav_softc *sc, int offset)
759 {
760 u_int8_t val = 0;
761
762 if (sc == NULL)
763 return (0);
764
765 DPRINTFN(0x200,
766 ("%s: %s: enter\n", USBDEVNAME(sc->sc_dev), __func__));
767
768 if (sc->sc_dying)
769 return (0);
770
771 return (udav_csr_read(sc, offset, &val, 1) ? 0 : val);
772 }
773
774 /* write a register */
775 Static int
776 udav_csr_write1(struct udav_softc *sc, int offset, unsigned char ch)
777 {
778 usb_device_request_t req;
779 usbd_status err;
780
781 if (sc == NULL)
782 return (0);
783
784 DPRINTFN(0x200,
785 ("%s: %s: enter\n", USBDEVNAME(sc->sc_dev), __func__));
786
787 if (sc->sc_dying)
788 return (0);
789
790 offset &= 0xff;
791
792 req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
793 req.bRequest = UDAV_REQ_REG_WRITE1;
794 USETW(req.wValue, ch);
795 USETW(req.wIndex, offset);
796 USETW(req.wLength, 0x0000);
797
798 sc->sc_refcnt++;
799 err = usbd_do_request(sc->sc_udev, &req, NULL);
800 if (--sc->sc_refcnt < 0)
801 usb_detach_wakeup(USBDEV(sc->sc_dev));
802 if (err) {
803 DPRINTF(("%s: %s: write failed. off=%04x, err=%d\n",
804 USBDEVNAME(sc->sc_dev), __func__, offset, err));
805 }
806
807 return (err);
808 }
809
810 #if defined(__NetBSD__)
811 Static int
812 udav_init(struct ifnet *ifp)
813 #elif defined(__FreeBSD__)
814 Static void
815 udav_init(void *xsc)
816 #endif
817 {
818 #if defined(__NetBSD__)
819 struct udav_softc *sc = ifp->if_softc;
820 #elif defined(__FreeBSD__)
821 struct udav_softc *sc = (struct udav_softc *)xsc;
822 struct ifnet *ifp = GET_IFP(sc);
823 #endif
824 struct mii_data *mii = GET_MII(sc);
825 u_char *eaddr;
826 #if defined(__NetBSD__)
827 int s;
828 #endif
829
830 DPRINTF(("%s: %s: enter\n", USBDEVNAME(sc->sc_dev), __func__));
831
832 if (sc->sc_dying)
833 #if defined(__NetBSD__)
834 return (EIO);
835 #elif defined(__FreeBSD__)
836 return ;
837 #endif
838
839 #if defined(__NetBSD__)
840 s = splnet();
841 #elif defined(__FreeBSD__)
842 UDAV_LOCK(sc);
843 #endif
844
845 /* Cancel pending I/O and free all TX/RX buffers */
846 udav_stop(ifp, 1);
847
848 #if defined(__NetBSD__)
849 eaddr = LLADDR(ifp->if_sadl);
850 #elif defined(__FreeBSD__)
851 eaddr = IFP2ENADDR(ifp);
852 #endif
853 udav_csr_write(sc, UDAV_PAR, eaddr, ETHER_ADDR_LEN);
854
855 /* Initialize network control register */
856 /* Disable loopback */
857 UDAV_CLRBIT(sc, UDAV_NCR, UDAV_NCR_LBK0 | UDAV_NCR_LBK1);
858
859 /* Initialize RX control register */
860 UDAV_SETBIT(sc, UDAV_RCR, UDAV_RCR_DIS_LONG | UDAV_RCR_DIS_CRC);
861
862 /* If we want promiscuous mode, accept all physical frames. */
863 if (ifp->if_flags & IFF_PROMISC)
864 UDAV_SETBIT(sc, UDAV_RCR, UDAV_RCR_ALL|UDAV_RCR_PRMSC);
865 else
866 UDAV_CLRBIT(sc, UDAV_RCR, UDAV_RCR_ALL|UDAV_RCR_PRMSC);
867
868 /* Initialize transmit ring */
869 if (usb_ether_tx_list_init(sc, &sc->sc_cdata,
870 sc->sc_udev) == ENOBUFS) {
871 printf("%s: tx list init failed\n", USBDEVNAME(sc->sc_dev));
872 #if defined(__NetBSD__)
873 splx(s);
874 return (EIO);
875 #elif defined(__FreeBSD__)
876 UDAV_UNLOCK(sc);
877 return ;
878 #endif
879
880 }
881
882 /* Initialize receive ring */
883 if (usb_ether_rx_list_init(sc, &sc->sc_cdata,
884 sc->sc_udev) == ENOBUFS) {
885 printf("%s: rx list init failed\n", USBDEVNAME(sc->sc_dev));
886 #if defined(__NetBSD__)
887 splx(s);
888 return (EIO);
889 #elif defined(__FreeBSD__)
890 UDAV_UNLOCK(sc);
891 return ;
892 #endif
893 }
894
895 /* Load the multicast filter */
896 udav_setmulti(sc);
897
898 /* Enable RX */
899 UDAV_SETBIT(sc, UDAV_RCR, UDAV_RCR_RXEN);
900
901 /* clear POWER_DOWN state of internal PHY */
902 UDAV_SETBIT(sc, UDAV_GPCR, UDAV_GPCR_GEP_CNTL0);
903 UDAV_CLRBIT(sc, UDAV_GPR, UDAV_GPR_GEPIO0);
904
905 mii_mediachg(mii);
906
907 if (sc->sc_pipe_tx == NULL || sc->sc_pipe_rx == NULL) {
908 if (udav_openpipes(sc)) {
909 #if defined(__NetBSD__)
910 splx(s);
911 return (EIO);
912 #elif defined(__FreeBSD__)
913 UDAV_UNLOCK(sc);
914 return ;
915 #endif
916 }
917 }
918
919 #if defined(__FreeBSD__)
920 ifp->if_drv_flags |= IFF_DRV_RUNNING;
921 ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
922 #else
923 ifp->if_flags |= IFF_RUNNING;
924 ifp->if_flags &= ~IFF_OACTIVE;
925 #endif
926
927 #if defined(__NetBSD__)
928 splx(s);
929 #elif defined(__FreeBSD__)
930 UDAV_UNLOCK(sc);
931 #endif
932
933 usb_callout(sc->sc_stat_ch, hz, udav_tick, sc);
934
935 #if defined(__NetBSD__)
936 return (0);
937 #elif defined(__FreeBSD__)
938 return ;
939 #endif
940 }
941
942 Static void
943 udav_reset(struct udav_softc *sc)
944 {
945 int i;
946
947 DPRINTF(("%s: %s: enter\n", USBDEVNAME(sc->sc_dev), __func__));
948
949 if (sc->sc_dying)
950 return;
951
952 /* Select PHY */
953 #if 1
954 /*
955 * XXX: force select internal phy.
956 * external phy routines are not tested.
957 */
958 UDAV_CLRBIT(sc, UDAV_NCR, UDAV_NCR_EXT_PHY);
959 #else
960 if (sc->sc_flags & UDAV_EXT_PHY) {
961 UDAV_SETBIT(sc, UDAV_NCR, UDAV_NCR_EXT_PHY);
962 } else {
963 UDAV_CLRBIT(sc, UDAV_NCR, UDAV_NCR_EXT_PHY);
964 }
965 #endif
966
967 UDAV_SETBIT(sc, UDAV_NCR, UDAV_NCR_RST);
968
969 for (i = 0; i < UDAV_TX_TIMEOUT; i++) {
970 if (!(udav_csr_read1(sc, UDAV_NCR) & UDAV_NCR_RST))
971 break;
972 delay(10); /* XXX */
973 }
974 delay(10000); /* XXX */
975 }
976
977 #if defined(__NetBSD__) || defined(__OpenBSD__)
978 int
979 udav_activate(device_ptr_t self, enum devact act)
980 {
981 struct udav_softc *sc = (struct udav_softc *)self;
982
983 DPRINTF(("%s: %s: enter, act=%d\n", USBDEVNAME(sc->sc_dev),
984 __func__, act));
985 switch (act) {
986 case DVACT_ACTIVATE:
987 return (EOPNOTSUPP);
988 break;
989
990 case DVACT_DEACTIVATE:
991 if_deactivate(&sc->sc_ec.ec_if);
992 sc->sc_dying = 1;
993 break;
994 }
995 return (0);
996 }
997 #endif
998
999 #define UDAV_BITS 6
1000
1001 #define UDAV_CALCHASH(addr) \
1002 (ether_crc32_le((addr), ETHER_ADDR_LEN) & ((1 << UDAV_BITS) - 1))
1003
1004 Static void
1005 udav_setmulti(struct udav_softc *sc)
1006 {
1007 struct ifnet *ifp;
1008 #if defined(__NetBSD__)
1009 struct ether_multi *enm;
1010 struct ether_multistep step;
1011 #elif defined(__FreeBSD__)
1012 struct ifmultiaddr *ifma;
1013 #endif
1014 u_int8_t hashes[8];
1015 int h = 0;
1016
1017 DPRINTF(("%s: %s: enter\n", USBDEVNAME(sc->sc_dev), __func__));
1018
1019 if (sc->sc_dying)
1020 return;
1021
1022 ifp = GET_IFP(sc);
1023
1024 if (ifp->if_flags & IFF_PROMISC) {
1025 UDAV_SETBIT(sc, UDAV_RCR, UDAV_RCR_ALL|UDAV_RCR_PRMSC);
1026 return;
1027 } else if (ifp->if_flags & IFF_ALLMULTI) {
1028 #if defined(__NetBSD__)
1029 allmulti:
1030 #endif
1031 ifp->if_flags |= IFF_ALLMULTI;
1032 UDAV_SETBIT(sc, UDAV_RCR, UDAV_RCR_ALL);
1033 UDAV_CLRBIT(sc, UDAV_RCR, UDAV_RCR_PRMSC);
1034 return;
1035 }
1036
1037 /* first, zot all the existing hash bits */
1038 memset(hashes, 0x00, sizeof(hashes));
1039 hashes[7] |= 0x80; /* broadcast address */
1040 udav_csr_write(sc, UDAV_MAR, hashes, sizeof(hashes));
1041
1042 /* now program new ones */
1043 #if defined(__NetBSD__)
1044 ETHER_FIRST_MULTI(step, &sc->sc_ec, enm);
1045 while (enm != NULL) {
1046 if (memcmp(enm->enm_addrlo, enm->enm_addrhi,
1047 ETHER_ADDR_LEN) != 0)
1048 goto allmulti;
1049
1050 h = UDAV_CALCHASH(enm->enm_addrlo);
1051 hashes[h>>3] |= 1 << (h & 0x7);
1052 ETHER_NEXT_MULTI(step, enm);
1053 }
1054 #elif defined(__FreeBSD__)
1055 IF_ADDR_LOCK(ifp);
1056 TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link)
1057 {
1058 if (ifma->ifma_addr->sa_family != AF_LINK)
1059 continue;
1060 h = UDAV_CALCHASH(LLADDR((struct sockaddr_dl *)
1061 ifma->ifma_addr));
1062 hashes[h>>3] |= 1 << (h & 0x7);
1063 }
1064 IF_ADDR_UNLOCK(ifp);
1065 #endif
1066
1067 /* disable all multicast */
1068 ifp->if_flags &= ~IFF_ALLMULTI;
1069 UDAV_CLRBIT(sc, UDAV_RCR, UDAV_RCR_ALL);
1070
1071 /* write hash value to the register */
1072 udav_csr_write(sc, UDAV_MAR, hashes, sizeof(hashes));
1073 }
1074
1075 Static int
1076 udav_openpipes(struct udav_softc *sc)
1077 {
1078 struct ue_chain *c;
1079 usbd_status err;
1080 int i;
1081 int error = 0;
1082
1083 if (sc->sc_dying)
1084 return (EIO);
1085
1086 sc->sc_refcnt++;
1087
1088 /* Open RX pipe */
1089 err = usbd_open_pipe(sc->sc_ctl_iface, sc->sc_bulkin_no,
1090 USBD_EXCLUSIVE_USE, &sc->sc_pipe_rx);
1091 if (err) {
1092 printf("%s: open rx pipe failed: %s\n",
1093 USBDEVNAME(sc->sc_dev), usbd_errstr(err));
1094 error = EIO;
1095 goto done;
1096 }
1097
1098 /* Open TX pipe */
1099 err = usbd_open_pipe(sc->sc_ctl_iface, sc->sc_bulkout_no,
1100 USBD_EXCLUSIVE_USE, &sc->sc_pipe_tx);
1101 if (err) {
1102 printf("%s: open tx pipe failed: %s\n",
1103 USBDEVNAME(sc->sc_dev), usbd_errstr(err));
1104 error = EIO;
1105 goto done;
1106 }
1107
1108 #if 0
1109 /* XXX: interrupt endpoint is not yet supported */
1110 /* Open Interrupt pipe */
1111 err = usbd_open_pipe_intr(sc->sc_ctl_iface, sc->sc_intrin_no,
1112 USBD_EXCLUSIVE_USE, &sc->sc_pipe_intr, sc,
1113 &sc->sc_cdata.ue_ibuf, UDAV_INTR_PKGLEN,
1114 udav_intr, UDAV_INTR_INTERVAL);
1115 if (err) {
1116 printf("%s: open intr pipe failed: %s\n",
1117 USBDEVNAME(sc->sc_dev), usbd_errstr(err));
1118 error = EIO;
1119 goto done;
1120 }
1121 #endif
1122
1123
1124 /* Start up the receive pipe. */
1125 for (i = 0; i < UE_RX_LIST_CNT; i++) {
1126 c = &sc->sc_cdata.ue_rx_chain[i];
1127 usbd_setup_xfer(c->ue_xfer, sc->sc_pipe_rx,
1128 c, c->ue_buf, UE_BUFSZ,
1129 USBD_SHORT_XFER_OK | USBD_NO_COPY,
1130 USBD_NO_TIMEOUT, udav_rxeof);
1131 (void)usbd_transfer(c->ue_xfer);
1132 DPRINTF(("%s: %s: start read\n", USBDEVNAME(sc->sc_dev),
1133 __func__));
1134 }
1135
1136 done:
1137 if (--sc->sc_refcnt < 0)
1138 usb_detach_wakeup(USBDEV(sc->sc_dev));
1139
1140 return (error);
1141 }
1142
1143 Static void
1144 udav_start(struct ifnet *ifp)
1145 {
1146 struct udav_softc *sc = ifp->if_softc;
1147 struct mbuf *m_head = NULL;
1148
1149 DPRINTF(("%s: %s: enter, link=%d\n", USBDEVNAME(sc->sc_dev),
1150 __func__, sc->sc_link));
1151
1152 if (sc->sc_dying)
1153 return;
1154
1155 if (!sc->sc_link)
1156 return;
1157
1158 #if defined(__FreeBSD__)
1159 if (ifp->if_drv_flags & IFF_DRV_OACTIVE)
1160 #else
1161 if (ifp->if_flags & IFF_OACTIVE)
1162 #endif
1163 return;
1164 #if defined(__NetBSD__)
1165 IFQ_POLL(&ifp->if_snd, m_head);
1166 #elif defined(__FreeBSD__)
1167 IF_DEQUEUE(&ifp->if_snd, m_head);
1168 #endif
1169 if (m_head == NULL)
1170 return;
1171
1172 if (udav_send(sc, m_head, 0)) {
1173 #if defined(__FreeBSD__)
1174 IF_PREPEND(&ifp->if_snd, m_head);
1175 ifp->if_drv_flags |= IFF_DRV_OACTIVE;
1176 #else
1177 ifp->if_flags |= IFF_OACTIVE;
1178 #endif
1179 return;
1180 }
1181
1182 #if defined(__NetBSD__)
1183 IFQ_DEQUEUE(&ifp->if_snd, m_head);
1184 #endif
1185
1186 #if NBPFILTER > 0
1187 BPF_MTAP(ifp, m_head);
1188 #endif
1189
1190 #if defined(__FreeBSD__)
1191 ifp->if_drv_flags |= IFF_DRV_OACTIVE;
1192 #else
1193 ifp->if_flags |= IFF_OACTIVE;
1194 #endif
1195
1196 /* Set a timeout in case the chip goes out to lunch. */
1197 ifp->if_timer = 5;
1198 }
1199
1200 Static int
1201 udav_send(struct udav_softc *sc, struct mbuf *m, int idx)
1202 {
1203 int total_len;
1204 struct ue_chain *c;
1205 usbd_status err;
1206
1207 DPRINTF(("%s: %s: enter\n", USBDEVNAME(sc->sc_dev),__func__));
1208
1209 c = &sc->sc_cdata.ue_tx_chain[idx];
1210
1211 /* Copy the mbuf data into a contiguous buffer */
1212 /* first 2 bytes are packet length */
1213 m_copydata(m, 0, m->m_pkthdr.len, c->ue_buf + 2);
1214 c->ue_mbuf = m;
1215 total_len = m->m_pkthdr.len;
1216 if (total_len < UDAV_MIN_FRAME_LEN) {
1217 memset(c->ue_buf + 2 + total_len, 0,
1218 UDAV_MIN_FRAME_LEN - total_len);
1219 total_len = UDAV_MIN_FRAME_LEN;
1220 }
1221
1222 /* Frame length is specified in the first 2bytes of the buffer */
1223 c->ue_buf[0] = (u_int8_t)total_len;
1224 c->ue_buf[1] = (u_int8_t)(total_len >> 8);
1225 total_len += 2;
1226
1227 usbd_setup_xfer(c->ue_xfer, sc->sc_pipe_tx, c, c->ue_buf, total_len,
1228 USBD_FORCE_SHORT_XFER | USBD_NO_COPY,
1229 UDAV_TX_TIMEOUT, udav_txeof);
1230
1231 /* Transmit */
1232 sc->sc_refcnt++;
1233 err = usbd_transfer(c->ue_xfer);
1234 if (--sc->sc_refcnt < 0)
1235 usb_detach_wakeup(USBDEV(sc->sc_dev));
1236 if (err != USBD_IN_PROGRESS) {
1237 printf("%s: udav_send error=%s\n", USBDEVNAME(sc->sc_dev),
1238 usbd_errstr(err));
1239 /* Stop the interface */
1240 usb_add_task(sc->sc_udev, &sc->sc_stop_task);
1241 return (EIO);
1242 }
1243
1244 DPRINTF(("%s: %s: send %d bytes\n", USBDEVNAME(sc->sc_dev),
1245 __func__, total_len));
1246
1247 sc->sc_cdata.ue_tx_cnt++;
1248
1249 return (0);
1250 }
1251
1252 Static void
1253 udav_txeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)
1254 {
1255 struct ue_chain *c = priv;
1256 struct udav_softc *sc = c->ue_sc;
1257 struct ifnet *ifp = GET_IFP(sc);
1258 #if defined(__NetBSD__)
1259 int s;
1260 #endif
1261
1262 if (sc->sc_dying)
1263 return;
1264
1265 #if defined(__NetBSD__)
1266 s = splnet();
1267 #elif defined(__FreeBSD__)
1268 UDAV_LOCK(sc);
1269 #endif
1270
1271 DPRINTF(("%s: %s: enter\n", USBDEVNAME(sc->sc_dev), __func__));
1272
1273 ifp->if_timer = 0;
1274 #if defined(__FreeBSD__)
1275 ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
1276 #else
1277 ifp->if_flags &= ~IFF_OACTIVE;
1278 #endif
1279
1280 if (status != USBD_NORMAL_COMPLETION) {
1281 if (status == USBD_NOT_STARTED || status == USBD_CANCELLED) {
1282 #if defined(__NetBSD__)
1283 splx(s);
1284 #elif defined(__FreeBSD__)
1285 UDAV_UNLOCK(sc);
1286 #endif
1287 return;
1288 }
1289 ifp->if_oerrors++;
1290 printf("%s: usb error on tx: %s\n", USBDEVNAME(sc->sc_dev),
1291 usbd_errstr(status));
1292 if (status == USBD_STALLED) {
1293 sc->sc_refcnt++;
1294 usbd_clear_endpoint_stall(sc->sc_pipe_tx);
1295 if (--sc->sc_refcnt < 0)
1296 usb_detach_wakeup(USBDEV(sc->sc_dev));
1297 }
1298 #if defined(__NetBSD__)
1299 splx(s);
1300 #elif defined(__FreeBSD__)
1301 UDAV_UNLOCK(sc);
1302 #endif
1303 return;
1304 }
1305
1306 ifp->if_opackets++;
1307
1308 m_freem(c->ue_mbuf);
1309 c->ue_mbuf = NULL;
1310
1311 #if defined(__NetBSD__)
1312 if (IFQ_IS_EMPTY(&ifp->if_snd) == 0)
1313 #elif defined(__FreeBSD__)
1314 if ( ifp->if_snd.ifq_head != NULL )
1315 #endif
1316 udav_start(ifp);
1317
1318 #if defined(__NetBSD__)
1319 splx(s);
1320 #elif defined(__FreeBSD__)
1321 UDAV_UNLOCK(sc);
1322 #endif
1323 }
1324
1325 Static void
1326 udav_rxeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)
1327 {
1328 struct ue_chain *c = priv;
1329 struct udav_softc *sc = c->ue_sc;
1330 struct ifnet *ifp = GET_IFP(sc);
1331 struct mbuf *m;
1332 u_int32_t total_len;
1333 u_int8_t *pktstat;
1334 #if defined(__NetBSD__)
1335 int s;
1336 #endif
1337
1338 DPRINTF(("%s: %s: enter\n", USBDEVNAME(sc->sc_dev),__func__));
1339
1340 if (sc->sc_dying)
1341 return;
1342
1343 if (status != USBD_NORMAL_COMPLETION) {
1344 if (status == USBD_NOT_STARTED || status == USBD_CANCELLED)
1345 return;
1346 sc->sc_rx_errs++;
1347 if (usbd_ratecheck(&sc->sc_rx_notice)) {
1348 printf("%s: %u usb errors on rx: %s\n",
1349 USBDEVNAME(sc->sc_dev), sc->sc_rx_errs,
1350 usbd_errstr(status));
1351 sc->sc_rx_errs = 0;
1352 }
1353 if (status == USBD_STALLED) {
1354 sc->sc_refcnt++;
1355 usbd_clear_endpoint_stall(sc->sc_pipe_rx);
1356 if (--sc->sc_refcnt < 0)
1357 usb_detach_wakeup(USBDEV(sc->sc_dev));
1358 }
1359 goto done;
1360 }
1361
1362 usbd_get_xfer_status(xfer, NULL, NULL, &total_len, NULL);
1363
1364 /* copy data to mbuf */
1365 m = c->ue_mbuf;
1366 memcpy(mtod(m, char *), c->ue_buf, total_len);
1367
1368 /* first byte in received data */
1369 pktstat = mtod(m, u_int8_t *);
1370 m_adj(m, sizeof(u_int8_t));
1371 DPRINTF(("%s: RX Status: 0x%02x\n", USBDEVNAME(sc->sc_dev), *pktstat));
1372
1373 total_len = UGETW(mtod(m, u_int8_t *));
1374 m_adj(m, sizeof(u_int16_t));
1375
1376 if (*pktstat & UDAV_RSR_LCS) {
1377 ifp->if_collisions++;
1378 goto done;
1379 }
1380
1381 if (total_len < sizeof(struct ether_header) ||
1382 *pktstat & UDAV_RSR_ERR) {
1383 ifp->if_ierrors++;
1384 goto done;
1385 }
1386
1387 ifp->if_ipackets++;
1388 total_len -= ETHER_CRC_LEN;
1389
1390 m->m_pkthdr.len = m->m_len = total_len;
1391 #if defined(__NetBSD__)
1392 m->m_pkthdr.rcvif = ifp;
1393 #elif defined(__FreeBSD__)
1394 m->m_pkthdr.rcvif = (struct ifnet *)&sc->sc_qdat;
1395 #endif
1396
1397 #if defined(__NetBSD__)
1398 s = splnet();
1399 #elif defined(__FreeBSD__)
1400 UDAV_LOCK(sc);
1401 #endif
1402
1403 #if defined(__NetBSD__)
1404 c->ue_mbuf = usb_ether_newbuf();
1405 if (c->ue_mbuf == NULL) {
1406 printf("%s: no memory for rx list "
1407 "-- packet dropped!\n", USBDEVNAME(sc->sc_dev));
1408 ifp->if_ierrors++;
1409 goto done1;
1410 }
1411 #endif
1412
1413 #if NBPFILTER > 0
1414 BPF_MTAP(ifp, m);
1415 #endif
1416
1417 DPRINTF(("%s: %s: deliver %d\n", USBDEVNAME(sc->sc_dev),
1418 __func__, m->m_len));
1419 #if defined(__NetBSD__)
1420 IF_INPUT(ifp, m);
1421 #endif
1422 #if defined(__FreeBSD__)
1423 usb_ether_input(m);
1424 UDAV_UNLOCK(sc);
1425 return ;
1426 #endif
1427
1428 #if defined(__NetBSD__)
1429 done1:
1430 splx(s);
1431 #elif defined(__FreeBSD__)
1432 UDAV_UNLOCK(sc);
1433 #endif
1434 done:
1435 /* Setup new transfer */
1436 usbd_setup_xfer(xfer, sc->sc_pipe_rx, c, c->ue_buf, UE_BUFSZ,
1437 USBD_SHORT_XFER_OK | USBD_NO_COPY,
1438 USBD_NO_TIMEOUT, udav_rxeof);
1439 sc->sc_refcnt++;
1440 usbd_transfer(xfer);
1441 if (--sc->sc_refcnt < 0)
1442 usb_detach_wakeup(USBDEV(sc->sc_dev));
1443
1444 DPRINTF(("%s: %s: start rx\n", USBDEVNAME(sc->sc_dev), __func__));
1445 }
1446
1447 #if 0
1448 Static void udav_intr()
1449 {
1450 }
1451 #endif
1452
1453 Static int
1454 udav_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
1455 {
1456 struct udav_softc *sc = ifp->if_softc;
1457 struct ifreq *ifr = (struct ifreq *)data;
1458 struct mii_data *mii;
1459 #if defined(__NetBSD__)
1460 int s;
1461 #endif
1462 int error = 0;
1463
1464 DPRINTF(("%s: %s: enter\n", USBDEVNAME(sc->sc_dev), __func__));
1465
1466 if (sc->sc_dying)
1467 return (EIO);
1468
1469 #if defined(__NetBSD__)
1470 s = splnet();
1471 #elif defined(__FreeBSD__)
1472 UDAV_LOCK(sc);
1473 #endif
1474
1475 switch (cmd) {
1476 #if defined(__FreeBSD__)
1477 case SIOCSIFFLAGS:
1478 if (ifp->if_flags & IFF_UP) {
1479 if (ifp->if_drv_flags & IFF_DRV_RUNNING &&
1480 ifp->if_flags & IFF_PROMISC) {
1481 UDAV_SETBIT(sc, UDAV_RCR,
1482 UDAV_RCR_ALL|UDAV_RCR_PRMSC);
1483 } else if (ifp->if_drv_flags & IFF_DRV_RUNNING &&
1484 !(ifp->if_flags & IFF_PROMISC)) {
1485 if (ifp->if_flags & IFF_ALLMULTI)
1486 UDAV_CLRBIT(sc, UDAV_RCR,
1487 UDAV_RCR_PRMSC);
1488 else
1489 UDAV_CLRBIT(sc, UDAV_RCR,
1490 UDAV_RCR_ALL|UDAV_RCR_PRMSC);
1491 } else if (!(ifp->if_drv_flags & IFF_DRV_RUNNING))
1492 udav_init(sc);
1493 } else {
1494 if (ifp->if_drv_flags & IFF_DRV_RUNNING)
1495 udav_stop(ifp, 1);
1496 }
1497 error = 0;
1498 break;
1499 case SIOCADDMULTI:
1500 case SIOCDELMULTI:
1501 udav_setmulti(sc);
1502 error = 0;
1503 break;
1504 #endif
1505 case SIOCGIFMEDIA:
1506 case SIOCSIFMEDIA:
1507 mii = GET_MII(sc);
1508 error = ifmedia_ioctl(ifp, ifr, &mii->mii_media, cmd);
1509 break;
1510
1511 default:
1512 error = ether_ioctl(ifp, cmd, data);
1513 #if defined(__NetBSD__)
1514 if (error == ENETRESET) {
1515 udav_setmulti(sc);
1516 error = 0;
1517 }
1518 #endif
1519 break;
1520 }
1521
1522 #if defined(__NetBSD__)
1523 splx(s);
1524 #elif defined(__FreeBSD__)
1525 UDAV_UNLOCK(sc);
1526 #endif
1527
1528 return (error);
1529 }
1530
1531 Static void
1532 udav_watchdog(struct ifnet *ifp)
1533 {
1534 struct udav_softc *sc = ifp->if_softc;
1535 struct ue_chain *c;
1536 usbd_status stat;
1537 #if defined(__NetBSD__)
1538 int s;
1539 #endif
1540
1541 DPRINTF(("%s: %s: enter\n", USBDEVNAME(sc->sc_dev), __func__));
1542
1543 ifp->if_oerrors++;
1544 printf("%s: watchdog timeout\n", USBDEVNAME(sc->sc_dev));
1545
1546 #if defined(__NetBSD__)
1547 s = splusb();
1548 #elif defined(__FreeBSD__)
1549 UDAV_LOCK(sc)
1550 #endif
1551 c = &sc->sc_cdata.ue_tx_chain[0];
1552 usbd_get_xfer_status(c->ue_xfer, NULL, NULL, NULL, &stat);
1553 udav_txeof(c->ue_xfer, c, stat);
1554
1555 #if defined(__NetBSD__)
1556 if (IFQ_IS_EMPTY(&ifp->if_snd) == 0)
1557 #elif defined(__FreeBSD__)
1558 if ( ifp->if_snd.ifq_head != NULL )
1559 #endif
1560 udav_start(ifp);
1561 #if defined(__NetBSD__)
1562 splx(s);
1563 #elif defined(__FreeBSD__)
1564 UDAV_UNLOCK(sc);
1565 #endif
1566 }
1567
1568 Static void
1569 udav_stop_task(struct udav_softc *sc)
1570 {
1571 udav_stop(GET_IFP(sc), 1);
1572 }
1573
1574 /* Stop the adapter and free any mbufs allocated to the RX and TX lists. */
1575 Static void
1576 udav_stop(struct ifnet *ifp, int disable)
1577 {
1578 struct udav_softc *sc = ifp->if_softc;
1579 usbd_status err;
1580
1581 DPRINTF(("%s: %s: enter\n", USBDEVNAME(sc->sc_dev), __func__));
1582
1583 ifp->if_timer = 0;
1584
1585 udav_reset(sc);
1586
1587 usb_uncallout(sc->sc_stat_ch, udav_tick, sc);
1588
1589 /* Stop transfers */
1590 /* RX endpoint */
1591 if (sc->sc_pipe_rx != NULL) {
1592 err = usbd_abort_pipe(sc->sc_pipe_rx);
1593 if (err)
1594 printf("%s: abort rx pipe failed: %s\n",
1595 USBDEVNAME(sc->sc_dev), usbd_errstr(err));
1596 err = usbd_close_pipe(sc->sc_pipe_rx);
1597 if (err)
1598 printf("%s: close rx pipe failed: %s\n",
1599 USBDEVNAME(sc->sc_dev), usbd_errstr(err));
1600 sc->sc_pipe_rx = NULL;
1601 }
1602
1603 /* TX endpoint */
1604 if (sc->sc_pipe_tx != NULL) {
1605 err = usbd_abort_pipe(sc->sc_pipe_tx);
1606 if (err)
1607 printf("%s: abort tx pipe failed: %s\n",
1608 USBDEVNAME(sc->sc_dev), usbd_errstr(err));
1609 err = usbd_close_pipe(sc->sc_pipe_tx);
1610 if (err)
1611 printf("%s: close tx pipe failed: %s\n",
1612 USBDEVNAME(sc->sc_dev), usbd_errstr(err));
1613 sc->sc_pipe_tx = NULL;
1614 }
1615
1616 #if 0
1617 /* XXX: Interrupt endpoint is not yet supported!! */
1618 /* Interrupt endpoint */
1619 if (sc->sc_pipe_intr != NULL) {
1620 err = usbd_abort_pipe(sc->sc_pipe_intr);
1621 if (err)
1622 printf("%s: abort intr pipe failed: %s\n",
1623 USBDEVNAME(sc->sc_dev), usbd_errstr(err));
1624 err = usbd_close_pipe(sc->sc_pipe_intr);
1625 if (err)
1626 printf("%s: close intr pipe failed: %s\n",
1627 USBDEVNAME(sc->sc_dev), usbd_errstr(err));
1628 sc->sc_pipe_intr = NULL;
1629 }
1630 #endif
1631
1632 /* Free RX resources. */
1633 usb_ether_rx_list_free(&sc->sc_cdata);
1634 /* Free TX resources. */
1635 usb_ether_tx_list_free(&sc->sc_cdata);
1636
1637 sc->sc_link = 0;
1638 #if defined(__FreeBSD__)
1639 ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
1640 #else
1641 ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE);
1642 #endif
1643 }
1644
1645 /* Set media options */
1646 Static int
1647 udav_ifmedia_change(struct ifnet *ifp)
1648 {
1649 struct udav_softc *sc = ifp->if_softc;
1650 struct mii_data *mii = GET_MII(sc);
1651
1652 DPRINTF(("%s: %s: enter\n", USBDEVNAME(sc->sc_dev), __func__));
1653
1654 if (sc->sc_dying)
1655 return (0);
1656
1657 sc->sc_link = 0;
1658 if (mii->mii_instance) {
1659 struct mii_softc *miisc;
1660 for (miisc = LIST_FIRST(&mii->mii_phys); miisc != NULL;
1661 miisc = LIST_NEXT(miisc, mii_list))
1662 mii_phy_reset(miisc);
1663 }
1664
1665 return (mii_mediachg(mii));
1666 }
1667
1668 /* Report current media status. */
1669 Static void
1670 udav_ifmedia_status(struct ifnet *ifp, struct ifmediareq *ifmr)
1671 {
1672 struct udav_softc *sc = ifp->if_softc;
1673 struct mii_data *mii = GET_MII(sc);
1674
1675 DPRINTF(("%s: %s: enter\n", USBDEVNAME(sc->sc_dev), __func__));
1676
1677 if (sc->sc_dying)
1678 return;
1679
1680 #if defined(__FreeBSD__)
1681 if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) {
1682 #else
1683 if ((ifp->if_flags & IFF_RUNNING) == 0) {
1684 #endif
1685 ifmr->ifm_active = IFM_ETHER | IFM_NONE;
1686 ifmr->ifm_status = 0;
1687 return;
1688 }
1689
1690 mii_pollstat(mii);
1691 ifmr->ifm_active = mii->mii_media_active;
1692 ifmr->ifm_status = mii->mii_media_status;
1693 }
1694
1695 Static void
1696 udav_tick(void *xsc)
1697 {
1698 struct udav_softc *sc = xsc;
1699
1700 if (sc == NULL)
1701 return;
1702
1703 DPRINTFN(0xff, ("%s: %s: enter\n", USBDEVNAME(sc->sc_dev),
1704 __func__));
1705
1706 if (sc->sc_dying)
1707 return;
1708
1709 /* Perform periodic stuff in process context */
1710 usb_add_task(sc->sc_udev, &sc->sc_tick_task);
1711 }
1712
1713 Static void
1714 udav_tick_task(void *xsc)
1715 {
1716 struct udav_softc *sc = xsc;
1717 struct ifnet *ifp;
1718 struct mii_data *mii;
1719 #if defined(__NetBSD__)
1720 int s;
1721 #endif
1722
1723 if (sc == NULL)
1724 return;
1725
1726 DPRINTFN(0xff, ("%s: %s: enter\n", USBDEVNAME(sc->sc_dev),
1727 __func__));
1728
1729 if (sc->sc_dying)
1730 return;
1731
1732 ifp = GET_IFP(sc);
1733 mii = GET_MII(sc);
1734
1735 if (mii == NULL)
1736 return;
1737
1738 #if defined(__NetBSD__)
1739 s = splnet();
1740 #elif defined(__FreeBSD__)
1741 UDAV_LOCK(sc);
1742 #endif
1743
1744 mii_tick(mii);
1745 if (!sc->sc_link) {
1746 mii_pollstat(mii);
1747 if (mii->mii_media_status & IFM_ACTIVE &&
1748 IFM_SUBTYPE(mii->mii_media_active) != IFM_NONE) {
1749 DPRINTF(("%s: %s: got link\n",
1750 USBDEVNAME(sc->sc_dev), __func__));
1751 sc->sc_link++;
1752 #if defined(__NetBSD__)
1753 if (IFQ_IS_EMPTY(&ifp->if_snd) == 0)
1754 #elif defined(__FreeBSD__)
1755 if ( ifp->if_snd.ifq_head != NULL )
1756 #endif
1757 udav_start(ifp);
1758 }
1759 }
1760
1761 usb_callout(sc->sc_stat_ch, hz, udav_tick, sc);
1762
1763 #if defined(__NetBSD__)
1764 splx(s);
1765 #elif defined(__FreeBSD__)
1766 UDAV_UNLOCK(sc);
1767 #endif
1768 }
1769
1770 /* Get exclusive access to the MII registers */
1771 Static void
1772 udav_lock_mii(struct udav_softc *sc)
1773 {
1774 DPRINTFN(0xff, ("%s: %s: enter\n", USBDEVNAME(sc->sc_dev),
1775 __func__));
1776
1777 sc->sc_refcnt++;
1778 #if defined(__NetBSD__)
1779 lockmgr(&sc->sc_mii_lock, LK_EXCLUSIVE, NULL);
1780 #elif defined(__FreeBSD__)
1781 lockmgr(&sc->sc_mii_lock, LK_EXCLUSIVE, NULL, NULL);
1782 #endif
1783 }
1784
1785 Static void
1786 udav_unlock_mii(struct udav_softc *sc)
1787 {
1788 DPRINTFN(0xff, ("%s: %s: enter\n", USBDEVNAME(sc->sc_dev),
1789 __func__));
1790
1791 #if defined(__NetBSD__)
1792 lockmgr(&sc->sc_mii_lock, LK_RELEASE, NULL);
1793 #elif defined(__FreeBSD__)
1794 lockmgr(&sc->sc_mii_lock, LK_RELEASE, NULL, NULL);
1795 #endif
1796 if (--sc->sc_refcnt < 0)
1797 usb_detach_wakeup(USBDEV(sc->sc_dev));
1798 }
1799
1800 Static int
1801 udav_miibus_readreg(device_ptr_t dev, int phy, int reg)
1802 {
1803 struct udav_softc *sc;
1804 u_int8_t val[2];
1805 u_int16_t data16;
1806
1807 if (dev == NULL)
1808 return (0);
1809
1810 sc = USBGETSOFTC(dev);
1811
1812 DPRINTFN(0xff, ("%s: %s: enter, phy=%d reg=0x%04x\n",
1813 USBDEVNAME(sc->sc_dev), __func__, phy, reg));
1814
1815 if (sc->sc_dying) {
1816 #ifdef DIAGNOSTIC
1817 printf("%s: %s: dying\n", USBDEVNAME(sc->sc_dev),
1818 __func__);
1819 #endif
1820 return (0);
1821 }
1822
1823 /* XXX: one PHY only for the internal PHY */
1824 if (phy != 0) {
1825 DPRINTFN(0xff, ("%s: %s: phy=%d is not supported\n",
1826 USBDEVNAME(sc->sc_dev), __func__, phy));
1827 return (0);
1828 }
1829
1830 udav_lock_mii(sc);
1831
1832 /* select internal PHY and set PHY register address */
1833 udav_csr_write1(sc, UDAV_EPAR,
1834 UDAV_EPAR_PHY_ADR0 | (reg & UDAV_EPAR_EROA_MASK));
1835
1836 /* select PHY operation and start read command */
1837 udav_csr_write1(sc, UDAV_EPCR, UDAV_EPCR_EPOS | UDAV_EPCR_ERPRR);
1838
1839 /* XXX: should be wait? */
1840
1841 /* end read command */
1842 UDAV_CLRBIT(sc, UDAV_EPCR, UDAV_EPCR_ERPRR);
1843
1844 /* retrieve the result from data registers */
1845 udav_csr_read(sc, UDAV_EPDRL, val, 2);
1846
1847 udav_unlock_mii(sc);
1848
1849 data16 = val[0] | (val[1] << 8);
1850
1851 DPRINTFN(0xff, ("%s: %s: phy=%d reg=0x%04x => 0x%04x\n",
1852 USBDEVNAME(sc->sc_dev), __func__, phy, reg, data16));
1853
1854 return (data16);
1855 }
1856
1857 Static void
1858 udav_miibus_writereg(device_ptr_t dev, int phy, int reg, int data)
1859 {
1860 struct udav_softc *sc;
1861 u_int8_t val[2];
1862
1863 if (dev == NULL)
1864 return;
1865
1866 sc = USBGETSOFTC(dev);
1867
1868 DPRINTFN(0xff, ("%s: %s: enter, phy=%d reg=0x%04x data=0x%04x\n",
1869 USBDEVNAME(sc->sc_dev), __func__, phy, reg, data));
1870
1871 if (sc->sc_dying) {
1872 #ifdef DIAGNOSTIC
1873 printf("%s: %s: dying\n", USBDEVNAME(sc->sc_dev),
1874 __func__);
1875 #endif
1876 return;
1877 }
1878
1879 /* XXX: one PHY only for the internal PHY */
1880 if (phy != 0) {
1881 DPRINTFN(0xff, ("%s: %s: phy=%d is not supported\n",
1882 USBDEVNAME(sc->sc_dev), __func__, phy));
1883 return;
1884 }
1885
1886 udav_lock_mii(sc);
1887
1888 /* select internal PHY and set PHY register address */
1889 udav_csr_write1(sc, UDAV_EPAR,
1890 UDAV_EPAR_PHY_ADR0 | (reg & UDAV_EPAR_EROA_MASK));
1891
1892 /* put the value to the data registers */
1893 val[0] = data & 0xff;
1894 val[1] = (data >> 8) & 0xff;
1895 udav_csr_write(sc, UDAV_EPDRL, val, 2);
1896
1897 /* select PHY operation and start write command */
1898 udav_csr_write1(sc, UDAV_EPCR, UDAV_EPCR_EPOS | UDAV_EPCR_ERPRW);
1899
1900 /* XXX: should be wait? */
1901
1902 /* end write command */
1903 UDAV_CLRBIT(sc, UDAV_EPCR, UDAV_EPCR_ERPRW);
1904
1905 udav_unlock_mii(sc);
1906
1907 return;
1908 }
1909
1910 Static void
1911 udav_miibus_statchg(device_ptr_t dev)
1912 {
1913 #ifdef UDAV_DEBUG
1914 struct udav_softc *sc;
1915
1916 if (dev == NULL)
1917 return;
1918
1919 sc = USBGETSOFTC(dev);
1920 DPRINTF(("%s: %s: enter\n", USBDEVNAME(sc->sc_dev), __func__));
1921 #endif
1922 /* Nothing to do */
1923 }
1924
1925 #if defined(__FreeBSD__)
1926 /*
1927 * Stop all chip I/O so that the kernel's probe routines don't
1928 * get confused by errant DMAs when rebooting.
1929 */
1930 Static void
1931 udav_shutdown(device_ptr_t dev)
1932 {
1933 struct udav_softc *sc;
1934
1935 sc = device_get_softc(dev);
1936
1937 udav_stop_task(sc);
1938
1939 return;
1940 }
1941
1942 Static void
1943 udav_rxstart(struct ifnet *ifp)
1944 {
1945 struct udav_softc *sc;
1946 struct ue_chain *c;
1947
1948 sc = ifp->if_softc;
1949 UDAV_LOCK(sc);
1950 c = &sc->sc_cdata.ue_rx_chain[sc->sc_cdata.ue_rx_prod];
1951
1952 c->ue_mbuf = usb_ether_newbuf();
1953 if (c->ue_mbuf == NULL) {
1954 printf("%s: no memory for rx list "
1955 "-- packet dropped!\n", USBDEVNAME(sc->sc_dev));
1956 ifp->if_ierrors++;
1957 UDAV_UNLOCK(sc);
1958 return;
1959 }
1960
1961 /* Setup new transfer. */
1962 usbd_setup_xfer(c->ue_xfer, sc->sc_pipe_rx,
1963 c, c->ue_buf, UE_BUFSZ,
1964 USBD_SHORT_XFER_OK | USBD_NO_COPY,
1965 USBD_NO_TIMEOUT, udav_rxeof);
1966 usbd_transfer(c->ue_xfer);
1967
1968 UDAV_UNLOCK(sc);
1969 return;
1970 }
1971 #endif
Cache object: 09f2801034ca734967c0d384880229ad
|