ether_addr_copy(vfres->vsi_res[0].default_mac_addr,
                        vf->dflt_lan_addr.addr);
 
+       /* match guest capabilities */
+       vf->driver_caps = vfres->vf_cap_flags;
+
        set_bit(ICE_VF_STATE_ACTIVE, vf->vf_states);
 
 err:
        return ret;
 }
 
+/**
+ * ice_vf_vlan_offload_ena - determine if capabilities support VLAN offloads
+ * @caps: VF driver negotiated capabilities
+ *
+ * Return true if VIRTCHNL_VF_OFFLOAD_VLAN capability is set, else return false
+ */
+static bool ice_vf_vlan_offload_ena(u32 caps)
+{
+       return !!(caps & VIRTCHNL_VF_OFFLOAD_VLAN);
+}
+
 /**
  * ice_vc_process_vlan_msg
  * @vf: pointer to the VF info
                goto error_param;
        }
 
+       if (!ice_vf_vlan_offload_ena(vf->driver_caps)) {
+               v_ret = VIRTCHNL_STATUS_ERR_PARAM;
+               goto error_param;
+       }
+
        if (!ice_vc_isvalid_vsi_id(vf, vfl->vsi_id)) {
                v_ret = VIRTCHNL_STATUS_ERR_PARAM;
                goto error_param;
                goto error_param;
        }
 
+       if (!ice_vf_vlan_offload_ena(vf->driver_caps)) {
+               v_ret = VIRTCHNL_STATUS_ERR_PARAM;
+               goto error_param;
+       }
+
        vsi = pf->vsi[vf->lan_vsi_idx];
        if (ice_vsi_manage_vlan_stripping(vsi, true))
                v_ret = VIRTCHNL_STATUS_ERR_PARAM;
                goto error_param;
        }
 
+       if (!ice_vf_vlan_offload_ena(vf->driver_caps)) {
+               v_ret = VIRTCHNL_STATUS_ERR_PARAM;
+               goto error_param;
+       }
+
        vsi = pf->vsi[vf->lan_vsi_idx];
        if (!vsi) {
                v_ret = VIRTCHNL_STATUS_ERR_PARAM;