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

Cache object: 62db4c6f5bce34bb53bdc31677d4515f


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