diff options
author | Huazhong Tan <tanhuazhong@huawei.com> | 2020-09-29 12:32:02 +0300 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2020-09-29 23:14:24 +0300 |
commit | fe735c84be2937b53f9011f0954c22f37b16d7de (patch) | |
tree | 7060bbe4e114e5b3fa6e1597dc3a40591a212d32 /drivers/net | |
parent | 0692cfe94a760d17793d2e1c8ca2fe10118e55de (diff) | |
download | linux-fe735c84be2937b53f9011f0954c22f37b16d7de.tar.xz |
net: hns3: Add RoCE VF reset support
Add RoCE VF client reset support by notifying the RoCE VF client
when hns3 VF is resetting and adding a interface to query whether
CMDQ is ready to work.
Signed-off-by: Huazhong Tan <tanhuazhong@huawei.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net')
-rw-r--r-- | drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c | 50 | ||||
-rw-r--r-- | drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.h | 1 |
2 files changed, 51 insertions, 0 deletions
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c index 8c8e666b6152..50c84c5e65d2 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c @@ -1702,6 +1702,26 @@ static int hclgevf_notify_client(struct hclgevf_dev *hdev, return ret; } +static int hclgevf_notify_roce_client(struct hclgevf_dev *hdev, + enum hnae3_reset_notify_type type) +{ + struct hnae3_client *client = hdev->roce_client; + struct hnae3_handle *handle = &hdev->roce; + int ret; + + if (!test_bit(HCLGEVF_STATE_ROCE_REGISTERED, &hdev->state) || !client) + return 0; + + if (!client->ops->reset_notify) + return -EOPNOTSUPP; + + ret = client->ops->reset_notify(handle, type); + if (ret) + dev_err(&hdev->pdev->dev, "notify roce client failed %d(%d)", + type, ret); + return ret; +} + static int hclgevf_reset_wait(struct hclgevf_dev *hdev) { #define HCLGEVF_RESET_WAIT_US 20000 @@ -1865,6 +1885,11 @@ static int hclgevf_reset_prepare(struct hclgevf_dev *hdev) hdev->rst_stats.rst_cnt++; + /* perform reset of the stack & ae device for a client */ + ret = hclgevf_notify_roce_client(hdev, HNAE3_DOWN_CLIENT); + if (ret) + return ret; + rtnl_lock(); /* bring down the nic to stop any ongoing TX/RX */ ret = hclgevf_notify_client(hdev, HNAE3_DOWN_CLIENT); @@ -1880,6 +1905,9 @@ static int hclgevf_reset_rebuild(struct hclgevf_dev *hdev) int ret; hdev->rst_stats.hw_rst_done_cnt++; + ret = hclgevf_notify_roce_client(hdev, HNAE3_UNINIT_CLIENT); + if (ret) + return ret; rtnl_lock(); /* now, re-initialize the nic client and ae device */ @@ -1890,6 +1918,18 @@ static int hclgevf_reset_rebuild(struct hclgevf_dev *hdev) return ret; } + ret = hclgevf_notify_roce_client(hdev, HNAE3_INIT_CLIENT); + /* ignore RoCE notify error if it fails HCLGEVF_RESET_MAX_FAIL_CNT - 1 + * times + */ + if (ret && + hdev->rst_stats.rst_fail_cnt < HCLGEVF_RESET_MAX_FAIL_CNT - 1) + return ret; + + ret = hclgevf_notify_roce_client(hdev, HNAE3_UP_CLIENT); + if (ret) + return ret; + hdev->last_reset_time = jiffies; hdev->rst_stats.rst_done_cnt++; hdev->rst_stats.rst_fail_cnt = 0; @@ -2757,6 +2797,7 @@ static int hclgevf_init_roce_client_instance(struct hnae3_ae_dev *ae_dev, if (ret) return ret; + set_bit(HCLGEVF_STATE_ROCE_REGISTERED, &hdev->state); hnae3_set_client_init_flag(client, ae_dev, 1); return 0; @@ -2817,6 +2858,7 @@ static void hclgevf_uninit_client_instance(struct hnae3_client *client, /* un-init roce, if it exists */ if (hdev->roce_client) { + clear_bit(HCLGEVF_STATE_ROCE_REGISTERED, &hdev->state); hdev->roce_client->ops->uninit_instance(&hdev->roce, 0); hdev->roce_client = NULL; hdev->roce.client = NULL; @@ -3419,6 +3461,13 @@ static bool hclgevf_get_hw_reset_stat(struct hnae3_handle *handle) return !!hclgevf_read_dev(&hdev->hw, HCLGEVF_RST_ING); } +static bool hclgevf_get_cmdq_stat(struct hnae3_handle *handle) +{ + struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle); + + return test_bit(HCLGEVF_STATE_CMD_DISABLE, &hdev->state); +} + static bool hclgevf_ae_dev_resetting(struct hnae3_handle *handle) { struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle); @@ -3604,6 +3653,7 @@ static const struct hnae3_ae_ops hclgevf_ops = { .get_link_mode = hclgevf_get_link_mode, .set_promisc_mode = hclgevf_set_promisc_mode, .request_update_promisc_mode = hclgevf_request_update_promisc_mode, + .get_cmdq_stat = hclgevf_get_cmdq_stat, }; static struct hnae3_ae_algo ae_algovf = { diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.h b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.h index c1fac8920ae3..c5bcc3894fd5 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.h +++ b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.h @@ -139,6 +139,7 @@ enum hclgevf_states { HCLGEVF_STATE_IRQ_INITED, HCLGEVF_STATE_REMOVING, HCLGEVF_STATE_NIC_REGISTERED, + HCLGEVF_STATE_ROCE_REGISTERED, /* task states */ HCLGEVF_STATE_RST_SERVICE_SCHED, HCLGEVF_STATE_RST_HANDLING, |