From: Oleksij Rempel Date: Tue, 10 Jun 2025 09:13:54 +0000 (+0200) Subject: net: phy: micrel: add cable test support for KSZ9477-class PHYs X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=b2f96c3c96314ff3888ebb7d3126cf5f5e7c278b;p=thirdparty%2Flinux.git net: phy: micrel: add cable test support for KSZ9477-class PHYs Enable cable test support for KSZ9477-class PHYs by reusing the existing KSZ9131 implementation. This also adds support for 100Mbit-only PHYs like KSZ8563, which are identified as KSZ9477. For these PHYs, only two wire pairs (A and B) are active, so the cable test logic limits the pair_mask accordingly. Support for KSZ8563 is untested but added based on its register compatibility and PHY ID match. Tested on KSZ9893 (Gigabit): open and short conditions were correctly detected on all four pairs. Fault length reporting is functional and varies by pair. For example: - 2m cable: open faults reported ~1.2m (pairs B–D), 0.0m (pair A) - No cable: all pairs report 0.0m fault length Signed-off-by: Oleksij Rempel Reviewed-by: Andrew Lunn Link: https://patch.msgid.link/20250610091354.4060454-4-o.rempel@pengutronix.de Signed-off-by: Jakub Kicinski --- diff --git a/drivers/net/phy/micrel.c b/drivers/net/phy/micrel.c index 68d86383e6c7a..d0429dc8f5613 100644 --- a/drivers/net/phy/micrel.c +++ b/drivers/net/phy/micrel.c @@ -1723,7 +1723,8 @@ static int ksz9x31_cable_test_fault_length(struct phy_device *phydev, u16 stat) * * distance to fault = (VCT_DATA - 22) * 4 / cable propagation velocity */ - if (phydev_id_compare(phydev, PHY_ID_KSZ9131)) + if (phydev_id_compare(phydev, PHY_ID_KSZ9131) || + phydev_id_compare(phydev, PHY_ID_KSZ9477)) dt = clamp(dt - 22, 0, 255); return (dt * 400) / 10; @@ -1797,12 +1798,20 @@ static int ksz9x31_cable_test_get_status(struct phy_device *phydev, bool *finished) { struct kszphy_priv *priv = phydev->priv; - unsigned long pair_mask = 0xf; + unsigned long pair_mask; int retries = 20; int pair, ret, rv; *finished = false; + if (linkmode_test_bit(ETHTOOL_LINK_MODE_1000baseT_Full_BIT, + phydev->supported) || + linkmode_test_bit(ETHTOOL_LINK_MODE_1000baseT_Half_BIT, + phydev->supported)) + pair_mask = 0xf; /* All pairs */ + else + pair_mask = 0x3; /* Pairs A and B only */ + /* Try harder if link partner is active */ while (pair_mask && retries--) { for_each_set_bit(pair, &pair_mask, 4) { @@ -5790,6 +5799,8 @@ static struct phy_driver ksphy_driver[] = { .resume = ksz9477_resume, .get_phy_stats = kszphy_get_phy_stats, .update_stats = kszphy_update_stats, + .cable_test_start = ksz9x31_cable_test_start, + .cable_test_get_status = ksz9x31_cable_test_get_status, } }; module_phy_driver(ksphy_driver);