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/net/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  * SPDX-License-Identifier: BSD-4-Clause AND BSD-2-Clause-FreeBSD
   29  *
   30  * Copyright (c) 1997, 1998, 1999, 2000
   31  *      Bill Paul <wpaul@ee.columbia.edu>.  All rights reserved.
   32  *
   33  * Redistribution and use in source and binary forms, with or without
   34  * modification, are permitted provided that the following conditions
   35  * are met:
   36  * 1. Redistributions of source code must retain the above copyright
   37  *    notice, this list of conditions and the following disclaimer.
   38  * 2. Redistributions in binary form must reproduce the above copyright
   39  *    notice, this list of conditions and the following disclaimer in the
   40  *    documentation and/or other materials provided with the distribution.
   41  * 3. All advertising materials mentioning features or use of this software
   42  *    must display the following acknowledgement:
   43  *      This product includes software developed by Bill Paul.
   44  * 4. Neither the name of the author nor the names of any co-contributors
   45  *    may be used to endorse or promote products derived from this software
   46  *    without specific prior written permission.
   47  *
   48  * THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND
   49  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   50  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   51  * ARE DISCLAIMED.  IN NO EVENT SHALL Bill Paul OR THE VOICES IN HIS HEAD
   52  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
   53  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
   54  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
   55  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
   56  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   57  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
   58  * THE POSSIBILITY OF SUCH DAMAGE.
   59  */
   60 
   61 #include <sys/cdefs.h>
   62 __FBSDID("$FreeBSD$");
   63 
   64 /*
   65  * RealTek RTL8150 USB to fast ethernet controller driver.
   66  * Datasheet is available from
   67  * ftp://ftp.realtek.com.tw/lancard/data_sheet/8150/.
   68  */
   69 
   70 #include <sys/stdint.h>
   71 #include <sys/stddef.h>
   72 #include <sys/param.h>
   73 #include <sys/queue.h>
   74 #include <sys/types.h>
   75 #include <sys/systm.h>
   76 #include <sys/socket.h>
   77 #include <sys/kernel.h>
   78 #include <sys/bus.h>
   79 #include <sys/module.h>
   80 #include <sys/lock.h>
   81 #include <sys/mutex.h>
   82 #include <sys/condvar.h>
   83 #include <sys/sysctl.h>
   84 #include <sys/sx.h>
   85 #include <sys/unistd.h>
   86 #include <sys/callout.h>
   87 #include <sys/malloc.h>
   88 #include <sys/priv.h>
   89 
   90 #include <net/if.h>
   91 #include <net/if_var.h>
   92 #include <net/if_media.h>
   93 
   94 #include <dev/mii/mii.h>
   95 #include <dev/mii/miivar.h>
   96 
   97 #include <dev/usb/usb.h>
   98 #include <dev/usb/usbdi.h>
   99 #include <dev/usb/usbdi_util.h>
  100 #include "usbdevs.h"
  101 
  102 #define USB_DEBUG_VAR rue_debug
  103 #include <dev/usb/usb_debug.h>
  104 #include <dev/usb/usb_process.h>
  105 
  106 #include <dev/usb/net/usb_ethernet.h>
  107 #include <dev/usb/net/if_ruereg.h>
  108 
  109 #include "miibus_if.h"
  110 
  111 #ifdef USB_DEBUG
  112 static int rue_debug = 0;
  113 
  114 static SYSCTL_NODE(_hw_usb, OID_AUTO, rue, CTLFLAG_RW | CTLFLAG_MPSAFE, 0,
  115     "USB rue");
  116 SYSCTL_INT(_hw_usb_rue, OID_AUTO, debug, CTLFLAG_RWTUN,
  117     &rue_debug, 0, "Debug level");
  118 #endif
  119 
  120 /*
  121  * Various supported device vendors/products.
  122  */
  123 
  124 static const STRUCT_USB_HOST_ID rue_devs[] = {
  125         {USB_VPI(USB_VENDOR_MELCO, USB_PRODUCT_MELCO_LUAKTX, 0)},
  126         {USB_VPI(USB_VENDOR_REALTEK, USB_PRODUCT_REALTEK_USBKR100, 0)},
  127         {USB_VPI(USB_VENDOR_OQO, USB_PRODUCT_OQO_ETHER01, 0)},
  128 };
  129 
  130 /* prototypes */
  131 
  132 static device_probe_t rue_probe;
  133 static device_attach_t rue_attach;
  134 static device_detach_t rue_detach;
  135 
  136 static miibus_readreg_t rue_miibus_readreg;
  137 static miibus_writereg_t rue_miibus_writereg;
  138 static miibus_statchg_t rue_miibus_statchg;
  139 
  140 static usb_callback_t rue_intr_callback;
  141 static usb_callback_t rue_bulk_read_callback;
  142 static usb_callback_t rue_bulk_write_callback;
  143 
  144 static uether_fn_t rue_attach_post;
  145 static uether_fn_t rue_init;
  146 static uether_fn_t rue_stop;
  147 static uether_fn_t rue_start;
  148 static uether_fn_t rue_tick;
  149 static uether_fn_t rue_setmulti;
  150 static uether_fn_t rue_setpromisc;
  151 
  152 static int      rue_read_mem(struct rue_softc *, uint16_t, void *, int);
  153 static int      rue_write_mem(struct rue_softc *, uint16_t, void *, int);
  154 static uint8_t  rue_csr_read_1(struct rue_softc *, uint16_t);
  155 static uint16_t rue_csr_read_2(struct rue_softc *, uint16_t);
  156 static int      rue_csr_write_1(struct rue_softc *, uint16_t, uint8_t);
  157 static int      rue_csr_write_2(struct rue_softc *, uint16_t, uint16_t);
  158 static int      rue_csr_write_4(struct rue_softc *, int, uint32_t);
  159 
  160 static void     rue_reset(struct rue_softc *);
  161 static int      rue_ifmedia_upd(struct ifnet *);
  162 static void     rue_ifmedia_sts(struct ifnet *, struct ifmediareq *);
  163 
  164 static const struct usb_config rue_config[RUE_N_TRANSFER] = {
  165         [RUE_BULK_DT_WR] = {
  166                 .type = UE_BULK,
  167                 .endpoint = UE_ADDR_ANY,
  168                 .direction = UE_DIR_OUT,
  169                 .bufsize = MCLBYTES,
  170                 .flags = {.pipe_bof = 1,.force_short_xfer = 1,},
  171                 .callback = rue_bulk_write_callback,
  172                 .timeout = 10000,       /* 10 seconds */
  173         },
  174 
  175         [RUE_BULK_DT_RD] = {
  176                 .type = UE_BULK,
  177                 .endpoint = UE_ADDR_ANY,
  178                 .direction = UE_DIR_IN,
  179                 .bufsize = (MCLBYTES + 4),
  180                 .flags = {.pipe_bof = 1,.short_xfer_ok = 1,},
  181                 .callback = rue_bulk_read_callback,
  182                 .timeout = 0,   /* no timeout */
  183         },
  184 
  185         [RUE_INTR_DT_RD] = {
  186                 .type = UE_INTERRUPT,
  187                 .endpoint = UE_ADDR_ANY,
  188                 .direction = UE_DIR_IN,
  189                 .flags = {.pipe_bof = 1,.short_xfer_ok = 1,},
  190                 .bufsize = 0,   /* use wMaxPacketSize */
  191                 .callback = rue_intr_callback,
  192         },
  193 };
  194 
  195 static device_method_t rue_methods[] = {
  196         /* Device interface */
  197         DEVMETHOD(device_probe, rue_probe),
  198         DEVMETHOD(device_attach, rue_attach),
  199         DEVMETHOD(device_detach, rue_detach),
  200 
  201         /* MII interface */
  202         DEVMETHOD(miibus_readreg, rue_miibus_readreg),
  203         DEVMETHOD(miibus_writereg, rue_miibus_writereg),
  204         DEVMETHOD(miibus_statchg, rue_miibus_statchg),
  205 
  206         DEVMETHOD_END
  207 };
  208 
  209 static driver_t rue_driver = {
  210         .name = "rue",
  211         .methods = rue_methods,
  212         .size = sizeof(struct rue_softc),
  213 };
  214 
  215 DRIVER_MODULE_ORDERED(rue, uhub, rue_driver, NULL, NULL, SI_ORDER_ANY);
  216 DRIVER_MODULE(miibus, rue, miibus_driver, NULL, NULL);
  217 MODULE_DEPEND(rue, uether, 1, 1, 1);
  218 MODULE_DEPEND(rue, usb, 1, 1, 1);
  219 MODULE_DEPEND(rue, ether, 1, 1, 1);
  220 MODULE_DEPEND(rue, miibus, 1, 1, 1);
  221 MODULE_VERSION(rue, 1);
  222 USB_PNP_HOST_INFO(rue_devs);
  223 
  224 static const struct usb_ether_methods rue_ue_methods = {
  225         .ue_attach_post = rue_attach_post,
  226         .ue_start = rue_start,
  227         .ue_init = rue_init,
  228         .ue_stop = rue_stop,
  229         .ue_tick = rue_tick,
  230         .ue_setmulti = rue_setmulti,
  231         .ue_setpromisc = rue_setpromisc,
  232         .ue_mii_upd = rue_ifmedia_upd,
  233         .ue_mii_sts = rue_ifmedia_sts,
  234 };
  235 
  236 #define RUE_SETBIT(sc, reg, x) \
  237         rue_csr_write_1(sc, reg, rue_csr_read_1(sc, reg) | (x))
  238 
  239 #define RUE_CLRBIT(sc, reg, x) \
  240         rue_csr_write_1(sc, reg, rue_csr_read_1(sc, reg) & ~(x))
  241 
  242 static int
  243 rue_read_mem(struct rue_softc *sc, uint16_t addr, void *buf, int len)
  244 {
  245         struct usb_device_request req;
  246 
  247         req.bmRequestType = UT_READ_VENDOR_DEVICE;
  248         req.bRequest = UR_SET_ADDRESS;
  249         USETW(req.wValue, addr);
  250         USETW(req.wIndex, 0);
  251         USETW(req.wLength, len);
  252 
  253         return (uether_do_request(&sc->sc_ue, &req, buf, 1000));
  254 }
  255 
  256 static int
  257 rue_write_mem(struct rue_softc *sc, uint16_t addr, void *buf, int len)
  258 {
  259         struct usb_device_request req;
  260 
  261         req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
  262         req.bRequest = UR_SET_ADDRESS;
  263         USETW(req.wValue, addr);
  264         USETW(req.wIndex, 0);
  265         USETW(req.wLength, len);
  266 
  267         return (uether_do_request(&sc->sc_ue, &req, buf, 1000));
  268 }
  269 
  270 static uint8_t
  271 rue_csr_read_1(struct rue_softc *sc, uint16_t reg)
  272 {
  273         uint8_t val;
  274 
  275         rue_read_mem(sc, reg, &val, 1);
  276         return (val);
  277 }
  278 
  279 static uint16_t
  280 rue_csr_read_2(struct rue_softc *sc, uint16_t reg)
  281 {
  282         uint8_t val[2];
  283 
  284         rue_read_mem(sc, reg, &val, 2);
  285         return (UGETW(val));
  286 }
  287 
  288 static int
  289 rue_csr_write_1(struct rue_softc *sc, uint16_t reg, uint8_t val)
  290 {
  291         return (rue_write_mem(sc, reg, &val, 1));
  292 }
  293 
  294 static int
  295 rue_csr_write_2(struct rue_softc *sc, uint16_t reg, uint16_t val)
  296 {
  297         uint8_t temp[2];
  298 
  299         USETW(temp, val);
  300         return (rue_write_mem(sc, reg, &temp, 2));
  301 }
  302 
  303 static int
  304 rue_csr_write_4(struct rue_softc *sc, int reg, uint32_t val)
  305 {
  306         uint8_t temp[4];
  307 
  308         USETDW(temp, val);
  309         return (rue_write_mem(sc, reg, &temp, 4));
  310 }
  311 
  312 static int
  313 rue_miibus_readreg(device_t dev, int phy, int reg)
  314 {
  315         struct rue_softc *sc = device_get_softc(dev);
  316         uint16_t rval;
  317         uint16_t ruereg;
  318         int locked;
  319 
  320         if (phy != 0)           /* RTL8150 supports PHY == 0, only */
  321                 return (0);
  322 
  323         locked = mtx_owned(&sc->sc_mtx);
  324         if (!locked)
  325                 RUE_LOCK(sc);
  326 
  327         switch (reg) {
  328         case MII_BMCR:
  329                 ruereg = RUE_BMCR;
  330                 break;
  331         case MII_BMSR:
  332                 ruereg = RUE_BMSR;
  333                 break;
  334         case MII_ANAR:
  335                 ruereg = RUE_ANAR;
  336                 break;
  337         case MII_ANER:
  338                 ruereg = RUE_AER;
  339                 break;
  340         case MII_ANLPAR:
  341                 ruereg = RUE_ANLP;
  342                 break;
  343         case MII_PHYIDR1:
  344         case MII_PHYIDR2:
  345                 rval = 0;
  346                 goto done;
  347         default:
  348                 if (RUE_REG_MIN <= reg && reg <= RUE_REG_MAX) {
  349                         rval = rue_csr_read_1(sc, reg);
  350                         goto done;
  351                 }
  352                 device_printf(sc->sc_ue.ue_dev, "bad phy register\n");
  353                 rval = 0;
  354                 goto done;
  355         }
  356 
  357         rval = rue_csr_read_2(sc, ruereg);
  358 done:
  359         if (!locked)
  360                 RUE_UNLOCK(sc);
  361         return (rval);
  362 }
  363 
  364 static int
  365 rue_miibus_writereg(device_t dev, int phy, int reg, int data)
  366 {
  367         struct rue_softc *sc = device_get_softc(dev);
  368         uint16_t ruereg;
  369         int locked;
  370 
  371         if (phy != 0)           /* RTL8150 supports PHY == 0, only */
  372                 return (0);
  373 
  374         locked = mtx_owned(&sc->sc_mtx);
  375         if (!locked)
  376                 RUE_LOCK(sc);
  377 
  378         switch (reg) {
  379         case MII_BMCR:
  380                 ruereg = RUE_BMCR;
  381                 break;
  382         case MII_BMSR:
  383                 ruereg = RUE_BMSR;
  384                 break;
  385         case MII_ANAR:
  386                 ruereg = RUE_ANAR;
  387                 break;
  388         case MII_ANER:
  389                 ruereg = RUE_AER;
  390                 break;
  391         case MII_ANLPAR:
  392                 ruereg = RUE_ANLP;
  393                 break;
  394         case MII_PHYIDR1:
  395         case MII_PHYIDR2:
  396                 goto done;
  397         default:
  398                 if (RUE_REG_MIN <= reg && reg <= RUE_REG_MAX) {
  399                         rue_csr_write_1(sc, reg, data);
  400                         goto done;
  401                 }
  402                 device_printf(sc->sc_ue.ue_dev, " bad phy register\n");
  403                 goto done;
  404         }
  405         rue_csr_write_2(sc, ruereg, data);
  406 done:
  407         if (!locked)
  408                 RUE_UNLOCK(sc);
  409         return (0);
  410 }
  411 
  412 static void
  413 rue_miibus_statchg(device_t dev)
  414 {
  415         /*
  416          * When the code below is enabled the card starts doing weird
  417          * things after link going from UP to DOWN and back UP.
  418          *
  419          * Looks like some of register writes below messes up PHY
  420          * interface.
  421          *
  422          * No visible regressions were found after commenting this code
  423          * out, so that disable it for good.
  424          */
  425 #if 0
  426         struct rue_softc *sc = device_get_softc(dev);
  427         struct mii_data *mii = GET_MII(sc);
  428         uint16_t bmcr;
  429         int locked;
  430 
  431         locked = mtx_owned(&sc->sc_mtx);
  432         if (!locked)
  433                 RUE_LOCK(sc);
  434 
  435         RUE_CLRBIT(sc, RUE_CR, (RUE_CR_RE | RUE_CR_TE));
  436 
  437         bmcr = rue_csr_read_2(sc, RUE_BMCR);
  438 
  439         if (IFM_SUBTYPE(mii->mii_media_active) == IFM_100_TX)
  440                 bmcr |= RUE_BMCR_SPD_SET;
  441         else
  442                 bmcr &= ~RUE_BMCR_SPD_SET;
  443 
  444         if ((mii->mii_media_active & IFM_GMASK) == IFM_FDX)
  445                 bmcr |= RUE_BMCR_DUPLEX;
  446         else
  447                 bmcr &= ~RUE_BMCR_DUPLEX;
  448 
  449         rue_csr_write_2(sc, RUE_BMCR, bmcr);
  450 
  451         RUE_SETBIT(sc, RUE_CR, (RUE_CR_RE | RUE_CR_TE));
  452 
  453         if (!locked)
  454                 RUE_UNLOCK(sc);
  455 #endif
  456 }
  457 
  458 static void
  459 rue_setpromisc(struct usb_ether *ue)
  460 {
  461         struct rue_softc *sc = uether_getsc(ue);
  462         struct ifnet *ifp = uether_getifp(ue);
  463 
  464         RUE_LOCK_ASSERT(sc, MA_OWNED);
  465 
  466         /* If we want promiscuous mode, set the allframes bit. */
  467         if (ifp->if_flags & IFF_PROMISC)
  468                 RUE_SETBIT(sc, RUE_RCR, RUE_RCR_AAP);
  469         else
  470                 RUE_CLRBIT(sc, RUE_RCR, RUE_RCR_AAP);
  471 }
  472 
  473 static u_int
  474 rue_hash_maddr(void *arg, struct sockaddr_dl *sdl, u_int cnt)
  475 {
  476         uint32_t *hashes = arg;
  477         int h;
  478 
  479         h = ether_crc32_be(LLADDR(sdl), ETHER_ADDR_LEN) >> 26;
  480         if (h < 32)
  481                 hashes[0] |= (1 << h);
  482         else
  483                 hashes[1] |= (1 << (h - 32));
  484 
  485         return (1);
  486 }
  487 
  488 /*
  489  * Program the 64-bit multicast hash filter.
  490  */
  491 static void
  492 rue_setmulti(struct usb_ether *ue)
  493 {
  494         struct rue_softc *sc = uether_getsc(ue);
  495         struct ifnet *ifp = uether_getifp(ue);
  496         uint16_t rxcfg;
  497         uint32_t hashes[2] = { 0, 0 };
  498         int mcnt;
  499 
  500         RUE_LOCK_ASSERT(sc, MA_OWNED);
  501 
  502         rxcfg = rue_csr_read_2(sc, RUE_RCR);
  503 
  504         if (ifp->if_flags & IFF_ALLMULTI || ifp->if_flags & IFF_PROMISC) {
  505                 rxcfg |= (RUE_RCR_AAM | RUE_RCR_AAP);
  506                 rxcfg &= ~RUE_RCR_AM;
  507                 rue_csr_write_2(sc, RUE_RCR, rxcfg);
  508                 rue_csr_write_4(sc, RUE_MAR0, 0xFFFFFFFF);
  509                 rue_csr_write_4(sc, RUE_MAR4, 0xFFFFFFFF);
  510                 return;
  511         }
  512 
  513         /* first, zot all the existing hash bits */
  514         rue_csr_write_4(sc, RUE_MAR0, 0);
  515         rue_csr_write_4(sc, RUE_MAR4, 0);
  516 
  517         /* now program new ones */
  518         mcnt = if_foreach_llmaddr(ifp, rue_hash_maddr, &hashes);
  519 
  520         if (mcnt)
  521                 rxcfg |= RUE_RCR_AM;
  522         else
  523                 rxcfg &= ~RUE_RCR_AM;
  524 
  525         rxcfg &= ~(RUE_RCR_AAM | RUE_RCR_AAP);
  526 
  527         rue_csr_write_2(sc, RUE_RCR, rxcfg);
  528         rue_csr_write_4(sc, RUE_MAR0, hashes[0]);
  529         rue_csr_write_4(sc, RUE_MAR4, hashes[1]);
  530 }
  531 
  532 static void
  533 rue_reset(struct rue_softc *sc)
  534 {
  535         int i;
  536 
  537         rue_csr_write_1(sc, RUE_CR, RUE_CR_SOFT_RST);
  538 
  539         for (i = 0; i != RUE_TIMEOUT; i++) {
  540                 if (uether_pause(&sc->sc_ue, hz / 1000))
  541                         break;
  542                 if (!(rue_csr_read_1(sc, RUE_CR) & RUE_CR_SOFT_RST))
  543                         break;
  544         }
  545         if (i == RUE_TIMEOUT)
  546                 device_printf(sc->sc_ue.ue_dev, "reset never completed\n");
  547 
  548         uether_pause(&sc->sc_ue, hz / 100);
  549 }
  550 
  551 static void
  552 rue_attach_post(struct usb_ether *ue)
  553 {
  554         struct rue_softc *sc = uether_getsc(ue);
  555 
  556         /* reset the adapter */
  557         rue_reset(sc);
  558 
  559         /* get station address from the EEPROM */
  560         rue_read_mem(sc, RUE_EEPROM_IDR0, ue->ue_eaddr, ETHER_ADDR_LEN);
  561 }
  562 
  563 /*
  564  * Probe for a RTL8150 chip.
  565  */
  566 static int
  567 rue_probe(device_t dev)
  568 {
  569         struct usb_attach_arg *uaa = device_get_ivars(dev);
  570 
  571         if (uaa->usb_mode != USB_MODE_HOST)
  572                 return (ENXIO);
  573         if (uaa->info.bConfigIndex != RUE_CONFIG_IDX)
  574                 return (ENXIO);
  575         if (uaa->info.bIfaceIndex != RUE_IFACE_IDX)
  576                 return (ENXIO);
  577 
  578         return (usbd_lookup_id_by_uaa(rue_devs, sizeof(rue_devs), uaa));
  579 }
  580 
  581 /*
  582  * Attach the interface. Allocate softc structures, do ifmedia
  583  * setup and ethernet/BPF attach.
  584  */
  585 static int
  586 rue_attach(device_t dev)
  587 {
  588         struct usb_attach_arg *uaa = device_get_ivars(dev);
  589         struct rue_softc *sc = device_get_softc(dev);
  590         struct usb_ether *ue = &sc->sc_ue;
  591         uint8_t iface_index;
  592         int error;
  593 
  594         device_set_usb_desc(dev);
  595         mtx_init(&sc->sc_mtx, device_get_nameunit(dev), NULL, MTX_DEF);
  596 
  597         iface_index = RUE_IFACE_IDX;
  598         error = usbd_transfer_setup(uaa->device, &iface_index,
  599             sc->sc_xfer, rue_config, RUE_N_TRANSFER,
  600             sc, &sc->sc_mtx);
  601         if (error) {
  602                 device_printf(dev, "allocating USB transfers failed\n");
  603                 goto detach;
  604         }
  605 
  606         ue->ue_sc = sc;
  607         ue->ue_dev = dev;
  608         ue->ue_udev = uaa->device;
  609         ue->ue_mtx = &sc->sc_mtx;
  610         ue->ue_methods = &rue_ue_methods;
  611 
  612         error = uether_ifattach(ue);
  613         if (error) {
  614                 device_printf(dev, "could not attach interface\n");
  615                 goto detach;
  616         }
  617         return (0);                     /* success */
  618 
  619 detach:
  620         rue_detach(dev);
  621         return (ENXIO);                 /* failure */
  622 }
  623 
  624 static int
  625 rue_detach(device_t dev)
  626 {
  627         struct rue_softc *sc = device_get_softc(dev);
  628         struct usb_ether *ue = &sc->sc_ue;
  629 
  630         usbd_transfer_unsetup(sc->sc_xfer, RUE_N_TRANSFER);
  631         uether_ifdetach(ue);
  632         mtx_destroy(&sc->sc_mtx);
  633 
  634         return (0);
  635 }
  636 
  637 static void
  638 rue_intr_callback(struct usb_xfer *xfer, usb_error_t error)
  639 {
  640         struct rue_softc *sc = usbd_xfer_softc(xfer);
  641         struct ifnet *ifp = uether_getifp(&sc->sc_ue);
  642         struct rue_intrpkt pkt;
  643         struct usb_page_cache *pc;
  644         int actlen;
  645 
  646         usbd_xfer_status(xfer, &actlen, NULL, NULL, NULL);
  647 
  648         switch (USB_GET_STATE(xfer)) {
  649         case USB_ST_TRANSFERRED:
  650 
  651                 if (ifp && (ifp->if_drv_flags & IFF_DRV_RUNNING) &&
  652                     actlen >= (int)sizeof(pkt)) {
  653                         pc = usbd_xfer_get_frame(xfer, 0);
  654                         usbd_copy_out(pc, 0, &pkt, sizeof(pkt));
  655 
  656                         if_inc_counter(ifp, IFCOUNTER_IERRORS, pkt.rue_rxlost_cnt);
  657                         if_inc_counter(ifp, IFCOUNTER_IERRORS, pkt.rue_crcerr_cnt);
  658                         if_inc_counter(ifp, IFCOUNTER_COLLISIONS, pkt.rue_col_cnt);
  659                 }
  660                 /* FALLTHROUGH */
  661         case USB_ST_SETUP:
  662 tr_setup:
  663                 usbd_xfer_set_frame_len(xfer, 0, usbd_xfer_max_len(xfer));
  664                 usbd_transfer_submit(xfer);
  665                 return;
  666 
  667         default:                        /* Error */
  668                 if (error != USB_ERR_CANCELLED) {
  669                         /* try to clear stall first */
  670                         usbd_xfer_set_stall(xfer);
  671                         goto tr_setup;
  672                 }
  673                 return;
  674         }
  675 }
  676 
  677 static void
  678 rue_bulk_read_callback(struct usb_xfer *xfer, usb_error_t error)
  679 {
  680         struct rue_softc *sc = usbd_xfer_softc(xfer);
  681         struct usb_ether *ue = &sc->sc_ue;
  682         struct ifnet *ifp = uether_getifp(ue);
  683         struct usb_page_cache *pc;
  684         uint16_t status;
  685         int actlen;
  686 
  687         usbd_xfer_status(xfer, &actlen, NULL, NULL, NULL);
  688 
  689         switch (USB_GET_STATE(xfer)) {
  690         case USB_ST_TRANSFERRED:
  691 
  692                 if (actlen < 4) {
  693                         if_inc_counter(ifp, IFCOUNTER_IERRORS, 1);
  694                         goto tr_setup;
  695                 }
  696                 pc = usbd_xfer_get_frame(xfer, 0);
  697                 usbd_copy_out(pc, actlen - 4, &status, sizeof(status));
  698                 actlen -= 4;
  699 
  700                 /* check receive packet was valid or not */
  701                 status = le16toh(status);
  702                 if ((status & RUE_RXSTAT_VALID) == 0) {
  703                         if_inc_counter(ifp, IFCOUNTER_IERRORS, 1);
  704                         goto tr_setup;
  705                 }
  706                 uether_rxbuf(ue, pc, 0, actlen);
  707                 /* FALLTHROUGH */
  708         case USB_ST_SETUP:
  709 tr_setup:
  710                 usbd_xfer_set_frame_len(xfer, 0, usbd_xfer_max_len(xfer));
  711                 usbd_transfer_submit(xfer);
  712                 uether_rxflush(ue);
  713                 return;
  714 
  715         default:                        /* Error */
  716                 DPRINTF("bulk read error, %s\n",
  717                     usbd_errstr(error));
  718 
  719                 if (error != USB_ERR_CANCELLED) {
  720                         /* try to clear stall first */
  721                         usbd_xfer_set_stall(xfer);
  722                         goto tr_setup;
  723                 }
  724                 return;
  725         }
  726 }
  727 
  728 static void
  729 rue_bulk_write_callback(struct usb_xfer *xfer, usb_error_t error)
  730 {
  731         struct rue_softc *sc = usbd_xfer_softc(xfer);
  732         struct ifnet *ifp = uether_getifp(&sc->sc_ue);
  733         struct usb_page_cache *pc;
  734         struct mbuf *m;
  735         int temp_len;
  736 
  737         switch (USB_GET_STATE(xfer)) {
  738         case USB_ST_TRANSFERRED:
  739                 DPRINTFN(11, "transfer complete\n");
  740                 if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1);
  741 
  742                 /* FALLTHROUGH */
  743         case USB_ST_SETUP:
  744 tr_setup:
  745                 if ((sc->sc_flags & RUE_FLAG_LINK) == 0) {
  746                         /*
  747                          * don't send anything if there is no link !
  748                          */
  749                         return;
  750                 }
  751                 IFQ_DRV_DEQUEUE(&ifp->if_snd, m);
  752 
  753                 if (m == NULL)
  754                         return;
  755                 if (m->m_pkthdr.len > MCLBYTES)
  756                         m->m_pkthdr.len = MCLBYTES;
  757                 temp_len = m->m_pkthdr.len;
  758 
  759                 pc = usbd_xfer_get_frame(xfer, 0);
  760                 usbd_m_copy_in(pc, 0, m, 0, m->m_pkthdr.len);
  761 
  762                 /*
  763                  * This is an undocumented behavior.
  764                  * RTL8150 chip doesn't send frame length smaller than
  765                  * RUE_MIN_FRAMELEN (60) byte packet.
  766                  */
  767                 if (temp_len < RUE_MIN_FRAMELEN) {
  768                         usbd_frame_zero(pc, temp_len,
  769                             RUE_MIN_FRAMELEN - temp_len);
  770                         temp_len = RUE_MIN_FRAMELEN;
  771                 }
  772                 usbd_xfer_set_frame_len(xfer, 0, temp_len);
  773 
  774                 /*
  775                  * if there's a BPF listener, bounce a copy
  776                  * of this frame to him:
  777                  */
  778                 BPF_MTAP(ifp, m);
  779 
  780                 m_freem(m);
  781 
  782                 usbd_transfer_submit(xfer);
  783 
  784                 return;
  785 
  786         default:                        /* Error */
  787                 DPRINTFN(11, "transfer error, %s\n",
  788                     usbd_errstr(error));
  789 
  790                 if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
  791 
  792                 if (error != USB_ERR_CANCELLED) {
  793                         /* try to clear stall first */
  794                         usbd_xfer_set_stall(xfer);
  795                         goto tr_setup;
  796                 }
  797                 return;
  798         }
  799 }
  800 
  801 static void
  802 rue_tick(struct usb_ether *ue)
  803 {
  804         struct rue_softc *sc = uether_getsc(ue);
  805         struct mii_data *mii = GET_MII(sc);
  806 
  807         RUE_LOCK_ASSERT(sc, MA_OWNED);
  808 
  809         mii_tick(mii);
  810         if ((sc->sc_flags & RUE_FLAG_LINK) == 0
  811             && mii->mii_media_status & IFM_ACTIVE &&
  812             IFM_SUBTYPE(mii->mii_media_active) != IFM_NONE) {
  813                 sc->sc_flags |= RUE_FLAG_LINK;
  814                 rue_start(ue);
  815         }
  816 }
  817 
  818 static void
  819 rue_start(struct usb_ether *ue)
  820 {
  821         struct rue_softc *sc = uether_getsc(ue);
  822 
  823         /*
  824          * start the USB transfers, if not already started:
  825          */
  826         usbd_transfer_start(sc->sc_xfer[RUE_INTR_DT_RD]);
  827         usbd_transfer_start(sc->sc_xfer[RUE_BULK_DT_RD]);
  828         usbd_transfer_start(sc->sc_xfer[RUE_BULK_DT_WR]);
  829 }
  830 
  831 static void
  832 rue_init(struct usb_ether *ue)
  833 {
  834         struct rue_softc *sc = uether_getsc(ue);
  835         struct ifnet *ifp = uether_getifp(ue);
  836 
  837         RUE_LOCK_ASSERT(sc, MA_OWNED);
  838 
  839         /*
  840          * Cancel pending I/O
  841          */
  842         rue_reset(sc);
  843 
  844         /* Set MAC address */
  845         rue_write_mem(sc, RUE_IDR0, IF_LLADDR(ifp), ETHER_ADDR_LEN);
  846 
  847         rue_stop(ue);
  848 
  849         /*
  850          * Set the initial TX and RX configuration.
  851          */
  852         rue_csr_write_1(sc, RUE_TCR, RUE_TCR_CONFIG);
  853         rue_csr_write_2(sc, RUE_RCR, RUE_RCR_CONFIG|RUE_RCR_AB);
  854 
  855         /* Load the multicast filter */
  856         rue_setpromisc(ue);
  857         /* Load the multicast filter. */
  858         rue_setmulti(ue);
  859 
  860         /* Enable RX and TX */
  861         rue_csr_write_1(sc, RUE_CR, (RUE_CR_TE | RUE_CR_RE | RUE_CR_EP3CLREN));
  862 
  863         usbd_xfer_set_stall(sc->sc_xfer[RUE_BULK_DT_WR]);
  864 
  865         ifp->if_drv_flags |= IFF_DRV_RUNNING;
  866         rue_start(ue);
  867 }
  868 
  869 /*
  870  * Set media options.
  871  */
  872 static int
  873 rue_ifmedia_upd(struct ifnet *ifp)
  874 {
  875         struct rue_softc *sc = ifp->if_softc;
  876         struct mii_data *mii = GET_MII(sc);
  877         struct mii_softc *miisc;
  878         int error;
  879 
  880         RUE_LOCK_ASSERT(sc, MA_OWNED);
  881 
  882         sc->sc_flags &= ~RUE_FLAG_LINK;
  883         LIST_FOREACH(miisc, &mii->mii_phys, mii_list)
  884                 PHY_RESET(miisc);
  885         error = mii_mediachg(mii);
  886         return (error);
  887 }
  888 
  889 /*
  890  * Report current media status.
  891  */
  892 static void
  893 rue_ifmedia_sts(struct ifnet *ifp, struct ifmediareq *ifmr)
  894 {
  895         struct rue_softc *sc = ifp->if_softc;
  896         struct mii_data *mii = GET_MII(sc);
  897 
  898         RUE_LOCK(sc);
  899         mii_pollstat(mii);
  900         ifmr->ifm_active = mii->mii_media_active;
  901         ifmr->ifm_status = mii->mii_media_status;
  902         RUE_UNLOCK(sc);
  903 }
  904 
  905 static void
  906 rue_stop(struct usb_ether *ue)
  907 {
  908         struct rue_softc *sc = uether_getsc(ue);
  909         struct ifnet *ifp = uether_getifp(ue);
  910 
  911         RUE_LOCK_ASSERT(sc, MA_OWNED);
  912 
  913         ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
  914         sc->sc_flags &= ~RUE_FLAG_LINK;
  915 
  916         /*
  917          * stop all the transfers, if not already stopped:
  918          */
  919         usbd_transfer_stop(sc->sc_xfer[RUE_BULK_DT_WR]);
  920         usbd_transfer_stop(sc->sc_xfer[RUE_BULK_DT_RD]);
  921         usbd_transfer_stop(sc->sc_xfer[RUE_INTR_DT_RD]);
  922 
  923         rue_csr_write_1(sc, RUE_CR, 0x00);
  924 
  925         rue_reset(sc);
  926 }

Cache object: f10355afcf82cd76aacb1bb62e59be2c


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