2020-02-23 12:20:11 +00:00
|
|
|
From caf32f96f13df7d3ae6cb8bf8001c88ae22025ca Mon Sep 17 00:00:00 2001
|
|
|
|
From: Russell King <rmk+kernel@armlinux.org.uk>
|
|
|
|
Date: Fri, 8 Nov 2019 15:28:22 +0000
|
|
|
|
Subject: [PATCH 650/660] net: phylink: support Clause 45 PHYs on SFP+ modules
|
|
|
|
|
|
|
|
Some SFP+ modules have Clause 45 PHYs embedded on them, which need a
|
|
|
|
little more handling in order to ensure that they are correctly setup,
|
|
|
|
as they switch the PHY link mode according to the negotiated speed.
|
|
|
|
|
|
|
|
With Clause 22 PHYs, we assumed that they would operate in SGMII mode,
|
|
|
|
but this assumption is now false. Adapt phylink to support Clause 45
|
|
|
|
PHYs on SFP+ modules.
|
|
|
|
|
|
|
|
Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
|
|
|
|
---
|
|
|
|
drivers/net/phy/phylink.c | 21 ++++++++++++++++-----
|
|
|
|
1 file changed, 16 insertions(+), 5 deletions(-)
|
|
|
|
|
|
|
|
--- a/drivers/net/phy/phylink.c
|
|
|
|
+++ b/drivers/net/phy/phylink.c
|
2019-11-25 15:08:31 +00:00
|
|
|
@@ -712,7 +712,8 @@ static void phylink_phy_change(struct ph
|
|
|
|
phy_duplex_to_str(phydev->duplex));
|
2020-02-23 12:20:11 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
-static int phylink_bringup_phy(struct phylink *pl, struct phy_device *phy)
|
|
|
|
+static int phylink_bringup_phy(struct phylink *pl, struct phy_device *phy,
|
|
|
|
+ phy_interface_t interface)
|
|
|
|
{
|
|
|
|
struct phylink_link_state config;
|
|
|
|
__ETHTOOL_DECLARE_LINK_MODE_MASK(supported);
|
2019-11-25 15:08:31 +00:00
|
|
|
@@ -730,7 +731,7 @@ static int phylink_bringup_phy(struct ph
|
|
|
|
memset(&config, 0, sizeof(config));
|
|
|
|
linkmode_copy(supported, phy->supported);
|
|
|
|
linkmode_copy(config.advertising, phy->advertising);
|
2020-02-23 12:20:11 +00:00
|
|
|
- config.interface = pl->link_config.interface;
|
|
|
|
+ config.interface = interface;
|
|
|
|
|
|
|
|
ret = phylink_validate(pl, supported, &config);
|
|
|
|
if (ret)
|
2019-11-25 15:08:31 +00:00
|
|
|
@@ -746,6 +747,7 @@ static int phylink_bringup_phy(struct ph
|
2020-02-23 12:20:11 +00:00
|
|
|
mutex_lock(&phy->lock);
|
|
|
|
mutex_lock(&pl->state_mutex);
|
|
|
|
pl->phydev = phy;
|
|
|
|
+ pl->phy_state.interface = interface;
|
|
|
|
linkmode_copy(pl->supported, supported);
|
|
|
|
linkmode_copy(pl->link_config.advertising, config.advertising);
|
|
|
|
|
2019-11-25 15:08:31 +00:00
|
|
|
@@ -808,7 +810,7 @@ int phylink_connect_phy(struct phylink *
|
2020-02-23 12:20:11 +00:00
|
|
|
if (ret < 0)
|
|
|
|
return ret;
|
|
|
|
|
|
|
|
- ret = phylink_bringup_phy(pl, phy);
|
|
|
|
+ ret = phylink_bringup_phy(pl, phy, pl->link_config.interface);
|
|
|
|
if (ret)
|
|
|
|
phy_detach(phy);
|
|
|
|
|
2019-11-25 15:08:31 +00:00
|
|
|
@@ -861,7 +863,7 @@ int phylink_of_phy_connect(struct phylin
|
2020-02-23 12:20:11 +00:00
|
|
|
if (!phy_dev)
|
|
|
|
return -ENODEV;
|
|
|
|
|
|
|
|
- ret = phylink_bringup_phy(pl, phy_dev);
|
|
|
|
+ ret = phylink_bringup_phy(pl, phy_dev, pl->link_config.interface);
|
|
|
|
if (ret)
|
|
|
|
phy_detach(phy_dev);
|
|
|
|
|
2019-11-25 15:08:31 +00:00
|
|
|
@@ -1814,13 +1816,22 @@ static void phylink_sfp_link_up(void *up
|
2020-02-23 12:20:11 +00:00
|
|
|
static int phylink_sfp_connect_phy(void *upstream, struct phy_device *phy)
|
|
|
|
{
|
|
|
|
struct phylink *pl = upstream;
|
|
|
|
+ phy_interface_t interface = pl->link_config.interface;
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
ret = phylink_attach_phy(pl, phy, pl->link_config.interface);
|
|
|
|
if (ret < 0)
|
|
|
|
return ret;
|
|
|
|
|
|
|
|
- ret = phylink_bringup_phy(pl, phy);
|
|
|
|
+ /* Clause 45 PHYs switch their Serdes lane between several different
|
|
|
|
+ * modes, normally 10GBASE-R, SGMII. Some use 2500BASE-X for 2.5G
|
|
|
|
+ * speeds. We really need to know which interface modes the PHY and
|
|
|
|
+ * MAC supports to properly work out which linkmodes can be supported.
|
|
|
|
+ */
|
|
|
|
+ if (phy->is_c45)
|
|
|
|
+ interface = PHY_INTERFACE_MODE_NA;
|
|
|
|
+
|
|
|
|
+ ret = phylink_bringup_phy(pl, phy, interface);
|
|
|
|
if (ret)
|
|
|
|
phy_detach(phy);
|
|
|
|
|