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