svn commit: r290217 - head/sys/mips/atheros

Adrian Chadd adrian at FreeBSD.org
Fri Oct 30 23:59:54 UTC 2015


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);
 }
 


More information about the svn-src-head mailing list