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


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