aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBaruch Siach <baruch@tkos.co.il>2018-10-03 12:04:49 -0400
committerDavid S. Miller <davem@davemloft.net>2018-10-05 04:04:12 -0400
commit7e4183752735deb7543e179a44f4f4b44917cd6f (patch)
tree8e824d068ccec95206d0ff741d9224a2da60ab29
parent2d52527e80c2dc0c5f43f50adf183781262ec565 (diff)
net: phy: phylink: fix SFP interface autodetection
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: 9525ae83959b6 ("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>
-rw-r--r--drivers/net/phy/phylink.c48
1 files changed, 28 insertions, 20 deletions
diff --git a/drivers/net/phy/phylink.c b/drivers/net/phy/phylink.c
index 3ba5cf2a8a5f..7abca86c3aa9 100644
--- a/drivers/net/phy/phylink.c
+++ b/drivers/net/phy/phylink.c
@@ -717,6 +717,30 @@ static int phylink_bringup_phy(struct phylink *pl, struct phy_device *phy)
717 return 0; 717 return 0;
718} 718}
719 719
720static int __phylink_connect_phy(struct phylink *pl, struct phy_device *phy,
721 phy_interface_t interface)
722{
723 int ret;
724
725 if (WARN_ON(pl->link_an_mode == MLO_AN_FIXED ||
726 (pl->link_an_mode == MLO_AN_INBAND &&
727 phy_interface_mode_is_8023z(interface))))
728 return -EINVAL;
729
730 if (pl->phydev)
731 return -EBUSY;
732
733 ret = phy_attach_direct(pl->netdev, phy, 0, interface);
734 if (ret)
735 return ret;
736
737 ret = phylink_bringup_phy(pl, phy);
738 if (ret)
739 phy_detach(phy);
740
741 return ret;
742}
743
720/** 744/**
721 * phylink_connect_phy() - connect a PHY to the phylink instance 745 * phylink_connect_phy() - connect a PHY to the phylink instance
722 * @pl: a pointer to a &struct phylink returned from phylink_create() 746 * @pl: a pointer to a &struct phylink returned from phylink_create()
@@ -734,31 +758,13 @@ static int phylink_bringup_phy(struct phylink *pl, struct phy_device *phy)
734 */ 758 */
735int phylink_connect_phy(struct phylink *pl, struct phy_device *phy) 759int phylink_connect_phy(struct phylink *pl, struct phy_device *phy)
736{ 760{
737 int ret;
738
739 if (WARN_ON(pl->link_an_mode == MLO_AN_FIXED ||
740 (pl->link_an_mode == MLO_AN_INBAND &&
741 phy_interface_mode_is_8023z(pl->link_interface))))
742 return -EINVAL;
743
744 if (pl->phydev)
745 return -EBUSY;
746
747 /* Use PHY device/driver interface */ 761 /* Use PHY device/driver interface */
748 if (pl->link_interface == PHY_INTERFACE_MODE_NA) { 762 if (pl->link_interface == PHY_INTERFACE_MODE_NA) {
749 pl->link_interface = phy->interface; 763 pl->link_interface = phy->interface;
750 pl->link_config.interface = pl->link_interface; 764 pl->link_config.interface = pl->link_interface;
751 } 765 }
752 766
753 ret = phy_attach_direct(pl->netdev, phy, 0, pl->link_interface); 767 return __phylink_connect_phy(pl, phy, pl->link_interface);
754 if (ret)
755 return ret;
756
757 ret = phylink_bringup_phy(pl, phy);
758 if (ret)
759 phy_detach(phy);
760
761 return ret;
762} 768}
763EXPORT_SYMBOL_GPL(phylink_connect_phy); 769EXPORT_SYMBOL_GPL(phylink_connect_phy);
764 770
@@ -1672,7 +1678,9 @@ static void phylink_sfp_link_up(void *upstream)
1672 1678
1673static int phylink_sfp_connect_phy(void *upstream, struct phy_device *phy) 1679static int phylink_sfp_connect_phy(void *upstream, struct phy_device *phy)
1674{ 1680{
1675 return phylink_connect_phy(upstream, phy); 1681 struct phylink *pl = upstream;
1682
1683 return __phylink_connect_phy(upstream, phy, pl->link_config.interface);
1676} 1684}
1677 1685
1678static void phylink_sfp_disconnect_phy(void *upstream) 1686static void phylink_sfp_disconnect_phy(void *upstream)