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


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

FreeBSD/Linux Kernel Cross Reference
sys/dev/usb/if_axe.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) 1997, 1998, 1999, 2000-2003
    3  *      Bill Paul <wpaul@windriver.com>.  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  * 3. All advertising materials mentioning features or use of this software
   14  *    must display the following acknowledgement:
   15  *      This product includes software developed by Bill Paul.
   16  * 4. Neither the name of the author nor the names of any co-contributors
   17  *    may be used to endorse or promote products derived from this software
   18  *    without specific prior written permission.
   19  *
   20  * THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND
   21  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   22  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   23  * ARE DISCLAIMED.  IN NO EVENT SHALL Bill Paul OR THE VOICES IN HIS HEAD
   24  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
   25  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
   26  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
   27  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
   28  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   29  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
   30  * THE POSSIBILITY OF SUCH DAMAGE.
   31  */
   32 
   33 #include <sys/cdefs.h>
   34 __FBSDID("$FreeBSD: releng/7.3/sys/dev/usb/if_axe.c 188260 2009-02-07 01:43:04Z thompsa $");
   35 
   36 /*
   37  * ASIX Electronics AX88172/AX88178/AX88778 USB 2.0 ethernet driver.
   38  * Used in the LinkSys USB200M and various other adapters.
   39  *
   40  * Manuals available from:
   41  * http://www.asix.com.tw/datasheet/mac/Ax88172.PDF
   42  * Note: you need the manual for the AX88170 chip (USB 1.x ethernet
   43  * controller) to find the definitions for the RX control register.
   44  * http://www.asix.com.tw/datasheet/mac/Ax88170.PDF
   45  *
   46  * Written by Bill Paul <wpaul@windriver.com>
   47  * Senior Engineer
   48  * Wind River Systems
   49  */
   50 
   51 /*
   52  * The AX88172 provides USB ethernet supports at 10 and 100Mbps.
   53  * It uses an external PHY (reference designs use a RealTek chip),
   54  * and has a 64-bit multicast hash filter. There is some information
   55  * missing from the manual which one needs to know in order to make
   56  * the chip function:
   57  *
   58  * - You must set bit 7 in the RX control register, otherwise the
   59  *   chip won't receive any packets.
   60  * - You must initialize all 3 IPG registers, or you won't be able
   61  *   to send any packets.
   62  *
   63  * Note that this device appears to only support loading the station
   64  * address via autload from the EEPROM (i.e. there's no way to manaully
   65  * set it).
   66  *
   67  * (Adam Weinberger wanted me to name this driver if_gir.c.)
   68  */
   69 
   70 #include <sys/param.h>
   71 #include <sys/systm.h>
   72 #include <sys/endian.h>
   73 #include <sys/sockio.h>
   74 #include <sys/mbuf.h>
   75 #include <sys/malloc.h>
   76 #include <sys/lock.h>
   77 #include <sys/kernel.h>
   78 #include <sys/module.h>
   79 #include <sys/socket.h>
   80 #include <sys/sx.h>
   81 
   82 #include <net/if.h>
   83 #include <net/if_arp.h>
   84 #include <net/ethernet.h>
   85 #include <net/if_dl.h>
   86 #include <net/if_media.h>
   87 #include <net/if_types.h>
   88 
   89 #include <net/bpf.h>
   90 
   91 #include <sys/bus.h>
   92 #include <machine/bus.h>
   93 
   94 #include <dev/usb/usb.h>
   95 #include <dev/usb/usbdi.h>
   96 #include <dev/usb/usbdi_util.h>
   97 #include <dev/usb/usbdivar.h>
   98 #include "usbdevs.h"
   99 #include <dev/usb/usb_ethersubr.h>
  100 
  101 #include <dev/mii/mii.h>
  102 #include <dev/mii/miivar.h>
  103 
  104 /* "device miibus" required.  See GENERIC if you get errors here. */
  105 #include "miibus_if.h"
  106 
  107 /*
  108  * AXE_178_MAX_FRAME_BURST
  109  * max frame burst size for Ax88178 and Ax88772
  110  *      0       2048 bytes
  111  *      1       4096 bytes
  112  *      2       8192 bytes
  113  *      3       16384 bytes
  114  * use the largest your system can handle without usb stalling.
  115  *
  116  * NB: 88772 parts appear to generate lots of input errors with
  117  * a 2K rx buffer and 8K is only slightly faster than 4K on an
  118  * EHCI port on a T42 so change at your own risk.
  119  */
  120 #define AXE_178_MAX_FRAME_BURST 1
  121 
  122 #include <dev/usb/if_axereg.h>
  123 
  124 /*
  125  * Various supported device vendors/products.
  126  */
  127 const struct axe_type axe_devs[] = {
  128         { { USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_UF200}, 0 },
  129         { { USB_VENDOR_ACERCM, USB_PRODUCT_ACERCM_EP1427X2}, 0 },
  130         { { USB_VENDOR_APPLE, USB_PRODUCT_APPLE_ETHERNET}, AX772 },
  131         { { USB_VENDOR_ASIX, USB_PRODUCT_ASIX_AX88172}, 0 },
  132         { { USB_VENDOR_ASIX, USB_PRODUCT_ASIX_AX88772}, AX772 },
  133         { { USB_VENDOR_ASIX, USB_PRODUCT_ASIX_AX88178}, AX178 },
  134         { { USB_VENDOR_ATEN, USB_PRODUCT_ATEN_UC210T}, 0 },
  135         { { USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_F5D5055 }, AX178 },
  136         { { USB_VENDOR_BILLIONTON, USB_PRODUCT_BILLIONTON_USB2AR}, 0},
  137         { { USB_VENDOR_CISCOLINKSYS, USB_PRODUCT_CISCOLINKSYS_USB200MV2}, AX772 },
  138         { { USB_VENDOR_COREGA, USB_PRODUCT_COREGA_FETHER_USB2_TX }, 0},
  139         { { USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DUBE100}, 0 },
  140         { { USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DUBE100B1 }, AX772 },
  141         { { USB_VENDOR_GOODWAY, USB_PRODUCT_GOODWAY_GWUSB2E}, 0 },
  142         { { USB_VENDOR_IODATA, USB_PRODUCT_IODATA_ETGUS2 }, AX178 },
  143         { { USB_VENDOR_JVC, USB_PRODUCT_JVC_MP_PRX1}, 0 },
  144         { { USB_VENDOR_LINKSYS2, USB_PRODUCT_LINKSYS2_USB200M}, 0 },
  145         { { USB_VENDOR_LINKSYS4, USB_PRODUCT_LINKSYS4_USB1000 }, AX178 },
  146         { { USB_VENDOR_MELCO, USB_PRODUCT_MELCO_LUAU2KTX}, 0 },
  147         { { USB_VENDOR_NETGEAR, USB_PRODUCT_NETGEAR_FA120}, 0 },
  148         { { USB_VENDOR_OQO, USB_PRODUCT_OQO_ETHER01PLUS }, AX772 },
  149         { { USB_VENDOR_PLANEX3, USB_PRODUCT_PLANEX3_GU1000T }, AX178 },
  150         { { USB_VENDOR_SYSTEMTALKS, USB_PRODUCT_SYSTEMTALKS_SGCX2UL}, 0 },
  151         { { USB_VENDOR_SITECOM, USB_PRODUCT_SITECOM_LN029}, 0 },
  152         { { USB_VENDOR_SITECOMEU, USB_PRODUCT_SITECOMEU_LN028 }, AX178 }
  153 };
  154 
  155 #define axe_lookup(v, p) ((const struct axe_type *)usb_lookup(axe_devs, v, p))
  156 
  157 static device_probe_t axe_match;
  158 static device_attach_t axe_attach;
  159 static device_detach_t axe_detach;
  160 static device_shutdown_t axe_shutdown;
  161 static miibus_readreg_t axe_miibus_readreg;
  162 static miibus_writereg_t axe_miibus_writereg;
  163 static miibus_statchg_t axe_miibus_statchg;
  164 
  165 static int axe_encap(struct axe_softc *, struct mbuf *, int);
  166 static void axe_rxeof(usbd_xfer_handle, usbd_private_handle, usbd_status);
  167 static void axe_txeof(usbd_xfer_handle, usbd_private_handle, usbd_status);
  168 static void axe_tick(void *);
  169 static void axe_tick_task(void *);
  170 static void axe_start(struct ifnet *);
  171 static int axe_ioctl(struct ifnet *, u_long, caddr_t);
  172 static void axe_init(void *);
  173 static void axe_stop(struct axe_softc *);
  174 static void axe_watchdog(struct ifnet *);
  175 static int axe_cmd(struct axe_softc *, int, int, int, void *);
  176 static int axe_ifmedia_upd(struct ifnet *);
  177 static void axe_ifmedia_sts(struct ifnet *, struct ifmediareq *);
  178 
  179 static void axe_setmulti(struct axe_softc *);
  180 
  181 static device_method_t axe_methods[] = {
  182         /* Device interface */
  183         DEVMETHOD(device_probe,         axe_match),
  184         DEVMETHOD(device_attach,        axe_attach),
  185         DEVMETHOD(device_detach,        axe_detach),
  186         DEVMETHOD(device_shutdown,      axe_shutdown),
  187 
  188         /* bus interface */
  189         DEVMETHOD(bus_print_child,      bus_generic_print_child),
  190         DEVMETHOD(bus_driver_added,     bus_generic_driver_added),
  191 
  192         /* MII interface */
  193         DEVMETHOD(miibus_readreg,       axe_miibus_readreg),
  194         DEVMETHOD(miibus_writereg,      axe_miibus_writereg),
  195         DEVMETHOD(miibus_statchg,       axe_miibus_statchg),
  196 
  197         { 0, 0 }
  198 };
  199 
  200 static driver_t axe_driver = {
  201         "axe",
  202         axe_methods,
  203         sizeof(struct axe_softc)
  204 };
  205 
  206 static devclass_t axe_devclass;
  207 
  208 DRIVER_MODULE(axe, uhub, axe_driver, axe_devclass, usbd_driver_load, 0);
  209 DRIVER_MODULE(miibus, axe, miibus_driver, miibus_devclass, 0, 0);
  210 MODULE_DEPEND(axe, usb, 1, 1, 1);
  211 MODULE_DEPEND(axe, miibus, 1, 1, 1);
  212 
  213 static int
  214 axe_cmd(struct axe_softc *sc, int cmd, int index, int val, void *buf)
  215 {
  216         usb_device_request_t    req;
  217         usbd_status             err;
  218 
  219         AXE_SLEEPLOCKASSERT(sc);
  220         if (sc->axe_dying)
  221                 return(0);
  222 
  223         if (AXE_CMD_DIR(cmd))
  224                 req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
  225         else
  226                 req.bmRequestType = UT_READ_VENDOR_DEVICE;
  227         req.bRequest = AXE_CMD_CMD(cmd);
  228         USETW(req.wValue, val);
  229         USETW(req.wIndex, index);
  230         USETW(req.wLength, AXE_CMD_LEN(cmd));
  231 
  232         err = usbd_do_request(sc->axe_udev, &req, buf);
  233 
  234         if (err)
  235                 return(-1);
  236 
  237         return(0);
  238 }
  239 
  240 static int
  241 axe_miibus_readreg(device_t dev, int phy, int reg)
  242 {
  243         struct axe_softc        *sc = device_get_softc(dev);
  244         usbd_status             err;
  245         u_int16_t               val;
  246 
  247         if (sc->axe_dying)
  248                 return(0);
  249 
  250         AXE_SLEEPLOCKASSERT(sc);
  251 #ifdef notdef
  252         /*
  253          * The chip tells us the MII address of any supported
  254          * PHYs attached to the chip, so only read from those.
  255          */
  256 
  257         if (sc->axe_phyaddrs[0] != AXE_NOPHY && phy != sc->axe_phyaddrs[0])
  258                 return (0);
  259 
  260         if (sc->axe_phyaddrs[1] != AXE_NOPHY && phy != sc->axe_phyaddrs[1])
  261                 return (0);
  262 #endif
  263         if (sc->axe_phyaddrs[0] != 0xFF && sc->axe_phyaddrs[0] != phy)
  264                 return (0);
  265 
  266         AXE_LOCK(sc);
  267         axe_cmd(sc, AXE_CMD_MII_OPMODE_SW, 0, 0, NULL);
  268         err = axe_cmd(sc, AXE_CMD_MII_READ_REG, reg, phy, (void *)&val);
  269         axe_cmd(sc, AXE_CMD_MII_OPMODE_HW, 0, 0, NULL);
  270         AXE_UNLOCK(sc);
  271 
  272         if (err) {
  273                 device_printf(sc->axe_dev, "read PHY failed\n");
  274                 return(-1);
  275         }
  276 
  277         if (val && val != 0xffff)
  278                 sc->axe_phyaddrs[0] = phy;
  279 
  280         return (le16toh(val));
  281 }
  282 
  283 static int
  284 axe_miibus_writereg(device_t dev, int phy, int reg, int val)
  285 {
  286         struct axe_softc        *sc = device_get_softc(dev);
  287         usbd_status             err;
  288 
  289         if (sc->axe_dying)
  290                 return(0);
  291 
  292         AXE_SLEEPLOCKASSERT(sc);
  293         AXE_LOCK(sc);
  294         axe_cmd(sc, AXE_CMD_MII_OPMODE_SW, 0, 0, NULL);
  295         val = htole32(val);
  296         err = axe_cmd(sc, AXE_CMD_MII_WRITE_REG, reg, phy, (void *)&val);
  297         axe_cmd(sc, AXE_CMD_MII_OPMODE_HW, 0, 0, NULL);
  298         AXE_UNLOCK(sc);
  299 
  300         if (err) {
  301                 device_printf(sc->axe_dev, "write PHY failed\n");
  302                 return(-1);
  303         }
  304 
  305         return (0);
  306 }
  307 
  308 static void
  309 axe_miibus_statchg(device_t dev)
  310 {
  311         struct axe_softc        *sc = device_get_softc(dev);
  312         struct mii_data         *mii = GET_MII(sc);
  313         int                     val, err;
  314 
  315         val = (mii->mii_media_active & IFM_GMASK) == IFM_FDX ?
  316             AXE_MEDIA_FULL_DUPLEX : 0;
  317         if (sc->axe_flags & (AX178|AX772)) {
  318                 val |= AXE_178_MEDIA_RX_EN | AXE_178_MEDIA_MAGIC;
  319 
  320                 switch (IFM_SUBTYPE(mii->mii_media_active)) {
  321                 case IFM_1000_T:
  322                         val |= AXE_178_MEDIA_GMII | AXE_178_MEDIA_ENCK;
  323                         break;
  324                 case IFM_100_TX:
  325                         val |= AXE_178_MEDIA_100TX;
  326                         break;
  327                 case IFM_10_T:
  328                         /* doesn't need to be handled */
  329                         break;
  330                 }
  331         }
  332         err = axe_cmd(sc, AXE_CMD_WRITE_MEDIA, 0, val, NULL);
  333         if (err)
  334                 device_printf(dev, "media change failed, error %d\n", err);
  335 }
  336 
  337 /*
  338  * Set media options.
  339  */
  340 static int
  341 axe_ifmedia_upd(struct ifnet *ifp)
  342 {
  343         struct axe_softc        *sc = ifp->if_softc;
  344         struct mii_data         *mii = GET_MII(sc);
  345 
  346         sc->axe_link = 0;
  347         if (mii->mii_instance) {
  348                 struct mii_softc        *miisc;
  349                 LIST_FOREACH(miisc, &mii->mii_phys, mii_list)
  350                          mii_phy_reset(miisc);
  351         }
  352         mii_mediachg(mii);
  353 
  354         return (0);
  355 }
  356 
  357 /*
  358  * Report current media status.
  359  */
  360 static void
  361 axe_ifmedia_sts(struct ifnet *ifp, struct ifmediareq *ifmr)
  362 {
  363         struct axe_softc        *sc = ifp->if_softc;
  364         struct mii_data         *mii = GET_MII(sc);
  365 
  366         mii_pollstat(mii);
  367         ifmr->ifm_active = mii->mii_media_active;
  368         ifmr->ifm_status = mii->mii_media_status;
  369 
  370         return;
  371 }
  372 
  373 static void
  374 axe_setmulti(struct axe_softc *sc)
  375 {
  376         struct ifnet            *ifp;
  377         struct ifmultiaddr      *ifma;
  378         u_int32_t               h = 0;
  379         u_int16_t               rxmode;
  380         u_int8_t                hashtbl[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
  381 
  382         ifp = sc->axe_ifp;
  383 
  384         AXE_LOCK(sc);
  385         axe_cmd(sc, AXE_CMD_RXCTL_READ, 0, 0, (void *)&rxmode);
  386         rxmode = le16toh(rxmode);
  387 
  388         if (ifp->if_flags & IFF_ALLMULTI || ifp->if_flags & IFF_PROMISC) {
  389                 rxmode |= AXE_RXCMD_ALLMULTI;
  390                 axe_cmd(sc, AXE_CMD_RXCTL_WRITE, 0, rxmode, NULL);
  391                 AXE_UNLOCK(sc);
  392                 return;
  393         } else
  394                 rxmode &= ~AXE_RXCMD_ALLMULTI;
  395 
  396         IF_ADDR_LOCK(ifp);
  397         TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link)
  398         {
  399                 if (ifma->ifma_addr->sa_family != AF_LINK)
  400                         continue;
  401                 h = ether_crc32_be(LLADDR((struct sockaddr_dl *)
  402                     ifma->ifma_addr), ETHER_ADDR_LEN) >> 26;
  403                 hashtbl[h / 8] |= 1 << (h % 8);
  404         }
  405         IF_ADDR_UNLOCK(ifp);
  406 
  407         axe_cmd(sc, AXE_CMD_WRITE_MCAST, 0, 0, (void *)&hashtbl);
  408         axe_cmd(sc, AXE_CMD_RXCTL_WRITE, 0, rxmode, NULL);
  409         AXE_UNLOCK(sc);
  410 
  411         return;
  412 }
  413 
  414 static void
  415 axe_ax88178_init(struct axe_softc *sc)
  416 {
  417         int gpio0 = 0, phymode = 0;
  418         u_int16_t eeprom;
  419 
  420         axe_cmd(sc, AXE_CMD_SROM_WR_ENABLE, 0, 0, NULL);
  421         /* XXX magic */
  422         axe_cmd(sc, AXE_CMD_SROM_READ, 0, 0x0017, &eeprom);
  423         eeprom = le16toh(eeprom);
  424         axe_cmd(sc, AXE_CMD_SROM_WR_DISABLE, 0, 0, NULL);
  425 
  426         /* if EEPROM is invalid we have to use to GPIO0 */
  427         if (eeprom == 0xffff) {
  428                 phymode = 0;
  429                 gpio0 = 1;
  430         } else {
  431                 phymode = eeprom & 7;
  432                 gpio0 = (eeprom & 0x80) ? 0 : 1;
  433         }
  434 
  435         axe_cmd(sc, AXE_CMD_WRITE_GPIO, 0, 0x008c, NULL);
  436         usbd_delay_ms(sc->axe_udev, 40);
  437         if ((eeprom >> 8) != 1) {
  438                 axe_cmd(sc, AXE_CMD_WRITE_GPIO, 0, 0x003c, NULL);
  439                 usbd_delay_ms(sc->axe_udev, 30);
  440 
  441                 axe_cmd(sc, AXE_CMD_WRITE_GPIO, 0, 0x001c, NULL);
  442                 usbd_delay_ms(sc->axe_udev, 300);
  443 
  444                 axe_cmd(sc, AXE_CMD_WRITE_GPIO, 0, 0x003c, NULL);
  445                 usbd_delay_ms(sc->axe_udev, 30);
  446         } else {
  447                 axe_cmd(sc, AXE_CMD_WRITE_GPIO, 0, 0x0004, NULL);
  448                 usbd_delay_ms(sc->axe_udev, 30);
  449                 axe_cmd(sc, AXE_CMD_WRITE_GPIO, 0, 0x000c, NULL);
  450                 usbd_delay_ms(sc->axe_udev, 30);
  451         }
  452 
  453         /* soft reset */
  454         axe_cmd(sc, AXE_CMD_SW_RESET_REG, 0, 0, NULL);
  455         usbd_delay_ms(sc->axe_udev, 150);
  456         axe_cmd(sc, AXE_CMD_SW_RESET_REG, 0,
  457             AXE_SW_RESET_PRL | AXE_178_RESET_MAGIC, NULL);
  458         usbd_delay_ms(sc->axe_udev, 150);
  459         axe_cmd(sc, AXE_CMD_RXCTL_WRITE, 0, 0, NULL);
  460 }
  461 
  462 static void
  463 axe_ax88772_init(struct axe_softc *sc)
  464 {
  465         axe_cmd(sc, AXE_CMD_WRITE_GPIO, 0, 0x00b0, NULL);
  466         usbd_delay_ms(sc->axe_udev, 40);
  467 
  468         if (sc->axe_phyaddrs[1] == AXE_INTPHY) {
  469                 /* ask for embedded PHY */
  470                 axe_cmd(sc, AXE_CMD_SW_PHY_SELECT, 0, 0x01, NULL);
  471                 usbd_delay_ms(sc->axe_udev, 10);
  472 
  473                 /* power down and reset state, pin reset state */
  474                 axe_cmd(sc, AXE_CMD_SW_RESET_REG, 0, AXE_SW_RESET_CLEAR, NULL);
  475                 usbd_delay_ms(sc->axe_udev, 60);
  476 
  477                 /* power down/reset state, pin operating state */
  478                 axe_cmd(sc, AXE_CMD_SW_RESET_REG, 0,
  479                     AXE_SW_RESET_IPPD | AXE_SW_RESET_PRL, NULL);
  480                 usbd_delay_ms(sc->axe_udev, 150);
  481 
  482                 /* power up, reset */
  483                 axe_cmd(sc, AXE_CMD_SW_RESET_REG, 0, AXE_SW_RESET_PRL, NULL);
  484 
  485                 /* power up, operating */
  486                 axe_cmd(sc, AXE_CMD_SW_RESET_REG, 0,
  487                     AXE_SW_RESET_IPRL | AXE_SW_RESET_PRL, NULL);
  488         } else {
  489                 /* ask for external PHY */
  490                 axe_cmd(sc, AXE_CMD_SW_PHY_SELECT, 0, 0x00, NULL);
  491                 usbd_delay_ms(sc->axe_udev, 10);
  492 
  493                 /* power down/reset state, pin operating state */
  494                 axe_cmd(sc, AXE_CMD_SW_RESET_REG, 0,
  495                     AXE_SW_RESET_IPPD | AXE_SW_RESET_PRL, NULL);
  496         }
  497 
  498         usbd_delay_ms(sc->axe_udev, 150);
  499         axe_cmd(sc, AXE_CMD_RXCTL_WRITE, 0, 0, NULL);
  500 }
  501 
  502 static void
  503 axe_reset(struct axe_softc *sc)
  504 {
  505         if (sc->axe_dying)
  506                 return;
  507 
  508         if (usbd_set_config_no(sc->axe_udev, AXE_CONFIG_NO, 1) ||
  509             usbd_device2interface_handle(sc->axe_udev, AXE_IFACE_IDX,
  510             &sc->axe_iface)) {
  511                 device_printf(sc->axe_dev, "getting interface handle failed\n");
  512         }
  513 
  514         /* Wait a little while for the chip to get its brains in order. */
  515         DELAY(1000);
  516         return;
  517 }
  518 
  519 /*
  520  * Probe for a AX88172 chip.
  521  */
  522 static int
  523 axe_match(device_t self)
  524 {
  525         struct usb_attach_arg *uaa = device_get_ivars(self);
  526 
  527         if (!uaa->iface)
  528                 return(UMATCH_NONE);
  529         return (axe_lookup(uaa->vendor, uaa->product) != NULL ?
  530                 UMATCH_VENDOR_PRODUCT : UMATCH_NONE);
  531 }
  532 
  533 /*
  534  * Attach the interface. Allocate softc structures, do ifmedia
  535  * setup and ethernet/BPF attach.
  536  */
  537 static int
  538 axe_attach(device_t self)
  539 {
  540         struct axe_softc *sc = device_get_softc(self);
  541         struct usb_attach_arg *uaa = device_get_ivars(self);
  542         const struct axe_type *type;
  543         u_char                  eaddr[ETHER_ADDR_LEN];
  544         struct ifnet            *ifp;
  545         usb_interface_descriptor_t      *id;
  546         usb_endpoint_descriptor_t       *ed;
  547         int                     i;
  548 
  549         sc->axe_udev = uaa->device;
  550         sc->axe_dev = self;
  551         type = axe_lookup(uaa->vendor, uaa->product);
  552         if (type != NULL)
  553                 sc->axe_flags = type->axe_flags;
  554 
  555         if (usbd_set_config_no(sc->axe_udev, AXE_CONFIG_NO, 1)) {
  556                 device_printf(sc->axe_dev, "getting interface handle failed\n");
  557                 return ENXIO;
  558         }
  559 
  560         usb_init_task(&sc->axe_tick_task, axe_tick_task, sc);
  561 
  562         if (usbd_device2interface_handle(uaa->device,
  563             AXE_IFACE_IDX, &sc->axe_iface)) {
  564                 device_printf(sc->axe_dev, "getting interface handle failed\n");
  565                 return ENXIO;
  566         }
  567 
  568         sc->axe_boundary = 64;
  569         if (sc->axe_flags & (AX178|AX772)) {
  570                 if (sc->axe_udev->speed == USB_SPEED_HIGH) {
  571                         sc->axe_bufsz = AXE_178_MAX_BUFSZ;
  572                         sc->axe_boundary = 512;
  573                 } else
  574                         sc->axe_bufsz = AXE_178_MIN_BUFSZ;
  575         } else
  576                 sc->axe_bufsz = AXE_172_BUFSZ;
  577 { /* XXX debug */
  578 device_printf(sc->axe_dev, "%s, bufsz %d, boundary %d\n",
  579         sc->axe_flags & AX178 ? "AX88178" :
  580         sc->axe_flags & AX772 ? "AX88772" : "AX88172",
  581         sc->axe_bufsz, sc->axe_boundary);
  582 }
  583 
  584         id = usbd_get_interface_descriptor(sc->axe_iface);
  585 
  586         /* Find endpoints. */
  587         for (i = 0; i < id->bNumEndpoints; i++) {
  588                 ed = usbd_interface2endpoint_descriptor(sc->axe_iface, i);
  589                 if (!ed) {
  590                         device_printf(sc->axe_dev, "couldn't get ep %d\n", i);
  591                         return ENXIO;
  592                 }
  593                 if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN &&
  594                     UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) {
  595                         sc->axe_ed[AXE_ENDPT_RX] = ed->bEndpointAddress;
  596                 } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT &&
  597                            UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) {
  598                         sc->axe_ed[AXE_ENDPT_TX] = ed->bEndpointAddress;
  599                 } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN &&
  600                            UE_GET_XFERTYPE(ed->bmAttributes) == UE_INTERRUPT) {
  601                         sc->axe_ed[AXE_ENDPT_INTR] = ed->bEndpointAddress;
  602                 }
  603         }
  604 
  605         mtx_init(&sc->axe_mtx, device_get_nameunit(self), MTX_NETWORK_LOCK,
  606             MTX_DEF | MTX_RECURSE);
  607         sx_init(&sc->axe_sleeplock, device_get_nameunit(self));
  608         AXE_SLEEPLOCK(sc);
  609         AXE_LOCK(sc);
  610 
  611         /* We need the PHYID for the init dance in some cases */
  612         axe_cmd(sc, AXE_CMD_READ_PHYID, 0, 0, (void *)&sc->axe_phyaddrs);
  613 
  614         if (sc->axe_flags & AX178)
  615                 axe_ax88178_init(sc);
  616         else if (sc->axe_flags & AX772)
  617                 axe_ax88772_init(sc);
  618 
  619         /*
  620          * Get station address.
  621          */
  622         if (sc->axe_flags & (AX178|AX772))
  623                 axe_cmd(sc, AXE_178_CMD_READ_NODEID, 0, 0, &eaddr);
  624         else
  625                 axe_cmd(sc, AXE_172_CMD_READ_NODEID, 0, 0, &eaddr);
  626 
  627         /*
  628          * Fetch IPG values.
  629          */
  630         axe_cmd(sc, AXE_CMD_READ_IPG012, 0, 0, (void *)&sc->axe_ipgs);
  631 
  632         /*
  633          * Work around broken adapters that appear to lie about
  634          * their PHY addresses.
  635          */
  636         sc->axe_phyaddrs[0] = sc->axe_phyaddrs[1] = 0xFF;
  637 
  638         ifp = sc->axe_ifp = if_alloc(IFT_ETHER);
  639         if (ifp == NULL) {
  640                 device_printf(sc->axe_dev, "can not if_alloc()\n");
  641                 AXE_UNLOCK(sc);
  642                 AXE_SLEEPUNLOCK(sc);
  643                 sx_destroy(&sc->axe_sleeplock);
  644                 mtx_destroy(&sc->axe_mtx);
  645                 return ENXIO;
  646         }
  647         ifp->if_softc = sc;
  648         if_initname(ifp, "axe", device_get_unit(sc->axe_dev));
  649         ifp->if_mtu = ETHERMTU;
  650         ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST |
  651             IFF_NEEDSGIANT;
  652         ifp->if_ioctl = axe_ioctl;
  653         ifp->if_start = axe_start;
  654         ifp->if_watchdog = axe_watchdog;
  655         ifp->if_init = axe_init;
  656         IFQ_SET_MAXLEN(&ifp->if_snd, IFQ_MAXLEN);
  657         ifp->if_snd.ifq_drv_maxlen = IFQ_MAXLEN;
  658         IFQ_SET_READY(&ifp->if_snd);
  659 
  660         if (mii_phy_probe(self, &sc->axe_miibus,
  661             axe_ifmedia_upd, axe_ifmedia_sts)) {
  662                 device_printf(sc->axe_dev, "MII without any PHY!\n");
  663                 if_free(ifp);
  664                 AXE_UNLOCK(sc);
  665                 AXE_SLEEPUNLOCK(sc);
  666                 sx_destroy(&sc->axe_sleeplock);
  667                 mtx_destroy(&sc->axe_mtx);
  668                 return ENXIO;
  669         }
  670 
  671         /*
  672          * Call MI attach routine.
  673          */
  674 
  675         ether_ifattach(ifp, eaddr);
  676         callout_handle_init(&sc->axe_stat_ch);
  677         usb_register_netisr();
  678 
  679         sc->axe_dying = 0;
  680 
  681         AXE_UNLOCK(sc);
  682         AXE_SLEEPUNLOCK(sc);
  683 
  684         return 0;
  685 }
  686 
  687 static int
  688 axe_detach(device_t dev)
  689 {
  690         struct axe_softc        *sc;
  691         struct ifnet            *ifp;
  692 
  693         sc = device_get_softc(dev);
  694         AXE_LOCK(sc);
  695         ifp = sc->axe_ifp;
  696 
  697         sc->axe_dying = 1;
  698         untimeout(axe_tick, sc, sc->axe_stat_ch);
  699         usb_rem_task(sc->axe_udev, &sc->axe_tick_task);
  700 
  701         ether_ifdetach(ifp);
  702         if_free(ifp);
  703 
  704         if (sc->axe_ep[AXE_ENDPT_TX] != NULL)
  705                 usbd_abort_pipe(sc->axe_ep[AXE_ENDPT_TX]);
  706         if (sc->axe_ep[AXE_ENDPT_RX] != NULL)
  707                 usbd_abort_pipe(sc->axe_ep[AXE_ENDPT_RX]);
  708         if (sc->axe_ep[AXE_ENDPT_INTR] != NULL)
  709                 usbd_abort_pipe(sc->axe_ep[AXE_ENDPT_INTR]);
  710 
  711         AXE_UNLOCK(sc);
  712         sx_destroy(&sc->axe_sleeplock);
  713         mtx_destroy(&sc->axe_mtx);
  714 
  715         return(0);
  716 }
  717 
  718 static int
  719 axe_rx_list_init(struct axe_softc *sc)
  720 {
  721         struct axe_cdata        *cd;
  722         struct axe_chain        *c;
  723         int                     i;
  724 
  725         cd = &sc->axe_cdata;
  726         for (i = 0; i < AXE_RX_LIST_CNT; i++) {
  727                 c = &cd->axe_rx_chain[i];
  728                 c->axe_sc = sc;
  729                 c->axe_idx = i;
  730                 c->axe_mbuf = NULL;
  731                 if (c->axe_xfer == NULL) {
  732                         c->axe_xfer = usbd_alloc_xfer(sc->axe_udev);
  733                         if (c->axe_xfer == NULL)
  734                                 return (ENOBUFS);
  735                         c->axe_buf = usbd_alloc_buffer(c->axe_xfer,
  736                             sc->axe_bufsz);
  737                         if (c->axe_buf == NULL) {
  738                                 usbd_free_xfer(c->axe_xfer);
  739                                 return (ENOBUFS);
  740                         }
  741                 }
  742         }
  743 
  744         return (0);
  745 }
  746 
  747 static void
  748 axe_rx_list_free(struct axe_softc *sc)
  749 {
  750         int i;
  751 
  752         for (i = 0; i < AXE_RX_LIST_CNT; i++) {
  753                 if (sc->axe_cdata.axe_rx_chain[i].axe_mbuf != NULL) {
  754                         m_freem(sc->axe_cdata.axe_rx_chain[i].axe_mbuf);
  755                         sc->axe_cdata.axe_rx_chain[i].axe_mbuf = NULL;
  756                 }
  757                 if (sc->axe_cdata.axe_rx_chain[i].axe_xfer != NULL) {
  758                         usbd_free_xfer(sc->axe_cdata.axe_rx_chain[i].axe_xfer);
  759                         sc->axe_cdata.axe_rx_chain[i].axe_xfer = NULL;
  760                 }
  761         }
  762 }
  763 
  764 static int
  765 axe_tx_list_init(struct axe_softc *sc)
  766 {
  767         struct axe_cdata        *cd;
  768         struct axe_chain        *c;
  769         int                     i;
  770 
  771         cd = &sc->axe_cdata;
  772         for (i = 0; i < AXE_TX_LIST_CNT; i++) {
  773                 c = &cd->axe_tx_chain[i];
  774                 c->axe_sc = sc;
  775                 c->axe_idx = i;
  776                 c->axe_mbuf = NULL;
  777                 if (c->axe_xfer == NULL) {
  778                         c->axe_xfer = usbd_alloc_xfer(sc->axe_udev);
  779                         if (c->axe_xfer == NULL)
  780                                 return (ENOBUFS);
  781                         c->axe_buf = usbd_alloc_buffer(c->axe_xfer,
  782                             sc->axe_bufsz);
  783                         if (c->axe_buf == NULL) {
  784                                 usbd_free_xfer(c->axe_xfer);
  785                                 return (ENOBUFS);
  786                         }
  787                 }
  788         }
  789 
  790         return (0);
  791 }
  792 
  793 static void
  794 axe_tx_list_free(struct axe_softc *sc)
  795 {
  796         int i;
  797 
  798         /* Free TX resources. */
  799         for (i = 0; i < AXE_TX_LIST_CNT; i++) {
  800                 if (sc->axe_cdata.axe_tx_chain[i].axe_mbuf != NULL) {
  801                         m_freem(sc->axe_cdata.axe_tx_chain[i].axe_mbuf);
  802                         sc->axe_cdata.axe_tx_chain[i].axe_mbuf = NULL;
  803                 }
  804                 if (sc->axe_cdata.axe_tx_chain[i].axe_xfer != NULL) {
  805                         usbd_free_xfer(sc->axe_cdata.axe_tx_chain[i].axe_xfer);
  806                         sc->axe_cdata.axe_tx_chain[i].axe_xfer = NULL;
  807                 }
  808         }
  809 }
  810 
  811 /*
  812  * A frame has been uploaded: pass the resulting mbuf chain up to
  813  * the higher level protocols.
  814  */
  815 static void
  816 axe_rxeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)
  817 {
  818         struct axe_softc        *sc;
  819         struct axe_chain        *c = (struct axe_chain *) priv;
  820         struct mbuf             *m;
  821         u_char                  *buf;
  822         struct ifnet            *ifp;
  823         struct axe_sframe_hdr   *hdr;
  824         int                     total_len = 0;
  825         int                     pktlen = 0;
  826 
  827         sc = c->axe_sc;
  828         AXE_LOCK(sc);
  829         ifp = sc->axe_ifp;
  830 
  831         if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) {
  832                 AXE_UNLOCK(sc);
  833                 return;
  834         }
  835 
  836         if (status != USBD_NORMAL_COMPLETION) {
  837                 if (status == USBD_NOT_STARTED || status == USBD_CANCELLED) {
  838                         AXE_UNLOCK(sc);
  839                         return;
  840                 }
  841                 if (usbd_ratecheck(&sc->axe_rx_notice))
  842                         device_printf(sc->axe_dev, "usb error on rx: %s\n",
  843                             usbd_errstr(status));
  844                 if (status == USBD_STALLED)
  845                         usbd_clear_endpoint_stall(sc->axe_ep[AXE_ENDPT_RX]);
  846                 goto done;
  847         }
  848 
  849         usbd_get_xfer_status(xfer, NULL, NULL, &total_len, NULL);
  850 
  851         buf = c->axe_buf;
  852 
  853         do {
  854                 if (sc->axe_flags & (AX178|AX772)) {
  855                         if (total_len < sizeof(struct axe_sframe_hdr)) {
  856                                 ifp->if_ierrors++;
  857                                 goto done;
  858                         }
  859                         if ((pktlen % 2) != 0)
  860                                 pktlen++;
  861                         buf += pktlen;
  862 
  863                         hdr = (struct axe_sframe_hdr *) buf;
  864                         total_len -= sizeof(struct axe_sframe_hdr);
  865                         if ((hdr->len ^ hdr->ilen) != 0xffff) {
  866                                 ifp->if_ierrors++;
  867                                 goto done;
  868                         }
  869                         pktlen = le16toh(hdr->len);
  870                         if (pktlen > total_len) {
  871                                 ifp->if_ierrors++;
  872                                 goto done;
  873                         }
  874 
  875                         buf += sizeof(struct axe_sframe_hdr);
  876                         total_len -= pktlen + (pktlen % 2);
  877                 } else {
  878                         pktlen = total_len;
  879                         total_len = 0;
  880                 }
  881 
  882                 if (pktlen < sizeof(struct ether_header)) {
  883                         ifp->if_ierrors++;
  884                         goto done;
  885                 }
  886                 m = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR);
  887                 if (m == NULL) {
  888                         ifp->if_ierrors++;
  889                         goto done;
  890                 }
  891                 m->m_data += ETHER_ALIGN;
  892                 memcpy(mtod(m, void *), buf, pktlen);
  893                 m->m_pkthdr.len = m->m_len = pktlen;
  894                 m->m_pkthdr.rcvif = ifp;
  895 
  896                 ifp->if_input(ifp, m);
  897                 ifp->if_ipackets++;
  898         } while (total_len > 0);
  899         /* fall thru... */
  900 done:
  901         /* Setup new transfer. */
  902         usbd_setup_xfer(xfer, sc->axe_ep[AXE_ENDPT_RX],
  903             c, c->axe_buf, sc->axe_bufsz, USBD_SHORT_XFER_OK | USBD_NO_COPY,
  904             USBD_NO_TIMEOUT, axe_rxeof);
  905         usbd_transfer(xfer);
  906         AXE_UNLOCK(sc);
  907 
  908         return;
  909 }
  910 
  911 /*
  912  * A frame was downloaded to the chip. It's safe for us to clean up
  913  * the list buffers.
  914  */
  915 
  916 static void
  917 axe_txeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)
  918 {
  919         struct axe_softc        *sc;
  920         struct axe_chain        *c;
  921         struct ifnet            *ifp;
  922         usbd_status             err;
  923 
  924         c = priv;
  925         sc = c->axe_sc;
  926         AXE_LOCK(sc);
  927         ifp = sc->axe_ifp;
  928 
  929         if (status != USBD_NORMAL_COMPLETION) {
  930                 if (status == USBD_NOT_STARTED || status == USBD_CANCELLED) {
  931                         AXE_UNLOCK(sc);
  932                         return;
  933                 }
  934                 device_printf(sc->axe_dev, "usb error on tx: %s\n",
  935                     usbd_errstr(status));
  936                 if (status == USBD_STALLED)
  937                         usbd_clear_endpoint_stall(sc->axe_ep[AXE_ENDPT_TX]);
  938                 AXE_UNLOCK(sc);
  939                 return;
  940         }
  941 
  942         ifp->if_timer = 0;
  943         ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
  944         usbd_get_xfer_status(c->axe_xfer, NULL, NULL, NULL, &err);
  945 
  946         if (c->axe_mbuf != NULL) {
  947                 m_freem(c->axe_mbuf);
  948                 c->axe_mbuf = NULL;
  949         }
  950 
  951         if (err)
  952                 ifp->if_oerrors++;
  953         else
  954                 ifp->if_opackets++;
  955 
  956         AXE_UNLOCK(sc);
  957 
  958         if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd))
  959                 axe_start(ifp);
  960 
  961         return;
  962 }
  963 
  964 static void
  965 axe_tick(void *xsc)
  966 {
  967         struct axe_softc *sc = xsc;
  968 
  969         if (sc == NULL)
  970                 return;
  971         if (sc->axe_dying)
  972                 return;
  973 
  974         /* Perform periodic stuff in process context */
  975         usb_add_task(sc->axe_udev, &sc->axe_tick_task, USB_TASKQ_DRIVER);
  976 }
  977 
  978 static void
  979 axe_tick_task(void *xsc)
  980 {
  981         struct axe_softc        *sc;
  982         struct ifnet            *ifp;
  983         struct mii_data         *mii;
  984 
  985         sc = xsc;
  986 
  987         if (sc == NULL)
  988                 return;
  989 
  990         AXE_SLEEPLOCK(sc);
  991         AXE_LOCK(sc);
  992 
  993         ifp = sc->axe_ifp;
  994         mii = GET_MII(sc);
  995         if (mii == NULL) {
  996                 AXE_UNLOCK(sc);
  997                 AXE_SLEEPUNLOCK(sc);
  998                 return;
  999         }
 1000 
 1001         mii_tick(mii);
 1002         if (!sc->axe_link && mii->mii_media_status & IFM_ACTIVE &&
 1003             IFM_SUBTYPE(mii->mii_media_active) != IFM_NONE) {
 1004                 sc->axe_link++;
 1005                 if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd))
 1006                         axe_start(ifp);
 1007         }
 1008 
 1009         sc->axe_stat_ch = timeout(axe_tick, sc, hz);
 1010 
 1011         AXE_UNLOCK(sc);
 1012         AXE_SLEEPUNLOCK(sc);
 1013 
 1014         return;
 1015 }
 1016 
 1017 static int
 1018 axe_encap(struct axe_softc *sc, struct mbuf *m, int idx)
 1019 {
 1020         struct axe_chain        *c;
 1021         usbd_status             err;
 1022         struct axe_sframe_hdr   hdr;
 1023         int                     length;
 1024 
 1025         c = &sc->axe_cdata.axe_tx_chain[idx];
 1026 
 1027         /*
 1028          * Copy the mbuf data into a contiguous buffer, leaving two
 1029          * bytes at the beginning to hold the frame length.
 1030          */
 1031         if (sc->axe_flags & (AX178|AX772)) {
 1032                 hdr.len = htole16(m->m_pkthdr.len);
 1033                 hdr.ilen = ~hdr.len;
 1034 
 1035                 memcpy(c->axe_buf, &hdr, sizeof(hdr));
 1036                 length = sizeof(hdr);
 1037 
 1038                 m_copydata(m, 0, m->m_pkthdr.len, c->axe_buf + length);
 1039                 length += m->m_pkthdr.len;
 1040 
 1041                 if ((length % sc->axe_boundary) == 0) {
 1042                         hdr.len = 0;
 1043                         hdr.ilen = 0xffff;
 1044                         memcpy(c->axe_buf + length, &hdr, sizeof(hdr));
 1045                         length += sizeof(hdr);
 1046                 }
 1047         } else {
 1048                 m_copydata(m, 0, m->m_pkthdr.len, c->axe_buf);
 1049                 length = m->m_pkthdr.len;
 1050         }
 1051         c->axe_mbuf = m;
 1052 
 1053         usbd_setup_xfer(c->axe_xfer, sc->axe_ep[AXE_ENDPT_TX],
 1054             c, c->axe_buf, length, USBD_FORCE_SHORT_XFER, 10000, axe_txeof);
 1055 
 1056         /* Transmit */
 1057         err = usbd_transfer(c->axe_xfer);
 1058         if (err != USBD_IN_PROGRESS) {
 1059                 /* XXX probably don't want to sleep here */
 1060                 AXE_SLEEPLOCK(sc);
 1061                 axe_stop(sc);
 1062                 AXE_SLEEPUNLOCK(sc);
 1063                 return(EIO);
 1064         }
 1065 
 1066         sc->axe_cdata.axe_tx_cnt++;
 1067 
 1068         return(0);
 1069 }
 1070 
 1071 static void
 1072 axe_start(struct ifnet *ifp)
 1073 {
 1074         struct axe_softc        *sc;
 1075         struct mbuf             *m_head = NULL;
 1076 
 1077         sc = ifp->if_softc;
 1078         AXE_LOCK(sc);
 1079 
 1080         if (!sc->axe_link) {
 1081                 AXE_UNLOCK(sc);
 1082                 return;
 1083         }
 1084 
 1085         if (ifp->if_drv_flags & IFF_DRV_OACTIVE) {
 1086                 AXE_UNLOCK(sc);
 1087                 return;
 1088         }
 1089 
 1090         IFQ_DRV_DEQUEUE(&ifp->if_snd, m_head);
 1091         if (m_head == NULL) {
 1092                 AXE_UNLOCK(sc);
 1093                 return;
 1094         }
 1095 
 1096         if (axe_encap(sc, m_head, 0)) {
 1097                 IFQ_DRV_PREPEND(&ifp->if_snd, m_head);
 1098                 ifp->if_drv_flags |= IFF_DRV_OACTIVE;
 1099                 AXE_UNLOCK(sc);
 1100                 return;
 1101         }
 1102 
 1103         /*
 1104          * If there's a BPF listener, bounce a copy of this frame
 1105          * to him.
 1106          */
 1107         BPF_MTAP(ifp, m_head);
 1108 
 1109         ifp->if_drv_flags |= IFF_DRV_OACTIVE;
 1110 
 1111         /*
 1112          * Set a timeout in case the chip goes out to lunch.
 1113          */
 1114         ifp->if_timer = 5;
 1115         AXE_UNLOCK(sc);
 1116 
 1117         return;
 1118 }
 1119 
 1120 static void
 1121 axe_init(void *xsc)
 1122 {
 1123         struct axe_softc        *sc = xsc;
 1124         struct ifnet            *ifp = sc->axe_ifp;
 1125         struct axe_chain        *c;
 1126         usbd_status             err;
 1127         int                     i;
 1128         int                     rxmode;
 1129 
 1130         if (ifp->if_drv_flags & IFF_DRV_RUNNING)
 1131                 return;
 1132 
 1133         AXE_SLEEPLOCK(sc);
 1134         AXE_LOCK(sc);
 1135 
 1136         /*
 1137          * Cancel pending I/O and free all RX/TX buffers.
 1138          */
 1139 
 1140         axe_reset(sc);
 1141 
 1142 #ifdef notdef
 1143         /* Set MAC address */
 1144         axe_mac(sc, IF_LLADDR(sc->axe_ifp), 1);
 1145 #endif
 1146 
 1147         /* Enable RX logic. */
 1148 
 1149         /* Init TX ring. */
 1150         if (axe_tx_list_init(sc) == ENOBUFS) {
 1151                 device_printf(sc->axe_dev, "tx list init failed\n");
 1152                 AXE_UNLOCK(sc);
 1153                 AXE_SLEEPUNLOCK(sc);
 1154                 return;
 1155         }
 1156 
 1157         /* Init RX ring. */
 1158         if (axe_rx_list_init(sc) == ENOBUFS) {
 1159                 device_printf(sc->axe_dev, "rx list init failed\n");
 1160                 AXE_UNLOCK(sc);
 1161                 AXE_SLEEPUNLOCK(sc);
 1162                 return;
 1163         }
 1164 
 1165         /* Set transmitter IPG values */
 1166         if (sc->axe_flags & (AX178|AX772)) {
 1167                 axe_cmd(sc, AXE_178_CMD_WRITE_IPG012, sc->axe_ipgs[2],
 1168                     (sc->axe_ipgs[1]<<8) | sc->axe_ipgs[0], NULL);
 1169         } else {
 1170                 axe_cmd(sc, AXE_172_CMD_WRITE_IPG0, 0, sc->axe_ipgs[0], NULL);
 1171                 axe_cmd(sc, AXE_172_CMD_WRITE_IPG1, 0, sc->axe_ipgs[1], NULL);
 1172                 axe_cmd(sc, AXE_172_CMD_WRITE_IPG2, 0, sc->axe_ipgs[2], NULL);
 1173         }
 1174 
 1175         /* Enable receiver, set RX mode */
 1176         rxmode = AXE_RXCMD_MULTICAST|AXE_RXCMD_ENABLE;
 1177         if (sc->axe_flags & (AX178|AX772)) {
 1178                 if (sc->axe_bufsz == AXE_178_MAX_BUFSZ)
 1179                         rxmode |= AXE_178_RXCMD_MFB;
 1180         } else
 1181                 rxmode |= AXE_172_RXCMD_UNICAST;
 1182 
 1183         /* If we want promiscuous mode, set the allframes bit. */
 1184         if (ifp->if_flags & IFF_PROMISC)
 1185                 rxmode |= AXE_RXCMD_PROMISC;
 1186 
 1187         if (ifp->if_flags & IFF_BROADCAST)
 1188                 rxmode |= AXE_RXCMD_BROADCAST;
 1189 
 1190         axe_cmd(sc, AXE_CMD_RXCTL_WRITE, 0, rxmode, NULL);
 1191 
 1192         /* Load the multicast filter. */
 1193         axe_setmulti(sc);
 1194 
 1195         /* Open RX and TX pipes. */
 1196         err = usbd_open_pipe(sc->axe_iface, sc->axe_ed[AXE_ENDPT_RX],
 1197             USBD_EXCLUSIVE_USE, &sc->axe_ep[AXE_ENDPT_RX]);
 1198         if (err) {
 1199                 device_printf(sc->axe_dev, "open rx pipe failed: %s\n",
 1200                     usbd_errstr(err));
 1201                 AXE_UNLOCK(sc);
 1202                 AXE_SLEEPUNLOCK(sc);
 1203                 return;
 1204         }
 1205 
 1206         err = usbd_open_pipe(sc->axe_iface, sc->axe_ed[AXE_ENDPT_TX],
 1207             USBD_EXCLUSIVE_USE, &sc->axe_ep[AXE_ENDPT_TX]);
 1208         if (err) {
 1209                 device_printf(sc->axe_dev, "open tx pipe failed: %s\n",
 1210                     usbd_errstr(err));
 1211                 AXE_UNLOCK(sc);
 1212                 AXE_SLEEPUNLOCK(sc);
 1213                 return;
 1214         }
 1215 
 1216         /* Start up the receive pipe. */
 1217         for (i = 0; i < AXE_RX_LIST_CNT; i++) {
 1218                 c = &sc->axe_cdata.axe_rx_chain[i];
 1219                 usbd_setup_xfer(c->axe_xfer, sc->axe_ep[AXE_ENDPT_RX],
 1220                     c, c->axe_buf, sc->axe_bufsz,
 1221                     USBD_SHORT_XFER_OK | USBD_NO_COPY,
 1222                     USBD_NO_TIMEOUT, axe_rxeof);
 1223                 usbd_transfer(c->axe_xfer);
 1224         }
 1225 
 1226         ifp->if_drv_flags |= IFF_DRV_RUNNING;
 1227         ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
 1228 
 1229         AXE_UNLOCK(sc);
 1230         AXE_SLEEPUNLOCK(sc);
 1231 
 1232         sc->axe_stat_ch = timeout(axe_tick, sc, hz);
 1233 
 1234         return;
 1235 }
 1236 
 1237 static int
 1238 axe_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
 1239 {
 1240         struct axe_softc        *sc = ifp->if_softc;
 1241         struct ifreq            *ifr = (struct ifreq *)data;
 1242         struct mii_data         *mii;
 1243         u_int16_t               rxmode;
 1244         int                     error = 0;
 1245 
 1246         switch(command) {
 1247         case SIOCSIFFLAGS:
 1248                 if (ifp->if_flags & IFF_UP) {
 1249                         if (ifp->if_drv_flags & IFF_DRV_RUNNING &&
 1250                             ifp->if_flags & IFF_PROMISC &&
 1251                             !(sc->axe_if_flags & IFF_PROMISC)) {
 1252                                 AXE_SLEEPLOCK(sc);
 1253                                 AXE_LOCK(sc);
 1254                                 axe_cmd(sc, AXE_CMD_RXCTL_READ,
 1255                                         0, 0, (void *)&rxmode);
 1256                                 rxmode = le16toh(rxmode);
 1257                                 rxmode |= AXE_RXCMD_PROMISC;
 1258                                 axe_cmd(sc, AXE_CMD_RXCTL_WRITE,
 1259                                         0, rxmode, NULL);
 1260                                 AXE_UNLOCK(sc);
 1261                                 axe_setmulti(sc);
 1262                                 AXE_SLEEPUNLOCK(sc);
 1263                         } else if (ifp->if_drv_flags & IFF_DRV_RUNNING &&
 1264                             !(ifp->if_flags & IFF_PROMISC) &&
 1265                             sc->axe_if_flags & IFF_PROMISC) {
 1266                                 AXE_SLEEPLOCK(sc);
 1267                                 AXE_LOCK(sc);
 1268                                 axe_cmd(sc, AXE_CMD_RXCTL_READ,
 1269                                         0, 0, (void *)&rxmode);
 1270                                 rxmode = le16toh(rxmode);
 1271                                 rxmode &= ~AXE_RXCMD_PROMISC;
 1272                                 axe_cmd(sc, AXE_CMD_RXCTL_WRITE,
 1273                                         0, rxmode, NULL);
 1274                                 AXE_UNLOCK(sc);
 1275                                 axe_setmulti(sc);
 1276                                 AXE_SLEEPUNLOCK(sc);
 1277                         } else if (!(ifp->if_drv_flags & IFF_DRV_RUNNING))
 1278                                 axe_init(sc);
 1279                 } else {
 1280                         if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
 1281                                 AXE_SLEEPLOCK(sc);
 1282                                 axe_stop(sc);
 1283                                 AXE_SLEEPUNLOCK(sc);
 1284                         }
 1285                 }
 1286                 sc->axe_if_flags = ifp->if_flags;
 1287                 error = 0;
 1288                 break;
 1289         case SIOCADDMULTI:
 1290         case SIOCDELMULTI:
 1291                 AXE_SLEEPLOCK(sc);
 1292                 axe_setmulti(sc);
 1293                 AXE_SLEEPUNLOCK(sc);
 1294                 error = 0;
 1295                 break;
 1296         case SIOCGIFMEDIA:
 1297         case SIOCSIFMEDIA:
 1298                 AXE_SLEEPLOCK(sc);
 1299                 mii = GET_MII(sc);
 1300                 error = ifmedia_ioctl(ifp, ifr, &mii->mii_media, command);
 1301                 AXE_SLEEPUNLOCK(sc);
 1302                 break;
 1303 
 1304         default:
 1305                 error = ether_ioctl(ifp, command, data);
 1306                 break;
 1307         }
 1308 
 1309         return(error);
 1310 }
 1311 
 1312 static void
 1313 axe_watchdog(struct ifnet *ifp)
 1314 {
 1315         struct axe_softc        *sc;
 1316         struct axe_chain        *c;
 1317         usbd_status             stat;
 1318 
 1319         sc = ifp->if_softc;
 1320         AXE_LOCK(sc);
 1321 
 1322         ifp->if_oerrors++;
 1323         device_printf(sc->axe_dev, "watchdog timeout\n");
 1324 
 1325         c = &sc->axe_cdata.axe_tx_chain[0];
 1326         usbd_get_xfer_status(c->axe_xfer, NULL, NULL, NULL, &stat);
 1327         axe_txeof(c->axe_xfer, c, stat);
 1328 
 1329         AXE_UNLOCK(sc);
 1330 
 1331         if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd))
 1332                 axe_start(ifp);
 1333 
 1334         return;
 1335 }
 1336 
 1337 /*
 1338  * Stop the adapter and free any mbufs allocated to the
 1339  * RX and TX lists.
 1340  */
 1341 static void
 1342 axe_stop(struct axe_softc *sc)
 1343 {
 1344         usbd_status             err;
 1345         struct ifnet            *ifp;
 1346 
 1347         AXE_SLEEPLOCKASSERT(sc);
 1348         AXE_LOCK(sc);
 1349 
 1350         ifp = sc->axe_ifp;
 1351         ifp->if_timer = 0;
 1352 
 1353         untimeout(axe_tick, sc, sc->axe_stat_ch);
 1354 
 1355         /* Stop transfers. */
 1356         if (sc->axe_ep[AXE_ENDPT_RX] != NULL) {
 1357                 err = usbd_abort_pipe(sc->axe_ep[AXE_ENDPT_RX]);
 1358                 if (err) {
 1359                         device_printf(sc->axe_dev, "abort rx pipe failed: %s\n",
 1360                             usbd_errstr(err));
 1361                 }
 1362                 err = usbd_close_pipe(sc->axe_ep[AXE_ENDPT_RX]);
 1363                 if (err) {
 1364                         device_printf(sc->axe_dev, "close rx pipe failed: %s\n",
 1365                             usbd_errstr(err));
 1366                 }
 1367                 sc->axe_ep[AXE_ENDPT_RX] = NULL;
 1368         }
 1369 
 1370         if (sc->axe_ep[AXE_ENDPT_TX] != NULL) {
 1371                 err = usbd_abort_pipe(sc->axe_ep[AXE_ENDPT_TX]);
 1372                 if (err) {
 1373                         device_printf(sc->axe_dev, "abort tx pipe failed: %s\n",
 1374                             usbd_errstr(err));
 1375                 }
 1376                 err = usbd_close_pipe(sc->axe_ep[AXE_ENDPT_TX]);
 1377                 if (err) {
 1378                         device_printf(sc->axe_dev, "close tx pipe failed: %s\n",
 1379                             usbd_errstr(err));
 1380                 }
 1381                 sc->axe_ep[AXE_ENDPT_TX] = NULL;
 1382         }
 1383 
 1384         if (sc->axe_ep[AXE_ENDPT_INTR] != NULL) {
 1385                 err = usbd_abort_pipe(sc->axe_ep[AXE_ENDPT_INTR]);
 1386                 if (err) {
 1387                         device_printf(sc->axe_dev,
 1388                             "abort intr pipe failed: %s\n", usbd_errstr(err));
 1389                 }
 1390                 err = usbd_close_pipe(sc->axe_ep[AXE_ENDPT_INTR]);
 1391                 if (err) {
 1392                         device_printf(sc->axe_dev,
 1393                             "close intr pipe failed: %s\n", usbd_errstr(err));
 1394                 }
 1395                 sc->axe_ep[AXE_ENDPT_INTR] = NULL;
 1396         }
 1397 
 1398         axe_reset(sc);
 1399 
 1400         /* Free RX resources. */
 1401         axe_rx_list_free(sc);
 1402         /* Free TX resources. */
 1403         axe_tx_list_free(sc);
 1404 
 1405         ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
 1406         sc->axe_link = 0;
 1407         AXE_UNLOCK(sc);
 1408 
 1409         return;
 1410 }
 1411 
 1412 /*
 1413  * Stop all chip I/O so that the kernel's probe routines don't
 1414  * get confused by errant DMAs when rebooting.
 1415  */
 1416 static int
 1417 axe_shutdown(device_t dev)
 1418 {
 1419         struct axe_softc        *sc;
 1420 
 1421         sc = device_get_softc(dev);
 1422 
 1423         AXE_SLEEPLOCK(sc);
 1424         axe_stop(sc);
 1425         AXE_SLEEPUNLOCK(sc);
 1426 
 1427         return (0);
 1428 }

Cache object: 1aa8f312ac01066b8050e6e7602168ac


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