net: hns3: Fix for loopback selftest failed problem

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: c39c4d98dc ("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>
This commit is contained in:
Yunsheng Lin 2018-09-03 11:21:50 +01:00 committed by David S. Miller
parent ce2c1d2ea6
commit 0f29fc23b2
2 changed files with 34 additions and 40 deletions

View file

@ -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;

View file

@ -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);
@ -3719,33 +3721,10 @@ 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_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;
switch (loop_mode) {
case HNAE3_MAC_INTER_LOOP_MAC:
ret = hclge_set_mac_loopback(hdev, en);
break;
case HNAE3_MAC_INTER_LOOP_SERDES:
ret = hclge_set_serdes_loopback(hdev, en);
break;
default:
ret = -ENOTSUPP;
dev_err(&hdev->pdev->dev,
"loop_mode %d is not supported\n", loop_mode);
break;
}
return ret;
}
static int hclge_tqp_enable(struct hclge_dev *hdev, int tqp_id,
int stream_id, bool enable)
{
@ -3766,6 +3745,36 @@ static int hclge_tqp_enable(struct hclge_dev *hdev, int tqp_id,
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 i, ret;
switch (loop_mode) {
case HNAE3_MAC_INTER_LOOP_MAC:
ret = hclge_set_mac_loopback(hdev, en);
break;
case HNAE3_MAC_INTER_LOOP_SERDES:
ret = hclge_set_serdes_loopback(hdev, en);
break;
default:
ret = -ENOTSUPP;
dev_err(&hdev->pdev->dev,
"loop_mode %d is not supported\n", loop_mode);
break;
}
for (i = 0; i < vport->alloc_tqps; i++) {
ret = hclge_tqp_enable(hdev, i, 0, en);
if (ret)
return ret;
}
return 0;
}
static void hclge_reset_tqp_stats(struct hnae3_handle *handle)
{
struct hclge_vport *vport = hclge_get_vport(handle);