Commit 42b06fcc authored by Raju Rangoju's avatar Raju Rangoju Committed by Paolo Abeni
Browse files

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: default avatarRaju Rangoju <Raju.Rangoju@amd.com>
Reviewed-by: default avatarMaxime Chevallier <maxime.chevallier@bootlin.com>
Link: https://patch.msgid.link/20251031111555.774425-3-Raju.Rangoju@amd.com


Signed-off-by: default avatarPaolo Abeni <pabeni@redhat.com>
parent 862a64c8
Loading
Loading
Loading
Loading
+40 −0
Original line number Diff line number Diff line
@@ -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;