[RFC net-next PATCH 16/16] net: sfp: Add quirk to ignore PHYs
From: Sean Anderson <hidden>
Date: 2021-10-04 19:17:40
Also in:
lkml
Subsystem:
ethernet phy library, networking drivers, sff/sfp/sfp+ module support, the rest · Maintainers:
Andrew Lunn, Heiner Kallweit, "David S. Miller", Eric Dumazet, Jakub Kicinski, Paolo Abeni, Russell King, Linus Torvalds
Some modules have something at SFP_PHY_ADDR which isn't a PHY. If we try to
probe it, we might attach genphy anyway if addresses 2 and 3 return
something other than all 1s. To avoid this, add a quirk for these modules
so that we do not probe their PHY.
The particular module in this case is a Finisar SFP-GB-GE-T. This module is
also worked around in xgbe_phy_finisar_phy_quirks() by setting the support
manually. However, I do not believe that it has a PHY in the first place:
$ i2cdump -y -r 0-31 $BUS 0x56 w
0,8 1,9 2,a 3,b 4,c 5,d 6,e 7,f
00: ff01 ff01 ff01 c20c 010c 01c0 0f00 0120
08: fc48 000e ff78 0000 0000 0000 0000 00f0
10: 7800 00bc 0000 401c 680c 0300 0000 0000
18: ff41 0000 0a00 8890 0000 0000 0000 0000
The first several addresses contain the same value, which should almost
never be the case for a proper phy. In addition, the "OUI" 00-7F-C3 does
not match Finisar's OUI of 00-90-65 (or any other OUI for that matter).
Signed-off-by: Sean Anderson <redacted>
---
drivers/net/phy/sfp-bus.c | 12 +++++++++++-
drivers/net/phy/sfp.c | 3 +++
2 files changed, 14 insertions(+), 1 deletion(-)
diff --git a/drivers/net/phy/sfp-bus.c b/drivers/net/phy/sfp-bus.c
index 7362f8c3271c..0b79893a79ea 100644
--- a/drivers/net/phy/sfp-bus.c
+++ b/drivers/net/phy/sfp-bus.c@@ -14,6 +14,7 @@ struct sfp_quirk { const char *vendor; const char *part; void (*modes)(const struct sfp_eeprom_id *id, unsigned long *modes); + bool ignore_phy; }; /**
@@ -68,6 +69,12 @@ static const struct sfp_quirk sfp_quirks[] = { .vendor = "ALCATELLUCENT", .part = "3FE46541AA", .modes = sfp_quirk_2500basex, + }, { + // Finisar SFP-GB-GE-T has something on its I2C bus at + // SFP_PHY_ADDR, but it is not a (c22-compliant) phy + .vendor = "FS", + .part = "SFP-GB-GE-T", + .ignore_phy = true, }, { // Huawei MA5671A can operate at 2500base-X, but report 1.2GBd // NRZ in their EEPROM
@@ -204,6 +211,9 @@ EXPORT_SYMBOL_GPL(sfp_parse_port); */ bool sfp_may_have_phy(struct sfp_bus *bus, const struct sfp_eeprom_id *id) { + if (bus->sfp_quirk && bus->sfp_quirk->ignore_phy) + return false; + if (id->base.e1000_base_t) return true;
@@ -370,7 +380,7 @@ void sfp_parse_support(struct sfp_bus *bus, const struct sfp_eeprom_id *id, phylink_set(modes, 2500baseX_Full); } - if (bus->sfp_quirk) + if (bus->sfp_quirk && bus->sfp_quirk->modes) bus->sfp_quirk->modes(id, modes); bitmap_or(support, support, modes, __ETHTOOL_LINK_MODE_MASK_NBITS);
diff --git a/drivers/net/phy/sfp.c b/drivers/net/phy/sfp.c
index ab77a9f439ef..35c414eb1ecb 100644
--- a/drivers/net/phy/sfp.c
+++ b/drivers/net/phy/sfp.c@@ -1512,6 +1512,9 @@ static int sfp_sm_probe_phy(struct sfp *sfp, bool is_c45) struct phy_device *phy; int err; + if (!sfp_may_have_phy(sfp->sfp_bus, &sfp->id)) + return 0; + phy = get_phy_device(sfp->i2c_mii, SFP_PHY_ADDR, is_c45); if (phy == ERR_PTR(-ENODEV)) return PTR_ERR(phy);
--
2.25.1