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