Messages in this thread Patch in this message | | | From | Oleksij Rempel <> | Subject | [PATCH net-next v2 7/8] net: phy: at803x: Fix SmartEEE support for some link configurations | Date | Mon, 27 Mar 2023 16:22:01 +0200 |
| |
This commit fixes SmartEEE support for certain link configurations on the AR8035 PHY. Before this patch, if AR8035 was running with SmartEEE enabled (EEE and LPI are on), it would not be able to establish a 100BaseTX/Half or 1000BaseT/Half link. A similar issue would occur with 100BaseTX/Full and an LPI TX timer configured to less than 80 msec.
To avoid this issue, we need to keep LPI disabled before the link is established and enable it only when a supported link configuration is detected. By implementing this fix, the at803x driver can now correctly handle SmartEEE features for various link configurations, improving link establishment, compatibility, and overall performance.
Signed-off-by: Oleksij Rempel <o.rempel@pengutronix.de> --- drivers/net/phy/at803x.c | 38 +++++++++++++++++++++++++++++++++----- 1 file changed, 33 insertions(+), 5 deletions(-)
diff --git a/drivers/net/phy/at803x.c b/drivers/net/phy/at803x.c index 4f65b3ebf806..5a12f778d675 100644 --- a/drivers/net/phy/at803x.c +++ b/drivers/net/phy/at803x.c @@ -1014,10 +1014,15 @@ static int at803x_smarteee_config(struct phy_device *phydev) if (ret) return ret; - val = AT803X_MMD3_SMARTEEE_CTL3_LPI_EN | - FIELD_PREP(AT803X_MMD3_SMARTEEE_LPI_TIME_HIGH, - FIELD_GET(AT803X_MMD3_SMARTEEE_LPI_TIME_23_16, - tx_lpi_timer_raw)); + val = FIELD_PREP(AT803X_MMD3_SMARTEEE_LPI_TIME_HIGH, + FIELD_GET(AT803X_MMD3_SMARTEEE_LPI_TIME_23_16, + tx_lpi_timer_raw)); + + if (phydev->state == PHY_RUNNING && + phy_check_valid(phydev->speed, phydev->duplex, + phydev->supported_eee)) { + val |= AT803X_MMD3_SMARTEEE_CTL3_LPI_EN; + } return phy_modify_mmd(phydev, MDIO_MMD_PCS, AT803X_MMD3_SMARTEEE_CTL3, AT803X_MMD3_SMARTEEE_CTL3_LPI_EN | @@ -1691,7 +1696,7 @@ static int at803x_get_eee(struct phy_device *phydev, struct ethtool_eee *data) tx_timer_ns = tx_timer_raw * AT803X_MMD3_SMARTEEE_LPI_TIME_RESOL_NS; data->tx_lpi_timer = DIV_ROUND_CLOSEST_ULL(tx_timer_ns, NSEC_PER_USEC); - data->tx_lpi_enabled = !!(ret & AT803X_MMD3_SMARTEEE_CTL3_LPI_EN); + data->tx_lpi_enabled = priv->tx_lpi_on; return genphy_c45_ethtool_get_eee(phydev, data); } @@ -1725,6 +1730,28 @@ static int at803x_set_eee(struct phy_device *phydev, struct ethtool_eee *data) return genphy_c45_ethtool_set_eee(phydev, data); } +static void at8035_link_change_notify(struct phy_device *phydev) +{ + struct at803x_priv *priv = phydev->priv; + + if (phydev->mac_supports_eee || !phydev->is_smart_eee_phy) + return; + + if (phydev->state == PHY_RUNNING) { + if (priv->tx_lpi_on && phy_check_valid(phydev->speed, + phydev->duplex, + phydev->supported_eee)) + phy_set_bits_mmd(phydev, MDIO_MMD_PCS, + AT803X_MMD3_SMARTEEE_CTL3, + AT803X_MMD3_SMARTEEE_CTL3_LPI_EN); + } else { + if (priv->tx_lpi_on) + phy_clear_bits_mmd(phydev, MDIO_MMD_PCS, + AT803X_MMD3_SMARTEEE_CTL3, + AT803X_MMD3_SMARTEEE_CTL3_LPI_EN); + } +} + static int qca83xx_config_init(struct phy_device *phydev) { u8 switch_revision; @@ -2153,6 +2180,7 @@ static struct phy_driver at803x_driver[] = { .cable_test_get_status = at803x_cable_test_get_status, .get_eee = at803x_get_eee, .set_eee = at803x_set_eee, + .link_change_notify = at8035_link_change_notify, }, { /* Qualcomm Atheros AR8030 */ .phy_id = ATH8030_PHY_ID, -- 2.30.2
| |