All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] MPSL enabling
@ 2017-03-03  7:26 Beilei Xing
  2017-03-03  7:26 ` [PATCH 1/2] net/i40e: change tunnel filter function name Beilei Xing
                   ` (11 more replies)
  0 siblings, 12 replies; 82+ messages in thread
From: Beilei Xing @ 2017-03-03  7:26 UTC (permalink / raw)
  To: jingjing.wu; +Cc: helin.zhang, dev

Signed-off-by: Beilei Xing <beilei.xing@intel.com>
---
 app/test-pmd/cmdline_flow.c  |  23 ++++
 app/test-pmd/config.c        |   1 +
 drivers/net/i40e/i40e_flow.c | 245 +++++++++++++++++++++++++++++++++++++++++++
 lib/librte_ether/rte_flow.h  |  42 ++++++++
 4 files changed, 311 insertions(+)

diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c
index ff98690..eee691d 100644
--- a/app/test-pmd/cmdline_flow.c
+++ b/app/test-pmd/cmdline_flow.c
@@ -159,6 +159,8 @@ enum index {
 	ITEM_SCTP_CKSUM,
 	ITEM_VXLAN,
 	ITEM_VXLAN_VNI,
+	ITEM_MPLS,
+	ITEM_MPLS_LABEL,
 
 	/* Validate/create actions. */
 	ACTIONS,
@@ -432,6 +434,7 @@ static const enum index next_item[] = {
 	ITEM_TCP,
 	ITEM_SCTP,
 	ITEM_VXLAN,
+	ITEM_MPLS,
 	ZERO,
 };
 
@@ -538,6 +541,12 @@ static const enum index item_vxlan[] = {
 	ZERO,
 };
 
+static const enum index item_mpls[] = {
+	ITEM_MPLS_LABEL,
+	ITEM_NEXT,
+	ZERO,
+};
+
 static const enum index next_action[] = {
 	ACTION_END,
 	ACTION_VOID,
@@ -1279,6 +1288,20 @@ static const struct token token_list[] = {
 		.next = NEXT(item_vxlan, NEXT_ENTRY(UNSIGNED), item_param),
 		.args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_vxlan, vni)),
 	},
+	[ITEM_MPLS] = {
+		.name = "mpls",
+		.help = "match MPLS header",
+		.priv = PRIV_ITEM(MPLS, sizeof(struct rte_flow_item_mpls)),
+		.next = NEXT(item_mpls),
+		.call = parse_vc,
+	},
+	[ITEM_MPLS_LABEL] = {
+		.name = "label",
+		.help = "MPLS label",
+		.next = NEXT(item_mpls, NEXT_ENTRY(UNSIGNED), item_param),
+		.args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_mpls,
+					     label_tc_s_ttl)),
+	},
 	/* Validate/create actions. */
 	[ACTIONS] = {
 		.name = "actions",
diff --git a/app/test-pmd/config.c b/app/test-pmd/config.c
index 80491fc..3c7385a 100644
--- a/app/test-pmd/config.c
+++ b/app/test-pmd/config.c
@@ -963,6 +963,7 @@ static const struct {
 	MK_FLOW_ITEM(TCP, sizeof(struct rte_flow_item_tcp)),
 	MK_FLOW_ITEM(SCTP, sizeof(struct rte_flow_item_sctp)),
 	MK_FLOW_ITEM(VXLAN, sizeof(struct rte_flow_item_vxlan)),
+	MK_FLOW_ITEM(MPLS, sizeof(struct rte_flow_item_mpls)),
 };
 
 /** Compute storage space needed by item specification. */
diff --git a/drivers/net/i40e/i40e_flow.c b/drivers/net/i40e/i40e_flow.c
index 29f9513..1295f3c 100644
--- a/drivers/net/i40e/i40e_flow.c
+++ b/drivers/net/i40e/i40e_flow.c
@@ -57,6 +57,7 @@
 #define I40E_IPV6_FRAG_HEADER	44
 #define I40E_TENANT_ARRAY_NUM	3
 #define I40E_TCI_MASK		0xFFFF
+#define I40E_MPLS_LABEL_MASK	0xFFFFF
 
 static int i40e_flow_validate(struct rte_eth_dev *dev,
 			      const struct rte_flow_attr *attr,
@@ -114,6 +115,12 @@ static int i40e_flow_parse_vxlan_filter(struct rte_eth_dev *dev,
 					const struct rte_flow_action actions[],
 					struct rte_flow_error *error,
 					union i40e_filter_t *filter);
+static int i40e_flow_parse_mpls_filter(struct rte_eth_dev *dev,
+				       const struct rte_flow_attr *attr,
+				       const struct rte_flow_item pattern[],
+				       const struct rte_flow_action actions[],
+				       struct rte_flow_error *error,
+				       union i40e_filter_t *filter);
 static int i40e_flow_destroy_ethertype_filter(struct i40e_pf *pf,
 				      struct i40e_ethertype_filter *filter);
 static int i40e_flow_destroy_tunnel_filter(struct i40e_pf *pf,
@@ -278,6 +285,42 @@ static enum rte_flow_item_type pattern_vxlan_4[] = {
 	RTE_FLOW_ITEM_TYPE_END,
 };
 
+static enum rte_flow_item_type pattern_mpls_1[] = {
+	RTE_FLOW_ITEM_TYPE_ETH,
+	RTE_FLOW_ITEM_TYPE_IPV4,
+	RTE_FLOW_ITEM_TYPE_UDP,
+	RTE_FLOW_ITEM_TYPE_MPLS,
+	RTE_FLOW_ITEM_TYPE_ETH,
+        RTE_FLOW_ITEM_TYPE_END,
+};
+
+static enum rte_flow_item_type pattern_mpls_2[] = {
+	RTE_FLOW_ITEM_TYPE_ETH,
+	RTE_FLOW_ITEM_TYPE_IPV6,
+	RTE_FLOW_ITEM_TYPE_UDP,
+	RTE_FLOW_ITEM_TYPE_MPLS,
+	RTE_FLOW_ITEM_TYPE_ETH,
+        RTE_FLOW_ITEM_TYPE_END,
+};
+
+static enum rte_flow_item_type pattern_mpls_3[] = {
+	RTE_FLOW_ITEM_TYPE_ETH,
+	RTE_FLOW_ITEM_TYPE_IPV4,
+	RTE_FLOW_ITEM_TYPE_GRE,
+	RTE_FLOW_ITEM_TYPE_MPLS,
+	RTE_FLOW_ITEM_TYPE_ETH,
+        RTE_FLOW_ITEM_TYPE_END,
+};
+
+static enum rte_flow_item_type pattern_mpls_4[] = {
+	RTE_FLOW_ITEM_TYPE_ETH,
+	RTE_FLOW_ITEM_TYPE_IPV6,
+	RTE_FLOW_ITEM_TYPE_GRE,
+	RTE_FLOW_ITEM_TYPE_MPLS,
+	RTE_FLOW_ITEM_TYPE_ETH,
+        RTE_FLOW_ITEM_TYPE_END,
+};
+
 static struct i40e_valid_pattern i40e_supported_patterns[] = {
 	/* Ethertype */
 	{ pattern_ethertype, i40e_flow_parse_ethertype_filter },
@@ -303,6 +346,11 @@ static struct i40e_valid_pattern i40e_supported_patterns[] = {
 	{ pattern_vxlan_2, i40e_flow_parse_vxlan_filter },
 	{ pattern_vxlan_3, i40e_flow_parse_vxlan_filter },
 	{ pattern_vxlan_4, i40e_flow_parse_vxlan_filter },
+	/* MPLSoUDP & MPLSoGRE */
+	{ pattern_mpls_1, i40e_flow_parse_mpls_filter },
+	{ pattern_mpls_2, i40e_flow_parse_mpls_filter },
+	{ pattern_mpls_3, i40e_flow_parse_mpls_filter },
+	{ pattern_mpls_4, i40e_flow_parse_mpls_filter },
 };
 
 #define NEXT_ITEM_OF_ACTION(act, actions, index)                        \
@@ -1495,6 +1543,203 @@ i40e_flow_parse_vxlan_filter(struct rte_eth_dev *dev,
 	return ret;
 }
 
+/* 1. Last in item should be NULL as range is not supported.
+ * 2. Supported filter types: MPLS label.
+ * 3. Mask of fields which need to be matched should be
+ *    filled with 1.
+ * 4. Mask of fields which needn't to be matched should be
+ *    filled with 0.
+ */
+static int
+i40e_flow_parse_mpls_pattern(__rte_unused struct rte_eth_dev *dev,
+			      const struct rte_flow_item *pattern,
+			      struct rte_flow_error *error,
+			      struct rte_eth_tunnel_filter_conf *filter)
+{
+	const struct rte_flow_item *item = pattern;
+	const struct rte_flow_item_eth *eth_spec;
+	const struct rte_flow_item_eth *eth_mask;
+	const struct rte_flow_item_eth *i_eth_spec = NULL;
+	const struct rte_flow_item_eth *i_eth_mask = NULL;
+	const struct rte_flow_item_mpls *mpls_spec;
+	const struct rte_flow_item_mpls *mpls_mask;
+	enum rte_flow_item_type item_type;
+	bool mpls_flag = 0;
+	uint32_t mpls_cpu;
+
+	for (; item->type != RTE_FLOW_ITEM_TYPE_END; item++) {
+		if (item->last) {
+			rte_flow_error_set(error, EINVAL,
+					   RTE_FLOW_ERROR_TYPE_ITEM,
+					   item,
+					   "Not support range");
+			return -rte_errno;
+		}
+		item_type = item->type;
+		switch (item_type) {
+		case RTE_FLOW_ITEM_TYPE_ETH:
+			eth_spec = (const struct rte_flow_item_eth *)item->spec;
+			eth_mask = (const struct rte_flow_item_eth *)item->mask;
+
+			if ((!eth_spec && eth_mask) ||
+			    (eth_spec && !eth_mask)) {
+				rte_flow_error_set(error, EINVAL,
+						   RTE_FLOW_ERROR_TYPE_ITEM,
+						   item,
+						   "Invalid ether spec/mask");
+				return -rte_errno;
+			}
+
+			if (eth_spec && eth_mask) {
+				if (!mpls_flag) {
+					rte_flow_error_set(error, EINVAL,
+							   RTE_FLOW_ERROR_TYPE_ITEM,
+							   item,
+							   "Invalid ether spec/mask");
+					return -rte_errno;
+				}
+				/* DST address of inner MAC shouldn't be masked.
+				 * SRC address of Inner MAC should be masked.
+				 */
+				if (!is_broadcast_ether_addr(&eth_mask->dst) ||
+				    !is_zero_ether_addr(&eth_mask->src) ||
+				    eth_mask->type) {
+					rte_flow_error_set(error, EINVAL,
+						   RTE_FLOW_ERROR_TYPE_ITEM,
+						   item,
+						   "Invalid ether spec/mask");
+					return -rte_errno;
+				}
+
+				rte_memcpy(&filter->inner_mac,
+					   &eth_spec->dst,
+					   ETHER_ADDR_LEN);
+
+				i_eth_spec = eth_spec;
+				i_eth_mask = eth_mask;
+			}
+			break;
+		case RTE_FLOW_ITEM_TYPE_IPV4:
+			filter->ip_type = RTE_TUNNEL_IPTYPE_IPV4;
+			/* IPv4 is used to describe protocol,
+			 * spec amd mask should be NULL.
+			 */
+			if (item->spec || item->mask) {
+				rte_flow_error_set(error, EINVAL,
+						   RTE_FLOW_ERROR_TYPE_ITEM,
+						   item,
+						   "Invalid IPv4 item");
+				return -rte_errno;
+			}
+			break;
+		case RTE_FLOW_ITEM_TYPE_IPV6:
+			filter->ip_type = RTE_TUNNEL_IPTYPE_IPV6;
+			/* IPv6 is used to describe protocol,
+			 * spec amd mask should be NULL.
+			 */
+			if (item->spec || item->mask) {
+				rte_flow_error_set(error, EINVAL,
+						   RTE_FLOW_ERROR_TYPE_ITEM,
+						   item,
+						   "Invalid IPv6 item");
+				return -rte_errno;
+			}
+			break;
+		case RTE_FLOW_ITEM_TYPE_UDP:
+			/* UDP is used to describe protocol,
+			 * spec amd mask should be NULL.
+			 */
+			if (item->spec || item->mask) {
+				rte_flow_error_set(error, EINVAL,
+					   RTE_FLOW_ERROR_TYPE_ITEM,
+					   item,
+					   "Invalid UDP item");
+				return -rte_errno;
+			}
+			break;
+		case RTE_FLOW_ITEM_TYPE_GRE:
+			/* GRE is used to describe protocol,
+			 * spec amd mask should be NULL.
+			 */
+			if (item->spec || item->mask) {
+				rte_flow_error_set(error, EINVAL,
+						   RTE_FLOW_ERROR_TYPE_ITEM,
+						   item,
+						   "Invalid GRE item");
+				return -rte_errno;
+			}
+			break;
+		case RTE_FLOW_ITEM_TYPE_MPLS:
+			mpls_spec =
+				(const struct rte_flow_item_mpls *)item->spec;
+			mpls_mask =
+				(const struct rte_flow_item_mpls *)item->mask;
+
+			if (!mpls_spec || !mpls_mask) {
+				rte_flow_error_set(error, EINVAL,
+					   RTE_FLOW_ERROR_TYPE_ITEM,
+					   item,
+					   "Invalid VXLAN item");
+				return -rte_errno;
+			}
+
+			if ((mpls_mask->label_tc_s_ttl &
+			     rte_cpu_to_be_32(I40E_MPLS_LABEL_MASK)) !=
+			    rte_cpu_to_be_32(I40E_MPLS_LABEL_MASK)) {
+				rte_flow_error_set(error, EINVAL,
+						   RTE_FLOW_ERROR_TYPE_ITEM,
+						   item,
+						   "Invalid VXLAN mask");
+				return -rte_errno;
+			}
+
+			mpls_cpu = rte_be_to_cpu_32(mpls_spec->label_tc_s_ttl);
+			filter->tenant_id = mpls_cpu & I40E_MPLS_LABEL_MASK;
+			mpls_flag = 1;
+			break;
+		default:
+			break;
+		}
+	}
+
+	if (i_eth_spec && i_eth_mask && mpls_spec && mpls_mask)
+		filter->filter_type = RTE_TUNNEL_FILTER_IMAC_TENID;
+
+	filter->tunnel_type = RTE_TUNNEL_TYPE_VXLAN;
+
+	return 0;
+}
+
+static int
+i40e_flow_parse_mpls_filter(struct rte_eth_dev *dev,
+			    const struct rte_flow_attr *attr,
+			    const struct rte_flow_item pattern[],
+			    const struct rte_flow_action actions[],
+			    struct rte_flow_error *error,
+			    union i40e_filter_t *filter)
+{
+	struct rte_eth_tunnel_filter_conf *tunnel_filter =
+		&filter->tunnel_filter;
+	int ret;
+
+	ret = i40e_flow_parse_mpls_pattern(dev, pattern,
+					   error, tunnel_filter);
+	if (ret)
+		return ret;
+
+	ret = i40e_flow_parse_tunnel_action(dev, actions, error, tunnel_filter);
+	if (ret)
+		return ret;
+
+	ret = i40e_flow_parse_attr(attr, error);
+	if (ret)
+		return ret;
+
+	cons_filter_type = RTE_ETH_FILTER_TUNNEL;
+
+	return ret;
+}
+
 static int
 i40e_flow_validate(struct rte_eth_dev *dev,
 		   const struct rte_flow_attr *attr,
diff --git a/lib/librte_ether/rte_flow.h b/lib/librte_ether/rte_flow.h
index 171a569..25d8e3c 100644
--- a/lib/librte_ether/rte_flow.h
+++ b/lib/librte_ether/rte_flow.h
@@ -282,6 +282,20 @@ enum rte_flow_item_type {
 	 * See struct rte_flow_item_nvgre.
 	 */
 	RTE_FLOW_ITEM_TYPE_NVGRE,
+
+	/**
+	 * Matches a MPLS header.
+	 *
+	 * See struct rte_flow_item_mpls.
+	 */
+	RTE_FLOW_ITEM_TYPE_MPLS,
+
+	/**
+	 * Matches a GRE header.
+	 *
+	 * See struct rte_flow_item_gre.
+	 */
+	RTE_FLOW_ITEM_TYPE_GRE,
 };
 
 /**
@@ -599,6 +613,34 @@ struct rte_flow_item_nvgre {
 };
 
 /**
+ * RTE_FLOW_ITEM_TYPE_MPLS.
+ *
+ * Matches a MPLS header.
+ */
+struct rte_flow_item_mpls {
+	/**
+	 * Lable (20b), TC (3b), Bottom of Stack (1b), TTL (8b).
+	 */
+	uint32_t label_tc_s_ttl;
+};
+
+/**
+ * RTE_FLOW_ITEM_TYPE_GRE.
+ *
+ * Matches a GRE header.
+ */
+struct rte_flow_item_gre {
+	/**
+	 * Checksum (1b), reserved 0 (12b), version (3b).
+	 * Refer to RFC 2784.
+	 */
+	uint16_t c_rsvd0_ver;
+	uint16_t protocol; /**< Protocol type. */
+	uint16_t checksum;
+	uint16_t rsvd1;
+};
+
+/**
  * Matching pattern item definition.
  *
  * A pattern is formed by stacking items starting from the lowest protocol
-- 
2.5.5

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

* [PATCH 1/2] net/i40e: change tunnel filter function name
  2017-03-03  7:26 [PATCH] MPSL enabling Beilei Xing
@ 2017-03-03  7:26 ` Beilei Xing
  2017-03-03  7:26 ` [PATCH] ppp implemantation Beilei Xing
                   ` (10 subsequent siblings)
  11 siblings, 0 replies; 82+ messages in thread
From: Beilei Xing @ 2017-03-03  7:26 UTC (permalink / raw)
  To: jingjing.wu; +Cc: helin.zhang, dev

Change tunnel filter function name to VXLAN filter
function, prepare for NVGRE filter function.

Signed-off-by: Beilei Xing <beilei.xing@intel.com>
---
 drivers/net/i40e/i40e_flow.c | 56 ++++++++++++++++----------------------------
 1 file changed, 20 insertions(+), 36 deletions(-)

diff --git a/drivers/net/i40e/i40e_flow.c b/drivers/net/i40e/i40e_flow.c
index c6e4d87..d0ef4bc 100644
--- a/drivers/net/i40e/i40e_flow.c
+++ b/drivers/net/i40e/i40e_flow.c
@@ -90,10 +90,6 @@ static int i40e_flow_parse_fdir_action(struct rte_eth_dev *dev,
 				       const struct rte_flow_action *actions,
 				       struct rte_flow_error *error,
 				       struct rte_eth_fdir_filter *filter);
-static int i40e_flow_parse_tunnel_pattern(__rte_unused struct rte_eth_dev *dev,
-				  const struct rte_flow_item *pattern,
-				  struct rte_flow_error *error,
-				  struct rte_eth_tunnel_filter_conf *filter);
 static int i40e_flow_parse_tunnel_action(struct rte_eth_dev *dev,
 				 const struct rte_flow_action *actions,
 				 struct rte_flow_error *error,
@@ -112,12 +108,12 @@ static int i40e_flow_parse_fdir_filter(struct rte_eth_dev *dev,
 				       const struct rte_flow_action actions[],
 				       struct rte_flow_error *error,
 				       union i40e_filter_t *filter);
-static int i40e_flow_parse_tunnel_filter(struct rte_eth_dev *dev,
-					 const struct rte_flow_attr *attr,
-					 const struct rte_flow_item pattern[],
-					 const struct rte_flow_action actions[],
-					 struct rte_flow_error *error,
-					 union i40e_filter_t *filter);
+static int i40e_flow_parse_vxlan_filter(struct rte_eth_dev *dev,
+					const struct rte_flow_attr *attr,
+					const struct rte_flow_item pattern[],
+					const struct rte_flow_action actions[],
+					struct rte_flow_error *error,
+					union i40e_filter_t *filter);
 static int i40e_flow_destroy_ethertype_filter(struct i40e_pf *pf,
 				      struct i40e_ethertype_filter *filter);
 static int i40e_flow_destroy_tunnel_filter(struct i40e_pf *pf,
@@ -303,10 +299,10 @@ static struct i40e_valid_pattern i40e_supported_patterns[] = {
 	{ pattern_fdir_ipv6_sctp, i40e_flow_parse_fdir_filter },
 	{ pattern_fdir_ipv6_sctp_ext, i40e_flow_parse_fdir_filter },
 	/* tunnel */
-	{ pattern_vxlan_1, i40e_flow_parse_tunnel_filter },
-	{ pattern_vxlan_2, i40e_flow_parse_tunnel_filter },
-	{ pattern_vxlan_3, i40e_flow_parse_tunnel_filter },
-	{ pattern_vxlan_4, i40e_flow_parse_tunnel_filter },
+	{ pattern_vxlan_1, i40e_flow_parse_vxlan_filter },
+	{ pattern_vxlan_2, i40e_flow_parse_vxlan_filter },
+	{ pattern_vxlan_3, i40e_flow_parse_vxlan_filter },
+	{ pattern_vxlan_4, i40e_flow_parse_vxlan_filter },
 };
 
 #define NEXT_ITEM_OF_ACTION(act, actions, index)                        \
@@ -1205,7 +1201,8 @@ i40e_check_tenant_id_mask(const uint8_t *mask)
  *    filled with 0.
  */
 static int
-i40e_flow_parse_vxlan_pattern(const struct rte_flow_item *pattern,
+i40e_flow_parse_vxlan_pattern(__rte_unused struct rte_eth_dev *dev,
+			      const struct rte_flow_item *pattern,
 			      struct rte_flow_error *error,
 			      struct rte_eth_tunnel_filter_conf *filter)
 {
@@ -1469,32 +1466,19 @@ i40e_flow_parse_vxlan_pattern(const struct rte_flow_item *pattern,
 }
 
 static int
-i40e_flow_parse_tunnel_pattern(__rte_unused struct rte_eth_dev *dev,
-			       const struct rte_flow_item *pattern,
-			       struct rte_flow_error *error,
-			       struct rte_eth_tunnel_filter_conf *filter)
-{
-	int ret;
-
-	ret = i40e_flow_parse_vxlan_pattern(pattern, error, filter);
-
-	return ret;
-}
-
-static int
-i40e_flow_parse_tunnel_filter(struct rte_eth_dev *dev,
-			      const struct rte_flow_attr *attr,
-			      const struct rte_flow_item pattern[],
-			      const struct rte_flow_action actions[],
-			      struct rte_flow_error *error,
-			      union i40e_filter_t *filter)
+i40e_flow_parse_vxlan_filter(struct rte_eth_dev *dev,
+			     const struct rte_flow_attr *attr,
+			     const struct rte_flow_item pattern[],
+			     const struct rte_flow_action actions[],
+			     struct rte_flow_error *error,
+			     union i40e_filter_t *filter)
 {
 	struct rte_eth_tunnel_filter_conf *tunnel_filter =
 		&filter->tunnel_filter;
 	int ret;
 
-	ret = i40e_flow_parse_tunnel_pattern(dev, pattern,
-					     error, tunnel_filter);
+	ret = i40e_flow_parse_vxlan_pattern(dev, pattern,
+					    error, tunnel_filter);
 	if (ret)
 		return ret;
 
-- 
2.5.5

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

* [PATCH] ppp implemantation
  2017-03-03  7:26 [PATCH] MPSL enabling Beilei Xing
  2017-03-03  7:26 ` [PATCH 1/2] net/i40e: change tunnel filter function name Beilei Xing
@ 2017-03-03  7:26 ` Beilei Xing
  2017-03-03  9:39   ` Bruce Richardson
  2017-03-03  7:26 ` [PATCH 2/2] net/i40e: parse NVGRE filter Beilei Xing
                   ` (9 subsequent siblings)
  11 siblings, 1 reply; 82+ messages in thread
From: Beilei Xing @ 2017-03-03  7:26 UTC (permalink / raw)
  To: jingjing.wu; +Cc: helin.zhang, dev

Signed-off-by: Beilei Xing <beilei.xing@intel.com>
---
 app/test-pmd/cmdline.c                  |  57 ++++++++
 app/test-pmd/config.c                   |  62 +++++++++
 app/test-pmd/testpmd.h                  |   3 +
 drivers/net/i40e/base/i40e_adminq_cmd.h |  32 +++++
 drivers/net/i40e/base/i40e_common.c     | 236 +++++++++++++++++++++++++++++++-
 drivers/net/i40e/base/i40e_prototype.h  |  17 +++
 drivers/net/i40e/base/i40e_type.h       |  79 +++++++++++
 drivers/net/i40e/i40e_ethdev.c          |  68 +++++++++
 drivers/net/i40e/rte_pmd_i40e.h         |   1 +
 9 files changed, 554 insertions(+), 1 deletion(-)

diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
index 43fc636..0d62a07 100644
--- a/app/test-pmd/cmdline.c
+++ b/app/test-pmd/cmdline.c
@@ -12395,6 +12395,62 @@ cmdline_parse_inst_t cmd_set_vf_vlan_tag = {
 	},
 };
 
+/* Write Pipeline Personalization Profile */
+struct cmd_write_ppp_result {
+	cmdline_fixed_string_t write;
+	cmdline_fixed_string_t ppp;
+	uint8_t port_id;
+	char filename[];
+};
+
+cmdline_parse_token_string_t cmd_write_ppp_write =
+	TOKEN_STRING_INITIALIZER(struct cmd_write_ppp_result, write, "write");
+cmdline_parse_token_string_t cmd_write_ppp_ppp =
+	TOKEN_STRING_INITIALIZER(struct cmd_write_ppp_result, ppp, "ppp");
+cmdline_parse_token_num_t cmd_write_ppp_port_id =
+	TOKEN_NUM_INITIALIZER(struct cmd_write_ppp_result, port_id, UINT8);
+cmdline_parse_token_string_t cmd_write_ppp_filename =
+	TOKEN_STRING_INITIALIZER(struct cmd_write_ppp_result, filename, NULL);
+
+static void
+cmd_write_ppp_parsed(
+	void *parsed_result,
+	__attribute__((unused)) struct cmdline *cl,
+	__attribute__((unused)) void *data)
+{
+	struct cmd_write_ppp_result *res = parsed_result;
+	uint8_t *buff;
+	int ret = -ENOTSUP;
+
+	if (res->port_id > nb_ports) {
+		printf("Invalid port, range is [0, %d]\n", nb_ports - 1);
+		return;
+	}
+
+	buff = open_package_file(res->filename);
+	if (!buff)
+		return;
+
+	ret = i40e_process_package(res->port_id, buff);
+	if (ret < 0)
+		printf("Failed to write profile.\n");
+
+	close_package_file(buff);
+}
+
+cmdline_parse_inst_t cmd_write_ppp = {
+	.f = cmd_write_ppp_parsed,
+	.data = NULL,
+	.help_str = "write ppp <port_id> <profile_name>",
+	.tokens = {
+		(void *)&cmd_write_ppp_write,
+		(void *)&cmd_write_ppp_ppp,
+		(void *)&cmd_write_ppp_port_id,
+		(void *)&cmd_write_ppp_filename,
+		NULL,
+	},
+};
+
 /* ******************************************************************************** */
 
 /* list of instructions */
@@ -12570,6 +12626,7 @@ cmdline_parse_ctx_t main_ctx[] = {
 	(cmdline_parse_inst_t *)&cmd_set_vf_allmulti,
 	(cmdline_parse_inst_t *)&cmd_set_vf_broadcast,
 	(cmdline_parse_inst_t *)&cmd_set_vf_vlan_tag,
+	(cmdline_parse_inst_t *)&cmd_write_ppp,
 	NULL,
 };
 
diff --git a/app/test-pmd/config.c b/app/test-pmd/config.c
index 80491fc..aa26da1 100644
--- a/app/test-pmd/config.c
+++ b/app/test-pmd/config.c
@@ -3245,3 +3245,65 @@ port_dcb_info_display(uint8_t port_id)
 		printf("\t%4d", dcb_info.tc_queue.tc_txq[0][i].nb_queue);
 	printf("\n");
 }
+
+uint8_t *
+open_package_file(const char *file_path)
+{
+	FILE *fh = fopen(file_path, "rb");
+	uint32_t pkg_size;
+	uint8_t *buf = NULL;
+	int ret = 0;
+
+	if (fh == NULL) {
+		printf("%s: Failed to open %s\n", __func__, file_path);
+		return buf;
+	}
+
+	ret = fseek(fh, 0, SEEK_END);
+	if (ret < 0) {
+		fclose(fh);
+		printf("%s: File operations failed\n", __func__);
+		return buf;
+	}
+
+	pkg_size = ftell(fh);
+
+	buf = (uint8_t *)malloc(pkg_size);
+	if (!buf) {
+		fclose(fh);
+		printf("%s: Failed to malloc memory\n",	__func__);
+		return buf;
+	}
+
+	ret = fseek(fh, 0, SEEK_SET);
+	if (ret < 0) {
+		fclose(fh);
+                printf("%s: File operations failed\n", __func__);
+		close_package_file(buf);
+		return NULL;
+        }
+	fread(buf, 1, pkg_size, fh);
+
+	for(uint32_t i = 0; i < pkg_size; i++) {
+		if (!(i % 16))
+			printf("   ");
+		printf(" 0x%02X,", buf[i]);
+		if (!((i + 1) % 16))
+			printf("\n");
+	}
+
+	fclose(fh);
+
+	return buf;
+}
+
+int
+close_package_file(uint8_t *buf)
+{
+	if (buf) {
+		free((void *)buf);
+		return 0;
+	}
+
+	return -1;
+}
diff --git a/app/test-pmd/testpmd.h b/app/test-pmd/testpmd.h
index 8cf2860..2a7f683 100644
--- a/app/test-pmd/testpmd.h
+++ b/app/test-pmd/testpmd.h
@@ -622,6 +622,9 @@ void mcast_addr_add(uint8_t port_id, struct ether_addr *mc_addr);
 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_package_file(const char *file_path);
+int close_package_file(uint8_t *buf);
+
 enum print_warning {
 	ENABLED_WARN = 0,
 	DISABLED_WARN
diff --git a/drivers/net/i40e/base/i40e_adminq_cmd.h b/drivers/net/i40e/base/i40e_adminq_cmd.h
index 67cef7c..bb1e978 100644
--- a/drivers/net/i40e/base/i40e_adminq_cmd.h
+++ b/drivers/net/i40e/base/i40e_adminq_cmd.h
@@ -198,6 +198,10 @@ enum i40e_admin_queue_opc {
 	i40e_aqc_opc_add_mirror_rule	= 0x0260,
 	i40e_aqc_opc_delete_mirror_rule	= 0x0261,
 
+	/* Support Pipeline Personalization Profile */
+        i40e_aqc_opc_write_personalization_profile	= 0x0270,
+        i40e_aqc_opc_get_personalization_profile_list	= 0x0271,
+
 	/* DCB commands */
 	i40e_aqc_opc_dcb_ignore_pfc	= 0x0301,
 	i40e_aqc_opc_dcb_updated	= 0x0302,
@@ -1441,6 +1445,34 @@ struct i40e_aqc_add_delete_mirror_rule_completion {
 
 I40E_CHECK_CMD_LENGTH(i40e_aqc_add_delete_mirror_rule_completion);
 
+/* Pipeline Personalization Profile */
+struct i40e_aqc_write_ppp {
+        u8      reserved[4];
+        __le32  profile_track_id;
+        __le32  addr_high;
+        __le32  addr_low;
+};
+
+I40E_CHECK_CMD_LENGTH(i40e_aqc_write_ppp);
+
+struct i40e_aqc_write_ppp_resp {
+        __le32 error_offset;
+        __le32 error_info;
+        __le32 addr_high;
+        __le32 addr_low;
+};
+
+struct i40e_aqc_get_ppp_list {
+	u8      flags;
+	#define I40E_AQC_WR_PPP_GET_CONF	0x1
+	#define I40E_AQC_WR_PPP_GET_RDPU_CONF	0x2
+	u8      reserved[7];
+	__le32  addr_high;
+	__le32  addr_low;
+};
+
+I40E_CHECK_CMD_LENGTH(i40e_aqc_get_ppp_list);
+
 /* DCB 0x03xx*/
 
 /* PFC Ignore (direct 0x0301)
diff --git a/drivers/net/i40e/base/i40e_common.c b/drivers/net/i40e/base/i40e_common.c
index b8d8165..98653d5 100644
--- a/drivers/net/i40e/base/i40e_common.c
+++ b/drivers/net/i40e/base/i40e_common.c
@@ -6997,4 +6997,238 @@ enum i40e_status_code i40e_aq_clear_all_wol_filters(struct i40e_hw *hw,
 	status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
 
 	return status;
-}
\ No newline at end of file
+}
+
+/**
+ * i40e_aq_write_ppp - Write pipeline personalization profile (ppp)
+ * @hw: pointer to the hw struct
+ * @buff: command buffer (size in bytes = buff_size)
+ * @buff_size: buffer size in bytes
+ * @track_id: package tracking id
+ * @error_offset: returns error offset
+ * @error_info: returns error information
+ * @cmd_details: pointer to command details structure or NULL
+ **/
+enum
+i40e_status_code i40e_aq_write_ppp(struct i40e_hw *hw, void *buff,
+				   u16 buff_size, u32 track_id,
+				   u32 *error_offset, u32 *error_info,
+				   struct i40e_asq_cmd_details *cmd_details)
+{
+	struct i40e_aq_desc desc;
+	struct i40e_aqc_write_ppp *cmd =
+		(struct i40e_aqc_write_ppp *)&desc.params.raw;
+	struct i40e_aqc_write_ppp_resp *resp;
+	enum i40e_status_code status;
+
+	i40e_fill_default_direct_cmd_desc(&desc,
+				  i40e_aqc_opc_write_personalization_profile);
+
+	desc.flags |= CPU_TO_LE16(I40E_AQ_FLAG_BUF | I40E_AQ_FLAG_RD);
+	if (buff_size > I40E_AQ_LARGE_BUF)
+		desc.flags |= CPU_TO_LE16((u16)I40E_AQ_FLAG_LB);
+
+	desc.datalen = CPU_TO_LE16(buff_size);
+
+	cmd->profile_track_id = CPU_TO_LE32(track_id);
+
+	status = i40e_asq_send_command(hw, &desc, buff, buff_size, cmd_details);
+	if (!status) {
+		resp = (struct i40e_aqc_write_ppp_resp *)&desc.params.raw;
+		if (error_offset)
+			*error_offset = LE32_TO_CPU(resp->error_offset);
+		if (error_info)
+			*error_info = LE32_TO_CPU(resp->error_info);
+	}
+
+	return status;
+}
+
+/**
+ * i40e_aq_get_ppp_list - Read pipeline personalization profile (ppp)
+ * @hw: pointer to the hw struct
+ * @buff: command buffer (size in bytes = buff_size)
+ * @buff_size: buffer size in bytes
+ * @cmd_details: pointer to command details structure or NULL
+ **/
+enum
+i40e_status_code i40e_aq_get_ppp_list(struct i40e_hw *hw, void *buff,
+				      u16 buff_size, u8 flags,
+				      struct i40e_asq_cmd_details *cmd_details)
+{
+	struct i40e_aq_desc desc;
+	struct i40e_aqc_get_ppp_list *cmd =
+		(struct i40e_aqc_get_ppp_list *)&desc.params.raw;
+	enum i40e_status_code status;
+
+	i40e_fill_default_direct_cmd_desc(&desc,
+			  i40e_aqc_opc_get_personalization_profile_list);
+
+	if (buff_size > I40E_AQ_LARGE_BUF)
+		desc.flags |= CPU_TO_LE16((u16)I40E_AQ_FLAG_LB);
+	desc.datalen = CPU_TO_LE16(buff_size);
+
+	cmd->flags = flags;
+
+	status = i40e_asq_send_command(hw, &desc, buff, buff_size, cmd_details);
+
+	return status;
+}
+
+/**
+ * i40e_find_segment_in_package
+ * @segment_type: the segment type to search for (i.e., SEGMENT_TYPE_I40E)
+ * @pkg_hdr: pointer to the package header to be searched
+ *
+ * This function searches a package file for a particular segment type. On
+ * success it returns a pointer to the segment header, otherwise it will
+ * return NULL.
+ */
+struct i40e_generic_seg_header *
+i40e_find_segment_in_package(u32 segment_type,
+			     struct i40e_package_header *pkg_hdr)
+{
+	struct i40e_generic_seg_header *segment;
+	u32 i;
+
+	PMD_DRV_LOG(INFO, "i40e_find_segment_in_package");
+	PMD_DRV_LOG(INFO, "Package version: %d.%d.%d.%d",
+		    pkg_hdr->version.major,
+		    pkg_hdr->version.minor,
+		    pkg_hdr->version.update,
+		    pkg_hdr->version.draft);
+
+	/* Search all package segments for the requested segment type */
+	for (i = 0; i < pkg_hdr->segment_count; i++) {
+		segment =
+			(struct i40e_generic_seg_header *)((u8 *)pkg_hdr +
+		         pkg_hdr->segment_offset[i]);
+
+		if (segment->type == segment_type)
+			return segment;
+	}
+
+	return NULL;
+}
+
+/**
+ * i40e_write_profile
+ * @hw: pointer to the hardware structure
+ * @profile: pointer to the profile segment of the package to be downloaded
+ * @track_id: package tracking id
+ *
+ * Handles the download of a complete package.
+ */
+enum i40e_status_code
+i40e_write_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;
+
+	PMD_DRV_LOG(INFO, "i40e_write_profile");
+	PMD_DRV_LOG(INFO, "Segment version: %d.%d.%d.%d",
+		    profile->header.version.major,
+		    profile->header.version.minor,
+		    profile->header.version.update,
+		    profile->header.version.draft);
+	PMD_DRV_LOG(INFO, "Seg: type 0x%X, size %d, name %s",
+		    LE32_TO_CPU(profile->header.type),
+		    LE32_TO_CPU(profile->header.size),
+		    profile->header.name);
+
+	if (!track_id) {
+		PMD_DRV_LOG(ERR, "Track_id can't be 0.");
+                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 (i == dev_cnt) {
+		PMD_DRV_LOG(ERR, "Device doesn't support PPP");
+		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]);
+
+		/* Skip 'AQ', 'note' and 'name' sections */
+		if (sec->section.type != SECTION_TYPE_MMIO)
+			continue;
+
+		section_size = sec->section.size +
+			sizeof(struct i40e_profile_section_header);
+
+		/* Write profile */
+		status = i40e_aq_write_ppp(hw, (void *)sec, (u16)section_size,
+					   track_id, &offset, &info, NULL);
+		if (status) {
+			PMD_DRV_LOG(ERR, "Failed to write profile: "
+				    "offset %d, info %d",
+				    offset, info);
+			break;
+		}
+	}
+
+	return status;
+}
+
+/**
+ * i40e_add_pinfo_to_list
+ * @hw: pointer to the hardware structure
+ * @profile: pointer to the profile segment of the package
+ * @profile_info_sec: buffer for information section
+ * @track_id: package tracking id
+ *
+ * Register a profile to the list of loaded profiles.
+ */
+enum i40e_status_code
+i40e_add_pinfo_to_list(struct i40e_hw *hw,
+		       struct i40e_profile_segment *profile,
+		       u8 *profile_info_sec, u32 track_id)
+{
+	enum i40e_status_code status = I40E_SUCCESS;
+        struct i40e_profile_section_header *sec = NULL;
+        struct i40e_profile_info *pinfo;
+        u32 offset = 0, info = 0;
+
+	sec = (struct i40e_profile_section_header *)profile_info_sec;
+        sec->tbl_size = 1;
+        sec->data_end = sizeof(struct i40e_profile_section_header) +
+                sizeof(struct i40e_profile_info);
+        sec->section.type = SECTION_TYPE_INFO;
+        sec->section.offset = sizeof(struct i40e_profile_section_header);
+        sec->section.size = sizeof(struct i40e_profile_info);
+        pinfo = (struct i40e_profile_info *)(profile_info_sec +
+                                             sec->section.offset);
+        pinfo->track_id = track_id;
+        pinfo->version = profile->version;
+        pinfo->op = I40E_PPP_ADD_TRACKID;
+        memcpy(pinfo->name, profile->name, I40E_PPP_NAME_SIZE);
+
+        status = i40e_aq_write_ppp(hw, (void *)sec, sec->data_end,
+                                   track_id, &offset, &info, NULL);
+        if (status)
+                        PMD_DRV_LOG(ERR, "Failed to add to list: "
+                                    "offset %d, info %d",
+                                    offset, info);
+
+        return status;
+}
diff --git a/drivers/net/i40e/base/i40e_prototype.h b/drivers/net/i40e/base/i40e_prototype.h
index 109d3c5..b9b3a46 100644
--- a/drivers/net/i40e/base/i40e_prototype.h
+++ b/drivers/net/i40e/base/i40e_prototype.h
@@ -555,4 +555,21 @@ enum i40e_status_code i40e_write_phy_register(struct i40e_hw *hw,
 u8 i40e_get_phy_address(struct i40e_hw *hw, u8 dev_num);
 enum i40e_status_code i40e_blink_phy_link_led(struct i40e_hw *hw,
 					      u32 time, u32 interval);
+enum i40e_status_code i40e_aq_write_ppp(struct i40e_hw *hw, void *buff,
+				u16 buff_size, u32 track_id,
+				u32 *error_offset, u32 *error_info,
+				struct i40e_asq_cmd_details *cmd_details);
+enum i40e_status_code i40e_aq_get_ppp_list(struct i40e_hw *hw, void *buff,
+				   u16 buff_size, u8 flags,
+				   struct i40e_asq_cmd_details *cmd_details);
+struct i40e_generic_seg_header *
+i40e_find_segment_in_package(u32 segment_type,
+			     struct i40e_package_header *pkg_header);
+enum i40e_status_code
+i40e_write_profile(struct i40e_hw *hw, struct i40e_profile_segment *i40e_seg,
+		   u32 track_id);
+enum i40e_status_code
+i40e_add_pinfo_to_list(struct i40e_hw *hw,
+		       struct i40e_profile_segment *profile,
+		       u8 *profile_info_sec, u32 track_id);
 #endif /* _I40E_PROTOTYPE_H_ */
diff --git a/drivers/net/i40e/base/i40e_type.h b/drivers/net/i40e/base/i40e_type.h
index 590d97c..28e5e89 100644
--- a/drivers/net/i40e/base/i40e_type.h
+++ b/drivers/net/i40e/base/i40e_type.h
@@ -1878,4 +1878,83 @@ struct i40e_lldp_variables {
 #define I40E_FLEX_56_MASK		(0x1ULL << I40E_FLEX_56_SHIFT)
 #define I40E_FLEX_57_SHIFT		6
 #define I40E_FLEX_57_MASK		(0x1ULL << I40E_FLEX_57_SHIFT)
+
+/* Version format for PPP */
+struct i40e_ppp_version {
+	u8 major;
+	u8 minor;
+	u8 update;
+	u8 draft;
+};
+
+#define I40E_PPP_NAME_SIZE	32
+
+/* Package header */
+struct i40e_package_header {
+	struct i40e_ppp_version version;
+	u32 segment_count;
+	u32 segment_offset[1];
+};
+
+/* Generic segment header */
+struct i40e_generic_seg_header {
+#define SEGMENT_TYPE_METADATA	0x00000001
+#define SEGMENT_TYPE_NOTES	0x00000002
+#define SEGMENT_TYPE_I40E	0x00000011
+#define SEGMENT_TYPE_X722	0x00000012
+	u32 type;
+	struct i40e_ppp_version version;
+	u32 size;
+	char name[I40E_PPP_NAME_SIZE];
+};
+
+struct i40e_metadata_segment {
+	struct i40e_generic_seg_header header;
+	struct i40e_ppp_version version;
+	u32 track_id;
+	char name[I40E_PPP_NAME_SIZE];
+};
+
+struct i40e_device_id_entry {
+	u32 vendor_dev_id;
+	u32 sub_vendor_dev_id;
+};
+
+struct i40e_profile_segment {
+	struct i40e_generic_seg_header header;
+	struct i40e_ppp_version version;
+	char name[I40E_PPP_NAME_SIZE];
+	u32 device_table_count;
+	struct i40e_device_id_entry device_table[1];
+};
+
+struct i40e_section_table {
+	u32 section_count;
+	u32 section_offset[1];
+};
+
+struct i40e_profile_section_header {
+	u16 tbl_size;
+	u16 data_end;
+	struct {
+#define SECTION_TYPE_INFO	0x0000010
+#define SECTION_TYPE_MMIO	0x0000800
+#define SECTION_TYPE_AQ		0x0000801
+#define SECTION_TYPE_NOTE	0x8000000
+#define SECTION_TYPE_NAME	0x8000001
+		u32 type;
+		u32 offset;
+		u32 size;
+	} section;
+};
+
+struct i40e_profile_info {
+	u32 track_id;
+	struct i40e_ppp_version version;
+	u8 op;
+#define I40E_PPP_ADD_TRACKID    0x01
+#define I40E_PPP_REMOVE_TRACKID 0x02
+	u8 reserved[7];
+	u8 name[I40E_PPP_NAME_SIZE];
+};
 #endif /* _I40E_TYPE_H_ */
diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index 303027b..2016b77 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -39,6 +39,10 @@
 #include <stdarg.h>
 #include <inttypes.h>
 #include <assert.h>
+#include <sys/stat.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <fcntl.h>
 
 #include <rte_string_fns.h>
 #include <rte_pci.h>
@@ -11212,3 +11216,67 @@ rte_pmd_i40e_reset_vf_stats(uint8_t port,
 
 	return 0;
 }
+
+/**
+ * i40e_process_package - Load package
+ * @port: port id
+ * @buff: buffer of package
+ **/
+int
+i40e_process_package(uint8_t port, uint8_t *buff)
+{
+	struct rte_eth_dev *dev = &rte_eth_devices[port];
+	struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+	struct i40e_package_header *pkg_hdr;
+	struct i40e_generic_seg_header *profile_seg_hdr;
+	struct i40e_generic_seg_header *metadata_seg_hdr;
+	uint32_t track_id;
+	uint8_t *profile_info_sec;
+	enum i40e_status_code status;
+
+	pkg_hdr = (struct i40e_package_header *)buff;
+
+	if (!pkg_hdr) {
+		PMD_DRV_LOG(ERR, "Failed to fill the package structure");
+		return -EINVAL;
+	}
+
+	/* Find metadata segment */
+	metadata_seg_hdr = i40e_find_segment_in_package(SEGMENT_TYPE_METADATA,
+							pkg_hdr);
+	if (!metadata_seg_hdr) {
+		PMD_DRV_LOG(ERR, "Failed to find metadata segment header");
+		return -EINVAL;
+	}
+	track_id = ((struct i40e_metadata_segment *)metadata_seg_hdr)->track_id;
+
+	/* Find profile segment */
+	profile_seg_hdr = i40e_find_segment_in_package(SEGMENT_TYPE_I40E,
+						       pkg_hdr);
+	if (!profile_seg_hdr) {
+		PMD_DRV_LOG(ERR, "Failed to find profile segment header");
+		return -EINVAL;
+	}
+
+	/* Write profile to HW */
+	status = i40e_write_profile(hw,
+			    (struct i40e_profile_segment *)profile_seg_hdr,
+			    track_id);
+	if (!status)
+		printf("Write profile successfully.\n");
+
+	/* Add the profile info to the list of loaded profiles */
+	profile_info_sec = rte_zmalloc("i40e_profile_info",
+			       sizeof(struct i40e_profile_section_header) +
+			       sizeof(struct i40e_profile_info),
+			       0);
+	status = i40e_add_pinfo_to_list(hw,
+			(struct i40e_profile_segment *)profile_seg_hdr,
+			profile_info_sec, track_id);
+	if (!status)
+		printf("Add profile info successfully.\n");
+
+	rte_free(profile_info_sec);
+
+	return status;
+}
diff --git a/drivers/net/i40e/rte_pmd_i40e.h b/drivers/net/i40e/rte_pmd_i40e.h
index a0ad88c..755a279 100644
--- a/drivers/net/i40e/rte_pmd_i40e.h
+++ b/drivers/net/i40e/rte_pmd_i40e.h
@@ -332,4 +332,5 @@ int rte_pmd_i40e_get_vf_stats(uint8_t port,
 int rte_pmd_i40e_reset_vf_stats(uint8_t port,
 				uint16_t vf_id);
 
+int i40e_process_package(uint8_t port, uint8_t *buff);
 #endif /* _PMD_I40E_H_ */
-- 
2.5.5

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

* [PATCH 2/2] net/i40e: parse NVGRE filter
  2017-03-03  7:26 [PATCH] MPSL enabling Beilei Xing
  2017-03-03  7:26 ` [PATCH 1/2] net/i40e: change tunnel filter function name Beilei Xing
  2017-03-03  7:26 ` [PATCH] ppp implemantation Beilei Xing
@ 2017-03-03  7:26 ` Beilei Xing
  2017-03-03  7:26 ` [PATCH] PPP prototype Beilei Xing
                   ` (8 subsequent siblings)
  11 siblings, 0 replies; 82+ messages in thread
From: Beilei Xing @ 2017-03-03  7:26 UTC (permalink / raw)
  To: jingjing.wu; +Cc: helin.zhang, dev

This patch adds i40e_flow_parse_nvgre_filter to check
if a rule is a NVGRE rule according to items of the flow
pattern, and the function also gets the tunnel info.

Signed-off-by: Beilei Xing <beilei.xing@intel.com>
---
 drivers/net/i40e/i40e_flow.c | 335 +++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 335 insertions(+)

diff --git a/drivers/net/i40e/i40e_flow.c b/drivers/net/i40e/i40e_flow.c
index d0ef4bc..99aec11 100644
--- a/drivers/net/i40e/i40e_flow.c
+++ b/drivers/net/i40e/i40e_flow.c
@@ -114,6 +114,12 @@ static int i40e_flow_parse_vxlan_filter(struct rte_eth_dev *dev,
 					const struct rte_flow_action actions[],
 					struct rte_flow_error *error,
 					union i40e_filter_t *filter);
+static int i40e_flow_parse_nvgre_filter(struct rte_eth_dev *dev,
+					const struct rte_flow_attr *attr,
+					const struct rte_flow_item pattern[],
+					const struct rte_flow_action actions[],
+					struct rte_flow_error *error,
+					union i40e_filter_t *filter);
 static int i40e_flow_destroy_ethertype_filter(struct i40e_pf *pf,
 				      struct i40e_ethertype_filter *filter);
 static int i40e_flow_destroy_tunnel_filter(struct i40e_pf *pf,
@@ -278,6 +284,40 @@ static enum rte_flow_item_type pattern_vxlan_4[] = {
 	RTE_FLOW_ITEM_TYPE_END,
 };
 
+static enum rte_flow_item_type pattern_nvgre_1[] = {
+	RTE_FLOW_ITEM_TYPE_ETH,
+	RTE_FLOW_ITEM_TYPE_IPV4,
+	RTE_FLOW_ITEM_TYPE_NVGRE,
+	RTE_FLOW_ITEM_TYPE_ETH,
+	RTE_FLOW_ITEM_TYPE_END,
+};
+
+static enum rte_flow_item_type pattern_nvgre_2[] = {
+	RTE_FLOW_ITEM_TYPE_ETH,
+	RTE_FLOW_ITEM_TYPE_IPV6,
+	RTE_FLOW_ITEM_TYPE_NVGRE,
+	RTE_FLOW_ITEM_TYPE_ETH,
+	RTE_FLOW_ITEM_TYPE_END,
+};
+
+static enum rte_flow_item_type pattern_nvgre_3[] = {
+	RTE_FLOW_ITEM_TYPE_ETH,
+	RTE_FLOW_ITEM_TYPE_IPV4,
+	RTE_FLOW_ITEM_TYPE_NVGRE,
+	RTE_FLOW_ITEM_TYPE_ETH,
+	RTE_FLOW_ITEM_TYPE_VLAN,
+	RTE_FLOW_ITEM_TYPE_END,
+};
+
+static enum rte_flow_item_type pattern_nvgre_4[] = {
+	RTE_FLOW_ITEM_TYPE_ETH,
+	RTE_FLOW_ITEM_TYPE_IPV6,
+	RTE_FLOW_ITEM_TYPE_NVGRE,
+	RTE_FLOW_ITEM_TYPE_ETH,
+	RTE_FLOW_ITEM_TYPE_VLAN,
+	RTE_FLOW_ITEM_TYPE_END,
+};
+
 static struct i40e_valid_pattern i40e_supported_patterns[] = {
 	/* Ethertype */
 	{ pattern_ethertype, i40e_flow_parse_ethertype_filter },
@@ -303,6 +343,10 @@ static struct i40e_valid_pattern i40e_supported_patterns[] = {
 	{ pattern_vxlan_2, i40e_flow_parse_vxlan_filter },
 	{ pattern_vxlan_3, i40e_flow_parse_vxlan_filter },
 	{ pattern_vxlan_4, i40e_flow_parse_vxlan_filter },
+	{ pattern_nvgre_1, i40e_flow_parse_nvgre_filter },
+	{ pattern_nvgre_2, i40e_flow_parse_nvgre_filter },
+	{ pattern_nvgre_3, i40e_flow_parse_nvgre_filter },
+	{ pattern_nvgre_4, i40e_flow_parse_nvgre_filter },
 };
 
 #define NEXT_ITEM_OF_ACTION(act, actions, index)                        \
@@ -1495,6 +1539,297 @@ i40e_flow_parse_vxlan_filter(struct rte_eth_dev *dev,
 	return ret;
 }
 
+/* 1. Last in item should be NULL as range is not supported.
+ * 2. Supported filter types: IMAC_IVLAN_TENID, IMAC_IVLAN,
+ *    IMAC_TENID, OMAC_TENID_IMAC and IMAC.
+ * 3. Mask of fields which need to be matched should be
+ *    filled with 1.
+ * 4. Mask of fields which needn't to be matched should be
+ *    filled with 0.
+ */
+static int
+i40e_flow_parse_nvgre_pattern(__rte_unused struct rte_eth_dev *dev,
+			      const struct rte_flow_item *pattern,
+			      struct rte_flow_error *error,
+			      struct rte_eth_tunnel_filter_conf *filter)
+{
+	const struct rte_flow_item *item = pattern;
+	const struct rte_flow_item_eth *eth_spec;
+	const struct rte_flow_item_eth *eth_mask;
+	const struct rte_flow_item_eth *o_eth_spec = NULL;
+	const struct rte_flow_item_eth *o_eth_mask = NULL;
+	const struct rte_flow_item_nvgre *nvgre_spec = NULL;
+	const struct rte_flow_item_nvgre *nvgre_mask = NULL;
+	const struct rte_flow_item_eth *i_eth_spec = NULL;
+	const struct rte_flow_item_eth *i_eth_mask = NULL;
+	const struct rte_flow_item_vlan *vlan_spec = NULL;
+	const struct rte_flow_item_vlan *vlan_mask = NULL;
+	bool is_tni_masked = 0;
+	enum rte_flow_item_type item_type;
+	bool nvgre_flag = 0;
+	uint32_t tenant_id_be = 0;
+
+	for (; item->type != RTE_FLOW_ITEM_TYPE_END; item++) {
+		if (item->last) {
+			rte_flow_error_set(error, EINVAL,
+					   RTE_FLOW_ERROR_TYPE_ITEM,
+					   item,
+					   "Not support range");
+			return -rte_errno;
+		}
+		item_type = item->type;
+		switch (item_type) {
+		case RTE_FLOW_ITEM_TYPE_ETH:
+			eth_spec = (const struct rte_flow_item_eth *)item->spec;
+			eth_mask = (const struct rte_flow_item_eth *)item->mask;
+			if ((!eth_spec && eth_mask) ||
+			    (eth_spec && !eth_mask)) {
+				rte_flow_error_set(error, EINVAL,
+						   RTE_FLOW_ERROR_TYPE_ITEM,
+						   item,
+						   "Invalid ether spec/mask");
+				return -rte_errno;
+			}
+
+			if (eth_spec && eth_mask) {
+				/* DST address of inner MAC shouldn't be masked.
+				 * SRC address of Inner MAC should be masked.
+				 */
+				if (!is_broadcast_ether_addr(&eth_mask->dst) ||
+				    !is_zero_ether_addr(&eth_mask->src) ||
+				    eth_mask->type) {
+					rte_flow_error_set(error, EINVAL,
+						   RTE_FLOW_ERROR_TYPE_ITEM,
+						   item,
+						   "Invalid ether spec/mask");
+					return -rte_errno;
+				}
+
+				if (!nvgre_flag)
+					rte_memcpy(&filter->outer_mac,
+						   &eth_spec->dst,
+						   ETHER_ADDR_LEN);
+				else
+					rte_memcpy(&filter->inner_mac,
+						   &eth_spec->dst,
+						   ETHER_ADDR_LEN);
+			}
+
+			if (!nvgre_flag) {
+				o_eth_spec = eth_spec;
+				o_eth_mask = eth_mask;
+			} else {
+				i_eth_spec = eth_spec;
+				i_eth_mask = eth_mask;
+			}
+
+			break;
+		case RTE_FLOW_ITEM_TYPE_VLAN:
+			vlan_spec =
+				(const struct rte_flow_item_vlan *)item->spec;
+			vlan_mask =
+				(const struct rte_flow_item_vlan *)item->mask;
+			if (nvgre_flag) {
+				vlan_spec =
+				(const struct rte_flow_item_vlan *)item->spec;
+				vlan_mask =
+				(const struct rte_flow_item_vlan *)item->mask;
+				if (!(vlan_spec && vlan_mask)) {
+					rte_flow_error_set(error, EINVAL,
+						   RTE_FLOW_ERROR_TYPE_ITEM,
+						   item,
+						   "Invalid vlan item");
+					return -rte_errno;
+				}
+			} else {
+				if (vlan_spec || vlan_mask)
+					rte_flow_error_set(error, EINVAL,
+						   RTE_FLOW_ERROR_TYPE_ITEM,
+						   item,
+						   "Invalid vlan item");
+				return -rte_errno;
+			}
+			break;
+		case RTE_FLOW_ITEM_TYPE_IPV4:
+			filter->ip_type = RTE_TUNNEL_IPTYPE_IPV4;
+			/* IPv4 is used to describe protocol,
+			 * spec amd mask should be NULL.
+			 */
+			if (item->spec || item->mask) {
+				rte_flow_error_set(error, EINVAL,
+						   RTE_FLOW_ERROR_TYPE_ITEM,
+						   item,
+						   "Invalid IPv4 item");
+				return -rte_errno;
+			}
+			break;
+		case RTE_FLOW_ITEM_TYPE_IPV6:
+			filter->ip_type = RTE_TUNNEL_IPTYPE_IPV6;
+			/* IPv6 is used to describe protocol,
+			 * spec amd mask should be NULL.
+			 */
+			if (item->spec || item->mask) {
+				rte_flow_error_set(error, EINVAL,
+						   RTE_FLOW_ERROR_TYPE_ITEM,
+						   item,
+						   "Invalid IPv6 item");
+				return -rte_errno;
+			}
+			break;
+		case RTE_FLOW_ITEM_TYPE_NVGRE:
+			nvgre_spec =
+				(const struct rte_flow_item_nvgre *)item->spec;
+			nvgre_mask =
+				(const struct rte_flow_item_nvgre *)item->mask;
+			/* Check if NVGRE item is used to describe protocol.
+			 * If yes, both spec and mask should be NULL.
+			 * If no, either spec or mask shouldn't be NULL.
+			 */
+			if ((!nvgre_spec && nvgre_mask) ||
+			    (nvgre_spec && !nvgre_mask)) {
+				rte_flow_error_set(error, EINVAL,
+					   RTE_FLOW_ERROR_TYPE_ITEM,
+					   item,
+					   "Invalid NVGRE item");
+				return -rte_errno;
+			}
+
+			/* Check if TNI is masked. */
+			if (nvgre_mask) {
+				is_tni_masked =
+				i40e_check_tenant_id_mask(nvgre_mask->tni);
+				if (is_tni_masked < 0) {
+					rte_flow_error_set(error, EINVAL,
+						   RTE_FLOW_ERROR_TYPE_ITEM,
+						   item,
+						   "Invalid TNI mask");
+					return -rte_errno;
+				}
+			}
+			nvgre_flag = 1;
+			break;
+		default:
+			break;
+		}
+	}
+
+	/* Check specification and mask to get the filter type */
+	if (vlan_spec && vlan_mask &&
+	    (vlan_mask->tci == rte_cpu_to_be_16(I40E_TCI_MASK))) {
+		/* If there's inner vlan */
+		filter->inner_vlan = rte_be_to_cpu_16(vlan_spec->tci)
+			& I40E_TCI_MASK;
+		if (nvgre_spec && nvgre_mask && !is_tni_masked) {
+			/* If there's nvgre */
+			rte_memcpy(((uint8_t *)&tenant_id_be + 1),
+				   nvgre_spec->tni, 3);
+			filter->tenant_id = rte_be_to_cpu_32(tenant_id_be);
+			if (!o_eth_spec && !o_eth_mask &&
+				i_eth_spec && i_eth_mask)
+				filter->filter_type =
+					RTE_TUNNEL_FILTER_IMAC_IVLAN_TENID;
+			else {
+				rte_flow_error_set(error, EINVAL,
+						   RTE_FLOW_ERROR_TYPE_ITEM,
+						   NULL,
+						   "Invalid filter type");
+				return -rte_errno;
+			}
+		} else if (!nvgre_spec && !nvgre_mask) {
+			/* If there's no nvgre */
+			if (!o_eth_spec && !o_eth_mask &&
+				i_eth_spec && i_eth_mask)
+				filter->filter_type =
+					RTE_TUNNEL_FILTER_IMAC_IVLAN;
+			else {
+				rte_flow_error_set(error, EINVAL,
+						   RTE_FLOW_ERROR_TYPE_ITEM,
+						   NULL,
+						   "Invalid filter type");
+				return -rte_errno;
+			}
+		} else {
+			rte_flow_error_set(error, EINVAL,
+					   RTE_FLOW_ERROR_TYPE_ITEM,
+					   NULL,
+					   "Invalid filter type");
+			return -rte_errno;
+		}
+	} else if ((!vlan_spec && !vlan_mask) ||
+		   (vlan_spec && vlan_mask && vlan_mask->tci == 0x0)) {
+		/* If there's no inner vlan */
+		if (nvgre_spec && nvgre_mask && !is_tni_masked) {
+			/* If there's nvgre */
+			rte_memcpy(((uint8_t *)&tenant_id_be + 1),
+				   nvgre_spec->tni, 3);
+			filter->tenant_id = rte_be_to_cpu_32(tenant_id_be);
+			if (!o_eth_spec && !o_eth_mask &&
+				i_eth_spec && i_eth_mask)
+				filter->filter_type =
+					RTE_TUNNEL_FILTER_IMAC_TENID;
+			else if (o_eth_spec && o_eth_mask &&
+				i_eth_spec && i_eth_mask)
+				filter->filter_type =
+					RTE_TUNNEL_FILTER_OMAC_TENID_IMAC;
+		} else if (!nvgre_spec && !nvgre_mask) {
+			/* If there's no nvgre */
+			if (!o_eth_spec && !o_eth_mask &&
+				i_eth_spec && i_eth_mask) {
+				filter->filter_type = ETH_TUNNEL_FILTER_IMAC;
+			} else {
+				rte_flow_error_set(error, EINVAL,
+					   RTE_FLOW_ERROR_TYPE_ITEM, NULL,
+					   "Invalid filter type");
+				return -rte_errno;
+			}
+		} else {
+			rte_flow_error_set(error, EINVAL,
+					   RTE_FLOW_ERROR_TYPE_ITEM, NULL,
+					   "Invalid filter type");
+			return -rte_errno;
+		}
+	} else {
+		rte_flow_error_set(error, EINVAL,
+				   RTE_FLOW_ERROR_TYPE_ITEM, NULL,
+				   "Not supported by tunnel filter.");
+		return -rte_errno;
+	}
+
+	filter->tunnel_type = RTE_TUNNEL_TYPE_NVGRE;
+
+	return 0;
+}
+
+static int
+i40e_flow_parse_nvgre_filter(struct rte_eth_dev *dev,
+			     const struct rte_flow_attr *attr,
+			     const struct rte_flow_item pattern[],
+			     const struct rte_flow_action actions[],
+			     struct rte_flow_error *error,
+			     union i40e_filter_t *filter)
+{
+	struct rte_eth_tunnel_filter_conf *tunnel_filter =
+		&filter->tunnel_filter;
+	int ret;
+
+	ret = i40e_flow_parse_nvgre_pattern(dev, pattern,
+					    error, tunnel_filter);
+	if (ret)
+		return ret;
+
+	ret = i40e_flow_parse_tunnel_action(dev, actions, error, tunnel_filter);
+	if (ret)
+		return ret;
+
+	ret = i40e_flow_parse_attr(attr, error);
+	if (ret)
+		return ret;
+
+	cons_filter_type = RTE_ETH_FILTER_TUNNEL;
+
+	return ret;
+}
+
 static int
 i40e_flow_validate(struct rte_eth_dev *dev,
 		   const struct rte_flow_attr *attr,
-- 
2.5.5

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

* [PATCH] PPP prototype
  2017-03-03  7:26 [PATCH] MPSL enabling Beilei Xing
                   ` (2 preceding siblings ...)
  2017-03-03  7:26 ` [PATCH 2/2] net/i40e: parse NVGRE filter Beilei Xing
@ 2017-03-03  7:26 ` Beilei Xing
  2017-03-03  7:26 ` [PATCH] ppp implemantation Beilei Xing
                   ` (7 subsequent siblings)
  11 siblings, 0 replies; 82+ messages in thread
From: Beilei Xing @ 2017-03-03  7:26 UTC (permalink / raw)
  To: jingjing.wu; +Cc: helin.zhang, dev, Qi Zhang

From: Qi Zhang <qi.z.zhang@intel.com>

Signed-off-by: Qi Zhang <qi.z.zhang@intel.com>
---
 app/test-pmd/cmdline.c                  |  57 ++++++++++++
 app/test-pmd/config.c                   | 114 +++++++++++++++++++++++
 app/test-pmd/testpmd.h                  |   3 +
 drivers/net/i40e/base/i40e_adminq_cmd.h |  33 +++++++
 drivers/net/i40e/base/i40e_common.c     | 160 +++++++++++++++++++++++++++++++-
 drivers/net/i40e/base/i40e_prototype.h  |  12 +++
 drivers/net/i40e/base/i40e_type.h       |  69 ++++++++++++++
 drivers/net/i40e/i40e_ethdev.c          |  55 +++++++++++
 drivers/net/i40e/rte_pmd_i40e.h         |   1 +
 9 files changed, 503 insertions(+), 1 deletion(-)

diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
index 43fc636..0d62a07 100644
--- a/app/test-pmd/cmdline.c
+++ b/app/test-pmd/cmdline.c
@@ -12395,6 +12395,62 @@ cmdline_parse_inst_t cmd_set_vf_vlan_tag = {
 	},
 };
 
+/* Write Pipeline Personalization Profile */
+struct cmd_write_ppp_result {
+	cmdline_fixed_string_t write;
+	cmdline_fixed_string_t ppp;
+	uint8_t port_id;
+	char filename[];
+};
+
+cmdline_parse_token_string_t cmd_write_ppp_write =
+	TOKEN_STRING_INITIALIZER(struct cmd_write_ppp_result, write, "write");
+cmdline_parse_token_string_t cmd_write_ppp_ppp =
+	TOKEN_STRING_INITIALIZER(struct cmd_write_ppp_result, ppp, "ppp");
+cmdline_parse_token_num_t cmd_write_ppp_port_id =
+	TOKEN_NUM_INITIALIZER(struct cmd_write_ppp_result, port_id, UINT8);
+cmdline_parse_token_string_t cmd_write_ppp_filename =
+	TOKEN_STRING_INITIALIZER(struct cmd_write_ppp_result, filename, NULL);
+
+static void
+cmd_write_ppp_parsed(
+	void *parsed_result,
+	__attribute__((unused)) struct cmdline *cl,
+	__attribute__((unused)) void *data)
+{
+	struct cmd_write_ppp_result *res = parsed_result;
+	uint8_t *buff;
+	int ret = -ENOTSUP;
+
+	if (res->port_id > nb_ports) {
+		printf("Invalid port, range is [0, %d]\n", nb_ports - 1);
+		return;
+	}
+
+	buff = open_package_file(res->filename);
+	if (!buff)
+		return;
+
+	ret = i40e_process_package(res->port_id, buff);
+	if (ret < 0)
+		printf("Failed to write profile.\n");
+
+	close_package_file(buff);
+}
+
+cmdline_parse_inst_t cmd_write_ppp = {
+	.f = cmd_write_ppp_parsed,
+	.data = NULL,
+	.help_str = "write ppp <port_id> <profile_name>",
+	.tokens = {
+		(void *)&cmd_write_ppp_write,
+		(void *)&cmd_write_ppp_ppp,
+		(void *)&cmd_write_ppp_port_id,
+		(void *)&cmd_write_ppp_filename,
+		NULL,
+	},
+};
+
 /* ******************************************************************************** */
 
 /* list of instructions */
@@ -12570,6 +12626,7 @@ cmdline_parse_ctx_t main_ctx[] = {
 	(cmdline_parse_inst_t *)&cmd_set_vf_allmulti,
 	(cmdline_parse_inst_t *)&cmd_set_vf_broadcast,
 	(cmdline_parse_inst_t *)&cmd_set_vf_vlan_tag,
+	(cmdline_parse_inst_t *)&cmd_write_ppp,
 	NULL,
 };
 
diff --git a/app/test-pmd/config.c b/app/test-pmd/config.c
index 80491fc..6dbb683 100644
--- a/app/test-pmd/config.c
+++ b/app/test-pmd/config.c
@@ -100,6 +100,11 @@
 
 #include "testpmd.h"
 
+#include <sys/stat.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <fcntl.h>
+
 static char *flowtype_to_str(uint16_t flow_type);
 
 static const struct {
@@ -3245,3 +3250,112 @@ port_dcb_info_display(uint8_t port_id)
 		printf("\t%4d", dcb_info.tc_queue.tc_txq[0][i].nb_queue);
 	printf("\n");
 }
+
+uint8_t *
+open_package_file(const char *file_path)
+{
+	FILE *fh = fopen(file_path, "rb");
+	uint32_t pkg_size;
+	uint8_t *buf = NULL;
+	int ret = 0;
+
+	if (fh == NULL) {
+		printf("%s: Failed to open %s\n", __func__, file_path);
+		return buf;
+	}
+
+	ret = fseek(fh, 0, SEEK_END);
+	if (ret < 0) {
+		fclose(fh);
+		printf("%s: File operations failed\n", __func__);
+		return buf;
+	}
+
+	pkg_size = ftell(fh);
+
+	buf = (uint8_t *)malloc(pkg_size);
+	if (!buf) {
+		fclose(fh);
+		printf("%s: Failed to malloc memory\n",	__func__);
+		return buf;
+	}
+
+	ret = fseek(fh, 0, SEEK_SET);
+	if (ret < 0) {
+		fclose(fh);
+                printf("%s: File operations failed\n", __func__);
+		close_package_file(buf);
+		return NULL;
+        }
+	fread(buf, 1, pkg_size, fh);
+
+	for(uint32_t i = 0; i < pkg_size; i++) {
+		if (!(i % 16))
+			printf("   ");
+		printf(" 0x%02X,", buf[i]);
+		if (!((i + 1) % 16))
+			printf("\n");
+	}
+
+	fclose(fh);
+
+	return buf;
+}
+
+/* uint8_t * */
+/* open_package_file(const char *file_path) */
+/* { */
+/* 	int fd = STDOUT_FILENO; */
+/*         struct stat stf; */
+/*         uint8_t *buf = NULL; */
+
+/*         if (stat(file_path, &stf) == -1) { */
+/*                 dprintf(fd, "unable to access '%s'\n", file_path); */
+/*                 return NULL; */
+/*         } */
+
+/*         if ((stf.st_mode & S_IFMT) != S_IFREG) { */
+/*                 dprintf(fd, "'%s' is not a file\n", file_path); */
+/*                 return NULL; */
+/*         } */
+
+/*         buf = (uint8_t *)malloc(stf.st_size); */
+/*         if (!buf) { */
+/*                 dprintf(fd, "not enough memory to load %u bytes\n", (uint32_t)stf.st_size); */
+/*                 return NULL; */
+/*         } */
+
+/*         int file = open(file_path, O_RDONLY, S_IRUSR); */
+/*         if (file < 0) { */
+/*                 dprintf(fd, "unable to open '%s'\n", file_path); */
+/*                 return NULL; */
+/*         } */
+
+/*         if (read(file, buf, stf.st_size) != stf.st_size) { */
+/*                 free((void *)buf); */
+/*                 dprintf(fd, "unable to read '%s'\n", file_path); */
+/*                 return NULL; */
+/*         } */
+/*         close(file); */
+
+/*      for(uint32_t i = 0; i < stf.st_size; i++) { */
+/*              if (!(i % 16)) */
+/*                      printf("   "); */
+/*              printf(" 0x%02X,", buf[i]); */
+/*              if (!((i + 1) % 16)) */
+/*                      printf("\n"); */
+/*      } */
+
+/* 	return buf; */
+/* } */
+
+int
+close_package_file(uint8_t *buf)
+{
+	if (buf) {
+		free((void *)buf);
+		return 0;
+	}
+
+	return -1;
+}
diff --git a/app/test-pmd/testpmd.h b/app/test-pmd/testpmd.h
index 8cf2860..2a7f683 100644
--- a/app/test-pmd/testpmd.h
+++ b/app/test-pmd/testpmd.h
@@ -622,6 +622,9 @@ void mcast_addr_add(uint8_t port_id, struct ether_addr *mc_addr);
 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_package_file(const char *file_path);
+int close_package_file(uint8_t *buf);
+
 enum print_warning {
 	ENABLED_WARN = 0,
 	DISABLED_WARN
diff --git a/drivers/net/i40e/base/i40e_adminq_cmd.h b/drivers/net/i40e/base/i40e_adminq_cmd.h
index 67cef7c..593394a 100644
--- a/drivers/net/i40e/base/i40e_adminq_cmd.h
+++ b/drivers/net/i40e/base/i40e_adminq_cmd.h
@@ -198,6 +198,10 @@ enum i40e_admin_queue_opc {
 	i40e_aqc_opc_add_mirror_rule	= 0x0260,
 	i40e_aqc_opc_delete_mirror_rule	= 0x0261,
 
+	/* Support Pipeline Personalization Profile */
+        i40e_aqc_opc_write_personalization_profile	= 0x0270,
+        i40e_aqc_opc_read_personalization_profile_list	= 0x0271,
+
 	/* DCB commands */
 	i40e_aqc_opc_dcb_ignore_pfc	= 0x0301,
 	i40e_aqc_opc_dcb_updated	= 0x0302,
@@ -1441,6 +1445,35 @@ struct i40e_aqc_add_delete_mirror_rule_completion {
 
 I40E_CHECK_CMD_LENGTH(i40e_aqc_add_delete_mirror_rule_completion);
 
+/* Pipeline Personalization Profile */
+struct i40e_aqc_write_ppp {
+        u8      flags;
+#define I40E_AQ_WR_PPP_ADD_TRACK_ID     0x01
+#define I40E_AQ_WR_PPP_REMOVE_TRACK_ID  0x02
+        u8      reserved[3];
+        __le32  profile_track_id;
+        __le32  addr_high;
+        __le32  addr_low;
+};
+
+I40E_CHECK_CMD_LENGTH(i40e_aqc_write_ppp);
+
+struct i40e_aqc_write_ppp_resp {
+        __le32 error_offset;
+        __le32 error_info;
+        __le32 addr_high;
+        __le32 addr_low;
+};
+
+struct i40e_aqc_read_ppp {
+	u8      flags;
+	u8      reserved[7];
+	__le32  addr_high;
+	__le32  addr_low;
+};
+
+I40E_CHECK_CMD_LENGTH(i40e_aqc_read_ppp);
+
 /* DCB 0x03xx*/
 
 /* PFC Ignore (direct 0x0301)
diff --git a/drivers/net/i40e/base/i40e_common.c b/drivers/net/i40e/base/i40e_common.c
index b8d8165..4fb419c 100644
--- a/drivers/net/i40e/base/i40e_common.c
+++ b/drivers/net/i40e/base/i40e_common.c
@@ -6997,4 +6997,162 @@ enum i40e_status_code i40e_aq_clear_all_wol_filters(struct i40e_hw *hw,
 	status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
 
 	return status;
-}
\ No newline at end of file
+}
+
+/**
+ * i40e_aq_write_ppp - Write pipeline personalization profile (ppp)
+ * @hw: pointer to the hw struct
+ * @buff: command buffer (size in bytes = buff_size)
+ * @buff_size: buffer size in bytes
+ * @track_id: package tracking id
+ * @cmd_details: pointer to command details structure or NULL
+ **/
+enum
+i40e_status_code i40e_aq_write_ppp(struct i40e_hw *hw, void *buff,
+				   u16 buff_size, u32 track_id,
+				   struct i40e_asq_cmd_details *cmd_details)
+{
+	struct i40e_aq_desc desc;
+	struct i40e_aqc_write_ppp *cmd =
+		(struct i40e_aqc_write_ppp *)&desc.params.raw;
+	struct i40e_aqc_write_ppp_resp *resp;
+	enum i40e_status_code status;
+
+	i40e_fill_default_direct_cmd_desc(&desc,
+				  i40e_aqc_opc_write_personalization_profile);
+
+	desc.flags |= CPU_TO_LE16(I40E_AQ_FLAG_BUF | I40E_AQ_FLAG_RD);
+	if (buff_size > I40E_AQ_LARGE_BUF)
+		desc.flags |= CPU_TO_LE16((u16)I40E_AQ_FLAG_LB);
+
+	desc.datalen = CPU_TO_LE16(buff_size);
+
+	cmd->profile_track_id = CPU_TO_LE32(track_id);
+
+	status = i40e_asq_send_command(hw, &desc, buff, buff_size, cmd_details);
+
+	return status;
+}
+
+/**
+ * i40e_aq_read_ppp - Read pipeline personalization profile (ppp)
+ * @hw: pointer to the hw struct
+ * @buff: command buffer (size in bytes = buff_size)
+ * @buff_size: buffer size in bytes
+ * @cmd_details: pointer to command details structure or NULL
+ **/
+enum
+i40e_status_code i40e_aq_read_ppp(struct i40e_hw *hw,
+				  void *buff, u16 buff_size,
+				  struct i40e_asq_cmd_details *cmd_details)
+{
+	struct i40e_aq_desc desc;
+	struct i40e_aqc_read_ppp *cmd =
+		(struct i40e_aqc_read_ppp *)&desc.params.raw;
+	enum i40e_status_code status;
+
+	i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_read_personalization_profile_list);
+
+	if (buff_size > I40E_AQ_LARGE_BUF)
+		desc.flags |= CPU_TO_LE16((u16)I40E_AQ_FLAG_LB);
+	desc.datalen = CPU_TO_LE16(buff_size);
+
+	status = i40e_asq_send_command(hw, &desc, buff, buff_size, cmd_details);
+
+	return status;
+}
+
+/**
+ * i40e_find_segment_in_package
+ * @segment_type: the segment type to search for (i.e., SEGMENT_TYPE_I40E)
+ * @pkg_hdr: pointer to the package header to be searched
+ *
+ * This function searches a package file for a particular segment type. On
+ * success it returns a pointer to the segment header, otherwise it will
+ * return NULL.
+ */
+struct i40e_generic_seg_header *
+i40e_find_segment_in_package(u32 segment_type,
+			     struct i40e_package_header *pkg_hdr)
+{
+	struct i40e_generic_seg_header *segment;
+	u32 i;
+
+	PMD_DRV_LOG(INFO, "i40e_find_segment_in_package");
+	PMD_DRV_LOG(INFO, "Package version: %d.%d.%d.%d",
+		    pkg_hdr->version.major,
+		    pkg_hdr->version.minor,
+		    pkg_hdr->version.update,
+		    pkg_hdr->version.draft);
+
+	/* Search all package segments for the requested segment type */
+	for (i = 0; i < pkg_hdr->segment_count; i++) {
+		segment =
+			(struct i40e_generic_seg_header *)((u8 *)pkg_hdr +
+		         pkg_hdr->segment_offset[i]);
+
+		if (segment->type == segment_type)
+			return segment;
+	}
+
+	return NULL;
+}
+
+/**
+ * i40e_write_profile
+ * @hw: pointer to the hardware structure
+ * @profile: pointer to the profile segment of the package to be downloaded
+ * @track_id: package tracking id
+ *
+ * Handles the download of a complete package.
+ */
+enum i40e_status_code
+i40e_write_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 *nvm;
+	u32 section_size = 0;
+	u32 i;
+
+	PMD_DRV_LOG(INFO, "i40e_write_profile");
+	PMD_DRV_LOG(INFO, "Segment version: %d.%d.%d.%d",
+		    profile->header.version.major,
+		    profile->header.version.minor,
+		    profile->header.version.update,
+		    profile->header.version.draft);
+	PMD_DRV_LOG(INFO, "Seg: type 0x%X, size %d, name %s",
+		    LE32_TO_CPU(profile->header.type),
+		    LE32_TO_CPU(profile->header.size),
+		    profile->header.name);
+
+	dev_cnt = profile->device_table_count;
+	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 *)((char *)profile +
+					     sec_tbl->section_offset[i]);
+
+		/* Skip 'AQ', 'note' and 'name' sections */
+		if (sec->section.type != SECTION_TYPE_MMIO)
+			continue;
+
+		section_size = sec->section.size +
+			sizeof(struct i40e_profile_section_header);
+		break;
+	}
+
+	/* Write profile */
+	status = i40e_aq_write_ppp(hw, (void *)sec, section_size,
+				   track_id, NULL);
+	if (status) {
+		PMD_DRV_LOG(ERR, "Failed to write profile!");
+		return status;
+	}
+
+	return status;
+}
diff --git a/drivers/net/i40e/base/i40e_prototype.h b/drivers/net/i40e/base/i40e_prototype.h
index 109d3c5..4f7b63f 100644
--- a/drivers/net/i40e/base/i40e_prototype.h
+++ b/drivers/net/i40e/base/i40e_prototype.h
@@ -555,4 +555,16 @@ enum i40e_status_code i40e_write_phy_register(struct i40e_hw *hw,
 u8 i40e_get_phy_address(struct i40e_hw *hw, u8 dev_num);
 enum i40e_status_code i40e_blink_phy_link_led(struct i40e_hw *hw,
 					      u32 time, u32 interval);
+enum i40e_status_code i40e_aq_write_ppp(struct i40e_hw *hw, void *buff,
+				u16 buff_size, u32 track_id,
+				struct i40e_asq_cmd_details *cmd_details);
+enum i40e_status_code i40e_aq_read_ppp(struct i40e_hw *hw,
+			       void *buff, u16 buff_size,
+			       struct i40e_asq_cmd_details *cmd_details);
+struct i40e_generic_seg_header *
+i40e_find_segment_in_package(u32 segment_type,
+			     struct i40e_package_header *pkg_header);
+enum i40e_status_code
+i40e_write_profile(struct i40e_hw *hw, struct i40e_profile_segment *i40e_seg,
+		   u32 track_id);
 #endif /* _I40E_PROTOTYPE_H_ */
diff --git a/drivers/net/i40e/base/i40e_type.h b/drivers/net/i40e/base/i40e_type.h
index 590d97c..dafb8d9 100644
--- a/drivers/net/i40e/base/i40e_type.h
+++ b/drivers/net/i40e/base/i40e_type.h
@@ -1878,4 +1878,73 @@ struct i40e_lldp_variables {
 #define I40E_FLEX_56_MASK		(0x1ULL << I40E_FLEX_56_SHIFT)
 #define I40E_FLEX_57_SHIFT		6
 #define I40E_FLEX_57_MASK		(0x1ULL << I40E_FLEX_57_SHIFT)
+
+/* Version format for PPP */
+struct i40e_ppp_version {
+	u8 major;
+	u8 minor;
+	u8 update;
+	u8 draft;
+};
+
+#define I40E_PPP_NAME_SIZE	32
+
+/* Package header */
+struct i40e_package_header {
+	struct i40e_ppp_version version;
+	u32 segment_count;
+	u32 segment_offset[1];
+};
+
+/* Generic segment header */
+struct i40e_generic_seg_header {
+	#define SEGMENT_TYPE_METADATA	0x00000001
+	#define SEGMENT_TYPE_NOTES	0x00000002
+	#define SEGMENT_TYPE_I40E	0x00000011
+	#define SEGMENT_TYPE_X722	0x00000012
+	u32 type;
+	struct i40e_ppp_version version;
+	u32 size;
+	char name[I40E_PPP_NAME_SIZE];
+};
+
+struct i40e_metadata_segment {
+	struct i40e_generic_seg_header header;
+	struct i40e_ppp_version version;
+	uint32_t track_id;
+	char     name[I40E_PPP_NAME_SIZE];
+};
+
+struct i40e_device_id_entry {
+	u32 device_id;
+	u32 sub_device_id;
+};
+
+struct i40e_profile_segment {
+	struct i40e_generic_seg_header header;
+	struct i40e_ppp_version version;
+	char name[I40E_PPP_NAME_SIZE];
+	u32 device_table_count;
+	struct i40e_device_id_entry device_table[1];
+};
+
+struct i40e_section_table {
+	u32 section_count;
+	u32 section_offset[1];
+};
+
+struct i40e_profile_section_header {
+	u16 tbl_size;
+	u16 data_end;
+	struct {
+		#define SECTION_TYPE_INFO	0x0000010
+		#define SECTION_TYPE_MMIO	0x0000800
+		#define SECTION_TYPE_AQ		0x0000801
+		#define SECTION_TYPE_NOTE	0x8000000
+		#define SECTION_TYPE_NAME	0x8000001
+		u32 type;
+		u32 offset;
+		u32 size;
+	} section;
+};
 #endif /* _I40E_TYPE_H_ */
diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index 303027b..a467711 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -39,6 +39,10 @@
 #include <stdarg.h>
 #include <inttypes.h>
 #include <assert.h>
+#include <sys/stat.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <fcntl.h>
 
 #include <rte_string_fns.h>
 #include <rte_pci.h>
@@ -11212,3 +11216,54 @@ rte_pmd_i40e_reset_vf_stats(uint8_t port,
 
 	return 0;
 }
+
+/**
+ * i40e_process_package - Load package
+ * @port: port id
+ * @filename: file name of the package
+ **/
+int
+i40e_process_package(uint8_t port, uint8_t *buff)
+{
+        struct rte_eth_dev *dev = &rte_eth_devices[port];
+	struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+        struct i40e_package_header *pkg_hdr;
+        struct i40e_generic_seg_header *profile_seg_hdr;
+        struct i40e_generic_seg_header *metadata_seg_hdr;
+        uint32_t track_id;
+        enum i40e_status_code status;
+
+        pkg_hdr = (struct i40e_package_header *)buff;
+
+        if (!pkg_hdr) {
+                PMD_DRV_LOG(ERR, "Failed to fill the package structure");
+                return -EINVAL;
+        }
+
+        /* Find metadata segment */
+        metadata_seg_hdr = i40e_find_segment_in_package(SEGMENT_TYPE_METADATA,
+                                                        pkg_hdr);
+        if (!metadata_seg_hdr) {
+                PMD_DRV_LOG(ERR, "Failed to find metadata segment header");
+                return -EINVAL;
+        }
+        track_id = ((struct i40e_metadata_segment *)metadata_seg_hdr)->track_id;
+
+	/* Find profile segment */
+        profile_seg_hdr = i40e_find_segment_in_package(SEGMENT_TYPE_I40E,
+                                                       pkg_hdr);
+        if (!profile_seg_hdr) {
+                PMD_DRV_LOG(ERR, "Failed to find profile segment header");
+                return -EINVAL;
+        }
+
+        /* Write profile to HW */
+        status = i40e_write_profile(hw,
+				    (struct i40e_profile_segment *)profile_seg_hdr,
+				    track_id);
+
+        if (!status)
+                printf("Write profile successfully.\n");
+
+        return status;
+}
diff --git a/drivers/net/i40e/rte_pmd_i40e.h b/drivers/net/i40e/rte_pmd_i40e.h
index a0ad88c..755a279 100644
--- a/drivers/net/i40e/rte_pmd_i40e.h
+++ b/drivers/net/i40e/rte_pmd_i40e.h
@@ -332,4 +332,5 @@ int rte_pmd_i40e_get_vf_stats(uint8_t port,
 int rte_pmd_i40e_reset_vf_stats(uint8_t port,
 				uint16_t vf_id);
 
+int i40e_process_package(uint8_t port, uint8_t *buff);
 #endif /* _PMD_I40E_H_ */
-- 
2.7.4

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

* [PATCH] ppp implemantation
  2017-03-03  7:26 [PATCH] MPSL enabling Beilei Xing
                   ` (3 preceding siblings ...)
  2017-03-03  7:26 ` [PATCH] PPP prototype Beilei Xing
@ 2017-03-03  7:26 ` Beilei Xing
  2017-03-03  7:26 ` [PATCH 0/6] net/i40e: support pipeline personalization profile Beilei Xing
                   ` (6 subsequent siblings)
  11 siblings, 0 replies; 82+ messages in thread
From: Beilei Xing @ 2017-03-03  7:26 UTC (permalink / raw)
  To: jingjing.wu; +Cc: helin.zhang, dev

Signed-off-by: Beilei Xing <beilei.xing@intel.com>
---
 app/test-pmd/cmdline.c                  |  57 ++++++++++++
 app/test-pmd/config.c                   |  62 +++++++++++++
 app/test-pmd/testpmd.h                  |   3 +
 drivers/net/i40e/base/i40e_adminq_cmd.h |  33 +++++++
 drivers/net/i40e/base/i40e_common.c     | 160 +++++++++++++++++++++++++++++++-
 drivers/net/i40e/base/i40e_prototype.h  |  12 +++
 drivers/net/i40e/base/i40e_type.h       |  69 ++++++++++++++
 drivers/net/i40e/i40e_ethdev.c          |  55 +++++++++++
 drivers/net/i40e/rte_pmd_i40e.h         |   1 +
 9 files changed, 451 insertions(+), 1 deletion(-)

diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
index 43fc636..0d62a07 100644
--- a/app/test-pmd/cmdline.c
+++ b/app/test-pmd/cmdline.c
@@ -12395,6 +12395,62 @@ cmdline_parse_inst_t cmd_set_vf_vlan_tag = {
 	},
 };
 
+/* Write Pipeline Personalization Profile */
+struct cmd_write_ppp_result {
+	cmdline_fixed_string_t write;
+	cmdline_fixed_string_t ppp;
+	uint8_t port_id;
+	char filename[];
+};
+
+cmdline_parse_token_string_t cmd_write_ppp_write =
+	TOKEN_STRING_INITIALIZER(struct cmd_write_ppp_result, write, "write");
+cmdline_parse_token_string_t cmd_write_ppp_ppp =
+	TOKEN_STRING_INITIALIZER(struct cmd_write_ppp_result, ppp, "ppp");
+cmdline_parse_token_num_t cmd_write_ppp_port_id =
+	TOKEN_NUM_INITIALIZER(struct cmd_write_ppp_result, port_id, UINT8);
+cmdline_parse_token_string_t cmd_write_ppp_filename =
+	TOKEN_STRING_INITIALIZER(struct cmd_write_ppp_result, filename, NULL);
+
+static void
+cmd_write_ppp_parsed(
+	void *parsed_result,
+	__attribute__((unused)) struct cmdline *cl,
+	__attribute__((unused)) void *data)
+{
+	struct cmd_write_ppp_result *res = parsed_result;
+	uint8_t *buff;
+	int ret = -ENOTSUP;
+
+	if (res->port_id > nb_ports) {
+		printf("Invalid port, range is [0, %d]\n", nb_ports - 1);
+		return;
+	}
+
+	buff = open_package_file(res->filename);
+	if (!buff)
+		return;
+
+	ret = i40e_process_package(res->port_id, buff);
+	if (ret < 0)
+		printf("Failed to write profile.\n");
+
+	close_package_file(buff);
+}
+
+cmdline_parse_inst_t cmd_write_ppp = {
+	.f = cmd_write_ppp_parsed,
+	.data = NULL,
+	.help_str = "write ppp <port_id> <profile_name>",
+	.tokens = {
+		(void *)&cmd_write_ppp_write,
+		(void *)&cmd_write_ppp_ppp,
+		(void *)&cmd_write_ppp_port_id,
+		(void *)&cmd_write_ppp_filename,
+		NULL,
+	},
+};
+
 /* ******************************************************************************** */
 
 /* list of instructions */
@@ -12570,6 +12626,7 @@ cmdline_parse_ctx_t main_ctx[] = {
 	(cmdline_parse_inst_t *)&cmd_set_vf_allmulti,
 	(cmdline_parse_inst_t *)&cmd_set_vf_broadcast,
 	(cmdline_parse_inst_t *)&cmd_set_vf_vlan_tag,
+	(cmdline_parse_inst_t *)&cmd_write_ppp,
 	NULL,
 };
 
diff --git a/app/test-pmd/config.c b/app/test-pmd/config.c
index 80491fc..aa26da1 100644
--- a/app/test-pmd/config.c
+++ b/app/test-pmd/config.c
@@ -3245,3 +3245,65 @@ port_dcb_info_display(uint8_t port_id)
 		printf("\t%4d", dcb_info.tc_queue.tc_txq[0][i].nb_queue);
 	printf("\n");
 }
+
+uint8_t *
+open_package_file(const char *file_path)
+{
+	FILE *fh = fopen(file_path, "rb");
+	uint32_t pkg_size;
+	uint8_t *buf = NULL;
+	int ret = 0;
+
+	if (fh == NULL) {
+		printf("%s: Failed to open %s\n", __func__, file_path);
+		return buf;
+	}
+
+	ret = fseek(fh, 0, SEEK_END);
+	if (ret < 0) {
+		fclose(fh);
+		printf("%s: File operations failed\n", __func__);
+		return buf;
+	}
+
+	pkg_size = ftell(fh);
+
+	buf = (uint8_t *)malloc(pkg_size);
+	if (!buf) {
+		fclose(fh);
+		printf("%s: Failed to malloc memory\n",	__func__);
+		return buf;
+	}
+
+	ret = fseek(fh, 0, SEEK_SET);
+	if (ret < 0) {
+		fclose(fh);
+                printf("%s: File operations failed\n", __func__);
+		close_package_file(buf);
+		return NULL;
+        }
+	fread(buf, 1, pkg_size, fh);
+
+	for(uint32_t i = 0; i < pkg_size; i++) {
+		if (!(i % 16))
+			printf("   ");
+		printf(" 0x%02X,", buf[i]);
+		if (!((i + 1) % 16))
+			printf("\n");
+	}
+
+	fclose(fh);
+
+	return buf;
+}
+
+int
+close_package_file(uint8_t *buf)
+{
+	if (buf) {
+		free((void *)buf);
+		return 0;
+	}
+
+	return -1;
+}
diff --git a/app/test-pmd/testpmd.h b/app/test-pmd/testpmd.h
index 8cf2860..2a7f683 100644
--- a/app/test-pmd/testpmd.h
+++ b/app/test-pmd/testpmd.h
@@ -622,6 +622,9 @@ void mcast_addr_add(uint8_t port_id, struct ether_addr *mc_addr);
 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_package_file(const char *file_path);
+int close_package_file(uint8_t *buf);
+
 enum print_warning {
 	ENABLED_WARN = 0,
 	DISABLED_WARN
diff --git a/drivers/net/i40e/base/i40e_adminq_cmd.h b/drivers/net/i40e/base/i40e_adminq_cmd.h
index 67cef7c..593394a 100644
--- a/drivers/net/i40e/base/i40e_adminq_cmd.h
+++ b/drivers/net/i40e/base/i40e_adminq_cmd.h
@@ -198,6 +198,10 @@ enum i40e_admin_queue_opc {
 	i40e_aqc_opc_add_mirror_rule	= 0x0260,
 	i40e_aqc_opc_delete_mirror_rule	= 0x0261,
 
+	/* Support Pipeline Personalization Profile */
+        i40e_aqc_opc_write_personalization_profile	= 0x0270,
+        i40e_aqc_opc_read_personalization_profile_list	= 0x0271,
+
 	/* DCB commands */
 	i40e_aqc_opc_dcb_ignore_pfc	= 0x0301,
 	i40e_aqc_opc_dcb_updated	= 0x0302,
@@ -1441,6 +1445,35 @@ struct i40e_aqc_add_delete_mirror_rule_completion {
 
 I40E_CHECK_CMD_LENGTH(i40e_aqc_add_delete_mirror_rule_completion);
 
+/* Pipeline Personalization Profile */
+struct i40e_aqc_write_ppp {
+        u8      flags;
+#define I40E_AQ_WR_PPP_ADD_TRACK_ID     0x01
+#define I40E_AQ_WR_PPP_REMOVE_TRACK_ID  0x02
+        u8      reserved[3];
+        __le32  profile_track_id;
+        __le32  addr_high;
+        __le32  addr_low;
+};
+
+I40E_CHECK_CMD_LENGTH(i40e_aqc_write_ppp);
+
+struct i40e_aqc_write_ppp_resp {
+        __le32 error_offset;
+        __le32 error_info;
+        __le32 addr_high;
+        __le32 addr_low;
+};
+
+struct i40e_aqc_read_ppp {
+	u8      flags;
+	u8      reserved[7];
+	__le32  addr_high;
+	__le32  addr_low;
+};
+
+I40E_CHECK_CMD_LENGTH(i40e_aqc_read_ppp);
+
 /* DCB 0x03xx*/
 
 /* PFC Ignore (direct 0x0301)
diff --git a/drivers/net/i40e/base/i40e_common.c b/drivers/net/i40e/base/i40e_common.c
index b8d8165..4fb419c 100644
--- a/drivers/net/i40e/base/i40e_common.c
+++ b/drivers/net/i40e/base/i40e_common.c
@@ -6997,4 +6997,162 @@ enum i40e_status_code i40e_aq_clear_all_wol_filters(struct i40e_hw *hw,
 	status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
 
 	return status;
-}
\ No newline at end of file
+}
+
+/**
+ * i40e_aq_write_ppp - Write pipeline personalization profile (ppp)
+ * @hw: pointer to the hw struct
+ * @buff: command buffer (size in bytes = buff_size)
+ * @buff_size: buffer size in bytes
+ * @track_id: package tracking id
+ * @cmd_details: pointer to command details structure or NULL
+ **/
+enum
+i40e_status_code i40e_aq_write_ppp(struct i40e_hw *hw, void *buff,
+				   u16 buff_size, u32 track_id,
+				   struct i40e_asq_cmd_details *cmd_details)
+{
+	struct i40e_aq_desc desc;
+	struct i40e_aqc_write_ppp *cmd =
+		(struct i40e_aqc_write_ppp *)&desc.params.raw;
+	struct i40e_aqc_write_ppp_resp *resp;
+	enum i40e_status_code status;
+
+	i40e_fill_default_direct_cmd_desc(&desc,
+				  i40e_aqc_opc_write_personalization_profile);
+
+	desc.flags |= CPU_TO_LE16(I40E_AQ_FLAG_BUF | I40E_AQ_FLAG_RD);
+	if (buff_size > I40E_AQ_LARGE_BUF)
+		desc.flags |= CPU_TO_LE16((u16)I40E_AQ_FLAG_LB);
+
+	desc.datalen = CPU_TO_LE16(buff_size);
+
+	cmd->profile_track_id = CPU_TO_LE32(track_id);
+
+	status = i40e_asq_send_command(hw, &desc, buff, buff_size, cmd_details);
+
+	return status;
+}
+
+/**
+ * i40e_aq_read_ppp - Read pipeline personalization profile (ppp)
+ * @hw: pointer to the hw struct
+ * @buff: command buffer (size in bytes = buff_size)
+ * @buff_size: buffer size in bytes
+ * @cmd_details: pointer to command details structure or NULL
+ **/
+enum
+i40e_status_code i40e_aq_read_ppp(struct i40e_hw *hw,
+				  void *buff, u16 buff_size,
+				  struct i40e_asq_cmd_details *cmd_details)
+{
+	struct i40e_aq_desc desc;
+	struct i40e_aqc_read_ppp *cmd =
+		(struct i40e_aqc_read_ppp *)&desc.params.raw;
+	enum i40e_status_code status;
+
+	i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_read_personalization_profile_list);
+
+	if (buff_size > I40E_AQ_LARGE_BUF)
+		desc.flags |= CPU_TO_LE16((u16)I40E_AQ_FLAG_LB);
+	desc.datalen = CPU_TO_LE16(buff_size);
+
+	status = i40e_asq_send_command(hw, &desc, buff, buff_size, cmd_details);
+
+	return status;
+}
+
+/**
+ * i40e_find_segment_in_package
+ * @segment_type: the segment type to search for (i.e., SEGMENT_TYPE_I40E)
+ * @pkg_hdr: pointer to the package header to be searched
+ *
+ * This function searches a package file for a particular segment type. On
+ * success it returns a pointer to the segment header, otherwise it will
+ * return NULL.
+ */
+struct i40e_generic_seg_header *
+i40e_find_segment_in_package(u32 segment_type,
+			     struct i40e_package_header *pkg_hdr)
+{
+	struct i40e_generic_seg_header *segment;
+	u32 i;
+
+	PMD_DRV_LOG(INFO, "i40e_find_segment_in_package");
+	PMD_DRV_LOG(INFO, "Package version: %d.%d.%d.%d",
+		    pkg_hdr->version.major,
+		    pkg_hdr->version.minor,
+		    pkg_hdr->version.update,
+		    pkg_hdr->version.draft);
+
+	/* Search all package segments for the requested segment type */
+	for (i = 0; i < pkg_hdr->segment_count; i++) {
+		segment =
+			(struct i40e_generic_seg_header *)((u8 *)pkg_hdr +
+		         pkg_hdr->segment_offset[i]);
+
+		if (segment->type == segment_type)
+			return segment;
+	}
+
+	return NULL;
+}
+
+/**
+ * i40e_write_profile
+ * @hw: pointer to the hardware structure
+ * @profile: pointer to the profile segment of the package to be downloaded
+ * @track_id: package tracking id
+ *
+ * Handles the download of a complete package.
+ */
+enum i40e_status_code
+i40e_write_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 *nvm;
+	u32 section_size = 0;
+	u32 i;
+
+	PMD_DRV_LOG(INFO, "i40e_write_profile");
+	PMD_DRV_LOG(INFO, "Segment version: %d.%d.%d.%d",
+		    profile->header.version.major,
+		    profile->header.version.minor,
+		    profile->header.version.update,
+		    profile->header.version.draft);
+	PMD_DRV_LOG(INFO, "Seg: type 0x%X, size %d, name %s",
+		    LE32_TO_CPU(profile->header.type),
+		    LE32_TO_CPU(profile->header.size),
+		    profile->header.name);
+
+	dev_cnt = profile->device_table_count;
+	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 *)((char *)profile +
+					     sec_tbl->section_offset[i]);
+
+		/* Skip 'AQ', 'note' and 'name' sections */
+		if (sec->section.type != SECTION_TYPE_MMIO)
+			continue;
+
+		section_size = sec->section.size +
+			sizeof(struct i40e_profile_section_header);
+		break;
+	}
+
+	/* Write profile */
+	status = i40e_aq_write_ppp(hw, (void *)sec, section_size,
+				   track_id, NULL);
+	if (status) {
+		PMD_DRV_LOG(ERR, "Failed to write profile!");
+		return status;
+	}
+
+	return status;
+}
diff --git a/drivers/net/i40e/base/i40e_prototype.h b/drivers/net/i40e/base/i40e_prototype.h
index 109d3c5..4f7b63f 100644
--- a/drivers/net/i40e/base/i40e_prototype.h
+++ b/drivers/net/i40e/base/i40e_prototype.h
@@ -555,4 +555,16 @@ enum i40e_status_code i40e_write_phy_register(struct i40e_hw *hw,
 u8 i40e_get_phy_address(struct i40e_hw *hw, u8 dev_num);
 enum i40e_status_code i40e_blink_phy_link_led(struct i40e_hw *hw,
 					      u32 time, u32 interval);
+enum i40e_status_code i40e_aq_write_ppp(struct i40e_hw *hw, void *buff,
+				u16 buff_size, u32 track_id,
+				struct i40e_asq_cmd_details *cmd_details);
+enum i40e_status_code i40e_aq_read_ppp(struct i40e_hw *hw,
+			       void *buff, u16 buff_size,
+			       struct i40e_asq_cmd_details *cmd_details);
+struct i40e_generic_seg_header *
+i40e_find_segment_in_package(u32 segment_type,
+			     struct i40e_package_header *pkg_header);
+enum i40e_status_code
+i40e_write_profile(struct i40e_hw *hw, struct i40e_profile_segment *i40e_seg,
+		   u32 track_id);
 #endif /* _I40E_PROTOTYPE_H_ */
diff --git a/drivers/net/i40e/base/i40e_type.h b/drivers/net/i40e/base/i40e_type.h
index 590d97c..dafb8d9 100644
--- a/drivers/net/i40e/base/i40e_type.h
+++ b/drivers/net/i40e/base/i40e_type.h
@@ -1878,4 +1878,73 @@ struct i40e_lldp_variables {
 #define I40E_FLEX_56_MASK		(0x1ULL << I40E_FLEX_56_SHIFT)
 #define I40E_FLEX_57_SHIFT		6
 #define I40E_FLEX_57_MASK		(0x1ULL << I40E_FLEX_57_SHIFT)
+
+/* Version format for PPP */
+struct i40e_ppp_version {
+	u8 major;
+	u8 minor;
+	u8 update;
+	u8 draft;
+};
+
+#define I40E_PPP_NAME_SIZE	32
+
+/* Package header */
+struct i40e_package_header {
+	struct i40e_ppp_version version;
+	u32 segment_count;
+	u32 segment_offset[1];
+};
+
+/* Generic segment header */
+struct i40e_generic_seg_header {
+	#define SEGMENT_TYPE_METADATA	0x00000001
+	#define SEGMENT_TYPE_NOTES	0x00000002
+	#define SEGMENT_TYPE_I40E	0x00000011
+	#define SEGMENT_TYPE_X722	0x00000012
+	u32 type;
+	struct i40e_ppp_version version;
+	u32 size;
+	char name[I40E_PPP_NAME_SIZE];
+};
+
+struct i40e_metadata_segment {
+	struct i40e_generic_seg_header header;
+	struct i40e_ppp_version version;
+	uint32_t track_id;
+	char     name[I40E_PPP_NAME_SIZE];
+};
+
+struct i40e_device_id_entry {
+	u32 device_id;
+	u32 sub_device_id;
+};
+
+struct i40e_profile_segment {
+	struct i40e_generic_seg_header header;
+	struct i40e_ppp_version version;
+	char name[I40E_PPP_NAME_SIZE];
+	u32 device_table_count;
+	struct i40e_device_id_entry device_table[1];
+};
+
+struct i40e_section_table {
+	u32 section_count;
+	u32 section_offset[1];
+};
+
+struct i40e_profile_section_header {
+	u16 tbl_size;
+	u16 data_end;
+	struct {
+		#define SECTION_TYPE_INFO	0x0000010
+		#define SECTION_TYPE_MMIO	0x0000800
+		#define SECTION_TYPE_AQ		0x0000801
+		#define SECTION_TYPE_NOTE	0x8000000
+		#define SECTION_TYPE_NAME	0x8000001
+		u32 type;
+		u32 offset;
+		u32 size;
+	} section;
+};
 #endif /* _I40E_TYPE_H_ */
diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index 303027b..a467711 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -39,6 +39,10 @@
 #include <stdarg.h>
 #include <inttypes.h>
 #include <assert.h>
+#include <sys/stat.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <fcntl.h>
 
 #include <rte_string_fns.h>
 #include <rte_pci.h>
@@ -11212,3 +11216,54 @@ rte_pmd_i40e_reset_vf_stats(uint8_t port,
 
 	return 0;
 }
+
+/**
+ * i40e_process_package - Load package
+ * @port: port id
+ * @filename: file name of the package
+ **/
+int
+i40e_process_package(uint8_t port, uint8_t *buff)
+{
+        struct rte_eth_dev *dev = &rte_eth_devices[port];
+	struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+        struct i40e_package_header *pkg_hdr;
+        struct i40e_generic_seg_header *profile_seg_hdr;
+        struct i40e_generic_seg_header *metadata_seg_hdr;
+        uint32_t track_id;
+        enum i40e_status_code status;
+
+        pkg_hdr = (struct i40e_package_header *)buff;
+
+        if (!pkg_hdr) {
+                PMD_DRV_LOG(ERR, "Failed to fill the package structure");
+                return -EINVAL;
+        }
+
+        /* Find metadata segment */
+        metadata_seg_hdr = i40e_find_segment_in_package(SEGMENT_TYPE_METADATA,
+                                                        pkg_hdr);
+        if (!metadata_seg_hdr) {
+                PMD_DRV_LOG(ERR, "Failed to find metadata segment header");
+                return -EINVAL;
+        }
+        track_id = ((struct i40e_metadata_segment *)metadata_seg_hdr)->track_id;
+
+	/* Find profile segment */
+        profile_seg_hdr = i40e_find_segment_in_package(SEGMENT_TYPE_I40E,
+                                                       pkg_hdr);
+        if (!profile_seg_hdr) {
+                PMD_DRV_LOG(ERR, "Failed to find profile segment header");
+                return -EINVAL;
+        }
+
+        /* Write profile to HW */
+        status = i40e_write_profile(hw,
+				    (struct i40e_profile_segment *)profile_seg_hdr,
+				    track_id);
+
+        if (!status)
+                printf("Write profile successfully.\n");
+
+        return status;
+}
diff --git a/drivers/net/i40e/rte_pmd_i40e.h b/drivers/net/i40e/rte_pmd_i40e.h
index a0ad88c..755a279 100644
--- a/drivers/net/i40e/rte_pmd_i40e.h
+++ b/drivers/net/i40e/rte_pmd_i40e.h
@@ -332,4 +332,5 @@ int rte_pmd_i40e_get_vf_stats(uint8_t port,
 int rte_pmd_i40e_reset_vf_stats(uint8_t port,
 				uint16_t vf_id);
 
+int i40e_process_package(uint8_t port, uint8_t *buff);
 #endif /* _PMD_I40E_H_ */
-- 
2.5.5

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

* [PATCH 0/6] net/i40e: support pipeline personalization profile
  2017-03-03  7:26 [PATCH] MPSL enabling Beilei Xing
                   ` (4 preceding siblings ...)
  2017-03-03  7:26 ` [PATCH] ppp implemantation Beilei Xing
@ 2017-03-03  7:26 ` Beilei Xing
  2017-03-03  7:39   ` [PATCH v2 0/5] " Beilei Xing
  2017-03-03  7:52   ` [PATCH 0/6] net/i40e: support pipeline personalization profile Xing, Beilei
  2017-03-03  7:26 ` [PATCH 1/6] net/i40e: fix a typo in flow Beilei Xing
                   ` (5 subsequent siblings)
  11 siblings, 2 replies; 82+ messages in thread
From: Beilei Xing @ 2017-03-03  7:26 UTC (permalink / raw)
  To: jingjing.wu; +Cc: helin.zhang, dev

Add APIs and driver to support load/get
i40e PPP (Pipeline Personalization Profile)
since PPP will be supported from FVL6 NVM.

Beilei Xing (5):
  net/i40e: support pipeline personalization profile
  net/i40e: add ppp processing
  app/testpmd: add command for writing personalization profile
  net/i40e: add get all loaded profiles
  app/testpmd: add command for getting loaded profiles

Rami Rosen (1):
  net/i40e: fix a typo in flow

 app/test-pmd/cmdline.c          | 121 +++++++++++++++
 app/test-pmd/config.c           |  54 +++++++
 app/test-pmd/testpmd.h          |   4 +
 drivers/net/i40e/i40e_ethdev.c  | 332 ++++++++++++++++++++++++++++++++++++++++
 drivers/net/i40e/i40e_ethdev.h  | 132 ++++++++++++++++
 drivers/net/i40e/i40e_flow.c    |   6 +-
 drivers/net/i40e/rte_pmd_i40e.h |  14 ++
 7 files changed, 660 insertions(+), 3 deletions(-)

-- 
2.5.5

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

* [PATCH 1/6] net/i40e: fix a typo in flow
  2017-03-03  7:26 [PATCH] MPSL enabling Beilei Xing
                   ` (5 preceding siblings ...)
  2017-03-03  7:26 ` [PATCH 0/6] net/i40e: support pipeline personalization profile Beilei Xing
@ 2017-03-03  7:26 ` Beilei Xing
  2017-03-03  7:26 ` [PATCH 2/6] net/i40e: support pipeline personalization profile Beilei Xing
                   ` (4 subsequent siblings)
  11 siblings, 0 replies; 82+ messages in thread
From: Beilei Xing @ 2017-03-03  7:26 UTC (permalink / raw)
  To: jingjing.wu; +Cc: helin.zhang, dev, Rami Rosen, stable

From: Rami Rosen <rami.rosen@intel.com>

This patch fixes a trivial typo in i40e_flow.c.

Fixes: 47c6782344b7 ("net/i40e: fix tunnel filter")
Fixes: d416530e6358 ("net/i40e: parse tunnel filter")
Cc: stable@dpdk.org

Signed-off-by: Rami Rosen <rami.rosen@intel.com>
Acked-by: John McNamara <john.mcnamara@intel.com>
Signed-off-by: Beilei Xing <beilei.xing@intel.com>
---
 drivers/net/i40e/i40e_flow.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/net/i40e/i40e_flow.c b/drivers/net/i40e/i40e_flow.c
index c6e4d87..f163ce5 100644
--- a/drivers/net/i40e/i40e_flow.c
+++ b/drivers/net/i40e/i40e_flow.c
@@ -1309,7 +1309,7 @@ i40e_flow_parse_vxlan_pattern(const struct rte_flow_item *pattern,
 		case RTE_FLOW_ITEM_TYPE_IPV4:
 			filter->ip_type = RTE_TUNNEL_IPTYPE_IPV4;
 			/* IPv4 is used to describe protocol,
-			 * spec amd mask should be NULL.
+			 * spec and mask should be NULL.
 			 */
 			if (item->spec || item->mask) {
 				rte_flow_error_set(error, EINVAL,
@@ -1322,7 +1322,7 @@ i40e_flow_parse_vxlan_pattern(const struct rte_flow_item *pattern,
 		case RTE_FLOW_ITEM_TYPE_IPV6:
 			filter->ip_type = RTE_TUNNEL_IPTYPE_IPV6;
 			/* IPv6 is used to describe protocol,
-			 * spec amd mask should be NULL.
+			 * spec and mask should be NULL.
 			 */
 			if (item->spec || item->mask) {
 				rte_flow_error_set(error, EINVAL,
@@ -1334,7 +1334,7 @@ i40e_flow_parse_vxlan_pattern(const struct rte_flow_item *pattern,
 			break;
 		case RTE_FLOW_ITEM_TYPE_UDP:
 			/* UDP is used to describe protocol,
-			 * spec amd mask should be NULL.
+			 * spec and mask should be NULL.
 			 */
 			if (item->spec || item->mask) {
 				rte_flow_error_set(error, EINVAL,
-- 
2.5.5

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

* [PATCH 2/6] net/i40e: support pipeline personalization profile
  2017-03-03  7:26 [PATCH] MPSL enabling Beilei Xing
                   ` (6 preceding siblings ...)
  2017-03-03  7:26 ` [PATCH 1/6] net/i40e: fix a typo in flow Beilei Xing
@ 2017-03-03  7:26 ` Beilei Xing
  2017-03-03  7:26 ` [PATCH 3/6] net/i40e: add ppp processing Beilei Xing
                   ` (3 subsequent siblings)
  11 siblings, 0 replies; 82+ messages in thread
From: Beilei Xing @ 2017-03-03  7:26 UTC (permalink / raw)
  To: jingjing.wu; +Cc: helin.zhang, dev

Add admin queue functions for Pipeline Personalization
Profile AQ commands defined in DCR 287:
 - Write Recipe Command buffer (Opcode: 0x0270)
 - Get Applied Profiles list (Opcode: 0x0271)
This patch will be moved to base driver in future.

Signed-off-by: Beilei Xing <beilei.xing@intel.com>
---
 drivers/net/i40e/i40e_ethdev.c | 237 +++++++++++++++++++++++++++++++++++++++++
 drivers/net/i40e/i40e_ethdev.h | 127 ++++++++++++++++++++++
 2 files changed, 364 insertions(+)

diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index 508fcc8..ca4a87d 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -11219,3 +11219,240 @@ rte_pmd_i40e_reset_vf_stats(uint8_t port,
 
 	return 0;
 }
+
+/**
+ * i40e_aq_write_ppp - Write pipeline personalization profile (ppp)
+ * @hw: pointer to the hw struct
+ * @buff: command buffer (size in bytes = buff_size)
+ * @buff_size: buffer size in bytes
+ * @track_id: package tracking id
+ * @error_offset: returns error offset
+ * @error_info: returns error information
+ * @cmd_details: pointer to command details structure or NULL
+ **/
+enum
+i40e_status_code i40e_aq_write_ppp(struct i40e_hw *hw, void *buff,
+				   uint16_t buff_size, uint32_t track_id,
+				   uint32_t *error_offset, uint32_t *error_info,
+				   struct i40e_asq_cmd_details *cmd_details)
+{
+	struct i40e_aq_desc desc;
+	struct i40e_aqc_write_personalization_profile *cmd =
+	(struct i40e_aqc_write_personalization_profile *)&desc.params.raw;
+	struct i40e_aqc_write_ppp_resp *resp;
+	enum i40e_status_code status;
+
+	i40e_fill_default_direct_cmd_desc(&desc,
+				  i40e_aqc_opc_write_personalization_profile);
+
+	desc.flags |= CPU_TO_LE16(I40E_AQ_FLAG_BUF | I40E_AQ_FLAG_RD);
+	if (buff_size > I40E_AQ_LARGE_BUF)
+		desc.flags |= CPU_TO_LE16((uint16_t)I40E_AQ_FLAG_LB);
+
+	desc.datalen = CPU_TO_LE16(buff_size);
+
+	cmd->profile_track_id = CPU_TO_LE32(track_id);
+
+	status = i40e_asq_send_command(hw, &desc, buff, buff_size, cmd_details);
+	if (!status) {
+		resp = (struct i40e_aqc_write_ppp_resp *)&desc.params.raw;
+		if (error_offset)
+			*error_offset = LE32_TO_CPU(resp->error_offset);
+		if (error_info)
+			*error_info = LE32_TO_CPU(resp->error_info);
+	}
+
+	return status;
+}
+
+/**
+ * i40e_aq_get_ppp_list - Read pipeline personalization profile (ppp)
+ * @hw: pointer to the hw struct
+ * @buff: command buffer (size in bytes = buff_size)
+ * @buff_size: buffer size in bytes
+ * @cmd_details: pointer to command details structure or NULL
+ **/
+enum
+i40e_status_code i40e_aq_get_ppp_list(struct i40e_hw *hw, void *buff,
+				      uint16_t buff_size, uint8_t flags,
+				      struct i40e_asq_cmd_details *cmd_details)
+{
+	struct i40e_aq_desc desc;
+	struct i40e_aqc_get_applied_profiles *cmd =
+		(struct i40e_aqc_get_applied_profiles *)&desc.params.raw;
+	enum i40e_status_code status;
+
+	i40e_fill_default_direct_cmd_desc(&desc,
+			  i40e_aqc_opc_get_personalization_profile_list);
+
+	desc.flags |= CPU_TO_LE16((u16)I40E_AQ_FLAG_BUF);
+	if (buff_size > I40E_AQ_LARGE_BUF)
+		desc.flags |= CPU_TO_LE16((uint16_t)I40E_AQ_FLAG_LB);
+	desc.datalen = CPU_TO_LE16(buff_size);
+
+	cmd->flags = flags;
+
+	status = i40e_asq_send_command(hw, &desc, buff, buff_size, cmd_details);
+
+	return status;
+}
+
+/**
+ * i40e_find_segment_in_package
+ * @segment_type: the segment type to search for (i.e., SEGMENT_TYPE_I40E)
+ * @pkg_hdr: pointer to the package header to be searched
+ *
+ * This function searches a package file for a particular segment type. On
+ * success it returns a pointer to the segment header, otherwise it will
+ * return NULL.
+ */
+struct i40e_generic_seg_header *
+i40e_find_segment_in_package(uint32_t segment_type,
+			     struct i40e_package_header *pkg_hdr)
+{
+	struct i40e_generic_seg_header *segment;
+	uint32_t i;
+
+	PMD_DRV_LOG(INFO, "i40e_find_segment_in_package");
+	PMD_DRV_LOG(INFO, "Package version: %d.%d.%d.%d",
+		    pkg_hdr->version.major,
+		    pkg_hdr->version.minor,
+		    pkg_hdr->version.update,
+		    pkg_hdr->version.draft);
+
+	/* Search all package segments for the requested segment type */
+	for (i = 0; i < pkg_hdr->segment_count; i++) {
+		segment =
+			(struct i40e_generic_seg_header *)((uint8_t *)pkg_hdr +
+			 pkg_hdr->segment_offset[i]);
+
+		if (segment->type == segment_type)
+			return segment;
+	}
+
+	return NULL;
+}
+
+/**
+ * i40e_write_profile
+ * @hw: pointer to the hardware structure
+ * @profile: pointer to the profile segment of the package to be downloaded
+ * @track_id: package tracking id
+ *
+ * Handles the download of a complete package.
+ */
+enum i40e_status_code
+i40e_write_profile(struct i40e_hw *hw, struct i40e_profile_segment *profile,
+		   uint32_t track_id)
+{
+	enum i40e_status_code status = I40E_SUCCESS;
+	struct i40e_section_table *sec_tbl;
+	struct i40e_profile_section_header *sec = NULL;
+	uint32_t dev_cnt;
+	uint32_t vendor_dev_id;
+	uint32_t *nvm;
+	uint32_t section_size = 0;
+	uint32_t offset = 0, info = 0;
+	uint32_t i;
+
+	PMD_DRV_LOG(INFO, "i40e_write_profile");
+	PMD_DRV_LOG(INFO, "Segment version: %d.%d.%d.%d",
+		    profile->header.version.major,
+		    profile->header.version.minor,
+		    profile->header.version.update,
+		    profile->header.version.draft);
+	PMD_DRV_LOG(INFO, "Seg: type 0x%X, size %d, name %s",
+		    LE32_TO_CPU(profile->header.type),
+		    LE32_TO_CPU(profile->header.size),
+		    profile->header.name);
+
+	if (!track_id) {
+		PMD_DRV_LOG(ERR, "Track_id can't be 0.");
+		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 (i == dev_cnt) {
+		PMD_DRV_LOG(ERR, "Device doesn't support PPP");
+		return I40E_ERR_DEVICE_NOT_SUPPORTED;
+	}
+
+	nvm = (uint32_t *)&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 *)
+			((uint8_t *)profile +
+			 sec_tbl->section_offset[i]);
+
+		/* Skip 'AQ', 'note' and 'name' sections */
+		if (sec->section.type != SECTION_TYPE_MMIO)
+			continue;
+
+		section_size = sec->section.size +
+			sizeof(struct i40e_profile_section_header);
+
+		/* Write profile */
+		status = i40e_aq_write_ppp(hw, (void *)sec,
+					   (uint16_t)section_size,
+					   track_id, &offset, &info, NULL);
+		if (status) {
+			PMD_DRV_LOG(ERR, "Failed to write profile: "
+				    "offset %d, info %d",
+				    offset, info);
+			break;
+		}
+	}
+
+	return status;
+}
+
+/**
+ * i40e_add_pinfo_to_list
+ * @hw: pointer to the hardware structure
+ * @profile: pointer to the profile segment of the package
+ * @profile_info_sec: buffer for information section
+ * @track_id: package tracking id
+ *
+ * Register a profile to the list of loaded profiles.
+ */
+enum i40e_status_code
+i40e_add_pinfo_to_list(struct i40e_hw *hw,
+		       struct i40e_profile_segment *profile,
+		       uint8_t *profile_info_sec, uint32_t track_id)
+{
+	enum i40e_status_code status = I40E_SUCCESS;
+	struct i40e_profile_section_header *sec = NULL;
+	struct i40e_profile_info *pinfo;
+	uint32_t offset = 0, info = 0;
+
+	sec = (struct i40e_profile_section_header *)profile_info_sec;
+	sec->tbl_size = 1;
+	sec->data_end = sizeof(struct i40e_profile_section_header) +
+		sizeof(struct i40e_profile_info);
+	sec->section.type = SECTION_TYPE_INFO;
+	sec->section.offset = sizeof(struct i40e_profile_section_header);
+	sec->section.size = sizeof(struct i40e_profile_info);
+	pinfo = (struct i40e_profile_info *)(profile_info_sec +
+					     sec->section.offset);
+	pinfo->track_id = track_id;
+	pinfo->version = profile->version;
+	pinfo->op = I40E_PPP_ADD_TRACKID;
+	memcpy(pinfo->name, profile->name, I40E_PPP_NAME_SIZE);
+
+	status = i40e_aq_write_ppp(hw, (void *)sec, sec->data_end,
+				   track_id, &offset, &info, NULL);
+	if (status)
+		PMD_DRV_LOG(ERR, "Failed to add to list: "
+			    "offset %d, info %d",
+			    offset, info);
+
+	return status;
+}
diff --git a/drivers/net/i40e/i40e_ethdev.h b/drivers/net/i40e/i40e_ethdev.h
index f545850..e3eb1b9 100644
--- a/drivers/net/i40e/i40e_ethdev.h
+++ b/drivers/net/i40e/i40e_ethdev.h
@@ -729,6 +729,116 @@ struct i40e_valid_pattern {
 	parse_filter_t parse_filter;
 };
 
+/* Support Pipeline Personalization Profile */
+#define i40e_aqc_opc_write_personalization_profile	0x0270
+#define i40e_aqc_opc_get_personalization_profile_list	0x0271
+struct i40e_aqc_write_personalization_profile {
+	uint8_t   reserved[4];
+	uint32_t  profile_track_id;
+	uint32_t  addr_high;
+	uint32_t  addr_low;
+};
+
+I40E_CHECK_CMD_LENGTH(i40e_aqc_write_personalization_profile);
+
+struct i40e_aqc_write_ppp_resp {
+	uint32_t error_offset;
+	uint32_t error_info;
+	uint32_t addr_high;
+	uint32_t addr_low;
+};
+
+struct i40e_aqc_get_applied_profiles {
+	uint8_t      flags;
+	#define I40E_AQC_GET_PPP_GET_CONF	0x1
+	#define I40E_AQC_GET_PPP_GET_RDPU_CONF	0x2
+	uint8_t   rsv[3];
+	uint32_t  reserved;
+	uint32_t  addr_high;
+	uint32_t  addr_low;
+};
+
+I40E_CHECK_CMD_LENGTH(i40e_aqc_get_applied_profiles);
+
+/* Version format for PPP */
+struct i40e_ppp_version {
+	uint8_t major;
+	uint8_t minor;
+	uint8_t update;
+	uint8_t draft;
+};
+
+#define I40E_PPP_NAME_SIZE	32
+
+/* Package header */
+struct i40e_package_header {
+	struct i40e_ppp_version version;
+	uint32_t segment_count;
+	uint32_t segment_offset[1];
+};
+
+/* Generic segment header */
+struct i40e_generic_seg_header {
+#define SEGMENT_TYPE_METADATA	0x00000001
+#define SEGMENT_TYPE_NOTES	0x00000002
+#define SEGMENT_TYPE_I40E	0x00000011
+#define SEGMENT_TYPE_X722	0x00000012
+	uint32_t type;
+	struct i40e_ppp_version version;
+	uint32_t size;
+	char name[I40E_PPP_NAME_SIZE];
+};
+
+struct i40e_metadata_segment {
+	struct i40e_generic_seg_header header;
+	struct i40e_ppp_version version;
+	uint32_t track_id;
+	char name[I40E_PPP_NAME_SIZE];
+};
+
+struct i40e_device_id_entry {
+	uint32_t vendor_dev_id;
+	uint32_t sub_vendor_dev_id;
+};
+
+struct i40e_profile_segment {
+	struct i40e_generic_seg_header header;
+	struct i40e_ppp_version version;
+	char name[I40E_PPP_NAME_SIZE];
+	uint32_t device_table_count;
+	struct i40e_device_id_entry device_table[1];
+};
+
+struct i40e_section_table {
+	uint32_t section_count;
+	uint32_t section_offset[1];
+};
+
+struct i40e_profile_section_header {
+	uint16_t tbl_size;
+	uint16_t data_end;
+	struct {
+#define SECTION_TYPE_INFO	0x0000010
+#define SECTION_TYPE_MMIO	0x0000800
+#define SECTION_TYPE_AQ		0x0000801
+#define SECTION_TYPE_NOTE	0x80000000
+#define SECTION_TYPE_NAME	0x80000001
+		uint32_t type;
+		uint32_t offset;
+		uint32_t size;
+	} section;
+};
+
+struct i40e_profile_info {
+	uint32_t track_id;
+	struct i40e_ppp_version version;
+	uint8_t op;
+#define I40E_PPP_ADD_TRACKID    0x01
+#define I40E_PPP_REMOVE_TRACKID 0x02
+	uint8_t reserved[7];
+	uint8_t name[I40E_PPP_NAME_SIZE];
+};
+
 int i40e_dev_switch_queues(struct i40e_pf *pf, bool on);
 int i40e_vsi_release(struct i40e_vsi *vsi);
 struct i40e_vsi *i40e_vsi_setup(struct i40e_pf *pf,
@@ -805,6 +915,23 @@ int i40e_dev_tunnel_filter_set(struct i40e_pf *pf,
 			       struct rte_eth_tunnel_filter_conf *tunnel_filter,
 			       uint8_t add);
 int i40e_fdir_flush(struct rte_eth_dev *dev);
+enum i40e_status_code i40e_aq_write_ppp(struct i40e_hw *hw, void *buff,
+				uint16_t buff_size, uint32_t track_id,
+				uint32_t *error_offset, uint32_t *error_info,
+				struct i40e_asq_cmd_details *cmd_details);
+enum i40e_status_code i40e_aq_get_ppp_list(struct i40e_hw *hw, void *buff,
+				   uint16_t buff_size, uint8_t flags,
+				   struct i40e_asq_cmd_details *cmd_details);
+struct i40e_generic_seg_header *
+i40e_find_segment_in_package(uint32_t segment_type,
+			     struct i40e_package_header *pkg_header);
+enum i40e_status_code
+i40e_write_profile(struct i40e_hw *hw, struct i40e_profile_segment *i40e_seg,
+		   uint32_t track_id);
+enum i40e_status_code
+i40e_add_pinfo_to_list(struct i40e_hw *hw,
+		       struct i40e_profile_segment *profile,
+		       uint8_t *profile_info_sec, uint32_t track_id);
 
 #define I40E_DEV_TO_PCI(eth_dev) \
 	RTE_DEV_TO_PCI((eth_dev)->device)
-- 
2.5.5

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

* [PATCH 3/6] net/i40e: add ppp processing
  2017-03-03  7:26 [PATCH] MPSL enabling Beilei Xing
                   ` (7 preceding siblings ...)
  2017-03-03  7:26 ` [PATCH 2/6] net/i40e: support pipeline personalization profile Beilei Xing
@ 2017-03-03  7:26 ` Beilei Xing
  2017-03-03  7:26 ` [PATCH 4/6] app/testpmd: add command for writing personalization profile Beilei Xing
                   ` (2 subsequent siblings)
  11 siblings, 0 replies; 82+ messages in thread
From: Beilei Xing @ 2017-03-03  7:26 UTC (permalink / raw)
  To: jingjing.wu; +Cc: helin.zhang, dev

Add loading profile function.

Signed-off-by: Beilei Xing <beilei.xing@intel.com>
---
 drivers/net/i40e/i40e_ethdev.c  | 59 +++++++++++++++++++++++++++++++++++++++++
 drivers/net/i40e/rte_pmd_i40e.h |  7 +++++
 2 files changed, 66 insertions(+)

diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index ca4a87d..dae4b97 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -11456,3 +11456,62 @@ i40e_add_pinfo_to_list(struct i40e_hw *hw,
 
 	return status;
 }
+
+int
+i40e_process_package(uint8_t port, uint8_t *buff)
+{
+	struct rte_eth_dev *dev = &rte_eth_devices[port];
+	struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+	struct i40e_package_header *pkg_hdr;
+	struct i40e_generic_seg_header *profile_seg_hdr;
+	struct i40e_generic_seg_header *metadata_seg_hdr;
+	uint32_t track_id;
+	uint8_t *profile_info_sec;
+	enum i40e_status_code status;
+
+	pkg_hdr = (struct i40e_package_header *)buff;
+
+	if (!pkg_hdr) {
+		PMD_DRV_LOG(ERR, "Failed to fill the package structure");
+		return -EINVAL;
+	}
+
+	/* Find metadata segment */
+	metadata_seg_hdr = i40e_find_segment_in_package(SEGMENT_TYPE_METADATA,
+							pkg_hdr);
+	if (!metadata_seg_hdr) {
+		PMD_DRV_LOG(ERR, "Failed to find metadata segment header");
+		return -EINVAL;
+	}
+	track_id = ((struct i40e_metadata_segment *)metadata_seg_hdr)->track_id;
+
+	/* Find profile segment */
+	profile_seg_hdr = i40e_find_segment_in_package(SEGMENT_TYPE_I40E,
+						       pkg_hdr);
+	if (!profile_seg_hdr) {
+		PMD_DRV_LOG(ERR, "Failed to find profile segment header");
+		return -EINVAL;
+	}
+
+	/* Write profile to HW */
+	status = i40e_write_profile(hw,
+			    (struct i40e_profile_segment *)profile_seg_hdr,
+			    track_id);
+	if (!status)
+		printf("Write profile successfully.\n");
+
+	/* Add the profile info to the list of loaded profiles */
+	profile_info_sec = rte_zmalloc("i40e_profile_info",
+			       sizeof(struct i40e_profile_section_header) +
+			       sizeof(struct i40e_profile_info),
+			       0);
+	status = i40e_add_pinfo_to_list(hw,
+			(struct i40e_profile_segment *)profile_seg_hdr,
+			profile_info_sec, track_id);
+	if (!status)
+		printf("Add profile info successfully.\n");
+
+	rte_free(profile_info_sec);
+
+	return status;
+}
diff --git a/drivers/net/i40e/rte_pmd_i40e.h b/drivers/net/i40e/rte_pmd_i40e.h
index a0ad88c..7bd444c 100644
--- a/drivers/net/i40e/rte_pmd_i40e.h
+++ b/drivers/net/i40e/rte_pmd_i40e.h
@@ -332,4 +332,11 @@ int rte_pmd_i40e_get_vf_stats(uint8_t port,
 int rte_pmd_i40e_reset_vf_stats(uint8_t port,
 				uint16_t vf_id);
 
+/**
+ * i40e_process_package - Load package
+ * @port: port id
+ * @buff: buffer of package
+ **/
+int i40e_process_package(uint8_t port, uint8_t *buff);
+
 #endif /* _PMD_I40E_H_ */
-- 
2.5.5

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

* [PATCH 4/6] app/testpmd: add command for writing personalization profile
  2017-03-03  7:26 [PATCH] MPSL enabling Beilei Xing
                   ` (8 preceding siblings ...)
  2017-03-03  7:26 ` [PATCH 3/6] net/i40e: add ppp processing Beilei Xing
@ 2017-03-03  7:26 ` Beilei Xing
  2017-03-03  7:26 ` [PATCH 5/6] net/i40e: add get all loaded profiles Beilei Xing
  2017-03-03  7:26 ` [PATCH 6/6] app/testpmd: add command for getting " Beilei Xing
  11 siblings, 0 replies; 82+ messages in thread
From: Beilei Xing @ 2017-03-03  7:26 UTC (permalink / raw)
  To: jingjing.wu; +Cc: helin.zhang, dev

This patch is to add testpmd CLI for writing personalization
profile.

Signed-off-by: Beilei Xing <beilei.xing@intel.com>
---
 app/test-pmd/cmdline.c | 61 ++++++++++++++++++++++++++++++++++++++++++++++++++
 app/test-pmd/config.c  | 54 ++++++++++++++++++++++++++++++++++++++++++++
 app/test-pmd/testpmd.h |  3 +++
 3 files changed, 118 insertions(+)

diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
index 43fc636..6b6af87 100644
--- a/app/test-pmd/cmdline.c
+++ b/app/test-pmd/cmdline.c
@@ -12395,6 +12395,66 @@ cmdline_parse_inst_t cmd_set_vf_vlan_tag = {
 	},
 };
 
+/* Write Pipeline Personalization Profile */
+struct cmd_write_ppp_result {
+	cmdline_fixed_string_t write;
+	cmdline_fixed_string_t ppp;
+	uint8_t port_id;
+	char filename[];
+};
+
+cmdline_parse_token_string_t cmd_write_ppp_write =
+	TOKEN_STRING_INITIALIZER(struct cmd_write_ppp_result, write, "write");
+cmdline_parse_token_string_t cmd_write_ppp_ppp =
+	TOKEN_STRING_INITIALIZER(struct cmd_write_ppp_result, ppp, "ppp");
+cmdline_parse_token_num_t cmd_write_ppp_port_id =
+	TOKEN_NUM_INITIALIZER(struct cmd_write_ppp_result, port_id, UINT8);
+cmdline_parse_token_string_t cmd_write_ppp_filename =
+	TOKEN_STRING_INITIALIZER(struct cmd_write_ppp_result, filename, NULL);
+
+static void
+cmd_write_ppp_parsed(
+	void *parsed_result,
+	__attribute__((unused)) struct cmdline *cl,
+	__attribute__((unused)) void *data)
+{
+	struct cmd_write_ppp_result *res = parsed_result;
+	uint8_t *buff;
+	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_package_file(res->filename);
+	if (!buff)
+		return;
+
+	ret = i40e_process_package(res->port_id, buff);
+	if (ret < 0)
+		printf("Failed to write profile.\n");
+
+	close_package_file(buff);
+}
+
+cmdline_parse_inst_t cmd_write_ppp = {
+	.f = cmd_write_ppp_parsed,
+	.data = NULL,
+	.help_str = "write ppp <port_id> <profile_name>",
+	.tokens = {
+		(void *)&cmd_write_ppp_write,
+		(void *)&cmd_write_ppp_ppp,
+		(void *)&cmd_write_ppp_port_id,
+		(void *)&cmd_write_ppp_filename,
+		NULL,
+	},
+};
 /* ******************************************************************************** */
 
 /* list of instructions */
@@ -12570,6 +12630,7 @@ cmdline_parse_ctx_t main_ctx[] = {
 	(cmdline_parse_inst_t *)&cmd_set_vf_allmulti,
 	(cmdline_parse_inst_t *)&cmd_set_vf_broadcast,
 	(cmdline_parse_inst_t *)&cmd_set_vf_vlan_tag,
+	(cmdline_parse_inst_t *)&cmd_write_ppp,
 	NULL,
 };
 
diff --git a/app/test-pmd/config.c b/app/test-pmd/config.c
index 80491fc..f520c42 100644
--- a/app/test-pmd/config.c
+++ b/app/test-pmd/config.c
@@ -3245,3 +3245,57 @@ port_dcb_info_display(uint8_t port_id)
 		printf("\t%4d", dcb_info.tc_queue.tc_txq[0][i].nb_queue);
 	printf("\n");
 }
+
+uint8_t *
+open_package_file(const char *file_path)
+{
+	FILE *fh = fopen(file_path, "rb");
+	uint32_t pkg_size;
+	uint8_t *buf = NULL;
+	int ret = 0;
+
+	if (fh == NULL) {
+		printf("%s: Failed to open %s\n", __func__, file_path);
+		return buf;
+	}
+
+	ret = fseek(fh, 0, SEEK_END);
+	if (ret < 0) {
+		fclose(fh);
+		printf("%s: File operations failed\n", __func__);
+		return buf;
+	}
+
+	pkg_size = ftell(fh);
+
+	buf = (uint8_t *)malloc(pkg_size);
+	if (!buf) {
+		fclose(fh);
+		printf("%s: Failed to malloc memory\n",	__func__);
+		return buf;
+	}
+
+	ret = fseek(fh, 0, SEEK_SET);
+	if (ret < 0) {
+		fclose(fh);
+		printf("%s: File operations failed\n", __func__);
+		close_package_file(buf);
+		return NULL;
+	}
+	fread(buf, 1, pkg_size, fh);
+
+	fclose(fh);
+
+	return buf;
+}
+
+int
+close_package_file(uint8_t *buf)
+{
+	if (buf) {
+		free((void *)buf);
+		return 0;
+	}
+
+	return -1;
+}
diff --git a/app/test-pmd/testpmd.h b/app/test-pmd/testpmd.h
index 8cf2860..2a7f683 100644
--- a/app/test-pmd/testpmd.h
+++ b/app/test-pmd/testpmd.h
@@ -622,6 +622,9 @@ void mcast_addr_add(uint8_t port_id, struct ether_addr *mc_addr);
 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_package_file(const char *file_path);
+int close_package_file(uint8_t *buf);
+
 enum print_warning {
 	ENABLED_WARN = 0,
 	DISABLED_WARN
-- 
2.5.5

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

* [PATCH 5/6] net/i40e: add get all loaded profiles
  2017-03-03  7:26 [PATCH] MPSL enabling Beilei Xing
                   ` (9 preceding siblings ...)
  2017-03-03  7:26 ` [PATCH 4/6] app/testpmd: add command for writing personalization profile Beilei Xing
@ 2017-03-03  7:26 ` Beilei Xing
  2017-03-03  7:26 ` [PATCH 6/6] app/testpmd: add command for getting " Beilei Xing
  11 siblings, 0 replies; 82+ messages in thread
From: Beilei Xing @ 2017-03-03  7:26 UTC (permalink / raw)
  To: jingjing.wu; +Cc: helin.zhang, dev

This patch is to add get all loaded profiles function.

Signed-off-by: Beilei Xing <beilei.xing@intel.com>
---
 drivers/net/i40e/i40e_ethdev.c  | 36 ++++++++++++++++++++++++++++++++++++
 drivers/net/i40e/i40e_ethdev.h  |  5 +++++
 drivers/net/i40e/rte_pmd_i40e.h |  7 +++++++
 3 files changed, 48 insertions(+)

diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index dae4b97..5361311 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -11515,3 +11515,39 @@ i40e_process_package(uint8_t port, uint8_t *buff)
 
 	return status;
 }
+
+#define I40E_PROFILE_INFO_SIZE 48
+#define I40E_MAX_PROFILE_NUM 16
+int
+i40e_get_ppp_list(uint8_t port, uint8_t *buff)
+{
+	struct rte_eth_dev *dev = &rte_eth_devices[port];
+	struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+	struct i40e_profile_list *p_list;
+	struct i40e_profile_info *p_info;
+	uint32_t p_num, i;
+	enum i40e_status_code status = I40E_SUCCESS;
+
+	status = i40e_aq_get_ppp_list(hw, (void *)buff,
+		      (I40E_PROFILE_INFO_SIZE * I40E_MAX_PROFILE_NUM + 4),
+		      0, NULL);
+	if (status < 0)
+		return status;
+
+	p_list = (struct i40e_profile_list *)buff;
+	p_num = p_list->p_count;
+	printf("Profile number is: %d\n\n", p_num);
+
+	for (i = 0; i < p_num; i++) {
+		p_info = &p_list->p_info[i];
+		printf("Profile %d:\n", i);
+		printf("Track id: 0x%x\n", p_info->track_id);
+		printf("Version: %d.%d.%d.%d \n\n",
+		       p_info->version.major,
+		       p_info->version.minor,
+		       p_info->version.update,
+		       p_info->version.draft);
+	}
+
+	return status;
+}
diff --git a/drivers/net/i40e/i40e_ethdev.h b/drivers/net/i40e/i40e_ethdev.h
index e3eb1b9..9efc20e 100644
--- a/drivers/net/i40e/i40e_ethdev.h
+++ b/drivers/net/i40e/i40e_ethdev.h
@@ -839,6 +839,11 @@ struct i40e_profile_info {
 	uint8_t name[I40E_PPP_NAME_SIZE];
 };
 
+struct i40e_profile_list {
+	uint32_t p_count;
+	struct i40e_profile_info p_info[1];
+};
+
 int i40e_dev_switch_queues(struct i40e_pf *pf, bool on);
 int i40e_vsi_release(struct i40e_vsi *vsi);
 struct i40e_vsi *i40e_vsi_setup(struct i40e_pf *pf,
diff --git a/drivers/net/i40e/rte_pmd_i40e.h b/drivers/net/i40e/rte_pmd_i40e.h
index 7bd444c..a9daf6c 100644
--- a/drivers/net/i40e/rte_pmd_i40e.h
+++ b/drivers/net/i40e/rte_pmd_i40e.h
@@ -339,4 +339,11 @@ int rte_pmd_i40e_reset_vf_stats(uint8_t port,
  **/
 int i40e_process_package(uint8_t port, uint8_t *buff);
 
+/**
+ * i40e_get_ppp_list - Get loaded profiles
+ * @port: port id
+ * @buff: buffer for response
+ **/
+int i40e_get_ppp_list(uint8_t port, uint8_t *buff);
+
 #endif /* _PMD_I40E_H_ */
-- 
2.5.5

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

* [PATCH 6/6] app/testpmd: add command for getting loaded profiles
  2017-03-03  7:26 [PATCH] MPSL enabling Beilei Xing
                   ` (10 preceding siblings ...)
  2017-03-03  7:26 ` [PATCH 5/6] net/i40e: add get all loaded profiles Beilei Xing
@ 2017-03-03  7:26 ` Beilei Xing
  11 siblings, 0 replies; 82+ messages in thread
From: Beilei Xing @ 2017-03-03  7:26 UTC (permalink / raw)
  To: jingjing.wu; +Cc: helin.zhang, dev

This patch is to add testpmd CLI for getting all loaded profiles.

Signed-off-by: Beilei Xing <beilei.xing@intel.com>
---
 app/test-pmd/cmdline.c | 60 ++++++++++++++++++++++++++++++++++++++++++++++++++
 app/test-pmd/testpmd.h |  1 +
 2 files changed, 61 insertions(+)

diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
index 6b6af87..b231c04 100644
--- a/app/test-pmd/cmdline.c
+++ b/app/test-pmd/cmdline.c
@@ -12455,6 +12455,65 @@ cmdline_parse_inst_t cmd_write_ppp = {
 		NULL,
 	},
 };
+
+/* Get Pipeline Personalization Profile list*/
+#define PROFILE_INFO_SIZE 48
+#define MAX_PROFILE_NUM 16
+
+struct cmd_get_ppp_list_result {
+	cmdline_fixed_string_t get;
+	cmdline_fixed_string_t ppp;
+	cmdline_fixed_string_t list;
+	uint8_t port_id;
+};
+
+cmdline_parse_token_string_t cmd_get_ppp_list_get =
+	TOKEN_STRING_INITIALIZER(struct cmd_get_ppp_list_result, get, "get");
+cmdline_parse_token_string_t cmd_get_ppp_list_ppp =
+	TOKEN_STRING_INITIALIZER(struct cmd_get_ppp_list_result, ppp, "ppp");
+cmdline_parse_token_string_t cmd_get_ppp_list_list =
+	TOKEN_STRING_INITIALIZER(struct cmd_get_ppp_list_result, list, "list");
+cmdline_parse_token_num_t cmd_get_ppp_list_port_id =
+	TOKEN_NUM_INITIALIZER(struct cmd_get_ppp_list_result, port_id, UINT8);
+
+static void
+cmd_get_ppp_list_parsed(
+	void *parsed_result,
+	__attribute__((unused)) struct cmdline *cl,
+	__attribute__((unused)) void *data)
+{
+	struct cmd_get_ppp_list_result *res = parsed_result;
+	uint8_t *buff;
+	int ret;
+
+	if (res->port_id > nb_ports) {
+		printf("Invalid port, range is [0, %d]\n", nb_ports - 1);
+		return;
+	}
+
+	buff = (uint8_t *)malloc(PROFILE_INFO_SIZE * MAX_PROFILE_NUM + 4);
+	if (!buff)
+		printf("%s: Failed to malloc buffer\n", __func__);
+
+	ret = i40e_get_ppp_list(res->port_id, buff);
+	if (ret < 0)
+		printf("Failed to get ppp list\n");
+
+	free(buff);
+}
+
+cmdline_parse_inst_t cmd_get_ppp_list = {
+	.f = cmd_get_ppp_list_parsed,
+	.data = NULL,
+	.help_str = "get ppp list <port_id>",
+	.tokens = {
+		(void *)&cmd_get_ppp_list_get,
+		(void *)&cmd_get_ppp_list_ppp,
+		(void *)&cmd_get_ppp_list_list,
+		(void *)&cmd_get_ppp_list_port_id,
+		NULL,
+	},
+};
 /* ******************************************************************************** */
 
 /* list of instructions */
@@ -12631,6 +12690,7 @@ cmdline_parse_ctx_t main_ctx[] = {
 	(cmdline_parse_inst_t *)&cmd_set_vf_broadcast,
 	(cmdline_parse_inst_t *)&cmd_set_vf_vlan_tag,
 	(cmdline_parse_inst_t *)&cmd_write_ppp,
+	(cmdline_parse_inst_t *)&cmd_get_ppp_list,
 	NULL,
 };
 
diff --git a/app/test-pmd/testpmd.h b/app/test-pmd/testpmd.h
index 2a7f683..a7aa218 100644
--- a/app/test-pmd/testpmd.h
+++ b/app/test-pmd/testpmd.h
@@ -624,6 +624,7 @@ void port_dcb_info_display(uint8_t port_id);
 
 uint8_t *open_package_file(const char *file_path);
 int close_package_file(uint8_t *buf);
+void get_ppp_list(uint8_t port_id);
 
 enum print_warning {
 	ENABLED_WARN = 0,
-- 
2.5.5

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

* [PATCH v2 0/5] net/i40e: support pipeline personalization profile
  2017-03-03  7:26 ` [PATCH 0/6] net/i40e: support pipeline personalization profile Beilei Xing
@ 2017-03-03  7:39   ` Beilei Xing
  2017-03-03  7:39     ` [PATCH v2 1/5] " Beilei Xing
                       ` (6 more replies)
  2017-03-03  7:52   ` [PATCH 0/6] net/i40e: support pipeline personalization profile Xing, Beilei
  1 sibling, 7 replies; 82+ messages in thread
From: Beilei Xing @ 2017-03-03  7:39 UTC (permalink / raw)
  To: jingjing.wu; +Cc: helin.zhang, dev

Add APIs and driver to support load/get
i40e PPP (Pipeline Personalization Profile)
since PPP will be supported from FVL6 NVM.

v2 change:
 Correct patch num.

Beilei Xing (5):
  net/i40e: support pipeline personalization profile
  net/i40e: add ppp processing
  app/testpmd: add command for writing personalization profile
  net/i40e: add get all loaded profiles
  app/testpmd: add command for getting loaded profiles

 app/test-pmd/cmdline.c          | 121 +++++++++++++++
 app/test-pmd/config.c           |  54 +++++++
 app/test-pmd/testpmd.h          |   4 +
 drivers/net/i40e/i40e_ethdev.c  | 332 ++++++++++++++++++++++++++++++++++++++++
 drivers/net/i40e/i40e_ethdev.h  | 132 ++++++++++++++++
 drivers/net/i40e/rte_pmd_i40e.h |  14 ++
 6 files changed, 657 insertions(+)

-- 
2.5.5

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

* [PATCH v2 1/5] net/i40e: support pipeline personalization profile
  2017-03-03  7:39   ` [PATCH v2 0/5] " Beilei Xing
@ 2017-03-03  7:39     ` Beilei Xing
  2017-03-08 12:07       ` Ferruh Yigit
  2017-03-03  7:39     ` [PATCH v2 2/5] net/i40e: add ppp processing Beilei Xing
                       ` (5 subsequent siblings)
  6 siblings, 1 reply; 82+ messages in thread
From: Beilei Xing @ 2017-03-03  7:39 UTC (permalink / raw)
  To: jingjing.wu; +Cc: helin.zhang, dev

Add admin queue functions for Pipeline Personalization
Profile AQ commands defined in DCR 287:
 - Write Recipe Command buffer (Opcode: 0x0270)
 - Get Applied Profiles list (Opcode: 0x0271)
This patch will be moved to base driver in future.

Signed-off-by: Beilei Xing <beilei.xing@intel.com>
---
 drivers/net/i40e/i40e_ethdev.c | 237 +++++++++++++++++++++++++++++++++++++++++
 drivers/net/i40e/i40e_ethdev.h | 127 ++++++++++++++++++++++
 2 files changed, 364 insertions(+)

diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index 508fcc8..ca4a87d 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -11219,3 +11219,240 @@ rte_pmd_i40e_reset_vf_stats(uint8_t port,
 
 	return 0;
 }
+
+/**
+ * i40e_aq_write_ppp - Write pipeline personalization profile (ppp)
+ * @hw: pointer to the hw struct
+ * @buff: command buffer (size in bytes = buff_size)
+ * @buff_size: buffer size in bytes
+ * @track_id: package tracking id
+ * @error_offset: returns error offset
+ * @error_info: returns error information
+ * @cmd_details: pointer to command details structure or NULL
+ **/
+enum
+i40e_status_code i40e_aq_write_ppp(struct i40e_hw *hw, void *buff,
+				   uint16_t buff_size, uint32_t track_id,
+				   uint32_t *error_offset, uint32_t *error_info,
+				   struct i40e_asq_cmd_details *cmd_details)
+{
+	struct i40e_aq_desc desc;
+	struct i40e_aqc_write_personalization_profile *cmd =
+	(struct i40e_aqc_write_personalization_profile *)&desc.params.raw;
+	struct i40e_aqc_write_ppp_resp *resp;
+	enum i40e_status_code status;
+
+	i40e_fill_default_direct_cmd_desc(&desc,
+				  i40e_aqc_opc_write_personalization_profile);
+
+	desc.flags |= CPU_TO_LE16(I40E_AQ_FLAG_BUF | I40E_AQ_FLAG_RD);
+	if (buff_size > I40E_AQ_LARGE_BUF)
+		desc.flags |= CPU_TO_LE16((uint16_t)I40E_AQ_FLAG_LB);
+
+	desc.datalen = CPU_TO_LE16(buff_size);
+
+	cmd->profile_track_id = CPU_TO_LE32(track_id);
+
+	status = i40e_asq_send_command(hw, &desc, buff, buff_size, cmd_details);
+	if (!status) {
+		resp = (struct i40e_aqc_write_ppp_resp *)&desc.params.raw;
+		if (error_offset)
+			*error_offset = LE32_TO_CPU(resp->error_offset);
+		if (error_info)
+			*error_info = LE32_TO_CPU(resp->error_info);
+	}
+
+	return status;
+}
+
+/**
+ * i40e_aq_get_ppp_list - Read pipeline personalization profile (ppp)
+ * @hw: pointer to the hw struct
+ * @buff: command buffer (size in bytes = buff_size)
+ * @buff_size: buffer size in bytes
+ * @cmd_details: pointer to command details structure or NULL
+ **/
+enum
+i40e_status_code i40e_aq_get_ppp_list(struct i40e_hw *hw, void *buff,
+				      uint16_t buff_size, uint8_t flags,
+				      struct i40e_asq_cmd_details *cmd_details)
+{
+	struct i40e_aq_desc desc;
+	struct i40e_aqc_get_applied_profiles *cmd =
+		(struct i40e_aqc_get_applied_profiles *)&desc.params.raw;
+	enum i40e_status_code status;
+
+	i40e_fill_default_direct_cmd_desc(&desc,
+			  i40e_aqc_opc_get_personalization_profile_list);
+
+	desc.flags |= CPU_TO_LE16((u16)I40E_AQ_FLAG_BUF);
+	if (buff_size > I40E_AQ_LARGE_BUF)
+		desc.flags |= CPU_TO_LE16((uint16_t)I40E_AQ_FLAG_LB);
+	desc.datalen = CPU_TO_LE16(buff_size);
+
+	cmd->flags = flags;
+
+	status = i40e_asq_send_command(hw, &desc, buff, buff_size, cmd_details);
+
+	return status;
+}
+
+/**
+ * i40e_find_segment_in_package
+ * @segment_type: the segment type to search for (i.e., SEGMENT_TYPE_I40E)
+ * @pkg_hdr: pointer to the package header to be searched
+ *
+ * This function searches a package file for a particular segment type. On
+ * success it returns a pointer to the segment header, otherwise it will
+ * return NULL.
+ */
+struct i40e_generic_seg_header *
+i40e_find_segment_in_package(uint32_t segment_type,
+			     struct i40e_package_header *pkg_hdr)
+{
+	struct i40e_generic_seg_header *segment;
+	uint32_t i;
+
+	PMD_DRV_LOG(INFO, "i40e_find_segment_in_package");
+	PMD_DRV_LOG(INFO, "Package version: %d.%d.%d.%d",
+		    pkg_hdr->version.major,
+		    pkg_hdr->version.minor,
+		    pkg_hdr->version.update,
+		    pkg_hdr->version.draft);
+
+	/* Search all package segments for the requested segment type */
+	for (i = 0; i < pkg_hdr->segment_count; i++) {
+		segment =
+			(struct i40e_generic_seg_header *)((uint8_t *)pkg_hdr +
+			 pkg_hdr->segment_offset[i]);
+
+		if (segment->type == segment_type)
+			return segment;
+	}
+
+	return NULL;
+}
+
+/**
+ * i40e_write_profile
+ * @hw: pointer to the hardware structure
+ * @profile: pointer to the profile segment of the package to be downloaded
+ * @track_id: package tracking id
+ *
+ * Handles the download of a complete package.
+ */
+enum i40e_status_code
+i40e_write_profile(struct i40e_hw *hw, struct i40e_profile_segment *profile,
+		   uint32_t track_id)
+{
+	enum i40e_status_code status = I40E_SUCCESS;
+	struct i40e_section_table *sec_tbl;
+	struct i40e_profile_section_header *sec = NULL;
+	uint32_t dev_cnt;
+	uint32_t vendor_dev_id;
+	uint32_t *nvm;
+	uint32_t section_size = 0;
+	uint32_t offset = 0, info = 0;
+	uint32_t i;
+
+	PMD_DRV_LOG(INFO, "i40e_write_profile");
+	PMD_DRV_LOG(INFO, "Segment version: %d.%d.%d.%d",
+		    profile->header.version.major,
+		    profile->header.version.minor,
+		    profile->header.version.update,
+		    profile->header.version.draft);
+	PMD_DRV_LOG(INFO, "Seg: type 0x%X, size %d, name %s",
+		    LE32_TO_CPU(profile->header.type),
+		    LE32_TO_CPU(profile->header.size),
+		    profile->header.name);
+
+	if (!track_id) {
+		PMD_DRV_LOG(ERR, "Track_id can't be 0.");
+		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 (i == dev_cnt) {
+		PMD_DRV_LOG(ERR, "Device doesn't support PPP");
+		return I40E_ERR_DEVICE_NOT_SUPPORTED;
+	}
+
+	nvm = (uint32_t *)&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 *)
+			((uint8_t *)profile +
+			 sec_tbl->section_offset[i]);
+
+		/* Skip 'AQ', 'note' and 'name' sections */
+		if (sec->section.type != SECTION_TYPE_MMIO)
+			continue;
+
+		section_size = sec->section.size +
+			sizeof(struct i40e_profile_section_header);
+
+		/* Write profile */
+		status = i40e_aq_write_ppp(hw, (void *)sec,
+					   (uint16_t)section_size,
+					   track_id, &offset, &info, NULL);
+		if (status) {
+			PMD_DRV_LOG(ERR, "Failed to write profile: "
+				    "offset %d, info %d",
+				    offset, info);
+			break;
+		}
+	}
+
+	return status;
+}
+
+/**
+ * i40e_add_pinfo_to_list
+ * @hw: pointer to the hardware structure
+ * @profile: pointer to the profile segment of the package
+ * @profile_info_sec: buffer for information section
+ * @track_id: package tracking id
+ *
+ * Register a profile to the list of loaded profiles.
+ */
+enum i40e_status_code
+i40e_add_pinfo_to_list(struct i40e_hw *hw,
+		       struct i40e_profile_segment *profile,
+		       uint8_t *profile_info_sec, uint32_t track_id)
+{
+	enum i40e_status_code status = I40E_SUCCESS;
+	struct i40e_profile_section_header *sec = NULL;
+	struct i40e_profile_info *pinfo;
+	uint32_t offset = 0, info = 0;
+
+	sec = (struct i40e_profile_section_header *)profile_info_sec;
+	sec->tbl_size = 1;
+	sec->data_end = sizeof(struct i40e_profile_section_header) +
+		sizeof(struct i40e_profile_info);
+	sec->section.type = SECTION_TYPE_INFO;
+	sec->section.offset = sizeof(struct i40e_profile_section_header);
+	sec->section.size = sizeof(struct i40e_profile_info);
+	pinfo = (struct i40e_profile_info *)(profile_info_sec +
+					     sec->section.offset);
+	pinfo->track_id = track_id;
+	pinfo->version = profile->version;
+	pinfo->op = I40E_PPP_ADD_TRACKID;
+	memcpy(pinfo->name, profile->name, I40E_PPP_NAME_SIZE);
+
+	status = i40e_aq_write_ppp(hw, (void *)sec, sec->data_end,
+				   track_id, &offset, &info, NULL);
+	if (status)
+		PMD_DRV_LOG(ERR, "Failed to add to list: "
+			    "offset %d, info %d",
+			    offset, info);
+
+	return status;
+}
diff --git a/drivers/net/i40e/i40e_ethdev.h b/drivers/net/i40e/i40e_ethdev.h
index f545850..e3eb1b9 100644
--- a/drivers/net/i40e/i40e_ethdev.h
+++ b/drivers/net/i40e/i40e_ethdev.h
@@ -729,6 +729,116 @@ struct i40e_valid_pattern {
 	parse_filter_t parse_filter;
 };
 
+/* Support Pipeline Personalization Profile */
+#define i40e_aqc_opc_write_personalization_profile	0x0270
+#define i40e_aqc_opc_get_personalization_profile_list	0x0271
+struct i40e_aqc_write_personalization_profile {
+	uint8_t   reserved[4];
+	uint32_t  profile_track_id;
+	uint32_t  addr_high;
+	uint32_t  addr_low;
+};
+
+I40E_CHECK_CMD_LENGTH(i40e_aqc_write_personalization_profile);
+
+struct i40e_aqc_write_ppp_resp {
+	uint32_t error_offset;
+	uint32_t error_info;
+	uint32_t addr_high;
+	uint32_t addr_low;
+};
+
+struct i40e_aqc_get_applied_profiles {
+	uint8_t      flags;
+	#define I40E_AQC_GET_PPP_GET_CONF	0x1
+	#define I40E_AQC_GET_PPP_GET_RDPU_CONF	0x2
+	uint8_t   rsv[3];
+	uint32_t  reserved;
+	uint32_t  addr_high;
+	uint32_t  addr_low;
+};
+
+I40E_CHECK_CMD_LENGTH(i40e_aqc_get_applied_profiles);
+
+/* Version format for PPP */
+struct i40e_ppp_version {
+	uint8_t major;
+	uint8_t minor;
+	uint8_t update;
+	uint8_t draft;
+};
+
+#define I40E_PPP_NAME_SIZE	32
+
+/* Package header */
+struct i40e_package_header {
+	struct i40e_ppp_version version;
+	uint32_t segment_count;
+	uint32_t segment_offset[1];
+};
+
+/* Generic segment header */
+struct i40e_generic_seg_header {
+#define SEGMENT_TYPE_METADATA	0x00000001
+#define SEGMENT_TYPE_NOTES	0x00000002
+#define SEGMENT_TYPE_I40E	0x00000011
+#define SEGMENT_TYPE_X722	0x00000012
+	uint32_t type;
+	struct i40e_ppp_version version;
+	uint32_t size;
+	char name[I40E_PPP_NAME_SIZE];
+};
+
+struct i40e_metadata_segment {
+	struct i40e_generic_seg_header header;
+	struct i40e_ppp_version version;
+	uint32_t track_id;
+	char name[I40E_PPP_NAME_SIZE];
+};
+
+struct i40e_device_id_entry {
+	uint32_t vendor_dev_id;
+	uint32_t sub_vendor_dev_id;
+};
+
+struct i40e_profile_segment {
+	struct i40e_generic_seg_header header;
+	struct i40e_ppp_version version;
+	char name[I40E_PPP_NAME_SIZE];
+	uint32_t device_table_count;
+	struct i40e_device_id_entry device_table[1];
+};
+
+struct i40e_section_table {
+	uint32_t section_count;
+	uint32_t section_offset[1];
+};
+
+struct i40e_profile_section_header {
+	uint16_t tbl_size;
+	uint16_t data_end;
+	struct {
+#define SECTION_TYPE_INFO	0x0000010
+#define SECTION_TYPE_MMIO	0x0000800
+#define SECTION_TYPE_AQ		0x0000801
+#define SECTION_TYPE_NOTE	0x80000000
+#define SECTION_TYPE_NAME	0x80000001
+		uint32_t type;
+		uint32_t offset;
+		uint32_t size;
+	} section;
+};
+
+struct i40e_profile_info {
+	uint32_t track_id;
+	struct i40e_ppp_version version;
+	uint8_t op;
+#define I40E_PPP_ADD_TRACKID    0x01
+#define I40E_PPP_REMOVE_TRACKID 0x02
+	uint8_t reserved[7];
+	uint8_t name[I40E_PPP_NAME_SIZE];
+};
+
 int i40e_dev_switch_queues(struct i40e_pf *pf, bool on);
 int i40e_vsi_release(struct i40e_vsi *vsi);
 struct i40e_vsi *i40e_vsi_setup(struct i40e_pf *pf,
@@ -805,6 +915,23 @@ int i40e_dev_tunnel_filter_set(struct i40e_pf *pf,
 			       struct rte_eth_tunnel_filter_conf *tunnel_filter,
 			       uint8_t add);
 int i40e_fdir_flush(struct rte_eth_dev *dev);
+enum i40e_status_code i40e_aq_write_ppp(struct i40e_hw *hw, void *buff,
+				uint16_t buff_size, uint32_t track_id,
+				uint32_t *error_offset, uint32_t *error_info,
+				struct i40e_asq_cmd_details *cmd_details);
+enum i40e_status_code i40e_aq_get_ppp_list(struct i40e_hw *hw, void *buff,
+				   uint16_t buff_size, uint8_t flags,
+				   struct i40e_asq_cmd_details *cmd_details);
+struct i40e_generic_seg_header *
+i40e_find_segment_in_package(uint32_t segment_type,
+			     struct i40e_package_header *pkg_header);
+enum i40e_status_code
+i40e_write_profile(struct i40e_hw *hw, struct i40e_profile_segment *i40e_seg,
+		   uint32_t track_id);
+enum i40e_status_code
+i40e_add_pinfo_to_list(struct i40e_hw *hw,
+		       struct i40e_profile_segment *profile,
+		       uint8_t *profile_info_sec, uint32_t track_id);
 
 #define I40E_DEV_TO_PCI(eth_dev) \
 	RTE_DEV_TO_PCI((eth_dev)->device)
-- 
2.5.5

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

* [PATCH v2 2/5] net/i40e: add ppp processing
  2017-03-03  7:39   ` [PATCH v2 0/5] " Beilei Xing
  2017-03-03  7:39     ` [PATCH v2 1/5] " Beilei Xing
@ 2017-03-03  7:39     ` Beilei Xing
  2017-03-08 12:07       ` Ferruh Yigit
  2017-03-03  7:39     ` [PATCH v2 3/5] app/testpmd: add command for writing personalization profile Beilei Xing
                       ` (4 subsequent siblings)
  6 siblings, 1 reply; 82+ messages in thread
From: Beilei Xing @ 2017-03-03  7:39 UTC (permalink / raw)
  To: jingjing.wu; +Cc: helin.zhang, dev

Add loading profile function.

Signed-off-by: Beilei Xing <beilei.xing@intel.com>
---
 drivers/net/i40e/i40e_ethdev.c  | 59 +++++++++++++++++++++++++++++++++++++++++
 drivers/net/i40e/rte_pmd_i40e.h |  7 +++++
 2 files changed, 66 insertions(+)

diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index ca4a87d..dae4b97 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -11456,3 +11456,62 @@ i40e_add_pinfo_to_list(struct i40e_hw *hw,
 
 	return status;
 }
+
+int
+i40e_process_package(uint8_t port, uint8_t *buff)
+{
+	struct rte_eth_dev *dev = &rte_eth_devices[port];
+	struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+	struct i40e_package_header *pkg_hdr;
+	struct i40e_generic_seg_header *profile_seg_hdr;
+	struct i40e_generic_seg_header *metadata_seg_hdr;
+	uint32_t track_id;
+	uint8_t *profile_info_sec;
+	enum i40e_status_code status;
+
+	pkg_hdr = (struct i40e_package_header *)buff;
+
+	if (!pkg_hdr) {
+		PMD_DRV_LOG(ERR, "Failed to fill the package structure");
+		return -EINVAL;
+	}
+
+	/* Find metadata segment */
+	metadata_seg_hdr = i40e_find_segment_in_package(SEGMENT_TYPE_METADATA,
+							pkg_hdr);
+	if (!metadata_seg_hdr) {
+		PMD_DRV_LOG(ERR, "Failed to find metadata segment header");
+		return -EINVAL;
+	}
+	track_id = ((struct i40e_metadata_segment *)metadata_seg_hdr)->track_id;
+
+	/* Find profile segment */
+	profile_seg_hdr = i40e_find_segment_in_package(SEGMENT_TYPE_I40E,
+						       pkg_hdr);
+	if (!profile_seg_hdr) {
+		PMD_DRV_LOG(ERR, "Failed to find profile segment header");
+		return -EINVAL;
+	}
+
+	/* Write profile to HW */
+	status = i40e_write_profile(hw,
+			    (struct i40e_profile_segment *)profile_seg_hdr,
+			    track_id);
+	if (!status)
+		printf("Write profile successfully.\n");
+
+	/* Add the profile info to the list of loaded profiles */
+	profile_info_sec = rte_zmalloc("i40e_profile_info",
+			       sizeof(struct i40e_profile_section_header) +
+			       sizeof(struct i40e_profile_info),
+			       0);
+	status = i40e_add_pinfo_to_list(hw,
+			(struct i40e_profile_segment *)profile_seg_hdr,
+			profile_info_sec, track_id);
+	if (!status)
+		printf("Add profile info successfully.\n");
+
+	rte_free(profile_info_sec);
+
+	return status;
+}
diff --git a/drivers/net/i40e/rte_pmd_i40e.h b/drivers/net/i40e/rte_pmd_i40e.h
index a0ad88c..7bd444c 100644
--- a/drivers/net/i40e/rte_pmd_i40e.h
+++ b/drivers/net/i40e/rte_pmd_i40e.h
@@ -332,4 +332,11 @@ int rte_pmd_i40e_get_vf_stats(uint8_t port,
 int rte_pmd_i40e_reset_vf_stats(uint8_t port,
 				uint16_t vf_id);
 
+/**
+ * i40e_process_package - Load package
+ * @port: port id
+ * @buff: buffer of package
+ **/
+int i40e_process_package(uint8_t port, uint8_t *buff);
+
 #endif /* _PMD_I40E_H_ */
-- 
2.5.5

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

* [PATCH v2 3/5] app/testpmd: add command for writing personalization profile
  2017-03-03  7:39   ` [PATCH v2 0/5] " Beilei Xing
  2017-03-03  7:39     ` [PATCH v2 1/5] " Beilei Xing
  2017-03-03  7:39     ` [PATCH v2 2/5] net/i40e: add ppp processing Beilei Xing
@ 2017-03-03  7:39     ` Beilei Xing
  2017-03-08 12:10       ` Ferruh Yigit
  2017-03-03  7:39     ` [PATCH v2 4/5] net/i40e: add get all loaded profiles Beilei Xing
                       ` (3 subsequent siblings)
  6 siblings, 1 reply; 82+ messages in thread
From: Beilei Xing @ 2017-03-03  7:39 UTC (permalink / raw)
  To: jingjing.wu; +Cc: helin.zhang, dev

This patch is to add testpmd CLI for writing personalization
profile.

Signed-off-by: Beilei Xing <beilei.xing@intel.com>
---
 app/test-pmd/cmdline.c | 61 ++++++++++++++++++++++++++++++++++++++++++++++++++
 app/test-pmd/config.c  | 54 ++++++++++++++++++++++++++++++++++++++++++++
 app/test-pmd/testpmd.h |  3 +++
 3 files changed, 118 insertions(+)

diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
index 43fc636..6b6af87 100644
--- a/app/test-pmd/cmdline.c
+++ b/app/test-pmd/cmdline.c
@@ -12395,6 +12395,66 @@ cmdline_parse_inst_t cmd_set_vf_vlan_tag = {
 	},
 };
 
+/* Write Pipeline Personalization Profile */
+struct cmd_write_ppp_result {
+	cmdline_fixed_string_t write;
+	cmdline_fixed_string_t ppp;
+	uint8_t port_id;
+	char filename[];
+};
+
+cmdline_parse_token_string_t cmd_write_ppp_write =
+	TOKEN_STRING_INITIALIZER(struct cmd_write_ppp_result, write, "write");
+cmdline_parse_token_string_t cmd_write_ppp_ppp =
+	TOKEN_STRING_INITIALIZER(struct cmd_write_ppp_result, ppp, "ppp");
+cmdline_parse_token_num_t cmd_write_ppp_port_id =
+	TOKEN_NUM_INITIALIZER(struct cmd_write_ppp_result, port_id, UINT8);
+cmdline_parse_token_string_t cmd_write_ppp_filename =
+	TOKEN_STRING_INITIALIZER(struct cmd_write_ppp_result, filename, NULL);
+
+static void
+cmd_write_ppp_parsed(
+	void *parsed_result,
+	__attribute__((unused)) struct cmdline *cl,
+	__attribute__((unused)) void *data)
+{
+	struct cmd_write_ppp_result *res = parsed_result;
+	uint8_t *buff;
+	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_package_file(res->filename);
+	if (!buff)
+		return;
+
+	ret = i40e_process_package(res->port_id, buff);
+	if (ret < 0)
+		printf("Failed to write profile.\n");
+
+	close_package_file(buff);
+}
+
+cmdline_parse_inst_t cmd_write_ppp = {
+	.f = cmd_write_ppp_parsed,
+	.data = NULL,
+	.help_str = "write ppp <port_id> <profile_name>",
+	.tokens = {
+		(void *)&cmd_write_ppp_write,
+		(void *)&cmd_write_ppp_ppp,
+		(void *)&cmd_write_ppp_port_id,
+		(void *)&cmd_write_ppp_filename,
+		NULL,
+	},
+};
 /* ******************************************************************************** */
 
 /* list of instructions */
@@ -12570,6 +12630,7 @@ cmdline_parse_ctx_t main_ctx[] = {
 	(cmdline_parse_inst_t *)&cmd_set_vf_allmulti,
 	(cmdline_parse_inst_t *)&cmd_set_vf_broadcast,
 	(cmdline_parse_inst_t *)&cmd_set_vf_vlan_tag,
+	(cmdline_parse_inst_t *)&cmd_write_ppp,
 	NULL,
 };
 
diff --git a/app/test-pmd/config.c b/app/test-pmd/config.c
index 80491fc..f520c42 100644
--- a/app/test-pmd/config.c
+++ b/app/test-pmd/config.c
@@ -3245,3 +3245,57 @@ port_dcb_info_display(uint8_t port_id)
 		printf("\t%4d", dcb_info.tc_queue.tc_txq[0][i].nb_queue);
 	printf("\n");
 }
+
+uint8_t *
+open_package_file(const char *file_path)
+{
+	FILE *fh = fopen(file_path, "rb");
+	uint32_t pkg_size;
+	uint8_t *buf = NULL;
+	int ret = 0;
+
+	if (fh == NULL) {
+		printf("%s: Failed to open %s\n", __func__, file_path);
+		return buf;
+	}
+
+	ret = fseek(fh, 0, SEEK_END);
+	if (ret < 0) {
+		fclose(fh);
+		printf("%s: File operations failed\n", __func__);
+		return buf;
+	}
+
+	pkg_size = ftell(fh);
+
+	buf = (uint8_t *)malloc(pkg_size);
+	if (!buf) {
+		fclose(fh);
+		printf("%s: Failed to malloc memory\n",	__func__);
+		return buf;
+	}
+
+	ret = fseek(fh, 0, SEEK_SET);
+	if (ret < 0) {
+		fclose(fh);
+		printf("%s: File operations failed\n", __func__);
+		close_package_file(buf);
+		return NULL;
+	}
+	fread(buf, 1, pkg_size, fh);
+
+	fclose(fh);
+
+	return buf;
+}
+
+int
+close_package_file(uint8_t *buf)
+{
+	if (buf) {
+		free((void *)buf);
+		return 0;
+	}
+
+	return -1;
+}
diff --git a/app/test-pmd/testpmd.h b/app/test-pmd/testpmd.h
index 8cf2860..2a7f683 100644
--- a/app/test-pmd/testpmd.h
+++ b/app/test-pmd/testpmd.h
@@ -622,6 +622,9 @@ void mcast_addr_add(uint8_t port_id, struct ether_addr *mc_addr);
 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_package_file(const char *file_path);
+int close_package_file(uint8_t *buf);
+
 enum print_warning {
 	ENABLED_WARN = 0,
 	DISABLED_WARN
-- 
2.5.5

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

* [PATCH v2 4/5] net/i40e: add get all loaded profiles
  2017-03-03  7:39   ` [PATCH v2 0/5] " Beilei Xing
                       ` (2 preceding siblings ...)
  2017-03-03  7:39     ` [PATCH v2 3/5] app/testpmd: add command for writing personalization profile Beilei Xing
@ 2017-03-03  7:39     ` Beilei Xing
  2017-03-03  7:39     ` [PATCH v2 5/5] app/testpmd: add command for getting " Beilei Xing
                       ` (2 subsequent siblings)
  6 siblings, 0 replies; 82+ messages in thread
From: Beilei Xing @ 2017-03-03  7:39 UTC (permalink / raw)
  To: jingjing.wu; +Cc: helin.zhang, dev

This patch is to add get all loaded profiles function.

Signed-off-by: Beilei Xing <beilei.xing@intel.com>
---
 drivers/net/i40e/i40e_ethdev.c  | 36 ++++++++++++++++++++++++++++++++++++
 drivers/net/i40e/i40e_ethdev.h  |  5 +++++
 drivers/net/i40e/rte_pmd_i40e.h |  7 +++++++
 3 files changed, 48 insertions(+)

diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index dae4b97..5361311 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -11515,3 +11515,39 @@ i40e_process_package(uint8_t port, uint8_t *buff)
 
 	return status;
 }
+
+#define I40E_PROFILE_INFO_SIZE 48
+#define I40E_MAX_PROFILE_NUM 16
+int
+i40e_get_ppp_list(uint8_t port, uint8_t *buff)
+{
+	struct rte_eth_dev *dev = &rte_eth_devices[port];
+	struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+	struct i40e_profile_list *p_list;
+	struct i40e_profile_info *p_info;
+	uint32_t p_num, i;
+	enum i40e_status_code status = I40E_SUCCESS;
+
+	status = i40e_aq_get_ppp_list(hw, (void *)buff,
+		      (I40E_PROFILE_INFO_SIZE * I40E_MAX_PROFILE_NUM + 4),
+		      0, NULL);
+	if (status < 0)
+		return status;
+
+	p_list = (struct i40e_profile_list *)buff;
+	p_num = p_list->p_count;
+	printf("Profile number is: %d\n\n", p_num);
+
+	for (i = 0; i < p_num; i++) {
+		p_info = &p_list->p_info[i];
+		printf("Profile %d:\n", i);
+		printf("Track id: 0x%x\n", p_info->track_id);
+		printf("Version: %d.%d.%d.%d \n\n",
+		       p_info->version.major,
+		       p_info->version.minor,
+		       p_info->version.update,
+		       p_info->version.draft);
+	}
+
+	return status;
+}
diff --git a/drivers/net/i40e/i40e_ethdev.h b/drivers/net/i40e/i40e_ethdev.h
index e3eb1b9..9efc20e 100644
--- a/drivers/net/i40e/i40e_ethdev.h
+++ b/drivers/net/i40e/i40e_ethdev.h
@@ -839,6 +839,11 @@ struct i40e_profile_info {
 	uint8_t name[I40E_PPP_NAME_SIZE];
 };
 
+struct i40e_profile_list {
+	uint32_t p_count;
+	struct i40e_profile_info p_info[1];
+};
+
 int i40e_dev_switch_queues(struct i40e_pf *pf, bool on);
 int i40e_vsi_release(struct i40e_vsi *vsi);
 struct i40e_vsi *i40e_vsi_setup(struct i40e_pf *pf,
diff --git a/drivers/net/i40e/rte_pmd_i40e.h b/drivers/net/i40e/rte_pmd_i40e.h
index 7bd444c..a9daf6c 100644
--- a/drivers/net/i40e/rte_pmd_i40e.h
+++ b/drivers/net/i40e/rte_pmd_i40e.h
@@ -339,4 +339,11 @@ int rte_pmd_i40e_reset_vf_stats(uint8_t port,
  **/
 int i40e_process_package(uint8_t port, uint8_t *buff);
 
+/**
+ * i40e_get_ppp_list - Get loaded profiles
+ * @port: port id
+ * @buff: buffer for response
+ **/
+int i40e_get_ppp_list(uint8_t port, uint8_t *buff);
+
 #endif /* _PMD_I40E_H_ */
-- 
2.5.5

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

* [PATCH v2 5/5] app/testpmd: add command for getting loaded profiles
  2017-03-03  7:39   ` [PATCH v2 0/5] " Beilei Xing
                       ` (3 preceding siblings ...)
  2017-03-03  7:39     ` [PATCH v2 4/5] net/i40e: add get all loaded profiles Beilei Xing
@ 2017-03-03  7:39     ` Beilei Xing
  2017-03-08 11:43     ` [PATCH v2 0/5] net/i40e: support pipeline personalization profile Ferruh Yigit
  2017-03-23 10:02     ` [PATCH v3 0/5] pipeline personalization profile support Beilei Xing
  6 siblings, 0 replies; 82+ messages in thread
From: Beilei Xing @ 2017-03-03  7:39 UTC (permalink / raw)
  To: jingjing.wu; +Cc: helin.zhang, dev

This patch is to add testpmd CLI for getting all loaded profiles.

Signed-off-by: Beilei Xing <beilei.xing@intel.com>
---
 app/test-pmd/cmdline.c | 60 ++++++++++++++++++++++++++++++++++++++++++++++++++
 app/test-pmd/testpmd.h |  1 +
 2 files changed, 61 insertions(+)

diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
index 6b6af87..b231c04 100644
--- a/app/test-pmd/cmdline.c
+++ b/app/test-pmd/cmdline.c
@@ -12455,6 +12455,65 @@ cmdline_parse_inst_t cmd_write_ppp = {
 		NULL,
 	},
 };
+
+/* Get Pipeline Personalization Profile list*/
+#define PROFILE_INFO_SIZE 48
+#define MAX_PROFILE_NUM 16
+
+struct cmd_get_ppp_list_result {
+	cmdline_fixed_string_t get;
+	cmdline_fixed_string_t ppp;
+	cmdline_fixed_string_t list;
+	uint8_t port_id;
+};
+
+cmdline_parse_token_string_t cmd_get_ppp_list_get =
+	TOKEN_STRING_INITIALIZER(struct cmd_get_ppp_list_result, get, "get");
+cmdline_parse_token_string_t cmd_get_ppp_list_ppp =
+	TOKEN_STRING_INITIALIZER(struct cmd_get_ppp_list_result, ppp, "ppp");
+cmdline_parse_token_string_t cmd_get_ppp_list_list =
+	TOKEN_STRING_INITIALIZER(struct cmd_get_ppp_list_result, list, "list");
+cmdline_parse_token_num_t cmd_get_ppp_list_port_id =
+	TOKEN_NUM_INITIALIZER(struct cmd_get_ppp_list_result, port_id, UINT8);
+
+static void
+cmd_get_ppp_list_parsed(
+	void *parsed_result,
+	__attribute__((unused)) struct cmdline *cl,
+	__attribute__((unused)) void *data)
+{
+	struct cmd_get_ppp_list_result *res = parsed_result;
+	uint8_t *buff;
+	int ret;
+
+	if (res->port_id > nb_ports) {
+		printf("Invalid port, range is [0, %d]\n", nb_ports - 1);
+		return;
+	}
+
+	buff = (uint8_t *)malloc(PROFILE_INFO_SIZE * MAX_PROFILE_NUM + 4);
+	if (!buff)
+		printf("%s: Failed to malloc buffer\n", __func__);
+
+	ret = i40e_get_ppp_list(res->port_id, buff);
+	if (ret < 0)
+		printf("Failed to get ppp list\n");
+
+	free(buff);
+}
+
+cmdline_parse_inst_t cmd_get_ppp_list = {
+	.f = cmd_get_ppp_list_parsed,
+	.data = NULL,
+	.help_str = "get ppp list <port_id>",
+	.tokens = {
+		(void *)&cmd_get_ppp_list_get,
+		(void *)&cmd_get_ppp_list_ppp,
+		(void *)&cmd_get_ppp_list_list,
+		(void *)&cmd_get_ppp_list_port_id,
+		NULL,
+	},
+};
 /* ******************************************************************************** */
 
 /* list of instructions */
@@ -12631,6 +12690,7 @@ cmdline_parse_ctx_t main_ctx[] = {
 	(cmdline_parse_inst_t *)&cmd_set_vf_broadcast,
 	(cmdline_parse_inst_t *)&cmd_set_vf_vlan_tag,
 	(cmdline_parse_inst_t *)&cmd_write_ppp,
+	(cmdline_parse_inst_t *)&cmd_get_ppp_list,
 	NULL,
 };
 
diff --git a/app/test-pmd/testpmd.h b/app/test-pmd/testpmd.h
index 2a7f683..a7aa218 100644
--- a/app/test-pmd/testpmd.h
+++ b/app/test-pmd/testpmd.h
@@ -624,6 +624,7 @@ void port_dcb_info_display(uint8_t port_id);
 
 uint8_t *open_package_file(const char *file_path);
 int close_package_file(uint8_t *buf);
+void get_ppp_list(uint8_t port_id);
 
 enum print_warning {
 	ENABLED_WARN = 0,
-- 
2.5.5

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

* Re: [PATCH 0/6] net/i40e: support pipeline personalization profile
  2017-03-03  7:26 ` [PATCH 0/6] net/i40e: support pipeline personalization profile Beilei Xing
  2017-03-03  7:39   ` [PATCH v2 0/5] " Beilei Xing
@ 2017-03-03  7:52   ` Xing, Beilei
  1 sibling, 0 replies; 82+ messages in thread
From: Xing, Beilei @ 2017-03-03  7:52 UTC (permalink / raw)
  To: Xing, Beilei, Wu, Jingjing; +Cc: Zhang, Helin, dev

Sorry for the mistake for the patch thread, which includes other irrelevant patches. 
Please ignore these patches, and just focus on the PPP v2 patchset.
Sorry for any inconvenient.

Thanks
Beilei

> -----Original Message-----
> From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Beilei Xing
> Sent: Friday, March 3, 2017 3:26 PM
> To: Wu, Jingjing <jingjing.wu@intel.com>
> Cc: Zhang, Helin <helin.zhang@intel.com>; dev@dpdk.org
> Subject: [dpdk-dev] [PATCH 0/6] net/i40e: support pipeline personalization
> profile
> 
> Add APIs and driver to support load/get
> i40e PPP (Pipeline Personalization Profile) since PPP will be supported from
> FVL6 NVM.
> 
> Beilei Xing (5):
>   net/i40e: support pipeline personalization profile
>   net/i40e: add ppp processing
>   app/testpmd: add command for writing personalization profile
>   net/i40e: add get all loaded profiles
>   app/testpmd: add command for getting loaded profiles
> 
> Rami Rosen (1):
>   net/i40e: fix a typo in flow
> 
>  app/test-pmd/cmdline.c          | 121 +++++++++++++++
>  app/test-pmd/config.c           |  54 +++++++
>  app/test-pmd/testpmd.h          |   4 +
>  drivers/net/i40e/i40e_ethdev.c  | 332
> ++++++++++++++++++++++++++++++++++++++++
>  drivers/net/i40e/i40e_ethdev.h  | 132 ++++++++++++++++
>  drivers/net/i40e/i40e_flow.c    |   6 +-
>  drivers/net/i40e/rte_pmd_i40e.h |  14 ++
>  7 files changed, 660 insertions(+), 3 deletions(-)
> 
> --
> 2.5.5

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

* Re: [PATCH] ppp implemantation
  2017-03-03  7:26 ` [PATCH] ppp implemantation Beilei Xing
@ 2017-03-03  9:39   ` Bruce Richardson
  2017-03-03  9:41     ` Bruce Richardson
  0 siblings, 1 reply; 82+ messages in thread
From: Bruce Richardson @ 2017-03-03  9:39 UTC (permalink / raw)
  To: Beilei Xing; +Cc: jingjing.wu, helin.zhang, dev

Given that this patch is not about point-to-point protocol, i.e. the
best-known expansion of "PPP", I think you need to clarify the acronym
in the commit message, at minimum, if not also in the commit title.

/Bruce

On Fri, Mar 03, 2017 at 03:26:07PM +0800, Beilei Xing wrote:
> Signed-off-by: Beilei Xing <beilei.xing@intel.com>
> ---
>  app/test-pmd/cmdline.c                  |  57 ++++++++
>  app/test-pmd/config.c                   |  62 +++++++++
>  app/test-pmd/testpmd.h                  |   3 +
>  drivers/net/i40e/base/i40e_adminq_cmd.h |  32 +++++
>  drivers/net/i40e/base/i40e_common.c     | 236 +++++++++++++++++++++++++++++++-
>  drivers/net/i40e/base/i40e_prototype.h  |  17 +++
>  drivers/net/i40e/base/i40e_type.h       |  79 +++++++++++
>  drivers/net/i40e/i40e_ethdev.c          |  68 +++++++++
>  drivers/net/i40e/rte_pmd_i40e.h         |   1 +
>  9 files changed, 554 insertions(+), 1 deletion(-)
> 
> diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
> index 43fc636..0d62a07 100644
> --- a/app/test-pmd/cmdline.c
> +++ b/app/test-pmd/cmdline.c
> @@ -12395,6 +12395,62 @@ cmdline_parse_inst_t cmd_set_vf_vlan_tag = {
>  	},
>  };
>  
> +/* Write Pipeline Personalization Profile */
> +struct cmd_write_ppp_result {
> +	cmdline_fixed_string_t write;
> +	cmdline_fixed_string_t ppp;
> +	uint8_t port_id;
> +	char filename[];
> +};
> +
> +cmdline_parse_token_string_t cmd_write_ppp_write =
> +	TOKEN_STRING_INITIALIZER(struct cmd_write_ppp_result, write, "write");
> +cmdline_parse_token_string_t cmd_write_ppp_ppp =
> +	TOKEN_STRING_INITIALIZER(struct cmd_write_ppp_result, ppp, "ppp");
> +cmdline_parse_token_num_t cmd_write_ppp_port_id =
> +	TOKEN_NUM_INITIALIZER(struct cmd_write_ppp_result, port_id, UINT8);
> +cmdline_parse_token_string_t cmd_write_ppp_filename =
> +	TOKEN_STRING_INITIALIZER(struct cmd_write_ppp_result, filename, NULL);
> +
> +static void
> +cmd_write_ppp_parsed(
> +	void *parsed_result,
> +	__attribute__((unused)) struct cmdline *cl,
> +	__attribute__((unused)) void *data)
> +{
> +	struct cmd_write_ppp_result *res = parsed_result;
> +	uint8_t *buff;
> +	int ret = -ENOTSUP;
> +
> +	if (res->port_id > nb_ports) {
> +		printf("Invalid port, range is [0, %d]\n", nb_ports - 1);
> +		return;
> +	}
> +
> +	buff = open_package_file(res->filename);
> +	if (!buff)
> +		return;
> +
> +	ret = i40e_process_package(res->port_id, buff);
> +	if (ret < 0)
> +		printf("Failed to write profile.\n");
> +
> +	close_package_file(buff);
> +}
> +
> +cmdline_parse_inst_t cmd_write_ppp = {
> +	.f = cmd_write_ppp_parsed,
> +	.data = NULL,
> +	.help_str = "write ppp <port_id> <profile_name>",
> +	.tokens = {
> +		(void *)&cmd_write_ppp_write,
> +		(void *)&cmd_write_ppp_ppp,
> +		(void *)&cmd_write_ppp_port_id,
> +		(void *)&cmd_write_ppp_filename,
> +		NULL,
> +	},
> +};
> +
>  /* ******************************************************************************** */
>  
>  /* list of instructions */
> @@ -12570,6 +12626,7 @@ cmdline_parse_ctx_t main_ctx[] = {
>  	(cmdline_parse_inst_t *)&cmd_set_vf_allmulti,
>  	(cmdline_parse_inst_t *)&cmd_set_vf_broadcast,
>  	(cmdline_parse_inst_t *)&cmd_set_vf_vlan_tag,
> +	(cmdline_parse_inst_t *)&cmd_write_ppp,
>  	NULL,
>  };
>  
> diff --git a/app/test-pmd/config.c b/app/test-pmd/config.c
> index 80491fc..aa26da1 100644
> --- a/app/test-pmd/config.c
> +++ b/app/test-pmd/config.c
> @@ -3245,3 +3245,65 @@ port_dcb_info_display(uint8_t port_id)
>  		printf("\t%4d", dcb_info.tc_queue.tc_txq[0][i].nb_queue);
>  	printf("\n");
>  }
> +
> +uint8_t *
> +open_package_file(const char *file_path)
> +{
> +	FILE *fh = fopen(file_path, "rb");
> +	uint32_t pkg_size;
> +	uint8_t *buf = NULL;
> +	int ret = 0;
> +
> +	if (fh == NULL) {
> +		printf("%s: Failed to open %s\n", __func__, file_path);
> +		return buf;
> +	}
> +
> +	ret = fseek(fh, 0, SEEK_END);
> +	if (ret < 0) {
> +		fclose(fh);
> +		printf("%s: File operations failed\n", __func__);
> +		return buf;
> +	}
> +
> +	pkg_size = ftell(fh);
> +
> +	buf = (uint8_t *)malloc(pkg_size);
> +	if (!buf) {
> +		fclose(fh);
> +		printf("%s: Failed to malloc memory\n",	__func__);
> +		return buf;
> +	}
> +
> +	ret = fseek(fh, 0, SEEK_SET);
> +	if (ret < 0) {
> +		fclose(fh);
> +                printf("%s: File operations failed\n", __func__);
> +		close_package_file(buf);
> +		return NULL;
> +        }
> +	fread(buf, 1, pkg_size, fh);
> +
> +	for(uint32_t i = 0; i < pkg_size; i++) {
> +		if (!(i % 16))
> +			printf("   ");
> +		printf(" 0x%02X,", buf[i]);
> +		if (!((i + 1) % 16))
> +			printf("\n");
> +	}
> +
> +	fclose(fh);
> +
> +	return buf;
> +}
> +
> +int
> +close_package_file(uint8_t *buf)
> +{
> +	if (buf) {
> +		free((void *)buf);
> +		return 0;
> +	}
> +
> +	return -1;
> +}
> diff --git a/app/test-pmd/testpmd.h b/app/test-pmd/testpmd.h
> index 8cf2860..2a7f683 100644
> --- a/app/test-pmd/testpmd.h
> +++ b/app/test-pmd/testpmd.h
> @@ -622,6 +622,9 @@ void mcast_addr_add(uint8_t port_id, struct ether_addr *mc_addr);
>  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_package_file(const char *file_path);
> +int close_package_file(uint8_t *buf);
> +
>  enum print_warning {
>  	ENABLED_WARN = 0,
>  	DISABLED_WARN
> diff --git a/drivers/net/i40e/base/i40e_adminq_cmd.h b/drivers/net/i40e/base/i40e_adminq_cmd.h
> index 67cef7c..bb1e978 100644
> --- a/drivers/net/i40e/base/i40e_adminq_cmd.h
> +++ b/drivers/net/i40e/base/i40e_adminq_cmd.h
> @@ -198,6 +198,10 @@ enum i40e_admin_queue_opc {
>  	i40e_aqc_opc_add_mirror_rule	= 0x0260,
>  	i40e_aqc_opc_delete_mirror_rule	= 0x0261,
>  
> +	/* Support Pipeline Personalization Profile */
> +        i40e_aqc_opc_write_personalization_profile	= 0x0270,
> +        i40e_aqc_opc_get_personalization_profile_list	= 0x0271,
> +
>  	/* DCB commands */
>  	i40e_aqc_opc_dcb_ignore_pfc	= 0x0301,
>  	i40e_aqc_opc_dcb_updated	= 0x0302,
> @@ -1441,6 +1445,34 @@ struct i40e_aqc_add_delete_mirror_rule_completion {
>  
>  I40E_CHECK_CMD_LENGTH(i40e_aqc_add_delete_mirror_rule_completion);
>  
> +/* Pipeline Personalization Profile */
> +struct i40e_aqc_write_ppp {
> +        u8      reserved[4];
> +        __le32  profile_track_id;
> +        __le32  addr_high;
> +        __le32  addr_low;
> +};
> +
> +I40E_CHECK_CMD_LENGTH(i40e_aqc_write_ppp);
> +
> +struct i40e_aqc_write_ppp_resp {
> +        __le32 error_offset;
> +        __le32 error_info;
> +        __le32 addr_high;
> +        __le32 addr_low;
> +};
> +
> +struct i40e_aqc_get_ppp_list {
> +	u8      flags;
> +	#define I40E_AQC_WR_PPP_GET_CONF	0x1
> +	#define I40E_AQC_WR_PPP_GET_RDPU_CONF	0x2
> +	u8      reserved[7];
> +	__le32  addr_high;
> +	__le32  addr_low;
> +};
> +
> +I40E_CHECK_CMD_LENGTH(i40e_aqc_get_ppp_list);
> +
>  /* DCB 0x03xx*/
>  
>  /* PFC Ignore (direct 0x0301)
> diff --git a/drivers/net/i40e/base/i40e_common.c b/drivers/net/i40e/base/i40e_common.c
> index b8d8165..98653d5 100644
> --- a/drivers/net/i40e/base/i40e_common.c
> +++ b/drivers/net/i40e/base/i40e_common.c
> @@ -6997,4 +6997,238 @@ enum i40e_status_code i40e_aq_clear_all_wol_filters(struct i40e_hw *hw,
>  	status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
>  
>  	return status;
> -}
> \ No newline at end of file
> +}
> +
> +/**
> + * i40e_aq_write_ppp - Write pipeline personalization profile (ppp)
> + * @hw: pointer to the hw struct
> + * @buff: command buffer (size in bytes = buff_size)
> + * @buff_size: buffer size in bytes
> + * @track_id: package tracking id
> + * @error_offset: returns error offset
> + * @error_info: returns error information
> + * @cmd_details: pointer to command details structure or NULL
> + **/
> +enum
> +i40e_status_code i40e_aq_write_ppp(struct i40e_hw *hw, void *buff,
> +				   u16 buff_size, u32 track_id,
> +				   u32 *error_offset, u32 *error_info,
> +				   struct i40e_asq_cmd_details *cmd_details)
> +{
> +	struct i40e_aq_desc desc;
> +	struct i40e_aqc_write_ppp *cmd =
> +		(struct i40e_aqc_write_ppp *)&desc.params.raw;
> +	struct i40e_aqc_write_ppp_resp *resp;
> +	enum i40e_status_code status;
> +
> +	i40e_fill_default_direct_cmd_desc(&desc,
> +				  i40e_aqc_opc_write_personalization_profile);
> +
> +	desc.flags |= CPU_TO_LE16(I40E_AQ_FLAG_BUF | I40E_AQ_FLAG_RD);
> +	if (buff_size > I40E_AQ_LARGE_BUF)
> +		desc.flags |= CPU_TO_LE16((u16)I40E_AQ_FLAG_LB);
> +
> +	desc.datalen = CPU_TO_LE16(buff_size);
> +
> +	cmd->profile_track_id = CPU_TO_LE32(track_id);
> +
> +	status = i40e_asq_send_command(hw, &desc, buff, buff_size, cmd_details);
> +	if (!status) {
> +		resp = (struct i40e_aqc_write_ppp_resp *)&desc.params.raw;
> +		if (error_offset)
> +			*error_offset = LE32_TO_CPU(resp->error_offset);
> +		if (error_info)
> +			*error_info = LE32_TO_CPU(resp->error_info);
> +	}
> +
> +	return status;
> +}
> +
> +/**
> + * i40e_aq_get_ppp_list - Read pipeline personalization profile (ppp)
> + * @hw: pointer to the hw struct
> + * @buff: command buffer (size in bytes = buff_size)
> + * @buff_size: buffer size in bytes
> + * @cmd_details: pointer to command details structure or NULL
> + **/
> +enum
> +i40e_status_code i40e_aq_get_ppp_list(struct i40e_hw *hw, void *buff,
> +				      u16 buff_size, u8 flags,
> +				      struct i40e_asq_cmd_details *cmd_details)
> +{
> +	struct i40e_aq_desc desc;
> +	struct i40e_aqc_get_ppp_list *cmd =
> +		(struct i40e_aqc_get_ppp_list *)&desc.params.raw;
> +	enum i40e_status_code status;
> +
> +	i40e_fill_default_direct_cmd_desc(&desc,
> +			  i40e_aqc_opc_get_personalization_profile_list);
> +
> +	if (buff_size > I40E_AQ_LARGE_BUF)
> +		desc.flags |= CPU_TO_LE16((u16)I40E_AQ_FLAG_LB);
> +	desc.datalen = CPU_TO_LE16(buff_size);
> +
> +	cmd->flags = flags;
> +
> +	status = i40e_asq_send_command(hw, &desc, buff, buff_size, cmd_details);
> +
> +	return status;
> +}
> +
> +/**
> + * i40e_find_segment_in_package
> + * @segment_type: the segment type to search for (i.e., SEGMENT_TYPE_I40E)
> + * @pkg_hdr: pointer to the package header to be searched
> + *
> + * This function searches a package file for a particular segment type. On
> + * success it returns a pointer to the segment header, otherwise it will
> + * return NULL.
> + */
> +struct i40e_generic_seg_header *
> +i40e_find_segment_in_package(u32 segment_type,
> +			     struct i40e_package_header *pkg_hdr)
> +{
> +	struct i40e_generic_seg_header *segment;
> +	u32 i;
> +
> +	PMD_DRV_LOG(INFO, "i40e_find_segment_in_package");
> +	PMD_DRV_LOG(INFO, "Package version: %d.%d.%d.%d",
> +		    pkg_hdr->version.major,
> +		    pkg_hdr->version.minor,
> +		    pkg_hdr->version.update,
> +		    pkg_hdr->version.draft);
> +
> +	/* Search all package segments for the requested segment type */
> +	for (i = 0; i < pkg_hdr->segment_count; i++) {
> +		segment =
> +			(struct i40e_generic_seg_header *)((u8 *)pkg_hdr +
> +		         pkg_hdr->segment_offset[i]);
> +
> +		if (segment->type == segment_type)
> +			return segment;
> +	}
> +
> +	return NULL;
> +}
> +
> +/**
> + * i40e_write_profile
> + * @hw: pointer to the hardware structure
> + * @profile: pointer to the profile segment of the package to be downloaded
> + * @track_id: package tracking id
> + *
> + * Handles the download of a complete package.
> + */
> +enum i40e_status_code
> +i40e_write_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;
> +
> +	PMD_DRV_LOG(INFO, "i40e_write_profile");
> +	PMD_DRV_LOG(INFO, "Segment version: %d.%d.%d.%d",
> +		    profile->header.version.major,
> +		    profile->header.version.minor,
> +		    profile->header.version.update,
> +		    profile->header.version.draft);
> +	PMD_DRV_LOG(INFO, "Seg: type 0x%X, size %d, name %s",
> +		    LE32_TO_CPU(profile->header.type),
> +		    LE32_TO_CPU(profile->header.size),
> +		    profile->header.name);
> +
> +	if (!track_id) {
> +		PMD_DRV_LOG(ERR, "Track_id can't be 0.");
> +                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 (i == dev_cnt) {
> +		PMD_DRV_LOG(ERR, "Device doesn't support PPP");
> +		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]);
> +
> +		/* Skip 'AQ', 'note' and 'name' sections */
> +		if (sec->section.type != SECTION_TYPE_MMIO)
> +			continue;
> +
> +		section_size = sec->section.size +
> +			sizeof(struct i40e_profile_section_header);
> +
> +		/* Write profile */
> +		status = i40e_aq_write_ppp(hw, (void *)sec, (u16)section_size,
> +					   track_id, &offset, &info, NULL);
> +		if (status) {
> +			PMD_DRV_LOG(ERR, "Failed to write profile: "
> +				    "offset %d, info %d",
> +				    offset, info);
> +			break;
> +		}
> +	}
> +
> +	return status;
> +}
> +
> +/**
> + * i40e_add_pinfo_to_list
> + * @hw: pointer to the hardware structure
> + * @profile: pointer to the profile segment of the package
> + * @profile_info_sec: buffer for information section
> + * @track_id: package tracking id
> + *
> + * Register a profile to the list of loaded profiles.
> + */
> +enum i40e_status_code
> +i40e_add_pinfo_to_list(struct i40e_hw *hw,
> +		       struct i40e_profile_segment *profile,
> +		       u8 *profile_info_sec, u32 track_id)
> +{
> +	enum i40e_status_code status = I40E_SUCCESS;
> +        struct i40e_profile_section_header *sec = NULL;
> +        struct i40e_profile_info *pinfo;
> +        u32 offset = 0, info = 0;
> +
> +	sec = (struct i40e_profile_section_header *)profile_info_sec;
> +        sec->tbl_size = 1;
> +        sec->data_end = sizeof(struct i40e_profile_section_header) +
> +                sizeof(struct i40e_profile_info);
> +        sec->section.type = SECTION_TYPE_INFO;
> +        sec->section.offset = sizeof(struct i40e_profile_section_header);
> +        sec->section.size = sizeof(struct i40e_profile_info);
> +        pinfo = (struct i40e_profile_info *)(profile_info_sec +
> +                                             sec->section.offset);
> +        pinfo->track_id = track_id;
> +        pinfo->version = profile->version;
> +        pinfo->op = I40E_PPP_ADD_TRACKID;
> +        memcpy(pinfo->name, profile->name, I40E_PPP_NAME_SIZE);
> +
> +        status = i40e_aq_write_ppp(hw, (void *)sec, sec->data_end,
> +                                   track_id, &offset, &info, NULL);
> +        if (status)
> +                        PMD_DRV_LOG(ERR, "Failed to add to list: "
> +                                    "offset %d, info %d",
> +                                    offset, info);
> +
> +        return status;
> +}
> diff --git a/drivers/net/i40e/base/i40e_prototype.h b/drivers/net/i40e/base/i40e_prototype.h
> index 109d3c5..b9b3a46 100644
> --- a/drivers/net/i40e/base/i40e_prototype.h
> +++ b/drivers/net/i40e/base/i40e_prototype.h
> @@ -555,4 +555,21 @@ enum i40e_status_code i40e_write_phy_register(struct i40e_hw *hw,
>  u8 i40e_get_phy_address(struct i40e_hw *hw, u8 dev_num);
>  enum i40e_status_code i40e_blink_phy_link_led(struct i40e_hw *hw,
>  					      u32 time, u32 interval);
> +enum i40e_status_code i40e_aq_write_ppp(struct i40e_hw *hw, void *buff,
> +				u16 buff_size, u32 track_id,
> +				u32 *error_offset, u32 *error_info,
> +				struct i40e_asq_cmd_details *cmd_details);
> +enum i40e_status_code i40e_aq_get_ppp_list(struct i40e_hw *hw, void *buff,
> +				   u16 buff_size, u8 flags,
> +				   struct i40e_asq_cmd_details *cmd_details);
> +struct i40e_generic_seg_header *
> +i40e_find_segment_in_package(u32 segment_type,
> +			     struct i40e_package_header *pkg_header);
> +enum i40e_status_code
> +i40e_write_profile(struct i40e_hw *hw, struct i40e_profile_segment *i40e_seg,
> +		   u32 track_id);
> +enum i40e_status_code
> +i40e_add_pinfo_to_list(struct i40e_hw *hw,
> +		       struct i40e_profile_segment *profile,
> +		       u8 *profile_info_sec, u32 track_id);
>  #endif /* _I40E_PROTOTYPE_H_ */
> diff --git a/drivers/net/i40e/base/i40e_type.h b/drivers/net/i40e/base/i40e_type.h
> index 590d97c..28e5e89 100644
> --- a/drivers/net/i40e/base/i40e_type.h
> +++ b/drivers/net/i40e/base/i40e_type.h
> @@ -1878,4 +1878,83 @@ struct i40e_lldp_variables {
>  #define I40E_FLEX_56_MASK		(0x1ULL << I40E_FLEX_56_SHIFT)
>  #define I40E_FLEX_57_SHIFT		6
>  #define I40E_FLEX_57_MASK		(0x1ULL << I40E_FLEX_57_SHIFT)
> +
> +/* Version format for PPP */
> +struct i40e_ppp_version {
> +	u8 major;
> +	u8 minor;
> +	u8 update;
> +	u8 draft;
> +};
> +
> +#define I40E_PPP_NAME_SIZE	32
> +
> +/* Package header */
> +struct i40e_package_header {
> +	struct i40e_ppp_version version;
> +	u32 segment_count;
> +	u32 segment_offset[1];
> +};
> +
> +/* Generic segment header */
> +struct i40e_generic_seg_header {
> +#define SEGMENT_TYPE_METADATA	0x00000001
> +#define SEGMENT_TYPE_NOTES	0x00000002
> +#define SEGMENT_TYPE_I40E	0x00000011
> +#define SEGMENT_TYPE_X722	0x00000012
> +	u32 type;
> +	struct i40e_ppp_version version;
> +	u32 size;
> +	char name[I40E_PPP_NAME_SIZE];
> +};
> +
> +struct i40e_metadata_segment {
> +	struct i40e_generic_seg_header header;
> +	struct i40e_ppp_version version;
> +	u32 track_id;
> +	char name[I40E_PPP_NAME_SIZE];
> +};
> +
> +struct i40e_device_id_entry {
> +	u32 vendor_dev_id;
> +	u32 sub_vendor_dev_id;
> +};
> +
> +struct i40e_profile_segment {
> +	struct i40e_generic_seg_header header;
> +	struct i40e_ppp_version version;
> +	char name[I40E_PPP_NAME_SIZE];
> +	u32 device_table_count;
> +	struct i40e_device_id_entry device_table[1];
> +};
> +
> +struct i40e_section_table {
> +	u32 section_count;
> +	u32 section_offset[1];
> +};
> +
> +struct i40e_profile_section_header {
> +	u16 tbl_size;
> +	u16 data_end;
> +	struct {
> +#define SECTION_TYPE_INFO	0x0000010
> +#define SECTION_TYPE_MMIO	0x0000800
> +#define SECTION_TYPE_AQ		0x0000801
> +#define SECTION_TYPE_NOTE	0x8000000
> +#define SECTION_TYPE_NAME	0x8000001
> +		u32 type;
> +		u32 offset;
> +		u32 size;
> +	} section;
> +};
> +
> +struct i40e_profile_info {
> +	u32 track_id;
> +	struct i40e_ppp_version version;
> +	u8 op;
> +#define I40E_PPP_ADD_TRACKID    0x01
> +#define I40E_PPP_REMOVE_TRACKID 0x02
> +	u8 reserved[7];
> +	u8 name[I40E_PPP_NAME_SIZE];
> +};
>  #endif /* _I40E_TYPE_H_ */
> diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
> index 303027b..2016b77 100644
> --- a/drivers/net/i40e/i40e_ethdev.c
> +++ b/drivers/net/i40e/i40e_ethdev.c
> @@ -39,6 +39,10 @@
>  #include <stdarg.h>
>  #include <inttypes.h>
>  #include <assert.h>
> +#include <sys/stat.h>
> +#include <stdlib.h>
> +#include <unistd.h>
> +#include <fcntl.h>
>  
>  #include <rte_string_fns.h>
>  #include <rte_pci.h>
> @@ -11212,3 +11216,67 @@ rte_pmd_i40e_reset_vf_stats(uint8_t port,
>  
>  	return 0;
>  }
> +
> +/**
> + * i40e_process_package - Load package
> + * @port: port id
> + * @buff: buffer of package
> + **/
> +int
> +i40e_process_package(uint8_t port, uint8_t *buff)
> +{
> +	struct rte_eth_dev *dev = &rte_eth_devices[port];
> +	struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
> +	struct i40e_package_header *pkg_hdr;
> +	struct i40e_generic_seg_header *profile_seg_hdr;
> +	struct i40e_generic_seg_header *metadata_seg_hdr;
> +	uint32_t track_id;
> +	uint8_t *profile_info_sec;
> +	enum i40e_status_code status;
> +
> +	pkg_hdr = (struct i40e_package_header *)buff;
> +
> +	if (!pkg_hdr) {
> +		PMD_DRV_LOG(ERR, "Failed to fill the package structure");
> +		return -EINVAL;
> +	}
> +
> +	/* Find metadata segment */
> +	metadata_seg_hdr = i40e_find_segment_in_package(SEGMENT_TYPE_METADATA,
> +							pkg_hdr);
> +	if (!metadata_seg_hdr) {
> +		PMD_DRV_LOG(ERR, "Failed to find metadata segment header");
> +		return -EINVAL;
> +	}
> +	track_id = ((struct i40e_metadata_segment *)metadata_seg_hdr)->track_id;
> +
> +	/* Find profile segment */
> +	profile_seg_hdr = i40e_find_segment_in_package(SEGMENT_TYPE_I40E,
> +						       pkg_hdr);
> +	if (!profile_seg_hdr) {
> +		PMD_DRV_LOG(ERR, "Failed to find profile segment header");
> +		return -EINVAL;
> +	}
> +
> +	/* Write profile to HW */
> +	status = i40e_write_profile(hw,
> +			    (struct i40e_profile_segment *)profile_seg_hdr,
> +			    track_id);
> +	if (!status)
> +		printf("Write profile successfully.\n");
> +
> +	/* Add the profile info to the list of loaded profiles */
> +	profile_info_sec = rte_zmalloc("i40e_profile_info",
> +			       sizeof(struct i40e_profile_section_header) +
> +			       sizeof(struct i40e_profile_info),
> +			       0);
> +	status = i40e_add_pinfo_to_list(hw,
> +			(struct i40e_profile_segment *)profile_seg_hdr,
> +			profile_info_sec, track_id);
> +	if (!status)
> +		printf("Add profile info successfully.\n");
> +
> +	rte_free(profile_info_sec);
> +
> +	return status;
> +}
> diff --git a/drivers/net/i40e/rte_pmd_i40e.h b/drivers/net/i40e/rte_pmd_i40e.h
> index a0ad88c..755a279 100644
> --- a/drivers/net/i40e/rte_pmd_i40e.h
> +++ b/drivers/net/i40e/rte_pmd_i40e.h
> @@ -332,4 +332,5 @@ int rte_pmd_i40e_get_vf_stats(uint8_t port,
>  int rte_pmd_i40e_reset_vf_stats(uint8_t port,
>  				uint16_t vf_id);
>  
> +int i40e_process_package(uint8_t port, uint8_t *buff);
>  #endif /* _PMD_I40E_H_ */
> -- 
> 2.5.5
> 

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

* Re: [PATCH] ppp implemantation
  2017-03-03  9:39   ` Bruce Richardson
@ 2017-03-03  9:41     ` Bruce Richardson
  0 siblings, 0 replies; 82+ messages in thread
From: Bruce Richardson @ 2017-03-03  9:41 UTC (permalink / raw)
  To: Beilei Xing; +Cc: jingjing.wu, helin.zhang, dev

On Fri, Mar 03, 2017 at 09:39:26AM +0000, Bruce Richardson wrote:
> Given that this patch is not about point-to-point protocol, i.e. the
> best-known expansion of "PPP", I think you need to clarify the acronym
> in the commit message, at minimum, if not also in the commit title.
> 
> /Bruce
> 

Never mind, I see your updated patchset has already been sent with
better titles.

/Bruce
> On Fri, Mar 03, 2017 at 03:26:07PM +0800, Beilei Xing wrote:
> > Signed-off-by: Beilei Xing <beilei.xing@intel.com>
> > ---
> >  app/test-pmd/cmdline.c                  |  57 ++++++++
> >  app/test-pmd/config.c                   |  62 +++++++++
> >  app/test-pmd/testpmd.h                  |   3 +
> >  drivers/net/i40e/base/i40e_adminq_cmd.h |  32 +++++
> >  drivers/net/i40e/base/i40e_common.c     | 236 +++++++++++++++++++++++++++++++-
> >  drivers/net/i40e/base/i40e_prototype.h  |  17 +++
> >  drivers/net/i40e/base/i40e_type.h       |  79 +++++++++++
> >  drivers/net/i40e/i40e_ethdev.c          |  68 +++++++++
> >  drivers/net/i40e/rte_pmd_i40e.h         |   1 +
> >  9 files changed, 554 insertions(+), 1 deletion(-)
> > 

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

* Re: [PATCH v2 0/5] net/i40e: support pipeline personalization profile
  2017-03-03  7:39   ` [PATCH v2 0/5] " Beilei Xing
                       ` (4 preceding siblings ...)
  2017-03-03  7:39     ` [PATCH v2 5/5] app/testpmd: add command for getting " Beilei Xing
@ 2017-03-08 11:43     ` Ferruh Yigit
  2017-03-09  3:07       ` Xing, Beilei
  2017-03-23 10:02     ` [PATCH v3 0/5] pipeline personalization profile support Beilei Xing
  6 siblings, 1 reply; 82+ messages in thread
From: Ferruh Yigit @ 2017-03-08 11:43 UTC (permalink / raw)
  To: Beilei Xing, jingjing.wu; +Cc: helin.zhang, dev

On 3/3/2017 7:39 AM, Beilei Xing wrote:
> Add APIs and driver to support load/get
> i40e PPP (Pipeline Personalization Profile)

Can you please describe what is "Pipeline Personalisation Profile" is?
If possible please provide some links to documents. And please feel free
to update NIC document about these details.

What are the use cases, what are the benefits of this feature?

And can you please update release notes to announce about added feature?

> since PPP will be supported from FVL6 NVM.
> 
> v2 change:
>  Correct patch num.
> 
> Beilei Xing (5):
>   net/i40e: support pipeline personalization profile
>   net/i40e: add ppp processing
>   app/testpmd: add command for writing personalization profile
>   net/i40e: add get all loaded profiles
>   app/testpmd: add command for getting loaded profiles

<...>

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

* Re: [PATCH v2 1/5] net/i40e: support pipeline personalization profile
  2017-03-03  7:39     ` [PATCH v2 1/5] " Beilei Xing
@ 2017-03-08 12:07       ` Ferruh Yigit
  2017-03-09  3:30         ` Xing, Beilei
  0 siblings, 1 reply; 82+ messages in thread
From: Ferruh Yigit @ 2017-03-08 12:07 UTC (permalink / raw)
  To: Beilei Xing, jingjing.wu; +Cc: helin.zhang, dev

On 3/3/2017 7:39 AM, Beilei Xing wrote:
> Add admin queue functions for Pipeline Personalization
> Profile AQ commands defined in DCR 287:

You can drop DCR reference here.

>  - Write Recipe Command buffer (Opcode: 0x0270)
>  - Get Applied Profiles list (Opcode: 0x0271)
> This patch will be moved to base driver in future.
> 
> Signed-off-by: Beilei Xing <beilei.xing@intel.com>

<...>

> +
> +/**
> + * i40e_aq_write_ppp - Write pipeline personalization profile (ppp)
> + * @hw: pointer to the hw struct
> + * @buff: command buffer (size in bytes = buff_size)
> + * @buff_size: buffer size in bytes
> + * @track_id: package tracking id
> + * @error_offset: returns error offset
> + * @error_info: returns error information
> + * @cmd_details: pointer to command details structure or NULL
> + **/
> +enum
> +i40e_status_code i40e_aq_write_ppp(struct i40e_hw *hw, void *buff,
> +				   uint16_t buff_size, uint32_t track_id,
> +				   uint32_t *error_offset, uint32_t *error_info,
> +				   struct i40e_asq_cmd_details *cmd_details)

Is there a reason to not make these functions "static" ?

What do you think making function calls more consistent, below is
"i40e_aq_get_ppp_list", so thi can be "i40e_aq_ppp_write"

And since this is NIC driver, ppp cane be confused with "Point-to-Point
Protocol", is there any possible abbreviation or capitalization to
prevent confusion?

<...>

> +/**
> + * i40e_find_segment_in_package
> + * @segment_type: the segment type to search for (i.e., SEGMENT_TYPE_I40E)
> + * @pkg_hdr: pointer to the package header to be searched
> + *
> + * This function searches a package file for a particular segment type. On
> + * success it returns a pointer to the segment header, otherwise it will
> + * return NULL.
> + */
> +struct i40e_generic_seg_header *
> +i40e_find_segment_in_package(uint32_t segment_type,
> +			     struct i40e_package_header *pkg_hdr)

This function name is also generic, what segment, what package. if this
is related to the ppp, please use relevant function name.

<...>

> +
> +/**
> + * i40e_write_profile
> + * @hw: pointer to the hardware structure
> + * @profile: pointer to the profile segment of the package to be downloaded
> + * @track_id: package tracking id
> + *
> + * Handles the download of a complete package.
> + */
> +enum i40e_status_code
> +i40e_write_profile(struct i40e_hw *hw, struct i40e_profile_segment *profile,
> +		   uint32_t track_id)

What about having "ppp" in API, like i40e_ppp_write()?

<...>

> +struct i40e_profile_section_header {
> +	uint16_t tbl_size;
> +	uint16_t data_end;
> +	struct {
> +#define SECTION_TYPE_INFO	0x0000010
> +#define SECTION_TYPE_MMIO	0x0000800
> +#define SECTION_TYPE_AQ		0x0000801

unaligned

> +#define SECTION_TYPE_NOTE	0x80000000
> +#define SECTION_TYPE_NAME	0x80000001
> +		uint32_t type;
> +		uint32_t offset;
> +		uint32_t size;
> +	} section;
> +};
> +

<...>

> @@ -805,6 +915,23 @@ int i40e_dev_tunnel_filter_set(struct i40e_pf *pf,
>  			       struct rte_eth_tunnel_filter_conf *tunnel_filter,
>  			       uint8_t add);
>  int i40e_fdir_flush(struct rte_eth_dev *dev);
> +enum i40e_status_code i40e_aq_write_ppp(struct i40e_hw *hw, void *buff,
> +				uint16_t buff_size, uint32_t track_id,
> +				uint32_t *error_offset, uint32_t *error_info,
> +				struct i40e_asq_cmd_details *cmd_details);
> +enum i40e_status_code i40e_aq_get_ppp_list(struct i40e_hw *hw, void *buff,
> +				   uint16_t buff_size, uint8_t flags,
> +				   struct i40e_asq_cmd_details *cmd_details);
> +struct i40e_generic_seg_header *
> +i40e_find_segment_in_package(uint32_t segment_type,
> +			     struct i40e_package_header *pkg_header);
> +enum i40e_status_code
> +i40e_write_profile(struct i40e_hw *hw, struct i40e_profile_segment *i40e_seg,
> +		   uint32_t track_id);
> +enum i40e_status_code
> +i40e_add_pinfo_to_list(struct i40e_hw *hw,
> +		       struct i40e_profile_segment *profile,
> +		       uint8_t *profile_info_sec, uint32_t track_id);

These declarations can go away if you make functions static.

>  
>  #define I40E_DEV_TO_PCI(eth_dev) \
>  	RTE_DEV_TO_PCI((eth_dev)->device)
> 

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

* Re: [PATCH v2 2/5] net/i40e: add ppp processing
  2017-03-03  7:39     ` [PATCH v2 2/5] net/i40e: add ppp processing Beilei Xing
@ 2017-03-08 12:07       ` Ferruh Yigit
  0 siblings, 0 replies; 82+ messages in thread
From: Ferruh Yigit @ 2017-03-08 12:07 UTC (permalink / raw)
  To: Beilei Xing, jingjing.wu; +Cc: helin.zhang, dev

On 3/3/2017 7:39 AM, Beilei Xing wrote:
> Add loading profile function.
> 
> Signed-off-by: Beilei Xing <beilei.xing@intel.com>
> ---
>  drivers/net/i40e/i40e_ethdev.c  | 59 +++++++++++++++++++++++++++++++++++++++++
>  drivers/net/i40e/rte_pmd_i40e.h |  7 +++++

Also you need to update *version.map file for new API.

<...>

> +
> +int
> +i40e_process_package(uint8_t port, uint8_t *buff)

Function name is so generic, please pick another one that associated
with ppp.

Also please use defined name_space for public API: rte_pmd_i40e_<...>

> +{
> +	struct rte_eth_dev *dev = &rte_eth_devices[port];

Now this is public API to user applications, no more driver function, so
requires more attention. Input values needs to be verified before using
them.

Also you need to check if provided port_id if i40e port id.

<...>

>  
> +/**
> + * i40e_process_package - Load package
> + * @port: port id
> + * @buff: buffer of package
> + **/

Please provide proper doxygen tags, these are causing error.

> +int i40e_process_package(uint8_t port, uint8_t *buff);
> +
>  #endif /* _PMD_I40E_H_ */
> 

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

* Re: [PATCH v2 3/5] app/testpmd: add command for writing personalization profile
  2017-03-03  7:39     ` [PATCH v2 3/5] app/testpmd: add command for writing personalization profile Beilei Xing
@ 2017-03-08 12:10       ` Ferruh Yigit
  0 siblings, 0 replies; 82+ messages in thread
From: Ferruh Yigit @ 2017-03-08 12:10 UTC (permalink / raw)
  To: Beilei Xing, jingjing.wu; +Cc: helin.zhang, dev

On 3/3/2017 7:39 AM, Beilei Xing wrote:
> This patch is to add testpmd CLI for writing personalization
> profile.
> 
> Signed-off-by: Beilei Xing <beilei.xing@intel.com>

<...>

> +static void
> +cmd_write_ppp_parsed(
> +	void *parsed_result,
> +	__attribute__((unused)) struct cmdline *cl,
> +	__attribute__((unused)) void *data)
> +{
> +	struct cmd_write_ppp_result *res = parsed_result;
> +	uint8_t *buff;
> +	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_package_file(res->filename);

Can you please update function name to indicate package is ppp package

> +	if (!buff)
> +		return;
> +
> +	ret = i40e_process_package(res->port_id, buff);

What if i40e support not compiled into library?

> +	if (ret < 0)
> +		printf("Failed to write profile.\n");
> +
> +	close_package_file(buff);
> +}
> +

<...>

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

* Re: [PATCH v2 0/5] net/i40e: support pipeline personalization profile
  2017-03-08 11:43     ` [PATCH v2 0/5] net/i40e: support pipeline personalization profile Ferruh Yigit
@ 2017-03-09  3:07       ` Xing, Beilei
  0 siblings, 0 replies; 82+ messages in thread
From: Xing, Beilei @ 2017-03-09  3:07 UTC (permalink / raw)
  To: Yigit, Ferruh, Wu, Jingjing; +Cc: Zhang, Helin, dev


> -----Original Message-----
> From: Yigit, Ferruh
> Sent: Wednesday, March 8, 2017 7:43 PM
> To: Xing, Beilei <beilei.xing@intel.com>; Wu, Jingjing <jingjing.wu@intel.com>
> Cc: Zhang, Helin <helin.zhang@intel.com>; dev@dpdk.org
> Subject: Re: [dpdk-dev] [PATCH v2 0/5] net/i40e: support pipeline
> personalization profile
> 
> On 3/3/2017 7:39 AM, Beilei Xing wrote:
> > Add APIs and driver to support load/get i40e PPP (Pipeline
> > Personalization Profile)
> 
> Can you please describe what is "Pipeline Personalisation Profile" is?
> If possible please provide some links to documents. And please feel free to
> update NIC document about these details.

Due to limited resources of X*710 (parser and analyzer configuration tables, number of packet classification types,
number of packet types, filters configuration tables, etc.), it's impossible to simultaneously support all protocols/filters
required for different parts on network.
To enable protocols/filters extensions for X*710, new Admin Command for loading user defined configurations is added.
PPP is a format of extend configuration  for X*710, it allows user to load user defined configuration to X*710.

Actually I have no released doc to share, the documents in my hand are draft and can't be forwarded.

> 
> What are the use cases, what are the benefits of this feature?

List of possible use cases for extended X*710 configuration using profiles could include following:
Configuring Analyzer/Parser to support new protocols, for example:
*	IP L2TPv3 tunneling protocol
*	IPSec ESP/AH protocols
*	MPLSoGRE, MPLSoUDP tunnels
*	GTP-C/GTP-U tunnels
New PCTYPEs for offloading packet classification to X*710. For example:
*	new IP Protocol in addition to TCP/UDP/SCTP
*	new TCP/UDP subtypes, like TCP SYN, TCP FIN 
*	new PCTYPE for tunneled packets like GTP-C, GTP-U
New PTYPEs for packets identification, for example:
*	MAC, MPLS, IP4, UDP
*	MAC, MPLS, MPLS, IP6, TCP
Fixes for NVM configuration, for example:
*	list of enabled stat counters to improve throughput
*	parser/analyzer configuration for some corner cases

> 
> And can you please update release notes to announce about added feature?
Yes, will update in next version.

> 
> > since PPP will be supported from FVL6 NVM.
> >
> > v2 change:
> >  Correct patch num.
> >
> > Beilei Xing (5):
> >   net/i40e: support pipeline personalization profile
> >   net/i40e: add ppp processing
> >   app/testpmd: add command for writing personalization profile
> >   net/i40e: add get all loaded profiles
> >   app/testpmd: add command for getting loaded profiles
> 
> <...>

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

* Re: [PATCH v2 1/5] net/i40e: support pipeline personalization profile
  2017-03-08 12:07       ` Ferruh Yigit
@ 2017-03-09  3:30         ` Xing, Beilei
  0 siblings, 0 replies; 82+ messages in thread
From: Xing, Beilei @ 2017-03-09  3:30 UTC (permalink / raw)
  To: Yigit, Ferruh, Wu, Jingjing; +Cc: Zhang, Helin, dev


> -----Original Message-----
> From: Yigit, Ferruh
> Sent: Wednesday, March 8, 2017 8:07 PM
> To: Xing, Beilei <beilei.xing@intel.com>; Wu, Jingjing <jingjing.wu@intel.com>
> Cc: Zhang, Helin <helin.zhang@intel.com>; dev@dpdk.org
> Subject: Re: [dpdk-dev] [PATCH v2 1/5] net/i40e: support pipeline
> personalization profile
> 
> On 3/3/2017 7:39 AM, Beilei Xing wrote:
> > Add admin queue functions for Pipeline Personalization Profile AQ
> > commands defined in DCR 287:
> 
> You can drop DCR reference here.

Sorry as the DCR in my hand is also draft and intel confidential. I will share it if it's released.

> 
> >  - Write Recipe Command buffer (Opcode: 0x0270)
> >  - Get Applied Profiles list (Opcode: 0x0271) This patch will be moved
> > to base driver in future.
> >
> > Signed-off-by: Beilei Xing <beilei.xing@intel.com>
> 
> <...>
> 
> > +
> > +/**
> > + * i40e_aq_write_ppp - Write pipeline personalization profile (ppp)
> > + * @hw: pointer to the hw struct
> > + * @buff: command buffer (size in bytes = buff_size)
> > + * @buff_size: buffer size in bytes
> > + * @track_id: package tracking id
> > + * @error_offset: returns error offset
> > + * @error_info: returns error information
> > + * @cmd_details: pointer to command details structure or NULL  **/
> > +enum i40e_status_code i40e_aq_write_ppp(struct i40e_hw *hw, void
> > +*buff,
> > +				   uint16_t buff_size, uint32_t track_id,
> > +				   uint32_t *error_offset, uint32_t
> *error_info,
> > +				   struct i40e_asq_cmd_details *cmd_details)
> 
> Is there a reason to not make these functions "static" ?

No.  In fact, I design the patch in base driver first, and follow the base code style.
Agree to use "static" if the function is in PMD.

> 
> What do you think making function calls more consistent, below is
> "i40e_aq_get_ppp_list", so thi can be "i40e_aq_ppp_write"
> 
> And since this is NIC driver, ppp cane be confused with "Point-to-Point
> Protocol", is there any possible abbreviation or capitalization to prevent
> confusion?

Yes, will consider about it.

> 
> <...>
> 
> > +/**
> > + * i40e_find_segment_in_package
> > + * @segment_type: the segment type to search for (i.e.,
> > +SEGMENT_TYPE_I40E)
> > + * @pkg_hdr: pointer to the package header to be searched
> > + *
> > + * This function searches a package file for a particular segment
> > +type. On
> > + * success it returns a pointer to the segment header, otherwise it
> > +will
> > + * return NULL.
> > + */
> > +struct i40e_generic_seg_header *
> > +i40e_find_segment_in_package(uint32_t segment_type,
> > +			     struct i40e_package_header *pkg_hdr)
> 
> This function name is also generic, what segment, what package. if this is
> related to the ppp, please use relevant function name.
OK.

> 
> <...>
> 
> > +
> > +/**
> > + * i40e_write_profile
> > + * @hw: pointer to the hardware structure
> > + * @profile: pointer to the profile segment of the package to be
> > +downloaded
> > + * @track_id: package tracking id
> > + *
> > + * Handles the download of a complete package.
> > + */
> > +enum i40e_status_code
> > +i40e_write_profile(struct i40e_hw *hw, struct i40e_profile_segment
> *profile,
> > +		   uint32_t track_id)
> 
> What about having "ppp" in API, like i40e_ppp_write()?

Seems good.


> 
> <...>
> 
> > +struct i40e_profile_section_header {
> > +	uint16_t tbl_size;
> > +	uint16_t data_end;
> > +	struct {
> > +#define SECTION_TYPE_INFO	0x0000010
> > +#define SECTION_TYPE_MMIO	0x0000800
> > +#define SECTION_TYPE_AQ		0x0000801
> 
> unaligned
> 
> > +#define SECTION_TYPE_NOTE	0x80000000
> > +#define SECTION_TYPE_NAME	0x80000001
> > +		uint32_t type;
> > +		uint32_t offset;
> > +		uint32_t size;
> > +	} section;
> > +};
> > +
> 
> <...>
> 
> > @@ -805,6 +915,23 @@ int i40e_dev_tunnel_filter_set(struct i40e_pf *pf,
> >  			       struct rte_eth_tunnel_filter_conf *tunnel_filter,
> >  			       uint8_t add);
> >  int i40e_fdir_flush(struct rte_eth_dev *dev);
> > +enum i40e_status_code i40e_aq_write_ppp(struct i40e_hw *hw, void
> *buff,
> > +				uint16_t buff_size, uint32_t track_id,
> > +				uint32_t *error_offset, uint32_t *error_info,
> > +				struct i40e_asq_cmd_details *cmd_details);
> enum i40e_status_code
> > +i40e_aq_get_ppp_list(struct i40e_hw *hw, void *buff,
> > +				   uint16_t buff_size, uint8_t flags,
> > +				   struct i40e_asq_cmd_details *cmd_details);
> struct
> > +i40e_generic_seg_header * i40e_find_segment_in_package(uint32_t
> > +segment_type,
> > +			     struct i40e_package_header *pkg_header); enum
> > +i40e_status_code i40e_write_profile(struct i40e_hw *hw, struct
> > +i40e_profile_segment *i40e_seg,
> > +		   uint32_t track_id);
> > +enum i40e_status_code
> > +i40e_add_pinfo_to_list(struct i40e_hw *hw,
> > +		       struct i40e_profile_segment *profile,
> > +		       uint8_t *profile_info_sec, uint32_t track_id);
> 
> These declarations can go away if you make functions static.
Yes.

> 
> >
> >  #define I40E_DEV_TO_PCI(eth_dev) \
> >  	RTE_DEV_TO_PCI((eth_dev)->device)
> >

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

* [PATCH v3 0/5] pipeline personalization profile support
  2017-03-03  7:39   ` [PATCH v2 0/5] " Beilei Xing
                       ` (5 preceding siblings ...)
  2017-03-08 11:43     ` [PATCH v2 0/5] net/i40e: support pipeline personalization profile Ferruh Yigit
@ 2017-03-23 10:02     ` Beilei Xing
  2017-03-23 10:02       ` [PATCH v3 1/5] net/i40e: add pipeline personalization profile processing Beilei Xing
                         ` (5 more replies)
  6 siblings, 6 replies; 82+ messages in thread
From: Beilei Xing @ 2017-03-23 10:02 UTC (permalink / raw)
  To: jingjing.wu; +Cc: helin.zhang, dev

Due to limited resources of X*710 (parser and analyzer configuration
tables, number of packet classification types, number of packet types,
filters configuration tables, etc.), it's impossible to simultaneously
support all protocols/filters required for different parts on network.
To enable protocols/filters extensions for X*710, new Admin Command
for loading user defined configurations is added.
PPP is a format of extend configuration for X*710, it allows user to
load user defined configuration to X*710.

List of possible use cases for extended X*710 configuration using
profiles could include following:
Configuring Analyzer/Parser to support new protocols, e.g.
- IP L2TPv3 tunneling protocol
- IPSec ESP/AH protocols
- MPLSoGRE, MPLSoUDP tunnels
- GTP-C/GTP-U tunnels
New PCTYPEs for offloading packet classification to X*710. e.g.
- new IP Protocol in addition to TCP/UDP/SCTP
- new TCP/UDP subtypes, like TCP SYN, TCP FIN
- new PCTYPE for tunneled packets like GTP-C, GTP-U
New PTYPEs for packets identification, e.g.
- MAC, MPLS, IP4, UDP
- MAC, MPLS, MPLS, IP6, TCP
Fixes for NVM configuration, e.g.
- list of enabled stat counters to improve throughput
- parser/analyzer configuration for some corner cases

Beilei Xing (5):
  net/i40e: add pipeline personalization profile processing
  app/testpmd: add command for loading a profile
  net/i40e: add get all loaded profiles
  app/testpmd: add command for getting loaded profiles
  doc: add pipeline personalization profile support for i40e

 app/test-pmd/cmdline.c                    | 163 +++++++++++++++++++++
 app/test-pmd/config.c                     |  67 +++++++++
 app/test-pmd/testpmd.h                    |  25 ++++
 doc/guides/rel_notes/release_17_05.rst    |   4 +
 drivers/net/i40e/i40e_ethdev.c            | 228 ++++++++++++++++++++++++++++++
 drivers/net/i40e/i40e_ethdev.h            |   5 +
 drivers/net/i40e/rte_pmd_i40e.h           |  32 +++++
 drivers/net/i40e/rte_pmd_i40e_version.map |   7 +
 8 files changed, 531 insertions(+)

-- 
2.5.5

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

* [PATCH v3 1/5] net/i40e: add pipeline personalization profile processing
  2017-03-23 10:02     ` [PATCH v3 0/5] pipeline personalization profile support Beilei Xing
@ 2017-03-23 10:02       ` Beilei Xing
  2017-03-23 14:50         ` Iremonger, Bernard
  2017-03-23 10:02       ` [PATCH v3 2/5] app/testpmd: add command for loading a profile Beilei Xing
                         ` (4 subsequent siblings)
  5 siblings, 1 reply; 82+ messages in thread
From: Beilei Xing @ 2017-03-23 10:02 UTC (permalink / raw)
  To: jingjing.wu; +Cc: helin.zhang, dev

Add support for adding or removing a pipeline personalization
profile package.

Signed-off-by: Beilei Xing <beilei.xing@intel.com>
---
 app/test-pmd/cmdline.c                    |   1 +
 drivers/net/i40e/i40e_ethdev.c            | 200 ++++++++++++++++++++++++++++++
 drivers/net/i40e/i40e_ethdev.h            |   5 +
 drivers/net/i40e/rte_pmd_i40e.h           |  21 ++++
 drivers/net/i40e/rte_pmd_i40e_version.map |   6 +
 5 files changed, 233 insertions(+)

diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
index 47f935d..6e0625d 100644
--- a/app/test-pmd/cmdline.c
+++ b/app/test-pmd/cmdline.c
@@ -37,6 +37,7 @@
 #include <stdio.h>
 #include <stdint.h>
 #include <stdarg.h>
+#include <stdbool.h>
 #include <string.h>
 #include <termios.h>
 #include <unistd.h>
diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index 3702214..7aff9a3 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -11259,3 +11259,203 @@ rte_pmd_i40e_reset_vf_stats(uint8_t port,
 
 	return 0;
 }
+
+static void
+i40e_generate_profile_info_sec(char *name, struct i40e_ppp_version *version,
+			       uint32_t track_id, uint8_t *profile_info_sec,
+			       bool add)
+{
+	struct i40e_profile_section_header *sec = NULL;
+	struct i40e_profile_info *pinfo;
+
+	sec = (struct i40e_profile_section_header *)profile_info_sec;
+	sec->tbl_size = 1;
+	sec->data_end = sizeof(struct i40e_profile_section_header) +
+		sizeof(struct i40e_profile_info);
+	sec->section.type = SECTION_TYPE_INFO;
+	sec->section.offset = sizeof(struct i40e_profile_section_header);
+	sec->section.size = sizeof(struct i40e_profile_info);
+	pinfo = (struct i40e_profile_info *)(profile_info_sec +
+					     sec->section.offset);
+	pinfo->track_id = track_id;
+	memcpy(pinfo->name, name, I40E_PPP_NAME_SIZE);
+	memcpy(&pinfo->version, version, sizeof(struct i40e_ppp_version));
+	if (add)
+		pinfo->op = I40E_PPP_ADD_TRACKID;
+	else
+		pinfo->op = I40E_PPP_REMOVE_TRACKID;
+}
+
+static enum i40e_status_code
+i40e_add_rm_profile_info(struct i40e_hw *hw, uint8_t *profile_info_sec)
+{
+	enum i40e_status_code status = I40E_SUCCESS;
+	struct i40e_profile_section_header *sec;
+	uint32_t track_id;
+	uint32_t offset = 0, info = 0;
+
+	sec = (struct i40e_profile_section_header *)profile_info_sec;
+	track_id = ((struct i40e_profile_info *)(profile_info_sec +
+					 sec->section.offset))->track_id;
+
+	status = i40e_aq_write_ppp(hw, (void *)sec, sec->data_end,
+				   track_id, &offset, &info, NULL);
+	if (status)
+		PMD_DRV_LOG(ERR, "Failed to add/remove profile info: "
+			    "offset %d, info %d",
+			    offset, info);
+
+	return status;
+}
+
+#define I40E_PROFILE_INFO_SIZE 48
+#define I40E_MAX_PROFILE_NUM 16
+
+/* Check if the profile info exists */
+static int
+i40e_check_profile_info(uint8_t port, uint8_t *profile_info_sec)
+{
+	struct rte_eth_dev *dev = &rte_eth_devices[port];
+	struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+	uint8_t *buff;
+	struct i40e_profile_list *p_list;
+	struct i40e_profile_info *pinfo, *p;
+	int ret;
+
+	buff = rte_zmalloc("i40e_pinfo_list",
+			   (I40E_PROFILE_INFO_SIZE * I40E_MAX_PROFILE_NUM + 4),
+			   0);
+	if (!buff) {
+		PMD_DRV_LOG(ERR, "failed to allocate memory");
+		return -1;
+	}
+
+	ret = i40e_aq_get_ppp_list(hw, (void *)buff,
+		      (I40E_PROFILE_INFO_SIZE * I40E_MAX_PROFILE_NUM + 4),
+		      0, NULL);
+	if (ret) {
+		PMD_DRV_LOG(ERR, "Failed to get profile info list.");
+		rte_free(buff);
+		return -1;
+	}
+	p_list = (struct i40e_profile_list *)buff;
+	pinfo = (struct i40e_profile_info *)(profile_info_sec +
+			     sizeof(struct i40e_profile_section_header));
+	for (uint32_t i = 0; i < p_list->p_count; i++) {
+		p = &p_list->p_info[i];
+		if ((pinfo->track_id == p->track_id) &&
+		    !memcmp(&pinfo->version, &p->version,
+			    sizeof(struct i40e_ppp_version)) &&
+		    !memcmp(&pinfo->name, &p->name,
+			    I40E_PPP_NAME_SIZE)) {
+			PMD_DRV_LOG(INFO, "Profile exists.");
+			rte_free(buff);
+			return 1;
+		}
+	}
+
+	rte_free(buff);
+	return 0;
+}
+
+int
+rte_pmd_i40e_process_ppp_package(uint8_t port, uint8_t *buff,
+				 uint32_t size, bool add)
+{
+	struct rte_eth_dev *dev;
+	struct i40e_hw *hw;
+	struct i40e_package_header *pkg_hdr;
+	struct i40e_generic_seg_header *profile_seg_hdr;
+	struct i40e_generic_seg_header *metadata_seg_hdr;
+	uint32_t track_id;
+	uint8_t *profile_info_sec;
+	int is_exist;
+	enum i40e_status_code status = I40E_SUCCESS;
+
+	RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
+
+	dev = &rte_eth_devices[port];
+
+	if (!is_device_supported(dev, &rte_i40e_pmd))
+		return -ENOTSUP;
+
+	hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+
+	if (size < (sizeof(struct i40e_package_header) +
+		    sizeof(struct i40e_metadata_segment) +
+		    sizeof(uint32_t) * 2)) {
+		PMD_DRV_LOG(ERR, "Buff is invalid.");
+		return -EINVAL;
+	}
+
+	pkg_hdr = (struct i40e_package_header *)buff;
+
+	if (!pkg_hdr) {
+		PMD_DRV_LOG(ERR, "Failed to fill the package structure");
+		return -EINVAL;
+	}
+
+	if (pkg_hdr->segment_count < 2) {
+		PMD_DRV_LOG(ERR, "Segment_count should be 2 at least.");
+		return -EINVAL;
+	}
+
+	/* Find metadata segment */
+	metadata_seg_hdr = i40e_find_segment_in_package(SEGMENT_TYPE_METADATA,
+							pkg_hdr);
+	if (!metadata_seg_hdr) {
+		PMD_DRV_LOG(ERR, "Failed to find metadata segment header");
+		return -EINVAL;
+	}
+	track_id = ((struct i40e_metadata_segment *)metadata_seg_hdr)->track_id;
+
+	/* Find profile segment */
+	profile_seg_hdr = i40e_find_segment_in_package(SEGMENT_TYPE_I40E,
+						       pkg_hdr);
+	if (!profile_seg_hdr) {
+		PMD_DRV_LOG(ERR, "Failed to find profile segment header");
+		return -EINVAL;
+	}
+
+	profile_info_sec = rte_zmalloc("i40e_profile_info",
+			       sizeof(struct i40e_profile_section_header) +
+			       sizeof(struct i40e_profile_info),
+			       0);
+	if (!profile_info_sec) {
+		PMD_DRV_LOG(ERR, "Failed to allocate memory");
+		return -EINVAL;
+	}
+
+	if (add) {
+		i40e_generate_profile_info_sec(
+		     ((struct i40e_profile_segment *)profile_seg_hdr)->name,
+		     &((struct i40e_profile_segment *)profile_seg_hdr)->version,
+		     track_id, profile_info_sec, 1);
+		is_exist = i40e_check_profile_info(port, profile_info_sec);
+		if (is_exist) {
+			PMD_DRV_LOG(ERR, "Profile already exists.");
+			rte_free(profile_info_sec);
+			return 1;
+		}
+
+		/* Write profile to HW */
+		status = i40e_write_profile(hw,
+				 (struct i40e_profile_segment *)profile_seg_hdr,
+				 track_id);
+		if (status)
+			PMD_DRV_LOG(ERR, "Failed to write profile.");
+	} else {
+		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, 0);
+	}
+
+	status = i40e_add_rm_profile_info(hw, profile_info_sec);
+	if (status)
+		PMD_DRV_LOG(ERR, "Failed to %s profile info.",
+			    add ? "add" : "remove");
+
+	rte_free(profile_info_sec);
+	return status;
+}
diff --git a/drivers/net/i40e/i40e_ethdev.h b/drivers/net/i40e/i40e_ethdev.h
index aebb097..f0be7a3 100644
--- a/drivers/net/i40e/i40e_ethdev.h
+++ b/drivers/net/i40e/i40e_ethdev.h
@@ -730,6 +730,11 @@ struct i40e_valid_pattern {
 	parse_filter_t parse_filter;
 };
 
+struct i40e_profile_list {
+	uint32_t p_count;
+	struct i40e_profile_info p_info[1];
+};
+
 int i40e_dev_switch_queues(struct i40e_pf *pf, bool on);
 int i40e_vsi_release(struct i40e_vsi *vsi);
 struct i40e_vsi *i40e_vsi_setup(struct i40e_pf *pf,
diff --git a/drivers/net/i40e/rte_pmd_i40e.h b/drivers/net/i40e/rte_pmd_i40e.h
index a0ad88c..7861a56 100644
--- a/drivers/net/i40e/rte_pmd_i40e.h
+++ b/drivers/net/i40e/rte_pmd_i40e.h
@@ -332,4 +332,25 @@ int rte_pmd_i40e_get_vf_stats(uint8_t port,
 int rte_pmd_i40e_reset_vf_stats(uint8_t port,
 				uint16_t vf_id);
 
+/**
+ * Load/Unload a ppp package
+ *
+ * @param port
+ *    The port identifier of the Ethernet device.
+ * @param buff
+ *    buffer of package.
+ * @param size
+ *    size of buffer.
+ * @param add
+ *   - (1) load profile.
+ *   - (0) remove profile.
+ * @return
+ *   - (0) if successful.
+ *   - (-ENODEV) if *port* invalid.
+ *   - (-EINVAL) if bad parameter.
+ *   - (1) if profile exists.
+ */
+int rte_pmd_i40e_process_ppp_package(uint8_t port, uint8_t *buff,
+				     uint32_t size, bool add);
+
 #endif /* _PMD_I40E_H_ */
diff --git a/drivers/net/i40e/rte_pmd_i40e_version.map b/drivers/net/i40e/rte_pmd_i40e_version.map
index 7a5d211..01c4a90 100644
--- a/drivers/net/i40e/rte_pmd_i40e_version.map
+++ b/drivers/net/i40e/rte_pmd_i40e_version.map
@@ -22,3 +22,9 @@ DPDK_17.02 {
 	rte_pmd_i40e_set_vf_vlan_tag;
 
 } DPDK_2.0;
+
+DPDK_17.05 {
+	global:
+
+	rte_pmd_i40e_process_ppp_package;
+};
-- 
2.5.5

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

* [PATCH v3 2/5] app/testpmd: add command for loading a profile
  2017-03-23 10:02     ` [PATCH v3 0/5] pipeline personalization profile support Beilei Xing
  2017-03-23 10:02       ` [PATCH v3 1/5] net/i40e: add pipeline personalization profile processing Beilei Xing
@ 2017-03-23 10:02       ` Beilei Xing
  2017-03-23 10:02       ` [PATCH v3 3/5] net/i40e: add get all loaded profiles Beilei Xing
                         ` (3 subsequent siblings)
  5 siblings, 0 replies; 82+ messages in thread
From: Beilei Xing @ 2017-03-23 10:02 UTC (permalink / raw)
  To: jingjing.wu; +Cc: helin.zhang, dev

This patch is to add testpmd CLI for loading a pipeline
personalization profile.

Signed-off-by: Beilei Xing <beilei.xing@intel.com>
---
 app/test-pmd/cmdline.c          | 73 +++++++++++++++++++++++++++++++++++++++++
 app/test-pmd/config.c           | 67 +++++++++++++++++++++++++++++++++++++
 app/test-pmd/testpmd.h          |  3 ++
 drivers/net/i40e/rte_pmd_i40e.h |  1 -
 4 files changed, 143 insertions(+), 1 deletion(-)

diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
index 6e0625d..5d6dd73 100644
--- a/app/test-pmd/cmdline.c
+++ b/app/test-pmd/cmdline.c
@@ -579,6 +579,9 @@ 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"
 
+			"add ppp (port_id) (profile_path)\n"
+			"    Load a profile package on a port\n\n"
+
 			, list_pkt_forwarding_modes()
 		);
 	}
@@ -12402,6 +12405,75 @@ cmdline_parse_inst_t cmd_set_vf_vlan_tag = {
 	},
 };
 
+/* Load Pipeline Personalization Profile */
+struct cmd_add_ppp_result {
+	cmdline_fixed_string_t add;
+	cmdline_fixed_string_t ppp;
+	uint8_t port_id;
+	char filepath[];
+};
+
+cmdline_parse_token_string_t cmd_add_ppp_add =
+	TOKEN_STRING_INITIALIZER(struct cmd_add_ppp_result, add, "add");
+cmdline_parse_token_string_t cmd_add_ppp_ppp =
+	TOKEN_STRING_INITIALIZER(struct cmd_add_ppp_result, ppp, "ppp");
+cmdline_parse_token_num_t cmd_add_ppp_port_id =
+	TOKEN_NUM_INITIALIZER(struct cmd_add_ppp_result, port_id, UINT8);
+cmdline_parse_token_string_t cmd_add_ppp_filepath =
+	TOKEN_STRING_INITIALIZER(struct cmd_add_ppp_result, filepath, NULL);
+
+static void
+cmd_add_ppp_parsed(
+	void *parsed_result,
+	__attribute__((unused)) struct cmdline *cl,
+	__attribute__((unused)) void *data)
+{
+	struct cmd_add_ppp_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_ppp_package_file(res->filepath, &size);
+	if (!buff)
+		return;
+
+#ifdef RTE_LIBRTE_I40E_PMD
+	if (ret == -ENOTSUP) {
+		ret = rte_pmd_i40e_process_ppp_package(res->port_id,
+						       buff, size, 1);
+		if (ret < 0)
+			printf("Failed to load profile.\n");
+		else if (ret > 0)
+			printf("Profile has already existed.\n");
+	}
+#endif
+
+	close_ppp_package_file(buff);
+}
+
+cmdline_parse_inst_t cmd_add_ppp = {
+	.f = cmd_add_ppp_parsed,
+	.data = NULL,
+	.help_str = "add/remove ppp <port_id> <profile_path>",
+	.tokens = {
+		(void *)&cmd_add_ppp_add,
+		(void *)&cmd_add_ppp_ppp,
+		(void *)&cmd_add_ppp_port_id,
+		(void *)&cmd_add_ppp_filepath,
+		NULL,
+	},
+};
+
 /* ******************************************************************************** */
 
 /* list of instructions */
@@ -12577,6 +12649,7 @@ cmdline_parse_ctx_t main_ctx[] = {
 	(cmdline_parse_inst_t *)&cmd_set_vf_allmulti,
 	(cmdline_parse_inst_t *)&cmd_set_vf_broadcast,
 	(cmdline_parse_inst_t *)&cmd_set_vf_vlan_tag,
+	(cmdline_parse_inst_t *)&cmd_add_ppp,
 	NULL,
 };
 
diff --git a/app/test-pmd/config.c b/app/test-pmd/config.c
index 80491fc..eb3d572 100644
--- a/app/test-pmd/config.c
+++ b/app/test-pmd/config.c
@@ -3245,3 +3245,70 @@ port_dcb_info_display(uint8_t port_id)
 		printf("\t%4d", dcb_info.tc_queue.tc_txq[0][i].nb_queue);
 	printf("\n");
 }
+
+uint8_t *
+open_ppp_package_file(const char *file_path, uint32_t *size)
+{
+	FILE *fh = fopen(file_path, "rb");
+	uint32_t pkg_size;
+	uint8_t *buf = NULL;
+	int ret = 0;
+
+	if (size)
+		*size = 0;
+
+	if (fh == NULL) {
+		printf("%s: Failed to open %s\n", __func__, file_path);
+		return buf;
+	}
+
+	ret = fseek(fh, 0, SEEK_END);
+	if (ret < 0) {
+		fclose(fh);
+		printf("%s: File operations failed\n", __func__);
+		return buf;
+	}
+
+	pkg_size = ftell(fh);
+
+	buf = (uint8_t *)malloc(pkg_size);
+	if (!buf) {
+		fclose(fh);
+		printf("%s: Failed to malloc memory\n",	__func__);
+		return buf;
+	}
+
+	ret = fseek(fh, 0, SEEK_SET);
+	if (ret < 0) {
+		fclose(fh);
+		printf("%s: File seek operation failed\n", __func__);
+		close_ppp_package_file(buf);
+		return NULL;
+	}
+
+	ret = fread(buf, 1, pkg_size, fh);
+	if (ret < 0) {
+		fclose(fh);
+		printf("%s: File read operation failed\n", __func__);
+		close_ppp_package_file(buf);
+		return NULL;
+	}
+
+	if (size)
+		*size = pkg_size;
+
+	fclose(fh);
+
+	return buf;
+}
+
+int
+close_ppp_package_file(uint8_t *buf)
+{
+	if (buf) {
+		free((void *)buf);
+		return 0;
+	}
+
+	return -1;
+}
diff --git a/app/test-pmd/testpmd.h b/app/test-pmd/testpmd.h
index 8cf2860..6bcd9c4 100644
--- a/app/test-pmd/testpmd.h
+++ b/app/test-pmd/testpmd.h
@@ -622,6 +622,9 @@ void mcast_addr_add(uint8_t port_id, struct ether_addr *mc_addr);
 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_ppp_package_file(const char *file_path, uint32_t *size);
+int close_ppp_package_file(uint8_t *buf);
+
 enum print_warning {
 	ENABLED_WARN = 0,
 	DISABLED_WARN
diff --git a/drivers/net/i40e/rte_pmd_i40e.h b/drivers/net/i40e/rte_pmd_i40e.h
index 7861a56..29e5c61 100644
--- a/drivers/net/i40e/rte_pmd_i40e.h
+++ b/drivers/net/i40e/rte_pmd_i40e.h
@@ -352,5 +352,4 @@ int rte_pmd_i40e_reset_vf_stats(uint8_t port,
  */
 int rte_pmd_i40e_process_ppp_package(uint8_t port, uint8_t *buff,
 				     uint32_t size, bool add);
-
 #endif /* _PMD_I40E_H_ */
-- 
2.5.5

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

* [PATCH v3 3/5] net/i40e: add get all loaded profiles
  2017-03-23 10:02     ` [PATCH v3 0/5] pipeline personalization profile support Beilei Xing
  2017-03-23 10:02       ` [PATCH v3 1/5] net/i40e: add pipeline personalization profile processing Beilei Xing
  2017-03-23 10:02       ` [PATCH v3 2/5] app/testpmd: add command for loading a profile Beilei Xing
@ 2017-03-23 10:02       ` Beilei Xing
  2017-03-23 10:02       ` [PATCH v3 4/5] app/testpmd: add command for getting " Beilei Xing
                         ` (2 subsequent siblings)
  5 siblings, 0 replies; 82+ messages in thread
From: Beilei Xing @ 2017-03-23 10:02 UTC (permalink / raw)
  To: jingjing.wu; +Cc: helin.zhang, dev

This patch is to add get all loaded profiles function.

Signed-off-by: Beilei Xing <beilei.xing@intel.com>
---
 drivers/net/i40e/i40e_ethdev.c            | 28 ++++++++++++++++++++++++++++
 drivers/net/i40e/rte_pmd_i40e.h           | 12 ++++++++++++
 drivers/net/i40e/rte_pmd_i40e_version.map |  1 +
 3 files changed, 41 insertions(+)

diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index 7aff9a3..9c0441b 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -11260,6 +11260,9 @@ rte_pmd_i40e_reset_vf_stats(uint8_t port,
 	return 0;
 }
 
+#define I40E_PROFILE_INFO_SIZE 48
+#define I40E_MAX_PROFILE_NUM 16
+
 static void
 i40e_generate_profile_info_sec(char *name, struct i40e_ppp_version *version,
 			       uint32_t track_id, uint8_t *profile_info_sec,
@@ -11459,3 +11462,28 @@ rte_pmd_i40e_process_ppp_package(uint8_t port, uint8_t *buff,
 	rte_free(profile_info_sec);
 	return status;
 }
+
+int
+rte_pmd_i40e_get_ppp_list(uint8_t port, uint8_t *buff, uint32_t size)
+{
+	struct rte_eth_dev *dev;
+	struct i40e_hw *hw;
+	enum i40e_status_code status = I40E_SUCCESS;
+
+	RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
+
+	dev = &rte_eth_devices[port];
+
+	if (!is_device_supported(dev, &rte_i40e_pmd))
+		return -ENOTSUP;
+
+	if (size < (I40E_PROFILE_INFO_SIZE * I40E_MAX_PROFILE_NUM + 4))
+		return -EINVAL;
+
+	hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+
+	status = i40e_aq_get_ppp_list(hw, (void *)buff,
+				      size, 0, NULL);
+
+	return status;
+}
diff --git a/drivers/net/i40e/rte_pmd_i40e.h b/drivers/net/i40e/rte_pmd_i40e.h
index 29e5c61..6d9488f 100644
--- a/drivers/net/i40e/rte_pmd_i40e.h
+++ b/drivers/net/i40e/rte_pmd_i40e.h
@@ -352,4 +352,16 @@ int rte_pmd_i40e_reset_vf_stats(uint8_t port,
  */
 int rte_pmd_i40e_process_ppp_package(uint8_t port, uint8_t *buff,
 				     uint32_t size, bool add);
+
+/**
+ * rte_pmd_i40e_get_ppp_list - Get loaded profile list
+ * @port: port id
+ * @buff: buffer for response
+ * @size: buffer size
+ * @return
+ *   - (0) if successful.
+ *   - (-ENODEV) if *port* invalid.
+ *   - (-EINVAL) if bad parameter.
+ */
+int rte_pmd_i40e_get_ppp_list(uint8_t port, uint8_t *buff, uint32_t size);
 #endif /* _PMD_I40E_H_ */
diff --git a/drivers/net/i40e/rte_pmd_i40e_version.map b/drivers/net/i40e/rte_pmd_i40e_version.map
index 01c4a90..9808893 100644
--- a/drivers/net/i40e/rte_pmd_i40e_version.map
+++ b/drivers/net/i40e/rte_pmd_i40e_version.map
@@ -27,4 +27,5 @@ DPDK_17.05 {
 	global:
 
 	rte_pmd_i40e_process_ppp_package;
+	rte_pmd_i40e_get_ppp_list;
 };
-- 
2.5.5

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

* [PATCH v3 4/5] app/testpmd: add command for getting loaded profiles
  2017-03-23 10:02     ` [PATCH v3 0/5] pipeline personalization profile support Beilei Xing
                         ` (2 preceding siblings ...)
  2017-03-23 10:02       ` [PATCH v3 3/5] net/i40e: add get all loaded profiles Beilei Xing
@ 2017-03-23 10:02       ` Beilei Xing
  2017-03-23 10:02       ` [PATCH v3 5/5] doc: add pipeline personalization profile support for i40e Beilei Xing
  2017-03-24 10:19       ` [PATCH v4 0/5] pipeline personalization profile support Beilei Xing
  5 siblings, 0 replies; 82+ messages in thread
From: Beilei Xing @ 2017-03-23 10:02 UTC (permalink / raw)
  To: jingjing.wu; +Cc: helin.zhang, dev

This patch is to add testpmd CLI for getting all loaded profiles.

Signed-off-by: Beilei Xing <beilei.xing@intel.com>
---
 app/test-pmd/cmdline.c | 89 ++++++++++++++++++++++++++++++++++++++++++++++++++
 app/test-pmd/testpmd.h | 22 +++++++++++++
 2 files changed, 111 insertions(+)

diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
index 5d6dd73..9ed17a5 100644
--- a/app/test-pmd/cmdline.c
+++ b/app/test-pmd/cmdline.c
@@ -215,6 +215,9 @@ static void cmd_help_long_parsed(void *parsed_result,
 
 			"read txd (port_id) (queue_id) (txd_id)\n"
 			"    Display a TX descriptor of a port TX queue.\n\n"
+
+			"get ppp list (port_id)\n"
+			"    Get ppp profile info list\n\n"
 		);
 	}
 
@@ -12474,6 +12477,91 @@ cmdline_parse_inst_t cmd_add_ppp = {
 	},
 };
 
+/* Get Pipeline Personalization Profile list*/
+#define PROFILE_INFO_SIZE 48
+#define MAX_PROFILE_NUM 16
+
+struct cmd_get_ppp_list_result {
+	cmdline_fixed_string_t get;
+	cmdline_fixed_string_t ppp;
+	cmdline_fixed_string_t list;
+	uint8_t port_id;
+};
+
+cmdline_parse_token_string_t cmd_get_ppp_list_get =
+	TOKEN_STRING_INITIALIZER(struct cmd_get_ppp_list_result, get, "get");
+cmdline_parse_token_string_t cmd_get_ppp_list_ppp =
+	TOKEN_STRING_INITIALIZER(struct cmd_get_ppp_list_result, ppp, "ppp");
+cmdline_parse_token_string_t cmd_get_ppp_list_list =
+	TOKEN_STRING_INITIALIZER(struct cmd_get_ppp_list_result, list, "list");
+cmdline_parse_token_num_t cmd_get_ppp_list_port_id =
+	TOKEN_NUM_INITIALIZER(struct cmd_get_ppp_list_result, port_id, UINT8);
+
+static void
+cmd_get_ppp_list_parsed(
+	void *parsed_result,
+	__attribute__((unused)) struct cmdline *cl,
+	__attribute__((unused)) void *data)
+{
+	struct cmd_get_ppp_list_result *res = parsed_result;
+	struct profile_list *p_list;
+	struct profile_info *p_info;
+	uint32_t p_num;
+	uint32_t size;
+	uint32_t i;
+	int ret = -ENOTSUP;
+
+	if (res->port_id > nb_ports) {
+		printf("Invalid port, range is [0, %d]\n", nb_ports - 1);
+		return;
+	}
+
+	size = PROFILE_INFO_SIZE * MAX_PROFILE_NUM + 4;
+	p_list = (struct profile_list *)malloc(size);
+	if (!p_list)
+		printf("%s: Failed to malloc buffer\n", __func__);
+
+#ifdef RTE_LIBRTE_I40E_PMD
+	if (ret == -ENOTSUP) {
+		ret = rte_pmd_i40e_get_ppp_list(res->port_id,
+						(uint8_t *)p_list, size);
+		if (ret < 0)
+			printf("Failed to get ppp list\n");
+	}
+#endif
+
+	if (!ret) {
+		p_num = p_list->p_count;
+		printf("Profile number is: %d\n\n", p_num);
+
+		for (i = 0; i < p_num; i++) {
+			p_info = &p_list->p_info[i];
+			printf("Profile %d:\n", i);
+			printf("Track id:     0x%x\n", p_info->track_id);
+			printf("Version:      %d.%d.%d.%d \n",
+			       p_info->version.major,
+			       p_info->version.minor,
+			       p_info->version.update,
+			       p_info->version.draft);
+			printf("Profile name: %s\n\n", p_info->name);
+		}
+	}
+
+	free(p_list);
+}
+
+cmdline_parse_inst_t cmd_get_ppp_list = {
+	.f = cmd_get_ppp_list_parsed,
+	.data = NULL,
+	.help_str = "get ppp list <port_id>",
+	.tokens = {
+		(void *)&cmd_get_ppp_list_get,
+		(void *)&cmd_get_ppp_list_ppp,
+		(void *)&cmd_get_ppp_list_list,
+		(void *)&cmd_get_ppp_list_port_id,
+		NULL,
+	},
+};
 /* ******************************************************************************** */
 
 /* list of instructions */
@@ -12650,6 +12738,7 @@ cmdline_parse_ctx_t main_ctx[] = {
 	(cmdline_parse_inst_t *)&cmd_set_vf_broadcast,
 	(cmdline_parse_inst_t *)&cmd_set_vf_vlan_tag,
 	(cmdline_parse_inst_t *)&cmd_add_ppp,
+	(cmdline_parse_inst_t *)&cmd_get_ppp_list,
 	NULL,
 };
 
diff --git a/app/test-pmd/testpmd.h b/app/test-pmd/testpmd.h
index 6bcd9c4..b9132fa 100644
--- a/app/test-pmd/testpmd.h
+++ b/app/test-pmd/testpmd.h
@@ -97,6 +97,28 @@ struct pkt_burst_stats {
 };
 #endif
 
+#ifdef RTE_LIBRTE_I40E_PMD
+#define PPP_NAME_SIZE 32
+struct ppp_version {
+	uint8_t major;
+	uint8_t minor;
+	uint8_t update;
+	uint8_t draft;
+};
+
+struct profile_info {
+	uint32_t track_id;
+	struct ppp_version version;
+	uint8_t reserved[8];
+	uint8_t name[PPP_NAME_SIZE];
+};
+
+struct profile_list {
+	uint32_t p_count;
+	struct profile_info p_info[1];
+};
+#endif
+
 /**
  * The data structure associated with a forwarding stream between a receive
  * port/queue and a transmit port/queue.
-- 
2.5.5

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

* [PATCH v3 5/5] doc: add pipeline personalization profile support for i40e
  2017-03-23 10:02     ` [PATCH v3 0/5] pipeline personalization profile support Beilei Xing
                         ` (3 preceding siblings ...)
  2017-03-23 10:02       ` [PATCH v3 4/5] app/testpmd: add command for getting " Beilei Xing
@ 2017-03-23 10:02       ` Beilei Xing
  2017-03-24 10:19       ` [PATCH v4 0/5] pipeline personalization profile support Beilei Xing
  5 siblings, 0 replies; 82+ messages in thread
From: Beilei Xing @ 2017-03-23 10:02 UTC (permalink / raw)
  To: jingjing.wu; +Cc: helin.zhang, dev

Signed-off-by: Beilei Xing <beilei.xing@intel.com>
---
 doc/guides/rel_notes/release_17_05.rst | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/doc/guides/rel_notes/release_17_05.rst b/doc/guides/rel_notes/release_17_05.rst
index 3e48224..f17e03b 100644
--- a/doc/guides/rel_notes/release_17_05.rst
+++ b/doc/guides/rel_notes/release_17_05.rst
@@ -85,6 +85,10 @@ New Features
   Data Ring, ability to register memory regions.
 
 
+* **Added pipeline personalization profile support for i40e.**
+
+  * Added loading pipeline personalization profile to i40e FW.
+
 Resolved Issues
 ---------------
 
-- 
2.5.5

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

* Re: [PATCH v3 1/5] net/i40e: add pipeline personalization profile processing
  2017-03-23 10:02       ` [PATCH v3 1/5] net/i40e: add pipeline personalization profile processing Beilei Xing
@ 2017-03-23 14:50         ` Iremonger, Bernard
  2017-03-24  2:01           ` Xing, Beilei
  0 siblings, 1 reply; 82+ messages in thread
From: Iremonger, Bernard @ 2017-03-23 14:50 UTC (permalink / raw)
  To: Xing, Beilei, Wu, Jingjing; +Cc: Zhang, Helin, dev

Hi Beilei,

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

There is a compile error in the "for" statement.

dpdk/drivers/net/i40e/i40e_ethdev.c:11561:2: error: 'for' loop initial declarations are only allowed in C99 mode
  for (uint32_t i = 0; i < p_list->p_count; i++) {

This is occurring with the following compiler:
gcc version 4.8.4 (Ubuntu 4.8.4-2ubuntu1~14.04.3)


> +		p = &p_list->p_info[i];
> +		if ((pinfo->track_id == p->track_id) &&
> +		    !memcmp(&pinfo->version, &p->version,
> +			    sizeof(struct i40e_ppp_version)) &&
> +		    !memcmp(&pinfo->name, &p->name,
> +			    I40E_PPP_NAME_SIZE)) {
> +			PMD_DRV_LOG(INFO, "Profile exists.");
> +			rte_free(buff);
> +			return 1;
> +		}
> +	}
> +
> +	rte_free(buff);
> +	return 0;
> +}
> +
> +int
> +rte_pmd_i40e_process_ppp_package(uint8_t port, uint8_t *buff,
> +				 uint32_t size, bool add)
> +{
> +	struct rte_eth_dev *dev;
> +	struct i40e_hw *hw;
> +	struct i40e_package_header *pkg_hdr;
> +	struct i40e_generic_seg_header *profile_seg_hdr;
> +	struct i40e_generic_seg_header *metadata_seg_hdr;
> +	uint32_t track_id;
> +	uint8_t *profile_info_sec;
> +	int is_exist;
> +	enum i40e_status_code status = I40E_SUCCESS;
> +
> +	RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
> +
> +	dev = &rte_eth_devices[port];
> +
> +	if (!is_device_supported(dev, &rte_i40e_pmd))
> +		return -ENOTSUP;
> +
> +	hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
> +
> +	if (size < (sizeof(struct i40e_package_header) +
> +		    sizeof(struct i40e_metadata_segment) +
> +		    sizeof(uint32_t) * 2)) {
> +		PMD_DRV_LOG(ERR, "Buff is invalid.");
> +		return -EINVAL;
> +	}
> +
> +	pkg_hdr = (struct i40e_package_header *)buff;
> +
> +	if (!pkg_hdr) {
> +		PMD_DRV_LOG(ERR, "Failed to fill the package structure");
> +		return -EINVAL;
> +	}
> +
> +	if (pkg_hdr->segment_count < 2) {
> +		PMD_DRV_LOG(ERR, "Segment_count should be 2 at
> least.");
> +		return -EINVAL;
> +	}
> +
> +	/* Find metadata segment */
> +	metadata_seg_hdr =
> i40e_find_segment_in_package(SEGMENT_TYPE_METADATA,
> +							pkg_hdr);
> +	if (!metadata_seg_hdr) {
> +		PMD_DRV_LOG(ERR, "Failed to find metadata segment
> header");
> +		return -EINVAL;
> +	}
> +	track_id = ((struct i40e_metadata_segment
> +*)metadata_seg_hdr)->track_id;
> +
> +	/* Find profile segment */
> +	profile_seg_hdr =
> i40e_find_segment_in_package(SEGMENT_TYPE_I40E,
> +						       pkg_hdr);
> +	if (!profile_seg_hdr) {
> +		PMD_DRV_LOG(ERR, "Failed to find profile segment
> header");
> +		return -EINVAL;
> +	}
> +
> +	profile_info_sec = rte_zmalloc("i40e_profile_info",
> +			       sizeof(struct i40e_profile_section_header) +
> +			       sizeof(struct i40e_profile_info),
> +			       0);
> +	if (!profile_info_sec) {
> +		PMD_DRV_LOG(ERR, "Failed to allocate memory");
> +		return -EINVAL;
> +	}
> +
> +	if (add) {
> +		i40e_generate_profile_info_sec(
> +		     ((struct i40e_profile_segment *)profile_seg_hdr)->name,
> +		     &((struct i40e_profile_segment *)profile_seg_hdr)-
> >version,
> +		     track_id, profile_info_sec, 1);
> +		is_exist = i40e_check_profile_info(port, profile_info_sec);
> +		if (is_exist) {
> +			PMD_DRV_LOG(ERR, "Profile already exists.");
> +			rte_free(profile_info_sec);
> +			return 1;
> +		}
> +
> +		/* Write profile to HW */
> +		status = i40e_write_profile(hw,
> +				 (struct i40e_profile_segment
> *)profile_seg_hdr,
> +				 track_id);
> +		if (status)
> +			PMD_DRV_LOG(ERR, "Failed to write profile.");
> +	} else {
> +		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, 0);
> +	}
> +
> +	status = i40e_add_rm_profile_info(hw, profile_info_sec);
> +	if (status)
> +		PMD_DRV_LOG(ERR, "Failed to %s profile info.",
> +			    add ? "add" : "remove");
> +
> +	rte_free(profile_info_sec);
> +	return status;
> +}
> diff --git a/drivers/net/i40e/i40e_ethdev.h
> b/drivers/net/i40e/i40e_ethdev.h index aebb097..f0be7a3 100644
> --- a/drivers/net/i40e/i40e_ethdev.h
> +++ b/drivers/net/i40e/i40e_ethdev.h
> @@ -730,6 +730,11 @@ struct i40e_valid_pattern {
>  	parse_filter_t parse_filter;
>  };
> 
> +struct i40e_profile_list {
> +	uint32_t p_count;
> +	struct i40e_profile_info p_info[1];
> +};
> +
>  int i40e_dev_switch_queues(struct i40e_pf *pf, bool on);  int
> i40e_vsi_release(struct i40e_vsi *vsi);  struct i40e_vsi *i40e_vsi_setup(struct
> i40e_pf *pf, diff --git a/drivers/net/i40e/rte_pmd_i40e.h
> b/drivers/net/i40e/rte_pmd_i40e.h index a0ad88c..7861a56 100644
> --- a/drivers/net/i40e/rte_pmd_i40e.h
> +++ b/drivers/net/i40e/rte_pmd_i40e.h
> @@ -332,4 +332,25 @@ int rte_pmd_i40e_get_vf_stats(uint8_t port,  int
> rte_pmd_i40e_reset_vf_stats(uint8_t port,
>  				uint16_t vf_id);
> 
> +/**
> + * Load/Unload a ppp package
> + *
> + * @param port
> + *    The port identifier of the Ethernet device.
> + * @param buff
> + *    buffer of package.
> + * @param size
> + *    size of buffer.
> + * @param add
> + *   - (1) load profile.
> + *   - (0) remove profile.
> + * @return
> + *   - (0) if successful.
> + *   - (-ENODEV) if *port* invalid.
> + *   - (-EINVAL) if bad parameter.
> + *   - (1) if profile exists.
> + */
> +int rte_pmd_i40e_process_ppp_package(uint8_t port, uint8_t *buff,
> +				     uint32_t size, bool add);
> +
>  #endif /* _PMD_I40E_H_ */
> diff --git a/drivers/net/i40e/rte_pmd_i40e_version.map
> b/drivers/net/i40e/rte_pmd_i40e_version.map
> index 7a5d211..01c4a90 100644
> --- a/drivers/net/i40e/rte_pmd_i40e_version.map
> +++ b/drivers/net/i40e/rte_pmd_i40e_version.map
> @@ -22,3 +22,9 @@ DPDK_17.02 {
>  	rte_pmd_i40e_set_vf_vlan_tag;
> 
>  } DPDK_2.0;
> +
> +DPDK_17.05 {
> +	global:
> +
> +	rte_pmd_i40e_process_ppp_package;
> +};
> --
> 2.5.5

Regards,

Bernard.

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

* Re: [PATCH v3 1/5] net/i40e: add pipeline personalization profile processing
  2017-03-23 14:50         ` Iremonger, Bernard
@ 2017-03-24  2:01           ` Xing, Beilei
  0 siblings, 0 replies; 82+ messages in thread
From: Xing, Beilei @ 2017-03-24  2:01 UTC (permalink / raw)
  To: Iremonger, Bernard, Wu, Jingjing; +Cc: Zhang, Helin, dev

Hi Bernard,

> -----Original Message-----
> From: Iremonger, Bernard
> Sent: Thursday, March 23, 2017 10:50 PM
> To: Xing, Beilei <beilei.xing@intel.com>; Wu, Jingjing <jingjing.wu@intel.com>
> Cc: Zhang, Helin <helin.zhang@intel.com>; dev@dpdk.org
> Subject: RE: [dpdk-dev] [PATCH v3 1/5] net/i40e: add pipeline
> personalization profile processing
> 
> Hi Beilei,
> 
> > -----Original Message-----
> > From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Beilei Xing
> > Sent: Thursday, March 23, 2017 10:02 AM
> > To: Wu, Jingjing <jingjing.wu@intel.com>
> > Cc: Zhang, Helin <helin.zhang@intel.com>; dev@dpdk.org
> > Subject: [dpdk-dev] [PATCH v3 1/5] net/i40e: add pipeline
> > personalization profile processing
> >
> > Add support for adding or removing a pipeline personalization profile
> > package.
> >
> > Signed-off-by: Beilei Xing <beilei.xing@intel.com>
> > ---
> >  app/test-pmd/cmdline.c                    |   1 +
> >  drivers/net/i40e/i40e_ethdev.c            | 200
> > ++++++++++++++++++++++++++++++
> >  drivers/net/i40e/i40e_ethdev.h            |   5 +
> >  drivers/net/i40e/rte_pmd_i40e.h           |  21 ++++
> >  drivers/net/i40e/rte_pmd_i40e_version.map |   6 +
> >  5 files changed, 233 insertions(+)
> >
> > diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c index
> > 47f935d..6e0625d 100644
> > --- a/app/test-pmd/cmdline.c
> > +++ b/app/test-pmd/cmdline.c
> > @@ -37,6 +37,7 @@
> >  #include <stdio.h>
> >  #include <stdint.h>
> >  #include <stdarg.h>
> > +#include <stdbool.h>
> >  #include <string.h>
> >  #include <termios.h>
> >  #include <unistd.h>
> > diff --git a/drivers/net/i40e/i40e_ethdev.c
> > b/drivers/net/i40e/i40e_ethdev.c index 3702214..7aff9a3 100644
> > --- a/drivers/net/i40e/i40e_ethdev.c
> > +++ b/drivers/net/i40e/i40e_ethdev.c
> > @@ -11259,3 +11259,203 @@ rte_pmd_i40e_reset_vf_stats(uint8_t port,
> >
> >  	return 0;
> >  }
> > +
> > +static void
> > +i40e_generate_profile_info_sec(char *name, struct i40e_ppp_version
> > *version,
> > +			       uint32_t track_id, uint8_t *profile_info_sec,
> > +			       bool add)
> > +{
> > +	struct i40e_profile_section_header *sec = NULL;
> > +	struct i40e_profile_info *pinfo;
> > +
> > +	sec = (struct i40e_profile_section_header *)profile_info_sec;
> > +	sec->tbl_size = 1;
> > +	sec->data_end = sizeof(struct i40e_profile_section_header) +
> > +		sizeof(struct i40e_profile_info);
> > +	sec->section.type = SECTION_TYPE_INFO;
> > +	sec->section.offset = sizeof(struct i40e_profile_section_header);
> > +	sec->section.size = sizeof(struct i40e_profile_info);
> > +	pinfo = (struct i40e_profile_info *)(profile_info_sec +
> > +					     sec->section.offset);
> > +	pinfo->track_id = track_id;
> > +	memcpy(pinfo->name, name, I40E_PPP_NAME_SIZE);
> > +	memcpy(&pinfo->version, version, sizeof(struct i40e_ppp_version));
> > +	if (add)
> > +		pinfo->op = I40E_PPP_ADD_TRACKID;
> > +	else
> > +		pinfo->op = I40E_PPP_REMOVE_TRACKID; }
> > +
> > +static enum i40e_status_code
> > +i40e_add_rm_profile_info(struct i40e_hw *hw, uint8_t
> > +*profile_info_sec) {
> > +	enum i40e_status_code status = I40E_SUCCESS;
> > +	struct i40e_profile_section_header *sec;
> > +	uint32_t track_id;
> > +	uint32_t offset = 0, info = 0;
> > +
> > +	sec = (struct i40e_profile_section_header *)profile_info_sec;
> > +	track_id = ((struct i40e_profile_info *)(profile_info_sec +
> > +					 sec->section.offset))->track_id;
> > +
> > +	status = i40e_aq_write_ppp(hw, (void *)sec, sec->data_end,
> > +				   track_id, &offset, &info, NULL);
> > +	if (status)
> > +		PMD_DRV_LOG(ERR, "Failed to add/remove profile info: "
> > +			    "offset %d, info %d",
> > +			    offset, info);
> > +
> > +	return status;
> > +}
> > +
> > +#define I40E_PROFILE_INFO_SIZE 48
> > +#define I40E_MAX_PROFILE_NUM 16
> > +
> > +/* Check if the profile info exists */ static int
> > +i40e_check_profile_info(uint8_t port, uint8_t *profile_info_sec) {
> > +	struct rte_eth_dev *dev = &rte_eth_devices[port];
> > +	struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data-
> > >dev_private);
> > +	uint8_t *buff;
> > +	struct i40e_profile_list *p_list;
> > +	struct i40e_profile_info *pinfo, *p;
> > +	int ret;
> > +
> > +	buff = rte_zmalloc("i40e_pinfo_list",
> > +			   (I40E_PROFILE_INFO_SIZE *
> > I40E_MAX_PROFILE_NUM + 4),
> > +			   0);
> > +	if (!buff) {
> > +		PMD_DRV_LOG(ERR, "failed to allocate memory");
> > +		return -1;
> > +	}
> > +
> > +	ret = i40e_aq_get_ppp_list(hw, (void *)buff,
> > +		      (I40E_PROFILE_INFO_SIZE * I40E_MAX_PROFILE_NUM +
> > 4),
> > +		      0, NULL);
> > +	if (ret) {
> > +		PMD_DRV_LOG(ERR, "Failed to get profile info list.");
> > +		rte_free(buff);
> > +		return -1;
> > +	}
> > +	p_list = (struct i40e_profile_list *)buff;
> > +	pinfo = (struct i40e_profile_info *)(profile_info_sec +
> > +			     sizeof(struct i40e_profile_section_header));
> > +	for (uint32_t i = 0; i < p_list->p_count; i++) {
> 
> There is a compile error in the "for" statement.
> 
> dpdk/drivers/net/i40e/i40e_ethdev.c:11561:2: error: 'for' loop initial
> declarations are only allowed in C99 mode
>   for (uint32_t i = 0; i < p_list->p_count; i++) {
> 
> This is occurring with the following compiler:
> gcc version 4.8.4 (Ubuntu 4.8.4-2ubuntu1~14.04.3)
> 

Thanks, will fix in next version.

> 
> > +		p = &p_list->p_info[i];
> > +		if ((pinfo->track_id == p->track_id) &&
> > +		    !memcmp(&pinfo->version, &p->version,
> > +			    sizeof(struct i40e_ppp_version)) &&
> > +		    !memcmp(&pinfo->name, &p->name,
> > +			    I40E_PPP_NAME_SIZE)) {
> > +			PMD_DRV_LOG(INFO, "Profile exists.");
> > +			rte_free(buff);
> > +			return 1;
> > +		}
> > +	}
> > +
> > +	rte_free(buff);
> > +	return 0;
> > +}
> > +
> > +int
> > +rte_pmd_i40e_process_ppp_package(uint8_t port, uint8_t *buff,
> > +				 uint32_t size, bool add)
> > +{
> > +	struct rte_eth_dev *dev;
> > +	struct i40e_hw *hw;
> > +	struct i40e_package_header *pkg_hdr;
> > +	struct i40e_generic_seg_header *profile_seg_hdr;
> > +	struct i40e_generic_seg_header *metadata_seg_hdr;
> > +	uint32_t track_id;
> > +	uint8_t *profile_info_sec;
> > +	int is_exist;
> > +	enum i40e_status_code status = I40E_SUCCESS;
> > +
> > +	RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
> > +
> > +	dev = &rte_eth_devices[port];
> > +
> > +	if (!is_device_supported(dev, &rte_i40e_pmd))
> > +		return -ENOTSUP;
> > +
> > +	hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
> > +
> > +	if (size < (sizeof(struct i40e_package_header) +
> > +		    sizeof(struct i40e_metadata_segment) +
> > +		    sizeof(uint32_t) * 2)) {
> > +		PMD_DRV_LOG(ERR, "Buff is invalid.");
> > +		return -EINVAL;
> > +	}
> > +
> > +	pkg_hdr = (struct i40e_package_header *)buff;
> > +
> > +	if (!pkg_hdr) {
> > +		PMD_DRV_LOG(ERR, "Failed to fill the package structure");
> > +		return -EINVAL;
> > +	}
> > +
> > +	if (pkg_hdr->segment_count < 2) {
> > +		PMD_DRV_LOG(ERR, "Segment_count should be 2 at
> > least.");
> > +		return -EINVAL;
> > +	}
> > +
> > +	/* Find metadata segment */
> > +	metadata_seg_hdr =
> > i40e_find_segment_in_package(SEGMENT_TYPE_METADATA,
> > +							pkg_hdr);
> > +	if (!metadata_seg_hdr) {
> > +		PMD_DRV_LOG(ERR, "Failed to find metadata segment
> > header");
> > +		return -EINVAL;
> > +	}
> > +	track_id = ((struct i40e_metadata_segment
> > +*)metadata_seg_hdr)->track_id;
> > +
> > +	/* Find profile segment */
> > +	profile_seg_hdr =
> > i40e_find_segment_in_package(SEGMENT_TYPE_I40E,
> > +						       pkg_hdr);
> > +	if (!profile_seg_hdr) {
> > +		PMD_DRV_LOG(ERR, "Failed to find profile segment
> > header");
> > +		return -EINVAL;
> > +	}
> > +
> > +	profile_info_sec = rte_zmalloc("i40e_profile_info",
> > +			       sizeof(struct i40e_profile_section_header) +
> > +			       sizeof(struct i40e_profile_info),
> > +			       0);
> > +	if (!profile_info_sec) {
> > +		PMD_DRV_LOG(ERR, "Failed to allocate memory");
> > +		return -EINVAL;
> > +	}
> > +
> > +	if (add) {
> > +		i40e_generate_profile_info_sec(
> > +		     ((struct i40e_profile_segment *)profile_seg_hdr)->name,
> > +		     &((struct i40e_profile_segment *)profile_seg_hdr)-
> > >version,
> > +		     track_id, profile_info_sec, 1);
> > +		is_exist = i40e_check_profile_info(port, profile_info_sec);
> > +		if (is_exist) {
> > +			PMD_DRV_LOG(ERR, "Profile already exists.");
> > +			rte_free(profile_info_sec);
> > +			return 1;
> > +		}
> > +
> > +		/* Write profile to HW */
> > +		status = i40e_write_profile(hw,
> > +				 (struct i40e_profile_segment
> > *)profile_seg_hdr,
> > +				 track_id);
> > +		if (status)
> > +			PMD_DRV_LOG(ERR, "Failed to write profile.");
> > +	} else {
> > +		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, 0);
> > +	}
> > +
> > +	status = i40e_add_rm_profile_info(hw, profile_info_sec);
> > +	if (status)
> > +		PMD_DRV_LOG(ERR, "Failed to %s profile info.",
> > +			    add ? "add" : "remove");
> > +
> > +	rte_free(profile_info_sec);
> > +	return status;
> > +}
> > diff --git a/drivers/net/i40e/i40e_ethdev.h
> > b/drivers/net/i40e/i40e_ethdev.h index aebb097..f0be7a3 100644
> > --- a/drivers/net/i40e/i40e_ethdev.h
> > +++ b/drivers/net/i40e/i40e_ethdev.h
> > @@ -730,6 +730,11 @@ struct i40e_valid_pattern {
> >  	parse_filter_t parse_filter;
> >  };
> >
> > +struct i40e_profile_list {
> > +	uint32_t p_count;
> > +	struct i40e_profile_info p_info[1];
> > +};
> > +
> >  int i40e_dev_switch_queues(struct i40e_pf *pf, bool on);  int
> > i40e_vsi_release(struct i40e_vsi *vsi);  struct i40e_vsi
> > *i40e_vsi_setup(struct i40e_pf *pf, diff --git
> > a/drivers/net/i40e/rte_pmd_i40e.h b/drivers/net/i40e/rte_pmd_i40e.h
> > index a0ad88c..7861a56 100644
> > --- a/drivers/net/i40e/rte_pmd_i40e.h
> > +++ b/drivers/net/i40e/rte_pmd_i40e.h
> > @@ -332,4 +332,25 @@ int rte_pmd_i40e_get_vf_stats(uint8_t port,  int
> > rte_pmd_i40e_reset_vf_stats(uint8_t port,
> >  				uint16_t vf_id);
> >
> > +/**
> > + * Load/Unload a ppp package
> > + *
> > + * @param port
> > + *    The port identifier of the Ethernet device.
> > + * @param buff
> > + *    buffer of package.
> > + * @param size
> > + *    size of buffer.
> > + * @param add
> > + *   - (1) load profile.
> > + *   - (0) remove profile.
> > + * @return
> > + *   - (0) if successful.
> > + *   - (-ENODEV) if *port* invalid.
> > + *   - (-EINVAL) if bad parameter.
> > + *   - (1) if profile exists.
> > + */
> > +int rte_pmd_i40e_process_ppp_package(uint8_t port, uint8_t *buff,
> > +				     uint32_t size, bool add);
> > +
> >  #endif /* _PMD_I40E_H_ */
> > diff --git a/drivers/net/i40e/rte_pmd_i40e_version.map
> > b/drivers/net/i40e/rte_pmd_i40e_version.map
> > index 7a5d211..01c4a90 100644
> > --- a/drivers/net/i40e/rte_pmd_i40e_version.map
> > +++ b/drivers/net/i40e/rte_pmd_i40e_version.map
> > @@ -22,3 +22,9 @@ DPDK_17.02 {
> >  	rte_pmd_i40e_set_vf_vlan_tag;
> >
> >  } DPDK_2.0;
> > +
> > +DPDK_17.05 {
> > +	global:
> > +
> > +	rte_pmd_i40e_process_ppp_package;
> > +};
> > --
> > 2.5.5
> 
> Regards,
> 
> Bernard.

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

* [PATCH v4 0/5] pipeline personalization profile support
  2017-03-23 10:02     ` [PATCH v3 0/5] pipeline personalization profile support Beilei Xing
                         ` (4 preceding siblings ...)
  2017-03-23 10:02       ` [PATCH v3 5/5] doc: add pipeline personalization profile support for i40e Beilei Xing
@ 2017-03-24 10:19       ` Beilei Xing
  2017-03-24 10:19         ` [PATCH v4 1/5] net/i40e: add pipeline personalization profile processing Beilei Xing
                           ` (5 more replies)
  5 siblings, 6 replies; 82+ messages in thread
From: Beilei Xing @ 2017-03-24 10:19 UTC (permalink / raw)
  To: jingjing.wu; +Cc: helin.zhang, dev

Due to limited resources of X*710 (parser and analyzer configuration
tables, number of packet classification types, number of packet types,
filters configuration tables, etc.), it's impossible to simultaneously
support all protocols/filters required for different parts on network.
To enable protocols/filters extensions for X*710, new Admin Command
for loading user defined configurations is added.
PPP is a format of extend configuration for X*710, it allows user to
load user defined configuration to X*710.

List of possible use cases for extended X*710 configuration using
profiles could include following:
Configuring Analyzer/Parser to support new protocols, e.g.
- IP L2TPv3 tunneling protocol
- IPSec ESP/AH protocols
- MPLSoGRE, MPLSoUDP tunnels
- GTP-C/GTP-U tunnels
New PCTYPEs for offloading packet classification to X*710. e.g.
- new IP Protocol in addition to TCP/UDP/SCTP
- new TCP/UDP subtypes, like TCP SYN, TCP FIN
- new PCTYPE for tunneled packets like GTP-C, GTP-U
New PTYPEs for packets identification, e.g.
- MAC, MPLS, IP4, UDP
- MAC, MPLS, MPLS, IP6, TCP
Fixes for NVM configuration, e.g.
- list of enabled stat counters to improve throughput
- parser/analyzer configuration for some corner cases

v4 changes:
 Fix compile error with gcc version 4.8.4 (Ubuntu 4.8.4-2ubuntu1~14.04.3).
 Move ppp related structures to rte_pmd_i40e.h.
 Not support remove PPP temporarily.

v3 changes:
 Move ppp AQ command code to base code.

Beilei Xing (5):
  net/i40e: add pipeline personalization profile processing
  app/testpmd: add command for loading a profile
  net/i40e: add get all loaded profiles
  app/testpmd: add command for getting loaded profiles
  doc: add pipeline personalization profile support for i40e

 app/test-pmd/cmdline.c                    | 165 ++++++++++++++++++++++
 app/test-pmd/config.c                     |  67 +++++++++
 app/test-pmd/testpmd.h                    |   3 +
 doc/guides/rel_notes/release_17_05.rst    |   4 +
 drivers/net/i40e/i40e_ethdev.c            | 226 ++++++++++++++++++++++++++++++
 drivers/net/i40e/rte_pmd_i40e.h           |  63 +++++++++
 drivers/net/i40e/rte_pmd_i40e_version.map |   7 +
 7 files changed, 535 insertions(+)

-- 
2.5.5

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

* [PATCH v4 1/5] net/i40e: add pipeline personalization profile processing
  2017-03-24 10:19       ` [PATCH v4 0/5] pipeline personalization profile support Beilei Xing
@ 2017-03-24 10:19         ` Beilei Xing
  2017-03-24 14:52           ` Chilikin, Andrey
  2017-03-24 10:19         ` [PATCH v4 2/5] app/testpmd: add command for loading a profile Beilei Xing
                           ` (4 subsequent siblings)
  5 siblings, 1 reply; 82+ messages in thread
From: Beilei Xing @ 2017-03-24 10:19 UTC (permalink / raw)
  To: jingjing.wu; +Cc: helin.zhang, dev

Add support for adding a pipeline personalization profile
package.

Signed-off-by: Beilei Xing <beilei.xing@intel.com>
---
 app/test-pmd/cmdline.c                    |   1 +
 drivers/net/i40e/i40e_ethdev.c            | 198 ++++++++++++++++++++++++++++++
 drivers/net/i40e/rte_pmd_i40e.h           |  51 ++++++++
 drivers/net/i40e/rte_pmd_i40e_version.map |   6 +
 4 files changed, 256 insertions(+)

diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
index 47f935d..6e0625d 100644
--- a/app/test-pmd/cmdline.c
+++ b/app/test-pmd/cmdline.c
@@ -37,6 +37,7 @@
 #include <stdio.h>
 #include <stdint.h>
 #include <stdarg.h>
+#include <stdbool.h>
 #include <string.h>
 #include <termios.h>
 #include <unistd.h>
diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index 3702214..bea593f 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -11259,3 +11259,201 @@ rte_pmd_i40e_reset_vf_stats(uint8_t port,
 
 	return 0;
 }
+
+static void
+i40e_generate_profile_info_sec(char *name, struct i40e_ppp_version *version,
+			       uint32_t track_id, uint8_t *profile_info_sec,
+			       bool add)
+{
+	struct i40e_profile_section_header *sec = NULL;
+	struct i40e_profile_info *pinfo;
+
+	sec = (struct i40e_profile_section_header *)profile_info_sec;
+	sec->tbl_size = 1;
+	sec->data_end = sizeof(struct i40e_profile_section_header) +
+		sizeof(struct i40e_profile_info);
+	sec->section.type = SECTION_TYPE_INFO;
+	sec->section.offset = sizeof(struct i40e_profile_section_header);
+	sec->section.size = sizeof(struct i40e_profile_info);
+	pinfo = (struct i40e_profile_info *)(profile_info_sec +
+					     sec->section.offset);
+	pinfo->track_id = track_id;
+	memcpy(pinfo->name, name, I40E_PPP_NAME_SIZE);
+	memcpy(&pinfo->version, version, sizeof(struct i40e_ppp_version));
+	if (add)
+		pinfo->op = I40E_PPP_ADD_TRACKID;
+	else
+		pinfo->op = I40E_PPP_REMOVE_TRACKID;
+}
+
+static enum i40e_status_code
+i40e_add_rm_profile_info(struct i40e_hw *hw, uint8_t *profile_info_sec)
+{
+	enum i40e_status_code status = I40E_SUCCESS;
+	struct i40e_profile_section_header *sec;
+	uint32_t track_id;
+	uint32_t offset = 0, info = 0;
+
+	sec = (struct i40e_profile_section_header *)profile_info_sec;
+	track_id = ((struct i40e_profile_info *)(profile_info_sec +
+					 sec->section.offset))->track_id;
+
+	status = i40e_aq_write_ppp(hw, (void *)sec, sec->data_end,
+				   track_id, &offset, &info, NULL);
+	if (status)
+		PMD_DRV_LOG(ERR, "Failed to add/remove profile info: "
+			    "offset %d, info %d",
+			    offset, info);
+
+	return status;
+}
+
+#define I40E_PROFILE_INFO_SIZE 48
+#define I40E_MAX_PROFILE_NUM 16
+
+/* Check if the profile info exists */
+static int
+i40e_check_profile_info(uint8_t port, uint8_t *profile_info_sec)
+{
+	struct rte_eth_dev *dev = &rte_eth_devices[port];
+	struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+	uint8_t *buff;
+	struct rte_pmd_i40e_profile_list *p_list;
+	struct rte_pmd_i40e_profile_info *pinfo, *p;
+	uint32_t i;
+	int ret;
+
+	buff = rte_zmalloc("pinfo_list",
+			   (I40E_PROFILE_INFO_SIZE * I40E_MAX_PROFILE_NUM + 4),
+			   0);
+	if (!buff) {
+		PMD_DRV_LOG(ERR, "failed to allocate memory");
+		return -1;
+	}
+
+	ret = i40e_aq_get_ppp_list(hw, (void *)buff,
+		      (I40E_PROFILE_INFO_SIZE * I40E_MAX_PROFILE_NUM + 4),
+		      0, NULL);
+	if (ret) {
+		PMD_DRV_LOG(ERR, "Failed to get profile info list.");
+		rte_free(buff);
+		return -1;
+	}
+	p_list = (struct rte_pmd_i40e_profile_list *)buff;
+	pinfo = (struct rte_pmd_i40e_profile_info *)(profile_info_sec +
+			     sizeof(struct i40e_profile_section_header));
+	for (i = 0; i < p_list->p_count; i++) {
+		p = &p_list->p_info[i];
+		if ((pinfo->track_id == p->track_id) &&
+		    !memcmp(&pinfo->version, &p->version,
+			    sizeof(struct i40e_ppp_version)) &&
+		    !memcmp(&pinfo->name, &p->name,
+			    I40E_PPP_NAME_SIZE)) {
+			PMD_DRV_LOG(INFO, "Profile exists.");
+			rte_free(buff);
+			return 1;
+		}
+	}
+
+	rte_free(buff);
+	return 0;
+}
+
+int
+rte_pmd_i40e_process_ppp_package(uint8_t port, uint8_t *buff,
+				 uint32_t size, bool add)
+{
+	struct rte_eth_dev *dev;
+	struct i40e_hw *hw;
+	struct i40e_package_header *pkg_hdr;
+	struct i40e_generic_seg_header *profile_seg_hdr;
+	struct i40e_generic_seg_header *metadata_seg_hdr;
+	uint32_t track_id;
+	uint8_t *profile_info_sec;
+	int is_exist;
+	enum i40e_status_code status = I40E_SUCCESS;
+
+	RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
+
+	dev = &rte_eth_devices[port];
+
+	if (!is_device_supported(dev, &rte_i40e_pmd))
+		return -ENOTSUP;
+
+	hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+
+	if (size < (sizeof(struct i40e_package_header) +
+		    sizeof(struct i40e_metadata_segment) +
+		    sizeof(uint32_t) * 2)) {
+		PMD_DRV_LOG(ERR, "Buff is invalid.");
+		return -EINVAL;
+	}
+
+	pkg_hdr = (struct i40e_package_header *)buff;
+
+	if (!pkg_hdr) {
+		PMD_DRV_LOG(ERR, "Failed to fill the package structure");
+		return -EINVAL;
+	}
+
+	if (pkg_hdr->segment_count < 2) {
+		PMD_DRV_LOG(ERR, "Segment_count should be 2 at least.");
+		return -EINVAL;
+	}
+
+	/* Find metadata segment */
+	metadata_seg_hdr = i40e_find_segment_in_package(SEGMENT_TYPE_METADATA,
+							pkg_hdr);
+	if (!metadata_seg_hdr) {
+		PMD_DRV_LOG(ERR, "Failed to find metadata segment header");
+		return -EINVAL;
+	}
+	track_id = ((struct i40e_metadata_segment *)metadata_seg_hdr)->track_id;
+
+	/* Find profile segment */
+	profile_seg_hdr = i40e_find_segment_in_package(SEGMENT_TYPE_I40E,
+						       pkg_hdr);
+	if (!profile_seg_hdr) {
+		PMD_DRV_LOG(ERR, "Failed to find profile segment header");
+		return -EINVAL;
+	}
+
+	profile_info_sec = rte_zmalloc("i40e_profile_info",
+			       sizeof(struct i40e_profile_section_header) +
+			       sizeof(struct i40e_profile_info),
+			       0);
+	if (!profile_info_sec) {
+		PMD_DRV_LOG(ERR, "Failed to allocate memory");
+		return -EINVAL;
+	}
+
+	if (add) {
+		/* Check if the profile exists */
+		i40e_generate_profile_info_sec(
+		     ((struct i40e_profile_segment *)profile_seg_hdr)->name,
+		     &((struct i40e_profile_segment *)profile_seg_hdr)->version,
+		     track_id, profile_info_sec, 1);
+		is_exist = i40e_check_profile_info(port, profile_info_sec);
+		if (is_exist) {
+			PMD_DRV_LOG(ERR, "Profile already exists.");
+			rte_free(profile_info_sec);
+			return 1;
+		}
+
+		/* Write profile to HW */
+		status = i40e_write_profile(hw,
+				 (struct i40e_profile_segment *)profile_seg_hdr,
+				 track_id);
+		if (status)
+			PMD_DRV_LOG(ERR, "Failed to write profile.");
+
+		/* Add profile info to info list */
+		status = i40e_add_rm_profile_info(hw, profile_info_sec);
+		if (status)
+			PMD_DRV_LOG(ERR, "Failed to add profile info.");
+	} else
+		PMD_DRV_LOG(ERR, "Action not supported temporarily.");
+
+	rte_free(profile_info_sec);
+	return status;
+}
diff --git a/drivers/net/i40e/rte_pmd_i40e.h b/drivers/net/i40e/rte_pmd_i40e.h
index a0ad88c..4f6cdb5 100644
--- a/drivers/net/i40e/rte_pmd_i40e.h
+++ b/drivers/net/i40e/rte_pmd_i40e.h
@@ -65,6 +65,36 @@ struct rte_pmd_i40e_mb_event_param {
 	uint16_t msglen;   /**< length of the message */
 };
 
+#define RTE_PMD_I40E_PPP_NAME_SIZE 32
+
+/**
+ * Pipeline personalization profile version
+ */
+struct rte_pmd_i40e_ppp_version {
+	uint8_t major;
+	uint8_t minor;
+	uint8_t update;
+	uint8_t draft;
+};
+
+/**
+ * Structure of profile information
+ */
+struct rte_pmd_i40e_profile_info {
+	uint32_t track_id;
+	struct rte_pmd_i40e_ppp_version version;
+	uint8_t reserved[8];
+	uint8_t name[RTE_PMD_I40E_PPP_NAME_SIZE];
+};
+
+/**
+ * Structure of profile information list
+ */
+struct rte_pmd_i40e_profile_list {
+	uint32_t p_count;
+	struct rte_pmd_i40e_profile_info p_info[1];
+};
+
 /**
  * Notify VF when PF link status changes.
  *
@@ -332,4 +362,25 @@ int rte_pmd_i40e_get_vf_stats(uint8_t port,
 int rte_pmd_i40e_reset_vf_stats(uint8_t port,
 				uint16_t vf_id);
 
+/**
+ * Load/Unload a ppp package
+ *
+ * @param port
+ *    The port identifier of the Ethernet device.
+ * @param buff
+ *    buffer of package.
+ * @param size
+ *    size of buffer.
+ * @param add
+ *   - (1) write profile.
+ *   - (0) remove profile.
+ * @return
+ *   - (0) if successful.
+ *   - (-ENODEV) if *port* invalid.
+ *   - (-EINVAL) if bad parameter.
+ *   - (1) if profile exists.
+ */
+int rte_pmd_i40e_process_ppp_package(uint8_t port, uint8_t *buff,
+				     uint32_t size, bool add);
+
 #endif /* _PMD_I40E_H_ */
diff --git a/drivers/net/i40e/rte_pmd_i40e_version.map b/drivers/net/i40e/rte_pmd_i40e_version.map
index 7a5d211..01c4a90 100644
--- a/drivers/net/i40e/rte_pmd_i40e_version.map
+++ b/drivers/net/i40e/rte_pmd_i40e_version.map
@@ -22,3 +22,9 @@ DPDK_17.02 {
 	rte_pmd_i40e_set_vf_vlan_tag;
 
 } DPDK_2.0;
+
+DPDK_17.05 {
+	global:
+
+	rte_pmd_i40e_process_ppp_package;
+};
-- 
2.5.5

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

* [PATCH v4 2/5] app/testpmd: add command for loading a profile
  2017-03-24 10:19       ` [PATCH v4 0/5] pipeline personalization profile support Beilei Xing
  2017-03-24 10:19         ` [PATCH v4 1/5] net/i40e: add pipeline personalization profile processing Beilei Xing
@ 2017-03-24 10:19         ` Beilei Xing
  2017-03-24 10:19         ` [PATCH v4 3/5] net/i40e: add get all loaded profiles Beilei Xing
                           ` (3 subsequent siblings)
  5 siblings, 0 replies; 82+ messages in thread
From: Beilei Xing @ 2017-03-24 10:19 UTC (permalink / raw)
  To: jingjing.wu; +Cc: helin.zhang, dev

This patch is to add testpmd CLI for loading a pipeline
personalization profile.

Signed-off-by: Beilei Xing <beilei.xing@intel.com>
---
 app/test-pmd/cmdline.c | 73 ++++++++++++++++++++++++++++++++++++++++++++++++++
 app/test-pmd/config.c  | 67 +++++++++++++++++++++++++++++++++++++++++++++
 app/test-pmd/testpmd.h |  3 +++
 3 files changed, 143 insertions(+)

diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
index 6e0625d..86177fb 100644
--- a/app/test-pmd/cmdline.c
+++ b/app/test-pmd/cmdline.c
@@ -579,6 +579,9 @@ 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"
 
+			"add ppp (port_id) (profile_path)\n"
+			"    Load a profile package on a port\n\n"
+
 			, list_pkt_forwarding_modes()
 		);
 	}
@@ -12402,6 +12405,75 @@ cmdline_parse_inst_t cmd_set_vf_vlan_tag = {
 	},
 };
 
+/* Load Pipeline Personalization Profile */
+struct cmd_add_ppp_result {
+	cmdline_fixed_string_t add;
+	cmdline_fixed_string_t ppp;
+	uint8_t port_id;
+	char filepath[];
+};
+
+cmdline_parse_token_string_t cmd_add_ppp_add =
+	TOKEN_STRING_INITIALIZER(struct cmd_add_ppp_result, add, "add");
+cmdline_parse_token_string_t cmd_add_ppp_ppp =
+	TOKEN_STRING_INITIALIZER(struct cmd_add_ppp_result, ppp, "ppp");
+cmdline_parse_token_num_t cmd_add_ppp_port_id =
+	TOKEN_NUM_INITIALIZER(struct cmd_add_ppp_result, port_id, UINT8);
+cmdline_parse_token_string_t cmd_add_ppp_filepath =
+	TOKEN_STRING_INITIALIZER(struct cmd_add_ppp_result, filepath, NULL);
+
+static void
+cmd_add_ppp_parsed(
+	void *parsed_result,
+	__attribute__((unused)) struct cmdline *cl,
+	__attribute__((unused)) void *data)
+{
+	struct cmd_add_ppp_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_ppp_package_file(res->filepath, &size);
+	if (!buff)
+		return;
+
+#ifdef RTE_LIBRTE_I40E_PMD
+	if (ret == -ENOTSUP)
+		ret = rte_pmd_i40e_process_ppp_package(res->port_id,
+						       buff, size, 1);
+#endif
+
+	if (ret < 0)
+		printf("Failed to load profile.\n");
+	else if (ret > 0)
+		printf("Profile has already existed.\n");
+
+	close_ppp_package_file(buff);
+}
+
+cmdline_parse_inst_t cmd_add_ppp = {
+	.f = cmd_add_ppp_parsed,
+	.data = NULL,
+	.help_str = "add/remove ppp <port_id> <profile_path>",
+	.tokens = {
+		(void *)&cmd_add_ppp_add,
+		(void *)&cmd_add_ppp_ppp,
+		(void *)&cmd_add_ppp_port_id,
+		(void *)&cmd_add_ppp_filepath,
+		NULL,
+	},
+};
+
 /* ******************************************************************************** */
 
 /* list of instructions */
@@ -12577,6 +12649,7 @@ cmdline_parse_ctx_t main_ctx[] = {
 	(cmdline_parse_inst_t *)&cmd_set_vf_allmulti,
 	(cmdline_parse_inst_t *)&cmd_set_vf_broadcast,
 	(cmdline_parse_inst_t *)&cmd_set_vf_vlan_tag,
+	(cmdline_parse_inst_t *)&cmd_add_ppp,
 	NULL,
 };
 
diff --git a/app/test-pmd/config.c b/app/test-pmd/config.c
index 80491fc..eb3d572 100644
--- a/app/test-pmd/config.c
+++ b/app/test-pmd/config.c
@@ -3245,3 +3245,70 @@ port_dcb_info_display(uint8_t port_id)
 		printf("\t%4d", dcb_info.tc_queue.tc_txq[0][i].nb_queue);
 	printf("\n");
 }
+
+uint8_t *
+open_ppp_package_file(const char *file_path, uint32_t *size)
+{
+	FILE *fh = fopen(file_path, "rb");
+	uint32_t pkg_size;
+	uint8_t *buf = NULL;
+	int ret = 0;
+
+	if (size)
+		*size = 0;
+
+	if (fh == NULL) {
+		printf("%s: Failed to open %s\n", __func__, file_path);
+		return buf;
+	}
+
+	ret = fseek(fh, 0, SEEK_END);
+	if (ret < 0) {
+		fclose(fh);
+		printf("%s: File operations failed\n", __func__);
+		return buf;
+	}
+
+	pkg_size = ftell(fh);
+
+	buf = (uint8_t *)malloc(pkg_size);
+	if (!buf) {
+		fclose(fh);
+		printf("%s: Failed to malloc memory\n",	__func__);
+		return buf;
+	}
+
+	ret = fseek(fh, 0, SEEK_SET);
+	if (ret < 0) {
+		fclose(fh);
+		printf("%s: File seek operation failed\n", __func__);
+		close_ppp_package_file(buf);
+		return NULL;
+	}
+
+	ret = fread(buf, 1, pkg_size, fh);
+	if (ret < 0) {
+		fclose(fh);
+		printf("%s: File read operation failed\n", __func__);
+		close_ppp_package_file(buf);
+		return NULL;
+	}
+
+	if (size)
+		*size = pkg_size;
+
+	fclose(fh);
+
+	return buf;
+}
+
+int
+close_ppp_package_file(uint8_t *buf)
+{
+	if (buf) {
+		free((void *)buf);
+		return 0;
+	}
+
+	return -1;
+}
diff --git a/app/test-pmd/testpmd.h b/app/test-pmd/testpmd.h
index 8cf2860..6bcd9c4 100644
--- a/app/test-pmd/testpmd.h
+++ b/app/test-pmd/testpmd.h
@@ -622,6 +622,9 @@ void mcast_addr_add(uint8_t port_id, struct ether_addr *mc_addr);
 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_ppp_package_file(const char *file_path, uint32_t *size);
+int close_ppp_package_file(uint8_t *buf);
+
 enum print_warning {
 	ENABLED_WARN = 0,
 	DISABLED_WARN
-- 
2.5.5

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

* [PATCH v4 3/5] net/i40e: add get all loaded profiles
  2017-03-24 10:19       ` [PATCH v4 0/5] pipeline personalization profile support Beilei Xing
  2017-03-24 10:19         ` [PATCH v4 1/5] net/i40e: add pipeline personalization profile processing Beilei Xing
  2017-03-24 10:19         ` [PATCH v4 2/5] app/testpmd: add command for loading a profile Beilei Xing
@ 2017-03-24 10:19         ` Beilei Xing
  2017-03-24 10:19         ` [PATCH v4 4/5] app/testpmd: add command for getting " Beilei Xing
                           ` (2 subsequent siblings)
  5 siblings, 0 replies; 82+ messages in thread
From: Beilei Xing @ 2017-03-24 10:19 UTC (permalink / raw)
  To: jingjing.wu; +Cc: helin.zhang, dev

This patch is to add get all loaded profiles function.

Signed-off-by: Beilei Xing <beilei.xing@intel.com>
---
 drivers/net/i40e/i40e_ethdev.c            | 28 ++++++++++++++++++++++++++++
 drivers/net/i40e/rte_pmd_i40e.h           | 12 ++++++++++++
 drivers/net/i40e/rte_pmd_i40e_version.map |  1 +
 3 files changed, 41 insertions(+)

diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index bea593f..bec3e5d 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -11260,6 +11260,9 @@ rte_pmd_i40e_reset_vf_stats(uint8_t port,
 	return 0;
 }
 
+#define I40E_PROFILE_INFO_SIZE 48
+#define I40E_MAX_PROFILE_NUM 16
+
 static void
 i40e_generate_profile_info_sec(char *name, struct i40e_ppp_version *version,
 			       uint32_t track_id, uint8_t *profile_info_sec,
@@ -11457,3 +11460,28 @@ rte_pmd_i40e_process_ppp_package(uint8_t port, uint8_t *buff,
 	rte_free(profile_info_sec);
 	return status;
 }
+
+int
+rte_pmd_i40e_get_ppp_list(uint8_t port, uint8_t *buff, uint32_t size)
+{
+	struct rte_eth_dev *dev;
+	struct i40e_hw *hw;
+	enum i40e_status_code status = I40E_SUCCESS;
+
+	RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
+
+	dev = &rte_eth_devices[port];
+
+	if (!is_device_supported(dev, &rte_i40e_pmd))
+		return -ENOTSUP;
+
+	if (size < (I40E_PROFILE_INFO_SIZE * I40E_MAX_PROFILE_NUM + 4))
+		return -EINVAL;
+
+	hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+
+	status = i40e_aq_get_ppp_list(hw, (void *)buff,
+				      size, 0, NULL);
+
+	return status;
+}
diff --git a/drivers/net/i40e/rte_pmd_i40e.h b/drivers/net/i40e/rte_pmd_i40e.h
index 4f6cdb5..d157a49 100644
--- a/drivers/net/i40e/rte_pmd_i40e.h
+++ b/drivers/net/i40e/rte_pmd_i40e.h
@@ -383,4 +383,16 @@ int rte_pmd_i40e_reset_vf_stats(uint8_t port,
 int rte_pmd_i40e_process_ppp_package(uint8_t port, uint8_t *buff,
 				     uint32_t size, bool add);
 
+/**
+ * rte_pmd_i40e_get_ppp_list - Get loaded profile list
+ * @port: port id
+ * @buff: buffer for response
+ * @size: buffer size
+ * @return
+ *   - (0) if successful.
+ *   - (-ENODEV) if *port* invalid.
+ *   - (-EINVAL) if bad parameter.
+ */
+int rte_pmd_i40e_get_ppp_list(uint8_t port, uint8_t *buff, uint32_t size);
+
 #endif /* _PMD_I40E_H_ */
diff --git a/drivers/net/i40e/rte_pmd_i40e_version.map b/drivers/net/i40e/rte_pmd_i40e_version.map
index 01c4a90..9808893 100644
--- a/drivers/net/i40e/rte_pmd_i40e_version.map
+++ b/drivers/net/i40e/rte_pmd_i40e_version.map
@@ -27,4 +27,5 @@ DPDK_17.05 {
 	global:
 
 	rte_pmd_i40e_process_ppp_package;
+	rte_pmd_i40e_get_ppp_list;
 };
-- 
2.5.5

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

* [PATCH v4 4/5] app/testpmd: add command for getting loaded profiles
  2017-03-24 10:19       ` [PATCH v4 0/5] pipeline personalization profile support Beilei Xing
                           ` (2 preceding siblings ...)
  2017-03-24 10:19         ` [PATCH v4 3/5] net/i40e: add get all loaded profiles Beilei Xing
@ 2017-03-24 10:19         ` Beilei Xing
  2017-03-24 10:19         ` [PATCH v4 5/5] doc: add pipeline personalization profile support for i40e Beilei Xing
  2017-03-27  6:17         ` [PATCH v5 0/5] pipeline personalization profile support Beilei Xing
  5 siblings, 0 replies; 82+ messages in thread
From: Beilei Xing @ 2017-03-24 10:19 UTC (permalink / raw)
  To: jingjing.wu; +Cc: helin.zhang, dev

This patch is to add testpmd CLI for getting all loaded profiles.

Signed-off-by: Beilei Xing <beilei.xing@intel.com>
---
 app/test-pmd/cmdline.c | 91 ++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 91 insertions(+)

diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
index 86177fb..7dafff3 100644
--- a/app/test-pmd/cmdline.c
+++ b/app/test-pmd/cmdline.c
@@ -215,6 +215,9 @@ static void cmd_help_long_parsed(void *parsed_result,
 
 			"read txd (port_id) (queue_id) (txd_id)\n"
 			"    Display a TX descriptor of a port TX queue.\n\n"
+
+			"get ppp list (port_id)\n"
+			"    Get ppp profile info list\n\n"
 		);
 	}
 
@@ -12474,6 +12477,93 @@ cmdline_parse_inst_t cmd_add_ppp = {
 	},
 };
 
+/* Get Pipeline Personalization Profile list*/
+#define PROFILE_INFO_SIZE 48
+#define MAX_PROFILE_NUM 16
+
+struct cmd_get_ppp_list_result {
+	cmdline_fixed_string_t get;
+	cmdline_fixed_string_t ppp;
+	cmdline_fixed_string_t list;
+	uint8_t port_id;
+};
+
+cmdline_parse_token_string_t cmd_get_ppp_list_get =
+	TOKEN_STRING_INITIALIZER(struct cmd_get_ppp_list_result, get, "get");
+cmdline_parse_token_string_t cmd_get_ppp_list_ppp =
+	TOKEN_STRING_INITIALIZER(struct cmd_get_ppp_list_result, ppp, "ppp");
+cmdline_parse_token_string_t cmd_get_ppp_list_list =
+	TOKEN_STRING_INITIALIZER(struct cmd_get_ppp_list_result, list, "list");
+cmdline_parse_token_num_t cmd_get_ppp_list_port_id =
+	TOKEN_NUM_INITIALIZER(struct cmd_get_ppp_list_result, port_id, UINT8);
+
+static void
+cmd_get_ppp_list_parsed(
+	void *parsed_result,
+	__attribute__((unused)) struct cmdline *cl,
+	__attribute__((unused)) void *data)
+{
+	struct cmd_get_ppp_list_result *res = parsed_result;
+#ifdef RTE_LIBRTE_I40E_PMD
+	struct rte_pmd_i40e_profile_list *p_list;
+	struct rte_pmd_i40e_profile_info *p_info;
+	uint32_t p_num;
+	uint32_t size;
+	uint32_t i;
+#endif
+	int ret = -ENOTSUP;
+
+	if (res->port_id > nb_ports) {
+		printf("Invalid port, range is [0, %d]\n", nb_ports - 1);
+		return;
+	}
+
+#ifdef RTE_LIBRTE_I40E_PMD
+	size = PROFILE_INFO_SIZE * MAX_PROFILE_NUM + 4;
+	p_list = (struct rte_pmd_i40e_profile_list *)malloc(size);
+	if (!p_list)
+		printf("%s: Failed to malloc buffer\n", __func__);
+
+	if (ret == -ENOTSUP)
+		ret = rte_pmd_i40e_get_ppp_list(res->port_id,
+						(uint8_t *)p_list, size);
+
+	if (!ret) {
+		p_num = p_list->p_count;
+		printf("Profile number is: %d\n\n", p_num);
+
+		for (i = 0; i < p_num; i++) {
+			p_info = &p_list->p_info[i];
+			printf("Profile %d:\n", i);
+			printf("Track id:     0x%x\n", p_info->track_id);
+			printf("Version:      %d.%d.%d.%d \n",
+			       p_info->version.major,
+			       p_info->version.minor,
+			       p_info->version.update,
+			       p_info->version.draft);
+			printf("Profile name: %s\n\n", p_info->name);
+		}
+	}
+
+	free(p_list);
+#endif
+
+	if (ret < 0)
+		printf("Failed to get ppp list\n");
+}
+
+cmdline_parse_inst_t cmd_get_ppp_list = {
+	.f = cmd_get_ppp_list_parsed,
+	.data = NULL,
+	.help_str = "get ppp list <port_id>",
+	.tokens = {
+		(void *)&cmd_get_ppp_list_get,
+		(void *)&cmd_get_ppp_list_ppp,
+		(void *)&cmd_get_ppp_list_list,
+		(void *)&cmd_get_ppp_list_port_id,
+		NULL,
+	},
+};
 /* ******************************************************************************** */
 
 /* list of instructions */
@@ -12650,6 +12740,7 @@ cmdline_parse_ctx_t main_ctx[] = {
 	(cmdline_parse_inst_t *)&cmd_set_vf_broadcast,
 	(cmdline_parse_inst_t *)&cmd_set_vf_vlan_tag,
 	(cmdline_parse_inst_t *)&cmd_add_ppp,
+	(cmdline_parse_inst_t *)&cmd_get_ppp_list,
 	NULL,
 };
 
-- 
2.5.5

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

* [PATCH v4 5/5] doc: add pipeline personalization profile support for i40e
  2017-03-24 10:19       ` [PATCH v4 0/5] pipeline personalization profile support Beilei Xing
                           ` (3 preceding siblings ...)
  2017-03-24 10:19         ` [PATCH v4 4/5] app/testpmd: add command for getting " Beilei Xing
@ 2017-03-24 10:19         ` Beilei Xing
  2017-03-24 14:31           ` Mcnamara, John
  2017-03-27  6:17         ` [PATCH v5 0/5] pipeline personalization profile support Beilei Xing
  5 siblings, 1 reply; 82+ messages in thread
From: Beilei Xing @ 2017-03-24 10:19 UTC (permalink / raw)
  To: jingjing.wu; +Cc: helin.zhang, dev

Signed-off-by: Beilei Xing <beilei.xing@intel.com>
---
 doc/guides/rel_notes/release_17_05.rst | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/doc/guides/rel_notes/release_17_05.rst b/doc/guides/rel_notes/release_17_05.rst
index 3e48224..f17e03b 100644
--- a/doc/guides/rel_notes/release_17_05.rst
+++ b/doc/guides/rel_notes/release_17_05.rst
@@ -85,6 +85,10 @@ New Features
   Data Ring, ability to register memory regions.
 
 
+* **Added pipeline personalization profile support for i40e.**
+
+  * Added loading pipeline personalization profile to i40e FW.
+
 Resolved Issues
 ---------------
 
-- 
2.5.5

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

* Re: [PATCH v4 5/5] doc: add pipeline personalization profile support for i40e
  2017-03-24 10:19         ` [PATCH v4 5/5] doc: add pipeline personalization profile support for i40e Beilei Xing
@ 2017-03-24 14:31           ` Mcnamara, John
  0 siblings, 0 replies; 82+ messages in thread
From: Mcnamara, John @ 2017-03-24 14:31 UTC (permalink / raw)
  To: Xing, Beilei, Wu, Jingjing; +Cc: Zhang, Helin, dev



> -----Original Message-----
> From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Beilei Xing
> Sent: Friday, March 24, 2017 10:19 AM
> To: Wu, Jingjing <jingjing.wu@intel.com>
> Cc: Zhang, Helin <helin.zhang@intel.com>; dev@dpdk.org
> Subject: [dpdk-dev] [PATCH v4 5/5] doc: add pipeline personalization
> profile support for i40e
> 
> Signed-off-by: Beilei Xing <beilei.xing@intel.com>

Acked-by: John McNamara <john.mcnamara@intel.com>

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

* Re: [PATCH v4 1/5] net/i40e: add pipeline personalization profile processing
  2017-03-24 10:19         ` [PATCH v4 1/5] net/i40e: add pipeline personalization profile processing Beilei Xing
@ 2017-03-24 14:52           ` Chilikin, Andrey
  2017-03-25  4:04             ` Xing, Beilei
  0 siblings, 1 reply; 82+ messages in thread
From: Chilikin, Andrey @ 2017-03-24 14:52 UTC (permalink / raw)
  To: Xing, Beilei, Wu, Jingjing; +Cc: Zhang, Helin, dev

Hi Beilei,

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

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

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

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

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

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

Regards,
Andrey

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

* Re: [PATCH v4 1/5] net/i40e: add pipeline personalization profile processing
  2017-03-24 14:52           ` Chilikin, Andrey
@ 2017-03-25  4:04             ` Xing, Beilei
  2017-03-25 21:03               ` Chilikin, Andrey
  0 siblings, 1 reply; 82+ messages in thread
From: Xing, Beilei @ 2017-03-25  4:04 UTC (permalink / raw)
  To: Chilikin, Andrey, Wu, Jingjing; +Cc: Zhang, Helin, dev

Hi Andrey,

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

Thanks for your comments, I considered your suggestion before, but it's a private API for user, I think there's only "add" and "remove" for users, user shouldn't want to know if the profile needs to be updated in the info list. So I think the first and the third items above should be distinguished by driver instead of application. Driver can distinguish them when driver parses the package by checking if track_id is 0.
What do you think?

In my opinion, the first item means add a profile, the second item means remove a profile, the third means add a read-only profile. Please correct me if I'm wrong. In fact we only support the first in this release, the second and third items above need to be supported after this release.

Beilei

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

Actually I define this for getting profile info but not updating profile info, so I thought there won't be "owner = REMOVE" in info list. please correct me if I'm wrong. In base driver, there's "struct i40e_profile_info " used for updating profile info. 
All the structures defined in "rte_pmd_i40e.h" are used for getting info by application.
Do you think "owner" member is used for user? If yes, I will update it. If no, I think user will be confused by "owner".

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

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

* Re: [PATCH v4 1/5] net/i40e: add pipeline personalization profile processing
  2017-03-25  4:04             ` Xing, Beilei
@ 2017-03-25 21:03               ` Chilikin, Andrey
  2017-03-27  2:09                 ` Xing, Beilei
  0 siblings, 1 reply; 82+ messages in thread
From: Chilikin, Andrey @ 2017-03-25 21:03 UTC (permalink / raw)
  To: Xing, Beilei, Wu, Jingjing; +Cc: Zhang, Helin, dev

Hi Beilei

> -----Original Message-----
> From: Xing, Beilei
> Sent: Saturday, March 25, 2017 4:04 AM
> To: Chilikin, Andrey <andrey.chilikin@intel.com>; Wu, Jingjing
> <jingjing.wu@intel.com>
> Cc: Zhang, Helin <helin.zhang@intel.com>; dev@dpdk.org
> Subject: RE: [dpdk-dev] [PATCH v4 1/5] net/i40e: add pipeline personalization
> profile processing
> 
> Hi Andrey,
> 
> > -----Original Message-----
> > From: Chilikin, Andrey
> > Sent: Friday, March 24, 2017 10:53 PM
> > To: Xing, Beilei <beilei.xing@intel.com>; Wu, Jingjing
> > <jingjing.wu@intel.com>
> > Cc: Zhang, Helin <helin.zhang@intel.com>; dev@dpdk.org
> > Subject: RE: [dpdk-dev] [PATCH v4 1/5] net/i40e: add pipeline
> > personalization profile processing
> >
> > Hi Beilei,
> >
> > > -----Original Message-----
> > > From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Beilei Xing
> > > Sent: Friday, March 24, 2017 10:19 AM
> > > To: Wu, Jingjing <jingjing.wu@intel.com>
> > > Cc: Zhang, Helin <helin.zhang@intel.com>; dev@dpdk.org
> > > Subject: [dpdk-dev] [PATCH v4 1/5] net/i40e: add pipeline
> > > personalization profile processing
> > >
> > > Add support for adding a pipeline personalization profile package.
> > >
> > > Signed-off-by: Beilei Xing <beilei.xing@intel.com>
> > > ---
> > >  app/test-pmd/cmdline.c                    |   1 +
> > >  drivers/net/i40e/i40e_ethdev.c            | 198
> > > ++++++++++++++++++++++++++++++
> > >  drivers/net/i40e/rte_pmd_i40e.h           |  51 ++++++++
> > >  drivers/net/i40e/rte_pmd_i40e_version.map |   6 +
> > >  4 files changed, 256 insertions(+)
> > >
> > > diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c index
> > > 47f935d..6e0625d 100644
> > > --- a/app/test-pmd/cmdline.c
> > > +++ b/app/test-pmd/cmdline.c
> > > @@ -37,6 +37,7 @@
> > >  #include <stdio.h>
> > >  #include <stdint.h>
> > >  #include <stdarg.h>
> > > +#include <stdbool.h>
> > >  #include <string.h>
> > >  #include <termios.h>
> > >  #include <unistd.h>
> > > diff --git a/drivers/net/i40e/i40e_ethdev.c
> > > b/drivers/net/i40e/i40e_ethdev.c index 3702214..bea593f 100644
> > > --- a/drivers/net/i40e/i40e_ethdev.c
> > > +++ b/drivers/net/i40e/i40e_ethdev.c
> > > @@ -11259,3 +11259,201 @@ rte_pmd_i40e_reset_vf_stats(uint8_t
> > port,
> > >
> > >  	return 0;
> > >  }
> > > +
> > > +static void
> > > +i40e_generate_profile_info_sec(char *name, struct i40e_ppp_version
> > > *version,
> > > +			       uint32_t track_id, uint8_t *profile_info_sec,
> > > +			       bool add)
> > > +{
> > > +	struct i40e_profile_section_header *sec = NULL;
> > > +	struct i40e_profile_info *pinfo;
> > > +
> > > +	sec = (struct i40e_profile_section_header *)profile_info_sec;
> > > +	sec->tbl_size = 1;
> > > +	sec->data_end = sizeof(struct i40e_profile_section_header) +
> > > +		sizeof(struct i40e_profile_info);
> > > +	sec->section.type = SECTION_TYPE_INFO;
> > > +	sec->section.offset = sizeof(struct i40e_profile_section_header);
> > > +	sec->section.size = sizeof(struct i40e_profile_info);
> > > +	pinfo = (struct i40e_profile_info *)(profile_info_sec +
> > > +					     sec->section.offset);
> > > +	pinfo->track_id = track_id;
> > > +	memcpy(pinfo->name, name, I40E_PPP_NAME_SIZE);
> > > +	memcpy(&pinfo->version, version, sizeof(struct i40e_ppp_version));
> > > +	if (add)
> > > +		pinfo->op = I40E_PPP_ADD_TRACKID;
> > > +	else
> > > +		pinfo->op = I40E_PPP_REMOVE_TRACKID; }
> > > +
> > > +static enum i40e_status_code
> > > +i40e_add_rm_profile_info(struct i40e_hw *hw, uint8_t
> > > +*profile_info_sec) {
> > > +	enum i40e_status_code status = I40E_SUCCESS;
> > > +	struct i40e_profile_section_header *sec;
> > > +	uint32_t track_id;
> > > +	uint32_t offset = 0, info = 0;
> > > +
> > > +	sec = (struct i40e_profile_section_header *)profile_info_sec;
> > > +	track_id = ((struct i40e_profile_info *)(profile_info_sec +
> > > +					 sec->section.offset))->track_id;
> > > +
> > > +	status = i40e_aq_write_ppp(hw, (void *)sec, sec->data_end,
> > > +				   track_id, &offset, &info, NULL);
> > > +	if (status)
> > > +		PMD_DRV_LOG(ERR, "Failed to add/remove profile info: "
> > > +			    "offset %d, info %d",
> > > +			    offset, info);
> > > +
> > > +	return status;
> > > +}
> > > +
> > > +#define I40E_PROFILE_INFO_SIZE 48
> > > +#define I40E_MAX_PROFILE_NUM 16
> > > +
> > > +/* Check if the profile info exists */ static int
> > > +i40e_check_profile_info(uint8_t port, uint8_t *profile_info_sec) {
> > > +	struct rte_eth_dev *dev = &rte_eth_devices[port];
> > > +	struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data-
> > > >dev_private);
> > > +	uint8_t *buff;
> > > +	struct rte_pmd_i40e_profile_list *p_list;
> > > +	struct rte_pmd_i40e_profile_info *pinfo, *p;
> > > +	uint32_t i;
> > > +	int ret;
> > > +
> > > +	buff = rte_zmalloc("pinfo_list",
> > > +			   (I40E_PROFILE_INFO_SIZE *
> > > I40E_MAX_PROFILE_NUM + 4),
> > > +			   0);
> > > +	if (!buff) {
> > > +		PMD_DRV_LOG(ERR, "failed to allocate memory");
> > > +		return -1;
> > > +	}
> > > +
> > > +	ret = i40e_aq_get_ppp_list(hw, (void *)buff,
> > > +		      (I40E_PROFILE_INFO_SIZE * I40E_MAX_PROFILE_NUM +
> > > 4),
> > > +		      0, NULL);
> > > +	if (ret) {
> > > +		PMD_DRV_LOG(ERR, "Failed to get profile info list.");
> > > +		rte_free(buff);
> > > +		return -1;
> > > +	}
> > > +	p_list = (struct rte_pmd_i40e_profile_list *)buff;
> > > +	pinfo = (struct rte_pmd_i40e_profile_info *)(profile_info_sec +
> > > +			     sizeof(struct i40e_profile_section_header));
> > > +	for (i = 0; i < p_list->p_count; i++) {
> > > +		p = &p_list->p_info[i];
> > > +		if ((pinfo->track_id == p->track_id) &&
> > > +		    !memcmp(&pinfo->version, &p->version,
> > > +			    sizeof(struct i40e_ppp_version)) &&
> > > +		    !memcmp(&pinfo->name, &p->name,
> > > +			    I40E_PPP_NAME_SIZE)) {
> > > +			PMD_DRV_LOG(INFO, "Profile exists.");
> > > +			rte_free(buff);
> > > +			return 1;
> > > +		}
> > > +	}
> > > +
> > > +	rte_free(buff);
> > > +	return 0;
> > > +}
> > > +
> > > +int
> > > +rte_pmd_i40e_process_ppp_package(uint8_t port, uint8_t *buff,
> > > +				 uint32_t size, bool add)
> >
> > To make this function future-proof it is better not to use 'bool add'
> > as there are at least three possible processing actions:
> >
> > 1. Process package and add it to the list of applied profiles
> > (applying new
> > personalization) 2. Process package and remove it from the list
> > (restoring original configuration) 3. Process package and to not
> > update the list (update already applied personalization)
> 
> Thanks for your comments, I considered your suggestion before, but it's a
> private API for user, I think there's only "add" and "remove" for users, user
> shouldn't want to know if the profile needs to be updated in the info list. So I
> think the first and the third items above should be distinguished by driver
> instead of application. Driver can distinguish them when driver parses the
> package by checking if track_id is 0.
> What do you think?
> 
> In my opinion, the first item means add a profile, the second item means
> remove a profile, the third means add a read-only profile. Please correct me if
> I'm wrong. In fact we only support the first in this release, the second and third
> items above need to be supported after this release.

You already have "Action not supported temporarily" message now, so it will not break anything but will save users updating their apps ABI in future.
In addition to read-only profiles, option 3 can be used for profiles which call generic admin commands, and only first call is needed to be registered. In this case TrackId will not be 0 and driver cannot used it directly.
This is very minor change and do not see why not declare parameters properly from the first release if support for all three options is needed anyway.
> 
> Beilei
> 
> >
> > > +{
> > > +	struct rte_eth_dev *dev;
> > > +	struct i40e_hw *hw;
> > > +	struct i40e_package_header *pkg_hdr;
> > > +	struct i40e_generic_seg_header *profile_seg_hdr;
> > > +	struct i40e_generic_seg_header *metadata_seg_hdr;
> > > +	uint32_t track_id;
> > > +	uint8_t *profile_info_sec;
> > > +	int is_exist;
> > > +	enum i40e_status_code status = I40E_SUCCESS;
> > > +
> > > +	RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
> > > +
> > > +	dev = &rte_eth_devices[port];
> > > +
> > > +	if (!is_device_supported(dev, &rte_i40e_pmd))
> > > +		return -ENOTSUP;
> > > +
> > > +	hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
> > > +
> > > +	if (size < (sizeof(struct i40e_package_header) +
> > > +		    sizeof(struct i40e_metadata_segment) +
> > > +		    sizeof(uint32_t) * 2)) {
> > > +		PMD_DRV_LOG(ERR, "Buff is invalid.");
> > > +		return -EINVAL;
> > > +	}
> > > +
> > > +	pkg_hdr = (struct i40e_package_header *)buff;
> > > +
> > > +	if (!pkg_hdr) {
> > > +		PMD_DRV_LOG(ERR, "Failed to fill the package structure");
> > > +		return -EINVAL;
> > > +	}
> > > +
> > > +	if (pkg_hdr->segment_count < 2) {
> > > +		PMD_DRV_LOG(ERR, "Segment_count should be 2 at least.");
> > > +		return -EINVAL;
> > > +	}
> > > +
> > > +	/* Find metadata segment */
> > > +	metadata_seg_hdr =
> > > i40e_find_segment_in_package(SEGMENT_TYPE_METADATA,
> > > +							pkg_hdr);
> > > +	if (!metadata_seg_hdr) {
> > > +		PMD_DRV_LOG(ERR, "Failed to find metadata segment
> > > header");
> > > +		return -EINVAL;
> > > +	}
> > > +	track_id = ((struct i40e_metadata_segment
> > > +*)metadata_seg_hdr)->track_id;
> > > +
> > > +	/* Find profile segment */
> > > +	profile_seg_hdr =
> > > i40e_find_segment_in_package(SEGMENT_TYPE_I40E,
> > > +						       pkg_hdr);
> > > +	if (!profile_seg_hdr) {
> > > +		PMD_DRV_LOG(ERR, "Failed to find profile segment header");
> > > +		return -EINVAL;
> > > +	}
> > > +
> > > +	profile_info_sec = rte_zmalloc("i40e_profile_info",
> > > +			       sizeof(struct i40e_profile_section_header) +
> > > +			       sizeof(struct i40e_profile_info),
> > > +			       0);
> > > +	if (!profile_info_sec) {
> > > +		PMD_DRV_LOG(ERR, "Failed to allocate memory");
> > > +		return -EINVAL;
> > > +	}
> > > +
> > > +	if (add) {
> > > +		/* Check if the profile exists */
> > > +		i40e_generate_profile_info_sec(
> > > +		     ((struct i40e_profile_segment *)profile_seg_hdr)->name,
> > > +		     &((struct i40e_profile_segment *)profile_seg_hdr)-
> > > >version,
> > > +		     track_id, profile_info_sec, 1);
> > > +		is_exist = i40e_check_profile_info(port, profile_info_sec);
> > > +		if (is_exist) {
> > > +			PMD_DRV_LOG(ERR, "Profile already exists.");
> > > +			rte_free(profile_info_sec);
> > > +			return 1;
> > > +		}
> > > +
> > > +		/* Write profile to HW */
> > > +		status = i40e_write_profile(hw,
> > > +				 (struct i40e_profile_segment
> > > *)profile_seg_hdr,
> > > +				 track_id);
> > > +		if (status)
> > > +			PMD_DRV_LOG(ERR, "Failed to write profile.");
> > > +
> > > +		/* Add profile info to info list */
> > > +		status = i40e_add_rm_profile_info(hw, profile_info_sec);
> > > +		if (status)
> > > +			PMD_DRV_LOG(ERR, "Failed to add profile info.");
> > > +	} else
> > > +		PMD_DRV_LOG(ERR, "Action not supported temporarily.");
> > > +
> > > +	rte_free(profile_info_sec);
> > > +	return status;
> > > +}
> > > diff --git a/drivers/net/i40e/rte_pmd_i40e.h
> > > b/drivers/net/i40e/rte_pmd_i40e.h index a0ad88c..4f6cdb5 100644
> > > --- a/drivers/net/i40e/rte_pmd_i40e.h
> > > +++ b/drivers/net/i40e/rte_pmd_i40e.h
> > > @@ -65,6 +65,36 @@ struct rte_pmd_i40e_mb_event_param {
> > >  	uint16_t msglen;   /**< length of the message */
> > >  };
> > >
> > > +#define RTE_PMD_I40E_PPP_NAME_SIZE 32
> > > +
> > > +/**
> > > + * Pipeline personalization profile version  */ struct
> > > +rte_pmd_i40e_ppp_version {
> > > +	uint8_t major;
> > > +	uint8_t minor;
> > > +	uint8_t update;
> > > +	uint8_t draft;
> > > +};
> > > +
> > > +/**
> > > + * Structure of profile information  */ struct
> > > +rte_pmd_i40e_profile_info {
> > > +	uint32_t track_id;
> > > +	struct rte_pmd_i40e_ppp_version version;
> > > +	uint8_t reserved[8];
> >
> > Instead of uint8_t reserved[8] it should be
> >     uint8_t owner;
> >     uint8_t reserved[7];
> 
> Actually I define this for getting profile info but not updating profile info, so I
> thought there won't be "owner = REMOVE" in info list. please correct me if I'm
> wrong. In base driver, there's "struct i40e_profile_info " used for updating
> profile info.
> All the structures defined in "rte_pmd_i40e.h" are used for getting info by
> application.
> Do you think "owner" member is used for user? If yes, I will update it. If no, I
> think user will be confused by "owner".

After calling "get profile info list" 'owner' contains PF function which was used to execute a profile, not 'operation'.

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

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

* Re: [PATCH v4 1/5] net/i40e: add pipeline personalization profile processing
  2017-03-25 21:03               ` Chilikin, Andrey
@ 2017-03-27  2:09                 ` Xing, Beilei
  0 siblings, 0 replies; 82+ messages in thread
From: Xing, Beilei @ 2017-03-27  2:09 UTC (permalink / raw)
  To: Chilikin, Andrey, Wu, Jingjing; +Cc: Zhang, Helin, dev

Hi Andrey,

> -----Original Message-----
> From: Chilikin, Andrey
> Sent: Sunday, March 26, 2017 5:04 AM
> To: Xing, Beilei <beilei.xing@intel.com>; Wu, Jingjing <jingjing.wu@intel.com>
> Cc: Zhang, Helin <helin.zhang@intel.com>; dev@dpdk.org
> Subject: RE: [dpdk-dev] [PATCH v4 1/5] net/i40e: add pipeline
> personalization profile processing
> 
> Hi Beilei
> 
> > -----Original Message-----
> > From: Xing, Beilei
> > Sent: Saturday, March 25, 2017 4:04 AM
> > To: Chilikin, Andrey <andrey.chilikin@intel.com>; Wu, Jingjing
> > <jingjing.wu@intel.com>
> > Cc: Zhang, Helin <helin.zhang@intel.com>; dev@dpdk.org
> > Subject: RE: [dpdk-dev] [PATCH v4 1/5] net/i40e: add pipeline
> > personalization profile processing
> >
> > Hi Andrey,
> >
> > > -----Original Message-----
> > > From: Chilikin, Andrey
> > > Sent: Friday, March 24, 2017 10:53 PM
> > > To: Xing, Beilei <beilei.xing@intel.com>; Wu, Jingjing
> > > <jingjing.wu@intel.com>
> > > Cc: Zhang, Helin <helin.zhang@intel.com>; dev@dpdk.org
> > > Subject: RE: [dpdk-dev] [PATCH v4 1/5] net/i40e: add pipeline
> > > personalization profile processing
> > >
> > > Hi Beilei,
> > >
> > > > -----Original Message-----
> > > > From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Beilei Xing
> > > > Sent: Friday, March 24, 2017 10:19 AM
> > > > To: Wu, Jingjing <jingjing.wu@intel.com>
> > > > Cc: Zhang, Helin <helin.zhang@intel.com>; dev@dpdk.org
> > > > Subject: [dpdk-dev] [PATCH v4 1/5] net/i40e: add pipeline
> > > > personalization profile processing
> > > >
> > > > Add support for adding a pipeline personalization profile package.
> > > >
> > > > Signed-off-by: Beilei Xing <beilei.xing@intel.com>
> > > > ---
> > > >  app/test-pmd/cmdline.c                    |   1 +
> > > >  drivers/net/i40e/i40e_ethdev.c            | 198
> > > > ++++++++++++++++++++++++++++++
> > > >  drivers/net/i40e/rte_pmd_i40e.h           |  51 ++++++++
> > > >  drivers/net/i40e/rte_pmd_i40e_version.map |   6 +
> > > >  4 files changed, 256 insertions(+)
> > > >
> > > > diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c index
> > > > 47f935d..6e0625d 100644
> > > > --- a/app/test-pmd/cmdline.c
> > > > +++ b/app/test-pmd/cmdline.c
> > > > @@ -37,6 +37,7 @@
> > > >  #include <stdio.h>
> > > >  #include <stdint.h>
> > > >  #include <stdarg.h>
> > > > +#include <stdbool.h>
> > > >  #include <string.h>
> > > >  #include <termios.h>
> > > >  #include <unistd.h>
> > > > diff --git a/drivers/net/i40e/i40e_ethdev.c
> > > > b/drivers/net/i40e/i40e_ethdev.c index 3702214..bea593f 100644
> > > > --- a/drivers/net/i40e/i40e_ethdev.c
> > > > +++ b/drivers/net/i40e/i40e_ethdev.c
> > > > @@ -11259,3 +11259,201 @@ rte_pmd_i40e_reset_vf_stats(uint8_t
> > > port,
> > > >
> > > >  	return 0;
> > > >  }
> > > > +
> > > > +static void
> > > > +i40e_generate_profile_info_sec(char *name, struct
> > > > +i40e_ppp_version
> > > > *version,
> > > > +			       uint32_t track_id, uint8_t *profile_info_sec,
> > > > +			       bool add)
> > > > +{
> > > > +	struct i40e_profile_section_header *sec = NULL;
> > > > +	struct i40e_profile_info *pinfo;
> > > > +
> > > > +	sec = (struct i40e_profile_section_header *)profile_info_sec;
> > > > +	sec->tbl_size = 1;
> > > > +	sec->data_end = sizeof(struct i40e_profile_section_header) +
> > > > +		sizeof(struct i40e_profile_info);
> > > > +	sec->section.type = SECTION_TYPE_INFO;
> > > > +	sec->section.offset = sizeof(struct i40e_profile_section_header);
> > > > +	sec->section.size = sizeof(struct i40e_profile_info);
> > > > +	pinfo = (struct i40e_profile_info *)(profile_info_sec +
> > > > +					     sec->section.offset);
> > > > +	pinfo->track_id = track_id;
> > > > +	memcpy(pinfo->name, name, I40E_PPP_NAME_SIZE);
> > > > +	memcpy(&pinfo->version, version, sizeof(struct i40e_ppp_version));
> > > > +	if (add)
> > > > +		pinfo->op = I40E_PPP_ADD_TRACKID;
> > > > +	else
> > > > +		pinfo->op = I40E_PPP_REMOVE_TRACKID; }
> > > > +
> > > > +static enum i40e_status_code
> > > > +i40e_add_rm_profile_info(struct i40e_hw *hw, uint8_t
> > > > +*profile_info_sec) {
> > > > +	enum i40e_status_code status = I40E_SUCCESS;
> > > > +	struct i40e_profile_section_header *sec;
> > > > +	uint32_t track_id;
> > > > +	uint32_t offset = 0, info = 0;
> > > > +
> > > > +	sec = (struct i40e_profile_section_header *)profile_info_sec;
> > > > +	track_id = ((struct i40e_profile_info *)(profile_info_sec +
> > > > +					 sec->section.offset))->track_id;
> > > > +
> > > > +	status = i40e_aq_write_ppp(hw, (void *)sec, sec->data_end,
> > > > +				   track_id, &offset, &info, NULL);
> > > > +	if (status)
> > > > +		PMD_DRV_LOG(ERR, "Failed to add/remove profile info: "
> > > > +			    "offset %d, info %d",
> > > > +			    offset, info);
> > > > +
> > > > +	return status;
> > > > +}
> > > > +
> > > > +#define I40E_PROFILE_INFO_SIZE 48 #define
> I40E_MAX_PROFILE_NUM 16
> > > > +
> > > > +/* Check if the profile info exists */ static int
> > > > +i40e_check_profile_info(uint8_t port, uint8_t *profile_info_sec) {
> > > > +	struct rte_eth_dev *dev = &rte_eth_devices[port];
> > > > +	struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data-
> > > > >dev_private);
> > > > +	uint8_t *buff;
> > > > +	struct rte_pmd_i40e_profile_list *p_list;
> > > > +	struct rte_pmd_i40e_profile_info *pinfo, *p;
> > > > +	uint32_t i;
> > > > +	int ret;
> > > > +
> > > > +	buff = rte_zmalloc("pinfo_list",
> > > > +			   (I40E_PROFILE_INFO_SIZE *
> > > > I40E_MAX_PROFILE_NUM + 4),
> > > > +			   0);
> > > > +	if (!buff) {
> > > > +		PMD_DRV_LOG(ERR, "failed to allocate memory");
> > > > +		return -1;
> > > > +	}
> > > > +
> > > > +	ret = i40e_aq_get_ppp_list(hw, (void *)buff,
> > > > +		      (I40E_PROFILE_INFO_SIZE * I40E_MAX_PROFILE_NUM +
> > > > 4),
> > > > +		      0, NULL);
> > > > +	if (ret) {
> > > > +		PMD_DRV_LOG(ERR, "Failed to get profile info list.");
> > > > +		rte_free(buff);
> > > > +		return -1;
> > > > +	}
> > > > +	p_list = (struct rte_pmd_i40e_profile_list *)buff;
> > > > +	pinfo = (struct rte_pmd_i40e_profile_info *)(profile_info_sec +
> > > > +			     sizeof(struct i40e_profile_section_header));
> > > > +	for (i = 0; i < p_list->p_count; i++) {
> > > > +		p = &p_list->p_info[i];
> > > > +		if ((pinfo->track_id == p->track_id) &&
> > > > +		    !memcmp(&pinfo->version, &p->version,
> > > > +			    sizeof(struct i40e_ppp_version)) &&
> > > > +		    !memcmp(&pinfo->name, &p->name,
> > > > +			    I40E_PPP_NAME_SIZE)) {
> > > > +			PMD_DRV_LOG(INFO, "Profile exists.");
> > > > +			rte_free(buff);
> > > > +			return 1;
> > > > +		}
> > > > +	}
> > > > +
> > > > +	rte_free(buff);
> > > > +	return 0;
> > > > +}
> > > > +
> > > > +int
> > > > +rte_pmd_i40e_process_ppp_package(uint8_t port, uint8_t *buff,
> > > > +				 uint32_t size, bool add)
> > >
> > > To make this function future-proof it is better not to use 'bool add'
> > > as there are at least three possible processing actions:
> > >
> > > 1. Process package and add it to the list of applied profiles
> > > (applying new
> > > personalization) 2. Process package and remove it from the list
> > > (restoring original configuration) 3. Process package and to not
> > > update the list (update already applied personalization)
> >
> > Thanks for your comments, I considered your suggestion before, but
> > it's a private API for user, I think there's only "add" and "remove"
> > for users, user shouldn't want to know if the profile needs to be
> > updated in the info list. So I think the first and the third items
> > above should be distinguished by driver instead of application. Driver
> > can distinguish them when driver parses the package by checking if track_id
> is 0.
> > What do you think?
> >
> > In my opinion, the first item means add a profile, the second item
> > means remove a profile, the third means add a read-only profile.
> > Please correct me if I'm wrong. In fact we only support the first in
> > this release, the second and third items above need to be supported after
> this release.
> 
> You already have "Action not supported temporarily" message now, so it will
> not break anything but will save users updating their apps ABI in future.
> In addition to read-only profiles, option 3 can be used for profiles which call
> generic admin commands, and only first call is needed to be registered. In
> this case TrackId will not be 0 and driver cannot used it directly.
> This is very minor change and do not see why not declare parameters
> properly from the first release if support for all three options is needed
> anyway.

OK, misunderstood for option 3, I thought there was only different track_id between option 1 and option 3.
Will update in next version, thanks for explanation.

> >
> > Beilei
> >
> > >
> > > > +{
> > > > +	struct rte_eth_dev *dev;
> > > > +	struct i40e_hw *hw;
> > > > +	struct i40e_package_header *pkg_hdr;
> > > > +	struct i40e_generic_seg_header *profile_seg_hdr;
> > > > +	struct i40e_generic_seg_header *metadata_seg_hdr;
> > > > +	uint32_t track_id;
> > > > +	uint8_t *profile_info_sec;
> > > > +	int is_exist;
> > > > +	enum i40e_status_code status = I40E_SUCCESS;
> > > > +
> > > > +	RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
> > > > +
> > > > +	dev = &rte_eth_devices[port];
> > > > +
> > > > +	if (!is_device_supported(dev, &rte_i40e_pmd))
> > > > +		return -ENOTSUP;
> > > > +
> > > > +	hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
> > > > +
> > > > +	if (size < (sizeof(struct i40e_package_header) +
> > > > +		    sizeof(struct i40e_metadata_segment) +
> > > > +		    sizeof(uint32_t) * 2)) {
> > > > +		PMD_DRV_LOG(ERR, "Buff is invalid.");
> > > > +		return -EINVAL;
> > > > +	}
> > > > +
> > > > +	pkg_hdr = (struct i40e_package_header *)buff;
> > > > +
> > > > +	if (!pkg_hdr) {
> > > > +		PMD_DRV_LOG(ERR, "Failed to fill the package structure");
> > > > +		return -EINVAL;
> > > > +	}
> > > > +
> > > > +	if (pkg_hdr->segment_count < 2) {
> > > > +		PMD_DRV_LOG(ERR, "Segment_count should be 2 at least.");
> > > > +		return -EINVAL;
> > > > +	}
> > > > +
> > > > +	/* Find metadata segment */
> > > > +	metadata_seg_hdr =
> > > > i40e_find_segment_in_package(SEGMENT_TYPE_METADATA,
> > > > +							pkg_hdr);
> > > > +	if (!metadata_seg_hdr) {
> > > > +		PMD_DRV_LOG(ERR, "Failed to find metadata segment
> > > > header");
> > > > +		return -EINVAL;
> > > > +	}
> > > > +	track_id = ((struct i40e_metadata_segment
> > > > +*)metadata_seg_hdr)->track_id;
> > > > +
> > > > +	/* Find profile segment */
> > > > +	profile_seg_hdr =
> > > > i40e_find_segment_in_package(SEGMENT_TYPE_I40E,
> > > > +						       pkg_hdr);
> > > > +	if (!profile_seg_hdr) {
> > > > +		PMD_DRV_LOG(ERR, "Failed to find profile segment
> header");
> > > > +		return -EINVAL;
> > > > +	}
> > > > +
> > > > +	profile_info_sec = rte_zmalloc("i40e_profile_info",
> > > > +			       sizeof(struct i40e_profile_section_header) +
> > > > +			       sizeof(struct i40e_profile_info),
> > > > +			       0);
> > > > +	if (!profile_info_sec) {
> > > > +		PMD_DRV_LOG(ERR, "Failed to allocate memory");
> > > > +		return -EINVAL;
> > > > +	}
> > > > +
> > > > +	if (add) {
> > > > +		/* Check if the profile exists */
> > > > +		i40e_generate_profile_info_sec(
> > > > +		     ((struct i40e_profile_segment *)profile_seg_hdr)->name,
> > > > +		     &((struct i40e_profile_segment *)profile_seg_hdr)-
> > > > >version,
> > > > +		     track_id, profile_info_sec, 1);
> > > > +		is_exist = i40e_check_profile_info(port, profile_info_sec);
> > > > +		if (is_exist) {
> > > > +			PMD_DRV_LOG(ERR, "Profile already exists.");
> > > > +			rte_free(profile_info_sec);
> > > > +			return 1;
> > > > +		}
> > > > +
> > > > +		/* Write profile to HW */
> > > > +		status = i40e_write_profile(hw,
> > > > +				 (struct i40e_profile_segment
> > > > *)profile_seg_hdr,
> > > > +				 track_id);
> > > > +		if (status)
> > > > +			PMD_DRV_LOG(ERR, "Failed to write profile.");
> > > > +
> > > > +		/* Add profile info to info list */
> > > > +		status = i40e_add_rm_profile_info(hw, profile_info_sec);
> > > > +		if (status)
> > > > +			PMD_DRV_LOG(ERR, "Failed to add profile info.");
> > > > +	} else
> > > > +		PMD_DRV_LOG(ERR, "Action not supported temporarily.");
> > > > +
> > > > +	rte_free(profile_info_sec);
> > > > +	return status;
> > > > +}
> > > > diff --git a/drivers/net/i40e/rte_pmd_i40e.h
> > > > b/drivers/net/i40e/rte_pmd_i40e.h index a0ad88c..4f6cdb5 100644
> > > > --- a/drivers/net/i40e/rte_pmd_i40e.h
> > > > +++ b/drivers/net/i40e/rte_pmd_i40e.h
> > > > @@ -65,6 +65,36 @@ struct rte_pmd_i40e_mb_event_param {
> > > >  	uint16_t msglen;   /**< length of the message */
> > > >  };
> > > >
> > > > +#define RTE_PMD_I40E_PPP_NAME_SIZE 32
> > > > +
> > > > +/**
> > > > + * Pipeline personalization profile version  */ struct
> > > > +rte_pmd_i40e_ppp_version {
> > > > +	uint8_t major;
> > > > +	uint8_t minor;
> > > > +	uint8_t update;
> > > > +	uint8_t draft;
> > > > +};
> > > > +
> > > > +/**
> > > > + * Structure of profile information  */ struct
> > > > +rte_pmd_i40e_profile_info {
> > > > +	uint32_t track_id;
> > > > +	struct rte_pmd_i40e_ppp_version version;
> > > > +	uint8_t reserved[8];
> > >
> > > Instead of uint8_t reserved[8] it should be
> > >     uint8_t owner;
> > >     uint8_t reserved[7];
> >
> > Actually I define this for getting profile info but not updating
> > profile info, so I thought there won't be "owner = REMOVE" in info
> > list. please correct me if I'm wrong. In base driver, there's "struct
> > i40e_profile_info " used for updating profile info.
> > All the structures defined in "rte_pmd_i40e.h" are used for getting
> > info by application.
> > Do you think "owner" member is used for user? If yes, I will update
> > it. If no, I think user will be confused by "owner".
> 
> After calling "get profile info list" 'owner' contains PF function which was
> used to execute a profile, not 'operation'.

OK, will update it.

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

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

* [PATCH v5 0/5] pipeline personalization profile support
  2017-03-24 10:19       ` [PATCH v4 0/5] pipeline personalization profile support Beilei Xing
                           ` (4 preceding siblings ...)
  2017-03-24 10:19         ` [PATCH v4 5/5] doc: add pipeline personalization profile support for i40e Beilei Xing
@ 2017-03-27  6:17         ` Beilei Xing
  2017-03-27  6:17           ` [PATCH v5 1/5] net/i40e: add pipeline personalization profile processing Beilei Xing
                             ` (5 more replies)
  5 siblings, 6 replies; 82+ messages in thread
From: Beilei Xing @ 2017-03-27  6:17 UTC (permalink / raw)
  To: jingjing.wu; +Cc: helin.zhang, dev

Due to limited resources of X*710 (parser and analyzer configuration
tables, number of packet classification types, number of packet types,
filters configuration tables, etc.), it's impossible to simultaneously
support all protocols/filters required for different parts on network.
To enable protocols/filters extensions for X*710, new Admin Command
for loading user defined configurations is added.
PPP is a format of extend configuration for X*710, it allows user to
load user defined configuration to X*710.

List of possible use cases for extended X*710 configuration using
profiles could include following:
Configuring Analyzer/Parser to support new protocols, e.g.
- IP L2TPv3 tunneling protocol
- IPSec ESP/AH protocols
- MPLSoGRE, MPLSoUDP tunnels
- GTP-C/GTP-U tunnels
New PCTYPEs for offloading packet classification to X*710. e.g.
- new IP Protocol in addition to TCP/UDP/SCTP
- new TCP/UDP subtypes, like TCP SYN, TCP FIN
- new PCTYPE for tunneled packets like GTP-C, GTP-U
New PTYPEs for packets identification, e.g.
- MAC, MPLS, IP4, UDP
- MAC, MPLS, MPLS, IP6, TCP
Fixes for NVM configuration, e.g.
- list of enabled stat counters to improve throughput
- parser/analyzer configuration for some corner cases

v5 changes:
 Change parameter of rte_pmd_i40e_process_ppp_package to extend operation.
 Change structure rte_pmd_i40e_profile_info.

v4 changes:
 Fix compile error with gcc version 4.8.4 (Ubuntu 4.8.4-2ubuntu1~14.04.3).
 Move ppp related structures to rte_pmd_i40e.h.
 Not support remove PPP temporarily.

v3 changes:
 Move ppp AQ command code to base code.

Beilei Xing (5):
  net/i40e: add pipeline personalization profile processing
  app/testpmd: add command for loading a profile
  net/i40e: add get all loaded profiles
  app/testpmd: add command for getting loaded profiles
  doc: add pipeline personalization profile support for i40e

 app/test-pmd/cmdline.c                    | 166 ++++++++++++++++++++++
 app/test-pmd/config.c                     |  67 +++++++++
 app/test-pmd/testpmd.h                    |   3 +
 doc/guides/rel_notes/release_17_05.rst    |   4 +
 drivers/net/i40e/i40e_ethdev.c            | 227 ++++++++++++++++++++++++++++++
 drivers/net/i40e/rte_pmd_i40e.h           |  69 +++++++++
 drivers/net/i40e/rte_pmd_i40e_version.map |   7 +
 7 files changed, 543 insertions(+)

-- 
2.5.5

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

* [PATCH v5 1/5] net/i40e: add pipeline personalization profile processing
  2017-03-27  6:17         ` [PATCH v5 0/5] pipeline personalization profile support Beilei Xing
@ 2017-03-27  6:17           ` Beilei Xing
  2017-03-27  6:17           ` [PATCH v5 2/5] app/testpmd: add command for loading a profile Beilei Xing
                             ` (4 subsequent siblings)
  5 siblings, 0 replies; 82+ messages in thread
From: Beilei Xing @ 2017-03-27  6:17 UTC (permalink / raw)
  To: jingjing.wu; +Cc: helin.zhang, dev

Add support for adding a pipeline personalization profile
package.

Signed-off-by: Beilei Xing <beilei.xing@intel.com>
---
 app/test-pmd/cmdline.c                    |   1 +
 drivers/net/i40e/i40e_ethdev.c            | 199 ++++++++++++++++++++++++++++++
 drivers/net/i40e/rte_pmd_i40e.h           |  58 +++++++++
 drivers/net/i40e/rte_pmd_i40e_version.map |   6 +
 4 files changed, 264 insertions(+)

diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
index 47f935d..6e0625d 100644
--- a/app/test-pmd/cmdline.c
+++ b/app/test-pmd/cmdline.c
@@ -37,6 +37,7 @@
 #include <stdio.h>
 #include <stdint.h>
 #include <stdarg.h>
+#include <stdbool.h>
 #include <string.h>
 #include <termios.h>
 #include <unistd.h>
diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index 3702214..4589e98 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -11259,3 +11259,202 @@ rte_pmd_i40e_reset_vf_stats(uint8_t port,
 
 	return 0;
 }
+
+static void
+i40e_generate_profile_info_sec(char *name, struct i40e_ppp_version *version,
+			       uint32_t track_id, uint8_t *profile_info_sec,
+			       bool add)
+{
+	struct i40e_profile_section_header *sec = NULL;
+	struct i40e_profile_info *pinfo;
+
+	sec = (struct i40e_profile_section_header *)profile_info_sec;
+	sec->tbl_size = 1;
+	sec->data_end = sizeof(struct i40e_profile_section_header) +
+		sizeof(struct i40e_profile_info);
+	sec->section.type = SECTION_TYPE_INFO;
+	sec->section.offset = sizeof(struct i40e_profile_section_header);
+	sec->section.size = sizeof(struct i40e_profile_info);
+	pinfo = (struct i40e_profile_info *)(profile_info_sec +
+					     sec->section.offset);
+	pinfo->track_id = track_id;
+	memcpy(pinfo->name, name, I40E_PPP_NAME_SIZE);
+	memcpy(&pinfo->version, version, sizeof(struct i40e_ppp_version));
+	if (add)
+		pinfo->op = I40E_PPP_ADD_TRACKID;
+	else
+		pinfo->op = I40E_PPP_REMOVE_TRACKID;
+}
+
+static enum i40e_status_code
+i40e_add_rm_profile_info(struct i40e_hw *hw, uint8_t *profile_info_sec)
+{
+	enum i40e_status_code status = I40E_SUCCESS;
+	struct i40e_profile_section_header *sec;
+	uint32_t track_id;
+	uint32_t offset = 0, info = 0;
+
+	sec = (struct i40e_profile_section_header *)profile_info_sec;
+	track_id = ((struct i40e_profile_info *)(profile_info_sec +
+					 sec->section.offset))->track_id;
+
+	status = i40e_aq_write_ppp(hw, (void *)sec, sec->data_end,
+				   track_id, &offset, &info, NULL);
+	if (status)
+		PMD_DRV_LOG(ERR, "Failed to add/remove profile info: "
+			    "offset %d, info %d",
+			    offset, info);
+
+	return status;
+}
+
+#define I40E_PROFILE_INFO_SIZE 48
+#define I40E_MAX_PROFILE_NUM 16
+
+/* Check if the profile info exists */
+static int
+i40e_check_profile_info(uint8_t port, uint8_t *profile_info_sec)
+{
+	struct rte_eth_dev *dev = &rte_eth_devices[port];
+	struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+	uint8_t *buff;
+	struct rte_pmd_i40e_profile_list *p_list;
+	struct rte_pmd_i40e_profile_info *pinfo, *p;
+	uint32_t i;
+	int ret;
+
+	buff = rte_zmalloc("pinfo_list",
+			   (I40E_PROFILE_INFO_SIZE * I40E_MAX_PROFILE_NUM + 4),
+			   0);
+	if (!buff) {
+		PMD_DRV_LOG(ERR, "failed to allocate memory");
+		return -1;
+	}
+
+	ret = i40e_aq_get_ppp_list(hw, (void *)buff,
+		      (I40E_PROFILE_INFO_SIZE * I40E_MAX_PROFILE_NUM + 4),
+		      0, NULL);
+	if (ret) {
+		PMD_DRV_LOG(ERR, "Failed to get profile info list.");
+		rte_free(buff);
+		return -1;
+	}
+	p_list = (struct rte_pmd_i40e_profile_list *)buff;
+	pinfo = (struct rte_pmd_i40e_profile_info *)(profile_info_sec +
+			     sizeof(struct i40e_profile_section_header));
+	for (i = 0; i < p_list->p_count; i++) {
+		p = &p_list->p_info[i];
+		if ((pinfo->track_id == p->track_id) &&
+		    !memcmp(&pinfo->version, &p->version,
+			    sizeof(struct i40e_ppp_version)) &&
+		    !memcmp(&pinfo->name, &p->name,
+			    I40E_PPP_NAME_SIZE)) {
+			PMD_DRV_LOG(INFO, "Profile exists.");
+			rte_free(buff);
+			return 1;
+		}
+	}
+
+	rte_free(buff);
+	return 0;
+}
+
+int
+rte_pmd_i40e_process_ppp_package(uint8_t port, uint8_t *buff,
+				 uint32_t size,
+				 enum rte_pmd_i40e_package_op op)
+{
+	struct rte_eth_dev *dev;
+	struct i40e_hw *hw;
+	struct i40e_package_header *pkg_hdr;
+	struct i40e_generic_seg_header *profile_seg_hdr;
+	struct i40e_generic_seg_header *metadata_seg_hdr;
+	uint32_t track_id;
+	uint8_t *profile_info_sec;
+	int is_exist;
+	enum i40e_status_code status = I40E_SUCCESS;
+
+	RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
+
+	dev = &rte_eth_devices[port];
+
+	if (!is_device_supported(dev, &rte_i40e_pmd))
+		return -ENOTSUP;
+
+	hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+
+	if (size < (sizeof(struct i40e_package_header) +
+		    sizeof(struct i40e_metadata_segment) +
+		    sizeof(uint32_t) * 2)) {
+		PMD_DRV_LOG(ERR, "Buff is invalid.");
+		return -EINVAL;
+	}
+
+	pkg_hdr = (struct i40e_package_header *)buff;
+
+	if (!pkg_hdr) {
+		PMD_DRV_LOG(ERR, "Failed to fill the package structure");
+		return -EINVAL;
+	}
+
+	if (pkg_hdr->segment_count < 2) {
+		PMD_DRV_LOG(ERR, "Segment_count should be 2 at least.");
+		return -EINVAL;
+	}
+
+	/* Find metadata segment */
+	metadata_seg_hdr = i40e_find_segment_in_package(SEGMENT_TYPE_METADATA,
+							pkg_hdr);
+	if (!metadata_seg_hdr) {
+		PMD_DRV_LOG(ERR, "Failed to find metadata segment header");
+		return -EINVAL;
+	}
+	track_id = ((struct i40e_metadata_segment *)metadata_seg_hdr)->track_id;
+
+	/* Find profile segment */
+	profile_seg_hdr = i40e_find_segment_in_package(SEGMENT_TYPE_I40E,
+						       pkg_hdr);
+	if (!profile_seg_hdr) {
+		PMD_DRV_LOG(ERR, "Failed to find profile segment header");
+		return -EINVAL;
+	}
+
+	profile_info_sec = rte_zmalloc("i40e_profile_info",
+			       sizeof(struct i40e_profile_section_header) +
+			       sizeof(struct i40e_profile_info),
+			       0);
+	if (!profile_info_sec) {
+		PMD_DRV_LOG(ERR, "Failed to allocate memory");
+		return -EINVAL;
+	}
+
+	if (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) {
+			PMD_DRV_LOG(ERR, "Profile already exists.");
+			rte_free(profile_info_sec);
+			return 1;
+		}
+
+		/* Write profile to HW */
+		status = i40e_write_profile(hw,
+				 (struct i40e_profile_segment *)profile_seg_hdr,
+				 track_id);
+		if (status)
+			PMD_DRV_LOG(ERR, "Failed to write profile.");
+
+		/* Add profile info to info list */
+		status = i40e_add_rm_profile_info(hw, profile_info_sec);
+		if (status)
+			PMD_DRV_LOG(ERR, "Failed to add profile info.");
+	} else
+		PMD_DRV_LOG(ERR, "Operation not supported.");
+
+	rte_free(profile_info_sec);
+	return status;
+}
diff --git a/drivers/net/i40e/rte_pmd_i40e.h b/drivers/net/i40e/rte_pmd_i40e.h
index a0ad88c..ac7a0e1 100644
--- a/drivers/net/i40e/rte_pmd_i40e.h
+++ b/drivers/net/i40e/rte_pmd_i40e.h
@@ -65,6 +65,43 @@ struct rte_pmd_i40e_mb_event_param {
 	uint16_t msglen;   /**< length of the message */
 };
 
+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_MAX = 32
+};
+
+#define RTE_PMD_I40E_PPP_NAME_SIZE 32
+
+/**
+ * Pipeline personalization profile version
+ */
+struct rte_pmd_i40e_ppp_version {
+	uint8_t major;
+	uint8_t minor;
+	uint8_t update;
+	uint8_t draft;
+};
+
+/**
+ * Structure of profile information
+ */
+struct rte_pmd_i40e_profile_info {
+	uint32_t track_id;
+	struct rte_pmd_i40e_ppp_version version;
+	uint8_t owner;
+	uint8_t reserved[7];
+	uint8_t name[RTE_PMD_I40E_PPP_NAME_SIZE];
+};
+
+/**
+ * Structure of profile information list
+ */
+struct rte_pmd_i40e_profile_list {
+	uint32_t p_count;
+	struct rte_pmd_i40e_profile_info p_info[1];
+};
+
 /**
  * Notify VF when PF link status changes.
  *
@@ -332,4 +369,25 @@ int rte_pmd_i40e_get_vf_stats(uint8_t port,
 int rte_pmd_i40e_reset_vf_stats(uint8_t port,
 				uint16_t vf_id);
 
+/**
+ * Load/Unload a ppp package
+ *
+ * @param port
+ *    The port identifier of the Ethernet device.
+ * @param buff
+ *    buffer of package.
+ * @param size
+ *    size of buffer.
+ * @param op
+ *   Operation of package processing
+ * @return
+ *   - (0) if successful.
+ *   - (-ENODEV) if *port* invalid.
+ *   - (-EINVAL) if bad parameter.
+ *   - (1) if profile exists.
+ */
+int rte_pmd_i40e_process_ppp_package(uint8_t port, uint8_t *buff,
+				     uint32_t size,
+				     enum rte_pmd_i40e_package_op op);
+
 #endif /* _PMD_I40E_H_ */
diff --git a/drivers/net/i40e/rte_pmd_i40e_version.map b/drivers/net/i40e/rte_pmd_i40e_version.map
index 7a5d211..01c4a90 100644
--- a/drivers/net/i40e/rte_pmd_i40e_version.map
+++ b/drivers/net/i40e/rte_pmd_i40e_version.map
@@ -22,3 +22,9 @@ DPDK_17.02 {
 	rte_pmd_i40e_set_vf_vlan_tag;
 
 } DPDK_2.0;
+
+DPDK_17.05 {
+	global:
+
+	rte_pmd_i40e_process_ppp_package;
+};
-- 
2.5.5

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

* [PATCH v5 2/5] app/testpmd: add command for loading a profile
  2017-03-27  6:17         ` [PATCH v5 0/5] pipeline personalization profile support Beilei Xing
  2017-03-27  6:17           ` [PATCH v5 1/5] net/i40e: add pipeline personalization profile processing Beilei Xing
@ 2017-03-27  6:17           ` Beilei Xing
  2017-03-27  6:17           ` [PATCH v5 3/5] net/i40e: add get all loaded profiles Beilei Xing
                             ` (3 subsequent siblings)
  5 siblings, 0 replies; 82+ messages in thread
From: Beilei Xing @ 2017-03-27  6:17 UTC (permalink / raw)
  To: jingjing.wu; +Cc: helin.zhang, dev

This patch is to add testpmd CLI for loading a pipeline
personalization profile.

Signed-off-by: Beilei Xing <beilei.xing@intel.com>
---
 app/test-pmd/cmdline.c | 74 ++++++++++++++++++++++++++++++++++++++++++++++++++
 app/test-pmd/config.c  | 67 +++++++++++++++++++++++++++++++++++++++++++++
 app/test-pmd/testpmd.h |  3 ++
 3 files changed, 144 insertions(+)

diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
index 6e0625d..bb99f85 100644
--- a/app/test-pmd/cmdline.c
+++ b/app/test-pmd/cmdline.c
@@ -579,6 +579,9 @@ 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"
 
+			"add ppp (port_id) (profile_path)\n"
+			"    Load a profile package on a port\n\n"
+
 			, list_pkt_forwarding_modes()
 		);
 	}
@@ -12402,6 +12405,76 @@ cmdline_parse_inst_t cmd_set_vf_vlan_tag = {
 	},
 };
 
+/* Load Pipeline Personalization Profile */
+struct cmd_add_ppp_result {
+	cmdline_fixed_string_t add;
+	cmdline_fixed_string_t ppp;
+	uint8_t port_id;
+	char filepath[];
+};
+
+cmdline_parse_token_string_t cmd_add_ppp_add =
+	TOKEN_STRING_INITIALIZER(struct cmd_add_ppp_result, add, "add");
+cmdline_parse_token_string_t cmd_add_ppp_ppp =
+	TOKEN_STRING_INITIALIZER(struct cmd_add_ppp_result, ppp, "ppp");
+cmdline_parse_token_num_t cmd_add_ppp_port_id =
+	TOKEN_NUM_INITIALIZER(struct cmd_add_ppp_result, port_id, UINT8);
+cmdline_parse_token_string_t cmd_add_ppp_filepath =
+	TOKEN_STRING_INITIALIZER(struct cmd_add_ppp_result, filepath, NULL);
+
+static void
+cmd_add_ppp_parsed(
+	void *parsed_result,
+	__attribute__((unused)) struct cmdline *cl,
+	__attribute__((unused)) void *data)
+{
+	struct cmd_add_ppp_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_ppp_package_file(res->filepath, &size);
+	if (!buff)
+		return;
+
+#ifdef RTE_LIBRTE_I40E_PMD
+	if (ret == -ENOTSUP)
+		ret = rte_pmd_i40e_process_ppp_package(res->port_id,
+					       buff, size,
+					       RTE_PMD_I40E_PKG_OP_WR_ADD);
+#endif
+
+	if (ret < 0)
+		printf("Failed to load profile.\n");
+	else if (ret > 0)
+		printf("Profile has already existed.\n");
+
+	close_ppp_package_file(buff);
+}
+
+cmdline_parse_inst_t cmd_add_ppp = {
+	.f = cmd_add_ppp_parsed,
+	.data = NULL,
+	.help_str = "add/remove ppp <port_id> <profile_path>",
+	.tokens = {
+		(void *)&cmd_add_ppp_add,
+		(void *)&cmd_add_ppp_ppp,
+		(void *)&cmd_add_ppp_port_id,
+		(void *)&cmd_add_ppp_filepath,
+		NULL,
+	},
+};
+
 /* ******************************************************************************** */
 
 /* list of instructions */
@@ -12577,6 +12650,7 @@ cmdline_parse_ctx_t main_ctx[] = {
 	(cmdline_parse_inst_t *)&cmd_set_vf_allmulti,
 	(cmdline_parse_inst_t *)&cmd_set_vf_broadcast,
 	(cmdline_parse_inst_t *)&cmd_set_vf_vlan_tag,
+	(cmdline_parse_inst_t *)&cmd_add_ppp,
 	NULL,
 };
 
diff --git a/app/test-pmd/config.c b/app/test-pmd/config.c
index 80491fc..eb3d572 100644
--- a/app/test-pmd/config.c
+++ b/app/test-pmd/config.c
@@ -3245,3 +3245,70 @@ port_dcb_info_display(uint8_t port_id)
 		printf("\t%4d", dcb_info.tc_queue.tc_txq[0][i].nb_queue);
 	printf("\n");
 }
+
+uint8_t *
+open_ppp_package_file(const char *file_path, uint32_t *size)
+{
+	FILE *fh = fopen(file_path, "rb");
+	uint32_t pkg_size;
+	uint8_t *buf = NULL;
+	int ret = 0;
+
+	if (size)
+		*size = 0;
+
+	if (fh == NULL) {
+		printf("%s: Failed to open %s\n", __func__, file_path);
+		return buf;
+	}
+
+	ret = fseek(fh, 0, SEEK_END);
+	if (ret < 0) {
+		fclose(fh);
+		printf("%s: File operations failed\n", __func__);
+		return buf;
+	}
+
+	pkg_size = ftell(fh);
+
+	buf = (uint8_t *)malloc(pkg_size);
+	if (!buf) {
+		fclose(fh);
+		printf("%s: Failed to malloc memory\n",	__func__);
+		return buf;
+	}
+
+	ret = fseek(fh, 0, SEEK_SET);
+	if (ret < 0) {
+		fclose(fh);
+		printf("%s: File seek operation failed\n", __func__);
+		close_ppp_package_file(buf);
+		return NULL;
+	}
+
+	ret = fread(buf, 1, pkg_size, fh);
+	if (ret < 0) {
+		fclose(fh);
+		printf("%s: File read operation failed\n", __func__);
+		close_ppp_package_file(buf);
+		return NULL;
+	}
+
+	if (size)
+		*size = pkg_size;
+
+	fclose(fh);
+
+	return buf;
+}
+
+int
+close_ppp_package_file(uint8_t *buf)
+{
+	if (buf) {
+		free((void *)buf);
+		return 0;
+	}
+
+	return -1;
+}
diff --git a/app/test-pmd/testpmd.h b/app/test-pmd/testpmd.h
index 8cf2860..6bcd9c4 100644
--- a/app/test-pmd/testpmd.h
+++ b/app/test-pmd/testpmd.h
@@ -622,6 +622,9 @@ void mcast_addr_add(uint8_t port_id, struct ether_addr *mc_addr);
 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_ppp_package_file(const char *file_path, uint32_t *size);
+int close_ppp_package_file(uint8_t *buf);
+
 enum print_warning {
 	ENABLED_WARN = 0,
 	DISABLED_WARN
-- 
2.5.5

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

* [PATCH v5 3/5] net/i40e: add get all loaded profiles
  2017-03-27  6:17         ` [PATCH v5 0/5] pipeline personalization profile support Beilei Xing
  2017-03-27  6:17           ` [PATCH v5 1/5] net/i40e: add pipeline personalization profile processing Beilei Xing
  2017-03-27  6:17           ` [PATCH v5 2/5] app/testpmd: add command for loading a profile Beilei Xing
@ 2017-03-27  6:17           ` Beilei Xing
  2017-03-27  6:17           ` [PATCH v5 4/5] app/testpmd: add command for getting " Beilei Xing
                             ` (2 subsequent siblings)
  5 siblings, 0 replies; 82+ messages in thread
From: Beilei Xing @ 2017-03-27  6:17 UTC (permalink / raw)
  To: jingjing.wu; +Cc: helin.zhang, dev

This patch is to add get all loaded profiles function.

Signed-off-by: Beilei Xing <beilei.xing@intel.com>
---
 drivers/net/i40e/i40e_ethdev.c            | 28 ++++++++++++++++++++++++++++
 drivers/net/i40e/rte_pmd_i40e.h           | 12 ++++++++++++
 drivers/net/i40e/rte_pmd_i40e_version.map |  1 +
 3 files changed, 41 insertions(+)

diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index 4589e98..50a4e01 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -11260,6 +11260,9 @@ rte_pmd_i40e_reset_vf_stats(uint8_t port,
 	return 0;
 }
 
+#define I40E_PROFILE_INFO_SIZE 48
+#define I40E_MAX_PROFILE_NUM 16
+
 static void
 i40e_generate_profile_info_sec(char *name, struct i40e_ppp_version *version,
 			       uint32_t track_id, uint8_t *profile_info_sec,
@@ -11458,3 +11461,28 @@ rte_pmd_i40e_process_ppp_package(uint8_t port, uint8_t *buff,
 	rte_free(profile_info_sec);
 	return status;
 }
+
+int
+rte_pmd_i40e_get_ppp_list(uint8_t port, uint8_t *buff, uint32_t size)
+{
+	struct rte_eth_dev *dev;
+	struct i40e_hw *hw;
+	enum i40e_status_code status = I40E_SUCCESS;
+
+	RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
+
+	dev = &rte_eth_devices[port];
+
+	if (!is_device_supported(dev, &rte_i40e_pmd))
+		return -ENOTSUP;
+
+	if (size < (I40E_PROFILE_INFO_SIZE * I40E_MAX_PROFILE_NUM + 4))
+		return -EINVAL;
+
+	hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+
+	status = i40e_aq_get_ppp_list(hw, (void *)buff,
+				      size, 0, NULL);
+
+	return status;
+}
diff --git a/drivers/net/i40e/rte_pmd_i40e.h b/drivers/net/i40e/rte_pmd_i40e.h
index ac7a0e1..969d465 100644
--- a/drivers/net/i40e/rte_pmd_i40e.h
+++ b/drivers/net/i40e/rte_pmd_i40e.h
@@ -390,4 +390,16 @@ int rte_pmd_i40e_process_ppp_package(uint8_t port, uint8_t *buff,
 				     uint32_t size,
 				     enum rte_pmd_i40e_package_op op);
 
+/**
+ * rte_pmd_i40e_get_ppp_list - Get loaded profile list
+ * @port: port id
+ * @buff: buffer for response
+ * @size: buffer size
+ * @return
+ *   - (0) if successful.
+ *   - (-ENODEV) if *port* invalid.
+ *   - (-EINVAL) if bad parameter.
+ */
+int rte_pmd_i40e_get_ppp_list(uint8_t port, uint8_t *buff, uint32_t size);
+
 #endif /* _PMD_I40E_H_ */
diff --git a/drivers/net/i40e/rte_pmd_i40e_version.map b/drivers/net/i40e/rte_pmd_i40e_version.map
index 01c4a90..9808893 100644
--- a/drivers/net/i40e/rte_pmd_i40e_version.map
+++ b/drivers/net/i40e/rte_pmd_i40e_version.map
@@ -27,4 +27,5 @@ DPDK_17.05 {
 	global:
 
 	rte_pmd_i40e_process_ppp_package;
+	rte_pmd_i40e_get_ppp_list;
 };
-- 
2.5.5

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

* [PATCH v5 4/5] app/testpmd: add command for getting loaded profiles
  2017-03-27  6:17         ` [PATCH v5 0/5] pipeline personalization profile support Beilei Xing
                             ` (2 preceding siblings ...)
  2017-03-27  6:17           ` [PATCH v5 3/5] net/i40e: add get all loaded profiles Beilei Xing
@ 2017-03-27  6:17           ` Beilei Xing
  2017-03-27  6:17           ` [PATCH v5 5/5] doc: add pipeline personalization profile support for i40e Beilei Xing
  2017-03-29 12:26           ` [PATCH v6 0/6] dynamic device profile support Beilei Xing
  5 siblings, 0 replies; 82+ messages in thread
From: Beilei Xing @ 2017-03-27  6:17 UTC (permalink / raw)
  To: jingjing.wu; +Cc: helin.zhang, dev

This patch is to add testpmd CLI for getting all loaded profiles.

Signed-off-by: Beilei Xing <beilei.xing@intel.com>
---
 app/test-pmd/cmdline.c | 91 ++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 91 insertions(+)

diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
index bb99f85..5cddb83 100644
--- a/app/test-pmd/cmdline.c
+++ b/app/test-pmd/cmdline.c
@@ -215,6 +215,9 @@ static void cmd_help_long_parsed(void *parsed_result,
 
 			"read txd (port_id) (queue_id) (txd_id)\n"
 			"    Display a TX descriptor of a port TX queue.\n\n"
+
+			"get ppp list (port_id)\n"
+			"    Get ppp profile info list\n\n"
 		);
 	}
 
@@ -12475,6 +12478,93 @@ cmdline_parse_inst_t cmd_add_ppp = {
 	},
 };
 
+/* Get Pipeline Personalization Profile list*/
+#define PROFILE_INFO_SIZE 48
+#define MAX_PROFILE_NUM 16
+
+struct cmd_get_ppp_list_result {
+	cmdline_fixed_string_t get;
+	cmdline_fixed_string_t ppp;
+	cmdline_fixed_string_t list;
+	uint8_t port_id;
+};
+
+cmdline_parse_token_string_t cmd_get_ppp_list_get =
+	TOKEN_STRING_INITIALIZER(struct cmd_get_ppp_list_result, get, "get");
+cmdline_parse_token_string_t cmd_get_ppp_list_ppp =
+	TOKEN_STRING_INITIALIZER(struct cmd_get_ppp_list_result, ppp, "ppp");
+cmdline_parse_token_string_t cmd_get_ppp_list_list =
+	TOKEN_STRING_INITIALIZER(struct cmd_get_ppp_list_result, list, "list");
+cmdline_parse_token_num_t cmd_get_ppp_list_port_id =
+	TOKEN_NUM_INITIALIZER(struct cmd_get_ppp_list_result, port_id, UINT8);
+
+static void
+cmd_get_ppp_list_parsed(
+	void *parsed_result,
+	__attribute__((unused)) struct cmdline *cl,
+	__attribute__((unused)) void *data)
+{
+	struct cmd_get_ppp_list_result *res = parsed_result;
+#ifdef RTE_LIBRTE_I40E_PMD
+	struct rte_pmd_i40e_profile_list *p_list;
+	struct rte_pmd_i40e_profile_info *p_info;
+	uint32_t p_num;
+	uint32_t size;
+	uint32_t i;
+#endif
+	int ret = -ENOTSUP;
+
+	if (res->port_id > nb_ports) {
+		printf("Invalid port, range is [0, %d]\n", nb_ports - 1);
+		return;
+	}
+
+#ifdef RTE_LIBRTE_I40E_PMD
+	size = PROFILE_INFO_SIZE * MAX_PROFILE_NUM + 4;
+	p_list = (struct rte_pmd_i40e_profile_list *)malloc(size);
+	if (!p_list)
+		printf("%s: Failed to malloc buffer\n", __func__);
+
+	if (ret == -ENOTSUP)
+		ret = rte_pmd_i40e_get_ppp_list(res->port_id,
+						(uint8_t *)p_list, size);
+
+	if (!ret) {
+		p_num = p_list->p_count;
+		printf("Profile number is: %d\n\n", p_num);
+
+		for (i = 0; i < p_num; i++) {
+			p_info = &p_list->p_info[i];
+			printf("Profile %d:\n", i);
+			printf("Track id:     0x%x\n", p_info->track_id);
+			printf("Version:      %d.%d.%d.%d \n",
+			       p_info->version.major,
+			       p_info->version.minor,
+			       p_info->version.update,
+			       p_info->version.draft);
+			printf("Profile name: %s\n\n", p_info->name);
+		}
+	}
+
+	free(p_list);
+#endif
+
+	if (ret < 0)
+		printf("Failed to get ppp list\n");
+}
+
+cmdline_parse_inst_t cmd_get_ppp_list = {
+	.f = cmd_get_ppp_list_parsed,
+	.data = NULL,
+	.help_str = "get ppp list <port_id>",
+	.tokens = {
+		(void *)&cmd_get_ppp_list_get,
+		(void *)&cmd_get_ppp_list_ppp,
+		(void *)&cmd_get_ppp_list_list,
+		(void *)&cmd_get_ppp_list_port_id,
+		NULL,
+	},
+};
 /* ******************************************************************************** */
 
 /* list of instructions */
@@ -12651,6 +12741,7 @@ cmdline_parse_ctx_t main_ctx[] = {
 	(cmdline_parse_inst_t *)&cmd_set_vf_broadcast,
 	(cmdline_parse_inst_t *)&cmd_set_vf_vlan_tag,
 	(cmdline_parse_inst_t *)&cmd_add_ppp,
+	(cmdline_parse_inst_t *)&cmd_get_ppp_list,
 	NULL,
 };
 
-- 
2.5.5

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

* [PATCH v5 5/5] doc: add pipeline personalization profile support for i40e
  2017-03-27  6:17         ` [PATCH v5 0/5] pipeline personalization profile support Beilei Xing
                             ` (3 preceding siblings ...)
  2017-03-27  6:17           ` [PATCH v5 4/5] app/testpmd: add command for getting " Beilei Xing
@ 2017-03-27  6:17           ` Beilei Xing
  2017-03-29 12:26           ` [PATCH v6 0/6] dynamic device profile support Beilei Xing
  5 siblings, 0 replies; 82+ messages in thread
From: Beilei Xing @ 2017-03-27  6:17 UTC (permalink / raw)
  To: jingjing.wu; +Cc: helin.zhang, dev

Signed-off-by: Beilei Xing <beilei.xing@intel.com>
Acked-by: John McNamara <john.mcnamara@intel.com>

---
 doc/guides/rel_notes/release_17_05.rst | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/doc/guides/rel_notes/release_17_05.rst b/doc/guides/rel_notes/release_17_05.rst
index 3e48224..f17e03b 100644
--- a/doc/guides/rel_notes/release_17_05.rst
+++ b/doc/guides/rel_notes/release_17_05.rst
@@ -85,6 +85,10 @@ New Features
   Data Ring, ability to register memory regions.
 
 
+* **Added pipeline personalization profile support for i40e.**
+
+  * Added loading pipeline personalization profile to i40e FW.
+
 Resolved Issues
 ---------------
 
-- 
2.5.5

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

* [PATCH v6 0/6] dynamic device profile support
  2017-03-27  6:17         ` [PATCH v5 0/5] pipeline personalization profile support Beilei Xing
                             ` (4 preceding siblings ...)
  2017-03-27  6:17           ` [PATCH v5 5/5] doc: add pipeline personalization profile support for i40e Beilei Xing
@ 2017-03-29 12:26           ` Beilei Xing
  2017-03-29 12:26             ` [PATCH v6 1/6] net/i40e/base: change ppp to ddp Beilei Xing
                               ` (6 more replies)
  5 siblings, 7 replies; 82+ messages in thread
From: Beilei Xing @ 2017-03-29 12:26 UTC (permalink / raw)
  To: jingjing.wu; +Cc: helin.zhang, bernard.iremonger, dev

Due to limited resources of X*710 (parser and analyzer configuration
tables, number of packet classification types, number of packet types,
filters configuration tables, etc.), it's impossible to simultaneously
support all protocols/filters required for different parts on network.
To enable protocols/filters extensions for X*710, new Admin Command
for loading user defined configurations is added.
PPP is a format of extend configuration for X*710, it allows user to
load user defined configuration to X*710.

List of possible use cases for extended X*710 configuration using
profiles could include following:
Configuring Analyzer/Parser to support new protocols, e.g.
- IP L2TPv3 tunneling protocol
- IPSec ESP/AH protocols
- MPLSoGRE, MPLSoUDP tunnels
- GTP-C/GTP-U tunnels
New PCTYPEs for offloading packet classification to X*710. e.g.
- new IP Protocol in addition to TCP/UDP/SCTP
- new TCP/UDP subtypes, like TCP SYN, TCP FIN
- new PCTYPE for tunneled packets like GTP-C, GTP-U
New PTYPEs for packets identification, e.g.
- MAC, MPLS, IP4, UDP
- MAC, MPLS, MPLS, IP6, TCP
Fixes for NVM configuration, e.g.
- list of enabled stat counters to improve throughput
- parser/analyzer configuration for some corner cases

v6 changes:
 Change pipeline personalization profile to dynamic device profile.

v5 changes:
 Change parameter of rte_pmd_i40e_process_ppp_package to extend operation.
 Change structure rte_pmd_i40e_profile_info.

v4 changes:
 Fix compile error with gcc version 4.8.4 (Ubuntu 4.8.4-2ubuntu1~14.04.3).
 Move ppp related structures to rte_pmd_i40e.h.
 Not support remove PPP temporarily.

v3 changes:
 Move ppp AQ command code to base code.

Beilei Xing (6):
  i40e/base: rename dynamic device profile
  net/i40e: add dynamic device profile processing
  app/testpmd: add command for loading a profile
  net/i40e: add get all loaded profiles
  app/testpmd: add command for getting loaded profiles
  doc: add dynamic device profile support for i40e

 app/test-pmd/cmdline.c                    | 164 +++++++++++++++++++++
 app/test-pmd/config.c                     |  67 +++++++++
 app/test-pmd/testpmd.h                    |   3 +
 doc/guides/rel_notes/release_17_05.rst    |   4 +
 drivers/net/i40e/base/i40e_adminq_cmd.h   |  18 +--
 drivers/net/i40e/base/i40e_common.c       |  32 ++---
 drivers/net/i40e/base/i40e_prototype.h    |   4 +-
 drivers/net/i40e/base/i40e_type.h         |  28 ++--
 drivers/net/i40e/i40e_ethdev.c            | 227 ++++++++++++++++++++++++++++++
 drivers/net/i40e/rte_pmd_i40e.h           |  70 +++++++++
 drivers/net/i40e/rte_pmd_i40e_version.map |   2 +
 11 files changed, 578 insertions(+), 41 deletions(-)

-- 
2.5.5

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

* [PATCH v6 1/6] net/i40e/base: change ppp to ddp
  2017-03-29 12:26           ` [PATCH v6 0/6] dynamic device profile support Beilei Xing
@ 2017-03-29 12:26             ` Beilei Xing
  2017-03-29 12:26             ` [PATCH v6 2/6] net/i40e: add dynamic device profile processing Beilei Xing
                               ` (5 subsequent siblings)
  6 siblings, 0 replies; 82+ messages in thread
From: Beilei Xing @ 2017-03-29 12:26 UTC (permalink / raw)
  To: jingjing.wu; +Cc: helin.zhang, bernard.iremonger, dev

Change pipeline personalization profile(ppp) to dynamic
device profile(ddp).

Signed-off-by: Beilei Xing <beilei.xing@intel.com>
---
 drivers/net/i40e/base/i40e_adminq_cmd.h | 18 +++++++++---------
 drivers/net/i40e/base/i40e_common.c     | 32 ++++++++++++++++----------------
 drivers/net/i40e/base/i40e_prototype.h  |  4 ++--
 drivers/net/i40e/base/i40e_type.h       | 28 ++++++++++++++--------------
 4 files changed, 41 insertions(+), 41 deletions(-)

diff --git a/drivers/net/i40e/base/i40e_adminq_cmd.h b/drivers/net/i40e/base/i40e_adminq_cmd.h
index 8fb3725..fdc6555 100644
--- a/drivers/net/i40e/base/i40e_adminq_cmd.h
+++ b/drivers/net/i40e/base/i40e_adminq_cmd.h
@@ -199,9 +199,9 @@ enum i40e_admin_queue_opc {
 	i40e_aqc_opc_add_mirror_rule	= 0x0260,
 	i40e_aqc_opc_delete_mirror_rule	= 0x0261,
 
-	/* Pipeline Personalization Profile */
-	i40e_aqc_opc_write_personalization_profile	= 0x0270,
-	i40e_aqc_opc_get_personalization_profile_list	= 0x0271,
+	/* Dynamic Device Profile */
+	i40e_aqc_opc_write_dynamic_device_profile	= 0x0270,
+	i40e_aqc_opc_get_dynamic_device_profile_list	= 0x0271,
 
 	/* DCB commands */
 	i40e_aqc_opc_dcb_ignore_pfc	= 0x0301,
@@ -1538,8 +1538,8 @@ struct i40e_aqc_add_delete_mirror_rule_completion {
 
 I40E_CHECK_CMD_LENGTH(i40e_aqc_add_delete_mirror_rule_completion);
 
-/* Pipeline Personalization Profile */
-struct i40e_aqc_write_personalization_profile {
+/* Dynamic Device Profile */
+struct i40e_aqc_write_dynamic_device_profile {
 	u8      flags;
 	u8      reserved[3];
 	__le32  profile_track_id;
@@ -1547,9 +1547,9 @@ struct i40e_aqc_write_personalization_profile {
 	__le32  addr_low;
 };
 
-I40E_CHECK_CMD_LENGTH(i40e_aqc_write_personalization_profile);
+I40E_CHECK_CMD_LENGTH(i40e_aqc_write_dynamic_device_profile);
 
-struct i40e_aqc_write_ppp_resp {
+struct i40e_aqc_write_ddp_resp {
 	__le32 error_offset;
 	__le32 error_info;
 	__le32 addr_high;
@@ -1558,8 +1558,8 @@ struct i40e_aqc_write_ppp_resp {
 
 struct i40e_aqc_get_applied_profiles {
 	u8      flags;
-#define I40E_AQC_GET_PPP_GET_CONF	0x1
-#define I40E_AQC_GET_PPP_GET_RDPU_CONF	0x2
+#define I40E_AQC_GET_DDP_GET_CONF	0x1
+#define I40E_AQC_GET_DDP_GET_RDPU_CONF	0x2
 	u8      rsv[3];
 	__le32  reserved;
 	__le32  addr_high;
diff --git a/drivers/net/i40e/base/i40e_common.c b/drivers/net/i40e/base/i40e_common.c
index 33ad49c..b5939ee 100644
--- a/drivers/net/i40e/base/i40e_common.c
+++ b/drivers/net/i40e/base/i40e_common.c
@@ -7155,7 +7155,7 @@ enum i40e_status_code i40e_aq_clear_all_wol_filters(struct i40e_hw *hw,
 
 
 /**
- * i40e_aq_write_ppp - Write pipeline personalization profile (ppp)
+ * i40e_aq_write_ddp - Write dynamic device profile (ddp)
  * @hw: pointer to the hw struct
  * @buff: command buffer (size in bytes = buff_size)
  * @buff_size: buffer size in bytes
@@ -7165,20 +7165,20 @@ enum i40e_status_code i40e_aq_clear_all_wol_filters(struct i40e_hw *hw,
  * @cmd_details: pointer to command details structure or NULL
  **/
 enum
-i40e_status_code i40e_aq_write_ppp(struct i40e_hw *hw, void *buff,
+i40e_status_code i40e_aq_write_ddp(struct i40e_hw *hw, void *buff,
 				   u16 buff_size, u32 track_id,
 				   u32 *error_offset, u32 *error_info,
 				   struct i40e_asq_cmd_details *cmd_details)
 {
 	struct i40e_aq_desc desc;
-	struct i40e_aqc_write_personalization_profile *cmd =
-		(struct i40e_aqc_write_personalization_profile *)
+	struct i40e_aqc_write_dynamic_device_profile *cmd =
+		(struct i40e_aqc_write_dynamic_device_profile *)
 		&desc.params.raw;
-	struct i40e_aqc_write_ppp_resp *resp;
+	struct i40e_aqc_write_ddp_resp *resp;
 	enum i40e_status_code status;
 
 	i40e_fill_default_direct_cmd_desc(&desc,
-				  i40e_aqc_opc_write_personalization_profile);
+				  i40e_aqc_opc_write_dynamic_device_profile);
 
 	desc.flags |= CPU_TO_LE16(I40E_AQ_FLAG_BUF | I40E_AQ_FLAG_RD);
 	if (buff_size > I40E_AQ_LARGE_BUF)
@@ -7190,7 +7190,7 @@ i40e_status_code i40e_aq_write_ppp(struct i40e_hw *hw, void *buff,
 
 	status = i40e_asq_send_command(hw, &desc, buff, buff_size, cmd_details);
 	if (!status) {
-		resp = (struct i40e_aqc_write_ppp_resp *)&desc.params.raw;
+		resp = (struct i40e_aqc_write_ddp_resp *)&desc.params.raw;
 		if (error_offset)
 			*error_offset = LE32_TO_CPU(resp->error_offset);
 		if (error_info)
@@ -7201,14 +7201,14 @@ i40e_status_code i40e_aq_write_ppp(struct i40e_hw *hw, void *buff,
 }
 
 /**
- * i40e_aq_get_ppp_list - Read pipeline personalization profile (ppp)
+ * i40e_aq_get_ddp_list - Read dynamic device profile (ddp)
  * @hw: pointer to the hw struct
  * @buff: command buffer (size in bytes = buff_size)
  * @buff_size: buffer size in bytes
  * @cmd_details: pointer to command details structure or NULL
  **/
 enum
-i40e_status_code i40e_aq_get_ppp_list(struct i40e_hw *hw, void *buff,
+i40e_status_code i40e_aq_get_ddp_list(struct i40e_hw *hw, void *buff,
 				      u16 buff_size, u8 flags,
 				      struct i40e_asq_cmd_details *cmd_details)
 {
@@ -7218,7 +7218,7 @@ i40e_status_code i40e_aq_get_ppp_list(struct i40e_hw *hw, void *buff,
 	enum i40e_status_code status;
 
 	i40e_fill_default_direct_cmd_desc(&desc,
-			  i40e_aqc_opc_get_personalization_profile_list);
+			  i40e_aqc_opc_get_dynamic_device_profile_list);
 
 	desc.flags |= CPU_TO_LE16((u16)I40E_AQ_FLAG_BUF);
 	if (buff_size > I40E_AQ_LARGE_BUF)
@@ -7297,7 +7297,7 @@ i40e_write_profile(struct i40e_hw *hw, struct i40e_profile_segment *profile,
 				break;
 	}
 	if (i == dev_cnt) {
-		i40e_debug(hw, I40E_DEBUG_PACKAGE, "Device doesn't support PPP");
+		i40e_debug(hw, I40E_DEBUG_PACKAGE, "Device doesn't support DDP");
 		return I40E_ERR_DEVICE_NOT_SUPPORTED;
 	}
 
@@ -7316,7 +7316,7 @@ i40e_write_profile(struct i40e_hw *hw, struct i40e_profile_segment *profile,
 			sizeof(struct i40e_profile_section_header);
 
 		/* Write profile */
-		status = i40e_aq_write_ppp(hw, (void *)sec, (u16)section_size,
+		status = i40e_aq_write_ddp(hw, (void *)sec, (u16)section_size,
 					   track_id, &offset, &info, NULL);
 		if (status) {
 			i40e_debug(hw, I40E_DEBUG_PACKAGE,
@@ -7358,10 +7358,10 @@ i40e_add_pinfo_to_list(struct i40e_hw *hw,
 					     sec->section.offset);
 	pinfo->track_id = track_id;
 	pinfo->version = profile->version;
-	pinfo->op = I40E_PPP_ADD_TRACKID;
-	memcpy(pinfo->name, profile->name, I40E_PPP_NAME_SIZE);
+	pinfo->op = I40E_DDP_ADD_TRACKID;
+	memcpy(pinfo->name, profile->name, I40E_DDP_NAME_SIZE);
 
-	status = i40e_aq_write_ppp(hw, (void *)sec, sec->data_end,
+	status = i40e_aq_write_ddp(hw, (void *)sec, sec->data_end,
 				track_id, &offset, &info, NULL);
 	return status;
-}
\ No newline at end of file
+}
diff --git a/drivers/net/i40e/base/i40e_prototype.h b/drivers/net/i40e/base/i40e_prototype.h
index 8662147..4bd589e 100644
--- a/drivers/net/i40e/base/i40e_prototype.h
+++ b/drivers/net/i40e/base/i40e_prototype.h
@@ -565,11 +565,11 @@ enum i40e_status_code i40e_write_phy_register(struct i40e_hw *hw,
 u8 i40e_get_phy_address(struct i40e_hw *hw, u8 dev_num);
 enum i40e_status_code i40e_blink_phy_link_led(struct i40e_hw *hw,
 					      u32 time, u32 interval);
-enum i40e_status_code i40e_aq_write_ppp(struct i40e_hw *hw, void *buff,
+enum i40e_status_code i40e_aq_write_ddp(struct i40e_hw *hw, void *buff,
 				u16 buff_size, u32 track_id,
 				u32 *error_offset, u32 *error_info,
 				struct i40e_asq_cmd_details *cmd_details);
-enum i40e_status_code i40e_aq_get_ppp_list(struct i40e_hw *hw, void *buff,
+enum i40e_status_code i40e_aq_get_ddp_list(struct i40e_hw *hw, void *buff,
 				   u16 buff_size, u8 flags,
 				   struct i40e_asq_cmd_details *cmd_details);
 struct i40e_generic_seg_header *
diff --git a/drivers/net/i40e/base/i40e_type.h b/drivers/net/i40e/base/i40e_type.h
index fc81a93..b1ca47b 100644
--- a/drivers/net/i40e/base/i40e_type.h
+++ b/drivers/net/i40e/base/i40e_type.h
@@ -1880,19 +1880,19 @@ struct i40e_lldp_variables {
 #define I40E_FLEX_57_SHIFT		6
 #define I40E_FLEX_57_MASK		(0x1ULL << I40E_FLEX_57_SHIFT)
 
-/* Version format for PPP */
-struct i40e_ppp_version {
+/* Version format for DDP */
+struct i40e_ddp_version {
 	u8 major;
 	u8 minor;
 	u8 update;
 	u8 draft;
 };
 
-#define I40E_PPP_NAME_SIZE	32
+#define I40E_DDP_NAME_SIZE	32
 
 /* Package header */
 struct i40e_package_header {
-	struct i40e_ppp_version version;
+	struct i40e_ddp_version version;
 	u32 segment_count;
 	u32 segment_offset[1];
 };
@@ -1904,16 +1904,16 @@ struct i40e_generic_seg_header {
 #define SEGMENT_TYPE_I40E	0x00000011
 #define SEGMENT_TYPE_X722	0x00000012
 	u32 type;
-	struct i40e_ppp_version version;
+	struct i40e_ddp_version version;
 	u32 size;
-	char name[I40E_PPP_NAME_SIZE];
+	char name[I40E_DDP_NAME_SIZE];
 };
 
 struct i40e_metadata_segment {
 	struct i40e_generic_seg_header header;
-	struct i40e_ppp_version version;
+	struct i40e_ddp_version version;
 	u32 track_id;
-	char     name[I40E_PPP_NAME_SIZE];
+	char     name[I40E_DDP_NAME_SIZE];
 };
 
 struct i40e_device_id_entry {
@@ -1923,8 +1923,8 @@ struct i40e_device_id_entry {
 
 struct i40e_profile_segment {
 	struct i40e_generic_seg_header header;
-	struct i40e_ppp_version version;
-	char name[I40E_PPP_NAME_SIZE];
+	struct i40e_ddp_version version;
+	char name[I40E_DDP_NAME_SIZE];
 	u32 device_table_count;
 	struct i40e_device_id_entry device_table[1];
 };
@@ -1951,11 +1951,11 @@ struct i40e_profile_section_header {
 
 struct i40e_profile_info {
 	u32 track_id;
-	struct i40e_ppp_version version;
+	struct i40e_ddp_version version;
 	u8 op;
-#define I40E_PPP_ADD_TRACKID		0x01
-#define I40E_PPP_REMOVE_TRACKID	0x02
+#define I40E_DDP_ADD_TRACKID		0x01
+#define I40E_DDP_REMOVE_TRACKID	0x02
 	u8 reserved[7];
-	u8 name[I40E_PPP_NAME_SIZE];
+	u8 name[I40E_DDP_NAME_SIZE];
 };
 #endif /* _I40E_TYPE_H_ */
-- 
2.5.5

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

* [PATCH v6 2/6] net/i40e: add dynamic device profile processing
  2017-03-29 12:26           ` [PATCH v6 0/6] dynamic device profile support Beilei Xing
  2017-03-29 12:26             ` [PATCH v6 1/6] net/i40e/base: change ppp to ddp Beilei Xing
@ 2017-03-29 12:26             ` Beilei Xing
  2017-03-29 13:17               ` Wu, Jingjing
  2017-03-29 12:26             ` [PATCH v6 3/6] app/testpmd: add command for loading a profile Beilei Xing
                               ` (4 subsequent siblings)
  6 siblings, 1 reply; 82+ messages in thread
From: Beilei Xing @ 2017-03-29 12:26 UTC (permalink / raw)
  To: jingjing.wu; +Cc: helin.zhang, bernard.iremonger, dev

Add support for adding a dynamic device profile.

Signed-off-by: Beilei Xing <beilei.xing@intel.com>
---
 drivers/net/i40e/i40e_ethdev.c            | 199 ++++++++++++++++++++++++++++++
 drivers/net/i40e/rte_pmd_i40e.h           |  58 +++++++++
 drivers/net/i40e/rte_pmd_i40e_version.map |   1 +
 3 files changed, 258 insertions(+)

diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index 2063603..764764f 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -11708,3 +11708,202 @@ rte_pmd_i40e_set_tc_strict_prio(uint8_t port, uint8_t tc_map)
 
 	return ret;
 }
+
+static void
+i40e_generate_profile_info_sec(char *name, struct i40e_ddp_version *version,
+			       uint32_t track_id, uint8_t *profile_info_sec,
+			       bool add)
+{
+	struct i40e_profile_section_header *sec = NULL;
+	struct i40e_profile_info *pinfo;
+
+	sec = (struct i40e_profile_section_header *)profile_info_sec;
+	sec->tbl_size = 1;
+	sec->data_end = sizeof(struct i40e_profile_section_header) +
+		sizeof(struct i40e_profile_info);
+	sec->section.type = SECTION_TYPE_INFO;
+	sec->section.offset = sizeof(struct i40e_profile_section_header);
+	sec->section.size = sizeof(struct i40e_profile_info);
+	pinfo = (struct i40e_profile_info *)(profile_info_sec +
+					     sec->section.offset);
+	pinfo->track_id = track_id;
+	memcpy(pinfo->name, name, I40E_DDP_NAME_SIZE);
+	memcpy(&pinfo->version, version, sizeof(struct i40e_ddp_version));
+	if (add)
+		pinfo->op = I40E_DDP_ADD_TRACKID;
+	else
+		pinfo->op = I40E_DDP_REMOVE_TRACKID;
+}
+
+static enum i40e_status_code
+i40e_add_rm_profile_info(struct i40e_hw *hw, uint8_t *profile_info_sec)
+{
+	enum i40e_status_code status = I40E_SUCCESS;
+	struct i40e_profile_section_header *sec;
+	uint32_t track_id;
+	uint32_t offset = 0, info = 0;
+
+	sec = (struct i40e_profile_section_header *)profile_info_sec;
+	track_id = ((struct i40e_profile_info *)(profile_info_sec +
+					 sec->section.offset))->track_id;
+
+	status = i40e_aq_write_ddp(hw, (void *)sec, sec->data_end,
+				   track_id, &offset, &info, NULL);
+	if (status)
+		PMD_DRV_LOG(ERR, "Failed to add/remove profile info: "
+			    "offset %d, info %d",
+			    offset, info);
+
+	return status;
+}
+
+#define I40E_PROFILE_INFO_SIZE 48
+#define I40E_MAX_PROFILE_NUM 16
+
+/* Check if the profile info exists */
+static int
+i40e_check_profile_info(uint8_t port, uint8_t *profile_info_sec)
+{
+	struct rte_eth_dev *dev = &rte_eth_devices[port];
+	struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+	uint8_t *buff;
+	struct rte_pmd_i40e_profile_list *p_list;
+	struct rte_pmd_i40e_profile_info *pinfo, *p;
+	uint32_t i;
+	int ret;
+
+	buff = rte_zmalloc("pinfo_list",
+			   (I40E_PROFILE_INFO_SIZE * I40E_MAX_PROFILE_NUM + 4),
+			   0);
+	if (!buff) {
+		PMD_DRV_LOG(ERR, "failed to allocate memory");
+		return -1;
+	}
+
+	ret = i40e_aq_get_ddp_list(hw, (void *)buff,
+		      (I40E_PROFILE_INFO_SIZE * I40E_MAX_PROFILE_NUM + 4),
+		      0, NULL);
+	if (ret) {
+		PMD_DRV_LOG(ERR, "Failed to get profile info list.");
+		rte_free(buff);
+		return -1;
+	}
+	p_list = (struct rte_pmd_i40e_profile_list *)buff;
+	pinfo = (struct rte_pmd_i40e_profile_info *)(profile_info_sec +
+			     sizeof(struct i40e_profile_section_header));
+	for (i = 0; i < p_list->p_count; i++) {
+		p = &p_list->p_info[i];
+		if ((pinfo->track_id == p->track_id) &&
+		    !memcmp(&pinfo->version, &p->version,
+			    sizeof(struct i40e_ddp_version)) &&
+		    !memcmp(&pinfo->name, &p->name,
+			    I40E_DDP_NAME_SIZE)) {
+			PMD_DRV_LOG(INFO, "Profile exists.");
+			rte_free(buff);
+			return 1;
+		}
+	}
+
+	rte_free(buff);
+	return 0;
+}
+
+int
+rte_pmd_i40e_process_ddp_package(uint8_t port, uint8_t *buff,
+				 uint32_t size,
+				 enum rte_pmd_i40e_package_op op)
+{
+	struct rte_eth_dev *dev;
+	struct i40e_hw *hw;
+	struct i40e_package_header *pkg_hdr;
+	struct i40e_generic_seg_header *profile_seg_hdr;
+	struct i40e_generic_seg_header *metadata_seg_hdr;
+	uint32_t track_id;
+	uint8_t *profile_info_sec;
+	int is_exist;
+	enum i40e_status_code status = I40E_SUCCESS;
+
+	RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
+
+	dev = &rte_eth_devices[port];
+
+	if (!is_device_supported(dev, &rte_i40e_pmd))
+		return -ENOTSUP;
+
+	hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+
+	if (size < (sizeof(struct i40e_package_header) +
+		    sizeof(struct i40e_metadata_segment) +
+		    sizeof(uint32_t) * 2)) {
+		PMD_DRV_LOG(ERR, "Buff is invalid.");
+		return -EINVAL;
+	}
+
+	pkg_hdr = (struct i40e_package_header *)buff;
+
+	if (!pkg_hdr) {
+		PMD_DRV_LOG(ERR, "Failed to fill the package structure");
+		return -EINVAL;
+	}
+
+	if (pkg_hdr->segment_count < 2) {
+		PMD_DRV_LOG(ERR, "Segment_count should be 2 at least.");
+		return -EINVAL;
+	}
+
+	/* Find metadata segment */
+	metadata_seg_hdr = i40e_find_segment_in_package(SEGMENT_TYPE_METADATA,
+							pkg_hdr);
+	if (!metadata_seg_hdr) {
+		PMD_DRV_LOG(ERR, "Failed to find metadata segment header");
+		return -EINVAL;
+	}
+	track_id = ((struct i40e_metadata_segment *)metadata_seg_hdr)->track_id;
+
+	/* Find profile segment */
+	profile_seg_hdr = i40e_find_segment_in_package(SEGMENT_TYPE_I40E,
+						       pkg_hdr);
+	if (!profile_seg_hdr) {
+		PMD_DRV_LOG(ERR, "Failed to find profile segment header");
+		return -EINVAL;
+	}
+
+	profile_info_sec = rte_zmalloc("i40e_profile_info",
+			       sizeof(struct i40e_profile_section_header) +
+			       sizeof(struct i40e_profile_info),
+			       0);
+	if (!profile_info_sec) {
+		PMD_DRV_LOG(ERR, "Failed to allocate memory");
+		return -EINVAL;
+	}
+
+	if (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) {
+			PMD_DRV_LOG(ERR, "Profile already exists.");
+			rte_free(profile_info_sec);
+			return 1;
+		}
+
+		/* Write profile to HW */
+		status = i40e_write_profile(hw,
+				 (struct i40e_profile_segment *)profile_seg_hdr,
+				 track_id);
+		if (status)
+			PMD_DRV_LOG(ERR, "Failed to write profile.");
+
+		/* Add profile info to info list */
+		status = i40e_add_rm_profile_info(hw, profile_info_sec);
+		if (status)
+			PMD_DRV_LOG(ERR, "Failed to add profile info.");
+	} else
+		PMD_DRV_LOG(ERR, "Operation not supported.");
+
+	rte_free(profile_info_sec);
+	return status;
+}
diff --git a/drivers/net/i40e/rte_pmd_i40e.h b/drivers/net/i40e/rte_pmd_i40e.h
index 3ca49a4..38a11f3 100644
--- a/drivers/net/i40e/rte_pmd_i40e.h
+++ b/drivers/net/i40e/rte_pmd_i40e.h
@@ -65,6 +65,43 @@ struct rte_pmd_i40e_mb_event_param {
 	uint16_t msglen;   /**< length of the message */
 };
 
+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_MAX = 32
+};
+
+#define RTE_PMD_I40E_DDP_NAME_SIZE 32
+
+/**
+ * Dynamic device profile version
+ */
+struct rte_pmd_i40e_ddp_version {
+	uint8_t major;
+	uint8_t minor;
+	uint8_t update;
+	uint8_t draft;
+};
+
+/**
+ * Structure of profile information
+ */
+struct rte_pmd_i40e_profile_info {
+	uint32_t track_id;
+	struct rte_pmd_i40e_ddp_version version;
+	uint8_t owner;
+	uint8_t reserved[7];
+	uint8_t name[RTE_PMD_I40E_DDP_NAME_SIZE];
+};
+
+/**
+ * Structure of profile information list
+ */
+struct rte_pmd_i40e_profile_list {
+	uint32_t p_count;
+	struct rte_pmd_i40e_profile_info p_info[1];
+};
+
 /**
  * Notify VF when PF link status changes.
  *
@@ -418,4 +455,25 @@ int rte_pmd_i40e_set_vf_tc_max_bw(uint8_t port,
  */
 int rte_pmd_i40e_set_tc_strict_prio(uint8_t port, uint8_t tc_map);
 
+/**
+ * Load/Unload a ddp package
+ *
+ * @param port
+ *    The port identifier of the Ethernet device.
+ * @param buff
+ *    buffer of package.
+ * @param size
+ *    size of buffer.
+ * @param op
+ *   Operation of package processing
+ * @return
+ *   - (0) if successful.
+ *   - (-ENODEV) if *port* invalid.
+ *   - (-EINVAL) if bad parameter.
+ *   - (1) if profile exists.
+ */
+int rte_pmd_i40e_process_ddp_package(uint8_t port, uint8_t *buff,
+				     uint32_t size,
+				     enum rte_pmd_i40e_package_op op);
+
 #endif /* _PMD_I40E_H_ */
diff --git a/drivers/net/i40e/rte_pmd_i40e_version.map b/drivers/net/i40e/rte_pmd_i40e_version.map
index 488e6b6..6d001a3 100644
--- a/drivers/net/i40e/rte_pmd_i40e_version.map
+++ b/drivers/net/i40e/rte_pmd_i40e_version.map
@@ -30,5 +30,6 @@ DPDK_17.05 {
 	rte_pmd_i40e_set_vf_max_bw;
 	rte_pmd_i40e_set_vf_tc_bw_alloc;
 	rte_pmd_i40e_set_vf_tc_max_bw;
+	rte_pmd_i40e_process_ddp_package;
 
 } DPDK_17.02;
-- 
2.5.5

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

* [PATCH v6 3/6] app/testpmd: add command for loading a profile
  2017-03-29 12:26           ` [PATCH v6 0/6] dynamic device profile support Beilei Xing
  2017-03-29 12:26             ` [PATCH v6 1/6] net/i40e/base: change ppp to ddp Beilei Xing
  2017-03-29 12:26             ` [PATCH v6 2/6] net/i40e: add dynamic device profile processing Beilei Xing
@ 2017-03-29 12:26             ` Beilei Xing
  2017-03-29 12:26             ` [PATCH v6 4/6] net/i40e: add get all loaded profiles Beilei Xing
                               ` (3 subsequent siblings)
  6 siblings, 0 replies; 82+ messages in thread
From: Beilei Xing @ 2017-03-29 12:26 UTC (permalink / raw)
  To: jingjing.wu; +Cc: helin.zhang, bernard.iremonger, dev

This patch is to add testpmd CLI for loading a dynamic
device profile.

Signed-off-by: Beilei Xing <beilei.xing@intel.com>
---
 app/test-pmd/cmdline.c | 73 ++++++++++++++++++++++++++++++++++++++++++++++++++
 app/test-pmd/config.c  | 67 +++++++++++++++++++++++++++++++++++++++++++++
 app/test-pmd/testpmd.h |  3 +++
 3 files changed, 143 insertions(+)

diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
index b93b096..42d0b24 100644
--- a/app/test-pmd/cmdline.c
+++ b/app/test-pmd/cmdline.c
@@ -590,6 +590,9 @@ 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"
 
+			"add ddp (port_id) (profile_path)\n"
+			"    Load a profile package on a port\n\n"
+
 			, list_pkt_forwarding_modes()
 		);
 	}
@@ -12739,6 +12742,75 @@ cmdline_parse_inst_t cmd_strict_link_prio = {
 	},
 };
 
+/* Load Dynamic Device Profile */
+struct cmd_add_ddp_result {
+	cmdline_fixed_string_t add;
+	cmdline_fixed_string_t ddp;
+	uint8_t port_id;
+	char filepath[];
+};
+
+cmdline_parse_token_string_t cmd_add_ddp_add =
+	TOKEN_STRING_INITIALIZER(struct cmd_add_ddp_result, add, "add");
+cmdline_parse_token_string_t cmd_add_ddp_ddp =
+	TOKEN_STRING_INITIALIZER(struct cmd_add_ddp_result, ddp, "ddp");
+cmdline_parse_token_num_t cmd_add_ddp_port_id =
+	TOKEN_NUM_INITIALIZER(struct cmd_add_ddp_result, port_id, UINT8);
+cmdline_parse_token_string_t cmd_add_ddp_filepath =
+	TOKEN_STRING_INITIALIZER(struct cmd_add_ddp_result, filepath, NULL);
+
+static void
+cmd_add_ddp_parsed(
+	void *parsed_result,
+	__attribute__((unused)) struct cmdline *cl,
+	__attribute__((unused)) void *data)
+{
+	struct cmd_add_ddp_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_ADD);
+#endif
+
+	if (ret < 0)
+		printf("Failed to load profile.\n");
+	else if (ret > 0)
+		printf("Profile has already existed.\n");
+
+	close_ddp_package_file(buff);
+}
+
+cmdline_parse_inst_t cmd_add_ddp = {
+	.f = cmd_add_ddp_parsed,
+	.data = NULL,
+	.help_str = "add/remove ddp <port_id> <profile_path>",
+	.tokens = {
+		(void *)&cmd_add_ddp_add,
+		(void *)&cmd_add_ddp_ddp,
+		(void *)&cmd_add_ddp_port_id,
+		(void *)&cmd_add_ddp_filepath,
+		NULL,
+	},
+};
 
 /* ******************************************************************************** */
 
@@ -12919,6 +12991,7 @@ cmdline_parse_ctx_t main_ctx[] = {
 	(cmdline_parse_inst_t *)&cmd_vf_tc_min_bw,
 	(cmdline_parse_inst_t *)&cmd_vf_tc_max_bw,
 	(cmdline_parse_inst_t *)&cmd_strict_link_prio,
+	(cmdline_parse_inst_t *)&cmd_add_ddp,
 	NULL,
 };
 
diff --git a/app/test-pmd/config.c b/app/test-pmd/config.c
index 80491fc..9865bf1 100644
--- a/app/test-pmd/config.c
+++ b/app/test-pmd/config.c
@@ -3245,3 +3245,70 @@ port_dcb_info_display(uint8_t port_id)
 		printf("\t%4d", dcb_info.tc_queue.tc_txq[0][i].nb_queue);
 	printf("\n");
 }
+
+uint8_t *
+open_ddp_package_file(const char *file_path, uint32_t *size)
+{
+	FILE *fh = fopen(file_path, "rb");
+	uint32_t pkg_size;
+	uint8_t *buf = NULL;
+	int ret = 0;
+
+	if (size)
+		*size = 0;
+
+	if (fh == NULL) {
+		printf("%s: Failed to open %s\n", __func__, file_path);
+		return buf;
+	}
+
+	ret = fseek(fh, 0, SEEK_END);
+	if (ret < 0) {
+		fclose(fh);
+		printf("%s: File operations failed\n", __func__);
+		return buf;
+	}
+
+	pkg_size = ftell(fh);
+
+	buf = (uint8_t *)malloc(pkg_size);
+	if (!buf) {
+		fclose(fh);
+		printf("%s: Failed to malloc memory\n",	__func__);
+		return buf;
+	}
+
+	ret = fseek(fh, 0, SEEK_SET);
+	if (ret < 0) {
+		fclose(fh);
+		printf("%s: File seek operation failed\n", __func__);
+		close_ddp_package_file(buf);
+		return NULL;
+	}
+
+	ret = fread(buf, 1, pkg_size, fh);
+	if (ret < 0) {
+		fclose(fh);
+		printf("%s: File read operation failed\n", __func__);
+		close_ddp_package_file(buf);
+		return NULL;
+	}
+
+	if (size)
+		*size = pkg_size;
+
+	fclose(fh);
+
+	return buf;
+}
+
+int
+close_ddp_package_file(uint8_t *buf)
+{
+	if (buf) {
+		free((void *)buf);
+		return 0;
+	}
+
+	return -1;
+}
diff --git a/app/test-pmd/testpmd.h b/app/test-pmd/testpmd.h
index 8cf2860..5c18151 100644
--- a/app/test-pmd/testpmd.h
+++ b/app/test-pmd/testpmd.h
@@ -622,6 +622,9 @@ void mcast_addr_add(uint8_t port_id, struct ether_addr *mc_addr);
 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 close_ddp_package_file(uint8_t *buf);
+
 enum print_warning {
 	ENABLED_WARN = 0,
 	DISABLED_WARN
-- 
2.5.5

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

* [PATCH v6 4/6] net/i40e: add get all loaded profiles
  2017-03-29 12:26           ` [PATCH v6 0/6] dynamic device profile support Beilei Xing
                               ` (2 preceding siblings ...)
  2017-03-29 12:26             ` [PATCH v6 3/6] app/testpmd: add command for loading a profile Beilei Xing
@ 2017-03-29 12:26             ` Beilei Xing
  2017-03-29 12:26             ` [PATCH v6 5/6] app/testpmd: add command for getting " Beilei Xing
                               ` (2 subsequent siblings)
  6 siblings, 0 replies; 82+ messages in thread
From: Beilei Xing @ 2017-03-29 12:26 UTC (permalink / raw)
  To: jingjing.wu; +Cc: helin.zhang, bernard.iremonger, dev

This patch is to add get all loaded profiles function.

Signed-off-by: Beilei Xing <beilei.xing@intel.com>
---
 drivers/net/i40e/i40e_ethdev.c            | 28 ++++++++++++++++++++++++++++
 drivers/net/i40e/rte_pmd_i40e.h           | 12 ++++++++++++
 drivers/net/i40e/rte_pmd_i40e_version.map |  1 +
 3 files changed, 41 insertions(+)

diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index 764764f..bcd81b0 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -11709,6 +11709,9 @@ rte_pmd_i40e_set_tc_strict_prio(uint8_t port, uint8_t tc_map)
 	return ret;
 }
 
+#define I40E_PROFILE_INFO_SIZE 48
+#define I40E_MAX_PROFILE_NUM 16
+
 static void
 i40e_generate_profile_info_sec(char *name, struct i40e_ddp_version *version,
 			       uint32_t track_id, uint8_t *profile_info_sec,
@@ -11907,3 +11910,28 @@ rte_pmd_i40e_process_ddp_package(uint8_t port, uint8_t *buff,
 	rte_free(profile_info_sec);
 	return status;
 }
+
+int
+rte_pmd_i40e_get_ddp_list(uint8_t port, uint8_t *buff, uint32_t size)
+{
+	struct rte_eth_dev *dev;
+	struct i40e_hw *hw;
+	enum i40e_status_code status = I40E_SUCCESS;
+
+	RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
+
+	dev = &rte_eth_devices[port];
+
+	if (!is_device_supported(dev, &rte_i40e_pmd))
+		return -ENOTSUP;
+
+	if (size < (I40E_PROFILE_INFO_SIZE * I40E_MAX_PROFILE_NUM + 4))
+		return -EINVAL;
+
+	hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+
+	status = i40e_aq_get_ddp_list(hw, (void *)buff,
+				      size, 0, NULL);
+
+	return status;
+}
diff --git a/drivers/net/i40e/rte_pmd_i40e.h b/drivers/net/i40e/rte_pmd_i40e.h
index 38a11f3..d05bec3 100644
--- a/drivers/net/i40e/rte_pmd_i40e.h
+++ b/drivers/net/i40e/rte_pmd_i40e.h
@@ -476,4 +476,16 @@ int rte_pmd_i40e_process_ddp_package(uint8_t port, uint8_t *buff,
 				     uint32_t size,
 				     enum rte_pmd_i40e_package_op op);
 
+/**
+ * rte_pmd_i40e_get_ddp_list - Get loaded profile list
+ * @port: port id
+ * @buff: buffer for response
+ * @size: buffer size
+ * @return
+ *   - (0) if successful.
+ *   - (-ENODEV) if *port* invalid.
+ *   - (-EINVAL) if bad parameter.
+ */
+int rte_pmd_i40e_get_ddp_list(uint8_t port, uint8_t *buff, uint32_t size);
+
 #endif /* _PMD_I40E_H_ */
diff --git a/drivers/net/i40e/rte_pmd_i40e_version.map b/drivers/net/i40e/rte_pmd_i40e_version.map
index 6d001a3..dbb994e 100644
--- a/drivers/net/i40e/rte_pmd_i40e_version.map
+++ b/drivers/net/i40e/rte_pmd_i40e_version.map
@@ -31,5 +31,6 @@ DPDK_17.05 {
 	rte_pmd_i40e_set_vf_tc_bw_alloc;
 	rte_pmd_i40e_set_vf_tc_max_bw;
 	rte_pmd_i40e_process_ddp_package;
+	rte_pmd_i40e_get_ddp_list;
 
 } DPDK_17.02;
-- 
2.5.5

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

* [PATCH v6 5/6] app/testpmd: add command for getting loaded profiles
  2017-03-29 12:26           ` [PATCH v6 0/6] dynamic device profile support Beilei Xing
                               ` (3 preceding siblings ...)
  2017-03-29 12:26             ` [PATCH v6 4/6] net/i40e: add get all loaded profiles Beilei Xing
@ 2017-03-29 12:26             ` Beilei Xing
  2017-03-29 12:26             ` [PATCH v6 6/6] doc: add dynamic device profile support for i40e Beilei Xing
  2017-03-29 14:44             ` [PATCH v7 0/6] dynamic device profile support Beilei Xing
  6 siblings, 0 replies; 82+ messages in thread
From: Beilei Xing @ 2017-03-29 12:26 UTC (permalink / raw)
  To: jingjing.wu; +Cc: helin.zhang, bernard.iremonger, dev

This patch is to add testpmd CLI for getting all loaded profiles.

Signed-off-by: Beilei Xing <beilei.xing@intel.com>
---
 app/test-pmd/cmdline.c | 91 ++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 91 insertions(+)

diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
index 42d0b24..0b47692 100644
--- a/app/test-pmd/cmdline.c
+++ b/app/test-pmd/cmdline.c
@@ -214,6 +214,9 @@ static void cmd_help_long_parsed(void *parsed_result,
 
 			"read txd (port_id) (queue_id) (txd_id)\n"
 			"    Display a TX descriptor of a port TX queue.\n\n"
+
+			"get ddp list (port_id)\n"
+			"    Get ddp profile info list\n\n"
 		);
 	}
 
@@ -12812,6 +12815,93 @@ cmdline_parse_inst_t cmd_add_ddp = {
 	},
 };
 
+/* Get Dynamic Device Profile list*/
+#define PROFILE_INFO_SIZE 48
+#define MAX_PROFILE_NUM 16
+
+struct cmd_get_ddp_list_result {
+	cmdline_fixed_string_t get;
+	cmdline_fixed_string_t ddp;
+	cmdline_fixed_string_t list;
+	uint8_t port_id;
+};
+
+cmdline_parse_token_string_t cmd_get_ddp_list_get =
+	TOKEN_STRING_INITIALIZER(struct cmd_get_ddp_list_result, get, "get");
+cmdline_parse_token_string_t cmd_get_ddp_list_ddp =
+	TOKEN_STRING_INITIALIZER(struct cmd_get_ddp_list_result, ddp, "ddp");
+cmdline_parse_token_string_t cmd_get_ddp_list_list =
+	TOKEN_STRING_INITIALIZER(struct cmd_get_ddp_list_result, list, "list");
+cmdline_parse_token_num_t cmd_get_ddp_list_port_id =
+	TOKEN_NUM_INITIALIZER(struct cmd_get_ddp_list_result, port_id, UINT8);
+
+static void
+cmd_get_ddp_list_parsed(
+	void *parsed_result,
+	__attribute__((unused)) struct cmdline *cl,
+	__attribute__((unused)) void *data)
+{
+	struct cmd_get_ddp_list_result *res = parsed_result;
+#ifdef RTE_LIBRTE_I40E_PMD
+	struct rte_pmd_i40e_profile_list *p_list;
+	struct rte_pmd_i40e_profile_info *p_info;
+	uint32_t p_num;
+	uint32_t size;
+	uint32_t i;
+#endif
+	int ret = -ENOTSUP;
+
+	if (res->port_id > nb_ports) {
+		printf("Invalid port, range is [0, %d]\n", nb_ports - 1);
+		return;
+	}
+
+#ifdef RTE_LIBRTE_I40E_PMD
+	size = PROFILE_INFO_SIZE * MAX_PROFILE_NUM + 4;
+	p_list = (struct rte_pmd_i40e_profile_list *)malloc(size);
+	if (!p_list)
+		printf("%s: Failed to malloc buffer\n", __func__);
+
+	if (ret == -ENOTSUP)
+		ret = rte_pmd_i40e_get_ddp_list(res->port_id,
+						(uint8_t *)p_list, size);
+
+	if (!ret) {
+		p_num = p_list->p_count;
+		printf("Profile number is: %d\n\n", p_num);
+
+		for (i = 0; i < p_num; i++) {
+			p_info = &p_list->p_info[i];
+			printf("Profile %d:\n", i);
+			printf("Track id:     0x%x\n", p_info->track_id);
+			printf("Version:      %d.%d.%d.%d \n",
+			       p_info->version.major,
+			       p_info->version.minor,
+			       p_info->version.update,
+			       p_info->version.draft);
+			printf("Profile name: %s\n\n", p_info->name);
+		}
+	}
+
+	free(p_list);
+#endif
+
+	if (ret < 0)
+		printf("Failed to get ddp list\n");
+}
+
+cmdline_parse_inst_t cmd_get_ddp_list = {
+	.f = cmd_get_ddp_list_parsed,
+	.data = NULL,
+	.help_str = "get ddp list <port_id>",
+	.tokens = {
+		(void *)&cmd_get_ddp_list_get,
+		(void *)&cmd_get_ddp_list_ddp,
+		(void *)&cmd_get_ddp_list_list,
+		(void *)&cmd_get_ddp_list_port_id,
+		NULL,
+	},
+};
 /* ******************************************************************************** */
 
 /* list of instructions */
@@ -12992,6 +13082,7 @@ cmdline_parse_ctx_t main_ctx[] = {
 	(cmdline_parse_inst_t *)&cmd_vf_tc_max_bw,
 	(cmdline_parse_inst_t *)&cmd_strict_link_prio,
 	(cmdline_parse_inst_t *)&cmd_add_ddp,
+	(cmdline_parse_inst_t *)&cmd_get_ddp_list,
 	NULL,
 };
 
-- 
2.5.5

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

* [PATCH v6 6/6] doc: add dynamic device profile support for i40e
  2017-03-29 12:26           ` [PATCH v6 0/6] dynamic device profile support Beilei Xing
                               ` (4 preceding siblings ...)
  2017-03-29 12:26             ` [PATCH v6 5/6] app/testpmd: add command for getting " Beilei Xing
@ 2017-03-29 12:26             ` Beilei Xing
  2017-03-29 14:44             ` [PATCH v7 0/6] dynamic device profile support Beilei Xing
  6 siblings, 0 replies; 82+ messages in thread
From: Beilei Xing @ 2017-03-29 12:26 UTC (permalink / raw)
  To: jingjing.wu; +Cc: helin.zhang, bernard.iremonger, dev

Signed-off-by: Beilei Xing <beilei.xing@intel.com>
Acked-by: John McNamara <john.mcnamara@intel.com>
---
 doc/guides/rel_notes/release_17_05.rst | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/doc/guides/rel_notes/release_17_05.rst b/doc/guides/rel_notes/release_17_05.rst
index cd95e35..50f70b8 100644
--- a/doc/guides/rel_notes/release_17_05.rst
+++ b/doc/guides/rel_notes/release_17_05.rst
@@ -133,6 +133,10 @@ New Features
   Data Ring, ability to register memory regions.
 
 
+* **Added dynamic device profile support for i40e.**
+
+  * Added loading dynamic device profile to i40e FW.
+
 Resolved Issues
 ---------------
 
-- 
2.5.5

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

* Re: [PATCH v6 2/6] net/i40e: add dynamic device profile processing
  2017-03-29 12:26             ` [PATCH v6 2/6] net/i40e: add dynamic device profile processing Beilei Xing
@ 2017-03-29 13:17               ` Wu, Jingjing
  2017-03-29 14:25                 ` Xing, Beilei
  0 siblings, 1 reply; 82+ messages in thread
From: Wu, Jingjing @ 2017-03-29 13:17 UTC (permalink / raw)
  To: Xing, Beilei; +Cc: Zhang, Helin, Iremonger, Bernard, dev

Looks good to me, only minor comments like below:

> -----Original Message-----
> From: Xing, Beilei
> Sent: Wednesday, March 29, 2017 8:27 PM
> To: Wu, Jingjing <jingjing.wu@intel.com>
> Cc: Zhang, Helin <helin.zhang@intel.com>; Iremonger, Bernard
> <bernard.iremonger@intel.com>; dev@dpdk.org
> Subject: [PATCH v6 2/6] net/i40e: add dynamic device profile processing
> 
> Add support for adding a dynamic device profile.
> 
> Signed-off-by: Beilei Xing <beilei.xing@intel.com>
> ---
>  drivers/net/i40e/i40e_ethdev.c            | 199
> ++++++++++++++++++++++++++++++
>  drivers/net/i40e/rte_pmd_i40e.h           |  58 +++++++++
>  drivers/net/i40e/rte_pmd_i40e_version.map |   1 +
>  3 files changed, 258 insertions(+)
> 
> diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
> index 2063603..764764f 100644
> --- a/drivers/net/i40e/i40e_ethdev.c
> +++ b/drivers/net/i40e/i40e_ethdev.c
> @@ -11708,3 +11708,202 @@ rte_pmd_i40e_set_tc_strict_prio(uint8_t port,
> uint8_t tc_map)
> 
>  	return ret;
>  }
> +
> +static void
> +i40e_generate_profile_info_sec(char *name, struct i40e_ddp_version *version,
> +			       uint32_t track_id, uint8_t *profile_info_sec,
> +			       bool add)
> +{
> +	struct i40e_profile_section_header *sec = NULL;
> +	struct i40e_profile_info *pinfo;
> +
> +	sec = (struct i40e_profile_section_header *)profile_info_sec;
> +	sec->tbl_size = 1;
> +	sec->data_end = sizeof(struct i40e_profile_section_header) +
> +		sizeof(struct i40e_profile_info);
> +	sec->section.type = SECTION_TYPE_INFO;
> +	sec->section.offset = sizeof(struct i40e_profile_section_header);
> +	sec->section.size = sizeof(struct i40e_profile_info);
> +	pinfo = (struct i40e_profile_info *)(profile_info_sec +
> +					     sec->section.offset);
> +	pinfo->track_id = track_id;
> +	memcpy(pinfo->name, name, I40E_DDP_NAME_SIZE);
> +	memcpy(&pinfo->version, version, sizeof(struct i40e_ddp_version));
> +	if (add)
> +		pinfo->op = I40E_DDP_ADD_TRACKID;
> +	else
> +		pinfo->op = I40E_DDP_REMOVE_TRACKID;
> +}
> +
> +static enum i40e_status_code
> +i40e_add_rm_profile_info(struct i40e_hw *hw, uint8_t *profile_info_sec)
> +{
> +	enum i40e_status_code status = I40E_SUCCESS;
> +	struct i40e_profile_section_header *sec;
> +	uint32_t track_id;
> +	uint32_t offset = 0, info = 0;

Cannot set more than one vars in one line according to the coding style.
uint32_t offset = 0;
uint32_t info = 0;



> +/* Check if the profile info exists */
> +static int
> +i40e_check_profile_info(uint8_t port, uint8_t *profile_info_sec) {
> +	struct rte_eth_dev *dev = &rte_eth_devices[port];
> +	struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data-
> >dev_private);
> +	uint8_t *buff;
> +	struct rte_pmd_i40e_profile_list *p_list;
> +	struct rte_pmd_i40e_profile_info *pinfo, *p;
> +	uint32_t i;
> +	int ret;
> +
> +	buff = rte_zmalloc("pinfo_list",
> +			   (I40E_PROFILE_INFO_SIZE *
> I40E_MAX_PROFILE_NUM + 4),
> +			   0);
> +	if (!buff) {
> +		PMD_DRV_LOG(ERR, "failed to allocate memory");
> +		return -1;
> +	}
> +
> +	ret = i40e_aq_get_ddp_list(hw, (void *)buff,
> +		      (I40E_PROFILE_INFO_SIZE * I40E_MAX_PROFILE_NUM + 4),
> +		      0, NULL);
> +	if (ret) {
> +		PMD_DRV_LOG(ERR, "Failed to get profile info list.");
> +		rte_free(buff);
> +		return -1;
> +	}
> +	p_list = (struct rte_pmd_i40e_profile_list *)buff;
> +	pinfo = (struct rte_pmd_i40e_profile_info *)(profile_info_sec +
> +			     sizeof(struct i40e_profile_section_header));
> +	for (i = 0; i < p_list->p_count; i++) {
> +		p = &p_list->p_info[i];
> +		if ((pinfo->track_id == p->track_id) &&
> +		    !memcmp(&pinfo->version, &p->version,
> +			    sizeof(struct i40e_ddp_version)) &&
> +		    !memcmp(&pinfo->name, &p->name,
> +			    I40E_DDP_NAME_SIZE)) {
> +			PMD_DRV_LOG(INFO, "Profile exists.");
> +			rte_free(buff);
> +			return 1;
> +		}
> +	}
> +
> +	rte_free(buff);
> +	return 0;
> +}
> +
> +int
> +rte_pmd_i40e_process_ddp_package(uint8_t port, uint8_t *buff,
> +				 uint32_t size,
> +				 enum rte_pmd_i40e_package_op op)
> +{
> +	struct rte_eth_dev *dev;
> +	struct i40e_hw *hw;
> +	struct i40e_package_header *pkg_hdr;
> +	struct i40e_generic_seg_header *profile_seg_hdr;
> +	struct i40e_generic_seg_header *metadata_seg_hdr;
> +	uint32_t track_id;
> +	uint8_t *profile_info_sec;
> +	int is_exist;
> +	enum i40e_status_code status = I40E_SUCCESS;
> +
> +	RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
> +
> +	dev = &rte_eth_devices[port];
> +
> +	if (!is_device_supported(dev, &rte_i40e_pmd))
> +		return -ENOTSUP;
> +
> +	hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
> +
> +	if (size < (sizeof(struct i40e_package_header) +
> +		    sizeof(struct i40e_metadata_segment) +
> +		    sizeof(uint32_t) * 2)) {
> +		PMD_DRV_LOG(ERR, "Buff is invalid.");
> +		return -EINVAL;
> +	}
> +
> +	pkg_hdr = (struct i40e_package_header *)buff;
> +
> +	if (!pkg_hdr) {
> +		PMD_DRV_LOG(ERR, "Failed to fill the package structure");
> +		return -EINVAL;
> +	}
> +
> +	if (pkg_hdr->segment_count < 2) {
> +		PMD_DRV_LOG(ERR, "Segment_count should be 2 at least.");
> +		return -EINVAL;
> +	}
> +
> +	/* Find metadata segment */
> +	metadata_seg_hdr =
> i40e_find_segment_in_package(SEGMENT_TYPE_METADATA,
> +							pkg_hdr);
> +	if (!metadata_seg_hdr) {
> +		PMD_DRV_LOG(ERR, "Failed to find metadata segment
> header");
> +		return -EINVAL;
> +	}
> +	track_id = ((struct i40e_metadata_segment
> +*)metadata_seg_hdr)->track_id;
> +
> +	/* Find profile segment */
> +	profile_seg_hdr = i40e_find_segment_in_package(SEGMENT_TYPE_I40E,
> +						       pkg_hdr);
> +	if (!profile_seg_hdr) {
> +		PMD_DRV_LOG(ERR, "Failed to find profile segment header");
> +		return -EINVAL;
> +	}
> +
> +	profile_info_sec = rte_zmalloc("i40e_profile_info",
> +			       sizeof(struct i40e_profile_section_header) +
> +			       sizeof(struct i40e_profile_info),
> +			       0);
> +	if (!profile_info_sec) {
> +		PMD_DRV_LOG(ERR, "Failed to allocate memory");
> +		return -EINVAL;
> +	}
> +
> +	if (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) {

The i40e_check_profile_info also has a return value like "-1".
It doesn't mean profile exists, right?

> +			PMD_DRV_LOG(ERR, "Profile already exists.");
> +			rte_free(profile_info_sec);
> +			return 1;
> +		}
> +
> +		/* Write profile to HW */
> +		status = i40e_write_profile(hw,
> +				 (struct i40e_profile_segment *)profile_seg_hdr,
> +				 track_id);
> +		if (status)
> +			PMD_DRV_LOG(ERR, "Failed to write profile.");
> +
> +		/* Add profile info to info list */
> +		status = i40e_add_rm_profile_info(hw, profile_info_sec);
If i40e_write_profile failed, do we still need to add profile info?

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

* Re: [PATCH v6 2/6] net/i40e: add dynamic device profile processing
  2017-03-29 13:17               ` Wu, Jingjing
@ 2017-03-29 14:25                 ` Xing, Beilei
  0 siblings, 0 replies; 82+ messages in thread
From: Xing, Beilei @ 2017-03-29 14:25 UTC (permalink / raw)
  To: Wu, Jingjing; +Cc: Zhang, Helin, Iremonger, Bernard, dev



> -----Original Message-----
> From: Wu, Jingjing
> Sent: Wednesday, March 29, 2017 9:17 PM
> To: Xing, Beilei <beilei.xing@intel.com>
> Cc: Zhang, Helin <helin.zhang@intel.com>; Iremonger, Bernard
> <bernard.iremonger@intel.com>; dev@dpdk.org
> Subject: RE: [PATCH v6 2/6] net/i40e: add dynamic device profile processing
> 
> Looks good to me, only minor comments like below:
> 
> > -----Original Message-----
> > From: Xing, Beilei
> > Sent: Wednesday, March 29, 2017 8:27 PM
> > To: Wu, Jingjing <jingjing.wu@intel.com>
> > Cc: Zhang, Helin <helin.zhang@intel.com>; Iremonger, Bernard
> > <bernard.iremonger@intel.com>; dev@dpdk.org
> > Subject: [PATCH v6 2/6] net/i40e: add dynamic device profile
> > processing
> >
> > Add support for adding a dynamic device profile.
> >
> > Signed-off-by: Beilei Xing <beilei.xing@intel.com>
> > ---
> >  drivers/net/i40e/i40e_ethdev.c            | 199
> > ++++++++++++++++++++++++++++++
> >  drivers/net/i40e/rte_pmd_i40e.h           |  58 +++++++++
> >  drivers/net/i40e/rte_pmd_i40e_version.map |   1 +
> >  3 files changed, 258 insertions(+)
> >
> > diff --git a/drivers/net/i40e/i40e_ethdev.c
> > b/drivers/net/i40e/i40e_ethdev.c index 2063603..764764f 100644
> > --- a/drivers/net/i40e/i40e_ethdev.c
> > +++ b/drivers/net/i40e/i40e_ethdev.c
> > @@ -11708,3 +11708,202 @@ rte_pmd_i40e_set_tc_strict_prio(uint8_t
> > port, uint8_t tc_map)
> >
> >  	return ret;
> >  }
> > +
> > +static void
> > +i40e_generate_profile_info_sec(char *name, struct i40e_ddp_version
> *version,
> > +			       uint32_t track_id, uint8_t *profile_info_sec,
> > +			       bool add)
> > +{
> > +	struct i40e_profile_section_header *sec = NULL;
> > +	struct i40e_profile_info *pinfo;
> > +
> > +	sec = (struct i40e_profile_section_header *)profile_info_sec;
> > +	sec->tbl_size = 1;
> > +	sec->data_end = sizeof(struct i40e_profile_section_header) +
> > +		sizeof(struct i40e_profile_info);
> > +	sec->section.type = SECTION_TYPE_INFO;
> > +	sec->section.offset = sizeof(struct i40e_profile_section_header);
> > +	sec->section.size = sizeof(struct i40e_profile_info);
> > +	pinfo = (struct i40e_profile_info *)(profile_info_sec +
> > +					     sec->section.offset);
> > +	pinfo->track_id = track_id;
> > +	memcpy(pinfo->name, name, I40E_DDP_NAME_SIZE);
> > +	memcpy(&pinfo->version, version, sizeof(struct i40e_ddp_version));
> > +	if (add)
> > +		pinfo->op = I40E_DDP_ADD_TRACKID;
> > +	else
> > +		pinfo->op = I40E_DDP_REMOVE_TRACKID; }
> > +
> > +static enum i40e_status_code
> > +i40e_add_rm_profile_info(struct i40e_hw *hw, uint8_t
> > +*profile_info_sec) {
> > +	enum i40e_status_code status = I40E_SUCCESS;
> > +	struct i40e_profile_section_header *sec;
> > +	uint32_t track_id;
> > +	uint32_t offset = 0, info = 0;
> 
> Cannot set more than one vars in one line according to the coding style.
> uint32_t offset = 0;
> uint32_t info = 0;
> 

OK, thanks.
> 
> 
> > +/* Check if the profile info exists */ static int
> > +i40e_check_profile_info(uint8_t port, uint8_t *profile_info_sec) {
> > +	struct rte_eth_dev *dev = &rte_eth_devices[port];
> > +	struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data-
> > >dev_private);
> > +	uint8_t *buff;
> > +	struct rte_pmd_i40e_profile_list *p_list;
> > +	struct rte_pmd_i40e_profile_info *pinfo, *p;
> > +	uint32_t i;
> > +	int ret;
> > +
> > +	buff = rte_zmalloc("pinfo_list",
> > +			   (I40E_PROFILE_INFO_SIZE *
> > I40E_MAX_PROFILE_NUM + 4),
> > +			   0);
> > +	if (!buff) {
> > +		PMD_DRV_LOG(ERR, "failed to allocate memory");
> > +		return -1;
> > +	}
> > +
> > +	ret = i40e_aq_get_ddp_list(hw, (void *)buff,
> > +		      (I40E_PROFILE_INFO_SIZE * I40E_MAX_PROFILE_NUM + 4),
> > +		      0, NULL);
> > +	if (ret) {
> > +		PMD_DRV_LOG(ERR, "Failed to get profile info list.");
> > +		rte_free(buff);
> > +		return -1;
> > +	}
> > +	p_list = (struct rte_pmd_i40e_profile_list *)buff;
> > +	pinfo = (struct rte_pmd_i40e_profile_info *)(profile_info_sec +
> > +			     sizeof(struct i40e_profile_section_header));
> > +	for (i = 0; i < p_list->p_count; i++) {
> > +		p = &p_list->p_info[i];
> > +		if ((pinfo->track_id == p->track_id) &&
> > +		    !memcmp(&pinfo->version, &p->version,
> > +			    sizeof(struct i40e_ddp_version)) &&
> > +		    !memcmp(&pinfo->name, &p->name,
> > +			    I40E_DDP_NAME_SIZE)) {
> > +			PMD_DRV_LOG(INFO, "Profile exists.");
> > +			rte_free(buff);
> > +			return 1;
> > +		}
> > +	}
> > +
> > +	rte_free(buff);
> > +	return 0;
> > +}
> > +
> > +int
> > +rte_pmd_i40e_process_ddp_package(uint8_t port, uint8_t *buff,
> > +				 uint32_t size,
> > +				 enum rte_pmd_i40e_package_op op) {
> > +	struct rte_eth_dev *dev;
> > +	struct i40e_hw *hw;
> > +	struct i40e_package_header *pkg_hdr;
> > +	struct i40e_generic_seg_header *profile_seg_hdr;
> > +	struct i40e_generic_seg_header *metadata_seg_hdr;
> > +	uint32_t track_id;
> > +	uint8_t *profile_info_sec;
> > +	int is_exist;
> > +	enum i40e_status_code status = I40E_SUCCESS;
> > +
> > +	RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
> > +
> > +	dev = &rte_eth_devices[port];
> > +
> > +	if (!is_device_supported(dev, &rte_i40e_pmd))
> > +		return -ENOTSUP;
> > +
> > +	hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
> > +
> > +	if (size < (sizeof(struct i40e_package_header) +
> > +		    sizeof(struct i40e_metadata_segment) +
> > +		    sizeof(uint32_t) * 2)) {
> > +		PMD_DRV_LOG(ERR, "Buff is invalid.");
> > +		return -EINVAL;
> > +	}
> > +
> > +	pkg_hdr = (struct i40e_package_header *)buff;
> > +
> > +	if (!pkg_hdr) {
> > +		PMD_DRV_LOG(ERR, "Failed to fill the package structure");
> > +		return -EINVAL;
> > +	}
> > +
> > +	if (pkg_hdr->segment_count < 2) {
> > +		PMD_DRV_LOG(ERR, "Segment_count should be 2 at least.");
> > +		return -EINVAL;
> > +	}
> > +
> > +	/* Find metadata segment */
> > +	metadata_seg_hdr =
> > i40e_find_segment_in_package(SEGMENT_TYPE_METADATA,
> > +							pkg_hdr);
> > +	if (!metadata_seg_hdr) {
> > +		PMD_DRV_LOG(ERR, "Failed to find metadata segment
> > header");
> > +		return -EINVAL;
> > +	}
> > +	track_id = ((struct i40e_metadata_segment
> > +*)metadata_seg_hdr)->track_id;
> > +
> > +	/* Find profile segment */
> > +	profile_seg_hdr = i40e_find_segment_in_package(SEGMENT_TYPE_I40E,
> > +						       pkg_hdr);
> > +	if (!profile_seg_hdr) {
> > +		PMD_DRV_LOG(ERR, "Failed to find profile segment header");
> > +		return -EINVAL;
> > +	}
> > +
> > +	profile_info_sec = rte_zmalloc("i40e_profile_info",
> > +			       sizeof(struct i40e_profile_section_header) +
> > +			       sizeof(struct i40e_profile_info),
> > +			       0);
> > +	if (!profile_info_sec) {
> > +		PMD_DRV_LOG(ERR, "Failed to allocate memory");
> > +		return -EINVAL;
> > +	}
> > +
> > +	if (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) {
> 
> The i40e_check_profile_info also has a return value like "-1".
> It doesn't mean profile exists, right?

Yes, only "1" means profile exists.

> 
> > +			PMD_DRV_LOG(ERR, "Profile already exists.");
> > +			rte_free(profile_info_sec);
> > +			return 1;
> > +		}
> > +
> > +		/* Write profile to HW */
> > +		status = i40e_write_profile(hw,
> > +				 (struct i40e_profile_segment *)profile_seg_hdr,
> > +				 track_id);
> > +		if (status)
> > +			PMD_DRV_LOG(ERR, "Failed to write profile.");
> > +
> > +		/* Add profile info to info list */
> > +		status = i40e_add_rm_profile_info(hw, profile_info_sec);
> If i40e_write_profile failed, do we still need to add profile info?
No, I missed the condition, thanks for catching it.

> 
> 

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

* [PATCH v7 0/6] dynamic device profile support
  2017-03-29 12:26           ` [PATCH v6 0/6] dynamic device profile support Beilei Xing
                               ` (5 preceding siblings ...)
  2017-03-29 12:26             ` [PATCH v6 6/6] doc: add dynamic device profile support for i40e Beilei Xing
@ 2017-03-29 14:44             ` Beilei Xing
  2017-03-29 14:44               ` [PATCH v7 1/6] net/i40e/base: change ppp to ddp Beilei Xing
                                 ` (6 more replies)
  6 siblings, 7 replies; 82+ messages in thread
From: Beilei Xing @ 2017-03-29 14:44 UTC (permalink / raw)
  To: jingjing.wu; +Cc: helin.zhang, dev

Due to limited resources of X*710 (parser and analyzer configuration
tables, number of packet classification types, number of packet types,
filters configuration tables, etc.), it's impossible to simultaneously
support all protocols/filters required for different parts on network.
To enable protocols/filters extensions for X*710, new Admin Command
for loading user defined configurations is added.
PPP is a format of extend configuration for X*710, it allows user to
load user defined configuration to X*710.

List of possible use cases for extended X*710 configuration using
profiles could include following:
Configuring Analyzer/Parser to support new protocols, e.g.
- IP L2TPv3 tunneling protocol
- IPSec ESP/AH protocols
- MPLSoGRE, MPLSoUDP tunnels
- GTP-C/GTP-U tunnels
New PCTYPEs for offloading packet classification to X*710. e.g.
- new IP Protocol in addition to TCP/UDP/SCTP
- new TCP/UDP subtypes, like TCP SYN, TCP FIN
- new PCTYPE for tunneled packets like GTP-C, GTP-U
New PTYPEs for packets identification, e.g.
- MAC, MPLS, IP4, UDP
- MAC, MPLS, MPLS, IP6, TCP
Fixes for NVM configuration, e.g.
- list of enabled stat counters to improve throughput
- parser/analyzer configuration for some corner cases

v7 changes:
 Fix one coding style problem.
 Add condition during ddp processing.

v6 changes:
 Change pipeline personalization profile to dynamic device profile.

v5 changes:
 Change parameter of rte_pmd_i40e_process_ppp_package to extend operation.
 Change structure rte_pmd_i40e_profile_info.

v4 changes:
 Fix compile error with gcc version 4.8.4 (Ubuntu 4.8.4-2ubuntu1~14.04.3).
 Move ppp related structures to rte_pmd_i40e.h.
 Not support remove PPP temporarily.

v3 changes:
 Move ppp AQ command code to base code.

Beilei Xing (6):
  net/i40e/base: change ppp to ddp
  net/i40e: add dynamic device profile processing
  app/testpmd: add command for loading a profile
  net/i40e: add get all loaded profiles
  app/testpmd: add command for getting loaded profiles
  doc: add dynamic device profile support for i40e

 app/test-pmd/cmdline.c                    | 164 +++++++++++++++++++++
 app/test-pmd/config.c                     |  67 +++++++++
 app/test-pmd/testpmd.h                    |   3 +
 doc/guides/rel_notes/release_17_05.rst    |   4 +
 drivers/net/i40e/base/i40e_adminq_cmd.h   |  18 +--
 drivers/net/i40e/base/i40e_common.c       |  32 ++--
 drivers/net/i40e/base/i40e_prototype.h    |   4 +-
 drivers/net/i40e/base/i40e_type.h         |  28 ++--
 drivers/net/i40e/i40e_ethdev.c            | 235 ++++++++++++++++++++++++++++++
 drivers/net/i40e/rte_pmd_i40e.h           |  70 +++++++++
 drivers/net/i40e/rte_pmd_i40e_version.map |   2 +
 11 files changed, 586 insertions(+), 41 deletions(-)

-- 
2.5.5

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

* [PATCH v7 1/6] net/i40e/base: change ppp to ddp
  2017-03-29 14:44             ` [PATCH v7 0/6] dynamic device profile support Beilei Xing
@ 2017-03-29 14:44               ` Beilei Xing
  2017-03-29 14:44               ` [PATCH v7 2/6] net/i40e: add dynamic device profile processing Beilei Xing
                                 ` (5 subsequent siblings)
  6 siblings, 0 replies; 82+ messages in thread
From: Beilei Xing @ 2017-03-29 14:44 UTC (permalink / raw)
  To: jingjing.wu; +Cc: helin.zhang, dev

Change pipeline personalization profile(ppp) to dynamic
device profile(ddp).

Signed-off-by: Beilei Xing <beilei.xing@intel.com>
---
 drivers/net/i40e/base/i40e_adminq_cmd.h | 18 +++++++++---------
 drivers/net/i40e/base/i40e_common.c     | 32 ++++++++++++++++----------------
 drivers/net/i40e/base/i40e_prototype.h  |  4 ++--
 drivers/net/i40e/base/i40e_type.h       | 28 ++++++++++++++--------------
 4 files changed, 41 insertions(+), 41 deletions(-)

diff --git a/drivers/net/i40e/base/i40e_adminq_cmd.h b/drivers/net/i40e/base/i40e_adminq_cmd.h
index 8fb3725..fdc6555 100644
--- a/drivers/net/i40e/base/i40e_adminq_cmd.h
+++ b/drivers/net/i40e/base/i40e_adminq_cmd.h
@@ -199,9 +199,9 @@ enum i40e_admin_queue_opc {
 	i40e_aqc_opc_add_mirror_rule	= 0x0260,
 	i40e_aqc_opc_delete_mirror_rule	= 0x0261,
 
-	/* Pipeline Personalization Profile */
-	i40e_aqc_opc_write_personalization_profile	= 0x0270,
-	i40e_aqc_opc_get_personalization_profile_list	= 0x0271,
+	/* Dynamic Device Profile */
+	i40e_aqc_opc_write_dynamic_device_profile	= 0x0270,
+	i40e_aqc_opc_get_dynamic_device_profile_list	= 0x0271,
 
 	/* DCB commands */
 	i40e_aqc_opc_dcb_ignore_pfc	= 0x0301,
@@ -1538,8 +1538,8 @@ struct i40e_aqc_add_delete_mirror_rule_completion {
 
 I40E_CHECK_CMD_LENGTH(i40e_aqc_add_delete_mirror_rule_completion);
 
-/* Pipeline Personalization Profile */
-struct i40e_aqc_write_personalization_profile {
+/* Dynamic Device Profile */
+struct i40e_aqc_write_dynamic_device_profile {
 	u8      flags;
 	u8      reserved[3];
 	__le32  profile_track_id;
@@ -1547,9 +1547,9 @@ struct i40e_aqc_write_personalization_profile {
 	__le32  addr_low;
 };
 
-I40E_CHECK_CMD_LENGTH(i40e_aqc_write_personalization_profile);
+I40E_CHECK_CMD_LENGTH(i40e_aqc_write_dynamic_device_profile);
 
-struct i40e_aqc_write_ppp_resp {
+struct i40e_aqc_write_ddp_resp {
 	__le32 error_offset;
 	__le32 error_info;
 	__le32 addr_high;
@@ -1558,8 +1558,8 @@ struct i40e_aqc_write_ppp_resp {
 
 struct i40e_aqc_get_applied_profiles {
 	u8      flags;
-#define I40E_AQC_GET_PPP_GET_CONF	0x1
-#define I40E_AQC_GET_PPP_GET_RDPU_CONF	0x2
+#define I40E_AQC_GET_DDP_GET_CONF	0x1
+#define I40E_AQC_GET_DDP_GET_RDPU_CONF	0x2
 	u8      rsv[3];
 	__le32  reserved;
 	__le32  addr_high;
diff --git a/drivers/net/i40e/base/i40e_common.c b/drivers/net/i40e/base/i40e_common.c
index 33ad49c..b5939ee 100644
--- a/drivers/net/i40e/base/i40e_common.c
+++ b/drivers/net/i40e/base/i40e_common.c
@@ -7155,7 +7155,7 @@ enum i40e_status_code i40e_aq_clear_all_wol_filters(struct i40e_hw *hw,
 
 
 /**
- * i40e_aq_write_ppp - Write pipeline personalization profile (ppp)
+ * i40e_aq_write_ddp - Write dynamic device profile (ddp)
  * @hw: pointer to the hw struct
  * @buff: command buffer (size in bytes = buff_size)
  * @buff_size: buffer size in bytes
@@ -7165,20 +7165,20 @@ enum i40e_status_code i40e_aq_clear_all_wol_filters(struct i40e_hw *hw,
  * @cmd_details: pointer to command details structure or NULL
  **/
 enum
-i40e_status_code i40e_aq_write_ppp(struct i40e_hw *hw, void *buff,
+i40e_status_code i40e_aq_write_ddp(struct i40e_hw *hw, void *buff,
 				   u16 buff_size, u32 track_id,
 				   u32 *error_offset, u32 *error_info,
 				   struct i40e_asq_cmd_details *cmd_details)
 {
 	struct i40e_aq_desc desc;
-	struct i40e_aqc_write_personalization_profile *cmd =
-		(struct i40e_aqc_write_personalization_profile *)
+	struct i40e_aqc_write_dynamic_device_profile *cmd =
+		(struct i40e_aqc_write_dynamic_device_profile *)
 		&desc.params.raw;
-	struct i40e_aqc_write_ppp_resp *resp;
+	struct i40e_aqc_write_ddp_resp *resp;
 	enum i40e_status_code status;
 
 	i40e_fill_default_direct_cmd_desc(&desc,
-				  i40e_aqc_opc_write_personalization_profile);
+				  i40e_aqc_opc_write_dynamic_device_profile);
 
 	desc.flags |= CPU_TO_LE16(I40E_AQ_FLAG_BUF | I40E_AQ_FLAG_RD);
 	if (buff_size > I40E_AQ_LARGE_BUF)
@@ -7190,7 +7190,7 @@ i40e_status_code i40e_aq_write_ppp(struct i40e_hw *hw, void *buff,
 
 	status = i40e_asq_send_command(hw, &desc, buff, buff_size, cmd_details);
 	if (!status) {
-		resp = (struct i40e_aqc_write_ppp_resp *)&desc.params.raw;
+		resp = (struct i40e_aqc_write_ddp_resp *)&desc.params.raw;
 		if (error_offset)
 			*error_offset = LE32_TO_CPU(resp->error_offset);
 		if (error_info)
@@ -7201,14 +7201,14 @@ i40e_status_code i40e_aq_write_ppp(struct i40e_hw *hw, void *buff,
 }
 
 /**
- * i40e_aq_get_ppp_list - Read pipeline personalization profile (ppp)
+ * i40e_aq_get_ddp_list - Read dynamic device profile (ddp)
  * @hw: pointer to the hw struct
  * @buff: command buffer (size in bytes = buff_size)
  * @buff_size: buffer size in bytes
  * @cmd_details: pointer to command details structure or NULL
  **/
 enum
-i40e_status_code i40e_aq_get_ppp_list(struct i40e_hw *hw, void *buff,
+i40e_status_code i40e_aq_get_ddp_list(struct i40e_hw *hw, void *buff,
 				      u16 buff_size, u8 flags,
 				      struct i40e_asq_cmd_details *cmd_details)
 {
@@ -7218,7 +7218,7 @@ i40e_status_code i40e_aq_get_ppp_list(struct i40e_hw *hw, void *buff,
 	enum i40e_status_code status;
 
 	i40e_fill_default_direct_cmd_desc(&desc,
-			  i40e_aqc_opc_get_personalization_profile_list);
+			  i40e_aqc_opc_get_dynamic_device_profile_list);
 
 	desc.flags |= CPU_TO_LE16((u16)I40E_AQ_FLAG_BUF);
 	if (buff_size > I40E_AQ_LARGE_BUF)
@@ -7297,7 +7297,7 @@ i40e_write_profile(struct i40e_hw *hw, struct i40e_profile_segment *profile,
 				break;
 	}
 	if (i == dev_cnt) {
-		i40e_debug(hw, I40E_DEBUG_PACKAGE, "Device doesn't support PPP");
+		i40e_debug(hw, I40E_DEBUG_PACKAGE, "Device doesn't support DDP");
 		return I40E_ERR_DEVICE_NOT_SUPPORTED;
 	}
 
@@ -7316,7 +7316,7 @@ i40e_write_profile(struct i40e_hw *hw, struct i40e_profile_segment *profile,
 			sizeof(struct i40e_profile_section_header);
 
 		/* Write profile */
-		status = i40e_aq_write_ppp(hw, (void *)sec, (u16)section_size,
+		status = i40e_aq_write_ddp(hw, (void *)sec, (u16)section_size,
 					   track_id, &offset, &info, NULL);
 		if (status) {
 			i40e_debug(hw, I40E_DEBUG_PACKAGE,
@@ -7358,10 +7358,10 @@ i40e_add_pinfo_to_list(struct i40e_hw *hw,
 					     sec->section.offset);
 	pinfo->track_id = track_id;
 	pinfo->version = profile->version;
-	pinfo->op = I40E_PPP_ADD_TRACKID;
-	memcpy(pinfo->name, profile->name, I40E_PPP_NAME_SIZE);
+	pinfo->op = I40E_DDP_ADD_TRACKID;
+	memcpy(pinfo->name, profile->name, I40E_DDP_NAME_SIZE);
 
-	status = i40e_aq_write_ppp(hw, (void *)sec, sec->data_end,
+	status = i40e_aq_write_ddp(hw, (void *)sec, sec->data_end,
 				track_id, &offset, &info, NULL);
 	return status;
-}
\ No newline at end of file
+}
diff --git a/drivers/net/i40e/base/i40e_prototype.h b/drivers/net/i40e/base/i40e_prototype.h
index 8662147..4bd589e 100644
--- a/drivers/net/i40e/base/i40e_prototype.h
+++ b/drivers/net/i40e/base/i40e_prototype.h
@@ -565,11 +565,11 @@ enum i40e_status_code i40e_write_phy_register(struct i40e_hw *hw,
 u8 i40e_get_phy_address(struct i40e_hw *hw, u8 dev_num);
 enum i40e_status_code i40e_blink_phy_link_led(struct i40e_hw *hw,
 					      u32 time, u32 interval);
-enum i40e_status_code i40e_aq_write_ppp(struct i40e_hw *hw, void *buff,
+enum i40e_status_code i40e_aq_write_ddp(struct i40e_hw *hw, void *buff,
 				u16 buff_size, u32 track_id,
 				u32 *error_offset, u32 *error_info,
 				struct i40e_asq_cmd_details *cmd_details);
-enum i40e_status_code i40e_aq_get_ppp_list(struct i40e_hw *hw, void *buff,
+enum i40e_status_code i40e_aq_get_ddp_list(struct i40e_hw *hw, void *buff,
 				   u16 buff_size, u8 flags,
 				   struct i40e_asq_cmd_details *cmd_details);
 struct i40e_generic_seg_header *
diff --git a/drivers/net/i40e/base/i40e_type.h b/drivers/net/i40e/base/i40e_type.h
index fc81a93..b1ca47b 100644
--- a/drivers/net/i40e/base/i40e_type.h
+++ b/drivers/net/i40e/base/i40e_type.h
@@ -1880,19 +1880,19 @@ struct i40e_lldp_variables {
 #define I40E_FLEX_57_SHIFT		6
 #define I40E_FLEX_57_MASK		(0x1ULL << I40E_FLEX_57_SHIFT)
 
-/* Version format for PPP */
-struct i40e_ppp_version {
+/* Version format for DDP */
+struct i40e_ddp_version {
 	u8 major;
 	u8 minor;
 	u8 update;
 	u8 draft;
 };
 
-#define I40E_PPP_NAME_SIZE	32
+#define I40E_DDP_NAME_SIZE	32
 
 /* Package header */
 struct i40e_package_header {
-	struct i40e_ppp_version version;
+	struct i40e_ddp_version version;
 	u32 segment_count;
 	u32 segment_offset[1];
 };
@@ -1904,16 +1904,16 @@ struct i40e_generic_seg_header {
 #define SEGMENT_TYPE_I40E	0x00000011
 #define SEGMENT_TYPE_X722	0x00000012
 	u32 type;
-	struct i40e_ppp_version version;
+	struct i40e_ddp_version version;
 	u32 size;
-	char name[I40E_PPP_NAME_SIZE];
+	char name[I40E_DDP_NAME_SIZE];
 };
 
 struct i40e_metadata_segment {
 	struct i40e_generic_seg_header header;
-	struct i40e_ppp_version version;
+	struct i40e_ddp_version version;
 	u32 track_id;
-	char     name[I40E_PPP_NAME_SIZE];
+	char     name[I40E_DDP_NAME_SIZE];
 };
 
 struct i40e_device_id_entry {
@@ -1923,8 +1923,8 @@ struct i40e_device_id_entry {
 
 struct i40e_profile_segment {
 	struct i40e_generic_seg_header header;
-	struct i40e_ppp_version version;
-	char name[I40E_PPP_NAME_SIZE];
+	struct i40e_ddp_version version;
+	char name[I40E_DDP_NAME_SIZE];
 	u32 device_table_count;
 	struct i40e_device_id_entry device_table[1];
 };
@@ -1951,11 +1951,11 @@ struct i40e_profile_section_header {
 
 struct i40e_profile_info {
 	u32 track_id;
-	struct i40e_ppp_version version;
+	struct i40e_ddp_version version;
 	u8 op;
-#define I40E_PPP_ADD_TRACKID		0x01
-#define I40E_PPP_REMOVE_TRACKID	0x02
+#define I40E_DDP_ADD_TRACKID		0x01
+#define I40E_DDP_REMOVE_TRACKID	0x02
 	u8 reserved[7];
-	u8 name[I40E_PPP_NAME_SIZE];
+	u8 name[I40E_DDP_NAME_SIZE];
 };
 #endif /* _I40E_TYPE_H_ */
-- 
2.5.5

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

* [PATCH v7 2/6] net/i40e: add dynamic device profile processing
  2017-03-29 14:44             ` [PATCH v7 0/6] dynamic device profile support Beilei Xing
  2017-03-29 14:44               ` [PATCH v7 1/6] net/i40e/base: change ppp to ddp Beilei Xing
@ 2017-03-29 14:44               ` Beilei Xing
  2017-03-29 14:44               ` [PATCH v7 3/6] app/testpmd: add command for loading a profile Beilei Xing
                                 ` (4 subsequent siblings)
  6 siblings, 0 replies; 82+ messages in thread
From: Beilei Xing @ 2017-03-29 14:44 UTC (permalink / raw)
  To: jingjing.wu; +Cc: helin.zhang, dev

Add support for adding a dynamic device profile.

Signed-off-by: Beilei Xing <beilei.xing@intel.com>
---
 drivers/net/i40e/i40e_ethdev.c            | 207 ++++++++++++++++++++++++++++++
 drivers/net/i40e/rte_pmd_i40e.h           |  58 +++++++++
 drivers/net/i40e/rte_pmd_i40e_version.map |   1 +
 3 files changed, 266 insertions(+)

diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index 2063603..bd0ba78 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -11708,3 +11708,210 @@ rte_pmd_i40e_set_tc_strict_prio(uint8_t port, uint8_t tc_map)
 
 	return ret;
 }
+
+static void
+i40e_generate_profile_info_sec(char *name, struct i40e_ddp_version *version,
+			       uint32_t track_id, uint8_t *profile_info_sec,
+			       bool add)
+{
+	struct i40e_profile_section_header *sec = NULL;
+	struct i40e_profile_info *pinfo;
+
+	sec = (struct i40e_profile_section_header *)profile_info_sec;
+	sec->tbl_size = 1;
+	sec->data_end = sizeof(struct i40e_profile_section_header) +
+		sizeof(struct i40e_profile_info);
+	sec->section.type = SECTION_TYPE_INFO;
+	sec->section.offset = sizeof(struct i40e_profile_section_header);
+	sec->section.size = sizeof(struct i40e_profile_info);
+	pinfo = (struct i40e_profile_info *)(profile_info_sec +
+					     sec->section.offset);
+	pinfo->track_id = track_id;
+	memcpy(pinfo->name, name, I40E_DDP_NAME_SIZE);
+	memcpy(&pinfo->version, version, sizeof(struct i40e_ddp_version));
+	if (add)
+		pinfo->op = I40E_DDP_ADD_TRACKID;
+	else
+		pinfo->op = I40E_DDP_REMOVE_TRACKID;
+}
+
+static enum i40e_status_code
+i40e_add_rm_profile_info(struct i40e_hw *hw, uint8_t *profile_info_sec)
+{
+	enum i40e_status_code status = I40E_SUCCESS;
+	struct i40e_profile_section_header *sec;
+	uint32_t track_id;
+	uint32_t offset = 0;
+	uint32_t info = 0;
+
+	sec = (struct i40e_profile_section_header *)profile_info_sec;
+	track_id = ((struct i40e_profile_info *)(profile_info_sec +
+					 sec->section.offset))->track_id;
+
+	status = i40e_aq_write_ddp(hw, (void *)sec, sec->data_end,
+				   track_id, &offset, &info, NULL);
+	if (status)
+		PMD_DRV_LOG(ERR, "Failed to add/remove profile info: "
+			    "offset %d, info %d",
+			    offset, info);
+
+	return status;
+}
+
+#define I40E_PROFILE_INFO_SIZE 48
+#define I40E_MAX_PROFILE_NUM 16
+
+/* Check if the profile info exists */
+static int
+i40e_check_profile_info(uint8_t port, uint8_t *profile_info_sec)
+{
+	struct rte_eth_dev *dev = &rte_eth_devices[port];
+	struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+	uint8_t *buff;
+	struct rte_pmd_i40e_profile_list *p_list;
+	struct rte_pmd_i40e_profile_info *pinfo, *p;
+	uint32_t i;
+	int ret;
+
+	buff = rte_zmalloc("pinfo_list",
+			   (I40E_PROFILE_INFO_SIZE * I40E_MAX_PROFILE_NUM + 4),
+			   0);
+	if (!buff) {
+		PMD_DRV_LOG(ERR, "failed to allocate memory");
+		return -1;
+	}
+
+	ret = i40e_aq_get_ddp_list(hw, (void *)buff,
+		      (I40E_PROFILE_INFO_SIZE * I40E_MAX_PROFILE_NUM + 4),
+		      0, NULL);
+	if (ret) {
+		PMD_DRV_LOG(ERR, "Failed to get profile info list.");
+		rte_free(buff);
+		return -1;
+	}
+	p_list = (struct rte_pmd_i40e_profile_list *)buff;
+	pinfo = (struct rte_pmd_i40e_profile_info *)(profile_info_sec +
+			     sizeof(struct i40e_profile_section_header));
+	for (i = 0; i < p_list->p_count; i++) {
+		p = &p_list->p_info[i];
+		if ((pinfo->track_id == p->track_id) &&
+		    !memcmp(&pinfo->version, &p->version,
+			    sizeof(struct i40e_ddp_version)) &&
+		    !memcmp(&pinfo->name, &p->name,
+			    I40E_DDP_NAME_SIZE)) {
+			PMD_DRV_LOG(INFO, "Profile exists.");
+			rte_free(buff);
+			return 1;
+		}
+	}
+
+	rte_free(buff);
+	return 0;
+}
+
+int
+rte_pmd_i40e_process_ddp_package(uint8_t port, uint8_t *buff,
+				 uint32_t size,
+				 enum rte_pmd_i40e_package_op op)
+{
+	struct rte_eth_dev *dev;
+	struct i40e_hw *hw;
+	struct i40e_package_header *pkg_hdr;
+	struct i40e_generic_seg_header *profile_seg_hdr;
+	struct i40e_generic_seg_header *metadata_seg_hdr;
+	uint32_t track_id;
+	uint8_t *profile_info_sec;
+	int is_exist;
+	enum i40e_status_code status = I40E_SUCCESS;
+
+	RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
+
+	dev = &rte_eth_devices[port];
+
+	if (!is_device_supported(dev, &rte_i40e_pmd))
+		return -ENOTSUP;
+
+	hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+
+	if (size < (sizeof(struct i40e_package_header) +
+		    sizeof(struct i40e_metadata_segment) +
+		    sizeof(uint32_t) * 2)) {
+		PMD_DRV_LOG(ERR, "Buff is invalid.");
+		return -EINVAL;
+	}
+
+	pkg_hdr = (struct i40e_package_header *)buff;
+
+	if (!pkg_hdr) {
+		PMD_DRV_LOG(ERR, "Failed to fill the package structure");
+		return -EINVAL;
+	}
+
+	if (pkg_hdr->segment_count < 2) {
+		PMD_DRV_LOG(ERR, "Segment_count should be 2 at least.");
+		return -EINVAL;
+	}
+
+	/* Find metadata segment */
+	metadata_seg_hdr = i40e_find_segment_in_package(SEGMENT_TYPE_METADATA,
+							pkg_hdr);
+	if (!metadata_seg_hdr) {
+		PMD_DRV_LOG(ERR, "Failed to find metadata segment header");
+		return -EINVAL;
+	}
+	track_id = ((struct i40e_metadata_segment *)metadata_seg_hdr)->track_id;
+
+	/* Find profile segment */
+	profile_seg_hdr = i40e_find_segment_in_package(SEGMENT_TYPE_I40E,
+						       pkg_hdr);
+	if (!profile_seg_hdr) {
+		PMD_DRV_LOG(ERR, "Failed to find profile segment header");
+		return -EINVAL;
+	}
+
+	profile_info_sec = rte_zmalloc("i40e_profile_info",
+			       sizeof(struct i40e_profile_section_header) +
+			       sizeof(struct i40e_profile_info),
+			       0);
+	if (!profile_info_sec) {
+		PMD_DRV_LOG(ERR, "Failed to allocate memory");
+		return -EINVAL;
+	}
+
+	if (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) {
+			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.");
+			rte_free(profile_info_sec);
+			return -EINVAL;
+		}
+
+		/* Write profile to HW */
+		status = i40e_write_profile(hw,
+				 (struct i40e_profile_segment *)profile_seg_hdr,
+				 track_id);
+		if (status) {
+			PMD_DRV_LOG(ERR, "Failed to write profile.");
+			rte_free(profile_info_sec);
+			return status;
+		}
+
+		/* Add profile info to info list */
+		status = i40e_add_rm_profile_info(hw, profile_info_sec);
+		if (status)
+			PMD_DRV_LOG(ERR, "Failed to add profile info.");
+	} else
+		PMD_DRV_LOG(ERR, "Operation not supported.");
+
+	rte_free(profile_info_sec);
+	return status;
+}
diff --git a/drivers/net/i40e/rte_pmd_i40e.h b/drivers/net/i40e/rte_pmd_i40e.h
index 3ca49a4..38a11f3 100644
--- a/drivers/net/i40e/rte_pmd_i40e.h
+++ b/drivers/net/i40e/rte_pmd_i40e.h
@@ -65,6 +65,43 @@ struct rte_pmd_i40e_mb_event_param {
 	uint16_t msglen;   /**< length of the message */
 };
 
+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_MAX = 32
+};
+
+#define RTE_PMD_I40E_DDP_NAME_SIZE 32
+
+/**
+ * Dynamic device profile version
+ */
+struct rte_pmd_i40e_ddp_version {
+	uint8_t major;
+	uint8_t minor;
+	uint8_t update;
+	uint8_t draft;
+};
+
+/**
+ * Structure of profile information
+ */
+struct rte_pmd_i40e_profile_info {
+	uint32_t track_id;
+	struct rte_pmd_i40e_ddp_version version;
+	uint8_t owner;
+	uint8_t reserved[7];
+	uint8_t name[RTE_PMD_I40E_DDP_NAME_SIZE];
+};
+
+/**
+ * Structure of profile information list
+ */
+struct rte_pmd_i40e_profile_list {
+	uint32_t p_count;
+	struct rte_pmd_i40e_profile_info p_info[1];
+};
+
 /**
  * Notify VF when PF link status changes.
  *
@@ -418,4 +455,25 @@ int rte_pmd_i40e_set_vf_tc_max_bw(uint8_t port,
  */
 int rte_pmd_i40e_set_tc_strict_prio(uint8_t port, uint8_t tc_map);
 
+/**
+ * Load/Unload a ddp package
+ *
+ * @param port
+ *    The port identifier of the Ethernet device.
+ * @param buff
+ *    buffer of package.
+ * @param size
+ *    size of buffer.
+ * @param op
+ *   Operation of package processing
+ * @return
+ *   - (0) if successful.
+ *   - (-ENODEV) if *port* invalid.
+ *   - (-EINVAL) if bad parameter.
+ *   - (1) if profile exists.
+ */
+int rte_pmd_i40e_process_ddp_package(uint8_t port, uint8_t *buff,
+				     uint32_t size,
+				     enum rte_pmd_i40e_package_op op);
+
 #endif /* _PMD_I40E_H_ */
diff --git a/drivers/net/i40e/rte_pmd_i40e_version.map b/drivers/net/i40e/rte_pmd_i40e_version.map
index 488e6b6..6d001a3 100644
--- a/drivers/net/i40e/rte_pmd_i40e_version.map
+++ b/drivers/net/i40e/rte_pmd_i40e_version.map
@@ -30,5 +30,6 @@ DPDK_17.05 {
 	rte_pmd_i40e_set_vf_max_bw;
 	rte_pmd_i40e_set_vf_tc_bw_alloc;
 	rte_pmd_i40e_set_vf_tc_max_bw;
+	rte_pmd_i40e_process_ddp_package;
 
 } DPDK_17.02;
-- 
2.5.5

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

* [PATCH v7 3/6] app/testpmd: add command for loading a profile
  2017-03-29 14:44             ` [PATCH v7 0/6] dynamic device profile support Beilei Xing
  2017-03-29 14:44               ` [PATCH v7 1/6] net/i40e/base: change ppp to ddp Beilei Xing
  2017-03-29 14:44               ` [PATCH v7 2/6] net/i40e: add dynamic device profile processing Beilei Xing
@ 2017-03-29 14:44               ` Beilei Xing
  2017-03-29 14:44               ` [PATCH v7 4/6] net/i40e: add get all loaded profiles Beilei Xing
                                 ` (3 subsequent siblings)
  6 siblings, 0 replies; 82+ messages in thread
From: Beilei Xing @ 2017-03-29 14:44 UTC (permalink / raw)
  To: jingjing.wu; +Cc: helin.zhang, dev

This patch is to add testpmd CLI for loading a dynamic
device profile.

Signed-off-by: Beilei Xing <beilei.xing@intel.com>
---
 app/test-pmd/cmdline.c | 73 ++++++++++++++++++++++++++++++++++++++++++++++++++
 app/test-pmd/config.c  | 67 +++++++++++++++++++++++++++++++++++++++++++++
 app/test-pmd/testpmd.h |  3 +++
 3 files changed, 143 insertions(+)

diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
index b93b096..42d0b24 100644
--- a/app/test-pmd/cmdline.c
+++ b/app/test-pmd/cmdline.c
@@ -590,6 +590,9 @@ 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"
 
+			"add ddp (port_id) (profile_path)\n"
+			"    Load a profile package on a port\n\n"
+
 			, list_pkt_forwarding_modes()
 		);
 	}
@@ -12739,6 +12742,75 @@ cmdline_parse_inst_t cmd_strict_link_prio = {
 	},
 };
 
+/* Load Dynamic Device Profile */
+struct cmd_add_ddp_result {
+	cmdline_fixed_string_t add;
+	cmdline_fixed_string_t ddp;
+	uint8_t port_id;
+	char filepath[];
+};
+
+cmdline_parse_token_string_t cmd_add_ddp_add =
+	TOKEN_STRING_INITIALIZER(struct cmd_add_ddp_result, add, "add");
+cmdline_parse_token_string_t cmd_add_ddp_ddp =
+	TOKEN_STRING_INITIALIZER(struct cmd_add_ddp_result, ddp, "ddp");
+cmdline_parse_token_num_t cmd_add_ddp_port_id =
+	TOKEN_NUM_INITIALIZER(struct cmd_add_ddp_result, port_id, UINT8);
+cmdline_parse_token_string_t cmd_add_ddp_filepath =
+	TOKEN_STRING_INITIALIZER(struct cmd_add_ddp_result, filepath, NULL);
+
+static void
+cmd_add_ddp_parsed(
+	void *parsed_result,
+	__attribute__((unused)) struct cmdline *cl,
+	__attribute__((unused)) void *data)
+{
+	struct cmd_add_ddp_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_ADD);
+#endif
+
+	if (ret < 0)
+		printf("Failed to load profile.\n");
+	else if (ret > 0)
+		printf("Profile has already existed.\n");
+
+	close_ddp_package_file(buff);
+}
+
+cmdline_parse_inst_t cmd_add_ddp = {
+	.f = cmd_add_ddp_parsed,
+	.data = NULL,
+	.help_str = "add/remove ddp <port_id> <profile_path>",
+	.tokens = {
+		(void *)&cmd_add_ddp_add,
+		(void *)&cmd_add_ddp_ddp,
+		(void *)&cmd_add_ddp_port_id,
+		(void *)&cmd_add_ddp_filepath,
+		NULL,
+	},
+};
 
 /* ******************************************************************************** */
 
@@ -12919,6 +12991,7 @@ cmdline_parse_ctx_t main_ctx[] = {
 	(cmdline_parse_inst_t *)&cmd_vf_tc_min_bw,
 	(cmdline_parse_inst_t *)&cmd_vf_tc_max_bw,
 	(cmdline_parse_inst_t *)&cmd_strict_link_prio,
+	(cmdline_parse_inst_t *)&cmd_add_ddp,
 	NULL,
 };
 
diff --git a/app/test-pmd/config.c b/app/test-pmd/config.c
index 80491fc..9865bf1 100644
--- a/app/test-pmd/config.c
+++ b/app/test-pmd/config.c
@@ -3245,3 +3245,70 @@ port_dcb_info_display(uint8_t port_id)
 		printf("\t%4d", dcb_info.tc_queue.tc_txq[0][i].nb_queue);
 	printf("\n");
 }
+
+uint8_t *
+open_ddp_package_file(const char *file_path, uint32_t *size)
+{
+	FILE *fh = fopen(file_path, "rb");
+	uint32_t pkg_size;
+	uint8_t *buf = NULL;
+	int ret = 0;
+
+	if (size)
+		*size = 0;
+
+	if (fh == NULL) {
+		printf("%s: Failed to open %s\n", __func__, file_path);
+		return buf;
+	}
+
+	ret = fseek(fh, 0, SEEK_END);
+	if (ret < 0) {
+		fclose(fh);
+		printf("%s: File operations failed\n", __func__);
+		return buf;
+	}
+
+	pkg_size = ftell(fh);
+
+	buf = (uint8_t *)malloc(pkg_size);
+	if (!buf) {
+		fclose(fh);
+		printf("%s: Failed to malloc memory\n",	__func__);
+		return buf;
+	}
+
+	ret = fseek(fh, 0, SEEK_SET);
+	if (ret < 0) {
+		fclose(fh);
+		printf("%s: File seek operation failed\n", __func__);
+		close_ddp_package_file(buf);
+		return NULL;
+	}
+
+	ret = fread(buf, 1, pkg_size, fh);
+	if (ret < 0) {
+		fclose(fh);
+		printf("%s: File read operation failed\n", __func__);
+		close_ddp_package_file(buf);
+		return NULL;
+	}
+
+	if (size)
+		*size = pkg_size;
+
+	fclose(fh);
+
+	return buf;
+}
+
+int
+close_ddp_package_file(uint8_t *buf)
+{
+	if (buf) {
+		free((void *)buf);
+		return 0;
+	}
+
+	return -1;
+}
diff --git a/app/test-pmd/testpmd.h b/app/test-pmd/testpmd.h
index 8cf2860..5c18151 100644
--- a/app/test-pmd/testpmd.h
+++ b/app/test-pmd/testpmd.h
@@ -622,6 +622,9 @@ void mcast_addr_add(uint8_t port_id, struct ether_addr *mc_addr);
 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 close_ddp_package_file(uint8_t *buf);
+
 enum print_warning {
 	ENABLED_WARN = 0,
 	DISABLED_WARN
-- 
2.5.5

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

* [PATCH v7 4/6] net/i40e: add get all loaded profiles
  2017-03-29 14:44             ` [PATCH v7 0/6] dynamic device profile support Beilei Xing
                                 ` (2 preceding siblings ...)
  2017-03-29 14:44               ` [PATCH v7 3/6] app/testpmd: add command for loading a profile Beilei Xing
@ 2017-03-29 14:44               ` Beilei Xing
  2017-03-29 14:44               ` [PATCH v7 5/6] app/testpmd: add command for getting " Beilei Xing
                                 ` (2 subsequent siblings)
  6 siblings, 0 replies; 82+ messages in thread
From: Beilei Xing @ 2017-03-29 14:44 UTC (permalink / raw)
  To: jingjing.wu; +Cc: helin.zhang, dev

This patch is to add get all loaded profiles function.

Signed-off-by: Beilei Xing <beilei.xing@intel.com>
---
 drivers/net/i40e/i40e_ethdev.c            | 28 ++++++++++++++++++++++++++++
 drivers/net/i40e/rte_pmd_i40e.h           | 12 ++++++++++++
 drivers/net/i40e/rte_pmd_i40e_version.map |  1 +
 3 files changed, 41 insertions(+)

diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index bd0ba78..0b28b13 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -11709,6 +11709,9 @@ rte_pmd_i40e_set_tc_strict_prio(uint8_t port, uint8_t tc_map)
 	return ret;
 }
 
+#define I40E_PROFILE_INFO_SIZE 48
+#define I40E_MAX_PROFILE_NUM 16
+
 static void
 i40e_generate_profile_info_sec(char *name, struct i40e_ddp_version *version,
 			       uint32_t track_id, uint8_t *profile_info_sec,
@@ -11915,3 +11918,28 @@ rte_pmd_i40e_process_ddp_package(uint8_t port, uint8_t *buff,
 	rte_free(profile_info_sec);
 	return status;
 }
+
+int
+rte_pmd_i40e_get_ddp_list(uint8_t port, uint8_t *buff, uint32_t size)
+{
+	struct rte_eth_dev *dev;
+	struct i40e_hw *hw;
+	enum i40e_status_code status = I40E_SUCCESS;
+
+	RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
+
+	dev = &rte_eth_devices[port];
+
+	if (!is_device_supported(dev, &rte_i40e_pmd))
+		return -ENOTSUP;
+
+	if (size < (I40E_PROFILE_INFO_SIZE * I40E_MAX_PROFILE_NUM + 4))
+		return -EINVAL;
+
+	hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+
+	status = i40e_aq_get_ddp_list(hw, (void *)buff,
+				      size, 0, NULL);
+
+	return status;
+}
diff --git a/drivers/net/i40e/rte_pmd_i40e.h b/drivers/net/i40e/rte_pmd_i40e.h
index 38a11f3..d05bec3 100644
--- a/drivers/net/i40e/rte_pmd_i40e.h
+++ b/drivers/net/i40e/rte_pmd_i40e.h
@@ -476,4 +476,16 @@ int rte_pmd_i40e_process_ddp_package(uint8_t port, uint8_t *buff,
 				     uint32_t size,
 				     enum rte_pmd_i40e_package_op op);
 
+/**
+ * rte_pmd_i40e_get_ddp_list - Get loaded profile list
+ * @port: port id
+ * @buff: buffer for response
+ * @size: buffer size
+ * @return
+ *   - (0) if successful.
+ *   - (-ENODEV) if *port* invalid.
+ *   - (-EINVAL) if bad parameter.
+ */
+int rte_pmd_i40e_get_ddp_list(uint8_t port, uint8_t *buff, uint32_t size);
+
 #endif /* _PMD_I40E_H_ */
diff --git a/drivers/net/i40e/rte_pmd_i40e_version.map b/drivers/net/i40e/rte_pmd_i40e_version.map
index 6d001a3..dbb994e 100644
--- a/drivers/net/i40e/rte_pmd_i40e_version.map
+++ b/drivers/net/i40e/rte_pmd_i40e_version.map
@@ -31,5 +31,6 @@ DPDK_17.05 {
 	rte_pmd_i40e_set_vf_tc_bw_alloc;
 	rte_pmd_i40e_set_vf_tc_max_bw;
 	rte_pmd_i40e_process_ddp_package;
+	rte_pmd_i40e_get_ddp_list;
 
 } DPDK_17.02;
-- 
2.5.5

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

* [PATCH v7 5/6] app/testpmd: add command for getting loaded profiles
  2017-03-29 14:44             ` [PATCH v7 0/6] dynamic device profile support Beilei Xing
                                 ` (3 preceding siblings ...)
  2017-03-29 14:44               ` [PATCH v7 4/6] net/i40e: add get all loaded profiles Beilei Xing
@ 2017-03-29 14:44               ` Beilei Xing
  2017-03-29 14:44               ` [PATCH v7 6/6] doc: add dynamic device profile support for i40e Beilei Xing
  2017-03-30  2:51               ` [PATCH v8 0/6] dynamic device personalization support Beilei Xing
  6 siblings, 0 replies; 82+ messages in thread
From: Beilei Xing @ 2017-03-29 14:44 UTC (permalink / raw)
  To: jingjing.wu; +Cc: helin.zhang, dev

This patch is to add testpmd CLI for getting all loaded profiles.

Signed-off-by: Beilei Xing <beilei.xing@intel.com>
---
 app/test-pmd/cmdline.c | 91 ++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 91 insertions(+)

diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
index 42d0b24..0b47692 100644
--- a/app/test-pmd/cmdline.c
+++ b/app/test-pmd/cmdline.c
@@ -214,6 +214,9 @@ static void cmd_help_long_parsed(void *parsed_result,
 
 			"read txd (port_id) (queue_id) (txd_id)\n"
 			"    Display a TX descriptor of a port TX queue.\n\n"
+
+			"get ddp list (port_id)\n"
+			"    Get ddp profile info list\n\n"
 		);
 	}
 
@@ -12812,6 +12815,93 @@ cmdline_parse_inst_t cmd_add_ddp = {
 	},
 };
 
+/* Get Dynamic Device Profile list*/
+#define PROFILE_INFO_SIZE 48
+#define MAX_PROFILE_NUM 16
+
+struct cmd_get_ddp_list_result {
+	cmdline_fixed_string_t get;
+	cmdline_fixed_string_t ddp;
+	cmdline_fixed_string_t list;
+	uint8_t port_id;
+};
+
+cmdline_parse_token_string_t cmd_get_ddp_list_get =
+	TOKEN_STRING_INITIALIZER(struct cmd_get_ddp_list_result, get, "get");
+cmdline_parse_token_string_t cmd_get_ddp_list_ddp =
+	TOKEN_STRING_INITIALIZER(struct cmd_get_ddp_list_result, ddp, "ddp");
+cmdline_parse_token_string_t cmd_get_ddp_list_list =
+	TOKEN_STRING_INITIALIZER(struct cmd_get_ddp_list_result, list, "list");
+cmdline_parse_token_num_t cmd_get_ddp_list_port_id =
+	TOKEN_NUM_INITIALIZER(struct cmd_get_ddp_list_result, port_id, UINT8);
+
+static void
+cmd_get_ddp_list_parsed(
+	void *parsed_result,
+	__attribute__((unused)) struct cmdline *cl,
+	__attribute__((unused)) void *data)
+{
+	struct cmd_get_ddp_list_result *res = parsed_result;
+#ifdef RTE_LIBRTE_I40E_PMD
+	struct rte_pmd_i40e_profile_list *p_list;
+	struct rte_pmd_i40e_profile_info *p_info;
+	uint32_t p_num;
+	uint32_t size;
+	uint32_t i;
+#endif
+	int ret = -ENOTSUP;
+
+	if (res->port_id > nb_ports) {
+		printf("Invalid port, range is [0, %d]\n", nb_ports - 1);
+		return;
+	}
+
+#ifdef RTE_LIBRTE_I40E_PMD
+	size = PROFILE_INFO_SIZE * MAX_PROFILE_NUM + 4;
+	p_list = (struct rte_pmd_i40e_profile_list *)malloc(size);
+	if (!p_list)
+		printf("%s: Failed to malloc buffer\n", __func__);
+
+	if (ret == -ENOTSUP)
+		ret = rte_pmd_i40e_get_ddp_list(res->port_id,
+						(uint8_t *)p_list, size);
+
+	if (!ret) {
+		p_num = p_list->p_count;
+		printf("Profile number is: %d\n\n", p_num);
+
+		for (i = 0; i < p_num; i++) {
+			p_info = &p_list->p_info[i];
+			printf("Profile %d:\n", i);
+			printf("Track id:     0x%x\n", p_info->track_id);
+			printf("Version:      %d.%d.%d.%d \n",
+			       p_info->version.major,
+			       p_info->version.minor,
+			       p_info->version.update,
+			       p_info->version.draft);
+			printf("Profile name: %s\n\n", p_info->name);
+		}
+	}
+
+	free(p_list);
+#endif
+
+	if (ret < 0)
+		printf("Failed to get ddp list\n");
+}
+
+cmdline_parse_inst_t cmd_get_ddp_list = {
+	.f = cmd_get_ddp_list_parsed,
+	.data = NULL,
+	.help_str = "get ddp list <port_id>",
+	.tokens = {
+		(void *)&cmd_get_ddp_list_get,
+		(void *)&cmd_get_ddp_list_ddp,
+		(void *)&cmd_get_ddp_list_list,
+		(void *)&cmd_get_ddp_list_port_id,
+		NULL,
+	},
+};
 /* ******************************************************************************** */
 
 /* list of instructions */
@@ -12992,6 +13082,7 @@ cmdline_parse_ctx_t main_ctx[] = {
 	(cmdline_parse_inst_t *)&cmd_vf_tc_max_bw,
 	(cmdline_parse_inst_t *)&cmd_strict_link_prio,
 	(cmdline_parse_inst_t *)&cmd_add_ddp,
+	(cmdline_parse_inst_t *)&cmd_get_ddp_list,
 	NULL,
 };
 
-- 
2.5.5

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

* [PATCH v7 6/6] doc: add dynamic device profile support for i40e
  2017-03-29 14:44             ` [PATCH v7 0/6] dynamic device profile support Beilei Xing
                                 ` (4 preceding siblings ...)
  2017-03-29 14:44               ` [PATCH v7 5/6] app/testpmd: add command for getting " Beilei Xing
@ 2017-03-29 14:44               ` Beilei Xing
  2017-03-30  2:51               ` [PATCH v8 0/6] dynamic device personalization support Beilei Xing
  6 siblings, 0 replies; 82+ messages in thread
From: Beilei Xing @ 2017-03-29 14:44 UTC (permalink / raw)
  To: jingjing.wu; +Cc: helin.zhang, dev

Signed-off-by: Beilei Xing <beilei.xing@intel.com>
Acked-by: John McNamara <john.mcnamara@intel.com>
---
 doc/guides/rel_notes/release_17_05.rst | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/doc/guides/rel_notes/release_17_05.rst b/doc/guides/rel_notes/release_17_05.rst
index cd95e35..50f70b8 100644
--- a/doc/guides/rel_notes/release_17_05.rst
+++ b/doc/guides/rel_notes/release_17_05.rst
@@ -133,6 +133,10 @@ New Features
   Data Ring, ability to register memory regions.
 
 
+* **Added dynamic device profile support for i40e.**
+
+  * Added loading dynamic device profile to i40e FW.
+
 Resolved Issues
 ---------------
 
-- 
2.5.5

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

* [PATCH v8 0/6] dynamic device personalization support
  2017-03-29 14:44             ` [PATCH v7 0/6] dynamic device profile support Beilei Xing
                                 ` (5 preceding siblings ...)
  2017-03-29 14:44               ` [PATCH v7 6/6] doc: add dynamic device profile support for i40e Beilei Xing
@ 2017-03-30  2:51               ` Beilei Xing
  2017-03-30  2:51                 ` [PATCH v8 1/6] net/i40e/base: change ppp to ddp Beilei Xing
                                   ` (6 more replies)
  6 siblings, 7 replies; 82+ messages in thread
From: Beilei Xing @ 2017-03-30  2:51 UTC (permalink / raw)
  To: jingjing.wu; +Cc: helin.zhang, dev

Due to limited resources of X*710 (parser and analyzer configuration
tables, number of packet classification types, number of packet types,
filters configuration tables, etc.), it's impossible to simultaneously
support all protocols/filters required for different parts on network.
To enable protocols/filters extensions for X*710, new Admin Command
for loading user defined configurations is added.
PPP is a format of extend configuration for X*710, it allows user to
load user defined configuration to X*710.

List of possible use cases for extended X*710 configuration using
profiles could include following:
Configuring Analyzer/Parser to support new protocols, e.g.
- IP L2TPv3 tunneling protocol
- IPSec ESP/AH protocols
- MPLSoGRE, MPLSoUDP tunnels
- GTP-C/GTP-U tunnels
New PCTYPEs for offloading packet classification to X*710. e.g.
- new IP Protocol in addition to TCP/UDP/SCTP
- new TCP/UDP subtypes, like TCP SYN, TCP FIN
- new PCTYPE for tunneled packets like GTP-C, GTP-U
New PTYPEs for packets identification, e.g.
- MAC, MPLS, IP4, UDP
- MAC, MPLS, MPLS, IP6, TCP
Fixes for NVM configuration, e.g.
- list of enabled stat counters to improve throughput
- parser/analyzer configuration for some corner cases

v8 changes:
 Change dynamic device profile to dynamic device personalization.

v7 changes:
 Fix one coding style problem.
 Add condition during ddp processing.

v6 changes:
 Change pipeline personalization profile to dynamic device profile.

v5 changes:
 Change parameter of rte_pmd_i40e_process_ppp_package to extend operation.
 Change structure rte_pmd_i40e_profile_info.

v4 changes:
 Fix compile error with gcc version 4.8.4 (Ubuntu 4.8.4-2ubuntu1~14.04.3).
 Move ppp related structures to rte_pmd_i40e.h.
 Not support remove PPP temporarily.

v3 changes:
 Move ppp AQ command code to base code.

Beilei Xing (6):
  net/i40e/base: change ppp to ddp
  net/i40e: add dynamic device personalization processing
  app/testpmd: add command for loading ddp
  net/i40e: add get all loaded profiles
  app/testpmd: add command for getting loaded profiles
  doc: add dynamic device personalization support for i40e

 app/test-pmd/cmdline.c                    | 164 +++++++++++++++++++++
 app/test-pmd/config.c                     |  67 +++++++++
 app/test-pmd/testpmd.h                    |   3 +
 doc/guides/rel_notes/release_17_05.rst    |   4 +
 drivers/net/i40e/base/i40e_adminq_cmd.h   |  10 +-
 drivers/net/i40e/base/i40e_common.c       |  24 +--
 drivers/net/i40e/base/i40e_prototype.h    |   4 +-
 drivers/net/i40e/base/i40e_type.h         |  28 ++--
 drivers/net/i40e/i40e_ethdev.c            | 235 ++++++++++++++++++++++++++++++
 drivers/net/i40e/rte_pmd_i40e.h           |  70 +++++++++
 drivers/net/i40e/rte_pmd_i40e_version.map |   2 +
 11 files changed, 578 insertions(+), 33 deletions(-)

-- 
2.5.5

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

* [PATCH v8 1/6] net/i40e/base: change ppp to ddp
  2017-03-30  2:51               ` [PATCH v8 0/6] dynamic device personalization support Beilei Xing
@ 2017-03-30  2:51                 ` Beilei Xing
  2017-03-30 14:06                   ` Ferruh Yigit
  2017-03-30  2:51                 ` [PATCH v8 2/6] net/i40e: add dynamic device personalization processing Beilei Xing
                                   ` (5 subsequent siblings)
  6 siblings, 1 reply; 82+ messages in thread
From: Beilei Xing @ 2017-03-30  2:51 UTC (permalink / raw)
  To: jingjing.wu; +Cc: helin.zhang, dev

Change pipeline personalization profile(ppp) to dynamic
device personalization(ddp).

Signed-off-by: Beilei Xing <beilei.xing@intel.com>
---
 drivers/net/i40e/base/i40e_adminq_cmd.h | 10 +++++-----
 drivers/net/i40e/base/i40e_common.c     | 24 ++++++++++++------------
 drivers/net/i40e/base/i40e_prototype.h  |  4 ++--
 drivers/net/i40e/base/i40e_type.h       | 28 ++++++++++++++--------------
 4 files changed, 33 insertions(+), 33 deletions(-)

diff --git a/drivers/net/i40e/base/i40e_adminq_cmd.h b/drivers/net/i40e/base/i40e_adminq_cmd.h
index 8fb3725..09f5bf5 100644
--- a/drivers/net/i40e/base/i40e_adminq_cmd.h
+++ b/drivers/net/i40e/base/i40e_adminq_cmd.h
@@ -199,7 +199,7 @@ enum i40e_admin_queue_opc {
 	i40e_aqc_opc_add_mirror_rule	= 0x0260,
 	i40e_aqc_opc_delete_mirror_rule	= 0x0261,
 
-	/* Pipeline Personalization Profile */
+	/* Dynamic Device Personalization */
 	i40e_aqc_opc_write_personalization_profile	= 0x0270,
 	i40e_aqc_opc_get_personalization_profile_list	= 0x0271,
 
@@ -1538,7 +1538,7 @@ struct i40e_aqc_add_delete_mirror_rule_completion {
 
 I40E_CHECK_CMD_LENGTH(i40e_aqc_add_delete_mirror_rule_completion);
 
-/* Pipeline Personalization Profile */
+/* Dynamic Device Personalization */
 struct i40e_aqc_write_personalization_profile {
 	u8      flags;
 	u8      reserved[3];
@@ -1549,7 +1549,7 @@ struct i40e_aqc_write_personalization_profile {
 
 I40E_CHECK_CMD_LENGTH(i40e_aqc_write_personalization_profile);
 
-struct i40e_aqc_write_ppp_resp {
+struct i40e_aqc_write_ddp_resp {
 	__le32 error_offset;
 	__le32 error_info;
 	__le32 addr_high;
@@ -1558,8 +1558,8 @@ struct i40e_aqc_write_ppp_resp {
 
 struct i40e_aqc_get_applied_profiles {
 	u8      flags;
-#define I40E_AQC_GET_PPP_GET_CONF	0x1
-#define I40E_AQC_GET_PPP_GET_RDPU_CONF	0x2
+#define I40E_AQC_GET_DDP_GET_CONF	0x1
+#define I40E_AQC_GET_DDP_GET_RDPU_CONF	0x2
 	u8      rsv[3];
 	__le32  reserved;
 	__le32  addr_high;
diff --git a/drivers/net/i40e/base/i40e_common.c b/drivers/net/i40e/base/i40e_common.c
index 33ad49c..03e94bc 100644
--- a/drivers/net/i40e/base/i40e_common.c
+++ b/drivers/net/i40e/base/i40e_common.c
@@ -7155,7 +7155,7 @@ enum i40e_status_code i40e_aq_clear_all_wol_filters(struct i40e_hw *hw,
 
 
 /**
- * i40e_aq_write_ppp - Write pipeline personalization profile (ppp)
+ * i40e_aq_write_ddp - Write dynamic device personalization (ddp)
  * @hw: pointer to the hw struct
  * @buff: command buffer (size in bytes = buff_size)
  * @buff_size: buffer size in bytes
@@ -7165,7 +7165,7 @@ enum i40e_status_code i40e_aq_clear_all_wol_filters(struct i40e_hw *hw,
  * @cmd_details: pointer to command details structure or NULL
  **/
 enum
-i40e_status_code i40e_aq_write_ppp(struct i40e_hw *hw, void *buff,
+i40e_status_code i40e_aq_write_ddp(struct i40e_hw *hw, void *buff,
 				   u16 buff_size, u32 track_id,
 				   u32 *error_offset, u32 *error_info,
 				   struct i40e_asq_cmd_details *cmd_details)
@@ -7174,7 +7174,7 @@ i40e_status_code i40e_aq_write_ppp(struct i40e_hw *hw, void *buff,
 	struct i40e_aqc_write_personalization_profile *cmd =
 		(struct i40e_aqc_write_personalization_profile *)
 		&desc.params.raw;
-	struct i40e_aqc_write_ppp_resp *resp;
+	struct i40e_aqc_write_ddp_resp *resp;
 	enum i40e_status_code status;
 
 	i40e_fill_default_direct_cmd_desc(&desc,
@@ -7190,7 +7190,7 @@ i40e_status_code i40e_aq_write_ppp(struct i40e_hw *hw, void *buff,
 
 	status = i40e_asq_send_command(hw, &desc, buff, buff_size, cmd_details);
 	if (!status) {
-		resp = (struct i40e_aqc_write_ppp_resp *)&desc.params.raw;
+		resp = (struct i40e_aqc_write_ddp_resp *)&desc.params.raw;
 		if (error_offset)
 			*error_offset = LE32_TO_CPU(resp->error_offset);
 		if (error_info)
@@ -7201,14 +7201,14 @@ i40e_status_code i40e_aq_write_ppp(struct i40e_hw *hw, void *buff,
 }
 
 /**
- * i40e_aq_get_ppp_list - Read pipeline personalization profile (ppp)
+ * i40e_aq_get_ddp_list - Read dynamic device personalization (ddp)
  * @hw: pointer to the hw struct
  * @buff: command buffer (size in bytes = buff_size)
  * @buff_size: buffer size in bytes
  * @cmd_details: pointer to command details structure or NULL
  **/
 enum
-i40e_status_code i40e_aq_get_ppp_list(struct i40e_hw *hw, void *buff,
+i40e_status_code i40e_aq_get_ddp_list(struct i40e_hw *hw, void *buff,
 				      u16 buff_size, u8 flags,
 				      struct i40e_asq_cmd_details *cmd_details)
 {
@@ -7297,7 +7297,7 @@ i40e_write_profile(struct i40e_hw *hw, struct i40e_profile_segment *profile,
 				break;
 	}
 	if (i == dev_cnt) {
-		i40e_debug(hw, I40E_DEBUG_PACKAGE, "Device doesn't support PPP");
+		i40e_debug(hw, I40E_DEBUG_PACKAGE, "Device doesn't support DDP");
 		return I40E_ERR_DEVICE_NOT_SUPPORTED;
 	}
 
@@ -7316,7 +7316,7 @@ i40e_write_profile(struct i40e_hw *hw, struct i40e_profile_segment *profile,
 			sizeof(struct i40e_profile_section_header);
 
 		/* Write profile */
-		status = i40e_aq_write_ppp(hw, (void *)sec, (u16)section_size,
+		status = i40e_aq_write_ddp(hw, (void *)sec, (u16)section_size,
 					   track_id, &offset, &info, NULL);
 		if (status) {
 			i40e_debug(hw, I40E_DEBUG_PACKAGE,
@@ -7358,10 +7358,10 @@ i40e_add_pinfo_to_list(struct i40e_hw *hw,
 					     sec->section.offset);
 	pinfo->track_id = track_id;
 	pinfo->version = profile->version;
-	pinfo->op = I40E_PPP_ADD_TRACKID;
-	memcpy(pinfo->name, profile->name, I40E_PPP_NAME_SIZE);
+	pinfo->op = I40E_DDP_ADD_TRACKID;
+	memcpy(pinfo->name, profile->name, I40E_DDP_NAME_SIZE);
 
-	status = i40e_aq_write_ppp(hw, (void *)sec, sec->data_end,
+	status = i40e_aq_write_ddp(hw, (void *)sec, sec->data_end,
 				track_id, &offset, &info, NULL);
 	return status;
-}
\ No newline at end of file
+}
diff --git a/drivers/net/i40e/base/i40e_prototype.h b/drivers/net/i40e/base/i40e_prototype.h
index 8662147..4bd589e 100644
--- a/drivers/net/i40e/base/i40e_prototype.h
+++ b/drivers/net/i40e/base/i40e_prototype.h
@@ -565,11 +565,11 @@ enum i40e_status_code i40e_write_phy_register(struct i40e_hw *hw,
 u8 i40e_get_phy_address(struct i40e_hw *hw, u8 dev_num);
 enum i40e_status_code i40e_blink_phy_link_led(struct i40e_hw *hw,
 					      u32 time, u32 interval);
-enum i40e_status_code i40e_aq_write_ppp(struct i40e_hw *hw, void *buff,
+enum i40e_status_code i40e_aq_write_ddp(struct i40e_hw *hw, void *buff,
 				u16 buff_size, u32 track_id,
 				u32 *error_offset, u32 *error_info,
 				struct i40e_asq_cmd_details *cmd_details);
-enum i40e_status_code i40e_aq_get_ppp_list(struct i40e_hw *hw, void *buff,
+enum i40e_status_code i40e_aq_get_ddp_list(struct i40e_hw *hw, void *buff,
 				   u16 buff_size, u8 flags,
 				   struct i40e_asq_cmd_details *cmd_details);
 struct i40e_generic_seg_header *
diff --git a/drivers/net/i40e/base/i40e_type.h b/drivers/net/i40e/base/i40e_type.h
index fc81a93..84d5757 100644
--- a/drivers/net/i40e/base/i40e_type.h
+++ b/drivers/net/i40e/base/i40e_type.h
@@ -1880,19 +1880,19 @@ struct i40e_lldp_variables {
 #define I40E_FLEX_57_SHIFT		6
 #define I40E_FLEX_57_MASK		(0x1ULL << I40E_FLEX_57_SHIFT)
 
-/* Version format for PPP */
-struct i40e_ppp_version {
+/* Version format for Dynamic Device Personalization(DDP) */
+struct i40e_ddp_version {
 	u8 major;
 	u8 minor;
 	u8 update;
 	u8 draft;
 };
 
-#define I40E_PPP_NAME_SIZE	32
+#define I40E_DDP_NAME_SIZE	32
 
 /* Package header */
 struct i40e_package_header {
-	struct i40e_ppp_version version;
+	struct i40e_ddp_version version;
 	u32 segment_count;
 	u32 segment_offset[1];
 };
@@ -1904,16 +1904,16 @@ struct i40e_generic_seg_header {
 #define SEGMENT_TYPE_I40E	0x00000011
 #define SEGMENT_TYPE_X722	0x00000012
 	u32 type;
-	struct i40e_ppp_version version;
+	struct i40e_ddp_version version;
 	u32 size;
-	char name[I40E_PPP_NAME_SIZE];
+	char name[I40E_DDP_NAME_SIZE];
 };
 
 struct i40e_metadata_segment {
 	struct i40e_generic_seg_header header;
-	struct i40e_ppp_version version;
+	struct i40e_ddp_version version;
 	u32 track_id;
-	char     name[I40E_PPP_NAME_SIZE];
+	char     name[I40E_DDP_NAME_SIZE];
 };
 
 struct i40e_device_id_entry {
@@ -1923,8 +1923,8 @@ struct i40e_device_id_entry {
 
 struct i40e_profile_segment {
 	struct i40e_generic_seg_header header;
-	struct i40e_ppp_version version;
-	char name[I40E_PPP_NAME_SIZE];
+	struct i40e_ddp_version version;
+	char name[I40E_DDP_NAME_SIZE];
 	u32 device_table_count;
 	struct i40e_device_id_entry device_table[1];
 };
@@ -1951,11 +1951,11 @@ struct i40e_profile_section_header {
 
 struct i40e_profile_info {
 	u32 track_id;
-	struct i40e_ppp_version version;
+	struct i40e_ddp_version version;
 	u8 op;
-#define I40E_PPP_ADD_TRACKID		0x01
-#define I40E_PPP_REMOVE_TRACKID	0x02
+#define I40E_DDP_ADD_TRACKID		0x01
+#define I40E_DDP_REMOVE_TRACKID	0x02
 	u8 reserved[7];
-	u8 name[I40E_PPP_NAME_SIZE];
+	u8 name[I40E_DDP_NAME_SIZE];
 };
 #endif /* _I40E_TYPE_H_ */
-- 
2.5.5

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

* [PATCH v8 2/6] net/i40e: add dynamic device personalization processing
  2017-03-30  2:51               ` [PATCH v8 0/6] dynamic device personalization support Beilei Xing
  2017-03-30  2:51                 ` [PATCH v8 1/6] net/i40e/base: change ppp to ddp Beilei Xing
@ 2017-03-30  2:51                 ` Beilei Xing
  2017-03-30 14:06                   ` Ferruh Yigit
  2017-03-30 14:08                   ` Ferruh Yigit
  2017-03-30  2:51                 ` [PATCH v8 3/6] app/testpmd: add command for loading ddp Beilei Xing
                                   ` (4 subsequent siblings)
  6 siblings, 2 replies; 82+ messages in thread
From: Beilei Xing @ 2017-03-30  2:51 UTC (permalink / raw)
  To: jingjing.wu; +Cc: helin.zhang, dev

Add support for loading a dynamic device personalization
profile.

Signed-off-by: Beilei Xing <beilei.xing@intel.com>
---
 drivers/net/i40e/i40e_ethdev.c            | 207 ++++++++++++++++++++++++++++++
 drivers/net/i40e/rte_pmd_i40e.h           |  58 +++++++++
 drivers/net/i40e/rte_pmd_i40e_version.map |   1 +
 3 files changed, 266 insertions(+)

diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index 2063603..bd0ba78 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -11708,3 +11708,210 @@ rte_pmd_i40e_set_tc_strict_prio(uint8_t port, uint8_t tc_map)
 
 	return ret;
 }
+
+static void
+i40e_generate_profile_info_sec(char *name, struct i40e_ddp_version *version,
+			       uint32_t track_id, uint8_t *profile_info_sec,
+			       bool add)
+{
+	struct i40e_profile_section_header *sec = NULL;
+	struct i40e_profile_info *pinfo;
+
+	sec = (struct i40e_profile_section_header *)profile_info_sec;
+	sec->tbl_size = 1;
+	sec->data_end = sizeof(struct i40e_profile_section_header) +
+		sizeof(struct i40e_profile_info);
+	sec->section.type = SECTION_TYPE_INFO;
+	sec->section.offset = sizeof(struct i40e_profile_section_header);
+	sec->section.size = sizeof(struct i40e_profile_info);
+	pinfo = (struct i40e_profile_info *)(profile_info_sec +
+					     sec->section.offset);
+	pinfo->track_id = track_id;
+	memcpy(pinfo->name, name, I40E_DDP_NAME_SIZE);
+	memcpy(&pinfo->version, version, sizeof(struct i40e_ddp_version));
+	if (add)
+		pinfo->op = I40E_DDP_ADD_TRACKID;
+	else
+		pinfo->op = I40E_DDP_REMOVE_TRACKID;
+}
+
+static enum i40e_status_code
+i40e_add_rm_profile_info(struct i40e_hw *hw, uint8_t *profile_info_sec)
+{
+	enum i40e_status_code status = I40E_SUCCESS;
+	struct i40e_profile_section_header *sec;
+	uint32_t track_id;
+	uint32_t offset = 0;
+	uint32_t info = 0;
+
+	sec = (struct i40e_profile_section_header *)profile_info_sec;
+	track_id = ((struct i40e_profile_info *)(profile_info_sec +
+					 sec->section.offset))->track_id;
+
+	status = i40e_aq_write_ddp(hw, (void *)sec, sec->data_end,
+				   track_id, &offset, &info, NULL);
+	if (status)
+		PMD_DRV_LOG(ERR, "Failed to add/remove profile info: "
+			    "offset %d, info %d",
+			    offset, info);
+
+	return status;
+}
+
+#define I40E_PROFILE_INFO_SIZE 48
+#define I40E_MAX_PROFILE_NUM 16
+
+/* Check if the profile info exists */
+static int
+i40e_check_profile_info(uint8_t port, uint8_t *profile_info_sec)
+{
+	struct rte_eth_dev *dev = &rte_eth_devices[port];
+	struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+	uint8_t *buff;
+	struct rte_pmd_i40e_profile_list *p_list;
+	struct rte_pmd_i40e_profile_info *pinfo, *p;
+	uint32_t i;
+	int ret;
+
+	buff = rte_zmalloc("pinfo_list",
+			   (I40E_PROFILE_INFO_SIZE * I40E_MAX_PROFILE_NUM + 4),
+			   0);
+	if (!buff) {
+		PMD_DRV_LOG(ERR, "failed to allocate memory");
+		return -1;
+	}
+
+	ret = i40e_aq_get_ddp_list(hw, (void *)buff,
+		      (I40E_PROFILE_INFO_SIZE * I40E_MAX_PROFILE_NUM + 4),
+		      0, NULL);
+	if (ret) {
+		PMD_DRV_LOG(ERR, "Failed to get profile info list.");
+		rte_free(buff);
+		return -1;
+	}
+	p_list = (struct rte_pmd_i40e_profile_list *)buff;
+	pinfo = (struct rte_pmd_i40e_profile_info *)(profile_info_sec +
+			     sizeof(struct i40e_profile_section_header));
+	for (i = 0; i < p_list->p_count; i++) {
+		p = &p_list->p_info[i];
+		if ((pinfo->track_id == p->track_id) &&
+		    !memcmp(&pinfo->version, &p->version,
+			    sizeof(struct i40e_ddp_version)) &&
+		    !memcmp(&pinfo->name, &p->name,
+			    I40E_DDP_NAME_SIZE)) {
+			PMD_DRV_LOG(INFO, "Profile exists.");
+			rte_free(buff);
+			return 1;
+		}
+	}
+
+	rte_free(buff);
+	return 0;
+}
+
+int
+rte_pmd_i40e_process_ddp_package(uint8_t port, uint8_t *buff,
+				 uint32_t size,
+				 enum rte_pmd_i40e_package_op op)
+{
+	struct rte_eth_dev *dev;
+	struct i40e_hw *hw;
+	struct i40e_package_header *pkg_hdr;
+	struct i40e_generic_seg_header *profile_seg_hdr;
+	struct i40e_generic_seg_header *metadata_seg_hdr;
+	uint32_t track_id;
+	uint8_t *profile_info_sec;
+	int is_exist;
+	enum i40e_status_code status = I40E_SUCCESS;
+
+	RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
+
+	dev = &rte_eth_devices[port];
+
+	if (!is_device_supported(dev, &rte_i40e_pmd))
+		return -ENOTSUP;
+
+	hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+
+	if (size < (sizeof(struct i40e_package_header) +
+		    sizeof(struct i40e_metadata_segment) +
+		    sizeof(uint32_t) * 2)) {
+		PMD_DRV_LOG(ERR, "Buff is invalid.");
+		return -EINVAL;
+	}
+
+	pkg_hdr = (struct i40e_package_header *)buff;
+
+	if (!pkg_hdr) {
+		PMD_DRV_LOG(ERR, "Failed to fill the package structure");
+		return -EINVAL;
+	}
+
+	if (pkg_hdr->segment_count < 2) {
+		PMD_DRV_LOG(ERR, "Segment_count should be 2 at least.");
+		return -EINVAL;
+	}
+
+	/* Find metadata segment */
+	metadata_seg_hdr = i40e_find_segment_in_package(SEGMENT_TYPE_METADATA,
+							pkg_hdr);
+	if (!metadata_seg_hdr) {
+		PMD_DRV_LOG(ERR, "Failed to find metadata segment header");
+		return -EINVAL;
+	}
+	track_id = ((struct i40e_metadata_segment *)metadata_seg_hdr)->track_id;
+
+	/* Find profile segment */
+	profile_seg_hdr = i40e_find_segment_in_package(SEGMENT_TYPE_I40E,
+						       pkg_hdr);
+	if (!profile_seg_hdr) {
+		PMD_DRV_LOG(ERR, "Failed to find profile segment header");
+		return -EINVAL;
+	}
+
+	profile_info_sec = rte_zmalloc("i40e_profile_info",
+			       sizeof(struct i40e_profile_section_header) +
+			       sizeof(struct i40e_profile_info),
+			       0);
+	if (!profile_info_sec) {
+		PMD_DRV_LOG(ERR, "Failed to allocate memory");
+		return -EINVAL;
+	}
+
+	if (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) {
+			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.");
+			rte_free(profile_info_sec);
+			return -EINVAL;
+		}
+
+		/* Write profile to HW */
+		status = i40e_write_profile(hw,
+				 (struct i40e_profile_segment *)profile_seg_hdr,
+				 track_id);
+		if (status) {
+			PMD_DRV_LOG(ERR, "Failed to write profile.");
+			rte_free(profile_info_sec);
+			return status;
+		}
+
+		/* Add profile info to info list */
+		status = i40e_add_rm_profile_info(hw, profile_info_sec);
+		if (status)
+			PMD_DRV_LOG(ERR, "Failed to add profile info.");
+	} else
+		PMD_DRV_LOG(ERR, "Operation not supported.");
+
+	rte_free(profile_info_sec);
+	return status;
+}
diff --git a/drivers/net/i40e/rte_pmd_i40e.h b/drivers/net/i40e/rte_pmd_i40e.h
index 3ca49a4..94dd92e 100644
--- a/drivers/net/i40e/rte_pmd_i40e.h
+++ b/drivers/net/i40e/rte_pmd_i40e.h
@@ -65,6 +65,43 @@ struct rte_pmd_i40e_mb_event_param {
 	uint16_t msglen;   /**< length of the message */
 };
 
+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_MAX = 32
+};
+
+#define RTE_PMD_I40E_DDP_NAME_SIZE 32
+
+/**
+ * Dynamic device personalization version
+ */
+struct rte_pmd_i40e_ddp_version {
+	uint8_t major;
+	uint8_t minor;
+	uint8_t update;
+	uint8_t draft;
+};
+
+/**
+ * Structure of profile information
+ */
+struct rte_pmd_i40e_profile_info {
+	uint32_t track_id;
+	struct rte_pmd_i40e_ddp_version version;
+	uint8_t owner;
+	uint8_t reserved[7];
+	uint8_t name[RTE_PMD_I40E_DDP_NAME_SIZE];
+};
+
+/**
+ * Structure of profile information list
+ */
+struct rte_pmd_i40e_profile_list {
+	uint32_t p_count;
+	struct rte_pmd_i40e_profile_info p_info[1];
+};
+
 /**
  * Notify VF when PF link status changes.
  *
@@ -418,4 +455,25 @@ int rte_pmd_i40e_set_vf_tc_max_bw(uint8_t port,
  */
 int rte_pmd_i40e_set_tc_strict_prio(uint8_t port, uint8_t tc_map);
 
+/**
+ * Load/Unload a ddp package
+ *
+ * @param port
+ *    The port identifier of the Ethernet device.
+ * @param buff
+ *    buffer of package.
+ * @param size
+ *    size of buffer.
+ * @param op
+ *   Operation of package processing
+ * @return
+ *   - (0) if successful.
+ *   - (-ENODEV) if *port* invalid.
+ *   - (-EINVAL) if bad parameter.
+ *   - (1) if profile exists.
+ */
+int rte_pmd_i40e_process_ddp_package(uint8_t port, uint8_t *buff,
+				     uint32_t size,
+				     enum rte_pmd_i40e_package_op op);
+
 #endif /* _PMD_I40E_H_ */
diff --git a/drivers/net/i40e/rte_pmd_i40e_version.map b/drivers/net/i40e/rte_pmd_i40e_version.map
index 488e6b6..6d001a3 100644
--- a/drivers/net/i40e/rte_pmd_i40e_version.map
+++ b/drivers/net/i40e/rte_pmd_i40e_version.map
@@ -30,5 +30,6 @@ DPDK_17.05 {
 	rte_pmd_i40e_set_vf_max_bw;
 	rte_pmd_i40e_set_vf_tc_bw_alloc;
 	rte_pmd_i40e_set_vf_tc_max_bw;
+	rte_pmd_i40e_process_ddp_package;
 
 } DPDK_17.02;
-- 
2.5.5

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

* [PATCH v8 3/6] app/testpmd: add command for loading ddp
  2017-03-30  2:51               ` [PATCH v8 0/6] dynamic device personalization support Beilei Xing
  2017-03-30  2:51                 ` [PATCH v8 1/6] net/i40e/base: change ppp to ddp Beilei Xing
  2017-03-30  2:51                 ` [PATCH v8 2/6] net/i40e: add dynamic device personalization processing Beilei Xing
@ 2017-03-30  2:51                 ` Beilei Xing
  2017-03-30  2:51                 ` [PATCH v8 4/6] net/i40e: add get all loaded profiles Beilei Xing
                                   ` (3 subsequent siblings)
  6 siblings, 0 replies; 82+ messages in thread
From: Beilei Xing @ 2017-03-30  2:51 UTC (permalink / raw)
  To: jingjing.wu; +Cc: helin.zhang, dev

This patch is to add testpmd CLI for loading dynamic
device personalization.

Signed-off-by: Beilei Xing <beilei.xing@intel.com>
---
 app/test-pmd/cmdline.c | 73 ++++++++++++++++++++++++++++++++++++++++++++++++++
 app/test-pmd/config.c  | 67 +++++++++++++++++++++++++++++++++++++++++++++
 app/test-pmd/testpmd.h |  3 +++
 3 files changed, 143 insertions(+)

diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
index b93b096..73e29db 100644
--- a/app/test-pmd/cmdline.c
+++ b/app/test-pmd/cmdline.c
@@ -590,6 +590,9 @@ 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"
 
+			"add ddp (port_id) (profile_path)\n"
+			"    Load a profile package on a port\n\n"
+
 			, list_pkt_forwarding_modes()
 		);
 	}
@@ -12739,6 +12742,75 @@ cmdline_parse_inst_t cmd_strict_link_prio = {
 	},
 };
 
+/* Load dynamic device personalization*/
+struct cmd_add_ddp_result {
+	cmdline_fixed_string_t add;
+	cmdline_fixed_string_t ddp;
+	uint8_t port_id;
+	char filepath[];
+};
+
+cmdline_parse_token_string_t cmd_add_ddp_add =
+	TOKEN_STRING_INITIALIZER(struct cmd_add_ddp_result, add, "add");
+cmdline_parse_token_string_t cmd_add_ddp_ddp =
+	TOKEN_STRING_INITIALIZER(struct cmd_add_ddp_result, ddp, "ddp");
+cmdline_parse_token_num_t cmd_add_ddp_port_id =
+	TOKEN_NUM_INITIALIZER(struct cmd_add_ddp_result, port_id, UINT8);
+cmdline_parse_token_string_t cmd_add_ddp_filepath =
+	TOKEN_STRING_INITIALIZER(struct cmd_add_ddp_result, filepath, NULL);
+
+static void
+cmd_add_ddp_parsed(
+	void *parsed_result,
+	__attribute__((unused)) struct cmdline *cl,
+	__attribute__((unused)) void *data)
+{
+	struct cmd_add_ddp_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_ADD);
+#endif
+
+	if (ret < 0)
+		printf("Failed to load profile.\n");
+	else if (ret > 0)
+		printf("Profile has already existed.\n");
+
+	close_ddp_package_file(buff);
+}
+
+cmdline_parse_inst_t cmd_add_ddp = {
+	.f = cmd_add_ddp_parsed,
+	.data = NULL,
+	.help_str = "add/remove ddp <port_id> <profile_path>",
+	.tokens = {
+		(void *)&cmd_add_ddp_add,
+		(void *)&cmd_add_ddp_ddp,
+		(void *)&cmd_add_ddp_port_id,
+		(void *)&cmd_add_ddp_filepath,
+		NULL,
+	},
+};
 
 /* ******************************************************************************** */
 
@@ -12919,6 +12991,7 @@ cmdline_parse_ctx_t main_ctx[] = {
 	(cmdline_parse_inst_t *)&cmd_vf_tc_min_bw,
 	(cmdline_parse_inst_t *)&cmd_vf_tc_max_bw,
 	(cmdline_parse_inst_t *)&cmd_strict_link_prio,
+	(cmdline_parse_inst_t *)&cmd_add_ddp,
 	NULL,
 };
 
diff --git a/app/test-pmd/config.c b/app/test-pmd/config.c
index 80491fc..9865bf1 100644
--- a/app/test-pmd/config.c
+++ b/app/test-pmd/config.c
@@ -3245,3 +3245,70 @@ port_dcb_info_display(uint8_t port_id)
 		printf("\t%4d", dcb_info.tc_queue.tc_txq[0][i].nb_queue);
 	printf("\n");
 }
+
+uint8_t *
+open_ddp_package_file(const char *file_path, uint32_t *size)
+{
+	FILE *fh = fopen(file_path, "rb");
+	uint32_t pkg_size;
+	uint8_t *buf = NULL;
+	int ret = 0;
+
+	if (size)
+		*size = 0;
+
+	if (fh == NULL) {
+		printf("%s: Failed to open %s\n", __func__, file_path);
+		return buf;
+	}
+
+	ret = fseek(fh, 0, SEEK_END);
+	if (ret < 0) {
+		fclose(fh);
+		printf("%s: File operations failed\n", __func__);
+		return buf;
+	}
+
+	pkg_size = ftell(fh);
+
+	buf = (uint8_t *)malloc(pkg_size);
+	if (!buf) {
+		fclose(fh);
+		printf("%s: Failed to malloc memory\n",	__func__);
+		return buf;
+	}
+
+	ret = fseek(fh, 0, SEEK_SET);
+	if (ret < 0) {
+		fclose(fh);
+		printf("%s: File seek operation failed\n", __func__);
+		close_ddp_package_file(buf);
+		return NULL;
+	}
+
+	ret = fread(buf, 1, pkg_size, fh);
+	if (ret < 0) {
+		fclose(fh);
+		printf("%s: File read operation failed\n", __func__);
+		close_ddp_package_file(buf);
+		return NULL;
+	}
+
+	if (size)
+		*size = pkg_size;
+
+	fclose(fh);
+
+	return buf;
+}
+
+int
+close_ddp_package_file(uint8_t *buf)
+{
+	if (buf) {
+		free((void *)buf);
+		return 0;
+	}
+
+	return -1;
+}
diff --git a/app/test-pmd/testpmd.h b/app/test-pmd/testpmd.h
index 8cf2860..5c18151 100644
--- a/app/test-pmd/testpmd.h
+++ b/app/test-pmd/testpmd.h
@@ -622,6 +622,9 @@ void mcast_addr_add(uint8_t port_id, struct ether_addr *mc_addr);
 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 close_ddp_package_file(uint8_t *buf);
+
 enum print_warning {
 	ENABLED_WARN = 0,
 	DISABLED_WARN
-- 
2.5.5

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

* [PATCH v8 4/6] net/i40e: add get all loaded profiles
  2017-03-30  2:51               ` [PATCH v8 0/6] dynamic device personalization support Beilei Xing
                                   ` (2 preceding siblings ...)
  2017-03-30  2:51                 ` [PATCH v8 3/6] app/testpmd: add command for loading ddp Beilei Xing
@ 2017-03-30  2:51                 ` Beilei Xing
  2017-03-30  2:51                 ` [PATCH v8 5/6] app/testpmd: add command for getting " Beilei Xing
                                   ` (2 subsequent siblings)
  6 siblings, 0 replies; 82+ messages in thread
From: Beilei Xing @ 2017-03-30  2:51 UTC (permalink / raw)
  To: jingjing.wu; +Cc: helin.zhang, dev

This patch is to add get all loaded profiles function.

Signed-off-by: Beilei Xing <beilei.xing@intel.com>
---
 drivers/net/i40e/i40e_ethdev.c            | 28 ++++++++++++++++++++++++++++
 drivers/net/i40e/rte_pmd_i40e.h           | 12 ++++++++++++
 drivers/net/i40e/rte_pmd_i40e_version.map |  1 +
 3 files changed, 41 insertions(+)

diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index bd0ba78..0b28b13 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -11709,6 +11709,9 @@ rte_pmd_i40e_set_tc_strict_prio(uint8_t port, uint8_t tc_map)
 	return ret;
 }
 
+#define I40E_PROFILE_INFO_SIZE 48
+#define I40E_MAX_PROFILE_NUM 16
+
 static void
 i40e_generate_profile_info_sec(char *name, struct i40e_ddp_version *version,
 			       uint32_t track_id, uint8_t *profile_info_sec,
@@ -11915,3 +11918,28 @@ rte_pmd_i40e_process_ddp_package(uint8_t port, uint8_t *buff,
 	rte_free(profile_info_sec);
 	return status;
 }
+
+int
+rte_pmd_i40e_get_ddp_list(uint8_t port, uint8_t *buff, uint32_t size)
+{
+	struct rte_eth_dev *dev;
+	struct i40e_hw *hw;
+	enum i40e_status_code status = I40E_SUCCESS;
+
+	RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
+
+	dev = &rte_eth_devices[port];
+
+	if (!is_device_supported(dev, &rte_i40e_pmd))
+		return -ENOTSUP;
+
+	if (size < (I40E_PROFILE_INFO_SIZE * I40E_MAX_PROFILE_NUM + 4))
+		return -EINVAL;
+
+	hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+
+	status = i40e_aq_get_ddp_list(hw, (void *)buff,
+				      size, 0, NULL);
+
+	return status;
+}
diff --git a/drivers/net/i40e/rte_pmd_i40e.h b/drivers/net/i40e/rte_pmd_i40e.h
index 94dd92e..93cc56d 100644
--- a/drivers/net/i40e/rte_pmd_i40e.h
+++ b/drivers/net/i40e/rte_pmd_i40e.h
@@ -476,4 +476,16 @@ int rte_pmd_i40e_process_ddp_package(uint8_t port, uint8_t *buff,
 				     uint32_t size,
 				     enum rte_pmd_i40e_package_op op);
 
+/**
+ * rte_pmd_i40e_get_ddp_list - Get loaded profile list
+ * @port: port id
+ * @buff: buffer for response
+ * @size: buffer size
+ * @return
+ *   - (0) if successful.
+ *   - (-ENODEV) if *port* invalid.
+ *   - (-EINVAL) if bad parameter.
+ */
+int rte_pmd_i40e_get_ddp_list(uint8_t port, uint8_t *buff, uint32_t size);
+
 #endif /* _PMD_I40E_H_ */
diff --git a/drivers/net/i40e/rte_pmd_i40e_version.map b/drivers/net/i40e/rte_pmd_i40e_version.map
index 6d001a3..dbb994e 100644
--- a/drivers/net/i40e/rte_pmd_i40e_version.map
+++ b/drivers/net/i40e/rte_pmd_i40e_version.map
@@ -31,5 +31,6 @@ DPDK_17.05 {
 	rte_pmd_i40e_set_vf_tc_bw_alloc;
 	rte_pmd_i40e_set_vf_tc_max_bw;
 	rte_pmd_i40e_process_ddp_package;
+	rte_pmd_i40e_get_ddp_list;
 
 } DPDK_17.02;
-- 
2.5.5

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

* [PATCH v8 5/6] app/testpmd: add command for getting loaded profiles
  2017-03-30  2:51               ` [PATCH v8 0/6] dynamic device personalization support Beilei Xing
                                   ` (3 preceding siblings ...)
  2017-03-30  2:51                 ` [PATCH v8 4/6] net/i40e: add get all loaded profiles Beilei Xing
@ 2017-03-30  2:51                 ` Beilei Xing
  2017-03-30 14:07                   ` Ferruh Yigit
  2017-03-30  2:51                 ` [PATCH v8 6/6] doc: add dynamic device personalization support for i40e Beilei Xing
  2017-03-30  6:18                 ` [PATCH v8 0/6] dynamic device personalization support Wu, Jingjing
  6 siblings, 1 reply; 82+ messages in thread
From: Beilei Xing @ 2017-03-30  2:51 UTC (permalink / raw)
  To: jingjing.wu; +Cc: helin.zhang, dev

This patch is to add testpmd CLI for getting all loaded
ddp profiles.

Signed-off-by: Beilei Xing <beilei.xing@intel.com>
---
 app/test-pmd/cmdline.c | 91 ++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 91 insertions(+)

diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
index 73e29db..51f178c 100644
--- a/app/test-pmd/cmdline.c
+++ b/app/test-pmd/cmdline.c
@@ -214,6 +214,9 @@ static void cmd_help_long_parsed(void *parsed_result,
 
 			"read txd (port_id) (queue_id) (txd_id)\n"
 			"    Display a TX descriptor of a port TX queue.\n\n"
+
+			"get ddp list (port_id)\n"
+			"    Get ddp profile info list\n\n"
 		);
 	}
 
@@ -12812,6 +12815,93 @@ cmdline_parse_inst_t cmd_add_ddp = {
 	},
 };
 
+/* Get dynamic device personalization profile info list*/
+#define PROFILE_INFO_SIZE 48
+#define MAX_PROFILE_NUM 16
+
+struct cmd_get_ddp_list_result {
+	cmdline_fixed_string_t get;
+	cmdline_fixed_string_t ddp;
+	cmdline_fixed_string_t list;
+	uint8_t port_id;
+};
+
+cmdline_parse_token_string_t cmd_get_ddp_list_get =
+	TOKEN_STRING_INITIALIZER(struct cmd_get_ddp_list_result, get, "get");
+cmdline_parse_token_string_t cmd_get_ddp_list_ddp =
+	TOKEN_STRING_INITIALIZER(struct cmd_get_ddp_list_result, ddp, "ddp");
+cmdline_parse_token_string_t cmd_get_ddp_list_list =
+	TOKEN_STRING_INITIALIZER(struct cmd_get_ddp_list_result, list, "list");
+cmdline_parse_token_num_t cmd_get_ddp_list_port_id =
+	TOKEN_NUM_INITIALIZER(struct cmd_get_ddp_list_result, port_id, UINT8);
+
+static void
+cmd_get_ddp_list_parsed(
+	void *parsed_result,
+	__attribute__((unused)) struct cmdline *cl,
+	__attribute__((unused)) void *data)
+{
+	struct cmd_get_ddp_list_result *res = parsed_result;
+#ifdef RTE_LIBRTE_I40E_PMD
+	struct rte_pmd_i40e_profile_list *p_list;
+	struct rte_pmd_i40e_profile_info *p_info;
+	uint32_t p_num;
+	uint32_t size;
+	uint32_t i;
+#endif
+	int ret = -ENOTSUP;
+
+	if (res->port_id > nb_ports) {
+		printf("Invalid port, range is [0, %d]\n", nb_ports - 1);
+		return;
+	}
+
+#ifdef RTE_LIBRTE_I40E_PMD
+	size = PROFILE_INFO_SIZE * MAX_PROFILE_NUM + 4;
+	p_list = (struct rte_pmd_i40e_profile_list *)malloc(size);
+	if (!p_list)
+		printf("%s: Failed to malloc buffer\n", __func__);
+
+	if (ret == -ENOTSUP)
+		ret = rte_pmd_i40e_get_ddp_list(res->port_id,
+						(uint8_t *)p_list, size);
+
+	if (!ret) {
+		p_num = p_list->p_count;
+		printf("Profile number is: %d\n\n", p_num);
+
+		for (i = 0; i < p_num; i++) {
+			p_info = &p_list->p_info[i];
+			printf("Profile %d:\n", i);
+			printf("Track id:     0x%x\n", p_info->track_id);
+			printf("Version:      %d.%d.%d.%d \n",
+			       p_info->version.major,
+			       p_info->version.minor,
+			       p_info->version.update,
+			       p_info->version.draft);
+			printf("Profile name: %s\n\n", p_info->name);
+		}
+	}
+
+	free(p_list);
+#endif
+
+	if (ret < 0)
+		printf("Failed to get ddp list\n");
+}
+
+cmdline_parse_inst_t cmd_get_ddp_list = {
+	.f = cmd_get_ddp_list_parsed,
+	.data = NULL,
+	.help_str = "get ddp list <port_id>",
+	.tokens = {
+		(void *)&cmd_get_ddp_list_get,
+		(void *)&cmd_get_ddp_list_ddp,
+		(void *)&cmd_get_ddp_list_list,
+		(void *)&cmd_get_ddp_list_port_id,
+		NULL,
+	},
+};
 /* ******************************************************************************** */
 
 /* list of instructions */
@@ -12992,6 +13082,7 @@ cmdline_parse_ctx_t main_ctx[] = {
 	(cmdline_parse_inst_t *)&cmd_vf_tc_max_bw,
 	(cmdline_parse_inst_t *)&cmd_strict_link_prio,
 	(cmdline_parse_inst_t *)&cmd_add_ddp,
+	(cmdline_parse_inst_t *)&cmd_get_ddp_list,
 	NULL,
 };
 
-- 
2.5.5

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

* [PATCH v8 6/6] doc: add dynamic device personalization support for i40e
  2017-03-30  2:51               ` [PATCH v8 0/6] dynamic device personalization support Beilei Xing
                                   ` (4 preceding siblings ...)
  2017-03-30  2:51                 ` [PATCH v8 5/6] app/testpmd: add command for getting " Beilei Xing
@ 2017-03-30  2:51                 ` Beilei Xing
  2017-03-30  6:18                 ` [PATCH v8 0/6] dynamic device personalization support Wu, Jingjing
  6 siblings, 0 replies; 82+ messages in thread
From: Beilei Xing @ 2017-03-30  2:51 UTC (permalink / raw)
  To: jingjing.wu; +Cc: helin.zhang, dev

Signed-off-by: Beilei Xing <beilei.xing@intel.com>
---
 doc/guides/rel_notes/release_17_05.rst | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/doc/guides/rel_notes/release_17_05.rst b/doc/guides/rel_notes/release_17_05.rst
index 26ae57f..fe25e6b 100644
--- a/doc/guides/rel_notes/release_17_05.rst
+++ b/doc/guides/rel_notes/release_17_05.rst
@@ -144,6 +144,10 @@ New Features
     items with DROP, QUEUE and PASSTHRU actions for ingress traffic.
 
 
+* **Added dynamic device personalization support.**
+
+  * Added dynamic device personalization processing to i40e FW.
+
 Resolved Issues
 ---------------
 
-- 
2.5.5

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

* Re: [PATCH v8 0/6] dynamic device personalization support
  2017-03-30  2:51               ` [PATCH v8 0/6] dynamic device personalization support Beilei Xing
                                   ` (5 preceding siblings ...)
  2017-03-30  2:51                 ` [PATCH v8 6/6] doc: add dynamic device personalization support for i40e Beilei Xing
@ 2017-03-30  6:18                 ` Wu, Jingjing
  2017-03-30 14:05                   ` Ferruh Yigit
  6 siblings, 1 reply; 82+ messages in thread
From: Wu, Jingjing @ 2017-03-30  6:18 UTC (permalink / raw)
  To: Xing, Beilei; +Cc: Zhang, Helin, dev



> -----Original Message-----
> From: Xing, Beilei
> Sent: Thursday, March 30, 2017 10:52 AM
> To: Wu, Jingjing <jingjing.wu@intel.com>
> Cc: Zhang, Helin <helin.zhang@intel.com>; dev@dpdk.org
> Subject: [PATCH v8 0/6] dynamic device personalization support
> 
> Due to limited resources of X*710 (parser and analyzer configuration tables,
> number of packet classification types, number of packet types, filters
> configuration tables, etc.), it's impossible to simultaneously support all
> protocols/filters required for different parts on network.
> To enable protocols/filters extensions for X*710, new Admin Command for
> loading user defined configurations is added.
> PPP is a format of extend configuration for X*710, it allows user to load user
> defined configuration to X*710.
> 
> List of possible use cases for extended X*710 configuration using profiles could
> include following:
> Configuring Analyzer/Parser to support new protocols, e.g.
> - IP L2TPv3 tunneling protocol
> - IPSec ESP/AH protocols
> - MPLSoGRE, MPLSoUDP tunnels
> - GTP-C/GTP-U tunnels
> New PCTYPEs for offloading packet classification to X*710. e.g.
> - new IP Protocol in addition to TCP/UDP/SCTP
> - new TCP/UDP subtypes, like TCP SYN, TCP FIN
> - new PCTYPE for tunneled packets like GTP-C, GTP-U New PTYPEs for packets
> identification, e.g.
> - MAC, MPLS, IP4, UDP
> - MAC, MPLS, MPLS, IP6, TCP
> Fixes for NVM configuration, e.g.
> - list of enabled stat counters to improve throughput
> - parser/analyzer configuration for some corner cases
> 
> v8 changes:
>  Change dynamic device profile to dynamic device personalization.
> 
> v7 changes:
>  Fix one coding style problem.
>  Add condition during ddp processing.
> 
> v6 changes:
>  Change pipeline personalization profile to dynamic device profile.
> 
> v5 changes:
>  Change parameter of rte_pmd_i40e_process_ppp_package to extend
> operation.
>  Change structure rte_pmd_i40e_profile_info.
> 
> v4 changes:
>  Fix compile error with gcc version 4.8.4 (Ubuntu 4.8.4-2ubuntu1~14.04.3).
>  Move ppp related structures to rte_pmd_i40e.h.
>  Not support remove PPP temporarily.
> 
> v3 changes:
>  Move ppp AQ command code to base code.

Series Acked-by Jingjing Wu <jingjing.wu@intel.com>

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

* Re: [PATCH v8 0/6] dynamic device personalization support
  2017-03-30  6:18                 ` [PATCH v8 0/6] dynamic device personalization support Wu, Jingjing
@ 2017-03-30 14:05                   ` Ferruh Yigit
  0 siblings, 0 replies; 82+ messages in thread
From: Ferruh Yigit @ 2017-03-30 14:05 UTC (permalink / raw)
  To: Wu, Jingjing, Xing, Beilei; +Cc: Zhang, Helin, dev

On 3/30/2017 7:18 AM, Wu, Jingjing wrote:
> 
> 
>> -----Original Message-----
>> From: Xing, Beilei
>> Sent: Thursday, March 30, 2017 10:52 AM
>> To: Wu, Jingjing <jingjing.wu@intel.com>
>> Cc: Zhang, Helin <helin.zhang@intel.com>; dev@dpdk.org
>> Subject: [PATCH v8 0/6] dynamic device personalization support
>>
>> Due to limited resources of X*710 (parser and analyzer configuration tables,
>> number of packet classification types, number of packet types, filters
>> configuration tables, etc.), it's impossible to simultaneously support all
>> protocols/filters required for different parts on network.
>> To enable protocols/filters extensions for X*710, new Admin Command for
>> loading user defined configurations is added.
>> PPP is a format of extend configuration for X*710, it allows user to load user
>> defined configuration to X*710.
>>
>> List of possible use cases for extended X*710 configuration using profiles could
>> include following:
>> Configuring Analyzer/Parser to support new protocols, e.g.
>> - IP L2TPv3 tunneling protocol
>> - IPSec ESP/AH protocols
>> - MPLSoGRE, MPLSoUDP tunnels
>> - GTP-C/GTP-U tunnels
>> New PCTYPEs for offloading packet classification to X*710. e.g.
>> - new IP Protocol in addition to TCP/UDP/SCTP
>> - new TCP/UDP subtypes, like TCP SYN, TCP FIN
>> - new PCTYPE for tunneled packets like GTP-C, GTP-U New PTYPEs for packets
>> identification, e.g.
>> - MAC, MPLS, IP4, UDP
>> - MAC, MPLS, MPLS, IP6, TCP
>> Fixes for NVM configuration, e.g.
>> - list of enabled stat counters to improve throughput
>> - parser/analyzer configuration for some corner cases
>>
>> v8 changes:
>>  Change dynamic device profile to dynamic device personalization.
>>
>> v7 changes:
>>  Fix one coding style problem.
>>  Add condition during ddp processing.
>>
>> v6 changes:
>>  Change pipeline personalization profile to dynamic device profile.
>>
>> v5 changes:
>>  Change parameter of rte_pmd_i40e_process_ppp_package to extend
>> operation.
>>  Change structure rte_pmd_i40e_profile_info.
>>
>> v4 changes:
>>  Fix compile error with gcc version 4.8.4 (Ubuntu 4.8.4-2ubuntu1~14.04.3).
>>  Move ppp related structures to rte_pmd_i40e.h.
>>  Not support remove PPP temporarily.
>>
>> v3 changes:
>>  Move ppp AQ command code to base code.
> 
> Series Acked-by Jingjing Wu <jingjing.wu@intel.com>

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

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

* Re: [PATCH v8 1/6] net/i40e/base: change ppp to ddp
  2017-03-30  2:51                 ` [PATCH v8 1/6] net/i40e/base: change ppp to ddp Beilei Xing
@ 2017-03-30 14:06                   ` Ferruh Yigit
  0 siblings, 0 replies; 82+ messages in thread
From: Ferruh Yigit @ 2017-03-30 14:06 UTC (permalink / raw)
  To: Beilei Xing, jingjing.wu; +Cc: helin.zhang, dev

On 3/30/2017 3:51 AM, Beilei Xing wrote:
> Change pipeline personalization profile(ppp) to dynamic
> device personalization(ddp).
> 
> Signed-off-by: Beilei Xing <beilei.xing@intel.com>

This is not functional patch, just renaming, and not merged yet, so:

In next-net, squashed into original commit [1].

[1]
("net/i40e/base: new AQ commands for PPP")

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

* Re: [PATCH v8 2/6] net/i40e: add dynamic device personalization processing
  2017-03-30  2:51                 ` [PATCH v8 2/6] net/i40e: add dynamic device personalization processing Beilei Xing
@ 2017-03-30 14:06                   ` Ferruh Yigit
  2017-03-30 14:08                   ` Ferruh Yigit
  1 sibling, 0 replies; 82+ messages in thread
From: Ferruh Yigit @ 2017-03-30 14:06 UTC (permalink / raw)
  To: Beilei Xing, jingjing.wu; +Cc: helin.zhang, dev

On 3/30/2017 3:51 AM, Beilei Xing wrote:
> Add support for loading a dynamic device personalization
> profile.
> 
> Signed-off-by: Beilei Xing <beilei.xing@intel.com>

<...>

> +/**
> + * Load/Unload a ddp package
> + *
> + * @param port
> + *    The port identifier of the Ethernet device.
> + * @param buff
> + *    buffer of package.
> + * @param size
> + *    size of buffer.
> + * @param op
> + *   Operation of package processing
> + * @return
> + *   - (0) if successful.
> + *   - (-ENODEV) if *port* invalid.
> + *   - (-EINVAL) if bad parameter.
> + *   - (1) if profile exists.
> + */
> +int rte_pmd_i40e_process_ddp_package(uint8_t port, uint8_t *buff,
> +				     uint32_t size,
> +				     enum rte_pmd_i40e_package_op op);

Doxygen warnings [1] fixed while applying.

[1]
.../net/i40e/rte_pmd_i40e.h:481: warning: Found unknown command `\port'
.../net/i40e/rte_pmd_i40e.h:482: warning: Found unknown command `\buff'
.../net/i40e/rte_pmd_i40e.h:483: warning: Found unknown command `\size'

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

* Re: [PATCH v8 5/6] app/testpmd: add command for getting loaded profiles
  2017-03-30  2:51                 ` [PATCH v8 5/6] app/testpmd: add command for getting " Beilei Xing
@ 2017-03-30 14:07                   ` Ferruh Yigit
  0 siblings, 0 replies; 82+ messages in thread
From: Ferruh Yigit @ 2017-03-30 14:07 UTC (permalink / raw)
  To: Beilei Xing, jingjing.wu; +Cc: helin.zhang, dev

On 3/30/2017 3:51 AM, Beilei Xing wrote:
> This patch is to add testpmd CLI for getting all loaded
> ddp profiles.
> 
> Signed-off-by: Beilei Xing <beilei.xing@intel.com>

checkpatch warning [1] fixed while applying.

[1]
WARNING:QUOTED_WHITESPACE_BEFORE_NEWLINE: unnecessary whitespace before
a quoted newline
#101: FILE: app/test-pmd/cmdline.c:12877:
+			printf("Version:      %d.%d.%d.%d

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

* Re: [PATCH v8 2/6] net/i40e: add dynamic device personalization processing
  2017-03-30  2:51                 ` [PATCH v8 2/6] net/i40e: add dynamic device personalization processing Beilei Xing
  2017-03-30 14:06                   ` Ferruh Yigit
@ 2017-03-30 14:08                   ` Ferruh Yigit
  1 sibling, 0 replies; 82+ messages in thread
From: Ferruh Yigit @ 2017-03-30 14:08 UTC (permalink / raw)
  To: Beilei Xing, jingjing.wu; +Cc: helin.zhang, dev

On 3/30/2017 3:51 AM, Beilei Xing wrote:
> Add support for loading a dynamic device personalization
> profile.
> 
> Signed-off-by: Beilei Xing <beilei.xing@intel.com>

<...>

> diff --git a/drivers/net/i40e/rte_pmd_i40e.h b/drivers/net/i40e/rte_pmd_i40e.h
> index 3ca49a4..94dd92e 100644
> --- a/drivers/net/i40e/rte_pmd_i40e.h
> +++ b/drivers/net/i40e/rte_pmd_i40e.h
> @@ -65,6 +65,43 @@ struct rte_pmd_i40e_mb_event_param {
>  	uint16_t msglen;   /**< length of the message */
>  };
>  
> +enum rte_pmd_i40e_package_op {

This is generating a doxygen warning [1], can you please address this in
a separate patch?

Meanwhile some of the bellowing doxygen comments are not very detailed.
Please feel free to update them at will in patch.

Thanks,
ferruh

[1]
net/i40e/rte_pmd_i40e.h:68: warning: Member rte_pmd_i40e_package_op
(enumeration) of file rte_pmd_i40e.h is not documented.

> +	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_MAX = 32
> +};
> +
> +#define RTE_PMD_I40E_DDP_NAME_SIZE 32
> +
> +/**
> + * Dynamic device personalization version
> + */
> +struct rte_pmd_i40e_ddp_version {
> +	uint8_t major;
> +	uint8_t minor;
> +	uint8_t update;
> +	uint8_t draft;
> +};
> +
> +/**
> + * Structure of profile information
> + */
> +struct rte_pmd_i40e_profile_info {
> +	uint32_t track_id;
> +	struct rte_pmd_i40e_ddp_version version;
> +	uint8_t owner;
> +	uint8_t reserved[7];
> +	uint8_t name[RTE_PMD_I40E_DDP_NAME_SIZE];
> +};
> +
> +/**
> + * Structure of profile information list
> + */
> +struct rte_pmd_i40e_profile_list {
> +	uint32_t p_count;
> +	struct rte_pmd_i40e_profile_info p_info[1];
> +};

<...>

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

end of thread, other threads:[~2017-03-30 14:08 UTC | newest]

Thread overview: 82+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-03-03  7:26 [PATCH] MPSL enabling Beilei Xing
2017-03-03  7:26 ` [PATCH 1/2] net/i40e: change tunnel filter function name Beilei Xing
2017-03-03  7:26 ` [PATCH] ppp implemantation Beilei Xing
2017-03-03  9:39   ` Bruce Richardson
2017-03-03  9:41     ` Bruce Richardson
2017-03-03  7:26 ` [PATCH 2/2] net/i40e: parse NVGRE filter Beilei Xing
2017-03-03  7:26 ` [PATCH] PPP prototype Beilei Xing
2017-03-03  7:26 ` [PATCH] ppp implemantation Beilei Xing
2017-03-03  7:26 ` [PATCH 0/6] net/i40e: support pipeline personalization profile Beilei Xing
2017-03-03  7:39   ` [PATCH v2 0/5] " Beilei Xing
2017-03-03  7:39     ` [PATCH v2 1/5] " Beilei Xing
2017-03-08 12:07       ` Ferruh Yigit
2017-03-09  3:30         ` Xing, Beilei
2017-03-03  7:39     ` [PATCH v2 2/5] net/i40e: add ppp processing Beilei Xing
2017-03-08 12:07       ` Ferruh Yigit
2017-03-03  7:39     ` [PATCH v2 3/5] app/testpmd: add command for writing personalization profile Beilei Xing
2017-03-08 12:10       ` Ferruh Yigit
2017-03-03  7:39     ` [PATCH v2 4/5] net/i40e: add get all loaded profiles Beilei Xing
2017-03-03  7:39     ` [PATCH v2 5/5] app/testpmd: add command for getting " Beilei Xing
2017-03-08 11:43     ` [PATCH v2 0/5] net/i40e: support pipeline personalization profile Ferruh Yigit
2017-03-09  3:07       ` Xing, Beilei
2017-03-23 10:02     ` [PATCH v3 0/5] pipeline personalization profile support Beilei Xing
2017-03-23 10:02       ` [PATCH v3 1/5] net/i40e: add pipeline personalization profile processing Beilei Xing
2017-03-23 14:50         ` Iremonger, Bernard
2017-03-24  2:01           ` Xing, Beilei
2017-03-23 10:02       ` [PATCH v3 2/5] app/testpmd: add command for loading a profile Beilei Xing
2017-03-23 10:02       ` [PATCH v3 3/5] net/i40e: add get all loaded profiles Beilei Xing
2017-03-23 10:02       ` [PATCH v3 4/5] app/testpmd: add command for getting " Beilei Xing
2017-03-23 10:02       ` [PATCH v3 5/5] doc: add pipeline personalization profile support for i40e Beilei Xing
2017-03-24 10:19       ` [PATCH v4 0/5] pipeline personalization profile support Beilei Xing
2017-03-24 10:19         ` [PATCH v4 1/5] net/i40e: add pipeline personalization profile processing Beilei Xing
2017-03-24 14:52           ` Chilikin, Andrey
2017-03-25  4:04             ` Xing, Beilei
2017-03-25 21:03               ` Chilikin, Andrey
2017-03-27  2:09                 ` Xing, Beilei
2017-03-24 10:19         ` [PATCH v4 2/5] app/testpmd: add command for loading a profile Beilei Xing
2017-03-24 10:19         ` [PATCH v4 3/5] net/i40e: add get all loaded profiles Beilei Xing
2017-03-24 10:19         ` [PATCH v4 4/5] app/testpmd: add command for getting " Beilei Xing
2017-03-24 10:19         ` [PATCH v4 5/5] doc: add pipeline personalization profile support for i40e Beilei Xing
2017-03-24 14:31           ` Mcnamara, John
2017-03-27  6:17         ` [PATCH v5 0/5] pipeline personalization profile support Beilei Xing
2017-03-27  6:17           ` [PATCH v5 1/5] net/i40e: add pipeline personalization profile processing Beilei Xing
2017-03-27  6:17           ` [PATCH v5 2/5] app/testpmd: add command for loading a profile Beilei Xing
2017-03-27  6:17           ` [PATCH v5 3/5] net/i40e: add get all loaded profiles Beilei Xing
2017-03-27  6:17           ` [PATCH v5 4/5] app/testpmd: add command for getting " Beilei Xing
2017-03-27  6:17           ` [PATCH v5 5/5] doc: add pipeline personalization profile support for i40e Beilei Xing
2017-03-29 12:26           ` [PATCH v6 0/6] dynamic device profile support Beilei Xing
2017-03-29 12:26             ` [PATCH v6 1/6] net/i40e/base: change ppp to ddp Beilei Xing
2017-03-29 12:26             ` [PATCH v6 2/6] net/i40e: add dynamic device profile processing Beilei Xing
2017-03-29 13:17               ` Wu, Jingjing
2017-03-29 14:25                 ` Xing, Beilei
2017-03-29 12:26             ` [PATCH v6 3/6] app/testpmd: add command for loading a profile Beilei Xing
2017-03-29 12:26             ` [PATCH v6 4/6] net/i40e: add get all loaded profiles Beilei Xing
2017-03-29 12:26             ` [PATCH v6 5/6] app/testpmd: add command for getting " Beilei Xing
2017-03-29 12:26             ` [PATCH v6 6/6] doc: add dynamic device profile support for i40e Beilei Xing
2017-03-29 14:44             ` [PATCH v7 0/6] dynamic device profile support Beilei Xing
2017-03-29 14:44               ` [PATCH v7 1/6] net/i40e/base: change ppp to ddp Beilei Xing
2017-03-29 14:44               ` [PATCH v7 2/6] net/i40e: add dynamic device profile processing Beilei Xing
2017-03-29 14:44               ` [PATCH v7 3/6] app/testpmd: add command for loading a profile Beilei Xing
2017-03-29 14:44               ` [PATCH v7 4/6] net/i40e: add get all loaded profiles Beilei Xing
2017-03-29 14:44               ` [PATCH v7 5/6] app/testpmd: add command for getting " Beilei Xing
2017-03-29 14:44               ` [PATCH v7 6/6] doc: add dynamic device profile support for i40e Beilei Xing
2017-03-30  2:51               ` [PATCH v8 0/6] dynamic device personalization support Beilei Xing
2017-03-30  2:51                 ` [PATCH v8 1/6] net/i40e/base: change ppp to ddp Beilei Xing
2017-03-30 14:06                   ` Ferruh Yigit
2017-03-30  2:51                 ` [PATCH v8 2/6] net/i40e: add dynamic device personalization processing Beilei Xing
2017-03-30 14:06                   ` Ferruh Yigit
2017-03-30 14:08                   ` Ferruh Yigit
2017-03-30  2:51                 ` [PATCH v8 3/6] app/testpmd: add command for loading ddp Beilei Xing
2017-03-30  2:51                 ` [PATCH v8 4/6] net/i40e: add get all loaded profiles Beilei Xing
2017-03-30  2:51                 ` [PATCH v8 5/6] app/testpmd: add command for getting " Beilei Xing
2017-03-30 14:07                   ` Ferruh Yigit
2017-03-30  2:51                 ` [PATCH v8 6/6] doc: add dynamic device personalization support for i40e Beilei Xing
2017-03-30  6:18                 ` [PATCH v8 0/6] dynamic device personalization support Wu, Jingjing
2017-03-30 14:05                   ` Ferruh Yigit
2017-03-03  7:52   ` [PATCH 0/6] net/i40e: support pipeline personalization profile Xing, Beilei
2017-03-03  7:26 ` [PATCH 1/6] net/i40e: fix a typo in flow Beilei Xing
2017-03-03  7:26 ` [PATCH 2/6] net/i40e: support pipeline personalization profile Beilei Xing
2017-03-03  7:26 ` [PATCH 3/6] net/i40e: add ppp processing Beilei Xing
2017-03-03  7:26 ` [PATCH 4/6] app/testpmd: add command for writing personalization profile Beilei Xing
2017-03-03  7:26 ` [PATCH 5/6] net/i40e: add get all loaded profiles Beilei Xing
2017-03-03  7:26 ` [PATCH 6/6] app/testpmd: add command for getting " Beilei Xing

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.