All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] net/i40e: extended list of operations for ddp processing
@ 2017-05-27 16:04 Andrey Chilikin
  2017-06-27  8:18 ` [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 related	[flat|nested] 17+ messages in thread

* [PATCH v2 0/2] net/i40e: extended list of operations for ddp processing
  2017-05-27 16:04 [PATCH] net/i40e: extended list of operations for ddp processing Andrey Chilikin
@ 2017-06-27  8:18 ` Andrey Chilikin
  2017-06-27  8:18 ` [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

* [PATCH v2 1/2] net/i40e: extended list of operations for ddp processing
  2017-05-27 16:04 [PATCH] net/i40e: extended list of operations for ddp processing Andrey Chilikin
  2017-06-27  8:18 ` [PATCH v2 0/2] " Andrey Chilikin
@ 2017-06-27  8:18 ` Andrey Chilikin
  2017-06-27  8:18 ` [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 related	[flat|nested] 17+ messages in thread

* [PATCH v2 2/2] app/testpmd: enable ddp remove profile feature
  2017-05-27 16:04 [PATCH] net/i40e: extended list of operations for ddp processing Andrey Chilikin
  2017-06-27  8:18 ` [PATCH v2 0/2] " Andrey Chilikin
  2017-06-27  8:18 ` [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 ` [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 related	[flat|nested] 17+ messages in thread

* Re: [PATCH v2 2/2] app/testpmd: enable ddp remove profile feature
  2017-06-27  8:18 ` [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

* [PATCH v3 0/2] net/i40e: extended list of operations for ddp processing
  2017-05-27 16:04 [PATCH] net/i40e: extended list of operations for ddp processing Andrey Chilikin
                   ` (2 preceding siblings ...)
  2017-06-27  8:18 ` [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 ` [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

* [PATCH v3 1/2] net/i40e: extended list of operations for ddp processing
  2017-05-27 16:04 [PATCH] net/i40e: extended list of operations for ddp processing Andrey Chilikin
                   ` (3 preceding siblings ...)
  2017-06-27 13:35 ` [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 ` [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 related	[flat|nested] 17+ messages in thread

* [PATCH v3 2/2] app/testpmd: enable ddp remove profile feature
  2017-05-27 16:04 [PATCH] net/i40e: extended list of operations for ddp processing Andrey Chilikin
                   ` (4 preceding siblings ...)
  2017-06-27 13:35 ` [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 ` [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 related	[flat|nested] 17+ messages in thread

* Re: [PATCH v3 2/2] app/testpmd: enable ddp remove profile feature
  2017-06-27 13:35 ` [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: [PATCH v3 1/2] net/i40e: extended list of operations for ddp processing
  2017-06-27 13:35 ` [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: [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: [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

* [PATCH v4 0/2] net/i40e: extended list of operations for ddp processing
  2017-05-27 16:04 [PATCH] net/i40e: extended list of operations for ddp processing Andrey Chilikin
                   ` (5 preceding siblings ...)
  2017-06-27 13:35 ` [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 ` [PATCH v4 1/2] " Andrey Chilikin
  2017-06-28  8:15 ` [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

* [PATCH v4 1/2] net/i40e: extended list of operations for ddp processing
  2017-05-27 16:04 [PATCH] net/i40e: extended list of operations for ddp processing Andrey Chilikin
                   ` (6 preceding siblings ...)
  2017-06-28  8:15 ` [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 ` [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 related	[flat|nested] 17+ messages in thread

* [PATCH v4 2/2] app/testpmd: enable ddp remove profile feature
  2017-05-27 16:04 [PATCH] net/i40e: extended list of operations for ddp processing Andrey Chilikin
                   ` (7 preceding siblings ...)
  2017-06-28  8:15 ` [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 related	[flat|nested] 17+ messages in thread

* Re: [PATCH v4 1/2] net/i40e: extended list of operations for ddp processing
  2017-06-28  8:15 ` [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: [PATCH v4 0/2] net/i40e: extended list of operations for ddp processing
  2017-06-28  8:15 ` [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 [PATCH] net/i40e: extended list of operations for ddp processing Andrey Chilikin
2017-06-27  8:18 ` [PATCH v2 0/2] " Andrey Chilikin
2017-06-27  8:18 ` [PATCH v2 1/2] " Andrey Chilikin
2017-06-27  8:18 ` [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 ` [PATCH v3 0/2] net/i40e: extended list of operations for ddp processing Andrey Chilikin
2017-06-27 13:35 ` [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 ` [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 ` [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 ` [PATCH v4 1/2] " Andrey Chilikin
2017-06-28  8:25   ` Xing, Beilei
2017-06-28  8:15 ` [PATCH v4 2/2] app/testpmd: enable ddp remove profile feature Andrey Chilikin

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.