public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH net-next v4 0/2] Use PHYlib for reset randomization and adjustable polling
@ 2025-02-10  8:23 Oleksij Rempel
  2025-02-10  8:23 ` [PATCH net-next v4 1/2] net: phy: Add support for driver-specific next update time Oleksij Rempel
                   ` (2 more replies)
  0 siblings, 3 replies; 6+ messages in thread
From: Oleksij Rempel @ 2025-02-10  8:23 UTC (permalink / raw)
  To: Andrew Lunn, Heiner Kallweit, Russell King, David S. Miller,
	Eric Dumazet, Jakub Kicinski, Paolo Abeni
  Cc: Oleksij Rempel, kernel, linux-kernel, netdev

Hi all,

This patch set tackles a DP83TG720 reset lock issue and improves PHY
polling. Rather than adding a separate polling worker to randomize PHY
resets, I chose to extend the PHYlib framework - which already handles
most of the needed functionality - with adjustable polling. This
approach not only addresses the DP83TG720-specific problem (where
synchronized resets can lock the link) but also lays the groundwork for
optimizing PHY stats polling across all PHY drivers. With generic PHY
stats coming in, we can adjust the polling interval based on hardware
characteristics, such as using longer intervals for PHYs with stable HW
counters or shorter ones for high-speed links prone to counter
overflows.

Patch version changes are tracked in separate patches.

Oleksij Rempel (2):
  net: phy: Add support for driver-specific next update time
  net: phy: dp83tg720: Add randomized polling intervals for link
    detection

 drivers/net/phy/dp83tg720.c | 78 +++++++++++++++++++++++++++++++++++++
 drivers/net/phy/phy.c       | 21 +++++++++-
 include/linux/phy.h         | 13 +++++++
 3 files changed, 111 insertions(+), 1 deletion(-)

--
2.39.5


^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH net-next v4 1/2] net: phy: Add support for driver-specific next update time
  2025-02-10  8:23 [PATCH net-next v4 0/2] Use PHYlib for reset randomization and adjustable polling Oleksij Rempel
@ 2025-02-10  8:23 ` Oleksij Rempel
  2025-02-12 12:59   ` Andrew Lunn
  2025-02-10  8:23 ` [PATCH net-next v4 2/2] net: phy: dp83tg720: Add randomized polling intervals for link detection Oleksij Rempel
  2025-02-12 19:20 ` [PATCH net-next v4 0/2] Use PHYlib for reset randomization and adjustable polling patchwork-bot+netdevbpf
  2 siblings, 1 reply; 6+ messages in thread
From: Oleksij Rempel @ 2025-02-10  8:23 UTC (permalink / raw)
  To: Andrew Lunn, Heiner Kallweit, Russell King, David S. Miller,
	Eric Dumazet, Jakub Kicinski, Paolo Abeni
  Cc: Oleksij Rempel, kernel, linux-kernel, netdev

Introduce the `phy_get_next_update_time` function to allow PHY drivers
to dynamically determine the time (in jiffies) until the next state
update event. This enables more flexible and adaptive polling intervals
based on the link state or other conditions.

Signed-off-by: Oleksij Rempel <o.rempel@pengutronix.de>
---
changes v4:
- fix comment width
- fix copy paste artifact in the comment
changes v3:
- use jiffies instead of milliseconds
changes v2:
- phy_get_next_update_time: remove useless variable
---
 drivers/net/phy/phy.c | 21 ++++++++++++++++++++-
 include/linux/phy.h   | 13 +++++++++++++
 2 files changed, 33 insertions(+), 1 deletion(-)

diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c
index d0c1718e2b16..347ad1b64497 100644
--- a/drivers/net/phy/phy.c
+++ b/drivers/net/phy/phy.c
@@ -1501,6 +1501,24 @@ void phy_free_interrupt(struct phy_device *phydev)
 }
 EXPORT_SYMBOL(phy_free_interrupt);
 
+/**
+ * phy_get_next_update_time - Determine the next PHY update time
+ * @phydev: Pointer to the phy_device structure
+ *
+ * This function queries the PHY driver to get the time for the next polling
+ * event. If the driver does not implement the callback, a default value is
+ * used.
+ *
+ * Return: The time for the next polling event in jiffies
+ */
+static unsigned int phy_get_next_update_time(struct phy_device *phydev)
+{
+	if (phydev->drv && phydev->drv->get_next_update_time)
+		return phydev->drv->get_next_update_time(phydev);
+
+	return PHY_STATE_TIME;
+}
+
 enum phy_state_work {
 	PHY_STATE_WORK_NONE,
 	PHY_STATE_WORK_ANEG,
@@ -1580,7 +1598,8 @@ static enum phy_state_work _phy_state_machine(struct phy_device *phydev)
 	 * called from phy_disconnect() synchronously.
 	 */
 	if (phy_polling_mode(phydev) && phy_is_started(phydev))
-		phy_queue_state_machine(phydev, PHY_STATE_TIME);
+		phy_queue_state_machine(phydev,
+					phy_get_next_update_time(phydev));
 
 	return state_work;
 }
diff --git a/include/linux/phy.h b/include/linux/phy.h
index 19f076a71f94..0493553ed60b 100644
--- a/include/linux/phy.h
+++ b/include/linux/phy.h
@@ -1273,6 +1273,19 @@ struct phy_driver {
 	 */
 	int (*led_polarity_set)(struct phy_device *dev, int index,
 				unsigned long modes);
+
+	/**
+	 * @get_next_update_time: Get the time until the next update event
+	 * @dev: PHY device
+	 *
+	 * Callback to determine the time (in jiffies) until the next
+	 * update event for the PHY state  machine. Allows PHY drivers to
+	 * dynamically adjust polling intervals based on link state or other
+	 * conditions.
+	 *
+	 * Returns the time in jiffies until the next update event.
+	 */
+	unsigned int (*get_next_update_time)(struct phy_device *dev);
 };
 #define to_phy_driver(d) container_of_const(to_mdio_common_driver(d),		\
 				      struct phy_driver, mdiodrv)
-- 
2.39.5


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH net-next v4 2/2] net: phy: dp83tg720: Add randomized polling intervals for link detection
  2025-02-10  8:23 [PATCH net-next v4 0/2] Use PHYlib for reset randomization and adjustable polling Oleksij Rempel
  2025-02-10  8:23 ` [PATCH net-next v4 1/2] net: phy: Add support for driver-specific next update time Oleksij Rempel
@ 2025-02-10  8:23 ` Oleksij Rempel
  2025-02-12 12:59   ` Andrew Lunn
  2025-02-12 19:20 ` [PATCH net-next v4 0/2] Use PHYlib for reset randomization and adjustable polling patchwork-bot+netdevbpf
  2 siblings, 1 reply; 6+ messages in thread
From: Oleksij Rempel @ 2025-02-10  8:23 UTC (permalink / raw)
  To: Andrew Lunn, Heiner Kallweit, Russell King, David S. Miller,
	Eric Dumazet, Jakub Kicinski, Paolo Abeni
  Cc: Oleksij Rempel, kernel, linux-kernel, netdev

Address the limitations of the DP83TG720 PHY, which cannot reliably
detect or report a stable link state. To handle this, the PHY must be
periodically reset when the link is down. However, synchronized reset
intervals between the PHY and its link partner can result in a deadlock,
preventing the link from re-establishing.

This change introduces a randomized polling interval when the link is
down to desynchronize resets between link partners.

Signed-off-by: Oleksij Rempel <o.rempel@pengutronix.de>
---
changes v4:
- s/dp83tg720_phy_get_next_update_time/dp83tg720_get_next_update_time/
- wrap comments at max 80 chars
---
 drivers/net/phy/dp83tg720.c | 78 +++++++++++++++++++++++++++++++++++++
 1 file changed, 78 insertions(+)

diff --git a/drivers/net/phy/dp83tg720.c b/drivers/net/phy/dp83tg720.c
index 050f4537d140..7e76323409c4 100644
--- a/drivers/net/phy/dp83tg720.c
+++ b/drivers/net/phy/dp83tg720.c
@@ -4,12 +4,31 @@
  */
 #include <linux/bitfield.h>
 #include <linux/ethtool_netlink.h>
+#include <linux/jiffies.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/phy.h>
+#include <linux/random.h>
 
 #include "open_alliance_helpers.h"
 
+/*
+ * DP83TG720S_POLL_ACTIVE_LINK - Polling interval in milliseconds when the link
+ *				 is active.
+ * DP83TG720S_POLL_NO_LINK_MIN - Minimum polling interval in milliseconds when
+ *				 the link is down.
+ * DP83TG720S_POLL_NO_LINK_MAX - Maximum polling interval in milliseconds when
+ *				 the link is down.
+ *
+ * These values are not documented or officially recommended by the vendor but
+ * were determined through empirical testing. They achieve a good balance in
+ * minimizing the number of reset retries while ensuring reliable link recovery
+ * within a reasonable timeframe.
+ */
+#define DP83TG720S_POLL_ACTIVE_LINK		1000
+#define DP83TG720S_POLL_NO_LINK_MIN		100
+#define DP83TG720S_POLL_NO_LINK_MAX		1000
+
 #define DP83TG720S_PHY_ID			0x2000a284
 
 /* MDIO_MMD_VEND2 registers */
@@ -371,6 +390,13 @@ static int dp83tg720_read_status(struct phy_device *phydev)
 		if (ret)
 			return ret;
 
+		/* Sleep 600ms for PHY stabilization post-reset.
+		 * Empirically chosen value (not documented).
+		 * Helps reduce reset bounces with link partners having similar
+		 * issues.
+		 */
+		msleep(600);
+
 		/* After HW reset we need to restore master/slave configuration.
 		 * genphy_c45_pma_baset1_read_master_slave() call will be done
 		 * by the dp83tg720_config_aneg() function.
@@ -498,6 +524,57 @@ static int dp83tg720_probe(struct phy_device *phydev)
 	return 0;
 }
 
+/**
+ * dp83tg720_get_next_update_time - Determine the next update time for PHY
+ *                                  state
+ * @phydev: Pointer to the phy_device structure
+ *
+ * This function addresses a limitation of the DP83TG720 PHY, which cannot
+ * reliably detect or report a stable link state. To recover from such
+ * scenarios, the PHY must be periodically reset when the link is down. However,
+ * if the link partner also runs Linux with the same driver, synchronized reset
+ * intervals can lead to a deadlock where the link never establishes due to
+ * simultaneous resets on both sides.
+ *
+ * To avoid this, the function implements randomized polling intervals when the
+ * link is down. It ensures that reset intervals are desynchronized by
+ * introducing a random delay between a configured minimum and maximum range.
+ * When the link is up, a fixed polling interval is used to minimize overhead.
+ *
+ * This mechanism guarantees that the link will reestablish within 10 seconds
+ * in the worst-case scenario.
+ *
+ * Return: Time (in jiffies) until the next update event for the PHY state
+ * machine.
+ */
+static unsigned int dp83tg720_get_next_update_time(struct phy_device *phydev)
+{
+	unsigned int next_time_jiffies;
+
+	if (phydev->link) {
+		/* When the link is up, use a fixed 1000ms interval
+		 * (in jiffies)
+		 */
+		next_time_jiffies =
+			msecs_to_jiffies(DP83TG720S_POLL_ACTIVE_LINK);
+	} else {
+		unsigned int min_jiffies, max_jiffies, rand_jiffies;
+
+		/* When the link is down, randomize interval between min/max
+		 * (in jiffies)
+		 */
+		min_jiffies = msecs_to_jiffies(DP83TG720S_POLL_NO_LINK_MIN);
+		max_jiffies = msecs_to_jiffies(DP83TG720S_POLL_NO_LINK_MAX);
+
+		rand_jiffies = min_jiffies +
+			get_random_u32_below(max_jiffies - min_jiffies + 1);
+		next_time_jiffies = rand_jiffies;
+	}
+
+	/* Ensure the polling time is at least one jiffy */
+	return max(next_time_jiffies, 1U);
+}
+
 static struct phy_driver dp83tg720_driver[] = {
 {
 	PHY_ID_MATCH_MODEL(DP83TG720S_PHY_ID),
@@ -516,6 +593,7 @@ static struct phy_driver dp83tg720_driver[] = {
 	.get_link_stats	= dp83tg720_get_link_stats,
 	.get_phy_stats	= dp83tg720_get_phy_stats,
 	.update_stats	= dp83tg720_update_stats,
+	.get_next_update_time = dp83tg720_get_next_update_time,
 
 	.suspend	= genphy_suspend,
 	.resume		= genphy_resume,
-- 
2.39.5


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* Re: [PATCH net-next v4 1/2] net: phy: Add support for driver-specific next update time
  2025-02-10  8:23 ` [PATCH net-next v4 1/2] net: phy: Add support for driver-specific next update time Oleksij Rempel
@ 2025-02-12 12:59   ` Andrew Lunn
  0 siblings, 0 replies; 6+ messages in thread
From: Andrew Lunn @ 2025-02-12 12:59 UTC (permalink / raw)
  To: Oleksij Rempel
  Cc: Heiner Kallweit, Russell King, David S. Miller, Eric Dumazet,
	Jakub Kicinski, Paolo Abeni, kernel, linux-kernel, netdev

On Mon, Feb 10, 2025 at 09:23:57AM +0100, Oleksij Rempel wrote:
> Introduce the `phy_get_next_update_time` function to allow PHY drivers
> to dynamically determine the time (in jiffies) until the next state
> update event. This enables more flexible and adaptive polling intervals
> based on the link state or other conditions.
> 
> Signed-off-by: Oleksij Rempel <o.rempel@pengutronix.de>

Reviewed-by: Andrew Lunn <andrew@lunn.ch>

    Andrew

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH net-next v4 2/2] net: phy: dp83tg720: Add randomized polling intervals for link detection
  2025-02-10  8:23 ` [PATCH net-next v4 2/2] net: phy: dp83tg720: Add randomized polling intervals for link detection Oleksij Rempel
@ 2025-02-12 12:59   ` Andrew Lunn
  0 siblings, 0 replies; 6+ messages in thread
From: Andrew Lunn @ 2025-02-12 12:59 UTC (permalink / raw)
  To: Oleksij Rempel
  Cc: Heiner Kallweit, Russell King, David S. Miller, Eric Dumazet,
	Jakub Kicinski, Paolo Abeni, kernel, linux-kernel, netdev

On Mon, Feb 10, 2025 at 09:23:58AM +0100, Oleksij Rempel wrote:
61;7803;1c> Address the limitations of the DP83TG720 PHY, which cannot reliably
> detect or report a stable link state. To handle this, the PHY must be
> periodically reset when the link is down. However, synchronized reset
> intervals between the PHY and its link partner can result in a deadlock,
> preventing the link from re-establishing.
> 
> This change introduces a randomized polling interval when the link is
> down to desynchronize resets between link partners.
> 
> Signed-off-by: Oleksij Rempel <o.rempel@pengutronix.de>

Reviewed-by: Andrew Lunn <andrew@lunn.ch>

    Andrew

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH net-next v4 0/2] Use PHYlib for reset randomization and adjustable polling
  2025-02-10  8:23 [PATCH net-next v4 0/2] Use PHYlib for reset randomization and adjustable polling Oleksij Rempel
  2025-02-10  8:23 ` [PATCH net-next v4 1/2] net: phy: Add support for driver-specific next update time Oleksij Rempel
  2025-02-10  8:23 ` [PATCH net-next v4 2/2] net: phy: dp83tg720: Add randomized polling intervals for link detection Oleksij Rempel
@ 2025-02-12 19:20 ` patchwork-bot+netdevbpf
  2 siblings, 0 replies; 6+ messages in thread
From: patchwork-bot+netdevbpf @ 2025-02-12 19:20 UTC (permalink / raw)
  To: Oleksij Rempel
  Cc: andrew, hkallweit1, linux, davem, edumazet, kuba, pabeni, kernel,
	linux-kernel, netdev

Hello:

This series was applied to netdev/net-next.git (main)
by Jakub Kicinski <kuba@kernel.org>:

On Mon, 10 Feb 2025 09:23:56 +0100 you wrote:
> Hi all,
> 
> This patch set tackles a DP83TG720 reset lock issue and improves PHY
> polling. Rather than adding a separate polling worker to randomize PHY
> resets, I chose to extend the PHYlib framework - which already handles
> most of the needed functionality - with adjustable polling. This
> approach not only addresses the DP83TG720-specific problem (where
> synchronized resets can lock the link) but also lays the groundwork for
> optimizing PHY stats polling across all PHY drivers. With generic PHY
> stats coming in, we can adjust the polling interval based on hardware
> characteristics, such as using longer intervals for PHYs with stable HW
> counters or shorter ones for high-speed links prone to counter
> overflows.
> 
> [...]

Here is the summary with links:
  - [net-next,v4,1/2] net: phy: Add support for driver-specific next update time
    https://git.kernel.org/netdev/net-next/c/8bf47e4d7b87
  - [net-next,v4,2/2] net: phy: dp83tg720: Add randomized polling intervals for link detection
    https://git.kernel.org/netdev/net-next/c/e252af1a67fe

You are awesome, thank you!
-- 
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html



^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2025-02-12 19:20 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-02-10  8:23 [PATCH net-next v4 0/2] Use PHYlib for reset randomization and adjustable polling Oleksij Rempel
2025-02-10  8:23 ` [PATCH net-next v4 1/2] net: phy: Add support for driver-specific next update time Oleksij Rempel
2025-02-12 12:59   ` Andrew Lunn
2025-02-10  8:23 ` [PATCH net-next v4 2/2] net: phy: dp83tg720: Add randomized polling intervals for link detection Oleksij Rempel
2025-02-12 12:59   ` Andrew Lunn
2025-02-12 19:20 ` [PATCH net-next v4 0/2] Use PHYlib for reset randomization and adjustable polling patchwork-bot+netdevbpf

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox