6cbd0864f73dd7de4052323f98ca200c61bdca0c
[openwrt/staging/blogic.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 }