Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/dev/usb Sync with FreeBSD/OpenBSD and add support for 88...



details:   https://anonhg.NetBSD.org/src/rev/8ef61f067dad
branches:  trunk
changeset: 819428:8ef61f067dad
user:      skrll <skrll%NetBSD.org@localhost>
date:      Sun Dec 04 10:07:06 2016 +0000

description:
Sync with FreeBSD/OpenBSD and add support for 88772B devices.

While I'm here convert to USB_DEBUG

diffstat:

 sys/dev/usb/if_axe.c    |  729 +++++++++++++++++++++++++++++++++++------------
 sys/dev/usb/if_axereg.h |  259 ++++++++++++++--
 2 files changed, 769 insertions(+), 219 deletions(-)

diffs (truncated from 1665 to 300 lines):

diff -r fe69dc59238f -r 8ef61f067dad sys/dev/usb/if_axe.c
--- a/sys/dev/usb/if_axe.c      Sun Dec 04 08:21:08 2016 +0000
+++ b/sys/dev/usb/if_axe.c      Sun Dec 04 10:07:06 2016 +0000
@@ -1,5 +1,5 @@
-/*     $NetBSD: if_axe.c,v 1.75 2016/11/25 12:56:29 skrll Exp $        */
-/*     $OpenBSD: if_axe.c,v 1.96 2010/01/09 05:33:08 jsg Exp $ */
+/*     $NetBSD: if_axe.c,v 1.76 2016/12/04 10:07:06 skrll Exp $        */
+/*     $OpenBSD: if_axe.c,v 1.137 2016/04/13 11:03:37 mpi Exp $ */
 
 /*
  * Copyright (c) 2005, 2006, 2007 Jonathan Gray <jsg%openbsd.org@localhost>
@@ -50,14 +50,8 @@
  */
 
 /*
- * ASIX Electronics AX88172 USB 2.0 ethernet driver. Used in the
- * LinkSys USB200M and various other adapters.
- *
- * Manuals available from:
- * http://www.asix.com.tw/datasheet/mac/Ax88172.PDF
- * Note: you need the manual for the AX88170 chip (USB 1.x ethernet
- * controller) to find the definitions for the RX control register.
- * http://www.asix.com.tw/datasheet/mac/Ax88170.PDF
+ * ASIX Electronics AX88172/AX88178/AX88778 USB 2.0 ethernet driver.
+ * Used in the LinkSys USB200M and various other adapters.
  *
  * Written by Bill Paul <wpaul%windriver.com@localhost>
  * Senior Engineer
@@ -77,19 +71,23 @@
  *   to send any packets.
  *
  * Note that this device appears to only support loading the station
- * address via autoload from the EEPROM (i.e. there's no way to manaully
+ * address via autoload from the EEPROM (i.e. there's no way to manually
  * set it).
  *
  * (Adam Weinberger wanted me to name this driver if_gir.c.)
  */
 
 /*
- * Ported to OpenBSD 3/28/2004 by Greg Taleck <taleck%oz.net@localhost>
- * with bits and pieces from the aue and url drivers.
+ * Ax88178 and Ax88772 support backported from the OpenBSD driver.
+ * 2007/02/12, J.R. Oldroyd, fbsd%opal.com@localhost
+ *
+ * Manual here:
+ * http://www.asix.com.tw/FrootAttach/datasheet/AX88178_datasheet_Rev10.pdf
+ * http://www.asix.com.tw/FrootAttach/datasheet/AX88772_datasheet_Rev10.pdf
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_axe.c,v 1.75 2016/11/25 12:56:29 skrll Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_axe.c,v 1.76 2016/12/04 10:07:06 skrll Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_inet.h"
@@ -120,6 +118,7 @@
 #include <dev/mii/miivar.h>
 
 #include <dev/usb/usb.h>
+#include <dev/usb/usbhist.h>
 #include <dev/usb/usbdi.h>
 #include <dev/usb/usbdi_util.h>
 #include <dev/usb/usbdivar.h>
@@ -127,14 +126,62 @@
 
 #include <dev/usb/if_axereg.h>
 
-#ifdef AXE_DEBUG
-#define DPRINTF(x)     do { if (axedebug) printf x; } while (0)
-#define DPRINTFN(n,x)  do { if (axedebug >= (n)) printf x; } while (0)
-int    axedebug = 0;
+/*
+ * AXE_178_MAX_FRAME_BURST
+ * max frame burst size for Ax88178 and Ax88772
+ *     0       2048 bytes
+ *     1       4096 bytes
+ *     2       8192 bytes
+ *     3       16384 bytes
+ * use the largest your system can handle without USB stalling.
+ *
+ * NB: 88772 parts appear to generate lots of input errors with
+ * a 2K rx buffer and 8K is only slightly faster than 4K on an
+ * EHCI port on a T42 so change at your own risk.
+ */
+#define AXE_178_MAX_FRAME_BURST        1
+
+
+#ifdef USB_DEBUG
+#ifndef AXE_DEBUG
+#define axedebug 0
 #else
-#define DPRINTF(x)
-#define DPRINTFN(n,x)
-#endif
+static int axedebug = 20;
+
+SYSCTL_SETUP(sysctl_hw_axe_setup, "sysctl hw.axe setup")
+{
+       int err;
+       const struct sysctlnode *rnode;
+       const struct sysctlnode *cnode;
+
+       err = sysctl_createv(clog, 0, NULL, &rnode,
+           CTLFLAG_PERMANENT, CTLTYPE_NODE, "axe",
+           SYSCTL_DESCR("axe global controls"),
+           NULL, 0, NULL, 0, CTL_HW, CTL_CREATE, CTL_EOL);
+
+       if (err)
+               goto fail;
+
+       /* control debugging printfs */
+       err = sysctl_createv(clog, 0, &rnode, &cnode,
+           CTLFLAG_PERMANENT|CTLFLAG_READWRITE, CTLTYPE_INT,
+           "debug", SYSCTL_DESCR("Enable debugging output"),
+           NULL, 0, &axedebug, sizeof(axedebug), CTL_CREATE, CTL_EOL);
+       if (err)
+               goto fail;
+
+       return;
+fail:
+       aprint_error("%s: sysctl_createv failed (err = %d)\n", __func__, err);
+}
+
+#endif /* AXE_DEBUG */
+#endif /* USB_DEBUG */
+
+#define DPRINTF(FMT,A,B,C,D)   USBHIST_LOGN(axedebug,1,FMT,A,B,C,D)
+#define DPRINTFN(N,FMT,A,B,C,D)        USBHIST_LOGN(axedebug,N,FMT,A,B,C,D)
+#define AXEHIST_FUNC()         USBHIST_FUNC()
+#define AXEHIST_CALLED(name)   USBHIST_CALLED(axedebug)
 
 /*
  * Various supported device vendors/products.
@@ -146,22 +193,23 @@
        { { USB_VENDOR_ASIX,            USB_PRODUCT_ASIX_AX88172}, 0 },
        { { USB_VENDOR_ASIX,            USB_PRODUCT_ASIX_AX88772}, AX772 },
        { { USB_VENDOR_ASIX,            USB_PRODUCT_ASIX_AX88772A}, AX772 },
-       { { USB_VENDOR_ASIX,            USB_PRODUCT_ASIX_AX88772B}, AX772 | AX772B },
-       { { USB_VENDOR_ASIX,            USB_PRODUCT_ASIX_AX88772B_1}, AX772 | AX772B },
+       { { USB_VENDOR_ASIX,            USB_PRODUCT_ASIX_AX88772B}, AX772B },
+       { { USB_VENDOR_ASIX,            USB_PRODUCT_ASIX_AX88772B_1}, AX772B },
        { { USB_VENDOR_ASIX,            USB_PRODUCT_ASIX_AX88178}, AX178 },
        { { USB_VENDOR_ATEN,            USB_PRODUCT_ATEN_UC210T}, 0 },
        { { USB_VENDOR_BELKIN,          USB_PRODUCT_BELKIN_F5D5055 }, AX178 },
        { { USB_VENDOR_BILLIONTON,      USB_PRODUCT_BILLIONTON_USB2AR}, 0},
-       { { USB_VENDOR_CISCOLINKSYS,    USB_PRODUCT_CISCOLINKSYS_USB200MV2}, AX772 },
+       { { USB_VENDOR_CISCOLINKSYS,    USB_PRODUCT_CISCOLINKSYS_USB200MV2}, AX772A },
        { { USB_VENDOR_COREGA,          USB_PRODUCT_COREGA_FETHER_USB2_TX }, 0},
        { { USB_VENDOR_DLINK,           USB_PRODUCT_DLINK_DUBE100}, 0 },
        { { USB_VENDOR_DLINK,           USB_PRODUCT_DLINK_DUBE100B1 }, AX772 },
        { { USB_VENDOR_DLINK2,          USB_PRODUCT_DLINK2_DUBE100B1 }, AX772 },
-       { { USB_VENDOR_DLINK,           USB_PRODUCT_DLINK_DUBE100C1 }, AX772 | AX772B },
+       { { USB_VENDOR_DLINK,           USB_PRODUCT_DLINK_DUBE100C1 }, AX772B },
        { { USB_VENDOR_GOODWAY,         USB_PRODUCT_GOODWAY_GWUSB2E}, 0 },
        { { USB_VENDOR_IODATA,          USB_PRODUCT_IODATA_ETGUS2 }, AX178 },
        { { USB_VENDOR_JVC,             USB_PRODUCT_JVC_MP_PRX1}, 0 },
-       { { USB_VENDOR_LENOVO,          USB_PRODUCT_LENOVO_ETHERNET }, AX772 | AX772B },
+       { { USB_VENDOR_LENOVO,          USB_PRODUCT_LENOVO_ETHERNET }, AX772B },
+       { { USB_VENDOR_LINKSYS,         USB_PRODUCT_LINKSYS_HG20F9}, AX772B },
        { { USB_VENDOR_LINKSYS2,        USB_PRODUCT_LINKSYS2_USB200M}, 0 },
        { { USB_VENDOR_LINKSYS4,        USB_PRODUCT_LINKSYS4_USB1000 }, AX178 },
        { { USB_VENDOR_LOGITEC,         USB_PRODUCT_LOGITEC_LAN_GTJU2}, AX178 },
@@ -171,12 +219,24 @@
        { { USB_VENDOR_NETGEAR,         USB_PRODUCT_NETGEAR_FA120}, 0 },
        { { USB_VENDOR_OQO,             USB_PRODUCT_OQO_ETHER01PLUS }, AX772 },
        { { USB_VENDOR_PLANEX3,         USB_PRODUCT_PLANEX3_GU1000T }, AX178 },
+       { { USB_VENDOR_SITECOM,         USB_PRODUCT_SITECOM_LN029}, 0 },
+       { { USB_VENDOR_SITECOMEU,       USB_PRODUCT_SITECOMEU_LN028 }, AX178 },
+       { { USB_VENDOR_SITECOMEU,       USB_PRODUCT_SITECOMEU_LN031 }, AX178 },
        { { USB_VENDOR_SYSTEMTALKS,     USB_PRODUCT_SYSTEMTALKS_SGCX2UL}, 0 },
-       { { USB_VENDOR_SITECOM,         USB_PRODUCT_SITECOM_LN029}, 0 },
-       { { USB_VENDOR_SITECOMEU,       USB_PRODUCT_SITECOMEU_LN028 }, AX178 }
 };
 #define axe_lookup(v, p) ((const struct axe_type *)usb_lookup(axe_devs, v, p))
 
+static const struct ax88772b_mfb ax88772b_mfb_table[] = {
+       { 0x8000, 0x8001, 2048 },
+       { 0x8100, 0x8147, 4096 },
+       { 0x8200, 0x81EB, 6144 },
+       { 0x8300, 0x83D7, 8192 },
+       { 0x8400, 0x851E, 16384 },
+       { 0x8500, 0x8666, 20480 },
+       { 0x8600, 0x87AE, 24576 },
+       { 0x8700, 0x8A3D, 32768 }
+};
+
 int    axe_match(device_t, cfdata_t, void *);
 void   axe_attach(device_t, device_t, void *);
 int    axe_detach(device_t, int);
@@ -204,8 +264,6 @@
 static void    axe_miibus_statchg(struct ifnet *);
 static int     axe_cmd(struct axe_softc *, int, int, int, void *);
 static void    axe_reset(struct axe_softc *);
-static int     axe_ifmedia_upd(struct ifnet *);
-static void    axe_ifmedia_sts(struct ifnet *, struct ifmediareq *);
 
 static void    axe_setmulti(struct axe_softc *);
 static void    axe_lock_mii(struct axe_softc *);
@@ -235,6 +293,7 @@
 static int
 axe_cmd(struct axe_softc *sc, int cmd, int index, int val, void *buf)
 {
+       AXEHIST_FUNC(); AXEHIST_CALLED();
        usb_device_request_t req;
        usbd_status err;
 
@@ -243,6 +302,8 @@
        if (sc->axe_dying)
                return 0;
 
+       DPRINTFN(20, "cmd %#x index %#x val %#x", cmd, index, val, 0);
+
        if (AXE_CMD_DIR(cmd))
                req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
        else
@@ -255,7 +316,7 @@
        err = usbd_do_request(sc->axe_udev, &req, buf);
 
        if (err) {
-               DPRINTF(("axe_cmd err: cmd %d err %d\n", cmd, err));
+               DPRINTF("cmd %d err %d", cmd, err, 0, 0);
                return -1;
        }
        return 0;
@@ -264,11 +325,15 @@
 static int
 axe_miibus_readreg_locked(device_t dev, int phy, int reg)
 {
+       AXEHIST_FUNC(); AXEHIST_CALLED();
        struct axe_softc *sc = device_private(dev);
        usbd_status err;
        uint16_t val;
 
+       DPRINTFN(30, "phy 0x%x reg 0x%x\n", phy, reg, 0, 0);
+
        axe_cmd(sc, AXE_CMD_MII_OPMODE_SW, 0, 0, NULL);
+
        err = axe_cmd(sc, AXE_CMD_MII_READ_REG, reg, phy, (void *)&val);
        axe_cmd(sc, AXE_CMD_MII_OPMODE_HW, 0, 0, NULL);
        if (err) {
@@ -277,18 +342,17 @@
        }
 
        val = le16toh(val);
-       if (sc->axe_flags & AX772 && reg == MII_BMSR) {
+       if (AXE_IS_772(sc) && reg == MII_BMSR) {
                /*
-                * BMSR of AX88772 indicates it supports extended
+                * BMSR of AX88772 indicates that it supports extended
                 * capability but the extended status register is
-                * reserverd for embedded ethernet PHY. So clear the
+                * reserved for embedded ethernet PHY. So clear the
                 * extended capability bit of BMSR.
                 */
                 val &= ~BMSR_EXTCAP;
        }
 
-       DPRINTF(("axe_miibus_readreg: phy 0x%x reg 0x%x val 0x%x\n",
-           phy, reg, val));
+       DPRINTFN(30, "phy 0x%x reg 0x%x val %#x", phy, reg, val, 0);
 
        return val;
 }
@@ -350,17 +414,26 @@
 static void
 axe_miibus_statchg(struct ifnet *ifp)
 {
+       AXEHIST_FUNC(); AXEHIST_CALLED();
+
        struct axe_softc *sc = ifp->if_softc;
        struct mii_data *mii = &sc->axe_mii;
        int val, err;
 
-       if ((mii->mii_media_active & IFM_GMASK) == IFM_FDX)
-               val = AXE_MEDIA_FULL_DUPLEX;
-       else
-               val = 0;
-
-       if (sc->axe_flags & AX178 || sc->axe_flags & AX772) {
-               val |= (AXE_178_MEDIA_RX_EN | AXE_178_MEDIA_MAGIC);
+       val = 0;
+       if ((IFM_OPTIONS(mii->mii_media_active) & IFM_FDX) != 0) {
+               val |= AXE_MEDIA_FULL_DUPLEX;
+               if (AXE_IS_178_FAMILY(sc)) {
+                       if ((IFM_OPTIONS(mii->mii_media_active) &
+                           IFM_ETH_TXPAUSE) != 0)
+                               val |= AXE_178_MEDIA_TXFLOW_CONTROL_EN;
+                       if ((IFM_OPTIONS(mii->mii_media_active) &
+                           IFM_ETH_RXPAUSE) != 0)
+                               val |= AXE_178_MEDIA_RXFLOW_CONTROL_EN;
+               }
+       }
+       if (AXE_IS_178_FAMILY(sc)) {
+               val |= AXE_178_MEDIA_RX_EN | AXE_178_MEDIA_MAGIC;
                if (sc->axe_flags & AX178)
                        val |= AXE_178_MEDIA_ENCK;
                switch (IFM_SUBTYPE(mii->mii_media_active)) {
@@ -376,7 +449,7 @@
                }



Home | Main Index | Thread Index | Old Index