mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [PATCH RFC net-next 0/2] net: hibmcge: add support for selftest
@ 2025-04-21 13:43 Jijie Shao
  2025-04-21 13:43 ` [PATCH RFC net-next 1/2] net: selftest: add net_selftest_custom() interface Jijie Shao
  2025-04-21 13:43 ` [PATCH RFC net-next 2/2] net: hibmcge: add support for selftest Jijie Shao
  0 siblings, 2 replies; 4+ messages in thread
From: Jijie Shao @ 2025-04-21 13:43 UTC (permalink / raw)
  To: davem, edumazet, kuba, pabeni, andrew+netdev, horms
  Cc: shenjian15, wangpeiyang1, liuyonglong, chenhao418,
	jonathan.cameron, shameerali.kolothum.thodi, salil.mehta, netdev,
	linux-kernel, gerhard, shaojijie

patch1: the net_selftest_custom() interface is added
to support driver customized loopback tests and
common loopback tests.

patch2: add selftest support for hibmcge

Jijie Shao (2):
  net: selftest: add net_selftest_custom() interface
  net: hibmcge: add support for selftest

 .../ethernet/hisilicon/hibmcge/hbg_common.h   |   2 +
 .../ethernet/hisilicon/hibmcge/hbg_ethtool.c  |  60 +++++-
 .../net/ethernet/hisilicon/hibmcge/hbg_hw.c   |   6 +
 .../net/ethernet/hisilicon/hibmcge/hbg_hw.h   |   1 +
 .../net/ethernet/hisilicon/hibmcge/hbg_reg.h  |   1 +
 .../net/ethernet/hisilicon/hibmcge/hbg_txrx.c |   3 +-
 include/net/selftests.h                       |  61 ++++++
 net/core/selftests.c                          | 188 +++++++++++++++++-
 8 files changed, 310 insertions(+), 12 deletions(-)

-- 
2.33.0


^ permalink raw reply	[flat|nested] 4+ messages in thread

* [PATCH RFC net-next 1/2] net: selftest: add net_selftest_custom() interface
  2025-04-21 13:43 [PATCH RFC net-next 0/2] net: hibmcge: add support for selftest Jijie Shao
@ 2025-04-21 13:43 ` Jijie Shao
  2025-04-25 20:15   ` Gerhard Engleder
  2025-04-21 13:43 ` [PATCH RFC net-next 2/2] net: hibmcge: add support for selftest Jijie Shao
  1 sibling, 1 reply; 4+ messages in thread
From: Jijie Shao @ 2025-04-21 13:43 UTC (permalink / raw)
  To: davem, edumazet, kuba, pabeni, andrew+netdev, horms
  Cc: shenjian15, wangpeiyang1, liuyonglong, chenhao418,
	jonathan.cameron, shameerali.kolothum.thodi, salil.mehta, netdev,
	linux-kernel, gerhard, shaojijie

In net/core/selftests.c,
net_selftest() supports loopback tests.
However, the loopback content of this interface is a fixed common test
and cannot be expanded to add the driver's own test.

In this patch, the net_selftest_custom() interface is added
to support driver customized loopback tests and
extra common loopback tests.

Signed-off-by: Jijie Shao <shaojijie@huawei.com>
---
 include/net/selftests.h |  61 +++++++++++++
 net/core/selftests.c    | 188 +++++++++++++++++++++++++++++++++++++++-
 2 files changed, 245 insertions(+), 4 deletions(-)

diff --git a/include/net/selftests.h b/include/net/selftests.h
index e65e8d230d33..a36e6ee0a41f 100644
--- a/include/net/selftests.h
+++ b/include/net/selftests.h
@@ -4,6 +4,48 @@
 
 #include <linux/ethtool.h>
 
+#define NET_TEST_NETIF_CARRIER		BIT(0)
+#define NET_TEST_FULL_DUPLEX		BIT(1)
+#define NET_TEST_TCP			BIT(2)
+#define NET_TEST_UDP			BIT(3)
+#define NET_TEST_UDP_MAX_MTU		BIT(4)
+
+#define NET_EXTRA_CARRIER_TEST		BIT(0)
+#define NET_EXTRA_FULL_DUPLEX_TEST	BIT(1)
+#define NET_EXTRA_PHY_TEST		BIT(2)
+
+struct net_test_entry {
+	char name[ETH_GSTRING_LEN];
+
+	/* can set to NULL */
+	int (*enable)(struct net_device *ndev, bool enable);
+
+	/* can set to NULL */
+	int (*fn)(struct net_device *ndev);
+
+	/* if flag is set, fn() will be ignored,
+	 * and will do test according to the flag,
+	 * such as NET_TEST_UDP...
+	 */
+	unsigned long flags;
+};
+
+#define NET_TEST_E(_name, _enable, _flags) { \
+	.name = _name, \
+	.enable = _enable, \
+	.fn = NULL, \
+	.flags = _flags }
+
+#define NET_TEST_ENTRY_MAX_COUNT	10
+struct net_test {
+	/* extra tests will be added based on this flag */
+	unsigned long extra_flags;
+
+	struct net_test_entry entries[NET_TEST_ENTRY_MAX_COUNT];
+	/* the count of entries, must <= NET_TEST_ENTRY_MAX_COUNT */
+	u32 count;
+};
+
 #if IS_ENABLED(CONFIG_NET_SELFTESTS)
 
 void net_selftest(struct net_device *ndev, struct ethtool_test *etest,
@@ -11,6 +53,11 @@ void net_selftest(struct net_device *ndev, struct ethtool_test *etest,
 int net_selftest_get_count(void);
 void net_selftest_get_strings(u8 *data);
 
+void net_selftest_custom(struct net_device *ndev, const struct net_test *test,
+			 struct ethtool_test *etest, u64 *buf);
+int net_selftest_get_count_custom(const struct net_test *test);
+void net_selftest_get_strings_custom(const struct net_test *test, u8 *data);
+
 #else
 
 static inline void net_selftest(struct net_device *ndev, struct ethtool_test *etest,
@@ -27,5 +74,19 @@ static inline void net_selftest_get_strings(u8 *data)
 {
 }
 
+void net_selftest_custom(struct net_device *ndev, struct net_test *test,
+			 struct ethtool_test *etest, u64 *buf)
+{
+}
+
+int net_selftest_get_count_custom(struct net_test *test)
+{
+	return 0;
+}
+
+void net_selftest_get_strings_custom(struct net_test *test, u8 *data)
+{
+}
+
 #endif
 #endif /* _NET_SELFTESTS */
diff --git a/net/core/selftests.c b/net/core/selftests.c
index e99ae983fca9..e6abae17f324 100644
--- a/net/core/selftests.c
+++ b/net/core/selftests.c
@@ -289,6 +289,11 @@ static int net_test_netif_carrier(struct net_device *ndev)
 	return netif_carrier_ok(ndev) ? 0 : -ENOLINK;
 }
 
+static int net_test_full_duplex(struct net_device *ndev)
+{
+	return ndev->phydev->duplex == DUPLEX_FULL ? 0 : -EINVAL;
+}
+
 static int net_test_phy_phydev(struct net_device *ndev)
 {
 	return ndev->phydev ? 0 : -EOPNOTSUPP;
@@ -336,10 +341,7 @@ static int net_test_phy_loopback_tcp(struct net_device *ndev)
 	return __net_test_loopback(ndev, &attr);
 }
 
-static const struct net_test {
-	char name[ETH_GSTRING_LEN];
-	int (*fn)(struct net_device *ndev);
-} net_selftests[] = {
+static const struct net_test_entry net_selftests[] = {
 	{
 		.name = "Carrier                       ",
 		.fn = net_test_netif_carrier,
@@ -405,6 +407,184 @@ void net_selftest_get_strings(u8 *data)
 }
 EXPORT_SYMBOL_GPL(net_selftest_get_strings);
 
+static const struct net_do_test_func {
+	int flag;
+	int (*fn)(struct net_device *ndev);
+} net_do_test_funcs[] = {
+	{ NET_TEST_NETIF_CARRIER, net_test_netif_carrier },
+	{ NET_TEST_FULL_DUPLEX, net_test_full_duplex },
+	{ NET_TEST_UDP, net_test_phy_loopback_udp },
+	{ NET_TEST_TCP, net_test_phy_loopback_tcp },
+	{ NET_TEST_UDP_MAX_MTU, net_test_phy_loopback_udp_mtu },
+};
+
+static int net_do_test(struct net_device *ndev,
+		       const struct net_test_entry *entry)
+{
+	int ret = -EOPNOTSUPP;
+	u32 i;
+
+	if (!entry->flags && entry->fn)
+		return entry->fn(ndev);
+
+	for (i = 0; i < ARRAY_SIZE(net_do_test_funcs); i++) {
+		if (!(entry->flags & net_do_test_funcs[i].flag))
+			continue;
+
+		ret = net_do_test_funcs[i].fn(ndev);
+		if (ret) {
+			netdev_err(ndev, "failed to do test, bit: %#x\n",
+				   net_do_test_funcs[i].flag);
+			return ret;
+		}
+	}
+
+	return ret;
+}
+
+static int net_selftest_entry(struct net_device *ndev,
+			      const struct net_test_entry *entry)
+{
+	int ret;
+
+	if (entry->enable) {
+		ret = entry->enable(ndev, true);
+		if (ret) {
+			netdev_err(ndev,
+				   "failed to enable test, ret = %d\n", ret);
+			return ret;
+		}
+	}
+
+	ret = net_do_test(ndev, entry);
+	if (entry->enable)
+		entry->enable(ndev, false);
+	return ret;
+}
+
+static void net_selftest_check_result(struct net_device *ndev,
+				      const struct net_test_entry *entry,
+				      struct ethtool_test *etest, u64 *result)
+{
+	*result = net_selftest_entry(ndev, entry);
+	if (*result)
+		etest->flags |= ETH_TEST_FL_FAILED;
+}
+
+static int net_test_prepare(struct net_device *ndev,
+			    const struct net_test *test,
+			    struct ethtool_test *etest, u64 *buf)
+{
+	u32 i;
+
+	/* first set all results to -ENOEXEC,
+	 * test->count is also checked in .net_selftest_get_count_custom()
+	 */
+	for (i = 0; i < net_selftest_get_count_custom(test); i++)
+		buf[i] = -ENOEXEC;
+
+	if (etest->flags != ETH_TEST_FL_OFFLINE) {
+		netdev_err(ndev, "Only offline tests are supported\n");
+		etest->flags |= ETH_TEST_FL_FAILED;
+		return -EOPNOTSUPP;
+	}
+
+	if (test->count > ARRAY_SIZE(test->entries)) {
+		netdev_err(ndev, "The count of entries exceeds the maximum\n");
+		etest->flags |= ETH_TEST_FL_FAILED;
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int net_test_phy_enable(struct net_device *ndev, bool enable)
+{
+	if (!ndev->phydev)
+		return -EOPNOTSUPP;
+
+	return phy_loopback(ndev->phydev, enable, 0);
+}
+
+static const struct net_extra_test {
+	int flag;
+	struct net_test_entry entry;
+} net_extra_tests[] = {
+	{
+		.flag = NET_EXTRA_CARRIER_TEST,
+		.entry = NET_TEST_E("Carrier", NULL, NET_TEST_NETIF_CARRIER),
+	}, {
+		.flag = NET_EXTRA_FULL_DUPLEX_TEST,
+		.entry = NET_TEST_E("Full Duplex", NULL, NET_TEST_FULL_DUPLEX),
+	}, {
+		/* this test must be the last one */
+		.flag = NET_EXTRA_PHY_TEST,
+		.entry = NET_TEST_E("PHY internal loopback",
+				    net_test_phy_enable,
+				    NET_TEST_UDP_MAX_MTU | NET_TEST_TCP),
+	}
+};
+
+void net_selftest_custom(struct net_device *ndev, const struct net_test *test,
+			 struct ethtool_test *etest, u64 *buf)
+{
+	u32 i, j = 0;
+	int ret;
+
+	ret = net_test_prepare(ndev, test, etest, buf);
+	if (ret)
+		return;
+
+	for (i = 0; i < test->count; i++)
+		net_selftest_check_result(ndev, &test->entries[i],
+					  etest, &buf[j++]);
+
+	for (i = 0; i < ARRAY_SIZE(net_extra_tests); i++)
+		if (test->extra_flags & net_extra_tests[i].flag)
+			net_selftest_check_result(ndev,
+						  &net_extra_tests[i].entry,
+						  etest, &buf[j++]);
+}
+EXPORT_SYMBOL_GPL(net_selftest_custom);
+
+int net_selftest_get_count_custom(const struct net_test *test)
+{
+	u32 i, exter_count = 0;
+
+	if (test->count > ARRAY_SIZE(test->entries))
+		return 0;
+
+	for (i = 0; i < ARRAY_SIZE(net_extra_tests); i++)
+		if (test->extra_flags & net_extra_tests[i].flag)
+			exter_count++;
+
+	return test->count + exter_count;
+}
+EXPORT_SYMBOL_GPL(net_selftest_get_count_custom);
+
+static void net_selftest_get_entry_string(const struct net_test_entry *entry,
+					  u32 index, u8 **data)
+{
+	ethtool_sprintf(data, "%2d. %-30s", index, entry->name);
+}
+
+void net_selftest_get_strings_custom(const struct net_test *test, u8 *data)
+{
+	u32 i, j = 1;
+
+	if (test->count > ARRAY_SIZE(test->entries))
+		return;
+
+	for (i = 0; i < test->count; i++)
+		net_selftest_get_entry_string(&test->entries[i], j++, &data);
+
+	for (i = 0; i < ARRAY_SIZE(net_extra_tests); i++)
+		if (test->extra_flags & net_extra_tests[i].flag)
+			net_selftest_get_entry_string(&net_extra_tests[i].entry,
+						      j++, &data);
+}
+EXPORT_SYMBOL_GPL(net_selftest_get_strings_custom);
+
 MODULE_DESCRIPTION("Common library for generic PHY ethtool selftests");
 MODULE_LICENSE("GPL v2");
 MODULE_AUTHOR("Oleksij Rempel <o.rempel@pengutronix.de>");
-- 
2.33.0


^ permalink raw reply	[flat|nested] 4+ messages in thread

* [PATCH RFC net-next 2/2] net: hibmcge: add support for selftest
  2025-04-21 13:43 [PATCH RFC net-next 0/2] net: hibmcge: add support for selftest Jijie Shao
  2025-04-21 13:43 ` [PATCH RFC net-next 1/2] net: selftest: add net_selftest_custom() interface Jijie Shao
@ 2025-04-21 13:43 ` Jijie Shao
  1 sibling, 0 replies; 4+ messages in thread
From: Jijie Shao @ 2025-04-21 13:43 UTC (permalink / raw)
  To: davem, edumazet, kuba, pabeni, andrew+netdev, horms
  Cc: shenjian15, wangpeiyang1, liuyonglong, chenhao418,
	jonathan.cameron, shameerali.kolothum.thodi, salil.mehta, netdev,
	linux-kernel, gerhard, shaojijie

This patch implements selftest, including MAC and SerDes selftest,
which is the driver's own test. The .enable() is implemented by the driver.

In addition, the driver sets extra_flags to
test the carrier status, full duplex, and PHY.

For example:
ethtool -t enp132s0f1
The test result is PASS
The test extra info:
 1. MAC internal loopback      	 0
 2. Serdes internal loopback   	 0
 3. Carrier                    	 0
 4. Full Duplex                	 0
 5. PHY internal loopback      	 0

Signed-off-by: Jijie Shao <shaojijie@huawei.com>
---
 .../ethernet/hisilicon/hibmcge/hbg_common.h   |  2 +
 .../ethernet/hisilicon/hibmcge/hbg_ethtool.c  | 60 ++++++++++++++++---
 .../net/ethernet/hisilicon/hibmcge/hbg_hw.c   |  6 ++
 .../net/ethernet/hisilicon/hibmcge/hbg_hw.h   |  1 +
 .../net/ethernet/hisilicon/hibmcge/hbg_reg.h  |  1 +
 .../net/ethernet/hisilicon/hibmcge/hbg_txrx.c |  3 +-
 6 files changed, 65 insertions(+), 8 deletions(-)

diff --git a/drivers/net/ethernet/hisilicon/hibmcge/hbg_common.h b/drivers/net/ethernet/hisilicon/hibmcge/hbg_common.h
index 7725cb0c5c8a..876933f88329 100644
--- a/drivers/net/ethernet/hisilicon/hibmcge/hbg_common.h
+++ b/drivers/net/ethernet/hisilicon/hibmcge/hbg_common.h
@@ -84,6 +84,8 @@ enum hbg_hw_event_type {
 	HBG_HW_EVENT_INIT, /* driver is loading */
 	HBG_HW_EVENT_RESET,
 	HBG_HW_EVENT_CORE_RESET,
+	HBG_HW_EVENT_SERDES_LOOP_ENABLE,
+	HBG_HW_EVENT_SERDES_LOOP_DISABLE = 5,
 };
 
 struct hbg_dev_specs {
diff --git a/drivers/net/ethernet/hisilicon/hibmcge/hbg_ethtool.c b/drivers/net/ethernet/hisilicon/hibmcge/hbg_ethtool.c
index 8f1107b85fbb..cc60bd76890d 100644
--- a/drivers/net/ethernet/hisilicon/hibmcge/hbg_ethtool.c
+++ b/drivers/net/ethernet/hisilicon/hibmcge/hbg_ethtool.c
@@ -4,6 +4,7 @@
 #include <linux/ethtool.h>
 #include <linux/phy.h>
 #include <linux/rtnetlink.h>
+#include <net/selftests.h>
 #include "hbg_common.h"
 #include "hbg_err.h"
 #include "hbg_ethtool.h"
@@ -339,12 +340,55 @@ void hbg_update_stats(struct hbg_priv *priv)
 				 ARRAY_SIZE(hbg_ethtool_ctrl_stats_info));
 }
 
+static int hbg_test_mac_loopback_enable(struct net_device *ndev,
+					bool enable)
+{
+	struct hbg_priv *priv = netdev_priv(ndev);
+
+	hbg_hw_loop_enable(priv, enable);
+	return 0;
+}
+
+static int hbg_test_serdes_loopback_enable(struct net_device *ndev,
+					   bool enable)
+{
+	struct hbg_priv *priv = netdev_priv(ndev);
+	u32 event = enable ? HBG_HW_EVENT_SERDES_LOOP_ENABLE :
+			     HBG_HW_EVENT_SERDES_LOOP_DISABLE;
+
+	return hbg_hw_event_notify(priv, event);
+}
+
+static const struct net_test hbg_test = {
+	.extra_flags = NET_EXTRA_CARRIER_TEST |
+		       NET_EXTRA_FULL_DUPLEX_TEST |
+		       NET_EXTRA_PHY_TEST,
+	.entries = {
+		NET_TEST_E("MAC internal loopback",
+			   hbg_test_mac_loopback_enable,
+			   NET_TEST_UDP_MAX_MTU | NET_TEST_TCP),
+		NET_TEST_E("Serdes internal loopback",
+			   hbg_test_serdes_loopback_enable,
+			   NET_TEST_UDP_MAX_MTU | NET_TEST_TCP),
+	},
+	.count = 2,
+};
+
+static void hbg_ethtool_self_test(struct net_device *netdev,
+				  struct ethtool_test *etest,
+				  u64 *buf)
+{
+	net_selftest_custom(netdev, &hbg_test, etest, buf);
+}
+
 static int hbg_ethtool_get_sset_count(struct net_device *netdev, int stringset)
 {
-	if (stringset != ETH_SS_STATS)
-		return -EOPNOTSUPP;
+	if (stringset == ETH_SS_STATS)
+		return ARRAY_SIZE(hbg_ethtool_stats_info);
+	else if (stringset == ETH_SS_TEST)
+		return net_selftest_get_count_custom(&hbg_test);
 
-	return ARRAY_SIZE(hbg_ethtool_stats_info);
+	return -EOPNOTSUPP;
 }
 
 static void hbg_ethtool_get_strings(struct net_device *netdev,
@@ -352,11 +396,12 @@ static void hbg_ethtool_get_strings(struct net_device *netdev,
 {
 	u32 i;
 
-	if (stringset != ETH_SS_STATS)
-		return;
+	if (stringset == ETH_SS_STATS)
+		for (i = 0; i < ARRAY_SIZE(hbg_ethtool_stats_info); i++)
+			ethtool_puts(&data, hbg_ethtool_stats_info[i].name);
+	else if (stringset == ETH_SS_TEST)
+		net_selftest_get_strings_custom(&hbg_test, data);
 
-	for (i = 0; i < ARRAY_SIZE(hbg_ethtool_stats_info); i++)
-		ethtool_puts(&data, hbg_ethtool_stats_info[i].name);
 }
 
 static void hbg_ethtool_get_stats(struct net_device *netdev,
@@ -488,6 +533,7 @@ static const struct ethtool_ops hbg_ethtool_ops = {
 	.get_eth_mac_stats	= hbg_ethtool_get_eth_mac_stats,
 	.get_eth_ctrl_stats	= hbg_ethtool_get_eth_ctrl_stats,
 	.get_rmon_stats		= hbg_ethtool_get_rmon_stats,
+	.self_test		= hbg_ethtool_self_test,
 };
 
 void hbg_ethtool_set_ops(struct net_device *netdev)
diff --git a/drivers/net/ethernet/hisilicon/hibmcge/hbg_hw.c b/drivers/net/ethernet/hisilicon/hibmcge/hbg_hw.c
index 9b65eef62b3f..ad3fc572bc13 100644
--- a/drivers/net/ethernet/hisilicon/hibmcge/hbg_hw.c
+++ b/drivers/net/ethernet/hisilicon/hibmcge/hbg_hw.c
@@ -264,6 +264,12 @@ void hbg_hw_set_rx_pause_mac_addr(struct hbg_priv *priv, u64 mac_addr)
 	hbg_reg_write64(priv, HBG_REG_FD_FC_ADDR_LOW_ADDR, mac_addr);
 }
 
+void hbg_hw_loop_enable(struct hbg_priv *priv, u32 enable)
+{
+	hbg_reg_write_field(priv, HBG_REG_LOOP_REG_ADDR,
+			    HBG_REG_CF_CG2MI_LP_EN_B, enable);
+}
+
 static void hbg_hw_init_transmit_ctrl(struct hbg_priv *priv)
 {
 	u32 ctrl = 0;
diff --git a/drivers/net/ethernet/hisilicon/hibmcge/hbg_hw.h b/drivers/net/ethernet/hisilicon/hibmcge/hbg_hw.h
index a4a049b5121d..f7917a5353c2 100644
--- a/drivers/net/ethernet/hisilicon/hibmcge/hbg_hw.h
+++ b/drivers/net/ethernet/hisilicon/hibmcge/hbg_hw.h
@@ -59,5 +59,6 @@ void hbg_hw_set_mac_filter_enable(struct hbg_priv *priv, u32 enable);
 void hbg_hw_set_pause_enable(struct hbg_priv *priv, u32 tx_en, u32 rx_en);
 void hbg_hw_get_pause_enable(struct hbg_priv *priv, u32 *tx_en, u32 *rx_en);
 void hbg_hw_set_rx_pause_mac_addr(struct hbg_priv *priv, u64 mac_addr);
+void hbg_hw_loop_enable(struct hbg_priv *priv, u32 enable);
 
 #endif
diff --git a/drivers/net/ethernet/hisilicon/hibmcge/hbg_reg.h b/drivers/net/ethernet/hisilicon/hibmcge/hbg_reg.h
index a6e7f5e62b48..85b46f35b876 100644
--- a/drivers/net/ethernet/hisilicon/hibmcge/hbg_reg.h
+++ b/drivers/net/ethernet/hisilicon/hibmcge/hbg_reg.h
@@ -117,6 +117,7 @@
 #define HBG_REG_MODE_CHANGE_EN_ADDR		(HBG_REG_SGMII_BASE + 0x01B4)
 #define HBG_REG_MODE_CHANGE_EN_B		BIT(0)
 #define HBG_REG_LOOP_REG_ADDR			(HBG_REG_SGMII_BASE + 0x01DC)
+#define HBG_REG_CF_CG2MI_LP_EN_B		BIT(2)
 #define HBG_REG_RECV_CTRL_ADDR			(HBG_REG_SGMII_BASE + 0x01E0)
 #define HBG_REG_RECV_CTRL_STRIP_PAD_EN_B	BIT(3)
 #define HBG_REG_VLAN_CODE_ADDR			(HBG_REG_SGMII_BASE + 0x01E8)
diff --git a/drivers/net/ethernet/hisilicon/hibmcge/hbg_txrx.c b/drivers/net/ethernet/hisilicon/hibmcge/hbg_txrx.c
index 8d814c8f19ea..5802748f3a13 100644
--- a/drivers/net/ethernet/hisilicon/hibmcge/hbg_txrx.c
+++ b/drivers/net/ethernet/hisilicon/hibmcge/hbg_txrx.c
@@ -258,7 +258,8 @@ static bool hbg_rx_check_l3l4_error(struct hbg_priv *priv,
 		break;
 	case HBG_L4_ZERO_PORT_NUM:
 		priv->stats.rx_desc_l4_zero_port_num_cnt++;
-		return false;
+		/* Don't drop packets whose L4 port number is 0. */
+		break;
 	default:
 		priv->stats.rx_desc_l4_other_cnt++;
 		return false;
-- 
2.33.0


^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH RFC net-next 1/2] net: selftest: add net_selftest_custom() interface
  2025-04-21 13:43 ` [PATCH RFC net-next 1/2] net: selftest: add net_selftest_custom() interface Jijie Shao
@ 2025-04-25 20:15   ` Gerhard Engleder
  0 siblings, 0 replies; 4+ messages in thread
From: Gerhard Engleder @ 2025-04-25 20:15 UTC (permalink / raw)
  To: Jijie Shao
  Cc: shenjian15, wangpeiyang1, liuyonglong, chenhao418,
	jonathan.cameron, shameerali.kolothum.thodi, salil.mehta, netdev,
	linux-kernel, davem, edumazet, kuba, pabeni, andrew+netdev,
	horms

On 21.04.25 15:43, Jijie Shao wrote:
> In net/core/selftests.c,
> net_selftest() supports loopback tests.
> However, the loopback content of this interface is a fixed common test
> and cannot be expanded to add the driver's own test.
> 
> In this patch, the net_selftest_custom() interface is added
> to support driver customized loopback tests and
> extra common loopback tests.
> 
> Signed-off-by: Jijie Shao <shaojijie@huawei.com>
> ---
>   include/net/selftests.h |  61 +++++++++++++
>   net/core/selftests.c    | 188 +++++++++++++++++++++++++++++++++++++++-
>   2 files changed, 245 insertions(+), 4 deletions(-)
> 
> diff --git a/include/net/selftests.h b/include/net/selftests.h
> index e65e8d230d33..a36e6ee0a41f 100644
> --- a/include/net/selftests.h
> +++ b/include/net/selftests.h
> @@ -4,6 +4,48 @@
>   
>   #include <linux/ethtool.h>
>   
> +#define NET_TEST_NETIF_CARRIER		BIT(0)
> +#define NET_TEST_FULL_DUPLEX		BIT(1)
> +#define NET_TEST_TCP			BIT(2)
> +#define NET_TEST_UDP			BIT(3)
> +#define NET_TEST_UDP_MAX_MTU		BIT(4)
> +
> +#define NET_EXTRA_CARRIER_TEST		BIT(0)
> +#define NET_EXTRA_FULL_DUPLEX_TEST	BIT(1)
> +#define NET_EXTRA_PHY_TEST		BIT(2)

What is the difference between NET_TEST_NETIF_CARRIER and
NET_EXTRA_CARRIER_TEST? Aren't these the same tests?

> +struct net_test_entry {
> +	char name[ETH_GSTRING_LEN];
> +
> +	/* can set to NULL */
> +	int (*enable)(struct net_device *ndev, bool enable);
> +
> +	/* can set to NULL */
> +	int (*fn)(struct net_device *ndev);
> +
> +	/* if flag is set, fn() will be ignored,
> +	 * and will do test according to the flag,
> +	 * such as NET_TEST_UDP...
> +	 */
> +	unsigned long flags;

Looks limited, this interface does not scale as the bits in flags are
limited.

> +};
> +
> +#define NET_TEST_E(_name, _enable, _flags) { \
> +	.name = _name, \
> +	.enable = _enable, \
> +	.fn = NULL, \
> +	.flags = _flags }
> +
> +#define NET_TEST_ENTRY_MAX_COUNT	10

I expect that you have to eliminate this limitation too.

> +struct net_test {
> +	/* extra tests will be added based on this flag */
> +	unsigned long extra_flags;

Why this extra_flags to trigger tests? AFAIU the same tests can be
triggered with entries.

> +
> +	struct net_test_entry entries[NET_TEST_ENTRY_MAX_COUNT];
> +	/* the count of entries, must <= NET_TEST_ENTRY_MAX_COUNT */
> +	u32 count;
> +};

You try to make net selftests more usable for drivers. I also tried
that, but Andrew Lunn argumented for controlling the selftests some
user space interface is expected. IMO the situation has not changed.

https://lore.kernel.org/netdev/20250227203138.60420-3-gerhard@engleder-embedded.com/T/#md5e4ac1ca41adbdb43755d3c189aa8b8228bf8c9

Gerhard

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2025-04-25 21:10 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2025-04-21 13:43 [PATCH RFC net-next 0/2] net: hibmcge: add support for selftest Jijie Shao
2025-04-21 13:43 ` [PATCH RFC net-next 1/2] net: selftest: add net_selftest_custom() interface Jijie Shao
2025-04-25 20:15   ` Gerhard Engleder
2025-04-21 13:43 ` [PATCH RFC net-next 2/2] net: hibmcge: add support for selftest Jijie Shao

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®