[v6,12/12] net/ice: support DCF new VLAN capabilities

Message ID 20220427181301.1414196-13-kevinx.liu@intel.com (mailing list archive)
State Superseded, archived
Delegated to: Qi Zhang
Headers
Series complete common VF features for DCF |

Checks

Context Check Description
ci/checkpatch success coding style OK
ci/Intel-compilation success Compilation OK
ci/intel-Testing success Testing PASS

Commit Message

Kevin Liu April 27, 2022, 6:13 p.m. UTC
  From: Alvin Zhang <alvinx.zhang@intel.com>

The new VLAN virtchnl opcodes introduce new capabilities like VLAN
filtering, stripping and insertion.

The DCF needs to query the VLAN capabilities based on current device
configuration firstly.

DCF is able to configure inner VLAN filter when port VLAN is enabled
base on negotiation; and DCF is able to configure outer VLAN (0x8100)
if port VLAN is disabled to be compatible with legacy mode.

When port VLAN is updated by DCF, the DCF needs to reset to query the
new VLAN capabilities.

Signed-off-by: Alvin Zhang <alvinx.zhang@intel.com>
Signed-off-by: Kevin Liu <kevinx.liu@intel.com>
---
 doc/guides/rel_notes/release_22_07.rst |   1 +
 drivers/net/ice/ice_dcf.c              |  27 ++++
 drivers/net/ice/ice_dcf.h              |   1 +
 drivers/net/ice/ice_dcf_ethdev.c       | 171 ++++++++++++++++++++++---
 4 files changed, 183 insertions(+), 17 deletions(-)
  

Comments

Qi Zhang April 27, 2022, 10:46 a.m. UTC | #1
> -----Original Message-----
> From: Liu, KevinX <kevinx.liu@intel.com>
> Sent: Thursday, April 28, 2022 2:13 AM
> To: dev@dpdk.org
> Cc: Yang, Qiming <qiming.yang@intel.com>; Zhang, Qi Z
> <qi.z.zhang@intel.com>; Yang, SteveX <stevex.yang@intel.com>; Alvin Zhang
> <alvinx.zhang@intel.com>; Liu, KevinX <kevinx.liu@intel.com>
> Subject: [PATCH v6 12/12] net/ice: support DCF new VLAN capabilities
> 
> From: Alvin Zhang <alvinx.zhang@intel.com>
> 
> The new VLAN virtchnl opcodes introduce new capabilities like VLAN filtering,
> stripping and insertion.
> 
> The DCF needs to query the VLAN capabilities based on current device
> configuration firstly.
> 
> DCF is able to configure inner VLAN filter when port VLAN is enabled base on
> negotiation; and DCF is able to configure outer VLAN (0x8100) if port VLAN is
> disabled to be compatible with legacy mode.
> 
> When port VLAN is updated by DCF, the DCF needs to reset to query the new
> VLAN capabilities.
> 
> Signed-off-by: Alvin Zhang <alvinx.zhang@intel.com>
> Signed-off-by: Kevin Liu <kevinx.liu@intel.com>
> ---
>  doc/guides/rel_notes/release_22_07.rst |   1 +
>  drivers/net/ice/ice_dcf.c              |  27 ++++
>  drivers/net/ice/ice_dcf.h              |   1 +
>  drivers/net/ice/ice_dcf_ethdev.c       | 171 ++++++++++++++++++++++---
>  4 files changed, 183 insertions(+), 17 deletions(-)
> 
> diff --git a/doc/guides/rel_notes/release_22_07.rst
> b/doc/guides/rel_notes/release_22_07.rst
> index 004a6d3343..7c932a7c8a 100644
> --- a/doc/guides/rel_notes/release_22_07.rst
> +++ b/doc/guides/rel_notes/release_22_07.rst
> @@ -73,6 +73,7 @@ New Features
>   * Added add extended stats.
>   * Added support queue information getting.
>   * Added implement power management.
> + * Added support DCF new VLAN capabilities.

This feature is not exposed to user, no need release note update.

> 
>  Removed Items
>  -------------
> diff --git a/drivers/net/ice/ice_dcf.c b/drivers/net/ice/ice_dcf.c index
> 55ae68c456..885d58c0f4 100644
> --- a/drivers/net/ice/ice_dcf.c
> +++ b/drivers/net/ice/ice_dcf.c
> @@ -587,6 +587,29 @@ ice_dcf_get_supported_rxdid(struct ice_dcf_hw *hw)
>  	return 0;
>  }
> 
> +static int
> +dcf_get_vlan_offload_caps_v2(struct ice_dcf_hw *hw) {
> +	struct virtchnl_vlan_caps vlan_v2_caps;
> +	struct dcf_virtchnl_cmd args;
> +	int ret;
> +
> +	memset(&args, 0, sizeof(args));
> +	args.v_op = VIRTCHNL_OP_GET_OFFLOAD_VLAN_V2_CAPS;
> +	args.rsp_msgbuf = (uint8_t *)&vlan_v2_caps;
> +	args.rsp_buflen = sizeof(vlan_v2_caps);
> +
> +	ret = ice_dcf_execute_virtchnl_cmd(hw, &args);
> +	if (ret) {
> +		PMD_DRV_LOG(ERR,
> +			    "Failed to execute command of
> VIRTCHNL_OP_GET_OFFLOAD_VLAN_V2_CAPS");
> +		return ret;
> +	}
> +
> +	rte_memcpy(&hw->vlan_v2_caps, &vlan_v2_caps,
> sizeof(vlan_v2_caps));
> +	return 0;
> +}
> +
>  int
>  ice_dcf_init_hw(struct rte_eth_dev *eth_dev, struct ice_dcf_hw *hw)  { @@ -
> 701,6 +724,10 @@ ice_dcf_init_hw(struct rte_eth_dev *eth_dev, struct
> ice_dcf_hw *hw)
>  	rte_intr_enable(pci_dev->intr_handle);
>  	ice_dcf_enable_irq0(hw);
> 
> +	if ((hw->vf_res->vf_cap_flags & VIRTCHNL_VF_OFFLOAD_VLAN_V2)
> &&
> +	    dcf_get_vlan_offload_caps_v2(hw))
> +		goto err_rss;
> +
>  	return 0;
> 
>  err_rss:
> diff --git a/drivers/net/ice/ice_dcf.h b/drivers/net/ice/ice_dcf.h index
> 44a61404c3..7f42ebabe9 100644
> --- a/drivers/net/ice/ice_dcf.h
> +++ b/drivers/net/ice/ice_dcf.h
> @@ -129,6 +129,7 @@ struct ice_dcf_hw {
>  	uint16_t nb_msix;
>  	uint16_t rxq_map[16];
>  	struct virtchnl_eth_stats eth_stats_offset;
> +	struct virtchnl_vlan_caps vlan_v2_caps;
> 
>  	/* Link status */
>  	bool link_up;
> diff --git a/drivers/net/ice/ice_dcf_ethdev.c b/drivers/net/ice/ice_dcf_ethdev.c
> index 236c0395e0..8005eb2ab8 100644
> --- a/drivers/net/ice/ice_dcf_ethdev.c
> +++ b/drivers/net/ice/ice_dcf_ethdev.c
> @@ -1050,6 +1050,46 @@ dcf_dev_set_default_mac_addr(struct
> rte_eth_dev *dev,
>  	return 0;
>  }
> 
> +static int
> +dcf_add_del_vlan_v2(struct ice_dcf_hw *hw, uint16_t vlanid, bool add) {
> +	struct virtchnl_vlan_supported_caps *supported_caps =
> +			&hw->vlan_v2_caps.filtering.filtering_support;
> +	struct virtchnl_vlan *vlan_setting;
> +	struct virtchnl_vlan_filter_list_v2 vlan_filter;
> +	struct dcf_virtchnl_cmd args;
> +	uint32_t filtering_caps;
> +	int err;
> +
> +	if (supported_caps->outer) {
> +		filtering_caps = supported_caps->outer;
> +		vlan_setting = &vlan_filter.filters[0].outer;
> +	} else {
> +		filtering_caps = supported_caps->inner;
> +		vlan_setting = &vlan_filter.filters[0].inner;
> +	}
> +
> +	if (!(filtering_caps & VIRTCHNL_VLAN_ETHERTYPE_8100))
> +		return -ENOTSUP;
> +
> +	memset(&vlan_filter, 0, sizeof(vlan_filter));
> +	vlan_filter.vport_id = hw->vsi_res->vsi_id;
> +	vlan_filter.num_elements = 1;
> +	vlan_setting->tpid = RTE_ETHER_TYPE_VLAN;
> +	vlan_setting->tci = vlanid;
> +
> +	memset(&args, 0, sizeof(args));
> +	args.v_op = add ? VIRTCHNL_OP_ADD_VLAN_V2 :
> VIRTCHNL_OP_DEL_VLAN_V2;
> +	args.req_msg = (uint8_t *)&vlan_filter;
> +	args.req_msglen = sizeof(vlan_filter);
> +	err = ice_dcf_execute_virtchnl_cmd(hw, &args);
> +	if (err)
> +		PMD_DRV_LOG(ERR, "fail to execute command %s",
> +			    add ? "OP_ADD_VLAN_V2" :  "OP_DEL_VLAN_V2");
> +
> +	return err;
> +}
> +
>  static int
>  dcf_add_del_vlan(struct ice_dcf_hw *hw, uint16_t vlanid, bool add)  { @@ -
> 1076,6 +1116,116 @@ dcf_add_del_vlan(struct ice_dcf_hw *hw, uint16_t
> vlanid, bool add)
>  	return err;
>  }
> 
> +static int
> +dcf_dev_vlan_filter_set(struct rte_eth_dev *dev, uint16_t vlan_id, int
> +on) {
> +	struct ice_dcf_adapter *adapter = dev->data->dev_private;
> +	struct ice_dcf_hw *hw = &adapter->real_hw;
> +	int err;
> +
> +	if (hw->vf_res->vf_cap_flags & VIRTCHNL_VF_OFFLOAD_VLAN_V2) {
> +		err = dcf_add_del_vlan_v2(hw, vlan_id, on);
> +		if (err)
> +			return -EIO;
> +		return 0;
> +	}
> +
> +	if (!(hw->vf_res->vf_cap_flags & VIRTCHNL_VF_OFFLOAD_VLAN))
> +		return -ENOTSUP;
> +
> +	err = dcf_add_del_vlan(hw, vlan_id, on);
> +	if (err)
> +		return -EIO;
> +	return 0;
> +}
> +
> +static void
> +dcf_iterate_vlan_filters_v2(struct rte_eth_dev *dev, bool enable) {
> +	struct rte_vlan_filter_conf *vfc = &dev->data->vlan_filter_conf;
> +	struct ice_dcf_adapter *adapter = dev->data->dev_private;
> +	struct ice_dcf_hw *hw = &adapter->real_hw;
> +	uint32_t i, j;
> +	uint64_t ids;
> +
> +	for (i = 0; i < RTE_DIM(vfc->ids); i++) {
> +		if (vfc->ids[i] == 0)
> +			continue;
> +
> +		ids = vfc->ids[i];
> +		for (j = 0; ids != 0 && j < 64; j++, ids >>= 1) {
> +			if (ids & 1)
> +				dcf_add_del_vlan_v2(hw, 64 * i + j, enable);
> +		}
> +	}
> +}
> +
> +static int
> +dcf_config_vlan_strip_v2(struct ice_dcf_hw *hw, bool enable) {
> +	struct virtchnl_vlan_supported_caps *stripping_caps =
> +			&hw->vlan_v2_caps.offloads.stripping_support;
> +	struct virtchnl_vlan_setting vlan_strip;
> +	struct dcf_virtchnl_cmd args;
> +	uint32_t *ethertype;
> +	int ret;
> +
> +	if ((stripping_caps->outer & VIRTCHNL_VLAN_ETHERTYPE_8100) &&
> +	    (stripping_caps->outer & VIRTCHNL_VLAN_TOGGLE))
> +		ethertype = &vlan_strip.outer_ethertype_setting;
> +	else if ((stripping_caps->inner & VIRTCHNL_VLAN_ETHERTYPE_8100)
> &&
> +		 (stripping_caps->inner & VIRTCHNL_VLAN_TOGGLE))
> +		ethertype = &vlan_strip.inner_ethertype_setting;
> +	else
> +		return -ENOTSUP;
> +
> +	memset(&vlan_strip, 0, sizeof(vlan_strip));
> +	vlan_strip.vport_id = hw->vsi_res->vsi_id;
> +	*ethertype = VIRTCHNL_VLAN_ETHERTYPE_8100;
> +
> +	memset(&args, 0, sizeof(args));
> +	args.v_op = enable ? VIRTCHNL_OP_ENABLE_VLAN_STRIPPING_V2 :
> +			    VIRTCHNL_OP_DISABLE_VLAN_STRIPPING_V2;
> +	args.req_msg = (uint8_t *)&vlan_strip;
> +	args.req_msglen = sizeof(vlan_strip);
> +	ret = ice_dcf_execute_virtchnl_cmd(hw, &args);
> +	if (ret)
> +		PMD_DRV_LOG(ERR, "fail to execute command %s",
> +			    enable ?
> "VIRTCHNL_OP_ENABLE_VLAN_STRIPPING_V2" :
> +
> "VIRTCHNL_OP_DISABLE_VLAN_STRIPPING_V2");
> +
> +	return ret;
> +}
> +
> +static int
> +dcf_dev_vlan_offload_set_v2(struct rte_eth_dev *dev, int mask) {
> +	struct rte_eth_rxmode *rxmode = &dev->data->dev_conf.rxmode;
> +	struct ice_dcf_adapter *adapter = dev->data->dev_private;
> +	struct ice_dcf_hw *hw = &adapter->real_hw;
> +	bool enable;
> +	int err;
> +
> +	if (mask & RTE_ETH_VLAN_FILTER_MASK) {
> +		enable = !!(rxmode->offloads &
> RTE_ETH_RX_OFFLOAD_VLAN_FILTER);
> +
> +		dcf_iterate_vlan_filters_v2(dev, enable);
> +	}
> +
> +	if (mask & RTE_ETH_VLAN_STRIP_MASK) {
> +		enable = !!(rxmode->offloads &
> RTE_ETH_RX_OFFLOAD_VLAN_STRIP);
> +
> +		err = dcf_config_vlan_strip_v2(hw, enable);
> +		/* If not support, the stripping is already disabled by PF */
> +		if (err == -ENOTSUP && !enable)
> +			err = 0;
> +		if (err)
> +			return -EIO;
> +	}
> +
> +	return 0;
> +}
> +
>  static int
>  dcf_enable_vlan_strip(struct ice_dcf_hw *hw)  { @@ -1108,30 +1258,17 @@
> dcf_disable_vlan_strip(struct ice_dcf_hw *hw)
>  	return ret;
>  }
> 
> -static int
> -dcf_dev_vlan_filter_set(struct rte_eth_dev *dev, uint16_t vlan_id, int on) -{
> -	struct ice_dcf_adapter *adapter = dev->data->dev_private;
> -	struct ice_dcf_hw *hw = &adapter->real_hw;
> -	int err;
> -
> -	if (!(hw->vf_res->vf_cap_flags & VIRTCHNL_VF_OFFLOAD_VLAN))
> -		return -ENOTSUP;
> -
> -	err = dcf_add_del_vlan(hw, vlan_id, on);
> -	if (err)
> -		return -EIO;
> -	return 0;
> -}
> -
>  static int
>  dcf_dev_vlan_offload_set(struct rte_eth_dev *dev, int mask)  {
> +	struct rte_eth_conf *dev_conf = &dev->data->dev_conf;
>  	struct ice_dcf_adapter *adapter = dev->data->dev_private;
>  	struct ice_dcf_hw *hw = &adapter->real_hw;
> -	struct rte_eth_conf *dev_conf = &dev->data->dev_conf;
>  	int err;
> 
> +	if (hw->vf_res->vf_cap_flags & VIRTCHNL_VF_OFFLOAD_VLAN_V2)
> +		return dcf_dev_vlan_offload_set_v2(dev, mask);
> +
>  	if (!(hw->vf_res->vf_cap_flags & VIRTCHNL_VF_OFFLOAD_VLAN))
>  		return -ENOTSUP;
> 
> --
> 2.33.1
  

Patch

diff --git a/doc/guides/rel_notes/release_22_07.rst b/doc/guides/rel_notes/release_22_07.rst
index 004a6d3343..7c932a7c8a 100644
--- a/doc/guides/rel_notes/release_22_07.rst
+++ b/doc/guides/rel_notes/release_22_07.rst
@@ -73,6 +73,7 @@  New Features
  * Added add extended stats.
  * Added support queue information getting.
  * Added implement power management.
+ * Added support DCF new VLAN capabilities.
 
 Removed Items
 -------------
diff --git a/drivers/net/ice/ice_dcf.c b/drivers/net/ice/ice_dcf.c
index 55ae68c456..885d58c0f4 100644
--- a/drivers/net/ice/ice_dcf.c
+++ b/drivers/net/ice/ice_dcf.c
@@ -587,6 +587,29 @@  ice_dcf_get_supported_rxdid(struct ice_dcf_hw *hw)
 	return 0;
 }
 
+static int
+dcf_get_vlan_offload_caps_v2(struct ice_dcf_hw *hw)
+{
+	struct virtchnl_vlan_caps vlan_v2_caps;
+	struct dcf_virtchnl_cmd args;
+	int ret;
+
+	memset(&args, 0, sizeof(args));
+	args.v_op = VIRTCHNL_OP_GET_OFFLOAD_VLAN_V2_CAPS;
+	args.rsp_msgbuf = (uint8_t *)&vlan_v2_caps;
+	args.rsp_buflen = sizeof(vlan_v2_caps);
+
+	ret = ice_dcf_execute_virtchnl_cmd(hw, &args);
+	if (ret) {
+		PMD_DRV_LOG(ERR,
+			    "Failed to execute command of VIRTCHNL_OP_GET_OFFLOAD_VLAN_V2_CAPS");
+		return ret;
+	}
+
+	rte_memcpy(&hw->vlan_v2_caps, &vlan_v2_caps, sizeof(vlan_v2_caps));
+	return 0;
+}
+
 int
 ice_dcf_init_hw(struct rte_eth_dev *eth_dev, struct ice_dcf_hw *hw)
 {
@@ -701,6 +724,10 @@  ice_dcf_init_hw(struct rte_eth_dev *eth_dev, struct ice_dcf_hw *hw)
 	rte_intr_enable(pci_dev->intr_handle);
 	ice_dcf_enable_irq0(hw);
 
+	if ((hw->vf_res->vf_cap_flags & VIRTCHNL_VF_OFFLOAD_VLAN_V2) &&
+	    dcf_get_vlan_offload_caps_v2(hw))
+		goto err_rss;
+
 	return 0;
 
 err_rss:
diff --git a/drivers/net/ice/ice_dcf.h b/drivers/net/ice/ice_dcf.h
index 44a61404c3..7f42ebabe9 100644
--- a/drivers/net/ice/ice_dcf.h
+++ b/drivers/net/ice/ice_dcf.h
@@ -129,6 +129,7 @@  struct ice_dcf_hw {
 	uint16_t nb_msix;
 	uint16_t rxq_map[16];
 	struct virtchnl_eth_stats eth_stats_offset;
+	struct virtchnl_vlan_caps vlan_v2_caps;
 
 	/* Link status */
 	bool link_up;
diff --git a/drivers/net/ice/ice_dcf_ethdev.c b/drivers/net/ice/ice_dcf_ethdev.c
index 236c0395e0..8005eb2ab8 100644
--- a/drivers/net/ice/ice_dcf_ethdev.c
+++ b/drivers/net/ice/ice_dcf_ethdev.c
@@ -1050,6 +1050,46 @@  dcf_dev_set_default_mac_addr(struct rte_eth_dev *dev,
 	return 0;
 }
 
+static int
+dcf_add_del_vlan_v2(struct ice_dcf_hw *hw, uint16_t vlanid, bool add)
+{
+	struct virtchnl_vlan_supported_caps *supported_caps =
+			&hw->vlan_v2_caps.filtering.filtering_support;
+	struct virtchnl_vlan *vlan_setting;
+	struct virtchnl_vlan_filter_list_v2 vlan_filter;
+	struct dcf_virtchnl_cmd args;
+	uint32_t filtering_caps;
+	int err;
+
+	if (supported_caps->outer) {
+		filtering_caps = supported_caps->outer;
+		vlan_setting = &vlan_filter.filters[0].outer;
+	} else {
+		filtering_caps = supported_caps->inner;
+		vlan_setting = &vlan_filter.filters[0].inner;
+	}
+
+	if (!(filtering_caps & VIRTCHNL_VLAN_ETHERTYPE_8100))
+		return -ENOTSUP;
+
+	memset(&vlan_filter, 0, sizeof(vlan_filter));
+	vlan_filter.vport_id = hw->vsi_res->vsi_id;
+	vlan_filter.num_elements = 1;
+	vlan_setting->tpid = RTE_ETHER_TYPE_VLAN;
+	vlan_setting->tci = vlanid;
+
+	memset(&args, 0, sizeof(args));
+	args.v_op = add ? VIRTCHNL_OP_ADD_VLAN_V2 : VIRTCHNL_OP_DEL_VLAN_V2;
+	args.req_msg = (uint8_t *)&vlan_filter;
+	args.req_msglen = sizeof(vlan_filter);
+	err = ice_dcf_execute_virtchnl_cmd(hw, &args);
+	if (err)
+		PMD_DRV_LOG(ERR, "fail to execute command %s",
+			    add ? "OP_ADD_VLAN_V2" :  "OP_DEL_VLAN_V2");
+
+	return err;
+}
+
 static int
 dcf_add_del_vlan(struct ice_dcf_hw *hw, uint16_t vlanid, bool add)
 {
@@ -1076,6 +1116,116 @@  dcf_add_del_vlan(struct ice_dcf_hw *hw, uint16_t vlanid, bool add)
 	return err;
 }
 
+static int
+dcf_dev_vlan_filter_set(struct rte_eth_dev *dev, uint16_t vlan_id, int on)
+{
+	struct ice_dcf_adapter *adapter = dev->data->dev_private;
+	struct ice_dcf_hw *hw = &adapter->real_hw;
+	int err;
+
+	if (hw->vf_res->vf_cap_flags & VIRTCHNL_VF_OFFLOAD_VLAN_V2) {
+		err = dcf_add_del_vlan_v2(hw, vlan_id, on);
+		if (err)
+			return -EIO;
+		return 0;
+	}
+
+	if (!(hw->vf_res->vf_cap_flags & VIRTCHNL_VF_OFFLOAD_VLAN))
+		return -ENOTSUP;
+
+	err = dcf_add_del_vlan(hw, vlan_id, on);
+	if (err)
+		return -EIO;
+	return 0;
+}
+
+static void
+dcf_iterate_vlan_filters_v2(struct rte_eth_dev *dev, bool enable)
+{
+	struct rte_vlan_filter_conf *vfc = &dev->data->vlan_filter_conf;
+	struct ice_dcf_adapter *adapter = dev->data->dev_private;
+	struct ice_dcf_hw *hw = &adapter->real_hw;
+	uint32_t i, j;
+	uint64_t ids;
+
+	for (i = 0; i < RTE_DIM(vfc->ids); i++) {
+		if (vfc->ids[i] == 0)
+			continue;
+
+		ids = vfc->ids[i];
+		for (j = 0; ids != 0 && j < 64; j++, ids >>= 1) {
+			if (ids & 1)
+				dcf_add_del_vlan_v2(hw, 64 * i + j, enable);
+		}
+	}
+}
+
+static int
+dcf_config_vlan_strip_v2(struct ice_dcf_hw *hw, bool enable)
+{
+	struct virtchnl_vlan_supported_caps *stripping_caps =
+			&hw->vlan_v2_caps.offloads.stripping_support;
+	struct virtchnl_vlan_setting vlan_strip;
+	struct dcf_virtchnl_cmd args;
+	uint32_t *ethertype;
+	int ret;
+
+	if ((stripping_caps->outer & VIRTCHNL_VLAN_ETHERTYPE_8100) &&
+	    (stripping_caps->outer & VIRTCHNL_VLAN_TOGGLE))
+		ethertype = &vlan_strip.outer_ethertype_setting;
+	else if ((stripping_caps->inner & VIRTCHNL_VLAN_ETHERTYPE_8100) &&
+		 (stripping_caps->inner & VIRTCHNL_VLAN_TOGGLE))
+		ethertype = &vlan_strip.inner_ethertype_setting;
+	else
+		return -ENOTSUP;
+
+	memset(&vlan_strip, 0, sizeof(vlan_strip));
+	vlan_strip.vport_id = hw->vsi_res->vsi_id;
+	*ethertype = VIRTCHNL_VLAN_ETHERTYPE_8100;
+
+	memset(&args, 0, sizeof(args));
+	args.v_op = enable ? VIRTCHNL_OP_ENABLE_VLAN_STRIPPING_V2 :
+			    VIRTCHNL_OP_DISABLE_VLAN_STRIPPING_V2;
+	args.req_msg = (uint8_t *)&vlan_strip;
+	args.req_msglen = sizeof(vlan_strip);
+	ret = ice_dcf_execute_virtchnl_cmd(hw, &args);
+	if (ret)
+		PMD_DRV_LOG(ERR, "fail to execute command %s",
+			    enable ? "VIRTCHNL_OP_ENABLE_VLAN_STRIPPING_V2" :
+				     "VIRTCHNL_OP_DISABLE_VLAN_STRIPPING_V2");
+
+	return ret;
+}
+
+static int
+dcf_dev_vlan_offload_set_v2(struct rte_eth_dev *dev, int mask)
+{
+	struct rte_eth_rxmode *rxmode = &dev->data->dev_conf.rxmode;
+	struct ice_dcf_adapter *adapter = dev->data->dev_private;
+	struct ice_dcf_hw *hw = &adapter->real_hw;
+	bool enable;
+	int err;
+
+	if (mask & RTE_ETH_VLAN_FILTER_MASK) {
+		enable = !!(rxmode->offloads & RTE_ETH_RX_OFFLOAD_VLAN_FILTER);
+
+		dcf_iterate_vlan_filters_v2(dev, enable);
+	}
+
+	if (mask & RTE_ETH_VLAN_STRIP_MASK) {
+		enable = !!(rxmode->offloads & RTE_ETH_RX_OFFLOAD_VLAN_STRIP);
+
+		err = dcf_config_vlan_strip_v2(hw, enable);
+		/* If not support, the stripping is already disabled by PF */
+		if (err == -ENOTSUP && !enable)
+			err = 0;
+		if (err)
+			return -EIO;
+	}
+
+	return 0;
+}
+
 static int
 dcf_enable_vlan_strip(struct ice_dcf_hw *hw)
 {
@@ -1108,30 +1258,17 @@  dcf_disable_vlan_strip(struct ice_dcf_hw *hw)
 	return ret;
 }
 
-static int
-dcf_dev_vlan_filter_set(struct rte_eth_dev *dev, uint16_t vlan_id, int on)
-{
-	struct ice_dcf_adapter *adapter = dev->data->dev_private;
-	struct ice_dcf_hw *hw = &adapter->real_hw;
-	int err;
-
-	if (!(hw->vf_res->vf_cap_flags & VIRTCHNL_VF_OFFLOAD_VLAN))
-		return -ENOTSUP;
-
-	err = dcf_add_del_vlan(hw, vlan_id, on);
-	if (err)
-		return -EIO;
-	return 0;
-}
-
 static int
 dcf_dev_vlan_offload_set(struct rte_eth_dev *dev, int mask)
 {
+	struct rte_eth_conf *dev_conf = &dev->data->dev_conf;
 	struct ice_dcf_adapter *adapter = dev->data->dev_private;
 	struct ice_dcf_hw *hw = &adapter->real_hw;
-	struct rte_eth_conf *dev_conf = &dev->data->dev_conf;
 	int err;
 
+	if (hw->vf_res->vf_cap_flags & VIRTCHNL_VF_OFFLOAD_VLAN_V2)
+		return dcf_dev_vlan_offload_set_v2(dev, mask);
+
 	if (!(hw->vf_res->vf_cap_flags & VIRTCHNL_VF_OFFLOAD_VLAN))
 		return -ENOTSUP;