mail archive of the barebox mailing list
 help / color / mirror / Atom feed
* [PATCH v1] net: phy: Add support for PHY-specific link polling interval and randomization
@ 2024-06-12 14:09 Oleksij Rempel
  2024-06-12 14:23 ` Ahmad Fatoum
  0 siblings, 1 reply; 3+ messages in thread
From: Oleksij Rempel @ 2024-06-12 14:09 UTC (permalink / raw)
  To: barebox; +Cc: Oleksij Rempel

Introduce the ability to use PHY-specific link polling intervals. Some
PHYs, such as the TI DP83TG720, require different polling intervals for
link status checks. This is particularly necessary for PHYs that do not
support autonegotiation and need frequent assistance to establish a
link.

For instance, the TI DP83TG720 PHY may need to be reset if a link is not
established within 100 milliseconds. If two identical PHYs are connected
to each other and require the same software assistance, they might reset
at the same frequency and fail to establish a link. To mitigate this, a
randomization mechanism is added to the polling interval.

Signed-off-by: Oleksij Rempel <o.rempel@pengutronix.de>
---
 drivers/net/phy/dp83tg720.c | 17 +++++++++++++++++
 include/linux/phy.h         |  2 ++
 net/eth.c                   |  9 ++++++++-
 3 files changed, 27 insertions(+), 1 deletion(-)

diff --git a/drivers/net/phy/dp83tg720.c b/drivers/net/phy/dp83tg720.c
index d57985539d..b42438292d 100644
--- a/drivers/net/phy/dp83tg720.c
+++ b/drivers/net/phy/dp83tg720.c
@@ -5,6 +5,7 @@
 #include <common.h>
 #include <linux/mdio.h>
 #include <linux/phy.h>
+#include <stdlib.h>
 
 #define DP83TG720S_PHY_ID			0x2000a284
 
@@ -26,6 +27,8 @@
 /* Power Mode 0 is Normal mode */
 #define DP83TG720S_LPS_CFG3_PWR_MODE_0		BIT(0)
 
+#define DP83TG720S_POLL_TIMEOUT_MS		100
+
 static int dp83tg720_config_rgmii_delay(struct phy_device *phydev)
 {
 	u16 rgmii_delay_mask;
@@ -92,6 +95,12 @@ static int dp83tg720_read_status(struct phy_device *phydev)
 {
 	u16 phy_sts;
 
+	/* Randomize the polling interval to avoid synchronization of multiple
+	 * PHYs. The polling interval is set to 150ms +/- 50ms.
+	 */
+	phydev->polling_interval = (DP83TG720S_POLL_TIMEOUT_MS +
+				    (rand() % 10) * 10) * MSECOND;
+
 	phy_sts = phy_read(phydev, DP83TG720S_MII_REG_10);
 	phydev->link = !!(phy_sts & DP83TG720S_LINK_STATUS);
 	if (!phydev->link) {
@@ -112,12 +121,20 @@ static int dp83tg720_read_status(struct phy_device *phydev)
 	return 0;
 }
 
+static int dp83tg720_probe(struct phy_device *phydev)
+{
+	phydev->polling_interval = DP83TG720S_POLL_TIMEOUT_MS * MSECOND;
+
+	return 0;
+}
+
 static struct phy_driver dp83tg720_driver[] = {
 	{
 		PHY_ID_MATCH_MODEL(DP83TG720S_PHY_ID),
 		.drv.name	= "TI DP83TG720S",
 		.read_status	= dp83tg720_read_status,
 		.config_init	= dp83tg720_phy_init,
+		.probe		= dp83tg720_probe,
 	}
 };
 device_phy_drivers(dp83tg720_driver);
diff --git a/include/linux/phy.h b/include/linux/phy.h
index ef25dec033..ccc1857adc 100644
--- a/include/linux/phy.h
+++ b/include/linux/phy.h
@@ -247,6 +247,8 @@ struct phy_device {
 	void (*adjust_link)(struct eth_device *dev);
 
 	struct cdev cdev;
+
+	uint64_t polling_interval;
 };
 #define to_phy_device(d) container_of(d, struct phy_device, dev)
 
diff --git a/net/eth.c b/net/eth.c
index 98567d8d3f..b9e047ebf9 100644
--- a/net/eth.c
+++ b/net/eth.c
@@ -197,14 +197,21 @@ int eth_carrier_poll_once(struct eth_device *edev)
  */
 static int eth_carrier_check(struct eth_device *edev, bool may_wait)
 {
+	uint64_t timeout;
+
 	if (!IS_ENABLED(CONFIG_PHYLIB))
 		return 0;
 
 	if (!edev->phydev)
 		return 0;
 
+	if (edev->phydev->polling_interval)
+		timeout = edev->phydev->polling_interval;
+	else
+		timeout = 5 * SECOND;
+
 	if (!edev->last_link_check ||
-	    is_timeout(edev->last_link_check, 5 * SECOND))
+	    is_timeout(edev->last_link_check, timeout))
 		eth_carrier_poll_once(edev);
 
 	if (may_wait && !edev->phydev->link) {
-- 
2.39.2




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

* Re: [PATCH v1] net: phy: Add support for PHY-specific link polling interval and randomization
  2024-06-12 14:09 [PATCH v1] net: phy: Add support for PHY-specific link polling interval and randomization Oleksij Rempel
@ 2024-06-12 14:23 ` Ahmad Fatoum
  2024-06-12 16:21   ` Oleksij Rempel
  0 siblings, 1 reply; 3+ messages in thread
From: Ahmad Fatoum @ 2024-06-12 14:23 UTC (permalink / raw)
  To: Oleksij Rempel, barebox

Hello Oleksij,

On 12.06.24 16:09, Oleksij Rempel wrote:
>  static int eth_carrier_check(struct eth_device *edev, bool may_wait)
>  {
> +	uint64_t timeout;
> +
>  	if (!IS_ENABLED(CONFIG_PHYLIB))
>  		return 0;
>  
>  	if (!edev->phydev)
>  		return 0;
>  
> +	if (edev->phydev->polling_interval)
> +		timeout = edev->phydev->polling_interval;
> +	else
> +		timeout = 5 * SECOND;

IMO, you should initialize edev->phydev->polling_interval in phy_device_create(),
so phydev->polling_interval always has a valid value.

Cheers,
Ahmad


> +
>  	if (!edev->last_link_check ||
> -	    is_timeout(edev->last_link_check, 5 * SECOND))
> +	    is_timeout(edev->last_link_check, timeout))
>  		eth_carrier_poll_once(edev);
>  
>  	if (may_wait && !edev->phydev->link) {

-- 
Pengutronix e.K.                           |                             |
Steuerwalder Str. 21                       | http://www.pengutronix.de/  |
31137 Hildesheim, Germany                  | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |




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

* Re: [PATCH v1] net: phy: Add support for PHY-specific link polling interval and randomization
  2024-06-12 14:23 ` Ahmad Fatoum
@ 2024-06-12 16:21   ` Oleksij Rempel
  0 siblings, 0 replies; 3+ messages in thread
From: Oleksij Rempel @ 2024-06-12 16:21 UTC (permalink / raw)
  To: Ahmad Fatoum; +Cc: barebox

On Wed, Jun 12, 2024 at 04:23:41PM +0200, Ahmad Fatoum wrote:
> Hello Oleksij,
> 
> On 12.06.24 16:09, Oleksij Rempel wrote:
> >  static int eth_carrier_check(struct eth_device *edev, bool may_wait)
> >  {
> > +	uint64_t timeout;
> > +
> >  	if (!IS_ENABLED(CONFIG_PHYLIB))
> >  		return 0;
> >  
> >  	if (!edev->phydev)
> >  		return 0;
> >  
> > +	if (edev->phydev->polling_interval)
> > +		timeout = edev->phydev->polling_interval;
> > +	else
> > +		timeout = 5 * SECOND;
> 
> IMO, you should initialize edev->phydev->polling_interval in phy_device_create(),
> so phydev->polling_interval always has a valid value.
 
Good point.

-- 
Pengutronix e.K.                           |                             |
Steuerwalder Str. 21                       | http://www.pengutronix.de/  |
31137 Hildesheim, Germany                  | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |



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

end of thread, other threads:[~2024-06-12 16:22 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-06-12 14:09 [PATCH v1] net: phy: Add support for PHY-specific link polling interval and randomization Oleksij Rempel
2024-06-12 14:23 ` Ahmad Fatoum
2024-06-12 16:21   ` Oleksij Rempel

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