1 From fdff863a4ce3677907f64396e34c45025abb6600 Mon Sep 17 00:00:00 2001
2 From: Russell King <rmk+kernel@armlinux.org.uk>
3 Date: Tue, 5 Nov 2019 12:59:36 +0000
4 Subject: [PATCH 631/660] net: sfp: split power mode switching from probe
6 Switch the power mode switching from the probe, so that we don't
7 repeatedly re-probe the SFP device if there is a problem accessing
8 the registers at I2C address 0x51.
10 In splitting this out, we can also fix a bug where we leave the module
11 in high-power mode when the upstream device is detached but the module
14 Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
16 drivers/net/phy/sfp.c | 101 ++++++++++++++++++++++++++----------------
17 1 file changed, 64 insertions(+), 37 deletions(-)
19 --- a/drivers/net/phy/sfp.c
20 +++ b/drivers/net/phy/sfp.c
21 @@ -47,6 +47,7 @@ enum {
29 @@ -69,6 +70,7 @@ static const char * const mod_state_str
30 [SFP_MOD_EMPTY] = "empty",
31 [SFP_MOD_PROBE] = "probe",
32 [SFP_MOD_HPOWER] = "hpower",
33 + [SFP_MOD_WAITPWR] = "waitpwr",
34 [SFP_MOD_PRESENT] = "present",
35 [SFP_MOD_ERROR] = "error",
37 @@ -1358,37 +1360,34 @@ static int sfp_module_parse_power(struct
41 -static int sfp_sm_mod_hpower(struct sfp *sfp)
42 +static int sfp_sm_mod_hpower(struct sfp *sfp, bool enable)
47 - if (sfp->module_power_mW <= 1000)
50 err = sfp_read(sfp, true, SFP_EXT_STATUS, &val, sizeof(val));
51 if (err != sizeof(val)) {
52 dev_err(sfp->dev, "Failed to read EEPROM: %d\n", err);
64 err = sfp_write(sfp, true, SFP_EXT_STATUS, &val, sizeof(val));
65 if (err != sizeof(val)) {
66 dev_err(sfp->dev, "Failed to write EEPROM: %d\n", err);
72 - dev_info(sfp->dev, "Module switched to %u.%uW power level\n",
73 - sfp->module_power_mW / 1000,
74 - (sfp->module_power_mW / 100) % 10);
75 - return T_HPOWER_LEVEL;
77 + dev_info(sfp->dev, "Module switched to %u.%uW power level\n",
78 + sfp->module_power_mW / 1000,
79 + (sfp->module_power_mW / 100) % 10);
86 static int sfp_sm_mod_probe(struct sfp *sfp)
87 @@ -1484,7 +1483,7 @@ static int sfp_sm_mod_probe(struct sfp *
91 - return sfp_sm_mod_hpower(sfp);
95 static void sfp_sm_mod_remove(struct sfp *sfp)
96 @@ -1529,13 +1528,22 @@ static void sfp_sm_device(struct sfp *sf
98 static void sfp_sm_module(struct sfp *sfp, unsigned int event)
100 - /* Handle remove event globally, it resets this state machine.
101 - * Also deal with upstream detachment.
103 - if (event == SFP_E_REMOVE || sfp->sm_dev_state < SFP_DEV_DOWN) {
106 + /* Handle remove event globally, it resets this state machine */
107 + if (event == SFP_E_REMOVE) {
108 if (sfp->sm_mod_state > SFP_MOD_PROBE)
109 sfp_sm_mod_remove(sfp);
110 - if (sfp->sm_mod_state != SFP_MOD_EMPTY)
111 + sfp_sm_mod_next(sfp, SFP_MOD_EMPTY, 0);
115 + /* Handle device detach globally */
116 + if (sfp->sm_dev_state < SFP_DEV_DOWN) {
117 + if (sfp->module_power_mW > 1000 &&
118 + sfp->sm_mod_state > SFP_MOD_HPOWER)
119 + sfp_sm_mod_hpower(sfp, false);
120 + if (sfp->sm_mod_state > SFP_MOD_EMPTY)
121 sfp_sm_mod_next(sfp, SFP_MOD_EMPTY, 0);
124 @@ -1547,26 +1555,45 @@ static void sfp_sm_module(struct sfp *sf
128 - if (event == SFP_E_TIMEOUT) {
129 - int val = sfp_sm_mod_probe(sfp);
130 + if (event != SFP_E_TIMEOUT)
134 - sfp_sm_mod_next(sfp, SFP_MOD_PRESENT, 0);
136 - sfp_sm_mod_next(sfp, SFP_MOD_HPOWER, val);
137 - else if (val != -EAGAIN)
138 - sfp_sm_mod_next(sfp, SFP_MOD_ERROR, 0);
140 - sfp_sm_set_timer(sfp, T_PROBE_RETRY);
141 + err = sfp_sm_mod_probe(sfp);
142 + if (err == -EAGAIN) {
143 + sfp_sm_set_timer(sfp, T_PROBE_RETRY);
148 + sfp_sm_mod_next(sfp, SFP_MOD_ERROR, 0);
152 + /* If this is a power level 1 module, we are done */
153 + if (sfp->module_power_mW <= 1000)
156 + sfp_sm_mod_next(sfp, SFP_MOD_HPOWER, 0);
159 - if (event == SFP_E_TIMEOUT) {
160 - sfp_sm_mod_next(sfp, SFP_MOD_PRESENT, 0);
161 + /* Enable high power mode */
162 + err = sfp_sm_mod_hpower(sfp, true);
164 + sfp_sm_mod_next(sfp, SFP_MOD_WAITPWR, T_HPOWER_LEVEL);
165 + else if (err != -EAGAIN)
166 + sfp_sm_mod_next(sfp, SFP_MOD_ERROR, 0);
168 + sfp_sm_set_timer(sfp, T_PROBE_RETRY);
171 + case SFP_MOD_WAITPWR:
172 + /* Wait for T_HPOWER_LEVEL to time out */
173 + if (event != SFP_E_TIMEOUT)
179 + sfp_sm_mod_next(sfp, SFP_MOD_PRESENT, 0);
182 case SFP_MOD_PRESENT: