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

Cache object: 13adb1201f1fda0de3018787cb22b25b


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