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

Zhang, Qi Z qi.z.zhang at intel.com
Wed Apr 27 12:46:34 CEST 2022



> -----Original Message-----
> From: Liu, KevinX <kevinx.liu at intel.com>
> Sent: Thursday, April 28, 2022 2:13 AM
> To: dev at dpdk.org
> Cc: Yang, Qiming <qiming.yang at intel.com>; Zhang, Qi Z
> <qi.z.zhang at intel.com>; Yang, SteveX <stevex.yang at intel.com>; Alvin Zhang
> <alvinx.zhang at intel.com>; Liu, KevinX <kevinx.liu at intel.com>
> Subject: [PATCH v6 12/12] net/ice: support DCF new VLAN capabilities
> 
> From: Alvin Zhang <alvinx.zhang at 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 at intel.com>
> Signed-off-by: Kevin Liu <kevinx.liu at 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



More information about the dev mailing list