diff options
Diffstat (limited to 'sys/dev/tsec/if_tsec.c')
-rw-r--r-- | sys/dev/tsec/if_tsec.c | 38 |
1 files changed, 27 insertions, 11 deletions
diff --git a/sys/dev/tsec/if_tsec.c b/sys/dev/tsec/if_tsec.c index 8041776..242df3e 100644 --- a/sys/dev/tsec/if_tsec.c +++ b/sys/dev/tsec/if_tsec.c @@ -111,6 +111,8 @@ DRIVER_MODULE(miibus, tsec, miibus_driver, miibus_devclass, 0, 0); MODULE_DEPEND(tsec, ether, 1, 1, 1); MODULE_DEPEND(tsec, miibus, 1, 1, 1); +struct mtx tsec_phy_mtx; + int tsec_attach(struct tsec_softc *sc) { @@ -121,6 +123,10 @@ tsec_attach(struct tsec_softc *sc) int error = 0; int i; + /* Initialize global (because potentially shared) MII lock */ + if (!mtx_initialized(&tsec_phy_mtx)) + mtx_init(&tsec_phy_mtx, "tsec mii", NULL, MTX_DEF); + /* Reset all TSEC counters */ TSEC_TX_RX_COUNTERS_INIT(sc); @@ -406,21 +412,24 @@ tsec_init_locked(struct tsec_softc *sc) */ TSEC_WRITE(sc, TSEC_REG_TBIPA, 5); + TSEC_PHY_LOCK(sc); + /* Step 6: Reset the management interface */ - TSEC_WRITE(sc->phy_sc, TSEC_REG_MIIMCFG, TSEC_MIIMCFG_RESETMGMT); + TSEC_PHY_WRITE(sc, TSEC_REG_MIIMCFG, TSEC_MIIMCFG_RESETMGMT); /* Step 7: Setup the MII Mgmt clock speed */ - TSEC_WRITE(sc->phy_sc, TSEC_REG_MIIMCFG, TSEC_MIIMCFG_CLKDIV28); + 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_READ(sc->phy_sc, TSEC_REG_MIIMIND) & + while (--timeout && (TSEC_PHY_READ(sc, TSEC_REG_MIIMIND) & TSEC_MIIMIND_BUSY)) DELAY(TSEC_READ_DELAY); if (timeout == 0) { 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); @@ -1561,22 +1570,27 @@ tsec_miibus_readreg(device_t dev, int phy, int reg) { struct tsec_softc *sc; uint32_t timeout; + int rv; sc = device_get_softc(dev); - TSEC_WRITE(sc->phy_sc, TSEC_REG_MIIMADD, (phy << 8) | reg); - TSEC_WRITE(sc->phy_sc, TSEC_REG_MIIMCOM, 0); - TSEC_WRITE(sc->phy_sc, TSEC_REG_MIIMCOM, TSEC_MIIMCOM_READCYCLE); + TSEC_PHY_LOCK(); + TSEC_PHY_WRITE(sc, TSEC_REG_MIIMADD, (phy << 8) | reg); + 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_READ(sc->phy_sc, TSEC_REG_MIIMIND) & + while (--timeout && TSEC_PHY_READ(sc, TSEC_REG_MIIMIND) & (TSEC_MIIMIND_NOTVALID | TSEC_MIIMIND_BUSY)) DELAY(TSEC_READ_DELAY); if (timeout == 0) device_printf(dev, "Timeout while reading from PHY!\n"); - return (TSEC_READ(sc->phy_sc, TSEC_REG_MIIMSTAT)); + rv = TSEC_PHY_READ(sc, TSEC_REG_MIIMSTAT); + TSEC_PHY_UNLOCK(); + + return (rv); } int @@ -1587,13 +1601,15 @@ tsec_miibus_writereg(device_t dev, int phy, int reg, int value) sc = device_get_softc(dev); - TSEC_WRITE(sc->phy_sc, TSEC_REG_MIIMADD, (phy << 8) | reg); - TSEC_WRITE(sc->phy_sc, TSEC_REG_MIIMCON, value); + 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->phy_sc, TSEC_REG_MIIMIND) & + while (--timeout && (TSEC_READ(sc, TSEC_REG_MIIMIND) & TSEC_MIIMIND_BUSY)) DELAY(TSEC_READ_DELAY); + TSEC_PHY_UNLOCK(); if (timeout == 0) device_printf(dev, "Timeout while writing to PHY!\n"); |