#define HNAE3_SUPPORT_VF             BIT(3)
 #define HNAE3_SUPPORT_SERDES_PARALLEL_LOOPBACK BIT(4)
 
+#define HNAE3_USER_UPE         BIT(0)  /* unicast promisc enabled by user */
+#define HNAE3_USER_MPE         BIT(1)  /* mulitcast promisc enabled by user */
+#define HNAE3_BPE              BIT(2)  /* broadcast promisc enable */
+#define HNAE3_OVERFLOW_UPE     BIT(3)  /* unicast mac vlan overflow */
+#define HNAE3_OVERFLOW_MPE     BIT(4)  /* multicast mac vlan overflow */
+#define HNAE3_VLAN_FLTR                BIT(5)  /* enable vlan filter */
+#define HNAE3_UPE              (HNAE3_USER_UPE | HNAE3_OVERFLOW_UPE)
+#define HNAE3_MPE              (HNAE3_USER_MPE | HNAE3_OVERFLOW_MPE)
+
 struct hnae3_handle {
        struct hnae3_client *client;
        struct pci_dev *pdev;
        };
 
        u32 numa_node_mask;     /* for multi-chip support */
+
+       u8 netdev_flags;
 };
 
 #define hnae3_set_field(origin, mask, shift, val) \
 
        return 0;
 }
 
+static u8 hns3_get_netdev_flags(struct net_device *netdev)
+{
+       u8 flags = 0;
+
+       if (netdev->flags & IFF_PROMISC) {
+               flags = HNAE3_USER_UPE | HNAE3_USER_MPE;
+       } else {
+               flags |= HNAE3_VLAN_FLTR;
+               if (netdev->flags & IFF_ALLMULTI)
+                       flags |= HNAE3_USER_MPE;
+       }
+
+       return flags;
+}
+
 static void hns3_nic_set_rx_mode(struct net_device *netdev)
 {
        struct hnae3_handle *h = hns3_get_handle(netdev);
+       u8 new_flags;
+       int ret;
 
-       if (h->ae_algo->ops->set_promisc_mode) {
-               if (netdev->flags & IFF_PROMISC)
-                       h->ae_algo->ops->set_promisc_mode(h, true, true);
-               else if (netdev->flags & IFF_ALLMULTI)
-                       h->ae_algo->ops->set_promisc_mode(h, false, true);
-               else
-                       h->ae_algo->ops->set_promisc_mode(h, false, false);
-       }
-       if (__dev_uc_sync(netdev, hns3_nic_uc_sync, hns3_nic_uc_unsync))
+       new_flags = hns3_get_netdev_flags(netdev);
+
+       ret = __dev_uc_sync(netdev, hns3_nic_uc_sync, hns3_nic_uc_unsync);
+       if (ret) {
                netdev_err(netdev, "sync uc address fail\n");
+               if (ret == -ENOSPC)
+                       new_flags |= HNAE3_OVERFLOW_UPE;
+       }
+
        if (netdev->flags & IFF_MULTICAST) {
-               if (__dev_mc_sync(netdev, hns3_nic_mc_sync, hns3_nic_mc_unsync))
+               ret = __dev_mc_sync(netdev, hns3_nic_mc_sync,
+                                   hns3_nic_mc_unsync);
+               if (ret) {
                        netdev_err(netdev, "sync mc address fail\n");
+                       if (ret == -ENOSPC)
+                               new_flags |= HNAE3_OVERFLOW_MPE;
+               }
+       }
+
+       hns3_update_promisc_mode(netdev, new_flags);
+       /* User mode Promisc mode enable and vlan filtering is disabled to
+        * let all packets in. MAC-VLAN Table overflow Promisc enabled and
+        * vlan fitering is enabled
+        */
+       hns3_enable_vlan_filter(netdev, new_flags & HNAE3_VLAN_FLTR);
+       h->netdev_flags = new_flags;
+}
+
+void hns3_update_promisc_mode(struct net_device *netdev, u8 promisc_flags)
+{
+       struct hns3_nic_priv *priv = netdev_priv(netdev);
+       struct hnae3_handle *h = priv->ae_handle;
+
+       if (h->ae_algo->ops->set_promisc_mode) {
+               h->ae_algo->ops->set_promisc_mode(h,
+                                                 promisc_flags & HNAE3_UPE,
+                                                 promisc_flags & HNAE3_MPE);
+       }
+}
+
+void hns3_enable_vlan_filter(struct net_device *netdev, bool enable)
+{
+       struct hns3_nic_priv *priv = netdev_priv(netdev);
+       struct hnae3_handle *h = priv->ae_handle;
+       bool last_state;
+
+       if (h->pdev->revision >= 0x21 && h->ae_algo->ops->enable_vlan_filter) {
+               last_state = h->netdev_flags & HNAE3_VLAN_FLTR ? true : false;
+               if (enable != last_state) {
+                       netdev_info(netdev,
+                                   "%s vlan filter\n",
+                                   enable ? "enable" : "disable");
+                       h->ae_algo->ops->enable_vlan_filter(h, enable);
+               }
        }
 }
 
 
                hclge_set_vlan_filter_ctrl(hdev, HCLGE_FILTER_TYPE_VF,
                                           HCLGE_FILTER_FE_EGRESS_V1_B, enable);
        }
+       if (enable)
+               handle->netdev_flags |= HNAE3_VLAN_FLTR;
+       else
+               handle->netdev_flags &= ~HNAE3_VLAN_FLTR;
 }
 
 static int hclge_set_vf_vlan_common(struct hclge_dev *hdev, int vfid,
 {
 #define HCLGE_DEF_VLAN_TYPE            0x8100
 
-       struct hnae3_handle *handle;
+       struct hnae3_handle *handle = &hdev->vport[0].nic;
        struct hclge_vport *vport;
        int ret;
        int i;
                        return ret;
        }
 
+       handle->netdev_flags |= HNAE3_VLAN_FLTR;
+
        hdev->vlan_type_cfg.rx_in_fst_vlan_type = HCLGE_DEF_VLAN_TYPE;
        hdev->vlan_type_cfg.rx_in_sec_vlan_type = HCLGE_DEF_VLAN_TYPE;
        hdev->vlan_type_cfg.rx_ot_fst_vlan_type = HCLGE_DEF_VLAN_TYPE;
                        return ret;
        }
 
-       handle = &hdev->vport[0].nic;
        return hclge_set_vlan_filter(handle, htons(ETH_P_8021Q), 0, false);
 }