return ret;
                }
 
-               if (!reset || !test_bit(HCLGE_VPORT_STATE_ALIVE, &vport->state))
+               if (!reset ||
+                   !test_bit(HCLGE_VPORT_STATE_INITED, &vport->state))
                        continue;
 
+               if (!test_bit(HCLGE_VPORT_STATE_ALIVE, &vport->state) &&
+                   hdev->reset_type == HNAE3_FUNC_RESET) {
+                       set_bit(HCLGE_VPORT_NEED_NOTIFY_RESET,
+                               &vport->need_notify);
+                       continue;
+               }
+
                /* Inform VF to process the reset.
                 * hclge_inform_reset_assert_to_vf may fail if VF
                 * driver is not loaded.
 
 static void hclge_update_vport_alive(struct hclge_dev *hdev)
 {
+#define HCLGE_ALIVE_SECONDS_NORMAL             8
+
+       unsigned long alive_time = HCLGE_ALIVE_SECONDS_NORMAL * HZ;
        int i;
 
        /* start from vport 1 for PF is always alive */
        for (i = 1; i < hdev->num_alloc_vport; i++) {
                struct hclge_vport *vport = &hdev->vport[i];
 
-               if (time_after(jiffies, vport->last_active_jiffies + 8 * HZ))
+               if (!test_bit(HCLGE_VPORT_STATE_INITED, &vport->state) ||
+                   !test_bit(HCLGE_VPORT_STATE_ALIVE, &vport->state))
+                       continue;
+               if (time_after(jiffies, vport->last_active_jiffies +
+                              alive_time)) {
                        clear_bit(HCLGE_VPORT_STATE_ALIVE, &vport->state);
-
-               /* If vf is not alive, set to default value */
-               if (!test_bit(HCLGE_VPORT_STATE_ALIVE, &vport->state))
-                       vport->mps = HCLGE_MAC_DEFAULT_FRAME;
+                       dev_warn(&hdev->pdev->dev,
+                                "VF %u heartbeat timeout\n",
+                                i - HCLGE_VF_VPORT_START_NUM);
+               }
        }
 }
 
 {
        struct hclge_dev *hdev = vport->back;
 
+       set_bit(HCLGE_VPORT_STATE_INITED, &vport->state);
        set_bit(HCLGE_VPORT_STATE_ALIVE, &vport->state);
        set_bit(HCLGE_VPORT_STATE_PROMISC_CHANGE, &vport->state);
        vport->last_active_jiffies = jiffies;
+       vport->need_notify = 0;
 
        if (test_bit(vport->vport_id, hdev->vport_config_block)) {
                if (vport->vport_id) {
 
 void hclge_vport_stop(struct hclge_vport *vport)
 {
+       clear_bit(HCLGE_VPORT_STATE_INITED, &vport->state);
        clear_bit(HCLGE_VPORT_STATE_ALIVE, &vport->state);
+       vport->need_notify = 0;
 }
 
 static int hclge_client_start(struct hnae3_handle *handle)
                return 0;
        }
 
-       dev_info(&hdev->pdev->dev, "MAC of VF %d has been set to %s\n",
+       dev_info(&hdev->pdev->dev,
+                "MAC of VF %d has been set to %s, will be active after VF reset\n",
                 vf, format_mac_addr);
        return 0;
 }
         * for DEVICE_VERSION_V3, vf doesn't need to know about the port based
         * VLAN state.
         */
-       if (ae_dev->dev_version < HNAE3_DEVICE_VERSION_V3 &&
-           test_bit(HCLGE_VPORT_STATE_ALIVE, &vport->state))
-               (void)hclge_push_vf_port_base_vlan_info(&hdev->vport[0],
-                                                       vport->vport_id,
-                                                       state, &vlan_info);
-
+       if (ae_dev->dev_version < HNAE3_DEVICE_VERSION_V3) {
+               if (test_bit(HCLGE_VPORT_STATE_ALIVE, &vport->state))
+                       (void)hclge_push_vf_port_base_vlan_info(&hdev->vport[0],
+                                                               vport->vport_id,
+                                                               state,
+                                                               &vlan_info);
+               else
+                       set_bit(HCLGE_VPORT_NEED_NOTIFY_VF_VLAN,
+                               &vport->need_notify);
+       }
        return 0;
 }
 
        int i;
 
        for (i = 0; i < hdev->num_alloc_vport; i++) {
-               hclge_vport_stop(vport);
+               clear_bit(HCLGE_VPORT_STATE_ALIVE, &vport->state);
                vport++;
        }
 }
        struct hclge_vlan_info vlan_info;
        int ret;
 
+       clear_bit(HCLGE_VPORT_STATE_INITED, &vport->state);
+       clear_bit(HCLGE_VPORT_STATE_ALIVE, &vport->state);
+       vport->need_notify = 0;
+       vport->mps = 0;
+
        /* after disable sriov, clean VF rate configured by PF */
        ret = hclge_tm_qs_shaper_cfg(vport, 0);
        if (ret)
 
        HCLGE_VPORT_STATE_MAC_TBL_CHANGE,
        HCLGE_VPORT_STATE_PROMISC_CHANGE,
        HCLGE_VPORT_STATE_VLAN_FLTR_CHANGE,
+       HCLGE_VPORT_STATE_INITED,
        HCLGE_VPORT_STATE_MAX
 };
 
+enum HCLGE_VPORT_NEED_NOTIFY {
+       HCLGE_VPORT_NEED_NOTIFY_RESET,
+       HCLGE_VPORT_NEED_NOTIFY_VF_VLAN,
+};
+
 struct hclge_vlan_info {
        u16 vlan_proto; /* so far support 802.1Q only */
        u16 qos;
        struct hnae3_handle roce;
 
        unsigned long state;
+       unsigned long need_notify;
        unsigned long last_active_jiffies;
        u32 mps; /* Max packet size */
        struct hclge_vf_info vf_info;
 
        return status;
 }
 
+static int hclge_inform_vf_reset(struct hclge_vport *vport, u16 reset_type)
+{
+       __le16 msg_data;
+       u8 dest_vfid;
+
+       dest_vfid = (u8)vport->vport_id;
+       msg_data = cpu_to_le16(reset_type);
+
+       /* send this requested info to VF */
+       return hclge_send_mbx_msg(vport, (u8 *)&msg_data, sizeof(msg_data),
+                                 HCLGE_MBX_ASSERTING_RESET, dest_vfid);
+}
+
 int hclge_inform_reset_assert_to_vf(struct hclge_vport *vport)
 {
        struct hclge_dev *hdev = vport->back;
-       __le16 msg_data;
        u16 reset_type;
-       u8 dest_vfid;
 
        BUILD_BUG_ON(HNAE3_MAX_RESET > U16_MAX);
 
-       dest_vfid = (u8)vport->vport_id;
-
        if (hdev->reset_type == HNAE3_FUNC_RESET)
                reset_type = HNAE3_VF_PF_FUNC_RESET;
        else if (hdev->reset_type == HNAE3_FLR_RESET)
        else
                reset_type = HNAE3_VF_FUNC_RESET;
 
-       msg_data = cpu_to_le16(reset_type);
-
-       /* send this requested info to VF */
-       return hclge_send_mbx_msg(vport, (u8 *)&msg_data, sizeof(msg_data),
-                                 HCLGE_MBX_ASSERTING_RESET, dest_vfid);
+       return hclge_inform_vf_reset(vport, reset_type);
 }
 
 static void hclge_free_vector_ring_chain(struct hnae3_ring_chain_node *head)
        return hclge_func_reset_cmd(hdev, vport->vport_id);
 }
 
+static void hclge_notify_vf_config(struct hclge_vport *vport)
+{
+       struct hclge_dev *hdev = vport->back;
+       struct hnae3_ae_dev *ae_dev = pci_get_drvdata(hdev->pdev);
+       struct hclge_port_base_vlan_config *vlan_cfg;
+       int ret;
+
+       hclge_push_vf_link_status(vport);
+       if (test_bit(HCLGE_VPORT_NEED_NOTIFY_RESET, &vport->need_notify)) {
+               ret = hclge_inform_vf_reset(vport, HNAE3_VF_PF_FUNC_RESET);
+               if (ret) {
+                       dev_err(&hdev->pdev->dev,
+                               "failed to inform VF %u reset!",
+                               vport->vport_id - HCLGE_VF_VPORT_START_NUM);
+                       return;
+               }
+               vport->need_notify = 0;
+               return;
+       }
+
+       if (ae_dev->dev_version < HNAE3_DEVICE_VERSION_V3 &&
+           test_bit(HCLGE_VPORT_NEED_NOTIFY_VF_VLAN, &vport->need_notify)) {
+               vlan_cfg = &vport->port_base_vlan_cfg;
+               ret = hclge_push_vf_port_base_vlan_info(&hdev->vport[0],
+                                                       vport->vport_id,
+                                                       vlan_cfg->state,
+                                                       &vlan_cfg->vlan_info);
+               if (ret) {
+                       dev_err(&hdev->pdev->dev,
+                               "failed to inform VF %u port base vlan!",
+                               vport->vport_id - HCLGE_VF_VPORT_START_NUM);
+                       return;
+               }
+               clear_bit(HCLGE_VPORT_NEED_NOTIFY_VF_VLAN, &vport->need_notify);
+       }
+}
+
 static void hclge_vf_keep_alive(struct hclge_vport *vport)
 {
+       struct hclge_dev *hdev = vport->back;
+
        vport->last_active_jiffies = jiffies;
+
+       if (test_bit(HCLGE_VPORT_STATE_INITED, &vport->state) &&
+           !test_bit(HCLGE_VPORT_STATE_ALIVE, &vport->state)) {
+               set_bit(HCLGE_VPORT_STATE_ALIVE, &vport->state);
+               dev_info(&hdev->pdev->dev, "VF %u is alive!",
+                        vport->vport_id - HCLGE_VF_VPORT_START_NUM);
+               hclge_notify_vf_config(vport);
+       }
 }
 
 static int hclge_set_vf_mtu(struct hclge_vport *vport,
        hclge_rm_vport_all_mac_table(param->vport, true,
                                     HCLGE_MAC_ADDR_MC);
        hclge_rm_vport_all_vlan_table(param->vport, true);
+       param->vport->mps = 0;
        return 0;
 }