svn commit: r316478 - head/sys/dev/tsec
Justin Hibbits
jhibbits at FreeBSD.org
Tue Apr 4 00:43:10 UTC 2017
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)
More information about the svn-src-head
mailing list