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-next>] [day] [month] [year] [list]
Message-ID: <20260128094644.302313-1-michael@amarulasolutions.com>
Date: Wed, 28 Jan 2026 10:46:41 +0100
From: Michael Trimarchi <michael@...rulasolutions.com>
To: Wei Fang <wei.fang@....com>,
	Shenwei Wang <shenwei.wang@....com>,
	Clark Wang <xiaoning.wang@....com>,
	Andrew Lunn <andrew+netdev@...n.ch>,
	"David S. Miller" <davem@...emloft.net>,
	Eric Dumazet <edumazet@...gle.com>,
	Jakub Kicinski <kuba@...nel.org>,
	Paolo Abeni <pabeni@...hat.com>,
	Heiner Kallweit <hkallweit1@...il.com>,
	Russell King <linux@...linux.org.uk>,
	imx@...ts.linux.dev (open list:FREESCALE IMX / MXC FEC DRIVER),
	netdev@...r.kernel.org (open list:FREESCALE IMX / MXC FEC DRIVER),
	linux-kernel@...r.kernel.org (open list)
Cc: Michael Trimarchi <michael@...rulasolutions.com>,
	imx@...ts.linux.dev (open list:FREESCALE IMX / MXC FEC DRIVER),
	netdev@...r.kernel.org (open list:FREESCALE IMX / MXC FEC DRIVER),
	linux-kernel@...r.kernel.org (open list)
Subject: [RFC PATCH] net: phy: integrate reset-after-clock quirk into phy_init_hw

The current implementation of phy_reset_after_clk_enable requires MAC drivers
(like fec_main.c) to manually track PHY probing states and trigger resets
at specific points in their clock management flow and was created just for a SoC
vendor. This leads to fragile code in the Ethernet driver, involving complex
checks to see if the PHY device is bound.

This patch proposes moving the handling of the PHY_RST_AFTER_CLK_EN flag directly
into the generic phy_init_hw() function.

Signed-off-by: Michael Trimarchi <michael@...rulasolutions.com>
---

I need to test better some boards that need this reset, but
I need to confirm if the general approach is ok

---
 drivers/net/ethernet/freescale/fec_main.c | 41 -----------------------
 drivers/net/phy/phy_device.c              | 27 ++-------------
 include/linux/phy.h                       |  1 -
 3 files changed, 3 insertions(+), 66 deletions(-)

diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c
index e2b75d1970ae..ea112385e77e 100644
--- a/drivers/net/ethernet/freescale/fec_main.c
+++ b/drivers/net/ethernet/freescale/fec_main.c
@@ -2364,28 +2364,6 @@ static int fec_enet_mdio_write_c45(struct mii_bus *bus, int mii_id,
 	return ret;
 }
 
-static void fec_enet_phy_reset_after_clk_enable(struct net_device *ndev)
-{
-	struct fec_enet_private *fep = netdev_priv(ndev);
-	struct phy_device *phy_dev = ndev->phydev;
-
-	if (phy_dev) {
-		phy_reset_after_clk_enable(phy_dev);
-	} else if (fep->phy_node) {
-		/*
-		 * If the PHY still is not bound to the MAC, but there is
-		 * OF PHY node and a matching PHY device instance already,
-		 * use the OF PHY node to obtain the PHY device instance,
-		 * and then use that PHY device instance when triggering
-		 * the PHY reset.
-		 */
-		phy_dev = of_phy_find_device(fep->phy_node);
-		phy_reset_after_clk_enable(phy_dev);
-		if (phy_dev)
-			put_device(&phy_dev->mdio.dev);
-	}
-}
-
 static int fec_enet_clk_enable(struct net_device *ndev, bool enable)
 {
 	struct fec_enet_private *fep = netdev_priv(ndev);
@@ -2416,7 +2394,6 @@ static int fec_enet_clk_enable(struct net_device *ndev, bool enable)
 		if (ret)
 			goto failed_clk_2x_txclk;
 
-		fec_enet_phy_reset_after_clk_enable(ndev);
 	} else {
 		clk_disable_unprepare(fep->clk_enet_out);
 		if (fep->clk_ptp) {
@@ -3554,7 +3531,6 @@ fec_enet_open(struct net_device *ndev)
 {
 	struct fec_enet_private *fep = netdev_priv(ndev);
 	int ret;
-	bool reset_again;
 
 	ret = pm_runtime_resume_and_get(&fep->pdev->dev);
 	if (ret < 0)
@@ -3565,17 +3541,6 @@ fec_enet_open(struct net_device *ndev)
 	if (ret)
 		goto clk_enable;
 
-	/* During the first fec_enet_open call the PHY isn't probed at this
-	 * point. Therefore the phy_reset_after_clk_enable() call within
-	 * fec_enet_clk_enable() fails. As we need this reset in order to be
-	 * sure the PHY is working correctly we check if we need to reset again
-	 * later when the PHY is probed
-	 */
-	if (ndev->phydev && ndev->phydev->drv)
-		reset_again = false;
-	else
-		reset_again = true;
-
 	/* I should reset the ring buffers here, but I don't yet know
 	 * a simple way to do that.
 	 */
@@ -3587,12 +3552,6 @@ fec_enet_open(struct net_device *ndev)
 	/* Init MAC prior to mii bus probe */
 	fec_restart(ndev);
 
-	/* Call phy_reset_after_clk_enable() again if it failed during
-	 * phy_reset_after_clk_enable() before because the PHY wasn't probed.
-	 */
-	if (reset_again)
-		fec_enet_phy_reset_after_clk_enable(ndev);
-
 	/* Probe and connect to PHY when open the interface */
 	ret = fec_enet_mii_probe(ndev);
 	if (ret)
diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c
index 7a67c900e79a..3af652cbd7d2 100644
--- a/drivers/net/phy/phy_device.c
+++ b/drivers/net/phy/phy_device.c
@@ -1376,6 +1376,9 @@ int phy_init_hw(struct phy_device *phydev)
 {
 	int ret = 0;
 
+	if (phydev->drv->flags & PHY_RST_AFTER_CLK_EN)
+		phy_device_reset(phydev, 1);
+
 	/* Deassert the reset signal */
 	phy_device_reset(phydev, 0);
 
@@ -1956,30 +1959,6 @@ int phy_resume(struct phy_device *phydev)
 }
 EXPORT_SYMBOL(phy_resume);
 
-/**
- * phy_reset_after_clk_enable - perform a PHY reset if needed
- * @phydev: target phy_device struct
- *
- * Description: Some PHYs are known to need a reset after their refclk was
- *   enabled. This function evaluates the flags and perform the reset if it's
- *   needed. Returns < 0 on error, 0 if the phy wasn't reset and 1 if the phy
- *   was reset.
- */
-int phy_reset_after_clk_enable(struct phy_device *phydev)
-{
-	if (!phydev || !phydev->drv)
-		return -ENODEV;
-
-	if (phydev->drv->flags & PHY_RST_AFTER_CLK_EN) {
-		phy_device_reset(phydev, 1);
-		phy_device_reset(phydev, 0);
-		return 1;
-	}
-
-	return 0;
-}
-EXPORT_SYMBOL(phy_reset_after_clk_enable);
-
 /* Generic PHY support and helper functions */
 
 /**
diff --git a/include/linux/phy.h b/include/linux/phy.h
index 0bc00a4cceb2..d843415e65a6 100644
--- a/include/linux/phy.h
+++ b/include/linux/phy.h
@@ -1876,7 +1876,6 @@ int phy_speed_up(struct phy_device *phydev);
 bool phy_check_valid(int speed, int duplex, unsigned long *features);
 
 int phy_restart_aneg(struct phy_device *phydev);
-int phy_reset_after_clk_enable(struct phy_device *phydev);
 
 #if IS_ENABLED(CONFIG_PHYLIB)
 int phy_start_cable_test(struct phy_device *phydev,
-- 
2.51.0


Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ