diff options
author | Huazhong Tan <tanhuazhong@huawei.com> | 2018-11-09 22:07:50 +0800 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2018-11-09 16:47:35 -0800 |
commit | ef5f8e507ec9c226ef961c21ede99bab9fd313d4 (patch) | |
tree | b7860382019e88ce55aec8d494ec8352bba95678 /drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_cmd.c | |
parent | net: hns3: add reset handling for VF when doing Core/Global/IMP reset (diff) | |
download | linux-ef5f8e507ec9c226ef961c21ede99bab9fd313d4.tar.xz linux-ef5f8e507ec9c226ef961c21ede99bab9fd313d4.zip |
net: hns3: stop handling command queue while resetting VF
According to hardware's description, after the reset occurs, the driver
needs to re-initialize the command queue before sending and receiving
any commands. Therefore, the VF's driver needs to identify the command
queue needs to re-initialize with HCLGEVF_STATE_CMD_DISABLE, and does
not allow sending or receiving commands before the re-initialization.
Signed-off-by: Huazhong Tan <tanhuazhong@huawei.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_cmd.c')
-rw-r--r-- | drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_cmd.c | 13 |
1 files changed, 12 insertions, 1 deletions
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_cmd.c b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_cmd.c index b917acf71ee6..d5765c8cf3a3 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_cmd.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_cmd.c @@ -189,7 +189,8 @@ int hclgevf_cmd_send(struct hclgevf_hw *hw, struct hclgevf_desc *desc, int num) spin_lock_bh(&hw->cmq.csq.lock); - if (num > hclgevf_ring_space(&hw->cmq.csq)) { + if (num > hclgevf_ring_space(&hw->cmq.csq) || + test_bit(HCLGEVF_STATE_CMD_DISABLE, &hdev->state)) { spin_unlock_bh(&hw->cmq.csq.lock); return -EBUSY; } @@ -338,6 +339,16 @@ int hclgevf_cmd_init(struct hclgevf_dev *hdev) spin_unlock_bh(&hdev->hw.cmq.crq.lock); spin_unlock_bh(&hdev->hw.cmq.csq.lock); + clear_bit(HCLGEVF_STATE_CMD_DISABLE, &hdev->state); + + /* Check if there is new reset pending, because the higher level + * reset may happen when lower level reset is being processed. + */ + if (hclgevf_is_reset_pending(hdev)) { + set_bit(HCLGEVF_STATE_CMD_DISABLE, &hdev->state); + return -EBUSY; + } + /* get firmware version */ ret = hclgevf_cmd_query_firmware_version(&hdev->hw, &version); if (ret) { |