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

Cache object: 5f52ad825a4437153a1c1c9e5fbe1c85


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