[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/dev/usb/if_udav.c

Version: -  FREEBSD  -  FREEBSD8  -  FREEBSD7  -  FREEBSD72  -  FREEBSD71  -  FREEBSD70  -  FREEBSD6  -  FREEBSD64  -  FREEBSD63  -  FREEBSD62  -  FREEBSD61  -  FREEBSD60  -  FREEBSD5  -  FREEBSD55  -  FREEBSD54  -  FREEBSD53  -  FREEBSD52  -  FREEBSD51  -  FREEBSD50  -  FREEBSD4  -  FREEBSD3  -  FREEBSD22  -  linux-2.6  -  linux-2.4.22  -  MK83  -  MK84  -  PLAN9  -  DFBSD  -  NETBSD  -  NETBSD5  -  NETBSD4  -  NETBSD3  -  NETBSD20  -  OPENBSD  -  xnu-517  -  xnu-792  -  xnu-792.6.70  -  xnu-1228  -  xnu-1456.1.26  -  OPENSOLARIS  -  minix-3-1-1  -  FREEBSD-LIBC  -  FREEBSD7-LIBC  -  FREEBSD6-LIBC  -  GLIBC27 
SearchContext: -  none  -  excerpts  -  bigexcerpts 

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

Cache object: 09f2801034ca734967c0d384880229ad


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.