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

Cache object: 97cbcc97bec136af8d8cc4b616378dc0


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