From: "Marek Behún" <kabel@kernel.org>
To: netdev@vger.kernel.org, Russell King <rmk+kernel@armlinux.org.uk>
Cc: "Jakub Kicinski" <kuba@kernel.org>,
"Andrew Lunn" <andrew@lunn.ch>, "Marek Behún" <kabel@kernel.org>
Subject: [PATCH net-next RFC] net: sfp: rework the RollBall PHY waiting code
Date: Fri, 10 Nov 2023 14:12:23 +0100 [thread overview]
Message-ID: <20231110131223.32201-1-kabel@kernel.org> (raw)
RollBall SFP modules allow the access to PHY registers only after a
certain time has passed. Until then, the registers read 0xffff.
Currently we have quirks for modules where we need to wait either 25
seconds or 4 seconds, but recently I got hands on another module where
the wait is even shorter.
Instead of hardcoding different wait times, lets rework the code:
- increase the PHY retry count to 25
- when RollBall module is detected, increase the PHY retry time from
50ms to 1s
Signed-off-by: Marek Behún <kabel@kernel.org>
---
drivers/net/phy/sfp.c | 41 +++++++++++++++++++++--------------------
1 file changed, 21 insertions(+), 20 deletions(-)
diff --git a/drivers/net/phy/sfp.c b/drivers/net/phy/sfp.c
index 5468bd209fab..5eb00295b8bf 100644
--- a/drivers/net/phy/sfp.c
+++ b/drivers/net/phy/sfp.c
@@ -191,7 +191,7 @@ static const enum gpiod_flags gpio_flags[] = {
* R_PHY_RETRY is the number of attempts.
*/
#define T_PHY_RETRY msecs_to_jiffies(50)
-#define R_PHY_RETRY 12
+#define R_PHY_RETRY 25
/* SFP module presence detection is poor: the three MOD DEF signals are
* the same length on the PCB, which means it's possible for MOD DEF 0 to
@@ -274,7 +274,7 @@ struct sfp {
struct sfp_eeprom_id id;
unsigned int module_power_mW;
unsigned int module_t_start_up;
- unsigned int module_t_wait;
+ unsigned int phy_t_retry;
unsigned int rate_kbd;
unsigned int rs_threshold_kbd;
@@ -372,18 +372,22 @@ static void sfp_fixup_10gbaset_30m(struct sfp *sfp)
sfp->id.base.extended_cc = SFF8024_ECC_10GBASE_T_SR;
}
-static void sfp_fixup_rollball_proto(struct sfp *sfp, unsigned int secs)
+static void sfp_fixup_rollball(struct sfp *sfp)
{
sfp->mdio_protocol = MDIO_I2C_ROLLBALL;
- sfp->module_t_wait = msecs_to_jiffies(secs * 1000);
+
+ /* RollBall modules may disallow access to PHY registers for up to 25
+ * seconds, and the reads return 0xffff before that. Increase the time
+ * between PHY probe retries from 50ms to 1s so that we will wait for
+ * the PHY for a sufficient amount of time.
+ */
+ sfp->phy_t_retry = msecs_to_jiffies(1000);
}
static void sfp_fixup_fs_10gt(struct sfp *sfp)
{
sfp_fixup_10gbaset_30m(sfp);
-
- // These SFPs need 4 seconds before the PHY can be accessed
- sfp_fixup_rollball_proto(sfp, 4);
+ sfp_fixup_rollball(sfp);
}
static void sfp_fixup_halny_gsfp(struct sfp *sfp)
@@ -395,12 +399,6 @@ static void sfp_fixup_halny_gsfp(struct sfp *sfp)
sfp->state_hw_mask &= ~(SFP_F_TX_FAULT | SFP_F_LOS);
}
-static void sfp_fixup_rollball(struct sfp *sfp)
-{
- // Rollball SFPs need 25 seconds before the PHY can be accessed
- sfp_fixup_rollball_proto(sfp, 25);
-}
-
static void sfp_fixup_rollball_cc(struct sfp *sfp)
{
sfp_fixup_rollball(sfp);
@@ -2331,7 +2329,7 @@ static int sfp_sm_mod_probe(struct sfp *sfp, bool report)
mask |= SFP_F_RS1;
sfp->module_t_start_up = T_START_UP;
- sfp->module_t_wait = T_WAIT;
+ sfp->phy_t_retry = T_PHY_RETRY;
sfp->state_ignore_mask = 0;
@@ -2568,10 +2566,9 @@ static void sfp_sm_main(struct sfp *sfp, unsigned int event)
/* We need to check the TX_FAULT state, which is not defined
* while TX_DISABLE is asserted. The earliest we want to do
- * anything (such as probe for a PHY) is 50ms (or more on
- * specific modules).
+ * anything (such as probe for a PHY) is 50ms.
*/
- sfp_sm_next(sfp, SFP_S_WAIT, sfp->module_t_wait);
+ sfp_sm_next(sfp, SFP_S_WAIT, T_WAIT);
break;
case SFP_S_WAIT:
@@ -2585,8 +2582,8 @@ static void sfp_sm_main(struct sfp *sfp, unsigned int event)
* deasserting.
*/
timeout = sfp->module_t_start_up;
- if (timeout > sfp->module_t_wait)
- timeout -= sfp->module_t_wait;
+ if (timeout > T_WAIT)
+ timeout -= T_WAIT;
else
timeout = 1;
@@ -2629,7 +2626,11 @@ static void sfp_sm_main(struct sfp *sfp, unsigned int event)
ret = sfp_sm_probe_for_phy(sfp);
if (ret == -ENODEV) {
if (--sfp->sm_phy_retries) {
- sfp_sm_next(sfp, SFP_S_INIT_PHY, T_PHY_RETRY);
+ sfp_sm_next(sfp, SFP_S_INIT_PHY,
+ sfp->phy_t_retry);
+ dev_dbg(sfp->dev,
+ "no PHY detected, %u tries left\n",
+ sfp->sm_phy_retries);
break;
} else {
dev_info(sfp->dev, "no PHY detected\n");
--
2.41.0
reply other threads:[~2023-11-10 13:12 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
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=20231110131223.32201-1-kabel@kernel.org \
--to=kabel@kernel.org \
--cc=andrew@lunn.ch \
--cc=kuba@kernel.org \
--cc=netdev@vger.kernel.org \
--cc=rmk+kernel@armlinux.org.uk \
/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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.