[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20211004191527.1610759-17-sean.anderson@seco.com>
Date: Mon, 4 Oct 2021 15:15:27 -0400
From: Sean Anderson <sean.anderson@...o.com>
To: netdev@...r.kernel.org, "David S . Miller" <davem@...emloft.net>,
Jakub Kicinski <kuba@...nel.org>, linux-kernel@...r.kernel.org
Cc: Andrew Lunn <andrew@...n.ch>,
Heiner Kallweit <hkallweit1@...il.com>,
Russell King <linux@...linux.org.uk>,
Sean Anderson <sean.anderson@...o.com>
Subject: [RFC net-next PATCH 16/16] net: sfp: Add quirk to ignore PHYs
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 <sean.anderson@...o.com>
---
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
Powered by blists - more mailing lists