set bulk buffers according to link and bus speed. values are taken
from freebsd and linux drivers.

while here, only enable full duplex if link is also full duplex.

---
 dev/usb/if_axen.c    | 119 +++++++++++++++++++++++--------------------
 dev/usb/if_axenreg.h |  13 +++--
 2 files changed, 72 insertions(+), 60 deletions(-)

diff --git a/dev/usb/if_axen.c b/dev/usb/if_axen.c
index 909c04f..dfdcecf 100644
--- a/dev/usb/if_axen.c
+++ b/dev/usb/if_axen.c
@@ -120,6 +120,13 @@ void       axen_unlock_mii(struct axen_softc *sc);
 
 void   axen_ax88179_init(struct axen_softc *);
 
+struct axen_qctrl axen_bulk_size[] = {
+       { 7, 0x4f, 0x00, AXEN_BUFSZ_SS, 0xff },
+       { 7, 0x20, 0x03, AXEN_BUFSZ_HS, 0xff },
+       { 7, 0xae, 0x07, AXEN_BUFSZ_LS, 0xff },
+       { 7, 0xcc, 0x4c, AXEN_BUFSZ_LS, 0x08 }
+};
+
 /* Get exclusive access to the MII registers */
 void
 axen_lock_mii(struct axen_softc *sc)
@@ -235,13 +242,17 @@ axen_miibus_statchg(struct device *dev)
        struct mii_data         *mii = GET_MII(sc);
        struct ifnet            *ifp;
        int                     err;
+       uint8_t                 link_status;
        uint16_t                val;
        uWord                   wval;
+       struct axen_qctrl       *qctrl;
+
+       axen_lock_mii(sc);
 
        ifp = GET_IFP(sc);
        if (mii == NULL || ifp == NULL ||
            (ifp->if_flags & IFF_RUNNING) == 0)
-               return;
+               goto done;
 
        sc->axen_link = 0;
        if ((mii->mii_media_status & (IFM_ACTIVE | IFM_AVALID)) ==
@@ -249,10 +260,8 @@ axen_miibus_statchg(struct device *dev)
                switch (IFM_SUBTYPE(mii->mii_media_active)) {
                    case IFM_10_T:
                    case IFM_100_TX:
-                       sc->axen_link++;
-                       break;
                    case IFM_1000_T:
-                       sc->axen_link++;
+                       sc->axen_link = 1;
                        break;
                    default:
                        break;
@@ -261,36 +270,68 @@ axen_miibus_statchg(struct device *dev)
 
        /* Lost link, do nothing. */
        if (sc->axen_link == 0)
-               return;
+               goto done;
 
-       val = 0;
-       if ((IFM_OPTIONS(mii->mii_media_active) & IFM_FDX) != 0)
-               val |= AXEN_MEDIUM_FDX;
+       err = axen_cmd(sc, AXEN_CMD_MAC_READ, 1, AXEN_PHYSICAL_LINK_STATUS,
+           &link_status);
+       if (err)
+               goto error;
 
-       val |= (AXEN_MEDIUM_RECV_EN | AXEN_MEDIUM_ALWAYS_ONE);
-       val |= (AXEN_MEDIUM_RXFLOW_CTRL_EN | AXEN_MEDIUM_TXFLOW_CTRL_EN);
+       /* both freebsd and linux don't define/set AXEN_MEDIUM_ALWAYS_ONE,
+        * but 6.2.2.10 of the datasheet (p40) sets it to 1 */
+       val = AXEN_MEDIUM_RECV_EN | AXEN_MEDIUM_ALWAYS_ONE;
+
+       if ((IFM_OPTIONS(mii->mii_media_active) & IFM_FDX) != 0) {
+               val |= AXEN_MEDIUM_FDX;
+               val |= AXEN_MEDIUM_TXFLOW_CTRL_EN | AXEN_MEDIUM_RXFLOW_CTRL_EN;
+       }
 
        switch (IFM_SUBTYPE(mii->mii_media_active)) {
        case IFM_1000_T:
-               val |= AXEN_MEDIUM_GIGA | AXEN_MEDIUM_EN_125MHZ;
+               val |= AXEN_MEDIUM_GIGA;
+               if (link_status & AXEN_USB_SS)
+                       qctrl = &axen_bulk_size[0];
+               else if (link_status & AXEN_USB_HS)
+                       qctrl = &axen_bulk_size[1];
+               else
+                       qctrl = &axen_bulk_size[3];
                break;
        case IFM_100_TX:
-               val |= AXEN_MEDIUM_PS;
+               val |= AXEN_MEDIUM_PORTSPEED_100;
+               if (link_status & (AXEN_USB_SS | AXEN_USB_HS))
+                       qctrl = &axen_bulk_size[2];
+               else
+                       qctrl = &axen_bulk_size[3];
                break;
        case IFM_10_T:
-               /* doesn't need to be handled */
+               qctrl = &axen_bulk_size[3];
                break;
+       default:
+               printf("%s: unknown uplink bus: 0x%02x\n",
+                   sc->axen_dev.dv_xname, link_status);
+               goto error;
        }
+       /* XXX change buffer size here */
+
+       /* RX bulk configuration. */
+       err = axen_cmd(sc, AXEN_CMD_MAC_SET_RXSR, 5, AXEN_RX_BULKIN_QCTRL,
+           qctrl);
+       if (err)
+               goto error;
 
-       DPRINTF(("axen_miibus_statchg: val=0x%x\n", val));
+       DPRINTF(("%s: %s: val=0x%x\n", sc->axen_dev.dv_xname, __func__,val));
        USETW(wval, val);
-       axen_lock_mii(sc);
        err = axen_cmd(sc, AXEN_CMD_MAC_WRITE2, 2, AXEN_MEDIUM_STATUS, &wval);
+       if (err)
+               goto error;
+
+       goto done;
+
+error:
+       printf("%s: media change failed (err: 0x%x)\n", sc->axen_dev.dv_xname,
+           err);
+done:
        axen_unlock_mii(sc);
-       if (err) {
-               printf("%s: media change failed\n", sc->axen_dev.dv_xname);
-               return;
-       }
 }
 
 /*
@@ -407,7 +448,6 @@ axen_ax88179_init(struct axen_softc *sc)
        uWord           wval;
        uByte           val;
        u_int16_t       ctl, temp;
-       struct axen_qctrl qctrl;
 
        axen_lock_mii(sc);
 
@@ -439,6 +479,10 @@ axen_ax88179_init(struct axen_softc *sc)
        axen_cmd(sc, AXEN_CMD_MAC_WRITE, 1, AXEN_PHYCLK, &val);
        usbd_delay_ms(sc->axen_udev, 100);
 
+       /* RX bulk configuration */
+       axen_cmd(sc, AXEN_CMD_MAC_SET_RXSR, 5, AXEN_RX_BULKIN_QCTRL,
+           &axen_bulk_size[0]);
+
        /* set monitor mode (disable) */
        val = AXEN_MONITOR_NONE;
        axen_cmd(sc, AXEN_CMD_MAC_WRITE, 1, AXEN_MONITOR_MODE, &val);
@@ -465,41 +509,6 @@ axen_ax88179_init(struct axen_softc *sc)
                    sc->axen_dev.dv_xname, ctl);
        }
 
-       /* bulkin queue setting */
-       axen_cmd(sc, AXEN_CMD_MAC_READ, 1, AXEN_USB_UPLINK, &val);
-       switch (val) {
-       case AXEN_USB_FS:
-               DPRINTF(("uplink: USB1.1\n"));
-               qctrl.ctrl      = 0x07;
-               qctrl.timer_low = 0xcc;
-               qctrl.timer_high= 0x4c;
-               qctrl.bufsize   = AXEN_BUFSZ_LS - 1;
-               qctrl.ifg       = 0x08;
-               break;
-       case AXEN_USB_HS:
-               DPRINTF(("uplink: USB2.0\n"));
-               qctrl.ctrl      = 0x07;
-               qctrl.timer_low = 0x02;
-               qctrl.timer_high= 0xa0;
-               qctrl.bufsize   = AXEN_BUFSZ_HS - 1;
-               qctrl.ifg       = 0xff;
-               break;
-       case AXEN_USB_SS:
-               DPRINTF(("uplink: USB3.0\n"));
-               qctrl.ctrl      = 0x07;
-               qctrl.timer_low = 0x4f;
-               qctrl.timer_high= 0x00;
-               qctrl.bufsize   = AXEN_BUFSZ_SS - 1;
-               qctrl.ifg       = 0xff;
-               break;
-       default:
-               printf("%s: unknown uplink bus:0x%02x\n",
-                   sc->axen_dev.dv_xname, val);
-               axen_unlock_mii(sc);
-               return;
-       }
-       axen_cmd(sc, AXEN_CMD_MAC_SET_RXSR, 5, AXEN_RX_BULKIN_QCTRL, &qctrl);
-
        /* Set MAC address. */
        axen_cmd(sc, AXEN_CMD_MAC_WRITE_ETHER, ETHER_ADDR_LEN,
            AXEN_CMD_MAC_NODE_ID, &sc->arpcom.ac_enaddr);
diff --git a/dev/usb/if_axenreg.h b/dev/usb/if_axenreg.h
index bbfb035..336727f 100644
--- a/dev/usb/if_axenreg.h
+++ b/dev/usb/if_axenreg.h
@@ -12,9 +12,9 @@
 #define AXEN_PHY_ID            0x0003
 #define AXEN_MCAST_FILTER_SIZE 8
 /* unit: KB */
-#define AXEN_BUFSZ_LS          8
-#define AXEN_BUFSZ_HS          16
-#define AXEN_BUFSZ_SS          24
+#define AXEN_BUFSZ_LS          0x18
+#define AXEN_BUFSZ_HS          0x16
+#define AXEN_BUFSZ_SS          0x12
 
 #define AXEN_REV_UA1           0
 #define AXEN_REV_UA2           1
@@ -92,10 +92,13 @@
 #define AXEN_CMD_MAC_READ                      0x1001
 #define AXEN_CMD_MAC_WRITE                     0x1101
 
-#define   AXEN_USB_UPLINK                      0x02
+#define   AXEN_PHYSICAL_LINK_STATUS            0x02
 #define     AXEN_USB_FS                                  0x01
 #define     AXEN_USB_HS                                  0x02
 #define     AXEN_USB_SS                                  0x04
+#define     AXEN_EPHY_10                         0x10
+#define     AXEN_EPHY_100                        0x20
+#define     AXEN_EPHY_1000                       0x40
 #define   AXEN_GENERAL_STATUS                  0x03
 #define     AXEN_GENERAL_STATUS_MASK             0x4
 #define     AXEN_REV0                            0x0
@@ -170,7 +173,7 @@
 #define            AXEN_MEDIUM_RXFLOW_CTRL_EN            0x0010
 #define            AXEN_MEDIUM_TXFLOW_CTRL_EN            0x0020
 #define            AXEN_MEDIUM_RECV_EN                   0x0100
-#define            AXEN_MEDIUM_PS                        0x0200
+#define            AXEN_MEDIUM_PORTSPEED_100             0x0200
 #define            AXEN_MEDIUM_JUMBO_EN                  0x8040
 #define   AXEN_PHYPWR_RSTCTL                   0x26
 #define     AXEN_PHYPWR_RSTCTL_BZ                0x0010
-- 
2.20.1

Reply via email to