@@ -97,6 +97,7 @@ port_id = Y
queue = Y
represented_port = Y
rss = Y
+sample = Y
security = Y
skip_cman = Y
vf = Y
@@ -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");