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

Cache object: d90979de20f90772290c8e3d1c633eeb


[ 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.