315 lines
12 KiB
Diff
315 lines
12 KiB
Diff
From 2c4c382df8cddb5878faaf8ec544ddaf2ae276e2 Mon Sep 17 00:00:00 2001
|
|
From: Guangbin Huang <huangguangbin2@huawei.com>
|
|
Date: Sat, 24 Jul 2021 15:43:51 +0800
|
|
Subject: [PATCH 059/283] net: hns3: add phy loopback support for
|
|
imp-controlled PHYs
|
|
|
|
mainline inclusion
|
|
from mainline-v5.13-rc1
|
|
commit b47cfe1f402dbf10279b8f12131388fdff9d2259
|
|
category: feature
|
|
bugzilla: https://gitee.com/src-openeuler/kernel/issues/I8EMQV
|
|
CVE: NA
|
|
|
|
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=b47cfe1f402dbf10279b8f12131388fdff9d2259
|
|
|
|
----------------------------------------------------------------------
|
|
|
|
If the imp-controlled PHYs feature is enabled, driver can not
|
|
call phy driver interface to set loopback anymore and needs
|
|
to send command to firmware to start phy loopback.
|
|
|
|
Driver reuses the existing firmware command 0x0315 to start
|
|
phy loopback, just add a setting bit in this command. As this
|
|
command is not only for serdes loopback anymore, rename this
|
|
command to "xxx_COMMON_LOOPBACK", and modify function name,
|
|
macro name and logs related to it.
|
|
|
|
Signed-off-by: Guangbin Huang <huangguangbin2@huawei.com>
|
|
Signed-off-by: Huazhong Tan <tanhuazhong@huawei.com>
|
|
Signed-off-by: David S. Miller <davem@davemloft.net>
|
|
Reviewed-by: Yongxin Li <liyongxin1@huawei.com>
|
|
Signed-off-by: Junxin Chen <chenjunxin1@huawei.com>
|
|
Signed-off-by: Zheng Zengkai <zhengzengkai@huawei.com>
|
|
Signed-off-by: Xiaodong Li <lixiaodong67@huawei.com>
|
|
|
|
Conflicts:
|
|
drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_debugfs.c
|
|
drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
|
|
---
|
|
.../hisilicon/hns3/hns3_cae/hns3_cae_mac.c | 4 +-
|
|
.../hisilicon/hns3/hns3pf/hclge_cmd.h | 9 +--
|
|
.../hisilicon/hns3/hns3pf/hclge_debugfs.c | 32 ++++++----
|
|
.../hisilicon/hns3/hns3pf/hclge_main.c | 64 ++++++++++---------
|
|
4 files changed, 58 insertions(+), 51 deletions(-)
|
|
|
|
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_cae/hns3_cae_mac.c b/drivers/net/ethernet/hisilicon/hns3/hns3_cae/hns3_cae_mac.c
|
|
index acbb684cf43b..fe71b673e00d 100644
|
|
--- a/drivers/net/ethernet/hisilicon/hns3/hns3_cae/hns3_cae_mac.c
|
|
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3_cae/hns3_cae_mac.c
|
|
@@ -61,7 +61,7 @@ int hns3_cae_mac_loop_cfg(const struct hns3_nic_priv *net_priv,
|
|
out_info->rx2tx_loop_en =
|
|
hnae3_get_bit(req2->txrx_pad_fcs_loop_en,
|
|
HCLGE_MAC_LINE_LP_B);
|
|
- hns3_cae_cmd_setup_basic_desc(&desc, HCLGE_OPC_SERDES_LOOPBACK,
|
|
+ hns3_cae_cmd_setup_basic_desc(&desc, HCLGE_OPC_COMMON_LOOPBACK,
|
|
true);
|
|
ret = hns3_cae_cmd_send(hdev, &desc, 1);
|
|
if (ret) {
|
|
@@ -111,7 +111,7 @@ int hns3_cae_mac_loop_cfg(const struct hns3_nic_priv *net_priv,
|
|
}
|
|
} else {
|
|
hns3_cae_cmd_setup_basic_desc(&desc,
|
|
- HCLGE_OPC_SERDES_LOOPBACK,
|
|
+ HCLGE_OPC_COMMON_LOOPBACK,
|
|
true);
|
|
ret = hns3_cae_cmd_send(hdev, &desc, 1);
|
|
if (ret) {
|
|
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h
|
|
index 88aefd3685a7..028ff1722614 100644
|
|
--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h
|
|
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h
|
|
@@ -127,7 +127,7 @@ enum hclge_opcode_type {
|
|
HCLGE_OPC_QUERY_MAC_TNL_INT = 0x0310,
|
|
HCLGE_OPC_MAC_TNL_INT_EN = 0x0311,
|
|
HCLGE_OPC_CLEAR_MAC_TNL_INT = 0x0312,
|
|
- HCLGE_OPC_SERDES_LOOPBACK = 0x0315,
|
|
+ HCLGE_OPC_COMMON_LOOPBACK = 0x0315,
|
|
HCLGE_OPC_CONFIG_FEC_MODE = 0x031A,
|
|
/* check sum command */
|
|
HCLGE_OPC_CFG_CHECKSUM_EN = 0x0601,
|
|
@@ -976,9 +976,10 @@ struct hclge_pf_rst_done_cmd {
|
|
|
|
#define HCLGE_CMD_SERDES_SERIAL_INNER_LOOP_B BIT(0)
|
|
#define HCLGE_CMD_SERDES_PARALLEL_INNER_LOOP_B BIT(2)
|
|
-#define HCLGE_CMD_SERDES_DONE_B BIT(0)
|
|
-#define HCLGE_CMD_SERDES_SUCCESS_B BIT(1)
|
|
-struct hclge_serdes_lb_cmd {
|
|
+#define HCLGE_CMD_GE_PHY_INNER_LOOP_B BIT(3)
|
|
+#define HCLGE_CMD_COMMON_LB_DONE_B BIT(0)
|
|
+#define HCLGE_CMD_COMMON_LB_SUCCESS_B BIT(1)
|
|
+struct hclge_common_lb_cmd {
|
|
u8 mask;
|
|
u8 enable;
|
|
u8 result;
|
|
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_debugfs.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_debugfs.c
|
|
index e73e10d17222..c65abb2c2b09 100644
|
|
--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_debugfs.c
|
|
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_debugfs.c
|
|
@@ -1845,14 +1845,14 @@ static int hclge_dbg_dump_loopback(struct hclge_dev *hdev, char *buf, int len)
|
|
{
|
|
struct phy_device *phydev = hdev->hw.mac.phydev;
|
|
struct hclge_config_mac_mode_cmd *req_app;
|
|
- struct hclge_serdes_lb_cmd *req_serdes;
|
|
+ struct hclge_common_lb_cmd *req_common;
|
|
struct hclge_desc desc;
|
|
u8 loopback_en;
|
|
int pos = 0;
|
|
int ret;
|
|
|
|
req_app = (struct hclge_config_mac_mode_cmd *)desc.data;
|
|
- req_serdes = (struct hclge_serdes_lb_cmd *)desc.data;
|
|
+ req_common = (struct hclge_common_lb_cmd *)desc.data;
|
|
|
|
pos += scnprintf(buf + pos, len - pos, "mac id: %u\n",
|
|
hdev->hw.mac.mac_id);
|
|
@@ -1870,28 +1870,32 @@ static int hclge_dbg_dump_loopback(struct hclge_dev *hdev, char *buf, int len)
|
|
pos += scnprintf(buf + pos, len - pos, "app loopback: %s\n",
|
|
state_str[loopback_en]);
|
|
|
|
- hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_SERDES_LOOPBACK, true);
|
|
+ hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_COMMON_LOOPBACK, true);
|
|
ret = hclge_cmd_send(&hdev->hw, &desc, 1);
|
|
if (ret) {
|
|
dev_err(&hdev->pdev->dev,
|
|
- "failed to dump serdes loopback status, ret = %d\n",
|
|
+ "failed to dump common loopback status, ret = %d\n",
|
|
ret);
|
|
return ret;
|
|
}
|
|
|
|
- loopback_en = req_serdes->enable & HCLGE_CMD_SERDES_SERIAL_INNER_LOOP_B;
|
|
- pos += scnprintf(buf + pos, len - pos, "serdes serial loopback: %s\n",
|
|
- state_str[loopback_en]);
|
|
+ loopback_en = req_common->enable & HCLGE_CMD_SERDES_SERIAL_INNER_LOOP_B;
|
|
+ dev_info(&hdev->pdev->dev, "serdes serial loopback: %s\n",
|
|
+ loopback_en ? "on" : "off");
|
|
|
|
- loopback_en = req_serdes->enable &
|
|
- HCLGE_CMD_SERDES_PARALLEL_INNER_LOOP_B ? 1 : 0;
|
|
- pos += scnprintf(buf + pos, len - pos, "serdes parallel loopback: %s\n",
|
|
- state_str[loopback_en]);
|
|
+ loopback_en = req_common->enable &
|
|
+ HCLGE_CMD_SERDES_PARALLEL_INNER_LOOP_B;
|
|
+ dev_info(&hdev->pdev->dev, "serdes parallel loopback: %s\n",
|
|
+ loopback_en ? "on" : "off");
|
|
|
|
if (phydev) {
|
|
- loopback_en = phydev->loopback_enabled;
|
|
- pos += scnprintf(buf + pos, len - pos, "phy loopback: %s\n",
|
|
- state_str[loopback_en]);
|
|
+ dev_info(&hdev->pdev->dev, "phy loopback: %s\n",
|
|
+ phydev->loopback_enabled ? "on" : "off");
|
|
+ } else if (hnae3_dev_phy_imp_supported(hdev)) {
|
|
+ loopback_en = req_common->enable &
|
|
+ HCLGE_CMD_GE_PHY_INNER_LOOP_B;
|
|
+ dev_info(&hdev->pdev->dev, "phy loopback: %s\n",
|
|
+ loopback_en ? "on" : "off");
|
|
}
|
|
|
|
return 0;
|
|
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
|
|
index abd79d4bc56d..949dfc433e3e 100644
|
|
--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
|
|
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
|
|
@@ -752,8 +752,9 @@ static int hclge_get_sset_count(struct hnae3_handle *handle, int stringset)
|
|
handle->flags |= HNAE3_SUPPORT_SERDES_SERIAL_LOOPBACK;
|
|
handle->flags |= HNAE3_SUPPORT_SERDES_PARALLEL_LOOPBACK;
|
|
|
|
- if (hdev->hw.mac.phydev && hdev->hw.mac.phydev->drv &&
|
|
- hdev->hw.mac.phydev->drv->set_loopback) {
|
|
+ if ((hdev->hw.mac.phydev && hdev->hw.mac.phydev->drv &&
|
|
+ hdev->hw.mac.phydev->drv->set_loopback) ||
|
|
+ hnae3_dev_phy_imp_supported(hdev)) {
|
|
count += 1;
|
|
handle->flags |= HNAE3_SUPPORT_PHY_LOOPBACK;
|
|
}
|
|
@@ -6863,19 +6864,19 @@ static int hclge_set_app_loopback(struct hclge_dev *hdev, bool en)
|
|
return ret;
|
|
}
|
|
|
|
-static int hclge_cfg_serdes_loopback(struct hclge_dev *hdev, bool en,
|
|
+static int hclge_cfg_common_loopback(struct hclge_dev *hdev, bool en,
|
|
enum hnae3_loop loop_mode)
|
|
{
|
|
-#define HCLGE_SERDES_RETRY_MS 10
|
|
-#define HCLGE_SERDES_RETRY_NUM 100
|
|
+#define HCLGE_COMMON_LB_RETRY_MS 10
|
|
+#define HCLGE_COMMON_LB_RETRY_NUM 100
|
|
|
|
- struct hclge_serdes_lb_cmd *req;
|
|
+ struct hclge_common_lb_cmd *req;
|
|
struct hclge_desc desc;
|
|
int ret, i = 0;
|
|
u8 loop_mode_b;
|
|
|
|
- req = (struct hclge_serdes_lb_cmd *)desc.data;
|
|
- hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_SERDES_LOOPBACK, false);
|
|
+ req = (struct hclge_common_lb_cmd *)desc.data;
|
|
+ hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_COMMON_LOOPBACK, false);
|
|
|
|
switch (loop_mode) {
|
|
case HNAE3_LOOP_SERIAL_SERDES:
|
|
@@ -6884,9 +6885,12 @@ static int hclge_cfg_serdes_loopback(struct hclge_dev *hdev, bool en,
|
|
case HNAE3_LOOP_PARALLEL_SERDES:
|
|
loop_mode_b = HCLGE_CMD_SERDES_PARALLEL_INNER_LOOP_B;
|
|
break;
|
|
+ case HNAE3_LOOP_PHY:
|
|
+ loop_mode_b = HCLGE_CMD_GE_PHY_INNER_LOOP_B;
|
|
+ break;
|
|
default:
|
|
dev_err(&hdev->pdev->dev,
|
|
- "unsupported serdes loopback mode %d\n", loop_mode);
|
|
+ "unsupported common loopback mode %d\n", loop_mode);
|
|
return -ENOTSUPP;
|
|
}
|
|
|
|
@@ -6900,45 +6904,39 @@ static int hclge_cfg_serdes_loopback(struct hclge_dev *hdev, bool en,
|
|
ret = hclge_cmd_send(&hdev->hw, &desc, 1);
|
|
if (ret) {
|
|
dev_err(&hdev->pdev->dev,
|
|
- "serdes loopback set fail, ret = %d\n", ret);
|
|
+ "common loopback set fail, ret = %d\n", ret);
|
|
return ret;
|
|
}
|
|
|
|
do {
|
|
- msleep(HCLGE_SERDES_RETRY_MS);
|
|
- hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_SERDES_LOOPBACK,
|
|
+ msleep(HCLGE_COMMON_LB_RETRY_MS);
|
|
+ hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_COMMON_LOOPBACK,
|
|
true);
|
|
ret = hclge_cmd_send(&hdev->hw, &desc, 1);
|
|
if (ret) {
|
|
dev_err(&hdev->pdev->dev,
|
|
- "serdes loopback get, ret = %d\n", ret);
|
|
+ "common loopback get, ret = %d\n", ret);
|
|
return ret;
|
|
}
|
|
- } while (++i < HCLGE_SERDES_RETRY_NUM &&
|
|
- !(req->result & HCLGE_CMD_SERDES_DONE_B));
|
|
+ } while (++i < HCLGE_COMMON_LB_RETRY_NUM &&
|
|
+ !(req->result & HCLGE_CMD_COMMON_LB_DONE_B));
|
|
|
|
- if (!(req->result & HCLGE_CMD_SERDES_DONE_B)) {
|
|
- dev_err(&hdev->pdev->dev, "serdes loopback set timeout\n");
|
|
+ if (!(req->result & HCLGE_CMD_COMMON_LB_DONE_B)) {
|
|
+ dev_err(&hdev->pdev->dev, "common loopback set timeout\n");
|
|
return -EBUSY;
|
|
- } else if (!(req->result & HCLGE_CMD_SERDES_SUCCESS_B)) {
|
|
- dev_err(&hdev->pdev->dev, "serdes loopback set failed in fw\n");
|
|
+ } else if (!(req->result & HCLGE_CMD_COMMON_LB_SUCCESS_B)) {
|
|
+ dev_err(&hdev->pdev->dev, "common loopback set failed in fw\n");
|
|
return -EIO;
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
-static int hclge_set_serdes_loopback(struct hclge_dev *hdev, bool en,
|
|
+static int hclge_set_common_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);
|
|
+ ret = hclge_cfg_common_loopback(hdev, en, loop_mode);
|
|
if (ret)
|
|
return ret;
|
|
|
|
@@ -7000,8 +6998,12 @@ static int hclge_set_phy_loopback(struct hclge_dev *hdev, bool en)
|
|
u8 duplex;
|
|
int ret;
|
|
|
|
- if (!phydev)
|
|
+ if (!phydev) {
|
|
+ if (hnae3_dev_phy_imp_supported(hdev))
|
|
+ return hclge_set_common_loopback(hdev, en,
|
|
+ HNAE3_LOOP_PHY);
|
|
return -ENOTSUPP;
|
|
+ }
|
|
|
|
duplex = en ? DUPLEX_FULL : hdev->hw.mac.duplex;
|
|
ret = hclge_cfg_mac_speed_dup_hw(hdev, hdev->hw.mac.speed, duplex);
|
|
@@ -7086,7 +7088,7 @@ static int hclge_set_loopback(struct hnae3_handle *handle,
|
|
break;
|
|
case HNAE3_LOOP_SERIAL_SERDES:
|
|
case HNAE3_LOOP_PARALLEL_SERDES:
|
|
- ret = hclge_set_serdes_loopback(hdev, en, loop_mode);
|
|
+ ret = hclge_set_common_loopback(hdev, en, loop_mode);
|
|
break;
|
|
case HNAE3_LOOP_PHY:
|
|
ret = hclge_set_phy_loopback(hdev, en);
|
|
@@ -7117,11 +7119,11 @@ static int hclge_set_default_loopback(struct hclge_dev *hdev)
|
|
if (ret)
|
|
return ret;
|
|
|
|
- ret = hclge_cfg_serdes_loopback(hdev, false, HNAE3_LOOP_SERIAL_SERDES);
|
|
+ ret = hclge_cfg_common_loopback(hdev, false, HNAE3_LOOP_SERIAL_SERDES);
|
|
if (ret)
|
|
return ret;
|
|
|
|
- return hclge_cfg_serdes_loopback(hdev, false,
|
|
+ return hclge_cfg_common_loopback(hdev, false,
|
|
HNAE3_LOOP_PARALLEL_SERDES);
|
|
}
|
|
|
|
--
|
|
2.34.1
|
|
|