vport->back = hdev;
                vport->vport_id = i;
                vport->mps = HCLGE_MAC_DEFAULT_FRAME;
+               vport->port_base_vlan_cfg.state = HNAE3_PORT_BASE_VLAN_DISABLE;
+               vport->rxvlan_cfg.rx_vlan_offload_en = true;
                INIT_LIST_HEAD(&vport->vlan_list);
                INIT_LIST_HEAD(&vport->uc_mac_list);
                INIT_LIST_HEAD(&vport->mc_mac_list);
        return status;
 }
 
+static int hclge_vlan_offload_cfg(struct hclge_vport *vport,
+                                 u16 port_base_vlan_state,
+                                 u16 vlan_tag)
+{
+       int ret;
+
+       if (port_base_vlan_state == HNAE3_PORT_BASE_VLAN_DISABLE) {
+               vport->txvlan_cfg.accept_tag1 = true;
+               vport->txvlan_cfg.insert_tag1_en = false;
+               vport->txvlan_cfg.default_tag1 = 0;
+       } else {
+               vport->txvlan_cfg.accept_tag1 = false;
+               vport->txvlan_cfg.insert_tag1_en = true;
+               vport->txvlan_cfg.default_tag1 = vlan_tag;
+       }
+
+       vport->txvlan_cfg.accept_untag1 = true;
+
+       /* accept_tag2 and accept_untag2 are not supported on
+        * pdev revision(0x20), new revision support them,
+        * this two fields can not be configured by user.
+        */
+       vport->txvlan_cfg.accept_tag2 = true;
+       vport->txvlan_cfg.accept_untag2 = true;
+       vport->txvlan_cfg.insert_tag2_en = false;
+       vport->txvlan_cfg.default_tag2 = 0;
+
+       if (port_base_vlan_state == HNAE3_PORT_BASE_VLAN_DISABLE) {
+               vport->rxvlan_cfg.strip_tag1_en = false;
+               vport->rxvlan_cfg.strip_tag2_en =
+                               vport->rxvlan_cfg.rx_vlan_offload_en;
+       } else {
+               vport->rxvlan_cfg.strip_tag1_en =
+                               vport->rxvlan_cfg.rx_vlan_offload_en;
+               vport->rxvlan_cfg.strip_tag2_en = true;
+       }
+       vport->rxvlan_cfg.vlan1_vlan_prionly = false;
+       vport->rxvlan_cfg.vlan2_vlan_prionly = false;
+
+       ret = hclge_set_vlan_tx_offload_cfg(vport);
+       if (ret)
+               return ret;
+
+       return hclge_set_vlan_rx_offload_cfg(vport);
+}
+
 static int hclge_set_vlan_protocol_type(struct hclge_dev *hdev)
 {
        struct hclge_rx_vlan_type_cfg_cmd *rx_req;
                return ret;
 
        for (i = 0; i < hdev->num_alloc_vport; i++) {
-               vport = &hdev->vport[i];
-               vport->txvlan_cfg.accept_tag1 = true;
-               vport->txvlan_cfg.accept_untag1 = true;
-
-               /* accept_tag2 and accept_untag2 are not supported on
-                * pdev revision(0x20), new revision support them. The
-                * value of this two fields will not return error when driver
-                * send command to fireware in revision(0x20).
-                * This two fields can not configured by user.
-                */
-               vport->txvlan_cfg.accept_tag2 = true;
-               vport->txvlan_cfg.accept_untag2 = true;
+               u16 vlan_tag;
 
-               vport->txvlan_cfg.insert_tag1_en = false;
-               vport->txvlan_cfg.insert_tag2_en = false;
-               vport->txvlan_cfg.default_tag1 = 0;
-               vport->txvlan_cfg.default_tag2 = 0;
-
-               ret = hclge_set_vlan_tx_offload_cfg(vport);
-               if (ret)
-                       return ret;
-
-               vport->rxvlan_cfg.strip_tag1_en = false;
-               vport->rxvlan_cfg.strip_tag2_en = true;
-               vport->rxvlan_cfg.vlan1_vlan_prionly = false;
-               vport->rxvlan_cfg.vlan2_vlan_prionly = false;
+               vport = &hdev->vport[i];
+               vlan_tag = vport->port_base_vlan_cfg.vlan_info.vlan_tag;
 
-               ret = hclge_set_vlan_rx_offload_cfg(vport);
+               ret = hclge_vlan_offload_cfg(vport,
+                                            vport->port_base_vlan_cfg.state,
+                                            vlan_tag);
                if (ret)
                        return ret;
        }
 
 
 /* VPort level vlan tag configuration for RX direction */
 struct hclge_rx_vtag_cfg {
-       bool strip_tag1_en;     /* Whether strip inner vlan tag */
-       bool strip_tag2_en;     /* Whether strip outer vlan tag */
-       bool vlan1_vlan_prionly;/* Inner VLAN Tag up to descriptor Enable */
-       bool vlan2_vlan_prionly;/* Outer VLAN Tag up to descriptor Enable */
+       u8 rx_vlan_offload_en;  /* Whether enable rx vlan offload */
+       u8 strip_tag1_en;       /* Whether strip inner vlan tag */
+       u8 strip_tag2_en;       /* Whether strip outer vlan tag */
+       u8 vlan1_vlan_prionly;  /* Inner VLAN Tag up to descriptor Enable */
+       u8 vlan2_vlan_prionly;  /* Outer VLAN Tag up to descriptor Enable */
 };
 
 struct hclge_rss_tuple_cfg {
        HCLGE_VPORT_STATE_MAX
 };
 
+struct hclge_vlan_info {
+       u16 vlan_proto; /* so far support 802.1Q only */
+       u16 qos;
+       u16 vlan_tag;
+};
+
+struct hclge_port_base_vlan_config {
+       u16 state;
+       struct hclge_vlan_info vlan_info;
+};
+
 struct hclge_vport {
        u16 alloc_tqps; /* Allocated Tx/Rx queues */
 
        u16 bw_limit;           /* VSI BW Limit (0 = disabled) */
        u8  dwrr;
 
+       struct hclge_port_base_vlan_config port_base_vlan_cfg;
        struct hclge_tx_vtag_cfg  txvlan_cfg;
        struct hclge_rx_vtag_cfg  rxvlan_cfg;