The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/dev/usb/if_rue.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*-
    2  * Copyright (c) 2001-2003, Shunsuke Akiyama <akiyama@FreeBSD.org>.
    3  * Copyright (c) 1997, 1998, 1999, 2000 Bill Paul <wpaul@ee.columbia.edu>.
    4  * All rights reserved.
    5  *
    6  * Redistribution and use in source and binary forms, with or without
    7  * modification, are permitted provided that the following conditions
    8  * are met:
    9  * 1. Redistributions of source code must retain the above copyright
   10  *    notice, this list of conditions and the following disclaimer.
   11  * 2. Redistributions in binary form must reproduce the above copyright
   12  *    notice, this list of conditions and the following disclaimer in the
   13  *    documentation and/or other materials provided with the distribution.
   14  *
   15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
   16  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   17  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   18  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
   19  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   20  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   21  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   22  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   23  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   24  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   25  * SUCH DAMAGE.
   26  */
   27 /*-
   28  * Copyright (c) 1997, 1998, 1999, 2000
   29  *      Bill Paul <wpaul@ee.columbia.edu>.  All rights reserved.
   30  *
   31  * Redistribution and use in source and binary forms, with or without
   32  * modification, are permitted provided that the following conditions
   33  * are met:
   34  * 1. Redistributions of source code must retain the above copyright
   35  *    notice, this list of conditions and the following disclaimer.
   36  * 2. Redistributions in binary form must reproduce the above copyright
   37  *    notice, this list of conditions and the following disclaimer in the
   38  *    documentation and/or other materials provided with the distribution.
   39  * 3. All advertising materials mentioning features or use of this software
   40  *    must display the following acknowledgement:
   41  *      This product includes software developed by Bill Paul.
   42  * 4. Neither the name of the author nor the names of any co-contributors
   43  *    may be used to endorse or promote products derived from this software
   44  *    without specific prior written permission.
   45  *
   46  * THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND
   47  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   48  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   49  * ARE DISCLAIMED.  IN NO EVENT SHALL Bill Paul OR THE VOICES IN HIS HEAD
   50  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
   51  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
   52  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
   53  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
   54  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   55  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
   56  * THE POSSIBILITY OF SUCH DAMAGE.
   57  */
   58 
   59 #include <sys/cdefs.h>
   60 __FBSDID("$FreeBSD: releng/7.3/sys/dev/usb/if_rue.c 171327 2007-07-09 16:58:07Z imp $");
   61 
   62 /*
   63  * RealTek RTL8150 USB to fast ethernet controller driver.
   64  * Datasheet is available from
   65  * ftp://ftp.realtek.com.tw/lancard/data_sheet/8150/.
   66  */
   67 
   68 #include <sys/param.h>
   69 #include <sys/systm.h>
   70 #include <sys/sockio.h>
   71 #include <sys/mbuf.h>
   72 #include <sys/malloc.h>
   73 #include <sys/kernel.h>
   74 #include <sys/module.h>
   75 #include <sys/socket.h>
   76 #include <sys/sysctl.h>
   77 
   78 #include <net/if.h>
   79 #include <net/if_arp.h>
   80 #include <net/ethernet.h>
   81 #include <net/if_dl.h>
   82 #include <net/if_media.h>
   83 #include <net/if_types.h>
   84 
   85 #include <net/bpf.h>
   86 
   87 #include <sys/bus.h>
   88 #include <machine/bus.h>
   89 
   90 #include <dev/usb/usb.h>
   91 #include <dev/usb/usbdi.h>
   92 #include <dev/usb/usbdi_util.h>
   93 #include <dev/usb/usbdivar.h>
   94 #include "usbdevs.h"
   95 #include <dev/usb/usb_ethersubr.h>
   96 
   97 #include <dev/mii/mii.h>
   98 #include <dev/mii/miivar.h>
   99 
  100 #include <dev/usb/if_ruereg.h>
  101 
  102 /* "device miibus" required.  See GENERIC if you get errors here. */
  103 #include "miibus_if.h"
  104 
  105 #ifdef USB_DEBUG
  106 static int      ruedebug = 0;
  107 SYSCTL_NODE(_hw_usb, OID_AUTO, rue, CTLFLAG_RW, 0, "USB rue");
  108 SYSCTL_INT(_hw_usb_rue, OID_AUTO, debug, CTLFLAG_RW,
  109            &ruedebug, 0, "rue debug level");
  110 
  111 #define DPRINTFN(n, x)  do { \
  112                                 if (ruedebug > (n)) \
  113                                         printf x; \
  114                         } while (0);
  115 #else
  116 #define DPRINTFN(n, x)
  117 #endif
  118 #define DPRINTF(x)      DPRINTFN(0, x)
  119 
  120 /*
  121  * Various supported device vendors/products.
  122  */
  123 
  124 static struct rue_type rue_devs[] = {
  125         { USB_VENDOR_MELCO, USB_PRODUCT_MELCO_LUAKTX },
  126         { USB_VENDOR_REALTEK, USB_PRODUCT_REALTEK_USBKR100 },
  127         { 0, 0 }
  128 };
  129 
  130 static device_probe_t rue_match;
  131 static device_attach_t rue_attach;
  132 static device_detach_t rue_detach;
  133 static device_shutdown_t rue_shutdown;
  134 static miibus_readreg_t rue_miibus_readreg;
  135 static miibus_writereg_t rue_miibus_writereg;
  136 static miibus_statchg_t rue_miibus_statchg;
  137 
  138 static int rue_encap(struct rue_softc *, struct mbuf *, int);
  139 #ifdef RUE_INTR_PIPE
  140 static void rue_intr(usbd_xfer_handle, usbd_private_handle, usbd_status);
  141 #endif
  142 static void rue_rxeof(usbd_xfer_handle, usbd_private_handle, usbd_status);
  143 static void rue_txeof(usbd_xfer_handle, usbd_private_handle, usbd_status);
  144 static void rue_tick(void *);
  145 static void rue_tick_task(void *);
  146 static void rue_rxstart(struct ifnet *);
  147 static void rue_start(struct ifnet *);
  148 static int rue_ioctl(struct ifnet *, u_long, caddr_t);
  149 static void rue_init(void *);
  150 static void rue_stop(struct rue_softc *);
  151 static void rue_watchdog(struct ifnet *);
  152 static int rue_ifmedia_upd(struct ifnet *);
  153 static void rue_ifmedia_sts(struct ifnet *, struct ifmediareq *);
  154 
  155 static void rue_setmulti(struct rue_softc *);
  156 static void rue_reset(struct rue_softc *);
  157 
  158 static int rue_read_mem(struct rue_softc *, u_int16_t, void *, u_int16_t);
  159 static int rue_write_mem(struct rue_softc *, u_int16_t, void *, u_int16_t);
  160 static int rue_csr_read_1(struct rue_softc *, int);
  161 static int rue_csr_write_1(struct rue_softc *, int, u_int8_t);
  162 static int rue_csr_read_2(struct rue_softc *, int);
  163 static int rue_csr_write_2(struct rue_softc *, int, u_int16_t);
  164 static int rue_csr_write_4(struct rue_softc *, int, u_int32_t);
  165 
  166 static device_method_t rue_methods[] = {
  167         /* Device interface */
  168         DEVMETHOD(device_probe, rue_match),
  169         DEVMETHOD(device_attach, rue_attach),
  170         DEVMETHOD(device_detach, rue_detach),
  171         DEVMETHOD(device_shutdown, rue_shutdown),
  172 
  173         /* Bus interface */
  174         DEVMETHOD(bus_print_child, bus_generic_print_child),
  175         DEVMETHOD(bus_driver_added, bus_generic_driver_added),
  176 
  177         /* MII interface */
  178         DEVMETHOD(miibus_readreg, rue_miibus_readreg),
  179         DEVMETHOD(miibus_writereg, rue_miibus_writereg),
  180         DEVMETHOD(miibus_statchg, rue_miibus_statchg),
  181 
  182         { 0, 0 }
  183 };
  184 
  185 static driver_t rue_driver = {
  186         "rue",
  187         rue_methods,
  188         sizeof(struct rue_softc)
  189 };
  190 
  191 static devclass_t rue_devclass;
  192 
  193 DRIVER_MODULE(rue, uhub, rue_driver, rue_devclass, usbd_driver_load, 0);
  194 DRIVER_MODULE(miibus, rue, miibus_driver, miibus_devclass, 0, 0);
  195 MODULE_DEPEND(rue, usb, 1, 1, 1);
  196 MODULE_DEPEND(rue, ether, 1, 1, 1);
  197 MODULE_DEPEND(rue, miibus, 1, 1, 1);
  198 
  199 #define RUE_SETBIT(sc, reg, x) \
  200         rue_csr_write_1(sc, reg, rue_csr_read_1(sc, reg) | (x))
  201 
  202 #define RUE_CLRBIT(sc, reg, x) \
  203         rue_csr_write_1(sc, reg, rue_csr_read_1(sc, reg) & ~(x))
  204 
  205 #define RUE_SETBIT_2(sc, reg, x) \
  206         rue_csr_write_2(sc, reg, rue_csr_read_2(sc, reg) | (x))
  207 
  208 #define RUE_CLRBIT_2(sc, reg, x) \
  209         rue_csr_write_2(sc, reg, rue_csr_read_2(sc, reg) & ~(x))
  210 
  211 static int
  212 rue_read_mem(struct rue_softc *sc, u_int16_t addr, void *buf, u_int16_t len)
  213 {
  214         usb_device_request_t    req;
  215         usbd_status             err;
  216 
  217         if (sc->rue_dying)
  218                 return (0);
  219 
  220         RUE_LOCK(sc);
  221 
  222         req.bmRequestType = UT_READ_VENDOR_DEVICE;
  223         req.bRequest = UR_SET_ADDRESS;
  224         USETW(req.wValue, addr);
  225         USETW(req.wIndex, 0);
  226         USETW(req.wLength, len);
  227 
  228         err = usbd_do_request(sc->rue_udev, &req, buf);
  229 
  230         RUE_UNLOCK(sc);
  231 
  232         if (err) {
  233                 device_printf(sc->rue_dev, "control pipe read failed: %s\n",
  234                     usbd_errstr(err));
  235                 return (-1);
  236         }
  237 
  238         return (0);
  239 }
  240 
  241 static int
  242 rue_write_mem(struct rue_softc *sc, u_int16_t addr, void *buf, u_int16_t len)
  243 {
  244         usb_device_request_t    req;
  245         usbd_status             err;
  246 
  247         if (sc->rue_dying)
  248                 return (0);
  249 
  250         RUE_LOCK(sc);
  251 
  252         req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
  253         req.bRequest = UR_SET_ADDRESS;
  254         USETW(req.wValue, addr);
  255         USETW(req.wIndex, 0);
  256         USETW(req.wLength, len);
  257 
  258         err = usbd_do_request(sc->rue_udev, &req, buf);
  259 
  260         RUE_UNLOCK(sc);
  261 
  262         if (err) {
  263                 device_printf(sc->rue_dev, "control pipe write failed: %s\n",
  264                     usbd_errstr(err));
  265                 return (-1);
  266         }
  267 
  268         return (0);
  269 }
  270 
  271 static int
  272 rue_csr_read_1(struct rue_softc *sc, int reg)
  273 {
  274         int             err;
  275         u_int8_t        val = 0;
  276 
  277         err = rue_read_mem(sc, reg, &val, 1);
  278 
  279         if (err)
  280                 return (0);
  281 
  282         return (val);
  283 }
  284 
  285 static int
  286 rue_csr_read_2(struct rue_softc *sc, int reg)
  287 {
  288         int             err;
  289         u_int16_t       val = 0;
  290         uWord           w;
  291 
  292         USETW(w, val);
  293         err = rue_read_mem(sc, reg, &w, 2);
  294         val = UGETW(w);
  295 
  296         if (err)
  297                 return (0);
  298 
  299         return (val);
  300 }
  301 
  302 static int
  303 rue_csr_write_1(struct rue_softc *sc, int reg, u_int8_t val)
  304 {
  305         int     err;
  306 
  307         err = rue_write_mem(sc, reg, &val, 1);
  308 
  309         if (err)
  310                 return (-1);
  311 
  312         return (0);
  313 }
  314 
  315 static int
  316 rue_csr_write_2(struct rue_softc *sc, int reg, u_int16_t val)
  317 {
  318         int     err;
  319         uWord   w;
  320 
  321         USETW(w, val);
  322         err = rue_write_mem(sc, reg, &w, 2);
  323 
  324         if (err)
  325                 return (-1);
  326 
  327         return (0);
  328 }
  329 
  330 static int
  331 rue_csr_write_4(struct rue_softc *sc, int reg, u_int32_t val)
  332 {
  333         int     err;
  334         uDWord  dw;
  335 
  336         USETDW(dw, val);
  337         err = rue_write_mem(sc, reg, &dw, 4);
  338 
  339         if (err)
  340                 return (-1);
  341 
  342         return (0);
  343 }
  344 
  345 static int
  346 rue_miibus_readreg(device_t dev, int phy, int reg)
  347 {
  348         struct rue_softc        *sc = device_get_softc(dev);
  349         int                     rval;
  350         int                     ruereg;
  351 
  352         if (phy != 0)           /* RTL8150 supports PHY == 0, only */
  353                 return (0);
  354 
  355         switch (reg) {
  356         case MII_BMCR:
  357                 ruereg = RUE_BMCR;
  358                 break;
  359         case MII_BMSR:
  360                 ruereg = RUE_BMSR;
  361                 break;
  362         case MII_ANAR:
  363                 ruereg = RUE_ANAR;
  364                 break;
  365         case MII_ANER:
  366                 ruereg = RUE_AER;
  367                 break;
  368         case MII_ANLPAR:
  369                 ruereg = RUE_ANLP;
  370                 break;
  371         case MII_PHYIDR1:
  372         case MII_PHYIDR2:
  373                 return (0);
  374                 break;
  375         default:
  376                 if (RUE_REG_MIN <= reg && reg <= RUE_REG_MAX) {
  377                         rval = rue_csr_read_1(sc, reg);
  378                         return (rval);
  379                 }
  380                 device_printf(sc->rue_dev, "bad phy register\n");
  381                 return (0);
  382         }
  383 
  384         rval = rue_csr_read_2(sc, ruereg);
  385 
  386         return (rval);
  387 }
  388 
  389 static int
  390 rue_miibus_writereg(device_t dev, int phy, int reg, int data)
  391 {
  392         struct rue_softc        *sc = device_get_softc(dev);
  393         int                     ruereg;
  394 
  395         if (phy != 0)           /* RTL8150 supports PHY == 0, only */
  396                 return (0);
  397 
  398         switch (reg) {
  399         case MII_BMCR:
  400                 ruereg = RUE_BMCR;
  401                 break;
  402         case MII_BMSR:
  403                 ruereg = RUE_BMSR;
  404                 break;
  405         case MII_ANAR:
  406                 ruereg = RUE_ANAR;
  407                 break;
  408         case MII_ANER:
  409                 ruereg = RUE_AER;
  410                 break;
  411         case MII_ANLPAR:
  412                 ruereg = RUE_ANLP;
  413                 break;
  414         case MII_PHYIDR1:
  415         case MII_PHYIDR2:
  416                 return (0);
  417                 break;
  418         default:
  419                 if (RUE_REG_MIN <= reg && reg <= RUE_REG_MAX) {
  420                         rue_csr_write_1(sc, reg, data);
  421                         return (0);
  422                 }
  423                 device_printf(sc->rue_dev, "bad phy register\n");
  424                 return (0);
  425         }
  426         rue_csr_write_2(sc, ruereg, data);
  427 
  428         return (0);
  429 }
  430 
  431 static void
  432 rue_miibus_statchg(device_t dev)
  433 {
  434         /*
  435          * When the code below is enabled the card starts doing weird
  436          * things after link going from UP to DOWN and back UP.
  437          *
  438          * Looks like some of register writes below messes up PHY
  439          * interface.
  440          *
  441          * No visible regressions were found after commenting this code
  442          * out, so that disable it for good.
  443          */
  444 #if 0
  445         struct rue_softc        *sc = device_get_softc(dev);
  446         struct mii_data         *mii = GET_MII(sc);
  447         int                     bmcr;
  448 
  449         RUE_CLRBIT(sc, RUE_CR, (RUE_CR_RE | RUE_CR_TE));
  450 
  451         bmcr = rue_csr_read_2(sc, RUE_BMCR);
  452 
  453         if (IFM_SUBTYPE(mii->mii_media_active) == IFM_100_TX)
  454                 bmcr |= RUE_BMCR_SPD_SET;
  455         else
  456                 bmcr &= ~RUE_BMCR_SPD_SET;
  457 
  458         if ((mii->mii_media_active & IFM_GMASK) == IFM_FDX)
  459                 bmcr |= RUE_BMCR_DUPLEX;
  460         else
  461                 bmcr &= ~RUE_BMCR_DUPLEX;
  462 
  463         rue_csr_write_2(sc, RUE_BMCR, bmcr);
  464 
  465         RUE_SETBIT(sc, RUE_CR, (RUE_CR_RE | RUE_CR_TE));
  466 #endif
  467 }
  468 
  469 /*
  470  * Program the 64-bit multicast hash filter.
  471  */
  472 
  473 static void
  474 rue_setmulti(struct rue_softc *sc)
  475 {
  476         struct ifnet            *ifp;
  477         int                     h = 0;
  478         u_int32_t               hashes[2] = { 0, 0 };
  479         struct ifmultiaddr      *ifma;
  480         u_int32_t               rxcfg;
  481         int                     mcnt = 0;
  482 
  483         ifp = sc->rue_ifp;
  484 
  485         rxcfg = rue_csr_read_2(sc, RUE_RCR);
  486 
  487         if (ifp->if_flags & IFF_ALLMULTI || ifp->if_flags & IFF_PROMISC) {
  488                 rxcfg |= (RUE_RCR_AAM | RUE_RCR_AAP);
  489                 rxcfg &= ~RUE_RCR_AM;
  490                 rue_csr_write_2(sc, RUE_RCR, rxcfg);
  491                 rue_csr_write_4(sc, RUE_MAR0, 0xFFFFFFFF);
  492                 rue_csr_write_4(sc, RUE_MAR4, 0xFFFFFFFF);
  493                 return;
  494         }
  495 
  496         /* first, zot all the existing hash bits */
  497         rue_csr_write_4(sc, RUE_MAR0, 0);
  498         rue_csr_write_4(sc, RUE_MAR4, 0);
  499 
  500         /* now program new ones */
  501         IF_ADDR_LOCK(ifp);
  502         TAILQ_FOREACH (ifma, &ifp->if_multiaddrs, ifma_link)
  503         {
  504                 if (ifma->ifma_addr->sa_family != AF_LINK)
  505                         continue;
  506                 h = ether_crc32_be(LLADDR((struct sockaddr_dl *)
  507                     ifma->ifma_addr), ETHER_ADDR_LEN) >> 26;
  508                 if (h < 32)
  509                         hashes[0] |= (1 << h);
  510                 else
  511                         hashes[1] |= (1 << (h - 32));
  512                 mcnt++;
  513         }
  514         IF_ADDR_UNLOCK(ifp);
  515 
  516         if (mcnt)
  517                 rxcfg |= RUE_RCR_AM;
  518         else
  519                 rxcfg &= ~RUE_RCR_AM;
  520 
  521         rxcfg &= ~(RUE_RCR_AAM | RUE_RCR_AAP);
  522 
  523         rue_csr_write_2(sc, RUE_RCR, rxcfg);
  524         rue_csr_write_4(sc, RUE_MAR0, hashes[0]);
  525         rue_csr_write_4(sc, RUE_MAR4, hashes[1]);
  526 }
  527 
  528 static void
  529 rue_reset(struct rue_softc *sc)
  530 {
  531         int     i;
  532 
  533         rue_csr_write_1(sc, RUE_CR, RUE_CR_SOFT_RST);
  534 
  535         for (i = 0; i < RUE_TIMEOUT; i++) {
  536                 DELAY(500);
  537                 if (!(rue_csr_read_1(sc, RUE_CR) & RUE_CR_SOFT_RST))
  538                         break;
  539         }
  540         if (i == RUE_TIMEOUT)
  541                 device_printf(sc->rue_dev, "reset never completed!\n");
  542 
  543         DELAY(10000);
  544 }
  545 
  546 /*
  547  * Probe for a RTL8150 chip.
  548  */
  549 
  550 static int
  551 rue_match(device_t self)
  552 {
  553         struct usb_attach_arg *uaa = device_get_ivars(self);
  554         struct rue_type *t;
  555 
  556         if (uaa->iface == NULL)
  557                 return (UMATCH_NONE);
  558 
  559         t = rue_devs;
  560         while (t->rue_vid) {
  561                 if (uaa->vendor == t->rue_vid &&
  562                     uaa->product == t->rue_did) {
  563                         return (UMATCH_VENDOR_PRODUCT);
  564                 }
  565                 t++;
  566         }
  567 
  568         return (UMATCH_NONE);
  569 }
  570 
  571 /*
  572  * Attach the interface. Allocate softc structures, do ifmedia
  573  * setup and ethernet/BPF attach.
  574  */
  575 
  576 static int
  577 rue_attach(device_t self)
  578 {
  579         struct rue_softc *sc = device_get_softc(self);
  580         struct usb_attach_arg *uaa = device_get_ivars(self);
  581         u_char                          eaddr[ETHER_ADDR_LEN];
  582         struct ifnet                    *ifp;
  583         usbd_interface_handle           iface;
  584         usbd_status                     err;
  585         usb_interface_descriptor_t      *id;
  586         usb_endpoint_descriptor_t       *ed;
  587         int                             i;
  588         struct rue_type                 *t;
  589 
  590         sc->rue_dev = self;
  591         sc->rue_udev = uaa->device;
  592 
  593         if (usbd_set_config_no(sc->rue_udev, RUE_CONFIG_NO, 0)) {
  594                 device_printf(sc->rue_dev, "getting interface handle failed\n");
  595                 goto error;
  596         }
  597 
  598         usb_init_task(&sc->rue_tick_task, rue_tick_task, sc);
  599 
  600         err = usbd_device2interface_handle(uaa->device, RUE_IFACE_IDX, &iface);
  601         if (err) {
  602                 device_printf(sc->rue_dev, "getting interface handle failed\n");
  603                 goto error;
  604         }
  605 
  606         sc->rue_iface = iface;
  607 
  608         t = rue_devs;
  609         while (t->rue_vid) {
  610                 if (uaa->vendor == t->rue_vid &&
  611                     uaa->product == t->rue_did) {
  612                         sc->rue_info = t;
  613                         break;
  614                 }
  615                 t++;
  616         }
  617 
  618         id = usbd_get_interface_descriptor(sc->rue_iface);
  619 
  620         /* Find endpoints */
  621         for (i = 0; i < id->bNumEndpoints; i++) {
  622                 ed = usbd_interface2endpoint_descriptor(iface, i);
  623                 if (ed == NULL) {
  624                         device_printf(sc->rue_dev, "couldn't get ep %d\n", i);
  625                         goto error;
  626                 }
  627                 if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN &&
  628                     UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) {
  629                         sc->rue_ed[RUE_ENDPT_RX] = ed->bEndpointAddress;
  630                 } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT &&
  631                            UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) {
  632                         sc->rue_ed[RUE_ENDPT_TX] = ed->bEndpointAddress;
  633                 } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN &&
  634                            UE_GET_XFERTYPE(ed->bmAttributes) == UE_INTERRUPT) {
  635                         sc->rue_ed[RUE_ENDPT_INTR] = ed->bEndpointAddress;
  636                 }
  637         }
  638 
  639         mtx_init(&sc->rue_mtx, device_get_nameunit(self), MTX_NETWORK_LOCK,
  640                  MTX_DEF | MTX_RECURSE);
  641         RUE_LOCK(sc);
  642 
  643         /* Reset the adapter */
  644         rue_reset(sc);
  645 
  646         /* Get station address from the EEPROM */
  647         err = rue_read_mem(sc, RUE_EEPROM_IDR0,
  648                            (caddr_t)&eaddr, ETHER_ADDR_LEN);
  649         if (err) {
  650                 device_printf(sc->rue_dev, "couldn't get station address\n");
  651                 goto error1;
  652         }
  653 
  654         ifp = sc->rue_ifp = if_alloc(IFT_ETHER);
  655         if (ifp == NULL) {
  656                 device_printf(sc->rue_dev, "can not if_alloc()\n");
  657                 goto error1;
  658         }
  659         ifp->if_softc = sc;
  660         if_initname(ifp, "rue", device_get_unit(sc->rue_dev));
  661         ifp->if_mtu = ETHERMTU;
  662         ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST |
  663             IFF_NEEDSGIANT;
  664         ifp->if_ioctl = rue_ioctl;
  665         ifp->if_start = rue_start;
  666         ifp->if_watchdog = rue_watchdog;
  667         ifp->if_init = rue_init;
  668         ifp->if_snd.ifq_maxlen = IFQ_MAXLEN;
  669 
  670         /* MII setup */
  671         if (mii_phy_probe(self, &sc->rue_miibus,
  672                           rue_ifmedia_upd, rue_ifmedia_sts)) {
  673                 device_printf(sc->rue_dev, "MII without any PHY!\n");
  674                 goto error2;
  675         }
  676 
  677         sc->rue_qdat.ifp = ifp;
  678         sc->rue_qdat.if_rxstart = rue_rxstart;
  679 
  680         /* Call MI attach routine */
  681         ether_ifattach(ifp, eaddr);
  682         callout_handle_init(&sc->rue_stat_ch);
  683         usb_register_netisr();
  684         sc->rue_dying = 0;
  685 
  686         RUE_UNLOCK(sc);
  687         return 0;
  688 
  689     error2:
  690         if_free(ifp);
  691     error1:
  692         RUE_UNLOCK(sc);
  693         mtx_destroy(&sc->rue_mtx);
  694     error:
  695         return ENXIO;
  696 }
  697 
  698 static int
  699 rue_detach(device_t dev)
  700 {
  701         struct rue_softc        *sc;
  702         struct ifnet            *ifp;
  703 
  704         sc = device_get_softc(dev);
  705         RUE_LOCK(sc);
  706         ifp = sc->rue_ifp;
  707 
  708         sc->rue_dying = 1;
  709         untimeout(rue_tick, sc, sc->rue_stat_ch);
  710         usb_rem_task(sc->rue_udev, &sc->rue_tick_task);
  711         ether_ifdetach(ifp);
  712         if_free(ifp);
  713 
  714         if (sc->rue_ep[RUE_ENDPT_TX] != NULL)
  715                 usbd_abort_pipe(sc->rue_ep[RUE_ENDPT_TX]);
  716         if (sc->rue_ep[RUE_ENDPT_RX] != NULL)
  717                 usbd_abort_pipe(sc->rue_ep[RUE_ENDPT_RX]);
  718 #ifdef RUE_INTR_PIPE
  719         if (sc->rue_ep[RUE_ENDPT_INTR] != NULL)
  720                 usbd_abort_pipe(sc->rue_ep[RUE_ENDPT_INTR]);
  721 #endif
  722 
  723         RUE_UNLOCK(sc);
  724         mtx_destroy(&sc->rue_mtx);
  725 
  726         return (0);
  727 }
  728 
  729 #ifdef RUE_INTR_PIPE
  730 static void
  731 rue_intr(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)
  732 {
  733         struct rue_softc        *sc = priv;
  734         struct ifnet            *ifp;
  735         struct rue_intrpkt      *p;
  736 
  737         RUE_LOCK(sc);
  738         ifp = sc->rue_ifp;
  739 
  740         if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) {
  741                 RUE_UNLOCK(sc);
  742                 return;
  743         }
  744 
  745         if (status != USBD_NORMAL_COMPLETION) {
  746                 if (status == USBD_NOT_STARTED || status == USBD_CANCELLED) {
  747                         RUE_UNLOCK(sc);
  748                         return;
  749                 }
  750                 device_printf(sc->rue_dev, "usb error on intr: %s\n",
  751                     usbd_errstr(status));
  752                 if (status == USBD_STALLED)
  753                         usbd_clear_endpoint_stall(sc->rue_ep[RUE_ENDPT_INTR]);
  754                 RUE_UNLOCK(sc);
  755                 return;
  756         }
  757 
  758         usbd_get_xfer_status(xfer, NULL, (void **)&p, NULL, NULL);
  759 
  760         ifp->if_ierrors += p->rue_rxlost_cnt;
  761         ifp->if_ierrors += p->rue_crcerr_cnt;
  762         ifp->if_collisions += p->rue_col_cnt;
  763 
  764         RUE_UNLOCK(sc);
  765 }
  766 #endif
  767 
  768 static void
  769 rue_rxstart(struct ifnet *ifp)
  770 {
  771         struct rue_softc        *sc;
  772         struct ue_chain *c;
  773 
  774         sc = ifp->if_softc;
  775         RUE_LOCK(sc);
  776         c = &sc->rue_cdata.ue_rx_chain[sc->rue_cdata.ue_rx_prod];
  777 
  778         c->ue_mbuf = usb_ether_newbuf();
  779         if (c->ue_mbuf == NULL) {
  780                 printf("%s: no memory for rx list "
  781                     "-- packet dropped!\n", device_get_nameunit(sc->rue_dev));
  782                 ifp->if_ierrors++;
  783                 RUE_UNLOCK(sc);
  784                 return;
  785         }
  786 
  787         /* Setup new transfer. */
  788         usbd_setup_xfer(c->ue_xfer, sc->rue_ep[RUE_ENDPT_RX],
  789                 c, mtod(c->ue_mbuf, char *), UE_BUFSZ, USBD_SHORT_XFER_OK,
  790                 USBD_NO_TIMEOUT, rue_rxeof);
  791         usbd_transfer(c->ue_xfer);
  792 
  793         RUE_UNLOCK(sc);
  794 }
  795 
  796 /*
  797  * A frame has been uploaded: pass the resulting mbuf chain up to
  798  * the higher level protocols.
  799  */
  800 
  801 static void
  802 rue_rxeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)
  803 {
  804         struct ue_chain *c = priv;
  805         struct rue_softc        *sc = c->ue_sc;
  806         struct mbuf             *m;
  807         struct ifnet            *ifp;
  808         int                     total_len = 0;
  809         struct rue_rxpkt        r;
  810 
  811         if (sc->rue_dying)
  812                 return;
  813         RUE_LOCK(sc);
  814         ifp = sc->rue_ifp;
  815 
  816         if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) {
  817                 RUE_UNLOCK(sc);
  818                 return;
  819         }
  820 
  821         if (status != USBD_NORMAL_COMPLETION) {
  822                 if (status == USBD_NOT_STARTED || status == USBD_CANCELLED) {
  823                         RUE_UNLOCK(sc);
  824                         return;
  825                 }
  826                 if (usbd_ratecheck(&sc->rue_rx_notice))
  827                         device_printf(sc->rue_dev, "usb error on rx: %s\n",
  828                             usbd_errstr(status));
  829                 if (status == USBD_STALLED)
  830                         usbd_clear_endpoint_stall(sc->rue_ep[RUE_ENDPT_RX]);
  831                 goto done;
  832         }
  833 
  834         usbd_get_xfer_status(xfer, NULL, NULL, &total_len, NULL);
  835 
  836         if (total_len <= ETHER_CRC_LEN) {
  837                 ifp->if_ierrors++;
  838                 goto done;
  839         }
  840 
  841         m = c->ue_mbuf;
  842         bcopy(mtod(m, char *) + total_len - 4, (char *)&r, sizeof (r));
  843 
  844         /* Check recieve packet was valid or not */
  845         if ((r.rue_rxstat & RUE_RXSTAT_VALID) == 0) {
  846                 ifp->if_ierrors++;
  847                 goto done;
  848         }
  849 
  850         /* No errors; receive the packet. */
  851         total_len -= ETHER_CRC_LEN;
  852 
  853         ifp->if_ipackets++;
  854         m->m_pkthdr.rcvif = (void *)&sc->rue_qdat;
  855         m->m_pkthdr.len = m->m_len = total_len;
  856 
  857         /* Put the packet on the special USB input queue. */
  858         usb_ether_input(m);
  859 
  860         RUE_UNLOCK(sc);
  861         return;
  862 
  863     done:
  864         /* Setup new transfer. */
  865         usbd_setup_xfer(xfer, sc->rue_ep[RUE_ENDPT_RX],
  866                         c, mtod(c->ue_mbuf, char *), UE_BUFSZ,
  867                         USBD_SHORT_XFER_OK, USBD_NO_TIMEOUT, rue_rxeof);
  868         usbd_transfer(xfer);
  869         RUE_UNLOCK(sc);
  870 }
  871 
  872 /*
  873  * A frame was downloaded to the chip. It's safe for us to clean up
  874  * the list buffers.
  875  */
  876 
  877 static void
  878 rue_txeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)
  879 {
  880         struct ue_chain *c = priv;
  881         struct rue_softc        *sc = c->ue_sc;
  882         struct ifnet            *ifp;
  883         usbd_status             err;
  884 
  885         RUE_LOCK(sc);
  886 
  887         ifp = sc->rue_ifp;
  888 
  889         if (status != USBD_NORMAL_COMPLETION) {
  890                 if (status == USBD_NOT_STARTED || status == USBD_CANCELLED) {
  891                         RUE_UNLOCK(sc);
  892                         return;
  893                 }
  894                 device_printf(sc->rue_dev, "usb error on tx: %s\n",
  895                     usbd_errstr(status));
  896                 if (status == USBD_STALLED)
  897                         usbd_clear_endpoint_stall(sc->rue_ep[RUE_ENDPT_TX]);
  898                 RUE_UNLOCK(sc);
  899                 return;
  900         }
  901 
  902         ifp->if_timer = 0;
  903         ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
  904         usbd_get_xfer_status(c->ue_xfer, NULL, NULL, NULL, &err);
  905 
  906         if (c->ue_mbuf != NULL) {
  907                 c->ue_mbuf->m_pkthdr.rcvif = ifp;
  908                 usb_tx_done(c->ue_mbuf);
  909                 c->ue_mbuf = NULL;
  910         }
  911 
  912         if (err)
  913                 ifp->if_oerrors++;
  914         else
  915                 ifp->if_opackets++;
  916 
  917         RUE_UNLOCK(sc);
  918 }
  919 
  920 static void
  921 rue_tick(void *xsc)
  922 {
  923         struct rue_softc *sc = xsc;
  924 
  925         if (sc == NULL)
  926                 return;
  927         if (sc->rue_dying)
  928                 return;
  929 
  930         /* Perform periodic stuff in process context */
  931         usb_add_task(sc->rue_udev, &sc->rue_tick_task, USB_TASKQ_DRIVER);
  932 }
  933 
  934 static void
  935 rue_tick_task(void *xsc)
  936 {
  937         struct rue_softc        *sc = xsc;
  938         struct ifnet            *ifp;
  939         struct mii_data         *mii;
  940 
  941         if (sc == NULL)
  942                 return;
  943 
  944         RUE_LOCK(sc);
  945 
  946         ifp = sc->rue_ifp;
  947         mii = GET_MII(sc);
  948         if (mii == NULL) {
  949                 RUE_UNLOCK(sc);
  950                 return;
  951         }
  952 
  953         mii_tick(mii);
  954         if (!sc->rue_link && mii->mii_media_status & IFM_ACTIVE &&
  955             IFM_SUBTYPE(mii->mii_media_active) != IFM_NONE) {
  956                 sc->rue_link++;
  957                 if (ifp->if_snd.ifq_head != NULL)
  958                         rue_start(ifp);
  959         }
  960 
  961         sc->rue_stat_ch = timeout(rue_tick, sc, hz);
  962 
  963         RUE_UNLOCK(sc);
  964 }
  965 
  966 static int
  967 rue_encap(struct rue_softc *sc, struct mbuf *m, int idx)
  968 {
  969         int                     total_len;
  970         struct ue_chain *c;
  971         usbd_status             err;
  972 
  973         c = &sc->rue_cdata.ue_tx_chain[idx];
  974 
  975         /*
  976          * Copy the mbuf data into a contiguous buffer
  977          */
  978         m_copydata(m, 0, m->m_pkthdr.len, c->ue_buf);
  979         c->ue_mbuf = m;
  980 
  981         total_len = m->m_pkthdr.len;
  982 
  983         /*
  984          * This is an undocumented behavior.
  985          * RTL8150 chip doesn't send frame length smaller than
  986          * RUE_MIN_FRAMELEN (60) byte packet.
  987          */
  988         if (total_len < RUE_MIN_FRAMELEN)
  989                 total_len = RUE_MIN_FRAMELEN;
  990 
  991         usbd_setup_xfer(c->ue_xfer, sc->rue_ep[RUE_ENDPT_TX],
  992                         c, c->ue_buf, total_len, USBD_FORCE_SHORT_XFER,
  993                         10000, rue_txeof);
  994 
  995         /* Transmit */
  996         err = usbd_transfer(c->ue_xfer);
  997         if (err != USBD_IN_PROGRESS) {
  998                 rue_stop(sc);
  999                 return (EIO);
 1000         }
 1001 
 1002         sc->rue_cdata.ue_tx_cnt++;
 1003 
 1004         return (0);
 1005 }
 1006 
 1007 static void
 1008 rue_start(struct ifnet *ifp)
 1009 {
 1010         struct rue_softc        *sc = ifp->if_softc;
 1011         struct mbuf             *m_head = NULL;
 1012 
 1013         RUE_LOCK(sc);
 1014 
 1015         if (!sc->rue_link) {
 1016                 RUE_UNLOCK(sc);
 1017                 return;
 1018         }
 1019 
 1020         if (ifp->if_drv_flags & IFF_DRV_OACTIVE) {
 1021                 RUE_UNLOCK(sc);
 1022                 return;
 1023         }
 1024 
 1025         IF_DEQUEUE(&ifp->if_snd, m_head);
 1026         if (m_head == NULL) {
 1027                 RUE_UNLOCK(sc);
 1028                 return;
 1029         }
 1030 
 1031         if (rue_encap(sc, m_head, 0)) {
 1032                 IF_PREPEND(&ifp->if_snd, m_head);
 1033                 ifp->if_drv_flags |= IFF_DRV_OACTIVE;
 1034                 RUE_UNLOCK(sc);
 1035                 return;
 1036         }
 1037 
 1038         /*
 1039          * If there's a BPF listener, bounce a copy of this frame
 1040          * to him.
 1041          */
 1042         BPF_MTAP(ifp, m_head);
 1043 
 1044         ifp->if_drv_flags |= IFF_DRV_OACTIVE;
 1045 
 1046         /*
 1047          * Set a timeout in case the chip goes out to lunch.
 1048          */
 1049         ifp->if_timer = 5;
 1050 
 1051         RUE_UNLOCK(sc);
 1052 }
 1053 
 1054 static void
 1055 rue_init(void *xsc)
 1056 {
 1057         struct rue_softc        *sc = xsc;
 1058         struct ifnet            *ifp = sc->rue_ifp;
 1059         struct mii_data         *mii = GET_MII(sc);
 1060         struct ue_chain *c;
 1061         usbd_status             err;
 1062         int                     i;
 1063         int                     rxcfg;
 1064 
 1065         RUE_LOCK(sc);
 1066 
 1067         if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
 1068                 RUE_UNLOCK(sc);
 1069                 return;
 1070         }
 1071 
 1072         /*
 1073          * Cancel pending I/O and free all RX/TX buffers.
 1074          */
 1075         rue_reset(sc);
 1076 
 1077         /* Set MAC address */
 1078         rue_write_mem(sc, RUE_IDR0, IF_LLADDR(sc->rue_ifp),
 1079             ETHER_ADDR_LEN);
 1080 
 1081         /* Init TX ring. */
 1082         if (usb_ether_tx_list_init(sc, &sc->rue_cdata,
 1083             sc->rue_udev) == ENOBUFS) {
 1084                 device_printf(sc->rue_dev, "tx list init failed\n");
 1085                 RUE_UNLOCK(sc);
 1086                 return;
 1087         }
 1088 
 1089         /* Init RX ring. */
 1090         if (usb_ether_rx_list_init(sc, &sc->rue_cdata,
 1091             sc->rue_udev) == ENOBUFS) {
 1092                 device_printf(sc->rue_dev, "rx list init failed\n");
 1093                 RUE_UNLOCK(sc);
 1094                 return;
 1095         }
 1096 
 1097 #ifdef RUE_INTR_PIPE
 1098         sc->rue_cdata.ue_ibuf = malloc(RUE_INTR_PKTLEN, M_USBDEV, M_NOWAIT);
 1099 #endif
 1100 
 1101         /*
 1102          * Set the initial TX and RX configuration.
 1103          */
 1104         rue_csr_write_1(sc, RUE_TCR, RUE_TCR_CONFIG);
 1105 
 1106         rxcfg = RUE_RCR_CONFIG;
 1107 
 1108         /* Set capture broadcast bit to capture broadcast frames. */
 1109         if (ifp->if_flags & IFF_BROADCAST)
 1110                 rxcfg |= RUE_RCR_AB;
 1111         else
 1112                 rxcfg &= ~RUE_RCR_AB;
 1113 
 1114         /* If we want promiscuous mode, set the allframes bit. */
 1115         if (ifp->if_flags & IFF_PROMISC)
 1116                 rxcfg |= RUE_RCR_AAP;
 1117         else
 1118                 rxcfg &= ~RUE_RCR_AAP;
 1119 
 1120         rue_csr_write_2(sc, RUE_RCR, rxcfg);
 1121 
 1122         /* Load the multicast filter. */
 1123         rue_setmulti(sc);
 1124 
 1125         /* Enable RX and TX */
 1126         rue_csr_write_1(sc, RUE_CR, (RUE_CR_TE | RUE_CR_RE | RUE_CR_EP3CLREN));
 1127 
 1128         mii_mediachg(mii);
 1129 
 1130         /* Open RX and TX pipes. */
 1131         err = usbd_open_pipe(sc->rue_iface, sc->rue_ed[RUE_ENDPT_RX],
 1132                              USBD_EXCLUSIVE_USE, &sc->rue_ep[RUE_ENDPT_RX]);
 1133         if (err) {
 1134                 device_printf(sc->rue_dev, "open rx pipe failed: %s\n",
 1135                     usbd_errstr(err));
 1136                 RUE_UNLOCK(sc);
 1137                 return;
 1138         }
 1139         err = usbd_open_pipe(sc->rue_iface, sc->rue_ed[RUE_ENDPT_TX],
 1140                              USBD_EXCLUSIVE_USE, &sc->rue_ep[RUE_ENDPT_TX]);
 1141         if (err) {
 1142                 device_printf(sc->rue_dev, "open tx pipe failed: %s\n",
 1143                     usbd_errstr(err));
 1144                 RUE_UNLOCK(sc);
 1145                 return;
 1146         }
 1147 
 1148 #ifdef RUE_INTR_PIPE
 1149         err = usbd_open_pipe_intr(sc->rue_iface, sc->rue_ed[RUE_ENDPT_INTR],
 1150                                   USBD_SHORT_XFER_OK,
 1151                                   &sc->rue_ep[RUE_ENDPT_INTR], sc,
 1152                                   sc->rue_cdata.ue_ibuf, RUE_INTR_PKTLEN,
 1153                                   rue_intr, RUE_INTR_INTERVAL);
 1154         if (err) {
 1155                 device_printf(sc->rue_dev, "open intr pipe failed: %s\n",
 1156                     usbd_errstr(err));
 1157                 RUE_UNLOCK(sc);
 1158                 return;
 1159         }
 1160 #endif
 1161 
 1162         /* Start up the receive pipe. */
 1163         for (i = 0; i < UE_RX_LIST_CNT; i++) {
 1164                 c = &sc->rue_cdata.ue_rx_chain[i];
 1165                 usbd_setup_xfer(c->ue_xfer, sc->rue_ep[RUE_ENDPT_RX],
 1166                                 c, mtod(c->ue_mbuf, char *), UE_BUFSZ,
 1167                                 USBD_SHORT_XFER_OK, USBD_NO_TIMEOUT, rue_rxeof);
 1168                 usbd_transfer(c->ue_xfer);
 1169         }
 1170 
 1171         ifp->if_drv_flags |= IFF_DRV_RUNNING;
 1172         ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
 1173 
 1174         sc->rue_stat_ch = timeout(rue_tick, sc, hz);
 1175 
 1176         RUE_UNLOCK(sc);
 1177 }
 1178 
 1179 /*
 1180  * Set media options.
 1181  */
 1182 
 1183 static int
 1184 rue_ifmedia_upd(struct ifnet *ifp)
 1185 {
 1186         struct rue_softc        *sc = ifp->if_softc;
 1187         struct mii_data         *mii = GET_MII(sc);
 1188 
 1189         sc->rue_link = 0;
 1190         if (mii->mii_instance) {
 1191                 struct mii_softc        *miisc;
 1192                 LIST_FOREACH (miisc, &mii->mii_phys, mii_list)
 1193                         mii_phy_reset(miisc);
 1194         }
 1195         mii_mediachg(mii);
 1196 
 1197         return (0);
 1198 }
 1199 
 1200 /*
 1201  * Report current media status.
 1202  */
 1203 
 1204 static void
 1205 rue_ifmedia_sts(struct ifnet *ifp, struct ifmediareq *ifmr)
 1206 {
 1207         struct rue_softc        *sc = ifp->if_softc;
 1208         struct mii_data         *mii = GET_MII(sc);
 1209 
 1210         mii_pollstat(mii);
 1211         ifmr->ifm_active = mii->mii_media_active;
 1212         ifmr->ifm_status = mii->mii_media_status;
 1213 }
 1214 
 1215 static int
 1216 rue_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
 1217 {
 1218         struct rue_softc        *sc = ifp->if_softc;
 1219         struct ifreq            *ifr = (struct ifreq *)data;
 1220         struct mii_data         *mii;
 1221         int                     error = 0;
 1222 
 1223         RUE_LOCK(sc);
 1224 
 1225         switch (command) {
 1226         case SIOCSIFFLAGS:
 1227                 if (ifp->if_flags & IFF_UP) {
 1228                         if (ifp->if_drv_flags & IFF_DRV_RUNNING &&
 1229                             ifp->if_flags & IFF_PROMISC &&
 1230                             !(sc->rue_if_flags & IFF_PROMISC)) {
 1231                                 RUE_SETBIT_2(sc, RUE_RCR,
 1232                                              (RUE_RCR_AAM | RUE_RCR_AAP));
 1233                                 rue_setmulti(sc);
 1234                         } else if (ifp->if_drv_flags & IFF_DRV_RUNNING &&
 1235                                    !(ifp->if_flags & IFF_PROMISC) &&
 1236                                    sc->rue_if_flags & IFF_PROMISC) {
 1237                                 RUE_CLRBIT_2(sc, RUE_RCR,
 1238                                              (RUE_RCR_AAM | RUE_RCR_AAP));
 1239                                 rue_setmulti(sc);
 1240                         } else if (!(ifp->if_drv_flags & IFF_DRV_RUNNING))
 1241                                 rue_init(sc);
 1242                 } else {
 1243                         if (ifp->if_drv_flags & IFF_DRV_RUNNING)
 1244                                 rue_stop(sc);
 1245                 }
 1246                 sc->rue_if_flags = ifp->if_flags;
 1247                 error = 0;
 1248                 break;
 1249         case SIOCADDMULTI:
 1250         case SIOCDELMULTI:
 1251                 rue_setmulti(sc);
 1252                 error = 0;
 1253                 break;
 1254         case SIOCGIFMEDIA:
 1255         case SIOCSIFMEDIA:
 1256                 mii = GET_MII(sc);
 1257                 error = ifmedia_ioctl(ifp, ifr, &mii->mii_media, command);
 1258                 break;
 1259         default:
 1260                 error = ether_ioctl(ifp, command, data);
 1261                 break;
 1262         }
 1263 
 1264         RUE_UNLOCK(sc);
 1265 
 1266         return (error);
 1267 }
 1268 
 1269 static void
 1270 rue_watchdog(struct ifnet *ifp)
 1271 {
 1272         struct rue_softc        *sc = ifp->if_softc;
 1273         struct ue_chain *c;
 1274         usbd_status             stat;
 1275 
 1276         RUE_LOCK(sc);
 1277 
 1278         ifp->if_oerrors++;
 1279         device_printf(sc->rue_dev, "watchdog timeout\n");
 1280 
 1281         c = &sc->rue_cdata.ue_tx_chain[0];
 1282         usbd_get_xfer_status(c->ue_xfer, NULL, NULL, NULL, &stat);
 1283         rue_txeof(c->ue_xfer, c, stat);
 1284 
 1285         if (ifp->if_snd.ifq_head != NULL)
 1286                 rue_start(ifp);
 1287 
 1288         RUE_UNLOCK(sc);
 1289 }
 1290 
 1291 /*
 1292  * Stop the adapter and free any mbufs allocated to the
 1293  * RX and TX lists.
 1294  */
 1295 
 1296 static void
 1297 rue_stop(struct rue_softc *sc)
 1298 {
 1299         usbd_status     err;
 1300         struct ifnet    *ifp;
 1301 
 1302         RUE_LOCK(sc);
 1303 
 1304         ifp = sc->rue_ifp;
 1305         ifp->if_timer = 0;
 1306 
 1307         rue_csr_write_1(sc, RUE_CR, 0x00);
 1308         rue_reset(sc);
 1309 
 1310         untimeout(rue_tick, sc, sc->rue_stat_ch);
 1311 
 1312         /* Stop transfers. */
 1313         if (sc->rue_ep[RUE_ENDPT_RX] != NULL) {
 1314                 err = usbd_abort_pipe(sc->rue_ep[RUE_ENDPT_RX]);
 1315                 if (err) {
 1316                         device_printf(sc->rue_dev, "abort rx pipe failed: %s\n",
 1317                             usbd_errstr(err));
 1318                 }
 1319                 err = usbd_close_pipe(sc->rue_ep[RUE_ENDPT_RX]);
 1320                 if (err) {
 1321                         device_printf(sc->rue_dev, "close rx pipe failed: %s\n",
 1322                             usbd_errstr(err));
 1323                 }
 1324                 sc->rue_ep[RUE_ENDPT_RX] = NULL;
 1325         }
 1326 
 1327         if (sc->rue_ep[RUE_ENDPT_TX] != NULL) {
 1328                 err = usbd_abort_pipe(sc->rue_ep[RUE_ENDPT_TX]);
 1329                 if (err) {
 1330                         device_printf(sc->rue_dev, "abort tx pipe failed: %s\n",
 1331                             usbd_errstr(err));
 1332                 }
 1333                 err = usbd_close_pipe(sc->rue_ep[RUE_ENDPT_TX]);
 1334                 if (err) {
 1335                         device_printf(sc->rue_dev, "close tx pipe failed: %s\n",
 1336                             usbd_errstr(err));
 1337                 }
 1338                 sc->rue_ep[RUE_ENDPT_TX] = NULL;
 1339         }
 1340 
 1341 #ifdef RUE_INTR_PIPE
 1342         if (sc->rue_ep[RUE_ENDPT_INTR] != NULL) {
 1343                 err = usbd_abort_pipe(sc->rue_ep[RUE_ENDPT_INTR]);
 1344                 if (err) {
 1345                         device_printf(sc->rue_dev, "abort intr pipe failed: %s\n",
 1346                             usbd_errstr(err));
 1347                 }
 1348                 err = usbd_close_pipe(sc->rue_ep[RUE_ENDPT_INTR]);
 1349                 if (err) {
 1350                         device_printf(sc->rue_dev, "close intr pipe failed: %s\n",
 1351                             usbd_errstr(err));
 1352                 }
 1353                 sc->rue_ep[RUE_ENDPT_INTR] = NULL;
 1354         }
 1355 #endif
 1356 
 1357         /* Free RX resources. */
 1358         usb_ether_rx_list_free(&sc->rue_cdata);
 1359         /* Free TX resources. */
 1360         usb_ether_tx_list_free(&sc->rue_cdata);
 1361 
 1362 #ifdef RUE_INTR_PIPE
 1363         free(sc->rue_cdata.ue_ibuf, M_USBDEV);
 1364         sc->rue_cdata.ue_ibuf = NULL;
 1365 #endif
 1366 
 1367         sc->rue_link = 0;
 1368 
 1369         ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
 1370 
 1371         RUE_UNLOCK(sc);
 1372 }
 1373 
 1374 /*
 1375  * Stop all chip I/O so that the kernel's probe routines don't
 1376  * get confused by errant DMAs when rebooting.
 1377  */
 1378 
 1379 static int
 1380 rue_shutdown(device_t dev)
 1381 {
 1382         struct rue_softc        *sc;
 1383 
 1384         sc = device_get_softc(dev);
 1385 
 1386         sc->rue_dying++;
 1387         RUE_LOCK(sc);
 1388         rue_reset(sc);
 1389         rue_stop(sc);
 1390         RUE_UNLOCK(sc);
 1391 
 1392         return (0);
 1393 }

Cache object: f014c0a81ee434e17b1984b1ba60654d


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