Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 4 Apr 2017 00:43:09 +0000 (UTC)
From:      Justin Hibbits <jhibbits@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r316478 - head/sys/dev/tsec
Message-ID:  <201704040043.v340h9mC073232@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: jhibbits
Date: Tue Apr  4 00:43:09 2017
New Revision: 316478
URL: https://svnweb.freebsd.org/changeset/base/316478

Log:
  Use a common tsec_mii_wait() function to busy wait for status changes.
  
  The status indicators are not set immediatly after a command.  Discard
  the first value.
  
  Unlock the PHY mutex after a timeout in tsec_init_locked().
  
  Tested on the P1020RDB.
  
  Submitted by:	Sebastian Huber <sebastian_DOT_huber_AT_embedded-brains_DOT_de>

Modified:
  head/sys/dev/tsec/if_tsec.c

Modified: head/sys/dev/tsec/if_tsec.c
==============================================================================
--- head/sys/dev/tsec/if_tsec.c	Mon Apr  3 23:16:51 2017	(r316477)
+++ head/sys/dev/tsec/if_tsec.c	Tue Apr  4 00:43:09 2017	(r316478)
@@ -357,13 +357,33 @@ tsec_init(void *xsc)
 	TSEC_GLOBAL_UNLOCK(sc);
 }
 
+static int
+tsec_mii_wait(struct tsec_softc *sc, uint32_t flags)
+{
+	int timeout;
+
+	/*
+	 * The status indicators are not set immediatly after a command.
+	 * Discard the first value.
+	 */
+	TSEC_PHY_READ(sc, TSEC_REG_MIIMIND);
+
+	timeout = TSEC_READ_RETRY;
+	while ((TSEC_PHY_READ(sc, TSEC_REG_MIIMIND) & flags) && --timeout)
+	    DELAY(TSEC_READ_DELAY);
+
+	return (timeout == 0);
+}
+
+
 static void
 tsec_init_locked(struct tsec_softc *sc)
 {
 	struct tsec_desc *tx_desc = sc->tsec_tx_vaddr;
 	struct tsec_desc *rx_desc = sc->tsec_rx_vaddr;
 	struct ifnet *ifp = sc->tsec_ifp;
-	uint32_t timeout, val, i;
+	uint32_t val, i;
+	int timeout;
 
 	if (ifp->if_drv_flags & IFF_DRV_RUNNING)
 		return;
@@ -422,15 +442,13 @@ tsec_init_locked(struct tsec_softc *sc)
 	TSEC_PHY_WRITE(sc, TSEC_REG_MIIMCFG, TSEC_MIIMCFG_CLKDIV28);
 
 	/* Step 8: Read MII Mgmt indicator register and check for Busy = 0 */
-	timeout = TSEC_READ_RETRY;
-	while (--timeout && (TSEC_PHY_READ(sc, TSEC_REG_MIIMIND) &
-	    TSEC_MIIMIND_BUSY))
-		DELAY(TSEC_READ_DELAY);
-	if (timeout == 0) {
+	timeout = tsec_mii_wait(sc, TSEC_MIIMIND_BUSY);
+
+	TSEC_PHY_UNLOCK(sc);
+	if (timeout) {
 		if_printf(ifp, "tsec_init_locked(): Mgmt busy timeout\n");
 		return;
 	}
-	TSEC_PHY_UNLOCK(sc);
 
 	/* Step 9: Setup the MII Mgmt */
 	mii_mediachg(sc->tsec_mii);
@@ -1570,7 +1588,7 @@ int
 tsec_miibus_readreg(device_t dev, int phy, int reg)
 {
 	struct tsec_softc *sc;
-	uint32_t timeout;
+	int timeout;
 	int rv;
 
 	sc = device_get_softc(dev);
@@ -1580,17 +1598,13 @@ tsec_miibus_readreg(device_t dev, int ph
 	TSEC_PHY_WRITE(sc, TSEC_REG_MIIMCOM, 0);
 	TSEC_PHY_WRITE(sc, TSEC_REG_MIIMCOM, TSEC_MIIMCOM_READCYCLE);
 
-	timeout = TSEC_READ_RETRY;
-	while (--timeout && TSEC_PHY_READ(sc, TSEC_REG_MIIMIND) &
-	    (TSEC_MIIMIND_NOTVALID | TSEC_MIIMIND_BUSY))
-		DELAY(TSEC_READ_DELAY);
+	timeout = tsec_mii_wait(sc, TSEC_MIIMIND_NOTVALID | TSEC_MIIMIND_BUSY);
+	rv = TSEC_PHY_READ(sc, TSEC_REG_MIIMSTAT);
+	TSEC_PHY_UNLOCK();
 
 	if (timeout == 0)
 		device_printf(dev, "Timeout while reading from PHY!\n");
 
-	rv = TSEC_PHY_READ(sc, TSEC_REG_MIIMSTAT);
-	TSEC_PHY_UNLOCK();
-
 	return (rv);
 }
 
@@ -1598,18 +1612,14 @@ int
 tsec_miibus_writereg(device_t dev, int phy, int reg, int value)
 {
 	struct tsec_softc *sc;
-	uint32_t timeout;
+	int timeout;
 
 	sc = device_get_softc(dev);
 
 	TSEC_PHY_LOCK();
 	TSEC_PHY_WRITE(sc, TSEC_REG_MIIMADD, (phy << 8) | reg);
 	TSEC_PHY_WRITE(sc, TSEC_REG_MIIMCON, value);
-
-	timeout = TSEC_READ_RETRY;
-	while (--timeout && (TSEC_READ(sc, TSEC_REG_MIIMIND) &
-	    TSEC_MIIMIND_BUSY))
-		DELAY(TSEC_READ_DELAY);
+	timeout = tsec_mii_wait(sc, TSEC_MIIMIND_BUSY);
 	TSEC_PHY_UNLOCK();
 
 	if (timeout == 0)



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201704040043.v340h9mC073232>