net: sfp: remove incomplete 100BASE-FX and 100BASE-LX support
[linux-2.6-block.git] / drivers / net / phy / sfp-bus.c
CommitLineData
457c8996 1// SPDX-License-Identifier: GPL-2.0-only
ce0aa27f
RK
2#include <linux/export.h>
3#include <linux/kref.h>
4#include <linux/list.h>
5#include <linux/mutex.h>
6#include <linux/phylink.h>
2203cbf2 7#include <linux/property.h>
ce0aa27f
RK
8#include <linux/rtnetlink.h>
9#include <linux/slab.h>
10
11#include "sfp.h"
12
b34bb2cb
RK
13struct sfp_quirk {
14 const char *vendor;
15 const char *part;
16 void (*modes)(const struct sfp_eeprom_id *id, unsigned long *modes);
17};
18
0a6fcd3f
RK
19/**
20 * struct sfp_bus - internal representation of a sfp bus
21 */
ce0aa27f 22struct sfp_bus {
0a6fcd3f 23 /* private: */
ce0aa27f
RK
24 struct kref kref;
25 struct list_head node;
c19bb000 26 struct fwnode_handle *fwnode;
ce0aa27f
RK
27
28 const struct sfp_socket_ops *socket_ops;
29 struct device *sfp_dev;
30 struct sfp *sfp;
b34bb2cb 31 const struct sfp_quirk *sfp_quirk;
ce0aa27f
RK
32
33 const struct sfp_upstream_ops *upstream_ops;
34 void *upstream;
ce0aa27f
RK
35 struct phy_device *phydev;
36
37 bool registered;
38 bool started;
39};
40
b0eae33b
RK
41static void sfp_quirk_2500basex(const struct sfp_eeprom_id *id,
42 unsigned long *modes)
43{
44 phylink_set(modes, 2500baseX_Full);
45}
46
b34bb2cb 47static const struct sfp_quirk sfp_quirks[] = {
b0eae33b
RK
48 {
49 // Alcatel Lucent G-010S-P can operate at 2500base-X, but
50 // incorrectly report 2500MBd NRZ in their EEPROM
51 .vendor = "ALCATELLUCENT",
52 .part = "G010SP",
53 .modes = sfp_quirk_2500basex,
54 }, {
55 // Alcatel Lucent G-010S-A can operate at 2500base-X, but
56 // report 3.2GBd NRZ in their EEPROM
57 .vendor = "ALCATELLUCENT",
58 .part = "3FE46541AA",
59 .modes = sfp_quirk_2500basex,
60 }, {
61 // Huawei MA5671A can operate at 2500base-X, but report 1.2GBd
62 // NRZ in their EEPROM
63 .vendor = "HUAWEI",
64 .part = "MA5671A",
65 .modes = sfp_quirk_2500basex,
66 },
b34bb2cb
RK
67};
68
69static size_t sfp_strlen(const char *str, size_t maxlen)
70{
71 size_t size, i;
72
73 /* Trailing characters should be filled with space chars */
74 for (i = 0, size = 0; i < maxlen; i++)
75 if (str[i] != ' ')
76 size = i + 1;
77
78 return size;
79}
80
81static bool sfp_match(const char *qs, const char *str, size_t len)
82{
83 if (!qs)
84 return true;
85 if (strlen(qs) != len)
86 return false;
87 return !strncmp(qs, str, len);
88}
89
90static const struct sfp_quirk *sfp_lookup_quirk(const struct sfp_eeprom_id *id)
91{
92 const struct sfp_quirk *q;
93 unsigned int i;
94 size_t vs, ps;
95
96 vs = sfp_strlen(id->base.vendor_name, ARRAY_SIZE(id->base.vendor_name));
97 ps = sfp_strlen(id->base.vendor_pn, ARRAY_SIZE(id->base.vendor_pn));
98
99 for (i = 0, q = sfp_quirks; i < ARRAY_SIZE(sfp_quirks); i++, q++)
100 if (sfp_match(q->vendor, id->base.vendor_name, vs) &&
101 sfp_match(q->part, id->base.vendor_pn, ps))
102 return q;
103
104 return NULL;
105}
0a6fcd3f
RK
106/**
107 * sfp_parse_port() - Parse the EEPROM base ID, setting the port type
108 * @bus: a pointer to the &struct sfp_bus structure for the sfp module
109 * @id: a pointer to the module's &struct sfp_eeprom_id
110 * @support: optional pointer to an array of unsigned long for the
111 * ethtool support mask
112 *
113 * Parse the EEPROM identification given in @id, and return one of
114 * %PORT_TP, %PORT_FIBRE or %PORT_OTHER. If @support is non-%NULL,
115 * also set the ethtool %ETHTOOL_LINK_MODE_xxx_BIT corresponding with
116 * the connector type.
117 *
118 * If the port type is not known, returns %PORT_OTHER.
119 */
ce0aa27f
RK
120int sfp_parse_port(struct sfp_bus *bus, const struct sfp_eeprom_id *id,
121 unsigned long *support)
122{
123 int port;
124
125 /* port is the physical connector, set this from the connector field. */
126 switch (id->base.connector) {
127 case SFP_CONNECTOR_SC:
128 case SFP_CONNECTOR_FIBERJACK:
129 case SFP_CONNECTOR_LC:
130 case SFP_CONNECTOR_MT_RJ:
131 case SFP_CONNECTOR_MU:
132 case SFP_CONNECTOR_OPTICAL_PIGTAIL:
ce0aa27f
RK
133 port = PORT_FIBRE;
134 break;
135
136 case SFP_CONNECTOR_RJ45:
ce0aa27f
RK
137 port = PORT_TP;
138 break;
139
f10fcbcf
RK
140 case SFP_CONNECTOR_COPPER_PIGTAIL:
141 port = PORT_DA;
142 break;
143
ce0aa27f
RK
144 case SFP_CONNECTOR_UNSPEC:
145 if (id->base.e1000_base_t) {
ce0aa27f
RK
146 port = PORT_TP;
147 break;
148 }
149 /* fallthrough */
150 case SFP_CONNECTOR_SG: /* guess */
151 case SFP_CONNECTOR_MPO_1X12:
152 case SFP_CONNECTOR_MPO_2X16:
153 case SFP_CONNECTOR_HSSDC_II:
ce0aa27f
RK
154 case SFP_CONNECTOR_NOSEPARATE:
155 case SFP_CONNECTOR_MXC_2X16:
156 port = PORT_OTHER;
157 break;
158 default:
159 dev_warn(bus->sfp_dev, "SFP: unknown connector id 0x%02x\n",
160 id->base.connector);
161 port = PORT_OTHER;
162 break;
163 }
164
f10fcbcf
RK
165 if (support) {
166 switch (port) {
167 case PORT_FIBRE:
168 phylink_set(support, FIBRE);
169 break;
170
171 case PORT_TP:
172 phylink_set(support, TP);
173 break;
174 }
175 }
176
ce0aa27f
RK
177 return port;
178}
179EXPORT_SYMBOL_GPL(sfp_parse_port);
180
0a6fcd3f
RK
181/**
182 * sfp_parse_support() - Parse the eeprom id for supported link modes
183 * @bus: a pointer to the &struct sfp_bus structure for the sfp module
184 * @id: a pointer to the module's &struct sfp_eeprom_id
185 * @support: pointer to an array of unsigned long for the ethtool support mask
186 *
187 * Parse the EEPROM identification information and derive the supported
188 * ethtool link modes for the module.
189 */
ce0aa27f
RK
190void sfp_parse_support(struct sfp_bus *bus, const struct sfp_eeprom_id *id,
191 unsigned long *support)
192{
9962acf7 193 unsigned int br_min, br_nom, br_max;
03145864 194 __ETHTOOL_DECLARE_LINK_MODE_MASK(modes) = { 0, };
ce0aa27f 195
9962acf7
RK
196 /* Decode the bitrate information to MBd */
197 br_min = br_nom = br_max = 0;
198 if (id->base.br_nominal) {
199 if (id->base.br_nominal != 255) {
200 br_nom = id->base.br_nominal * 100;
52c5cd1b 201 br_min = br_nom - id->base.br_nominal * id->ext.br_min;
9962acf7
RK
202 br_max = br_nom + id->base.br_nominal * id->ext.br_max;
203 } else if (id->ext.br_max) {
204 br_nom = 250 * id->ext.br_max;
205 br_max = br_nom + br_nom * id->ext.br_min / 100;
206 br_min = br_nom - br_nom * id->ext.br_min / 100;
207 }
2b999ba8
AT
208
209 /* When using passive cables, in case neither BR,min nor BR,max
210 * are specified, set br_min to 0 as the nominal value is then
211 * used as the maximum.
212 */
213 if (br_min == br_max && id->base.sfp_ct_passive)
214 br_min = 0;
9962acf7
RK
215 }
216
ce0aa27f
RK
217 /* Set ethtool support from the compliance fields. */
218 if (id->base.e10g_base_sr)
03145864 219 phylink_set(modes, 10000baseSR_Full);
ce0aa27f 220 if (id->base.e10g_base_lr)
03145864 221 phylink_set(modes, 10000baseLR_Full);
ce0aa27f 222 if (id->base.e10g_base_lrm)
03145864 223 phylink_set(modes, 10000baseLRM_Full);
ce0aa27f 224 if (id->base.e10g_base_er)
03145864 225 phylink_set(modes, 10000baseER_Full);
ce0aa27f
RK
226 if (id->base.e1000_base_sx ||
227 id->base.e1000_base_lx ||
228 id->base.e1000_base_cx)
03145864 229 phylink_set(modes, 1000baseX_Full);
ce0aa27f 230 if (id->base.e1000_base_t) {
03145864
RK
231 phylink_set(modes, 1000baseT_Half);
232 phylink_set(modes, 1000baseT_Full);
ce0aa27f
RK
233 }
234
9962acf7
RK
235 /* 1000Base-PX or 1000Base-BX10 */
236 if ((id->base.e_base_px || id->base.e_base_bx10) &&
237 br_min <= 1300 && br_max >= 1200)
d7f7e001 238 phylink_set(modes, 1000baseX_Full);
9962acf7 239
f10fcbcf
RK
240 /* For active or passive cables, select the link modes
241 * based on the bit rates and the cable compliance bytes.
242 */
243 if ((id->base.sfp_ct_passive || id->base.sfp_ct_active) && br_nom) {
244 /* This may look odd, but some manufacturers use 12000MBd */
245 if (br_min <= 12000 && br_max >= 10300)
03145864 246 phylink_set(modes, 10000baseCR_Full);
f10fcbcf 247 if (br_min <= 3200 && br_max >= 3100)
03145864 248 phylink_set(modes, 2500baseX_Full);
f10fcbcf 249 if (br_min <= 1300 && br_max >= 1200)
03145864 250 phylink_set(modes, 1000baseX_Full);
f10fcbcf
RK
251 }
252 if (id->base.sfp_ct_passive) {
253 if (id->base.passive.sff8431_app_e)
03145864 254 phylink_set(modes, 10000baseCR_Full);
f10fcbcf
RK
255 }
256 if (id->base.sfp_ct_active) {
257 if (id->base.active.sff8431_app_e ||
258 id->base.active.sff8431_lim) {
03145864 259 phylink_set(modes, 10000baseCR_Full);
f10fcbcf
RK
260 }
261 }
262
ce0aa27f
RK
263 switch (id->base.extended_cc) {
264 case 0x00: /* Unspecified */
265 break;
266 case 0x02: /* 100Gbase-SR4 or 25Gbase-SR */
03145864
RK
267 phylink_set(modes, 100000baseSR4_Full);
268 phylink_set(modes, 25000baseSR_Full);
ce0aa27f
RK
269 break;
270 case 0x03: /* 100Gbase-LR4 or 25Gbase-LR */
271 case 0x04: /* 100Gbase-ER4 or 25Gbase-ER */
03145864 272 phylink_set(modes, 100000baseLR4_ER4_Full);
ce0aa27f
RK
273 break;
274 case 0x0b: /* 100Gbase-CR4 or 25Gbase-CR CA-L */
275 case 0x0c: /* 25Gbase-CR CA-S */
276 case 0x0d: /* 25Gbase-CR CA-N */
03145864
RK
277 phylink_set(modes, 100000baseCR4_Full);
278 phylink_set(modes, 25000baseCR_Full);
ce0aa27f
RK
279 break;
280 default:
281 dev_warn(bus->sfp_dev,
282 "Unknown/unsupported extended compliance code: 0x%02x\n",
283 id->base.extended_cc);
284 break;
285 }
286
287 /* For fibre channel SFP, derive possible BaseX modes */
288 if (id->base.fc_speed_100 ||
289 id->base.fc_speed_200 ||
290 id->base.fc_speed_400) {
291 if (id->base.br_nominal >= 31)
03145864 292 phylink_set(modes, 2500baseX_Full);
ce0aa27f 293 if (id->base.br_nominal >= 12)
03145864 294 phylink_set(modes, 1000baseX_Full);
ce0aa27f 295 }
03145864
RK
296
297 /* If we haven't discovered any modes that this module supports, try
298 * the encoding and bitrate to determine supported modes. Some BiDi
299 * modules (eg, 1310nm/1550nm) are not 1000BASE-BX compliant due to
300 * the differing wavelengths, so do not set any transceiver bits.
301 */
302 if (bitmap_empty(modes, __ETHTOOL_LINK_MODE_MASK_NBITS)) {
303 /* If the encoding and bit rate allows 1000baseX */
304 if (id->base.encoding == SFP_ENCODING_8B10B && br_nom &&
305 br_min <= 1300 && br_max >= 1200)
306 phylink_set(modes, 1000baseX_Full);
307 }
308
b34bb2cb
RK
309 if (bus->sfp_quirk)
310 bus->sfp_quirk->modes(id, modes);
311
03145864
RK
312 bitmap_or(support, support, modes, __ETHTOOL_LINK_MODE_MASK_NBITS);
313
314 phylink_set(support, Autoneg);
315 phylink_set(support, Pause);
316 phylink_set(support, Asym_Pause);
ce0aa27f
RK
317}
318EXPORT_SYMBOL_GPL(sfp_parse_support);
319
a9c79364
RK
320/**
321 * sfp_select_interface() - Select appropriate phy_interface_t mode
322 * @bus: a pointer to the &struct sfp_bus structure for the sfp module
323 * @id: a pointer to the module's &struct sfp_eeprom_id
324 * @link_modes: ethtool link modes mask
325 *
326 * Derive the phy_interface_t mode for the information found in the
327 * module's identifying EEPROM and the link modes mask. There is no
328 * standard or defined way to derive this information, so we decide
329 * based upon the link mode mask.
330 */
331phy_interface_t sfp_select_interface(struct sfp_bus *bus,
332 const struct sfp_eeprom_id *id,
333 unsigned long *link_modes)
334{
335 if (phylink_test(link_modes, 10000baseCR_Full) ||
336 phylink_test(link_modes, 10000baseSR_Full) ||
337 phylink_test(link_modes, 10000baseLR_Full) ||
338 phylink_test(link_modes, 10000baseLRM_Full) ||
339 phylink_test(link_modes, 10000baseER_Full))
340 return PHY_INTERFACE_MODE_10GKR;
341
342 if (phylink_test(link_modes, 2500baseX_Full))
343 return PHY_INTERFACE_MODE_2500BASEX;
344
fa2de660 345 if (id->base.e1000_base_t)
a9c79364
RK
346 return PHY_INTERFACE_MODE_SGMII;
347
348 if (phylink_test(link_modes, 1000baseX_Full))
349 return PHY_INTERFACE_MODE_1000BASEX;
350
351 dev_warn(bus->sfp_dev, "Unable to ascertain link mode\n");
352
353 return PHY_INTERFACE_MODE_NA;
354}
355EXPORT_SYMBOL_GPL(sfp_select_interface);
356
ce0aa27f
RK
357static LIST_HEAD(sfp_buses);
358static DEFINE_MUTEX(sfp_mutex);
359
360static const struct sfp_upstream_ops *sfp_get_upstream_ops(struct sfp_bus *bus)
361{
362 return bus->registered ? bus->upstream_ops : NULL;
363}
364
c19bb000 365static struct sfp_bus *sfp_bus_get(struct fwnode_handle *fwnode)
ce0aa27f
RK
366{
367 struct sfp_bus *sfp, *new, *found = NULL;
368
369 new = kzalloc(sizeof(*new), GFP_KERNEL);
370
371 mutex_lock(&sfp_mutex);
372
373 list_for_each_entry(sfp, &sfp_buses, node) {
c19bb000 374 if (sfp->fwnode == fwnode) {
ce0aa27f
RK
375 kref_get(&sfp->kref);
376 found = sfp;
377 break;
378 }
379 }
380
381 if (!found && new) {
382 kref_init(&new->kref);
c19bb000 383 new->fwnode = fwnode;
ce0aa27f
RK
384 list_add(&new->node, &sfp_buses);
385 found = new;
386 new = NULL;
387 }
388
389 mutex_unlock(&sfp_mutex);
390
391 kfree(new);
392
393 return found;
394}
395
b6e67d6d 396static void sfp_bus_release(struct kref *kref)
ce0aa27f
RK
397{
398 struct sfp_bus *bus = container_of(kref, struct sfp_bus, kref);
399
400 list_del(&bus->node);
401 mutex_unlock(&sfp_mutex);
402 kfree(bus);
403}
404
727b3668
RK
405/**
406 * sfp_bus_put() - put a reference on the &struct sfp_bus
2fca4ac9 407 * @bus: the &struct sfp_bus found via sfp_bus_find_fwnode()
727b3668
RK
408 *
409 * Put a reference on the &struct sfp_bus and free the underlying structure
410 * if this was the last reference.
411 */
412void sfp_bus_put(struct sfp_bus *bus)
ce0aa27f 413{
727b3668
RK
414 if (bus)
415 kref_put_mutex(&bus->kref, sfp_bus_release, &sfp_mutex);
ce0aa27f 416}
727b3668 417EXPORT_SYMBOL_GPL(sfp_bus_put);
ce0aa27f
RK
418
419static int sfp_register_bus(struct sfp_bus *bus)
420{
421 const struct sfp_upstream_ops *ops = bus->upstream_ops;
422 int ret;
423
424 if (ops) {
425 if (ops->link_down)
426 ops->link_down(bus->upstream);
427 if (ops->connect_phy && bus->phydev) {
428 ret = ops->connect_phy(bus->upstream, bus->phydev);
429 if (ret)
430 return ret;
431 }
432 }
727b3668 433 bus->registered = true;
b5bfc21a 434 bus->socket_ops->attach(bus->sfp);
ce0aa27f
RK
435 if (bus->started)
436 bus->socket_ops->start(bus->sfp);
320587e6 437 bus->upstream_ops->attach(bus->upstream, bus);
ce0aa27f
RK
438 return 0;
439}
440
441static void sfp_unregister_bus(struct sfp_bus *bus)
442{
443 const struct sfp_upstream_ops *ops = bus->upstream_ops;
444
445 if (bus->registered) {
320587e6 446 bus->upstream_ops->detach(bus->upstream, bus);
ce0aa27f
RK
447 if (bus->started)
448 bus->socket_ops->stop(bus->sfp);
b5bfc21a 449 bus->socket_ops->detach(bus->sfp);
ce0aa27f
RK
450 if (bus->phydev && ops && ops->disconnect_phy)
451 ops->disconnect_phy(bus->upstream);
452 }
453 bus->registered = false;
454}
455
0a6fcd3f
RK
456/**
457 * sfp_get_module_info() - Get the ethtool_modinfo for a SFP module
458 * @bus: a pointer to the &struct sfp_bus structure for the sfp module
459 * @modinfo: a &struct ethtool_modinfo
460 *
461 * Fill in the type and eeprom_len parameters in @modinfo for a module on
462 * the sfp bus specified by @bus.
463 *
464 * Returns 0 on success or a negative errno number.
465 */
ce0aa27f
RK
466int sfp_get_module_info(struct sfp_bus *bus, struct ethtool_modinfo *modinfo)
467{
ce0aa27f
RK
468 return bus->socket_ops->module_info(bus->sfp, modinfo);
469}
470EXPORT_SYMBOL_GPL(sfp_get_module_info);
471
0a6fcd3f
RK
472/**
473 * sfp_get_module_eeprom() - Read the SFP module EEPROM
474 * @bus: a pointer to the &struct sfp_bus structure for the sfp module
475 * @ee: a &struct ethtool_eeprom
476 * @data: buffer to contain the EEPROM data (must be at least @ee->len bytes)
477 *
478 * Read the EEPROM as specified by the supplied @ee. See the documentation
479 * for &struct ethtool_eeprom for the region to be read.
480 *
481 * Returns 0 on success or a negative errno number.
482 */
ce0aa27f 483int sfp_get_module_eeprom(struct sfp_bus *bus, struct ethtool_eeprom *ee,
516b29ed 484 u8 *data)
ce0aa27f 485{
ce0aa27f
RK
486 return bus->socket_ops->module_eeprom(bus->sfp, ee, data);
487}
488EXPORT_SYMBOL_GPL(sfp_get_module_eeprom);
489
0a6fcd3f
RK
490/**
491 * sfp_upstream_start() - Inform the SFP that the network device is up
492 * @bus: a pointer to the &struct sfp_bus structure for the sfp module
493 *
494 * Inform the SFP socket that the network device is now up, so that the
495 * module can be enabled by allowing TX_DISABLE to be deasserted. This
496 * should be called from the network device driver's &struct net_device_ops
497 * ndo_open() method.
498 */
ce0aa27f
RK
499void sfp_upstream_start(struct sfp_bus *bus)
500{
501 if (bus->registered)
502 bus->socket_ops->start(bus->sfp);
503 bus->started = true;
504}
505EXPORT_SYMBOL_GPL(sfp_upstream_start);
506
0a6fcd3f
RK
507/**
508 * sfp_upstream_stop() - Inform the SFP that the network device is down
509 * @bus: a pointer to the &struct sfp_bus structure for the sfp module
510 *
511 * Inform the SFP socket that the network device is now up, so that the
512 * module can be disabled by asserting TX_DISABLE, disabling the laser
513 * in optical modules. This should be called from the network device
514 * driver's &struct net_device_ops ndo_stop() method.
515 */
ce0aa27f
RK
516void sfp_upstream_stop(struct sfp_bus *bus)
517{
518 if (bus->registered)
519 bus->socket_ops->stop(bus->sfp);
520 bus->started = false;
521}
522EXPORT_SYMBOL_GPL(sfp_upstream_stop);
523
f20a4c46
RK
524static void sfp_upstream_clear(struct sfp_bus *bus)
525{
526 bus->upstream_ops = NULL;
527 bus->upstream = NULL;
f20a4c46
RK
528}
529
0a6fcd3f 530/**
727b3668 531 * sfp_bus_find_fwnode() - parse and locate the SFP bus from fwnode
2203cbf2 532 * @fwnode: firmware node for the parent device (MAC or PHY)
0a6fcd3f 533 *
727b3668
RK
534 * Parse the parent device's firmware node for a SFP bus, and locate
535 * the sfp_bus structure, incrementing its reference count. This must
536 * be put via sfp_bus_put() when done.
0a6fcd3f 537 *
2203cbf2
RK
538 * Returns: on success, a pointer to the sfp_bus structure,
539 * %NULL if no SFP is specified,
540 * on failure, an error pointer value:
541 * corresponding to the errors detailed for
542 * fwnode_property_get_reference_args().
543 * %-ENOMEM if we failed to allocate the bus.
544 * an error from the upstream's connect_phy() method.
0a6fcd3f 545 */
727b3668 546struct sfp_bus *sfp_bus_find_fwnode(struct fwnode_handle *fwnode)
ce0aa27f 547{
2203cbf2
RK
548 struct fwnode_reference_args ref;
549 struct sfp_bus *bus;
550 int ret;
ce0aa27f 551
2203cbf2
RK
552 ret = fwnode_property_get_reference_args(fwnode, "sfp", NULL,
553 0, 0, &ref);
554 if (ret == -ENOENT)
555 return NULL;
556 else if (ret < 0)
557 return ERR_PTR(ret);
ce0aa27f 558
2203cbf2
RK
559 bus = sfp_bus_get(ref.fwnode);
560 fwnode_handle_put(ref.fwnode);
561 if (!bus)
562 return ERR_PTR(-ENOMEM);
563
727b3668
RK
564 return bus;
565}
566EXPORT_SYMBOL_GPL(sfp_bus_find_fwnode);
567
568/**
569 * sfp_bus_add_upstream() - parse and register the neighbouring device
570 * @bus: the &struct sfp_bus found via sfp_bus_find_fwnode()
571 * @upstream: the upstream private data
572 * @ops: the upstream's &struct sfp_upstream_ops
573 *
574 * Add upstream driver for the SFP bus, and if the bus is complete, register
575 * the SFP bus using sfp_register_upstream(). This takes a reference on the
576 * bus, so it is safe to put the bus after this call.
577 *
578 * Returns: on success, a pointer to the sfp_bus structure,
579 * %NULL if no SFP is specified,
580 * on failure, an error pointer value:
581 * corresponding to the errors detailed for
582 * fwnode_property_get_reference_args().
583 * %-ENOMEM if we failed to allocate the bus.
584 * an error from the upstream's connect_phy() method.
585 */
586int sfp_bus_add_upstream(struct sfp_bus *bus, void *upstream,
587 const struct sfp_upstream_ops *ops)
588{
589 int ret;
590
591 /* If no bus, return success */
592 if (!bus)
593 return 0;
594
2203cbf2 595 rtnl_lock();
727b3668 596 kref_get(&bus->kref);
2203cbf2
RK
597 bus->upstream_ops = ops;
598 bus->upstream = upstream;
599
600 if (bus->sfp) {
601 ret = sfp_register_bus(bus);
602 if (ret)
603 sfp_upstream_clear(bus);
604 } else {
605 ret = 0;
ce0aa27f 606 }
2203cbf2 607 rtnl_unlock();
ce0aa27f 608
727b3668 609 if (ret)
ce0aa27f 610 sfp_bus_put(bus);
ce0aa27f 611
727b3668 612 return ret;
ce0aa27f 613}
727b3668 614EXPORT_SYMBOL_GPL(sfp_bus_add_upstream);
ce0aa27f 615
0a6fcd3f 616/**
727b3668 617 * sfp_bus_del_upstream() - Delete a sfp bus
0a6fcd3f
RK
618 * @bus: a pointer to the &struct sfp_bus structure for the sfp module
619 *
727b3668
RK
620 * Delete a previously registered upstream connection for the SFP
621 * module. @bus should have been added by sfp_bus_add_upstream().
0a6fcd3f 622 */
727b3668 623void sfp_bus_del_upstream(struct sfp_bus *bus)
ce0aa27f 624{
727b3668
RK
625 if (bus) {
626 rtnl_lock();
627 if (bus->sfp)
628 sfp_unregister_bus(bus);
629 sfp_upstream_clear(bus);
630 rtnl_unlock();
ce0aa27f 631
727b3668
RK
632 sfp_bus_put(bus);
633 }
ce0aa27f 634}
727b3668 635EXPORT_SYMBOL_GPL(sfp_bus_del_upstream);
ce0aa27f 636
ce0aa27f
RK
637/* Socket driver entry points */
638int sfp_add_phy(struct sfp_bus *bus, struct phy_device *phydev)
639{
640 const struct sfp_upstream_ops *ops = sfp_get_upstream_ops(bus);
641 int ret = 0;
642
643 if (ops && ops->connect_phy)
644 ret = ops->connect_phy(bus->upstream, phydev);
645
646 if (ret == 0)
647 bus->phydev = phydev;
648
649 return ret;
650}
651EXPORT_SYMBOL_GPL(sfp_add_phy);
652
653void sfp_remove_phy(struct sfp_bus *bus)
654{
655 const struct sfp_upstream_ops *ops = sfp_get_upstream_ops(bus);
656
657 if (ops && ops->disconnect_phy)
658 ops->disconnect_phy(bus->upstream);
659 bus->phydev = NULL;
660}
661EXPORT_SYMBOL_GPL(sfp_remove_phy);
662
ce0aa27f
RK
663void sfp_link_up(struct sfp_bus *bus)
664{
665 const struct sfp_upstream_ops *ops = sfp_get_upstream_ops(bus);
666
667 if (ops && ops->link_up)
668 ops->link_up(bus->upstream);
669}
670EXPORT_SYMBOL_GPL(sfp_link_up);
671
672void sfp_link_down(struct sfp_bus *bus)
673{
674 const struct sfp_upstream_ops *ops = sfp_get_upstream_ops(bus);
675
676 if (ops && ops->link_down)
677 ops->link_down(bus->upstream);
678}
679EXPORT_SYMBOL_GPL(sfp_link_down);
680
681int sfp_module_insert(struct sfp_bus *bus, const struct sfp_eeprom_id *id)
682{
683 const struct sfp_upstream_ops *ops = sfp_get_upstream_ops(bus);
684 int ret = 0;
685
b34bb2cb
RK
686 bus->sfp_quirk = sfp_lookup_quirk(id);
687
ce0aa27f
RK
688 if (ops && ops->module_insert)
689 ret = ops->module_insert(bus->upstream, id);
690
691 return ret;
692}
693EXPORT_SYMBOL_GPL(sfp_module_insert);
694
695void sfp_module_remove(struct sfp_bus *bus)
696{
697 const struct sfp_upstream_ops *ops = sfp_get_upstream_ops(bus);
698
699 if (ops && ops->module_remove)
700 ops->module_remove(bus->upstream);
b34bb2cb
RK
701
702 bus->sfp_quirk = NULL;
ce0aa27f
RK
703}
704EXPORT_SYMBOL_GPL(sfp_module_remove);
705
f20a4c46
RK
706static void sfp_socket_clear(struct sfp_bus *bus)
707{
708 bus->sfp_dev = NULL;
709 bus->sfp = NULL;
710 bus->socket_ops = NULL;
711}
712
ce0aa27f
RK
713struct sfp_bus *sfp_register_socket(struct device *dev, struct sfp *sfp,
714 const struct sfp_socket_ops *ops)
715{
c19bb000 716 struct sfp_bus *bus = sfp_bus_get(dev->fwnode);
ce0aa27f
RK
717 int ret = 0;
718
719 if (bus) {
720 rtnl_lock();
721 bus->sfp_dev = dev;
722 bus->sfp = sfp;
723 bus->socket_ops = ops;
724
54f70b3b 725 if (bus->upstream_ops) {
ce0aa27f 726 ret = sfp_register_bus(bus);
f20a4c46
RK
727 if (ret)
728 sfp_socket_clear(bus);
729 }
ce0aa27f
RK
730 rtnl_unlock();
731 }
732
733 if (ret) {
734 sfp_bus_put(bus);
735 bus = NULL;
736 }
737
738 return bus;
739}
740EXPORT_SYMBOL_GPL(sfp_register_socket);
741
742void sfp_unregister_socket(struct sfp_bus *bus)
743{
744 rtnl_lock();
54f70b3b 745 if (bus->upstream_ops)
0b2122e4 746 sfp_unregister_bus(bus);
f20a4c46 747 sfp_socket_clear(bus);
ce0aa27f
RK
748 rtnl_unlock();
749
750 sfp_bus_put(bus);
751}
752EXPORT_SYMBOL_GPL(sfp_unregister_socket);