From nobody Sun Feb 8 15:58:32 2026 Received: from mail-wm1-f42.google.com (mail-wm1-f42.google.com [209.85.128.42]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 0282534CFBB for ; Wed, 28 Jan 2026 09:46:52 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.42 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1769593614; cv=none; b=MjuS7T/VPz62tOQwdwtGe+O/OdhmNkewJ9RzRu56/4q5mmGCaDuiC5iTEfUVp3Wcg+6WwhLwn8DKNz/MjHp9vSBnBnsNOtxAe1YOBk5fz/JOV1Tj/bvLZQujH+P4hMmRGk+w6urPsbFiwEPdyq3RWbOc9U4FfF/zr9h4MTH+lz0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1769593614; c=relaxed/simple; bh=TC15+6dILqv3V4br20k0HKU4BMDLCWRE3mXpBKGswAU=; h=From:To:Cc:Subject:Date:Message-ID:MIME-Version; b=RRRjw+IQPPMgMmsFEaXhkTGAwXkp5WobkHh8NGDbOAxA8xBn9jKUcGNzqK4Mo0O10HvF2aJ5Y2lUFsk1vvlcibTigFLTLzWAF1u2QM74y0Rn7DV+pGQnb4FNFIdaJpjxMSaqfNQ6s1RokiEe2LO2Jt4jxod74wgkRzONSrmPmUM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=amarulasolutions.com; spf=pass smtp.mailfrom=amarulasolutions.com; dkim=pass (1024-bit key) header.d=amarulasolutions.com header.i=@amarulasolutions.com header.b=e+WUT4Lj; arc=none smtp.client-ip=209.85.128.42 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=amarulasolutions.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=amarulasolutions.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=amarulasolutions.com header.i=@amarulasolutions.com header.b="e+WUT4Lj" Received: by mail-wm1-f42.google.com with SMTP id 5b1f17b1804b1-47edd6111b4so74888105e9.1 for ; Wed, 28 Jan 2026 01:46:52 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=amarulasolutions.com; s=google; t=1769593611; x=1770198411; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:from:to:cc:subject:date:message-id:reply-to; bh=fbeoicRBBkRysu8QvYpatvGi1IIIWH8ilPA26WAsQkU=; b=e+WUT4LjjJDpmAktI8jsxiNQypqkQI2/0M8kNi+2TCuAJsmT44/mgwnm2bWORk5ALA SgW+lw/SyXZ1bpsltBRIZOYzEv+CRuF9t883oylmBeAmrbowGaPwVd2joI0UirtzLvnp d+wLds5EvzC6mzlfLXhzbWILLoOTKTjLwKFxo= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1769593611; x=1770198411; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:x-gm-gg:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to; bh=fbeoicRBBkRysu8QvYpatvGi1IIIWH8ilPA26WAsQkU=; b=GeOnt5dCOnkrm6Vn43LIewRNWQqY96+Y8A9S5Uf1J34zXuu43i+7+LmqgwgdS9FwMP bH8QqREBCA1E6odth6Kc4UAxmXgU7bWzRVkH4ezxJJJVUNTQUfHkQ0L9PAbxRPpeZyV6 al00n8sJ42Er97FVyWbw+Z5239R01m2nXLh67Lxc3i/HyMxdconM67crGWNjiqU2SvbD uO0doEcGBzC5LqW+Krfk4cFKKDa86r7fajMgFk0rsiFnbalPtUdbs1GgRH7bIg/UFnFI z8WHUK81KdEKstyYm3WkAkt7D4pZGXLtjWVHWqBSrxLMxux6qELBHIVdzV6atN2I9MAz LyIg== X-Forwarded-Encrypted: i=1; AJvYcCUQ2Z/1vsqMtt6neDErSiZMZzeUywzPxUU8GSVca/c9GGrLj7fD9VDXbmaGYeYYQfcpby8LDcfutjiK77s=@vger.kernel.org X-Gm-Message-State: AOJu0YyOb8iNGxgZLn3La/pj2VQm2Cu5ZW6WA3gNhhe9M94NKgZJM0pk 3WpnTbbBvzRps8G/FMRYHcetY7QTel/k58gHYPM+FVkYzfmyIklWEP5YXjNmOt2IXjI= X-Gm-Gg: AZuq6aKI6/Y4n4NcU6u1uY38IHg1ZD33Fo+fFNT9KIZU3gUnQjETywuZtDLpok147u1 PDQ3rmsKMJ9tpHQLrHrKVsXvqrJOxgXBx+dLHW3N5fFz4/yGygALVcpcLFuByx63HM5kWqrvcdN cCag6xcdAfoze0IWayz2onBkFpQy0uff6BRZZqDNKJ5UZ6AC9Se2kyvHASfxlYpjn3nkTyt/xQc bsxeKpvyV7mxjlZf4z0yfCfYFo5h4shKslFW5GX2MFnr2+2MEDTzU5nkddpCnG//BzCgnQ9dpTs 9TWHM5mQ7CrWQzFPnh+PEidG/VaugbyF5d2yzfHuvWVlvSs7dX79lGffe7qU0bLp1aFAzIiiwDX pmuAGx9R0sKPEvCG5ueUh89KWLXZGdHrCAbMe5GndCgWHnFBDV2sGrlaUGfIGlHYpDoUN/hNFQx ga010NOa6gWIYdvo94dKGSdx16QVcvqkUdmUDuqlHQrP0LCwKss31Dd0COpspSJ8ABu4yZEwEOA 4iqy9rVdu7VQVVI X-Received: by 2002:a05:600c:1554:b0:480:1d0b:2d32 with SMTP id 5b1f17b1804b1-48069c1c2f4mr58353885e9.12.1769593610912; Wed, 28 Jan 2026 01:46:50 -0800 (PST) Received: from panicking.amarulasolutions.com ([46.18.137.29]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-4806d2585c6sm5821715e9.0.2026.01.28.01.46.49 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 28 Jan 2026 01:46:50 -0800 (PST) From: Michael Trimarchi To: Wei Fang , Shenwei Wang , Clark Wang , Andrew Lunn , "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Heiner Kallweit , Russell King , 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 , 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 Message-ID: <20260128094644.302313-1-michael@amarulasolutions.com> X-Mailer: git-send-email 2.51.0 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 Content-Type: text/plain; charset="utf-8" The current implementation of phy_reset_after_clk_enable requires MAC drive= rs (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 di= rectly into the generic phy_init_hw() function. Signed-off-by: Michael Trimarchi --- 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/ethern= et/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 *b= us, int mii_id, return ret; } =20 -static void fec_enet_phy_reset_after_clk_enable(struct net_device *ndev) -{ - struct fec_enet_private *fep =3D netdev_priv(ndev); - struct phy_device *phy_dev =3D 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 =3D 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 =3D netdev_priv(ndev); @@ -2416,7 +2394,6 @@ static int fec_enet_clk_enable(struct net_device *nde= v, bool enable) if (ret) goto failed_clk_2x_txclk; =20 - 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 =3D netdev_priv(ndev); int ret; - bool reset_again; =20 ret =3D 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; =20 - /* 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 =3D false; - else - reset_again =3D 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); =20 - /* 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 =3D 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 =3D 0; =20 + if (phydev->drv->flags & PHY_RST_AFTER_CLK_EN) + phy_device_reset(phydev, 1); + /* Deassert the reset signal */ phy_device_reset(phydev, 0); =20 @@ -1956,30 +1959,6 @@ int phy_resume(struct phy_device *phydev) } EXPORT_SYMBOL(phy_resume); =20 -/** - * 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 i= t'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 */ =20 /** 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); =20 int phy_restart_aneg(struct phy_device *phydev); -int phy_reset_after_clk_enable(struct phy_device *phydev); =20 #if IS_ENABLED(CONFIG_PHYLIB) int phy_start_cable_test(struct phy_device *phydev, --=20 2.51.0