return status;
 }
 
-static int hclge_inform_reset_assert_to_vf(struct hclge_vport *vport)
+int hclge_inform_reset_assert_to_vf(struct hclge_vport *vport)
 {
        u8 msg_data[2];
        u8 dest_vfid;
        int ret;
 
        dev_warn(&hdev->pdev->dev, "PF received VF reset request from VF %d!",
-                mbx_req->mbx_src_vfid);
-
-       /* Acknowledge VF that PF is now about to assert the reset for the VF.
-        * On receiving this message VF will get into pending state and will
-        * start polling for the hardware reset completion status.
-        */
-       ret = hclge_inform_reset_assert_to_vf(vport);
-       if (ret) {
-               dev_err(&hdev->pdev->dev,
-                       "PF fail(%d) to inform VF(%d)of reset, reset failed!\n",
-                       ret, vport->vport_id);
-               return;
-       }
+                vport->vport_id);
 
-       dev_warn(&hdev->pdev->dev, "PF is now resetting VF %d.\n",
-                mbx_req->mbx_src_vfid);
-       /* reset this virtual function */
-       hclge_func_reset_cmd(hdev, mbx_req->mbx_src_vfid);
+       ret = hclge_func_reset_cmd(hdev, vport->vport_id);
+       hclge_gen_resp_to_vf(vport, mbx_req, ret, NULL, 0);
 }
 
 static bool hclge_cmd_crq_empty(struct hclge_hw *hw)
 
        struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle);
        int ret, vector_id;
 
+       if (test_bit(HCLGEVF_STATE_RST_HANDLING, &hdev->state))
+               return 0;
+
        vector_id = hclgevf_get_vector_index(hdev, vector);
        if (vector_id < 0) {
                dev_err(&handle->pdev->dev,
        return 0;
 }
 
+static int hclgevf_reset_prepare_wait(struct hclgevf_dev *hdev)
+{
+       int ret = 0;
+
+       switch (hdev->reset_type) {
+       case HNAE3_VF_FUNC_RESET:
+               ret = hclgevf_send_mbx_msg(hdev, HCLGE_MBX_RESET, 0, NULL,
+                                          0, true, NULL, sizeof(u8));
+               break;
+       default:
+               break;
+       }
+
+       dev_info(&hdev->pdev->dev, "prepare reset(%d) wait done, ret:%d\n",
+                hdev->reset_type, ret);
+
+       return ret;
+}
+
 static int hclgevf_reset(struct hclgevf_dev *hdev)
 {
+       struct hnae3_ae_dev *ae_dev = pci_get_drvdata(hdev->pdev);
        int ret;
 
+       /* Initialize ae_dev reset status as well, in case enet layer wants to
+        * know if device is undergoing reset
+        */
+       ae_dev->reset_type = hdev->reset_type;
        hdev->reset_count++;
        rtnl_lock();
 
 
        rtnl_unlock();
 
+       hclgevf_reset_prepare_wait(hdev);
+
        /* check if VF could successfully fetch the hardware reset completion
         * status from the hardware
         */
        return ret;
 }
 
-static int hclgevf_do_reset(struct hclgevf_dev *hdev)
-{
-       int status;
-       u8 respmsg;
-
-       status = hclgevf_send_mbx_msg(hdev, HCLGE_MBX_RESET, 0, NULL,
-                                     0, false, &respmsg, sizeof(u8));
-       if (status)
-               dev_err(&hdev->pdev->dev,
-                       "VF reset request to PF failed(=%d)\n", status);
-
-       return status;
-}
-
 static enum hnae3_reset_type hclgevf_get_reset_level(struct hclgevf_dev *hdev,
                                                     unsigned long *addr)
 {
        enum hnae3_reset_type rst_level = HNAE3_NONE_RESET;
 
-       if (test_bit(HNAE3_VF_RESET, addr)) {
-               rst_level = HNAE3_VF_RESET;
-               clear_bit(HNAE3_VF_RESET, addr);
+       /* return the highest priority reset level amongst all */
+       if (test_bit(HNAE3_VF_FULL_RESET, addr)) {
+               rst_level = HNAE3_VF_FULL_RESET;
+               clear_bit(HNAE3_VF_FULL_RESET, addr);
+               clear_bit(HNAE3_VF_FUNC_RESET, addr);
+       } else if (test_bit(HNAE3_VF_FUNC_RESET, addr)) {
+               rst_level = HNAE3_VF_FUNC_RESET;
+               clear_bit(HNAE3_VF_FUNC_RESET, addr);
        }
 
        return rst_level;
                        hclgevf_get_reset_level(hdev,
                                                &hdev->default_reset_request);
        else
-               hdev->reset_level = HNAE3_VF_RESET;
+               hdev->reset_level = HNAE3_VF_FUNC_RESET;
 
        /* reset of this VF requested */
        set_bit(HCLGEVF_RESET_REQUESTED, &hdev->reset_state);
                 */
                hdev->reset_attempts = 0;
 
-               ret = hclgevf_reset(hdev);
-               if (ret)
-                       dev_err(&hdev->pdev->dev, "VF stack reset failed.\n");
+               hdev->last_reset_time = jiffies;
+               while ((hdev->reset_type =
+                       hclgevf_get_reset_level(hdev, &hdev->reset_pending))
+                      != HNAE3_NONE_RESET) {
+                       ret = hclgevf_reset(hdev);
+                       if (ret)
+                               dev_err(&hdev->pdev->dev,
+                                       "VF stack reset failed %d.\n", ret);
+               }
        } else if (test_and_clear_bit(HCLGEVF_RESET_REQUESTED,
                                      &hdev->reset_state)) {
                /* we could be here when either of below happens:
                 */
                if (hdev->reset_attempts > 3) {
                        /* prepare for full reset of stack + pcie interface */
-                       hdev->reset_level = HNAE3_VF_FULL_RESET;
+                       set_bit(HNAE3_VF_FULL_RESET, &hdev->reset_pending);
 
                        /* "defer" schedule the reset task again */
                        set_bit(HCLGEVF_RESET_PENDING, &hdev->reset_state);
                } else {
                        hdev->reset_attempts++;
 
-                       /* request PF for resetting this VF via mailbox */
-                       ret = hclgevf_do_reset(hdev);
-                       if (ret)
-                               dev_warn(&hdev->pdev->dev,
-                                        "VF rst fail, stack will call\n");
+                       set_bit(hdev->reset_level, &hdev->reset_pending);
+                       set_bit(HCLGEVF_RESET_PENDING, &hdev->reset_state);
                }
+               hclgevf_reset_task_schedule(hdev);
        }
 
        clear_bit(HCLGEVF_STATE_RST_HANDLING, &hdev->state);
        }
 
        hclgevf_state_init(hdev);
-       hdev->reset_level = HNAE3_VF_RESET;
+       hdev->reset_level = HNAE3_VF_FUNC_RESET;
 
        ret = hclgevf_misc_irq_init(hdev);
        if (ret) {