From: Raju Rangoju Date: Fri, 31 Oct 2025 11:15:55 +0000 (+0530) Subject: amd-xgbe: add ethtool phy loopback selftest X-Git-Tag: v6.19-rc1~170^2~224^2~2 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=42b06fcc878d08785a0c44d2af42c8db453487e2;p=thirdparty%2Flinux.git amd-xgbe: add ethtool phy loopback selftest Add support for PHY loopback testing via ethtool self-test. The test uses phy_loopback() which enables PHY-level loopback through the PHY driver's set_loopback callback if provided, else uses the genphy_loopback(). Signed-off-by: Raju Rangoju Reviewed-by: Maxime Chevallier Link: https://patch.msgid.link/20251031111555.774425-3-Raju.Rangoju@amd.com Signed-off-by: Paolo Abeni --- diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-selftest.c b/drivers/net/ethernet/amd/xgbe/xgbe-selftest.c index 8a3a6279584d3..23b9d568a861e 100644 --- a/drivers/net/ethernet/amd/xgbe/xgbe-selftest.c +++ b/drivers/net/ethernet/amd/xgbe/xgbe-selftest.c @@ -19,6 +19,7 @@ #define XGBE_LOOPBACK_NONE 0 #define XGBE_LOOPBACK_MAC 1 +#define XGBE_LOOPBACK_PHY 2 struct xgbe_test { char name[ETH_GSTRING_LEN]; @@ -151,11 +152,36 @@ static int xgbe_test_mac_loopback(struct xgbe_prv_data *pdata) return __xgbe_test_loopback(pdata, &attr); } +static int xgbe_test_phy_loopback(struct xgbe_prv_data *pdata) +{ + struct net_packet_attrs attr = {}; + int ret; + + if (!pdata->netdev->phydev) { + netdev_err(pdata->netdev, "phydev not found: cannot start PHY loopback test\n"); + return -EOPNOTSUPP; + } + + ret = phy_loopback(pdata->netdev->phydev, true, 0); + if (ret) + return ret; + + attr.dst = pdata->netdev->dev_addr; + ret = __xgbe_test_loopback(pdata, &attr); + + phy_loopback(pdata->netdev->phydev, false, 0); + return ret; +} + static const struct xgbe_test xgbe_selftests[] = { { .name = "MAC Loopback ", .lb = XGBE_LOOPBACK_MAC, .fn = xgbe_test_mac_loopback, + }, { + .name = "PHY Loopback ", + .lb = XGBE_LOOPBACK_NONE, + .fn = xgbe_test_phy_loopback, }, }; @@ -187,6 +213,13 @@ void xgbe_selftest_run(struct net_device *dev, ret = 0; switch (xgbe_selftests[i].lb) { + case XGBE_LOOPBACK_PHY: + ret = -EOPNOTSUPP; + if (dev->phydev) + ret = phy_loopback(dev->phydev, true, 0); + if (!ret) + break; + fallthrough; case XGBE_LOOPBACK_MAC: ret = xgbe_enable_mac_loopback(pdata); break; @@ -213,6 +246,13 @@ void xgbe_selftest_run(struct net_device *dev, buf[i] = ret; switch (xgbe_selftests[i].lb) { + case XGBE_LOOPBACK_PHY: + ret = -EOPNOTSUPP; + if (dev->phydev) + ret = phy_loopback(dev->phydev, false, 0); + if (!ret) + break; + fallthrough; case XGBE_LOOPBACK_MAC: xgbe_disable_mac_loopback(pdata); break;