From nobody Mon Feb 9 22:02:48 2026 Received: from metis.whiteo.stw.pengutronix.de (metis.whiteo.stw.pengutronix.de [185.203.201.7]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 4906A30DD30 for ; Fri, 23 Jan 2026 09:07:50 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.203.201.7 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1769159272; cv=none; b=N/S1bMdWKGxfUI2z95rbxokgoS3h3PRTLQ/bMS+KXhHQlc2FK7leYMBiwj5LEa3re2lKACTj7WCJ+bRY17L9aH633YImC1awqQbLbxlKXv8f7U7xAJw8ggwWyS+H0h/M5RmCWK5Bq84TaWfvE22pjyRzyozlIaqDLep7H+WlCMg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1769159272; c=relaxed/simple; bh=/0cL2fuHdGpIi6bdL6UK4t+rDuKh3T0YQNJtD/9d/c0=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=jpks14i+beXpwJjZuthb50SYClRutY7fkazWQ+Fi5IfA2CAa8FKdqybIfeae7QEVwfesQwRUQzrgn0U58ZMNgLfVBf1+BF1iDyNsDWSl8LMb5gvvPsyxXmJYeAR+ayk8KrlGeHjnVi6Ltvg97nUzSEXLkuAB4zZ/aOXCmbp45Sw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=pengutronix.de; spf=pass smtp.mailfrom=pengutronix.de; arc=none smtp.client-ip=185.203.201.7 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=pengutronix.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=pengutronix.de Received: from drehscheibe.grey.stw.pengutronix.de ([2a0a:edc0:0:c01:1d::a2]) by metis.whiteo.stw.pengutronix.de with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1vjD8q-00027I-58; Fri, 23 Jan 2026 10:07:44 +0100 Received: from dude04.red.stw.pengutronix.de ([2a0a:edc0:0:1101:1d::ac] helo=dude04) by drehscheibe.grey.stw.pengutronix.de with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1vjD8p-002451-0k; Fri, 23 Jan 2026 10:07:42 +0100 Received: from ore by dude04 with local (Exim 4.98.2) (envelope-from ) id 1vjD8o-00000006ZXC-20KC; Fri, 23 Jan 2026 10:07:42 +0100 From: Oleksij Rempel To: "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Andrew Lunn , Thangaraj Samynathan , Rengarajan Sundararajan Cc: Oleksij Rempel , kernel@pengutronix.de, linux-kernel@vger.kernel.org, netdev@vger.kernel.org, UNGLinuxDriver@microchip.com Subject: [RFC PATCH 4/4] net: lan78xx: Add debugfs file for error injection testing Date: Fri, 23 Jan 2026 10:07:40 +0100 Message-ID: <20260123090741.1566469-5-o.rempel@pengutronix.de> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20260123090741.1566469-1-o.rempel@pengutronix.de> References: <20260123090741.1566469-1-o.rempel@pengutronix.de> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-SA-Exim-Connect-IP: 2a0a:edc0:0:c01:1d::a2 X-SA-Exim-Mail-From: ore@pengutronix.de X-SA-Exim-Scanned: No (on metis.whiteo.stw.pengutronix.de); SAEximRunCond expanded to false X-PTX-Original-Recipient: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" 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 --- 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 +#include #include #include #include @@ -519,6 +520,8 @@ struct lan78xx_net { =20 struct irq_domain_data domain_data; =20 + struct dentry *debugfs_pdev; + struct phylink *phylink; struct phylink_config phylink_config; =20 @@ -5088,6 +5091,68 @@ static const struct devlink_ops lan78xx_devlink_ops = =3D { .info_get =3D lan78xx_devlink_info_get, }; =20 +static ssize_t lan78xx_inject_write(struct file *file, const char __user *= user_buf, + size_t count, loff_t *ppos) +{ + struct lan78xx_net *dev =3D file->private_data; + char buf[32]; + int val, ret; + u32 reg_val; + + if (count >=3D sizeof(buf)) + return -EINVAL; + + if (copy_from_user(buf, user_buf, count)) + return -EFAULT; + buf[count] =3D 0; + + if (kstrtoint(buf, 0, &val)) + return -EINVAL; + + switch (val) { + case 1: /* Trigger Burst Cap Violation (Hang UTX) */ + /* Enable Burst Cap Enforcement */ + ret =3D lan78xx_read_reg(dev, USB_CFG0, ®_val); + if (ret < 0) + return ret; + reg_val |=3D 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 =3D lan78xx_read_reg(dev, USB_CFG0, ®_val); + if (ret < 0) + return ret; + reg_val |=3D USB_CFG0_UTX_RESET_; + lan78xx_write_reg(dev, USB_CFG0, reg_val); + break; + + case 3: /* Destabilize USB PHY (Invalid HS State) */ + ret =3D lan78xx_read_reg(dev, LAN78XX_USB2_TEST_REG, ®_val); + if (ret < 0) + return ret; + /* Set bits 15:14 to '10' (Binary) - Defined as "Invalid combination" */ + reg_val &=3D ~(0x3 << 14); + reg_val |=3D (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 =3D { + .open =3D simple_open, + .write =3D lan78xx_inject_write, + .llseek =3D 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 =3D interface_to_usbdev(intf); net =3D dev->net; =20 + 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); } =20 + dev->debugfs_pdev =3D debugfs_create_dir(netdev_name(netdev), NULL); + debugfs_create_file("inject_error", 0200, dev->debugfs_pdev, dev, + &lan78xx_inject_fops); + return 0; =20 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 */ --=20 2.47.3