[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-ID: <d73c74c0-5832-4358-a18e-1f555e928e79@kabelmail.de>
Date: Mon, 29 Sep 2025 13:44:24 +0200
From: Janpieter Sollie <janpieter.sollie@...elmail.de>
To: "Russell King (Oracle)" <linux@...linux.org.uk>,
Andrew Lunn <andrew@...n.ch>, Heiner Kallweit <hkallweit1@...il.com>,
"David S. Miller" <davem@...emloft.net>, Eric Dumazet <edumazet@...gle.com>,
Jakub Kicinski <kuba@...nel.org>, Paolo Abeni <pabeni@...hat.com>,
netdev@...r.kernel.org, Marek Behún <kabel@...nel.org>
Subject: [PATCH RFC] increase i2c_mii_poll timeout for very slow SFP modules
originally developed by Marek,
commit 09bbedac72d5a9267088c15d1a71c8c3a8fb47e7
while most SFP cages do function properly in i2c_rollball_mii_poll(),
SFP+ modules from no-name vendors seem to behave slowly.
This gets even worse on embedded devices,
where power constraints are in place.
i2c_rollball_mii_poll() could timeout here.
dynamically increase waiting time, so the phy gets more time to finish the job.
It it beyond my knowledge how much the target gets interrupted by a poll() call.
A better method might be to add a kconfig option "allow very slow SFP MDIO",
so strict timeout errors can be detected where useful,
and be avoided when the kernel is built to work on embedded devices.
Janpieter Sollie
--- a/drivers/net/mdio/mdio-i2c.c 2025-09-19 16:35:52.000000000 +0200
+++ b/drivers/net/mdio/mdio-i2c.c 2025-09-27 14:11:59.406323627 +0200
@@ -248,12 +248,15 @@ static int i2c_rollball_mii_poll(struct mii_bus *bus, int bus_addr, u8 *buf,
msgs[1].len = len;
msgs[1].buf = res;
- /* By experiment it takes up to 70 ms to access a register for these
- * SFPs. Sleep 20ms between iterations and try 10 times.
+ /* By experiment it takes up to 70 ms
+ * to access a register for normal SFPs.
+ * Sleep at least 20ms between iterations and try 10 times.
+ * Slower modules on embedded devices may need more.
+ * Dynamically increase sleep to avoid wasted i2c_transfer_rollball() calls
*/
i = 10;
do {
- msleep(20);
+ msleep(20+2*(10-i));
ret = i2c_transfer_rollball(i2c, msgs, ARRAY_SIZE(msgs));
if (ret)
Powered by blists - more mailing lists