summaryrefslogtreecommitdiff
path: root/drivers/net/phy/phylink.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/phy/phylink.c')
-rw-r--r--drivers/net/phy/phylink.c56
1 files changed, 31 insertions, 25 deletions
diff --git a/drivers/net/phy/phylink.c b/drivers/net/phy/phylink.c
index ac48a1db9979..39d85e47422e 100644
--- a/drivers/net/phy/phylink.c
+++ b/drivers/net/phy/phylink.c
@@ -1760,6 +1760,35 @@ static void phylink_phy_change(struct phy_device *phydev, bool up)
phylink_pause_to_str(pl->phy_state.pause));
}
+static int phylink_validate_phy(struct phylink *pl, struct phy_device *phy,
+ unsigned long *supported,
+ struct phylink_link_state *state)
+{
+ /* Check whether we would use rate matching for the proposed interface
+ * mode.
+ */
+ state->rate_matching = phy_get_rate_matching(phy, state->interface);
+
+ /* Clause 45 PHYs may switch their Serdes lane between, e.g. 10GBASE-R,
+ * 5GBASE-R, 2500BASE-X and SGMII if they are not using rate matching.
+ * For some interface modes (e.g. RXAUI, XAUI and USXGMII) switching
+ * their Serdes is either unnecessary or not reasonable.
+ *
+ * For these which switch interface modes, we really need to know which
+ * interface modes the PHY supports to properly work out which ethtool
+ * linkmodes can be supported. For now, as a work-around, we validate
+ * against all interface modes, which may lead to more ethtool link
+ * modes being advertised than are actually supported.
+ */
+ if (phy->is_c45 && state->rate_matching == RATE_MATCH_NONE &&
+ state->interface != PHY_INTERFACE_MODE_RXAUI &&
+ state->interface != PHY_INTERFACE_MODE_XAUI &&
+ state->interface != PHY_INTERFACE_MODE_USXGMII)
+ state->interface = PHY_INTERFACE_MODE_NA;
+
+ return phylink_validate(pl, supported, state);
+}
+
static int phylink_bringup_phy(struct phylink *pl, struct phy_device *phy,
phy_interface_t interface)
{
@@ -1780,32 +1809,9 @@ static int phylink_bringup_phy(struct phylink *pl, struct phy_device *phy,
memset(&config, 0, sizeof(config));
linkmode_copy(supported, phy->supported);
linkmode_copy(config.advertising, phy->advertising);
+ config.interface = interface;
- /* Check whether we would use rate matching for the proposed interface
- * mode.
- */
- config.rate_matching = phy_get_rate_matching(phy, interface);
-
- /* Clause 45 PHYs may switch their Serdes lane between, e.g. 10GBASE-R,
- * 5GBASE-R, 2500BASE-X and SGMII if they are not using rate matching.
- * For some interface modes (e.g. RXAUI, XAUI and USXGMII) switching
- * their Serdes is either unnecessary or not reasonable.
- *
- * For these which switch interface modes, we really need to know which
- * interface modes the PHY supports to properly work out which ethtool
- * linkmodes can be supported. For now, as a work-around, we validate
- * against all interface modes, which may lead to more ethtool link
- * modes being advertised than are actually supported.
- */
- if (phy->is_c45 && config.rate_matching == RATE_MATCH_NONE &&
- interface != PHY_INTERFACE_MODE_RXAUI &&
- interface != PHY_INTERFACE_MODE_XAUI &&
- interface != PHY_INTERFACE_MODE_USXGMII)
- config.interface = PHY_INTERFACE_MODE_NA;
- else
- config.interface = interface;
-
- ret = phylink_validate(pl, supported, &config);
+ ret = phylink_validate_phy(pl, phy, supported, &config);
if (ret) {
phylink_warn(pl, "validation of %s with support %*pb and advertisement %*pb failed: %pe\n",
phy_modes(config.interface),