[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20250610091354.4060454-4-o.rempel@pengutronix.de>
Date: Tue, 10 Jun 2025 11:13:54 +0200
From: Oleksij Rempel <o.rempel@...gutronix.de>
To: Andrew Lunn <andrew@...n.ch>,
Heiner Kallweit <hkallweit1@...il.com>,
"David S. Miller" <davem@...emloft.net>,
Eric Dumazet <edumazet@...gle.com>,
Jakub Kicinski <kuba@...nel.org>,
Paolo Abeni <pabeni@...hat.com>
Cc: Oleksij Rempel <o.rempel@...gutronix.de>,
kernel@...gutronix.de,
linux-kernel@...r.kernel.org,
Russell King <linux@...linux.org.uk>,
netdev@...r.kernel.org
Subject: [PATCH net-next v1 3/3] 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@...gutronix.de>
---
drivers/net/phy/micrel.c | 15 +++++++++++++--
1 file 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);
--
2.39.5
Powered by blists - more mailing lists