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_udav.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 /*      $NetBSD: if_udav.c,v 1.2 2003/09/04 15:17:38 tsutsui Exp $      */
    2 /*      $nabe: if_udav.c,v 1.3 2003/08/21 16:57:19 nabe Exp $   */
    3 /*      $FreeBSD$       */
    4 /*-
    5  * SPDX-License-Identifier: BSD-3-Clause
    6  *
    7  * Copyright (c) 2003
    8  *     Shingo WATANABE <nabe@nabechan.org>.  All rights reserved.
    9  *
   10  * Redistribution and use in source and binary forms, with or without
   11  * modification, are permitted provided that the following conditions
   12  * are met:
   13  * 1. Redistributions of source code must retain the above copyright
   14  *    notice, this list of conditions and the following disclaimer.
   15  * 2. Redistributions in binary form must reproduce the above copyright
   16  *    notice, this list of conditions and the following disclaimer in the
   17  *    documentation and/or other materials provided with the distribution.
   18  * 3. Neither the name of the author nor the names of any co-contributors
   19  *    may be used to endorse or promote products derived from this software
   20  *    without specific prior written permission.
   21  *
   22  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
   23  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   24  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   25  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
   26  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   27  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   28  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   29  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   30  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   31  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   32  * SUCH DAMAGE.
   33  *
   34  */
   35 
   36 /*
   37  * DM9601(DAVICOM USB to Ethernet MAC Controller with Integrated 10/100 PHY)
   38  * The spec can be found at the following url.
   39  *   http://ptm2.cc.utu.fi/ftp/network/cards/DM9601/From_NET/DM9601-DS-P01-930914.pdf
   40  */
   41 
   42 /*
   43  * TODO:
   44  *      Interrupt Endpoint support
   45  *      External PHYs
   46  */
   47 
   48 #include <sys/cdefs.h>
   49 __FBSDID("$FreeBSD$");
   50 
   51 #include <sys/stdint.h>
   52 #include <sys/stddef.h>
   53 #include <sys/param.h>
   54 #include <sys/queue.h>
   55 #include <sys/types.h>
   56 #include <sys/systm.h>
   57 #include <sys/socket.h>
   58 #include <sys/kernel.h>
   59 #include <sys/bus.h>
   60 #include <sys/module.h>
   61 #include <sys/lock.h>
   62 #include <sys/mutex.h>
   63 #include <sys/condvar.h>
   64 #include <sys/sysctl.h>
   65 #include <sys/sx.h>
   66 #include <sys/unistd.h>
   67 #include <sys/callout.h>
   68 #include <sys/malloc.h>
   69 #include <sys/priv.h>
   70 
   71 #include <net/if.h>
   72 #include <net/if_var.h>
   73 #include <net/if_media.h>
   74 
   75 #include <dev/mii/mii.h>
   76 #include <dev/mii/miivar.h>
   77 
   78 #include <dev/usb/usb.h>
   79 #include <dev/usb/usbdi.h>
   80 #include <dev/usb/usbdi_util.h>
   81 #include "usbdevs.h"
   82 
   83 #include "miibus_if.h"
   84 
   85 #define USB_DEBUG_VAR udav_debug
   86 #include <dev/usb/usb_debug.h>
   87 #include <dev/usb/usb_process.h>
   88 
   89 #include <dev/usb/net/usb_ethernet.h>
   90 #include <dev/usb/net/if_udavreg.h>
   91 
   92 /* prototypes */
   93 
   94 static device_probe_t udav_probe;
   95 static device_attach_t udav_attach;
   96 static device_detach_t udav_detach;
   97 
   98 static usb_callback_t udav_bulk_write_callback;
   99 static usb_callback_t udav_bulk_read_callback;
  100 static usb_callback_t udav_intr_callback;
  101 
  102 static uether_fn_t udav_attach_post;
  103 static uether_fn_t udav_init;
  104 static uether_fn_t udav_stop;
  105 static uether_fn_t udav_start;
  106 static uether_fn_t udav_tick;
  107 static uether_fn_t udav_setmulti;
  108 static uether_fn_t udav_setpromisc;
  109 
  110 static int      udav_csr_read(struct udav_softc *, uint16_t, void *, int);
  111 static int      udav_csr_write(struct udav_softc *, uint16_t, void *, int);
  112 static uint8_t  udav_csr_read1(struct udav_softc *, uint16_t);
  113 static int      udav_csr_write1(struct udav_softc *, uint16_t, uint8_t);
  114 static void     udav_reset(struct udav_softc *);
  115 static int      udav_ifmedia_upd(struct ifnet *);
  116 static void     udav_ifmedia_status(struct ifnet *, struct ifmediareq *);
  117 
  118 static miibus_readreg_t udav_miibus_readreg;
  119 static miibus_writereg_t udav_miibus_writereg;
  120 static miibus_statchg_t udav_miibus_statchg;
  121 
  122 static const struct usb_config udav_config[UDAV_N_TRANSFER] = {
  123         [UDAV_BULK_DT_WR] = {
  124                 .type = UE_BULK,
  125                 .endpoint = UE_ADDR_ANY,
  126                 .direction = UE_DIR_OUT,
  127                 .bufsize = (MCLBYTES + 2),
  128                 .flags = {.pipe_bof = 1,.force_short_xfer = 1,},
  129                 .callback = udav_bulk_write_callback,
  130                 .timeout = 10000,       /* 10 seconds */
  131         },
  132 
  133         [UDAV_BULK_DT_RD] = {
  134                 .type = UE_BULK,
  135                 .endpoint = UE_ADDR_ANY,
  136                 .direction = UE_DIR_IN,
  137                 .bufsize = (MCLBYTES + 3),
  138                 .flags = {.pipe_bof = 1,.short_xfer_ok = 1,},
  139                 .callback = udav_bulk_read_callback,
  140                 .timeout = 0,   /* no timeout */
  141         },
  142 
  143         [UDAV_INTR_DT_RD] = {
  144                 .type = UE_INTERRUPT,
  145                 .endpoint = UE_ADDR_ANY,
  146                 .direction = UE_DIR_IN,
  147                 .flags = {.pipe_bof = 1,.short_xfer_ok = 1,},
  148                 .bufsize = 0,   /* use wMaxPacketSize */
  149                 .callback = udav_intr_callback,
  150         },
  151 };
  152 
  153 static device_method_t udav_methods[] = {
  154         /* Device interface */
  155         DEVMETHOD(device_probe, udav_probe),
  156         DEVMETHOD(device_attach, udav_attach),
  157         DEVMETHOD(device_detach, udav_detach),
  158 
  159         /* MII interface */
  160         DEVMETHOD(miibus_readreg, udav_miibus_readreg),
  161         DEVMETHOD(miibus_writereg, udav_miibus_writereg),
  162         DEVMETHOD(miibus_statchg, udav_miibus_statchg),
  163 
  164         DEVMETHOD_END
  165 };
  166 
  167 static driver_t udav_driver = {
  168         .name = "udav",
  169         .methods = udav_methods,
  170         .size = sizeof(struct udav_softc),
  171 };
  172 
  173 static const STRUCT_USB_HOST_ID udav_devs[] = {
  174         /* ShanTou DM9601 USB NIC */
  175         {USB_VPI(USB_VENDOR_SHANTOU, USB_PRODUCT_SHANTOU_DM9601, 0)},
  176         /* ShanTou ST268 USB NIC */
  177         {USB_VPI(USB_VENDOR_SHANTOU, USB_PRODUCT_SHANTOU_ST268, 0)},
  178         /* Corega USB-TXC */
  179         {USB_VPI(USB_VENDOR_COREGA, USB_PRODUCT_COREGA_FETHER_USB_TXC, 0)},
  180         /* ShanTou AMD8515 USB NIC */
  181         {USB_VPI(USB_VENDOR_SHANTOU, USB_PRODUCT_SHANTOU_ADM8515, 0)},
  182         /* Kontron AG USB Ethernet */
  183         {USB_VPI(USB_VENDOR_KONTRON, USB_PRODUCT_KONTRON_DM9601, 0)},
  184         {USB_VPI(USB_VENDOR_KONTRON, USB_PRODUCT_KONTRON_JP1082,
  185             UDAV_FLAG_NO_PHY)},
  186 };
  187 
  188 DRIVER_MODULE(udav, uhub, udav_driver, NULL, NULL);
  189 DRIVER_MODULE(miibus, udav, miibus_driver, 0, 0);
  190 MODULE_DEPEND(udav, uether, 1, 1, 1);
  191 MODULE_DEPEND(udav, usb, 1, 1, 1);
  192 MODULE_DEPEND(udav, ether, 1, 1, 1);
  193 MODULE_DEPEND(udav, miibus, 1, 1, 1);
  194 MODULE_VERSION(udav, 1);
  195 USB_PNP_HOST_INFO(udav_devs);
  196 
  197 static const struct usb_ether_methods udav_ue_methods = {
  198         .ue_attach_post = udav_attach_post,
  199         .ue_start = udav_start,
  200         .ue_init = udav_init,
  201         .ue_stop = udav_stop,
  202         .ue_tick = udav_tick,
  203         .ue_setmulti = udav_setmulti,
  204         .ue_setpromisc = udav_setpromisc,
  205         .ue_mii_upd = udav_ifmedia_upd,
  206         .ue_mii_sts = udav_ifmedia_status,
  207 };
  208 
  209 static const struct usb_ether_methods udav_ue_methods_nophy = {
  210         .ue_attach_post = udav_attach_post,
  211         .ue_start = udav_start,
  212         .ue_init = udav_init,
  213         .ue_stop = udav_stop,
  214         .ue_setmulti = udav_setmulti,
  215         .ue_setpromisc = udav_setpromisc,
  216 };
  217 
  218 #ifdef USB_DEBUG
  219 static int udav_debug = 0;
  220 
  221 static SYSCTL_NODE(_hw_usb, OID_AUTO, udav, CTLFLAG_RW | CTLFLAG_MPSAFE, 0,
  222     "USB udav");
  223 SYSCTL_INT(_hw_usb_udav, OID_AUTO, debug, CTLFLAG_RWTUN, &udav_debug, 0,
  224     "Debug level");
  225 #endif
  226 
  227 #define UDAV_SETBIT(sc, reg, x) \
  228         udav_csr_write1(sc, reg, udav_csr_read1(sc, reg) | (x))
  229 
  230 #define UDAV_CLRBIT(sc, reg, x) \
  231         udav_csr_write1(sc, reg, udav_csr_read1(sc, reg) & ~(x))
  232 
  233 static void
  234 udav_attach_post(struct usb_ether *ue)
  235 {
  236         struct udav_softc *sc = uether_getsc(ue);
  237 
  238         /* reset the adapter */
  239         udav_reset(sc);
  240 
  241         /* Get Ethernet Address */
  242         udav_csr_read(sc, UDAV_PAR, ue->ue_eaddr, ETHER_ADDR_LEN);
  243 }
  244 
  245 static int
  246 udav_probe(device_t dev)
  247 {
  248         struct usb_attach_arg *uaa = device_get_ivars(dev);
  249 
  250         if (uaa->usb_mode != USB_MODE_HOST)
  251                 return (ENXIO);
  252         if (uaa->info.bConfigIndex != UDAV_CONFIG_INDEX)
  253                 return (ENXIO);
  254         if (uaa->info.bIfaceIndex != UDAV_IFACE_INDEX)
  255                 return (ENXIO);
  256 
  257         return (usbd_lookup_id_by_uaa(udav_devs, sizeof(udav_devs), uaa));
  258 }
  259 
  260 static int
  261 udav_attach(device_t dev)
  262 {
  263         struct usb_attach_arg *uaa = device_get_ivars(dev);
  264         struct udav_softc *sc = device_get_softc(dev);
  265         struct usb_ether *ue = &sc->sc_ue;
  266         uint8_t iface_index;
  267         int error;
  268 
  269         sc->sc_flags = USB_GET_DRIVER_INFO(uaa);
  270 
  271         device_set_usb_desc(dev);
  272 
  273         mtx_init(&sc->sc_mtx, device_get_nameunit(dev), NULL, MTX_DEF);
  274 
  275         iface_index = UDAV_IFACE_INDEX;
  276         error = usbd_transfer_setup(uaa->device, &iface_index,
  277             sc->sc_xfer, udav_config, UDAV_N_TRANSFER, sc, &sc->sc_mtx);
  278         if (error) {
  279                 device_printf(dev, "allocating USB transfers failed\n");
  280                 goto detach;
  281         }
  282 
  283         /*
  284          * The JP1082 has an unusable PHY and provides no link information.
  285          */
  286         if (sc->sc_flags & UDAV_FLAG_NO_PHY) {
  287                 ue->ue_methods = &udav_ue_methods_nophy;
  288                 sc->sc_flags |= UDAV_FLAG_LINK;
  289         } else {
  290                 ue->ue_methods = &udav_ue_methods;
  291         }
  292 
  293         ue->ue_sc = sc;
  294         ue->ue_dev = dev;
  295         ue->ue_udev = uaa->device;
  296         ue->ue_mtx = &sc->sc_mtx;
  297 
  298         error = uether_ifattach(ue);
  299         if (error) {
  300                 device_printf(dev, "could not attach interface\n");
  301                 goto detach;
  302         }
  303 
  304         return (0);                     /* success */
  305 
  306 detach:
  307         udav_detach(dev);
  308         return (ENXIO);                 /* failure */
  309 }
  310 
  311 static int
  312 udav_detach(device_t dev)
  313 {
  314         struct udav_softc *sc = device_get_softc(dev);
  315         struct usb_ether *ue = &sc->sc_ue;
  316 
  317         usbd_transfer_unsetup(sc->sc_xfer, UDAV_N_TRANSFER);
  318         uether_ifdetach(ue);
  319         mtx_destroy(&sc->sc_mtx);
  320 
  321         return (0);
  322 }
  323 
  324 #if 0
  325 static int
  326 udav_mem_read(struct udav_softc *sc, uint16_t offset, void *buf,
  327     int len)
  328 {
  329         struct usb_device_request req;
  330 
  331         len &= 0xff;
  332 
  333         req.bmRequestType = UT_READ_VENDOR_DEVICE;
  334         req.bRequest = UDAV_REQ_MEM_READ;
  335         USETW(req.wValue, 0x0000);
  336         USETW(req.wIndex, offset);
  337         USETW(req.wLength, len);
  338 
  339         return (uether_do_request(&sc->sc_ue, &req, buf, 1000));
  340 }
  341 
  342 static int
  343 udav_mem_write(struct udav_softc *sc, uint16_t offset, void *buf,
  344     int len)
  345 {
  346         struct usb_device_request req;
  347 
  348         len &= 0xff;
  349 
  350         req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
  351         req.bRequest = UDAV_REQ_MEM_WRITE;
  352         USETW(req.wValue, 0x0000);
  353         USETW(req.wIndex, offset);
  354         USETW(req.wLength, len);
  355 
  356         return (uether_do_request(&sc->sc_ue, &req, buf, 1000));
  357 }
  358 
  359 static int
  360 udav_mem_write1(struct udav_softc *sc, uint16_t offset,
  361     uint8_t ch)
  362 {
  363         struct usb_device_request req;
  364 
  365         req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
  366         req.bRequest = UDAV_REQ_MEM_WRITE1;
  367         USETW(req.wValue, ch);
  368         USETW(req.wIndex, offset);
  369         USETW(req.wLength, 0x0000);
  370 
  371         return (uether_do_request(&sc->sc_ue, &req, NULL, 1000));
  372 }
  373 #endif
  374 
  375 static int
  376 udav_csr_read(struct udav_softc *sc, uint16_t offset, void *buf, int len)
  377 {
  378         struct usb_device_request req;
  379 
  380         len &= 0xff;
  381 
  382         req.bmRequestType = UT_READ_VENDOR_DEVICE;
  383         req.bRequest = UDAV_REQ_REG_READ;
  384         USETW(req.wValue, 0x0000);
  385         USETW(req.wIndex, offset);
  386         USETW(req.wLength, len);
  387 
  388         return (uether_do_request(&sc->sc_ue, &req, buf, 1000));
  389 }
  390 
  391 static int
  392 udav_csr_write(struct udav_softc *sc, uint16_t offset, void *buf, int len)
  393 {
  394         struct usb_device_request req;
  395 
  396         offset &= 0xff;
  397         len &= 0xff;
  398 
  399         req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
  400         req.bRequest = UDAV_REQ_REG_WRITE;
  401         USETW(req.wValue, 0x0000);
  402         USETW(req.wIndex, offset);
  403         USETW(req.wLength, len);
  404 
  405         return (uether_do_request(&sc->sc_ue, &req, buf, 1000));
  406 }
  407 
  408 static uint8_t
  409 udav_csr_read1(struct udav_softc *sc, uint16_t offset)
  410 {
  411         uint8_t val;
  412 
  413         udav_csr_read(sc, offset, &val, 1);
  414         return (val);
  415 }
  416 
  417 static int
  418 udav_csr_write1(struct udav_softc *sc, uint16_t offset,
  419     uint8_t ch)
  420 {
  421         struct usb_device_request req;
  422 
  423         offset &= 0xff;
  424 
  425         req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
  426         req.bRequest = UDAV_REQ_REG_WRITE1;
  427         USETW(req.wValue, ch);
  428         USETW(req.wIndex, offset);
  429         USETW(req.wLength, 0x0000);
  430 
  431         return (uether_do_request(&sc->sc_ue, &req, NULL, 1000));
  432 }
  433 
  434 static void
  435 udav_init(struct usb_ether *ue)
  436 {
  437         struct udav_softc *sc = ue->ue_sc;
  438         struct ifnet *ifp = uether_getifp(&sc->sc_ue);
  439 
  440         UDAV_LOCK_ASSERT(sc, MA_OWNED);
  441 
  442         /*
  443          * Cancel pending I/O
  444          */
  445         udav_stop(ue);
  446 
  447         /* set MAC address */
  448         udav_csr_write(sc, UDAV_PAR, IF_LLADDR(ifp), ETHER_ADDR_LEN);
  449 
  450         /* initialize network control register */
  451 
  452         /* disable loopback  */
  453         UDAV_CLRBIT(sc, UDAV_NCR, UDAV_NCR_LBK0 | UDAV_NCR_LBK1);
  454 
  455         /* Initialize RX control register */
  456         UDAV_SETBIT(sc, UDAV_RCR, UDAV_RCR_DIS_LONG | UDAV_RCR_DIS_CRC);
  457 
  458         /* load multicast filter and update promiscious mode bit */
  459         udav_setpromisc(ue);
  460 
  461         /* enable RX */
  462         UDAV_SETBIT(sc, UDAV_RCR, UDAV_RCR_RXEN);
  463 
  464         /* clear POWER_DOWN state of internal PHY */
  465         UDAV_SETBIT(sc, UDAV_GPCR, UDAV_GPCR_GEP_CNTL0);
  466         UDAV_CLRBIT(sc, UDAV_GPR, UDAV_GPR_GEPIO0);
  467 
  468         usbd_xfer_set_stall(sc->sc_xfer[UDAV_BULK_DT_WR]);
  469 
  470         ifp->if_drv_flags |= IFF_DRV_RUNNING;
  471         udav_start(ue);
  472 }
  473 
  474 static void
  475 udav_reset(struct udav_softc *sc)
  476 {
  477         int i;
  478 
  479         /* Select PHY */
  480 #if 1
  481         /*
  482          * XXX: force select internal phy.
  483          *      external phy routines are not tested.
  484          */
  485         UDAV_CLRBIT(sc, UDAV_NCR, UDAV_NCR_EXT_PHY);
  486 #else
  487         if (sc->sc_flags & UDAV_EXT_PHY)
  488                 UDAV_SETBIT(sc, UDAV_NCR, UDAV_NCR_EXT_PHY);
  489         else
  490                 UDAV_CLRBIT(sc, UDAV_NCR, UDAV_NCR_EXT_PHY);
  491 #endif
  492 
  493         UDAV_SETBIT(sc, UDAV_NCR, UDAV_NCR_RST);
  494 
  495         for (i = 0; i < UDAV_TX_TIMEOUT; i++) {
  496                 if (!(udav_csr_read1(sc, UDAV_NCR) & UDAV_NCR_RST))
  497                         break;
  498                 if (uether_pause(&sc->sc_ue, hz / 100))
  499                         break;
  500         }
  501 
  502         uether_pause(&sc->sc_ue, hz / 100);
  503 }
  504 
  505 static u_int
  506 udav_hash_maddr(void *arg, struct sockaddr_dl *sdl, u_int cnt)
  507 {
  508         uint8_t *hashtbl = arg;
  509         int h;
  510 
  511         h = ether_crc32_be(LLADDR(sdl), ETHER_ADDR_LEN) >> 26;
  512         hashtbl[h / 8] |= 1 << (h % 8);
  513 
  514         return (1);
  515 }
  516 
  517 static void
  518 udav_setmulti(struct usb_ether *ue)
  519 {
  520         struct udav_softc *sc = ue->ue_sc;
  521         struct ifnet *ifp = uether_getifp(&sc->sc_ue);
  522         uint8_t hashtbl[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
  523 
  524         UDAV_LOCK_ASSERT(sc, MA_OWNED);
  525 
  526         if (ifp->if_flags & IFF_ALLMULTI || ifp->if_flags & IFF_PROMISC) {
  527                 UDAV_SETBIT(sc, UDAV_RCR, UDAV_RCR_ALL|UDAV_RCR_PRMSC);
  528                 return;
  529         }
  530 
  531         /* first, zot all the existing hash bits */
  532         memset(hashtbl, 0x00, sizeof(hashtbl));
  533         hashtbl[7] |= 0x80;     /* broadcast address */
  534         udav_csr_write(sc, UDAV_MAR, hashtbl, sizeof(hashtbl));
  535 
  536         /* now program new ones */
  537         if_foreach_llmaddr(ifp, udav_hash_maddr, hashtbl);
  538 
  539         /* disable all multicast */
  540         UDAV_CLRBIT(sc, UDAV_RCR, UDAV_RCR_ALL);
  541 
  542         /* write hash value to the register */
  543         udav_csr_write(sc, UDAV_MAR, hashtbl, sizeof(hashtbl));
  544 }
  545 
  546 static void
  547 udav_setpromisc(struct usb_ether *ue)
  548 {
  549         struct udav_softc *sc = ue->ue_sc;
  550         struct ifnet *ifp = uether_getifp(&sc->sc_ue);
  551         uint8_t rxmode;
  552 
  553         rxmode = udav_csr_read1(sc, UDAV_RCR);
  554         rxmode &= ~(UDAV_RCR_ALL | UDAV_RCR_PRMSC);
  555 
  556         if (ifp->if_flags & IFF_PROMISC)
  557                 rxmode |= UDAV_RCR_ALL | UDAV_RCR_PRMSC;
  558         else if (ifp->if_flags & IFF_ALLMULTI)
  559                 rxmode |= UDAV_RCR_ALL;
  560 
  561         /* write new mode bits */
  562         udav_csr_write1(sc, UDAV_RCR, rxmode);
  563 }
  564 
  565 static void
  566 udav_start(struct usb_ether *ue)
  567 {
  568         struct udav_softc *sc = ue->ue_sc;
  569 
  570         /*
  571          * start the USB transfers, if not already started:
  572          */
  573         usbd_transfer_start(sc->sc_xfer[UDAV_INTR_DT_RD]);
  574         usbd_transfer_start(sc->sc_xfer[UDAV_BULK_DT_RD]);
  575         usbd_transfer_start(sc->sc_xfer[UDAV_BULK_DT_WR]);
  576 }
  577 
  578 static void
  579 udav_bulk_write_callback(struct usb_xfer *xfer, usb_error_t error)
  580 {
  581         struct udav_softc *sc = usbd_xfer_softc(xfer);
  582         struct ifnet *ifp = uether_getifp(&sc->sc_ue);
  583         struct usb_page_cache *pc;
  584         struct mbuf *m;
  585         int extra_len;
  586         int temp_len;
  587         uint8_t buf[2];
  588 
  589         switch (USB_GET_STATE(xfer)) {
  590         case USB_ST_TRANSFERRED:
  591                 DPRINTFN(11, "transfer complete\n");
  592                 if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1);
  593 
  594                 /* FALLTHROUGH */
  595         case USB_ST_SETUP:
  596 tr_setup:
  597                 if ((sc->sc_flags & UDAV_FLAG_LINK) == 0) {
  598                         /*
  599                          * don't send anything if there is no link !
  600                          */
  601                         return;
  602                 }
  603                 IFQ_DRV_DEQUEUE(&ifp->if_snd, m);
  604 
  605                 if (m == NULL)
  606                         return;
  607                 if (m->m_pkthdr.len > MCLBYTES)
  608                         m->m_pkthdr.len = MCLBYTES;
  609                 if (m->m_pkthdr.len < UDAV_MIN_FRAME_LEN) {
  610                         extra_len = UDAV_MIN_FRAME_LEN - m->m_pkthdr.len;
  611                 } else {
  612                         extra_len = 0;
  613                 }
  614 
  615                 temp_len = (m->m_pkthdr.len + extra_len);
  616 
  617                 /*
  618                  * the frame length is specified in the first 2 bytes of the
  619                  * buffer
  620                  */
  621                 buf[0] = (uint8_t)(temp_len);
  622                 buf[1] = (uint8_t)(temp_len >> 8);
  623 
  624                 temp_len += 2;
  625 
  626                 pc = usbd_xfer_get_frame(xfer, 0);
  627                 usbd_copy_in(pc, 0, buf, 2);
  628                 usbd_m_copy_in(pc, 2, m, 0, m->m_pkthdr.len);
  629 
  630                 if (extra_len)
  631                         usbd_frame_zero(pc, temp_len - extra_len, extra_len);
  632                 /*
  633                  * if there's a BPF listener, bounce a copy
  634                  * of this frame to him:
  635                  */
  636                 BPF_MTAP(ifp, m);
  637 
  638                 m_freem(m);
  639 
  640                 usbd_xfer_set_frame_len(xfer, 0, temp_len);
  641                 usbd_transfer_submit(xfer);
  642                 return;
  643 
  644         default:                        /* Error */
  645                 DPRINTFN(11, "transfer error, %s\n",
  646                     usbd_errstr(error));
  647 
  648                 if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
  649 
  650                 if (error != USB_ERR_CANCELLED) {
  651                         /* try to clear stall first */
  652                         usbd_xfer_set_stall(xfer);
  653                         goto tr_setup;
  654                 }
  655                 return;
  656         }
  657 }
  658 
  659 static void
  660 udav_bulk_read_callback(struct usb_xfer *xfer, usb_error_t error)
  661 {
  662         struct udav_softc *sc = usbd_xfer_softc(xfer);
  663         struct usb_ether *ue = &sc->sc_ue;
  664         struct ifnet *ifp = uether_getifp(ue);
  665         struct usb_page_cache *pc;
  666         struct udav_rxpkt stat;
  667         int len;
  668         int actlen;
  669 
  670         usbd_xfer_status(xfer, &actlen, NULL, NULL, NULL);
  671 
  672         switch (USB_GET_STATE(xfer)) {
  673         case USB_ST_TRANSFERRED:
  674 
  675                 if (actlen < (int)(sizeof(stat) + ETHER_CRC_LEN)) {
  676                         if_inc_counter(ifp, IFCOUNTER_IERRORS, 1);
  677                         goto tr_setup;
  678                 }
  679                 pc = usbd_xfer_get_frame(xfer, 0);
  680                 usbd_copy_out(pc, 0, &stat, sizeof(stat));
  681                 actlen -= sizeof(stat);
  682                 len = min(actlen, le16toh(stat.pktlen));
  683                 len -= ETHER_CRC_LEN;
  684 
  685                 if (stat.rxstat & UDAV_RSR_LCS) {
  686                         if_inc_counter(ifp, IFCOUNTER_COLLISIONS, 1);
  687                         goto tr_setup;
  688                 }
  689                 if (stat.rxstat & UDAV_RSR_ERR) {
  690                         if_inc_counter(ifp, IFCOUNTER_IERRORS, 1);
  691                         goto tr_setup;
  692                 }
  693                 uether_rxbuf(ue, pc, sizeof(stat), len);
  694                 /* FALLTHROUGH */
  695         case USB_ST_SETUP:
  696 tr_setup:
  697                 usbd_xfer_set_frame_len(xfer, 0, usbd_xfer_max_len(xfer));
  698                 usbd_transfer_submit(xfer);
  699                 uether_rxflush(ue);
  700                 return;
  701 
  702         default:                        /* Error */
  703                 DPRINTF("bulk read error, %s\n",
  704                     usbd_errstr(error));
  705 
  706                 if (error != USB_ERR_CANCELLED) {
  707                         /* try to clear stall first */
  708                         usbd_xfer_set_stall(xfer);
  709                         goto tr_setup;
  710                 }
  711                 return;
  712         }
  713 }
  714 
  715 static void
  716 udav_intr_callback(struct usb_xfer *xfer, usb_error_t error)
  717 {
  718         switch (USB_GET_STATE(xfer)) {
  719         case USB_ST_TRANSFERRED:
  720         case USB_ST_SETUP:
  721 tr_setup:
  722                 usbd_xfer_set_frame_len(xfer, 0, usbd_xfer_max_len(xfer));
  723                 usbd_transfer_submit(xfer);
  724                 return;
  725 
  726         default:                        /* Error */
  727                 if (error != USB_ERR_CANCELLED) {
  728                         /* try to clear stall first */
  729                         usbd_xfer_set_stall(xfer);
  730                         goto tr_setup;
  731                 }
  732                 return;
  733         }
  734 }
  735 
  736 static void
  737 udav_stop(struct usb_ether *ue)
  738 {
  739         struct udav_softc *sc = ue->ue_sc;
  740         struct ifnet *ifp = uether_getifp(&sc->sc_ue);
  741 
  742         UDAV_LOCK_ASSERT(sc, MA_OWNED);
  743 
  744         ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
  745         if (!(sc->sc_flags & UDAV_FLAG_NO_PHY))
  746                 sc->sc_flags &= ~UDAV_FLAG_LINK;
  747 
  748         /*
  749          * stop all the transfers, if not already stopped:
  750          */
  751         usbd_transfer_stop(sc->sc_xfer[UDAV_BULK_DT_WR]);
  752         usbd_transfer_stop(sc->sc_xfer[UDAV_BULK_DT_RD]);
  753         usbd_transfer_stop(sc->sc_xfer[UDAV_INTR_DT_RD]);
  754 
  755         udav_reset(sc);
  756 }
  757 
  758 static int
  759 udav_ifmedia_upd(struct ifnet *ifp)
  760 {
  761         struct udav_softc *sc = ifp->if_softc;
  762         struct mii_data *mii = GET_MII(sc);
  763         struct mii_softc *miisc;
  764         int error;
  765 
  766         UDAV_LOCK_ASSERT(sc, MA_OWNED);
  767 
  768         sc->sc_flags &= ~UDAV_FLAG_LINK;
  769         LIST_FOREACH(miisc, &mii->mii_phys, mii_list)
  770                 PHY_RESET(miisc);
  771         error = mii_mediachg(mii);
  772         return (error);
  773 }
  774 
  775 static void
  776 udav_ifmedia_status(struct ifnet *ifp, struct ifmediareq *ifmr)
  777 {
  778         struct udav_softc *sc = ifp->if_softc;
  779         struct mii_data *mii = GET_MII(sc);
  780 
  781         UDAV_LOCK(sc);
  782         mii_pollstat(mii);
  783         ifmr->ifm_active = mii->mii_media_active;
  784         ifmr->ifm_status = mii->mii_media_status;
  785         UDAV_UNLOCK(sc);
  786 }
  787 
  788 static void
  789 udav_tick(struct usb_ether *ue)
  790 {
  791         struct udav_softc *sc = ue->ue_sc;
  792         struct mii_data *mii = GET_MII(sc);
  793 
  794         UDAV_LOCK_ASSERT(sc, MA_OWNED);
  795 
  796         mii_tick(mii);
  797         if ((sc->sc_flags & UDAV_FLAG_LINK) == 0
  798             && mii->mii_media_status & IFM_ACTIVE &&
  799             IFM_SUBTYPE(mii->mii_media_active) != IFM_NONE) {
  800                 sc->sc_flags |= UDAV_FLAG_LINK;
  801                 udav_start(ue);
  802         }
  803 }
  804 
  805 static int
  806 udav_miibus_readreg(device_t dev, int phy, int reg)
  807 {
  808         struct udav_softc *sc = device_get_softc(dev);
  809         uint16_t data16;
  810         uint8_t val[2];
  811         int locked;
  812 
  813         /* XXX: one PHY only for the internal PHY */
  814         if (phy != 0)
  815                 return (0);
  816 
  817         locked = mtx_owned(&sc->sc_mtx);
  818         if (!locked)
  819                 UDAV_LOCK(sc);
  820 
  821         /* select internal PHY and set PHY register address */
  822         udav_csr_write1(sc, UDAV_EPAR,
  823             UDAV_EPAR_PHY_ADR0 | (reg & UDAV_EPAR_EROA_MASK));
  824 
  825         /* select PHY operation and start read command */
  826         udav_csr_write1(sc, UDAV_EPCR, UDAV_EPCR_EPOS | UDAV_EPCR_ERPRR);
  827 
  828         /* XXX: should we wait? */
  829 
  830         /* end read command */
  831         UDAV_CLRBIT(sc, UDAV_EPCR, UDAV_EPCR_ERPRR);
  832 
  833         /* retrieve the result from data registers */
  834         udav_csr_read(sc, UDAV_EPDRL, val, 2);
  835 
  836         data16 = (val[0] | (val[1] << 8));
  837 
  838         DPRINTFN(11, "phy=%d reg=0x%04x => 0x%04x\n",
  839             phy, reg, data16);
  840 
  841         if (!locked)
  842                 UDAV_UNLOCK(sc);
  843         return (data16);
  844 }
  845 
  846 static int
  847 udav_miibus_writereg(device_t dev, int phy, int reg, int data)
  848 {
  849         struct udav_softc *sc = device_get_softc(dev);
  850         uint8_t val[2];
  851         int locked;
  852 
  853         /* XXX: one PHY only for the internal PHY */
  854         if (phy != 0)
  855                 return (0);
  856 
  857         locked = mtx_owned(&sc->sc_mtx);
  858         if (!locked)
  859                 UDAV_LOCK(sc);
  860 
  861         /* select internal PHY and set PHY register address */
  862         udav_csr_write1(sc, UDAV_EPAR,
  863             UDAV_EPAR_PHY_ADR0 | (reg & UDAV_EPAR_EROA_MASK));
  864 
  865         /* put the value to the data registers */
  866         val[0] = (data & 0xff);
  867         val[1] = (data >> 8) & 0xff;
  868         udav_csr_write(sc, UDAV_EPDRL, val, 2);
  869 
  870         /* select PHY operation and start write command */
  871         udav_csr_write1(sc, UDAV_EPCR, UDAV_EPCR_EPOS | UDAV_EPCR_ERPRW);
  872 
  873         /* XXX: should we wait? */
  874 
  875         /* end write command */
  876         UDAV_CLRBIT(sc, UDAV_EPCR, UDAV_EPCR_ERPRW);
  877 
  878         if (!locked)
  879                 UDAV_UNLOCK(sc);
  880         return (0);
  881 }
  882 
  883 static void
  884 udav_miibus_statchg(device_t dev)
  885 {
  886         /* nothing to do */
  887 }

Cache object: c7af61bf713ef2fa8ed52770a2cf32cd


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