Author: adrian
Date: Fri Oct 30 23:59:52 2015
New Revision: 290217
URL: https://svnweb.freebsd.org/changeset/base/290217

Log:
  arge_mdio: fix barriers; correctly check MII indicator register.
  
  * use barriers in a slightly better fashion.  You can blame this
    glass of whiskey on putting barriers in the wrong spot.  Grr adrian.
  
  * steal/rewrite the mdio busy check from ag7100 from openwrt and
    refactor the existing code out.  This is .. more correct.
  
  This seems to fix the boot-to-boot variation that I've been seeing
  and it quietens the switch port status flapping.
  
  Tested:
  
  * QCA9558 SoC (AP135.)
  
  Obtained from:        Linux OpenWRT

Modified:
  head/sys/mips/atheros/if_arge.c

Modified: head/sys/mips/atheros/if_arge.c
==============================================================================
--- head/sys/mips/atheros/if_arge.c     Fri Oct 30 23:57:20 2015        
(r290216)
+++ head/sys/mips/atheros/if_arge.c     Fri Oct 30 23:59:52 2015        
(r290217)
@@ -1067,34 +1067,47 @@ arge_hinted_child(device_t bus, const ch
 }
 
 static int
+arge_mdio_busy(struct arge_softc *sc)
+{
+       int i,result;
+
+       for (i = 0; i < ARGE_MII_TIMEOUT; i++) {
+               DELAY(5);
+               ARGE_MDIO_BARRIER_READ(sc);
+               result = ARGE_MDIO_READ(sc, AR71XX_MAC_MII_INDICATOR);
+               if (! result)
+                       return (0);
+               DELAY(5);
+       }
+       return (-1);
+}
+
+static int
 arge_miibus_readreg(device_t dev, int phy, int reg)
 {
        struct arge_softc * sc = device_get_softc(dev);
-       int i, result;
+       int result;
        uint32_t addr = (phy << MAC_MII_PHY_ADDR_SHIFT)
            | (reg & MAC_MII_REG_MASK);
 
        mtx_lock(&miibus_mtx);
+       ARGE_MDIO_BARRIER_RW(sc);
        ARGE_MDIO_WRITE(sc, AR71XX_MAC_MII_CMD, MAC_MII_CMD_WRITE);
+       ARGE_MDIO_BARRIER_WRITE(sc);
        ARGE_MDIO_WRITE(sc, AR71XX_MAC_MII_ADDR, addr);
+       ARGE_MDIO_BARRIER_WRITE(sc);
        ARGE_MDIO_WRITE(sc, AR71XX_MAC_MII_CMD, MAC_MII_CMD_READ);
 
-       i = ARGE_MII_TIMEOUT;
-       while ((ARGE_MDIO_READ(sc, AR71XX_MAC_MII_INDICATOR) & 
-           MAC_MII_INDICATOR_BUSY) && (i--)) {
-               ARGE_MDIO_BARRIER_READ(sc);
-               DELAY(5);
-       }
-
-       if (i < 0) {
+       if (arge_mdio_busy(sc) != 0) {
                mtx_unlock(&miibus_mtx);
                ARGEDEBUG(sc, ARGE_DBG_MII, "%s timedout\n", __func__);
                /* XXX: return ERRNO istead? */
                return (-1);
        }
 
-       result = ARGE_MDIO_READ(sc, AR71XX_MAC_MII_STATUS) & 
MAC_MII_STATUS_MASK;
        ARGE_MDIO_BARRIER_READ(sc);
+       result = ARGE_MDIO_READ(sc, AR71XX_MAC_MII_STATUS) & 
MAC_MII_STATUS_MASK;
+       ARGE_MDIO_BARRIER_RW(sc);
        ARGE_MDIO_WRITE(sc, AR71XX_MAC_MII_CMD, MAC_MII_CMD_WRITE);
        mtx_unlock(&miibus_mtx);
 
@@ -1109,7 +1122,6 @@ static int
 arge_miibus_writereg(device_t dev, int phy, int reg, int data)
 {
        struct arge_softc * sc = device_get_softc(dev);
-       int i;
        uint32_t addr =
            (phy << MAC_MII_PHY_ADDR_SHIFT) | (reg & MAC_MII_REG_MASK);
 
@@ -1117,24 +1129,20 @@ arge_miibus_writereg(device_t dev, int p
            phy, reg, data);
 
        mtx_lock(&miibus_mtx);
+       ARGE_MDIO_BARRIER_RW(sc);
        ARGE_MDIO_WRITE(sc, AR71XX_MAC_MII_ADDR, addr);
+       ARGE_MDIO_BARRIER_WRITE(sc);
        ARGE_MDIO_WRITE(sc, AR71XX_MAC_MII_CONTROL, data);
+       ARGE_MDIO_BARRIER_WRITE(sc);
 
-       i = ARGE_MII_TIMEOUT;
-       while ((ARGE_MDIO_READ(sc, AR71XX_MAC_MII_INDICATOR) & 
-           MAC_MII_INDICATOR_BUSY) && (i--)) {
-               ARGE_MDIO_BARRIER_READ(sc);
-               DELAY(5);
-       }
-
-       mtx_unlock(&miibus_mtx);
-
-       if (i < 0) {
+       if (arge_mdio_busy(sc) != 0) {
+               mtx_unlock(&miibus_mtx);
                ARGEDEBUG(sc, ARGE_DBG_MII, "%s timedout\n", __func__);
                /* XXX: return ERRNO istead? */
                return (-1);
        }
 
+       mtx_unlock(&miibus_mtx);
        return (0);
 }
 
_______________________________________________
[email protected] mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "[email protected]"

Reply via email to