root/dev/usb/if_udav.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. udav_match
  2. udav_attach
  3. udav_detach
  4. udav_mem_read
  5. udav_mem_write
  6. udav_mem_write1
  7. udav_csr_read
  8. udav_csr_write
  9. udav_csr_read1
  10. udav_csr_write1
  11. udav_init
  12. udav_reset
  13. udav_activate
  14. udav_setmulti
  15. udav_openpipes
  16. udav_newbuf
  17. udav_rx_list_init
  18. udav_tx_list_init
  19. udav_start
  20. udav_send
  21. udav_txeof
  22. udav_rxeof
  23. udav_intr
  24. udav_ioctl
  25. udav_watchdog
  26. udav_stop_task
  27. udav_stop
  28. udav_ifmedia_change
  29. udav_ifmedia_status
  30. udav_tick
  31. udav_tick_task
  32. udav_lock_mii
  33. udav_unlock_mii
  34. udav_miibus_readreg
  35. udav_miibus_writereg
  36. udav_miibus_statchg

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

/* [<][>][^][v][top][bottom][index][help] */