]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
amd-xgbe: do not double read link status
authorRaju Rangoju <Raju.Rangoju@amd.com>
Tue, 1 Jul 2025 06:50:16 +0000 (12:20 +0530)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 10 Jul 2025 14:03:12 +0000 (16:03 +0200)
[ Upstream commit 16ceda2ef683a50cd0783006c0504e1931cd8879 ]

The link status is latched low so that momentary link drops
can be detected. Always double-reading the status defeats this
design feature. Only double read if link was already down

This prevents unnecessary duplicate readings of the link status.

Fixes: 4f3b20bfbb75 ("amd-xgbe: add support for rx-adaptation")
Signed-off-by: Raju Rangoju <Raju.Rangoju@amd.com>
Reviewed-by: Simon Horman <horms@kernel.org>
Link: https://patch.msgid.link/20250701065016.4140707-1-Raju.Rangoju@amd.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
drivers/net/ethernet/amd/xgbe/xgbe-mdio.c
drivers/net/ethernet/amd/xgbe/xgbe-phy-v2.c

index 154e7598a32bfb76c9f90ff393918e3045851951..8345d439184ebe8fbd28627f5806d0630b3ac0f0 100644 (file)
@@ -1413,6 +1413,10 @@ static void xgbe_phy_status(struct xgbe_prv_data *pdata)
 
        pdata->phy.link = pdata->phy_if.phy_impl.link_status(pdata,
                                                             &an_restart);
+       /* bail out if the link status register read fails */
+       if (pdata->phy.link < 0)
+               return;
+
        if (an_restart) {
                xgbe_phy_config_aneg(pdata);
                goto adjust_link;
index 268399dfcf22f0313348327bfa806be11eebdb25..32e633d11348438a0f36997f573d3f86ae901e86 100644 (file)
@@ -2855,8 +2855,7 @@ static bool xgbe_phy_valid_speed(struct xgbe_prv_data *pdata, int speed)
 static int xgbe_phy_link_status(struct xgbe_prv_data *pdata, int *an_restart)
 {
        struct xgbe_phy_data *phy_data = pdata->phy_data;
-       unsigned int reg;
-       int ret;
+       int reg, ret;
 
        *an_restart = 0;
 
@@ -2890,11 +2889,20 @@ static int xgbe_phy_link_status(struct xgbe_prv_data *pdata, int *an_restart)
                        return 0;
        }
 
-       /* Link status is latched low, so read once to clear
-        * and then read again to get current state
-        */
-       reg = XMDIO_READ(pdata, MDIO_MMD_PCS, MDIO_STAT1);
        reg = XMDIO_READ(pdata, MDIO_MMD_PCS, MDIO_STAT1);
+       if (reg < 0)
+               return reg;
+
+       /* Link status is latched low so that momentary link drops
+        * can be detected. If link was already down read again
+        * to get the latest state.
+        */
+
+       if (!pdata->phy.link && !(reg & MDIO_STAT1_LSTATUS)) {
+               reg = XMDIO_READ(pdata, MDIO_MMD_PCS, MDIO_STAT1);
+               if (reg < 0)
+                       return reg;
+       }
 
        if (pdata->en_rx_adap) {
                /* if the link is available and adaptation is done,
@@ -2913,9 +2921,7 @@ static int xgbe_phy_link_status(struct xgbe_prv_data *pdata, int *an_restart)
                        xgbe_phy_set_mode(pdata, phy_data->cur_mode);
                }
 
-               /* check again for the link and adaptation status */
-               reg = XMDIO_READ(pdata, MDIO_MMD_PCS, MDIO_STAT1);
-               if ((reg & MDIO_STAT1_LSTATUS) && pdata->rx_adapt_done)
+               if (pdata->rx_adapt_done)
                        return 1;
        } else if (reg & MDIO_STAT1_LSTATUS)
                return 1;