[RTE_FLOW_ITEM_TYPE_IPV6] = {ROC_NPC_ITEM_TYPE_IPV6,
sizeof(struct rte_flow_item_ipv6)},
[RTE_FLOW_ITEM_TYPE_ARP_ETH_IPV4] = {
- ROC_NPC_ITEM_TYPE_ARP_ETH_IPV4,
- sizeof(struct rte_flow_item_arp_eth_ipv4)},
+ ROC_NPC_ITEM_TYPE_ARP_ETH_IPV4,
+ sizeof(struct rte_flow_item_arp_eth_ipv4)},
[RTE_FLOW_ITEM_TYPE_MPLS] = {ROC_NPC_ITEM_TYPE_MPLS,
sizeof(struct rte_flow_item_mpls)},
[RTE_FLOW_ITEM_TYPE_ICMP] = {ROC_NPC_ITEM_TYPE_ICMP,
[RTE_FLOW_ITEM_TYPE_ANY] = {ROC_NPC_ITEM_TYPE_ANY, 0},
[RTE_FLOW_ITEM_TYPE_GRE_KEY] = {ROC_NPC_ITEM_TYPE_GRE_KEY,
sizeof(uint32_t)},
- [RTE_FLOW_ITEM_TYPE_HIGIG2] = {
- ROC_NPC_ITEM_TYPE_HIGIG2,
- sizeof(struct rte_flow_item_higig2_hdr)}
-};
+ [RTE_FLOW_ITEM_TYPE_HIGIG2] = {ROC_NPC_ITEM_TYPE_HIGIG2,
+ sizeof(struct rte_flow_item_higig2_hdr)},
+ [RTE_FLOW_ITEM_TYPE_RAW] = {ROC_NPC_ITEM_TYPE_RAW,
+ sizeof(struct rte_flow_item_raw)}};
+
+static int
+npc_rss_action_validate(struct rte_eth_dev *eth_dev,
+ const struct rte_flow_attr *attr,
+ const struct rte_flow_action *act)
+{
+ const struct rte_flow_action_rss *rss;
+
+ rss = (const struct rte_flow_action_rss *)act->conf;
+
+ if (attr->egress) {
+ plt_err("No support of RSS in egress");
+ return -EINVAL;
+ }
+
+ if (eth_dev->data->dev_conf.rxmode.mq_mode != ETH_MQ_RX_RSS) {
+ plt_err("multi-queue mode is disabled");
+ return -ENOTSUP;
+ }
+
+ if (!rss || !rss->queue_num) {
+ plt_err("no valid queues");
+ return -EINVAL;
+ }
+
+ if (rss->func != RTE_ETH_HASH_FUNCTION_DEFAULT) {
+ plt_err("non-default RSS hash functions are not supported");
+ return -ENOTSUP;
+ }
+
+ if (rss->key_len && rss->key_len > ROC_NIX_RSS_KEY_LEN) {
+ plt_err("RSS hash key too large");
+ return -ENOTSUP;
+ }
+
+ return 0;
+}
+
+static void
+npc_rss_flowkey_get(struct cnxk_eth_dev *eth_dev,
+ const struct roc_npc_action *rss_action,
+ uint32_t *flowkey_cfg)
+{
+ const struct roc_npc_action_rss *rss;
+
+ rss = (const struct roc_npc_action_rss *)rss_action->conf;
+
+ *flowkey_cfg = cnxk_rss_ethdev_to_nix(eth_dev, rss->types, rss->level);
+}
static int
-cnxk_map_actions(struct rte_eth_dev *eth_dev,
+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 in_actions[], uint32_t *flowkey_cfg)
{
+ struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
const struct rte_flow_action_count *act_count;
const struct rte_flow_action_queue *act_q;
+ int i = 0, rc = 0;
int rq;
- int i = 0;
for (; actions->type != RTE_FLOW_ACTION_TYPE_END; actions++) {
switch (actions->type) {
break;
case RTE_FLOW_ACTION_TYPE_RSS:
+ rc = npc_rss_action_validate(eth_dev, attr, actions);
+ if (rc)
+ goto err_exit;
in_actions[i].type = ROC_NPC_ACTION_TYPE_RSS;
+ in_actions[i].conf = actions->conf;
+ npc_rss_flowkey_get(dev, &in_actions[i], flowkey_cfg);
break;
case RTE_FLOW_ACTION_TYPE_SECURITY:
in_actions[i].type = ROC_NPC_ACTION_TYPE_SEC;
break;
+ case RTE_FLOW_ACTION_TYPE_OF_POP_VLAN:
+ in_actions[i].type = ROC_NPC_ACTION_TYPE_VLAN_STRIP;
+ break;
+ case RTE_FLOW_ACTION_TYPE_OF_SET_VLAN_VID:
+ in_actions[i].type = ROC_NPC_ACTION_TYPE_VLAN_INSERT;
+ in_actions[i].conf = actions->conf;
+ break;
+ case RTE_FLOW_ACTION_TYPE_OF_PUSH_VLAN:
+ in_actions[i].type =
+ ROC_NPC_ACTION_TYPE_VLAN_ETHTYPE_INSERT;
+ in_actions[i].conf = actions->conf;
+ break;
+ case RTE_FLOW_ACTION_TYPE_OF_SET_VLAN_PCP:
+ in_actions[i].type =
+ ROC_NPC_ACTION_TYPE_VLAN_PCP_INSERT;
+ in_actions[i].conf = actions->conf;
+ break;
default:
plt_npc_dbg("Action is not supported = %d",
actions->type);
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[])
+ struct roc_npc_action in_actions[], uint32_t *flowkey_cfg)
{
int i = 0;
}
in_pattern[i].type = ROC_NPC_ITEM_TYPE_END;
- return cnxk_map_actions(eth_dev, actions, in_actions);
+ return cnxk_map_actions(eth_dev, attr, actions, in_actions,
+ flowkey_cfg);
}
static int
struct roc_npc *npc = &dev->npc;
struct roc_npc_attr in_attr;
struct roc_npc_flow flow;
+ uint32_t flowkey_cfg = 0;
int rc;
memset(&flow, 0, sizeof(flow));
rc = cnxk_map_flow_data(eth_dev, attr, pattern, actions, &in_attr,
- in_pattern, in_actions);
+ in_pattern, in_actions, &flowkey_cfg);
if (rc) {
rte_flow_error_set(error, 0, RTE_FLOW_ERROR_TYPE_ACTION_NUM,
NULL, "Failed to map flow data");
struct roc_npc *npc = &dev->npc;
struct roc_npc_attr in_attr;
struct roc_npc_flow *flow;
- int errcode;
+ int errcode = 0;
int rc;
rc = cnxk_map_flow_data(eth_dev, attr, pattern, actions, &in_attr,
- in_pattern, in_actions);
+ in_pattern, in_actions,
+ &npc->flowkey_cfg_state);
if (rc) {
rte_flow_error_set(error, 0, RTE_FLOW_ERROR_TYPE_ACTION_NUM,
NULL, "Failed to map flow data");
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)
+{
+ struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
+ struct roc_npc *npc = &dev->npc;
+
+ if (file == NULL) {
+ rte_flow_error_set(error, EINVAL,
+ RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
+ "Invalid file");
+ return -rte_errno;
+ }
+
+ if (flow != NULL) {
+ rte_flow_error_set(error, EINVAL,
+ RTE_FLOW_ERROR_TYPE_HANDLE,
+ NULL,
+ "Invalid argument");
+ return -EINVAL;
+ }
+
+ roc_npc_flow_dump(file, npc);
+
+ return 0;
+}
+
struct rte_flow_ops cnxk_flow_ops = {
.validate = cnxk_flow_validate,
.flush = cnxk_flow_flush,
.query = cnxk_flow_query,
.isolate = cnxk_flow_isolate,
+ .dev_dump = cnxk_flow_dev_dump,
};