public inbox for netdev@vger.kernel.org
 help / color / mirror / Atom feed
From: Michael Trimarchi <michael@amarulasolutions.com>
To: Wei Fang <wei.fang@nxp.com>, Shenwei Wang <shenwei.wang@nxp.com>,
	Clark Wang <xiaoning.wang@nxp.com>,
	Andrew Lunn <andrew+netdev@lunn.ch>,
	"David S. Miller" <davem@davemloft.net>,
	Eric Dumazet <edumazet@google.com>,
	Jakub Kicinski <kuba@kernel.org>, Paolo Abeni <pabeni@redhat.com>,
	Heiner Kallweit <hkallweit1@gmail.com>,
	Russell King <linux@armlinux.org.uk>,
	imx@lists.linux.dev (open list:FREESCALE IMX / MXC FEC DRIVER),
	netdev@vger.kernel.org (open list:FREESCALE IMX / MXC FEC DRIVER),
	linux-kernel@vger.kernel.org (open list)
Cc: Michael Trimarchi <michael@amarulasolutions.com>,
	imx@lists.linux.dev (open list:FREESCALE IMX / MXC FEC DRIVER),
	netdev@vger.kernel.org (open list:FREESCALE IMX / MXC FEC DRIVER),
	linux-kernel@vger.kernel.org (open list)
Subject: [RFC PATCH] net: phy: integrate reset-after-clock quirk into phy_init_hw
Date: Wed, 28 Jan 2026 10:46:41 +0100	[thread overview]
Message-ID: <20260128094644.302313-1-michael@amarulasolutions.com> (raw)

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


             reply	other threads:[~2026-01-28  9:46 UTC|newest]

Thread overview: 21+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-01-28  9:46 Michael Trimarchi [this message]
2026-01-28 13:25 ` [RFC PATCH] net: phy: integrate reset-after-clock quirk into phy_init_hw Andrew Lunn
2026-01-28 13:33   ` Michael Nazzareno Trimarchi
2026-01-28 13:58     ` Russell King (Oracle)
2026-01-28 14:34       ` Michael Nazzareno Trimarchi
2026-01-28 20:26       ` Marco Felsch
2026-01-28 20:51         ` Andrew Lunn
2026-01-28 21:04           ` Michael Nazzareno Trimarchi
2026-01-28 21:20             ` Michael Nazzareno Trimarchi
2026-01-28 21:45             ` Andrew Lunn
2026-01-28 22:17               ` Russell King (Oracle)
2026-01-28 22:48                 ` Russell King (Oracle)
2026-01-28 22:13         ` Russell King (Oracle)
2026-01-29 10:41           ` Marco Felsch
2026-01-29 10:55             ` Russell King (Oracle)
2026-01-29 11:17               ` Marco Felsch
2026-01-29 13:12                 ` Russell King (Oracle)
2026-01-29 13:19                   ` Russell King (Oracle)
2026-01-29 14:30                     ` Russell King (Oracle)
2026-01-30  2:25 ` Wei Fang
2026-02-11  9:21   ` Michael Nazzareno Trimarchi

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260128094644.302313-1-michael@amarulasolutions.com \
    --to=michael@amarulasolutions.com \
    --cc=andrew+netdev@lunn.ch \
    --cc=davem@davemloft.net \
    --cc=edumazet@google.com \
    --cc=hkallweit1@gmail.com \
    --cc=imx@lists.linux.dev \
    --cc=kuba@kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux@armlinux.org.uk \
    --cc=netdev@vger.kernel.org \
    --cc=pabeni@redhat.com \
    --cc=shenwei.wang@nxp.com \
    --cc=wei.fang@nxp.com \
    --cc=xiaoning.wang@nxp.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox