blob: e49bde27e3257f609d21ec0deada59e235f73396 [file] [log] [blame]
b.liue9582032025-04-17 19:18:16 +08001From 57cbf7453551db1df619b79410d79fc418d862d5 Mon Sep 17 00:00:00 2001
2From: Russell King <rmk+kernel@armlinux.org.uk>
3Date: Tue, 5 Nov 2019 13:00:45 +0000
4Subject: [PATCH 632/660] net: sfp: move module insert reporting out of probe
5
6Move the module insertion reporting out of the probe handling, but
7after we have detected that the upstream has attached (since that is
8whom we are reporting insertion to.)
9
10Only report module removal if we had previously reported a module
11insertion.
12
13This gives cleaner semantics, and means we can probe the module before
14we have an upstream attached.
15
16Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
17---
18 drivers/net/phy/sfp.c | 58 +++++++++++++++++++++++++++++--------------
19 1 file changed, 40 insertions(+), 18 deletions(-)
20
21--- a/drivers/net/phy/sfp.c
22+++ b/drivers/net/phy/sfp.c
23@@ -47,11 +47,12 @@ enum {
24 SFP_E_TIMEOUT,
25
26 SFP_MOD_EMPTY = 0,
27+ SFP_MOD_ERROR,
28 SFP_MOD_PROBE,
29+ SFP_MOD_WAITDEV,
30 SFP_MOD_HPOWER,
31 SFP_MOD_WAITPWR,
32 SFP_MOD_PRESENT,
33- SFP_MOD_ERROR,
34
35 SFP_DEV_DETACHED = 0,
36 SFP_DEV_DOWN,
37@@ -70,11 +71,12 @@ enum {
38
39 static const char * const mod_state_strings[] = {
40 [SFP_MOD_EMPTY] = "empty",
41+ [SFP_MOD_ERROR] = "error",
42 [SFP_MOD_PROBE] = "probe",
43+ [SFP_MOD_WAITDEV] = "waitdev",
44 [SFP_MOD_HPOWER] = "hpower",
45 [SFP_MOD_WAITPWR] = "waitpwr",
46 [SFP_MOD_PRESENT] = "present",
47- [SFP_MOD_ERROR] = "error",
48 };
49
50 static const char *mod_state_to_str(unsigned short mod_state)
51@@ -1544,16 +1546,13 @@ static int sfp_sm_mod_probe(struct sfp *
52 if (ret < 0)
53 return ret;
54
55- ret = sfp_module_insert(sfp->sfp_bus, &sfp->id);
56- if (ret < 0)
57- return ret;
58-
59 return 0;
60 }
61
62 static void sfp_sm_mod_remove(struct sfp *sfp)
63 {
64- sfp_module_remove(sfp->sfp_bus);
65+ if (sfp->sm_mod_state > SFP_MOD_WAITDEV)
66+ sfp_module_remove(sfp->sfp_bus);
67
68 sfp_hwmon_remove(sfp);
69
70@@ -1604,12 +1603,12 @@ static void sfp_sm_module(struct sfp *sf
71 }
72
73 /* Handle device detach globally */
74- if (sfp->sm_dev_state < SFP_DEV_DOWN) {
75+ if (sfp->sm_dev_state < SFP_DEV_DOWN &&
76+ sfp->sm_mod_state > SFP_MOD_WAITDEV) {
77 if (sfp->module_power_mW > 1000 &&
78 sfp->sm_mod_state > SFP_MOD_HPOWER)
79 sfp_sm_mod_hpower(sfp, false);
80- if (sfp->sm_mod_state > SFP_MOD_EMPTY)
81- sfp_sm_mod_next(sfp, SFP_MOD_EMPTY, 0);
82+ sfp_sm_mod_next(sfp, SFP_MOD_WAITDEV, 0);
83 return;
84 }
85
86@@ -1620,6 +1619,7 @@ static void sfp_sm_module(struct sfp *sf
87 break;
88
89 case SFP_MOD_PROBE:
90+ /* Wait for T_PROBE_INIT to time out */
91 if (event != SFP_E_TIMEOUT)
92 break;
93
94@@ -1633,6 +1633,20 @@ static void sfp_sm_module(struct sfp *sf
95 break;
96 }
97
98+ sfp_sm_mod_next(sfp, SFP_MOD_WAITDEV, 0);
99+ /* fall through */
100+ case SFP_MOD_WAITDEV:
101+ /* Ensure that the device is attached before proceeding */
102+ if (sfp->sm_dev_state < SFP_DEV_DOWN)
103+ break;
104+
105+ /* Report the module insertion to the upstream device */
106+ err = sfp_module_insert(sfp->sfp_bus, &sfp->id);
107+ if (err < 0) {
108+ sfp_sm_mod_next(sfp, SFP_MOD_ERROR, 0);
109+ break;
110+ }
111+
112 /* If this is a power level 1 module, we are done */
113 if (sfp->module_power_mW <= 1000)
114 goto insert;
115@@ -1642,12 +1656,17 @@ static void sfp_sm_module(struct sfp *sf
116 case SFP_MOD_HPOWER:
117 /* Enable high power mode */
118 err = sfp_sm_mod_hpower(sfp, true);
119- if (err == 0)
120- sfp_sm_mod_next(sfp, SFP_MOD_WAITPWR, T_HPOWER_LEVEL);
121- else if (err != -EAGAIN)
122- sfp_sm_mod_next(sfp, SFP_MOD_ERROR, 0);
123- else
124- sfp_sm_set_timer(sfp, T_PROBE_RETRY);
125+ if (err < 0) {
126+ if (err != -EAGAIN) {
127+ sfp_module_remove(sfp->sfp_bus);
128+ sfp_sm_mod_next(sfp, SFP_MOD_ERROR, 0);
129+ } else {
130+ sfp_sm_set_timer(sfp, T_PROBE_RETRY);
131+ }
132+ break;
133+ }
134+
135+ sfp_sm_mod_next(sfp, SFP_MOD_WAITPWR, T_HPOWER_LEVEL);
136 break;
137
138 case SFP_MOD_WAITPWR:
139@@ -1815,8 +1834,6 @@ static void sfp_sm_event(struct sfp *sfp
140 static void sfp_attach(struct sfp *sfp)
141 {
142 sfp_sm_event(sfp, SFP_E_DEV_ATTACH);
143- if (sfp->state & SFP_F_PRESENT)
144- sfp_sm_event(sfp, SFP_E_INSERT);
145 }
146
147 static void sfp_detach(struct sfp *sfp)
148@@ -2084,6 +2101,11 @@ static int sfp_probe(struct platform_dev
149 sfp->state |= SFP_F_RATE_SELECT;
150 sfp_set_state(sfp, sfp->state);
151 sfp_module_tx_disable(sfp);
152+ if (sfp->state & SFP_F_PRESENT) {
153+ rtnl_lock();
154+ sfp_sm_event(sfp, SFP_E_INSERT);
155+ rtnl_unlock();
156+ }
157
158 for (i = 0; i < GPIO_MAX; i++) {
159 if (gpio_flags[i] != GPIOD_IN || !sfp->gpio[i])