From a3f3dd8bf4eb0984eea91f93e589b4d363d9dfaf Mon Sep 17 00:00:00 2001 From: Russell King Date: Tue, 9 May 2017 20:13:38 +0100 Subject: phylink: configure fixed link depending on phy interface mode As we now support 1000BaseX and 2500BaseX phy interface modes, we can select the appropriate autoneg mode and advertising masks from the phy interface mode. We also need to set the phy interface mode when different SFP modules are plugged in (causing changes in the autonegotiation mode.) Signed-off-by: Russell King --- drivers/net/phy/phylink.c | 47 ++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 40 insertions(+), 7 deletions(-) diff --git a/drivers/net/phy/phylink.c b/drivers/net/phy/phylink.c index b4c384cffdef..4b6a1cb66d2c 100644 --- a/drivers/net/phy/phylink.c +++ b/drivers/net/phy/phylink.c @@ -244,13 +244,33 @@ static int phylink_parse_mode(struct phylink *pl, struct device_node *np) phylink_set(pl->supported, Pause); pl->link_config.an_enabled = true; - phylink_set(pl->supported, 10baseT_Half); - phylink_set(pl->supported, 10baseT_Full); - phylink_set(pl->supported, 100baseT_Half); - phylink_set(pl->supported, 100baseT_Full); - phylink_set(pl->supported, 1000baseT_Half); - phylink_set(pl->supported, 1000baseT_Full); - pl->link_an_mode = MLO_AN_SGMII; + switch (pl->link_config.interface) { + case PHY_INTERFACE_MODE_SGMII: + phylink_set(pl->supported, 10baseT_Half); + phylink_set(pl->supported, 10baseT_Full); + phylink_set(pl->supported, 100baseT_Half); + phylink_set(pl->supported, 100baseT_Full); + phylink_set(pl->supported, 1000baseT_Half); + phylink_set(pl->supported, 1000baseT_Full); + pl->link_an_mode = MLO_AN_SGMII; + break; + + case PHY_INTERFACE_MODE_1000BASEX: + phylink_set(pl->supported, 1000baseX_Full); + pl->link_an_mode = MLO_AN_8023Z; + break; + + case PHY_INTERFACE_MODE_2500BASEX: + phylink_set(pl->supported, 2500baseX_Full); + pl->link_an_mode = MLO_AN_8023Z; + break; + + default: + netdev_err(pl->netdev, + "incorrect link mode %s for in-band status\n", + phy_modes(pl->link_config.interface)); + return -EINVAL; + } pl->ops->validate_support(pl->netdev, pl->link_an_mode, pl->supported); } @@ -1347,6 +1367,19 @@ int phylink_set_link(struct phylink *pl, unsigned int mode, u8 port, } if (pl->link_an_mode != mode) { + switch (mode) { + case MLO_AN_SGMII: + pl->link_config.interface = + PHY_INTERFACE_MODE_SGMII; + break; + case MLO_AN_8023Z: + pl->link_config.interface = + PHY_INTERFACE_MODE_1000BASEX; + break; + default: + pl->link_config.interface = pl->link_interface; + break; + } pl->link_an_mode = mode; changed = true; -- cgit