mirror of
git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-09-18 22:14:16 +00:00
net: hns3: Add serdes parallel inner loopback support
This patch adds serdes parallel inner loopback support for self test. Signed-off-by: Fuyun Liang <liangfuyun1@huawei.com> Signed-off-by: Peng Li <lipeng321@huawei.com> Signed-off-by: Salil Mehta <salil.mehta@huawei.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
eb66d50352
commit
4dc13b9668
4 changed files with 57 additions and 20 deletions
|
@ -85,7 +85,8 @@ struct hnae3_queue {
|
||||||
/*hnae3 loop mode*/
|
/*hnae3 loop mode*/
|
||||||
enum hnae3_loop {
|
enum hnae3_loop {
|
||||||
HNAE3_LOOP_APP,
|
HNAE3_LOOP_APP,
|
||||||
HNAE3_LOOP_SERDES,
|
HNAE3_LOOP_SERIAL_SERDES,
|
||||||
|
HNAE3_LOOP_PARALLEL_SERDES,
|
||||||
HNAE3_LOOP_PHY,
|
HNAE3_LOOP_PHY,
|
||||||
HNAE3_LOOP_NONE,
|
HNAE3_LOOP_NONE,
|
||||||
};
|
};
|
||||||
|
@ -480,8 +481,9 @@ struct hnae3_unic_private_info {
|
||||||
|
|
||||||
#define HNAE3_SUPPORT_APP_LOOPBACK BIT(0)
|
#define HNAE3_SUPPORT_APP_LOOPBACK BIT(0)
|
||||||
#define HNAE3_SUPPORT_PHY_LOOPBACK BIT(1)
|
#define HNAE3_SUPPORT_PHY_LOOPBACK BIT(1)
|
||||||
#define HNAE3_SUPPORT_SERDES_LOOPBACK BIT(2)
|
#define HNAE3_SUPPORT_SERDES_SERIAL_LOOPBACK BIT(2)
|
||||||
#define HNAE3_SUPPORT_VF BIT(3)
|
#define HNAE3_SUPPORT_VF BIT(3)
|
||||||
|
#define HNAE3_SUPPORT_SERDES_PARALLEL_LOOPBACK BIT(4)
|
||||||
|
|
||||||
struct hnae3_handle {
|
struct hnae3_handle {
|
||||||
struct hnae3_client *client;
|
struct hnae3_client *client;
|
||||||
|
|
|
@ -53,7 +53,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_TYPE_NUM 2
|
#define HNS3_SELF_TEST_TPYE_NUM 3
|
||||||
#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
|
||||||
|
@ -78,7 +78,8 @@ static int hns3_lp_setup(struct net_device *ndev, enum hnae3_loop loop, bool en)
|
||||||
return -EOPNOTSUPP;
|
return -EOPNOTSUPP;
|
||||||
|
|
||||||
switch (loop) {
|
switch (loop) {
|
||||||
case HNAE3_LOOP_SERDES:
|
case HNAE3_LOOP_SERIAL_SERDES:
|
||||||
|
case HNAE3_LOOP_PARALLEL_SERDES:
|
||||||
case HNAE3_LOOP_APP:
|
case HNAE3_LOOP_APP:
|
||||||
ret = h->ae_algo->ops->set_loopback(h, loop, en);
|
ret = h->ae_algo->ops->set_loopback(h, loop, en);
|
||||||
break;
|
break;
|
||||||
|
@ -290,9 +291,14 @@ static void hns3_self_test(struct net_device *ndev,
|
||||||
st_param[HNAE3_LOOP_APP][1] =
|
st_param[HNAE3_LOOP_APP][1] =
|
||||||
h->flags & HNAE3_SUPPORT_APP_LOOPBACK;
|
h->flags & HNAE3_SUPPORT_APP_LOOPBACK;
|
||||||
|
|
||||||
st_param[HNAE3_LOOP_SERDES][0] = HNAE3_LOOP_SERDES;
|
st_param[HNAE3_LOOP_SERIAL_SERDES][0] = HNAE3_LOOP_SERIAL_SERDES;
|
||||||
st_param[HNAE3_LOOP_SERDES][1] =
|
st_param[HNAE3_LOOP_SERIAL_SERDES][1] =
|
||||||
h->flags & HNAE3_SUPPORT_SERDES_LOOPBACK;
|
h->flags & HNAE3_SUPPORT_SERDES_SERIAL_LOOPBACK;
|
||||||
|
|
||||||
|
st_param[HNAE3_LOOP_PARALLEL_SERDES][0] =
|
||||||
|
HNAE3_LOOP_PARALLEL_SERDES;
|
||||||
|
st_param[HNAE3_LOOP_PARALLEL_SERDES][1] =
|
||||||
|
h->flags & HNAE3_SUPPORT_SERDES_PARALLEL_LOOPBACK;
|
||||||
|
|
||||||
if (if_running)
|
if (if_running)
|
||||||
ndev->netdev_ops->ndo_stop(ndev);
|
ndev->netdev_ops->ndo_stop(ndev);
|
||||||
|
|
|
@ -778,6 +778,7 @@ struct hclge_reset_cmd {
|
||||||
};
|
};
|
||||||
|
|
||||||
#define HCLGE_CMD_SERDES_SERIAL_INNER_LOOP_B BIT(0)
|
#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_DONE_B BIT(0)
|
||||||
#define HCLGE_CMD_SERDES_SUCCESS_B BIT(1)
|
#define HCLGE_CMD_SERDES_SUCCESS_B BIT(1)
|
||||||
struct hclge_serdes_lb_cmd {
|
struct hclge_serdes_lb_cmd {
|
||||||
|
|
|
@ -50,7 +50,8 @@ MODULE_DEVICE_TABLE(pci, ae_algo_pci_tbl);
|
||||||
|
|
||||||
static const char hns3_nic_test_strs[][ETH_GSTRING_LEN] = {
|
static const char hns3_nic_test_strs[][ETH_GSTRING_LEN] = {
|
||||||
"App Loopback test",
|
"App Loopback test",
|
||||||
"Serdes Loopback test",
|
"Serdes serial Loopback test",
|
||||||
|
"Serdes parallel Loopback test",
|
||||||
"Phy Loopback test"
|
"Phy Loopback test"
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -475,7 +476,10 @@ static void hclge_update_stats(struct hnae3_handle *handle,
|
||||||
|
|
||||||
static int hclge_get_sset_count(struct hnae3_handle *handle, int stringset)
|
static int hclge_get_sset_count(struct hnae3_handle *handle, int stringset)
|
||||||
{
|
{
|
||||||
#define HCLGE_LOOPBACK_TEST_FLAGS 0x7
|
#define HCLGE_LOOPBACK_TEST_FLAGS (HNAE3_SUPPORT_APP_LOOPBACK |\
|
||||||
|
HNAE3_SUPPORT_PHY_LOOPBACK |\
|
||||||
|
HNAE3_SUPPORT_SERDES_SERIAL_LOOPBACK |\
|
||||||
|
HNAE3_SUPPORT_SERDES_PARALLEL_LOOPBACK)
|
||||||
|
|
||||||
struct hclge_vport *vport = hclge_get_vport(handle);
|
struct hclge_vport *vport = hclge_get_vport(handle);
|
||||||
struct hclge_dev *hdev = vport->back;
|
struct hclge_dev *hdev = vport->back;
|
||||||
|
@ -489,15 +493,17 @@ static int hclge_get_sset_count(struct hnae3_handle *handle, int stringset)
|
||||||
if (stringset == ETH_SS_TEST) {
|
if (stringset == ETH_SS_TEST) {
|
||||||
/* clear loopback bit flags at first */
|
/* clear loopback bit flags at first */
|
||||||
handle->flags = (handle->flags & (~HCLGE_LOOPBACK_TEST_FLAGS));
|
handle->flags = (handle->flags & (~HCLGE_LOOPBACK_TEST_FLAGS));
|
||||||
if (hdev->hw.mac.speed == HCLGE_MAC_SPEED_10M ||
|
if (hdev->pdev->revision >= HNAE3_REVISION_ID_21 ||
|
||||||
|
hdev->hw.mac.speed == HCLGE_MAC_SPEED_10M ||
|
||||||
hdev->hw.mac.speed == HCLGE_MAC_SPEED_100M ||
|
hdev->hw.mac.speed == HCLGE_MAC_SPEED_100M ||
|
||||||
hdev->hw.mac.speed == HCLGE_MAC_SPEED_1G) {
|
hdev->hw.mac.speed == HCLGE_MAC_SPEED_1G) {
|
||||||
count += 1;
|
count += 1;
|
||||||
handle->flags |= HNAE3_SUPPORT_APP_LOOPBACK;
|
handle->flags |= HNAE3_SUPPORT_APP_LOOPBACK;
|
||||||
}
|
}
|
||||||
|
|
||||||
count++;
|
count += 2;
|
||||||
handle->flags |= HNAE3_SUPPORT_SERDES_LOOPBACK;
|
handle->flags |= HNAE3_SUPPORT_SERDES_SERIAL_LOOPBACK;
|
||||||
|
handle->flags |= HNAE3_SUPPORT_SERDES_PARALLEL_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);
|
||||||
|
@ -527,9 +533,15 @@ static void hclge_get_strings(struct hnae3_handle *handle,
|
||||||
ETH_GSTRING_LEN);
|
ETH_GSTRING_LEN);
|
||||||
p += ETH_GSTRING_LEN;
|
p += ETH_GSTRING_LEN;
|
||||||
}
|
}
|
||||||
if (handle->flags & HNAE3_SUPPORT_SERDES_LOOPBACK) {
|
if (handle->flags & HNAE3_SUPPORT_SERDES_SERIAL_LOOPBACK) {
|
||||||
memcpy(p,
|
memcpy(p,
|
||||||
hns3_nic_test_strs[HNAE3_LOOP_SERDES],
|
hns3_nic_test_strs[HNAE3_LOOP_SERIAL_SERDES],
|
||||||
|
ETH_GSTRING_LEN);
|
||||||
|
p += ETH_GSTRING_LEN;
|
||||||
|
}
|
||||||
|
if (handle->flags & HNAE3_SUPPORT_SERDES_PARALLEL_LOOPBACK) {
|
||||||
|
memcpy(p,
|
||||||
|
hns3_nic_test_strs[HNAE3_LOOP_PARALLEL_SERDES],
|
||||||
ETH_GSTRING_LEN);
|
ETH_GSTRING_LEN);
|
||||||
p += ETH_GSTRING_LEN;
|
p += ETH_GSTRING_LEN;
|
||||||
}
|
}
|
||||||
|
@ -3381,22 +3393,37 @@ static int hclge_set_app_loopback(struct hclge_dev *hdev, bool en)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int hclge_set_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)
|
||||||
{
|
{
|
||||||
#define HCLGE_SERDES_RETRY_MS 10
|
#define HCLGE_SERDES_RETRY_MS 10
|
||||||
#define HCLGE_SERDES_RETRY_NUM 100
|
#define HCLGE_SERDES_RETRY_NUM 100
|
||||||
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;
|
||||||
|
u8 loop_mode_b;
|
||||||
|
|
||||||
req = (struct hclge_serdes_lb_cmd *)desc.data;
|
req = (struct hclge_serdes_lb_cmd *)desc.data;
|
||||||
hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_SERDES_LOOPBACK, false);
|
hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_SERDES_LOOPBACK, false);
|
||||||
|
|
||||||
|
switch (loop_mode) {
|
||||||
|
case HNAE3_LOOP_SERIAL_SERDES:
|
||||||
|
loop_mode_b = HCLGE_CMD_SERDES_SERIAL_INNER_LOOP_B;
|
||||||
|
break;
|
||||||
|
case HNAE3_LOOP_PARALLEL_SERDES:
|
||||||
|
loop_mode_b = HCLGE_CMD_SERDES_PARALLEL_INNER_LOOP_B;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
dev_err(&hdev->pdev->dev,
|
||||||
|
"unsupported serdes loopback mode %d\n", loop_mode);
|
||||||
|
return -ENOTSUPP;
|
||||||
|
}
|
||||||
|
|
||||||
if (en) {
|
if (en) {
|
||||||
req->enable = HCLGE_CMD_SERDES_SERIAL_INNER_LOOP_B;
|
req->enable = loop_mode_b;
|
||||||
req->mask = HCLGE_CMD_SERDES_SERIAL_INNER_LOOP_B;
|
req->mask = loop_mode_b;
|
||||||
} else {
|
} else {
|
||||||
req->mask = HCLGE_CMD_SERDES_SERIAL_INNER_LOOP_B;
|
req->mask = loop_mode_b;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = hclge_cmd_send(&hdev->hw, &desc, 1);
|
ret = hclge_cmd_send(&hdev->hw, &desc, 1);
|
||||||
|
@ -3462,8 +3489,9 @@ static int hclge_set_loopback(struct hnae3_handle *handle,
|
||||||
case HNAE3_LOOP_APP:
|
case HNAE3_LOOP_APP:
|
||||||
ret = hclge_set_app_loopback(hdev, en);
|
ret = hclge_set_app_loopback(hdev, en);
|
||||||
break;
|
break;
|
||||||
case HNAE3_LOOP_SERDES:
|
case HNAE3_LOOP_SERIAL_SERDES:
|
||||||
ret = hclge_set_serdes_loopback(hdev, en);
|
case HNAE3_LOOP_PARALLEL_SERDES:
|
||||||
|
ret = hclge_set_serdes_loopback(hdev, en, loop_mode);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
ret = -ENOTSUPP;
|
ret = -ENOTSUPP;
|
||||||
|
|
Loading…
Add table
Reference in a new issue