[dpdk-dev] [PATCH v4 1/5] net/i40e: add pipeline personalization profile processing

Chilikin, Andrey andrey.chilikin at intel.com
Fri Mar 24 15:52:33 CET 2017


Hi Beilei,

> -----Original Message-----
> From: dev [mailto:dev-bounces at dpdk.org] On Behalf Of Beilei Xing
> Sent: Friday, March 24, 2017 10:19 AM
> To: Wu, Jingjing <jingjing.wu at intel.com>
> Cc: Zhang, Helin <helin.zhang at intel.com>; dev at dpdk.org
> Subject: [dpdk-dev] [PATCH v4 1/5] net/i40e: add pipeline personalization
> profile processing
> 
> Add support for adding a pipeline personalization profile package.
> 
> Signed-off-by: Beilei Xing <beilei.xing at intel.com>
> ---
>  app/test-pmd/cmdline.c                    |   1 +
>  drivers/net/i40e/i40e_ethdev.c            | 198
> ++++++++++++++++++++++++++++++
>  drivers/net/i40e/rte_pmd_i40e.h           |  51 ++++++++
>  drivers/net/i40e/rte_pmd_i40e_version.map |   6 +
>  4 files changed, 256 insertions(+)
> 
> diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c index
> 47f935d..6e0625d 100644
> --- a/app/test-pmd/cmdline.c
> +++ b/app/test-pmd/cmdline.c
> @@ -37,6 +37,7 @@
>  #include <stdio.h>
>  #include <stdint.h>
>  #include <stdarg.h>
> +#include <stdbool.h>
>  #include <string.h>
>  #include <termios.h>
>  #include <unistd.h>
> diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
> index 3702214..bea593f 100644
> --- a/drivers/net/i40e/i40e_ethdev.c
> +++ b/drivers/net/i40e/i40e_ethdev.c
> @@ -11259,3 +11259,201 @@ rte_pmd_i40e_reset_vf_stats(uint8_t port,
> 
>  	return 0;
>  }
> +
> +static void
> +i40e_generate_profile_info_sec(char *name, struct i40e_ppp_version
> *version,
> +			       uint32_t track_id, uint8_t *profile_info_sec,
> +			       bool add)
> +{
> +	struct i40e_profile_section_header *sec = NULL;
> +	struct i40e_profile_info *pinfo;
> +
> +	sec = (struct i40e_profile_section_header *)profile_info_sec;
> +	sec->tbl_size = 1;
> +	sec->data_end = sizeof(struct i40e_profile_section_header) +
> +		sizeof(struct i40e_profile_info);
> +	sec->section.type = SECTION_TYPE_INFO;
> +	sec->section.offset = sizeof(struct i40e_profile_section_header);
> +	sec->section.size = sizeof(struct i40e_profile_info);
> +	pinfo = (struct i40e_profile_info *)(profile_info_sec +
> +					     sec->section.offset);
> +	pinfo->track_id = track_id;
> +	memcpy(pinfo->name, name, I40E_PPP_NAME_SIZE);
> +	memcpy(&pinfo->version, version, sizeof(struct i40e_ppp_version));
> +	if (add)
> +		pinfo->op = I40E_PPP_ADD_TRACKID;
> +	else
> +		pinfo->op = I40E_PPP_REMOVE_TRACKID;
> +}
> +
> +static enum i40e_status_code
> +i40e_add_rm_profile_info(struct i40e_hw *hw, uint8_t *profile_info_sec)
> +{
> +	enum i40e_status_code status = I40E_SUCCESS;
> +	struct i40e_profile_section_header *sec;
> +	uint32_t track_id;
> +	uint32_t offset = 0, info = 0;
> +
> +	sec = (struct i40e_profile_section_header *)profile_info_sec;
> +	track_id = ((struct i40e_profile_info *)(profile_info_sec +
> +					 sec->section.offset))->track_id;
> +
> +	status = i40e_aq_write_ppp(hw, (void *)sec, sec->data_end,
> +				   track_id, &offset, &info, NULL);
> +	if (status)
> +		PMD_DRV_LOG(ERR, "Failed to add/remove profile info: "
> +			    "offset %d, info %d",
> +			    offset, info);
> +
> +	return status;
> +}
> +
> +#define I40E_PROFILE_INFO_SIZE 48
> +#define I40E_MAX_PROFILE_NUM 16
> +
> +/* Check if the profile info exists */
> +static int
> +i40e_check_profile_info(uint8_t port, uint8_t *profile_info_sec) {
> +	struct rte_eth_dev *dev = &rte_eth_devices[port];
> +	struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data-
> >dev_private);
> +	uint8_t *buff;
> +	struct rte_pmd_i40e_profile_list *p_list;
> +	struct rte_pmd_i40e_profile_info *pinfo, *p;
> +	uint32_t i;
> +	int ret;
> +
> +	buff = rte_zmalloc("pinfo_list",
> +			   (I40E_PROFILE_INFO_SIZE *
> I40E_MAX_PROFILE_NUM + 4),
> +			   0);
> +	if (!buff) {
> +		PMD_DRV_LOG(ERR, "failed to allocate memory");
> +		return -1;
> +	}
> +
> +	ret = i40e_aq_get_ppp_list(hw, (void *)buff,
> +		      (I40E_PROFILE_INFO_SIZE * I40E_MAX_PROFILE_NUM +
> 4),
> +		      0, NULL);
> +	if (ret) {
> +		PMD_DRV_LOG(ERR, "Failed to get profile info list.");
> +		rte_free(buff);
> +		return -1;
> +	}
> +	p_list = (struct rte_pmd_i40e_profile_list *)buff;
> +	pinfo = (struct rte_pmd_i40e_profile_info *)(profile_info_sec +
> +			     sizeof(struct i40e_profile_section_header));
> +	for (i = 0; i < p_list->p_count; i++) {
> +		p = &p_list->p_info[i];
> +		if ((pinfo->track_id == p->track_id) &&
> +		    !memcmp(&pinfo->version, &p->version,
> +			    sizeof(struct i40e_ppp_version)) &&
> +		    !memcmp(&pinfo->name, &p->name,
> +			    I40E_PPP_NAME_SIZE)) {
> +			PMD_DRV_LOG(INFO, "Profile exists.");
> +			rte_free(buff);
> +			return 1;
> +		}
> +	}
> +
> +	rte_free(buff);
> +	return 0;
> +}
> +
> +int
> +rte_pmd_i40e_process_ppp_package(uint8_t port, uint8_t *buff,
> +				 uint32_t size, bool add)

To make this function future-proof it is better not to use 'bool add' as there are at least three possible processing actions:

1. Process package and add it to the list of applied profiles (applying new personalization)
2. Process package and remove it from the list (restoring original configuration)
3. Process package and to not update the list (update already applied personalization)

> +{
> +	struct rte_eth_dev *dev;
> +	struct i40e_hw *hw;
> +	struct i40e_package_header *pkg_hdr;
> +	struct i40e_generic_seg_header *profile_seg_hdr;
> +	struct i40e_generic_seg_header *metadata_seg_hdr;
> +	uint32_t track_id;
> +	uint8_t *profile_info_sec;
> +	int is_exist;
> +	enum i40e_status_code status = I40E_SUCCESS;
> +
> +	RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
> +
> +	dev = &rte_eth_devices[port];
> +
> +	if (!is_device_supported(dev, &rte_i40e_pmd))
> +		return -ENOTSUP;
> +
> +	hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
> +
> +	if (size < (sizeof(struct i40e_package_header) +
> +		    sizeof(struct i40e_metadata_segment) +
> +		    sizeof(uint32_t) * 2)) {
> +		PMD_DRV_LOG(ERR, "Buff is invalid.");
> +		return -EINVAL;
> +	}
> +
> +	pkg_hdr = (struct i40e_package_header *)buff;
> +
> +	if (!pkg_hdr) {
> +		PMD_DRV_LOG(ERR, "Failed to fill the package structure");
> +		return -EINVAL;
> +	}
> +
> +	if (pkg_hdr->segment_count < 2) {
> +		PMD_DRV_LOG(ERR, "Segment_count should be 2 at least.");
> +		return -EINVAL;
> +	}
> +
> +	/* Find metadata segment */
> +	metadata_seg_hdr =
> i40e_find_segment_in_package(SEGMENT_TYPE_METADATA,
> +							pkg_hdr);
> +	if (!metadata_seg_hdr) {
> +		PMD_DRV_LOG(ERR, "Failed to find metadata segment
> header");
> +		return -EINVAL;
> +	}
> +	track_id = ((struct i40e_metadata_segment
> +*)metadata_seg_hdr)->track_id;
> +
> +	/* Find profile segment */
> +	profile_seg_hdr =
> i40e_find_segment_in_package(SEGMENT_TYPE_I40E,
> +						       pkg_hdr);
> +	if (!profile_seg_hdr) {
> +		PMD_DRV_LOG(ERR, "Failed to find profile segment header");
> +		return -EINVAL;
> +	}
> +
> +	profile_info_sec = rte_zmalloc("i40e_profile_info",
> +			       sizeof(struct i40e_profile_section_header) +
> +			       sizeof(struct i40e_profile_info),
> +			       0);
> +	if (!profile_info_sec) {
> +		PMD_DRV_LOG(ERR, "Failed to allocate memory");
> +		return -EINVAL;
> +	}
> +
> +	if (add) {
> +		/* Check if the profile exists */
> +		i40e_generate_profile_info_sec(
> +		     ((struct i40e_profile_segment *)profile_seg_hdr)->name,
> +		     &((struct i40e_profile_segment *)profile_seg_hdr)-
> >version,
> +		     track_id, profile_info_sec, 1);
> +		is_exist = i40e_check_profile_info(port, profile_info_sec);
> +		if (is_exist) {
> +			PMD_DRV_LOG(ERR, "Profile already exists.");
> +			rte_free(profile_info_sec);
> +			return 1;
> +		}
> +
> +		/* Write profile to HW */
> +		status = i40e_write_profile(hw,
> +				 (struct i40e_profile_segment
> *)profile_seg_hdr,
> +				 track_id);
> +		if (status)
> +			PMD_DRV_LOG(ERR, "Failed to write profile.");
> +
> +		/* Add profile info to info list */
> +		status = i40e_add_rm_profile_info(hw, profile_info_sec);
> +		if (status)
> +			PMD_DRV_LOG(ERR, "Failed to add profile info.");
> +	} else
> +		PMD_DRV_LOG(ERR, "Action not supported temporarily.");
> +
> +	rte_free(profile_info_sec);
> +	return status;
> +}
> diff --git a/drivers/net/i40e/rte_pmd_i40e.h
> b/drivers/net/i40e/rte_pmd_i40e.h index a0ad88c..4f6cdb5 100644
> --- a/drivers/net/i40e/rte_pmd_i40e.h
> +++ b/drivers/net/i40e/rte_pmd_i40e.h
> @@ -65,6 +65,36 @@ struct rte_pmd_i40e_mb_event_param {
>  	uint16_t msglen;   /**< length of the message */
>  };
> 
> +#define RTE_PMD_I40E_PPP_NAME_SIZE 32
> +
> +/**
> + * Pipeline personalization profile version  */ struct
> +rte_pmd_i40e_ppp_version {
> +	uint8_t major;
> +	uint8_t minor;
> +	uint8_t update;
> +	uint8_t draft;
> +};
> +
> +/**
> + * Structure of profile information
> + */
> +struct rte_pmd_i40e_profile_info {
> +	uint32_t track_id;
> +	struct rte_pmd_i40e_ppp_version version;
> +	uint8_t reserved[8];

Instead of uint8_t reserved[8] it should be
    uint8_t owner;
    uint8_t reserved[7];

> +	uint8_t name[RTE_PMD_I40E_PPP_NAME_SIZE]; };
> +
> +/**
> + * Structure of profile information list  */ struct
> +rte_pmd_i40e_profile_list {
> +	uint32_t p_count;
> +	struct rte_pmd_i40e_profile_info p_info[1]; };
> +
>  /**
>   * Notify VF when PF link status changes.
>   *
> @@ -332,4 +362,25 @@ int rte_pmd_i40e_get_vf_stats(uint8_t port,  int
> rte_pmd_i40e_reset_vf_stats(uint8_t port,
>  				uint16_t vf_id);
> 
> +/**
> + * Load/Unload a ppp package
> + *
> + * @param port
> + *    The port identifier of the Ethernet device.
> + * @param buff
> + *    buffer of package.
> + * @param size
> + *    size of buffer.
> + * @param add
> + *   - (1) write profile.
> + *   - (0) remove profile.
> + * @return
> + *   - (0) if successful.
> + *   - (-ENODEV) if *port* invalid.
> + *   - (-EINVAL) if bad parameter.
> + *   - (1) if profile exists.
> + */
> +int rte_pmd_i40e_process_ppp_package(uint8_t port, uint8_t *buff,
> +				     uint32_t size, bool add);
> +
>  #endif /* _PMD_I40E_H_ */
> diff --git a/drivers/net/i40e/rte_pmd_i40e_version.map
> b/drivers/net/i40e/rte_pmd_i40e_version.map
> index 7a5d211..01c4a90 100644
> --- a/drivers/net/i40e/rte_pmd_i40e_version.map
> +++ b/drivers/net/i40e/rte_pmd_i40e_version.map
> @@ -22,3 +22,9 @@ DPDK_17.02 {
>  	rte_pmd_i40e_set_vf_vlan_tag;
> 
>  } DPDK_2.0;
> +
> +DPDK_17.05 {
> +	global:
> +
> +	rte_pmd_i40e_process_ppp_package;
> +};
> --
> 2.5.5

Regards,
Andrey


More information about the dev mailing list