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

Cache object: e601b7c030d46653b91a7d557bc41dfa


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