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] [thread-next>] [day] [month] [year] [list]
Message-ID: <20260123090741.1566469-5-o.rempel@pengutronix.de>
Date: Fri, 23 Jan 2026 10:07:40 +0100
From: Oleksij Rempel <o.rempel@...gutronix.de>
To: "David S. Miller" <davem@...emloft.net>,
	Eric Dumazet <edumazet@...gle.com>,
	Jakub Kicinski <kuba@...nel.org>,
	Paolo Abeni <pabeni@...hat.com>,
	Andrew Lunn <andrew+netdev@...n.ch>,
	Thangaraj Samynathan <Thangaraj.S@...rochip.com>,
	Rengarajan Sundararajan <Rengarajan.S@...rochip.com>
Cc: Oleksij Rempel <o.rempel@...gutronix.de>,
	kernel@...gutronix.de,
	linux-kernel@...r.kernel.org,
	netdev@...r.kernel.org,
	UNGLinuxDriver@...rochip.com
Subject: [RFC PATCH 4/4] net: lan78xx: Add debugfs file for error injection testing

Add a debugfs file (inject\_error) to allow users to trigger specific
hardware errors (e.g., Burst Cap Violation, RX FIFO Overflow, USB PHY
destabilization) for testing the newly introduced health and recovery
mechanisms.

Signed-off-by: Oleksij Rempel <o.rempel@...gutronix.de>
---
 drivers/net/usb/lan78xx.c | 71 +++++++++++++++++++++++++++++++++++++++
 drivers/net/usb/lan78xx.h |  4 +++
 2 files changed, 75 insertions(+)

diff --git a/drivers/net/usb/lan78xx.c b/drivers/net/usb/lan78xx.c
index 316a3a8d0534..ae721025cf3d 100644
--- a/drivers/net/usb/lan78xx.c
+++ b/drivers/net/usb/lan78xx.c
@@ -3,6 +3,7 @@
  * Copyright (C) 2015 Microchip Technology
  */
 #include <linux/crc32.h>
+#include <linux/debugfs.h>
 #include <linux/etherdevice.h>
 #include <linux/ethtool.h>
 #include <linux/if_vlan.h>
@@ -519,6 +520,8 @@ struct lan78xx_net {
 
 	struct irq_domain_data	domain_data;
 
+	struct dentry		*debugfs_pdev;
+
 	struct phylink		*phylink;
 	struct phylink_config	phylink_config;
 
@@ -5088,6 +5091,68 @@ static const struct devlink_ops lan78xx_devlink_ops = {
 	.info_get = lan78xx_devlink_info_get,
 };
 
+static ssize_t lan78xx_inject_write(struct file *file, const char __user *user_buf,
+				    size_t count, loff_t *ppos)
+{
+	struct lan78xx_net *dev = file->private_data;
+	char buf[32];
+	int val, ret;
+	u32 reg_val;
+
+	if (count >= sizeof(buf))
+		return -EINVAL;
+
+	if (copy_from_user(buf, user_buf, count))
+		return -EFAULT;
+	buf[count] = 0;
+
+	if (kstrtoint(buf, 0, &val))
+		return -EINVAL;
+
+	switch (val) {
+	case 1: /* Trigger Burst Cap Violation (Hang UTX) */
+		/* Enable Burst Cap Enforcement */
+		ret = lan78xx_read_reg(dev, USB_CFG0, &reg_val);
+		if (ret < 0)
+			return ret;
+		reg_val |= USB_CFG_BCE_;
+		lan78xx_write_reg(dev, USB_CFG0, reg_val);
+
+		/* Set illegal Burst Cap size (512 bytes < Max Frame) */
+		lan78xx_write_reg(dev, BURST_CAP, 0x01);
+		break;
+
+	case 2: /* Trigger RX FIFO Overflow (Hold UTX in Reset) */
+		ret = lan78xx_read_reg(dev, USB_CFG0, &reg_val);
+		if (ret < 0)
+			return ret;
+		reg_val |= USB_CFG0_UTX_RESET_;
+		lan78xx_write_reg(dev, USB_CFG0, reg_val);
+		break;
+
+	case 3: /* Destabilize USB PHY (Invalid HS State) */
+		ret = lan78xx_read_reg(dev, LAN78XX_USB2_TEST_REG, &reg_val);
+		if (ret < 0)
+			return ret;
+		/* Set bits 15:14 to '10' (Binary) - Defined as "Invalid combination" */
+		reg_val &= ~(0x3 << 14);
+		reg_val |= (0x2 << 14);
+		lan78xx_write_reg(dev, LAN78XX_USB2_TEST_REG, reg_val);
+		break;
+
+	default:
+		return -EINVAL;
+	}
+
+	return count;
+}
+
+static const struct file_operations lan78xx_inject_fops = {
+	.open = simple_open,
+	.write = lan78xx_inject_write,
+	.llseek = default_llseek,
+};
+
 static void lan78xx_disconnect(struct usb_interface *intf)
 {
 	struct lan78xx_net *dev;
@@ -5102,6 +5167,8 @@ static void lan78xx_disconnect(struct usb_interface *intf)
 	udev = interface_to_usbdev(intf);
 	net = dev->net;
 
+	debugfs_remove_recursive(dev->debugfs_pdev);
+
 	lan78xx_health_cleanup(dev);
 	if (dev->devlink) {
 		cancel_work_sync(&dev->tx_timeout_work);
@@ -5594,6 +5661,10 @@ static int lan78xx_probe(struct usb_interface *intf,
 		lan78xx_health_init(dev);
 	}
 
+	dev->debugfs_pdev = debugfs_create_dir(netdev_name(netdev), NULL);
+	debugfs_create_file("inject_error", 0200, dev->debugfs_pdev, dev,
+			    &lan78xx_inject_fops);
+
 	return 0;
 
 phy_uninit:
diff --git a/drivers/net/usb/lan78xx.h b/drivers/net/usb/lan78xx.h
index 968e5e5faee0..16666a998441 100644
--- a/drivers/net/usb/lan78xx.h
+++ b/drivers/net/usb/lan78xx.h
@@ -366,6 +366,7 @@
 #define USB_CFG_MAX_DEV_SPEED_SS_	(0x00008000)
 #define USB_CFG_MAX_DEV_SPEED_HS_	(0x00000000)
 #define USB_CFG_MAX_DEV_SPEED_FS_	(0x00002000)
+#define USB_CFG0_UTX_RESET_		(0x00000400)
 #define USB_CFG_PHY_BOOST_MASK_		(0x00000180)
 #define USB_CFG_PHY_BOOST_PLUS_12_	(0x00000180)
 #define USB_CFG_PHY_BOOST_PLUS_8_	(0x00000100)
@@ -876,4 +877,7 @@
 #define OTP_TPVSR_VAL			(OTP_BASE_ADDR + 4 * 0x3A)
 #define OTP_TPVHR_VAL			(OTP_BASE_ADDR + 4 * 0x3B)
 #define OTP_TPVSA_VAL			(OTP_BASE_ADDR + 4 * 0x3C)
+
+#define LAN78XX_USB2_TEST_REG		(0x12C4)
+
 #endif /* _LAN78XX_H */
-- 
2.47.3


Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ