1 From fb56cd08880aff8fb030e684fa4311bef712a499 Mon Sep 17 00:00:00 2001
2 From: Russell King <rmk+kernel@armlinux.org.uk>
3 Date: Tue, 5 Nov 2019 13:02:30 +0000
4 Subject: [PATCH 633/660] net: sfp: allow sfp to probe slow to initialise GPON
7 Some GPON modules (e.g. Huawei MA5671A) take a significant amount of
8 time to start responding on the I2C bus, contary to the SFF
11 Work around this by implementing a two-level timeout strategy, where
12 we initially quickly retry for the module, and then use a slower retry
13 after we exceed a maximum number of quick attempts.
15 Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
17 drivers/net/phy/sfp.c | 38 ++++++++++++++++++++++++++++----------
18 1 file changed, 28 insertions(+), 10 deletions(-)
20 --- a/drivers/net/phy/sfp.c
21 +++ b/drivers/net/phy/sfp.c
22 @@ -167,9 +167,12 @@ static const enum gpiod_flags gpio_flags
23 * The SFF-8472 specifies t_serial ("Time from power on until module is
24 * ready for data transmission over the two wire serial bus.") as 300ms.
26 -#define T_SERIAL msecs_to_jiffies(300)
27 -#define T_HPOWER_LEVEL msecs_to_jiffies(300)
28 -#define T_PROBE_RETRY msecs_to_jiffies(100)
29 +#define T_SERIAL msecs_to_jiffies(300)
30 +#define T_HPOWER_LEVEL msecs_to_jiffies(300)
31 +#define T_PROBE_RETRY_INIT msecs_to_jiffies(100)
32 +#define R_PROBE_RETRY_INIT 10
33 +#define T_PROBE_RETRY_SLOW msecs_to_jiffies(5000)
34 +#define R_PROBE_RETRY_SLOW 12
36 /* SFP modules appear to always have their PHY configured for bus address
37 * 0x56 (which with mdio-i2c, translates to a PHY address of 22).
38 @@ -204,6 +207,8 @@ struct sfp {
39 struct delayed_work timeout;
40 struct mutex sm_mutex; /* Protects state machine */
41 unsigned char sm_mod_state;
42 + unsigned char sm_mod_tries_init;
43 + unsigned char sm_mod_tries;
44 unsigned char sm_dev_state;
45 unsigned short sm_state;
46 unsigned int sm_retries;
47 @@ -1457,7 +1462,7 @@ static int sfp_sm_mod_hpower(struct sfp
51 -static int sfp_sm_mod_probe(struct sfp *sfp)
52 +static int sfp_sm_mod_probe(struct sfp *sfp, bool report)
54 /* SFP module inserted - read I2C data */
55 struct sfp_eeprom_id id;
56 @@ -1467,7 +1472,8 @@ static int sfp_sm_mod_probe(struct sfp *
58 ret = sfp_read(sfp, false, 0, &id, sizeof(id));
60 - dev_err(sfp->dev, "failed to read EEPROM: %d\n", ret);
62 + dev_err(sfp->dev, "failed to read EEPROM: %d\n", ret);
66 @@ -1614,8 +1620,11 @@ static void sfp_sm_module(struct sfp *sf
68 switch (sfp->sm_mod_state) {
70 - if (event == SFP_E_INSERT)
71 + if (event == SFP_E_INSERT) {
72 sfp_sm_mod_next(sfp, SFP_MOD_PROBE, T_SERIAL);
73 + sfp->sm_mod_tries_init = R_PROBE_RETRY_INIT;
74 + sfp->sm_mod_tries = R_PROBE_RETRY_SLOW;
79 @@ -1623,10 +1632,19 @@ static void sfp_sm_module(struct sfp *sf
80 if (event != SFP_E_TIMEOUT)
83 - err = sfp_sm_mod_probe(sfp);
84 + err = sfp_sm_mod_probe(sfp, sfp->sm_mod_tries == 1);
86 - sfp_sm_set_timer(sfp, T_PROBE_RETRY);
88 + if (sfp->sm_mod_tries_init &&
89 + --sfp->sm_mod_tries_init) {
90 + sfp_sm_set_timer(sfp, T_PROBE_RETRY_INIT);
92 + } else if (sfp->sm_mod_tries && --sfp->sm_mod_tries) {
93 + if (sfp->sm_mod_tries == R_PROBE_RETRY_SLOW - 1)
95 + "please wait, module slow to respond\n");
96 + sfp_sm_set_timer(sfp, T_PROBE_RETRY_SLOW);
101 sfp_sm_mod_next(sfp, SFP_MOD_ERROR, 0);
102 @@ -1661,7 +1679,7 @@ static void sfp_sm_module(struct sfp *sf
103 sfp_module_remove(sfp->sfp_bus);
104 sfp_sm_mod_next(sfp, SFP_MOD_ERROR, 0);
106 - sfp_sm_set_timer(sfp, T_PROBE_RETRY);
107 + sfp_sm_set_timer(sfp, T_PROBE_RETRY_INIT);