summaryrefslogtreecommitdiff
path: root/drivers/net/phy/micrel.c
diff options
context:
space:
mode:
authorOleksij Rempel <o.rempel@pengutronix.de>2025-06-10 11:13:54 +0200
committerJakub Kicinski <kuba@kernel.org>2025-06-11 17:37:48 -0700
commitb2f96c3c96314ff3888ebb7d3126cf5f5e7c278b (patch)
tree2420f1fd98e9161bac3e90e8f71ce87689057363 /drivers/net/phy/micrel.c
parent597ebdf37222ba7deb2ed24aa4de777d7edf22f7 (diff)
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>
Diffstat (limited to 'drivers/net/phy/micrel.c')
-rw-r--r--drivers/net/phy/micrel.c15
1 files changed, 13 insertions, 2 deletions
diff --git a/drivers/net/phy/micrel.c b/drivers/net/phy/micrel.c
index 68d86383e6c7..d0429dc8f561 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);