diff options
author | Oleksij Rempel <o.rempel@pengutronix.de> | 2021-04-19 15:01:02 +0200 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2021-04-20 16:08:02 -0700 |
commit | 014068dcb5b17dae110354c4de241833124edba1 (patch) | |
tree | 3499634ec0f208cf20e67d7cb1278c552b4b46c5 /drivers/net/phy/phy_device.c | |
parent | f4f86d8d2c04bc0c90f8d944a1fcc30349ba01b3 (diff) | |
download | lwn-014068dcb5b17dae110354c4de241833124edba1.tar.gz lwn-014068dcb5b17dae110354c4de241833124edba1.zip |
net: phy: genphy_loopback: add link speed configuration
In case of loopback, in most cases we need to disable autoneg support
and force some speed configuration. Otherwise, depending on currently
active auto negotiated link speed, the loopback may or may not work.
This patch was tested with following PHYs: TJA1102, KSZ8081, KSZ9031,
AT8035, AR9331.
Signed-off-by: Oleksij Rempel <o.rempel@pengutronix.de>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/phy/phy_device.c')
-rw-r--r-- | drivers/net/phy/phy_device.c | 28 |
1 files changed, 26 insertions, 2 deletions
diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c index 320a3e5cd10a..0a2d8bedf73d 100644 --- a/drivers/net/phy/phy_device.c +++ b/drivers/net/phy/phy_device.c @@ -2565,8 +2565,32 @@ EXPORT_SYMBOL(genphy_resume); int genphy_loopback(struct phy_device *phydev, bool enable) { - return phy_modify(phydev, MII_BMCR, BMCR_LOOPBACK, - enable ? BMCR_LOOPBACK : 0); + if (enable) { + u16 val, ctl = BMCR_LOOPBACK; + int ret; + + if (phydev->speed == SPEED_1000) + ctl |= BMCR_SPEED1000; + else if (phydev->speed == SPEED_100) + ctl |= BMCR_SPEED100; + + if (phydev->duplex == DUPLEX_FULL) + ctl |= BMCR_FULLDPLX; + + phy_modify(phydev, MII_BMCR, ~0, ctl); + + ret = phy_read_poll_timeout(phydev, MII_BMSR, val, + val & BMSR_LSTATUS, + 5000, 500000, true); + if (ret) + return ret; + } else { + phy_modify(phydev, MII_BMCR, BMCR_LOOPBACK, 0); + + phy_config_aneg(phydev); + } + + return 0; } EXPORT_SYMBOL(genphy_loopback); |