Skip to content

Commit

Permalink
net: phy: phylink: fix SFP interface autodetection
Browse files Browse the repository at this point in the history
When connecting SFP PHY to phylink use the detected interface.
Otherwise, the link fails to come up when the configured 'phy-mode'
differs from the SFP detected mode.

Move most of phylink_connect_phy() into __phylink_connect_phy(), and
leave phylink_connect_phy() as a wrapper. phylink_sfp_connect_phy() can
now pass the SFP detected PHY interface to __phylink_connect_phy().

This fixes 1GB SFP module link up on eth3 of the Macchiatobin board that
is configured in the DT to "2500base-x" phy-mode.

Fixes: 9525ae8 ("phylink: add phylink infrastructure")
Suggested-by: Russell King <rmk+kernel@armlinux.org.uk>
Signed-off-by: Baruch Siach <baruch@tkos.co.il>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Baruch Siach authored and David S. Miller committed Oct 5, 2018
1 parent 2d52527 commit 7e41837
Showing 1 changed file with 28 additions and 20 deletions.
48 changes: 28 additions & 20 deletions drivers/net/phy/phylink.c
Original file line number Diff line number Diff line change
Expand Up @@ -717,6 +717,30 @@ static int phylink_bringup_phy(struct phylink *pl, struct phy_device *phy)
return 0;
}

static int __phylink_connect_phy(struct phylink *pl, struct phy_device *phy,
phy_interface_t interface)
{
int ret;

if (WARN_ON(pl->link_an_mode == MLO_AN_FIXED ||
(pl->link_an_mode == MLO_AN_INBAND &&
phy_interface_mode_is_8023z(interface))))
return -EINVAL;

if (pl->phydev)
return -EBUSY;

ret = phy_attach_direct(pl->netdev, phy, 0, interface);
if (ret)
return ret;

ret = phylink_bringup_phy(pl, phy);
if (ret)
phy_detach(phy);

return ret;
}

/**
* phylink_connect_phy() - connect a PHY to the phylink instance
* @pl: a pointer to a &struct phylink returned from phylink_create()
Expand All @@ -734,31 +758,13 @@ static int phylink_bringup_phy(struct phylink *pl, struct phy_device *phy)
*/
int phylink_connect_phy(struct phylink *pl, struct phy_device *phy)
{
int ret;

if (WARN_ON(pl->link_an_mode == MLO_AN_FIXED ||
(pl->link_an_mode == MLO_AN_INBAND &&
phy_interface_mode_is_8023z(pl->link_interface))))
return -EINVAL;

if (pl->phydev)
return -EBUSY;

/* Use PHY device/driver interface */
if (pl->link_interface == PHY_INTERFACE_MODE_NA) {
pl->link_interface = phy->interface;
pl->link_config.interface = pl->link_interface;
}

ret = phy_attach_direct(pl->netdev, phy, 0, pl->link_interface);
if (ret)
return ret;

ret = phylink_bringup_phy(pl, phy);
if (ret)
phy_detach(phy);

return ret;
return __phylink_connect_phy(pl, phy, pl->link_interface);
}
EXPORT_SYMBOL_GPL(phylink_connect_phy);

Expand Down Expand Up @@ -1672,7 +1678,9 @@ static void phylink_sfp_link_up(void *upstream)

static int phylink_sfp_connect_phy(void *upstream, struct phy_device *phy)
{
return phylink_connect_phy(upstream, phy);
struct phylink *pl = upstream;

return __phylink_connect_phy(upstream, phy, pl->link_config.interface);
}

static void phylink_sfp_disconnect_phy(void *upstream)
Expand Down

0 comments on commit 7e41837

Please sign in to comment.