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 <o.rempel@pengutronix.de>
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Link: https://patch.msgid.link/20250610091354.4060454-4-o.rempel@pengutronix.de
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
Oleksij Rempel
2025-06-11 17:37:48 -07:00
committed by Jakub Kicinski
parent 597ebdf372
commit b2f96c3c96
+13 -2
View File
@@ -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);