DPDK patches and discussions
 help / color / mirror / Atom feed
* [dpdk-dev] [PATCH] net/i40e: extended list of operations for ddp processing
@ 2017-05-27 16:04 Andrey Chilikin
  2017-06-27  8:18 ` [dpdk-dev] [PATCH v2 0/2] " Andrey Chilikin
                   ` (8 more replies)
  0 siblings, 9 replies; 17+ messages in thread
From: Andrey Chilikin @ 2017-05-27 16:04 UTC (permalink / raw)
  To: dev; +Cc: beilei.xing, jingjing.wu, Andrey Chilikin

This patch adds ability to remove already loaded profile
or write profile without registering it

Signed-off-by: Andrey Chilikin <andrey.chilikin@intel.com>
---
 drivers/net/i40e/rte_pmd_i40e.c |  165 ++++++++++++++++++++++++++++++++-------
 drivers/net/i40e/rte_pmd_i40e.h |    6 +-
 2 files changed, 141 insertions(+), 30 deletions(-)

diff --git a/drivers/net/i40e/rte_pmd_i40e.c b/drivers/net/i40e/rte_pmd_i40e.c
index f7ce62b..5ebd7cf 100644
--- a/drivers/net/i40e/rte_pmd_i40e.c
+++ b/drivers/net/i40e/rte_pmd_i40e.c
@@ -1523,6 +1523,9 @@ int rte_pmd_i40e_set_vf_vlan_filter(uint8_t port, uint16_t vlan_id,
 #define I40E_PROFILE_INFO_SIZE 48
 #define I40E_MAX_PROFILE_NUM 16
 
+#define I40E_DDP_TRACKID_INVALID 0xFFFFFFFF
+#define SECTION_TYPE_RB_MMIO 0x00001800
+
 /* Check if the profile info exists */
 static int
 i40e_check_profile_info(uint8_t port, uint8_t *profile_info_sec)
@@ -1557,11 +1560,7 @@ int rte_pmd_i40e_set_vf_vlan_filter(uint8_t port, uint16_t vlan_id,
 			     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_ddp_version)) &&
-		    !memcmp(&pinfo->name, &p->name,
-			    I40E_DDP_NAME_SIZE)) {
+		if (pinfo->track_id == p->track_id) {
 			PMD_DRV_LOG(INFO, "Profile exists.");
 			rte_free(buff);
 			return 1;
@@ -1572,6 +1571,88 @@ int rte_pmd_i40e_set_vf_vlan_filter(uint8_t port, uint16_t vlan_id,
 	return 0;
 }
 
+/**
+ * i40e_rollback_profile
+ * @hw: pointer to the hardware structure
+ * @profile: pointer to the profile segment of the package to be removed
+ * @track_id: package tracking id
+ *
+ * Rolls back previously loaded package.
+ */
+static enum i40e_status_code
+i40e_rollback_profile(struct i40e_hw *hw, struct i40e_profile_segment *profile,
+		   u32 track_id)
+{
+	enum i40e_status_code status = I40E_SUCCESS;
+	struct i40e_section_table *sec_tbl;
+	struct i40e_profile_section_header *sec = NULL;
+	u32 dev_cnt;
+	u32 vendor_dev_id;
+	u32 *nvm;
+	u32 section_size = 0;
+	u32 offset = 0, info = 0;
+	u32 i, n;
+
+	if (track_id == I40E_DDP_TRACKID_INVALID) {
+		PMD_DRV_LOG(ERR, "Invalid track_id");
+		return I40E_NOT_SUPPORTED;
+	}
+
+	dev_cnt = profile->device_table_count;
+
+	for (i = 0; i < dev_cnt; i++) {
+		vendor_dev_id = profile->device_table[i].vendor_dev_id;
+		if ((vendor_dev_id >> 16) == I40E_INTEL_VENDOR_ID)
+			if (hw->device_id == (vendor_dev_id & 0xFFFF))
+				break;
+	}
+	if (dev_cnt && (i == dev_cnt)) {
+		PMD_DRV_LOG(ERR, "Device doesn't support DDP");
+		return I40E_ERR_DEVICE_NOT_SUPPORTED;
+	}
+
+	nvm = (u32 *)&profile->device_table[dev_cnt];
+	sec_tbl = (struct i40e_section_table *)&nvm[nvm[0] + 1];
+
+	for (i = 0; i < sec_tbl->section_count; i++) {
+		sec = (struct i40e_profile_section_header *)((u8 *)profile +
+			sec_tbl->section_offset[i]);
+		if (sec->section.type == SECTION_TYPE_AQ) {
+			PMD_DRV_LOG(ERR, "Rollback not supported for AQ sections");
+			return I40E_NOT_SUPPORTED;
+		}
+		if (sec->section.type == SECTION_TYPE_MMIO) {
+			PMD_DRV_LOG(ERR, "Not a roll-back package");
+			return I40E_NOT_SUPPORTED;
+		}
+	}
+
+	for (i = 0; i < sec_tbl->section_count; i++) {
+		/* For rollback write sections in reverse */
+		n = sec_tbl->section_count - i - 1;
+		sec = (struct i40e_profile_section_header *)((u8 *)profile +
+					     sec_tbl->section_offset[n]);
+
+		/* Skip any non-rollback sections */
+		if (sec->section.type != SECTION_TYPE_RB_MMIO)
+			continue;
+
+		section_size = sec->section.size +
+			sizeof(struct i40e_profile_section_header);
+
+		/* Write roll-back MMIO section */
+		status = i40e_aq_write_ddp(hw, (void *)sec, (u16)section_size,
+					   track_id, &offset, &info, NULL);
+		if (status) {
+			PMD_DRV_LOG(ERR,
+				   "Failed to write profile: section %d, offset %d, info %d",
+				   n, offset, info);
+			break;
+		}
+	}
+	return status;
+}
+
 int
 rte_pmd_i40e_process_ddp_package(uint8_t port, uint8_t *buff,
 				 uint32_t size,
@@ -1587,6 +1668,13 @@ int rte_pmd_i40e_set_vf_vlan_filter(uint8_t port, uint16_t vlan_id,
 	int is_exist;
 	enum i40e_status_code status = I40E_SUCCESS;
 
+	if (op != RTE_PMD_I40E_PKG_OP_WR_ADD &&
+		op != RTE_PMD_I40E_PKG_OP_WR_ONLY &&
+		op != RTE_PMD_I40E_PKG_OP_WR_DEL) {
+		PMD_DRV_LOG(ERR, "Operation not supported.");
+		return -ENOTSUP;
+	}
+
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
 
 	dev = &rte_eth_devices[port];
@@ -1623,6 +1711,10 @@ int rte_pmd_i40e_set_vf_vlan_filter(uint8_t port, uint16_t vlan_id,
 		return -EINVAL;
 	}
 	track_id = ((struct i40e_metadata_segment *)metadata_seg_hdr)->track_id;
+	if (track_id == I40E_DDP_TRACKID_INVALID) {
+		PMD_DRV_LOG(ERR, "Invalid track_id");
+		return -EINVAL;
+	}
 
 	/* Find profile segment */
 	profile_seg_hdr = i40e_find_segment_in_package(SEGMENT_TYPE_I40E,
@@ -1642,40 +1734,55 @@ int rte_pmd_i40e_set_vf_vlan_filter(uint8_t port, uint16_t vlan_id,
 		return -EINVAL;
 	}
 
+	/* Check if the profile already loaded */
+	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,
+		op == RTE_PMD_I40E_PKG_OP_WR_ADD);
+	is_exist = i40e_check_profile_info(port, profile_info_sec);
+	if (is_exist < 0) {
+		PMD_DRV_LOG(ERR, "Failed to check profile.");
+		rte_free(profile_info_sec);
+		return -EINVAL;
+	}
+
 	if (op == RTE_PMD_I40E_PKG_OP_WR_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 > 0) {
+		if (is_exist) {
 			PMD_DRV_LOG(ERR, "Profile already exists.");
 			rte_free(profile_info_sec);
-			return 1;
-		} else if (is_exist < 0) {
-			PMD_DRV_LOG(ERR, "Failed to check profile.");
+			return -EEXIST;
+		}
+	} else if (op == RTE_PMD_I40E_PKG_OP_WR_DEL) {
+		if (!is_exist) {
+			PMD_DRV_LOG(ERR, "Profile does not exist.");
 			rte_free(profile_info_sec);
-			return -EINVAL;
+			return -EACCES;
 		}
+	}
 
-		/* Write profile to HW */
+	if (op == RTE_PMD_I40E_PKG_OP_WR_DEL)
+		status = i40e_rollback_profile(
+			hw,
+			(struct i40e_profile_segment *)profile_seg_hdr,
+			track_id);
+	else
 		status = i40e_write_profile(
-				hw,
-				(struct i40e_profile_segment *)profile_seg_hdr,
-				track_id);
-		if (status) {
-			PMD_DRV_LOG(ERR, "Failed to write profile.");
-			rte_free(profile_info_sec);
-			return status;
-		}
+			hw,
+			(struct i40e_profile_segment *)profile_seg_hdr,
+			track_id);
+
+	if (status) {
+		PMD_DRV_LOG(ERR, "Failed to write profile.");
+		rte_free(profile_info_sec);
+		return status;
+	}
 
-		/* Add profile info to info list */
+	if (track_id && (op != RTE_PMD_I40E_PKG_OP_WR_ONLY)) {
+		/* Modify loaded profiles 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, "Operation not supported.");
+			PMD_DRV_LOG(ERR, "Failed to modify profile info list.");
 	}
 
 	rte_free(profile_info_sec);
diff --git a/drivers/net/i40e/rte_pmd_i40e.h b/drivers/net/i40e/rte_pmd_i40e.h
index 1efb2c4..46287cc 100644
--- a/drivers/net/i40e/rte_pmd_i40e.h
+++ b/drivers/net/i40e/rte_pmd_i40e.h
@@ -71,6 +71,8 @@ struct rte_pmd_i40e_mb_event_param {
 enum rte_pmd_i40e_package_op {
 	RTE_PMD_I40E_PKG_OP_UNDEFINED = 0,
 	RTE_PMD_I40E_PKG_OP_WR_ADD,   /**< load package and add to info list */
+	RTE_PMD_I40E_PKG_OP_WR_DEL, /** load package and delete from info list */
+	RTE_PMD_I40E_PKG_OP_WR_ONLY, /**< load package without modifying info list */
 	RTE_PMD_I40E_PKG_OP_MAX = 32
 };
 
@@ -492,7 +494,9 @@ int rte_pmd_i40e_set_vf_tc_max_bw(uint8_t port,
  *   - (0) if successful.
  *   - (-ENODEV) if *port* invalid.
  *   - (-EINVAL) if bad parameter.
- *   - (1) if profile exists.
+ *   - (-EEXIST) if profile exists.
+ *   - (-EACCES) if profile does not exist.
+ *   - (-ENOTSUP) if operation not supported.
  */
 int rte_pmd_i40e_process_ddp_package(uint8_t port, uint8_t *buff,
 				     uint32_t size,
-- 
1.7.0.7

^ permalink raw reply	[flat|nested] 17+ messages in thread

* [dpdk-dev] [PATCH v2 0/2] net/i40e: extended list of operations for ddp processing
  2017-05-27 16:04 [dpdk-dev] [PATCH] net/i40e: extended list of operations for ddp processing Andrey Chilikin
@ 2017-06-27  8:18 ` Andrey Chilikin
  2017-06-27  8:18 ` [dpdk-dev] [PATCH v2 1/2] " Andrey Chilikin
                   ` (7 subsequent siblings)
  8 siblings, 0 replies; 17+ messages in thread
From: Andrey Chilikin @ 2017-06-27  8:18 UTC (permalink / raw)
  To: dev; +Cc: beilei.xing, jingjing.wu, Andrey Chilikin

This patchset adds two new operations for dynamic device personalisation:
* remove already loaded profile and delete it from the list
* write profile without registering it

This patchset depends on:
[PATCH v2 00/16] net/i40e: base code update
http://dpdk.org/ml/archives/dev/2017-June/068732.html
http://dpdk.org/dev/patchwork/patch/25705/

v2:
- Local static functions replaced by corresponding new
  functions in i40e base code
- Test-pmd command added


Andrey Chilikin (2):
  net/i40e: extended list of operations for ddp processing
  app/testpmd: enable ddp remove profile feature

 app/test-pmd/cmdline.c                      | 103 ++++++++++++++++++++++++++--
 app/test-pmd/config.c                       |  21 ++++++
 app/test-pmd/testpmd.h                      |   1 +
 doc/guides/testpmd_app_ug/testpmd_funcs.rst |   7 ++
 drivers/net/i40e/rte_pmd_i40e.c             |  87 ++++++++++++++++-------
 drivers/net/i40e/rte_pmd_i40e.h             |   6 +-
 6 files changed, 191 insertions(+), 34 deletions(-)

-- 
2.13.0

^ permalink raw reply	[flat|nested] 17+ messages in thread

* [dpdk-dev] [PATCH v2 1/2] net/i40e: extended list of operations for ddp processing
  2017-05-27 16:04 [dpdk-dev] [PATCH] net/i40e: extended list of operations for ddp processing Andrey Chilikin
  2017-06-27  8:18 ` [dpdk-dev] [PATCH v2 0/2] " Andrey Chilikin
@ 2017-06-27  8:18 ` Andrey Chilikin
  2017-06-27  8:18 ` [dpdk-dev] [PATCH v2 2/2] app/testpmd: enable ddp remove profile feature Andrey Chilikin
                   ` (6 subsequent siblings)
  8 siblings, 0 replies; 17+ messages in thread
From: Andrey Chilikin @ 2017-06-27  8:18 UTC (permalink / raw)
  To: dev; +Cc: beilei.xing, jingjing.wu, Andrey Chilikin

This patch adds ability to remove already loaded profile
or write profile without registering it

Signed-off-by: Andrey Chilikin <andrey.chilikin@intel.com>
---
 drivers/net/i40e/rte_pmd_i40e.c | 87 +++++++++++++++++++++++++++++------------
 drivers/net/i40e/rte_pmd_i40e.h |  6 ++-
 2 files changed, 66 insertions(+), 27 deletions(-)

diff --git a/drivers/net/i40e/rte_pmd_i40e.c b/drivers/net/i40e/rte_pmd_i40e.c
index f7ce62b..e292903 100644
--- a/drivers/net/i40e/rte_pmd_i40e.c
+++ b/drivers/net/i40e/rte_pmd_i40e.c
@@ -1557,11 +1557,7 @@ i40e_check_profile_info(uint8_t port, uint8_t *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_ddp_version)) &&
-		    !memcmp(&pinfo->name, &p->name,
-			    I40E_DDP_NAME_SIZE)) {
+		if (pinfo->track_id == p->track_id) {
 			PMD_DRV_LOG(INFO, "Profile exists.");
 			rte_free(buff);
 			return 1;
@@ -1587,6 +1583,13 @@ rte_pmd_i40e_process_ddp_package(uint8_t port, uint8_t *buff,
 	int is_exist;
 	enum i40e_status_code status = I40E_SUCCESS;
 
+	if (op != RTE_PMD_I40E_PKG_OP_WR_ADD &&
+		op != RTE_PMD_I40E_PKG_OP_WR_ONLY &&
+		op != RTE_PMD_I40E_PKG_OP_WR_DEL) {
+		PMD_DRV_LOG(ERR, "Operation not supported.");
+		return -ENOTSUP;
+	}
+
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
 
 	dev = &rte_eth_devices[port];
@@ -1623,6 +1626,10 @@ rte_pmd_i40e_process_ddp_package(uint8_t port, uint8_t *buff,
 		return -EINVAL;
 	}
 	track_id = ((struct i40e_metadata_segment *)metadata_seg_hdr)->track_id;
+	if (track_id == I40E_DDP_TRACKID_INVALID) {
+		PMD_DRV_LOG(ERR, "Invalid track_id");
+		return -EINVAL;
+	}
 
 	/* Find profile segment */
 	profile_seg_hdr = i40e_find_segment_in_package(SEGMENT_TYPE_I40E,
@@ -1642,40 +1649,68 @@ rte_pmd_i40e_process_ddp_package(uint8_t port, uint8_t *buff,
 		return -EINVAL;
 	}
 
+	/* Check if the profile already loaded */
+	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,
+		op == RTE_PMD_I40E_PKG_OP_WR_ADD);
+	is_exist = i40e_check_profile_info(port, profile_info_sec);
+	if (is_exist < 0) {
+		PMD_DRV_LOG(ERR, "Failed to check profile.");
+		rte_free(profile_info_sec);
+		return -EINVAL;
+	}
+
 	if (op == RTE_PMD_I40E_PKG_OP_WR_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 > 0) {
+		if (is_exist) {
 			PMD_DRV_LOG(ERR, "Profile already exists.");
 			rte_free(profile_info_sec);
-			return 1;
-		} else if (is_exist < 0) {
-			PMD_DRV_LOG(ERR, "Failed to check profile.");
+			return -EEXIST;
+		}
+	} else if (op == RTE_PMD_I40E_PKG_OP_WR_DEL) {
+		if (!is_exist) {
+			PMD_DRV_LOG(ERR, "Profile does not exist.");
 			rte_free(profile_info_sec);
-			return -EINVAL;
+			return -EACCES;
 		}
+	}
 
-		/* Write profile to HW */
+	if (op == RTE_PMD_I40E_PKG_OP_WR_DEL) {
+		status = i40e_rollback_profile(
+			hw,
+			(struct i40e_profile_segment *)profile_seg_hdr,
+			track_id);
+		if (status) {
+			PMD_DRV_LOG(ERR, "Failed to write profile for delete.");
+			rte_free(profile_info_sec);
+			return status;
+		}
+	}
+	else {
 		status = i40e_write_profile(
-				hw,
-				(struct i40e_profile_segment *)profile_seg_hdr,
-				track_id);
+			hw,
+			(struct i40e_profile_segment *)profile_seg_hdr,
+			track_id);
 		if (status) {
-			PMD_DRV_LOG(ERR, "Failed to write profile.");
+			if (op == RTE_PMD_I40E_PKG_OP_WR_ADD)
+				PMD_DRV_LOG(ERR, "Failed to write profile for add.");
+			else
+				PMD_DRV_LOG(ERR, "Failed to write profile.");
 			rte_free(profile_info_sec);
 			return status;
 		}
+	}
 
-		/* Add profile info to info list */
+	if (track_id && (op != RTE_PMD_I40E_PKG_OP_WR_ONLY)) {
+		/* Modify loaded profiles 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, "Operation not supported.");
+		if (status) {
+			if (op == RTE_PMD_I40E_PKG_OP_WR_ADD)
+				PMD_DRV_LOG(ERR, "Failed to add profile to info list.");
+			else
+				PMD_DRV_LOG(ERR, "Failed to delete profile from info list.");
+		}
 	}
 
 	rte_free(profile_info_sec);
diff --git a/drivers/net/i40e/rte_pmd_i40e.h b/drivers/net/i40e/rte_pmd_i40e.h
index cbe742e..09b2ace 100644
--- a/drivers/net/i40e/rte_pmd_i40e.h
+++ b/drivers/net/i40e/rte_pmd_i40e.h
@@ -71,6 +71,8 @@ struct rte_pmd_i40e_mb_event_param {
 enum rte_pmd_i40e_package_op {
 	RTE_PMD_I40E_PKG_OP_UNDEFINED = 0,
 	RTE_PMD_I40E_PKG_OP_WR_ADD,   /**< load package and add to info list */
+	RTE_PMD_I40E_PKG_OP_WR_DEL, /** load package and delete from info list */
+	RTE_PMD_I40E_PKG_OP_WR_ONLY, /**< load package without modifying info list */
 	RTE_PMD_I40E_PKG_OP_MAX = 32
 };
 
@@ -492,7 +494,9 @@ int rte_pmd_i40e_set_tc_strict_prio(uint8_t port, uint8_t tc_map);
  *   - (0) if successful.
  *   - (-ENODEV) if *port* invalid.
  *   - (-EINVAL) if bad parameter.
- *   - (1) if profile exists.
+ *   - (-EEXIST) if profile exists.
+ *   - (-EACCES) if profile does not exist.
+ *   - (-ENOTSUP) if operation not supported.
  */
 int rte_pmd_i40e_process_ddp_package(uint8_t port, uint8_t *buff,
 				     uint32_t size,
-- 
2.13.0

^ permalink raw reply	[flat|nested] 17+ messages in thread

* [dpdk-dev] [PATCH v2 2/2] app/testpmd: enable ddp remove profile feature
  2017-05-27 16:04 [dpdk-dev] [PATCH] net/i40e: extended list of operations for ddp processing Andrey Chilikin
  2017-06-27  8:18 ` [dpdk-dev] [PATCH v2 0/2] " Andrey Chilikin
  2017-06-27  8:18 ` [dpdk-dev] [PATCH v2 1/2] " Andrey Chilikin
@ 2017-06-27  8:18 ` Andrey Chilikin
  2017-06-27  9:55   ` Ferruh Yigit
  2017-06-27 13:35 ` [dpdk-dev] [PATCH v3 0/2] net/i40e: extended list of operations for ddp processing Andrey Chilikin
                   ` (5 subsequent siblings)
  8 siblings, 1 reply; 17+ messages in thread
From: Andrey Chilikin @ 2017-06-27  8:18 UTC (permalink / raw)
  To: dev; +Cc: beilei.xing, jingjing.wu, Andrey Chilikin

New command 'ddp del (port) (profile_path)' removes previously
loaded profile and deletes it from the list of the loaded profiles.

Signed-off-by: Andrey Chilikin <andrey.chilikin@intel.com>
---
 app/test-pmd/cmdline.c                      | 103 ++++++++++++++++++++++++++--
 app/test-pmd/config.c                       |  21 ++++++
 app/test-pmd/testpmd.h                      |   1 +
 doc/guides/testpmd_app_ug/testpmd_funcs.rst |   7 ++
 4 files changed, 125 insertions(+), 7 deletions(-)

diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
index 0afac68..73baaa6 100644
--- a/app/test-pmd/cmdline.c
+++ b/app/test-pmd/cmdline.c
@@ -602,9 +602,12 @@ static void cmd_help_long_parsed(void *parsed_result,
 			"E-tag set filter del e-tag-id (value) port (port_id)\n"
 			"    Delete an E-tag forwarding filter on a port\n\n"
 
-			"ddp add (port_id) (profile_path)\n"
+			"ddp add (port_id) (profile_path[,output_path])\n"
 			"    Load a profile package on a port\n\n"
 
+			"ddp del (port_id) (profile_path)\n"
+			"    Delete a profile package from a port\n\n"
+
 			"ptype mapping get (port_id) (valid_only)\n"
 			"    Get ptype mapping on a port\n\n"
 
@@ -12860,6 +12863,9 @@ cmd_ddp_add_parsed(
 	struct cmd_ddp_add_result *res = parsed_result;
 	uint8_t *buff;
 	uint32_t size;
+	char *filepath;
+	char *file_fld[2];
+	int file_num;
 	int ret = -ENOTSUP;
 
 	if (res->port_id > nb_ports) {
@@ -12872,9 +12878,18 @@ cmd_ddp_add_parsed(
 		return;
 	}
 
-	buff = open_ddp_package_file(res->filepath, &size);
-	if (!buff)
+	filepath = strdup(res->filepath);
+	if (filepath == NULL) {
+		printf("Failed to allocate memory\n");
 		return;
+	}
+	file_num = rte_strsplit(filepath, strlen(filepath), file_fld, 2, ',');
+
+	buff = open_ddp_package_file(file_fld[0], &size);
+	if (!buff) {
+		free((void *)filepath);
+		return;
+	}
 
 #ifdef RTE_LIBRTE_I40E_PMD
 	if (ret == -ENOTSUP)
@@ -12883,18 +12898,21 @@ cmd_ddp_add_parsed(
 					       RTE_PMD_I40E_PKG_OP_WR_ADD);
 #endif
 
-	if (ret < 0)
-		printf("Failed to load profile.\n");
-	else if (ret > 0)
+	if (ret == -EEXIST)
 		printf("Profile has already existed.\n");
+	else if (ret < 0)
+		printf("Failed to load profile.\n");
+	else if (file_num == 2)
+		save_ddp_package_file(file_fld[1], buff, size);
 
 	close_ddp_package_file(buff);
+	free((void *)filepath);
 }
 
 cmdline_parse_inst_t cmd_ddp_add = {
 	.f = cmd_ddp_add_parsed,
 	.data = NULL,
-	.help_str = "ddp add <port_id> <profile_path>",
+	.help_str = "ddp add <port_id> <profile_path[,output_path]>",
 	.tokens = {
 		(void *)&cmd_ddp_add_ddp,
 		(void *)&cmd_ddp_add_add,
@@ -12904,6 +12922,76 @@ cmdline_parse_inst_t cmd_ddp_add = {
 	},
 };
 
+/* Delete dynamic device personalization*/
+struct cmd_ddp_del_result {
+	cmdline_fixed_string_t ddp;
+	cmdline_fixed_string_t del;
+	uint8_t port_id;
+	char filepath[];
+};
+
+cmdline_parse_token_string_t cmd_ddp_del_ddp =
+	TOKEN_STRING_INITIALIZER(struct cmd_ddp_del_result, ddp, "ddp");
+cmdline_parse_token_string_t cmd_ddp_del_del =
+	TOKEN_STRING_INITIALIZER(struct cmd_ddp_del_result, del, "del");
+cmdline_parse_token_num_t cmd_ddp_del_port_id =
+	TOKEN_NUM_INITIALIZER(struct cmd_ddp_del_result, port_id, UINT8);
+cmdline_parse_token_string_t cmd_ddp_del_filepath =
+	TOKEN_STRING_INITIALIZER(struct cmd_ddp_del_result, filepath, NULL);
+
+static void
+cmd_ddp_del_parsed(
+	void *parsed_result,
+	__attribute__((unused)) struct cmdline *cl,
+	__attribute__((unused)) void *data)
+{
+	struct cmd_ddp_del_result *res = parsed_result;
+	uint8_t *buff;
+	uint32_t size;
+	int ret = -ENOTSUP;
+
+	if (res->port_id > nb_ports) {
+		printf("Invalid port, range is [0, %d]\n", nb_ports - 1);
+		return;
+	}
+
+	if (!all_ports_stopped()) {
+		printf("Please stop all ports first\n");
+		return;
+	}
+
+	buff = open_ddp_package_file(res->filepath, &size);
+	if (!buff)
+		return;
+
+#ifdef RTE_LIBRTE_I40E_PMD
+	if (ret == -ENOTSUP)
+		ret = rte_pmd_i40e_process_ddp_package(res->port_id,
+					       buff, size,
+					       RTE_PMD_I40E_PKG_OP_WR_DEL);
+#endif
+
+	if (ret == -EACCES)
+		printf("Profile does not exist.\n");
+	else if (ret < 0)
+		printf("Failed to delete profile.\n");
+
+	close_ddp_package_file(buff);
+}
+
+cmdline_parse_inst_t cmd_ddp_del = {
+	.f = cmd_ddp_del_parsed,
+	.data = NULL,
+	.help_str = "ddp del <port_id> <profile_path>",
+	.tokens = {
+		(void *)&cmd_ddp_del_ddp,
+		(void *)&cmd_ddp_del_del,
+		(void *)&cmd_ddp_del_port_id,
+		(void *)&cmd_ddp_del_filepath,
+		NULL,
+	},
+};
+
 /* Get dynamic device personalization profile info list*/
 #define PROFILE_INFO_SIZE 48
 #define MAX_PROFILE_NUM 16
@@ -13747,6 +13835,7 @@ cmdline_parse_ctx_t main_ctx[] = {
 	(cmdline_parse_inst_t *)&cmd_strict_link_prio,
 	(cmdline_parse_inst_t *)&cmd_tc_min_bw,
 	(cmdline_parse_inst_t *)&cmd_ddp_add,
+	(cmdline_parse_inst_t *)&cmd_ddp_del,
 	(cmdline_parse_inst_t *)&cmd_ddp_get_list,
 	(cmdline_parse_inst_t *)&cmd_show_vf_stats,
 	(cmdline_parse_inst_t *)&cmd_clear_vf_stats,
diff --git a/app/test-pmd/config.c b/app/test-pmd/config.c
index 4d873cd..a4606d3 100644
--- a/app/test-pmd/config.c
+++ b/app/test-pmd/config.c
@@ -3310,6 +3310,27 @@ open_ddp_package_file(const char *file_path, uint32_t *size)
 }
 
 int
+save_ddp_package_file(const char *file_path, uint8_t *buf, uint32_t size)
+{
+	FILE *fh = fopen(file_path, "wb");
+
+	if (fh == NULL) {
+		printf("%s: Failed to open %s\n", __func__, file_path);
+		return -1;
+	}
+
+	if (fwrite(buf, 1, size, fh) != size) {
+		fclose(fh);
+		printf("%s: File write operation failed\n", __func__);
+		return -1;
+	}
+
+	fclose(fh);
+
+	return 0;
+}
+
+int
 close_ddp_package_file(uint8_t *buf)
 {
 	if (buf) {
diff --git a/app/test-pmd/testpmd.h b/app/test-pmd/testpmd.h
index e6c43ba..107a1b2 100644
--- a/app/test-pmd/testpmd.h
+++ b/app/test-pmd/testpmd.h
@@ -632,6 +632,7 @@ void mcast_addr_remove(uint8_t port_id, struct ether_addr *mc_addr);
 void port_dcb_info_display(uint8_t port_id);
 
 uint8_t *open_ddp_package_file(const char *file_path, uint32_t *size);
+int save_ddp_package_file(const char *file_path, uint8_t *buf, uint32_t size);
 int close_ddp_package_file(uint8_t *buf);
 
 enum print_warning {
diff --git a/doc/guides/testpmd_app_ug/testpmd_funcs.rst b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
index 0e50c10..4de61f6 100644
--- a/doc/guides/testpmd_app_ug/testpmd_funcs.rst
+++ b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
@@ -1211,6 +1211,13 @@ Add an E-tag forwarding filter on a port::
 Delete an E-tag forwarding filter on a port::
    testpmd> E-tag set filter del e-tag-id (value) port (port_id)
 
+ddp del
+~~~~~~~
+
+Delete a dynamic device personalization package::
+
+   testpmd> ddp del (port_id) (package_path)
+
 ptype mapping
 ~~~~~~~~~~~~~
 
-- 
2.13.0

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [dpdk-dev] [PATCH v2 2/2] app/testpmd: enable ddp remove profile feature
  2017-06-27  8:18 ` [dpdk-dev] [PATCH v2 2/2] app/testpmd: enable ddp remove profile feature Andrey Chilikin
@ 2017-06-27  9:55   ` Ferruh Yigit
  0 siblings, 0 replies; 17+ messages in thread
From: Ferruh Yigit @ 2017-06-27  9:55 UTC (permalink / raw)
  To: Andrey Chilikin, dev; +Cc: beilei.xing, jingjing.wu

On 6/27/2017 9:18 AM, Andrey Chilikin wrote:
> New command 'ddp del (port) (profile_path)' removes previously
> loaded profile and deletes it from the list of the loaded profiles.
> 
> Signed-off-by: Andrey Chilikin <andrey.chilikin@intel.com>

<...>

> @@ -12860,6 +12863,9 @@ cmd_ddp_add_parsed(
>  	struct cmd_ddp_add_result *res = parsed_result;
>  	uint8_t *buff;
>  	uint32_t size;
> +	char *filepath;
> +	char *file_fld[2];
> +	int file_num;
>  	int ret = -ENOTSUP;
>  
>  	if (res->port_id > nb_ports) {
> @@ -12872,9 +12878,18 @@ cmd_ddp_add_parsed(
>  		return;
>  	}
>  
> -	buff = open_ddp_package_file(res->filepath, &size);
> -	if (!buff)
> +	filepath = strdup(res->filepath);
> +	if (filepath == NULL) {
> +		printf("Failed to allocate memory\n");
>  		return;
> +	}
> +	file_num = rte_strsplit(filepath, strlen(filepath), file_fld, 2, ',');
> +
> +	buff = open_ddp_package_file(file_fld[0], &size);
> +	if (!buff) {
> +		free((void *)filepath);
> +		return;
> +	}

<...>

Can you please export ddp_add related changes into different patch?

Thanks,
ferruh

^ permalink raw reply	[flat|nested] 17+ messages in thread

* [dpdk-dev] [PATCH v3 0/2] net/i40e: extended list of operations for ddp processing
  2017-05-27 16:04 [dpdk-dev] [PATCH] net/i40e: extended list of operations for ddp processing Andrey Chilikin
                   ` (2 preceding siblings ...)
  2017-06-27  8:18 ` [dpdk-dev] [PATCH v2 2/2] app/testpmd: enable ddp remove profile feature Andrey Chilikin
@ 2017-06-27 13:35 ` Andrey Chilikin
  2017-06-27 13:35 ` [dpdk-dev] [PATCH v3 1/2] " Andrey Chilikin
                   ` (4 subsequent siblings)
  8 siblings, 0 replies; 17+ messages in thread
From: Andrey Chilikin @ 2017-06-27 13:35 UTC (permalink / raw)
  To: dev; +Cc: beilei.xing, jingjing.wu, Andrey Chilikin

This patch adds two new operations for dynamic device personalisation:
* remove already loaded profile and delete it from the list
* write profile without registering it

This patchset depends on:
[PATCH v2 00/16] net/i40e: base code update
http://dpdk.org/ml/archives/dev/2017-June/068732.html
http://dpdk.org/dev/patchwork/patch/25705/

v3:
- move testpmd updates to 'ddp add' command to a separate
  patch http://dpdk.org/dev/patchwork/patch/25779/

v2:
- Local static functions replaced by corresponding new
  functions in i40e base code
- Test-pmd command added


Andrey Chilikin (2):
  net/i40e: extended list of operations for ddp processing
  app/testpmd: enable ddp remove profile feature

 app/test-pmd/cmdline.c                      | 74 ++++++++++++++++++++++++
 doc/guides/testpmd_app_ug/testpmd_funcs.rst |  7 +++
 drivers/net/i40e/rte_pmd_i40e.c             | 87 ++++++++++++++++++++---------
 drivers/net/i40e/rte_pmd_i40e.h             |  6 +-
 4 files changed, 147 insertions(+), 27 deletions(-)

-- 
2.13.0

^ permalink raw reply	[flat|nested] 17+ messages in thread

* [dpdk-dev] [PATCH v3 1/2] net/i40e: extended list of operations for ddp processing
  2017-05-27 16:04 [dpdk-dev] [PATCH] net/i40e: extended list of operations for ddp processing Andrey Chilikin
                   ` (3 preceding siblings ...)
  2017-06-27 13:35 ` [dpdk-dev] [PATCH v3 0/2] net/i40e: extended list of operations for ddp processing Andrey Chilikin
@ 2017-06-27 13:35 ` Andrey Chilikin
  2017-06-28  6:57   ` Xing, Beilei
  2017-06-27 13:35 ` [dpdk-dev] [PATCH v3 2/2] app/testpmd: enable ddp remove profile feature Andrey Chilikin
                   ` (3 subsequent siblings)
  8 siblings, 1 reply; 17+ messages in thread
From: Andrey Chilikin @ 2017-06-27 13:35 UTC (permalink / raw)
  To: dev; +Cc: beilei.xing, jingjing.wu, Andrey Chilikin

This patch adds ability to remove already loaded profile
or write profile without registering it

Signed-off-by: Andrey Chilikin <andrey.chilikin@intel.com>
---
 drivers/net/i40e/rte_pmd_i40e.c | 87 +++++++++++++++++++++++++++++------------
 drivers/net/i40e/rte_pmd_i40e.h |  6 ++-
 2 files changed, 66 insertions(+), 27 deletions(-)

diff --git a/drivers/net/i40e/rte_pmd_i40e.c b/drivers/net/i40e/rte_pmd_i40e.c
index 45cdcfaa3..ca2515d96 100644
--- a/drivers/net/i40e/rte_pmd_i40e.c
+++ b/drivers/net/i40e/rte_pmd_i40e.c
@@ -1554,11 +1554,7 @@ i40e_check_profile_info(uint8_t port, uint8_t *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_ddp_version)) &&
-		    !memcmp(&pinfo->name, &p->name,
-			    I40E_DDP_NAME_SIZE)) {
+		if (pinfo->track_id == p->track_id) {
 			PMD_DRV_LOG(INFO, "Profile exists.");
 			rte_free(buff);
 			return 1;
@@ -1584,6 +1580,13 @@ rte_pmd_i40e_process_ddp_package(uint8_t port, uint8_t *buff,
 	int is_exist;
 	enum i40e_status_code status = I40E_SUCCESS;
 
+	if (op != RTE_PMD_I40E_PKG_OP_WR_ADD &&
+		op != RTE_PMD_I40E_PKG_OP_WR_ONLY &&
+		op != RTE_PMD_I40E_PKG_OP_WR_DEL) {
+		PMD_DRV_LOG(ERR, "Operation not supported.");
+		return -ENOTSUP;
+	}
+
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
 
 	dev = &rte_eth_devices[port];
@@ -1620,6 +1623,10 @@ rte_pmd_i40e_process_ddp_package(uint8_t port, uint8_t *buff,
 		return -EINVAL;
 	}
 	track_id = ((struct i40e_metadata_segment *)metadata_seg_hdr)->track_id;
+	if (track_id == I40E_DDP_TRACKID_INVALID) {
+		PMD_DRV_LOG(ERR, "Invalid track_id");
+		return -EINVAL;
+	}
 
 	/* Find profile segment */
 	profile_seg_hdr = i40e_find_segment_in_package(SEGMENT_TYPE_I40E,
@@ -1639,40 +1646,68 @@ rte_pmd_i40e_process_ddp_package(uint8_t port, uint8_t *buff,
 		return -EINVAL;
 	}
 
+	/* Check if the profile already loaded */
+	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,
+		op == RTE_PMD_I40E_PKG_OP_WR_ADD);
+	is_exist = i40e_check_profile_info(port, profile_info_sec);
+	if (is_exist < 0) {
+		PMD_DRV_LOG(ERR, "Failed to check profile.");
+		rte_free(profile_info_sec);
+		return -EINVAL;
+	}
+
 	if (op == RTE_PMD_I40E_PKG_OP_WR_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 > 0) {
+		if (is_exist) {
 			PMD_DRV_LOG(ERR, "Profile already exists.");
 			rte_free(profile_info_sec);
-			return 1;
-		} else if (is_exist < 0) {
-			PMD_DRV_LOG(ERR, "Failed to check profile.");
+			return -EEXIST;
+		}
+	} else if (op == RTE_PMD_I40E_PKG_OP_WR_DEL) {
+		if (!is_exist) {
+			PMD_DRV_LOG(ERR, "Profile does not exist.");
 			rte_free(profile_info_sec);
-			return -EINVAL;
+			return -EACCES;
 		}
+	}
 
-		/* Write profile to HW */
+	if (op == RTE_PMD_I40E_PKG_OP_WR_DEL) {
+		status = i40e_rollback_profile(
+			hw,
+			(struct i40e_profile_segment *)profile_seg_hdr,
+			track_id);
+		if (status) {
+			PMD_DRV_LOG(ERR, "Failed to write profile for delete.");
+			rte_free(profile_info_sec);
+			return status;
+		}
+	}
+	else {
 		status = i40e_write_profile(
-				hw,
-				(struct i40e_profile_segment *)profile_seg_hdr,
-				track_id);
+			hw,
+			(struct i40e_profile_segment *)profile_seg_hdr,
+			track_id);
 		if (status) {
-			PMD_DRV_LOG(ERR, "Failed to write profile.");
+			if (op == RTE_PMD_I40E_PKG_OP_WR_ADD)
+				PMD_DRV_LOG(ERR, "Failed to write profile for add.");
+			else
+				PMD_DRV_LOG(ERR, "Failed to write profile.");
 			rte_free(profile_info_sec);
 			return status;
 		}
+	}
 
-		/* Add profile info to info list */
+	if (track_id && (op != RTE_PMD_I40E_PKG_OP_WR_ONLY)) {
+		/* Modify loaded profiles 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, "Operation not supported.");
+		if (status) {
+			if (op == RTE_PMD_I40E_PKG_OP_WR_ADD)
+				PMD_DRV_LOG(ERR, "Failed to add profile to info list.");
+			else
+				PMD_DRV_LOG(ERR, "Failed to delete profile from info list.");
+		}
 	}
 
 	rte_free(profile_info_sec);
diff --git a/drivers/net/i40e/rte_pmd_i40e.h b/drivers/net/i40e/rte_pmd_i40e.h
index 4a867ad6f..356fa89d7 100644
--- a/drivers/net/i40e/rte_pmd_i40e.h
+++ b/drivers/net/i40e/rte_pmd_i40e.h
@@ -71,6 +71,8 @@ struct rte_pmd_i40e_mb_event_param {
 enum rte_pmd_i40e_package_op {
 	RTE_PMD_I40E_PKG_OP_UNDEFINED = 0,
 	RTE_PMD_I40E_PKG_OP_WR_ADD,   /**< load package and add to info list */
+	RTE_PMD_I40E_PKG_OP_WR_DEL, /**< load package and delete from info list */
+	RTE_PMD_I40E_PKG_OP_WR_ONLY, /**< load package without modifying info list */
 	RTE_PMD_I40E_PKG_OP_MAX = 32
 };
 
@@ -517,7 +519,9 @@ int rte_pmd_i40e_set_tc_strict_prio(uint8_t port, uint8_t tc_map);
  *   - (0) if successful.
  *   - (-ENODEV) if *port* invalid.
  *   - (-EINVAL) if bad parameter.
- *   - (1) if profile exists.
+ *   - (-EEXIST) if profile exists.
+ *   - (-EACCES) if profile does not exist.
+ *   - (-ENOTSUP) if operation not supported.
  */
 int rte_pmd_i40e_process_ddp_package(uint8_t port, uint8_t *buff,
 				     uint32_t size,
-- 
2.13.0

^ permalink raw reply	[flat|nested] 17+ messages in thread

* [dpdk-dev] [PATCH v3 2/2] app/testpmd: enable ddp remove profile feature
  2017-05-27 16:04 [dpdk-dev] [PATCH] net/i40e: extended list of operations for ddp processing Andrey Chilikin
                   ` (4 preceding siblings ...)
  2017-06-27 13:35 ` [dpdk-dev] [PATCH v3 1/2] " Andrey Chilikin
@ 2017-06-27 13:35 ` Andrey Chilikin
  2017-06-28  6:40   ` Xing, Beilei
  2017-06-28  8:15 ` [dpdk-dev] [PATCH v4 0/2] net/i40e: extended list of operations for ddp processing Andrey Chilikin
                   ` (2 subsequent siblings)
  8 siblings, 1 reply; 17+ messages in thread
From: Andrey Chilikin @ 2017-06-27 13:35 UTC (permalink / raw)
  To: dev; +Cc: beilei.xing, jingjing.wu, Andrey Chilikin

New command 'ddp del (port) (profile_path)' removes previously
loaded profile and deletes it from the list of the loaded profiles.

Signed-off-by: Andrey Chilikin <andrey.chilikin@intel.com>
---
 app/test-pmd/cmdline.c                      | 74 +++++++++++++++++++++++++++++
 doc/guides/testpmd_app_ug/testpmd_funcs.rst |  7 +++
 2 files changed, 81 insertions(+)

diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
index 632d6f03f..425ffccb9 100644
--- a/app/test-pmd/cmdline.c
+++ b/app/test-pmd/cmdline.c
@@ -606,6 +606,9 @@ static void cmd_help_long_parsed(void *parsed_result,
 			"ddp add (port_id) (profile_path)\n"
 			"    Load a profile package on a port\n\n"
 
+			"ddp del (port_id) (profile_path)\n"
+			"    Delete a profile package from a port\n\n"
+
 			"ptype mapping get (port_id) (valid_only)\n"
 			"    Get ptype mapping on a port\n\n"
 
@@ -12999,6 +13002,76 @@ cmdline_parse_inst_t cmd_ddp_add = {
 	},
 };
 
+/* Delete dynamic device personalization*/
+struct cmd_ddp_del_result {
+	cmdline_fixed_string_t ddp;
+	cmdline_fixed_string_t del;
+	uint8_t port_id;
+	char filepath[];
+};
+
+cmdline_parse_token_string_t cmd_ddp_del_ddp =
+	TOKEN_STRING_INITIALIZER(struct cmd_ddp_del_result, ddp, "ddp");
+cmdline_parse_token_string_t cmd_ddp_del_del =
+	TOKEN_STRING_INITIALIZER(struct cmd_ddp_del_result, del, "del");
+cmdline_parse_token_num_t cmd_ddp_del_port_id =
+	TOKEN_NUM_INITIALIZER(struct cmd_ddp_del_result, port_id, UINT8);
+cmdline_parse_token_string_t cmd_ddp_del_filepath =
+	TOKEN_STRING_INITIALIZER(struct cmd_ddp_del_result, filepath, NULL);
+
+static void
+cmd_ddp_del_parsed(
+	void *parsed_result,
+	__attribute__((unused)) struct cmdline *cl,
+	__attribute__((unused)) void *data)
+{
+	struct cmd_ddp_del_result *res = parsed_result;
+	uint8_t *buff;
+	uint32_t size;
+	int ret = -ENOTSUP;
+
+	if (res->port_id > nb_ports) {
+		printf("Invalid port, range is [0, %d]\n", nb_ports - 1);
+		return;
+	}
+
+	if (!all_ports_stopped()) {
+		printf("Please stop all ports first\n");
+		return;
+	}
+
+	buff = open_ddp_package_file(res->filepath, &size);
+	if (!buff)
+		return;
+
+#ifdef RTE_LIBRTE_I40E_PMD
+	if (ret == -ENOTSUP)
+		ret = rte_pmd_i40e_process_ddp_package(res->port_id,
+					       buff, size,
+					       RTE_PMD_I40E_PKG_OP_WR_DEL);
+#endif
+
+	if (ret == -EACCES)
+		printf("Profile does not exist.\n");
+	else if (ret < 0)
+		printf("Failed to delete profile.\n");
+
+	close_ddp_package_file(buff);
+}
+
+cmdline_parse_inst_t cmd_ddp_del = {
+	.f = cmd_ddp_del_parsed,
+	.data = NULL,
+	.help_str = "ddp del <port_id> <profile_path>",
+	.tokens = {
+		(void *)&cmd_ddp_del_ddp,
+		(void *)&cmd_ddp_del_del,
+		(void *)&cmd_ddp_del_port_id,
+		(void *)&cmd_ddp_del_filepath,
+		NULL,
+	},
+};
+
 /* Get dynamic device personalization profile info */
 struct cmd_ddp_info_result {
 	cmdline_fixed_string_t ddp;
@@ -13978,6 +14051,7 @@ cmdline_parse_ctx_t main_ctx[] = {
 	(cmdline_parse_inst_t *)&cmd_strict_link_prio,
 	(cmdline_parse_inst_t *)&cmd_tc_min_bw,
 	(cmdline_parse_inst_t *)&cmd_ddp_add,
+	(cmdline_parse_inst_t *)&cmd_ddp_del,
 	(cmdline_parse_inst_t *)&cmd_ddp_get_list,
 	(cmdline_parse_inst_t *)&cmd_ddp_get_info,
 	(cmdline_parse_inst_t *)&cmd_show_vf_stats,
diff --git a/doc/guides/testpmd_app_ug/testpmd_funcs.rst b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
index 18ee8a3fe..76809b859 100644
--- a/doc/guides/testpmd_app_ug/testpmd_funcs.rst
+++ b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
@@ -1232,6 +1232,13 @@ Load a dynamic device personalization (DDP) package::
 
    testpmd> ddp add (port_id) (package_path)
 
+ddp del
+~~~~~~~
+
+Delete a dynamic device personalization package::
+
+   testpmd> ddp del (port_id) (package_path)
+
 ptype mapping
 ~~~~~~~~~~~~~
 
-- 
2.13.0

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [dpdk-dev] [PATCH v3 2/2] app/testpmd: enable ddp remove profile feature
  2017-06-27 13:35 ` [dpdk-dev] [PATCH v3 2/2] app/testpmd: enable ddp remove profile feature Andrey Chilikin
@ 2017-06-28  6:40   ` Xing, Beilei
  0 siblings, 0 replies; 17+ messages in thread
From: Xing, Beilei @ 2017-06-28  6:40 UTC (permalink / raw)
  To: Chilikin, Andrey, dev; +Cc: Wu, Jingjing

> -----Original Message-----
> From: Chilikin, Andrey
> Sent: Tuesday, June 27, 2017 9:35 PM
> To: dev@dpdk.org
> Cc: Xing, Beilei <beilei.xing@intel.com>; Wu, Jingjing
> <jingjing.wu@intel.com>; Chilikin, Andrey <andrey.chilikin@intel.com>
> Subject: [PATCH v3 2/2] app/testpmd: enable ddp remove profile feature
> 
> New command 'ddp del (port) (profile_path)' removes previously loaded
> profile and deletes it from the list of the loaded profiles.
> 
> Signed-off-by: Andrey Chilikin <andrey.chilikin@intel.com>

Acked-by: Beilei Xing <beilei.xing@intel.com>

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [dpdk-dev] [PATCH v3 1/2] net/i40e: extended list of operations for ddp processing
  2017-06-27 13:35 ` [dpdk-dev] [PATCH v3 1/2] " Andrey Chilikin
@ 2017-06-28  6:57   ` Xing, Beilei
  2017-06-28  7:40     ` Chilikin, Andrey
  0 siblings, 1 reply; 17+ messages in thread
From: Xing, Beilei @ 2017-06-28  6:57 UTC (permalink / raw)
  To: Chilikin, Andrey, dev; +Cc: Wu, Jingjing

Hi Andrey,

> -----Original Message-----
> From: Chilikin, Andrey
> Sent: Tuesday, June 27, 2017 9:35 PM
> To: dev@dpdk.org
> Cc: Xing, Beilei <beilei.xing@intel.com>; Wu, Jingjing
> <jingjing.wu@intel.com>; Chilikin, Andrey <andrey.chilikin@intel.com>
> Subject: [PATCH v3 1/2] net/i40e: extended list of operations for ddp
> processing
> 
> This patch adds ability to remove already loaded profile or write profile
> without registering it
> 
> Signed-off-by: Andrey Chilikin <andrey.chilikin@intel.com>
> ---
>  drivers/net/i40e/rte_pmd_i40e.c | 87
> +++++++++++++++++++++++++++++------------
>  drivers/net/i40e/rte_pmd_i40e.h |  6 ++-
>  2 files changed, 66 insertions(+), 27 deletions(-)
> 
> diff --git a/drivers/net/i40e/rte_pmd_i40e.c
> b/drivers/net/i40e/rte_pmd_i40e.c index 45cdcfaa3..ca2515d96 100644
> --- a/drivers/net/i40e/rte_pmd_i40e.c
> +++ b/drivers/net/i40e/rte_pmd_i40e.c
> @@ -1554,11 +1554,7 @@ i40e_check_profile_info(uint8_t port, uint8_t
> *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_ddp_version)) &&
> -		    !memcmp(&pinfo->name, &p->name,
> -			    I40E_DDP_NAME_SIZE)) {
> +		if (pinfo->track_id == p->track_id) {
>  			PMD_DRV_LOG(INFO, "Profile exists.");
>  			rte_free(buff);
>  			return 1;
> @@ -1584,6 +1580,13 @@ rte_pmd_i40e_process_ddp_package(uint8_t
> port, uint8_t *buff,
>  	int is_exist;
>  	enum i40e_status_code status = I40E_SUCCESS;
> 
> +	if (op != RTE_PMD_I40E_PKG_OP_WR_ADD &&
> +		op != RTE_PMD_I40E_PKG_OP_WR_ONLY &&
> +		op != RTE_PMD_I40E_PKG_OP_WR_DEL) {
> +		PMD_DRV_LOG(ERR, "Operation not supported.");
> +		return -ENOTSUP;
> +	}
> +
>  	RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
> 
>  	dev = &rte_eth_devices[port];
> @@ -1620,6 +1623,10 @@ rte_pmd_i40e_process_ddp_package(uint8_t
> port, uint8_t *buff,
>  		return -EINVAL;
>  	}
>  	track_id = ((struct i40e_metadata_segment *)metadata_seg_hdr)-
> >track_id;
> +	if (track_id == I40E_DDP_TRACKID_INVALID) {
> +		PMD_DRV_LOG(ERR, "Invalid track_id");
> +		return -EINVAL;
> +	}
> 
>  	/* Find profile segment */
>  	profile_seg_hdr =
> i40e_find_segment_in_package(SEGMENT_TYPE_I40E,
> @@ -1639,40 +1646,68 @@ rte_pmd_i40e_process_ddp_package(uint8_t
> port, uint8_t *buff,
>  		return -EINVAL;
>  	}
> 
> +	/* Check if the profile already loaded */
> +	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,
> +		op == RTE_PMD_I40E_PKG_OP_WR_ADD);
> +	is_exist = i40e_check_profile_info(port, profile_info_sec);
> +	if (is_exist < 0) {
> +		PMD_DRV_LOG(ERR, "Failed to check profile.");
> +		rte_free(profile_info_sec);
> +		return -EINVAL;
> +	}
> +
>  	if (op == RTE_PMD_I40E_PKG_OP_WR_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 > 0) {
> +		if (is_exist) {
>  			PMD_DRV_LOG(ERR, "Profile already exists.");
>  			rte_free(profile_info_sec);
> -			return 1;
> -		} else if (is_exist < 0) {
> -			PMD_DRV_LOG(ERR, "Failed to check profile.");
> +			return -EEXIST;
> +		}
> +	} else if (op == RTE_PMD_I40E_PKG_OP_WR_DEL) {
> +		if (!is_exist) {
> +			PMD_DRV_LOG(ERR, "Profile does not exist.");
>  			rte_free(profile_info_sec);
> -			return -EINVAL;
> +			return -EACCES;
>  		}
> +	}
> 
> -		/* Write profile to HW */
> +	if (op == RTE_PMD_I40E_PKG_OP_WR_DEL) {
> +		status = i40e_rollback_profile(
> +			hw,
> +			(struct i40e_profile_segment *)profile_seg_hdr,
> +			track_id);
> +		if (status) {
> +			PMD_DRV_LOG(ERR, "Failed to write profile for
> delete.");
> +			rte_free(profile_info_sec);
> +			return status;
> +		}
> +	}
> +	else {

Should be  } else {  here according to the coding style.

>  		status = i40e_write_profile(
> -				hw,
> -				(struct i40e_profile_segment
> *)profile_seg_hdr,
> -				track_id);
> +			hw,
> +			(struct i40e_profile_segment *)profile_seg_hdr,
> +			track_id);
>  		if (status) {
> -			PMD_DRV_LOG(ERR, "Failed to write profile.");
> +			if (op == RTE_PMD_I40E_PKG_OP_WR_ADD)
> +				PMD_DRV_LOG(ERR, "Failed to write profile
> for add.");
> +			else
> +				PMD_DRV_LOG(ERR, "Failed to write
> profile.");
>  			rte_free(profile_info_sec);
>  			return status;
>  		}
> +	}
> 
> -		/* Add profile info to info list */
> +	if (track_id && (op != RTE_PMD_I40E_PKG_OP_WR_ONLY)) {
> +		/* Modify loaded profiles 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, "Operation not supported.");
> +		if (status) {
> +			if (op == RTE_PMD_I40E_PKG_OP_WR_ADD)
> +				PMD_DRV_LOG(ERR, "Failed to add profile to
> info list.");
> +			else
> +				PMD_DRV_LOG(ERR, "Failed to delete profile
> from info list.");
> +		}
>  	}
> 
>  	rte_free(profile_info_sec);
> diff --git a/drivers/net/i40e/rte_pmd_i40e.h
> b/drivers/net/i40e/rte_pmd_i40e.h index 4a867ad6f..356fa89d7 100644
> --- a/drivers/net/i40e/rte_pmd_i40e.h
> +++ b/drivers/net/i40e/rte_pmd_i40e.h
> @@ -71,6 +71,8 @@ struct rte_pmd_i40e_mb_event_param {  enum
> rte_pmd_i40e_package_op {
>  	RTE_PMD_I40E_PKG_OP_UNDEFINED = 0,
>  	RTE_PMD_I40E_PKG_OP_WR_ADD,   /**< load package and add to
> info list */
> +	RTE_PMD_I40E_PKG_OP_WR_DEL, /**< load package and delete
> from info list */
> +	RTE_PMD_I40E_PKG_OP_WR_ONLY, /**< load package without
> modifying info
> +list */

The only difference between RTE_PMD_I40E_PKG_OP_WR_ADD and RTE_PMD_I40E_PKG_OP_WR_ONLY is if need to change info list, right? Is there any difference between the profiles added? Do we need another CLI in testpmd to indicate how/when we need to use RTE_PMD_I40E_PKG_OP_WR_ONLY?

Beilei

>  	RTE_PMD_I40E_PKG_OP_MAX = 32
>  };
> 
> @@ -517,7 +519,9 @@ int rte_pmd_i40e_set_tc_strict_prio(uint8_t port,
> uint8_t tc_map);
>   *   - (0) if successful.
>   *   - (-ENODEV) if *port* invalid.
>   *   - (-EINVAL) if bad parameter.
> - *   - (1) if profile exists.
> + *   - (-EEXIST) if profile exists.
> + *   - (-EACCES) if profile does not exist.
> + *   - (-ENOTSUP) if operation not supported.
>   */
>  int rte_pmd_i40e_process_ddp_package(uint8_t port, uint8_t *buff,
>  				     uint32_t size,
> --
> 2.13.0

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [dpdk-dev] [PATCH v3 1/2] net/i40e: extended list of operations for ddp processing
  2017-06-28  6:57   ` Xing, Beilei
@ 2017-06-28  7:40     ` Chilikin, Andrey
  2017-06-28  8:03       ` Xing, Beilei
  0 siblings, 1 reply; 17+ messages in thread
From: Chilikin, Andrey @ 2017-06-28  7:40 UTC (permalink / raw)
  To: Xing, Beilei, dev; +Cc: Wu, Jingjing

Hi Beilei,

> -----Original Message-----
> From: Xing, Beilei
> Sent: Wednesday, June 28, 2017 7:58 AM
> To: Chilikin, Andrey <andrey.chilikin@intel.com>; dev@dpdk.org
> Cc: Wu, Jingjing <jingjing.wu@intel.com>
> Subject: RE: [PATCH v3 1/2] net/i40e: extended list of operations for ddp
> processing
> 
> Hi Andrey,
> 
<snip>
> > +	}
> > +	else {
> 
> Should be  } else {  here according to the coding style.

Will fix in v4

> > --- a/drivers/net/i40e/rte_pmd_i40e.h
> > +++ b/drivers/net/i40e/rte_pmd_i40e.h
> > @@ -71,6 +71,8 @@ struct rte_pmd_i40e_mb_event_param {  enum
> > rte_pmd_i40e_package_op {
> >  	RTE_PMD_I40E_PKG_OP_UNDEFINED = 0,
> >  	RTE_PMD_I40E_PKG_OP_WR_ADD,   /**< load package and add to
> > info list */
> > +	RTE_PMD_I40E_PKG_OP_WR_DEL, /**< load package and delete
> > from info list */
> > +	RTE_PMD_I40E_PKG_OP_WR_ONLY, /**< load package without
> > modifying info
> > +list */
> 
> The only difference between RTE_PMD_I40E_PKG_OP_WR_ADD and
> RTE_PMD_I40E_PKG_OP_WR_ONLY is if need to change info list, right? Is there
> any difference between the profiles added? Do we need another CLI in testpmd
> to indicate how/when we need to use RTE_PMD_I40E_PKG_OP_WR_ONLY?
> 
I believe that existing testpmd CLI is enough for i40e as this 'if' statement
if (track_id && (op != RTE_PMD_I40E_PKG_OP_WR_ONLY)) {
will not register profiles with track_id == 0

> Beilei

Regards,
Andrey

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [dpdk-dev] [PATCH v3 1/2] net/i40e: extended list of operations for ddp processing
  2017-06-28  7:40     ` Chilikin, Andrey
@ 2017-06-28  8:03       ` Xing, Beilei
  0 siblings, 0 replies; 17+ messages in thread
From: Xing, Beilei @ 2017-06-28  8:03 UTC (permalink / raw)
  To: Chilikin, Andrey, dev; +Cc: Wu, Jingjing

Hi Andrey,

> -----Original Message-----
> From: Chilikin, Andrey
> Sent: Wednesday, June 28, 2017 3:40 PM
> To: Xing, Beilei <beilei.xing@intel.com>; dev@dpdk.org
> Cc: Wu, Jingjing <jingjing.wu@intel.com>
> Subject: RE: [PATCH v3 1/2] net/i40e: extended list of operations for ddp
> processing
> 
> Hi Beilei,
> 
> > -----Original Message-----
> > From: Xing, Beilei
> > Sent: Wednesday, June 28, 2017 7:58 AM
> > To: Chilikin, Andrey <andrey.chilikin@intel.com>; dev@dpdk.org
> > Cc: Wu, Jingjing <jingjing.wu@intel.com>
> > Subject: RE: [PATCH v3 1/2] net/i40e: extended list of operations for
> > ddp processing
> >
> > Hi Andrey,
> >
> <snip>
> > > +	}
> > > +	else {
> >
> > Should be  } else {  here according to the coding style.
> 
> Will fix in v4
> 
> > > --- a/drivers/net/i40e/rte_pmd_i40e.h
> > > +++ b/drivers/net/i40e/rte_pmd_i40e.h
> > > @@ -71,6 +71,8 @@ struct rte_pmd_i40e_mb_event_param {  enum
> > > rte_pmd_i40e_package_op {
> > >  	RTE_PMD_I40E_PKG_OP_UNDEFINED = 0,
> > >  	RTE_PMD_I40E_PKG_OP_WR_ADD,   /**< load package and add to
> > > info list */
> > > +	RTE_PMD_I40E_PKG_OP_WR_DEL, /**< load package and delete
> > > from info list */
> > > +	RTE_PMD_I40E_PKG_OP_WR_ONLY, /**< load package without
> > > modifying info
> > > +list */
> >
> > The only difference between RTE_PMD_I40E_PKG_OP_WR_ADD and
> > RTE_PMD_I40E_PKG_OP_WR_ONLY is if need to change info list, right? Is
> > there any difference between the profiles added? Do we need another
> > CLI in testpmd to indicate how/when we need to use
> RTE_PMD_I40E_PKG_OP_WR_ONLY?
> >
> I believe that existing testpmd CLI is enough for i40e as this 'if' statement if
> (track_id && (op != RTE_PMD_I40E_PKG_OP_WR_ONLY)) { will not register
> profiles with track_id == 0
> 

OK, so track_id=0 is for RTE_PMD_I40E_PKG_OP_WR_ONLY. From the patch, it seems we needn't new operation RTE_PMD_I40E_PKG_OP_WR_ONLY exposed to application as PMD can decide if register WR_ONLY profiles by track_id. 

^ permalink raw reply	[flat|nested] 17+ messages in thread

* [dpdk-dev] [PATCH v4 0/2] net/i40e: extended list of operations for ddp processing
  2017-05-27 16:04 [dpdk-dev] [PATCH] net/i40e: extended list of operations for ddp processing Andrey Chilikin
                   ` (5 preceding siblings ...)
  2017-06-27 13:35 ` [dpdk-dev] [PATCH v3 2/2] app/testpmd: enable ddp remove profile feature Andrey Chilikin
@ 2017-06-28  8:15 ` Andrey Chilikin
  2017-06-28  9:47   ` Ferruh Yigit
  2017-06-28  8:15 ` [dpdk-dev] [PATCH v4 1/2] " Andrey Chilikin
  2017-06-28  8:15 ` [dpdk-dev] [PATCH v4 2/2] app/testpmd: enable ddp remove profile feature Andrey Chilikin
  8 siblings, 1 reply; 17+ messages in thread
From: Andrey Chilikin @ 2017-06-28  8:15 UTC (permalink / raw)
  To: dev; +Cc: beilei.xing, jingjing.wu, Andrey Chilikin

This patch adds two new operations for dynamic device personalisation:
* remove already loaded profile and delete it from the list
* write profile without registering it

This patchset depends on:
[PATCH v2 00/16] net/i40e: base code update
http://dpdk.org/ml/archives/dev/2017-June/068732.html
http://dpdk.org/dev/patchwork/patch/25705/

v4:
- code style fixed in rte_pmd_i40e.c

v3:
- move testpmd updates to 'ddp add' command to a separate
  patch http://dpdk.org/dev/patchwork/patch/25779/

v2:
- Local static functions replaced by corresponding new
  functions in i40e base code
- Test-pmd command added

Andrey Chilikin (2):
  net/i40e: extended list of operations for ddp processing
  app/testpmd: enable ddp remove profile feature

 app/test-pmd/cmdline.c                      | 74 +++++++++++++++++++++++++
 doc/guides/testpmd_app_ug/testpmd_funcs.rst |  7 +++
 drivers/net/i40e/rte_pmd_i40e.c             | 86 ++++++++++++++++++++---------
 drivers/net/i40e/rte_pmd_i40e.h             |  6 +-
 4 files changed, 146 insertions(+), 27 deletions(-)

-- 
2.13.0

^ permalink raw reply	[flat|nested] 17+ messages in thread

* [dpdk-dev] [PATCH v4 1/2] net/i40e: extended list of operations for ddp processing
  2017-05-27 16:04 [dpdk-dev] [PATCH] net/i40e: extended list of operations for ddp processing Andrey Chilikin
                   ` (6 preceding siblings ...)
  2017-06-28  8:15 ` [dpdk-dev] [PATCH v4 0/2] net/i40e: extended list of operations for ddp processing Andrey Chilikin
@ 2017-06-28  8:15 ` Andrey Chilikin
  2017-06-28  8:25   ` Xing, Beilei
  2017-06-28  8:15 ` [dpdk-dev] [PATCH v4 2/2] app/testpmd: enable ddp remove profile feature Andrey Chilikin
  8 siblings, 1 reply; 17+ messages in thread
From: Andrey Chilikin @ 2017-06-28  8:15 UTC (permalink / raw)
  To: dev; +Cc: beilei.xing, jingjing.wu, Andrey Chilikin

This patch adds ability to remove already loaded profile
or write profile without registering it

Signed-off-by: Andrey Chilikin <andrey.chilikin@intel.com>
---
 drivers/net/i40e/rte_pmd_i40e.c | 86 ++++++++++++++++++++++++++++-------------
 drivers/net/i40e/rte_pmd_i40e.h |  6 ++-
 2 files changed, 65 insertions(+), 27 deletions(-)

diff --git a/drivers/net/i40e/rte_pmd_i40e.c b/drivers/net/i40e/rte_pmd_i40e.c
index 45cdcfaa3..467238891 100644
--- a/drivers/net/i40e/rte_pmd_i40e.c
+++ b/drivers/net/i40e/rte_pmd_i40e.c
@@ -1554,11 +1554,7 @@ i40e_check_profile_info(uint8_t port, uint8_t *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_ddp_version)) &&
-		    !memcmp(&pinfo->name, &p->name,
-			    I40E_DDP_NAME_SIZE)) {
+		if (pinfo->track_id == p->track_id) {
 			PMD_DRV_LOG(INFO, "Profile exists.");
 			rte_free(buff);
 			return 1;
@@ -1584,6 +1580,13 @@ rte_pmd_i40e_process_ddp_package(uint8_t port, uint8_t *buff,
 	int is_exist;
 	enum i40e_status_code status = I40E_SUCCESS;
 
+	if (op != RTE_PMD_I40E_PKG_OP_WR_ADD &&
+		op != RTE_PMD_I40E_PKG_OP_WR_ONLY &&
+		op != RTE_PMD_I40E_PKG_OP_WR_DEL) {
+		PMD_DRV_LOG(ERR, "Operation not supported.");
+		return -ENOTSUP;
+	}
+
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
 
 	dev = &rte_eth_devices[port];
@@ -1620,6 +1623,10 @@ rte_pmd_i40e_process_ddp_package(uint8_t port, uint8_t *buff,
 		return -EINVAL;
 	}
 	track_id = ((struct i40e_metadata_segment *)metadata_seg_hdr)->track_id;
+	if (track_id == I40E_DDP_TRACKID_INVALID) {
+		PMD_DRV_LOG(ERR, "Invalid track_id");
+		return -EINVAL;
+	}
 
 	/* Find profile segment */
 	profile_seg_hdr = i40e_find_segment_in_package(SEGMENT_TYPE_I40E,
@@ -1639,40 +1646,67 @@ rte_pmd_i40e_process_ddp_package(uint8_t port, uint8_t *buff,
 		return -EINVAL;
 	}
 
+	/* Check if the profile already loaded */
+	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,
+		op == RTE_PMD_I40E_PKG_OP_WR_ADD);
+	is_exist = i40e_check_profile_info(port, profile_info_sec);
+	if (is_exist < 0) {
+		PMD_DRV_LOG(ERR, "Failed to check profile.");
+		rte_free(profile_info_sec);
+		return -EINVAL;
+	}
+
 	if (op == RTE_PMD_I40E_PKG_OP_WR_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 > 0) {
+		if (is_exist) {
 			PMD_DRV_LOG(ERR, "Profile already exists.");
 			rte_free(profile_info_sec);
-			return 1;
-		} else if (is_exist < 0) {
-			PMD_DRV_LOG(ERR, "Failed to check profile.");
+			return -EEXIST;
+		}
+	} else if (op == RTE_PMD_I40E_PKG_OP_WR_DEL) {
+		if (!is_exist) {
+			PMD_DRV_LOG(ERR, "Profile does not exist.");
 			rte_free(profile_info_sec);
-			return -EINVAL;
+			return -EACCES;
 		}
+	}
 
-		/* Write profile to HW */
+	if (op == RTE_PMD_I40E_PKG_OP_WR_DEL) {
+		status = i40e_rollback_profile(
+			hw,
+			(struct i40e_profile_segment *)profile_seg_hdr,
+			track_id);
+		if (status) {
+			PMD_DRV_LOG(ERR, "Failed to write profile for delete.");
+			rte_free(profile_info_sec);
+			return status;
+		}
+	} else {
 		status = i40e_write_profile(
-				hw,
-				(struct i40e_profile_segment *)profile_seg_hdr,
-				track_id);
+			hw,
+			(struct i40e_profile_segment *)profile_seg_hdr,
+			track_id);
 		if (status) {
-			PMD_DRV_LOG(ERR, "Failed to write profile.");
+			if (op == RTE_PMD_I40E_PKG_OP_WR_ADD)
+				PMD_DRV_LOG(ERR, "Failed to write profile for add.");
+			else
+				PMD_DRV_LOG(ERR, "Failed to write profile.");
 			rte_free(profile_info_sec);
 			return status;
 		}
+	}
 
-		/* Add profile info to info list */
+	if (track_id && (op != RTE_PMD_I40E_PKG_OP_WR_ONLY)) {
+		/* Modify loaded profiles 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, "Operation not supported.");
+		if (status) {
+			if (op == RTE_PMD_I40E_PKG_OP_WR_ADD)
+				PMD_DRV_LOG(ERR, "Failed to add profile to info list.");
+			else
+				PMD_DRV_LOG(ERR, "Failed to delete profile from info list.");
+		}
 	}
 
 	rte_free(profile_info_sec);
diff --git a/drivers/net/i40e/rte_pmd_i40e.h b/drivers/net/i40e/rte_pmd_i40e.h
index 4a867ad6f..356fa89d7 100644
--- a/drivers/net/i40e/rte_pmd_i40e.h
+++ b/drivers/net/i40e/rte_pmd_i40e.h
@@ -71,6 +71,8 @@ struct rte_pmd_i40e_mb_event_param {
 enum rte_pmd_i40e_package_op {
 	RTE_PMD_I40E_PKG_OP_UNDEFINED = 0,
 	RTE_PMD_I40E_PKG_OP_WR_ADD,   /**< load package and add to info list */
+	RTE_PMD_I40E_PKG_OP_WR_DEL, /**< load package and delete from info list */
+	RTE_PMD_I40E_PKG_OP_WR_ONLY, /**< load package without modifying info list */
 	RTE_PMD_I40E_PKG_OP_MAX = 32
 };
 
@@ -517,7 +519,9 @@ int rte_pmd_i40e_set_tc_strict_prio(uint8_t port, uint8_t tc_map);
  *   - (0) if successful.
  *   - (-ENODEV) if *port* invalid.
  *   - (-EINVAL) if bad parameter.
- *   - (1) if profile exists.
+ *   - (-EEXIST) if profile exists.
+ *   - (-EACCES) if profile does not exist.
+ *   - (-ENOTSUP) if operation not supported.
  */
 int rte_pmd_i40e_process_ddp_package(uint8_t port, uint8_t *buff,
 				     uint32_t size,
-- 
2.13.0

^ permalink raw reply	[flat|nested] 17+ messages in thread

* [dpdk-dev] [PATCH v4 2/2] app/testpmd: enable ddp remove profile feature
  2017-05-27 16:04 [dpdk-dev] [PATCH] net/i40e: extended list of operations for ddp processing Andrey Chilikin
                   ` (7 preceding siblings ...)
  2017-06-28  8:15 ` [dpdk-dev] [PATCH v4 1/2] " Andrey Chilikin
@ 2017-06-28  8:15 ` Andrey Chilikin
  8 siblings, 0 replies; 17+ messages in thread
From: Andrey Chilikin @ 2017-06-28  8:15 UTC (permalink / raw)
  To: dev; +Cc: beilei.xing, jingjing.wu, Andrey Chilikin

New command 'ddp del (port) (profile_path)' removes previously
loaded profile and deletes it from the list of the loaded profiles.

Signed-off-by: Andrey Chilikin <andrey.chilikin@intel.com>
Acked-by: Beilei Xing <beilei.xing@intel.com>
---
 app/test-pmd/cmdline.c                      | 74 +++++++++++++++++++++++++++++
 doc/guides/testpmd_app_ug/testpmd_funcs.rst |  7 +++
 2 files changed, 81 insertions(+)

diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
index 81d1f84fe..0fc40a6fd 100644
--- a/app/test-pmd/cmdline.c
+++ b/app/test-pmd/cmdline.c
@@ -606,6 +606,9 @@ static void cmd_help_long_parsed(void *parsed_result,
 			"ddp add (port_id) (profile_path[,output_path])\n"
 			"    Load a profile package on a port\n\n"
 
+			"ddp del (port_id) (profile_path)\n"
+			"    Delete a profile package from a port\n\n"
+
 			"ptype mapping get (port_id) (valid_only)\n"
 			"    Get ptype mapping on a port\n\n"
 
@@ -13014,6 +13017,76 @@ cmdline_parse_inst_t cmd_ddp_add = {
 	},
 };
 
+/* Delete dynamic device personalization*/
+struct cmd_ddp_del_result {
+	cmdline_fixed_string_t ddp;
+	cmdline_fixed_string_t del;
+	uint8_t port_id;
+	char filepath[];
+};
+
+cmdline_parse_token_string_t cmd_ddp_del_ddp =
+	TOKEN_STRING_INITIALIZER(struct cmd_ddp_del_result, ddp, "ddp");
+cmdline_parse_token_string_t cmd_ddp_del_del =
+	TOKEN_STRING_INITIALIZER(struct cmd_ddp_del_result, del, "del");
+cmdline_parse_token_num_t cmd_ddp_del_port_id =
+	TOKEN_NUM_INITIALIZER(struct cmd_ddp_del_result, port_id, UINT8);
+cmdline_parse_token_string_t cmd_ddp_del_filepath =
+	TOKEN_STRING_INITIALIZER(struct cmd_ddp_del_result, filepath, NULL);
+
+static void
+cmd_ddp_del_parsed(
+	void *parsed_result,
+	__attribute__((unused)) struct cmdline *cl,
+	__attribute__((unused)) void *data)
+{
+	struct cmd_ddp_del_result *res = parsed_result;
+	uint8_t *buff;
+	uint32_t size;
+	int ret = -ENOTSUP;
+
+	if (res->port_id > nb_ports) {
+		printf("Invalid port, range is [0, %d]\n", nb_ports - 1);
+		return;
+	}
+
+	if (!all_ports_stopped()) {
+		printf("Please stop all ports first\n");
+		return;
+	}
+
+	buff = open_ddp_package_file(res->filepath, &size);
+	if (!buff)
+		return;
+
+#ifdef RTE_LIBRTE_I40E_PMD
+	if (ret == -ENOTSUP)
+		ret = rte_pmd_i40e_process_ddp_package(res->port_id,
+					       buff, size,
+					       RTE_PMD_I40E_PKG_OP_WR_DEL);
+#endif
+
+	if (ret == -EACCES)
+		printf("Profile does not exist.\n");
+	else if (ret < 0)
+		printf("Failed to delete profile.\n");
+
+	close_ddp_package_file(buff);
+}
+
+cmdline_parse_inst_t cmd_ddp_del = {
+	.f = cmd_ddp_del_parsed,
+	.data = NULL,
+	.help_str = "ddp del <port_id> <profile_path>",
+	.tokens = {
+		(void *)&cmd_ddp_del_ddp,
+		(void *)&cmd_ddp_del_del,
+		(void *)&cmd_ddp_del_port_id,
+		(void *)&cmd_ddp_del_filepath,
+		NULL,
+	},
+};
+
 /* Get dynamic device personalization profile info */
 struct cmd_ddp_info_result {
 	cmdline_fixed_string_t ddp;
@@ -13993,6 +14066,7 @@ cmdline_parse_ctx_t main_ctx[] = {
 	(cmdline_parse_inst_t *)&cmd_strict_link_prio,
 	(cmdline_parse_inst_t *)&cmd_tc_min_bw,
 	(cmdline_parse_inst_t *)&cmd_ddp_add,
+	(cmdline_parse_inst_t *)&cmd_ddp_del,
 	(cmdline_parse_inst_t *)&cmd_ddp_get_list,
 	(cmdline_parse_inst_t *)&cmd_ddp_get_info,
 	(cmdline_parse_inst_t *)&cmd_show_vf_stats,
diff --git a/doc/guides/testpmd_app_ug/testpmd_funcs.rst b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
index e6b0b514a..b8f47fde8 100644
--- a/doc/guides/testpmd_app_ug/testpmd_funcs.rst
+++ b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
@@ -1232,6 +1232,13 @@ Load a dynamic device personalization (DDP) package::
 
    testpmd> ddp add (port_id) (package_path[,output_path])
 
+ddp del
+~~~~~~~
+
+Delete a dynamic device personalization package::
+
+   testpmd> ddp del (port_id) (package_path)
+
 ptype mapping
 ~~~~~~~~~~~~~
 
-- 
2.13.0

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [dpdk-dev] [PATCH v4 1/2] net/i40e: extended list of operations for ddp processing
  2017-06-28  8:15 ` [dpdk-dev] [PATCH v4 1/2] " Andrey Chilikin
@ 2017-06-28  8:25   ` Xing, Beilei
  0 siblings, 0 replies; 17+ messages in thread
From: Xing, Beilei @ 2017-06-28  8:25 UTC (permalink / raw)
  To: Chilikin, Andrey, dev; +Cc: Wu, Jingjing


> -----Original Message-----
> From: Chilikin, Andrey
> Sent: Wednesday, June 28, 2017 4:15 PM
> To: dev@dpdk.org
> Cc: Xing, Beilei <beilei.xing@intel.com>; Wu, Jingjing
> <jingjing.wu@intel.com>; Chilikin, Andrey <andrey.chilikin@intel.com>
> Subject: [PATCH v4 1/2] net/i40e: extended list of operations for ddp
> processing
> 
> This patch adds ability to remove already loaded profile or write profile
> without registering it
> 
> Signed-off-by: Andrey Chilikin <andrey.chilikin@intel.com>

Acked-by: Beilei Xing <beilei.xing@intel.com>

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [dpdk-dev] [PATCH v4 0/2] net/i40e: extended list of operations for ddp processing
  2017-06-28  8:15 ` [dpdk-dev] [PATCH v4 0/2] net/i40e: extended list of operations for ddp processing Andrey Chilikin
@ 2017-06-28  9:47   ` Ferruh Yigit
  0 siblings, 0 replies; 17+ messages in thread
From: Ferruh Yigit @ 2017-06-28  9:47 UTC (permalink / raw)
  To: Andrey Chilikin, dev; +Cc: beilei.xing, jingjing.wu

On 6/28/2017 9:15 AM, Andrey Chilikin wrote:
> This patch adds two new operations for dynamic device personalisation:
> * remove already loaded profile and delete it from the list
> * write profile without registering it
> 
> This patchset depends on:
> [PATCH v2 00/16] net/i40e: base code update
> http://dpdk.org/ml/archives/dev/2017-June/068732.html
> http://dpdk.org/dev/patchwork/patch/25705/
> 
> v4:
> - code style fixed in rte_pmd_i40e.c
> 
> v3:
> - move testpmd updates to 'ddp add' command to a separate
>   patch http://dpdk.org/dev/patchwork/patch/25779/
> 
> v2:
> - Local static functions replaced by corresponding new
>   functions in i40e base code
> - Test-pmd command added
> 
> Andrey Chilikin (2):
>   net/i40e: extended list of operations for ddp processing
>   app/testpmd: enable ddp remove profile feature

Series applied to dpdk-next-net/master, thanks.

^ permalink raw reply	[flat|nested] 17+ messages in thread

end of thread, other threads:[~2017-06-28  9:47 UTC | newest]

Thread overview: 17+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-05-27 16:04 [dpdk-dev] [PATCH] net/i40e: extended list of operations for ddp processing Andrey Chilikin
2017-06-27  8:18 ` [dpdk-dev] [PATCH v2 0/2] " Andrey Chilikin
2017-06-27  8:18 ` [dpdk-dev] [PATCH v2 1/2] " Andrey Chilikin
2017-06-27  8:18 ` [dpdk-dev] [PATCH v2 2/2] app/testpmd: enable ddp remove profile feature Andrey Chilikin
2017-06-27  9:55   ` Ferruh Yigit
2017-06-27 13:35 ` [dpdk-dev] [PATCH v3 0/2] net/i40e: extended list of operations for ddp processing Andrey Chilikin
2017-06-27 13:35 ` [dpdk-dev] [PATCH v3 1/2] " Andrey Chilikin
2017-06-28  6:57   ` Xing, Beilei
2017-06-28  7:40     ` Chilikin, Andrey
2017-06-28  8:03       ` Xing, Beilei
2017-06-27 13:35 ` [dpdk-dev] [PATCH v3 2/2] app/testpmd: enable ddp remove profile feature Andrey Chilikin
2017-06-28  6:40   ` Xing, Beilei
2017-06-28  8:15 ` [dpdk-dev] [PATCH v4 0/2] net/i40e: extended list of operations for ddp processing Andrey Chilikin
2017-06-28  9:47   ` Ferruh Yigit
2017-06-28  8:15 ` [dpdk-dev] [PATCH v4 1/2] " Andrey Chilikin
2017-06-28  8:25   ` Xing, Beilei
2017-06-28  8:15 ` [dpdk-dev] [PATCH v4 2/2] app/testpmd: enable ddp remove profile feature Andrey Chilikin

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).