blob: abc9f65f09a3846f571304fc0cb02ae707cc11a8 [file] [log] [blame]
b.liue9582032025-04-17 19:18:16 +08001From 40e0b3b15f7da92e6b065292b14af7b9bfb1c6e0 Mon Sep 17 00:00:00 2001
2From: Russell King <rmk+kernel@armlinux.org.uk>
3Date: Fri, 13 Sep 2019 23:00:35 +0100
4Subject: [PATCH 642/660] net: sfp: soft status and control support
5
6Add support for the soft status and control register, which allows
7TX_FAULT and RX_LOS to be monitored and TX_DISABLE to be set. We
8make use of this when the board does not support GPIOs for these
9signals.
10
11Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
12---
13 drivers/net/phy/sfp.c | 110 ++++++++++++++++++++++++++++++++++--------
14 include/linux/sfp.h | 4 ++
15 2 files changed, 94 insertions(+), 20 deletions(-)
16
17--- a/drivers/net/phy/sfp.c
18+++ b/drivers/net/phy/sfp.c
19@@ -201,7 +201,10 @@ struct sfp {
20 struct gpio_desc *gpio[GPIO_MAX];
21 int gpio_irq[GPIO_MAX];
22
23+ bool need_poll;
24+
25 struct mutex st_mutex; /* Protects state */
26+ unsigned int state_soft_mask;
27 unsigned int state;
28 struct delayed_work poll;
29 struct delayed_work timeout;
30@@ -395,24 +398,90 @@ static int sfp_i2c_configure(struct sfp
31 }
32
33 /* Interface */
34-static unsigned int sfp_get_state(struct sfp *sfp)
35+static int sfp_read(struct sfp *sfp, bool a2, u8 addr, void *buf, size_t len)
36 {
37- return sfp->get_state(sfp);
38+ return sfp->read(sfp, a2, addr, buf, len);
39 }
40
41-static void sfp_set_state(struct sfp *sfp, unsigned int state)
42+static int sfp_write(struct sfp *sfp, bool a2, u8 addr, void *buf, size_t len)
43 {
44- sfp->set_state(sfp, state);
45+ return sfp->write(sfp, a2, addr, buf, len);
46 }
47
48-static int sfp_read(struct sfp *sfp, bool a2, u8 addr, void *buf, size_t len)
49+static unsigned int sfp_soft_get_state(struct sfp *sfp)
50 {
51- return sfp->read(sfp, a2, addr, buf, len);
52+ unsigned int state = 0;
53+ u8 status;
54+
55+ if (sfp_read(sfp, true, SFP_STATUS, &status, sizeof(status)) ==
56+ sizeof(status)) {
57+ if (status & SFP_STATUS_RX_LOS)
58+ state |= SFP_F_LOS;
59+ if (status & SFP_STATUS_TX_FAULT)
60+ state |= SFP_F_TX_FAULT;
61+ }
62+
63+ return state & sfp->state_soft_mask;
64 }
65
66-static int sfp_write(struct sfp *sfp, bool a2, u8 addr, void *buf, size_t len)
67+static void sfp_soft_set_state(struct sfp *sfp, unsigned int state)
68 {
69- return sfp->write(sfp, a2, addr, buf, len);
70+ u8 status;
71+
72+ if (sfp_read(sfp, true, SFP_STATUS, &status, sizeof(status)) ==
73+ sizeof(status)) {
74+ if (state & SFP_F_TX_DISABLE)
75+ status |= SFP_STATUS_TX_DISABLE_FORCE;
76+ else
77+ status &= ~SFP_STATUS_TX_DISABLE_FORCE;
78+
79+ sfp_write(sfp, true, SFP_STATUS, &status, sizeof(status));
80+ }
81+}
82+
83+static void sfp_soft_start_poll(struct sfp *sfp)
84+{
85+ const struct sfp_eeprom_id *id = &sfp->id;
86+
87+ sfp->state_soft_mask = 0;
88+ if (id->ext.enhopts & SFP_ENHOPTS_SOFT_TX_DISABLE &&
89+ !sfp->gpio[GPIO_TX_DISABLE])
90+ sfp->state_soft_mask |= SFP_F_TX_DISABLE;
91+ if (id->ext.enhopts & SFP_ENHOPTS_SOFT_TX_FAULT &&
92+ !sfp->gpio[GPIO_TX_FAULT])
93+ sfp->state_soft_mask |= SFP_F_TX_FAULT;
94+ if (id->ext.enhopts & SFP_ENHOPTS_SOFT_RX_LOS &&
95+ !sfp->gpio[GPIO_LOS])
96+ sfp->state_soft_mask |= SFP_F_LOS;
97+
98+ if (sfp->state_soft_mask & (SFP_F_LOS | SFP_F_TX_FAULT) &&
99+ !sfp->need_poll)
100+ mod_delayed_work(system_wq, &sfp->poll, poll_jiffies);
101+}
102+
103+static void sfp_soft_stop_poll(struct sfp *sfp)
104+{
105+ sfp->state_soft_mask = 0;
106+}
107+
108+static unsigned int sfp_get_state(struct sfp *sfp)
109+{
110+ unsigned int state = sfp->get_state(sfp);
111+
112+ if (state & SFP_F_PRESENT &&
113+ sfp->state_soft_mask & (SFP_F_LOS | SFP_F_TX_FAULT))
114+ state |= sfp_soft_get_state(sfp);
115+
116+ return state;
117+}
118+
119+static void sfp_set_state(struct sfp *sfp, unsigned int state)
120+{
121+ sfp->set_state(sfp, state);
122+
123+ if (state & SFP_F_PRESENT &&
124+ sfp->state_soft_mask & SFP_F_TX_DISABLE)
125+ sfp_soft_set_state(sfp, state);
126 }
127
128 static unsigned int sfp_check(void *buf, size_t len)
129@@ -1407,11 +1476,6 @@ static void sfp_sm_fault(struct sfp *sfp
130 }
131 }
132
133-static void sfp_sm_mod_init(struct sfp *sfp)
134-{
135- sfp_module_tx_enable(sfp);
136-}
137-
138 static void sfp_sm_probe_for_phy(struct sfp *sfp)
139 {
140 /* Setting the serdes link mode is guesswork: there's no
141@@ -1574,7 +1638,7 @@ static int sfp_sm_mod_probe(struct sfp *
142 (int)sizeof(id.ext.datecode), id.ext.datecode);
143
144 /* Check whether we support this module */
145- if (!sfp->type->module_supported(&sfp->id)) {
146+ if (!sfp->type->module_supported(&id)) {
147 dev_err(sfp->dev,
148 "module is not supported - phys id 0x%02x 0x%02x\n",
149 sfp->id.base.phys_id, sfp->id.base.phys_ext_id);
150@@ -1764,6 +1828,7 @@ static void sfp_sm_main(struct sfp *sfp,
151 if (sfp->mod_phy)
152 sfp_sm_phy_detach(sfp);
153 sfp_module_tx_disable(sfp);
154+ sfp_soft_stop_poll(sfp);
155 sfp_sm_next(sfp, SFP_S_DOWN, 0);
156 return;
157 }
158@@ -1775,7 +1840,10 @@ static void sfp_sm_main(struct sfp *sfp,
159 sfp->sm_dev_state != SFP_DEV_UP)
160 break;
161
162- sfp_sm_mod_init(sfp);
163+ if (!(sfp->id.ext.diagmon & SFP_DIAGMON_ADDRMODE))
164+ sfp_soft_start_poll(sfp);
165+
166+ sfp_module_tx_enable(sfp);
167
168 /* Initialise the fault clearance retries */
169 sfp->sm_retries = 5;
170@@ -2031,7 +2099,10 @@ static void sfp_poll(struct work_struct
171 struct sfp *sfp = container_of(work, struct sfp, poll.work);
172
173 sfp_check_state(sfp);
174- mod_delayed_work(system_wq, &sfp->poll, poll_jiffies);
175+
176+ if (sfp->state_soft_mask & (SFP_F_LOS | SFP_F_TX_FAULT) ||
177+ sfp->need_poll)
178+ mod_delayed_work(system_wq, &sfp->poll, poll_jiffies);
179 }
180
181 static struct sfp *sfp_alloc(struct device *dev)
182@@ -2076,7 +2147,6 @@ static int sfp_probe(struct platform_dev
183 const struct sff_data *sff;
184 struct i2c_adapter *i2c;
185 struct sfp *sfp;
186- bool poll = false;
187 int err, i;
188
189 sfp = sfp_alloc(&pdev->dev);
190@@ -2184,7 +2254,7 @@ static int sfp_probe(struct platform_dev
191 sfp->gpio_irq[i] = gpiod_to_irq(sfp->gpio[i]);
192 if (sfp->gpio_irq[i] < 0) {
193 sfp->gpio_irq[i] = 0;
194- poll = true;
195+ sfp->need_poll = true;
196 continue;
197 }
198
199@@ -2196,11 +2266,11 @@ static int sfp_probe(struct platform_dev
200 dev_name(sfp->dev), sfp);
201 if (err) {
202 sfp->gpio_irq[i] = 0;
203- poll = true;
204+ sfp->need_poll = true;
205 }
206 }
207
208- if (poll)
209+ if (sfp->need_poll)
210 mod_delayed_work(system_wq, &sfp->poll, poll_jiffies);
211
212 /* We could have an issue in cases no Tx disable pin is available or
213--- a/include/linux/sfp.h
214+++ b/include/linux/sfp.h
215@@ -428,6 +428,10 @@ enum {
216 SFP_TEC_CUR = 0x6c,
217
218 SFP_STATUS = 0x6e,
219+ SFP_STATUS_TX_DISABLE = BIT(7),
220+ SFP_STATUS_TX_DISABLE_FORCE = BIT(6),
221+ SFP_STATUS_TX_FAULT = BIT(2),
222+ SFP_STATUS_RX_LOS = BIT(1),
223 SFP_ALARM0 = 0x70,
224 SFP_ALARM0_TEMP_HIGH = BIT(7),
225 SFP_ALARM0_TEMP_LOW = BIT(6),