From: Gerhard Engleder <gerhard@engleder-embedded.com>
To: andrew@lunn.ch, hkallweit1@gmail.com, linux@armlinux.org.uk,
davem@davemloft.net, edumazet@google.com, kuba@kernel.org,
pabeni@redhat.com
Cc: netdev@vger.kernel.org, Gerhard Engleder <gerhard@engleder-embedded.com>
Subject: [PATCH net-next v5 7/7] tsnep: Add PHY loopback selftests
Date: Wed, 5 Feb 2025 20:08:23 +0100 [thread overview]
Message-ID: <20250205190823.23528-8-gerhard@engleder-embedded.com> (raw)
In-Reply-To: <20250205190823.23528-1-gerhard@engleder-embedded.com>
Add loopback selftests on PHY level. This enables quick testing of
loopback functionality to ensure working loopback for testing.
Signed-off-by: Gerhard Engleder <gerhard@engleder-embedded.com>
---
drivers/net/ethernet/engleder/Kconfig | 1 +
.../net/ethernet/engleder/tsnep_selftests.c | 153 +++++++++++++++++-
2 files changed, 150 insertions(+), 4 deletions(-)
diff --git a/drivers/net/ethernet/engleder/Kconfig b/drivers/net/ethernet/engleder/Kconfig
index 3df6bf476ae7..8245a9c4377d 100644
--- a/drivers/net/ethernet/engleder/Kconfig
+++ b/drivers/net/ethernet/engleder/Kconfig
@@ -32,6 +32,7 @@ config TSNEP_SELFTESTS
bool "TSN endpoint self test support"
default n
depends on TSNEP
+ imply NET_SELFTESTS
help
This enables self test support within the TSN endpoint driver.
diff --git a/drivers/net/ethernet/engleder/tsnep_selftests.c b/drivers/net/ethernet/engleder/tsnep_selftests.c
index 8a9145f93147..c9857e5a8033 100644
--- a/drivers/net/ethernet/engleder/tsnep_selftests.c
+++ b/drivers/net/ethernet/engleder/tsnep_selftests.c
@@ -4,12 +4,15 @@
#include "tsnep.h"
#include <net/pkt_sched.h>
+#include <net/selftests.h>
enum tsnep_test {
TSNEP_TEST_ENABLE = 0,
TSNEP_TEST_TAPRIO,
TSNEP_TEST_TAPRIO_CHANGE,
TSNEP_TEST_TAPRIO_EXTENSION,
+ TSNEP_TEST_PHY_1000_LOOPBACK,
+ TSNEP_TEST_PHY_100_LOOPBACK,
};
static const char tsnep_test_strings[][ETH_GSTRING_LEN] = {
@@ -17,6 +20,8 @@ static const char tsnep_test_strings[][ETH_GSTRING_LEN] = {
"TAPRIO (offline)",
"TAPRIO change (offline)",
"TAPRIO extension (offline)",
+ "PHY 1000Mbps loopback (offline)",
+ "PHY 100Mbps loopback (offline)",
};
#define TSNEP_TEST_COUNT (sizeof(tsnep_test_strings) / ETH_GSTRING_LEN)
@@ -754,6 +759,133 @@ static bool tsnep_test_taprio_extension(struct tsnep_adapter *adapter)
return false;
}
+static bool test_loopback(struct tsnep_adapter *adapter, int speed)
+{
+ struct phy_device *phydev = adapter->phydev;
+ int retval;
+
+ retval = phy_loopback(phydev, true, speed);
+ if (retval || !phydev->loopback_enabled || !phydev->link ||
+ phydev->speed != speed)
+ return false;
+
+ retval = net_test_phy_loopback_udp(adapter->netdev);
+ if (retval)
+ return false;
+
+ retval = net_test_phy_loopback_udp_mtu(adapter->netdev);
+ if (retval)
+ return false;
+
+ retval = net_test_phy_loopback_tcp(adapter->netdev);
+ if (retval)
+ return false;
+
+ retval = phy_loopback(phydev, false, 0);
+ if (retval || phydev->loopback_enabled)
+ return false;
+
+ return true;
+}
+
+static bool set_speed(struct tsnep_adapter *adapter, int speed)
+{
+ struct ethtool_link_ksettings cmd;
+ int retval;
+
+ retval = tsnep_ethtool_ops.get_link_ksettings(adapter->netdev, &cmd);
+ if (retval)
+ return false;
+
+ if (speed) {
+ cmd.base.speed = speed;
+ cmd.base.duplex = DUPLEX_FULL;
+ cmd.base.autoneg = AUTONEG_DISABLE;
+ } else {
+ cmd.base.autoneg = AUTONEG_ENABLE;
+ }
+
+ retval = tsnep_ethtool_ops.set_link_ksettings(adapter->netdev, &cmd);
+ if (retval)
+ return false;
+
+ return true;
+}
+
+static bool tsnep_test_phy_1000_loopback(struct tsnep_adapter *adapter)
+{
+ if (!adapter->netdev->phydev)
+ return false;
+
+ if (!test_loopback(adapter, 1000))
+ goto failed;
+
+ /* after autonegotiation */
+ if (!set_speed(adapter, 0))
+ goto failed;
+ if (!test_loopback(adapter, 1000))
+ goto failed;
+
+ /* after 100Mbps fixed speed */
+ if (!set_speed(adapter, 100))
+ goto failed;
+ if (!test_loopback(adapter, 1000))
+ goto failed;
+
+ /* after 1000Mbps fixed speed */
+ if (!set_speed(adapter, 1000))
+ goto failed;
+ if (!test_loopback(adapter, 1000))
+ goto failed;
+
+ if (!set_speed(adapter, 0))
+ goto failed;
+
+ return true;
+
+failed:
+ phy_loopback(adapter->phydev, false, 0);
+ set_speed(adapter, 0);
+ return false;
+}
+
+static bool tsnep_test_phy_100_loopback(struct tsnep_adapter *adapter)
+{
+ if (!adapter->netdev->phydev)
+ return false;
+
+ if (!test_loopback(adapter, 100))
+ goto failed;
+
+ /* after autonegotiation */
+ if (!set_speed(adapter, 0))
+ goto failed;
+ if (!test_loopback(adapter, 100))
+ goto failed;
+
+ /* 100Mbps fixed speed */
+ if (!set_speed(adapter, 100))
+ goto failed;
+ if (!test_loopback(adapter, 100))
+ goto failed;
+
+ /* 1000Mbps fixed speed */
+ if (!set_speed(adapter, 1000))
+ goto failed;
+ if (!test_loopback(adapter, 100))
+ goto failed;
+
+ if (!set_speed(adapter, 0))
+ goto failed;
+
+ return true;
+
+failed:
+ phy_loopback(adapter->phydev, false, 0);
+ set_speed(adapter, 0);
+ return false;
+}
+
int tsnep_ethtool_get_test_count(void)
{
return TSNEP_TEST_COUNT;
@@ -768,15 +900,14 @@ void tsnep_ethtool_self_test(struct net_device *netdev,
struct ethtool_test *eth_test, u64 *data)
{
struct tsnep_adapter *adapter = netdev_priv(netdev);
+ int i;
eth_test->len = TSNEP_TEST_COUNT;
if (eth_test->flags != ETH_TEST_FL_OFFLINE) {
/* no tests are done online */
- data[TSNEP_TEST_ENABLE] = 0;
- data[TSNEP_TEST_TAPRIO] = 0;
- data[TSNEP_TEST_TAPRIO_CHANGE] = 0;
- data[TSNEP_TEST_TAPRIO_EXTENSION] = 0;
+ for (i = 0; i < TSNEP_TEST_COUNT; i++)
+ data[i] = 0;
return;
}
@@ -808,4 +939,18 @@ void tsnep_ethtool_self_test(struct net_device *netdev,
eth_test->flags |= ETH_TEST_FL_FAILED;
data[TSNEP_TEST_TAPRIO_EXTENSION] = 1;
}
+
+ if (tsnep_test_phy_1000_loopback(adapter)) {
+ data[TSNEP_TEST_PHY_1000_LOOPBACK] = 0;
+ } else {
+ eth_test->flags |= ETH_TEST_FL_FAILED;
+ data[TSNEP_TEST_PHY_1000_LOOPBACK] = 1;
+ }
+
+ if (tsnep_test_phy_100_loopback(adapter)) {
+ data[TSNEP_TEST_PHY_100_LOOPBACK] = 0;
+ } else {
+ eth_test->flags |= ETH_TEST_FL_FAILED;
+ data[TSNEP_TEST_PHY_100_LOOPBACK] = 1;
+ }
}
--
2.39.5
prev parent reply other threads:[~2025-02-05 19:08 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-02-05 19:08 [PATCH net-next v5 0/7] Support loopback mode speed selection Gerhard Engleder
2025-02-05 19:08 ` [PATCH net-next v5 1/7] net: phy: Allow loopback speed selection for PHY drivers Gerhard Engleder
2025-02-05 19:08 ` [PATCH net-next v5 2/7] net: phy: Support speed selection for PHY loopback Gerhard Engleder
2025-02-08 0:16 ` Jakub Kicinski
2025-02-09 18:52 ` Gerhard Engleder
2025-02-05 19:08 ` [PATCH net-next v5 3/7] net: phy: micrel: Add loopback support Gerhard Engleder
2025-02-05 19:08 ` [PATCH net-next v5 4/7] net: phy: marvell: Align set_loopback() implementation Gerhard Engleder
2025-02-05 19:08 ` [PATCH net-next v5 5/7] tsnep: Select speed for loopback Gerhard Engleder
2025-02-05 19:08 ` [PATCH net-next v5 6/7] net: selftests: Export net_test_phy_loopback_* Gerhard Engleder
2025-02-05 19:08 ` Gerhard Engleder [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20250205190823.23528-8-gerhard@engleder-embedded.com \
--to=gerhard@engleder-embedded.com \
--cc=andrew@lunn.ch \
--cc=davem@davemloft.net \
--cc=edumazet@google.com \
--cc=hkallweit1@gmail.com \
--cc=kuba@kernel.org \
--cc=linux@armlinux.org.uk \
--cc=netdev@vger.kernel.org \
--cc=pabeni@redhat.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.