Skip to content

Commit

Permalink
net: hns3: Fix for loopback selftest failed problem
Browse files Browse the repository at this point in the history
Tqp and mac need to be enabled when doing loopback selftest,
ae_algo->ops->start/stop is used to do the job, there is a
time window between ae_algo->ops->start/stop and loopback setup,
which will cause selftest failed problem when there is frame
coming in during that time window.

This patch fixes it by enabling the tqp and mac during loopback
setup process.

Fixes: c39c4d9 ("net: hns3: Add mac loopback selftest support in hns3 driver")
Signed-off-by: Yunsheng Lin <linyunsheng@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>
  • Loading branch information
Yunsheng Lin authored and David S. Miller committed Sep 4, 2018
1 parent ce2c1d2 commit 0f29fc2
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 37 deletions.
17 changes: 1 addition & 16 deletions drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c
Original file line number Diff line number Diff line change
Expand Up @@ -100,41 +100,26 @@ static int hns3_lp_up(struct net_device *ndev, enum hnae3_loop loop_mode)
struct hnae3_handle *h = hns3_get_handle(ndev);
int ret;

if (!h->ae_algo->ops->start)
return -EOPNOTSUPP;

ret = hns3_nic_reset_all_ring(h);
if (ret)
return ret;

ret = h->ae_algo->ops->start(h);
if (ret) {
netdev_err(ndev,
"hns3_lb_up ae start return error: %d\n", ret);
return ret;
}

ret = hns3_lp_setup(ndev, loop_mode, true);
usleep_range(10000, 20000);

return ret;
return 0;
}

static int hns3_lp_down(struct net_device *ndev, enum hnae3_loop loop_mode)
{
struct hnae3_handle *h = hns3_get_handle(ndev);
int ret;

if (!h->ae_algo->ops->stop)
return -EOPNOTSUPP;

ret = hns3_lp_setup(ndev, loop_mode, false);
if (ret) {
netdev_err(ndev, "lb_setup return error: %d\n", ret);
return ret;
}

h->ae_algo->ops->stop(h);
usleep_range(10000, 20000);

return 0;
Expand Down
51 changes: 30 additions & 21 deletions drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -3659,6 +3659,8 @@ static int hclge_set_mac_loopback(struct hclge_dev *hdev, bool en)
/* 2 Then setup the loopback flag */
loop_en = le32_to_cpu(req->txrx_pad_fcs_loop_en);
hnae3_set_bit(loop_en, HCLGE_MAC_APP_LP_B, en ? 1 : 0);
hnae3_set_bit(loop_en, HCLGE_MAC_TX_EN_B, en ? 1 : 0);
hnae3_set_bit(loop_en, HCLGE_MAC_RX_EN_B, en ? 1 : 0);

req->txrx_pad_fcs_loop_en = cpu_to_le32(loop_en);

Expand Down Expand Up @@ -3719,15 +3721,36 @@ static int hclge_set_serdes_loopback(struct hclge_dev *hdev, bool en)
return -EIO;
}

hclge_cfg_mac_mode(hdev, en);
return 0;
}

static int hclge_tqp_enable(struct hclge_dev *hdev, int tqp_id,
int stream_id, bool enable)
{
struct hclge_desc desc;
struct hclge_cfg_com_tqp_queue_cmd *req =
(struct hclge_cfg_com_tqp_queue_cmd *)desc.data;
int ret;

hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_CFG_COM_TQP_QUEUE, false);
req->tqp_id = cpu_to_le16(tqp_id & HCLGE_RING_ID_MASK);
req->stream_id = cpu_to_le16(stream_id);
req->enable |= enable << HCLGE_TQP_ENABLE_B;

ret = hclge_cmd_send(&hdev->hw, &desc, 1);
if (ret)
dev_err(&hdev->pdev->dev,
"Tqp enable fail, status =%d.\n", ret);
return ret;
}

static int hclge_set_loopback(struct hnae3_handle *handle,
enum hnae3_loop loop_mode, bool en)
{
struct hclge_vport *vport = hclge_get_vport(handle);
struct hclge_dev *hdev = vport->back;
int ret;
int i, ret;

switch (loop_mode) {
case HNAE3_MAC_INTER_LOOP_MAC:
Expand All @@ -3743,27 +3766,13 @@ static int hclge_set_loopback(struct hnae3_handle *handle,
break;
}

return ret;
}

static int hclge_tqp_enable(struct hclge_dev *hdev, int tqp_id,
int stream_id, bool enable)
{
struct hclge_desc desc;
struct hclge_cfg_com_tqp_queue_cmd *req =
(struct hclge_cfg_com_tqp_queue_cmd *)desc.data;
int ret;

hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_CFG_COM_TQP_QUEUE, false);
req->tqp_id = cpu_to_le16(tqp_id & HCLGE_RING_ID_MASK);
req->stream_id = cpu_to_le16(stream_id);
req->enable |= enable << HCLGE_TQP_ENABLE_B;
for (i = 0; i < vport->alloc_tqps; i++) {
ret = hclge_tqp_enable(hdev, i, 0, en);
if (ret)
return ret;
}

ret = hclge_cmd_send(&hdev->hw, &desc, 1);
if (ret)
dev_err(&hdev->pdev->dev,
"Tqp enable fail, status =%d.\n", ret);
return ret;
return 0;
}

static void hclge_reset_tqp_stats(struct hnae3_handle *handle)
Expand Down

0 comments on commit 0f29fc2

Please sign in to comment.