The Prolabs GLC-GE-100FX-C SFP module is a 100BaseFX module that plugs into a Cisco SGMII capable cage, thus allowing to use 100M fiber on ports that would usually only support SGMII and 1000BaseX. This module contains a Broadcom BCM5461 PHY, but fails to properly indicate support for e.100_fx mode. The FS SFP-GE-100FX-C is a similar module, but this one does have the e.100_fx bit set. Add a quirk and fixup for these modules, to have a consistent linkmode set, and make sure we use SGMII as the PHY interface. The Prolabs module absolutely needs single-byte mdio accesses, otherwise it freezes the i2c bus. Signed-off-by: Maxime Chevallier --- drivers/net/phy/sfp.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/drivers/net/phy/sfp.c b/drivers/net/phy/sfp.c index bff91735f681..fb12616a67c1 100644 --- a/drivers/net/phy/sfp.c +++ b/drivers/net/phy/sfp.c @@ -481,6 +481,23 @@ static void sfp_quirk_ubnt_uf_instant(const struct sfp_eeprom_id *id, caps->link_modes); } +static void sfp_fixup_sgmii_100fx(struct sfp *sfp) +{ + sfp->mdio_protocol = MDIO_I2C_SINGLE_BYTE_C22; + sfp->module_t_wait = msecs_to_jiffies(500); +} + +static void sfp_quirk_sgmii_100fx(const struct sfp_eeprom_id *id, + struct sfp_module_caps *caps) +{ + /* Prolabs GLC-GE-100FX-C SGMII to 100FX module doesn't set the + * base.e100_base_fx bit. + */ + linkmode_set_bit(ETHTOOL_LINK_MODE_100baseFX_Full_BIT, + caps->link_modes); + __set_bit(PHY_INTERFACE_MODE_SGMII, caps->interfaces); +} + #define SFP_QUIRK(_v, _p, _s, _f) \ { .vendor = _v, .part = _p, .support = _s, .fixup = _f, } #define SFP_QUIRK_S(_v, _p, _s) SFP_QUIRK(_v, _p, _s, NULL) @@ -553,6 +570,11 @@ static const struct sfp_quirk sfp_quirks[] = { SFP_QUIRK_F("Turris", "RTSFP-2.5G", sfp_fixup_rollball), SFP_QUIRK_F("Turris", "RTSFP-10", sfp_fixup_rollball), SFP_QUIRK_F("Turris", "RTSFP-10G", sfp_fixup_rollball), + + SFP_QUIRK("CISCO-PROLABS", "GLC-GE-100FX-C", + sfp_quirk_sgmii_100fx, sfp_fixup_sgmii_100fx), + SFP_QUIRK("FS", "SFP-GE-100FX", + sfp_quirk_sgmii_100fx, sfp_fixup_sgmii_100fx), }; static size_t sfp_strlen(const char *str, size_t maxlen) -- 2.49.0