From: Satheesh Paul <psathe...@marvell.com>

Added RTE_FLOW_ACTION_TYPE_SAMPLE action type for cnxk device.

Signed-off-by: Satheesh Paul <psathe...@marvell.com>
Reviewed-by: Kiran Kumar K <kirankum...@marvell.com>
---
 doc/guides/nics/features/cnxk.ini      |   1 +
 doc/guides/rel_notes/release_24_03.rst |   1 +
 drivers/net/cnxk/cnxk_flow.c           | 121 +++++++++++++++++++++++--
 3 files changed, 116 insertions(+), 7 deletions(-)

diff --git a/doc/guides/nics/features/cnxk.ini 
b/doc/guides/nics/features/cnxk.ini
index cc7deaeaa9..94e7a6ab8d 100644
--- a/doc/guides/nics/features/cnxk.ini
+++ b/doc/guides/nics/features/cnxk.ini
@@ -97,6 +97,7 @@ port_id              = Y
 queue                = Y
 represented_port     = Y
 rss                  = Y
+sample               = Y
 security             = Y
 skip_cman            = Y
 vf                   = Y
diff --git a/doc/guides/rel_notes/release_24_03.rst 
b/doc/guides/rel_notes/release_24_03.rst
index 866dd60fbf..282a3f9c8c 100644
--- a/doc/guides/rel_notes/release_24_03.rst
+++ b/doc/guides/rel_notes/release_24_03.rst
@@ -65,6 +65,7 @@ New Features
 * **Updated Marvell cnxk net driver.**
 
   * Added support for ``RTE_FLOW_ITEM_TYPE_PPPOES`` flow item.
+  * Added support for ``RTE_FLOW_ACTION_TYPE_SAMPLE`` flow item.
 
 Removed Items
 -------------
diff --git a/drivers/net/cnxk/cnxk_flow.c b/drivers/net/cnxk/cnxk_flow.c
index 2eee44ed09..11670d37e0 100644
--- a/drivers/net/cnxk/cnxk_flow.c
+++ b/drivers/net/cnxk/cnxk_flow.c
@@ -114,14 +114,102 @@ npc_rss_flowkey_get(struct cnxk_eth_dev *eth_dev,
        *flowkey_cfg = cnxk_rss_ethdev_to_nix(eth_dev, rss->types, rss->level);
 }
 
+static int
+npc_parse_port_id_action(struct rte_eth_dev *eth_dev, const struct 
rte_flow_action *action,
+                        uint16_t *dst_pf_func, uint16_t *dst_channel)
+{
+       const struct rte_flow_action_port_id *port_act;
+       struct rte_eth_dev *portid_eth_dev;
+       char if_name[RTE_ETH_NAME_MAX_LEN];
+       struct cnxk_eth_dev *hw_dst;
+       struct roc_npc *roc_npc_dst;
+       int rc = 0;
+
+       port_act = (const struct rte_flow_action_port_id *)action->conf;
+
+       rc = rte_eth_dev_get_name_by_port(port_act->id, if_name);
+       if (rc) {
+               plt_err("Name not found for output port id");
+               goto err_exit;
+       }
+       portid_eth_dev = rte_eth_dev_allocated(if_name);
+       if (!portid_eth_dev) {
+               plt_err("eth_dev not found for output port id");
+               goto err_exit;
+       }
+       if (strcmp(portid_eth_dev->device->driver->name, 
eth_dev->device->driver->name) != 0) {
+               plt_err("Output port not under same driver");
+               goto err_exit;
+       }
+       hw_dst = portid_eth_dev->data->dev_private;
+       roc_npc_dst = &hw_dst->npc;
+       *dst_pf_func = roc_npc_dst->pf_func;
+       *dst_channel = hw_dst->npc.channel;
+
+       return 0;
+
+err_exit:
+       return -EINVAL;
+}
+
+static int
+roc_npc_parse_sample_subaction(struct rte_eth_dev *eth_dev, const struct 
rte_flow_action actions[],
+                              struct roc_npc_action_sample *sample_action)
+{
+       uint16_t dst_pf_func = 0, dst_channel = 0;
+       const struct roc_npc_action_vf *vf_act;
+       int rc = 0, count = 0;
+       bool is_empty = true;
+
+       if (sample_action->ratio != 1) {
+               plt_err("Sample ratio must be 1");
+               return -EINVAL;
+       }
+
+       for (; actions->type != RTE_FLOW_ACTION_TYPE_END; actions++) {
+               is_empty = false;
+               switch (actions->type) {
+               case RTE_FLOW_ACTION_TYPE_PF:
+                       count++;
+                       sample_action->action_type |= ROC_NPC_ACTION_TYPE_PF;
+                       break;
+               case RTE_FLOW_ACTION_TYPE_VF:
+                       count++;
+                       vf_act = (const struct roc_npc_action_vf 
*)actions->conf;
+                       sample_action->action_type |= ROC_NPC_ACTION_TYPE_VF;
+                       sample_action->pf_func = vf_act->id & 
NPC_PFVF_FUNC_MASK;
+                       break;
+               case RTE_FLOW_ACTION_TYPE_PORT_ID:
+                       rc = npc_parse_port_id_action(eth_dev, actions, 
&dst_pf_func, &dst_channel);
+                       if (rc)
+                               return -EINVAL;
+
+                       count++;
+                       sample_action->action_type |= 
ROC_NPC_ACTION_TYPE_PORT_ID;
+                       sample_action->pf_func = dst_pf_func;
+                       sample_action->channel = dst_channel;
+                       break;
+               default:
+                       continue;
+               }
+       }
+
+       if (count > 1 || is_empty)
+               return -EINVAL;
+
+       return 0;
+}
+
 static int
 cnxk_map_actions(struct rte_eth_dev *eth_dev, const struct rte_flow_attr *attr,
                 const struct rte_flow_action actions[], struct roc_npc_action 
in_actions[],
-                uint32_t *flowkey_cfg, uint16_t *dst_pf_func)
+                struct roc_npc_action_sample *in_sample_actions, uint32_t 
*flowkey_cfg,
+                uint16_t *dst_pf_func)
 {
        struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
        const struct rte_flow_action_queue *act_q = NULL;
        const struct rte_flow_action_ethdev *act_ethdev;
+       const struct rte_flow_action_sample *act_sample;
        const struct rte_flow_action_port_id *port_act;
        struct rte_eth_dev *portid_eth_dev;
        char if_name[RTE_ETH_NAME_MAX_LEN];
@@ -237,9 +325,21 @@ cnxk_map_actions(struct rte_eth_dev *eth_dev, const struct 
rte_flow_attr *attr,
                        in_actions[i].type = ROC_NPC_ACTION_TYPE_AGE;
                        in_actions[i].conf = actions->conf;
                        break;
+               case RTE_FLOW_ACTION_TYPE_SAMPLE:
+                       act_sample = actions->conf;
+                       in_sample_actions->ratio = act_sample->ratio;
+                       rc = roc_npc_parse_sample_subaction(eth_dev, 
act_sample->actions,
+                                                           in_sample_actions);
+                       if (rc) {
+                               plt_err("Sample subaction parsing failed.");
+                               goto err_exit;
+                       }
+
+                       in_actions[i].type = ROC_NPC_ACTION_TYPE_SAMPLE;
+                       in_actions[i].conf = in_sample_actions;
+                       break;
                default:
-                       plt_npc_dbg("Action is not supported = %d",
-                                   actions->type);
+                       plt_npc_dbg("Action is not supported = %d", 
actions->type);
                        goto err_exit;
                }
                i++;
@@ -263,7 +363,9 @@ static int
 cnxk_map_flow_data(struct rte_eth_dev *eth_dev, const struct rte_flow_attr 
*attr,
                   const struct rte_flow_item pattern[], const struct 
rte_flow_action actions[],
                   struct roc_npc_attr *in_attr, struct roc_npc_item_info 
in_pattern[],
-                  struct roc_npc_action in_actions[], uint32_t *flowkey_cfg, 
uint16_t *dst_pf_func)
+                  struct roc_npc_action in_actions[],
+                  struct roc_npc_action_sample *in_sample_actions, uint32_t 
*flowkey_cfg,
+                  uint16_t *dst_pf_func)
 {
        int i = 0;
 
@@ -282,7 +384,8 @@ cnxk_map_flow_data(struct rte_eth_dev *eth_dev, const 
struct rte_flow_attr *attr
        }
        in_pattern[i].type = ROC_NPC_ITEM_TYPE_END;
 
-       return cnxk_map_actions(eth_dev, attr, actions, in_actions, 
flowkey_cfg, dst_pf_func);
+       return cnxk_map_actions(eth_dev, attr, actions, in_actions, 
in_sample_actions, flowkey_cfg,
+                               dst_pf_func);
 }
 
 static int
@@ -293,6 +396,7 @@ cnxk_flow_validate(struct rte_eth_dev *eth_dev, const 
struct rte_flow_attr *attr
        struct roc_npc_item_info in_pattern[ROC_NPC_ITEM_TYPE_END + 1];
        struct roc_npc_action in_actions[ROC_NPC_MAX_ACTION_COUNT];
        struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
+       struct roc_npc_action_sample in_sample_action;
        struct roc_npc *npc = &dev->npc;
        struct roc_npc_attr in_attr;
        struct roc_npc_flow flow;
@@ -306,10 +410,11 @@ cnxk_flow_validate(struct rte_eth_dev *eth_dev, const 
struct rte_flow_attr *attr
                return 0;
 
        memset(&flow, 0, sizeof(flow));
+       memset(&in_sample_action, 0, sizeof(in_sample_action));
        flow.is_validate = true;
 
        rc = cnxk_map_flow_data(eth_dev, attr, pattern, actions, &in_attr, 
in_pattern, in_actions,
-                               &flowkey_cfg, &dst_pf_func);
+                               &in_sample_action, &flowkey_cfg, &dst_pf_func);
        if (rc) {
                rte_flow_error_set(error, 0, RTE_FLOW_ERROR_TYPE_ACTION_NUM, 
NULL,
                                   "Failed to map flow data");
@@ -335,6 +440,7 @@ cnxk_flow_create(struct rte_eth_dev *eth_dev, const struct 
rte_flow_attr *attr,
        struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
        struct roc_npc_item_info in_pattern[ROC_NPC_ITEM_TYPE_END + 1];
        struct roc_npc_action in_actions[ROC_NPC_MAX_ACTION_COUNT];
+       struct roc_npc_action_sample in_sample_action;
        struct roc_npc *npc = &dev->npc;
        struct roc_npc_attr in_attr;
        struct roc_npc_flow *flow;
@@ -342,8 +448,9 @@ cnxk_flow_create(struct rte_eth_dev *eth_dev, const struct 
rte_flow_attr *attr,
        int errcode = 0;
        int rc;
 
+       memset(&in_sample_action, 0, sizeof(in_sample_action));
        rc = cnxk_map_flow_data(eth_dev, attr, pattern, actions, &in_attr, 
in_pattern, in_actions,
-                               &npc->flowkey_cfg_state, &dst_pf_func);
+                               &in_sample_action, &npc->flowkey_cfg_state, 
&dst_pf_func);
        if (rc) {
                rte_flow_error_set(error, 0, RTE_FLOW_ERROR_TYPE_ACTION_NUM, 
NULL,
                                   "Failed to map flow data");
-- 
2.39.2

Reply via email to