diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c index 9aed9b3b806b93456801bec97eff7950eaf206fd..aa6df095916e1b8ecdad6ca83e2a96d54d2e4d8f 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c @@ -6792,8 +6792,14 @@ static int hclge_cfg_serdes_loopback(struct hclge_dev *hdev, bool en, static int hclge_set_serdes_loopback(struct hclge_dev *hdev, bool en, enum hnae3_loop loop_mode) { + u8 duplex; int ret; + duplex = en ? DUPLEX_FULL : hdev->hw.mac.duplex; + ret = hclge_cfg_mac_speed_dup_hw(hdev, hdev->hw.mac.speed, duplex); + if (ret) + return ret; + ret = hclge_cfg_serdes_loopback(hdev, en, loop_mode); if (ret) return ret; @@ -6819,6 +6825,12 @@ static int hclge_enable_phy_loopback(struct hclge_dev *hdev, return ret; } + hdev->hw.mac.duplex_last = phydev->duplex; + + ret = phy_set_bits(phydev, MII_BMCR, BMCR_FULLDPLX); + if (ret) + return ret; + ret = phy_resume(phydev); if (ret) return ret; @@ -6835,17 +6847,29 @@ static int hclge_disable_phy_loopback(struct hclge_dev *hdev, if (ret) return ret; + if (hdev->hw.mac.duplex_last == DUPLEX_HALF) { + ret = phy_clear_bits(phydev, MII_BMCR, BMCR_FULLDPLX); + if (ret) + return ret; + } + return phy_suspend(phydev); } static int hclge_set_phy_loopback(struct hclge_dev *hdev, bool en) { struct phy_device *phydev = hdev->hw.mac.phydev; + u8 duplex; int ret; if (!phydev) return -ENOTSUPP; + duplex = en ? DUPLEX_FULL : hdev->hw.mac.duplex; + ret = hclge_cfg_mac_speed_dup_hw(hdev, hdev->hw.mac.speed, duplex); + if (ret) + return ret; + if (en) ret = hclge_enable_phy_loopback(hdev, phydev); else diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h index 864f50c2c6ee21450be9aa8579991fe537286d12..5ab8fd9f6518256a6107bfdc2ce0f04affa09553 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h @@ -261,7 +261,9 @@ struct hclge_mac { u8 media_type; /* port media type, e.g. fibre/copper/backplane */ u8 mac_addr[ETH_ALEN]; u8 autoneg; + u8 autoneg_last; u8 duplex; + u8 duplex_last; u8 support_autoneg; u8 speed_type; /* 0: sfp speed, 1: active speed */ u32 speed;