[PATCH] maintainers: update for intel PMD

2024-01-18 Thread Qi Zhang
Remove my name for next-net-intel, fm10k, ice and af_xdp.

Signed-off-by: Qi Zhang 
---
 MAINTAINERS | 4 
 1 file changed, 4 deletions(-)

diff --git a/MAINTAINERS b/MAINTAINERS
index 0d1c8126e3..7d74486d1a 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -37,7 +37,6 @@ M: Ajit Khaparde 
 T: git://dpdk.org/next/dpdk-next-net-brcm
 
 Next-net-intel Tree
-M: Qi Zhang 
 T: git://dpdk.org/next/dpdk-next-net-intel
 
 Next-net-mrvl Tree
@@ -634,7 +633,6 @@ F: doc/guides/nics/features/afpacket.ini
 
 Linux AF_XDP
 M: Ciara Loftus 
-M: Qi Zhang 
 F: drivers/net/af_xdp/
 F: doc/guides/nics/af_xdp.rst
 F: doc/guides/nics/features/af_xdp.ini
@@ -767,7 +765,6 @@ F: doc/guides/nics/intel_vf.rst
 F: doc/guides/nics/features/i40e*.ini
 
 Intel fm10k
-M: Qi Zhang 
 M: Xiao Wang 
 T: git://dpdk.org/next/dpdk-next-net-intel
 F: drivers/net/fm10k/
@@ -784,7 +781,6 @@ F: doc/guides/nics/features/iavf*.ini
 
 Intel ice
 M: Qiming Yang 
-M: Qi Zhang 
 T: git://dpdk.org/next/dpdk-next-net-intel
 F: drivers/net/ice/
 F: doc/guides/nics/ice.rst
-- 
2.31.1



[PATCH v4 3/3] doc: update ice document for qos

2024-01-08 Thread Qi Zhang
Add description for ice PMD's rte_tm capabilities.

Signed-off-by: Qi Zhang 
Acked-by: Wenjun Wu 
---
 doc/guides/nics/ice.rst | 19 +++
 1 file changed, 19 insertions(+)

diff --git a/doc/guides/nics/ice.rst b/doc/guides/nics/ice.rst
index bafb3ba022..163d6b8bb6 100644
--- a/doc/guides/nics/ice.rst
+++ b/doc/guides/nics/ice.rst
@@ -352,6 +352,25 @@ queue 3 using a raw pattern::
 
 Currently, raw pattern support is limited to the FDIR and Hash engines.
 
+Traffic Management Support
+~~
+
+The ice PMD provides support for the Traffic Management API (RTE_TM), allow
+users to offload a 3-layers Tx scheduler on the E810 NIC:
+
+- ``Port Layer``
+
+  This is the root layer, support peak bandwidth configuration, max to 32 
children.
+
+- ``Queue Group Layer``
+
+  The middel layer, support peak / committed bandwidth, weight, priority 
configurations,
+  max to 8 children.
+
+- ``Queue Layer``
+
+  The leaf layer, support peak / committed bandwidth, weight, priority 
configurations.
+
 Additional Options
 ++
 
-- 
2.31.1



[PATCH v4 2/3] net/ice: refactor tm config data structure

2024-01-08 Thread Qi Zhang
Simplified struct ice_tm_conf by removing per level node list.

Signed-off-by: Qi Zhang 
---
 drivers/net/ice/ice_ethdev.h |   5 +-
 drivers/net/ice/ice_tm.c | 248 ---
 2 files changed, 113 insertions(+), 140 deletions(-)

diff --git a/drivers/net/ice/ice_ethdev.h b/drivers/net/ice/ice_ethdev.h
index ae22c29ffc..008a7a23b9 100644
--- a/drivers/net/ice/ice_ethdev.h
+++ b/drivers/net/ice/ice_ethdev.h
@@ -472,6 +472,7 @@ struct ice_tm_node {
uint32_t id;
uint32_t priority;
uint32_t weight;
+   uint32_t level;
uint32_t reference_count;
struct ice_tm_node *parent;
struct ice_tm_node **children;
@@ -492,10 +493,6 @@ enum ice_tm_node_type {
 struct ice_tm_conf {
struct ice_shaper_profile_list shaper_profile_list;
struct ice_tm_node *root; /* root node - port */
-   struct ice_tm_node_list qgroup_list; /* node list for all the queue 
groups */
-   struct ice_tm_node_list queue_list; /* node list for all the queues */
-   uint32_t nb_qgroup_node;
-   uint32_t nb_queue_node;
bool committed;
bool clear_on_fail;
 };
diff --git a/drivers/net/ice/ice_tm.c b/drivers/net/ice/ice_tm.c
index d67783c77e..fbab0b8808 100644
--- a/drivers/net/ice/ice_tm.c
+++ b/drivers/net/ice/ice_tm.c
@@ -6,6 +6,9 @@
 #include "ice_ethdev.h"
 #include "ice_rxtx.h"
 
+#define MAX_CHILDREN_PER_SCHED_NODE8
+#define MAX_CHILDREN_PER_TM_NODE   256
+
 static int ice_hierarchy_commit(struct rte_eth_dev *dev,
 int clear_on_fail,
 __rte_unused struct rte_tm_error *error);
@@ -43,20 +46,28 @@ ice_tm_conf_init(struct rte_eth_dev *dev)
/* initialize node configuration */
TAILQ_INIT(&pf->tm_conf.shaper_profile_list);
pf->tm_conf.root = NULL;
-   TAILQ_INIT(&pf->tm_conf.qgroup_list);
-   TAILQ_INIT(&pf->tm_conf.queue_list);
-   pf->tm_conf.nb_qgroup_node = 0;
-   pf->tm_conf.nb_queue_node = 0;
pf->tm_conf.committed = false;
pf->tm_conf.clear_on_fail = false;
 }
 
+static void free_node(struct ice_tm_node *root)
+{
+   uint32_t i;
+
+   if (root == NULL)
+   return;
+
+   for (i = 0; i < root->reference_count; i++)
+   free_node(root->children[i]);
+
+   rte_free(root);
+}
+
 void
 ice_tm_conf_uninit(struct rte_eth_dev *dev)
 {
struct ice_pf *pf = ICE_DEV_PRIVATE_TO_PF(dev->data->dev_private);
struct ice_tm_shaper_profile *shaper_profile;
-   struct ice_tm_node *tm_node;
 
/* clear profile */
while ((shaper_profile = 
TAILQ_FIRST(&pf->tm_conf.shaper_profile_list))) {
@@ -64,52 +75,8 @@ ice_tm_conf_uninit(struct rte_eth_dev *dev)
rte_free(shaper_profile);
}
 
-   /* clear node configuration */
-   while ((tm_node = TAILQ_FIRST(&pf->tm_conf.queue_list))) {
-   TAILQ_REMOVE(&pf->tm_conf.queue_list, tm_node, node);
-   rte_free(tm_node);
-   }
-   pf->tm_conf.nb_queue_node = 0;
-   while ((tm_node = TAILQ_FIRST(&pf->tm_conf.qgroup_list))) {
-   TAILQ_REMOVE(&pf->tm_conf.qgroup_list, tm_node, node);
-   rte_free(tm_node);
-   }
-   pf->tm_conf.nb_qgroup_node = 0;
-   if (pf->tm_conf.root) {
-   rte_free(pf->tm_conf.root);
-   pf->tm_conf.root = NULL;
-   }
-}
-
-static inline struct ice_tm_node *
-ice_tm_node_search(struct rte_eth_dev *dev,
-   uint32_t node_id, enum ice_tm_node_type *node_type)
-{
-   struct ice_pf *pf = ICE_DEV_PRIVATE_TO_PF(dev->data->dev_private);
-   struct ice_tm_node_list *qgroup_list = &pf->tm_conf.qgroup_list;
-   struct ice_tm_node_list *queue_list = &pf->tm_conf.queue_list;
-   struct ice_tm_node *tm_node;
-
-   if (pf->tm_conf.root && pf->tm_conf.root->id == node_id) {
-   *node_type = ICE_TM_NODE_TYPE_PORT;
-   return pf->tm_conf.root;
-   }
-
-   TAILQ_FOREACH(tm_node, qgroup_list, node) {
-   if (tm_node->id == node_id) {
-   *node_type = ICE_TM_NODE_TYPE_QGROUP;
-   return tm_node;
-   }
-   }
-
-   TAILQ_FOREACH(tm_node, queue_list, node) {
-   if (tm_node->id == node_id) {
-   *node_type = ICE_TM_NODE_TYPE_QUEUE;
-   return tm_node;
-   }
-   }
-
-   return NULL;
+   free_node(pf->tm_conf.root);
+   pf->tm_conf.root = NULL;
 }
 
 static int
@@ -202,11 +169,29 @@ ice_node_param_check(struct ice_pf *pf, uint32_t node_id,
return 0;
 }
 
+static struct ice_tm_node *
+find_node(struct ice_tm_node *root, uint32_t id)
+{
+   uint32_t i;
+
+   if (root == NULL || ro

[PATCH v4 1/3] net/ice: hide port and TC layer in Tx sched tree

2024-01-08 Thread Qi Zhang
In currently 5 layer tree implementation, the port and tc layer
is not configurable, so its not necessary to expose them to application.

The patch hides the top 2 layers and represented the root of the tree at
VSI layer. From application's point of view, its a 3 layer scheduler tree:

Port -> Queue Group -> Queue.

Signed-off-by: Qi Zhang 
Acked-by: Wenjun Wu 
---
 drivers/net/ice/ice_ethdev.h |  7 
 drivers/net/ice/ice_tm.c | 79 
 2 files changed, 7 insertions(+), 79 deletions(-)

diff --git a/drivers/net/ice/ice_ethdev.h b/drivers/net/ice/ice_ethdev.h
index fa4981ed14..ae22c29ffc 100644
--- a/drivers/net/ice/ice_ethdev.h
+++ b/drivers/net/ice/ice_ethdev.h
@@ -470,7 +470,6 @@ struct ice_tm_shaper_profile {
 struct ice_tm_node {
TAILQ_ENTRY(ice_tm_node) node;
uint32_t id;
-   uint32_t tc;
uint32_t priority;
uint32_t weight;
uint32_t reference_count;
@@ -484,8 +483,6 @@ struct ice_tm_node {
 /* node type of Traffic Manager */
 enum ice_tm_node_type {
ICE_TM_NODE_TYPE_PORT,
-   ICE_TM_NODE_TYPE_TC,
-   ICE_TM_NODE_TYPE_VSI,
ICE_TM_NODE_TYPE_QGROUP,
ICE_TM_NODE_TYPE_QUEUE,
ICE_TM_NODE_TYPE_MAX,
@@ -495,12 +492,8 @@ enum ice_tm_node_type {
 struct ice_tm_conf {
struct ice_shaper_profile_list shaper_profile_list;
struct ice_tm_node *root; /* root node - port */
-   struct ice_tm_node_list tc_list; /* node list for all the TCs */
-   struct ice_tm_node_list vsi_list; /* node list for all the VSIs */
struct ice_tm_node_list qgroup_list; /* node list for all the queue 
groups */
struct ice_tm_node_list queue_list; /* node list for all the queues */
-   uint32_t nb_tc_node;
-   uint32_t nb_vsi_node;
uint32_t nb_qgroup_node;
uint32_t nb_queue_node;
bool committed;
diff --git a/drivers/net/ice/ice_tm.c b/drivers/net/ice/ice_tm.c
index c00ecb6a97..d67783c77e 100644
--- a/drivers/net/ice/ice_tm.c
+++ b/drivers/net/ice/ice_tm.c
@@ -43,12 +43,8 @@ ice_tm_conf_init(struct rte_eth_dev *dev)
/* initialize node configuration */
TAILQ_INIT(&pf->tm_conf.shaper_profile_list);
pf->tm_conf.root = NULL;
-   TAILQ_INIT(&pf->tm_conf.tc_list);
-   TAILQ_INIT(&pf->tm_conf.vsi_list);
TAILQ_INIT(&pf->tm_conf.qgroup_list);
TAILQ_INIT(&pf->tm_conf.queue_list);
-   pf->tm_conf.nb_tc_node = 0;
-   pf->tm_conf.nb_vsi_node = 0;
pf->tm_conf.nb_qgroup_node = 0;
pf->tm_conf.nb_queue_node = 0;
pf->tm_conf.committed = false;
@@ -79,16 +75,6 @@ ice_tm_conf_uninit(struct rte_eth_dev *dev)
rte_free(tm_node);
}
pf->tm_conf.nb_qgroup_node = 0;
-   while ((tm_node = TAILQ_FIRST(&pf->tm_conf.vsi_list))) {
-   TAILQ_REMOVE(&pf->tm_conf.vsi_list, tm_node, node);
-   rte_free(tm_node);
-   }
-   pf->tm_conf.nb_vsi_node = 0;
-   while ((tm_node = TAILQ_FIRST(&pf->tm_conf.tc_list))) {
-   TAILQ_REMOVE(&pf->tm_conf.tc_list, tm_node, node);
-   rte_free(tm_node);
-   }
-   pf->tm_conf.nb_tc_node = 0;
if (pf->tm_conf.root) {
rte_free(pf->tm_conf.root);
pf->tm_conf.root = NULL;
@@ -100,8 +86,6 @@ ice_tm_node_search(struct rte_eth_dev *dev,
uint32_t node_id, enum ice_tm_node_type *node_type)
 {
struct ice_pf *pf = ICE_DEV_PRIVATE_TO_PF(dev->data->dev_private);
-   struct ice_tm_node_list *tc_list = &pf->tm_conf.tc_list;
-   struct ice_tm_node_list *vsi_list = &pf->tm_conf.vsi_list;
struct ice_tm_node_list *qgroup_list = &pf->tm_conf.qgroup_list;
struct ice_tm_node_list *queue_list = &pf->tm_conf.queue_list;
struct ice_tm_node *tm_node;
@@ -111,20 +95,6 @@ ice_tm_node_search(struct rte_eth_dev *dev,
return pf->tm_conf.root;
}
 
-   TAILQ_FOREACH(tm_node, tc_list, node) {
-   if (tm_node->id == node_id) {
-   *node_type = ICE_TM_NODE_TYPE_TC;
-   return tm_node;
-   }
-   }
-
-   TAILQ_FOREACH(tm_node, vsi_list, node) {
-   if (tm_node->id == node_id) {
-   *node_type = ICE_TM_NODE_TYPE_VSI;
-   return tm_node;
-   }
-   }
-
TAILQ_FOREACH(tm_node, qgroup_list, node) {
if (tm_node->id == node_id) {
*node_type = ICE_TM_NODE_TYPE_QGROUP;
@@ -378,6 +348,8 @@ ice_shaper_profile_del(struct rte_eth_dev *dev,
return 0;
 }
 
+#define MAX_QUEUE_PER_GROUP8
+
 static int
 ice_tm_node_add(struct rte_eth_dev *dev, uint32_t node_id,
  uint32_t parent_node_id, uint32_t priority,
@@ -391,8 +363,6 @@ ice_tm_node_add

[PATCH v4 0/3] simplified to 3 layer Tx scheduler

2024-01-08 Thread Qi Zhang
Remove dummy layers, code refactor, complete document

v4:
- rebase.

v3:
- fix tm_node memory free.
- fix corrupt when slibling node deletion is not in a reversed order.

v2:
- fix typos.

Qi Zhang (3):
  net/ice: hide port and TC layer in Tx sched tree
  net/ice: refactor tm config data structure
  doc: update ice document for qos

 doc/guides/nics/ice.rst  |  19 +++
 drivers/net/ice/ice_ethdev.h |  12 +-
 drivers/net/ice/ice_tm.c | 317 +--
 3 files changed, 134 insertions(+), 214 deletions(-)

-- 
2.31.1



[PATCH] net/ice: fix memory leak

2024-01-07 Thread Qi Zhang
Free memory for AQ buffer at icd_move_recfg_lan_txq
Free memory for profile list at ice_tm_conf_uninit

Fixes: 8c481c3bb65b ("net/ice: support queue and queue group bandwidth limit")
Cc: sta...@dpdk.org

Signed-off-by: Qi Zhang 
---
 drivers/net/ice/ice_tm.c | 12 
 1 file changed, 12 insertions(+)

diff --git a/drivers/net/ice/ice_tm.c b/drivers/net/ice/ice_tm.c
index b570798f07..c00ecb6a97 100644
--- a/drivers/net/ice/ice_tm.c
+++ b/drivers/net/ice/ice_tm.c
@@ -59,8 +59,15 @@ void
 ice_tm_conf_uninit(struct rte_eth_dev *dev)
 {
struct ice_pf *pf = ICE_DEV_PRIVATE_TO_PF(dev->data->dev_private);
+   struct ice_tm_shaper_profile *shaper_profile;
struct ice_tm_node *tm_node;
 
+   /* clear profile */
+   while ((shaper_profile = 
TAILQ_FIRST(&pf->tm_conf.shaper_profile_list))) {
+   TAILQ_REMOVE(&pf->tm_conf.shaper_profile_list, shaper_profile, 
node);
+   rte_free(shaper_profile);
+   }
+
/* clear node configuration */
while ((tm_node = TAILQ_FIRST(&pf->tm_conf.queue_list))) {
TAILQ_REMOVE(&pf->tm_conf.queue_list, tm_node, node);
@@ -636,6 +643,8 @@ static int ice_move_recfg_lan_txq(struct rte_eth_dev *dev,
uint16_t buf_size = ice_struct_size(buf, txqs, 1);
 
buf = (struct ice_aqc_move_txqs_data *)ice_malloc(hw, sizeof(*buf));
+   if (buf == NULL)
+   return -ENOMEM;
 
queue_parent_node = queue_sched_node->parent;
buf->src_teid = queue_parent_node->info.node_teid;
@@ -647,6 +656,7 @@ static int ice_move_recfg_lan_txq(struct rte_eth_dev *dev,
NULL, buf, buf_size, &txqs_moved, NULL);
if (ret || txqs_moved == 0) {
PMD_DRV_LOG(ERR, "move lan queue %u failed", queue_id);
+   rte_free(buf);
return ICE_ERR_PARAM;
}
 
@@ -656,12 +666,14 @@ static int ice_move_recfg_lan_txq(struct rte_eth_dev *dev,
} else {
PMD_DRV_LOG(ERR, "invalid children number %d for queue %u",
queue_parent_node->num_children, queue_id);
+   rte_free(buf);
return ICE_ERR_PARAM;
}
dst_node->children[dst_node->num_children++] = queue_sched_node;
queue_sched_node->parent = dst_node;
ice_sched_query_elem(hw, queue_sched_node->info.node_teid, 
&queue_sched_node->info);
 
+   rte_free(buf);
return ret;
 }
 
-- 
2.31.1



[PATCH v3 3/3] doc: update ice document for qos

2024-01-05 Thread Qi Zhang
Add description for ice PMD's rte_tm capabilities.

Signed-off-by: Qi Zhang 
Acked-by: Wenjun Wu 
---
 doc/guides/nics/ice.rst | 19 +++
 1 file changed, 19 insertions(+)

diff --git a/doc/guides/nics/ice.rst b/doc/guides/nics/ice.rst
index bafb3ba022..3d381a266b 100644
--- a/doc/guides/nics/ice.rst
+++ b/doc/guides/nics/ice.rst
@@ -352,6 +352,25 @@ queue 3 using a raw pattern::
 
 Currently, raw pattern support is limited to the FDIR and Hash engines.
 
+Traffic Management Support
+~~
+
+The ice PMD provides support for the Traffic Management API (RTE_RM), allow
+users to offload a 3-layers Tx scheduler on the E810 NIC:
+
+- ``Port Layer``
+
+  This is the root layer, support peak bandwidth configuration, max to 32 
children.
+
+- ``Queue Group Layer``
+
+  The middel layer, support peak / committed bandwidth, weight, priority 
configurations,
+  max to 8 children.
+
+- ``Queue Layer``
+
+  The leaf layer, support peak / committed bandwidth, weight, priority 
configurations.
+
 Additional Options
 ++
 
-- 
2.31.1



[PATCH v3 2/3] net/ice: refactor tm config data structure

2024-01-05 Thread Qi Zhang
Simplified struct ice_tm_conf by removing per level node list.

Signed-off-by: Qi Zhang 
---
 drivers/net/ice/ice_ethdev.h |   5 +-
 drivers/net/ice/ice_tm.c | 244 ---
 2 files changed, 111 insertions(+), 138 deletions(-)

diff --git a/drivers/net/ice/ice_ethdev.h b/drivers/net/ice/ice_ethdev.h
index ae22c29ffc..008a7a23b9 100644
--- a/drivers/net/ice/ice_ethdev.h
+++ b/drivers/net/ice/ice_ethdev.h
@@ -472,6 +472,7 @@ struct ice_tm_node {
uint32_t id;
uint32_t priority;
uint32_t weight;
+   uint32_t level;
uint32_t reference_count;
struct ice_tm_node *parent;
struct ice_tm_node **children;
@@ -492,10 +493,6 @@ enum ice_tm_node_type {
 struct ice_tm_conf {
struct ice_shaper_profile_list shaper_profile_list;
struct ice_tm_node *root; /* root node - port */
-   struct ice_tm_node_list qgroup_list; /* node list for all the queue 
groups */
-   struct ice_tm_node_list queue_list; /* node list for all the queues */
-   uint32_t nb_qgroup_node;
-   uint32_t nb_queue_node;
bool committed;
bool clear_on_fail;
 };
diff --git a/drivers/net/ice/ice_tm.c b/drivers/net/ice/ice_tm.c
index 7ae68c683b..c579662843 100644
--- a/drivers/net/ice/ice_tm.c
+++ b/drivers/net/ice/ice_tm.c
@@ -6,6 +6,9 @@
 #include "ice_ethdev.h"
 #include "ice_rxtx.h"
 
+#define MAX_CHILDREN_PER_SCHED_NODE8
+#define MAX_CHILDREN_PER_TM_NODE   256
+
 static int ice_hierarchy_commit(struct rte_eth_dev *dev,
 int clear_on_fail,
 __rte_unused struct rte_tm_error *error);
@@ -43,66 +46,30 @@ ice_tm_conf_init(struct rte_eth_dev *dev)
/* initialize node configuration */
TAILQ_INIT(&pf->tm_conf.shaper_profile_list);
pf->tm_conf.root = NULL;
-   TAILQ_INIT(&pf->tm_conf.qgroup_list);
-   TAILQ_INIT(&pf->tm_conf.queue_list);
-   pf->tm_conf.nb_qgroup_node = 0;
-   pf->tm_conf.nb_queue_node = 0;
pf->tm_conf.committed = false;
pf->tm_conf.clear_on_fail = false;
 }
 
-void
-ice_tm_conf_uninit(struct rte_eth_dev *dev)
+static void free_node(struct ice_tm_node *root)
 {
-   struct ice_pf *pf = ICE_DEV_PRIVATE_TO_PF(dev->data->dev_private);
-   struct ice_tm_node *tm_node;
+   uint32_t i;
 
-   /* clear node configuration */
-   while ((tm_node = TAILQ_FIRST(&pf->tm_conf.queue_list))) {
-   TAILQ_REMOVE(&pf->tm_conf.queue_list, tm_node, node);
-   rte_free(tm_node);
-   }
-   pf->tm_conf.nb_queue_node = 0;
-   while ((tm_node = TAILQ_FIRST(&pf->tm_conf.qgroup_list))) {
-   TAILQ_REMOVE(&pf->tm_conf.qgroup_list, tm_node, node);
-   rte_free(tm_node);
-   }
-   pf->tm_conf.nb_qgroup_node = 0;
-   if (pf->tm_conf.root) {
-   rte_free(pf->tm_conf.root);
-   pf->tm_conf.root = NULL;
-   }
+   if (root == NULL)
+   return;
+
+   for (i = 0; i < root->reference_count; i++)
+   free_node(root->children[i]);
+
+   rte_free(root);
 }
 
-static inline struct ice_tm_node *
-ice_tm_node_search(struct rte_eth_dev *dev,
-   uint32_t node_id, enum ice_tm_node_type *node_type)
+void
+ice_tm_conf_uninit(struct rte_eth_dev *dev)
 {
struct ice_pf *pf = ICE_DEV_PRIVATE_TO_PF(dev->data->dev_private);
-   struct ice_tm_node_list *qgroup_list = &pf->tm_conf.qgroup_list;
-   struct ice_tm_node_list *queue_list = &pf->tm_conf.queue_list;
-   struct ice_tm_node *tm_node;
-
-   if (pf->tm_conf.root && pf->tm_conf.root->id == node_id) {
-   *node_type = ICE_TM_NODE_TYPE_PORT;
-   return pf->tm_conf.root;
-   }
 
-   TAILQ_FOREACH(tm_node, qgroup_list, node) {
-   if (tm_node->id == node_id) {
-   *node_type = ICE_TM_NODE_TYPE_QGROUP;
-   return tm_node;
-   }
-   }
-
-   TAILQ_FOREACH(tm_node, queue_list, node) {
-   if (tm_node->id == node_id) {
-   *node_type = ICE_TM_NODE_TYPE_QUEUE;
-   return tm_node;
-   }
-   }
-
-   return NULL;
+   free_node(pf->tm_conf.root);
+   pf->tm_conf.root = NULL;
 }
 
 static int
@@ -195,11 +162,29 @@ ice_node_param_check(struct ice_pf *pf, uint32_t node_id,
return 0;
 }
 
+static struct ice_tm_node *
+find_node(struct ice_tm_node *root, uint32_t id)
+{
+   uint32_t i;
+
+   if (root == NULL || root->id == id)
+   return root;
+
+   for (i = 0; i < root->reference_count; i++) {
+   struct ice_tm_node *node = find_node(root->children[i], id);
+
+   if (node)
+   return

[PATCH v3 1/3] net/ice: hide port and TC layer in Tx sched tree

2024-01-05 Thread Qi Zhang
In currently 5 layer tree implementation, the port and tc layer
is not configurable, so its not necessary to expose them to application.

The patch hides the top 2 layers and represented the root of the tree at
VSI layer. From application's point of view, its a 3 layer scheduler tree:

Port -> Queue Group -> Queue.

Signed-off-by: Qi Zhang 
Acked-by: Wenjun Wu 
---
 drivers/net/ice/ice_ethdev.h |  7 
 drivers/net/ice/ice_tm.c | 79 
 2 files changed, 7 insertions(+), 79 deletions(-)

diff --git a/drivers/net/ice/ice_ethdev.h b/drivers/net/ice/ice_ethdev.h
index fa4981ed14..ae22c29ffc 100644
--- a/drivers/net/ice/ice_ethdev.h
+++ b/drivers/net/ice/ice_ethdev.h
@@ -470,7 +470,6 @@ struct ice_tm_shaper_profile {
 struct ice_tm_node {
TAILQ_ENTRY(ice_tm_node) node;
uint32_t id;
-   uint32_t tc;
uint32_t priority;
uint32_t weight;
uint32_t reference_count;
@@ -484,8 +483,6 @@ struct ice_tm_node {
 /* node type of Traffic Manager */
 enum ice_tm_node_type {
ICE_TM_NODE_TYPE_PORT,
-   ICE_TM_NODE_TYPE_TC,
-   ICE_TM_NODE_TYPE_VSI,
ICE_TM_NODE_TYPE_QGROUP,
ICE_TM_NODE_TYPE_QUEUE,
ICE_TM_NODE_TYPE_MAX,
@@ -495,12 +492,8 @@ enum ice_tm_node_type {
 struct ice_tm_conf {
struct ice_shaper_profile_list shaper_profile_list;
struct ice_tm_node *root; /* root node - port */
-   struct ice_tm_node_list tc_list; /* node list for all the TCs */
-   struct ice_tm_node_list vsi_list; /* node list for all the VSIs */
struct ice_tm_node_list qgroup_list; /* node list for all the queue 
groups */
struct ice_tm_node_list queue_list; /* node list for all the queues */
-   uint32_t nb_tc_node;
-   uint32_t nb_vsi_node;
uint32_t nb_qgroup_node;
uint32_t nb_queue_node;
bool committed;
diff --git a/drivers/net/ice/ice_tm.c b/drivers/net/ice/ice_tm.c
index b570798f07..7ae68c683b 100644
--- a/drivers/net/ice/ice_tm.c
+++ b/drivers/net/ice/ice_tm.c
@@ -43,12 +43,8 @@ ice_tm_conf_init(struct rte_eth_dev *dev)
/* initialize node configuration */
TAILQ_INIT(&pf->tm_conf.shaper_profile_list);
pf->tm_conf.root = NULL;
-   TAILQ_INIT(&pf->tm_conf.tc_list);
-   TAILQ_INIT(&pf->tm_conf.vsi_list);
TAILQ_INIT(&pf->tm_conf.qgroup_list);
TAILQ_INIT(&pf->tm_conf.queue_list);
-   pf->tm_conf.nb_tc_node = 0;
-   pf->tm_conf.nb_vsi_node = 0;
pf->tm_conf.nb_qgroup_node = 0;
pf->tm_conf.nb_queue_node = 0;
pf->tm_conf.committed = false;
@@ -72,16 +68,6 @@ ice_tm_conf_uninit(struct rte_eth_dev *dev)
rte_free(tm_node);
}
pf->tm_conf.nb_qgroup_node = 0;
-   while ((tm_node = TAILQ_FIRST(&pf->tm_conf.vsi_list))) {
-   TAILQ_REMOVE(&pf->tm_conf.vsi_list, tm_node, node);
-   rte_free(tm_node);
-   }
-   pf->tm_conf.nb_vsi_node = 0;
-   while ((tm_node = TAILQ_FIRST(&pf->tm_conf.tc_list))) {
-   TAILQ_REMOVE(&pf->tm_conf.tc_list, tm_node, node);
-   rte_free(tm_node);
-   }
-   pf->tm_conf.nb_tc_node = 0;
if (pf->tm_conf.root) {
rte_free(pf->tm_conf.root);
pf->tm_conf.root = NULL;
@@ -93,8 +79,6 @@ ice_tm_node_search(struct rte_eth_dev *dev,
uint32_t node_id, enum ice_tm_node_type *node_type)
 {
struct ice_pf *pf = ICE_DEV_PRIVATE_TO_PF(dev->data->dev_private);
-   struct ice_tm_node_list *tc_list = &pf->tm_conf.tc_list;
-   struct ice_tm_node_list *vsi_list = &pf->tm_conf.vsi_list;
struct ice_tm_node_list *qgroup_list = &pf->tm_conf.qgroup_list;
struct ice_tm_node_list *queue_list = &pf->tm_conf.queue_list;
struct ice_tm_node *tm_node;
@@ -104,20 +88,6 @@ ice_tm_node_search(struct rte_eth_dev *dev,
return pf->tm_conf.root;
}
 
-   TAILQ_FOREACH(tm_node, tc_list, node) {
-   if (tm_node->id == node_id) {
-   *node_type = ICE_TM_NODE_TYPE_TC;
-   return tm_node;
-   }
-   }
-
-   TAILQ_FOREACH(tm_node, vsi_list, node) {
-   if (tm_node->id == node_id) {
-   *node_type = ICE_TM_NODE_TYPE_VSI;
-   return tm_node;
-   }
-   }
-
TAILQ_FOREACH(tm_node, qgroup_list, node) {
if (tm_node->id == node_id) {
*node_type = ICE_TM_NODE_TYPE_QGROUP;
@@ -371,6 +341,8 @@ ice_shaper_profile_del(struct rte_eth_dev *dev,
return 0;
 }
 
+#define MAX_QUEUE_PER_GROUP8
+
 static int
 ice_tm_node_add(struct rte_eth_dev *dev, uint32_t node_id,
  uint32_t parent_node_id, uint32_t priority,
@@ -384,8 +356,6 @@ ice_tm_node_add

[PATCH v3 0/3] net/ice: simplified to 3 layer Tx scheduler

2024-01-05 Thread Qi Zhang
Remove dummy layers, code refactor, complete document

v3:
- fix tm_node memory free.
- fix corrupt when slibling node deletion is not in a reversed order.

v2:
- fix typos.

Qi Zhang (3):
  net/ice: hide port and TC layer in Tx sched tree
  net/ice: refactor tm config data structure
  doc: update ice document for qos

 doc/guides/nics/ice.rst  |  19 +++
 drivers/net/ice/ice_ethdev.h |  12 +-
 drivers/net/ice/ice_tm.c | 313 +--
 3 files changed, 132 insertions(+), 212 deletions(-)

-- 
2.31.1



[PATCH v2 3/3] doc: update ice document for qos

2024-01-04 Thread Qi Zhang
Add description for ice PMD's rte_tm capabilities.

Signed-off-by: Qi Zhang 
---
 doc/guides/nics/ice.rst | 19 +++
 1 file changed, 19 insertions(+)

diff --git a/doc/guides/nics/ice.rst b/doc/guides/nics/ice.rst
index bafb3ba022..3d381a266b 100644
--- a/doc/guides/nics/ice.rst
+++ b/doc/guides/nics/ice.rst
@@ -352,6 +352,25 @@ queue 3 using a raw pattern::
 
 Currently, raw pattern support is limited to the FDIR and Hash engines.
 
+Traffic Management Support
+~~
+
+The ice PMD provides support for the Traffic Management API (RTE_RM), allow
+users to offload a 3-layers Tx scheduler on the E810 NIC:
+
+- ``Port Layer``
+
+  This is the root layer, support peak bandwidth configuration, max to 32 
children.
+
+- ``Queue Group Layer``
+
+  The middel layer, support peak / committed bandwidth, weight, priority 
configurations,
+  max to 8 children.
+
+- ``Queue Layer``
+
+  The leaf layer, support peak / committed bandwidth, weight, priority 
configurations.
+
 Additional Options
 ++
 
-- 
2.31.1



[PATCH v2 2/3] net/ice: refactor tm config data structure

2024-01-04 Thread Qi Zhang
Simplified struct ice_tm_conf by removing per level node list.

Signed-off-by: Qi Zhang 
---
 drivers/net/ice/ice_ethdev.h |   5 +-
 drivers/net/ice/ice_tm.c | 210 +++
 2 files changed, 88 insertions(+), 127 deletions(-)

diff --git a/drivers/net/ice/ice_ethdev.h b/drivers/net/ice/ice_ethdev.h
index ae22c29ffc..008a7a23b9 100644
--- a/drivers/net/ice/ice_ethdev.h
+++ b/drivers/net/ice/ice_ethdev.h
@@ -472,6 +472,7 @@ struct ice_tm_node {
uint32_t id;
uint32_t priority;
uint32_t weight;
+   uint32_t level;
uint32_t reference_count;
struct ice_tm_node *parent;
struct ice_tm_node **children;
@@ -492,10 +493,6 @@ enum ice_tm_node_type {
 struct ice_tm_conf {
struct ice_shaper_profile_list shaper_profile_list;
struct ice_tm_node *root; /* root node - port */
-   struct ice_tm_node_list qgroup_list; /* node list for all the queue 
groups */
-   struct ice_tm_node_list queue_list; /* node list for all the queues */
-   uint32_t nb_qgroup_node;
-   uint32_t nb_queue_node;
bool committed;
bool clear_on_fail;
 };
diff --git a/drivers/net/ice/ice_tm.c b/drivers/net/ice/ice_tm.c
index 7ae68c683b..7c662f8a85 100644
--- a/drivers/net/ice/ice_tm.c
+++ b/drivers/net/ice/ice_tm.c
@@ -43,66 +43,30 @@ ice_tm_conf_init(struct rte_eth_dev *dev)
/* initialize node configuration */
TAILQ_INIT(&pf->tm_conf.shaper_profile_list);
pf->tm_conf.root = NULL;
-   TAILQ_INIT(&pf->tm_conf.qgroup_list);
-   TAILQ_INIT(&pf->tm_conf.queue_list);
-   pf->tm_conf.nb_qgroup_node = 0;
-   pf->tm_conf.nb_queue_node = 0;
pf->tm_conf.committed = false;
pf->tm_conf.clear_on_fail = false;
 }
 
-void
-ice_tm_conf_uninit(struct rte_eth_dev *dev)
+static void free_node(struct ice_tm_node *root)
 {
-   struct ice_pf *pf = ICE_DEV_PRIVATE_TO_PF(dev->data->dev_private);
-   struct ice_tm_node *tm_node;
+   uint32_t i;
 
-   /* clear node configuration */
-   while ((tm_node = TAILQ_FIRST(&pf->tm_conf.queue_list))) {
-   TAILQ_REMOVE(&pf->tm_conf.queue_list, tm_node, node);
-   rte_free(tm_node);
-   }
-   pf->tm_conf.nb_queue_node = 0;
-   while ((tm_node = TAILQ_FIRST(&pf->tm_conf.qgroup_list))) {
-   TAILQ_REMOVE(&pf->tm_conf.qgroup_list, tm_node, node);
-   rte_free(tm_node);
-   }
-   pf->tm_conf.nb_qgroup_node = 0;
-   if (pf->tm_conf.root) {
-   rte_free(pf->tm_conf.root);
-   pf->tm_conf.root = NULL;
-   }
+   if (root == NULL)
+   return;
+
+   for (i = 0; i < root->reference_count; i++)
+   free_node(root->children[i]);
+
+   rte_free(root);
 }
 
-static inline struct ice_tm_node *
-ice_tm_node_search(struct rte_eth_dev *dev,
-   uint32_t node_id, enum ice_tm_node_type *node_type)
+void
+ice_tm_conf_uninit(struct rte_eth_dev *dev)
 {
struct ice_pf *pf = ICE_DEV_PRIVATE_TO_PF(dev->data->dev_private);
-   struct ice_tm_node_list *qgroup_list = &pf->tm_conf.qgroup_list;
-   struct ice_tm_node_list *queue_list = &pf->tm_conf.queue_list;
-   struct ice_tm_node *tm_node;
-
-   if (pf->tm_conf.root && pf->tm_conf.root->id == node_id) {
-   *node_type = ICE_TM_NODE_TYPE_PORT;
-   return pf->tm_conf.root;
-   }
 
-   TAILQ_FOREACH(tm_node, qgroup_list, node) {
-   if (tm_node->id == node_id) {
-   *node_type = ICE_TM_NODE_TYPE_QGROUP;
-   return tm_node;
-   }
-   }
-
-   TAILQ_FOREACH(tm_node, queue_list, node) {
-   if (tm_node->id == node_id) {
-   *node_type = ICE_TM_NODE_TYPE_QUEUE;
-   return tm_node;
-   }
-   }
-
-   return NULL;
+   free_node(pf->tm_conf.root);
+   pf->tm_conf.root = NULL;
 }
 
 static int
@@ -195,11 +159,29 @@ ice_node_param_check(struct ice_pf *pf, uint32_t node_id,
return 0;
 }
 
+static struct ice_tm_node *
+find_node(struct ice_tm_node *root, uint32_t id)
+{
+   uint32_t i;
+
+   if (root == NULL || root->id == id)
+   return root;
+
+   for (i = 0; i < root->reference_count; i++) {
+   struct ice_tm_node *node = find_node(root->children[i], id);
+
+   if (node)
+   return node;
+   }
+
+   return NULL;
+}
+
 static int
 ice_node_type_get(struct rte_eth_dev *dev, uint32_t node_id,
   int *is_leaf, struct rte_tm_error *error)
 {
-   enum ice_tm_node_type node_type = ICE_TM_NODE_TYPE_MAX;
+   struct ice_pf *pf = ICE_DEV_PRIVATE_TO_PF(dev->data->dev_private);
struct ice_tm_node *tm_node;
 
  

[PATCH v2 1/3] net/ice: hide port and TC layer in Tx sched tree

2024-01-04 Thread Qi Zhang
In currently 5 layer tree implementation, the port and tc layer
is not configurable, so its not necessary to expose them to application.

The patch hides the top 2 layers and represented the root of the tree at
VSI layer. From application's point of view, its a 3 layer scheduler tree:

Port -> Queue Group -> Queue.

Signed-off-by: Qi Zhang 
---
 drivers/net/ice/ice_ethdev.h |  7 
 drivers/net/ice/ice_tm.c | 79 
 2 files changed, 7 insertions(+), 79 deletions(-)

diff --git a/drivers/net/ice/ice_ethdev.h b/drivers/net/ice/ice_ethdev.h
index fa4981ed14..ae22c29ffc 100644
--- a/drivers/net/ice/ice_ethdev.h
+++ b/drivers/net/ice/ice_ethdev.h
@@ -470,7 +470,6 @@ struct ice_tm_shaper_profile {
 struct ice_tm_node {
TAILQ_ENTRY(ice_tm_node) node;
uint32_t id;
-   uint32_t tc;
uint32_t priority;
uint32_t weight;
uint32_t reference_count;
@@ -484,8 +483,6 @@ struct ice_tm_node {
 /* node type of Traffic Manager */
 enum ice_tm_node_type {
ICE_TM_NODE_TYPE_PORT,
-   ICE_TM_NODE_TYPE_TC,
-   ICE_TM_NODE_TYPE_VSI,
ICE_TM_NODE_TYPE_QGROUP,
ICE_TM_NODE_TYPE_QUEUE,
ICE_TM_NODE_TYPE_MAX,
@@ -495,12 +492,8 @@ enum ice_tm_node_type {
 struct ice_tm_conf {
struct ice_shaper_profile_list shaper_profile_list;
struct ice_tm_node *root; /* root node - port */
-   struct ice_tm_node_list tc_list; /* node list for all the TCs */
-   struct ice_tm_node_list vsi_list; /* node list for all the VSIs */
struct ice_tm_node_list qgroup_list; /* node list for all the queue 
groups */
struct ice_tm_node_list queue_list; /* node list for all the queues */
-   uint32_t nb_tc_node;
-   uint32_t nb_vsi_node;
uint32_t nb_qgroup_node;
uint32_t nb_queue_node;
bool committed;
diff --git a/drivers/net/ice/ice_tm.c b/drivers/net/ice/ice_tm.c
index b570798f07..7ae68c683b 100644
--- a/drivers/net/ice/ice_tm.c
+++ b/drivers/net/ice/ice_tm.c
@@ -43,12 +43,8 @@ ice_tm_conf_init(struct rte_eth_dev *dev)
/* initialize node configuration */
TAILQ_INIT(&pf->tm_conf.shaper_profile_list);
pf->tm_conf.root = NULL;
-   TAILQ_INIT(&pf->tm_conf.tc_list);
-   TAILQ_INIT(&pf->tm_conf.vsi_list);
TAILQ_INIT(&pf->tm_conf.qgroup_list);
TAILQ_INIT(&pf->tm_conf.queue_list);
-   pf->tm_conf.nb_tc_node = 0;
-   pf->tm_conf.nb_vsi_node = 0;
pf->tm_conf.nb_qgroup_node = 0;
pf->tm_conf.nb_queue_node = 0;
pf->tm_conf.committed = false;
@@ -72,16 +68,6 @@ ice_tm_conf_uninit(struct rte_eth_dev *dev)
rte_free(tm_node);
}
pf->tm_conf.nb_qgroup_node = 0;
-   while ((tm_node = TAILQ_FIRST(&pf->tm_conf.vsi_list))) {
-   TAILQ_REMOVE(&pf->tm_conf.vsi_list, tm_node, node);
-   rte_free(tm_node);
-   }
-   pf->tm_conf.nb_vsi_node = 0;
-   while ((tm_node = TAILQ_FIRST(&pf->tm_conf.tc_list))) {
-   TAILQ_REMOVE(&pf->tm_conf.tc_list, tm_node, node);
-   rte_free(tm_node);
-   }
-   pf->tm_conf.nb_tc_node = 0;
if (pf->tm_conf.root) {
rte_free(pf->tm_conf.root);
pf->tm_conf.root = NULL;
@@ -93,8 +79,6 @@ ice_tm_node_search(struct rte_eth_dev *dev,
uint32_t node_id, enum ice_tm_node_type *node_type)
 {
struct ice_pf *pf = ICE_DEV_PRIVATE_TO_PF(dev->data->dev_private);
-   struct ice_tm_node_list *tc_list = &pf->tm_conf.tc_list;
-   struct ice_tm_node_list *vsi_list = &pf->tm_conf.vsi_list;
struct ice_tm_node_list *qgroup_list = &pf->tm_conf.qgroup_list;
struct ice_tm_node_list *queue_list = &pf->tm_conf.queue_list;
struct ice_tm_node *tm_node;
@@ -104,20 +88,6 @@ ice_tm_node_search(struct rte_eth_dev *dev,
return pf->tm_conf.root;
}
 
-   TAILQ_FOREACH(tm_node, tc_list, node) {
-   if (tm_node->id == node_id) {
-   *node_type = ICE_TM_NODE_TYPE_TC;
-   return tm_node;
-   }
-   }
-
-   TAILQ_FOREACH(tm_node, vsi_list, node) {
-   if (tm_node->id == node_id) {
-   *node_type = ICE_TM_NODE_TYPE_VSI;
-   return tm_node;
-   }
-   }
-
TAILQ_FOREACH(tm_node, qgroup_list, node) {
if (tm_node->id == node_id) {
*node_type = ICE_TM_NODE_TYPE_QGROUP;
@@ -371,6 +341,8 @@ ice_shaper_profile_del(struct rte_eth_dev *dev,
return 0;
 }
 
+#define MAX_QUEUE_PER_GROUP8
+
 static int
 ice_tm_node_add(struct rte_eth_dev *dev, uint32_t node_id,
  uint32_t parent_node_id, uint32_t priority,
@@ -384,8 +356,6 @@ ice_tm_node_add(struct rte_eth_dev *dev,

[PATCH v2 0/3] net/ice: simplified to 3 layer Tx scheduler

2024-01-04 Thread Qi Zhang
Remove dummy layers, code refactor, complete document

Qi Zhang (3):
  net/ice: hide port and TC layer in Tx sched tree
  net/ice: refactor tm config data structure
  doc: update ice document for qos

v2:
- fix typos.

 doc/guides/nics/ice.rst  |  19 +++
 drivers/net/ice/ice_ethdev.h |  12 +-
 drivers/net/ice/ice_tm.c | 285 +++
 3 files changed, 112 insertions(+), 204 deletions(-)

-- 
2.31.1



[PATCH 3/3] doc: update ice document for qos

2024-01-04 Thread Qi Zhang
Add description for ice PMD's rte_tm capabilities.

Signed-off-by: Qi Zhang 
---
 doc/guides/nics/ice.rst | 19 +++
 1 file changed, 19 insertions(+)

diff --git a/doc/guides/nics/ice.rst b/doc/guides/nics/ice.rst
index bafb3ba022..1f737a009c 100644
--- a/doc/guides/nics/ice.rst
+++ b/doc/guides/nics/ice.rst
@@ -352,6 +352,25 @@ queue 3 using a raw pattern::
 
 Currently, raw pattern support is limited to the FDIR and Hash engines.
 
+Traffic Management Support
+~~
+
+The ice PMD provides support for the Traffic Management API (RTE_RM), allow
+users to offload a 3-layers Tx scheduler on the E810 NIC:
+
+- ``Port Layer``
+
+  This is the root layer, support peak bandwidth configuration, max to 32 
children.
+
+- ``Queue Group Layer``
+
+  The middel layer, support peak / committed bandwidth, weight, prioirty 
configurations,
+  max to 8 children.
+
+- ``Queue Layer``
+
+  The leaf layer, support peak / committed bandwidth, weight, prioirty 
configurations.
+
 Additional Options
 ++
 
-- 
2.31.1



[PATCH 2/3] net/ice: refactor tm config data struture

2024-01-04 Thread Qi Zhang
Simplified struct ice_tm_conf by removing per level node list.

Signed-off-by: Qi Zhang 
---
 drivers/net/ice/ice_ethdev.h |   5 +-
 drivers/net/ice/ice_tm.c | 210 +++
 2 files changed, 88 insertions(+), 127 deletions(-)

diff --git a/drivers/net/ice/ice_ethdev.h b/drivers/net/ice/ice_ethdev.h
index ae22c29ffc..008a7a23b9 100644
--- a/drivers/net/ice/ice_ethdev.h
+++ b/drivers/net/ice/ice_ethdev.h
@@ -472,6 +472,7 @@ struct ice_tm_node {
uint32_t id;
uint32_t priority;
uint32_t weight;
+   uint32_t level;
uint32_t reference_count;
struct ice_tm_node *parent;
struct ice_tm_node **children;
@@ -492,10 +493,6 @@ enum ice_tm_node_type {
 struct ice_tm_conf {
struct ice_shaper_profile_list shaper_profile_list;
struct ice_tm_node *root; /* root node - port */
-   struct ice_tm_node_list qgroup_list; /* node list for all the queue 
groups */
-   struct ice_tm_node_list queue_list; /* node list for all the queues */
-   uint32_t nb_qgroup_node;
-   uint32_t nb_queue_node;
bool committed;
bool clear_on_fail;
 };
diff --git a/drivers/net/ice/ice_tm.c b/drivers/net/ice/ice_tm.c
index 7ae68c683b..7c662f8a85 100644
--- a/drivers/net/ice/ice_tm.c
+++ b/drivers/net/ice/ice_tm.c
@@ -43,66 +43,30 @@ ice_tm_conf_init(struct rte_eth_dev *dev)
/* initialize node configuration */
TAILQ_INIT(&pf->tm_conf.shaper_profile_list);
pf->tm_conf.root = NULL;
-   TAILQ_INIT(&pf->tm_conf.qgroup_list);
-   TAILQ_INIT(&pf->tm_conf.queue_list);
-   pf->tm_conf.nb_qgroup_node = 0;
-   pf->tm_conf.nb_queue_node = 0;
pf->tm_conf.committed = false;
pf->tm_conf.clear_on_fail = false;
 }
 
-void
-ice_tm_conf_uninit(struct rte_eth_dev *dev)
+static void free_node(struct ice_tm_node *root)
 {
-   struct ice_pf *pf = ICE_DEV_PRIVATE_TO_PF(dev->data->dev_private);
-   struct ice_tm_node *tm_node;
+   uint32_t i;
 
-   /* clear node configuration */
-   while ((tm_node = TAILQ_FIRST(&pf->tm_conf.queue_list))) {
-   TAILQ_REMOVE(&pf->tm_conf.queue_list, tm_node, node);
-   rte_free(tm_node);
-   }
-   pf->tm_conf.nb_queue_node = 0;
-   while ((tm_node = TAILQ_FIRST(&pf->tm_conf.qgroup_list))) {
-   TAILQ_REMOVE(&pf->tm_conf.qgroup_list, tm_node, node);
-   rte_free(tm_node);
-   }
-   pf->tm_conf.nb_qgroup_node = 0;
-   if (pf->tm_conf.root) {
-   rte_free(pf->tm_conf.root);
-   pf->tm_conf.root = NULL;
-   }
+   if (root == NULL)
+   return;
+
+   for (i = 0; i < root->reference_count; i++)
+   free_node(root->children[i]);
+
+   rte_free(root);
 }
 
-static inline struct ice_tm_node *
-ice_tm_node_search(struct rte_eth_dev *dev,
-   uint32_t node_id, enum ice_tm_node_type *node_type)
+void
+ice_tm_conf_uninit(struct rte_eth_dev *dev)
 {
struct ice_pf *pf = ICE_DEV_PRIVATE_TO_PF(dev->data->dev_private);
-   struct ice_tm_node_list *qgroup_list = &pf->tm_conf.qgroup_list;
-   struct ice_tm_node_list *queue_list = &pf->tm_conf.queue_list;
-   struct ice_tm_node *tm_node;
-
-   if (pf->tm_conf.root && pf->tm_conf.root->id == node_id) {
-   *node_type = ICE_TM_NODE_TYPE_PORT;
-   return pf->tm_conf.root;
-   }
 
-   TAILQ_FOREACH(tm_node, qgroup_list, node) {
-   if (tm_node->id == node_id) {
-   *node_type = ICE_TM_NODE_TYPE_QGROUP;
-   return tm_node;
-   }
-   }
-
-   TAILQ_FOREACH(tm_node, queue_list, node) {
-   if (tm_node->id == node_id) {
-   *node_type = ICE_TM_NODE_TYPE_QUEUE;
-   return tm_node;
-   }
-   }
-
-   return NULL;
+   free_node(pf->tm_conf.root);
+   pf->tm_conf.root = NULL;
 }
 
 static int
@@ -195,11 +159,29 @@ ice_node_param_check(struct ice_pf *pf, uint32_t node_id,
return 0;
 }
 
+static struct ice_tm_node *
+find_node(struct ice_tm_node *root, uint32_t id)
+{
+   uint32_t i;
+
+   if (root == NULL || root->id == id)
+   return root;
+
+   for (i = 0; i < root->reference_count; i++) {
+   struct ice_tm_node *node = find_node(root->children[i], id);
+
+   if (node)
+   return node;
+   }
+
+   return NULL;
+}
+
 static int
 ice_node_type_get(struct rte_eth_dev *dev, uint32_t node_id,
   int *is_leaf, struct rte_tm_error *error)
 {
-   enum ice_tm_node_type node_type = ICE_TM_NODE_TYPE_MAX;
+   struct ice_pf *pf = ICE_DEV_PRIVATE_TO_PF(dev->data->dev_private);
struct ice_tm_node *tm_node;
 
  

[PATCH 1/3] net/ice: hide port and TC layer in Tx sched tree

2024-01-04 Thread Qi Zhang
In currently 5 layer tree implementation, the port and tc layer
is not configurable, so its not necessary to expose them to applicaiton.

The patch hides the top 2 layers and represented the root of the tree at
VSI layer. From application's point of view, its a 3 layer scheduler tree:

Port -> Queue Group -> Queue.

Signed-off-by: Qi Zhang 
---
 drivers/net/ice/ice_ethdev.h |  7 
 drivers/net/ice/ice_tm.c | 79 
 2 files changed, 7 insertions(+), 79 deletions(-)

diff --git a/drivers/net/ice/ice_ethdev.h b/drivers/net/ice/ice_ethdev.h
index fa4981ed14..ae22c29ffc 100644
--- a/drivers/net/ice/ice_ethdev.h
+++ b/drivers/net/ice/ice_ethdev.h
@@ -470,7 +470,6 @@ struct ice_tm_shaper_profile {
 struct ice_tm_node {
TAILQ_ENTRY(ice_tm_node) node;
uint32_t id;
-   uint32_t tc;
uint32_t priority;
uint32_t weight;
uint32_t reference_count;
@@ -484,8 +483,6 @@ struct ice_tm_node {
 /* node type of Traffic Manager */
 enum ice_tm_node_type {
ICE_TM_NODE_TYPE_PORT,
-   ICE_TM_NODE_TYPE_TC,
-   ICE_TM_NODE_TYPE_VSI,
ICE_TM_NODE_TYPE_QGROUP,
ICE_TM_NODE_TYPE_QUEUE,
ICE_TM_NODE_TYPE_MAX,
@@ -495,12 +492,8 @@ enum ice_tm_node_type {
 struct ice_tm_conf {
struct ice_shaper_profile_list shaper_profile_list;
struct ice_tm_node *root; /* root node - port */
-   struct ice_tm_node_list tc_list; /* node list for all the TCs */
-   struct ice_tm_node_list vsi_list; /* node list for all the VSIs */
struct ice_tm_node_list qgroup_list; /* node list for all the queue 
groups */
struct ice_tm_node_list queue_list; /* node list for all the queues */
-   uint32_t nb_tc_node;
-   uint32_t nb_vsi_node;
uint32_t nb_qgroup_node;
uint32_t nb_queue_node;
bool committed;
diff --git a/drivers/net/ice/ice_tm.c b/drivers/net/ice/ice_tm.c
index b570798f07..7ae68c683b 100644
--- a/drivers/net/ice/ice_tm.c
+++ b/drivers/net/ice/ice_tm.c
@@ -43,12 +43,8 @@ ice_tm_conf_init(struct rte_eth_dev *dev)
/* initialize node configuration */
TAILQ_INIT(&pf->tm_conf.shaper_profile_list);
pf->tm_conf.root = NULL;
-   TAILQ_INIT(&pf->tm_conf.tc_list);
-   TAILQ_INIT(&pf->tm_conf.vsi_list);
TAILQ_INIT(&pf->tm_conf.qgroup_list);
TAILQ_INIT(&pf->tm_conf.queue_list);
-   pf->tm_conf.nb_tc_node = 0;
-   pf->tm_conf.nb_vsi_node = 0;
pf->tm_conf.nb_qgroup_node = 0;
pf->tm_conf.nb_queue_node = 0;
pf->tm_conf.committed = false;
@@ -72,16 +68,6 @@ ice_tm_conf_uninit(struct rte_eth_dev *dev)
rte_free(tm_node);
}
pf->tm_conf.nb_qgroup_node = 0;
-   while ((tm_node = TAILQ_FIRST(&pf->tm_conf.vsi_list))) {
-   TAILQ_REMOVE(&pf->tm_conf.vsi_list, tm_node, node);
-   rte_free(tm_node);
-   }
-   pf->tm_conf.nb_vsi_node = 0;
-   while ((tm_node = TAILQ_FIRST(&pf->tm_conf.tc_list))) {
-   TAILQ_REMOVE(&pf->tm_conf.tc_list, tm_node, node);
-   rte_free(tm_node);
-   }
-   pf->tm_conf.nb_tc_node = 0;
if (pf->tm_conf.root) {
rte_free(pf->tm_conf.root);
pf->tm_conf.root = NULL;
@@ -93,8 +79,6 @@ ice_tm_node_search(struct rte_eth_dev *dev,
uint32_t node_id, enum ice_tm_node_type *node_type)
 {
struct ice_pf *pf = ICE_DEV_PRIVATE_TO_PF(dev->data->dev_private);
-   struct ice_tm_node_list *tc_list = &pf->tm_conf.tc_list;
-   struct ice_tm_node_list *vsi_list = &pf->tm_conf.vsi_list;
struct ice_tm_node_list *qgroup_list = &pf->tm_conf.qgroup_list;
struct ice_tm_node_list *queue_list = &pf->tm_conf.queue_list;
struct ice_tm_node *tm_node;
@@ -104,20 +88,6 @@ ice_tm_node_search(struct rte_eth_dev *dev,
return pf->tm_conf.root;
}
 
-   TAILQ_FOREACH(tm_node, tc_list, node) {
-   if (tm_node->id == node_id) {
-   *node_type = ICE_TM_NODE_TYPE_TC;
-   return tm_node;
-   }
-   }
-
-   TAILQ_FOREACH(tm_node, vsi_list, node) {
-   if (tm_node->id == node_id) {
-   *node_type = ICE_TM_NODE_TYPE_VSI;
-   return tm_node;
-   }
-   }
-
TAILQ_FOREACH(tm_node, qgroup_list, node) {
if (tm_node->id == node_id) {
*node_type = ICE_TM_NODE_TYPE_QGROUP;
@@ -371,6 +341,8 @@ ice_shaper_profile_del(struct rte_eth_dev *dev,
return 0;
 }
 
+#define MAX_QUEUE_PER_GROUP8
+
 static int
 ice_tm_node_add(struct rte_eth_dev *dev, uint32_t node_id,
  uint32_t parent_node_id, uint32_t priority,
@@ -384,8 +356,6 @@ ice_tm_node_add(struct rte_eth_dev *dev,

[PATCH 0/3] net/ice: simplified to 3 layer Tx scheduler.

2024-01-04 Thread Qi Zhang
Remove dummy layers, code refactor, complete document.

Qi Zhang (3):
  net/ice: hide port and TC layer in Tx sched tree
  net/ice: refactor tm config data struture
  doc: update ice document for qos

 doc/guides/nics/ice.rst  |  19 +++
 drivers/net/ice/ice_ethdev.h |  12 +-
 drivers/net/ice/ice_tm.c | 285 +++
 3 files changed, 112 insertions(+), 204 deletions(-)

-- 
2.31.1



[PATCH] net/ice: refine queue start stop

2024-01-04 Thread Qi Zhang
Not necessary to return fail when starting or stopping a queue
if the queue was already at required state.

Signed-off-by: Qi Zhang 
---
 drivers/net/ice/ice_rxtx.c | 16 
 1 file changed, 16 insertions(+)

diff --git a/drivers/net/ice/ice_rxtx.c b/drivers/net/ice/ice_rxtx.c
index 73e47ae92d..3286bb08fe 100644
--- a/drivers/net/ice/ice_rxtx.c
+++ b/drivers/net/ice/ice_rxtx.c
@@ -673,6 +673,10 @@ ice_rx_queue_start(struct rte_eth_dev *dev, uint16_t 
rx_queue_id)
return -EINVAL;
}
 
+   if (dev->data->rx_queue_state[rx_queue_id] ==
+   RTE_ETH_QUEUE_STATE_STARTED)
+   return 0;
+
if (dev->data->dev_conf.rxmode.offloads & RTE_ETH_RX_OFFLOAD_TIMESTAMP)
rxq->ts_enable = true;
err = ice_program_hw_rx_queue(rxq);
@@ -717,6 +721,10 @@ ice_rx_queue_stop(struct rte_eth_dev *dev, uint16_t 
rx_queue_id)
if (rx_queue_id < dev->data->nb_rx_queues) {
rxq = dev->data->rx_queues[rx_queue_id];
 
+   if (dev->data->rx_queue_state[rx_queue_id] ==
+   RTE_ETH_QUEUE_STATE_STOPPED)
+   return 0;
+
err = ice_switch_rx_queue(hw, rxq->reg_idx, false);
if (err) {
PMD_DRV_LOG(ERR, "Failed to switch RX queue %u off",
@@ -758,6 +766,10 @@ ice_tx_queue_start(struct rte_eth_dev *dev, uint16_t 
tx_queue_id)
return -EINVAL;
}
 
+   if (dev->data->tx_queue_state[tx_queue_id] ==
+   RTE_ETH_QUEUE_STATE_STARTED)
+   return 0;
+
buf_len = ice_struct_size(txq_elem, txqs, 1);
txq_elem = ice_malloc(hw, buf_len);
if (!txq_elem)
@@ -1066,6 +1078,10 @@ ice_tx_queue_stop(struct rte_eth_dev *dev, uint16_t 
tx_queue_id)
return -EINVAL;
}
 
+   if (dev->data->tx_queue_state[tx_queue_id] ==
+   RTE_ETH_QUEUE_STATE_STOPPED)
+   return 0;
+
q_ids[0] = txq->reg_idx;
q_teids[0] = txq->q_teid;
 
-- 
2.31.1



[PATCH 6/6] net/ice: support Tx sched commit before device start

2024-01-02 Thread Qi Zhang
Currently Tx hierarchy commit only take effect if device
already be started, as after a dev start / stop cycle, queues
has been removed and added back which cause the Tx scheduler
tree return to original topo.

In this patch, the hierarchy commit function will simply return
if device has not be started yet and all the commit actions will
be deferred to dev_start.

Signed-off-by: Qi Zhang 
---
 drivers/net/ice/ice_ethdev.c |  9 +
 drivers/net/ice/ice_ethdev.h |  4 
 drivers/net/ice/ice_tm.c | 25 ++---
 3 files changed, 35 insertions(+), 3 deletions(-)

diff --git a/drivers/net/ice/ice_ethdev.c b/drivers/net/ice/ice_ethdev.c
index 3c3bc49dc2..72e13f95f8 100644
--- a/drivers/net/ice/ice_ethdev.c
+++ b/drivers/net/ice/ice_ethdev.c
@@ -3717,6 +3717,7 @@ ice_dev_start(struct rte_eth_dev *dev)
int mask, ret;
uint8_t timer = hw->func_caps.ts_func_info.tmr_index_owned;
uint32_t pin_idx = ad->devargs.pin_idx;
+   struct rte_tm_error tm_err;
 
/* program Tx queues' context in hardware */
for (nb_txq = 0; nb_txq < data->nb_tx_queues; nb_txq++) {
@@ -3746,6 +3747,14 @@ ice_dev_start(struct rte_eth_dev *dev)
}
}
 
+   if (pf->tm_conf.committed) {
+   ret = ice_do_hierarchy_commit(dev, pf->tm_conf.clear_on_fail, 
&tm_err);
+   if (ret) {
+   PMD_DRV_LOG(ERR, "fail to commit Tx scheduler");
+   goto rx_err;
+   }
+   }
+
ice_set_rx_function(dev);
ice_set_tx_function(dev);
 
diff --git a/drivers/net/ice/ice_ethdev.h b/drivers/net/ice/ice_ethdev.h
index 3b2db6aaa6..fa4981ed14 100644
--- a/drivers/net/ice/ice_ethdev.h
+++ b/drivers/net/ice/ice_ethdev.h
@@ -504,6 +504,7 @@ struct ice_tm_conf {
uint32_t nb_qgroup_node;
uint32_t nb_queue_node;
bool committed;
+   bool clear_on_fail;
 };
 
 struct ice_pf {
@@ -686,6 +687,9 @@ int ice_rem_rss_cfg_wrap(struct ice_pf *pf, uint16_t vsi_id,
 struct ice_rss_hash_cfg *cfg);
 void ice_tm_conf_init(struct rte_eth_dev *dev);
 void ice_tm_conf_uninit(struct rte_eth_dev *dev);
+int ice_do_hierarchy_commit(struct rte_eth_dev *dev,
+   int clear_on_fail,
+   struct rte_tm_error *error);
 extern const struct rte_tm_ops ice_tm_ops;
 
 static inline int
diff --git a/drivers/net/ice/ice_tm.c b/drivers/net/ice/ice_tm.c
index 4d8dbff2dc..aa012897ed 100644
--- a/drivers/net/ice/ice_tm.c
+++ b/drivers/net/ice/ice_tm.c
@@ -52,6 +52,7 @@ ice_tm_conf_init(struct rte_eth_dev *dev)
pf->tm_conf.nb_qgroup_node = 0;
pf->tm_conf.nb_queue_node = 0;
pf->tm_conf.committed = false;
+   pf->tm_conf.clear_on_fail = false;
 }
 
 void
@@ -832,9 +833,9 @@ static int ice_add_leaf_nodes(struct rte_eth_dev *dev)
return ret;
 }
 
-static int ice_hierarchy_commit(struct rte_eth_dev *dev,
-int clear_on_fail,
-struct rte_tm_error *error)
+int ice_do_hierarchy_commit(struct rte_eth_dev *dev,
+   int clear_on_fail,
+   struct rte_tm_error *error)
 {
struct ice_pf *pf = ICE_DEV_PRIVATE_TO_PF(dev->data->dev_private);
struct ice_hw *hw = ICE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
@@ -959,6 +960,8 @@ static int ice_hierarchy_commit(struct rte_eth_dev *dev,
}
}
 
+   pf->tm_conf.committed = true;
+
return ret_val;
 
 reset_leaf:
@@ -974,3 +977,19 @@ static int ice_hierarchy_commit(struct rte_eth_dev *dev,
}
return ret_val;
 }
+
+static int ice_hierarchy_commit(struct rte_eth_dev *dev,
+int clear_on_fail,
+struct rte_tm_error *error)
+{
+   struct ice_pf *pf = ICE_DEV_PRIVATE_TO_PF(dev->data->dev_private);
+
+   /* if device not started, simply set committed flag and return. */
+   if (!dev->data->dev_started) {
+   pf->tm_conf.committed = true;
+   pf->tm_conf.clear_on_fail = clear_on_fail;
+   return 0;
+   }
+
+   return ice_do_hierarchy_commit(dev, clear_on_fail, error);
+}
-- 
2.31.1



[PATCH 5/6] net/ice: reset Tx sched node during commit

2024-01-02 Thread Qi Zhang
1. Always reset all Tx scheduler at the beginning of a commit action.
   This prevent unexpected remains from previous commit.
2. Reset all Tx scheduler nodes if a commit failed.

For leaf node, stop queues which will remove sched node from
scheduler tree, then start queues which will add sched node back to
default topo.
For noleaf node, simply reset to default parameters.

Signed-off-by: Qi Zhang 
---
 drivers/net/ice/ice_ethdev.h |   1 +
 drivers/net/ice/ice_tm.c | 130 ---
 2 files changed, 107 insertions(+), 24 deletions(-)

diff --git a/drivers/net/ice/ice_ethdev.h b/drivers/net/ice/ice_ethdev.h
index 1338c80d14..3b2db6aaa6 100644
--- a/drivers/net/ice/ice_ethdev.h
+++ b/drivers/net/ice/ice_ethdev.h
@@ -478,6 +478,7 @@ struct ice_tm_node {
struct ice_tm_node **children;
struct ice_tm_shaper_profile *shaper_profile;
struct rte_tm_node_params params;
+   struct ice_sched_node *sched_node;
 };
 
 /* node type of Traffic Manager */
diff --git a/drivers/net/ice/ice_tm.c b/drivers/net/ice/ice_tm.c
index 20cc47fff1..4d8dbff2dc 100644
--- a/drivers/net/ice/ice_tm.c
+++ b/drivers/net/ice/ice_tm.c
@@ -756,16 +756,91 @@ static int ice_cfg_hw_node(struct ice_hw *hw,
return 0;
 }
 
+static struct ice_sched_node *ice_get_vsi_node(struct ice_hw *hw)
+{
+   struct ice_sched_node *node = hw->port_info->root;
+   uint32_t vsi_layer = hw->num_tx_sched_layers - ICE_VSI_LAYER_OFFSET;
+   uint32_t i;
+
+   for (i = 0; i < vsi_layer; i++)
+   node = node->children[0];
+
+   return node;
+}
+
+static int ice_reset_noleaf_nodes(struct rte_eth_dev *dev)
+{
+   struct ice_pf *pf = ICE_DEV_PRIVATE_TO_PF(dev->data->dev_private);
+   struct ice_hw *hw = ICE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+   struct ice_tm_node_list *qgroup_list = &pf->tm_conf.qgroup_list;
+   struct ice_sched_node *vsi_node = ice_get_vsi_node(hw);
+   struct ice_tm_node *tm_node;
+   int ret;
+
+   /* reset vsi_node */
+   ret = ice_set_node_rate(hw, NULL, vsi_node);
+   if (ret) {
+   PMD_DRV_LOG(ERR, "reset vsi node failed");
+   return ret;
+   }
+
+   /* reset queue group nodes */
+   TAILQ_FOREACH(tm_node, qgroup_list, node) {
+   if (tm_node->sched_node == NULL)
+   continue;
+
+   ret = ice_cfg_hw_node(hw, NULL, tm_node->sched_node);
+   if (ret) {
+   PMD_DRV_LOG(ERR, "reset queue group node %u failed", 
tm_node->id);
+   return ret;
+   }
+   tm_node->sched_node = NULL;
+   }
+
+   return 0;
+}
+
+static int ice_remove_leaf_nodes(struct rte_eth_dev *dev)
+{
+   int ret = 0;
+   int i;
+
+   for (i = 0; i < dev->data->nb_tx_queues; i++) {
+   ret = ice_tx_queue_stop(dev, i);
+   if (ret) {
+   PMD_DRV_LOG(ERR, "stop queue %u failed", i);
+   break;
+   }
+   }
+
+   return ret;
+}
+
+static int ice_add_leaf_nodes(struct rte_eth_dev *dev)
+{
+   int ret = 0;
+   int i;
+
+   for (i = 0; i < dev->data->nb_tx_queues; i++) {
+   ret = ice_tx_queue_start(dev, i);
+   if (ret) {
+   PMD_DRV_LOG(ERR, "start queue %u failed", i);
+   break;
+   }
+   }
+
+   return ret;
+}
+
 static int ice_hierarchy_commit(struct rte_eth_dev *dev,
 int clear_on_fail,
-__rte_unused struct rte_tm_error *error)
+struct rte_tm_error *error)
 {
struct ice_pf *pf = ICE_DEV_PRIVATE_TO_PF(dev->data->dev_private);
struct ice_hw *hw = ICE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
struct ice_tm_node_list *qgroup_list = &pf->tm_conf.qgroup_list;
struct ice_tm_node_list *queue_list = &pf->tm_conf.queue_list;
struct ice_tm_node *tm_node;
-   struct ice_sched_node *node;
struct ice_sched_node *vsi_node = NULL;
struct ice_sched_node *queue_node;
struct ice_tx_queue *txq;
@@ -777,23 +852,25 @@ static int ice_hierarchy_commit(struct rte_eth_dev *dev,
uint32_t nb_qg;
uint32_t qid;
uint32_t q_teid;
-   uint32_t vsi_layer;
 
-   for (i = 0; i < dev->data->nb_tx_queues; i++) {
-   ret_val = ice_tx_queue_stop(dev, i);
-   if (ret_val) {
-   error->type = RTE_TM_ERROR_TYPE_UNSPECIFIED;
-   PMD_DRV_LOG(ERR, "stop queue %u failed", i);
-   goto fail_clear;
-   }
+   /* remove leaf nodes */
+   ret_val = ice_remove_leaf_nodes(dev);
+   if (ret_val) {
+   

[PATCH 3/6] net/ice: support queue group weight configure

2024-01-02 Thread Qi Zhang
Enable the configuration of weight for Tx scheduler node at
the queue group level. This patch also consolidate weight
configuration across various levels by exposing the base
code API 'ice_sched_cfg_node_bw_alloc'.

Signed-off-by: Qi Zhang 
---
 drivers/net/ice/base/ice_sched.c |  2 +-
 drivers/net/ice/base/ice_sched.h |  3 +++
 drivers/net/ice/ice_tm.c | 27 ---
 3 files changed, 24 insertions(+), 8 deletions(-)

diff --git a/drivers/net/ice/base/ice_sched.c b/drivers/net/ice/base/ice_sched.c
index 23cc1ee50a..a1dd0c6ace 100644
--- a/drivers/net/ice/base/ice_sched.c
+++ b/drivers/net/ice/base/ice_sched.c
@@ -3020,7 +3020,7 @@ ice_sched_update_elem(struct ice_hw *hw, struct 
ice_sched_node *node,
  *
  * This function configures node element's BW allocation.
  */
-static enum ice_status
+enum ice_status
 ice_sched_cfg_node_bw_alloc(struct ice_hw *hw, struct ice_sched_node *node,
enum ice_rl_type rl_type, u16 bw_alloc)
 {
diff --git a/drivers/net/ice/base/ice_sched.h b/drivers/net/ice/base/ice_sched.h
index a600ff9a24..5b35fd564e 100644
--- a/drivers/net/ice/base/ice_sched.h
+++ b/drivers/net/ice/base/ice_sched.h
@@ -240,4 +240,7 @@ ice_sched_replay_q_bw(struct ice_port_info *pi, struct 
ice_q_ctx *q_ctx);
 enum ice_status
 ice_sched_set_node_bw_lmt(struct ice_port_info *pi, struct ice_sched_node 
*node,
  enum ice_rl_type rl_type, u32 bw);
+enum ice_status
+ice_sched_cfg_node_bw_alloc(struct ice_hw *hw, struct ice_sched_node *node,
+   enum ice_rl_type rl_type, u16 bw_alloc);
 #endif /* _ICE_SCHED_H_ */
diff --git a/drivers/net/ice/ice_tm.c b/drivers/net/ice/ice_tm.c
index d9187af8af..604d045e2c 100644
--- a/drivers/net/ice/ice_tm.c
+++ b/drivers/net/ice/ice_tm.c
@@ -529,7 +529,8 @@ ice_tm_node_add(struct rte_eth_dev *dev, uint32_t node_id,
PMD_DRV_LOG(WARNING, "priority != 0 not supported in level %d",
level_id);
 
-   if (tm_node->weight != 1 && level_id != ICE_TM_NODE_TYPE_QUEUE)
+   if (tm_node->weight != 1 &&
+   level_id != ICE_TM_NODE_TYPE_QUEUE && level_id != 
ICE_TM_NODE_TYPE_QGROUP)
PMD_DRV_LOG(WARNING, "weight != 1 not supported in level %d",
level_id);
 
@@ -725,7 +726,6 @@ static int ice_hierarchy_commit(struct rte_eth_dev *dev,
struct ice_sched_node *vsi_node = NULL;
struct ice_sched_node *queue_node;
struct ice_tx_queue *txq;
-   struct ice_vsi *vsi;
int ret_val = ICE_SUCCESS;
uint8_t priority;
uint32_t i;
@@ -819,6 +819,18 @@ static int ice_hierarchy_commit(struct rte_eth_dev *dev,
tm_node->priority);
goto fail_clear;
}
+
+   ret_val = ice_sched_cfg_node_bw_alloc(hw, qgroup_sched_node,
+ ICE_MAX_BW,
+ 
(uint16_t)tm_node->weight);
+   if (ret_val) {
+   error->type = RTE_TM_ERROR_TYPE_NODE_WEIGHT;
+   PMD_DRV_LOG(ERR, "configure queue group %u weight %u 
failed",
+   tm_node->id,
+   tm_node->weight);
+   goto fail_clear;
+   }
+
idx_qg++;
if (idx_qg >= nb_qg) {
idx_qg = 0;
@@ -834,7 +846,6 @@ static int ice_hierarchy_commit(struct rte_eth_dev *dev,
TAILQ_FOREACH(tm_node, queue_list, node) {
qid = tm_node->id;
txq = dev->data->tx_queues[qid];
-   vsi = txq->vsi;
q_teid = txq->q_teid;
 
queue_node = ice_sched_get_node(hw->port_info, q_teid);
@@ -856,12 +867,14 @@ static int ice_hierarchy_commit(struct rte_eth_dev *dev,
goto fail_clear;
}
 
-   ret_val = ice_cfg_q_bw_alloc(hw->port_info, vsi->idx,
-tm_node->tc, tm_node->id,
-ICE_MAX_BW, (u32)tm_node->weight);
+   queue_node = ice_sched_get_node(hw->port_info, q_teid);
+   ret_val = ice_sched_cfg_node_bw_alloc(hw, queue_node, 
ICE_MAX_BW,
+ 
(uint16_t)tm_node->weight);
if (ret_val) {
error->type = RTE_TM_ERROR_TYPE_NODE_WEIGHT;
-   PMD_DRV_LOG(ERR, "configure queue %u weight failed", 
tm_node->weight);
+   PMD_DRV_LOG(ERR, "configure queue %u weight %u failed",
+   tm_node->id,
+   tm_node->weight);
goto fail_clear;
}
}
-- 
2.31.1



[PATCH 4/6] net/ice: refactor hardware Tx sched node config

2024-01-02 Thread Qi Zhang
Consolidate Tx scheduler node configuration into a function:
'ice_cfg_hw_node", where rate limit, weight, priority will be
configured for queue group level and queue level.

Signed-off-by: Qi Zhang 
---
 drivers/net/ice/ice_tm.c | 97 
 1 file changed, 49 insertions(+), 48 deletions(-)

diff --git a/drivers/net/ice/ice_tm.c b/drivers/net/ice/ice_tm.c
index 604d045e2c..20cc47fff1 100644
--- a/drivers/net/ice/ice_tm.c
+++ b/drivers/net/ice/ice_tm.c
@@ -713,6 +713,49 @@ static int ice_set_node_rate(struct ice_hw *hw,
return 0;
 }
 
+static int ice_cfg_hw_node(struct ice_hw *hw,
+  struct ice_tm_node *tm_node,
+  struct ice_sched_node *sched_node)
+{
+   enum ice_status status;
+   uint8_t priority;
+   uint16_t weight;
+   int ret;
+
+   ret = ice_set_node_rate(hw, tm_node, sched_node);
+   if (ret) {
+   PMD_DRV_LOG(ERR,
+   "configure queue group %u bandwidth failed",
+   sched_node->info.node_teid);
+   return ret;
+   }
+
+   priority = tm_node ? (7 - tm_node->priority) : 0;
+   status = ice_sched_cfg_sibl_node_prio(hw->port_info,
+ sched_node,
+ priority);
+   if (status) {
+   PMD_DRV_LOG(ERR, "configure node %u priority %u failed",
+   sched_node->info.node_teid,
+   priority);
+   return -EINVAL;
+   }
+
+   weight = tm_node ? (uint16_t)tm_node->weight : 4;
+
+   status = ice_sched_cfg_node_bw_alloc(hw, sched_node,
+ICE_MAX_BW,
+weight);
+   if (status) {
+   PMD_DRV_LOG(ERR, "configure node %u weight %u failed",
+   sched_node->info.node_teid,
+   weight);
+   return -EINVAL;
+   }
+
+   return 0;
+}
+
 static int ice_hierarchy_commit(struct rte_eth_dev *dev,
 int clear_on_fail,
 __rte_unused struct rte_tm_error *error)
@@ -726,8 +769,7 @@ static int ice_hierarchy_commit(struct rte_eth_dev *dev,
struct ice_sched_node *vsi_node = NULL;
struct ice_sched_node *queue_node;
struct ice_tx_queue *txq;
-   int ret_val = ICE_SUCCESS;
-   uint8_t priority;
+   int ret_val = 0;
uint32_t i;
uint32_t idx_vsi_child;
uint32_t idx_qg;
@@ -801,36 +843,15 @@ static int ice_hierarchy_commit(struct rte_eth_dev *dev,
}
}
 
-   ret_val = ice_set_node_rate(hw, tm_node, qgroup_sched_node);
+   ret_val = ice_cfg_hw_node(hw, tm_node, qgroup_sched_node);
if (ret_val) {
error->type = RTE_TM_ERROR_TYPE_UNSPECIFIED;
PMD_DRV_LOG(ERR,
-   "configure queue group %u bandwidth failed",
+   "configure queue group node %u failed",
tm_node->id);
goto reset_vsi;
}
 
-   priority = 7 - tm_node->priority;
-   ret_val = ice_sched_cfg_sibl_node_prio_lock(hw->port_info, 
qgroup_sched_node,
-   priority);
-   if (ret_val) {
-   error->type = RTE_TM_ERROR_TYPE_NODE_PRIORITY;
-   PMD_DRV_LOG(ERR, "configure queue group %u priority 
failed",
-   tm_node->priority);
-   goto fail_clear;
-   }
-
-   ret_val = ice_sched_cfg_node_bw_alloc(hw, qgroup_sched_node,
- ICE_MAX_BW,
- 
(uint16_t)tm_node->weight);
-   if (ret_val) {
-   error->type = RTE_TM_ERROR_TYPE_NODE_WEIGHT;
-   PMD_DRV_LOG(ERR, "configure queue group %u weight %u 
failed",
-   tm_node->id,
-   tm_node->weight);
-   goto fail_clear;
-   }
-
idx_qg++;
if (idx_qg >= nb_qg) {
idx_qg = 0;
@@ -847,36 +868,16 @@ static int ice_hierarchy_commit(struct rte_eth_dev *dev,
qid = tm_node->id;
txq = dev->data->tx_queues[qid];
q_teid = txq->q_teid;
-
queue_node = ice_sched_get_node(hw->port_info, q_teid);
-   ret_val = ice_set_node_rate(hw, tm_nod

[PATCH 2/6] net/ice: support VSI level bandwidth config

2024-01-02 Thread Qi Zhang
Enable the configuration of peak and committed rates for a Tx scheduler
node at the VSI level. This patch also consolidate rate configuration
across various levels into a single function 'ice_set_node_rate.'

Signed-off-by: Qi Zhang 
---
 drivers/net/ice/base/ice_sched.c |   2 +-
 drivers/net/ice/base/ice_sched.h |   4 +-
 drivers/net/ice/ice_tm.c | 142 +++
 3 files changed, 91 insertions(+), 57 deletions(-)

diff --git a/drivers/net/ice/base/ice_sched.c b/drivers/net/ice/base/ice_sched.c
index a4d31647fe..23cc1ee50a 100644
--- a/drivers/net/ice/base/ice_sched.c
+++ b/drivers/net/ice/base/ice_sched.c
@@ -4429,7 +4429,7 @@ ice_sched_set_node_bw(struct ice_port_info *pi, struct 
ice_sched_node *node,
  * NOTE: Caller provides the correct SRL node in case of shared profile
  * settings.
  */
-static enum ice_status
+enum ice_status
 ice_sched_set_node_bw_lmt(struct ice_port_info *pi, struct ice_sched_node 
*node,
  enum ice_rl_type rl_type, u32 bw)
 {
diff --git a/drivers/net/ice/base/ice_sched.h b/drivers/net/ice/base/ice_sched.h
index 4b68f3f535..a600ff9a24 100644
--- a/drivers/net/ice/base/ice_sched.h
+++ b/drivers/net/ice/base/ice_sched.h
@@ -237,5 +237,7 @@ enum ice_status ice_replay_vsi_agg(struct ice_hw *hw, u16 
vsi_handle);
 enum ice_status ice_sched_replay_root_node_bw(struct ice_port_info *pi);
 enum ice_status
 ice_sched_replay_q_bw(struct ice_port_info *pi, struct ice_q_ctx *q_ctx);
-
+enum ice_status
+ice_sched_set_node_bw_lmt(struct ice_port_info *pi, struct ice_sched_node 
*node,
+ enum ice_rl_type rl_type, u32 bw);
 #endif /* _ICE_SCHED_H_ */
diff --git a/drivers/net/ice/ice_tm.c b/drivers/net/ice/ice_tm.c
index 9e2f981fa3..d9187af8af 100644
--- a/drivers/net/ice/ice_tm.c
+++ b/drivers/net/ice/ice_tm.c
@@ -663,6 +663,55 @@ static int ice_move_recfg_lan_txq(struct rte_eth_dev *dev,
return ret;
 }
 
+static int ice_set_node_rate(struct ice_hw *hw,
+struct ice_tm_node *tm_node,
+struct ice_sched_node *sched_node)
+{
+   enum ice_status status;
+   bool reset = false;
+   uint32_t peak = 0;
+   uint32_t committed = 0;
+   uint32_t rate;
+
+   if (tm_node == NULL || tm_node->shaper_profile == NULL) {
+   reset = true;
+   } else {
+   peak = (uint32_t)tm_node->shaper_profile->profile.peak.rate;
+   committed = 
(uint32_t)tm_node->shaper_profile->profile.committed.rate;
+   }
+
+   if (reset || peak == 0)
+   rate = ICE_SCHED_DFLT_BW;
+   else
+   rate = peak / 1000 * BITS_PER_BYTE;
+
+
+   status = ice_sched_set_node_bw_lmt(hw->port_info,
+  sched_node,
+  ICE_MAX_BW,
+  rate);
+   if (status) {
+   PMD_DRV_LOG(ERR, "Failed to set max bandwidth for node %u", 
tm_node->id);
+   return -EINVAL;
+   }
+
+   if (reset || committed == 0)
+   rate = ICE_SCHED_DFLT_BW;
+   else
+   rate = committed / 1000 * BITS_PER_BYTE;
+
+   status = ice_sched_set_node_bw_lmt(hw->port_info,
+  sched_node,
+  ICE_MIN_BW,
+  rate);
+   if (status) {
+   PMD_DRV_LOG(ERR, "Failed to set min bandwidth for node %u", 
tm_node->id);
+   return -EINVAL;
+   }
+
+   return 0;
+}
+
 static int ice_hierarchy_commit(struct rte_eth_dev *dev,
 int clear_on_fail,
 __rte_unused struct rte_tm_error *error)
@@ -673,13 +722,11 @@ static int ice_hierarchy_commit(struct rte_eth_dev *dev,
struct ice_tm_node_list *queue_list = &pf->tm_conf.queue_list;
struct ice_tm_node *tm_node;
struct ice_sched_node *node;
-   struct ice_sched_node *vsi_node;
+   struct ice_sched_node *vsi_node = NULL;
struct ice_sched_node *queue_node;
struct ice_tx_queue *txq;
struct ice_vsi *vsi;
int ret_val = ICE_SUCCESS;
-   uint64_t peak = 0;
-   uint64_t committed = 0;
uint8_t priority;
uint32_t i;
uint32_t idx_vsi_child;
@@ -704,6 +751,18 @@ static int ice_hierarchy_commit(struct rte_eth_dev *dev,
for (i = 0; i < vsi_layer; i++)
node = node->children[0];
vsi_node = node;
+
+   tm_node = TAILQ_FIRST(&pf->tm_conf.vsi_list);
+
+   ret_val = ice_set_node_rate(hw, tm_node, vsi_node);
+   if (ret_val) {
+   error->type = RTE_TM_ERROR_TYPE_UNSPECIFIED;
+   PMD_DRV_LOG(ERR,
+   "configure vsi node %u bandwidth failed",
+  

[PATCH 1/6] net/ice: remove redundent code

2024-01-02 Thread Qi Zhang
The committed flag for tx schedular configuration is not used
in PF only mode, remove the redundent code.

Signed-off-by: Qi Zhang 
---
 drivers/net/ice/ice_tm.c | 14 --
 1 file changed, 14 deletions(-)

diff --git a/drivers/net/ice/ice_tm.c b/drivers/net/ice/ice_tm.c
index f5ea47ae83..9e2f981fa3 100644
--- a/drivers/net/ice/ice_tm.c
+++ b/drivers/net/ice/ice_tm.c
@@ -390,13 +390,6 @@ ice_tm_node_add(struct rte_eth_dev *dev, uint32_t node_id,
if (!params || !error)
return -EINVAL;
 
-   /* if already committed */
-   if (pf->tm_conf.committed) {
-   error->type = RTE_TM_ERROR_TYPE_UNSPECIFIED;
-   error->message = "already committed";
-   return -EINVAL;
-   }
-
ret = ice_node_param_check(pf, node_id, priority, weight,
params, error);
if (ret)
@@ -579,13 +572,6 @@ ice_tm_node_delete(struct rte_eth_dev *dev, uint32_t 
node_id,
if (!error)
return -EINVAL;
 
-   /* if already committed */
-   if (pf->tm_conf.committed) {
-   error->type = RTE_TM_ERROR_TYPE_UNSPECIFIED;
-   error->message = "already committed";
-   return -EINVAL;
-   }
-
if (node_id == RTE_TM_NODE_ID_NULL) {
error->type = RTE_TM_ERROR_TYPE_NODE_ID;
error->message = "invalid node id";
-- 
2.31.1



[PATCH 0/6] net/ice improve qos

2024-01-02 Thread Qi Zhang
The patchset enhanced ice rte_tm implemenations

Qi Zhang (6):
  net/ice: remove redundent code
  net/ice: support VSI level bandwidth config
  net/ice: support queue group weight configure
  net/ice: refactor hardware Tx sched node config
  net/ice: reset Tx sched node during commit
  net/ice: support Tx sched commit before dev_start

 drivers/net/ice/base/ice_sched.c |   4 +-
 drivers/net/ice/base/ice_sched.h |   7 +-
 drivers/net/ice/ice_ethdev.c |   9 +
 drivers/net/ice/ice_ethdev.h |   5 +
 drivers/net/ice/ice_tm.c | 361 +--
 5 files changed, 269 insertions(+), 117 deletions(-)

-- 
2.31.1



[PATCH v7 2/2] doc: add document for ice diagnostic utilities

2024-01-01 Thread Qi Zhang
Document ice specific testpmd CLI for diagnose purpose.

Signed-off-by: Qi Zhang 
---
v6:
- fix title

 doc/guides/nics/ice.rst | 36 
 1 file changed, 36 insertions(+)

diff --git a/doc/guides/nics/ice.rst b/doc/guides/nics/ice.rst
index 820a385b06..29309abe4d 100644
--- a/doc/guides/nics/ice.rst
+++ b/doc/guides/nics/ice.rst
@@ -411,6 +411,42 @@ To start ``testpmd``, and add vlan 10 to port 0:
 
 testpmd> rx_vlan add 10 0
 
+Diagnostic Utilities
+
+
+Dump DDP Package
+
+
+Dump the runtime packet processing pipeline configuration into a
+binary file. This helps the support team diagnose hardware
+configuration issues.
+
+Usage::
+
+testpmd>ddp dump  
+
+Dump Switch Configurations
+~~
+
+Dump detail hardware configurations related to the switch pipeline
+stage into a binary file.
+
+Usage::
+
+testpmd>ddp dump switch  
+
+Dump Tx Scheduling Tree
+~~~
+
+Dump the runtime Tx scheduling tree into a DOT file.
+
+Usage::
+
+testpmd>txsched dump   
+
+In "brief" mode, all scheduling nodes in the tree are displayed.
+In "detail" mode, each node's configuration parameters are also displayed.
+
 Limitations or Known issues
 ---
 
-- 
2.31.1



[PATCH v7 1/2] net/ice: add Tx scheduling tree dump support

2024-01-01 Thread Qi Zhang
Added Testpmd CLI support for dumping Tx scheduling tree.

Usage:
testpmd>txsched dump   

The output file is in "dot" format, which can be converted
into an image file using Graphviz.

- In "brief" mode, all scheduling nodes in the tree are displayed.
- In "detail" mode, each node's configuration parameters are also
  displayed.

Renamed `ice_ddp_package.c` to `ice_diagnose.c`, which now contains
all CLI support for diagnostic purposes.

Signed-off-by: Qi Zhang 
---
v7:
- fix ci warning.

v5:
- ignore the error when query node failed at queue level, as queue may
   be stopped.
v4:
- show node type in brief mode

v3:
- fix incorrect parameter when query rl profile

v2:
- fix CI build issue

 .../ice/{ice_ddp_package.c => ice_diagnose.c} | 372 ++
 drivers/net/ice/ice_ethdev.h  |   3 +
 drivers/net/ice/ice_testpmd.c |  65 +++
 drivers/net/ice/meson.build   |   2 +-
 drivers/net/ice/version.map   |   1 +
 5 files changed, 442 insertions(+), 1 deletion(-)
 rename drivers/net/ice/{ice_ddp_package.c => ice_diagnose.c} (60%)

diff --git a/drivers/net/ice/ice_ddp_package.c b/drivers/net/ice/ice_diagnose.c
similarity index 60%
rename from drivers/net/ice/ice_ddp_package.c
rename to drivers/net/ice/ice_diagnose.c
index 0aa19eb282..3be819d7f8 100644
--- a/drivers/net/ice/ice_ddp_package.c
+++ b/drivers/net/ice/ice_diagnose.c
@@ -11,6 +11,7 @@
 #include 
 
 #include "ice_ethdev.h"
+#include "ice_rxtx.h"
 
 #define ICE_BLK_MAX_COUNT  512
 #define ICE_BUFF_SEG_HEADER_FLAG   0x1
@@ -507,3 +508,374 @@ int rte_pmd_ice_dump_switch(uint16_t port, uint8_t 
**buff, uint32_t *size)
 
return ice_dump_switch(dev, buff, size);
 }
+
+static void print_rl_profile(struct ice_aqc_rl_profile_elem *prof,
+FILE *stream)
+{
+   fprintf(stream, "\t\t\t\t\t\n");
+   fprintf(stream, "\t\t\t\t\t\t\n");
+
+   fprintf(stream, "\t\t\t\t\t\t\t\n");
+   fprintf(stream, "\t\t\t\t\t\t\t\tid\n");
+   fprintf(stream, "\t\t\t\t\t\t\t\t%d\n", prof->profile_id);
+   fprintf(stream, "\t\t\t\t\t\t\t\n");
+
+   fprintf(stream, "\t\t\t\t\t\t\t\n");
+   fprintf(stream, "\t\t\t\t\t\t\t\tmax burst size\n");
+   fprintf(stream, "\t\t\t\t\t\t\t\t%d\n", prof->max_burst_size);
+   fprintf(stream, "\t\t\t\t\t\t\t\n");
+
+   fprintf(stream, "\t\t\t\t\t\t\t\n");
+   fprintf(stream, "\t\t\t\t\t\t\t\trate limit multiply\n");
+   fprintf(stream, "\t\t\t\t\t\t\t\t%d\n", prof->rl_multiply);
+   fprintf(stream, "\t\t\t\t\t\t\t\n");
+
+   fprintf(stream, "\t\t\t\t\t\t\t\n");
+   fprintf(stream, "\t\t\t\t\t\t\t\twake up calculation\n");
+   fprintf(stream, "\t\t\t\t\t\t\t\t%d\n", prof->wake_up_calc);
+   fprintf(stream, "\t\t\t\t\t\t\t\n");
+
+   fprintf(stream, "\t\t\t\t\t\t\t\n");
+   fprintf(stream, "\t\t\t\t\t\t\t\trate limit encode\n");
+   fprintf(stream, "\t\t\t\t\t\t\t\t%d\n", prof->rl_encode);
+   fprintf(stream, "\t\t\t\t\t\t\t\n");
+
+   fprintf(stream, "\t\t\t\t\t\t\n");
+   fprintf(stream, "\t\t\t\t\t\n");
+}
+
+static
+void print_elem_type(FILE *stream, u8 type)
+{
+   switch (type) {
+   case 1:
+   fprintf(stream, "root");
+   break;
+   case 2:
+   fprintf(stream, "tc");
+   break;
+   case 3:
+   fprintf(stream, "se_generic");
+   break;
+   case 4:
+   fprintf(stream, "entry_point");
+   break;
+   case 5:
+   fprintf(stream, "leaf");
+   break;
+   default:
+   fprintf(stream, "%d", type);
+   break;
+   }
+}
+
+static
+void print_valid_sections(FILE *stream, u8 vs)
+{
+   if ((vs & 0x1) != 0)
+   fprintf(stream, "generic ");
+   if ((vs & 0x2) != 0)
+   fprintf(stream, "cir ");
+   if ((vs & 0x4) != 0)
+   fprintf(stream, "eir ");
+   if ((vs & 0x8) != 0)
+   fprintf(stream, "shared ");
+}
+
+static
+void print_scheduling_mode(FILE *stream, bool flag)
+{
+   if (flag)
+   fprintf(stream, "pps");
+   else
+   fprintf(stream, "bps");
+}
+
+static
+void print_priority_mode(FILE *stream, bool flag)
+{
+   if (flag)
+   fprintf(stream, "single priority node");
+   else
+   fprintf(stream, "wfq");
+}
+
+static
+void print_node(struct ice_aqc_txsched_elem_data *data,
+ 

[PATCH v6 2/2] doc: add document for ice diagnostic utilities

2024-01-01 Thread Qi Zhang
Document CLI for diagnose purpose.

Signed-off-by: Qi Zhang 
---

v6:
- fix title

 doc/guides/nics/ice.rst | 36 
 1 file changed, 36 insertions(+)

diff --git a/doc/guides/nics/ice.rst b/doc/guides/nics/ice.rst
index 820a385b06..29309abe4d 100644
--- a/doc/guides/nics/ice.rst
+++ b/doc/guides/nics/ice.rst
@@ -411,6 +411,42 @@ To start ``testpmd``, and add vlan 10 to port 0:
 
 testpmd> rx_vlan add 10 0
 
+Diagnostic Utilities
+
+
+Dump DDP Package
+
+
+Dump the runtime packet processing pipeline configuration into a
+binary file. This helps the support team diagnose hardware
+configuration issues.
+
+Usage::
+
+testpmd>ddp dump  
+
+Dump Switch Configurations
+~~
+
+Dump detail hardware configurations related to the switch pipeline
+stage into a binary file.
+
+Usage::
+
+testpmd>ddp dump switch  
+
+Dump Tx Scheduling Tree
+~~~
+
+Dump the runtime Tx scheduling tree into a DOT file.
+
+Usage::
+
+testpmd>txsched dump   
+
+In "brief" mode, all scheduling nodes in the tree are displayed.
+In "detail" mode, each node's configuration parameters are also displayed.
+
 Limitations or Known issues
 ---
 
-- 
2.31.1



[PATCH v6 1/2] net/ice: add Tx scheduling tree dump support

2024-01-01 Thread Qi Zhang
Added Testpmd CLI support for dumping Tx scheduling tree.

Usage:
testpmd>txsched dump   

The output file is in "dot" format, which can be converted
into an image file using Graphviz.

- In "brief" mode, all scheduling nodes in the tree are displayed.
- In "detail" mode, each node's configuration parameters are also
  displayed.

Renamed `ice_ddp_package.c` to `ice_diagnose.c`, which now contains
all CLI support for diagnostic purposes.

Signed-off-by: Qi Zhang 
---
v5:
- ignore the error when query node failed at queue level, as queue may
   be stopped.
v4:
- show node type in brief mode

v3:
- fix incorrect parameter when query rl profile

v2:
- fix CI build issue

 .../ice/{ice_ddp_package.c => ice_diagnose.c} | 373 ++
 drivers/net/ice/ice_ethdev.h  |   3 +
 drivers/net/ice/ice_testpmd.c |  65 +++
 drivers/net/ice/meson.build   |   2 +-
 drivers/net/ice/version.map   |   1 +
 5 files changed, 443 insertions(+), 1 deletion(-)
 rename drivers/net/ice/{ice_ddp_package.c => ice_diagnose.c} (60%)

diff --git a/drivers/net/ice/ice_ddp_package.c b/drivers/net/ice/ice_diagnose.c
similarity index 60%
rename from drivers/net/ice/ice_ddp_package.c
rename to drivers/net/ice/ice_diagnose.c
index 0aa19eb282..2b9794d212 100644
--- a/drivers/net/ice/ice_ddp_package.c
+++ b/drivers/net/ice/ice_diagnose.c
@@ -11,6 +11,7 @@
 #include 
 
 #include "ice_ethdev.h"
+#include "ice_rxtx.h"
 
 #define ICE_BLK_MAX_COUNT  512
 #define ICE_BUFF_SEG_HEADER_FLAG   0x1
@@ -507,3 +508,375 @@ int rte_pmd_ice_dump_switch(uint16_t port, uint8_t 
**buff, uint32_t *size)
 
return ice_dump_switch(dev, buff, size);
 }
+
+static void print_rl_profile(struct ice_aqc_rl_profile_elem *prof,
+FILE *stream)
+{
+   fprintf(stream, "\t\t\t\t\t\n");
+   fprintf(stream, "\t\t\t\t\t\t\n");
+
+   fprintf(stream, "\t\t\t\t\t\t\t\n");
+   fprintf(stream, "\t\t\t\t\t\t\t\tid\n");
+   fprintf(stream, "\t\t\t\t\t\t\t\t%d\n", prof->profile_id);
+   fprintf(stream, "\t\t\t\t\t\t\t\n");
+
+   fprintf(stream, "\t\t\t\t\t\t\t\n");
+   fprintf(stream, "\t\t\t\t\t\t\t\tmax burst size\n");
+   fprintf(stream, "\t\t\t\t\t\t\t\t%d\n", prof->max_burst_size);
+   fprintf(stream, "\t\t\t\t\t\t\t\n");
+
+   fprintf(stream, "\t\t\t\t\t\t\t\n");
+   fprintf(stream, "\t\t\t\t\t\t\t\trate limit multiply\n");
+   fprintf(stream, "\t\t\t\t\t\t\t\t%d\n", prof->rl_multiply);
+   fprintf(stream, "\t\t\t\t\t\t\t\n");
+
+   fprintf(stream, "\t\t\t\t\t\t\t\n");
+   fprintf(stream, "\t\t\t\t\t\t\t\twake up calculation\n");
+   fprintf(stream, "\t\t\t\t\t\t\t\t%d\n", prof->wake_up_calc);
+   fprintf(stream, "\t\t\t\t\t\t\t\n");
+
+   fprintf(stream, "\t\t\t\t\t\t\t\n");
+   fprintf(stream, "\t\t\t\t\t\t\t\trate limit encode\n");
+   fprintf(stream, "\t\t\t\t\t\t\t\t%d\n", prof->rl_encode);
+   fprintf(stream, "\t\t\t\t\t\t\t\n");
+
+   fprintf(stream, "\t\t\t\t\t\t\n");
+   fprintf(stream, "\t\t\t\t\t\n");
+}
+
+static
+void print_elem_type(FILE *stream, u8 type)
+{
+   switch (type) {
+   case 1:
+   fprintf(stream, "root");
+   break;
+   case 2:
+   fprintf(stream, "tc");
+   break;
+   case 3:
+   fprintf(stream, "se_generic");
+   break;
+   case 4:
+   fprintf(stream, "entry_point");
+   break;
+   case 5:
+   fprintf(stream, "leaf");
+   break;
+   default:
+   fprintf(stream, "%d", type);
+   break;
+   }
+}
+
+static
+void print_valid_sections(FILE *stream, u8 vs)
+{
+   if ((vs & 0x1) != 0)
+   fprintf(stream, "generic ");
+   if ((vs & 0x2) != 0)
+   fprintf(stream, "cir ");
+   if ((vs & 0x4) != 0)
+   fprintf(stream, "eir ");
+   if ((vs & 0x8) != 0)
+   fprintf(stream, "shared ");
+}
+
+static
+void print_scheduling_mode(FILE *stream, bool flag)
+{
+   if (flag)
+   fprintf(stream, "pps");
+   else
+   fprintf(stream, "bps");
+}
+
+static
+void print_priority_mode(FILE *stream, bool flag)
+{
+   if (flag)
+   fprintf(stream, "single priority node");
+   else
+   fprintf(stream, "wfq");
+}
+
+static
+void print_node(struct ice_aqc_txsched_elem_data *data,
+   struct ice_aqc_rl_p

[PATCH v5 2/2] doc: add document for diagnostic utilities

2024-01-01 Thread Qi Zhang
Document CLI for diagnose purpose.

Signed-off-by: Qi Zhang 
---
 doc/guides/nics/ice.rst | 36 
 1 file changed, 36 insertions(+)

diff --git a/doc/guides/nics/ice.rst b/doc/guides/nics/ice.rst
index 820a385b06..29309abe4d 100644
--- a/doc/guides/nics/ice.rst
+++ b/doc/guides/nics/ice.rst
@@ -411,6 +411,42 @@ To start ``testpmd``, and add vlan 10 to port 0:
 
 testpmd> rx_vlan add 10 0
 
+Diagnostic Utilities
+
+
+Dump DDP Package
+
+
+Dump the runtime packet processing pipeline configuration into a
+binary file. This helps the support team diagnose hardware
+configuration issues.
+
+Usage::
+
+testpmd>ddp dump  
+
+Dump Switch Configurations
+~~
+
+Dump detail hardware configurations related to the switch pipeline
+stage into a binary file.
+
+Usage::
+
+testpmd>ddp dump switch  
+
+Dump Tx Scheduling Tree
+~~~
+
+Dump the runtime Tx scheduling tree into a DOT file.
+
+Usage::
+
+testpmd>txsched dump   
+
+In "brief" mode, all scheduling nodes in the tree are displayed.
+In "detail" mode, each node's configuration parameters are also displayed.
+
 Limitations or Known issues
 ---
 
-- 
2.31.1



[PATCH v5 1/2] net/ice: add Tx scheduling tree dump support

2024-01-01 Thread Qi Zhang
Added Testpmd CLI support for dumping Tx scheduling tree.

Usage:
testpmd>txsched dump   

The output file is in "dot" format, which can be converted
into an image file using Graphviz.

- In "brief" mode, all scheduling nodes in the tree are displayed.
- In "detail" mode, each node's configuration parameters are also
  displayed.

Renamed `ice_ddp_package.c` to `ice_diagnose.c`, which now contains
all CLI support for diagnostic purposes.

Signed-off-by: Qi Zhang 
---
v5:
- ignore the error when query node failed at queue level, as queue may
   be stopped.
v4:
- show node type in brief mode

v3:
- fix incorrect parameter when query rl profile

v2:
- fix CI build issue

 .../ice/{ice_ddp_package.c => ice_diagnose.c} | 373 ++
 drivers/net/ice/ice_ethdev.h  |   3 +
 drivers/net/ice/ice_testpmd.c |  65 +++
 drivers/net/ice/meson.build   |   2 +-
 drivers/net/ice/version.map   |   1 +
 5 files changed, 443 insertions(+), 1 deletion(-)
 rename drivers/net/ice/{ice_ddp_package.c => ice_diagnose.c} (60%)

diff --git a/drivers/net/ice/ice_ddp_package.c b/drivers/net/ice/ice_diagnose.c
similarity index 60%
rename from drivers/net/ice/ice_ddp_package.c
rename to drivers/net/ice/ice_diagnose.c
index 0aa19eb282..2b9794d212 100644
--- a/drivers/net/ice/ice_ddp_package.c
+++ b/drivers/net/ice/ice_diagnose.c
@@ -11,6 +11,7 @@
 #include 
 
 #include "ice_ethdev.h"
+#include "ice_rxtx.h"
 
 #define ICE_BLK_MAX_COUNT  512
 #define ICE_BUFF_SEG_HEADER_FLAG   0x1
@@ -507,3 +508,375 @@ int rte_pmd_ice_dump_switch(uint16_t port, uint8_t 
**buff, uint32_t *size)
 
return ice_dump_switch(dev, buff, size);
 }
+
+static void print_rl_profile(struct ice_aqc_rl_profile_elem *prof,
+FILE *stream)
+{
+   fprintf(stream, "\t\t\t\t\t\n");
+   fprintf(stream, "\t\t\t\t\t\t\n");
+
+   fprintf(stream, "\t\t\t\t\t\t\t\n");
+   fprintf(stream, "\t\t\t\t\t\t\t\tid\n");
+   fprintf(stream, "\t\t\t\t\t\t\t\t%d\n", prof->profile_id);
+   fprintf(stream, "\t\t\t\t\t\t\t\n");
+
+   fprintf(stream, "\t\t\t\t\t\t\t\n");
+   fprintf(stream, "\t\t\t\t\t\t\t\tmax burst size\n");
+   fprintf(stream, "\t\t\t\t\t\t\t\t%d\n", prof->max_burst_size);
+   fprintf(stream, "\t\t\t\t\t\t\t\n");
+
+   fprintf(stream, "\t\t\t\t\t\t\t\n");
+   fprintf(stream, "\t\t\t\t\t\t\t\trate limit multiply\n");
+   fprintf(stream, "\t\t\t\t\t\t\t\t%d\n", prof->rl_multiply);
+   fprintf(stream, "\t\t\t\t\t\t\t\n");
+
+   fprintf(stream, "\t\t\t\t\t\t\t\n");
+   fprintf(stream, "\t\t\t\t\t\t\t\twake up calculation\n");
+   fprintf(stream, "\t\t\t\t\t\t\t\t%d\n", prof->wake_up_calc);
+   fprintf(stream, "\t\t\t\t\t\t\t\n");
+
+   fprintf(stream, "\t\t\t\t\t\t\t\n");
+   fprintf(stream, "\t\t\t\t\t\t\t\trate limit encode\n");
+   fprintf(stream, "\t\t\t\t\t\t\t\t%d\n", prof->rl_encode);
+   fprintf(stream, "\t\t\t\t\t\t\t\n");
+
+   fprintf(stream, "\t\t\t\t\t\t\n");
+   fprintf(stream, "\t\t\t\t\t\n");
+}
+
+static
+void print_elem_type(FILE *stream, u8 type)
+{
+   switch (type) {
+   case 1:
+   fprintf(stream, "root");
+   break;
+   case 2:
+   fprintf(stream, "tc");
+   break;
+   case 3:
+   fprintf(stream, "se_generic");
+   break;
+   case 4:
+   fprintf(stream, "entry_point");
+   break;
+   case 5:
+   fprintf(stream, "leaf");
+   break;
+   default:
+   fprintf(stream, "%d", type);
+   break;
+   }
+}
+
+static
+void print_valid_sections(FILE *stream, u8 vs)
+{
+   if ((vs & 0x1) != 0)
+   fprintf(stream, "generic ");
+   if ((vs & 0x2) != 0)
+   fprintf(stream, "cir ");
+   if ((vs & 0x4) != 0)
+   fprintf(stream, "eir ");
+   if ((vs & 0x8) != 0)
+   fprintf(stream, "shared ");
+}
+
+static
+void print_scheduling_mode(FILE *stream, bool flag)
+{
+   if (flag)
+   fprintf(stream, "pps");
+   else
+   fprintf(stream, "bps");
+}
+
+static
+void print_priority_mode(FILE *stream, bool flag)
+{
+   if (flag)
+   fprintf(stream, "single priority node");
+   else
+   fprintf(stream, "wfq");
+}
+
+static
+void print_node(struct ice_aqc_txsched_elem_data *data,
+   struct ice_aqc_rl_p

[PATCH v4 2/2] doc: add document for diagnostic utilities

2024-01-01 Thread Qi Zhang
Document CLI for diagnose purpose.

Signed-off-by: Qi Zhang 
---
 doc/guides/nics/ice.rst | 36 
 1 file changed, 36 insertions(+)

diff --git a/doc/guides/nics/ice.rst b/doc/guides/nics/ice.rst
index 820a385b06..29309abe4d 100644
--- a/doc/guides/nics/ice.rst
+++ b/doc/guides/nics/ice.rst
@@ -411,6 +411,42 @@ To start ``testpmd``, and add vlan 10 to port 0:
 
 testpmd> rx_vlan add 10 0
 
+Diagnostic Utilities
+
+
+Dump DDP Package
+
+
+Dump the runtime packet processing pipeline configuration into a
+binary file. This helps the support team diagnose hardware
+configuration issues.
+
+Usage::
+
+testpmd>ddp dump  
+
+Dump Switch Configurations
+~~
+
+Dump detail hardware configurations related to the switch pipeline
+stage into a binary file.
+
+Usage::
+
+testpmd>ddp dump switch  
+
+Dump Tx Scheduling Tree
+~~~
+
+Dump the runtime Tx scheduling tree into a DOT file.
+
+Usage::
+
+testpmd>txsched dump   
+
+In "brief" mode, all scheduling nodes in the tree are displayed.
+In "detail" mode, each node's configuration parameters are also displayed.
+
 Limitations or Known issues
 ---
 
-- 
2.31.1



[PATCH v4 1/2] net/ice: add Tx scheduling tree dump support

2024-01-01 Thread Qi Zhang
Added Testpmd CLI support for dumping Tx scheduling tree.

Usage:
testpmd>txsched dump   

The output file is in "dot" format, which can be converted
into an image file using Graphviz.

- In "brief" mode, all scheduling nodes in the tree are displayed.
- In "detail" mode, each node's configuration parameters are also
  displayed.

Renamed `ice_ddp_package.c` to `ice_diagnose.c`, which now contains
all CLI support for diagnostic purposes.

Signed-off-by: Qi Zhang 
---
v4:
- show node type in brief mode

v3:
- fix incorrect parameter when query rl profile

v2:
- fix CI build issue

 .../ice/{ice_ddp_package.c => ice_diagnose.c} | 367 ++
 drivers/net/ice/ice_ethdev.h  |   3 +
 drivers/net/ice/ice_testpmd.c |  65 
 drivers/net/ice/meson.build   |   2 +-
 drivers/net/ice/version.map   |   1 +
 5 files changed, 437 insertions(+), 1 deletion(-)
 rename drivers/net/ice/{ice_ddp_package.c => ice_diagnose.c} (61%)

diff --git a/drivers/net/ice/ice_ddp_package.c b/drivers/net/ice/ice_diagnose.c
similarity index 61%
rename from drivers/net/ice/ice_ddp_package.c
rename to drivers/net/ice/ice_diagnose.c
index 0aa19eb282..f259244825 100644
--- a/drivers/net/ice/ice_ddp_package.c
+++ b/drivers/net/ice/ice_diagnose.c
@@ -11,6 +11,7 @@
 #include 
 
 #include "ice_ethdev.h"
+#include "ice_rxtx.h"
 
 #define ICE_BLK_MAX_COUNT  512
 #define ICE_BUFF_SEG_HEADER_FLAG   0x1
@@ -507,3 +508,369 @@ int rte_pmd_ice_dump_switch(uint16_t port, uint8_t 
**buff, uint32_t *size)
 
return ice_dump_switch(dev, buff, size);
 }
+
+static void print_rl_profile(struct ice_aqc_rl_profile_elem *prof,
+FILE *stream)
+{
+   fprintf(stream, "\t\t\t\t\t\n");
+   fprintf(stream, "\t\t\t\t\t\t\n");
+
+   fprintf(stream, "\t\t\t\t\t\t\t\n");
+   fprintf(stream, "\t\t\t\t\t\t\t\tid\n");
+   fprintf(stream, "\t\t\t\t\t\t\t\t%d\n", prof->profile_id);
+   fprintf(stream, "\t\t\t\t\t\t\t\n");
+
+   fprintf(stream, "\t\t\t\t\t\t\t\n");
+   fprintf(stream, "\t\t\t\t\t\t\t\tmax burst size\n");
+   fprintf(stream, "\t\t\t\t\t\t\t\t%d\n", prof->max_burst_size);
+   fprintf(stream, "\t\t\t\t\t\t\t\n");
+
+   fprintf(stream, "\t\t\t\t\t\t\t\n");
+   fprintf(stream, "\t\t\t\t\t\t\t\trate limit multiply\n");
+   fprintf(stream, "\t\t\t\t\t\t\t\t%d\n", prof->rl_multiply);
+   fprintf(stream, "\t\t\t\t\t\t\t\n");
+
+   fprintf(stream, "\t\t\t\t\t\t\t\n");
+   fprintf(stream, "\t\t\t\t\t\t\t\twake up calculation\n");
+   fprintf(stream, "\t\t\t\t\t\t\t\t%d\n", prof->wake_up_calc);
+   fprintf(stream, "\t\t\t\t\t\t\t\n");
+
+   fprintf(stream, "\t\t\t\t\t\t\t\n");
+   fprintf(stream, "\t\t\t\t\t\t\t\trate limit encode\n");
+   fprintf(stream, "\t\t\t\t\t\t\t\t%d\n", prof->rl_encode);
+   fprintf(stream, "\t\t\t\t\t\t\t\n");
+
+   fprintf(stream, "\t\t\t\t\t\t\n");
+   fprintf(stream, "\t\t\t\t\t\n");
+}
+
+static
+void print_elem_type(FILE *stream, u8 type)
+{
+   switch (type) {
+   case 1:
+   fprintf(stream, "root");
+   break;
+   case 2:
+   fprintf(stream, "tc");
+   break;
+   case 3:
+   fprintf(stream, "se_generic");
+   break;
+   case 4:
+   fprintf(stream, "entry_point");
+   break;
+   case 5:
+   fprintf(stream, "leaf");
+   break;
+   default:
+   fprintf(stream, "%d", type);
+   break;
+   }
+}
+
+static
+void print_valid_sections(FILE *stream, u8 vs)
+{
+   if ((vs & 0x1) != 0)
+   fprintf(stream, "generic ");
+   if ((vs & 0x2) != 0)
+   fprintf(stream, "cir ");
+   if ((vs & 0x4) != 0)
+   fprintf(stream, "eir ");
+   if ((vs & 0x8) != 0)
+   fprintf(stream, "shared ");
+}
+
+static
+void print_scheduling_mode(FILE *stream, bool flag)
+{
+   if (flag)
+   fprintf(stream, "pps");
+   else
+   fprintf(stream, "bps");
+}
+
+static
+void print_priority_mode(FILE *stream, bool flag)
+{
+   if (flag)
+   fprintf(stream, "single priority node");
+   else
+   fprintf(stream, "wfq");
+}
+
+static
+void print_node(struct ice_aqc_txsched_elem_data *data,
+   struct ice_aqc_rl_profile_elem *cir_prof,
+   struct ice_aqc_rl_profile_elem *eir_prof

[PATCH 2/2] doc: add document for diagnostic utilities

2024-01-01 Thread Qi Zhang
Document CLI for diagnose purpose.

Signed-off-by: Qi Zhang 
---
 doc/guides/nics/ice.rst | 36 
 1 file changed, 36 insertions(+)

diff --git a/doc/guides/nics/ice.rst b/doc/guides/nics/ice.rst
index 820a385b06..29309abe4d 100644
--- a/doc/guides/nics/ice.rst
+++ b/doc/guides/nics/ice.rst
@@ -411,6 +411,42 @@ To start ``testpmd``, and add vlan 10 to port 0:
 
 testpmd> rx_vlan add 10 0
 
+Diagnostic Utilities
+
+
+Dump DDP Package
+
+
+Dump the runtime packet processing pipeline configuration into a
+binary file. This helps the support team diagnose hardware
+configuration issues.
+
+Usage::
+
+testpmd>ddp dump  
+
+Dump Switch Configurations
+~~
+
+Dump detail hardware configurations related to the switch pipeline
+stage into a binary file.
+
+Usage::
+
+testpmd>ddp dump switch  
+
+Dump Tx Scheduling Tree
+~~~
+
+Dump the runtime Tx scheduling tree into a DOT file.
+
+Usage::
+
+testpmd>txsched dump   
+
+In "brief" mode, all scheduling nodes in the tree are displayed.
+In "detail" mode, each node's configuration parameters are also displayed.
+
 Limitations or Known issues
 ---
 
-- 
2.31.1



[PATCH 1/2] net/ice: add Tx scheduling tree dump support

2024-01-01 Thread Qi Zhang
Added Testpmd CLI support for dumping Tx scheduling tree.

Usage:
testpmd>txsched dump   

The output file is in "dot" format, which can be converted
into an image file using Graphviz.

- In "brief" mode, all scheduling nodes in the tree are displayed.
- In "detail" mode, each node's configuration parameters are also
  displayed.

Renamed `ice_ddp_package.c` to `ice_diagnose.c`, which now contains
all CLI support for diagnostic purposes.

Signed-off-by: Qi Zhang 
---
v4:
- show node type in brief mode.

v3:
- fix incorrect parameter when query rl profile

v2:
- fix CI build issue
 .../ice/{ice_ddp_package.c => ice_diagnose.c} | 367 ++
 drivers/net/ice/ice_ethdev.h  |   3 +
 drivers/net/ice/ice_testpmd.c |  65 
 drivers/net/ice/meson.build   |   2 +-
 drivers/net/ice/version.map   |   1 +
 5 files changed, 437 insertions(+), 1 deletion(-)
 rename drivers/net/ice/{ice_ddp_package.c => ice_diagnose.c} (61%)

diff --git a/drivers/net/ice/ice_ddp_package.c b/drivers/net/ice/ice_diagnose.c
similarity index 61%
rename from drivers/net/ice/ice_ddp_package.c
rename to drivers/net/ice/ice_diagnose.c
index 0aa19eb282..f259244825 100644
--- a/drivers/net/ice/ice_ddp_package.c
+++ b/drivers/net/ice/ice_diagnose.c
@@ -11,6 +11,7 @@
 #include 
 
 #include "ice_ethdev.h"
+#include "ice_rxtx.h"
 
 #define ICE_BLK_MAX_COUNT  512
 #define ICE_BUFF_SEG_HEADER_FLAG   0x1
@@ -507,3 +508,369 @@ int rte_pmd_ice_dump_switch(uint16_t port, uint8_t 
**buff, uint32_t *size)
 
return ice_dump_switch(dev, buff, size);
 }
+
+static void print_rl_profile(struct ice_aqc_rl_profile_elem *prof,
+FILE *stream)
+{
+   fprintf(stream, "\t\t\t\t\t\n");
+   fprintf(stream, "\t\t\t\t\t\t\n");
+
+   fprintf(stream, "\t\t\t\t\t\t\t\n");
+   fprintf(stream, "\t\t\t\t\t\t\t\tid\n");
+   fprintf(stream, "\t\t\t\t\t\t\t\t%d\n", prof->profile_id);
+   fprintf(stream, "\t\t\t\t\t\t\t\n");
+
+   fprintf(stream, "\t\t\t\t\t\t\t\n");
+   fprintf(stream, "\t\t\t\t\t\t\t\tmax burst size\n");
+   fprintf(stream, "\t\t\t\t\t\t\t\t%d\n", prof->max_burst_size);
+   fprintf(stream, "\t\t\t\t\t\t\t\n");
+
+   fprintf(stream, "\t\t\t\t\t\t\t\n");
+   fprintf(stream, "\t\t\t\t\t\t\t\trate limit multiply\n");
+   fprintf(stream, "\t\t\t\t\t\t\t\t%d\n", prof->rl_multiply);
+   fprintf(stream, "\t\t\t\t\t\t\t\n");
+
+   fprintf(stream, "\t\t\t\t\t\t\t\n");
+   fprintf(stream, "\t\t\t\t\t\t\t\twake up calculation\n");
+   fprintf(stream, "\t\t\t\t\t\t\t\t%d\n", prof->wake_up_calc);
+   fprintf(stream, "\t\t\t\t\t\t\t\n");
+
+   fprintf(stream, "\t\t\t\t\t\t\t\n");
+   fprintf(stream, "\t\t\t\t\t\t\t\trate limit encode\n");
+   fprintf(stream, "\t\t\t\t\t\t\t\t%d\n", prof->rl_encode);
+   fprintf(stream, "\t\t\t\t\t\t\t\n");
+
+   fprintf(stream, "\t\t\t\t\t\t\n");
+   fprintf(stream, "\t\t\t\t\t\n");
+}
+
+static
+void print_elem_type(FILE *stream, u8 type)
+{
+   switch (type) {
+   case 1:
+   fprintf(stream, "root");
+   break;
+   case 2:
+   fprintf(stream, "tc");
+   break;
+   case 3:
+   fprintf(stream, "se_generic");
+   break;
+   case 4:
+   fprintf(stream, "entry_point");
+   break;
+   case 5:
+   fprintf(stream, "leaf");
+   break;
+   default:
+   fprintf(stream, "%d", type);
+   break;
+   }
+}
+
+static
+void print_valid_sections(FILE *stream, u8 vs)
+{
+   if ((vs & 0x1) != 0)
+   fprintf(stream, "generic ");
+   if ((vs & 0x2) != 0)
+   fprintf(stream, "cir ");
+   if ((vs & 0x4) != 0)
+   fprintf(stream, "eir ");
+   if ((vs & 0x8) != 0)
+   fprintf(stream, "shared ");
+}
+
+static
+void print_scheduling_mode(FILE *stream, bool flag)
+{
+   if (flag)
+   fprintf(stream, "pps");
+   else
+   fprintf(stream, "bps");
+}
+
+static
+void print_priority_mode(FILE *stream, bool flag)
+{
+   if (flag)
+   fprintf(stream, "single priority node");
+   else
+   fprintf(stream, "wfq");
+}
+
+static
+void print_node(struct ice_aqc_txsched_elem_data *data,
+   struct ice_aqc_rl_profile_elem *cir_prof,
+   struct ice_aqc_rl_profile_elem *eir_prof

[PATCH v4 2/2] net/ice: support Tx sched commit before dev_start

2024-01-01 Thread Qi Zhang
Currently Tx hierarchy commit only take effect if device
already be started, as after a dev start / stop cycle, queues
has been removed and added back which cause the Tx scheduler
tree return to orignal topo.

In this patch, the hierarchy commit function will simply return
if device has not be started yet and all the commit actions will
be deferred to dev_start.

Signed-off-by: Qi Zhang 
---
 drivers/net/ice/ice_ethdev.c |  9 +
 drivers/net/ice/ice_ethdev.h |  3 +++
 drivers/net/ice/ice_tm.c | 23 ---
 3 files changed, 32 insertions(+), 3 deletions(-)

diff --git a/drivers/net/ice/ice_ethdev.c b/drivers/net/ice/ice_ethdev.c
index 3c3bc49dc2..d425a8f98b 100644
--- a/drivers/net/ice/ice_ethdev.c
+++ b/drivers/net/ice/ice_ethdev.c
@@ -3717,6 +3717,7 @@ ice_dev_start(struct rte_eth_dev *dev)
int mask, ret;
uint8_t timer = hw->func_caps.ts_func_info.tmr_index_owned;
uint32_t pin_idx = ad->devargs.pin_idx;
+   struct rte_tm_error tm_err;
 
/* program Tx queues' context in hardware */
for (nb_txq = 0; nb_txq < data->nb_tx_queues; nb_txq++) {
@@ -3746,6 +3747,14 @@ ice_dev_start(struct rte_eth_dev *dev)
}
}
 
+   if (pf->tm_conf.committed) {
+   ret = ice_do_hierarchy_commit(dev, true, &tm_err);
+   if (ret) {
+   PMD_DRV_LOG(ERR, "fail to commit Tx scheduler");
+   goto rx_err;
+   }
+   }
+
ice_set_rx_function(dev);
ice_set_tx_function(dev);
 
diff --git a/drivers/net/ice/ice_ethdev.h b/drivers/net/ice/ice_ethdev.h
index 3b2db6aaa6..5448dff48d 100644
--- a/drivers/net/ice/ice_ethdev.h
+++ b/drivers/net/ice/ice_ethdev.h
@@ -686,6 +686,9 @@ int ice_rem_rss_cfg_wrap(struct ice_pf *pf, uint16_t vsi_id,
 struct ice_rss_hash_cfg *cfg);
 void ice_tm_conf_init(struct rte_eth_dev *dev);
 void ice_tm_conf_uninit(struct rte_eth_dev *dev);
+int ice_do_hierarchy_commit(struct rte_eth_dev *dev,
+   int clear_on_fail,
+   struct rte_tm_error *error);
 extern const struct rte_tm_ops ice_tm_ops;
 
 static inline int
diff --git a/drivers/net/ice/ice_tm.c b/drivers/net/ice/ice_tm.c
index 2ae55418b0..26a440124a 100644
--- a/drivers/net/ice/ice_tm.c
+++ b/drivers/net/ice/ice_tm.c
@@ -843,9 +843,9 @@ static int ice_add_leaf_nodes(struct rte_eth_dev *dev)
return ret;
 }
 
-static int ice_hierarchy_commit(struct rte_eth_dev *dev,
-int clear_on_fail,
-struct rte_tm_error *error)
+int ice_do_hierarchy_commit(struct rte_eth_dev *dev,
+   int clear_on_fail,
+   struct rte_tm_error *error)
 {
struct ice_pf *pf = ICE_DEV_PRIVATE_TO_PF(dev->data->dev_private);
struct ice_hw *hw = ICE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
@@ -977,6 +977,8 @@ static int ice_hierarchy_commit(struct rte_eth_dev *dev,
}
}
 
+   pf->tm_conf.committed = true;
+
return ret_val;
 
 reset_leaf:
@@ -992,3 +994,18 @@ static int ice_hierarchy_commit(struct rte_eth_dev *dev,
}
return ret_val;
 }
+
+static int ice_hierarchy_commit(struct rte_eth_dev *dev,
+int clear_on_fail,
+struct rte_tm_error *error)
+{
+   struct ice_pf *pf = ICE_DEV_PRIVATE_TO_PF(dev->data->dev_private);
+
+   /* if device not started, simply set committed flag and return. */
+   if (!dev->data->dev_started) {
+   pf->tm_conf.committed = true;
+   return 0;
+   }
+
+   return ice_do_hierarchy_commit(dev, clear_on_fail, error);
+}
-- 
2.31.1



[PATCH v4 1/2] net/ice: reset Tx sched node during commit

2024-01-01 Thread Qi Zhang
1. Always reset all Tx scheduler at the begining of a commit action.
   This prevent unexpected remains from previous commit.
2. Reset all Tx scheduler nodes if a commit failed.

For leaf node, stop queues which will remove sched node from
scheduler tree, then start queues which will add sched node back to
default topo.
For noleaf node, simply reset to default parameters.

Signed-off-by: Qi Zhang 
---
v4:
- show node type in brief mode.

v3:
- fix incorrect parameter when query rl profile

v2:
- fix CI build issue

 drivers/net/ice/ice_ethdev.h |   1 +
 drivers/net/ice/ice_tm.c | 134 ---
 2 files changed, 111 insertions(+), 24 deletions(-)

diff --git a/drivers/net/ice/ice_ethdev.h b/drivers/net/ice/ice_ethdev.h
index 1338c80d14..3b2db6aaa6 100644
--- a/drivers/net/ice/ice_ethdev.h
+++ b/drivers/net/ice/ice_ethdev.h
@@ -478,6 +478,7 @@ struct ice_tm_node {
struct ice_tm_node **children;
struct ice_tm_shaper_profile *shaper_profile;
struct rte_tm_node_params params;
+   struct ice_sched_node *sched_node;
 };
 
 /* node type of Traffic Manager */
diff --git a/drivers/net/ice/ice_tm.c b/drivers/net/ice/ice_tm.c
index 1a30524b05..2ae55418b0 100644
--- a/drivers/net/ice/ice_tm.c
+++ b/drivers/net/ice/ice_tm.c
@@ -764,16 +764,94 @@ static int ice_cfg_hw_node(struct ice_hw *hw,
return 0;
 }
 
+static struct ice_sched_node *ice_get_vsi_node(struct ice_hw *hw)
+{
+   struct ice_sched_node *node = hw->port_info->root;
+   uint32_t vsi_layer = hw->num_tx_sched_layers - ICE_VSI_LAYER_OFFSET;
+   uint32_t i;
+
+   for (i = 0; i < vsi_layer; i++)
+   node = node->children[0];
+
+   return node;
+}
+
+static int ice_reset_noleaf_nodes(struct rte_eth_dev *dev)
+{
+   struct ice_pf *pf = ICE_DEV_PRIVATE_TO_PF(dev->data->dev_private);
+   struct ice_hw *hw = ICE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+   struct ice_tm_node_list *qgroup_list = &pf->tm_conf.qgroup_list;
+   struct ice_sched_node *vsi_node = ice_get_vsi_node(hw);
+   struct ice_tm_node *tm_node;
+   int ret;
+
+   /* reset vsi_node */
+   ret = ice_set_node_rate(hw, NULL, vsi_node->info.node_teid, 
ICE_AGG_TYPE_VSI);
+   if (ret) {
+   PMD_DRV_LOG(ERR, "reset vsi node failed");
+   return ret;
+   }
+
+   /* reset queue group nodes */
+   TAILQ_FOREACH(tm_node, qgroup_list, node) {
+   if (tm_node->sched_node == NULL)
+   continue;
+
+   ret = ice_cfg_hw_node(hw, NULL,
+ tm_node->sched_node,
+ ICE_AGG_TYPE_Q);
+
+   if (ret) {
+   PMD_DRV_LOG(ERR, "reset queue group node %u failed", 
tm_node->id);
+   return ret;
+   }
+   tm_node->sched_node = NULL;
+   }
+
+   return 0;
+}
+
+static int ice_remove_leaf_nodes(struct rte_eth_dev *dev)
+{
+   int ret = 0;
+   int i;
+
+   for (i = 0; i < dev->data->nb_tx_queues; i++) {
+   ret = ice_tx_queue_stop(dev, i);
+   if (ret) {
+   PMD_DRV_LOG(ERR, "stop queue %u failed", i);
+   break;
+   }
+   }
+
+   return ret;
+}
+
+static int ice_add_leaf_nodes(struct rte_eth_dev *dev)
+{
+   int ret = 0;
+   int i;
+
+   for (i = 0; i < dev->data->nb_tx_queues; i++) {
+   ret = ice_tx_queue_start(dev, i);
+   if (ret) {
+   PMD_DRV_LOG(ERR, "start queue %u failed", i);
+   break;
+   }
+   }
+
+   return ret;
+}
+
 static int ice_hierarchy_commit(struct rte_eth_dev *dev,
 int clear_on_fail,
-__rte_unused struct rte_tm_error *error)
+struct rte_tm_error *error)
 {
struct ice_pf *pf = ICE_DEV_PRIVATE_TO_PF(dev->data->dev_private);
struct ice_hw *hw = ICE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
struct ice_tm_node_list *qgroup_list = &pf->tm_conf.qgroup_list;
struct ice_tm_node_list *queue_list = &pf->tm_conf.queue_list;
struct ice_tm_node *tm_node;
-   struct ice_sched_node *node;
struct ice_sched_node *vsi_node = NULL;
struct ice_sched_node *queue_node;
struct ice_tx_queue *txq;
@@ -785,23 +863,25 @@ static int ice_hierarchy_commit(struct rte_eth_dev *dev,
uint32_t nb_qg;
uint32_t qid;
uint32_t q_teid;
-   uint32_t vsi_layer;
 
-   for (i = 0; i < dev->data->nb_tx_queues; i++) {
-   ret_val = ice_tx_queue_stop(dev, i);
-   if (ret_val) {
-   error->type = RTE_TM_ERROR_TYPE_UNSPECIFIED;

[PATCH v3 2/2] doc: add document for diagnostic utilities

2023-12-27 Thread Qi Zhang
Document CLI for diagnose purpose.

Signed-off-by: Qi Zhang 
---
 doc/guides/nics/ice.rst | 36 
 1 file changed, 36 insertions(+)

diff --git a/doc/guides/nics/ice.rst b/doc/guides/nics/ice.rst
index 820a385b06..29309abe4d 100644
--- a/doc/guides/nics/ice.rst
+++ b/doc/guides/nics/ice.rst
@@ -411,6 +411,42 @@ To start ``testpmd``, and add vlan 10 to port 0:
 
 testpmd> rx_vlan add 10 0
 
+Diagnostic Utilities
+
+
+Dump DDP Package
+
+
+Dump the runtime packet processing pipeline configuration into a
+binary file. This helps the support team diagnose hardware
+configuration issues.
+
+Usage::
+
+testpmd>ddp dump  
+
+Dump Switch Configurations
+~~
+
+Dump detail hardware configurations related to the switch pipeline
+stage into a binary file.
+
+Usage::
+
+testpmd>ddp dump switch  
+
+Dump Tx Scheduling Tree
+~~~
+
+Dump the runtime Tx scheduling tree into a DOT file.
+
+Usage::
+
+testpmd>txsched dump   
+
+In "brief" mode, all scheduling nodes in the tree are displayed.
+In "detail" mode, each node's configuration parameters are also displayed.
+
 Limitations or Known issues
 ---
 
-- 
2.31.1



[PATCH v3 1/2] net/ice: add Tx scheduling tree dump support

2023-12-27 Thread Qi Zhang
Added Testpmd CLI support for dumping Tx scheduling tree.

Usage:
testpmd>txsched dump   

The output file is in "dot" format, which can be converted
into an image file using Graphviz.

- In "brief" mode, all scheduling nodes in the tree are displayed.
- In "detail" mode, each node's configuration parameters are also
  displayed.

Renamed `ice_ddp_package.c` to `ice_diagnose.c`, which now contains
all CLI support for diagnostic purposes.

Signed-off-by: Qi Zhang 
---

v3:
- fix incorrect parameter when query rl profile

v2:
- fix CI build issue

 .../ice/{ice_ddp_package.c => ice_diagnose.c} | 367 ++
 drivers/net/ice/ice_ethdev.h  |   3 +
 drivers/net/ice/ice_testpmd.c |  65 
 drivers/net/ice/meson.build   |   2 +-
 drivers/net/ice/version.map   |   1 +
 5 files changed, 437 insertions(+), 1 deletion(-)
 rename drivers/net/ice/{ice_ddp_package.c => ice_diagnose.c} (61%)

diff --git a/drivers/net/ice/ice_ddp_package.c b/drivers/net/ice/ice_diagnose.c
similarity index 61%
rename from drivers/net/ice/ice_ddp_package.c
rename to drivers/net/ice/ice_diagnose.c
index 0aa19eb282..e54554fc9c 100644
--- a/drivers/net/ice/ice_ddp_package.c
+++ b/drivers/net/ice/ice_diagnose.c
@@ -11,6 +11,7 @@
 #include 
 
 #include "ice_ethdev.h"
+#include "ice_rxtx.h"
 
 #define ICE_BLK_MAX_COUNT  512
 #define ICE_BUFF_SEG_HEADER_FLAG   0x1
@@ -507,3 +508,369 @@ int rte_pmd_ice_dump_switch(uint16_t port, uint8_t 
**buff, uint32_t *size)
 
return ice_dump_switch(dev, buff, size);
 }
+
+static void print_rl_profile(struct ice_aqc_rl_profile_elem *prof,
+FILE *stream)
+{
+   fprintf(stream, "\t\t\t\t\t\n");
+   fprintf(stream, "\t\t\t\t\t\t\n");
+
+   fprintf(stream, "\t\t\t\t\t\t\t\n");
+   fprintf(stream, "\t\t\t\t\t\t\t\tid\n");
+   fprintf(stream, "\t\t\t\t\t\t\t\t%d\n", prof->profile_id);
+   fprintf(stream, "\t\t\t\t\t\t\t\n");
+
+   fprintf(stream, "\t\t\t\t\t\t\t\n");
+   fprintf(stream, "\t\t\t\t\t\t\t\tmax burst size\n");
+   fprintf(stream, "\t\t\t\t\t\t\t\t%d\n", prof->max_burst_size);
+   fprintf(stream, "\t\t\t\t\t\t\t\n");
+
+   fprintf(stream, "\t\t\t\t\t\t\t\n");
+   fprintf(stream, "\t\t\t\t\t\t\t\trate limit multiply\n");
+   fprintf(stream, "\t\t\t\t\t\t\t\t%d\n", prof->rl_multiply);
+   fprintf(stream, "\t\t\t\t\t\t\t\n");
+
+   fprintf(stream, "\t\t\t\t\t\t\t\n");
+   fprintf(stream, "\t\t\t\t\t\t\t\twake up calculation\n");
+   fprintf(stream, "\t\t\t\t\t\t\t\t%d\n", prof->wake_up_calc);
+   fprintf(stream, "\t\t\t\t\t\t\t\n");
+
+   fprintf(stream, "\t\t\t\t\t\t\t\n");
+   fprintf(stream, "\t\t\t\t\t\t\t\trate limit encode\n");
+   fprintf(stream, "\t\t\t\t\t\t\t\t%d\n", prof->rl_encode);
+   fprintf(stream, "\t\t\t\t\t\t\t\n");
+
+   fprintf(stream, "\t\t\t\t\t\t\n");
+   fprintf(stream, "\t\t\t\t\t\n");
+}
+
+static
+void print_elem_type(FILE *stream, u8 type)
+{
+   switch (type) {
+   case 1:
+   fprintf(stream, "root");
+   break;
+   case 2:
+   fprintf(stream, "tc");
+   break;
+   case 3:
+   fprintf(stream, "se_generic");
+   break;
+   case 4:
+   fprintf(stream, "entry_point");
+   break;
+   case 5:
+   fprintf(stream, "leaf");
+   break;
+   default:
+   fprintf(stream, "%d", type);
+   break;
+   }
+}
+
+static
+void print_valid_sections(FILE *stream, u8 vs)
+{
+   if ((vs & 0x1) != 0)
+   fprintf(stream, "generic ");
+   if ((vs & 0x2) != 0)
+   fprintf(stream, "cir ");
+   if ((vs & 0x4) != 0)
+   fprintf(stream, "eir ");
+   if ((vs & 0x8) != 0)
+   fprintf(stream, "shared ");
+}
+
+static
+void print_scheduling_mode(FILE *stream, bool flag)
+{
+   if (flag)
+   fprintf(stream, "pps");
+   else
+   fprintf(stream, "bps");
+}
+
+static
+void print_priority_mode(FILE *stream, bool flag)
+{
+   if (flag)
+   fprintf(stream, "single priority node");
+   else
+   fprintf(stream, "wfq");
+}
+
+static
+void print_node(struct ice_aqc_txsched_elem_data *data,
+   struct ice_aqc_rl_profile_elem *cir_prof,
+   struct ice_aqc_rl_profile_elem *eir_prof,
+   struct ice_aqc_rl_profile_ele

[PATCH v2 2/2] doc: add document for diagnostic utilities

2023-12-26 Thread Qi Zhang
Document CLI for diagnose purpose.

Signed-off-by: Qi Zhang 
---
 doc/guides/nics/ice.rst | 36 
 1 file changed, 36 insertions(+)

diff --git a/doc/guides/nics/ice.rst b/doc/guides/nics/ice.rst
index 820a385b06..29309abe4d 100644
--- a/doc/guides/nics/ice.rst
+++ b/doc/guides/nics/ice.rst
@@ -411,6 +411,42 @@ To start ``testpmd``, and add vlan 10 to port 0:
 
 testpmd> rx_vlan add 10 0
 
+Diagnostic Utilities
+
+
+Dump DDP Package
+
+
+Dump the runtime packet processing pipeline configuration into a
+binary file. This helps the support team diagnose hardware
+configuration issues.
+
+Usage::
+
+testpmd>ddp dump  
+
+Dump Switch Configurations
+~~
+
+Dump detail hardware configurations related to the switch pipeline
+stage into a binary file.
+
+Usage::
+
+testpmd>ddp dump switch  
+
+Dump Tx Scheduling Tree
+~~~
+
+Dump the runtime Tx scheduling tree into a DOT file.
+
+Usage::
+
+testpmd>txsched dump   
+
+In "brief" mode, all scheduling nodes in the tree are displayed.
+In "detail" mode, each node's configuration parameters are also displayed.
+
 Limitations or Known issues
 ---
 
-- 
2.31.1



[PATCH v2 1/2] net/ice: add Tx scheduling tree dump support

2023-12-26 Thread Qi Zhang
Added Testpmd CLI support for dumping Tx scheduling tree.

Usage:
testpmd>txsched dump   

The output file is in "dot" format, which can be converted
into an image file using Graphviz.

- In "brief" mode, all scheduling nodes in the tree are displayed.
- In "detail" mode, each node's configuration parameters are also
  displayed.

Renamed `ice_ddp_package.c` to `ice_diagnose.c`, which now contains
all CLI support for diagnostic purposes.

Signed-off-by: Qi Zhang 
---

v2:
- fix patchwork build issue.

 .../ice/{ice_ddp_package.c => ice_diagnose.c} | 367 ++
 drivers/net/ice/ice_ethdev.h  |   3 +
 drivers/net/ice/ice_testpmd.c |  65 
 drivers/net/ice/meson.build   |   2 +-
 drivers/net/ice/version.map   |   1 +
 5 files changed, 437 insertions(+), 1 deletion(-)
 rename drivers/net/ice/{ice_ddp_package.c => ice_diagnose.c} (61%)

diff --git a/drivers/net/ice/ice_ddp_package.c b/drivers/net/ice/ice_diagnose.c
similarity index 61%
rename from drivers/net/ice/ice_ddp_package.c
rename to drivers/net/ice/ice_diagnose.c
index 0aa19eb282..42459accfa 100644
--- a/drivers/net/ice/ice_ddp_package.c
+++ b/drivers/net/ice/ice_diagnose.c
@@ -11,6 +11,7 @@
 #include 
 
 #include "ice_ethdev.h"
+#include "ice_rxtx.h"
 
 #define ICE_BLK_MAX_COUNT  512
 #define ICE_BUFF_SEG_HEADER_FLAG   0x1
@@ -507,3 +508,369 @@ int rte_pmd_ice_dump_switch(uint16_t port, uint8_t 
**buff, uint32_t *size)
 
return ice_dump_switch(dev, buff, size);
 }
+
+static void print_rl_profile(struct ice_aqc_rl_profile_elem *prof,
+FILE *stream)
+{
+   fprintf(stream, "\t\t\t\t\t\n");
+   fprintf(stream, "\t\t\t\t\t\t\n");
+
+   fprintf(stream, "\t\t\t\t\t\t\t\n");
+   fprintf(stream, "\t\t\t\t\t\t\t\tid\n");
+   fprintf(stream, "\t\t\t\t\t\t\t\t%d\n", prof->profile_id);
+   fprintf(stream, "\t\t\t\t\t\t\t\n");
+
+   fprintf(stream, "\t\t\t\t\t\t\t\n");
+   fprintf(stream, "\t\t\t\t\t\t\t\tmax burst size\n");
+   fprintf(stream, "\t\t\t\t\t\t\t\t%d\n", prof->max_burst_size);
+   fprintf(stream, "\t\t\t\t\t\t\t\n");
+
+   fprintf(stream, "\t\t\t\t\t\t\t\n");
+   fprintf(stream, "\t\t\t\t\t\t\t\trate limit multiply\n");
+   fprintf(stream, "\t\t\t\t\t\t\t\t%d\n", prof->rl_multiply);
+   fprintf(stream, "\t\t\t\t\t\t\t\n");
+
+   fprintf(stream, "\t\t\t\t\t\t\t\n");
+   fprintf(stream, "\t\t\t\t\t\t\t\twake up calculation\n");
+   fprintf(stream, "\t\t\t\t\t\t\t\t%d\n", prof->wake_up_calc);
+   fprintf(stream, "\t\t\t\t\t\t\t\n");
+
+   fprintf(stream, "\t\t\t\t\t\t\t\n");
+   fprintf(stream, "\t\t\t\t\t\t\t\trate limit encode\n");
+   fprintf(stream, "\t\t\t\t\t\t\t\t%d\n", prof->rl_encode);
+   fprintf(stream, "\t\t\t\t\t\t\t\n");
+
+   fprintf(stream, "\t\t\t\t\t\t\n");
+   fprintf(stream, "\t\t\t\t\t\n");
+}
+
+static
+void print_elem_type(FILE *stream, u8 type)
+{
+   switch (type) {
+   case 1:
+   fprintf(stream, "root");
+   break;
+   case 2:
+   fprintf(stream, "tc");
+   break;
+   case 3:
+   fprintf(stream, "se_generic");
+   break;
+   case 4:
+   fprintf(stream, "entry_point");
+   break;
+   case 5:
+   fprintf(stream, "leaf");
+   break;
+   default:
+   fprintf(stream, "%d", type);
+   break;
+   }
+}
+
+static
+void print_valid_sections(FILE *stream, u8 vs)
+{
+   if ((vs & 0x1) != 0)
+   fprintf(stream, "generic ");
+   if ((vs & 0x2) != 0)
+   fprintf(stream, "cir ");
+   if ((vs & 0x4) != 0)
+   fprintf(stream, "eir ");
+   if ((vs & 0x8) != 0)
+   fprintf(stream, "shared ");
+}
+
+static
+void print_scheduling_mode(FILE *stream, bool flag)
+{
+   if (flag)
+   fprintf(stream, "pps");
+   else
+   fprintf(stream, "bps");
+}
+
+static
+void print_priority_mode(FILE *stream, bool flag)
+{
+   if (flag)
+   fprintf(stream, "single priority node");
+   else
+   fprintf(stream, "wfq");
+}
+
+static
+void print_node(struct ice_aqc_txsched_elem_data *data,
+   struct ice_aqc_rl_profile_elem *cir_prof,
+   struct ice_aqc_rl_profile_elem *eir_prof,
+   struct ice_aqc_rl_profile_elem *shared_prof,
+   bool detail, 

[PATCH 2/2] doc: add document for diagnostic utilities

2023-12-26 Thread Qi Zhang
Document CLI for diagnose purpose.

Signed-off-by: Qi Zhang 
---
 doc/guides/nics/ice.rst | 36 
 1 file changed, 36 insertions(+)

diff --git a/doc/guides/nics/ice.rst b/doc/guides/nics/ice.rst
index 820a385b06..29309abe4d 100644
--- a/doc/guides/nics/ice.rst
+++ b/doc/guides/nics/ice.rst
@@ -411,6 +411,42 @@ To start ``testpmd``, and add vlan 10 to port 0:
 
 testpmd> rx_vlan add 10 0
 
+Diagnostic Utilities
+
+
+Dump DDP Package
+
+
+Dump the runtime packet processing pipeline configuration into a
+binary file. This helps the support team diagnose hardware
+configuration issues.
+
+Usage::
+
+testpmd>ddp dump  
+
+Dump Switch Configurations
+~~
+
+Dump detail hardware configurations related to the switch pipeline
+stage into a binary file.
+
+Usage::
+
+testpmd>ddp dump switch  
+
+Dump Tx Scheduling Tree
+~~~
+
+Dump the runtime Tx scheduling tree into a DOT file.
+
+Usage::
+
+testpmd>txsched dump   
+
+In "brief" mode, all scheduling nodes in the tree are displayed.
+In "detail" mode, each node's configuration parameters are also displayed.
+
 Limitations or Known issues
 ---
 
-- 
2.31.1



[PATCH 1/2] net/ice: add Tx scheduling tree dump support

2023-12-26 Thread Qi Zhang
Added Testpmd CLI support for dumping Tx scheduling tree.

Usage:
testpmd>txsched dump   

The output file is in "dot" format, which can be converted
into an image file using Graphviz.

- In "brief" mode, all scheduling nodes in the tree are displayed.
- In "detail" mode, each node's configuration parameters are also
  displayed.

Renamed `ice_ddp_package.c` to `ice_diagnose.c`, which now contains
all CLI support for diagnostic purposes.

Signed-off-by: Qi Zhang 
---
 .../ice/{ice_ddp_package.c => ice_diagnose.c} | 361 ++
 drivers/net/ice/ice_ethdev.h  |   3 +
 drivers/net/ice/ice_testpmd.c |  78 
 drivers/net/ice/meson.build   |   2 +-
 drivers/net/ice/version.map   |   1 +
 5 files changed, 444 insertions(+), 1 deletion(-)
 rename drivers/net/ice/{ice_ddp_package.c => ice_diagnose.c} (61%)

diff --git a/drivers/net/ice/ice_ddp_package.c b/drivers/net/ice/ice_diagnose.c
similarity index 61%
rename from drivers/net/ice/ice_ddp_package.c
rename to drivers/net/ice/ice_diagnose.c
index 0aa19eb282..1968cf7039 100644
--- a/drivers/net/ice/ice_ddp_package.c
+++ b/drivers/net/ice/ice_diagnose.c
@@ -11,6 +11,7 @@
 #include 
 
 #include "ice_ethdev.h"
+#include "ice_rxtx.h"
 
 #define ICE_BLK_MAX_COUNT  512
 #define ICE_BUFF_SEG_HEADER_FLAG   0x1
@@ -507,3 +508,363 @@ int rte_pmd_ice_dump_switch(uint16_t port, uint8_t 
**buff, uint32_t *size)
 
return ice_dump_switch(dev, buff, size);
 }
+
+static void print_rl_profile(struct ice_aqc_rl_profile_elem *prof,
+FILE *stream)
+{
+   fprintf(stream, "\t\t\t\t\t\n");
+   fprintf(stream, "\t\t\t\t\t\t\n");
+
+   fprintf(stream, "\t\t\t\t\t\t\t\n");
+   fprintf(stream, "\t\t\t\t\t\t\t\tid\n");
+   fprintf(stream, "\t\t\t\t\t\t\t\t%d\n", prof->profile_id);
+   fprintf(stream, "\t\t\t\t\t\t\t\n");
+
+   fprintf(stream, "\t\t\t\t\t\t\t\n");
+   fprintf(stream, "\t\t\t\t\t\t\t\tmax burst size\n");
+   fprintf(stream, "\t\t\t\t\t\t\t\t%d\n", prof->max_burst_size);
+   fprintf(stream, "\t\t\t\t\t\t\t\n");
+
+   fprintf(stream, "\t\t\t\t\t\t\t\n");
+   fprintf(stream, "\t\t\t\t\t\t\t\trate limit multiply\n");
+   fprintf(stream, "\t\t\t\t\t\t\t\t%d\n", prof->rl_multiply);
+   fprintf(stream, "\t\t\t\t\t\t\t\n");
+
+   fprintf(stream, "\t\t\t\t\t\t\t\n");
+   fprintf(stream, "\t\t\t\t\t\t\t\twake up calculation\n");
+   fprintf(stream, "\t\t\t\t\t\t\t\t%d\n", prof->wake_up_calc);
+   fprintf(stream, "\t\t\t\t\t\t\t\n");
+
+   fprintf(stream, "\t\t\t\t\t\t\t\n");
+   fprintf(stream, "\t\t\t\t\t\t\t\trate limit encode\n");
+   fprintf(stream, "\t\t\t\t\t\t\t\t%d\n", prof->rl_encode);
+   fprintf(stream, "\t\t\t\t\t\t\t\n");
+
+   fprintf(stream, "\t\t\t\t\t\t\n");
+   fprintf(stream, "\t\t\t\t\t\n");
+}
+
+static
+void print_elem_type(FILE *stream, u8 type)
+{
+   switch (type) {
+   case 1:
+   fprintf(stream, "root");
+   break;
+   case 2:
+   fprintf(stream, "tc");
+   break;
+   case 3:
+   fprintf(stream, "se_generic");
+   break;
+   case 4:
+   fprintf(stream, "entry_point");
+   break;
+   case 5:
+   fprintf(stream, "leaf");
+   break;
+   default:
+   fprintf(stream, "%d", type);
+   break;
+   }
+}
+
+static
+void print_valid_sections(FILE *stream, u8 vs)
+{
+   if ((vs & 0x1) != 0)
+   fprintf(stream, "generic ");
+   if ((vs & 0x2) != 0)
+   fprintf(stream, "cir ");
+   if ((vs & 0x4) != 0)
+   fprintf(stream, "eir ");
+   if ((vs & 0x8) != 0)
+   fprintf(stream, "shared ");
+}
+
+static
+void print_scheduling_mode(FILE *stream, bool flag)
+{
+   if (flag)
+   fprintf(stream, "pps");
+   else
+   fprintf(stream, "bps");
+}
+
+static
+void print_priority_mode(FILE *stream, bool flag)
+{
+   if (flag)
+   fprintf(stream, "single priority node");
+   else
+   fprintf(stream, "wfq");
+}
+
+static
+void print_node(struct ice_aqc_txsched_elem_data *data,
+   struct ice_aqc_rl_profile_elem *cir_prof,
+   struct ice_aqc_rl_profile_elem *eir_prof,
+   struct ice_aqc_rl_profile_elem *shared_prof,
+   bool detail, FILE *stream)
+{
+   if (

[PATCH v2] net/ice: fix link update

2023-12-13 Thread Qi Zhang
The ice_aq_get_link_info function is not thread-safe. However,
it is possible to simultaneous invocations during both the dev_start
and the LSC interrupt handler, potentially leading to unexpected adminq
errors. This patch addresses the issue by introducing a thread-safe
wrapper that utilizes a spinlock.

Fixes: cf911d90e366 ("net/ice: support link update")
Cc: sta...@dpdk.org

Signed-off-by: Qi Zhang 
---
v2:
- fix coding style warning.

 drivers/net/ice/ice_ethdev.c | 26 --
 drivers/net/ice/ice_ethdev.h |  4 
 2 files changed, 24 insertions(+), 6 deletions(-)

diff --git a/drivers/net/ice/ice_ethdev.c b/drivers/net/ice/ice_ethdev.c
index 3ccba4db80..1f8ab5158a 100644
--- a/drivers/net/ice/ice_ethdev.c
+++ b/drivers/net/ice/ice_ethdev.c
@@ -1804,6 +1804,7 @@ ice_pf_setup(struct ice_pf *pf)
}
 
pf->main_vsi = vsi;
+   rte_spinlock_init(&pf->link_lock);
 
return 0;
 }
@@ -3621,17 +3622,31 @@ ice_rxq_intr_setup(struct rte_eth_dev *dev)
return 0;
 }
 
+static enum ice_status
+ice_get_link_info_safe(struct ice_pf *pf, bool ena_lse,
+  struct ice_link_status *link)
+{
+   struct ice_hw *hw = ICE_PF_TO_HW(pf);
+   int ret;
+
+   rte_spinlock_lock(&pf->link_lock);
+
+   ret = ice_aq_get_link_info(hw->port_info, ena_lse, link, NULL);
+
+   rte_spinlock_unlock(&pf->link_lock);
+
+   return ret;
+}
+
 static void
 ice_get_init_link_status(struct rte_eth_dev *dev)
 {
-   struct ice_hw *hw = ICE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
struct ice_pf *pf = ICE_DEV_PRIVATE_TO_PF(dev->data->dev_private);
bool enable_lse = dev->data->dev_conf.intr_conf.lsc ? true : false;
struct ice_link_status link_status;
int ret;
 
-   ret = ice_aq_get_link_info(hw->port_info, enable_lse,
-  &link_status, NULL);
+   ret = ice_get_link_info_safe(pf, enable_lse, &link_status);
if (ret != ICE_SUCCESS) {
PMD_DRV_LOG(ERR, "Failed to get link info");
pf->init_link_up = false;
@@ -3996,7 +4011,7 @@ ice_link_update(struct rte_eth_dev *dev, int 
wait_to_complete)
 {
 #define CHECK_INTERVAL 50  /* 50ms */
 #define MAX_REPEAT_TIME 40  /* 2s (40 * 50ms) in total */
-   struct ice_hw *hw = ICE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+   struct ice_pf *pf = ICE_DEV_PRIVATE_TO_PF(dev->data->dev_private);
struct ice_link_status link_status;
struct rte_eth_link link, old;
int status;
@@ -4010,8 +4025,7 @@ ice_link_update(struct rte_eth_dev *dev, int 
wait_to_complete)
 
do {
/* Get link status information from hardware */
-   status = ice_aq_get_link_info(hw->port_info, enable_lse,
- &link_status, NULL);
+   status = ice_get_link_info_safe(pf, enable_lse, &link_status);
if (status != ICE_SUCCESS) {
link.link_speed = RTE_ETH_SPEED_NUM_100M;
link.link_duplex = RTE_ETH_LINK_FULL_DUPLEX;
diff --git a/drivers/net/ice/ice_ethdev.h b/drivers/net/ice/ice_ethdev.h
index abe6dcdc23..d607f028e0 100644
--- a/drivers/net/ice/ice_ethdev.h
+++ b/drivers/net/ice/ice_ethdev.h
@@ -548,6 +548,10 @@ struct ice_pf {
uint64_t rss_hf;
struct ice_tm_conf tm_conf;
uint16_t outer_ethertype;
+   /* lock prevent race condition between lsc interrupt handler
+* and link status update during dev_start.
+*/
+   rte_spinlock_t link_lock;
 };
 
 #define ICE_MAX_QUEUE_NUM  2048
-- 
2.31.1



[PATCH] net/ice: fix link update

2023-11-28 Thread Qi Zhang
The ice_aq_get_link_info function is not thread-safe. However,
it is possible to simultaneous invocations during both the dev_start
and the LSC interrupt handler, potentially leading to unexpected adminq
errors. This patch addresses the issue by introducing a thread-safe
wrapper that utilizes a spinlock.

Fixes: cf911d90e366 ("net/ice: support link update")
Cc: sta...@dpdk.org

Signed-off-by: Qi Zhang 
---
 drivers/net/ice/ice_ethdev.c | 26 --
 drivers/net/ice/ice_ethdev.h |  3 +++
 2 files changed, 23 insertions(+), 6 deletions(-)

diff --git a/drivers/net/ice/ice_ethdev.c b/drivers/net/ice/ice_ethdev.c
index 3ccba4db80..1f8ab5158a 100644
--- a/drivers/net/ice/ice_ethdev.c
+++ b/drivers/net/ice/ice_ethdev.c
@@ -1804,6 +1804,7 @@ ice_pf_setup(struct ice_pf *pf)
}
 
pf->main_vsi = vsi;
+   rte_spinlock_init(&pf->link_lock);
 
return 0;
 }
@@ -3621,17 +3622,31 @@ ice_rxq_intr_setup(struct rte_eth_dev *dev)
return 0;
 }
 
+static enum ice_status
+ice_get_link_info_safe(struct ice_pf *pf, bool ena_lse,
+  struct ice_link_status *link)
+{
+   struct ice_hw *hw = ICE_PF_TO_HW(pf);
+   int ret;
+
+   rte_spinlock_lock(&pf->link_lock);
+
+   ret = ice_aq_get_link_info(hw->port_info, ena_lse, link, NULL);
+
+   rte_spinlock_unlock(&pf->link_lock);
+
+   return ret;
+}
+
 static void
 ice_get_init_link_status(struct rte_eth_dev *dev)
 {
-   struct ice_hw *hw = ICE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
struct ice_pf *pf = ICE_DEV_PRIVATE_TO_PF(dev->data->dev_private);
bool enable_lse = dev->data->dev_conf.intr_conf.lsc ? true : false;
struct ice_link_status link_status;
int ret;
 
-   ret = ice_aq_get_link_info(hw->port_info, enable_lse,
-  &link_status, NULL);
+   ret = ice_get_link_info_safe(pf, enable_lse, &link_status);
if (ret != ICE_SUCCESS) {
PMD_DRV_LOG(ERR, "Failed to get link info");
pf->init_link_up = false;
@@ -3996,7 +4011,7 @@ ice_link_update(struct rte_eth_dev *dev, int 
wait_to_complete)
 {
 #define CHECK_INTERVAL 50  /* 50ms */
 #define MAX_REPEAT_TIME 40  /* 2s (40 * 50ms) in total */
-   struct ice_hw *hw = ICE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+   struct ice_pf *pf = ICE_DEV_PRIVATE_TO_PF(dev->data->dev_private);
struct ice_link_status link_status;
struct rte_eth_link link, old;
int status;
@@ -4010,8 +4025,7 @@ ice_link_update(struct rte_eth_dev *dev, int 
wait_to_complete)
 
do {
/* Get link status information from hardware */
-   status = ice_aq_get_link_info(hw->port_info, enable_lse,
- &link_status, NULL);
+   status = ice_get_link_info_safe(pf, enable_lse, &link_status);
if (status != ICE_SUCCESS) {
link.link_speed = RTE_ETH_SPEED_NUM_100M;
link.link_duplex = RTE_ETH_LINK_FULL_DUPLEX;
diff --git a/drivers/net/ice/ice_ethdev.h b/drivers/net/ice/ice_ethdev.h
index abe6dcdc23..691893be13 100644
--- a/drivers/net/ice/ice_ethdev.h
+++ b/drivers/net/ice/ice_ethdev.h
@@ -548,6 +548,9 @@ struct ice_pf {
uint64_t rss_hf;
struct ice_tm_conf tm_conf;
uint16_t outer_ethertype;
+   /* lock prevent race condition between lsc interrupt handler
+* and link status update during dev_start */
+   rte_spinlock_t link_lock;
 };
 
 #define ICE_MAX_QUEUE_NUM  2048
-- 
2.31.1



[PATCH] doc: add prog action into default ini

2023-11-05 Thread Qi Zhang
Added prog action into nic feature default.ini.

Fixes: 8f1953f1914d ("ethdev: add flow API for P4-programmable devices")

Signed-off-by: Qi Zhang 
---
 doc/guides/nics/features/default.ini | 1 +
 1 file changed, 1 insertion(+)

diff --git a/doc/guides/nics/features/default.ini 
b/doc/guides/nics/features/default.ini
index e41a97b3bb..806cb033ff 100644
--- a/doc/guides/nics/features/default.ini
+++ b/doc/guides/nics/features/default.ini
@@ -188,6 +188,7 @@ passthru =
 pf   =
 port_id  =
 port_representor =
+prog =
 queue=
 quota=
 raw_decap=
-- 
2.31.1



[PATCH] doc: add prog action into default ini

2023-11-05 Thread Qi Zhang
Added prog action into nic feature default.ini.

Fixes: 8f1953f1914d ("ethdev: add flow API for P4-programmable devices")

Signed-off-by: Qi Zhang 
---
 doc/guides/nics/features/default.ini | 1 +
 1 file changed, 1 insertion(+)

diff --git a/doc/guides/nics/features/default.ini 
b/doc/guides/nics/features/default.ini
index e41a97b3bb..806cb033ff 100644
--- a/doc/guides/nics/features/default.ini
+++ b/doc/guides/nics/features/default.ini
@@ -188,6 +188,7 @@ passthru =
 pf   =
 port_id  =
 port_representor =
+prog =
 queue=
 quota=
 raw_decap=
-- 
2.31.1



[PATCH] doc: add prog action into default ini

2023-11-05 Thread Qi Zhang
Added prog action into nic feature default.ini.

Fixes: 8f1953f1914d ("ethdev: add flow API for P4-programmable devices")

Signed-off-by: Qi Zhang 
---
 doc/guides/nics/features/default.ini | 1 +
 1 file changed, 1 insertion(+)

diff --git a/doc/guides/nics/features/default.ini 
b/doc/guides/nics/features/default.ini
index e41a97b3bb..806cb033ff 100644
--- a/doc/guides/nics/features/default.ini
+++ b/doc/guides/nics/features/default.ini
@@ -188,6 +188,7 @@ passthru =
 pf   =
 port_id  =
 port_representor =
+prog =
 queue=
 quota=
 raw_decap=
-- 
2.31.1



[PATCH v2] net/ice: fix Tx preparation

2023-11-01 Thread Qi Zhang
1. Check nb_segs > 8 for NO TSO case
2. Check nb_segs > Tx ring size for TSO case
3. report nb_mtu_seg_max and nb_seg_max in dev_info.

Fixes: 17c7d0f9d6a4 ("net/ice: support basic Rx/Tx")
Cc: sta...@dpdk.org

Signed-off-by: Qi Zhang 
---
 drivers/net/ice/ice_ethdev.c |  2 ++
 drivers/net/ice/ice_rxtx.c   | 18 --
 drivers/net/ice/ice_rxtx.h   |  2 ++
 3 files changed, 20 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ice/ice_ethdev.c b/drivers/net/ice/ice_ethdev.c
index 6ef06b9926..3ccba4db80 100644
--- a/drivers/net/ice/ice_ethdev.c
+++ b/drivers/net/ice/ice_ethdev.c
@@ -3918,6 +3918,8 @@ ice_dev_info_get(struct rte_eth_dev *dev, struct 
rte_eth_dev_info *dev_info)
.nb_max = ICE_MAX_RING_DESC,
.nb_min = ICE_MIN_RING_DESC,
.nb_align = ICE_ALIGN_RING_DESC,
+   .nb_mtu_seg_max = ICE_TX_MTU_SEG_MAX,
+   .nb_seg_max = ICE_MAX_RING_DESC,
};
 
dev_info->speed_capa = RTE_ETH_LINK_SPEED_10M |
diff --git a/drivers/net/ice/ice_rxtx.c b/drivers/net/ice/ice_rxtx.c
index ee9cb7b955..73e47ae92d 100644
--- a/drivers/net/ice/ice_rxtx.c
+++ b/drivers/net/ice/ice_rxtx.c
@@ -3679,7 +3679,7 @@ ice_check_empty_mbuf(struct rte_mbuf *tx_pkt)
 }
 
 uint16_t
-ice_prep_pkts(__rte_unused void *tx_queue, struct rte_mbuf **tx_pkts,
+ice_prep_pkts(void *tx_queue, struct rte_mbuf **tx_pkts,
  uint16_t nb_pkts)
 {
int i, ret;
@@ -3690,9 +3690,23 @@ ice_prep_pkts(__rte_unused void *tx_queue, struct 
rte_mbuf **tx_pkts,
m = tx_pkts[i];
ol_flags = m->ol_flags;
 
-   if (ol_flags & RTE_MBUF_F_TX_TCP_SEG &&
+   if (!(ol_flags & RTE_MBUF_F_TX_TCP_SEG) &&
+   /**
+* No TSO case: nb->segs, pkt_len to not exceed
+* the limites.
+*/
+   (m->nb_segs > ICE_TX_MTU_SEG_MAX ||
+m->pkt_len > ICE_FRAME_SIZE_MAX)) {
+   rte_errno = EINVAL;
+   return i;
+   } else if (ol_flags & RTE_MBUF_F_TX_TCP_SEG &&
+   /** TSO case: tso_segsz, nb_segs, pkt_len not exceed
+* the limits.
+*/
(m->tso_segsz < ICE_MIN_TSO_MSS ||
 m->tso_segsz > ICE_MAX_TSO_MSS ||
+m->nb_segs >
+   ((struct ice_tx_queue *)tx_queue)->nb_tx_desc ||
 m->pkt_len > ICE_MAX_TSO_FRAME_SIZE)) {
/**
 * MSS outside the range are considered malicious
diff --git a/drivers/net/ice/ice_rxtx.h b/drivers/net/ice/ice_rxtx.h
index 268289716e..bd2c4abec9 100644
--- a/drivers/net/ice/ice_rxtx.h
+++ b/drivers/net/ice/ice_rxtx.h
@@ -56,6 +56,8 @@ extern int ice_timestamp_dynfield_offset;
 
 #define ICE_HEADER_SPLIT_ENA   BIT(0)
 
+#define ICE_TX_MTU_SEG_MAX 8
+
 typedef void (*ice_rx_release_mbufs_t)(struct ice_rx_queue *rxq);
 typedef void (*ice_tx_release_mbufs_t)(struct ice_tx_queue *txq);
 typedef void (*ice_rxd_to_pkt_fields_t)(struct ice_rx_queue *rxq,
-- 
2.31.1



[PATCH] net/iavf: fix Tx preparation

2023-11-01 Thread Qi Zhang
1. check nb_segs > Tx ring size for TSO case.
2. report nb_mtu_seg_max and nb_seg_max in dev_info.

Fixes: a2b29a7733ef ("net/avf: enable basic Rx Tx")
Cc: sta...@dpdk.org

Signed-off-by: Qi Zhang 
---
 drivers/net/iavf/iavf_ethdev.c | 2 ++
 drivers/net/iavf/iavf_rxtx.c   | 3 ++-
 2 files changed, 4 insertions(+), 1 deletion(-)

diff --git a/drivers/net/iavf/iavf_ethdev.c b/drivers/net/iavf/iavf_ethdev.c
index 98cc5c8ea8..0c6ab4ac5a 100644
--- a/drivers/net/iavf/iavf_ethdev.c
+++ b/drivers/net/iavf/iavf_ethdev.c
@@ -1207,6 +1207,8 @@ iavf_dev_info_get(struct rte_eth_dev *dev, struct 
rte_eth_dev_info *dev_info)
.nb_max = IAVF_MAX_RING_DESC,
.nb_min = IAVF_MIN_RING_DESC,
.nb_align = IAVF_ALIGN_RING_DESC,
+   .nb_mtu_seg_max = IAVF_TX_MAX_MTU_SEG,
+   .nb_seg_max = IAVF_MAX_RING_DESC,
};
 
dev_info->err_handle_mode = RTE_ETH_ERROR_HANDLE_MODE_PASSIVE;
diff --git a/drivers/net/iavf/iavf_rxtx.c b/drivers/net/iavf/iavf_rxtx.c
index 610912f635..45f638c1d2 100644
--- a/drivers/net/iavf/iavf_rxtx.c
+++ b/drivers/net/iavf/iavf_rxtx.c
@@ -3656,7 +3656,8 @@ iavf_prep_pkts(__rte_unused void *tx_queue, struct 
rte_mbuf **tx_pkts,
return i;
}
} else if ((m->tso_segsz < IAVF_MIN_TSO_MSS) ||
-  (m->tso_segsz > IAVF_MAX_TSO_MSS)) {
+  (m->tso_segsz > IAVF_MAX_TSO_MSS) ||
+  (m->nb_segs > txq->nb_tx_desc)) {
/* MSS outside the range are considered malicious */
rte_errno = EINVAL;
return i;
-- 
2.31.1



[PATCH] net/ice: fix Tx Prepareation

2023-11-01 Thread Qi Zhang
1. Check nb_segs > 8 for NO TSO case
2. Check nb_segs > Tx ring size for TSO case
3. report nb_mtu_seg_max and nb_seg_max in dev_info.

Fixes: 17c7d0f9d6a4 ("net/ice: support basic Rx/Tx")
Cc: sta...@dpdk.org

Signed-off-by: Qi Zhang 
---
 drivers/net/ice/ice_ethdev.c |  2 ++
 drivers/net/ice/ice_rxtx.c   | 16 +++-
 drivers/net/ice/ice_rxtx.h   |  2 ++
 3 files changed, 19 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ice/ice_ethdev.c b/drivers/net/ice/ice_ethdev.c
index 6ef06b9926..3ccba4db80 100644
--- a/drivers/net/ice/ice_ethdev.c
+++ b/drivers/net/ice/ice_ethdev.c
@@ -3918,6 +3918,8 @@ ice_dev_info_get(struct rte_eth_dev *dev, struct 
rte_eth_dev_info *dev_info)
.nb_max = ICE_MAX_RING_DESC,
.nb_min = ICE_MIN_RING_DESC,
.nb_align = ICE_ALIGN_RING_DESC,
+   .nb_mtu_seg_max = ICE_TX_MTU_SEG_MAX,
+   .nb_seg_max = ICE_MAX_RING_DESC,
};
 
dev_info->speed_capa = RTE_ETH_LINK_SPEED_10M |
diff --git a/drivers/net/ice/ice_rxtx.c b/drivers/net/ice/ice_rxtx.c
index ee9cb7b955..868ee59933 100644
--- a/drivers/net/ice/ice_rxtx.c
+++ b/drivers/net/ice/ice_rxtx.c
@@ -3690,9 +3690,23 @@ ice_prep_pkts(__rte_unused void *tx_queue, struct 
rte_mbuf **tx_pkts,
m = tx_pkts[i];
ol_flags = m->ol_flags;
 
-   if (ol_flags & RTE_MBUF_F_TX_TCP_SEG &&
+   if (!(ol_flags & RTE_MBUF_F_TX_TCP_SEG) &&
+   /**
+* No TSO case: nb->segs, pkt_len to not exceed
+* the limites.
+*/
+   (m->nb_segs > ICE_TX_MTU_SEG_MAX ||
+m->pkt_len > ICE_FRAME_SIZE_MAX)) {
+   rte_errno = EINVAL;
+   return i;
+   } else if (ol_flags & RTE_MBUF_F_TX_TCP_SEG &&
+   /** TSO case: tso_segsz, nb_segs, pkt_len not exceed
+* the limits.
+*/
(m->tso_segsz < ICE_MIN_TSO_MSS ||
 m->tso_segsz > ICE_MAX_TSO_MSS ||
+m->nb_segs >
+   ((struct ice_tx_queue *)tx_queue)->nb_tx_desc ||
 m->pkt_len > ICE_MAX_TSO_FRAME_SIZE)) {
/**
 * MSS outside the range are considered malicious
diff --git a/drivers/net/ice/ice_rxtx.h b/drivers/net/ice/ice_rxtx.h
index 268289716e..bd2c4abec9 100644
--- a/drivers/net/ice/ice_rxtx.h
+++ b/drivers/net/ice/ice_rxtx.h
@@ -56,6 +56,8 @@ extern int ice_timestamp_dynfield_offset;
 
 #define ICE_HEADER_SPLIT_ENA   BIT(0)
 
+#define ICE_TX_MTU_SEG_MAX 8
+
 typedef void (*ice_rx_release_mbufs_t)(struct ice_rx_queue *rxq);
 typedef void (*ice_tx_release_mbufs_t)(struct ice_tx_queue *txq);
 typedef void (*ice_rxd_to_pkt_fields_t)(struct ice_rx_queue *rxq,
-- 
2.31.1



[PATCH v6] app/testpmd: enable cli for programmable action

2023-10-10 Thread Qi Zhang
Parsing command line for rte_flow_action_prog.

Syntax:

"prog name  [arguments   \
   ... end]"

Use parse_string0 to parse name string.
Use parse_hex to parse hex string.
Use struct action_prog_data to store parsed result.

Example:

Action with 2 arguments:

"prog name action0 arguments field0 03FF field1 55AA end"

Action without argument:

"prog name action1"

Signed-off-by: Qi Zhang 
---
v6:
- fix typo.

v5:
- complete testpmd document.

v4:
- be more generous on the max size of name and value.

v3:
- refine struct action_prog_data
- enlarge the max size

v2:
- fix title
- minor coding style refine.

 app/test-pmd/cmdline_flow.c | 232 
 doc/guides/testpmd_app_ug/testpmd_funcs.rst |  17 ++
 2 files changed, 249 insertions(+)

diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c
index 70eef3e34d..d9152f9485 100644
--- a/app/test-pmd/cmdline_flow.c
+++ b/app/test-pmd/cmdline_flow.c
@@ -721,6 +721,13 @@ enum index {
ACTION_IPV6_EXT_PUSH,
ACTION_IPV6_EXT_PUSH_INDEX,
ACTION_IPV6_EXT_PUSH_INDEX_VALUE,
+   ACTION_PROG,
+   ACTION_PROG_NAME,
+   ACTION_PROG_NAME_STRING,
+   ACTION_PROG_ARGUMENTS,
+   ACTION_PROG_ARG_NAME,
+   ACTION_PROG_ARG_VALUE,
+   ACTION_PROG_ARG_END,
 };
 
 /** Maximum size for pattern in struct rte_flow_item_raw. */
@@ -751,6 +758,23 @@ struct action_rss_data {
uint16_t queue[ACTION_RSS_QUEUE_NUM];
 };
 
+#define ACTION_PROG_NAME_SIZE_MAX 256
+#define ACTION_PROG_ARG_NUM_MAX 16
+#define ACTION_PROG_ARG_VALUE_SIZE_MAX 64
+
+/** Storage for struct rte_flow_action_prog including external data. */
+struct action_prog_data {
+   struct rte_flow_action_prog conf;
+   struct {
+   char name[ACTION_PROG_NAME_SIZE_MAX];
+   struct rte_flow_action_prog_argument 
args[ACTION_PROG_ARG_NUM_MAX];
+   struct {
+   char names[ACTION_PROG_NAME_SIZE_MAX];
+   uint8_t value[ACTION_PROG_ARG_VALUE_SIZE_MAX];
+   } arg_data[ACTION_PROG_ARG_NUM_MAX];
+   } data;
+};
+
 /** Maximum data size in struct rte_flow_action_raw_encap. */
 #define ACTION_RAW_ENCAP_MAX_DATA 512
 #define RAW_ENCAP_CONFS_MAX_NUM 8
@@ -2178,6 +2202,7 @@ static const enum index next_action[] = {
ACTION_QUOTA_QU,
ACTION_IPV6_EXT_REMOVE,
ACTION_IPV6_EXT_PUSH,
+   ACTION_PROG,
ZERO,
 };
 
@@ -2519,6 +2544,13 @@ static const enum index action_represented_port[] = {
ZERO,
 };
 
+static const enum index action_prog[] = {
+   ACTION_PROG_NAME,
+   ACTION_PROG_ARGUMENTS,
+   ACTION_NEXT,
+   ZERO,
+};
+
 static int parse_set_raw_encap_decap(struct context *, const struct token *,
 const char *, unsigned int,
 void *, unsigned int);
@@ -2795,6 +2827,18 @@ static int
 parse_qu_mode_name(struct context *ctx, const struct token *token,
   const char *str, unsigned int len, void *buf,
   unsigned int size);
+static int
+parse_vc_action_prog(struct context *, const struct token *,
+const char *, unsigned int, void *,
+unsigned int);
+static int
+parse_vc_action_prog_arg_name(struct context *, const struct token *,
+ const char *, unsigned int, void *,
+ unsigned int);
+static int
+parse_vc_action_prog_arg_value(struct context *, const struct token *,
+  const char *, unsigned int, void *,
+  unsigned int);
 static int comp_none(struct context *, const struct token *,
 unsigned int, char *, unsigned int);
 static int comp_boolean(struct context *, const struct token *,
@@ -7543,6 +7587,48 @@ static const struct token token_list[] = {
.args = ARGS(ARGS_ENTRY(struct rte_flow_item_tx_queue,
tx_queue)),
},
+   [ACTION_PROG] = {
+   .name = "prog",
+   .help = "match a programmable action",
+   .priv = PRIV_ACTION(PROG, sizeof(struct action_prog_data)),
+   .next = NEXT(action_prog),
+   .call = parse_vc_action_prog,
+   },
+   [ACTION_PROG_NAME] = {
+   .name = "name",
+   .help = "programble action name",
+   .next = NEXT(action_prog, NEXT_ENTRY(ACTION_PROG_NAME_STRING)),
+   .args = ARGS(ARGS_ENTRY(struct action_prog_data, data.name)),
+   },
+   [ACTION_PROG_NAME_STRING] = {
+   .name = "{string}",
+   .type = "STRING",
+   .help = "programmable action name string",
+   .call = parse_string0,
+   },
+   [ACTION_PROG_ARGUMENTS] = {
+   .name = "arguments&q

[PATCH v5] app/testpmd: enable cli for programmable action

2023-10-10 Thread Qi Zhang
Parsing command line for rte_flow_action_prog.

Syntax:

"prog name  [arguments   \
   ... end]"

Use parse_string0 to parse name string.
Use parse_hex to parse hex string.
Use struct action_prog_data to store parsed result.

Example:

Action with 2 arguments:

"prog name action0 arguments field0 03FF field1 55AA end"

Action without argument:

"prog name action1"

Signed-off-by: Qi Zhang 
---
v5:
- complete testpmd document.

v4:
- be more generous on the max size of name and value.

v3:
- refine struct action_prog_data
- enlarge the max size

v2:
- fix title
- minor coding style refine.

 app/test-pmd/cmdline_flow.c | 232 
 doc/guides/testpmd_app_ug/testpmd_funcs.rst |  17 ++
 2 files changed, 249 insertions(+)

diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c
index 70eef3e34d..d9152f9485 100644
--- a/app/test-pmd/cmdline_flow.c
+++ b/app/test-pmd/cmdline_flow.c
@@ -721,6 +721,13 @@ enum index {
ACTION_IPV6_EXT_PUSH,
ACTION_IPV6_EXT_PUSH_INDEX,
ACTION_IPV6_EXT_PUSH_INDEX_VALUE,
+   ACTION_PROG,
+   ACTION_PROG_NAME,
+   ACTION_PROG_NAME_STRING,
+   ACTION_PROG_ARGUMENTS,
+   ACTION_PROG_ARG_NAME,
+   ACTION_PROG_ARG_VALUE,
+   ACTION_PROG_ARG_END,
 };
 
 /** Maximum size for pattern in struct rte_flow_item_raw. */
@@ -751,6 +758,23 @@ struct action_rss_data {
uint16_t queue[ACTION_RSS_QUEUE_NUM];
 };
 
+#define ACTION_PROG_NAME_SIZE_MAX 256
+#define ACTION_PROG_ARG_NUM_MAX 16
+#define ACTION_PROG_ARG_VALUE_SIZE_MAX 64
+
+/** Storage for struct rte_flow_action_prog including external data. */
+struct action_prog_data {
+   struct rte_flow_action_prog conf;
+   struct {
+   char name[ACTION_PROG_NAME_SIZE_MAX];
+   struct rte_flow_action_prog_argument 
args[ACTION_PROG_ARG_NUM_MAX];
+   struct {
+   char names[ACTION_PROG_NAME_SIZE_MAX];
+   uint8_t value[ACTION_PROG_ARG_VALUE_SIZE_MAX];
+   } arg_data[ACTION_PROG_ARG_NUM_MAX];
+   } data;
+};
+
 /** Maximum data size in struct rte_flow_action_raw_encap. */
 #define ACTION_RAW_ENCAP_MAX_DATA 512
 #define RAW_ENCAP_CONFS_MAX_NUM 8
@@ -2178,6 +2202,7 @@ static const enum index next_action[] = {
ACTION_QUOTA_QU,
ACTION_IPV6_EXT_REMOVE,
ACTION_IPV6_EXT_PUSH,
+   ACTION_PROG,
ZERO,
 };
 
@@ -2519,6 +2544,13 @@ static const enum index action_represented_port[] = {
ZERO,
 };
 
+static const enum index action_prog[] = {
+   ACTION_PROG_NAME,
+   ACTION_PROG_ARGUMENTS,
+   ACTION_NEXT,
+   ZERO,
+};
+
 static int parse_set_raw_encap_decap(struct context *, const struct token *,
 const char *, unsigned int,
 void *, unsigned int);
@@ -2795,6 +2827,18 @@ static int
 parse_qu_mode_name(struct context *ctx, const struct token *token,
   const char *str, unsigned int len, void *buf,
   unsigned int size);
+static int
+parse_vc_action_prog(struct context *, const struct token *,
+const char *, unsigned int, void *,
+unsigned int);
+static int
+parse_vc_action_prog_arg_name(struct context *, const struct token *,
+ const char *, unsigned int, void *,
+ unsigned int);
+static int
+parse_vc_action_prog_arg_value(struct context *, const struct token *,
+  const char *, unsigned int, void *,
+  unsigned int);
 static int comp_none(struct context *, const struct token *,
 unsigned int, char *, unsigned int);
 static int comp_boolean(struct context *, const struct token *,
@@ -7543,6 +7587,48 @@ static const struct token token_list[] = {
.args = ARGS(ARGS_ENTRY(struct rte_flow_item_tx_queue,
tx_queue)),
},
+   [ACTION_PROG] = {
+   .name = "prog",
+   .help = "match a programmable action",
+   .priv = PRIV_ACTION(PROG, sizeof(struct action_prog_data)),
+   .next = NEXT(action_prog),
+   .call = parse_vc_action_prog,
+   },
+   [ACTION_PROG_NAME] = {
+   .name = "name",
+   .help = "programble action name",
+   .next = NEXT(action_prog, NEXT_ENTRY(ACTION_PROG_NAME_STRING)),
+   .args = ARGS(ARGS_ENTRY(struct action_prog_data, data.name)),
+   },
+   [ACTION_PROG_NAME_STRING] = {
+   .name = "{string}",
+   .type = "STRING",
+   .help = "programmable action name string",
+   .call = parse_string0,
+   },
+   [ACTION_PROG_ARGUMENTS] = {
+   .name = "arguments&q

[PATCH v4] app/testpmd: enable cli for programmable action

2023-10-06 Thread Qi Zhang
Parsing command line for rte_flow_action_prog.

Syntax:

"prog name  [arguments   \
   ... end]"

Use parse_string0 to parse name string.
Use parse_hex to parse hex string.
Use struct action_prog_data to store parsed result.

Example:

Action with 2 arguments:

"prog name action0 arguments field0 03FF field1 55AA end"

Action without argument:

"prog name action1"

Signed-off-by: Qi Zhang 
---

v4:
- be more generous on the max size of name and value.

v3:
- refine struct action_prog_data
- enlarge the max size

v2:
- fix title
- minor coding style refine.

 app/test-pmd/cmdline_flow.c | 232 
 1 file changed, 232 insertions(+)

diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c
index 21828c144c..ae5556e704 100644
--- a/app/test-pmd/cmdline_flow.c
+++ b/app/test-pmd/cmdline_flow.c
@@ -719,6 +719,13 @@ enum index {
ACTION_IPV6_EXT_PUSH,
ACTION_IPV6_EXT_PUSH_INDEX,
ACTION_IPV6_EXT_PUSH_INDEX_VALUE,
+   ACTION_PROG,
+   ACTION_PROG_NAME,
+   ACTION_PROG_NAME_STRING,
+   ACTION_PROG_ARGUMENTS,
+   ACTION_PROG_ARG_NAME,
+   ACTION_PROG_ARG_VALUE,
+   ACTION_PROG_ARG_END,
 };
 
 /** Maximum size for pattern in struct rte_flow_item_raw. */
@@ -749,6 +756,23 @@ struct action_rss_data {
uint16_t queue[ACTION_RSS_QUEUE_NUM];
 };
 
+#define ACTION_PROG_NAME_SIZE_MAX 256
+#define ACTION_PROG_ARG_NUM_MAX 16
+#define ACTION_PROG_ARG_VALUE_SIZE_MAX 64
+
+/** Storage for struct rte_flow_action_prog including external data. */
+struct action_prog_data {
+   struct rte_flow_action_prog conf;
+   struct {
+   char name[ACTION_PROG_NAME_SIZE_MAX];
+   struct rte_flow_action_prog_argument 
args[ACTION_PROG_ARG_NUM_MAX];
+   struct {
+   char names[ACTION_PROG_NAME_SIZE_MAX];
+   uint8_t value[ACTION_PROG_ARG_VALUE_SIZE_MAX];
+   } arg_data[ACTION_PROG_ARG_NUM_MAX];
+   } data;
+};
+
 /** Maximum data size in struct rte_flow_action_raw_encap. */
 #define ACTION_RAW_ENCAP_MAX_DATA 512
 #define RAW_ENCAP_CONFS_MAX_NUM 8
@@ -2169,6 +2193,7 @@ static const enum index next_action[] = {
ACTION_QUOTA_QU,
ACTION_IPV6_EXT_REMOVE,
ACTION_IPV6_EXT_PUSH,
+   ACTION_PROG,
ZERO,
 };
 
@@ -2510,6 +2535,13 @@ static const enum index action_represented_port[] = {
ZERO,
 };
 
+static const enum index action_prog[] = {
+   ACTION_PROG_NAME,
+   ACTION_PROG_ARGUMENTS,
+   ACTION_NEXT,
+   ZERO,
+};
+
 static int parse_set_raw_encap_decap(struct context *, const struct token *,
 const char *, unsigned int,
 void *, unsigned int);
@@ -2786,6 +2818,18 @@ static int
 parse_qu_mode_name(struct context *ctx, const struct token *token,
   const char *str, unsigned int len, void *buf,
   unsigned int size);
+static int
+parse_vc_action_prog(struct context *, const struct token *,
+const char *, unsigned int, void *,
+unsigned int);
+static int
+parse_vc_action_prog_arg_name(struct context *, const struct token *,
+ const char *, unsigned int, void *,
+ unsigned int);
+static int
+parse_vc_action_prog_arg_value(struct context *, const struct token *,
+  const char *, unsigned int, void *,
+  unsigned int);
 static int comp_none(struct context *, const struct token *,
 unsigned int, char *, unsigned int);
 static int comp_boolean(struct context *, const struct token *,
@@ -7518,6 +7562,48 @@ static const struct token token_list[] = {
.args = ARGS(ARGS_ENTRY(struct rte_flow_item_tx_queue,
tx_queue)),
},
+   [ACTION_PROG] = {
+   .name = "prog",
+   .help = "match a programmable action",
+   .priv = PRIV_ACTION(PROG, sizeof(struct action_prog_data)),
+   .next = NEXT(action_prog),
+   .call = parse_vc_action_prog,
+   },
+   [ACTION_PROG_NAME] = {
+   .name = "name",
+   .help = "programble action name",
+   .next = NEXT(action_prog, NEXT_ENTRY(ACTION_PROG_NAME_STRING)),
+   .args = ARGS(ARGS_ENTRY(struct action_prog_data, data.name)),
+   },
+   [ACTION_PROG_NAME_STRING] = {
+   .name = "{string}",
+   .type = "STRING",
+   .help = "programmable action name string",
+   .call = parse_string0,
+   },
+   [ACTION_PROG_ARGUMENTS] = {
+   .name = "arguments",
+   .help = "programmable action name",
+   .next = NEXT(action_

[PATCH v3] app/testpmd: enable cli for programmable action

2023-10-05 Thread Qi Zhang
Parsing command line for rte_flow_action_prog.

Syntax:

"prog name  [arguments   \
   ... end]"

Use parse_string0 to parse name string.
Use parse_hex to parse hex string.
Use struct action_prog_data to store parsed result.

Example:

Action with 2 arguments:

"prog name action0 arguments field0 03FF field1 55AA end"

Action without argument:

"prog name action1"

Signed-off-by: Qi Zhang 
---

v3:
- refine struct action_prog_data
- enlarge the max size

v2:
- fix title
- minor coding style refine.

 app/test-pmd/cmdline_flow.c | 232 
 1 file changed, 232 insertions(+)

diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c
index 21828c144c..7b40b988ae 100644
--- a/app/test-pmd/cmdline_flow.c
+++ b/app/test-pmd/cmdline_flow.c
@@ -719,6 +719,13 @@ enum index {
ACTION_IPV6_EXT_PUSH,
ACTION_IPV6_EXT_PUSH_INDEX,
ACTION_IPV6_EXT_PUSH_INDEX_VALUE,
+   ACTION_PROG,
+   ACTION_PROG_NAME,
+   ACTION_PROG_NAME_STRING,
+   ACTION_PROG_ARGUMENTS,
+   ACTION_PROG_ARG_NAME,
+   ACTION_PROG_ARG_VALUE,
+   ACTION_PROG_ARG_END,
 };
 
 /** Maximum size for pattern in struct rte_flow_item_raw. */
@@ -749,6 +756,23 @@ struct action_rss_data {
uint16_t queue[ACTION_RSS_QUEUE_NUM];
 };
 
+#define ACTION_PROG_NAME_SIZE_MAX 32
+#define ACTION_PROG_ARG_NUM_MAX 16
+#define ACTION_PROG_ARG_VALUE_SIZE_MAX 32
+
+/** Storage for struct rte_flow_action_prog including external data. */
+struct action_prog_data {
+   struct rte_flow_action_prog conf;
+   struct {
+   char name[ACTION_PROG_NAME_SIZE_MAX];
+   struct rte_flow_action_prog_argument 
args[ACTION_PROG_ARG_NUM_MAX];
+   struct {
+   char names[ACTION_PROG_NAME_SIZE_MAX];
+   uint8_t value[ACTION_PROG_ARG_VALUE_SIZE_MAX];
+   } arg_data[ACTION_PROG_ARG_NUM_MAX];
+   } data;
+};
+
 /** Maximum data size in struct rte_flow_action_raw_encap. */
 #define ACTION_RAW_ENCAP_MAX_DATA 512
 #define RAW_ENCAP_CONFS_MAX_NUM 8
@@ -2169,6 +2193,7 @@ static const enum index next_action[] = {
ACTION_QUOTA_QU,
ACTION_IPV6_EXT_REMOVE,
ACTION_IPV6_EXT_PUSH,
+   ACTION_PROG,
ZERO,
 };
 
@@ -2510,6 +2535,13 @@ static const enum index action_represented_port[] = {
ZERO,
 };
 
+static const enum index action_prog[] = {
+   ACTION_PROG_NAME,
+   ACTION_PROG_ARGUMENTS,
+   ACTION_NEXT,
+   ZERO,
+};
+
 static int parse_set_raw_encap_decap(struct context *, const struct token *,
 const char *, unsigned int,
 void *, unsigned int);
@@ -2786,6 +2818,18 @@ static int
 parse_qu_mode_name(struct context *ctx, const struct token *token,
   const char *str, unsigned int len, void *buf,
   unsigned int size);
+static int
+parse_vc_action_prog(struct context *, const struct token *,
+const char *, unsigned int, void *,
+unsigned int);
+static int
+parse_vc_action_prog_arg_name(struct context *, const struct token *,
+ const char *, unsigned int, void *,
+ unsigned int);
+static int
+parse_vc_action_prog_arg_value(struct context *, const struct token *,
+  const char *, unsigned int, void *,
+  unsigned int);
 static int comp_none(struct context *, const struct token *,
 unsigned int, char *, unsigned int);
 static int comp_boolean(struct context *, const struct token *,
@@ -7518,6 +7562,48 @@ static const struct token token_list[] = {
.args = ARGS(ARGS_ENTRY(struct rte_flow_item_tx_queue,
tx_queue)),
},
+   [ACTION_PROG] = {
+   .name = "prog",
+   .help = "match a programmable action",
+   .priv = PRIV_ACTION(PROG, sizeof(struct action_prog_data)),
+   .next = NEXT(action_prog),
+   .call = parse_vc_action_prog,
+   },
+   [ACTION_PROG_NAME] = {
+   .name = "name",
+   .help = "programble action name",
+   .next = NEXT(action_prog, NEXT_ENTRY(ACTION_PROG_NAME_STRING)),
+   .args = ARGS(ARGS_ENTRY(struct action_prog_data, data.name)),
+   },
+   [ACTION_PROG_NAME_STRING] = {
+   .name = "{string}",
+   .type = "STRING",
+   .help = "programmable action name string",
+   .call = parse_string0,
+   },
+   [ACTION_PROG_ARGUMENTS] = {
+   .name = "arguments",
+   .help = "programmable action name",
+   .next = NEXT(action_prog, NEXT_ENTRY(ACTION_PROG_ARG_NAME)

[PATCH v2] app/testpmd: enable cli for programmable action

2023-10-04 Thread Qi Zhang
Parsing command line for rte_flow_action_prog.

Syntax:

"prog name  [arguments   \
   ... end]"

Use parse_string0 to parse name string.
Use parse_hex to parse hex string.
Use struct action_prog_data to store parsed result.

Example:

Action with 2 arguments:

"prog name action0 arguments field0 03FF field1 55AA end"

Action without argument:

"prog name action1"

Signed-off-by: Qi Zhang 
---

v2:
- fix title
- minor coding style refine.

 app/test-pmd/cmdline_flow.c | 230 
 1 file changed, 230 insertions(+)

diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c
index 21828c144c..c11b756360 100644
--- a/app/test-pmd/cmdline_flow.c
+++ b/app/test-pmd/cmdline_flow.c
@@ -719,6 +719,13 @@ enum index {
ACTION_IPV6_EXT_PUSH,
ACTION_IPV6_EXT_PUSH_INDEX,
ACTION_IPV6_EXT_PUSH_INDEX_VALUE,
+   ACTION_PROG,
+   ACTION_PROG_NAME,
+   ACTION_PROG_NAME_STRING,
+   ACTION_PROG_ARGUMENTS,
+   ACTION_PROG_ARG_NAME,
+   ACTION_PROG_ARG_VALUE,
+   ACTION_PROG_ARG_END,
 };
 
 /** Maximum size for pattern in struct rte_flow_item_raw. */
@@ -749,6 +756,19 @@ struct action_rss_data {
uint16_t queue[ACTION_RSS_QUEUE_NUM];
 };
 
+#define ACTION_PROG_NAME_SIZE_MAX 32
+#define ACTION_PROG_ARG_NUM_MAX 8
+#define ACTION_PROG_ARG_VALUE_SIZE_MAX 16
+
+/** Storage for struct rte_flow_action_prog including external data. */
+struct action_prog_data {
+   struct rte_flow_action_prog conf;
+   char name[ACTION_PROG_NAME_SIZE_MAX];
+   struct rte_flow_action_prog_argument args[ACTION_PROG_ARG_NUM_MAX];
+   char arg_names[ACTION_PROG_ARG_NUM_MAX][ACTION_PROG_NAME_SIZE_MAX];
+   uint8_t value[ACTION_PROG_ARG_NUM_MAX][ACTION_PROG_ARG_VALUE_SIZE_MAX];
+};
+
 /** Maximum data size in struct rte_flow_action_raw_encap. */
 #define ACTION_RAW_ENCAP_MAX_DATA 512
 #define RAW_ENCAP_CONFS_MAX_NUM 8
@@ -2169,6 +2189,7 @@ static const enum index next_action[] = {
ACTION_QUOTA_QU,
ACTION_IPV6_EXT_REMOVE,
ACTION_IPV6_EXT_PUSH,
+   ACTION_PROG,
ZERO,
 };
 
@@ -2510,6 +2531,13 @@ static const enum index action_represented_port[] = {
ZERO,
 };
 
+static const enum index action_prog[] = {
+   ACTION_PROG_NAME,
+   ACTION_PROG_ARGUMENTS,
+   ACTION_NEXT,
+   ZERO,
+};
+
 static int parse_set_raw_encap_decap(struct context *, const struct token *,
 const char *, unsigned int,
 void *, unsigned int);
@@ -2786,6 +2814,18 @@ static int
 parse_qu_mode_name(struct context *ctx, const struct token *token,
   const char *str, unsigned int len, void *buf,
   unsigned int size);
+static int
+parse_vc_action_prog(struct context *, const struct token *,
+const char *, unsigned int, void *,
+unsigned int);
+static int
+parse_vc_action_prog_arg_name(struct context *, const struct token *,
+ const char *, unsigned int, void *,
+ unsigned int);
+static int
+parse_vc_action_prog_arg_value(struct context *, const struct token *,
+  const char *, unsigned int, void *,
+  unsigned int);
 static int comp_none(struct context *, const struct token *,
 unsigned int, char *, unsigned int);
 static int comp_boolean(struct context *, const struct token *,
@@ -7518,6 +7558,48 @@ static const struct token token_list[] = {
.args = ARGS(ARGS_ENTRY(struct rte_flow_item_tx_queue,
tx_queue)),
},
+   [ACTION_PROG] = {
+   .name = "prog",
+   .help = "match a programmable action",
+   .priv = PRIV_ACTION(PROG, sizeof(struct action_prog_data)),
+   .next = NEXT(action_prog),
+   .call = parse_vc_action_prog,
+   },
+   [ACTION_PROG_NAME] = {
+   .name = "name",
+   .help = "programble action name",
+   .next = NEXT(action_prog, NEXT_ENTRY(ACTION_PROG_NAME_STRING)),
+   .args = ARGS(ARGS_ENTRY(struct action_prog_data, name)),
+   },
+   [ACTION_PROG_NAME_STRING] = {
+   .name = "{string}",
+   .type = "STRING",
+   .help = "programmable action name string",
+   .call = parse_string0,
+   },
+   [ACTION_PROG_ARGUMENTS] = {
+   .name = "arguments",
+   .help = "programmable action name",
+   .next = NEXT(action_prog, NEXT_ENTRY(ACTION_PROG_ARG_NAME)),
+   .call = parse_vc_conf,
+   },
+   [ACTION_PROG_ARG_NAME] = {
+   .name = "{string}",
+   .help = "programmable action

[PATCH 1/2] app/testpmd: enable cli for programmable action

2023-10-04 Thread Qi Zhang
Parsing command line for rte_flow_action_prog.

Syntax:

"prog name  [arguments   \
   ... end]"

Use parse_string0 to parse name string.
Use parse_hex to parse hex string.
Use struct action_prog_data to store parsed result.

Example:

Action with 2 arguments:

"prog name action0 arguments field0 03FF field1 55AA end"

Action without argument:

"prog name action1"

Signed-off-by: Qi Zhang 
---
 app/test-pmd/cmdline_flow.c | 223 
 1 file changed, 223 insertions(+)

diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c
index 21828c144c..028cff0150 100644
--- a/app/test-pmd/cmdline_flow.c
+++ b/app/test-pmd/cmdline_flow.c
@@ -719,6 +719,13 @@ enum index {
ACTION_IPV6_EXT_PUSH,
ACTION_IPV6_EXT_PUSH_INDEX,
ACTION_IPV6_EXT_PUSH_INDEX_VALUE,
+   ACTION_PROG,
+   ACTION_PROG_NAME,
+   ACTION_PROG_NAME_STRING,
+   ACTION_PROG_ARGUMENTS,
+   ACTION_PROG_ARG_NAME,
+   ACTION_PROG_ARG_VALUE,
+   ACTION_PROG_ARG_END,
 };
 
 /** Maximum size for pattern in struct rte_flow_item_raw. */
@@ -749,6 +756,19 @@ struct action_rss_data {
uint16_t queue[ACTION_RSS_QUEUE_NUM];
 };
 
+#define ACTION_PROG_NAME_SIZE_MAX 32
+#define ACTION_PROG_ARG_NUM_MAX 8
+#define ACTION_PROG_ARG_VALUE_SIZE_MAX 16
+
+/** Storage for struct rte_flow_action_prog including external data. */
+struct action_prog_data {
+   struct rte_flow_action_prog conf;
+   char name[ACTION_PROG_NAME_SIZE_MAX];
+   struct rte_flow_action_prog_argument args[ACTION_PROG_ARG_NUM_MAX];
+   char arg_names[ACTION_PROG_ARG_NUM_MAX][ACTION_PROG_NAME_SIZE_MAX];
+   uint8_t value[ACTION_PROG_ARG_NUM_MAX][ACTION_PROG_ARG_VALUE_SIZE_MAX];
+};
+
 /** Maximum data size in struct rte_flow_action_raw_encap. */
 #define ACTION_RAW_ENCAP_MAX_DATA 512
 #define RAW_ENCAP_CONFS_MAX_NUM 8
@@ -2169,6 +2189,7 @@ static const enum index next_action[] = {
ACTION_QUOTA_QU,
ACTION_IPV6_EXT_REMOVE,
ACTION_IPV6_EXT_PUSH,
+   ACTION_PROG,
ZERO,
 };
 
@@ -2510,6 +2531,13 @@ static const enum index action_represented_port[] = {
ZERO,
 };
 
+static const enum index action_prog[] = {
+   ACTION_PROG_NAME,
+   ACTION_PROG_ARGUMENTS,
+   ACTION_NEXT,
+   ZERO,
+};
+
 static int parse_set_raw_encap_decap(struct context *, const struct token *,
 const char *, unsigned int,
 void *, unsigned int);
@@ -2786,6 +2814,18 @@ static int
 parse_qu_mode_name(struct context *ctx, const struct token *token,
   const char *str, unsigned int len, void *buf,
   unsigned int size);
+static int
+parse_vc_action_prog(struct context *, const struct token *,
+const char *, unsigned int, void *,
+unsigned int);
+static int
+parse_vc_action_prog_arg_name(struct context *, const struct token *,
+ const char *, unsigned int, void *,
+ unsigned int);
+static int
+parse_vc_action_prog_arg_value(struct context *, const struct token *,
+  const char *, unsigned int, void *,
+  unsigned int);
 static int comp_none(struct context *, const struct token *,
 unsigned int, char *, unsigned int);
 static int comp_boolean(struct context *, const struct token *,
@@ -7518,6 +7558,48 @@ static const struct token token_list[] = {
.args = ARGS(ARGS_ENTRY(struct rte_flow_item_tx_queue,
tx_queue)),
},
+   [ACTION_PROG] = {
+   .name = "prog",
+   .help = "match a programmable action",
+   .priv = PRIV_ACTION(PROG, sizeof(struct action_prog_data)),
+   .next = NEXT(action_prog),
+   .call = parse_vc_action_prog,
+   },
+   [ACTION_PROG_NAME] = {
+   .name = "name",
+   .help = "programble action name",
+   .next = NEXT(action_prog, NEXT_ENTRY(ACTION_PROG_NAME_STRING)),
+   .args = ARGS(ARGS_ENTRY(struct action_prog_data, name)),
+   },
+   [ACTION_PROG_NAME_STRING] = {
+   .name = "{string}",
+   .type = "STRING",
+   .help = "programmable action name string",
+   .call = parse_string0,
+   },
+   [ACTION_PROG_ARGUMENTS] = {
+   .name = "arguments",
+   .help = "programmable action name",
+   .next = NEXT(action_prog, NEXT_ENTRY(ACTION_PROG_ARG_NAME)),
+   .call = parse_vc_conf,
+   },
+   [ACTION_PROG_ARG_NAME] = {
+   .name = "{string}",
+   .help = "programmable action argument name",
+   .next

[PATCH v5 5/5] doc: add generic flow doc for ice PMD

2023-09-25 Thread Qi Zhang
Add some document about how to use rte_flow on ice PMD.

Signed-off-by: Qi Zhang 
---
 doc/guides/nics/ice.rst | 45 +
 1 file changed, 45 insertions(+)

diff --git a/doc/guides/nics/ice.rst b/doc/guides/nics/ice.rst
index 5a47109c3f..b36a4c260a 100644
--- a/doc/guides/nics/ice.rst
+++ b/doc/guides/nics/ice.rst
@@ -301,6 +301,51 @@ The DCF PMD needs to advertise and acquire DCF capability 
which allows DCF to
 send AdminQ commands that it would like to execute over to the PF and receive
 responses for the same from PF.
 
+Generic Flow Support
+
+
+The ice PMD provides support for the Generic Flow API (RTE_FLOW), enabling
+users to offload various flow classification tasks to the E810 NIC.
+The E810 NIC's  packet processing pipeline consists of the following stages:
+
+Switch: Supports exact match and limited wildcard matching with a large flow
+capacity.
+
+ACL: Supports wildcard matching with a smaller flow capacity (DCF mode only).
+
+FDIR: Supports exact match with a large flow capacity (PF mode only).
+
+Hash: Supports RSS (PF mode only)
+
+The ice PMD utilizes the ice_flow_engine structure to represent each of these
+stages and leverages the rte_flow rule's ``group`` attribute for selecting the
+appropriate engine for Switch, ACL, and FDIR operations:
+
+Group 0 maps to Switch
+Group 1 maps to ACL
+Group 2 maps to FDIR
+
+In the case of RSS, it will only be selected if a ``RTE_FLOW_ACTION_RSS`` 
action
+is targeted to no queue group, and the group attribute is ignored.
+
+For each engine, a list of supported patterns is maintained in a global array
+named ``ice__supported_pattern``. The Ice PMD will reject any rule with
+a pattern that is not included in the supported list.
+
+One notable feature is the ice PMD's ability to leverage the Raw pattern,
+enabling protocol-agnostic flow offloading. Here is an example of creating
+a rule that matches an IPv4 destination address of 1.2.3.4 and redirects it to
+queue 3 using a raw pattern:
+
+flow create 0 ingress group 2 pattern raw \
+pattern spec \
+080045144000401001020304 \
+pattern mask \
+ \
+end actions queue index 3 / mark id 3 / end
+
+Currently, raw pattern support is limited to the FDIR and Hash engines.
+
 Additional Options
 ++
 
-- 
2.31.1



[PATCH v5 4/5] net/ice: refine supported flow pattern name

2023-09-25 Thread Qi Zhang
Unified the supported pattern array name as
ice__supported_pattern.

Signed-off-by: Qi Zhang 
---
 drivers/net/ice/ice_acl_filter.c| 6 +++---
 drivers/net/ice/ice_fdir_filter.c   | 6 +++---
 drivers/net/ice/ice_switch_filter.c | 6 +++---
 3 files changed, 9 insertions(+), 9 deletions(-)

diff --git a/drivers/net/ice/ice_acl_filter.c b/drivers/net/ice/ice_acl_filter.c
index e507bb927a..63a525b363 100644
--- a/drivers/net/ice/ice_acl_filter.c
+++ b/drivers/net/ice/ice_acl_filter.c
@@ -47,7 +47,7 @@ struct acl_rule {
 };
 
 static struct
-ice_pattern_match_item ice_acl_pattern[] = {
+ice_pattern_match_item ice_acl_supported_pattern[] = {
{pattern_eth_ipv4,  ICE_ACL_INSET_ETH_IPV4, ICE_INSET_NONE, 
ICE_INSET_NONE},
{pattern_eth_ipv4_udp,  ICE_ACL_INSET_ETH_IPV4_UDP, ICE_INSET_NONE, 
ICE_INSET_NONE},
{pattern_eth_ipv4_tcp,  ICE_ACL_INSET_ETH_IPV4_TCP, ICE_INSET_NONE, 
ICE_INSET_NONE},
@@ -1050,8 +1050,8 @@ ice_flow_engine ice_acl_engine = {
 struct
 ice_flow_parser ice_acl_parser = {
.engine = &ice_acl_engine,
-   .array = ice_acl_pattern,
-   .array_len = RTE_DIM(ice_acl_pattern),
+   .array = ice_acl_supported_pattern,
+   .array_len = RTE_DIM(ice_acl_supported_pattern),
.parse_pattern_action = ice_acl_parse,
.stage = ICE_FLOW_STAGE_DISTRIBUTOR,
 };
diff --git a/drivers/net/ice/ice_fdir_filter.c 
b/drivers/net/ice/ice_fdir_filter.c
index 6afcdf5376..0b7920ad44 100644
--- a/drivers/net/ice/ice_fdir_filter.c
+++ b/drivers/net/ice/ice_fdir_filter.c
@@ -106,7 +106,7 @@
ICE_INSET_IPV6_SRC | ICE_INSET_IPV6_DST | \
ICE_INSET_NAT_T_ESP_SPI)
 
-static struct ice_pattern_match_item ice_fdir_pattern_list[] = {
+static struct ice_pattern_match_item ice_fdir_supported_pattern[] = {
{pattern_raw,   ICE_INSET_NONE, 
ICE_INSET_NONE, ICE_INSET_NONE},
{pattern_ethertype, ICE_FDIR_INSET_ETH, 
ICE_INSET_NONE, ICE_INSET_NONE},
{pattern_eth_ipv4,  
ICE_FDIR_INSET_ETH_IPV4,ICE_INSET_NONE, ICE_INSET_NONE},
@@ -2494,8 +2494,8 @@ ice_fdir_parse(struct ice_adapter *ad,
 
 struct ice_flow_parser ice_fdir_parser = {
.engine = &ice_fdir_engine,
-   .array = ice_fdir_pattern_list,
-   .array_len = RTE_DIM(ice_fdir_pattern_list),
+   .array = ice_fdir_supported_pattern,
+   .array_len = RTE_DIM(ice_fdir_supported_pattern),
.parse_pattern_action = ice_fdir_parse,
.stage = ICE_FLOW_STAGE_DISTRIBUTOR,
 };
diff --git a/drivers/net/ice/ice_switch_filter.c 
b/drivers/net/ice/ice_switch_filter.c
index 8f29326762..122b87f625 100644
--- a/drivers/net/ice/ice_switch_filter.c
+++ b/drivers/net/ice/ice_switch_filter.c
@@ -202,7 +202,7 @@ struct ice_switch_filter_conf {
 };
 
 static struct
-ice_pattern_match_item ice_switch_pattern_dist_list[] = {
+ice_pattern_match_item ice_switch_supported_pattern[] = {
{pattern_any,   ICE_INSET_NONE, 
ICE_INSET_NONE, ICE_INSET_NONE},
{pattern_ethertype, ICE_SW_INSET_ETHER, 
ICE_INSET_NONE, ICE_INSET_NONE},
{pattern_ethertype_vlan,ICE_SW_INSET_MAC_VLAN,  
ICE_INSET_NONE, ICE_INSET_NONE},
@@ -2075,8 +2075,8 @@ ice_flow_engine ice_switch_engine = {
 struct
 ice_flow_parser ice_switch_parser = {
.engine = &ice_switch_engine,
-   .array = ice_switch_pattern_dist_list,
-   .array_len = RTE_DIM(ice_switch_pattern_dist_list),
+   .array = ice_switch_supported_pattern,
+   .array_len = RTE_DIM(ice_switch_supported_pattern),
.parse_pattern_action = ice_switch_parse_pattern_action,
.stage = ICE_FLOW_STAGE_DISTRIBUTOR,
 };
-- 
2.31.1



[PATCH v5 3/5] net/ice: map group to pipeline stage

2023-09-25 Thread Qi Zhang
Mapping rte_flow_attr->group to a specific hardware stage.

Group 0 -> switch filter
Group 1 -> acl filter (dcf mode only)
Group 2 -> fdir filter (pf mode only)

For RSS, it will only be selected if there is a RTE_FLOW_ACTION_RSS
action target no queue group and the group ID is ignored.

Since each flow parser will be selected based on the group, there is no
need to maintain a separate 'parser list' or related APIs for
registering/unregistering parsers.

Signed-off-by: Qi Zhang 
---
 drivers/net/ice/ice_acl_filter.c|  13 +-
 drivers/net/ice/ice_ethdev.h|   2 -
 drivers/net/ice/ice_fdir_filter.c   |  19 +--
 drivers/net/ice/ice_generic_flow.c  | 242 +---
 drivers/net/ice/ice_generic_flow.h  |   9 +-
 drivers/net/ice/ice_hash.c  |  16 +-
 drivers/net/ice/ice_switch_filter.c |  13 +-
 7 files changed, 91 insertions(+), 223 deletions(-)

diff --git a/drivers/net/ice/ice_acl_filter.c b/drivers/net/ice/ice_acl_filter.c
index 51f4feced4..e507bb927a 100644
--- a/drivers/net/ice/ice_acl_filter.c
+++ b/drivers/net/ice/ice_acl_filter.c
@@ -41,8 +41,6 @@
ICE_ACL_INSET_ETH_IPV4 | \
ICE_INSET_SCTP_SRC_PORT | ICE_INSET_SCTP_DST_PORT)
 
-static struct ice_flow_parser ice_acl_parser;
-
 struct acl_rule {
enum ice_fltr_ptype flow_type;
uint64_t entry_id[4];
@@ -993,7 +991,6 @@ ice_acl_init(struct ice_adapter *ad)
int ret = 0;
struct ice_pf *pf = &ad->pf;
struct ice_hw *hw = ICE_PF_TO_HW(pf);
-   struct ice_flow_parser *parser = &ice_acl_parser;
 
ret = ice_acl_prof_alloc(hw);
if (ret) {
@@ -1010,11 +1007,7 @@ ice_acl_init(struct ice_adapter *ad)
if (ret)
return ret;
 
-   ret = ice_acl_prof_init(pf);
-   if (ret)
-   return ret;
-
-   return ice_register_parser(parser, ad);
+   return ice_acl_prof_init(pf);
 }
 
 static void
@@ -1037,10 +1030,8 @@ ice_acl_uninit(struct ice_adapter *ad)
 {
struct ice_pf *pf = &ad->pf;
struct ice_hw *hw = ICE_PF_TO_HW(pf);
-   struct ice_flow_parser *parser = &ice_acl_parser;
 
if (ad->hw.dcf_enabled) {
-   ice_unregister_parser(parser, ad);
ice_deinit_acl(pf);
ice_acl_prof_free(hw);
}
@@ -1056,7 +1047,7 @@ ice_flow_engine ice_acl_engine = {
.type = ICE_FLOW_ENGINE_ACL,
 };
 
-static struct
+struct
 ice_flow_parser ice_acl_parser = {
.engine = &ice_acl_engine,
.array = ice_acl_pattern,
diff --git a/drivers/net/ice/ice_ethdev.h b/drivers/net/ice/ice_ethdev.h
index 1f88becd19..abe6dcdc23 100644
--- a/drivers/net/ice/ice_ethdev.h
+++ b/drivers/net/ice/ice_ethdev.h
@@ -541,8 +541,6 @@ struct ice_pf {
bool adapter_stopped;
struct ice_flow_list flow_list;
rte_spinlock_t flow_ops_lock;
-   struct ice_parser_list rss_parser_list;
-   struct ice_parser_list dist_parser_list;
bool init_link_up;
uint64_t old_rx_bytes;
uint64_t old_tx_bytes;
diff --git a/drivers/net/ice/ice_fdir_filter.c 
b/drivers/net/ice/ice_fdir_filter.c
index bc43883a92..6afcdf5376 100644
--- a/drivers/net/ice/ice_fdir_filter.c
+++ b/drivers/net/ice/ice_fdir_filter.c
@@ -137,8 +137,6 @@ static struct ice_pattern_match_item 
ice_fdir_pattern_list[] = {
{pattern_eth_ipv6_gtpu_eh,  
ICE_FDIR_INSET_IPV6_GTPU_EH,ICE_FDIR_INSET_IPV6_GTPU_EH,ICE_INSET_NONE},
 };
 
-static struct ice_flow_parser ice_fdir_parser;
-
 static int
 ice_fdir_is_tunnel_profile(enum ice_fdir_tunnel_type tunnel_type);
 
@@ -1147,31 +1145,18 @@ static int
 ice_fdir_init(struct ice_adapter *ad)
 {
struct ice_pf *pf = &ad->pf;
-   struct ice_flow_parser *parser;
-   int ret;
-
-   ret = ice_fdir_setup(pf);
-   if (ret)
-   return ret;
-
-   parser = &ice_fdir_parser;
 
-   return ice_register_parser(parser, ad);
+   return ice_fdir_setup(pf);
 }
 
 static void
 ice_fdir_uninit(struct ice_adapter *ad)
 {
-   struct ice_flow_parser *parser;
struct ice_pf *pf = &ad->pf;
 
if (ad->hw.dcf_enabled)
return;
 
-   parser = &ice_fdir_parser;
-
-   ice_unregister_parser(parser, ad);
-
ice_fdir_teardown(pf);
 }
 
@@ -2507,7 +2492,7 @@ ice_fdir_parse(struct ice_adapter *ad,
return ret;
 }
 
-static struct ice_flow_parser ice_fdir_parser = {
+struct ice_flow_parser ice_fdir_parser = {
.engine = &ice_fdir_engine,
.array = ice_fdir_pattern_list,
.array_len = RTE_DIM(ice_fdir_pattern_list),
diff --git a/drivers/net/ice/ice_generic_flow.c 
b/drivers/net/ice/ice_generic_flow.c
index 6695457bbd..50d760004f 100644
--- a/drivers/net/ice/ice_generic_flow.c
+++ b/drivers/net/ice/ice_generic_flow.c
@@ -1793,15 +1793,13 @@ enum rte_flow_item_type pattern_eth_ipv6_pfcp[] = {
RTE_FLOW_ITEM_TYPE_END,
 };

[PATCH v5 2/5] net/ice: refine flow engine disabling

2023-09-25 Thread Qi Zhang
Only "disable_engine_mask" for flow engine disabling

In PF mode, only ACL engine will be disabled.
In DCF mode, FDIR and HASH engine will be disabled.
In DCF mode with "acl=off", ACL engine will also be
disabled.

Signed-off-by: Qi Zhang 
---
 drivers/net/ice/ice_acl_filter.c  | 3 ---
 drivers/net/ice/ice_dcf_parent.c  | 3 +++
 drivers/net/ice/ice_ethdev.c  | 1 +
 drivers/net/ice/ice_fdir_filter.c | 3 ---
 drivers/net/ice/ice_hash.c| 3 ---
 5 files changed, 4 insertions(+), 9 deletions(-)

diff --git a/drivers/net/ice/ice_acl_filter.c b/drivers/net/ice/ice_acl_filter.c
index f2ddbd7b9b..51f4feced4 100644
--- a/drivers/net/ice/ice_acl_filter.c
+++ b/drivers/net/ice/ice_acl_filter.c
@@ -995,9 +995,6 @@ ice_acl_init(struct ice_adapter *ad)
struct ice_hw *hw = ICE_PF_TO_HW(pf);
struct ice_flow_parser *parser = &ice_acl_parser;
 
-   if (!ad->hw.dcf_enabled)
-   return 0;
-
ret = ice_acl_prof_alloc(hw);
if (ret) {
PMD_DRV_LOG(ERR, "Cannot allocate memory for "
diff --git a/drivers/net/ice/ice_dcf_parent.c b/drivers/net/ice/ice_dcf_parent.c
index 173ed9f81d..6e845f458a 100644
--- a/drivers/net/ice/ice_dcf_parent.c
+++ b/drivers/net/ice/ice_dcf_parent.c
@@ -474,6 +474,9 @@ ice_dcf_init_parent_adapter(struct rte_eth_dev *eth_dev)
if (ice_devargs_check(eth_dev->device->devargs, ICE_DCF_DEVARG_ACL))
parent_adapter->disabled_engine_mask |= 
BIT(ICE_FLOW_ENGINE_ACL);
 
+   parent_adapter->disabled_engine_mask |= BIT(ICE_FLOW_ENGINE_FDIR);
+   parent_adapter->disabled_engine_mask |= BIT(ICE_FLOW_ENGINE_HASH);
+
err = ice_flow_init(parent_adapter);
if (err) {
PMD_INIT_LOG(ERR, "Failed to initialize flow");
diff --git a/drivers/net/ice/ice_ethdev.c b/drivers/net/ice/ice_ethdev.c
index 036b068c22..f744bde8f4 100644
--- a/drivers/net/ice/ice_ethdev.c
+++ b/drivers/net/ice/ice_ethdev.c
@@ -2442,6 +2442,7 @@ ice_dev_init(struct rte_eth_dev *dev)
}
 
if (!ad->is_safe_mode) {
+   ad->disabled_engine_mask |= BIT(ICE_FLOW_ENGINE_ACL);
ret = ice_flow_init(ad);
if (ret) {
PMD_INIT_LOG(ERR, "Failed to initialize flow");
diff --git a/drivers/net/ice/ice_fdir_filter.c 
b/drivers/net/ice/ice_fdir_filter.c
index e9ee5a57d6..bc43883a92 100644
--- a/drivers/net/ice/ice_fdir_filter.c
+++ b/drivers/net/ice/ice_fdir_filter.c
@@ -1150,9 +1150,6 @@ ice_fdir_init(struct ice_adapter *ad)
struct ice_flow_parser *parser;
int ret;
 
-   if (ad->hw.dcf_enabled)
-   return 0;
-
ret = ice_fdir_setup(pf);
if (ret)
return ret;
diff --git a/drivers/net/ice/ice_hash.c b/drivers/net/ice/ice_hash.c
index e36e7da2b5..37bee808c6 100644
--- a/drivers/net/ice/ice_hash.c
+++ b/drivers/net/ice/ice_hash.c
@@ -591,9 +591,6 @@ ice_hash_init(struct ice_adapter *ad)
 {
struct ice_flow_parser *parser = NULL;
 
-   if (ad->hw.dcf_enabled)
-   return 0;
-
parser = &ice_hash_parser;
 
return ice_register_parser(parser, ad);
-- 
2.31.1



[PATCH v5 1/5] net/ice: remove pipeline mode

2023-09-25 Thread Qi Zhang
This marks the initial phase of refactoring the ice rte_flow
implementation.

The combination of switch and fdir rules within the same syntax has led
to inconvenient user experiences. Naturally, the switch filter and fdir
filter represent distinct pipeline stages with differing hardware
capabilities.

To address this, we have made the decision to assign each stage to a
separate rte_flow group. This will allow users to clearly specify their
intentions when creating a rule. Consequently, the need for a pipeline
mode can be removed.

Signed-off-by: Qi Zhang 
---
 doc/guides/nics/ice.rst |  19 -
 drivers/net/ice/ice_ethdev.c|   8 --
 drivers/net/ice/ice_ethdev.h|   2 -
 drivers/net/ice/ice_fdir_filter.c   |   2 +-
 drivers/net/ice/ice_generic_flow.c  | 120 
 drivers/net/ice/ice_generic_flow.h  |   6 +-
 drivers/net/ice/ice_switch_filter.c | 118 +--
 7 files changed, 40 insertions(+), 235 deletions(-)

diff --git a/doc/guides/nics/ice.rst b/doc/guides/nics/ice.rst
index c351c6bd74..5a47109c3f 100644
--- a/doc/guides/nics/ice.rst
+++ b/doc/guides/nics/ice.rst
@@ -90,25 +90,6 @@ Runtime Configuration
   NOTE: In Safe mode, only very limited features are available, features like 
RSS,
   checksum, fdir, tunneling ... are all disabled.
 
-- ``Generic Flow Pipeline Mode Support`` (default ``0``)
-
-  In pipeline mode, a flow can be set at one specific stage by setting 
parameter
-  ``priority``. Currently, we support two stages: priority = 0 or !0. Flows 
with
-  priority 0 located at the first pipeline stage which typically be used as a 
firewall
-  to drop the packet on a blocklist(we called it permission stage). At this 
stage,
-  flow rules are created for the device's exact match engine: switch. Flows 
with priority
-  !0 located at the second stage, typically packets are classified here and be 
steered to
-  specific queue or queue group (we called it distribution stage), At this 
stage, flow
-  rules are created for device's flow director engine.
-  For none-pipeline mode, ``priority`` is ignored, a flow rule can be created 
as a flow director
-  rule or a switch rule depends on its pattern/action and the resource 
allocation situation,
-  all flows are virtually at the same pipeline stage.
-  By default, generic flow API is enabled in none-pipeline mode, user can 
choose to
-  use pipeline mode by setting ``devargs`` parameter ``pipeline-mode-support``,
-  for example::
-
--a 80:00.0,pipeline-mode-support=1
-
 - ``Default MAC Disable`` (default ``0``)
 
   Disable the default MAC make the device drop all packets by default,
diff --git a/drivers/net/ice/ice_ethdev.c b/drivers/net/ice/ice_ethdev.c
index 4bad39c2c1..036b068c22 100644
--- a/drivers/net/ice/ice_ethdev.c
+++ b/drivers/net/ice/ice_ethdev.c
@@ -27,7 +27,6 @@
 
 /* devargs */
 #define ICE_SAFE_MODE_SUPPORT_ARG "safe-mode-support"
-#define ICE_PIPELINE_MODE_SUPPORT_ARG  "pipeline-mode-support"
 #define ICE_DEFAULT_MAC_DISABLE   "default-mac-disable"
 #define ICE_PROTO_XTR_ARG "proto_xtr"
 #define ICE_FIELD_OFFS_ARG   "field_offs"
@@ -43,7 +42,6 @@ int ice_timestamp_dynfield_offset = -1;
 
 static const char * const ice_valid_args[] = {
ICE_SAFE_MODE_SUPPORT_ARG,
-   ICE_PIPELINE_MODE_SUPPORT_ARG,
ICE_PROTO_XTR_ARG,
ICE_FIELD_OFFS_ARG,
ICE_FIELD_NAME_ARG,
@@ -2103,11 +2101,6 @@ static int ice_parse_devargs(struct rte_eth_dev *dev)
if (ret)
goto bail;
 
-   ret = rte_kvargs_process(kvlist, ICE_PIPELINE_MODE_SUPPORT_ARG,
-&parse_bool, &ad->devargs.pipe_mode_support);
-   if (ret)
-   goto bail;
-
ret = rte_kvargs_process(kvlist, ICE_DEFAULT_MAC_DISABLE,
&parse_bool, &ad->devargs.default_mac_disable);
if (ret)
@@ -6549,7 +6542,6 @@ RTE_PMD_REGISTER_PARAM_STRING(net_ice,
  ICE_HW_DEBUG_MASK_ARG "=0xXXX"
  ICE_PROTO_XTR_ARG 
"=[queue:]"
  ICE_SAFE_MODE_SUPPORT_ARG "=<0|1>"
- ICE_PIPELINE_MODE_SUPPORT_ARG "=<0|1>"
  ICE_DEFAULT_MAC_DISABLE "=<0|1>"
  ICE_RX_LOW_LATENCY_ARG "=<0|1>");
 
diff --git a/drivers/net/ice/ice_ethdev.h b/drivers/net/ice/ice_ethdev.h
index 9789cb8525..1f88becd19 100644
--- a/drivers/net/ice/ice_ethdev.h
+++ b/drivers/net/ice/ice_ethdev.h
@@ -542,7 +542,6 @@ struct ice_pf {
struct ice_flow_list flow_list;
rte_spinlock_t flow_ops_lock;
struct ice_parser_list rss_parser_list;
-   struct ice_parser_list perm_parser_list;
struct ice_parser_list dist_parser_list;
bool init_link_up;

[PATCH v5 0/5] net/ice: refactor rte_flow

2023-09-25 Thread Qi Zhang
1. remove pipeline mode
2. apply group to hardware pipeline stage static mapping
3. add genenic flow document

v5:
- remove incorrect group attr check in ice_flow_valid_attr

v4:
- fix error handling when target engine was disabled.

v3:
- fix the issue when acl=off on dcf mode
- refine the disabled engine handling
- unified the supported pattern variable name
- add document

v2:
- fix segment fault when an uninitialized engine has been selected.

Qi Zhang (5):
  net/ice: remove pipeline mode
  net/ice: refine flow engine disabling
  net/ice: map group to pipeline stage
  net/ice: refine supported flow pattern name
  doc: add generic flow doc for ice PMD

 doc/guides/nics/ice.rst |  64 --
 drivers/net/ice/ice_acl_filter.c|  22 +-
 drivers/net/ice/ice_dcf_parent.c|   3 +
 drivers/net/ice/ice_ethdev.c|   9 +-
 drivers/net/ice/ice_ethdev.h|   4 -
 drivers/net/ice/ice_fdir_filter.c   |  30 +--
 drivers/net/ice/ice_generic_flow.c  | 302 +++-
 drivers/net/ice/ice_generic_flow.h  |  15 +-
 drivers/net/ice/ice_hash.c  |  19 +-
 drivers/net/ice/ice_switch_filter.c | 133 +---
 10 files changed, 157 insertions(+), 444 deletions(-)

-- 
2.31.1



[PATCH v4 4/5] net/ice: refine supported flow pattern name

2023-09-24 Thread Qi Zhang
Unified the supported pattern array name as
ice__supported_pattern.

Signed-off-by: Qi Zhang 
---
 drivers/net/ice/ice_acl_filter.c| 6 +++---
 drivers/net/ice/ice_fdir_filter.c   | 6 +++---
 drivers/net/ice/ice_switch_filter.c | 6 +++---
 3 files changed, 9 insertions(+), 9 deletions(-)

diff --git a/drivers/net/ice/ice_acl_filter.c b/drivers/net/ice/ice_acl_filter.c
index e507bb927a..63a525b363 100644
--- a/drivers/net/ice/ice_acl_filter.c
+++ b/drivers/net/ice/ice_acl_filter.c
@@ -47,7 +47,7 @@ struct acl_rule {
 };
 
 static struct
-ice_pattern_match_item ice_acl_pattern[] = {
+ice_pattern_match_item ice_acl_supported_pattern[] = {
{pattern_eth_ipv4,  ICE_ACL_INSET_ETH_IPV4, ICE_INSET_NONE, 
ICE_INSET_NONE},
{pattern_eth_ipv4_udp,  ICE_ACL_INSET_ETH_IPV4_UDP, ICE_INSET_NONE, 
ICE_INSET_NONE},
{pattern_eth_ipv4_tcp,  ICE_ACL_INSET_ETH_IPV4_TCP, ICE_INSET_NONE, 
ICE_INSET_NONE},
@@ -1050,8 +1050,8 @@ ice_flow_engine ice_acl_engine = {
 struct
 ice_flow_parser ice_acl_parser = {
.engine = &ice_acl_engine,
-   .array = ice_acl_pattern,
-   .array_len = RTE_DIM(ice_acl_pattern),
+   .array = ice_acl_supported_pattern,
+   .array_len = RTE_DIM(ice_acl_supported_pattern),
.parse_pattern_action = ice_acl_parse,
.stage = ICE_FLOW_STAGE_DISTRIBUTOR,
 };
diff --git a/drivers/net/ice/ice_fdir_filter.c 
b/drivers/net/ice/ice_fdir_filter.c
index 6afcdf5376..0b7920ad44 100644
--- a/drivers/net/ice/ice_fdir_filter.c
+++ b/drivers/net/ice/ice_fdir_filter.c
@@ -106,7 +106,7 @@
ICE_INSET_IPV6_SRC | ICE_INSET_IPV6_DST | \
ICE_INSET_NAT_T_ESP_SPI)
 
-static struct ice_pattern_match_item ice_fdir_pattern_list[] = {
+static struct ice_pattern_match_item ice_fdir_supported_pattern[] = {
{pattern_raw,   ICE_INSET_NONE, 
ICE_INSET_NONE, ICE_INSET_NONE},
{pattern_ethertype, ICE_FDIR_INSET_ETH, 
ICE_INSET_NONE, ICE_INSET_NONE},
{pattern_eth_ipv4,  
ICE_FDIR_INSET_ETH_IPV4,ICE_INSET_NONE, ICE_INSET_NONE},
@@ -2494,8 +2494,8 @@ ice_fdir_parse(struct ice_adapter *ad,
 
 struct ice_flow_parser ice_fdir_parser = {
.engine = &ice_fdir_engine,
-   .array = ice_fdir_pattern_list,
-   .array_len = RTE_DIM(ice_fdir_pattern_list),
+   .array = ice_fdir_supported_pattern,
+   .array_len = RTE_DIM(ice_fdir_supported_pattern),
.parse_pattern_action = ice_fdir_parse,
.stage = ICE_FLOW_STAGE_DISTRIBUTOR,
 };
diff --git a/drivers/net/ice/ice_switch_filter.c 
b/drivers/net/ice/ice_switch_filter.c
index 8f29326762..122b87f625 100644
--- a/drivers/net/ice/ice_switch_filter.c
+++ b/drivers/net/ice/ice_switch_filter.c
@@ -202,7 +202,7 @@ struct ice_switch_filter_conf {
 };
 
 static struct
-ice_pattern_match_item ice_switch_pattern_dist_list[] = {
+ice_pattern_match_item ice_switch_supported_pattern[] = {
{pattern_any,   ICE_INSET_NONE, 
ICE_INSET_NONE, ICE_INSET_NONE},
{pattern_ethertype, ICE_SW_INSET_ETHER, 
ICE_INSET_NONE, ICE_INSET_NONE},
{pattern_ethertype_vlan,ICE_SW_INSET_MAC_VLAN,  
ICE_INSET_NONE, ICE_INSET_NONE},
@@ -2075,8 +2075,8 @@ ice_flow_engine ice_switch_engine = {
 struct
 ice_flow_parser ice_switch_parser = {
.engine = &ice_switch_engine,
-   .array = ice_switch_pattern_dist_list,
-   .array_len = RTE_DIM(ice_switch_pattern_dist_list),
+   .array = ice_switch_supported_pattern,
+   .array_len = RTE_DIM(ice_switch_supported_pattern),
.parse_pattern_action = ice_switch_parse_pattern_action,
.stage = ICE_FLOW_STAGE_DISTRIBUTOR,
 };
-- 
2.31.1



[PATCH v4 5/5] doc: add generic flow doc for ice PMD

2023-09-24 Thread Qi Zhang
Add some document about how to use rte_flow on ice PMD.

Signed-off-by: Qi Zhang 
---
 doc/guides/nics/ice.rst | 45 +
 1 file changed, 45 insertions(+)

diff --git a/doc/guides/nics/ice.rst b/doc/guides/nics/ice.rst
index 5a47109c3f..b36a4c260a 100644
--- a/doc/guides/nics/ice.rst
+++ b/doc/guides/nics/ice.rst
@@ -301,6 +301,51 @@ The DCF PMD needs to advertise and acquire DCF capability 
which allows DCF to
 send AdminQ commands that it would like to execute over to the PF and receive
 responses for the same from PF.
 
+Generic Flow Support
+
+
+The ice PMD provides support for the Generic Flow API (RTE_FLOW), enabling
+users to offload various flow classification tasks to the E810 NIC.
+The E810 NIC's  packet processing pipeline consists of the following stages:
+
+Switch: Supports exact match and limited wildcard matching with a large flow
+capacity.
+
+ACL: Supports wildcard matching with a smaller flow capacity (DCF mode only).
+
+FDIR: Supports exact match with a large flow capacity (PF mode only).
+
+Hash: Supports RSS (PF mode only)
+
+The ice PMD utilizes the ice_flow_engine structure to represent each of these
+stages and leverages the rte_flow rule's ``group`` attribute for selecting the
+appropriate engine for Switch, ACL, and FDIR operations:
+
+Group 0 maps to Switch
+Group 1 maps to ACL
+Group 2 maps to FDIR
+
+In the case of RSS, it will only be selected if a ``RTE_FLOW_ACTION_RSS`` 
action
+is targeted to no queue group, and the group attribute is ignored.
+
+For each engine, a list of supported patterns is maintained in a global array
+named ``ice__supported_pattern``. The Ice PMD will reject any rule with
+a pattern that is not included in the supported list.
+
+One notable feature is the ice PMD's ability to leverage the Raw pattern,
+enabling protocol-agnostic flow offloading. Here is an example of creating
+a rule that matches an IPv4 destination address of 1.2.3.4 and redirects it to
+queue 3 using a raw pattern:
+
+flow create 0 ingress group 2 pattern raw \
+pattern spec \
+080045144000401001020304 \
+pattern mask \
+ \
+end actions queue index 3 / mark id 3 / end
+
+Currently, raw pattern support is limited to the FDIR and Hash engines.
+
 Additional Options
 ++
 
-- 
2.31.1



[PATCH v4 3/5] net/ice: map group to pipeline stage

2023-09-24 Thread Qi Zhang
Mapping rte_flow_attr->group to a specific hardware stage.

Group 0 -> switch filter
Group 1 -> acl filter (dcf mode only)
Group 2 -> fdir filter (pf mode only)

For RSS, it will only be selected if there is a RTE_FLOW_ACTION_RSS
action target no queue group and the group ID is ignored.

Since each flow parser will be selected based on the group, there is no
need to maintain a separate 'parser list' or related APIs for
registering/unregistering parsers.

Signed-off-by: Qi Zhang 
---
 drivers/net/ice/ice_acl_filter.c|  13 +-
 drivers/net/ice/ice_ethdev.h|   2 -
 drivers/net/ice/ice_fdir_filter.c   |  19 +--
 drivers/net/ice/ice_generic_flow.c  | 234 +---
 drivers/net/ice/ice_generic_flow.h  |   9 +-
 drivers/net/ice/ice_hash.c  |  16 +-
 drivers/net/ice/ice_switch_filter.c |  13 +-
 7 files changed, 91 insertions(+), 215 deletions(-)

diff --git a/drivers/net/ice/ice_acl_filter.c b/drivers/net/ice/ice_acl_filter.c
index 51f4feced4..e507bb927a 100644
--- a/drivers/net/ice/ice_acl_filter.c
+++ b/drivers/net/ice/ice_acl_filter.c
@@ -41,8 +41,6 @@
ICE_ACL_INSET_ETH_IPV4 | \
ICE_INSET_SCTP_SRC_PORT | ICE_INSET_SCTP_DST_PORT)
 
-static struct ice_flow_parser ice_acl_parser;
-
 struct acl_rule {
enum ice_fltr_ptype flow_type;
uint64_t entry_id[4];
@@ -993,7 +991,6 @@ ice_acl_init(struct ice_adapter *ad)
int ret = 0;
struct ice_pf *pf = &ad->pf;
struct ice_hw *hw = ICE_PF_TO_HW(pf);
-   struct ice_flow_parser *parser = &ice_acl_parser;
 
ret = ice_acl_prof_alloc(hw);
if (ret) {
@@ -1010,11 +1007,7 @@ ice_acl_init(struct ice_adapter *ad)
if (ret)
return ret;
 
-   ret = ice_acl_prof_init(pf);
-   if (ret)
-   return ret;
-
-   return ice_register_parser(parser, ad);
+   return ice_acl_prof_init(pf);
 }
 
 static void
@@ -1037,10 +1030,8 @@ ice_acl_uninit(struct ice_adapter *ad)
 {
struct ice_pf *pf = &ad->pf;
struct ice_hw *hw = ICE_PF_TO_HW(pf);
-   struct ice_flow_parser *parser = &ice_acl_parser;
 
if (ad->hw.dcf_enabled) {
-   ice_unregister_parser(parser, ad);
ice_deinit_acl(pf);
ice_acl_prof_free(hw);
}
@@ -1056,7 +1047,7 @@ ice_flow_engine ice_acl_engine = {
.type = ICE_FLOW_ENGINE_ACL,
 };
 
-static struct
+struct
 ice_flow_parser ice_acl_parser = {
.engine = &ice_acl_engine,
.array = ice_acl_pattern,
diff --git a/drivers/net/ice/ice_ethdev.h b/drivers/net/ice/ice_ethdev.h
index 1f88becd19..abe6dcdc23 100644
--- a/drivers/net/ice/ice_ethdev.h
+++ b/drivers/net/ice/ice_ethdev.h
@@ -541,8 +541,6 @@ struct ice_pf {
bool adapter_stopped;
struct ice_flow_list flow_list;
rte_spinlock_t flow_ops_lock;
-   struct ice_parser_list rss_parser_list;
-   struct ice_parser_list dist_parser_list;
bool init_link_up;
uint64_t old_rx_bytes;
uint64_t old_tx_bytes;
diff --git a/drivers/net/ice/ice_fdir_filter.c 
b/drivers/net/ice/ice_fdir_filter.c
index bc43883a92..6afcdf5376 100644
--- a/drivers/net/ice/ice_fdir_filter.c
+++ b/drivers/net/ice/ice_fdir_filter.c
@@ -137,8 +137,6 @@ static struct ice_pattern_match_item 
ice_fdir_pattern_list[] = {
{pattern_eth_ipv6_gtpu_eh,  
ICE_FDIR_INSET_IPV6_GTPU_EH,ICE_FDIR_INSET_IPV6_GTPU_EH,ICE_INSET_NONE},
 };
 
-static struct ice_flow_parser ice_fdir_parser;
-
 static int
 ice_fdir_is_tunnel_profile(enum ice_fdir_tunnel_type tunnel_type);
 
@@ -1147,31 +1145,18 @@ static int
 ice_fdir_init(struct ice_adapter *ad)
 {
struct ice_pf *pf = &ad->pf;
-   struct ice_flow_parser *parser;
-   int ret;
-
-   ret = ice_fdir_setup(pf);
-   if (ret)
-   return ret;
-
-   parser = &ice_fdir_parser;
 
-   return ice_register_parser(parser, ad);
+   return ice_fdir_setup(pf);
 }
 
 static void
 ice_fdir_uninit(struct ice_adapter *ad)
 {
-   struct ice_flow_parser *parser;
struct ice_pf *pf = &ad->pf;
 
if (ad->hw.dcf_enabled)
return;
 
-   parser = &ice_fdir_parser;
-
-   ice_unregister_parser(parser, ad);
-
ice_fdir_teardown(pf);
 }
 
@@ -2507,7 +2492,7 @@ ice_fdir_parse(struct ice_adapter *ad,
return ret;
 }
 
-static struct ice_flow_parser ice_fdir_parser = {
+struct ice_flow_parser ice_fdir_parser = {
.engine = &ice_fdir_engine,
.array = ice_fdir_pattern_list,
.array_len = RTE_DIM(ice_fdir_pattern_list),
diff --git a/drivers/net/ice/ice_generic_flow.c 
b/drivers/net/ice/ice_generic_flow.c
index 6695457bbd..e06a1f562a 100644
--- a/drivers/net/ice/ice_generic_flow.c
+++ b/drivers/net/ice/ice_generic_flow.c
@@ -1793,15 +1793,13 @@ enum rte_flow_item_type pattern_eth_ipv6_pfcp[] = {
RTE_FLOW_ITEM_TYPE_END,
 };

[PATCH v4 2/5] net/ice: refine flow engine disabling

2023-09-24 Thread Qi Zhang
Only "disable_engine_mask" for flow engine disabling

In PF mode, only ACL engine will be disabled.
In DCF mode, FDIR and HASH engine will be disabled.
In DCF mode with "acl=off", ACL engine will also be
disabled.

Signed-off-by: Qi Zhang 
---
 drivers/net/ice/ice_acl_filter.c  | 3 ---
 drivers/net/ice/ice_dcf_parent.c  | 3 +++
 drivers/net/ice/ice_ethdev.c  | 1 +
 drivers/net/ice/ice_fdir_filter.c | 3 ---
 drivers/net/ice/ice_hash.c| 3 ---
 5 files changed, 4 insertions(+), 9 deletions(-)

diff --git a/drivers/net/ice/ice_acl_filter.c b/drivers/net/ice/ice_acl_filter.c
index f2ddbd7b9b..51f4feced4 100644
--- a/drivers/net/ice/ice_acl_filter.c
+++ b/drivers/net/ice/ice_acl_filter.c
@@ -995,9 +995,6 @@ ice_acl_init(struct ice_adapter *ad)
struct ice_hw *hw = ICE_PF_TO_HW(pf);
struct ice_flow_parser *parser = &ice_acl_parser;
 
-   if (!ad->hw.dcf_enabled)
-   return 0;
-
ret = ice_acl_prof_alloc(hw);
if (ret) {
PMD_DRV_LOG(ERR, "Cannot allocate memory for "
diff --git a/drivers/net/ice/ice_dcf_parent.c b/drivers/net/ice/ice_dcf_parent.c
index 173ed9f81d..6e845f458a 100644
--- a/drivers/net/ice/ice_dcf_parent.c
+++ b/drivers/net/ice/ice_dcf_parent.c
@@ -474,6 +474,9 @@ ice_dcf_init_parent_adapter(struct rte_eth_dev *eth_dev)
if (ice_devargs_check(eth_dev->device->devargs, ICE_DCF_DEVARG_ACL))
parent_adapter->disabled_engine_mask |= 
BIT(ICE_FLOW_ENGINE_ACL);
 
+   parent_adapter->disabled_engine_mask |= BIT(ICE_FLOW_ENGINE_FDIR);
+   parent_adapter->disabled_engine_mask |= BIT(ICE_FLOW_ENGINE_HASH);
+
err = ice_flow_init(parent_adapter);
if (err) {
PMD_INIT_LOG(ERR, "Failed to initialize flow");
diff --git a/drivers/net/ice/ice_ethdev.c b/drivers/net/ice/ice_ethdev.c
index 036b068c22..f744bde8f4 100644
--- a/drivers/net/ice/ice_ethdev.c
+++ b/drivers/net/ice/ice_ethdev.c
@@ -2442,6 +2442,7 @@ ice_dev_init(struct rte_eth_dev *dev)
}
 
if (!ad->is_safe_mode) {
+   ad->disabled_engine_mask |= BIT(ICE_FLOW_ENGINE_ACL);
ret = ice_flow_init(ad);
if (ret) {
PMD_INIT_LOG(ERR, "Failed to initialize flow");
diff --git a/drivers/net/ice/ice_fdir_filter.c 
b/drivers/net/ice/ice_fdir_filter.c
index e9ee5a57d6..bc43883a92 100644
--- a/drivers/net/ice/ice_fdir_filter.c
+++ b/drivers/net/ice/ice_fdir_filter.c
@@ -1150,9 +1150,6 @@ ice_fdir_init(struct ice_adapter *ad)
struct ice_flow_parser *parser;
int ret;
 
-   if (ad->hw.dcf_enabled)
-   return 0;
-
ret = ice_fdir_setup(pf);
if (ret)
return ret;
diff --git a/drivers/net/ice/ice_hash.c b/drivers/net/ice/ice_hash.c
index e36e7da2b5..37bee808c6 100644
--- a/drivers/net/ice/ice_hash.c
+++ b/drivers/net/ice/ice_hash.c
@@ -591,9 +591,6 @@ ice_hash_init(struct ice_adapter *ad)
 {
struct ice_flow_parser *parser = NULL;
 
-   if (ad->hw.dcf_enabled)
-   return 0;
-
parser = &ice_hash_parser;
 
return ice_register_parser(parser, ad);
-- 
2.31.1



[PATCH v4 1/5] net/ice: remove pipeline mode

2023-09-24 Thread Qi Zhang
This marks the initial phase of refactoring the ice rte_flow
implementation.

The combination of switch and fdir rules within the same syntax has led
to inconvenient user experiences. Naturally, the switch filter and fdir
filter represent distinct pipeline stages with differing hardware
capabilities.

To address this, we have made the decision to assign each stage to a
separate rte_flow group. This will allow users to clearly specify their
intentions when creating a rule. Consequently, the need for a pipeline
mode can be removed.

Signed-off-by: Qi Zhang 
---
 doc/guides/nics/ice.rst |  19 -
 drivers/net/ice/ice_ethdev.c|   8 --
 drivers/net/ice/ice_ethdev.h|   2 -
 drivers/net/ice/ice_fdir_filter.c   |   2 +-
 drivers/net/ice/ice_generic_flow.c  | 120 
 drivers/net/ice/ice_generic_flow.h  |   6 +-
 drivers/net/ice/ice_switch_filter.c | 118 +--
 7 files changed, 40 insertions(+), 235 deletions(-)

diff --git a/doc/guides/nics/ice.rst b/doc/guides/nics/ice.rst
index c351c6bd74..5a47109c3f 100644
--- a/doc/guides/nics/ice.rst
+++ b/doc/guides/nics/ice.rst
@@ -90,25 +90,6 @@ Runtime Configuration
   NOTE: In Safe mode, only very limited features are available, features like 
RSS,
   checksum, fdir, tunneling ... are all disabled.
 
-- ``Generic Flow Pipeline Mode Support`` (default ``0``)
-
-  In pipeline mode, a flow can be set at one specific stage by setting 
parameter
-  ``priority``. Currently, we support two stages: priority = 0 or !0. Flows 
with
-  priority 0 located at the first pipeline stage which typically be used as a 
firewall
-  to drop the packet on a blocklist(we called it permission stage). At this 
stage,
-  flow rules are created for the device's exact match engine: switch. Flows 
with priority
-  !0 located at the second stage, typically packets are classified here and be 
steered to
-  specific queue or queue group (we called it distribution stage), At this 
stage, flow
-  rules are created for device's flow director engine.
-  For none-pipeline mode, ``priority`` is ignored, a flow rule can be created 
as a flow director
-  rule or a switch rule depends on its pattern/action and the resource 
allocation situation,
-  all flows are virtually at the same pipeline stage.
-  By default, generic flow API is enabled in none-pipeline mode, user can 
choose to
-  use pipeline mode by setting ``devargs`` parameter ``pipeline-mode-support``,
-  for example::
-
--a 80:00.0,pipeline-mode-support=1
-
 - ``Default MAC Disable`` (default ``0``)
 
   Disable the default MAC make the device drop all packets by default,
diff --git a/drivers/net/ice/ice_ethdev.c b/drivers/net/ice/ice_ethdev.c
index 4bad39c2c1..036b068c22 100644
--- a/drivers/net/ice/ice_ethdev.c
+++ b/drivers/net/ice/ice_ethdev.c
@@ -27,7 +27,6 @@
 
 /* devargs */
 #define ICE_SAFE_MODE_SUPPORT_ARG "safe-mode-support"
-#define ICE_PIPELINE_MODE_SUPPORT_ARG  "pipeline-mode-support"
 #define ICE_DEFAULT_MAC_DISABLE   "default-mac-disable"
 #define ICE_PROTO_XTR_ARG "proto_xtr"
 #define ICE_FIELD_OFFS_ARG   "field_offs"
@@ -43,7 +42,6 @@ int ice_timestamp_dynfield_offset = -1;
 
 static const char * const ice_valid_args[] = {
ICE_SAFE_MODE_SUPPORT_ARG,
-   ICE_PIPELINE_MODE_SUPPORT_ARG,
ICE_PROTO_XTR_ARG,
ICE_FIELD_OFFS_ARG,
ICE_FIELD_NAME_ARG,
@@ -2103,11 +2101,6 @@ static int ice_parse_devargs(struct rte_eth_dev *dev)
if (ret)
goto bail;
 
-   ret = rte_kvargs_process(kvlist, ICE_PIPELINE_MODE_SUPPORT_ARG,
-&parse_bool, &ad->devargs.pipe_mode_support);
-   if (ret)
-   goto bail;
-
ret = rte_kvargs_process(kvlist, ICE_DEFAULT_MAC_DISABLE,
&parse_bool, &ad->devargs.default_mac_disable);
if (ret)
@@ -6549,7 +6542,6 @@ RTE_PMD_REGISTER_PARAM_STRING(net_ice,
  ICE_HW_DEBUG_MASK_ARG "=0xXXX"
  ICE_PROTO_XTR_ARG 
"=[queue:]"
  ICE_SAFE_MODE_SUPPORT_ARG "=<0|1>"
- ICE_PIPELINE_MODE_SUPPORT_ARG "=<0|1>"
  ICE_DEFAULT_MAC_DISABLE "=<0|1>"
  ICE_RX_LOW_LATENCY_ARG "=<0|1>");
 
diff --git a/drivers/net/ice/ice_ethdev.h b/drivers/net/ice/ice_ethdev.h
index 9789cb8525..1f88becd19 100644
--- a/drivers/net/ice/ice_ethdev.h
+++ b/drivers/net/ice/ice_ethdev.h
@@ -542,7 +542,6 @@ struct ice_pf {
struct ice_flow_list flow_list;
rte_spinlock_t flow_ops_lock;
struct ice_parser_list rss_parser_list;
-   struct ice_parser_list perm_parser_list;
struct ice_parser_list dist_parser_list;
bool init_link_up;

[PATCH v4 0/5] net/ice: refactor rte_flow

2023-09-24 Thread Qi Zhang
1. remove pipeline mode
2. apply group to hardware pipeline stage static mapping
3. add genenic flow document

v4:
- fix error handling when target engine was disabled.

v3:
- fix the issue when acl=off on dcf mode
- refine the disabled engine handling
- unified the supported pattern variable name
- add document

v2:
- fix segment fault when an unintialized engine has been selected.


Qi Zhang (5):
  net/ice: remove pipeline mode
  net/ice: refine flow engine disabling
  net/ice: map group to pipeline stage
  net/ice: refine supported flow pattern name
  doc: add generic flow doc for ice PMD

 doc/guides/nics/ice.rst |  64 --
 drivers/net/ice/ice_acl_filter.c|  22 +-
 drivers/net/ice/ice_dcf_parent.c|   3 +
 drivers/net/ice/ice_ethdev.c|   9 +-
 drivers/net/ice/ice_ethdev.h|   4 -
 drivers/net/ice/ice_fdir_filter.c   |  30 +--
 drivers/net/ice/ice_generic_flow.c  | 298 
 drivers/net/ice/ice_generic_flow.h  |  15 +-
 drivers/net/ice/ice_hash.c  |  19 +-
 drivers/net/ice/ice_switch_filter.c | 133 +
 10 files changed, 159 insertions(+), 438 deletions(-)

-- 
2.31.1



[PATCH v3 5/5] doc: add generic flow doc for ice PMD

2023-09-11 Thread Qi Zhang
Add some about document about the how to use
rte_flow on ice PMD.

Signed-off-by: Qi Zhang 
---
 doc/guides/nics/ice.rst | 45 +
 1 file changed, 45 insertions(+)

diff --git a/doc/guides/nics/ice.rst b/doc/guides/nics/ice.rst
index 5a47109c3f..b36a4c260a 100644
--- a/doc/guides/nics/ice.rst
+++ b/doc/guides/nics/ice.rst
@@ -301,6 +301,51 @@ The DCF PMD needs to advertise and acquire DCF capability 
which allows DCF to
 send AdminQ commands that it would like to execute over to the PF and receive
 responses for the same from PF.
 
+Generic Flow Support
+
+
+The ice PMD provides support for the Generic Flow API (RTE_FLOW), enabling
+users to offload various flow classification tasks to the E810 NIC.
+The E810 NIC's  packet processing pipeline consists of the following stages:
+
+Switch: Supports exact match and limited wildcard matching with a large flow
+capacity.
+
+ACL: Supports wildcard matching with a smaller flow capacity (DCF mode only).
+
+FDIR: Supports exact match with a large flow capacity (PF mode only).
+
+Hash: Supports RSS (PF mode only)
+
+The ice PMD utilizes the ice_flow_engine structure to represent each of these
+stages and leverages the rte_flow rule's ``group`` attribute for selecting the
+appropriate engine for Switch, ACL, and FDIR operations:
+
+Group 0 maps to Switch
+Group 1 maps to ACL
+Group 2 maps to FDIR
+
+In the case of RSS, it will only be selected if a ``RTE_FLOW_ACTION_RSS`` 
action
+is targeted to no queue group, and the group attribute is ignored.
+
+For each engine, a list of supported patterns is maintained in a global array
+named ``ice__supported_pattern``. The Ice PMD will reject any rule with
+a pattern that is not included in the supported list.
+
+One notable feature is the ice PMD's ability to leverage the Raw pattern,
+enabling protocol-agnostic flow offloading. Here is an example of creating
+a rule that matches an IPv4 destination address of 1.2.3.4 and redirects it to
+queue 3 using a raw pattern:
+
+flow create 0 ingress group 2 pattern raw \
+pattern spec \
+080045144000401001020304 \
+pattern mask \
+ \
+end actions queue index 3 / mark id 3 / end
+
+Currently, raw pattern support is limited to the FDIR and Hash engines.
+
 Additional Options
 ++
 
-- 
2.31.1



[PATCH v3 4/5] net/ice: refine supported flow pattern name

2023-09-11 Thread Qi Zhang
Unified the supported patten array name to flow
ice__supported_pattern.

Signed-off-by: Qi Zhang 
---
 drivers/net/ice/ice_acl_filter.c| 6 +++---
 drivers/net/ice/ice_fdir_filter.c   | 6 +++---
 drivers/net/ice/ice_switch_filter.c | 6 +++---
 3 files changed, 9 insertions(+), 9 deletions(-)

diff --git a/drivers/net/ice/ice_acl_filter.c b/drivers/net/ice/ice_acl_filter.c
index e507bb927a..63a525b363 100644
--- a/drivers/net/ice/ice_acl_filter.c
+++ b/drivers/net/ice/ice_acl_filter.c
@@ -47,7 +47,7 @@ struct acl_rule {
 };
 
 static struct
-ice_pattern_match_item ice_acl_pattern[] = {
+ice_pattern_match_item ice_acl_supported_pattern[] = {
{pattern_eth_ipv4,  ICE_ACL_INSET_ETH_IPV4, ICE_INSET_NONE, 
ICE_INSET_NONE},
{pattern_eth_ipv4_udp,  ICE_ACL_INSET_ETH_IPV4_UDP, ICE_INSET_NONE, 
ICE_INSET_NONE},
{pattern_eth_ipv4_tcp,  ICE_ACL_INSET_ETH_IPV4_TCP, ICE_INSET_NONE, 
ICE_INSET_NONE},
@@ -1050,8 +1050,8 @@ ice_flow_engine ice_acl_engine = {
 struct
 ice_flow_parser ice_acl_parser = {
.engine = &ice_acl_engine,
-   .array = ice_acl_pattern,
-   .array_len = RTE_DIM(ice_acl_pattern),
+   .array = ice_acl_supported_pattern,
+   .array_len = RTE_DIM(ice_acl_supported_pattern),
.parse_pattern_action = ice_acl_parse,
.stage = ICE_FLOW_STAGE_DISTRIBUTOR,
 };
diff --git a/drivers/net/ice/ice_fdir_filter.c 
b/drivers/net/ice/ice_fdir_filter.c
index 6afcdf5376..0b7920ad44 100644
--- a/drivers/net/ice/ice_fdir_filter.c
+++ b/drivers/net/ice/ice_fdir_filter.c
@@ -106,7 +106,7 @@
ICE_INSET_IPV6_SRC | ICE_INSET_IPV6_DST | \
ICE_INSET_NAT_T_ESP_SPI)
 
-static struct ice_pattern_match_item ice_fdir_pattern_list[] = {
+static struct ice_pattern_match_item ice_fdir_supported_pattern[] = {
{pattern_raw,   ICE_INSET_NONE, 
ICE_INSET_NONE, ICE_INSET_NONE},
{pattern_ethertype, ICE_FDIR_INSET_ETH, 
ICE_INSET_NONE, ICE_INSET_NONE},
{pattern_eth_ipv4,  
ICE_FDIR_INSET_ETH_IPV4,ICE_INSET_NONE, ICE_INSET_NONE},
@@ -2494,8 +2494,8 @@ ice_fdir_parse(struct ice_adapter *ad,
 
 struct ice_flow_parser ice_fdir_parser = {
.engine = &ice_fdir_engine,
-   .array = ice_fdir_pattern_list,
-   .array_len = RTE_DIM(ice_fdir_pattern_list),
+   .array = ice_fdir_supported_pattern,
+   .array_len = RTE_DIM(ice_fdir_supported_pattern),
.parse_pattern_action = ice_fdir_parse,
.stage = ICE_FLOW_STAGE_DISTRIBUTOR,
 };
diff --git a/drivers/net/ice/ice_switch_filter.c 
b/drivers/net/ice/ice_switch_filter.c
index 8f29326762..122b87f625 100644
--- a/drivers/net/ice/ice_switch_filter.c
+++ b/drivers/net/ice/ice_switch_filter.c
@@ -202,7 +202,7 @@ struct ice_switch_filter_conf {
 };
 
 static struct
-ice_pattern_match_item ice_switch_pattern_dist_list[] = {
+ice_pattern_match_item ice_switch_supported_pattern[] = {
{pattern_any,   ICE_INSET_NONE, 
ICE_INSET_NONE, ICE_INSET_NONE},
{pattern_ethertype, ICE_SW_INSET_ETHER, 
ICE_INSET_NONE, ICE_INSET_NONE},
{pattern_ethertype_vlan,ICE_SW_INSET_MAC_VLAN,  
ICE_INSET_NONE, ICE_INSET_NONE},
@@ -2075,8 +2075,8 @@ ice_flow_engine ice_switch_engine = {
 struct
 ice_flow_parser ice_switch_parser = {
.engine = &ice_switch_engine,
-   .array = ice_switch_pattern_dist_list,
-   .array_len = RTE_DIM(ice_switch_pattern_dist_list),
+   .array = ice_switch_supported_pattern,
+   .array_len = RTE_DIM(ice_switch_supported_pattern),
.parse_pattern_action = ice_switch_parse_pattern_action,
.stage = ICE_FLOW_STAGE_DISTRIBUTOR,
 };
-- 
2.31.1



[PATCH v3 3/5] net/ice: map group to pipeline stage

2023-09-11 Thread Qi Zhang
Mapping rte_flow_attr->group to a specific hardware stage.

Group 0 -> switch filter
Group 1 -> acl filter (dcf mode only)
Group 2 -> fdir filter (pf mode only)

For RSS, it will only be selected if there is a RTE_FLOW_ACTION_RSS
action target no queue group and the group ID is ignored.

Since each flow parser will be selected based on the group, there is no
need to maintain a separate 'parser list' or related APIs for
registering/unregistering parsers.

Signed-off-by: Qi Zhang 
---
 drivers/net/ice/ice_acl_filter.c|  13 +-
 drivers/net/ice/ice_ethdev.h|   2 -
 drivers/net/ice/ice_fdir_filter.c   |  19 +--
 drivers/net/ice/ice_generic_flow.c  | 220 
 drivers/net/ice/ice_generic_flow.h  |   9 +-
 drivers/net/ice/ice_hash.c  |  16 +-
 drivers/net/ice/ice_switch_filter.c |  13 +-
 7 files changed, 78 insertions(+), 214 deletions(-)

diff --git a/drivers/net/ice/ice_acl_filter.c b/drivers/net/ice/ice_acl_filter.c
index 51f4feced4..e507bb927a 100644
--- a/drivers/net/ice/ice_acl_filter.c
+++ b/drivers/net/ice/ice_acl_filter.c
@@ -41,8 +41,6 @@
ICE_ACL_INSET_ETH_IPV4 | \
ICE_INSET_SCTP_SRC_PORT | ICE_INSET_SCTP_DST_PORT)
 
-static struct ice_flow_parser ice_acl_parser;
-
 struct acl_rule {
enum ice_fltr_ptype flow_type;
uint64_t entry_id[4];
@@ -993,7 +991,6 @@ ice_acl_init(struct ice_adapter *ad)
int ret = 0;
struct ice_pf *pf = &ad->pf;
struct ice_hw *hw = ICE_PF_TO_HW(pf);
-   struct ice_flow_parser *parser = &ice_acl_parser;
 
ret = ice_acl_prof_alloc(hw);
if (ret) {
@@ -1010,11 +1007,7 @@ ice_acl_init(struct ice_adapter *ad)
if (ret)
return ret;
 
-   ret = ice_acl_prof_init(pf);
-   if (ret)
-   return ret;
-
-   return ice_register_parser(parser, ad);
+   return ice_acl_prof_init(pf);
 }
 
 static void
@@ -1037,10 +1030,8 @@ ice_acl_uninit(struct ice_adapter *ad)
 {
struct ice_pf *pf = &ad->pf;
struct ice_hw *hw = ICE_PF_TO_HW(pf);
-   struct ice_flow_parser *parser = &ice_acl_parser;
 
if (ad->hw.dcf_enabled) {
-   ice_unregister_parser(parser, ad);
ice_deinit_acl(pf);
ice_acl_prof_free(hw);
}
@@ -1056,7 +1047,7 @@ ice_flow_engine ice_acl_engine = {
.type = ICE_FLOW_ENGINE_ACL,
 };
 
-static struct
+struct
 ice_flow_parser ice_acl_parser = {
.engine = &ice_acl_engine,
.array = ice_acl_pattern,
diff --git a/drivers/net/ice/ice_ethdev.h b/drivers/net/ice/ice_ethdev.h
index 1f88becd19..abe6dcdc23 100644
--- a/drivers/net/ice/ice_ethdev.h
+++ b/drivers/net/ice/ice_ethdev.h
@@ -541,8 +541,6 @@ struct ice_pf {
bool adapter_stopped;
struct ice_flow_list flow_list;
rte_spinlock_t flow_ops_lock;
-   struct ice_parser_list rss_parser_list;
-   struct ice_parser_list dist_parser_list;
bool init_link_up;
uint64_t old_rx_bytes;
uint64_t old_tx_bytes;
diff --git a/drivers/net/ice/ice_fdir_filter.c 
b/drivers/net/ice/ice_fdir_filter.c
index bc43883a92..6afcdf5376 100644
--- a/drivers/net/ice/ice_fdir_filter.c
+++ b/drivers/net/ice/ice_fdir_filter.c
@@ -137,8 +137,6 @@ static struct ice_pattern_match_item 
ice_fdir_pattern_list[] = {
{pattern_eth_ipv6_gtpu_eh,  
ICE_FDIR_INSET_IPV6_GTPU_EH,ICE_FDIR_INSET_IPV6_GTPU_EH,ICE_INSET_NONE},
 };
 
-static struct ice_flow_parser ice_fdir_parser;
-
 static int
 ice_fdir_is_tunnel_profile(enum ice_fdir_tunnel_type tunnel_type);
 
@@ -1147,31 +1145,18 @@ static int
 ice_fdir_init(struct ice_adapter *ad)
 {
struct ice_pf *pf = &ad->pf;
-   struct ice_flow_parser *parser;
-   int ret;
-
-   ret = ice_fdir_setup(pf);
-   if (ret)
-   return ret;
-
-   parser = &ice_fdir_parser;
 
-   return ice_register_parser(parser, ad);
+   return ice_fdir_setup(pf);
 }
 
 static void
 ice_fdir_uninit(struct ice_adapter *ad)
 {
-   struct ice_flow_parser *parser;
struct ice_pf *pf = &ad->pf;
 
if (ad->hw.dcf_enabled)
return;
 
-   parser = &ice_fdir_parser;
-
-   ice_unregister_parser(parser, ad);
-
ice_fdir_teardown(pf);
 }
 
@@ -2507,7 +2492,7 @@ ice_fdir_parse(struct ice_adapter *ad,
return ret;
 }
 
-static struct ice_flow_parser ice_fdir_parser = {
+struct ice_flow_parser ice_fdir_parser = {
.engine = &ice_fdir_engine,
.array = ice_fdir_pattern_list,
.array_len = RTE_DIM(ice_fdir_pattern_list),
diff --git a/drivers/net/ice/ice_generic_flow.c 
b/drivers/net/ice/ice_generic_flow.c
index 6695457bbd..7eb3b1f236 100644
--- a/drivers/net/ice/ice_generic_flow.c
+++ b/drivers/net/ice/ice_generic_flow.c
@@ -1793,15 +1793,13 @@ enum rte_flow_item_type pattern_eth_ipv6_pfcp[] = {
RTE_FLOW_ITEM_TYPE_END,
 };

[PATCH v3 2/5] net/ice: refine flow engine disabling

2023-09-11 Thread Qi Zhang
Only use "disable_engine_mask" for flow engine disabling

In PF mode, only ACL engine will be disabled.
In DCF mode, FDIR and HASH engine will be disabled.
In DCF mode with "acl=off", ACL engine will also be
disabled.

Signed-off-by: Qi Zhang 
---
 drivers/net/ice/ice_acl_filter.c  | 3 ---
 drivers/net/ice/ice_dcf_parent.c  | 3 +++
 drivers/net/ice/ice_ethdev.c  | 1 +
 drivers/net/ice/ice_fdir_filter.c | 3 ---
 drivers/net/ice/ice_hash.c| 3 ---
 5 files changed, 4 insertions(+), 9 deletions(-)

diff --git a/drivers/net/ice/ice_acl_filter.c b/drivers/net/ice/ice_acl_filter.c
index f2ddbd7b9b..51f4feced4 100644
--- a/drivers/net/ice/ice_acl_filter.c
+++ b/drivers/net/ice/ice_acl_filter.c
@@ -995,9 +995,6 @@ ice_acl_init(struct ice_adapter *ad)
struct ice_hw *hw = ICE_PF_TO_HW(pf);
struct ice_flow_parser *parser = &ice_acl_parser;
 
-   if (!ad->hw.dcf_enabled)
-   return 0;
-
ret = ice_acl_prof_alloc(hw);
if (ret) {
PMD_DRV_LOG(ERR, "Cannot allocate memory for "
diff --git a/drivers/net/ice/ice_dcf_parent.c b/drivers/net/ice/ice_dcf_parent.c
index ad98a531de..0a20f6b4ca 100644
--- a/drivers/net/ice/ice_dcf_parent.c
+++ b/drivers/net/ice/ice_dcf_parent.c
@@ -475,6 +475,9 @@ ice_dcf_init_parent_adapter(struct rte_eth_dev *eth_dev)
if (ice_devargs_check(eth_dev->device->devargs, ICE_DCF_DEVARG_ACL))
parent_adapter->disabled_engine_mask |= 
BIT(ICE_FLOW_ENGINE_ACL);
 
+   parent_adapter->disabled_engine_mask |= BIT(ICE_FLOW_ENGINE_FDIR);
+   parent_adapter->disabled_engine_mask |= BIT(ICE_FLOW_ENGINE_HASH);
+
err = ice_flow_init(parent_adapter);
if (err) {
PMD_INIT_LOG(ERR, "Failed to initialize flow");
diff --git a/drivers/net/ice/ice_ethdev.c b/drivers/net/ice/ice_ethdev.c
index 036b068c22..f744bde8f4 100644
--- a/drivers/net/ice/ice_ethdev.c
+++ b/drivers/net/ice/ice_ethdev.c
@@ -2442,6 +2442,7 @@ ice_dev_init(struct rte_eth_dev *dev)
}
 
if (!ad->is_safe_mode) {
+   ad->disabled_engine_mask |= BIT(ICE_FLOW_ENGINE_ACL);
ret = ice_flow_init(ad);
if (ret) {
PMD_INIT_LOG(ERR, "Failed to initialize flow");
diff --git a/drivers/net/ice/ice_fdir_filter.c 
b/drivers/net/ice/ice_fdir_filter.c
index e9ee5a57d6..bc43883a92 100644
--- a/drivers/net/ice/ice_fdir_filter.c
+++ b/drivers/net/ice/ice_fdir_filter.c
@@ -1150,9 +1150,6 @@ ice_fdir_init(struct ice_adapter *ad)
struct ice_flow_parser *parser;
int ret;
 
-   if (ad->hw.dcf_enabled)
-   return 0;
-
ret = ice_fdir_setup(pf);
if (ret)
return ret;
diff --git a/drivers/net/ice/ice_hash.c b/drivers/net/ice/ice_hash.c
index e36e7da2b5..37bee808c6 100644
--- a/drivers/net/ice/ice_hash.c
+++ b/drivers/net/ice/ice_hash.c
@@ -591,9 +591,6 @@ ice_hash_init(struct ice_adapter *ad)
 {
struct ice_flow_parser *parser = NULL;
 
-   if (ad->hw.dcf_enabled)
-   return 0;
-
parser = &ice_hash_parser;
 
return ice_register_parser(parser, ad);
-- 
2.31.1



[PATCH v3 1/5] net/ice: remove pipeline mode

2023-09-11 Thread Qi Zhang
This marks the initial phase of refactoring the ice rte_flow
implementation.

The combination of switch and fdir rules within the same syntax has led
to inconvenient user experiences. Naturally, the switch filter and fdir
filter represent distinct pipeline stages with differing hardware
capabilities.

To address this, we have made the decision to assign each stage to a
separate rte_flow group. This will allow users to clearly specify their
intentions when creating a rule. Consequently, the need for a pipeline
mode can be removed.

Signed-off-by: Qi Zhang 
---
 doc/guides/nics/ice.rst |  19 -
 drivers/net/ice/ice_ethdev.c|   8 --
 drivers/net/ice/ice_ethdev.h|   2 -
 drivers/net/ice/ice_fdir_filter.c   |   2 +-
 drivers/net/ice/ice_generic_flow.c  | 120 
 drivers/net/ice/ice_generic_flow.h  |   6 +-
 drivers/net/ice/ice_switch_filter.c | 118 +--
 7 files changed, 40 insertions(+), 235 deletions(-)

diff --git a/doc/guides/nics/ice.rst b/doc/guides/nics/ice.rst
index c351c6bd74..5a47109c3f 100644
--- a/doc/guides/nics/ice.rst
+++ b/doc/guides/nics/ice.rst
@@ -90,25 +90,6 @@ Runtime Configuration
   NOTE: In Safe mode, only very limited features are available, features like 
RSS,
   checksum, fdir, tunneling ... are all disabled.
 
-- ``Generic Flow Pipeline Mode Support`` (default ``0``)
-
-  In pipeline mode, a flow can be set at one specific stage by setting 
parameter
-  ``priority``. Currently, we support two stages: priority = 0 or !0. Flows 
with
-  priority 0 located at the first pipeline stage which typically be used as a 
firewall
-  to drop the packet on a blocklist(we called it permission stage). At this 
stage,
-  flow rules are created for the device's exact match engine: switch. Flows 
with priority
-  !0 located at the second stage, typically packets are classified here and be 
steered to
-  specific queue or queue group (we called it distribution stage), At this 
stage, flow
-  rules are created for device's flow director engine.
-  For none-pipeline mode, ``priority`` is ignored, a flow rule can be created 
as a flow director
-  rule or a switch rule depends on its pattern/action and the resource 
allocation situation,
-  all flows are virtually at the same pipeline stage.
-  By default, generic flow API is enabled in none-pipeline mode, user can 
choose to
-  use pipeline mode by setting ``devargs`` parameter ``pipeline-mode-support``,
-  for example::
-
--a 80:00.0,pipeline-mode-support=1
-
 - ``Default MAC Disable`` (default ``0``)
 
   Disable the default MAC make the device drop all packets by default,
diff --git a/drivers/net/ice/ice_ethdev.c b/drivers/net/ice/ice_ethdev.c
index 4bad39c2c1..036b068c22 100644
--- a/drivers/net/ice/ice_ethdev.c
+++ b/drivers/net/ice/ice_ethdev.c
@@ -27,7 +27,6 @@
 
 /* devargs */
 #define ICE_SAFE_MODE_SUPPORT_ARG "safe-mode-support"
-#define ICE_PIPELINE_MODE_SUPPORT_ARG  "pipeline-mode-support"
 #define ICE_DEFAULT_MAC_DISABLE   "default-mac-disable"
 #define ICE_PROTO_XTR_ARG "proto_xtr"
 #define ICE_FIELD_OFFS_ARG   "field_offs"
@@ -43,7 +42,6 @@ int ice_timestamp_dynfield_offset = -1;
 
 static const char * const ice_valid_args[] = {
ICE_SAFE_MODE_SUPPORT_ARG,
-   ICE_PIPELINE_MODE_SUPPORT_ARG,
ICE_PROTO_XTR_ARG,
ICE_FIELD_OFFS_ARG,
ICE_FIELD_NAME_ARG,
@@ -2103,11 +2101,6 @@ static int ice_parse_devargs(struct rte_eth_dev *dev)
if (ret)
goto bail;
 
-   ret = rte_kvargs_process(kvlist, ICE_PIPELINE_MODE_SUPPORT_ARG,
-&parse_bool, &ad->devargs.pipe_mode_support);
-   if (ret)
-   goto bail;
-
ret = rte_kvargs_process(kvlist, ICE_DEFAULT_MAC_DISABLE,
&parse_bool, &ad->devargs.default_mac_disable);
if (ret)
@@ -6549,7 +6542,6 @@ RTE_PMD_REGISTER_PARAM_STRING(net_ice,
  ICE_HW_DEBUG_MASK_ARG "=0xXXX"
  ICE_PROTO_XTR_ARG 
"=[queue:]"
  ICE_SAFE_MODE_SUPPORT_ARG "=<0|1>"
- ICE_PIPELINE_MODE_SUPPORT_ARG "=<0|1>"
  ICE_DEFAULT_MAC_DISABLE "=<0|1>"
  ICE_RX_LOW_LATENCY_ARG "=<0|1>");
 
diff --git a/drivers/net/ice/ice_ethdev.h b/drivers/net/ice/ice_ethdev.h
index 9789cb8525..1f88becd19 100644
--- a/drivers/net/ice/ice_ethdev.h
+++ b/drivers/net/ice/ice_ethdev.h
@@ -542,7 +542,6 @@ struct ice_pf {
struct ice_flow_list flow_list;
rte_spinlock_t flow_ops_lock;
struct ice_parser_list rss_parser_list;
-   struct ice_parser_list perm_parser_list;
struct ice_parser_list dist_parser_list;
bool init_link_up;

[PATCH v3 0/5] refactor rte_flow

2023-09-11 Thread Qi Zhang
1. remove pipeline mode
2. apply group to hardware pipeline stage static mapping
3. add genenic flow document

v3:
- fix the issue when acl=off on dcf mode
- refine the disabled engine handling
- unified the supported pattern variable name
- add document

v2:
- fix segment fault when an unintialized engine has been selected.

Qi Zhang (5):
  net/ice: remove pipeline mode
  net/ice: refine flow engine disabling
  net/ice: map group to pipeline stage
  net/ice: refine supported flow pattern name
  doc: add generic flow doc for ice PMD

 doc/guides/nics/ice.rst |  64 +--
 drivers/net/ice/ice_acl_filter.c|  22 +--
 drivers/net/ice/ice_dcf_parent.c|   3 +
 drivers/net/ice/ice_ethdev.c|   9 +-
 drivers/net/ice/ice_ethdev.h|   4 -
 drivers/net/ice/ice_fdir_filter.c   |  30 +--
 drivers/net/ice/ice_generic_flow.c  | 284 +++-
 drivers/net/ice/ice_generic_flow.h  |  15 +-
 drivers/net/ice/ice_hash.c  |  19 +-
 drivers/net/ice/ice_switch_filter.c | 133 +
 10 files changed, 146 insertions(+), 437 deletions(-)

-- 
2.31.1



[PATCH v2 2/2] net/ice: map group to pipeline stage

2023-09-11 Thread Qi Zhang
Mapping rte_flow_attr->group to a specific hardware stage.

Group 0 -> switch filter
Group 1 -> acl filter
Group 2 -> fdir filter

For RSS, it will only be selected if there is a RTE_FLOW_ACTION_RSS
action target no queue group and the group ID is ignored.

Since each flow parser will be selected based on the group, there is no
need to maintain a separate 'parser list' or related APIs for
registering/unregistering parsers.

Signed-off-by: Qi Zhang 
---
 drivers/net/ice/ice_acl_filter.c|  13 +-
 drivers/net/ice/ice_ethdev.h|   2 -
 drivers/net/ice/ice_fdir_filter.c   |  19 +--
 drivers/net/ice/ice_generic_flow.c  | 188 +++-
 drivers/net/ice/ice_generic_flow.h  |   9 +-
 drivers/net/ice/ice_hash.c  |  19 +--
 drivers/net/ice/ice_switch_filter.c |  13 +-
 7 files changed, 62 insertions(+), 201 deletions(-)

diff --git a/drivers/net/ice/ice_acl_filter.c b/drivers/net/ice/ice_acl_filter.c
index f2ddbd7b9b..d79044732a 100644
--- a/drivers/net/ice/ice_acl_filter.c
+++ b/drivers/net/ice/ice_acl_filter.c
@@ -41,8 +41,6 @@
ICE_ACL_INSET_ETH_IPV4 | \
ICE_INSET_SCTP_SRC_PORT | ICE_INSET_SCTP_DST_PORT)
 
-static struct ice_flow_parser ice_acl_parser;
-
 struct acl_rule {
enum ice_fltr_ptype flow_type;
uint64_t entry_id[4];
@@ -993,7 +991,6 @@ ice_acl_init(struct ice_adapter *ad)
int ret = 0;
struct ice_pf *pf = &ad->pf;
struct ice_hw *hw = ICE_PF_TO_HW(pf);
-   struct ice_flow_parser *parser = &ice_acl_parser;
 
if (!ad->hw.dcf_enabled)
return 0;
@@ -1013,11 +1010,7 @@ ice_acl_init(struct ice_adapter *ad)
if (ret)
return ret;
 
-   ret = ice_acl_prof_init(pf);
-   if (ret)
-   return ret;
-
-   return ice_register_parser(parser, ad);
+   return ice_acl_prof_init(pf);
 }
 
 static void
@@ -1040,10 +1033,8 @@ ice_acl_uninit(struct ice_adapter *ad)
 {
struct ice_pf *pf = &ad->pf;
struct ice_hw *hw = ICE_PF_TO_HW(pf);
-   struct ice_flow_parser *parser = &ice_acl_parser;
 
if (ad->hw.dcf_enabled) {
-   ice_unregister_parser(parser, ad);
ice_deinit_acl(pf);
ice_acl_prof_free(hw);
}
@@ -1059,7 +1050,7 @@ ice_flow_engine ice_acl_engine = {
.type = ICE_FLOW_ENGINE_ACL,
 };
 
-static struct
+struct
 ice_flow_parser ice_acl_parser = {
.engine = &ice_acl_engine,
.array = ice_acl_pattern,
diff --git a/drivers/net/ice/ice_ethdev.h b/drivers/net/ice/ice_ethdev.h
index 1f88becd19..abe6dcdc23 100644
--- a/drivers/net/ice/ice_ethdev.h
+++ b/drivers/net/ice/ice_ethdev.h
@@ -541,8 +541,6 @@ struct ice_pf {
bool adapter_stopped;
struct ice_flow_list flow_list;
rte_spinlock_t flow_ops_lock;
-   struct ice_parser_list rss_parser_list;
-   struct ice_parser_list dist_parser_list;
bool init_link_up;
uint64_t old_rx_bytes;
uint64_t old_tx_bytes;
diff --git a/drivers/net/ice/ice_fdir_filter.c 
b/drivers/net/ice/ice_fdir_filter.c
index e9ee5a57d6..9ce243cc9c 100644
--- a/drivers/net/ice/ice_fdir_filter.c
+++ b/drivers/net/ice/ice_fdir_filter.c
@@ -137,8 +137,6 @@ static struct ice_pattern_match_item 
ice_fdir_pattern_list[] = {
{pattern_eth_ipv6_gtpu_eh,  
ICE_FDIR_INSET_IPV6_GTPU_EH,ICE_FDIR_INSET_IPV6_GTPU_EH,ICE_INSET_NONE},
 };
 
-static struct ice_flow_parser ice_fdir_parser;
-
 static int
 ice_fdir_is_tunnel_profile(enum ice_fdir_tunnel_type tunnel_type);
 
@@ -1147,34 +1145,21 @@ static int
 ice_fdir_init(struct ice_adapter *ad)
 {
struct ice_pf *pf = &ad->pf;
-   struct ice_flow_parser *parser;
-   int ret;
 
if (ad->hw.dcf_enabled)
return 0;
 
-   ret = ice_fdir_setup(pf);
-   if (ret)
-   return ret;
-
-   parser = &ice_fdir_parser;
-
-   return ice_register_parser(parser, ad);
+   return ice_fdir_setup(pf);
 }
 
 static void
 ice_fdir_uninit(struct ice_adapter *ad)
 {
-   struct ice_flow_parser *parser;
struct ice_pf *pf = &ad->pf;
 
if (ad->hw.dcf_enabled)
return;
 
-   parser = &ice_fdir_parser;
-
-   ice_unregister_parser(parser, ad);
-
ice_fdir_teardown(pf);
 }
 
@@ -2510,7 +2495,7 @@ ice_fdir_parse(struct ice_adapter *ad,
return ret;
 }
 
-static struct ice_flow_parser ice_fdir_parser = {
+struct ice_flow_parser ice_fdir_parser = {
.engine = &ice_fdir_engine,
.array = ice_fdir_pattern_list,
.array_len = RTE_DIM(ice_fdir_pattern_list),
diff --git a/drivers/net/ice/ice_generic_flow.c 
b/drivers/net/ice/ice_generic_flow.c
index 6695457bbd..e71e060653 100644
--- a/drivers/net/ice/ice_generic_flow.c
+++ b/drivers/net/ice/ice_generic_flow.c
@@ -1797,7 +1797,7 @@ enum rte_flow_item_type pattern_eth_ipv6_pfcp[] = {
 
 typedef str

[PATCH v2 1/2] net/ice: remove pipeline mode

2023-09-11 Thread Qi Zhang
This marks the initial phase of refactoring the ice rte_flow
implementation.

The combination of switch and fdir rules within the same syntax has led
to inconvenient user experiences. Naturally, the switch filter and fdir
filter represent distinct pipeline stages with differing hardware
capabilities.

To address this, we have made the decision to assign each stage to a
separate rte_flow group. This will allow users to clearly specify their
intentions when creating a rule. Consequently, the need for a pipeline
mode can be removed.

Signed-off-by: Qi Zhang 
---
 doc/guides/nics/ice.rst |  19 -
 drivers/net/ice/ice_ethdev.c|   8 --
 drivers/net/ice/ice_ethdev.h|   2 -
 drivers/net/ice/ice_fdir_filter.c   |   2 +-
 drivers/net/ice/ice_generic_flow.c  | 120 
 drivers/net/ice/ice_generic_flow.h  |   6 +-
 drivers/net/ice/ice_switch_filter.c | 118 +--
 7 files changed, 40 insertions(+), 235 deletions(-)

diff --git a/doc/guides/nics/ice.rst b/doc/guides/nics/ice.rst
index c351c6bd74..5a47109c3f 100644
--- a/doc/guides/nics/ice.rst
+++ b/doc/guides/nics/ice.rst
@@ -90,25 +90,6 @@ Runtime Configuration
   NOTE: In Safe mode, only very limited features are available, features like 
RSS,
   checksum, fdir, tunneling ... are all disabled.
 
-- ``Generic Flow Pipeline Mode Support`` (default ``0``)
-
-  In pipeline mode, a flow can be set at one specific stage by setting 
parameter
-  ``priority``. Currently, we support two stages: priority = 0 or !0. Flows 
with
-  priority 0 located at the first pipeline stage which typically be used as a 
firewall
-  to drop the packet on a blocklist(we called it permission stage). At this 
stage,
-  flow rules are created for the device's exact match engine: switch. Flows 
with priority
-  !0 located at the second stage, typically packets are classified here and be 
steered to
-  specific queue or queue group (we called it distribution stage), At this 
stage, flow
-  rules are created for device's flow director engine.
-  For none-pipeline mode, ``priority`` is ignored, a flow rule can be created 
as a flow director
-  rule or a switch rule depends on its pattern/action and the resource 
allocation situation,
-  all flows are virtually at the same pipeline stage.
-  By default, generic flow API is enabled in none-pipeline mode, user can 
choose to
-  use pipeline mode by setting ``devargs`` parameter ``pipeline-mode-support``,
-  for example::
-
--a 80:00.0,pipeline-mode-support=1
-
 - ``Default MAC Disable`` (default ``0``)
 
   Disable the default MAC make the device drop all packets by default,
diff --git a/drivers/net/ice/ice_ethdev.c b/drivers/net/ice/ice_ethdev.c
index 4bad39c2c1..036b068c22 100644
--- a/drivers/net/ice/ice_ethdev.c
+++ b/drivers/net/ice/ice_ethdev.c
@@ -27,7 +27,6 @@
 
 /* devargs */
 #define ICE_SAFE_MODE_SUPPORT_ARG "safe-mode-support"
-#define ICE_PIPELINE_MODE_SUPPORT_ARG  "pipeline-mode-support"
 #define ICE_DEFAULT_MAC_DISABLE   "default-mac-disable"
 #define ICE_PROTO_XTR_ARG "proto_xtr"
 #define ICE_FIELD_OFFS_ARG   "field_offs"
@@ -43,7 +42,6 @@ int ice_timestamp_dynfield_offset = -1;
 
 static const char * const ice_valid_args[] = {
ICE_SAFE_MODE_SUPPORT_ARG,
-   ICE_PIPELINE_MODE_SUPPORT_ARG,
ICE_PROTO_XTR_ARG,
ICE_FIELD_OFFS_ARG,
ICE_FIELD_NAME_ARG,
@@ -2103,11 +2101,6 @@ static int ice_parse_devargs(struct rte_eth_dev *dev)
if (ret)
goto bail;
 
-   ret = rte_kvargs_process(kvlist, ICE_PIPELINE_MODE_SUPPORT_ARG,
-&parse_bool, &ad->devargs.pipe_mode_support);
-   if (ret)
-   goto bail;
-
ret = rte_kvargs_process(kvlist, ICE_DEFAULT_MAC_DISABLE,
&parse_bool, &ad->devargs.default_mac_disable);
if (ret)
@@ -6549,7 +6542,6 @@ RTE_PMD_REGISTER_PARAM_STRING(net_ice,
  ICE_HW_DEBUG_MASK_ARG "=0xXXX"
  ICE_PROTO_XTR_ARG 
"=[queue:]"
  ICE_SAFE_MODE_SUPPORT_ARG "=<0|1>"
- ICE_PIPELINE_MODE_SUPPORT_ARG "=<0|1>"
  ICE_DEFAULT_MAC_DISABLE "=<0|1>"
  ICE_RX_LOW_LATENCY_ARG "=<0|1>");
 
diff --git a/drivers/net/ice/ice_ethdev.h b/drivers/net/ice/ice_ethdev.h
index 9789cb8525..1f88becd19 100644
--- a/drivers/net/ice/ice_ethdev.h
+++ b/drivers/net/ice/ice_ethdev.h
@@ -542,7 +542,6 @@ struct ice_pf {
struct ice_flow_list flow_list;
rte_spinlock_t flow_ops_lock;
struct ice_parser_list rss_parser_list;
-   struct ice_parser_list perm_parser_list;
struct ice_parser_list dist_parser_list;
bool init_link_up;

[PATCH v2 0/2] refactor rte_flow

2023-09-11 Thread Qi Zhang
1. remove pipeline mode
2. apply group to hardware pipeline stage static mapping

v2:
- fix segment fault when an unintialized engine has been selected.

Qi Zhang (2):
  net/ice: remove pipeline mode
  net/ice: map group to pipeline stage

 doc/guides/nics/ice.rst |  19 ---
 drivers/net/ice/ice_acl_filter.c|  13 +-
 drivers/net/ice/ice_ethdev.c|   8 -
 drivers/net/ice/ice_ethdev.h|   4 -
 drivers/net/ice/ice_fdir_filter.c   |  21 +--
 drivers/net/ice/ice_generic_flow.c  | 252 ++--
 drivers/net/ice/ice_generic_flow.h  |  15 +-
 drivers/net/ice/ice_hash.c  |  19 +--
 drivers/net/ice/ice_switch_filter.c | 127 +-
 9 files changed, 72 insertions(+), 406 deletions(-)

-- 
2.31.1



[PATCH 2/2] net/ice: map group to pipeline stage

2023-08-14 Thread Qi Zhang
Mapping rte_flow_attr->group to a specific hardware stage.

Group 0 -> switch filter
Group 1 -> acl filter
Group 2 -> fdir filter

For RSS, it will only be selected if there is a RTE_FLOW_ACTION_RSS
action target no queue group and the group ID is ignored.

Since each flow parser will be selected based on the group, there is no
need to maintain a separate 'parser list' or related APIs for
registering/unregistering parsers.

Signed-off-by: Qi Zhang 
---
 drivers/net/ice/ice_acl_filter.c|  13 +-
 drivers/net/ice/ice_ethdev.h|   2 -
 drivers/net/ice/ice_fdir_filter.c   |  19 +--
 drivers/net/ice/ice_generic_flow.c  | 187 +++-
 drivers/net/ice/ice_generic_flow.h  |   9 +-
 drivers/net/ice/ice_hash.c  |  19 +--
 drivers/net/ice/ice_switch_filter.c |  13 +-
 7 files changed, 61 insertions(+), 201 deletions(-)

diff --git a/drivers/net/ice/ice_acl_filter.c b/drivers/net/ice/ice_acl_filter.c
index f2ddbd7b9b..d79044732a 100644
--- a/drivers/net/ice/ice_acl_filter.c
+++ b/drivers/net/ice/ice_acl_filter.c
@@ -41,8 +41,6 @@
ICE_ACL_INSET_ETH_IPV4 | \
ICE_INSET_SCTP_SRC_PORT | ICE_INSET_SCTP_DST_PORT)
 
-static struct ice_flow_parser ice_acl_parser;
-
 struct acl_rule {
enum ice_fltr_ptype flow_type;
uint64_t entry_id[4];
@@ -993,7 +991,6 @@ ice_acl_init(struct ice_adapter *ad)
int ret = 0;
struct ice_pf *pf = &ad->pf;
struct ice_hw *hw = ICE_PF_TO_HW(pf);
-   struct ice_flow_parser *parser = &ice_acl_parser;
 
if (!ad->hw.dcf_enabled)
return 0;
@@ -1013,11 +1010,7 @@ ice_acl_init(struct ice_adapter *ad)
if (ret)
return ret;
 
-   ret = ice_acl_prof_init(pf);
-   if (ret)
-   return ret;
-
-   return ice_register_parser(parser, ad);
+   return ice_acl_prof_init(pf);
 }
 
 static void
@@ -1040,10 +1033,8 @@ ice_acl_uninit(struct ice_adapter *ad)
 {
struct ice_pf *pf = &ad->pf;
struct ice_hw *hw = ICE_PF_TO_HW(pf);
-   struct ice_flow_parser *parser = &ice_acl_parser;
 
if (ad->hw.dcf_enabled) {
-   ice_unregister_parser(parser, ad);
ice_deinit_acl(pf);
ice_acl_prof_free(hw);
}
@@ -1059,7 +1050,7 @@ ice_flow_engine ice_acl_engine = {
.type = ICE_FLOW_ENGINE_ACL,
 };
 
-static struct
+struct
 ice_flow_parser ice_acl_parser = {
.engine = &ice_acl_engine,
.array = ice_acl_pattern,
diff --git a/drivers/net/ice/ice_ethdev.h b/drivers/net/ice/ice_ethdev.h
index 3328c66824..1b6b7f9909 100644
--- a/drivers/net/ice/ice_ethdev.h
+++ b/drivers/net/ice/ice_ethdev.h
@@ -541,8 +541,6 @@ struct ice_pf {
bool adapter_stopped;
struct ice_flow_list flow_list;
rte_spinlock_t flow_ops_lock;
-   struct ice_parser_list rss_parser_list;
-   struct ice_parser_list dist_parser_list;
bool init_link_up;
uint64_t old_rx_bytes;
uint64_t old_tx_bytes;
diff --git a/drivers/net/ice/ice_fdir_filter.c 
b/drivers/net/ice/ice_fdir_filter.c
index e9ee5a57d6..9ce243cc9c 100644
--- a/drivers/net/ice/ice_fdir_filter.c
+++ b/drivers/net/ice/ice_fdir_filter.c
@@ -137,8 +137,6 @@ static struct ice_pattern_match_item 
ice_fdir_pattern_list[] = {
{pattern_eth_ipv6_gtpu_eh,  
ICE_FDIR_INSET_IPV6_GTPU_EH,ICE_FDIR_INSET_IPV6_GTPU_EH,ICE_INSET_NONE},
 };
 
-static struct ice_flow_parser ice_fdir_parser;
-
 static int
 ice_fdir_is_tunnel_profile(enum ice_fdir_tunnel_type tunnel_type);
 
@@ -1147,34 +1145,21 @@ static int
 ice_fdir_init(struct ice_adapter *ad)
 {
struct ice_pf *pf = &ad->pf;
-   struct ice_flow_parser *parser;
-   int ret;
 
if (ad->hw.dcf_enabled)
return 0;
 
-   ret = ice_fdir_setup(pf);
-   if (ret)
-   return ret;
-
-   parser = &ice_fdir_parser;
-
-   return ice_register_parser(parser, ad);
+   return ice_fdir_setup(pf);
 }
 
 static void
 ice_fdir_uninit(struct ice_adapter *ad)
 {
-   struct ice_flow_parser *parser;
struct ice_pf *pf = &ad->pf;
 
if (ad->hw.dcf_enabled)
return;
 
-   parser = &ice_fdir_parser;
-
-   ice_unregister_parser(parser, ad);
-
ice_fdir_teardown(pf);
 }
 
@@ -2510,7 +2495,7 @@ ice_fdir_parse(struct ice_adapter *ad,
return ret;
 }
 
-static struct ice_flow_parser ice_fdir_parser = {
+struct ice_flow_parser ice_fdir_parser = {
.engine = &ice_fdir_engine,
.array = ice_fdir_pattern_list,
.array_len = RTE_DIM(ice_fdir_pattern_list),
diff --git a/drivers/net/ice/ice_generic_flow.c 
b/drivers/net/ice/ice_generic_flow.c
index 6695457bbd..af52dd539c 100644
--- a/drivers/net/ice/ice_generic_flow.c
+++ b/drivers/net/ice/ice_generic_flow.c
@@ -1797,7 +1797,7 @@ enum rte_flow_item_type pattern_eth_ipv6_pfcp[] = {
 
 typedef str

[PATCH 1/2] net/ice: remove pipeline mode

2023-08-14 Thread Qi Zhang
This marks the initial phase of refactoring the ice rte_flow
implementation.

The combination of switch and fdir rules within the same syntax has led
to inconvenient user experiences. Naturally, the switch filter and fdir
filter represent distinct pipeline stages with differing hardware
capabilities.

To address this, we have made the decision to assign each stage to a
separate rte_flow group. This will allow users to clearly specify their
intentions when creating a rule. Consequently, the need for a pipeline
mode can be removed.

Signed-off-by: Qi Zhang 
---
 doc/guides/nics/ice.rst |  19 -
 drivers/net/ice/ice_ethdev.c|   8 --
 drivers/net/ice/ice_ethdev.h|   2 -
 drivers/net/ice/ice_fdir_filter.c   |   2 +-
 drivers/net/ice/ice_generic_flow.c  | 120 
 drivers/net/ice/ice_generic_flow.h  |   6 +-
 drivers/net/ice/ice_switch_filter.c | 118 +--
 7 files changed, 40 insertions(+), 235 deletions(-)

diff --git a/doc/guides/nics/ice.rst b/doc/guides/nics/ice.rst
index c351c6bd74..5a47109c3f 100644
--- a/doc/guides/nics/ice.rst
+++ b/doc/guides/nics/ice.rst
@@ -90,25 +90,6 @@ Runtime Configuration
   NOTE: In Safe mode, only very limited features are available, features like 
RSS,
   checksum, fdir, tunneling ... are all disabled.
 
-- ``Generic Flow Pipeline Mode Support`` (default ``0``)
-
-  In pipeline mode, a flow can be set at one specific stage by setting 
parameter
-  ``priority``. Currently, we support two stages: priority = 0 or !0. Flows 
with
-  priority 0 located at the first pipeline stage which typically be used as a 
firewall
-  to drop the packet on a blocklist(we called it permission stage). At this 
stage,
-  flow rules are created for the device's exact match engine: switch. Flows 
with priority
-  !0 located at the second stage, typically packets are classified here and be 
steered to
-  specific queue or queue group (we called it distribution stage), At this 
stage, flow
-  rules are created for device's flow director engine.
-  For none-pipeline mode, ``priority`` is ignored, a flow rule can be created 
as a flow director
-  rule or a switch rule depends on its pattern/action and the resource 
allocation situation,
-  all flows are virtually at the same pipeline stage.
-  By default, generic flow API is enabled in none-pipeline mode, user can 
choose to
-  use pipeline mode by setting ``devargs`` parameter ``pipeline-mode-support``,
-  for example::
-
--a 80:00.0,pipeline-mode-support=1
-
 - ``Default MAC Disable`` (default ``0``)
 
   Disable the default MAC make the device drop all packets by default,
diff --git a/drivers/net/ice/ice_ethdev.c b/drivers/net/ice/ice_ethdev.c
index 4bad39c2c1..036b068c22 100644
--- a/drivers/net/ice/ice_ethdev.c
+++ b/drivers/net/ice/ice_ethdev.c
@@ -27,7 +27,6 @@
 
 /* devargs */
 #define ICE_SAFE_MODE_SUPPORT_ARG "safe-mode-support"
-#define ICE_PIPELINE_MODE_SUPPORT_ARG  "pipeline-mode-support"
 #define ICE_DEFAULT_MAC_DISABLE   "default-mac-disable"
 #define ICE_PROTO_XTR_ARG "proto_xtr"
 #define ICE_FIELD_OFFS_ARG   "field_offs"
@@ -43,7 +42,6 @@ int ice_timestamp_dynfield_offset = -1;
 
 static const char * const ice_valid_args[] = {
ICE_SAFE_MODE_SUPPORT_ARG,
-   ICE_PIPELINE_MODE_SUPPORT_ARG,
ICE_PROTO_XTR_ARG,
ICE_FIELD_OFFS_ARG,
ICE_FIELD_NAME_ARG,
@@ -2103,11 +2101,6 @@ static int ice_parse_devargs(struct rte_eth_dev *dev)
if (ret)
goto bail;
 
-   ret = rte_kvargs_process(kvlist, ICE_PIPELINE_MODE_SUPPORT_ARG,
-&parse_bool, &ad->devargs.pipe_mode_support);
-   if (ret)
-   goto bail;
-
ret = rte_kvargs_process(kvlist, ICE_DEFAULT_MAC_DISABLE,
&parse_bool, &ad->devargs.default_mac_disable);
if (ret)
@@ -6549,7 +6542,6 @@ RTE_PMD_REGISTER_PARAM_STRING(net_ice,
  ICE_HW_DEBUG_MASK_ARG "=0xXXX"
  ICE_PROTO_XTR_ARG 
"=[queue:]"
  ICE_SAFE_MODE_SUPPORT_ARG "=<0|1>"
- ICE_PIPELINE_MODE_SUPPORT_ARG "=<0|1>"
  ICE_DEFAULT_MAC_DISABLE "=<0|1>"
  ICE_RX_LOW_LATENCY_ARG "=<0|1>");
 
diff --git a/drivers/net/ice/ice_ethdev.h b/drivers/net/ice/ice_ethdev.h
index f925231f34..3328c66824 100644
--- a/drivers/net/ice/ice_ethdev.h
+++ b/drivers/net/ice/ice_ethdev.h
@@ -542,7 +542,6 @@ struct ice_pf {
struct ice_flow_list flow_list;
rte_spinlock_t flow_ops_lock;
struct ice_parser_list rss_parser_list;
-   struct ice_parser_list perm_parser_list;
struct ice_parser_list dist_parser_list;
bool init_link_up;

[PATCH 0/2] refactor rte_flow

2023-08-14 Thread Qi Zhang
1. apply group to hardware pipeline stage static mapping 
2. remove pipeline mode

Qi Zhang (2):
  net/ice: remove pipeline mode
  net/ice: map group to pipeline stage

 doc/guides/nics/ice.rst |  19 ---
 drivers/net/ice/ice_acl_filter.c|  13 +-
 drivers/net/ice/ice_ethdev.c|   8 -
 drivers/net/ice/ice_ethdev.h|   4 -
 drivers/net/ice/ice_fdir_filter.c   |  21 +--
 drivers/net/ice/ice_generic_flow.c  | 251 ++--
 drivers/net/ice/ice_generic_flow.h  |  15 +-
 drivers/net/ice/ice_hash.c  |  19 +--
 drivers/net/ice/ice_switch_filter.c | 127 +-
 9 files changed, 71 insertions(+), 406 deletions(-)

-- 
2.31.1



[PATCH] ethdev: introduce generic flow item and action

2023-08-02 Thread Qi Zhang
From: Cristian Dumitrescu 

For network devices that are programmable through languages such as
the P4 language, there are no pre-defined flow items and actions.

The format of the protocol header and metadata fields that are used to
specify the flow items that make up the flow pattern, as well as the
flow actions, are all defined by the program, with an infinity of
possible combinations, as opposed to being selected from a finite
pre-defined list.

It is virtually impossible to pre-define all the flow items and the
flow actions that programs might ever use, as these are only limited
by the set of HW resources and the program developer's imagination.

To support the programmable network devices, we are introducing:

* A generic flow item: The flow item is expressed as an array of bytes
of a given length, whose meaning is defined by the program loaded by
the network device. The device is still expected to accept the
existing pre-defined flow items such as Ethernet, IPv4/IPv6 headers,
etc, as long as the program currently loaded on the device is defining
and using flow items with identical format, but the device is not
limited to the current set of pre-defined RTE_FLOW flow items.

* A generic flow action: The flow action exact processing is defined
by the program loaded by the network device, with the user expected to
know the set of program actions for the purpose of assigning actions
to flows. The device is still expected to accept the existing
pre-defined flow actions such as packet drop, packet redirection to
output queues, packet modifications, etc, as long as the program
currently loaded on the device is defining and using flow actions that
perform identical processing, but the device is not limited to the
current set of pre-defined RTE_FLOW flow actions.

Signed-off-by: Cristian Dumitrescu 
Signed-off-by: Qi Zhang 
---
 lib/ethdev/rte_flow.h | 82 +++
 1 file changed, 82 insertions(+)

diff --git a/lib/ethdev/rte_flow.h b/lib/ethdev/rte_flow.h
index 3fe57140f9..f7889d7dd0 100644
--- a/lib/ethdev/rte_flow.h
+++ b/lib/ethdev/rte_flow.h
@@ -688,6 +688,15 @@ enum rte_flow_item_type {
 * @see struct rte_flow_item_ib_bth.
 */
RTE_FLOW_ITEM_TYPE_IB_BTH,
+
+   /**
+* Matches a custom protocol header or metadata field represented
+* as a byte string of a given length, whose meaning is typically
+* defined by the data plane program.
+*
+* @see struct rte_flow_item_generic.
+*/
+   RTE_FLOW_ITEM_TYPE_GENERIC,
 };
 
 /**
@@ -2311,6 +2320,32 @@ static const struct rte_flow_item_tx_queue 
rte_flow_item_tx_queue_mask = {
 };
 #endif
 
+/**
+ * @warning
+ * @b EXPERIMENTAL: this structure may change without prior notice
+ *
+ * RTE_FLOW_ITEM_TYPE_GENERIC
+ *
+ * Matches a custom protocol header or metadata field represented as a byte
+ * array of a given length, whose meaning is typically defined by the data
+ * plane program.
+ *
+ * The field length must be non-zero. The field value must be non-NULL, with 
the
+ * value bytes specified in network byte order.
+ */
+struct rte_flow_item_generic {
+   uint32_t length; /**< Field length. */
+   const uint8_t *value; /**< Field value. */
+};
+
+/** Default mask for RTE_FLOW_ITEM_TYPE_GENERIC. */
+#ifndef __cplusplus
+static const struct rte_flow_item_generic rte_flow_item_generic_mask = {
+   .length = 0x,
+   .value = NULL,
+};
+#endif
+
 /**
  * Action types.
  *
@@ -2989,6 +3024,14 @@ enum rte_flow_action_type {
 * @see struct rte_flow_action_indirect_list
 */
RTE_FLOW_ACTION_TYPE_INDIRECT_LIST,
+
+   /**
+* Custom action whose processing is typically defined by the data plane
+* program.
+*
+* @see struct rte_flow_action_generic.
+*/
+   RTE_FLOW_ACTION_TYPE_GENERIC,
 };
 
 /**
@@ -4064,6 +4107,45 @@ struct rte_flow_indirect_update_flow_meter_mark {
enum rte_color init_color;
 };
 
+/**
+ * @warning
+ * @b EXPERIMENTAL: this structure may change without prior notice.
+ *
+ * Generic action argument configuration parameters.
+ *
+ * The action argument field length must be non-zero. The action argument field
+ * value must be non-NULL, with the value bytes specified in network byte 
order.
+ *
+ * @see struct rte_flow_action_generic
+ */
+struct rte_flow_action_generic_argument {
+   /** Argument field length. */
+   uint32_t length;
+   /** Argument field value. */
+   const uint8_t *value;
+};
+
+/**
+ * @warning
+ * @b EXPERIMENTAL: this structure may change without prior notice.
+ *
+ * RTE_FLOW_ACTION_TYPE_GENERIC
+ *
+ * Generic action configuration parameters.
+ *
+ * Each action can have zero or more arguments.
+ *
+ * @see RTE_FLOW_ACTION_TYPE_GENERIC
+ */
+struct rte_flow_action_generic {
+   /** Action ID. */
+   uint32_t action_id;
+   /** Number of action arguments. */
+   uint32_t acti

[PATCH] net/ice: init dvm mode for parser

2023-05-26 Thread Qi Zhang
Double Vlan mode need to be configured for parser
Otherwise parser result will not be consistent with hardware.

Fixes: 531d2555c8a6 ("net/ice: refactor parser usage")
Cc: sta...@dpdk.org

Signed-off-by: Qi Zhang 
---
 drivers/net/ice/ice_generic_flow.c | 5 +
 1 file changed, 5 insertions(+)

diff --git a/drivers/net/ice/ice_generic_flow.c 
b/drivers/net/ice/ice_generic_flow.c
index 86a32f8cb1..ed3075d555 100644
--- a/drivers/net/ice/ice_generic_flow.c
+++ b/drivers/net/ice/ice_generic_flow.c
@@ -1836,6 +1836,11 @@ ice_flow_init(struct ice_adapter *ad)
if (ice_parser_create(&ad->hw, &ad->psr) != ICE_SUCCESS)
PMD_INIT_LOG(WARNING, "Failed to initialize DDP parser, raw 
packet filter will not be supported");
 
+   if (ice_is_dvm_ena(&ad->hw))
+   ice_parser_dvm_set(ad->psr, true);
+   else
+   ice_parser_dvm_set(ad->psr, false);
+
RTE_TAILQ_FOREACH_SAFE(engine, &engine_list, node, temp) {
if (engine->init == NULL) {
PMD_INIT_LOG(ERR, "Invalid engine type (%d)",
-- 
2.31.1



[PATCH v2] net/ice: fix data length check

2023-05-22 Thread Qi Zhang
In TSO, It is possible mbuf->data_len exceed mtu.
Fixed the incorrect data length check in ice_prep_pkts.

Fixes: ccf33dccf7aa ("net/ice: check illegal packet sizes")
Cc: sta...@dpdk.org

Signed-off-by: Qi Zhang 
---
v2:
- fix build warning

 drivers/net/ice/ice_rxtx.c | 5 +
 1 file changed, 1 insertion(+), 4 deletions(-)

diff --git a/drivers/net/ice/ice_rxtx.c b/drivers/net/ice/ice_rxtx.c
index 560c1a4af7..cd0e61c85f 100644
--- a/drivers/net/ice/ice_rxtx.c
+++ b/drivers/net/ice/ice_rxtx.c
@@ -3669,9 +3669,6 @@ ice_prep_pkts(__rte_unused void *tx_queue, struct 
rte_mbuf **tx_pkts,
int i, ret;
uint64_t ol_flags;
struct rte_mbuf *m;
-   struct ice_tx_queue *txq = tx_queue;
-   struct rte_eth_dev *dev = &rte_eth_devices[txq->port_id];
-   uint16_t max_frame_size = dev->data->mtu + ICE_ETH_OVERHEAD;
 
for (i = 0; i < nb_pkts; i++) {
m = tx_pkts[i];
@@ -3690,7 +3687,7 @@ ice_prep_pkts(__rte_unused void *tx_queue, struct 
rte_mbuf **tx_pkts,
 
/* check the data_len in mbuf */
if (m->data_len < ICE_TX_MIN_PKT_LEN ||
-   m->data_len > max_frame_size) {
+   m->data_len > ICE_FRAME_SIZE_MAX) {
rte_errno = EINVAL;
PMD_DRV_LOG(ERR, "INVALID mbuf: bad data_len=[%hu]", 
m->data_len);
return i;
-- 
2.31.1



[PATCH] net/ice: fix data length check

2023-05-22 Thread Qi Zhang
In TSO, It is possible mbuf->data_len exceed mtu.
Fixed the incorrect data length check in ice_prep_pkts.

Fixes: ccf33dccf7aa ("net/ice: check illegal packet sizes")
Cc: sta...@dpdk.org

Signed-off-by: Qi Zhang 
---
 drivers/net/ice/ice_rxtx.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/drivers/net/ice/ice_rxtx.c b/drivers/net/ice/ice_rxtx.c
index 560c1a4af7..f4a4f43636 100644
--- a/drivers/net/ice/ice_rxtx.c
+++ b/drivers/net/ice/ice_rxtx.c
@@ -3671,7 +3671,6 @@ ice_prep_pkts(__rte_unused void *tx_queue, struct 
rte_mbuf **tx_pkts,
struct rte_mbuf *m;
struct ice_tx_queue *txq = tx_queue;
struct rte_eth_dev *dev = &rte_eth_devices[txq->port_id];
-   uint16_t max_frame_size = dev->data->mtu + ICE_ETH_OVERHEAD;
 
for (i = 0; i < nb_pkts; i++) {
m = tx_pkts[i];
@@ -3690,7 +3689,7 @@ ice_prep_pkts(__rte_unused void *tx_queue, struct 
rte_mbuf **tx_pkts,
 
/* check the data_len in mbuf */
if (m->data_len < ICE_TX_MIN_PKT_LEN ||
-   m->data_len > max_frame_size) {
+   m->data_len > ICE_FRAME_SIZE_MAX) {
rte_errno = EINVAL;
PMD_DRV_LOG(ERR, "INVALID mbuf: bad data_len=[%hu]", 
m->data_len);
return i;
-- 
2.31.1



[PATCH v2] common/idpf: remove unnecessary compile option

2023-04-26 Thread Qi Zhang
Remove compile option "__KERNEL" which should not be considered in
DPDK. Also only #include  in idpf_osdep.h.

Signed-off-by: Qi Zhang 
---
v2:
- add fallthrough comment back

 drivers/common/idpf/base/idpf_controlq.c | 4 
 drivers/common/idpf/base/idpf_controlq.h | 8 
 drivers/common/idpf/base/idpf_controlq_api.h | 6 --
 drivers/common/idpf/base/idpf_lan_txrx.h | 3 +--
 drivers/common/idpf/base/idpf_osdep.h| 1 +
 5 files changed, 2 insertions(+), 20 deletions(-)

diff --git a/drivers/common/idpf/base/idpf_controlq.c 
b/drivers/common/idpf/base/idpf_controlq.c
index 3af81e5a64..8adc727926 100644
--- a/drivers/common/idpf/base/idpf_controlq.c
+++ b/drivers/common/idpf/base/idpf_controlq.c
@@ -162,11 +162,7 @@ int idpf_ctlq_add(struct idpf_hw *hw,
switch (qinfo->type) {
case IDPF_CTLQ_TYPE_MAILBOX_RX:
is_rxq = true;
-#ifdef __KERNEL__
-   fallthrough;
-#else
/* fallthrough */
-#endif /* __KERNEL__ */
case IDPF_CTLQ_TYPE_MAILBOX_TX:
status = idpf_ctlq_alloc_ring_res(hw, *cq_out);
break;
diff --git a/drivers/common/idpf/base/idpf_controlq.h 
b/drivers/common/idpf/base/idpf_controlq.h
index e7b0d803b3..fea8dda618 100644
--- a/drivers/common/idpf/base/idpf_controlq.h
+++ b/drivers/common/idpf/base/idpf_controlq.h
@@ -5,14 +5,8 @@
 #ifndef _IDPF_CONTROLQ_H_
 #define _IDPF_CONTROLQ_H_
 
-#ifdef __KERNEL__
-#include 
-#endif
-
-#ifndef __KERNEL__
 #include "idpf_osdep.h"
 #include "idpf_alloc.h"
-#endif
 #include "idpf_controlq_api.h"
 
 /* Maximum buffer lengths for all control queue types */
@@ -26,14 +20,12 @@
((u16)R)->next_to_clean > (R)->next_to_use) ? 0 : (R)->ring_size) + 
\
   (R)->next_to_clean - (R)->next_to_use - 1))
 
-#ifndef __KERNEL__
 /* Data type manipulation macros. */
 #define IDPF_HI_DWORD(x)   ((u32)x) >> 16) >> 16) & 0x))
 #define IDPF_LO_DWORD(x)   ((u32)((x) & 0x))
 #define IDPF_HI_WORD(x)((u16)(((x) >> 16) & 0x))
 #define IDPF_LO_WORD(x)((u16)((x) & 0x))
 
-#endif
 /* Control Queue default settings */
 #define IDPF_CTRL_SQ_CMD_TIMEOUT   250  /* msecs */
 
diff --git a/drivers/common/idpf/base/idpf_controlq_api.h 
b/drivers/common/idpf/base/idpf_controlq_api.h
index 32d17baadf..e80debebb8 100644
--- a/drivers/common/idpf/base/idpf_controlq_api.h
+++ b/drivers/common/idpf/base/idpf_controlq_api.h
@@ -5,14 +5,8 @@
 #ifndef _IDPF_CONTROLQ_API_H_
 #define _IDPF_CONTROLQ_API_H_
 
-#ifdef __KERNEL__
-#include "idpf_mem.h"
-#else /* !__KERNEL__ */
 #include "idpf_osdep.h"
 
-#include 
-#endif /* !__KERNEL__ */
-
 struct idpf_hw;
 
 /* Used for queue init, response and events */
diff --git a/drivers/common/idpf/base/idpf_lan_txrx.h 
b/drivers/common/idpf/base/idpf_lan_txrx.h
index 98484b267c..2d635a0b9c 100644
--- a/drivers/common/idpf/base/idpf_lan_txrx.h
+++ b/drivers/common/idpf/base/idpf_lan_txrx.h
@@ -4,9 +4,8 @@
 
 #ifndef _IDPF_LAN_TXRX_H_
 #define _IDPF_LAN_TXRX_H_
-#ifndef __KERNEL__
+
 #include "idpf_osdep.h"
-#endif
 
 enum idpf_rss_hash {
/* Values 0 - 28 are reserved for future use */
diff --git a/drivers/common/idpf/base/idpf_osdep.h 
b/drivers/common/idpf/base/idpf_osdep.h
index 49bd7c4b21..3703421575 100644
--- a/drivers/common/idpf/base/idpf_osdep.h
+++ b/drivers/common/idpf/base/idpf_osdep.h
@@ -23,6 +23,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #define INLINE inline
 #define STATIC static
-- 
2.31.1



[PATCH] common/idpf: remove unnecessary compile option

2023-04-24 Thread Qi Zhang
Remove compile option "__KERNEL" which should not be considered in
DPDK. Also only #include  in idpf_osdep.h.

Signed-off-by: Qi Zhang 
---
 drivers/common/idpf/base/idpf_controlq.c | 5 -
 drivers/common/idpf/base/idpf_controlq.h | 8 
 drivers/common/idpf/base/idpf_controlq_api.h | 6 --
 drivers/common/idpf/base/idpf_lan_txrx.h | 3 +--
 drivers/common/idpf/base/idpf_osdep.h| 1 +
 5 files changed, 2 insertions(+), 21 deletions(-)

diff --git a/drivers/common/idpf/base/idpf_controlq.c 
b/drivers/common/idpf/base/idpf_controlq.c
index 3af81e5a64..93a3a20fd1 100644
--- a/drivers/common/idpf/base/idpf_controlq.c
+++ b/drivers/common/idpf/base/idpf_controlq.c
@@ -162,11 +162,6 @@ int idpf_ctlq_add(struct idpf_hw *hw,
switch (qinfo->type) {
case IDPF_CTLQ_TYPE_MAILBOX_RX:
is_rxq = true;
-#ifdef __KERNEL__
-   fallthrough;
-#else
-   /* fallthrough */
-#endif /* __KERNEL__ */
case IDPF_CTLQ_TYPE_MAILBOX_TX:
status = idpf_ctlq_alloc_ring_res(hw, *cq_out);
break;
diff --git a/drivers/common/idpf/base/idpf_controlq.h 
b/drivers/common/idpf/base/idpf_controlq.h
index e7b0d803b3..fea8dda618 100644
--- a/drivers/common/idpf/base/idpf_controlq.h
+++ b/drivers/common/idpf/base/idpf_controlq.h
@@ -5,14 +5,8 @@
 #ifndef _IDPF_CONTROLQ_H_
 #define _IDPF_CONTROLQ_H_
 
-#ifdef __KERNEL__
-#include 
-#endif
-
-#ifndef __KERNEL__
 #include "idpf_osdep.h"
 #include "idpf_alloc.h"
-#endif
 #include "idpf_controlq_api.h"
 
 /* Maximum buffer lengths for all control queue types */
@@ -26,14 +20,12 @@
((u16)R)->next_to_clean > (R)->next_to_use) ? 0 : (R)->ring_size) + 
\
   (R)->next_to_clean - (R)->next_to_use - 1))
 
-#ifndef __KERNEL__
 /* Data type manipulation macros. */
 #define IDPF_HI_DWORD(x)   ((u32)x) >> 16) >> 16) & 0x))
 #define IDPF_LO_DWORD(x)   ((u32)((x) & 0x))
 #define IDPF_HI_WORD(x)((u16)(((x) >> 16) & 0x))
 #define IDPF_LO_WORD(x)((u16)((x) & 0x))
 
-#endif
 /* Control Queue default settings */
 #define IDPF_CTRL_SQ_CMD_TIMEOUT   250  /* msecs */
 
diff --git a/drivers/common/idpf/base/idpf_controlq_api.h 
b/drivers/common/idpf/base/idpf_controlq_api.h
index 32d17baadf..e80debebb8 100644
--- a/drivers/common/idpf/base/idpf_controlq_api.h
+++ b/drivers/common/idpf/base/idpf_controlq_api.h
@@ -5,14 +5,8 @@
 #ifndef _IDPF_CONTROLQ_API_H_
 #define _IDPF_CONTROLQ_API_H_
 
-#ifdef __KERNEL__
-#include "idpf_mem.h"
-#else /* !__KERNEL__ */
 #include "idpf_osdep.h"
 
-#include 
-#endif /* !__KERNEL__ */
-
 struct idpf_hw;
 
 /* Used for queue init, response and events */
diff --git a/drivers/common/idpf/base/idpf_lan_txrx.h 
b/drivers/common/idpf/base/idpf_lan_txrx.h
index 98484b267c..2d635a0b9c 100644
--- a/drivers/common/idpf/base/idpf_lan_txrx.h
+++ b/drivers/common/idpf/base/idpf_lan_txrx.h
@@ -4,9 +4,8 @@
 
 #ifndef _IDPF_LAN_TXRX_H_
 #define _IDPF_LAN_TXRX_H_
-#ifndef __KERNEL__
+
 #include "idpf_osdep.h"
-#endif
 
 enum idpf_rss_hash {
/* Values 0 - 28 are reserved for future use */
diff --git a/drivers/common/idpf/base/idpf_osdep.h 
b/drivers/common/idpf/base/idpf_osdep.h
index 99ae9cf60a..78049e25b4 100644
--- a/drivers/common/idpf/base/idpf_osdep.h
+++ b/drivers/common/idpf/base/idpf_osdep.h
@@ -23,6 +23,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #define INLINE inline
 #define STATIC static
-- 
2.31.1



[PATCH] common/idpf: refine header file include

2023-04-24 Thread Qi Zhang
Replace #include  with #include "filename" for
local header file.

Signed-off-by: Qi Zhang 
---
 drivers/common/idpf/idpf_common_device.c  | 4 ++--
 drivers/common/idpf/idpf_common_device.h  | 6 +++---
 drivers/common/idpf/idpf_common_rxtx_avx512.c | 4 ++--
 drivers/common/idpf/idpf_common_virtchnl.c| 4 ++--
 drivers/common/idpf/idpf_common_virtchnl.h| 4 ++--
 5 files changed, 11 insertions(+), 11 deletions(-)

diff --git a/drivers/common/idpf/idpf_common_device.c 
b/drivers/common/idpf/idpf_common_device.c
index c5e7bbf66c..98029c9826 100644
--- a/drivers/common/idpf/idpf_common_device.c
+++ b/drivers/common/idpf/idpf_common_device.c
@@ -3,8 +3,8 @@
  */
 
 #include 
-#include 
-#include 
+#include "idpf_common_device.h"
+#include "idpf_common_virtchnl.h"
 
 static void
 idpf_reset_pf(struct idpf_hw *hw)
diff --git a/drivers/common/idpf/idpf_common_device.h 
b/drivers/common/idpf/idpf_common_device.h
index c2dc2f16b9..08e2517b3e 100644
--- a/drivers/common/idpf/idpf_common_device.h
+++ b/drivers/common/idpf/idpf_common_device.h
@@ -6,9 +6,9 @@
 #define _IDPF_COMMON_DEVICE_H_
 
 #include 
-#include 
-#include 
-#include 
+#include "base/idpf_prototype.h"
+#include "base/virtchnl2.h"
+#include "idpf_common_logs.h"
 
 #define IDPF_RSS_KEY_LEN   52
 
diff --git a/drivers/common/idpf/idpf_common_rxtx_avx512.c 
b/drivers/common/idpf/idpf_common_rxtx_avx512.c
index ee68e6a1f7..dffb11fcf2 100644
--- a/drivers/common/idpf/idpf_common_rxtx_avx512.c
+++ b/drivers/common/idpf/idpf_common_rxtx_avx512.c
@@ -3,8 +3,8 @@
  */
 
 #include 
-#include 
-#include 
+#include "idpf_common_device.h"
+#include "idpf_common_rxtx.h"
 
 #ifndef __INTEL_COMPILER
 #pragma GCC diagnostic ignored "-Wcast-qual"
diff --git a/drivers/common/idpf/idpf_common_virtchnl.c 
b/drivers/common/idpf/idpf_common_virtchnl.c
index 9ee7259539..b96cf8fdcc 100644
--- a/drivers/common/idpf/idpf_common_virtchnl.c
+++ b/drivers/common/idpf/idpf_common_virtchnl.c
@@ -2,8 +2,8 @@
  * Copyright(c) 2023 Intel Corporation
  */
 
-#include 
-#include 
+#include "idpf_common_virtchnl.h"
+#include "idpf_common_logs.h"
 
 static int
 idpf_vc_clean(struct idpf_adapter *adapter)
diff --git a/drivers/common/idpf/idpf_common_virtchnl.h 
b/drivers/common/idpf/idpf_common_virtchnl.h
index d479d93c8e..c45295290e 100644
--- a/drivers/common/idpf/idpf_common_virtchnl.h
+++ b/drivers/common/idpf/idpf_common_virtchnl.h
@@ -5,8 +5,8 @@
 #ifndef _IDPF_COMMON_VIRTCHNL_H_
 #define _IDPF_COMMON_VIRTCHNL_H_
 
-#include 
-#include 
+#include "idpf_common_device.h"
+#include "idpf_common_rxtx.h"
 
 __rte_internal
 int idpf_vc_api_version_check(struct idpf_adapter *adapter);
-- 
2.31.1



[PATCH] common/idpf: remove unnecessary field in vport

2023-04-20 Thread Qi Zhang
Remove the pointer to rte_eth_dev instance, as
1. there is already a pointer to  rte_eth_dev_data.
2. a pointer to rte_eth_dev will break multi-process usage.

Signed-off-by: Qi Zhang 
---
 drivers/common/idpf/idpf_common_device.h | 1 -
 drivers/net/cpfl/cpfl_ethdev.c   | 4 ++--
 drivers/net/idpf/idpf_ethdev.c   | 4 ++--
 3 files changed, 4 insertions(+), 5 deletions(-)

diff --git a/drivers/common/idpf/idpf_common_device.h 
b/drivers/common/idpf/idpf_common_device.h
index 7a54f7c937..d29bcc71ab 100644
--- a/drivers/common/idpf/idpf_common_device.h
+++ b/drivers/common/idpf/idpf_common_device.h
@@ -117,7 +117,6 @@ struct idpf_vport {
 
struct virtchnl2_vport_stats eth_stats_offset;
 
-   void *dev;
/* Event from ipf */
bool link_up;
uint32_t link_speed;
diff --git a/drivers/net/cpfl/cpfl_ethdev.c b/drivers/net/cpfl/cpfl_ethdev.c
index f1d4425ce2..680c2326ec 100644
--- a/drivers/net/cpfl/cpfl_ethdev.c
+++ b/drivers/net/cpfl/cpfl_ethdev.c
@@ -1061,7 +1061,8 @@ static void
 cpfl_handle_event_msg(struct idpf_vport *vport, uint8_t *msg, uint16_t msglen)
 {
struct virtchnl2_event *vc_event = (struct virtchnl2_event *)msg;
-   struct rte_eth_dev *dev = (struct rte_eth_dev *)vport->dev;
+   struct rte_eth_dev_data *data = vport->dev_data;
+   struct rte_eth_dev *dev = &rte_eth_devices[data->port_id];
 
if (msglen < sizeof(struct virtchnl2_event)) {
PMD_DRV_LOG(ERR, "Error event");
@@ -1245,7 +1246,6 @@ cpfl_dev_vport_init(struct rte_eth_dev *dev, void 
*init_params)
vport->adapter = &adapter->base;
vport->sw_idx = param->idx;
vport->devarg_id = param->devarg_id;
-   vport->dev = dev;
 
memset(&create_vport_info, 0, sizeof(create_vport_info));
ret = idpf_vport_info_init(vport, &create_vport_info);
diff --git a/drivers/net/idpf/idpf_ethdev.c b/drivers/net/idpf/idpf_ethdev.c
index e01eb3a2ec..38ad4e7ac0 100644
--- a/drivers/net/idpf/idpf_ethdev.c
+++ b/drivers/net/idpf/idpf_ethdev.c
@@ -1024,7 +1024,8 @@ static void
 idpf_handle_event_msg(struct idpf_vport *vport, uint8_t *msg, uint16_t msglen)
 {
struct virtchnl2_event *vc_event = (struct virtchnl2_event *)msg;
-   struct rte_eth_dev *dev = (struct rte_eth_dev *)vport->dev;
+   struct rte_eth_dev_data *data = vport->dev_data;
+   struct rte_eth_dev *dev = &rte_eth_devices[data->port_id];
 
if (msglen < sizeof(struct virtchnl2_event)) {
PMD_DRV_LOG(ERR, "Error event");
@@ -1235,7 +1236,6 @@ idpf_dev_vport_init(struct rte_eth_dev *dev, void 
*init_params)
vport->adapter = &adapter->base;
vport->sw_idx = param->idx;
vport->devarg_id = param->devarg_id;
-   vport->dev = dev;
 
memset(&create_vport_info, 0, sizeof(create_vport_info));
ret = idpf_vport_info_init(vport, &create_vport_info);
-- 
2.31.1



[PATCH] common/idpf: remove device stop flag

2023-04-20 Thread Qi Zhang
Remove device stop flag, as we already have dev->data-dev_started.
This also fixed the issue when close port directly without start it
first, some error message will be reported in dev_stop.

Fixes: 14aa6ed8f2ec ("net/idpf: support device start and stop")
Fixes: 1082a773a86b ("common/idpf: add vport structure")
Cc: sta...@dpdk.org

Signed-off-by: Qi Zhang 
---
 drivers/common/idpf/idpf_common_device.h | 2 --
 drivers/net/cpfl/cpfl_ethdev.c   | 6 +-
 drivers/net/idpf/idpf_ethdev.c   | 6 +-
 3 files changed, 2 insertions(+), 12 deletions(-)

diff --git a/drivers/common/idpf/idpf_common_device.h 
b/drivers/common/idpf/idpf_common_device.h
index c2dc2f16b9..7a54f7c937 100644
--- a/drivers/common/idpf/idpf_common_device.h
+++ b/drivers/common/idpf/idpf_common_device.h
@@ -110,8 +110,6 @@ struct idpf_vport {
 
uint16_t devarg_id;
 
-   bool stopped;
-
bool rx_vec_allowed;
bool tx_vec_allowed;
bool rx_use_avx512;
diff --git a/drivers/net/cpfl/cpfl_ethdev.c b/drivers/net/cpfl/cpfl_ethdev.c
index ede730fd50..f1d4425ce2 100644
--- a/drivers/net/cpfl/cpfl_ethdev.c
+++ b/drivers/net/cpfl/cpfl_ethdev.c
@@ -798,8 +798,6 @@ cpfl_dev_start(struct rte_eth_dev *dev)
if (cpfl_dev_stats_reset(dev))
PMD_DRV_LOG(ERR, "Failed to reset stats");
 
-   vport->stopped = 0;
-
return 0;
 
 err_vport:
@@ -817,7 +815,7 @@ cpfl_dev_stop(struct rte_eth_dev *dev)
 {
struct idpf_vport *vport = dev->data->dev_private;
 
-   if (vport->stopped == 1)
+   if (dev->data->dev_started == 0)
return 0;
 
idpf_vc_vport_ena_dis(vport, false);
@@ -828,8 +826,6 @@ cpfl_dev_stop(struct rte_eth_dev *dev)
 
idpf_vc_vectors_dealloc(vport);
 
-   vport->stopped = 1;
-
return 0;
 }
 
diff --git a/drivers/net/idpf/idpf_ethdev.c b/drivers/net/idpf/idpf_ethdev.c
index e02ec2ec5a..e01eb3a2ec 100644
--- a/drivers/net/idpf/idpf_ethdev.c
+++ b/drivers/net/idpf/idpf_ethdev.c
@@ -792,8 +792,6 @@ idpf_dev_start(struct rte_eth_dev *dev)
if (idpf_dev_stats_reset(dev))
PMD_DRV_LOG(ERR, "Failed to reset stats");
 
-   vport->stopped = 0;
-
return 0;
 
 err_vport:
@@ -811,7 +809,7 @@ idpf_dev_stop(struct rte_eth_dev *dev)
 {
struct idpf_vport *vport = dev->data->dev_private;
 
-   if (vport->stopped == 1)
+   if (dev->data->dev_started == 0)
return 0;
 
idpf_vc_vport_ena_dis(vport, false);
@@ -822,8 +820,6 @@ idpf_dev_stop(struct rte_eth_dev *dev)
 
idpf_vc_vectors_dealloc(vport);
 
-   vport->stopped = 1;
-
return 0;
 }
 
-- 
2.31.1



[PATCH] doc: fix dcf instructions

2023-03-27 Thread Qi Zhang
Replace the deprecated VF action with the represented_port action.

Fixes: 776c119736e7 ("net/ice: remove deprecated VF flow action")
Cc: sta...@dpdk.org

Signed-off-by: Qi Zhang 
---
 doc/guides/nics/ice.rst | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/doc/guides/nics/ice.rst b/doc/guides/nics/ice.rst
index 70e19c3318..f3d3540992 100644
--- a/doc/guides/nics/ice.rst
+++ b/doc/guides/nics/ice.rst
@@ -343,18 +343,18 @@ Additional Options
 
   ip link set dev enp24s0f0 vf 0 trust on
 
-#. Bind the VF0,  and run testpmd with 'cap=dcf' devarg::
+#. Bind the VF0, and run testpmd with 'cap=dcf' with port representor for VF 1 
and 2::
 
-  dpdk-testpmd -l 22-25 -n 4 -a 18:01.0,cap=dcf -- -i
+  dpdk-testpmd -l 22-25 -n 4 -a 18:01.0,cap=dcf,representor=vf[1-2] -- -i
 
 #. Monitor the VF2 interface network traffic::
 
   tcpdump -e -nn -i enp24s1f2
 
-#. Create one flow to redirect the traffic to VF2 by DCF::
+#. Create one flow to redirect the traffic to VF2 by DCF(assume the 
representor port id is 5)::
 
   flow create 0 priority 0 ingress pattern eth / ipv4 src is 192.168.0.2 \
-  dst is 192.168.0.3 / end actions vf id 2 / end
+  dst is 192.168.0.3 / end actions represented_port ethdev_port_id 5 / end
 
 #. Send the packet, and it should be displayed on tcpdump::
 
-- 
2.31.1



[PATCH v2] net/ice: support IOVA as VA mode

2022-12-12 Thread Qi Zhang
Claim pmd_supports_disable_iova_as_pa. Remove buf_iova access when
RTE_IOVA_AS_PA is not defined.

The patch simply replace buf_iova with buf_addr at IOVA as VA mode.
Some SIMD instructions in data path may be over used, further optimization
is expected.

Signed-off-by: Qi Zhang 
---
v2:
- fix title and commit log
- use rte_pktmbuf_iova

 drivers/common/iavf/meson.build   |  1 +
 drivers/net/ice/ice_rxtx_common_avx.h | 24 
 drivers/net/ice/ice_rxtx_vec_avx2.c   | 15 +--
 drivers/net/ice/ice_rxtx_vec_avx512.c | 20 ++--
 drivers/net/ice/ice_rxtx_vec_sse.c| 11 +--
 drivers/net/ice/meson.build   |  6 +++---
 6 files changed, 52 insertions(+), 25 deletions(-)

diff --git a/drivers/common/iavf/meson.build b/drivers/common/iavf/meson.build
index 977652223b..af8a4983e0 100644
--- a/drivers/common/iavf/meson.build
+++ b/drivers/common/iavf/meson.build
@@ -6,3 +6,4 @@ sources = files('iavf_adminq.c', 'iavf_common.c', 'iavf_impl.c')
 if cc.has_argument('-Wno-pointer-to-int-cast')
 cflags += '-Wno-pointer-to-int-cast'
 endif
+pmd_supports_disable_iova_as_pa = true
diff --git a/drivers/net/ice/ice_rxtx_common_avx.h 
b/drivers/net/ice/ice_rxtx_common_avx.h
index 81e0db5dd3..e69e23997f 100644
--- a/drivers/net/ice/ice_rxtx_common_avx.h
+++ b/drivers/net/ice/ice_rxtx_common_avx.h
@@ -54,15 +54,23 @@ ice_rxq_rearm_common(struct ice_rx_queue *rxq, __rte_unused 
bool avx512)
mb0 = rxep[0].mbuf;
mb1 = rxep[1].mbuf;
 
+#if RTE_IOVA_AS_PA
/* load buf_addr(lo 64bit) and buf_iova(hi 64bit) */
RTE_BUILD_BUG_ON(offsetof(struct rte_mbuf, buf_iova) !=
offsetof(struct rte_mbuf, buf_addr) + 8);
+#endif
vaddr0 = _mm_loadu_si128((__m128i *)&mb0->buf_addr);
vaddr1 = _mm_loadu_si128((__m128i *)&mb1->buf_addr);
 
+#if RTE_IOVA_AS_PA
/* convert pa to dma_addr hdr/data */
dma_addr0 = _mm_unpackhi_epi64(vaddr0, vaddr0);
dma_addr1 = _mm_unpackhi_epi64(vaddr1, vaddr1);
+#else
+   /* convert va to dma_addr hdr/data */
+   dma_addr0 = _mm_unpacklo_epi64(vaddr0, vaddr0);
+   dma_addr1 = _mm_unpacklo_epi64(vaddr1, vaddr1);
+#endif
 
/* add headroom to pa values */
dma_addr0 = _mm_add_epi64(dma_addr0, hdr_room);
@@ -97,9 +105,11 @@ ice_rxq_rearm_common(struct ice_rx_queue *rxq, __rte_unused 
bool avx512)
mb6 = rxep[6].mbuf;
mb7 = rxep[7].mbuf;
 
+#if RTE_IOVA_AS_PA
/* load buf_addr(lo 64bit) and buf_iova(hi 64bit) */
RTE_BUILD_BUG_ON(offsetof(struct rte_mbuf, buf_iova) !=
offsetof(struct rte_mbuf, buf_addr) + 
8);
+#endif
vaddr0 = _mm_loadu_si128((__m128i *)&mb0->buf_addr);
vaddr1 = _mm_loadu_si128((__m128i *)&mb1->buf_addr);
vaddr2 = _mm_loadu_si128((__m128i *)&mb2->buf_addr);
@@ -132,9 +142,15 @@ ice_rxq_rearm_common(struct ice_rx_queue *rxq, 
__rte_unused bool avx512)

_mm512_inserti64x4(_mm512_castsi256_si512(vaddr4_5),
   vaddr6_7, 1);
 
+#if RTE_IOVA_AS_PA
/* convert pa to dma_addr hdr/data */
dma_addr0_3 = _mm512_unpackhi_epi64(vaddr0_3, vaddr0_3);
dma_addr4_7 = _mm512_unpackhi_epi64(vaddr4_7, vaddr4_7);
+#else
+   /* convert va to dma_addr hdr/data */
+   dma_addr0_3 = _mm512_unpacklo_epi64(vaddr0_3, vaddr0_3);
+   dma_addr4_7 = _mm512_unpacklo_epi64(vaddr4_7, vaddr4_7);
+#endif
 
/* add headroom to pa values */
dma_addr0_3 = _mm512_add_epi64(dma_addr0_3, hdr_room);
@@ -161,9 +177,11 @@ ice_rxq_rearm_common(struct ice_rx_queue *rxq, 
__rte_unused bool avx512)
mb2 = rxep[2].mbuf;
mb3 = rxep[3].mbuf;
 
+#if RTE_IOVA_AS_PA
/* load buf_addr(lo 64bit) and buf_iova(hi 64bit) */
RTE_BUILD_BUG_ON(offsetof(struct rte_mbuf, buf_iova) !=
offsetof(struct rte_mbuf, buf_addr) + 
8);
+#endif
vaddr0 = _mm_loadu_si128((__m128i *)&mb0->buf_addr);
vaddr1 = _mm_loadu_si128((__m128i *)&mb1->buf_addr);
vaddr2 = _mm_loadu_si128((__m128i *)&mb2->buf_addr);
@@ -180,9 +198,15 @@ ice_rxq_rearm_common(struct ice_rx_queue *rxq, 
__rte_unused bool avx512)

_mm256_inserti128_si256(_mm256_castsi128_si256(vaddr2),
 

[PATCH] net/ice: support IOVA as PA mode

2022-12-11 Thread Qi Zhang
Claim pmd_supports_disable_iova_as_pa. Remove buf_iova access when
RTE_IOVA_AS_PA is not defined.

The patch simply replace buf_iova with buf_addr at no IOVA as PA mode.
Some SIMD instructions in data path may be over used, further optimization
is expected.

Signed-off-by: Qi Zhang 
---
 drivers/common/iavf/meson.build   |  1 +
 drivers/net/ice/ice_rxtx_common_avx.h | 24 
 drivers/net/ice/ice_rxtx_vec_avx2.c   | 15 +--
 drivers/net/ice/ice_rxtx_vec_avx512.c | 21 ++---
 drivers/net/ice/ice_rxtx_vec_common.h |  6 ++
 drivers/net/ice/ice_rxtx_vec_sse.c| 11 +--
 drivers/net/ice/meson.build   |  6 +++---
 7 files changed, 58 insertions(+), 26 deletions(-)

diff --git a/drivers/common/iavf/meson.build b/drivers/common/iavf/meson.build
index 977652223b..af8a4983e0 100644
--- a/drivers/common/iavf/meson.build
+++ b/drivers/common/iavf/meson.build
@@ -6,3 +6,4 @@ sources = files('iavf_adminq.c', 'iavf_common.c', 'iavf_impl.c')
 if cc.has_argument('-Wno-pointer-to-int-cast')
 cflags += '-Wno-pointer-to-int-cast'
 endif
+pmd_supports_disable_iova_as_pa = true
diff --git a/drivers/net/ice/ice_rxtx_common_avx.h 
b/drivers/net/ice/ice_rxtx_common_avx.h
index 81e0db5dd3..e69e23997f 100644
--- a/drivers/net/ice/ice_rxtx_common_avx.h
+++ b/drivers/net/ice/ice_rxtx_common_avx.h
@@ -54,15 +54,23 @@ ice_rxq_rearm_common(struct ice_rx_queue *rxq, __rte_unused 
bool avx512)
mb0 = rxep[0].mbuf;
mb1 = rxep[1].mbuf;
 
+#if RTE_IOVA_AS_PA
/* load buf_addr(lo 64bit) and buf_iova(hi 64bit) */
RTE_BUILD_BUG_ON(offsetof(struct rte_mbuf, buf_iova) !=
offsetof(struct rte_mbuf, buf_addr) + 8);
+#endif
vaddr0 = _mm_loadu_si128((__m128i *)&mb0->buf_addr);
vaddr1 = _mm_loadu_si128((__m128i *)&mb1->buf_addr);
 
+#if RTE_IOVA_AS_PA
/* convert pa to dma_addr hdr/data */
dma_addr0 = _mm_unpackhi_epi64(vaddr0, vaddr0);
dma_addr1 = _mm_unpackhi_epi64(vaddr1, vaddr1);
+#else
+   /* convert va to dma_addr hdr/data */
+   dma_addr0 = _mm_unpacklo_epi64(vaddr0, vaddr0);
+   dma_addr1 = _mm_unpacklo_epi64(vaddr1, vaddr1);
+#endif
 
/* add headroom to pa values */
dma_addr0 = _mm_add_epi64(dma_addr0, hdr_room);
@@ -97,9 +105,11 @@ ice_rxq_rearm_common(struct ice_rx_queue *rxq, __rte_unused 
bool avx512)
mb6 = rxep[6].mbuf;
mb7 = rxep[7].mbuf;
 
+#if RTE_IOVA_AS_PA
/* load buf_addr(lo 64bit) and buf_iova(hi 64bit) */
RTE_BUILD_BUG_ON(offsetof(struct rte_mbuf, buf_iova) !=
offsetof(struct rte_mbuf, buf_addr) + 
8);
+#endif
vaddr0 = _mm_loadu_si128((__m128i *)&mb0->buf_addr);
vaddr1 = _mm_loadu_si128((__m128i *)&mb1->buf_addr);
vaddr2 = _mm_loadu_si128((__m128i *)&mb2->buf_addr);
@@ -132,9 +142,15 @@ ice_rxq_rearm_common(struct ice_rx_queue *rxq, 
__rte_unused bool avx512)

_mm512_inserti64x4(_mm512_castsi256_si512(vaddr4_5),
   vaddr6_7, 1);
 
+#if RTE_IOVA_AS_PA
/* convert pa to dma_addr hdr/data */
dma_addr0_3 = _mm512_unpackhi_epi64(vaddr0_3, vaddr0_3);
dma_addr4_7 = _mm512_unpackhi_epi64(vaddr4_7, vaddr4_7);
+#else
+   /* convert va to dma_addr hdr/data */
+   dma_addr0_3 = _mm512_unpacklo_epi64(vaddr0_3, vaddr0_3);
+   dma_addr4_7 = _mm512_unpacklo_epi64(vaddr4_7, vaddr4_7);
+#endif
 
/* add headroom to pa values */
dma_addr0_3 = _mm512_add_epi64(dma_addr0_3, hdr_room);
@@ -161,9 +177,11 @@ ice_rxq_rearm_common(struct ice_rx_queue *rxq, 
__rte_unused bool avx512)
mb2 = rxep[2].mbuf;
mb3 = rxep[3].mbuf;
 
+#if RTE_IOVA_AS_PA
/* load buf_addr(lo 64bit) and buf_iova(hi 64bit) */
RTE_BUILD_BUG_ON(offsetof(struct rte_mbuf, buf_iova) !=
offsetof(struct rte_mbuf, buf_addr) + 
8);
+#endif
vaddr0 = _mm_loadu_si128((__m128i *)&mb0->buf_addr);
vaddr1 = _mm_loadu_si128((__m128i *)&mb1->buf_addr);
vaddr2 = _mm_loadu_si128((__m128i *)&mb2->buf_addr);
@@ -180,9 +198,15 @@ ice_rxq_rearm_common(struct ice_rx_queue *rxq, 
__rte_unused bool avx512)

_mm256_inserti128_si256(_mm256_castsi128_si256(vaddr2),
 

[PATCH v2] net: not build PMD AVX library when no IOVA as PA

2022-12-11 Thread Qi Zhang
PMD not announce pmd_supports_disable_iova_as_pa will not be build
when RTE_IOVA_AS_PA is not defined, but some AVX library for vector
path is not skipped by the build system which cause compile error.

The patch modify i40e, iavf, ice's meson file to skip AVX library
build when RTE_IOVA_AS_PA is not defined.

Cc: sta...@dpdk.org

Signed-off-by: Qi Zhang 
---
v2:
- fix build error due to wrong type of meson variable.

 drivers/net/i40e/meson.build | 5 +++--
 drivers/net/iavf/meson.build | 5 +++--
 drivers/net/ice/meson.build  | 5 +++--
 3 files changed, 9 insertions(+), 6 deletions(-)

diff --git a/drivers/net/i40e/meson.build b/drivers/net/i40e/meson.build
index e00c1a9ef9..ac8a4bd3f8 100644
--- a/drivers/net/i40e/meson.build
+++ b/drivers/net/i40e/meson.build
@@ -37,6 +37,7 @@ testpmd_sources = files('i40e_testpmd.c')
 
 deps += ['hash']
 includes += include_directories('base')
+iova_as_pa = dpdk_conf.get('RTE_IOVA_AS_PA')
 
 if arch_subdir == 'x86'
 sources += files('i40e_rxtx_vec_sse.c')
@@ -51,7 +52,7 @@ if arch_subdir == 'x86'
 if cc.get_define('__AVX2__', args: machine_args) != ''
 cflags += ['-DCC_AVX2_SUPPORT']
 sources += files('i40e_rxtx_vec_avx2.c')
-elif cc.has_argument('-mavx2')
+elif iova_as_pa == 1 and cc.has_argument('-mavx2')
 cflags += ['-DCC_AVX2_SUPPORT']
 i40e_avx2_lib = static_library('i40e_avx2_lib',
 'i40e_rxtx_vec_avx2.c',
@@ -71,7 +72,7 @@ if arch_subdir == 'x86'
 cc.has_argument('-mavx512f') and
 cc.has_argument('-mavx512bw'))
 
-if i40e_avx512_cpu_support == true or i40e_avx512_cc_support == true
+if iova_as_pa == 1 and (i40e_avx512_cpu_support == true or 
i40e_avx512_cc_support == true)
 cflags += ['-DCC_AVX512_SUPPORT']
 avx512_args = [cflags, '-mavx512f', '-mavx512bw']
 if cc.has_argument('-march=skylake-avx512')
diff --git a/drivers/net/iavf/meson.build b/drivers/net/iavf/meson.build
index 6df771f917..37968200c1 100644
--- a/drivers/net/iavf/meson.build
+++ b/drivers/net/iavf/meson.build
@@ -6,6 +6,7 @@ cflags += ['-Wno-strict-aliasing']
 
 includes += include_directories('../../common/iavf')
 deps += ['common_iavf', 'security', 'cryptodev']
+iova_as_pa = dpdk_conf.get('RTE_IOVA_AS_PA')
 
 sources = files(
 'iavf_ethdev.c',
@@ -32,7 +33,7 @@ if arch_subdir == 'x86'
 if cc.get_define('__AVX2__', args: machine_args) != ''
 cflags += ['-DCC_AVX2_SUPPORT']
 sources += files('iavf_rxtx_vec_avx2.c')
-elif cc.has_argument('-mavx2')
+elif iova_as_pa == 1 and cc.has_argument('-mavx2')
 cflags += ['-DCC_AVX2_SUPPORT']
 iavf_avx2_lib = static_library('iavf_avx2_lib',
 'iavf_rxtx_vec_avx2.c',
@@ -52,7 +53,7 @@ if arch_subdir == 'x86'
 cc.has_argument('-mavx512f') and
 cc.has_argument('-mavx512bw'))
 
-if iavf_avx512_cpu_support == true or iavf_avx512_cc_support == true
+if iova_as_pa == 1 and (iavf_avx512_cpu_support == true or 
iavf_avx512_cc_support == true)
 cflags += ['-DCC_AVX512_SUPPORT']
 avx512_args = [cflags, '-mavx512f', '-mavx512bw']
 if cc.has_argument('-march=skylake-avx512')
diff --git a/drivers/net/ice/meson.build b/drivers/net/ice/meson.build
index 528e77613e..8efa533e0b 100644
--- a/drivers/net/ice/meson.build
+++ b/drivers/net/ice/meson.build
@@ -20,6 +20,7 @@ testpmd_sources = files('ice_testpmd.c')
 
 deps += ['hash', 'net', 'common_iavf']
 includes += include_directories('base', '../../common/iavf')
+iova_as_pa = dpdk_conf.get('RTE_IOVA_AS_PA')
 
 if arch_subdir == 'x86'
 sources += files('ice_rxtx_vec_sse.c')
@@ -34,7 +35,7 @@ if arch_subdir == 'x86'
 if cc.get_define('__AVX2__', args: machine_args) != ''
 cflags += ['-DCC_AVX2_SUPPORT']
 sources += files('ice_rxtx_vec_avx2.c')
-elif cc.has_argument('-mavx2')
+elif iova_as_pa == 1 and cc.has_argument('-mavx2')
 cflags += ['-DCC_AVX2_SUPPORT']
 ice_avx2_lib = static_library('ice_avx2_lib',
 'ice_rxtx_vec_avx2.c',
@@ -55,7 +56,7 @@ if arch_subdir == 'x86'
 cc.has_argument('-mavx512bw')
 )
 
-if ice_avx512_cpu_support == true or ice_avx512_cc_support == true
+if iova_as_pa == 1 and (ice_avx512_cpu_support == true or 
ice_avx512_cc_support == true)
 cflags += ['-DCC_AVX512_SUPPORT']
 avx512_args = [cflags, '-mavx512f', '-mavx512bw']
 if cc.has_argument('-march=skylake-avx512')
-- 
2.31.1



[PATCH v2] net: not build PMD AVX library when no IOVA as PA

2022-12-11 Thread Qi Zhang
PMD not announce pmd_supports_disable_iova_as_pa will not be build
when RTE_IOVA_AS_PA is not defined, but some AVX library for vector
path is not skipped by the build system which cause compile error.

The patch modify i40e, iavf, ice's meson file to skip AVX library
build when RTE_IOVA_AS_PA is not defined.

Cc: sta...@dpdk.org

Signed-off-by: Qi Zhang 
---
 drivers/net/i40e/meson.build | 5 +++--
 drivers/net/iavf/meson.build | 5 +++--
 drivers/net/ice/meson.build  | 5 +++--
 3 files changed, 9 insertions(+), 6 deletions(-)

diff --git a/drivers/net/i40e/meson.build b/drivers/net/i40e/meson.build
index e00c1a9ef9..ac8a4bd3f8 100644
--- a/drivers/net/i40e/meson.build
+++ b/drivers/net/i40e/meson.build
@@ -37,6 +37,7 @@ testpmd_sources = files('i40e_testpmd.c')
 
 deps += ['hash']
 includes += include_directories('base')
+iova_as_pa = dpdk_conf.get('RTE_IOVA_AS_PA')
 
 if arch_subdir == 'x86'
 sources += files('i40e_rxtx_vec_sse.c')
@@ -51,7 +52,7 @@ if arch_subdir == 'x86'
 if cc.get_define('__AVX2__', args: machine_args) != ''
 cflags += ['-DCC_AVX2_SUPPORT']
 sources += files('i40e_rxtx_vec_avx2.c')
-elif cc.has_argument('-mavx2')
+elif iova_as_pa == 1 and cc.has_argument('-mavx2')
 cflags += ['-DCC_AVX2_SUPPORT']
 i40e_avx2_lib = static_library('i40e_avx2_lib',
 'i40e_rxtx_vec_avx2.c',
@@ -71,7 +72,7 @@ if arch_subdir == 'x86'
 cc.has_argument('-mavx512f') and
 cc.has_argument('-mavx512bw'))
 
-if i40e_avx512_cpu_support == true or i40e_avx512_cc_support == true
+if iova_as_pa == 1 and (i40e_avx512_cpu_support == true or 
i40e_avx512_cc_support == true)
 cflags += ['-DCC_AVX512_SUPPORT']
 avx512_args = [cflags, '-mavx512f', '-mavx512bw']
 if cc.has_argument('-march=skylake-avx512')
diff --git a/drivers/net/iavf/meson.build b/drivers/net/iavf/meson.build
index 6df771f917..37968200c1 100644
--- a/drivers/net/iavf/meson.build
+++ b/drivers/net/iavf/meson.build
@@ -6,6 +6,7 @@ cflags += ['-Wno-strict-aliasing']
 
 includes += include_directories('../../common/iavf')
 deps += ['common_iavf', 'security', 'cryptodev']
+iova_as_pa = dpdk_conf.get('RTE_IOVA_AS_PA')
 
 sources = files(
 'iavf_ethdev.c',
@@ -32,7 +33,7 @@ if arch_subdir == 'x86'
 if cc.get_define('__AVX2__', args: machine_args) != ''
 cflags += ['-DCC_AVX2_SUPPORT']
 sources += files('iavf_rxtx_vec_avx2.c')
-elif cc.has_argument('-mavx2')
+elif iova_as_pa == 1 and cc.has_argument('-mavx2')
 cflags += ['-DCC_AVX2_SUPPORT']
 iavf_avx2_lib = static_library('iavf_avx2_lib',
 'iavf_rxtx_vec_avx2.c',
@@ -52,7 +53,7 @@ if arch_subdir == 'x86'
 cc.has_argument('-mavx512f') and
 cc.has_argument('-mavx512bw'))
 
-if iavf_avx512_cpu_support == true or iavf_avx512_cc_support == true
+if iova_as_pa == 1 and (iavf_avx512_cpu_support == true or 
iavf_avx512_cc_support == true)
 cflags += ['-DCC_AVX512_SUPPORT']
 avx512_args = [cflags, '-mavx512f', '-mavx512bw']
 if cc.has_argument('-march=skylake-avx512')
diff --git a/drivers/net/ice/meson.build b/drivers/net/ice/meson.build
index 528e77613e..8efa533e0b 100644
--- a/drivers/net/ice/meson.build
+++ b/drivers/net/ice/meson.build
@@ -20,6 +20,7 @@ testpmd_sources = files('ice_testpmd.c')
 
 deps += ['hash', 'net', 'common_iavf']
 includes += include_directories('base', '../../common/iavf')
+iova_as_pa = dpdk_conf.get('RTE_IOVA_AS_PA')
 
 if arch_subdir == 'x86'
 sources += files('ice_rxtx_vec_sse.c')
@@ -34,7 +35,7 @@ if arch_subdir == 'x86'
 if cc.get_define('__AVX2__', args: machine_args) != ''
 cflags += ['-DCC_AVX2_SUPPORT']
 sources += files('ice_rxtx_vec_avx2.c')
-elif cc.has_argument('-mavx2')
+elif iova_as_pa == 1 and cc.has_argument('-mavx2')
 cflags += ['-DCC_AVX2_SUPPORT']
 ice_avx2_lib = static_library('ice_avx2_lib',
 'ice_rxtx_vec_avx2.c',
@@ -55,7 +56,7 @@ if arch_subdir == 'x86'
 cc.has_argument('-mavx512bw')
 )
 
-if ice_avx512_cpu_support == true or ice_avx512_cc_support == true
+if iova_as_pa == 1 and (ice_avx512_cpu_support == true or 
ice_avx512_cc_support == true)
 cflags += ['-DCC_AVX512_SUPPORT']
 avx512_args = [cflags, '-mavx512f', '-mavx512bw']
 if cc.has_argument('-march=skylake-avx512')
-- 
2.31.1



[PATCH] net: not compile PMD AVX library when no IOVA as PA

2022-12-11 Thread Qi Zhang
PMD not announce pmd_supports_disable_iova_as_pa will not be build
when RTE_IOVA_AS_PA is not defined, but some AVX library for vector
path is not skipped by the build system which cause compile error.

The patch modify i40e, iavf, ice's meson file to skip AVX library
build when RTE_IOVA_AS_PA is not defined.

Cc: sta...@dpdk.org

Signed-off-by: Qi Zhang 
---
 drivers/net/i40e/meson.build | 6 --
 drivers/net/iavf/meson.build | 6 --
 drivers/net/ice/meson.build  | 6 --
 3 files changed, 12 insertions(+), 6 deletions(-)

diff --git a/drivers/net/i40e/meson.build b/drivers/net/i40e/meson.build
index e00c1a9ef9..0001d4816b 100644
--- a/drivers/net/i40e/meson.build
+++ b/drivers/net/i40e/meson.build
@@ -37,6 +37,7 @@ testpmd_sources = files('i40e_testpmd.c')
 
 deps += ['hash']
 includes += include_directories('base')
+iova_as_pa = dpdk_conf.get('RTE_IOVA_AS_PA')
 
 if arch_subdir == 'x86'
 sources += files('i40e_rxtx_vec_sse.c')
@@ -51,7 +52,7 @@ if arch_subdir == 'x86'
 if cc.get_define('__AVX2__', args: machine_args) != ''
 cflags += ['-DCC_AVX2_SUPPORT']
 sources += files('i40e_rxtx_vec_avx2.c')
-elif cc.has_argument('-mavx2')
+elif iova_as_pa == true and cc.has_argument('-mavx2')
 cflags += ['-DCC_AVX2_SUPPORT']
 i40e_avx2_lib = static_library('i40e_avx2_lib',
 'i40e_rxtx_vec_avx2.c',
@@ -71,7 +72,8 @@ if arch_subdir == 'x86'
 cc.has_argument('-mavx512f') and
 cc.has_argument('-mavx512bw'))
 
-if i40e_avx512_cpu_support == true or i40e_avx512_cc_support == true
+if iova_as_pa == true and
+(i40e_avx512_cpu_support == true or i40e_avx512_cc_support == true)
 cflags += ['-DCC_AVX512_SUPPORT']
 avx512_args = [cflags, '-mavx512f', '-mavx512bw']
 if cc.has_argument('-march=skylake-avx512')
diff --git a/drivers/net/iavf/meson.build b/drivers/net/iavf/meson.build
index 6df771f917..90428fa2d8 100644
--- a/drivers/net/iavf/meson.build
+++ b/drivers/net/iavf/meson.build
@@ -6,6 +6,7 @@ cflags += ['-Wno-strict-aliasing']
 
 includes += include_directories('../../common/iavf')
 deps += ['common_iavf', 'security', 'cryptodev']
+iova_as_pa = dpdk_conf.get('RTE_IOVA_AS_PA')
 
 sources = files(
 'iavf_ethdev.c',
@@ -32,7 +33,7 @@ if arch_subdir == 'x86'
 if cc.get_define('__AVX2__', args: machine_args) != ''
 cflags += ['-DCC_AVX2_SUPPORT']
 sources += files('iavf_rxtx_vec_avx2.c')
-elif cc.has_argument('-mavx2')
+elif iova_as_pa == true and cc.has_argument('-mavx2')
 cflags += ['-DCC_AVX2_SUPPORT']
 iavf_avx2_lib = static_library('iavf_avx2_lib',
 'iavf_rxtx_vec_avx2.c',
@@ -52,7 +53,8 @@ if arch_subdir == 'x86'
 cc.has_argument('-mavx512f') and
 cc.has_argument('-mavx512bw'))
 
-if iavf_avx512_cpu_support == true or iavf_avx512_cc_support == true
+if iova_as_pa == true and
+(iavf_avx512_cpu_support == true or iavf_avx512_cc_support == true)
 cflags += ['-DCC_AVX512_SUPPORT']
 avx512_args = [cflags, '-mavx512f', '-mavx512bw']
 if cc.has_argument('-march=skylake-avx512')
diff --git a/drivers/net/ice/meson.build b/drivers/net/ice/meson.build
index 528e77613e..5d17039789 100644
--- a/drivers/net/ice/meson.build
+++ b/drivers/net/ice/meson.build
@@ -20,6 +20,7 @@ testpmd_sources = files('ice_testpmd.c')
 
 deps += ['hash', 'net', 'common_iavf']
 includes += include_directories('base', '../../common/iavf')
+iova_as_pa = dpdk_conf.get('RTE_IOVA_AS_PA')
 
 if arch_subdir == 'x86'
 sources += files('ice_rxtx_vec_sse.c')
@@ -34,7 +35,7 @@ if arch_subdir == 'x86'
 if cc.get_define('__AVX2__', args: machine_args) != ''
 cflags += ['-DCC_AVX2_SUPPORT']
 sources += files('ice_rxtx_vec_avx2.c')
-elif cc.has_argument('-mavx2')
+elif iova_as_pa == true and cc.has_argument('-mavx2')
 cflags += ['-DCC_AVX2_SUPPORT']
 ice_avx2_lib = static_library('ice_avx2_lib',
 'ice_rxtx_vec_avx2.c',
@@ -55,7 +56,8 @@ if arch_subdir == 'x86'
 cc.has_argument('-mavx512bw')
 )
 
-if ice_avx512_cpu_support == true or ice_avx512_cc_support == true
+if iova_as_pa == true and
+(avx512_cpu_support == true or ice_avx512_cc_support == true)
 cflags += ['-DCC_AVX512_SUPPORT']
 avx512_args = [cflags, '-mavx512f', '-mavx512bw']
 if cc.has_argument('-march=skylake-avx512')
-- 
2.31.1



[PATCH 3/3] net/iavf: support no IOVA as PA mode

2022-12-11 Thread Qi Zhang
Remove buf_iova access when RTE_IOVA_AS_PA is not defined.

Cc: sta...@dpdk.org

Signed-off-by: Qi Zhang 
---
 drivers/net/iavf/iavf_rxtx_vec_avx512.c | 20 ++--
 drivers/net/iavf/iavf_rxtx_vec_common.h | 12 
 2 files changed, 22 insertions(+), 10 deletions(-)

diff --git a/drivers/net/iavf/iavf_rxtx_vec_avx512.c 
b/drivers/net/iavf/iavf_rxtx_vec_avx512.c
index b416a716cf..f1507de79e 100644
--- a/drivers/net/iavf/iavf_rxtx_vec_avx512.c
+++ b/drivers/net/iavf/iavf_rxtx_vec_avx512.c
@@ -78,8 +78,13 @@ iavf_rxq_rearm(struct iavf_rx_queue *rxq)
}
}
 
+#if RTE_IOVA_AS_PA
const __m512i iova_offsets =  _mm512_set1_epi64(offsetof
(struct rte_mbuf, 
buf_iova));
+#else
+   const __m512i iova_offsets =  _mm512_set1_epi64(offsetof
+   (struct rte_mbuf, 
buf_addr));
+#endif
const __m512i headroom = _mm512_set1_epi64(RTE_PKTMBUF_HEADROOM);
 
 #ifndef RTE_LIBRTE_IAVF_16BYTE_RX_DESC
@@ -1896,8 +1901,7 @@ iavf_vtx1(volatile struct iavf_tx_desc *txdp,
if (offload)
iavf_txd_enable_offload(pkt, &high_qw);
 
-   __m128i descriptor = _mm_set_epi64x(high_qw,
-   pkt->buf_iova + pkt->data_off);
+   __m128i descriptor = _mm_set_epi64x(high_qw, _PKT_DATA_OFF_U64(pkt));
_mm_storeu_si128((__m128i *)txdp, descriptor);
 }
 
@@ -1946,14 +1950,10 @@ iavf_vtx(volatile struct iavf_tx_desc *txdp,
 
__m512i desc0_3 =
_mm512_set_epi64
-   (hi_qw3,
-pkt[3]->buf_iova + pkt[3]->data_off,
-hi_qw2,
-pkt[2]->buf_iova + pkt[2]->data_off,
-hi_qw1,
-pkt[1]->buf_iova + pkt[1]->data_off,
-hi_qw0,
-pkt[0]->buf_iova + pkt[0]->data_off);
+   (hi_qw3, _PKT_DATA_OFF_U64(pkt[3]),
+hi_qw2, _PKT_DATA_OFF_U64(pkt[2]),
+hi_qw1, _PKT_DATA_OFF_U64(pkt[1]),
+hi_qw0, _PKT_DATA_OFF_U64(pkt[0]));
_mm512_storeu_si512((void *)txdp, desc0_3);
}
 
diff --git a/drivers/net/iavf/iavf_rxtx_vec_common.h 
b/drivers/net/iavf/iavf_rxtx_vec_common.h
index a59cb2ceee..4aeeb4baaa 100644
--- a/drivers/net/iavf/iavf_rxtx_vec_common.h
+++ b/drivers/net/iavf/iavf_rxtx_vec_common.h
@@ -15,6 +15,12 @@
 #pragma GCC diagnostic ignored "-Wcast-qual"
 #endif
 
+#if RTE_IOVA_AS_PA
+   #define _PKT_DATA_OFF_U64(pkt) ((pkt)->buf_iova + (pkt)->data_off)
+#else
+   #define _PKT_DATA_OFF_U64(pkt) ((u64)(pkt)->buf_addr + (pkt)->data_off)
+#endif
+
 static __rte_always_inline uint16_t
 reassemble_packets(struct iavf_rx_queue *rxq, struct rte_mbuf **rx_bufs,
   uint16_t nb_bufs, uint8_t *split_flags)
@@ -421,9 +427,15 @@ iavf_rxq_rearm_common(struct iavf_rx_queue *rxq, 
__rte_unused bool avx512)
mb0 = rxp[0];
mb1 = rxp[1];
 
+#if RTE_IOVA_AS_PA
/* load buf_addr(lo 64bit) and buf_iova(hi 64bit) */
RTE_BUILD_BUG_ON(offsetof(struct rte_mbuf, buf_iova) !=
offsetof(struct rte_mbuf, buf_addr) + 8);
+#else
+   /* load buf_addr(lo 64bit) and next(hi 64bit) */
+   RTE_BUILD_BUG_ON(offsetof(struct rte_mbuf, next) !=
+   offsetof(struct rte_mbuf, buf_addr) + 8);
+#endif
vaddr0 = _mm_loadu_si128((__m128i *)&mb0->buf_addr);
vaddr1 = _mm_loadu_si128((__m128i *)&mb1->buf_addr);
 
-- 
2.31.1



[PATCH 2/3] net/i40e: support no IOVA as PA mode

2022-12-11 Thread Qi Zhang
Remove buf_iova access when RTE_IOVA_AS_PA is not defined.

Cc: sta...@dpdk.org

Signed-off-by: Qi Zhang 
---
 drivers/net/i40e/i40e_rxtx_common_avx.h | 12 
 drivers/net/i40e/i40e_rxtx_vec_avx512.c | 17 +++--
 2 files changed, 23 insertions(+), 6 deletions(-)

diff --git a/drivers/net/i40e/i40e_rxtx_common_avx.h 
b/drivers/net/i40e/i40e_rxtx_common_avx.h
index cfc1e63173..7ee2ae9ef2 100644
--- a/drivers/net/i40e/i40e_rxtx_common_avx.h
+++ b/drivers/net/i40e/i40e_rxtx_common_avx.h
@@ -15,6 +15,12 @@
 #pragma GCC diagnostic ignored "-Wcast-qual"
 #endif
 
+#if RTE_IOVA_AS_PA
+   #define _PKT_DATA_OFF_U64(pkt) ((pkt)->buf_iova + (pkt)->data_off)
+#else
+   #define _PKT_DATA_OFF_U64(pkt) ((u64)(pkt)->buf_addr + (pkt)->data_off)
+#endif
+
 #ifdef __AVX2__
 static __rte_always_inline void
 i40e_rxq_rearm_common(struct i40e_rx_queue *rxq, __rte_unused bool avx512)
@@ -57,9 +63,15 @@ i40e_rxq_rearm_common(struct i40e_rx_queue *rxq, 
__rte_unused bool avx512)
mb0 = rxep[0].mbuf;
mb1 = rxep[1].mbuf;
 
+#if RTE_IOVA_AS_PA
/* load buf_addr(lo 64bit) and buf_iova(hi 64bit) */
RTE_BUILD_BUG_ON(offsetof(struct rte_mbuf, buf_iova) !=
offsetof(struct rte_mbuf, buf_addr) + 8);
+#else
+   /* load buf_addr(lo 64bit) and next(hi 64bit) */
+   RTE_BUILD_BUG_ON(offsetof(struct rte_mbuf, next) !=
+   offsetof(struct rte_mbuf, buf_addr) + 8);
+#endif
vaddr0 = _mm_loadu_si128((__m128i *)&mb0->buf_addr);
vaddr1 = _mm_loadu_si128((__m128i *)&mb1->buf_addr);
 
diff --git a/drivers/net/i40e/i40e_rxtx_vec_avx512.c 
b/drivers/net/i40e/i40e_rxtx_vec_avx512.c
index 60c97d5331..280bda6c41 100644
--- a/drivers/net/i40e/i40e_rxtx_vec_avx512.c
+++ b/drivers/net/i40e/i40e_rxtx_vec_avx512.c
@@ -72,8 +72,14 @@ i40e_rxq_rearm(struct i40e_rx_queue *rxq)
}
}
 
+#if RTE_IOVA_AS_PA
const __m512i iova_offsets =  _mm512_set1_epi64
(offsetof(struct rte_mbuf, buf_iova));
+#else
+   const __m512i iova_offsets =  _mm512_set1_epi64
+   (offsetof(struct rte_mbuf, buf_addr));
+#endif
+
const __m512i headroom = _mm512_set1_epi64(RTE_PKTMBUF_HEADROOM);
 
 #ifndef RTE_LIBRTE_I40E_16BYTE_RX_DESC
@@ -993,8 +999,7 @@ vtx1(volatile struct i40e_tx_desc *txdp, struct rte_mbuf 
*pkt, uint64_t flags)
((uint64_t)flags  << I40E_TXD_QW1_CMD_SHIFT) |
((uint64_t)pkt->data_len << I40E_TXD_QW1_TX_BUF_SZ_SHIFT));
 
-   __m128i descriptor = _mm_set_epi64x(high_qw,
-   pkt->buf_iova + pkt->data_off);
+   __m128i descriptor = _mm_set_epi64x(high_qw, _PKT_DATA_OFF_U64(pkt));
_mm_store_si128((__m128i *)txdp, descriptor);
 }
 
@@ -1025,10 +1030,10 @@ vtx(volatile struct i40e_tx_desc *txdp,
 
__m512i desc0_3 =
_mm512_set_epi64
-   (hi_qw3, pkt[3]->buf_iova + pkt[3]->data_off,
-   hi_qw2, pkt[2]->buf_iova + pkt[2]->data_off,
-   hi_qw1, pkt[1]->buf_iova + pkt[1]->data_off,
-   hi_qw0, pkt[0]->buf_iova + pkt[0]->data_off);
+   (hi_qw3, _PKT_DATA_OFF_U64(pkt[3]),
+   hi_qw2, _PKT_DATA_OFF_U64(pkt[2]),
+   hi_qw1, _PKT_DATA_OFF_U64(pkt[1]),
+   hi_qw0, _PKT_DATA_OFF_U64(pkt[0]));
_mm512_storeu_si512((void *)txdp, desc0_3);
}
 
-- 
2.31.1



[PATCH 1/3] net/ice: support no IOVA as PA mode

2022-12-11 Thread Qi Zhang
Remove buf_iova access when RTE_IOVA_AS_PA is not defined.

Cc: sta...@dpdk.org

Signed-off-by: Qi Zhang 
---
 drivers/net/ice/ice_rxtx_common_avx.h | 24 
 drivers/net/ice/ice_rxtx_vec_avx2.c   | 11 +--
 drivers/net/ice/ice_rxtx_vec_avx512.c | 17 +++--
 3 files changed, 40 insertions(+), 12 deletions(-)

diff --git a/drivers/net/ice/ice_rxtx_common_avx.h 
b/drivers/net/ice/ice_rxtx_common_avx.h
index 81e0db5dd3..377740d43b 100644
--- a/drivers/net/ice/ice_rxtx_common_avx.h
+++ b/drivers/net/ice/ice_rxtx_common_avx.h
@@ -11,6 +11,12 @@
 #pragma GCC diagnostic ignored "-Wcast-qual"
 #endif
 
+#if RTE_IOVA_AS_PA
+#define _PKT_DATA_OFF_U64(pkt) ((pkt)->buf_iova + (pkt)->data_off)
+#else
+#define _PKT_DATA_OFF_U64(pkt) ((u64)(pkt)->buf_addr + (pkt)->data_off)
+#endif
+
 #ifdef __AVX2__
 static __rte_always_inline void
 ice_rxq_rearm_common(struct ice_rx_queue *rxq, __rte_unused bool avx512)
@@ -54,9 +60,15 @@ ice_rxq_rearm_common(struct ice_rx_queue *rxq, __rte_unused 
bool avx512)
mb0 = rxep[0].mbuf;
mb1 = rxep[1].mbuf;
 
+#if RTE_IOVA_AS_PA
/* load buf_addr(lo 64bit) and buf_iova(hi 64bit) */
RTE_BUILD_BUG_ON(offsetof(struct rte_mbuf, buf_iova) !=
offsetof(struct rte_mbuf, buf_addr) + 8);
+#else
+   /* load buf_addr(lo 64bit) and next(hi 64bit) */
+   RTE_BUILD_BUG_ON(offsetof(struct rte_mbuf, next) !=
+   offsetof(struct rte_mbuf, buf_addr) + 8);
+#endif
vaddr0 = _mm_loadu_si128((__m128i *)&mb0->buf_addr);
vaddr1 = _mm_loadu_si128((__m128i *)&mb1->buf_addr);
 
@@ -97,9 +109,15 @@ ice_rxq_rearm_common(struct ice_rx_queue *rxq, __rte_unused 
bool avx512)
mb6 = rxep[6].mbuf;
mb7 = rxep[7].mbuf;
 
+#if RTE_IOVA_AS_PA
/* load buf_addr(lo 64bit) and buf_iova(hi 64bit) */
RTE_BUILD_BUG_ON(offsetof(struct rte_mbuf, buf_iova) !=
offsetof(struct rte_mbuf, buf_addr) + 
8);
+#else
+   /* load buf_addr(lo 64bit) and next(hi 64bit) */
+   RTE_BUILD_BUG_ON(offsetof(struct rte_mbuf, next) !=
+   offsetof(struct rte_mbuf, buf_addr) + 
8);
+#endif
vaddr0 = _mm_loadu_si128((__m128i *)&mb0->buf_addr);
vaddr1 = _mm_loadu_si128((__m128i *)&mb1->buf_addr);
vaddr2 = _mm_loadu_si128((__m128i *)&mb2->buf_addr);
@@ -161,9 +179,15 @@ ice_rxq_rearm_common(struct ice_rx_queue *rxq, 
__rte_unused bool avx512)
mb2 = rxep[2].mbuf;
mb3 = rxep[3].mbuf;
 
+#if RTE_IOVA_AS_PA
/* load buf_addr(lo 64bit) and buf_iova(hi 64bit) */
RTE_BUILD_BUG_ON(offsetof(struct rte_mbuf, buf_iova) !=
offsetof(struct rte_mbuf, buf_addr) + 
8);
+#else
+   /* load buf_addr(lo 64bit) and next(hi 64bit) */
+   RTE_BUILD_BUG_ON(offsetof(struct rte_mbuf, next) !=
+   offsetof(struct rte_mbuf, buf_addr) + 
8);
+#endif
vaddr0 = _mm_loadu_si128((__m128i *)&mb0->buf_addr);
vaddr1 = _mm_loadu_si128((__m128i *)&mb1->buf_addr);
vaddr2 = _mm_loadu_si128((__m128i *)&mb2->buf_addr);
diff --git a/drivers/net/ice/ice_rxtx_vec_avx2.c 
b/drivers/net/ice/ice_rxtx_vec_avx2.c
index 31d6af42fd..b0fd51d37e 100644
--- a/drivers/net/ice/ice_rxtx_vec_avx2.c
+++ b/drivers/net/ice/ice_rxtx_vec_avx2.c
@@ -821,8 +821,7 @@ ice_vtx1(volatile struct ice_tx_desc *txdp,
if (offload)
ice_txd_enable_offload(pkt, &high_qw);
 
-   __m128i descriptor = _mm_set_epi64x(high_qw,
-   pkt->buf_iova + pkt->data_off);
+   __m128i descriptor = _mm_set_epi64x(high_qw, _PKT_DATA_OFF_U64(pkt));
_mm_store_si128((__m128i *)txdp, descriptor);
 }
 
@@ -869,15 +868,15 @@ ice_vtx(volatile struct ice_tx_desc *txdp,
__m256i desc2_3 =
_mm256_set_epi64x
(hi_qw3,
-pkt[3]->buf_iova + pkt[3]->data_off,
+_PKT_DATA_OFF_U64(pkt[3]),
 hi_qw2,
-pkt[2]->buf_iova + pkt[2]->data_off);
+_PKT_DATA_OFF_U64(pkt[2]));
__m256i desc0_1 =
_mm256_set_epi64x
(hi_qw1,
-pkt[1]->buf_iova + pkt[1]->data_off,
+_PKT_DATA_OFF_U64(pkt[1]),
   

  1   2   3   4   5   6   7   8   9   10   >