6cbd0864f73dd7de4052323f98ca200c61bdca0c
[oweals/openwrt.git] /
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
5  modules
6
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
9 specifications.
10
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.
14
15 Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
16 ---
17  drivers/net/phy/sfp.c | 38 ++++++++++++++++++++++++++++----------
18  1 file changed, 28 insertions(+), 10 deletions(-)
19
20 --- a/drivers/net/phy/sfp.c
21 +++ b/drivers/net/phy/sfp.c
22 @@ -165,9 +165,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.
25   */
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
35  
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 @@ -202,6 +205,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 @@ -1392,7 +1397,7 @@ static int sfp_sm_mod_hpower(struct sfp
48         return 0;
49  }
50  
51 -static int sfp_sm_mod_probe(struct sfp *sfp)
52 +static int sfp_sm_mod_probe(struct sfp *sfp, bool report)
53  {
54         /* SFP module inserted - read I2C data */
55         struct sfp_eeprom_id id;
56 @@ -1402,7 +1407,8 @@ static int sfp_sm_mod_probe(struct sfp *
57  
58         ret = sfp_read(sfp, false, 0, &id, sizeof(id));
59         if (ret < 0) {
60 -               dev_err(sfp->dev, "failed to read EEPROM: %d\n", ret);
61 +               if (report)
62 +                       dev_err(sfp->dev, "failed to read EEPROM: %d\n", ret);
63                 return -EAGAIN;
64         }
65  
66 @@ -1549,8 +1555,11 @@ static void sfp_sm_module(struct sfp *sf
67  
68         switch (sfp->sm_mod_state) {
69         default:
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;
75 +               }
76                 break;
77  
78         case SFP_MOD_PROBE:
79 @@ -1558,10 +1567,19 @@ static void sfp_sm_module(struct sfp *sf
80                 if (event != SFP_E_TIMEOUT)
81                         break;
82  
83 -               err = sfp_sm_mod_probe(sfp);
84 +               err = sfp_sm_mod_probe(sfp, sfp->sm_mod_tries == 1);
85                 if (err == -EAGAIN) {
86 -                       sfp_sm_set_timer(sfp, T_PROBE_RETRY);
87 -                       break;
88 +                       if (sfp->sm_mod_tries_init &&
89 +                          --sfp->sm_mod_tries_init) {
90 +                               sfp_sm_set_timer(sfp, T_PROBE_RETRY_INIT);
91 +                               break;
92 +                       } else if (sfp->sm_mod_tries && --sfp->sm_mod_tries) {
93 +                               if (sfp->sm_mod_tries == R_PROBE_RETRY_SLOW - 1)
94 +                                       dev_warn(sfp->dev,
95 +                                                "please wait, module slow to respond\n");
96 +                               sfp_sm_set_timer(sfp, T_PROBE_RETRY_SLOW);
97 +                               break;
98 +                       }
99                 }
100                 if (err < 0) {
101                         sfp_sm_mod_next(sfp, SFP_MOD_ERROR, 0);
102 @@ -1596,7 +1614,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);
105                         } else {
106 -                               sfp_sm_set_timer(sfp, T_PROBE_RETRY);
107 +                               sfp_sm_set_timer(sfp, T_PROBE_RETRY_INIT);
108                         }
109                         break;
110                 }