When using a C45 PHY that is in PHY_FORCING state we are currently not
taking into account that this kind of PHY has different update_link
functions.

Use the C45 Helpers instead or the driver built-in read_status() helper,
if possible.

Signed-off-by: Jose Abreu <joab...@synopsys.com>
Cc: Andrew Lunn <and...@lunn.ch>
Cc: Florian Fainelli <f.faine...@gmail.com>
Cc: "David S. Miller" <da...@davemloft.net>
Cc: Joao Pinto <joao.pi...@synopsys.com>
---
 drivers/net/phy/phy.c |  2 +-
 include/linux/phy.h   | 13 +++++++++++++
 2 files changed, 14 insertions(+), 1 deletion(-)

diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c
index c5675df5fc6f..1ef5dbc384d0 100644
--- a/drivers/net/phy/phy.c
+++ b/drivers/net/phy/phy.c
@@ -940,7 +940,7 @@ void phy_state_machine(struct work_struct *work)
                err = phy_check_link_status(phydev);
                break;
        case PHY_FORCING:
-               err = genphy_update_link(phydev);
+               err = phy_update_link(phydev);
                if (err)
                        break;
 
diff --git a/include/linux/phy.h b/include/linux/phy.h
index 872899136fdc..67caa7eb93b1 100644
--- a/include/linux/phy.h
+++ b/include/linux/phy.h
@@ -1036,6 +1036,19 @@ static inline int phy_read_status(struct phy_device 
*phydev)
                return genphy_read_status(phydev);
 }
 
+static inline int phy_update_link(struct phy_device *phydev)
+{
+       if (!phydev->drv)
+               return -EIO;
+
+       if (phydev->drv->read_status)
+               return phydev->drv->read_status(phydev);
+       else if (phydev->is_c45)
+               return gen10g_read_status(phydev);
+       else
+               return genphy_update_link(phydev);
+}
+
 void phy_driver_unregister(struct phy_driver *drv);
 void phy_drivers_unregister(struct phy_driver *drv, int n);
 int phy_driver_register(struct phy_driver *new_driver, struct module *owner);
-- 
2.7.4

Reply via email to