提交 b9dd49bc 编写于 作者: G Guangbin Huang 提交者: Yang Yingliang

net: hns3: fix loopback test of serdes and phy is failed if duplex is half

driver inclusion
category: bugfix
bugzilla: NA
CVE: NA

----------------------------

If duplex setting is half, mac and phy can not transmit and receive data
at the same time, loopback test of serdes and phy will be failed, print
message as follow:
hns3 0000:bd:00.1 eth5: self test start
hns3 0000:bd:00.1 eth5: net stop
hns3 0000:bd:00.1 eth5: link down
hns3 0000:bd:00.1 eth5: mode 1 recv fail, cnt=0x0, budget=0x1
hns3 0000:bd:00.1 eth5: mode 2 recv fail, cnt=0x0, budget=0x1
hns3 0000:bd:00.1 eth5: mode 3 recv fail, cnt=0x0, budget=0x1
hns3 0000:bd:00.1 eth5: net open
hns3 0000:bd:00.1 eth5: self test end
The test result is FAIL
The test extra info:
App    Loopback test     0
Serdes serial Loopback test      3
Serdes parallel Loopback test    3
Phy    Loopback test     3

To fix this problem, duplex setting of mac or phy will be set to
full before serdes and phy starting loopback test, and restore duplex
setting after test is end.
Signed-off-by: NGuangbin Huang <huangguangbin2@huawei.com>
Reviewed-by: NJian Shen <shenjian15@huawei.com>
Reviewed-by: NPeng Li <lipeng321@huawei.com>
Signed-off-by: NYonglong Liu <liuyonglong@huawei.com>
Reviewed-by: NYongxin Li <liyongxin1@huawei.com>
Signed-off-by: NYang Yingliang <yangyingliang@huawei.com>
上级 19741023
......@@ -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
......
......@@ -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;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册