提交 8c024f84 编写于 作者: Y Yufeng Mo 提交者: Xie XiuQi

net: hns3: add phy selftest function

driver inclusion
category: bugfix
bugzilla: NA
CVE: NA

Currently, the loopback test supports only mac selftest and serdes
selftest. This patch adds phy selftest.
Signed-off-by: NYufeng Mo <moyufeng@huawei.com>
Reviewed-by: Nlipeng <lipeng321@huawei.com>
Reviewed-by: NYang Yingliang <yangyingliang@huawei.com>
Signed-off-by: NYang Yingliang <yangyingliang@huawei.com>
上级 922b2672
...@@ -55,7 +55,7 @@ static const struct hns3_stats hns3_rxq_stats[] = { ...@@ -55,7 +55,7 @@ static const struct hns3_stats hns3_rxq_stats[] = {
#define HNS3_TQP_STATS_COUNT (HNS3_TXQ_STATS_COUNT + HNS3_RXQ_STATS_COUNT) #define HNS3_TQP_STATS_COUNT (HNS3_TXQ_STATS_COUNT + HNS3_RXQ_STATS_COUNT)
#define HNS3_SELF_TEST_TPYE_NUM 3 #define HNS3_SELF_TEST_TPYE_NUM 4
#define HNS3_NIC_LB_TEST_PKT_NUM 1 #define HNS3_NIC_LB_TEST_PKT_NUM 1
#define HNS3_NIC_LB_TEST_RING_ID 0 #define HNS3_NIC_LB_TEST_RING_ID 0
#define HNS3_NIC_LB_TEST_PACKET_SIZE 128 #define HNS3_NIC_LB_TEST_PACKET_SIZE 128
...@@ -85,6 +85,7 @@ static int hns3_lp_setup(struct net_device *ndev, enum hnae3_loop loop, bool en) ...@@ -85,6 +85,7 @@ static int hns3_lp_setup(struct net_device *ndev, enum hnae3_loop loop, bool en)
case HNAE3_LOOP_SERIAL_SERDES: case HNAE3_LOOP_SERIAL_SERDES:
case HNAE3_LOOP_PARALLEL_SERDES: case HNAE3_LOOP_PARALLEL_SERDES:
case HNAE3_LOOP_APP: case HNAE3_LOOP_APP:
case HNAE3_LOOP_PHY:
ret = h->ae_algo->ops->set_loopback(h, loop, en); ret = h->ae_algo->ops->set_loopback(h, loop, en);
break; break;
default: default:
...@@ -329,6 +330,10 @@ static void hns3_self_test(struct net_device *ndev, ...@@ -329,6 +330,10 @@ static void hns3_self_test(struct net_device *ndev,
st_param[HNAE3_LOOP_PARALLEL_SERDES][1] = st_param[HNAE3_LOOP_PARALLEL_SERDES][1] =
h->flags & HNAE3_SUPPORT_SERDES_PARALLEL_LOOPBACK; h->flags & HNAE3_SUPPORT_SERDES_PARALLEL_LOOPBACK;
st_param[HNAE3_LOOP_PHY][0] = HNAE3_LOOP_PHY;
st_param[HNAE3_LOOP_PHY][1] =
h->flags & HNAE3_SUPPORT_PHY_LOOPBACK;
if (if_running) if (if_running)
ndev->netdev_ops->ndo_stop(ndev); ndev->netdev_ops->ndo_stop(ndev);
......
...@@ -37,6 +37,8 @@ ...@@ -37,6 +37,8 @@
#define HCLGE_RESET_MAX_FAIL_CNT 5 #define HCLGE_RESET_MAX_FAIL_CNT 5
#define HCLGE_LINK_STATUS_MS 10
static int hclge_set_mac_mtu(struct hclge_dev *hdev, int new_mps); static int hclge_set_mac_mtu(struct hclge_dev *hdev, int new_mps);
static int hclge_init_vlan_config(struct hclge_dev *hdev); static int hclge_init_vlan_config(struct hclge_dev *hdev);
static void hclge_sync_vlan_filter(struct hclge_dev *hdev); static void hclge_sync_vlan_filter(struct hclge_dev *hdev);
...@@ -572,6 +574,7 @@ static int hclge_get_sset_count(struct hnae3_handle *handle, int stringset) ...@@ -572,6 +574,7 @@ static int hclge_get_sset_count(struct hnae3_handle *handle, int stringset)
HNAE3_SUPPORT_SERDES_PARALLEL_LOOPBACK) HNAE3_SUPPORT_SERDES_PARALLEL_LOOPBACK)
struct hclge_vport *vport = hclge_get_vport(handle); struct hclge_vport *vport = hclge_get_vport(handle);
struct phy_device *phy_dev = handle->netdev->phydev;
struct hclge_dev *hdev = vport->back; struct hclge_dev *hdev = vport->back;
int count = 0; int count = 0;
...@@ -594,6 +597,12 @@ static int hclge_get_sset_count(struct hnae3_handle *handle, int stringset) ...@@ -594,6 +597,12 @@ static int hclge_get_sset_count(struct hnae3_handle *handle, int stringset)
count += 2; count += 2;
handle->flags |= HNAE3_SUPPORT_SERDES_SERIAL_LOOPBACK; handle->flags |= HNAE3_SUPPORT_SERDES_SERIAL_LOOPBACK;
handle->flags |= HNAE3_SUPPORT_SERDES_PARALLEL_LOOPBACK; handle->flags |= HNAE3_SUPPORT_SERDES_PARALLEL_LOOPBACK;
if (phy_dev) {
count += 1;
handle->flags |= HNAE3_SUPPORT_PHY_LOOPBACK;
}
} else if (stringset == ETH_SS_STATS) { } else if (stringset == ETH_SS_STATS) {
count = ARRAY_SIZE(g_mac_stats_string) + count = ARRAY_SIZE(g_mac_stats_string) +
hclge_tqps_get_sset_count(handle, stringset); hclge_tqps_get_sset_count(handle, stringset);
...@@ -6088,6 +6097,63 @@ static void hclge_cfg_mac_mode(struct hclge_dev *hdev, bool enable) ...@@ -6088,6 +6097,63 @@ static void hclge_cfg_mac_mode(struct hclge_dev *hdev, bool enable)
"mac enable fail, ret =%d.\n", ret); "mac enable fail, ret =%d.\n", ret);
} }
static void hclge_phy_link_status_wait(struct hclge_dev *hdev,
struct phy_device *phydev, int link_ret)
{
#define HCLGE_PHY_LINK_STATUS_NUM 200
int i = 0;
int ret;
do {
ret = phy_read_status(phydev);
if (ret)
dev_warn(&hdev->pdev->dev,
"phy update link status fail\n");
if (phydev->link == link_ret)
break;
msleep(HCLGE_LINK_STATUS_MS);
} while (++i < HCLGE_PHY_LINK_STATUS_NUM);
}
static int hclge_mac_link_status_wait(struct hclge_dev *hdev, int link_ret)
{
#define HCLGE_MAC_LINK_STATUS_NUM 100
int i = 0;
int ret;
do {
ret = hclge_get_mac_link_status(hdev);
if (ret == link_ret)
return 0;
msleep(HCLGE_LINK_STATUS_MS);
} while (++i < HCLGE_MAC_LINK_STATUS_NUM);
return -EBUSY;
}
static int hclge_mac_phy_link_status_wait(struct hclge_dev *hdev, bool en)
{
#define HCLGE_LINK_STATUS_DOWN 0
#define HCLGE_LINK_STATUS_UP 1
struct phy_device *phydev = hdev->hw.mac.phydev;
int link_ret;
int ret;
if (en)
link_ret = HCLGE_LINK_STATUS_UP;
else
link_ret = HCLGE_LINK_STATUS_DOWN;
if (phydev)
hclge_phy_link_status_wait(hdev, phydev, link_ret);
ret = hclge_mac_link_status_wait(hdev, link_ret);
return ret;
}
static int hclge_set_app_loopback(struct hclge_dev *hdev, bool en) static int hclge_set_app_loopback(struct hclge_dev *hdev, bool en)
{ {
struct hclge_config_mac_mode_cmd *req; struct hclge_config_mac_mode_cmd *req;
...@@ -6130,15 +6196,9 @@ static int hclge_set_serdes_loopback(struct hclge_dev *hdev, bool en, ...@@ -6130,15 +6196,9 @@ static int hclge_set_serdes_loopback(struct hclge_dev *hdev, bool en,
#define HCLGE_SERDES_RETRY_MS 10 #define HCLGE_SERDES_RETRY_MS 10
#define HCLGE_SERDES_RETRY_NUM 100 #define HCLGE_SERDES_RETRY_NUM 100
#define HCLGE_MAC_LINK_STATUS_MS 10
#define HCLGE_MAC_LINK_STATUS_NUM 100
#define HCLGE_MAC_LINK_STATUS_DOWN 0
#define HCLGE_MAC_LINK_STATUS_UP 1
struct hclge_serdes_lb_cmd *req; struct hclge_serdes_lb_cmd *req;
struct hclge_desc desc; struct hclge_desc desc;
int ret, i = 0; int ret, i = 0;
int mac_link_ret = 0;
u8 loop_mode_b; u8 loop_mode_b;
req = (struct hclge_serdes_lb_cmd *)desc.data; req = (struct hclge_serdes_lb_cmd *)desc.data;
...@@ -6160,10 +6220,8 @@ static int hclge_set_serdes_loopback(struct hclge_dev *hdev, bool en, ...@@ -6160,10 +6220,8 @@ static int hclge_set_serdes_loopback(struct hclge_dev *hdev, bool en,
if (en) { if (en) {
req->enable = loop_mode_b; req->enable = loop_mode_b;
req->mask = loop_mode_b; req->mask = loop_mode_b;
mac_link_ret = HCLGE_MAC_LINK_STATUS_UP;
} else { } else {
req->mask = loop_mode_b; req->mask = loop_mode_b;
mac_link_ret = HCLGE_MAC_LINK_STATUS_DOWN;
} }
ret = hclge_cmd_send(&hdev->hw, &desc, 1); ret = hclge_cmd_send(&hdev->hw, &desc, 1);
...@@ -6196,19 +6254,69 @@ static int hclge_set_serdes_loopback(struct hclge_dev *hdev, bool en, ...@@ -6196,19 +6254,69 @@ static int hclge_set_serdes_loopback(struct hclge_dev *hdev, bool en,
hclge_cfg_mac_mode(hdev, en); hclge_cfg_mac_mode(hdev, en);
i = 0; ret = hclge_mac_phy_link_status_wait(hdev, en);
if (ret)
dev_err(&hdev->pdev->dev,
"serdes loopback config mac mode timeout\n");
do { return ret;
/* serdes Internal loopback, independent of the network cable.*/ }
msleep(HCLGE_MAC_LINK_STATUS_MS);
ret = hclge_get_mac_link_status(hdev); static int hclge_enable_phy_loopback(struct hclge_dev *hdev,
if (ret == mac_link_ret) struct phy_device *phydev)
return 0; {
} while (++i < HCLGE_MAC_LINK_STATUS_NUM); int ret;
dev_err(&hdev->pdev->dev, "config mac mode timeout\n"); if (!phydev->suspended) {
ret = phy_suspend(phydev);
if (ret)
return ret;
}
return -EBUSY; ret = phy_resume(phydev);
if (ret)
return ret;
ret = phy_loopback(phydev, true);
return ret;
}
static int hclge_disable_phy_loopback(struct hclge_dev *hdev,
struct phy_device *phydev)
{
int ret;
ret = phy_loopback(phydev, false);
if (ret)
return ret;
ret = phy_suspend(phydev);
return ret;
}
static int hclge_set_phy_loopback(struct hclge_dev *hdev,
struct phy_device *phydev, bool en)
{
int ret;
if (en)
ret = hclge_enable_phy_loopback(hdev, phydev);
else
ret = hclge_disable_phy_loopback(hdev, phydev);
if (ret) {
dev_err(&hdev->pdev->dev,
"set phy loopback fail, ret = %d\n", ret);
return ret;
}
hclge_cfg_mac_mode(hdev, en);
ret = hclge_mac_phy_link_status_wait(hdev, en);
if (ret)
dev_err(&hdev->pdev->dev,
"phy loopback config mac mode timeout\n");
return ret;
} }
static int hclge_tqp_enable(struct hclge_dev *hdev, unsigned int tqp_id, static int hclge_tqp_enable(struct hclge_dev *hdev, unsigned int tqp_id,
...@@ -6236,9 +6344,11 @@ static int hclge_set_loopback(struct hnae3_handle *handle, ...@@ -6236,9 +6344,11 @@ static int hclge_set_loopback(struct hnae3_handle *handle,
enum hnae3_loop loop_mode, bool en) enum hnae3_loop loop_mode, bool en)
{ {
struct hclge_vport *vport = hclge_get_vport(handle); struct hclge_vport *vport = hclge_get_vport(handle);
struct phy_device *phydev = handle->netdev->phydev;
struct hnae3_knic_private_info *kinfo; struct hnae3_knic_private_info *kinfo;
struct hclge_dev *hdev = vport->back; struct hclge_dev *hdev = vport->back;
int i, ret; int ret = 0;
int i;
switch (loop_mode) { switch (loop_mode) {
case HNAE3_LOOP_APP: case HNAE3_LOOP_APP:
...@@ -6248,6 +6358,10 @@ static int hclge_set_loopback(struct hnae3_handle *handle, ...@@ -6248,6 +6358,10 @@ static int hclge_set_loopback(struct hnae3_handle *handle,
case HNAE3_LOOP_PARALLEL_SERDES: case HNAE3_LOOP_PARALLEL_SERDES:
ret = hclge_set_serdes_loopback(hdev, en, loop_mode); ret = hclge_set_serdes_loopback(hdev, en, loop_mode);
break; break;
case HNAE3_LOOP_PHY:
if (phydev)
ret = hclge_set_phy_loopback(hdev, phydev, en);
break;
default: default:
ret = -ENOTSUPP; ret = -ENOTSUPP;
dev_err(&hdev->pdev->dev, dev_err(&hdev->pdev->dev,
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册