]> www.infradead.org Git - users/dwmw2/linux.git/commitdiff
net: amd-xgbe: Reset link when the link never comes back
authorShyam Sundar S K <Shyam-sundar.S-k@amd.com>
Tue, 16 Feb 2021 19:07:09 +0000 (00:37 +0530)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 3 Mar 2021 17:22:40 +0000 (18:22 +0100)
[ Upstream commit 84fe68eb67f9499309cffd97c1ba269de125ff14 ]

Normally, auto negotiation and reconnect should be automatically done by
the hardware. But there seems to be an issue where auto negotiation has
to be restarted manually. This happens because of link training and so
even though still connected to the partner the link never "comes back".
This needs an auto-negotiation restart.

Also, a change in xgbe-mdio is needed to get ethtool to recognize the
link down and get the link change message. This change is only
required in a backplane connection mode.

Fixes: abf0a1c2b26a ("amd-xgbe: Add support for SFP+ modules")
Co-developed-by: Sudheesh Mavila <sudheesh.mavila@amd.com>
Signed-off-by: Sudheesh Mavila <sudheesh.mavila@amd.com>
Signed-off-by: Shyam Sundar S K <Shyam-sundar.S-k@amd.com>
Acked-by: Tom Lendacky <thomas.lendacky@amd.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
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 119777986ea48ab26f148b372dd9702613422092..20ac6db6437b77da39dfc9403a0c27c34f11bfb0 100644 (file)
@@ -1355,7 +1355,7 @@ static void xgbe_phy_status(struct xgbe_prv_data *pdata)
                                                             &an_restart);
        if (an_restart) {
                xgbe_phy_config_aneg(pdata);
-               return;
+               goto adjust_link;
        }
 
        if (pdata->phy.link) {
index 4bb95ec6fba4a56891c7b4993264cb3de8da5485..bb6f0dcea6eab59265cc27270b351052f465eaae 100644 (file)
@@ -2435,6 +2435,14 @@ static int xgbe_phy_link_status(struct xgbe_prv_data *pdata, int *an_restart)
        if (reg & MDIO_STAT1_LSTATUS)
                return 1;
 
+       if (pdata->phy.autoneg == AUTONEG_ENABLE &&
+           phy_data->port_mode == XGBE_PORT_MODE_BACKPLANE) {
+               if (!test_bit(XGBE_LINK_INIT, &pdata->dev_state)) {
+                       netif_carrier_off(pdata->netdev);
+                       *an_restart = 1;
+               }
+       }
+
        /* No link, attempt a receiver reset cycle */
        if (phy_data->rrc_count++ > XGBE_RRC_FREQUENCY) {
                phy_data->rrc_count = 0;