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