@@ -223,7 +223,7 @@ 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[],
struct roc_npc_action_sample *in_sample_actions, uint32_t *flowkey_cfg,
- uint16_t *dst_pf_func, uint8_t has_tunnel_pattern)
+ uint16_t *dst_pf_func, uint8_t has_tunnel_pattern, bool is_rep)
{
struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
const struct rte_flow_action_queue *act_q = NULL;
@@ -274,15 +274,18 @@ cnxk_map_actions(struct rte_eth_dev *eth_dev, const struct rte_flow_attr *attr,
case RTE_FLOW_ACTION_TYPE_REPRESENTED_PORT:
case RTE_FLOW_ACTION_TYPE_PORT_REPRESENTOR:
case RTE_FLOW_ACTION_TYPE_PORT_ID:
+ /* No port ID action on representor ethdevs */
+ if (is_rep)
+ continue;
in_actions[i].type = ROC_NPC_ACTION_TYPE_PORT_ID;
in_actions[i].conf = actions->conf;
- act_ethdev = (const struct rte_flow_action_ethdev *)
- actions->conf;
- port_act = (const struct rte_flow_action_port_id *)
- actions->conf;
+ act_ethdev = (const struct rte_flow_action_ethdev *)actions->conf;
+ port_act = (const struct rte_flow_action_port_id *)actions->conf;
if (rte_eth_dev_get_name_by_port(
- actions->type != RTE_FLOW_ACTION_TYPE_PORT_ID ?
- act_ethdev->port_id : port_act->id, if_name)) {
+ actions->type != RTE_FLOW_ACTION_TYPE_PORT_ID ?
+ act_ethdev->port_id :
+ port_act->id,
+ if_name)) {
plt_err("Name not found for output port id");
goto err_exit;
}
@@ -321,6 +324,9 @@ cnxk_map_actions(struct rte_eth_dev *eth_dev, const struct rte_flow_attr *attr,
break;
case RTE_FLOW_ACTION_TYPE_RSS:
+ /* No RSS action on representor ethdevs */
+ if (is_rep)
+ continue;
rc = npc_rss_action_validate(eth_dev, attr, actions);
if (rc)
goto err_exit;
@@ -397,22 +403,37 @@ cnxk_map_actions(struct rte_eth_dev *eth_dev, const struct rte_flow_attr *attr,
static int
cnxk_map_pattern(struct rte_eth_dev *eth_dev, const struct rte_flow_item pattern[],
- struct roc_npc_item_info in_pattern[], uint8_t *has_tunnel_pattern)
+ struct roc_npc_item_info in_pattern[], uint8_t *has_tunnel_pattern, bool is_rep)
{
- struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
const struct rte_flow_item_ethdev *rep_eth_dev;
struct rte_eth_dev *portid_eth_dev;
char if_name[RTE_ETH_NAME_MAX_LEN];
struct cnxk_eth_dev *hw_dst;
+ struct cnxk_rep_dev *rdev;
+ struct cnxk_eth_dev *dev;
+ struct roc_npc *npc;
int i = 0;
+ if (!is_rep) {
+ dev = cnxk_eth_pmd_priv(eth_dev);
+ npc = &dev->npc;
+ } else {
+ rdev = cnxk_rep_pmd_priv(eth_dev);
+ npc = &rdev->parent_dev->npc;
+
+ npc->rep_npc = npc;
+ npc->rep_port_id = rdev->port_id;
+ npc->rep_pf_func = rdev->hw_func;
+ }
+
while (pattern->type != RTE_FLOW_ITEM_TYPE_END) {
in_pattern[i].spec = pattern->spec;
in_pattern[i].last = pattern->last;
in_pattern[i].mask = pattern->mask;
in_pattern[i].type = term[pattern->type].item_type;
in_pattern[i].size = term[pattern->type].item_size;
- if (pattern->type == RTE_FLOW_ITEM_TYPE_REPRESENTED_PORT) {
+ if (pattern->type == RTE_FLOW_ITEM_TYPE_REPRESENTED_PORT ||
+ pattern->type == RTE_FLOW_ITEM_TYPE_PORT_REPRESENTOR) {
rep_eth_dev = (const struct rte_flow_item_ethdev *)pattern->spec;
if (rte_eth_dev_get_name_by_port(rep_eth_dev->port_id, if_name)) {
plt_err("Name not found for output port id");
@@ -423,11 +444,6 @@ cnxk_map_pattern(struct rte_eth_dev *eth_dev, const struct rte_flow_item pattern
plt_err("eth_dev not found for output port id");
goto fail;
}
- if (strcmp(portid_eth_dev->device->driver->name,
- eth_dev->device->driver->name) != 0) {
- plt_err("Output port not under same driver");
- goto fail;
- }
if (cnxk_ethdev_is_representor(if_name)) {
/* Case where represented port not part of same
* app and represented by a representor port.
@@ -437,20 +453,25 @@ cnxk_map_pattern(struct rte_eth_dev *eth_dev, const struct rte_flow_item pattern
rep_dev = cnxk_rep_pmd_priv(portid_eth_dev);
eswitch_dev = rep_dev->parent_dev;
- dev->npc.rep_npc = &eswitch_dev->npc;
- dev->npc.rep_port_id = rep_eth_dev->port_id;
- dev->npc.rep_pf_func = rep_dev->hw_func;
+ npc->rep_npc = &eswitch_dev->npc;
+ npc->rep_port_id = rep_eth_dev->port_id;
+ npc->rep_pf_func = rep_dev->hw_func;
plt_rep_dbg("Represented port %d act port %d rep_dev->hw_func 0x%x",
rep_eth_dev->port_id, eth_dev->data->port_id,
rep_dev->hw_func);
} else {
+ if (strcmp(portid_eth_dev->device->driver->name,
+ eth_dev->device->driver->name) != 0) {
+ plt_err("Output port not under same driver");
+ goto fail;
+ }
/* Case where represented port part of same app
* as PF.
*/
hw_dst = portid_eth_dev->data->dev_private;
- dev->npc.rep_npc = &hw_dst->npc;
- dev->npc.rep_port_id = rep_eth_dev->port_id;
- dev->npc.rep_pf_func = hw_dst->npc.pf_func;
+ npc->rep_npc = &hw_dst->npc;
+ npc->rep_port_id = rep_eth_dev->port_id;
+ npc->rep_pf_func = hw_dst->npc.pf_func;
}
}
@@ -474,7 +495,7 @@ cnxk_map_flow_data(struct rte_eth_dev *eth_dev, const struct rte_flow_attr *attr
struct roc_npc_attr *in_attr, struct roc_npc_item_info in_pattern[],
struct roc_npc_action in_actions[],
struct roc_npc_action_sample *in_sample_actions, uint32_t *flowkey_cfg,
- uint16_t *dst_pf_func)
+ uint16_t *dst_pf_func, bool is_rep)
{
uint8_t has_tunnel_pattern = 0;
int rc;
@@ -482,44 +503,61 @@ cnxk_map_flow_data(struct rte_eth_dev *eth_dev, const struct rte_flow_attr *attr
in_attr->priority = attr->priority;
in_attr->ingress = attr->ingress;
in_attr->egress = attr->egress;
+ if (attr->transfer) {
+ /* For representor ethdevs transfer attribute corresponds to egress rule */
+ if (is_rep)
+ in_attr->egress = attr->transfer;
+ else
+ in_attr->ingress = attr->transfer;
+ }
- rc = cnxk_map_pattern(eth_dev, pattern, in_pattern, &has_tunnel_pattern);
+ rc = cnxk_map_pattern(eth_dev, pattern, in_pattern, &has_tunnel_pattern, is_rep);
if (rc) {
plt_err("Failed to map pattern list");
return rc;
}
return cnxk_map_actions(eth_dev, attr, actions, in_actions, in_sample_actions, flowkey_cfg,
- dst_pf_func, has_tunnel_pattern);
+ dst_pf_func, has_tunnel_pattern, is_rep);
}
-static int
-cnxk_flow_validate(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 rte_flow_error *error)
+int
+cnxk_flow_validate_common(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 rte_flow_error *error,
+ bool is_rep)
{
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 cnxk_rep_dev *rep_dev;
struct roc_npc_attr in_attr;
+ struct cnxk_eth_dev *dev;
struct roc_npc_flow flow;
uint32_t flowkey_cfg = 0;
uint16_t dst_pf_func = 0;
+ struct roc_npc *npc;
int rc;
- /* Skip flow validation for MACsec. */
- if (actions[0].type == RTE_FLOW_ACTION_TYPE_SECURITY &&
- cnxk_eth_macsec_sess_get_by_sess(dev, actions[0].conf) != NULL)
- return 0;
+ /* is_rep set for operation performed via representor ports */
+ if (!is_rep) {
+ dev = cnxk_eth_pmd_priv(eth_dev);
+ npc = &dev->npc;
+ /* Skip flow validation for MACsec. */
+ if (actions[0].type == RTE_FLOW_ACTION_TYPE_SECURITY &&
+ cnxk_eth_macsec_sess_get_by_sess(dev, actions[0].conf) != NULL)
+ return 0;
+ } else {
+ rep_dev = cnxk_rep_pmd_priv(eth_dev);
+ npc = &rep_dev->parent_dev->npc;
+ }
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,
- &in_sample_action, &flowkey_cfg, &dst_pf_func);
+ &in_sample_action, &flowkey_cfg, &dst_pf_func, is_rep);
if (rc) {
rte_flow_error_set(error, 0, RTE_FLOW_ERROR_TYPE_ACTION_NUM, NULL,
"Failed to map flow data");
@@ -536,27 +574,45 @@ cnxk_flow_validate(struct rte_eth_dev *eth_dev, const struct rte_flow_attr *attr
return 0;
}
+static int
+cnxk_flow_validate(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 rte_flow_error *error)
+{
+ return cnxk_flow_validate_common(eth_dev, attr, pattern, actions, error, false);
+}
+
struct roc_npc_flow *
-cnxk_flow_create(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 rte_flow_error *error)
+cnxk_flow_create_common(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 rte_flow_error *error,
+ bool is_rep)
{
- 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 cnxk_rep_dev *rep_dev = NULL;
+ struct cnxk_eth_dev *dev = NULL;
struct roc_npc_attr in_attr;
struct roc_npc_flow *flow;
uint16_t dst_pf_func = 0;
+ struct roc_npc *npc;
int errcode = 0;
int rc;
+ /* is_rep set for operation performed via representor ports */
+ if (!is_rep) {
+ dev = cnxk_eth_pmd_priv(eth_dev);
+ npc = &dev->npc;
+ } else {
+ rep_dev = cnxk_rep_pmd_priv(eth_dev);
+ npc = &rep_dev->parent_dev->npc;
+ }
+
memset(&in_sample_action, 0, sizeof(in_sample_action));
memset(&in_attr, 0, sizeof(struct roc_npc_attr));
rc = cnxk_map_flow_data(eth_dev, attr, pattern, actions, &in_attr, in_pattern, in_actions,
- &in_sample_action, &npc->flowkey_cfg_state, &dst_pf_func);
+ &in_sample_action, &npc->flowkey_cfg_state, &dst_pf_func, is_rep);
if (rc) {
rte_flow_error_set(error, 0, RTE_FLOW_ERROR_TYPE_ACTION_NUM, NULL,
"Failed to map flow data");
@@ -572,32 +628,67 @@ cnxk_flow_create(struct rte_eth_dev *eth_dev, const struct rte_flow_attr *attr,
return flow;
}
+struct roc_npc_flow *
+cnxk_flow_create(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 rte_flow_error *error)
+{
+ return cnxk_flow_create_common(eth_dev, attr, pattern, actions, error, false);
+}
+
int
-cnxk_flow_destroy(struct rte_eth_dev *eth_dev, struct roc_npc_flow *flow,
- struct rte_flow_error *error)
+cnxk_flow_destroy_common(struct rte_eth_dev *eth_dev, struct roc_npc_flow *flow,
+ struct rte_flow_error *error, bool is_rep)
{
- struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
- struct roc_npc *npc = &dev->npc;
+ struct cnxk_rep_dev *rep_dev;
+ struct cnxk_eth_dev *dev;
+ struct roc_npc *npc;
int rc;
+ /* is_rep set for operation performed via representor ports */
+ if (!is_rep) {
+ dev = cnxk_eth_pmd_priv(eth_dev);
+ npc = &dev->npc;
+ } else {
+ rep_dev = cnxk_rep_pmd_priv(eth_dev);
+ npc = &rep_dev->parent_dev->npc;
+ }
+
rc = roc_npc_flow_destroy(npc, flow);
if (rc)
- rte_flow_error_set(error, rc, RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
- NULL, "Flow Destroy failed");
+ rte_flow_error_set(error, rc, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
+ "Flow Destroy failed");
return rc;
}
-static int
-cnxk_flow_flush(struct rte_eth_dev *eth_dev, struct rte_flow_error *error)
+int
+cnxk_flow_destroy(struct rte_eth_dev *eth_dev, struct roc_npc_flow *flow,
+ struct rte_flow_error *error)
{
- struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
- struct roc_npc *npc = &dev->npc;
+ return cnxk_flow_destroy_common(eth_dev, flow, error, false);
+}
+
+int
+cnxk_flow_flush_common(struct rte_eth_dev *eth_dev, struct rte_flow_error *error, bool is_rep)
+{
+ struct cnxk_rep_dev *rep_dev;
+ struct cnxk_eth_dev *dev;
+ struct roc_npc *npc;
int rc;
+ /* is_rep set for operation performed via representor ports */
+ if (!is_rep) {
+ dev = cnxk_eth_pmd_priv(eth_dev);
+ npc = &dev->npc;
+ } else {
+ rep_dev = cnxk_rep_pmd_priv(eth_dev);
+ npc = &rep_dev->parent_dev->npc;
+ }
+
rc = roc_npc_mcam_free_all_resources(npc);
if (rc) {
- rte_flow_error_set(error, EIO, RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
- NULL, "Failed to flush filter");
+ rte_flow_error_set(error, EIO, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
+ "Failed to flush filter");
return -rte_errno;
}
@@ -605,14 +696,21 @@ cnxk_flow_flush(struct rte_eth_dev *eth_dev, struct rte_flow_error *error)
}
static int
-cnxk_flow_query(struct rte_eth_dev *eth_dev, struct rte_flow *flow,
- const struct rte_flow_action *action, void *data,
- struct rte_flow_error *error)
+cnxk_flow_flush(struct rte_eth_dev *eth_dev, struct rte_flow_error *error)
+{
+ return cnxk_flow_flush_common(eth_dev, error, false);
+}
+
+int
+cnxk_flow_query_common(struct rte_eth_dev *eth_dev, struct rte_flow *flow,
+ const struct rte_flow_action *action, void *data,
+ struct rte_flow_error *error, bool is_rep)
{
struct roc_npc_flow *in_flow = (struct roc_npc_flow *)flow;
- struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
- struct roc_npc *npc = &dev->npc;
struct rte_flow_query_count *query = data;
+ struct cnxk_rep_dev *rep_dev;
+ struct cnxk_eth_dev *dev;
+ struct roc_npc *npc;
const char *errmsg = NULL;
int errcode = ENOTSUP;
int rc;
@@ -627,6 +725,15 @@ cnxk_flow_query(struct rte_eth_dev *eth_dev, struct rte_flow *flow,
goto err_exit;
}
+ /* is_rep set for operation performed via representor ports */
+ if (!is_rep) {
+ dev = cnxk_eth_pmd_priv(eth_dev);
+ npc = &dev->npc;
+ } else {
+ rep_dev = cnxk_rep_pmd_priv(eth_dev);
+ npc = &rep_dev->parent_dev->npc;
+ }
+
if (in_flow->use_pre_alloc)
rc = roc_npc_inl_mcam_read_counter(in_flow->ctr_id, &query->hits);
else
@@ -660,8 +767,15 @@ cnxk_flow_query(struct rte_eth_dev *eth_dev, struct rte_flow *flow,
}
static int
-cnxk_flow_isolate(struct rte_eth_dev *eth_dev __rte_unused,
- int enable __rte_unused, struct rte_flow_error *error)
+cnxk_flow_query(struct rte_eth_dev *eth_dev, struct rte_flow *flow,
+ const struct rte_flow_action *action, void *data, struct rte_flow_error *error)
+{
+ return cnxk_flow_query_common(eth_dev, flow, action, data, error, false);
+}
+
+static int
+cnxk_flow_isolate(struct rte_eth_dev *eth_dev __rte_unused, int enable __rte_unused,
+ struct rte_flow_error *error)
{
/* If we support, we need to un-install the default mcam
* entry for this port.
@@ -673,16 +787,25 @@ cnxk_flow_isolate(struct rte_eth_dev *eth_dev __rte_unused,
return -rte_errno;
}
-static int
-cnxk_flow_dev_dump(struct rte_eth_dev *eth_dev, struct rte_flow *flow,
- FILE *file, struct rte_flow_error *error)
+int
+cnxk_flow_dev_dump_common(struct rte_eth_dev *eth_dev, struct rte_flow *flow, FILE *file,
+ struct rte_flow_error *error, bool is_rep)
{
- struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
- struct roc_npc *npc = &dev->npc;
+ struct cnxk_rep_dev *rep_dev;
+ struct cnxk_eth_dev *dev;
+ struct roc_npc *npc;
+
+ /* is_rep set for operation performed via representor ports */
+ if (!is_rep) {
+ dev = cnxk_eth_pmd_priv(eth_dev);
+ npc = &dev->npc;
+ } else {
+ rep_dev = cnxk_rep_pmd_priv(eth_dev);
+ npc = &rep_dev->parent_dev->npc;
+ }
if (file == NULL) {
- rte_flow_error_set(error, EINVAL,
- RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
+ rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
"Invalid file");
return -rte_errno;
}
@@ -701,8 +824,15 @@ cnxk_flow_dev_dump(struct rte_eth_dev *eth_dev, struct rte_flow *flow,
}
static int
-cnxk_flow_get_aged_flows(struct rte_eth_dev *eth_dev, void **context,
- uint32_t nb_contexts, struct rte_flow_error *err)
+cnxk_flow_dev_dump(struct rte_eth_dev *eth_dev, struct rte_flow *flow, FILE *file,
+ struct rte_flow_error *error)
+{
+ return cnxk_flow_dev_dump_common(eth_dev, flow, file, error, false);
+}
+
+static int
+cnxk_flow_get_aged_flows(struct rte_eth_dev *eth_dev, void **context, uint32_t nb_contexts,
+ struct rte_flow_error *err)
{
struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
struct roc_npc *roc_npc = &dev->npc;
@@ -24,4 +24,22 @@ struct roc_npc_flow *cnxk_flow_create(struct rte_eth_dev *dev,
int cnxk_flow_destroy(struct rte_eth_dev *dev, struct roc_npc_flow *flow,
struct rte_flow_error *error);
+struct roc_npc_flow *cnxk_flow_create_common(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 rte_flow_error *error, bool is_rep);
+int cnxk_flow_validate_common(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 rte_flow_error *error,
+ bool is_rep);
+int cnxk_flow_destroy_common(struct rte_eth_dev *eth_dev, struct roc_npc_flow *flow,
+ struct rte_flow_error *error, bool is_rep);
+int cnxk_flow_flush_common(struct rte_eth_dev *eth_dev, struct rte_flow_error *error, bool is_rep);
+int cnxk_flow_query_common(struct rte_eth_dev *eth_dev, struct rte_flow *flow,
+ const struct rte_flow_action *action, void *data,
+ struct rte_flow_error *error, bool is_rep);
+int cnxk_flow_dev_dump_common(struct rte_eth_dev *eth_dev, struct rte_flow *flow, FILE *file,
+ struct rte_flow_error *error, bool is_rep);
+
#endif /* __CNXK_RTE_FLOW_H__ */