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 + drivers/net/cnxk/cnxk_flow.c | 121 ++++++++++++++++++++++++++++-- 2 files changed, 115 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/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