lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Message-ID: <20250421134358.1241851-3-shaojijie@huawei.com>
Date: Mon, 21 Apr 2025 21:43:58 +0800
From: Jijie Shao <shaojijie@...wei.com>
To: <davem@...emloft.net>, <edumazet@...gle.com>, <kuba@...nel.org>,
	<pabeni@...hat.com>, <andrew+netdev@...n.ch>, <horms@...nel.org>
CC: <shenjian15@...wei.com>, <wangpeiyang1@...wei.com>,
	<liuyonglong@...wei.com>, <chenhao418@...wei.com>,
	<jonathan.cameron@...wei.com>, <shameerali.kolothum.thodi@...wei.com>,
	<salil.mehta@...wei.com>, <netdev@...r.kernel.org>,
	<linux-kernel@...r.kernel.org>, <gerhard@...leder-embedded.com>,
	<shaojijie@...wei.com>
Subject: [PATCH RFC net-next 2/2] net: hibmcge: add support for selftest

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@...wei.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


Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ