Thread (59 messages) 59 messages, 5 authors, 2021-10-22
STALE1695d

[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
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help