From: Jerin Jacob Date: Wed, 9 Feb 2022 16:50:26 +0000 (+0530) Subject: net/cnxk: unify file names X-Git-Url: http://git.droids-corp.org/?a=commitdiff_plain;h=795ac238916edbc5028b5edef5096adde0352f3a;p=dpdk.git net/cnxk: unify file names Except for the cn*_rte_flow* files, none of the other file has rte in the file name, remove the rte to unify the file name across the directory. Signed-off-by: Jerin Jacob Acked-by: Kiran Kumar K --- diff --git a/drivers/net/cnxk/cn10k_ethdev.c b/drivers/net/cnxk/cn10k_ethdev.c index 9bb08e1824..f3003dd3df 100644 --- a/drivers/net/cnxk/cn10k_ethdev.c +++ b/drivers/net/cnxk/cn10k_ethdev.c @@ -2,7 +2,7 @@ * Copyright(C) 2021 Marvell. */ #include "cn10k_ethdev.h" -#include "cn10k_rte_flow.h" +#include "cn10k_flow.h" #include "cn10k_rx.h" #include "cn10k_tx.h" diff --git a/drivers/net/cnxk/cn10k_flow.c b/drivers/net/cnxk/cn10k_flow.c new file mode 100644 index 0000000000..63281d41a4 --- /dev/null +++ b/drivers/net/cnxk/cn10k_flow.c @@ -0,0 +1,260 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(C) 2020 Marvell. + */ +#include +#include "cn10k_flow.h" +#include "cn10k_ethdev.h" +#include "cn10k_rx.h" + +static int +cn10k_mtr_connect(struct rte_eth_dev *eth_dev, uint32_t mtr_id) +{ + return nix_mtr_connect(eth_dev, mtr_id); +} + +static int +cn10k_mtr_destroy(struct rte_eth_dev *eth_dev, uint32_t mtr_id) +{ + struct rte_mtr_error mtr_error; + + return nix_mtr_destroy(eth_dev, mtr_id, &mtr_error); +} + +static int +cn10k_mtr_configure(struct rte_eth_dev *eth_dev, + const struct rte_flow_action actions[]) +{ + uint32_t mtr_id = 0xffff, prev_mtr_id = 0xffff, next_mtr_id = 0xffff; + const struct rte_flow_action_meter *mtr_conf; + const struct rte_flow_action_queue *q_conf; + const struct rte_flow_action_rss *rss_conf; + struct cnxk_mtr_policy_node *policy; + bool is_mtr_act = false; + int tree_level = 0; + int rc = -EINVAL, i; + + for (i = 0; actions[i].type != RTE_FLOW_ACTION_TYPE_END; i++) { + if (actions[i].type == RTE_FLOW_ACTION_TYPE_METER) { + mtr_conf = (const struct rte_flow_action_meter + *)(actions[i].conf); + mtr_id = mtr_conf->mtr_id; + is_mtr_act = true; + } + if (actions[i].type == RTE_FLOW_ACTION_TYPE_QUEUE) { + q_conf = (const struct rte_flow_action_queue + *)(actions[i].conf); + if (is_mtr_act) + nix_mtr_rq_update(eth_dev, mtr_id, 1, + &q_conf->index); + } + if (actions[i].type == RTE_FLOW_ACTION_TYPE_RSS) { + rss_conf = (const struct rte_flow_action_rss + *)(actions[i].conf); + if (is_mtr_act) + nix_mtr_rq_update(eth_dev, mtr_id, + rss_conf->queue_num, + rss_conf->queue); + } + } + + if (!is_mtr_act) + return rc; + + prev_mtr_id = mtr_id; + next_mtr_id = mtr_id; + while (next_mtr_id != 0xffff) { + rc = nix_mtr_validate(eth_dev, next_mtr_id); + if (rc) + return rc; + + rc = nix_mtr_policy_act_get(eth_dev, next_mtr_id, &policy); + if (rc) + return rc; + + rc = nix_mtr_color_action_validate(eth_dev, mtr_id, + &prev_mtr_id, &next_mtr_id, + policy, &tree_level); + if (rc) + return rc; + } + + return nix_mtr_configure(eth_dev, mtr_id); +} + +static int +cn10k_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; + + if (act == NULL) + return -EINVAL; + + 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 != RTE_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; +} + +struct rte_flow * +cn10k_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) +{ + struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev); + const struct rte_flow_action *action_rss = NULL; + const struct rte_flow_action_meter *mtr = NULL; + const struct rte_flow_action *act_q = NULL; + int mark_actions = 0, vtag_actions = 0; + struct roc_npc *npc = &dev->npc; + struct roc_npc_flow *flow; + uint32_t req_act = 0; + int i, rc; + + for (i = 0; actions[i].type != RTE_FLOW_ACTION_TYPE_END; i++) { + if (actions[i].type == RTE_FLOW_ACTION_TYPE_METER) + req_act |= ROC_NPC_ACTION_TYPE_METER; + + if (actions[i].type == RTE_FLOW_ACTION_TYPE_QUEUE) { + req_act |= ROC_NPC_ACTION_TYPE_QUEUE; + act_q = &actions[i]; + } + if (actions[i].type == RTE_FLOW_ACTION_TYPE_RSS) { + req_act |= ROC_NPC_ACTION_TYPE_RSS; + action_rss = &actions[i]; + } + } + + if (req_act & ROC_NPC_ACTION_TYPE_METER) { + if ((req_act & ROC_NPC_ACTION_TYPE_RSS) && + ((req_act & ROC_NPC_ACTION_TYPE_QUEUE))) { + return NULL; + } + if (req_act & ROC_NPC_ACTION_TYPE_RSS) { + rc = cn10k_rss_action_validate(eth_dev, attr, + action_rss); + if (rc) + return NULL; + } else if (req_act & ROC_NPC_ACTION_TYPE_QUEUE) { + const struct rte_flow_action_queue *act_queue; + act_queue = (const struct rte_flow_action_queue *) + act_q->conf; + if (act_queue->index > eth_dev->data->nb_rx_queues) + return NULL; + } else { + return NULL; + } + } + for (i = 0; actions[i].type != RTE_FLOW_ACTION_TYPE_END; i++) { + if (actions[i].type == RTE_FLOW_ACTION_TYPE_METER) { + mtr = (const struct rte_flow_action_meter *)actions[i] + .conf; + rc = cn10k_mtr_configure(eth_dev, actions); + if (rc) { + rte_flow_error_set(error, rc, + RTE_FLOW_ERROR_TYPE_ACTION, NULL, + "Failed to configure mtr "); + return NULL; + } + break; + } + } + + flow = cnxk_flow_create(eth_dev, attr, pattern, actions, error); + if (!flow) { + if (mtr) + nix_mtr_chain_reset(eth_dev, mtr->mtr_id); + + return NULL; + } else { + if (mtr) + cn10k_mtr_connect(eth_dev, mtr->mtr_id); + } + + mark_actions = roc_npc_mark_actions_get(npc); + + if (mark_actions) { + dev->rx_offload_flags |= NIX_RX_OFFLOAD_MARK_UPDATE_F; + cn10k_eth_set_rx_function(eth_dev); + } + + vtag_actions = roc_npc_vtag_actions_get(npc); + + if (vtag_actions) { + dev->rx_offload_flags |= NIX_RX_OFFLOAD_VLAN_STRIP_F; + cn10k_eth_set_rx_function(eth_dev); + } + + return (struct rte_flow *)flow; +} + +int +cn10k_flow_destroy(struct rte_eth_dev *eth_dev, struct rte_flow *rte_flow, + struct rte_flow_error *error) +{ + struct roc_npc_flow *flow = (struct roc_npc_flow *)rte_flow; + struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev); + int mark_actions = 0, vtag_actions = 0; + struct roc_npc *npc = &dev->npc; + uint32_t mtr_id; + int rc; + + mark_actions = roc_npc_mark_actions_get(npc); + if (mark_actions) { + mark_actions = roc_npc_mark_actions_sub_return(npc, 1); + if (mark_actions == 0) { + dev->rx_offload_flags &= ~NIX_RX_OFFLOAD_MARK_UPDATE_F; + cn10k_eth_set_rx_function(eth_dev); + } + } + + vtag_actions = roc_npc_vtag_actions_get(npc); + if (vtag_actions) { + if (flow->nix_intf == ROC_NPC_INTF_RX) { + vtag_actions = roc_npc_vtag_actions_sub_return(npc, 1); + if (vtag_actions == 0) { + dev->rx_offload_flags &= + ~NIX_RX_OFFLOAD_VLAN_STRIP_F; + cn10k_eth_set_rx_function(eth_dev); + } + } + } + + mtr_id = flow->mtr_id; + rc = cnxk_flow_destroy(eth_dev, flow, error); + if (!rc && mtr_id != ROC_NIX_MTR_ID_INVALID) { + rc = cn10k_mtr_destroy(eth_dev, mtr_id); + if (rc) { + rte_flow_error_set(error, ENXIO, + RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL, + "Meter attached to this flow does not exist"); + } + } + return rc; +} diff --git a/drivers/net/cnxk/cn10k_flow.h b/drivers/net/cnxk/cn10k_flow.h new file mode 100644 index 0000000000..f64fcf2a5e --- /dev/null +++ b/drivers/net/cnxk/cn10k_flow.h @@ -0,0 +1,17 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(C) 2020 Marvell. + */ +#ifndef __CN10K_RTE_FLOW_H__ +#define __CN10K_RTE_FLOW_H__ + +#include + +struct rte_flow *cn10k_flow_create(struct rte_eth_dev *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 cn10k_flow_destroy(struct rte_eth_dev *dev, struct rte_flow *flow, + struct rte_flow_error *error); + +#endif /* __CN10K_RTE_FLOW_H__ */ diff --git a/drivers/net/cnxk/cn10k_rte_flow.c b/drivers/net/cnxk/cn10k_rte_flow.c deleted file mode 100644 index 529fb0e4b7..0000000000 --- a/drivers/net/cnxk/cn10k_rte_flow.c +++ /dev/null @@ -1,260 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause - * Copyright(C) 2020 Marvell. - */ -#include -#include "cn10k_rte_flow.h" -#include "cn10k_ethdev.h" -#include "cn10k_rx.h" - -static int -cn10k_mtr_connect(struct rte_eth_dev *eth_dev, uint32_t mtr_id) -{ - return nix_mtr_connect(eth_dev, mtr_id); -} - -static int -cn10k_mtr_destroy(struct rte_eth_dev *eth_dev, uint32_t mtr_id) -{ - struct rte_mtr_error mtr_error; - - return nix_mtr_destroy(eth_dev, mtr_id, &mtr_error); -} - -static int -cn10k_mtr_configure(struct rte_eth_dev *eth_dev, - const struct rte_flow_action actions[]) -{ - uint32_t mtr_id = 0xffff, prev_mtr_id = 0xffff, next_mtr_id = 0xffff; - const struct rte_flow_action_meter *mtr_conf; - const struct rte_flow_action_queue *q_conf; - const struct rte_flow_action_rss *rss_conf; - struct cnxk_mtr_policy_node *policy; - bool is_mtr_act = false; - int tree_level = 0; - int rc = -EINVAL, i; - - for (i = 0; actions[i].type != RTE_FLOW_ACTION_TYPE_END; i++) { - if (actions[i].type == RTE_FLOW_ACTION_TYPE_METER) { - mtr_conf = (const struct rte_flow_action_meter - *)(actions[i].conf); - mtr_id = mtr_conf->mtr_id; - is_mtr_act = true; - } - if (actions[i].type == RTE_FLOW_ACTION_TYPE_QUEUE) { - q_conf = (const struct rte_flow_action_queue - *)(actions[i].conf); - if (is_mtr_act) - nix_mtr_rq_update(eth_dev, mtr_id, 1, - &q_conf->index); - } - if (actions[i].type == RTE_FLOW_ACTION_TYPE_RSS) { - rss_conf = (const struct rte_flow_action_rss - *)(actions[i].conf); - if (is_mtr_act) - nix_mtr_rq_update(eth_dev, mtr_id, - rss_conf->queue_num, - rss_conf->queue); - } - } - - if (!is_mtr_act) - return rc; - - prev_mtr_id = mtr_id; - next_mtr_id = mtr_id; - while (next_mtr_id != 0xffff) { - rc = nix_mtr_validate(eth_dev, next_mtr_id); - if (rc) - return rc; - - rc = nix_mtr_policy_act_get(eth_dev, next_mtr_id, &policy); - if (rc) - return rc; - - rc = nix_mtr_color_action_validate(eth_dev, mtr_id, - &prev_mtr_id, &next_mtr_id, - policy, &tree_level); - if (rc) - return rc; - } - - return nix_mtr_configure(eth_dev, mtr_id); -} - -static int -cn10k_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; - - if (act == NULL) - return -EINVAL; - - 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 != RTE_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; -} - -struct rte_flow * -cn10k_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) -{ - struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev); - const struct rte_flow_action *action_rss = NULL; - const struct rte_flow_action_meter *mtr = NULL; - const struct rte_flow_action *act_q = NULL; - int mark_actions = 0, vtag_actions = 0; - struct roc_npc *npc = &dev->npc; - struct roc_npc_flow *flow; - uint32_t req_act = 0; - int i, rc; - - for (i = 0; actions[i].type != RTE_FLOW_ACTION_TYPE_END; i++) { - if (actions[i].type == RTE_FLOW_ACTION_TYPE_METER) - req_act |= ROC_NPC_ACTION_TYPE_METER; - - if (actions[i].type == RTE_FLOW_ACTION_TYPE_QUEUE) { - req_act |= ROC_NPC_ACTION_TYPE_QUEUE; - act_q = &actions[i]; - } - if (actions[i].type == RTE_FLOW_ACTION_TYPE_RSS) { - req_act |= ROC_NPC_ACTION_TYPE_RSS; - action_rss = &actions[i]; - } - } - - if (req_act & ROC_NPC_ACTION_TYPE_METER) { - if ((req_act & ROC_NPC_ACTION_TYPE_RSS) && - ((req_act & ROC_NPC_ACTION_TYPE_QUEUE))) { - return NULL; - } - if (req_act & ROC_NPC_ACTION_TYPE_RSS) { - rc = cn10k_rss_action_validate(eth_dev, attr, - action_rss); - if (rc) - return NULL; - } else if (req_act & ROC_NPC_ACTION_TYPE_QUEUE) { - const struct rte_flow_action_queue *act_queue; - act_queue = (const struct rte_flow_action_queue *) - act_q->conf; - if (act_queue->index > eth_dev->data->nb_rx_queues) - return NULL; - } else { - return NULL; - } - } - for (i = 0; actions[i].type != RTE_FLOW_ACTION_TYPE_END; i++) { - if (actions[i].type == RTE_FLOW_ACTION_TYPE_METER) { - mtr = (const struct rte_flow_action_meter *)actions[i] - .conf; - rc = cn10k_mtr_configure(eth_dev, actions); - if (rc) { - rte_flow_error_set(error, rc, - RTE_FLOW_ERROR_TYPE_ACTION, NULL, - "Failed to configure mtr "); - return NULL; - } - break; - } - } - - flow = cnxk_flow_create(eth_dev, attr, pattern, actions, error); - if (!flow) { - if (mtr) - nix_mtr_chain_reset(eth_dev, mtr->mtr_id); - - return NULL; - } else { - if (mtr) - cn10k_mtr_connect(eth_dev, mtr->mtr_id); - } - - mark_actions = roc_npc_mark_actions_get(npc); - - if (mark_actions) { - dev->rx_offload_flags |= NIX_RX_OFFLOAD_MARK_UPDATE_F; - cn10k_eth_set_rx_function(eth_dev); - } - - vtag_actions = roc_npc_vtag_actions_get(npc); - - if (vtag_actions) { - dev->rx_offload_flags |= NIX_RX_OFFLOAD_VLAN_STRIP_F; - cn10k_eth_set_rx_function(eth_dev); - } - - return (struct rte_flow *)flow; -} - -int -cn10k_flow_destroy(struct rte_eth_dev *eth_dev, struct rte_flow *rte_flow, - struct rte_flow_error *error) -{ - struct roc_npc_flow *flow = (struct roc_npc_flow *)rte_flow; - struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev); - int mark_actions = 0, vtag_actions = 0; - struct roc_npc *npc = &dev->npc; - uint32_t mtr_id; - int rc; - - mark_actions = roc_npc_mark_actions_get(npc); - if (mark_actions) { - mark_actions = roc_npc_mark_actions_sub_return(npc, 1); - if (mark_actions == 0) { - dev->rx_offload_flags &= ~NIX_RX_OFFLOAD_MARK_UPDATE_F; - cn10k_eth_set_rx_function(eth_dev); - } - } - - vtag_actions = roc_npc_vtag_actions_get(npc); - if (vtag_actions) { - if (flow->nix_intf == ROC_NPC_INTF_RX) { - vtag_actions = roc_npc_vtag_actions_sub_return(npc, 1); - if (vtag_actions == 0) { - dev->rx_offload_flags &= - ~NIX_RX_OFFLOAD_VLAN_STRIP_F; - cn10k_eth_set_rx_function(eth_dev); - } - } - } - - mtr_id = flow->mtr_id; - rc = cnxk_flow_destroy(eth_dev, flow, error); - if (!rc && mtr_id != ROC_NIX_MTR_ID_INVALID) { - rc = cn10k_mtr_destroy(eth_dev, mtr_id); - if (rc) { - rte_flow_error_set(error, ENXIO, - RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL, - "Meter attached to this flow does not exist"); - } - } - return rc; -} diff --git a/drivers/net/cnxk/cn10k_rte_flow.h b/drivers/net/cnxk/cn10k_rte_flow.h deleted file mode 100644 index f64fcf2a5e..0000000000 --- a/drivers/net/cnxk/cn10k_rte_flow.h +++ /dev/null @@ -1,17 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause - * Copyright(C) 2020 Marvell. - */ -#ifndef __CN10K_RTE_FLOW_H__ -#define __CN10K_RTE_FLOW_H__ - -#include - -struct rte_flow *cn10k_flow_create(struct rte_eth_dev *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 cn10k_flow_destroy(struct rte_eth_dev *dev, struct rte_flow *flow, - struct rte_flow_error *error); - -#endif /* __CN10K_RTE_FLOW_H__ */ diff --git a/drivers/net/cnxk/cn9k_ethdev.c b/drivers/net/cnxk/cn9k_ethdev.c index 01e3850561..a890829065 100644 --- a/drivers/net/cnxk/cn9k_ethdev.c +++ b/drivers/net/cnxk/cn9k_ethdev.c @@ -2,7 +2,7 @@ * Copyright(C) 2021 Marvell. */ #include "cn9k_ethdev.h" -#include "cn9k_rte_flow.h" +#include "cn9k_flow.h" #include "cn9k_rx.h" #include "cn9k_tx.h" diff --git a/drivers/net/cnxk/cn9k_flow.c b/drivers/net/cnxk/cn9k_flow.c new file mode 100644 index 0000000000..d67580bf27 --- /dev/null +++ b/drivers/net/cnxk/cn9k_flow.c @@ -0,0 +1,72 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(C) 2020 Marvell. + */ +#include +#include "cn9k_ethdev.h" +#include "cn9k_flow.h" +#include "cn9k_rx.h" + +struct rte_flow * +cn9k_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) +{ + struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev); + int mark_actions = 0, vtag_actions = 0; + struct roc_npc *npc = &dev->npc; + struct roc_npc_flow *flow; + + flow = cnxk_flow_create(eth_dev, attr, pattern, actions, error); + if (!flow) + return NULL; + + mark_actions = roc_npc_mark_actions_get(npc); + + if (mark_actions) { + dev->rx_offload_flags |= NIX_RX_OFFLOAD_MARK_UPDATE_F; + cn9k_eth_set_rx_function(eth_dev); + } + + vtag_actions = roc_npc_vtag_actions_get(npc); + + if (vtag_actions) { + dev->rx_offload_flags |= NIX_RX_OFFLOAD_VLAN_STRIP_F; + cn9k_eth_set_rx_function(eth_dev); + } + + return (struct rte_flow *)flow; +} + +int +cn9k_flow_destroy(struct rte_eth_dev *eth_dev, struct rte_flow *rte_flow, + struct rte_flow_error *error) +{ + struct roc_npc_flow *flow = (struct roc_npc_flow *)rte_flow; + struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev); + int mark_actions = 0, vtag_actions = 0; + struct roc_npc *npc = &dev->npc; + + mark_actions = roc_npc_mark_actions_get(npc); + if (mark_actions) { + mark_actions = roc_npc_mark_actions_sub_return(npc, 1); + if (mark_actions == 0) { + dev->rx_offload_flags &= ~NIX_RX_OFFLOAD_MARK_UPDATE_F; + cn9k_eth_set_rx_function(eth_dev); + } + } + + vtag_actions = roc_npc_vtag_actions_get(npc); + if (vtag_actions) { + if (flow->nix_intf == ROC_NPC_INTF_RX) { + vtag_actions = roc_npc_vtag_actions_sub_return(npc, 1); + if (vtag_actions == 0) { + dev->rx_offload_flags &= + ~NIX_RX_OFFLOAD_VLAN_STRIP_F; + cn9k_eth_set_rx_function(eth_dev); + } + } + } + + return cnxk_flow_destroy(eth_dev, flow, error); +} diff --git a/drivers/net/cnxk/cn9k_flow.h b/drivers/net/cnxk/cn9k_flow.h new file mode 100644 index 0000000000..43d59e1eb2 --- /dev/null +++ b/drivers/net/cnxk/cn9k_flow.h @@ -0,0 +1,17 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(C) 2020 Marvell. + */ +#ifndef __CN9K_RTE_FLOW_H__ +#define __CN9K_RTE_FLOW_H__ + +#include + +struct rte_flow *cn9k_flow_create(struct rte_eth_dev *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 cn9k_flow_destroy(struct rte_eth_dev *dev, struct rte_flow *flow, + struct rte_flow_error *error); + +#endif /* __CN9K_RTE_FLOW_H__ */ diff --git a/drivers/net/cnxk/cn9k_rte_flow.c b/drivers/net/cnxk/cn9k_rte_flow.c deleted file mode 100644 index b94d29e547..0000000000 --- a/drivers/net/cnxk/cn9k_rte_flow.c +++ /dev/null @@ -1,72 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause - * Copyright(C) 2020 Marvell. - */ -#include -#include "cn9k_ethdev.h" -#include "cn9k_rte_flow.h" -#include "cn9k_rx.h" - -struct rte_flow * -cn9k_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) -{ - struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev); - int mark_actions = 0, vtag_actions = 0; - struct roc_npc *npc = &dev->npc; - struct roc_npc_flow *flow; - - flow = cnxk_flow_create(eth_dev, attr, pattern, actions, error); - if (!flow) - return NULL; - - mark_actions = roc_npc_mark_actions_get(npc); - - if (mark_actions) { - dev->rx_offload_flags |= NIX_RX_OFFLOAD_MARK_UPDATE_F; - cn9k_eth_set_rx_function(eth_dev); - } - - vtag_actions = roc_npc_vtag_actions_get(npc); - - if (vtag_actions) { - dev->rx_offload_flags |= NIX_RX_OFFLOAD_VLAN_STRIP_F; - cn9k_eth_set_rx_function(eth_dev); - } - - return (struct rte_flow *)flow; -} - -int -cn9k_flow_destroy(struct rte_eth_dev *eth_dev, struct rte_flow *rte_flow, - struct rte_flow_error *error) -{ - struct roc_npc_flow *flow = (struct roc_npc_flow *)rte_flow; - struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev); - int mark_actions = 0, vtag_actions = 0; - struct roc_npc *npc = &dev->npc; - - mark_actions = roc_npc_mark_actions_get(npc); - if (mark_actions) { - mark_actions = roc_npc_mark_actions_sub_return(npc, 1); - if (mark_actions == 0) { - dev->rx_offload_flags &= ~NIX_RX_OFFLOAD_MARK_UPDATE_F; - cn9k_eth_set_rx_function(eth_dev); - } - } - - vtag_actions = roc_npc_vtag_actions_get(npc); - if (vtag_actions) { - if (flow->nix_intf == ROC_NPC_INTF_RX) { - vtag_actions = roc_npc_vtag_actions_sub_return(npc, 1); - if (vtag_actions == 0) { - dev->rx_offload_flags &= - ~NIX_RX_OFFLOAD_VLAN_STRIP_F; - cn9k_eth_set_rx_function(eth_dev); - } - } - } - - return cnxk_flow_destroy(eth_dev, flow, error); -} diff --git a/drivers/net/cnxk/cn9k_rte_flow.h b/drivers/net/cnxk/cn9k_rte_flow.h deleted file mode 100644 index 43d59e1eb2..0000000000 --- a/drivers/net/cnxk/cn9k_rte_flow.h +++ /dev/null @@ -1,17 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause - * Copyright(C) 2020 Marvell. - */ -#ifndef __CN9K_RTE_FLOW_H__ -#define __CN9K_RTE_FLOW_H__ - -#include - -struct rte_flow *cn9k_flow_create(struct rte_eth_dev *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 cn9k_flow_destroy(struct rte_eth_dev *dev, struct rte_flow *flow, - struct rte_flow_error *error); - -#endif /* __CN9K_RTE_FLOW_H__ */ diff --git a/drivers/net/cnxk/cnxk_flow.c b/drivers/net/cnxk/cnxk_flow.c new file mode 100644 index 0000000000..8763ca63d6 --- /dev/null +++ b/drivers/net/cnxk/cnxk_flow.c @@ -0,0 +1,465 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(C) 2021 Marvell. + */ +#include + +const struct cnxk_rte_flow_term_info term[] = { + [RTE_FLOW_ITEM_TYPE_ETH] = {ROC_NPC_ITEM_TYPE_ETH, + sizeof(struct rte_flow_item_eth)}, + [RTE_FLOW_ITEM_TYPE_VLAN] = {ROC_NPC_ITEM_TYPE_VLAN, + sizeof(struct rte_flow_item_vlan)}, + [RTE_FLOW_ITEM_TYPE_E_TAG] = {ROC_NPC_ITEM_TYPE_E_TAG, + sizeof(struct rte_flow_item_e_tag)}, + [RTE_FLOW_ITEM_TYPE_IPV4] = {ROC_NPC_ITEM_TYPE_IPV4, + sizeof(struct rte_flow_item_ipv4)}, + [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)}, + [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, + sizeof(struct rte_flow_item_icmp)}, + [RTE_FLOW_ITEM_TYPE_UDP] = {ROC_NPC_ITEM_TYPE_UDP, + sizeof(struct rte_flow_item_udp)}, + [RTE_FLOW_ITEM_TYPE_TCP] = {ROC_NPC_ITEM_TYPE_TCP, + sizeof(struct rte_flow_item_tcp)}, + [RTE_FLOW_ITEM_TYPE_SCTP] = {ROC_NPC_ITEM_TYPE_SCTP, + sizeof(struct rte_flow_item_sctp)}, + [RTE_FLOW_ITEM_TYPE_ESP] = {ROC_NPC_ITEM_TYPE_ESP, + sizeof(struct rte_flow_item_esp)}, + [RTE_FLOW_ITEM_TYPE_GRE] = {ROC_NPC_ITEM_TYPE_GRE, + sizeof(struct rte_flow_item_gre)}, + [RTE_FLOW_ITEM_TYPE_NVGRE] = {ROC_NPC_ITEM_TYPE_NVGRE, + sizeof(struct rte_flow_item_nvgre)}, + [RTE_FLOW_ITEM_TYPE_VXLAN] = {ROC_NPC_ITEM_TYPE_VXLAN, + sizeof(struct rte_flow_item_vxlan)}, + [RTE_FLOW_ITEM_TYPE_GTPC] = {ROC_NPC_ITEM_TYPE_GTPC, + sizeof(struct rte_flow_item_gtp)}, + [RTE_FLOW_ITEM_TYPE_GTPU] = {ROC_NPC_ITEM_TYPE_GTPU, + sizeof(struct rte_flow_item_gtp)}, + [RTE_FLOW_ITEM_TYPE_GENEVE] = {ROC_NPC_ITEM_TYPE_GENEVE, + sizeof(struct rte_flow_item_geneve)}, + [RTE_FLOW_ITEM_TYPE_VXLAN_GPE] = { + ROC_NPC_ITEM_TYPE_VXLAN_GPE, + sizeof(struct rte_flow_item_vxlan_gpe)}, + [RTE_FLOW_ITEM_TYPE_IPV6_EXT] = {ROC_NPC_ITEM_TYPE_IPV6_EXT, + sizeof(struct rte_flow_item_ipv6_ext)}, + [RTE_FLOW_ITEM_TYPE_VOID] = {ROC_NPC_ITEM_TYPE_VOID, 0}, + [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_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 != RTE_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, const struct rte_flow_attr *attr, + const struct rte_flow_action 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_port_id *port_act; + const struct rte_flow_action_queue *act_q; + struct roc_npc *roc_npc_src = &dev->npc; + 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 i = 0, rc = 0; + int rq; + + for (; actions->type != RTE_FLOW_ACTION_TYPE_END; actions++) { + switch (actions->type) { + case RTE_FLOW_ACTION_TYPE_VOID: + in_actions[i].type = ROC_NPC_ACTION_TYPE_VOID; + break; + + case RTE_FLOW_ACTION_TYPE_MARK: + in_actions[i].type = ROC_NPC_ACTION_TYPE_MARK; + in_actions[i].conf = actions->conf; + break; + + case RTE_FLOW_ACTION_TYPE_FLAG: + in_actions[i].type = ROC_NPC_ACTION_TYPE_FLAG; + break; + + case RTE_FLOW_ACTION_TYPE_COUNT: + in_actions[i].type = ROC_NPC_ACTION_TYPE_COUNT; + break; + + case RTE_FLOW_ACTION_TYPE_DROP: + in_actions[i].type = ROC_NPC_ACTION_TYPE_DROP; + break; + + case RTE_FLOW_ACTION_TYPE_PF: + in_actions[i].type = ROC_NPC_ACTION_TYPE_PF; + break; + + case RTE_FLOW_ACTION_TYPE_VF: + in_actions[i].type = ROC_NPC_ACTION_TYPE_VF; + in_actions[i].conf = actions->conf; + break; + + case RTE_FLOW_ACTION_TYPE_PORT_ID: + in_actions[i].type = ROC_NPC_ACTION_TYPE_PORT_ID; + in_actions[i].conf = actions->conf; + port_act = (const struct rte_flow_action_port_id *) + actions->conf; + if (rte_eth_dev_get_name_by_port(port_act->id, + if_name)) { + 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; + + rc = roc_npc_validate_portid_action(roc_npc_src, + roc_npc_dst); + + if (rc) + goto err_exit; + break; + + case RTE_FLOW_ACTION_TYPE_QUEUE: + act_q = (const struct rte_flow_action_queue *) + actions->conf; + rq = act_q->index; + if (rq >= eth_dev->data->nb_rx_queues) { + plt_npc_dbg("Invalid queue index"); + goto err_exit; + } + in_actions[i].type = ROC_NPC_ACTION_TYPE_QUEUE; + in_actions[i].conf = actions->conf; + 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; + case RTE_FLOW_ACTION_TYPE_METER: + in_actions[i].type = ROC_NPC_ACTION_TYPE_METER; + in_actions[i].conf = actions->conf; + break; + default: + plt_npc_dbg("Action is not supported = %d", + actions->type); + goto err_exit; + } + i++; + } + in_actions[i].type = ROC_NPC_ACTION_TYPE_END; + return 0; + +err_exit: + return -EINVAL; +} + +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) +{ + int i = 0; + + in_attr->priority = attr->priority; + in_attr->ingress = attr->ingress; + in_attr->egress = attr->egress; + + 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; + pattern++; + i++; + } + in_pattern[i].type = ROC_NPC_ITEM_TYPE_END; + + return cnxk_map_actions(eth_dev, attr, actions, in_actions, + flowkey_cfg); +} + +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) +{ + 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 *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, &flowkey_cfg); + if (rc) { + rte_flow_error_set(error, 0, RTE_FLOW_ERROR_TYPE_ACTION_NUM, + NULL, "Failed to map flow data"); + return rc; + } + + return roc_npc_flow_parse(npc, &in_attr, in_pattern, in_actions, &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) +{ + 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 *npc = &dev->npc; + struct roc_npc_attr in_attr; + struct roc_npc_flow *flow; + int errcode = 0; + int rc; + + rc = cnxk_map_flow_data(eth_dev, attr, pattern, actions, &in_attr, + 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 NULL; + } + + flow = roc_npc_flow_create(npc, &in_attr, in_pattern, in_actions, + &errcode); + if (errcode != 0) { + rte_flow_error_set(error, errcode, errcode, NULL, + roc_error_msg_get(errcode)); + return NULL; + } + + return flow; +} + +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; + int rc; + + rc = roc_npc_flow_destroy(npc, flow); + if (rc) + 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) +{ + struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev); + struct roc_npc *npc = &dev->npc; + int rc; + + 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"); + return -rte_errno; + } + + return 0; +} + +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) +{ + 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; + const char *errmsg = NULL; + int errcode = ENOTSUP; + int rc; + + if (action->type != RTE_FLOW_ACTION_TYPE_COUNT) { + errmsg = "Only COUNT is supported in query"; + goto err_exit; + } + + if (in_flow->ctr_id == NPC_COUNTER_NONE) { + errmsg = "Counter is not available"; + goto err_exit; + } + + rc = roc_npc_mcam_read_counter(npc, in_flow->ctr_id, &query->hits); + if (rc != 0) { + errcode = EIO; + errmsg = "Error reading flow counter"; + goto err_exit; + } + query->hits_set = 1; + query->bytes_set = 0; + + if (query->reset) + rc = roc_npc_mcam_clear_counter(npc, in_flow->ctr_id); + if (rc != 0) { + errcode = EIO; + errmsg = "Error clearing flow counter"; + goto err_exit; + } + + return 0; + +err_exit: + rte_flow_error_set(error, errcode, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, + NULL, errmsg); + return -rte_errno; +} + +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. + */ + + rte_flow_error_set(error, ENOTSUP, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, + NULL, "Flow isolation not supported"); + + 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, +}; diff --git a/drivers/net/cnxk/cnxk_flow.h b/drivers/net/cnxk/cnxk_flow.h new file mode 100644 index 0000000000..bb23629819 --- /dev/null +++ b/drivers/net/cnxk/cnxk_flow.h @@ -0,0 +1,27 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(C) 2021 Marvell. + */ +#ifndef __CNXK_RTE_FLOW_H__ +#define __CNXK_RTE_FLOW_H__ + +#include +#include + +#include "cnxk_ethdev.h" +#include "roc_api.h" +#include "roc_npc_priv.h" + +struct cnxk_rte_flow_term_info { + uint16_t item_type; + uint16_t item_size; +}; + +struct roc_npc_flow *cnxk_flow_create(struct rte_eth_dev *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_destroy(struct rte_eth_dev *dev, struct roc_npc_flow *flow, + struct rte_flow_error *error); + +#endif /* __CNXK_RTE_FLOW_H__ */ diff --git a/drivers/net/cnxk/cnxk_rte_flow.c b/drivers/net/cnxk/cnxk_rte_flow.c deleted file mode 100644 index b08d7c34fa..0000000000 --- a/drivers/net/cnxk/cnxk_rte_flow.c +++ /dev/null @@ -1,465 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause - * Copyright(C) 2021 Marvell. - */ -#include - -const struct cnxk_rte_flow_term_info term[] = { - [RTE_FLOW_ITEM_TYPE_ETH] = {ROC_NPC_ITEM_TYPE_ETH, - sizeof(struct rte_flow_item_eth)}, - [RTE_FLOW_ITEM_TYPE_VLAN] = {ROC_NPC_ITEM_TYPE_VLAN, - sizeof(struct rte_flow_item_vlan)}, - [RTE_FLOW_ITEM_TYPE_E_TAG] = {ROC_NPC_ITEM_TYPE_E_TAG, - sizeof(struct rte_flow_item_e_tag)}, - [RTE_FLOW_ITEM_TYPE_IPV4] = {ROC_NPC_ITEM_TYPE_IPV4, - sizeof(struct rte_flow_item_ipv4)}, - [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)}, - [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, - sizeof(struct rte_flow_item_icmp)}, - [RTE_FLOW_ITEM_TYPE_UDP] = {ROC_NPC_ITEM_TYPE_UDP, - sizeof(struct rte_flow_item_udp)}, - [RTE_FLOW_ITEM_TYPE_TCP] = {ROC_NPC_ITEM_TYPE_TCP, - sizeof(struct rte_flow_item_tcp)}, - [RTE_FLOW_ITEM_TYPE_SCTP] = {ROC_NPC_ITEM_TYPE_SCTP, - sizeof(struct rte_flow_item_sctp)}, - [RTE_FLOW_ITEM_TYPE_ESP] = {ROC_NPC_ITEM_TYPE_ESP, - sizeof(struct rte_flow_item_esp)}, - [RTE_FLOW_ITEM_TYPE_GRE] = {ROC_NPC_ITEM_TYPE_GRE, - sizeof(struct rte_flow_item_gre)}, - [RTE_FLOW_ITEM_TYPE_NVGRE] = {ROC_NPC_ITEM_TYPE_NVGRE, - sizeof(struct rte_flow_item_nvgre)}, - [RTE_FLOW_ITEM_TYPE_VXLAN] = {ROC_NPC_ITEM_TYPE_VXLAN, - sizeof(struct rte_flow_item_vxlan)}, - [RTE_FLOW_ITEM_TYPE_GTPC] = {ROC_NPC_ITEM_TYPE_GTPC, - sizeof(struct rte_flow_item_gtp)}, - [RTE_FLOW_ITEM_TYPE_GTPU] = {ROC_NPC_ITEM_TYPE_GTPU, - sizeof(struct rte_flow_item_gtp)}, - [RTE_FLOW_ITEM_TYPE_GENEVE] = {ROC_NPC_ITEM_TYPE_GENEVE, - sizeof(struct rte_flow_item_geneve)}, - [RTE_FLOW_ITEM_TYPE_VXLAN_GPE] = { - ROC_NPC_ITEM_TYPE_VXLAN_GPE, - sizeof(struct rte_flow_item_vxlan_gpe)}, - [RTE_FLOW_ITEM_TYPE_IPV6_EXT] = {ROC_NPC_ITEM_TYPE_IPV6_EXT, - sizeof(struct rte_flow_item_ipv6_ext)}, - [RTE_FLOW_ITEM_TYPE_VOID] = {ROC_NPC_ITEM_TYPE_VOID, 0}, - [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_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 != RTE_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, const struct rte_flow_attr *attr, - const struct rte_flow_action 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_port_id *port_act; - const struct rte_flow_action_queue *act_q; - struct roc_npc *roc_npc_src = &dev->npc; - 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 i = 0, rc = 0; - int rq; - - for (; actions->type != RTE_FLOW_ACTION_TYPE_END; actions++) { - switch (actions->type) { - case RTE_FLOW_ACTION_TYPE_VOID: - in_actions[i].type = ROC_NPC_ACTION_TYPE_VOID; - break; - - case RTE_FLOW_ACTION_TYPE_MARK: - in_actions[i].type = ROC_NPC_ACTION_TYPE_MARK; - in_actions[i].conf = actions->conf; - break; - - case RTE_FLOW_ACTION_TYPE_FLAG: - in_actions[i].type = ROC_NPC_ACTION_TYPE_FLAG; - break; - - case RTE_FLOW_ACTION_TYPE_COUNT: - in_actions[i].type = ROC_NPC_ACTION_TYPE_COUNT; - break; - - case RTE_FLOW_ACTION_TYPE_DROP: - in_actions[i].type = ROC_NPC_ACTION_TYPE_DROP; - break; - - case RTE_FLOW_ACTION_TYPE_PF: - in_actions[i].type = ROC_NPC_ACTION_TYPE_PF; - break; - - case RTE_FLOW_ACTION_TYPE_VF: - in_actions[i].type = ROC_NPC_ACTION_TYPE_VF; - in_actions[i].conf = actions->conf; - break; - - case RTE_FLOW_ACTION_TYPE_PORT_ID: - in_actions[i].type = ROC_NPC_ACTION_TYPE_PORT_ID; - in_actions[i].conf = actions->conf; - port_act = (const struct rte_flow_action_port_id *) - actions->conf; - if (rte_eth_dev_get_name_by_port(port_act->id, - if_name)) { - 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; - - rc = roc_npc_validate_portid_action(roc_npc_src, - roc_npc_dst); - - if (rc) - goto err_exit; - break; - - case RTE_FLOW_ACTION_TYPE_QUEUE: - act_q = (const struct rte_flow_action_queue *) - actions->conf; - rq = act_q->index; - if (rq >= eth_dev->data->nb_rx_queues) { - plt_npc_dbg("Invalid queue index"); - goto err_exit; - } - in_actions[i].type = ROC_NPC_ACTION_TYPE_QUEUE; - in_actions[i].conf = actions->conf; - 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; - case RTE_FLOW_ACTION_TYPE_METER: - in_actions[i].type = ROC_NPC_ACTION_TYPE_METER; - in_actions[i].conf = actions->conf; - break; - default: - plt_npc_dbg("Action is not supported = %d", - actions->type); - goto err_exit; - } - i++; - } - in_actions[i].type = ROC_NPC_ACTION_TYPE_END; - return 0; - -err_exit: - return -EINVAL; -} - -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) -{ - int i = 0; - - in_attr->priority = attr->priority; - in_attr->ingress = attr->ingress; - in_attr->egress = attr->egress; - - 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; - pattern++; - i++; - } - in_pattern[i].type = ROC_NPC_ITEM_TYPE_END; - - return cnxk_map_actions(eth_dev, attr, actions, in_actions, - flowkey_cfg); -} - -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) -{ - 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 *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, &flowkey_cfg); - if (rc) { - rte_flow_error_set(error, 0, RTE_FLOW_ERROR_TYPE_ACTION_NUM, - NULL, "Failed to map flow data"); - return rc; - } - - return roc_npc_flow_parse(npc, &in_attr, in_pattern, in_actions, &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) -{ - 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 *npc = &dev->npc; - struct roc_npc_attr in_attr; - struct roc_npc_flow *flow; - int errcode = 0; - int rc; - - rc = cnxk_map_flow_data(eth_dev, attr, pattern, actions, &in_attr, - 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 NULL; - } - - flow = roc_npc_flow_create(npc, &in_attr, in_pattern, in_actions, - &errcode); - if (errcode != 0) { - rte_flow_error_set(error, errcode, errcode, NULL, - roc_error_msg_get(errcode)); - return NULL; - } - - return flow; -} - -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; - int rc; - - rc = roc_npc_flow_destroy(npc, flow); - if (rc) - 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) -{ - struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev); - struct roc_npc *npc = &dev->npc; - int rc; - - 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"); - return -rte_errno; - } - - return 0; -} - -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) -{ - 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; - const char *errmsg = NULL; - int errcode = ENOTSUP; - int rc; - - if (action->type != RTE_FLOW_ACTION_TYPE_COUNT) { - errmsg = "Only COUNT is supported in query"; - goto err_exit; - } - - if (in_flow->ctr_id == NPC_COUNTER_NONE) { - errmsg = "Counter is not available"; - goto err_exit; - } - - rc = roc_npc_mcam_read_counter(npc, in_flow->ctr_id, &query->hits); - if (rc != 0) { - errcode = EIO; - errmsg = "Error reading flow counter"; - goto err_exit; - } - query->hits_set = 1; - query->bytes_set = 0; - - if (query->reset) - rc = roc_npc_mcam_clear_counter(npc, in_flow->ctr_id); - if (rc != 0) { - errcode = EIO; - errmsg = "Error clearing flow counter"; - goto err_exit; - } - - return 0; - -err_exit: - rte_flow_error_set(error, errcode, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, - NULL, errmsg); - return -rte_errno; -} - -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. - */ - - rte_flow_error_set(error, ENOTSUP, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, - NULL, "Flow isolation not supported"); - - 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, -}; diff --git a/drivers/net/cnxk/cnxk_rte_flow.h b/drivers/net/cnxk/cnxk_rte_flow.h deleted file mode 100644 index bb23629819..0000000000 --- a/drivers/net/cnxk/cnxk_rte_flow.h +++ /dev/null @@ -1,27 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause - * Copyright(C) 2021 Marvell. - */ -#ifndef __CNXK_RTE_FLOW_H__ -#define __CNXK_RTE_FLOW_H__ - -#include -#include - -#include "cnxk_ethdev.h" -#include "roc_api.h" -#include "roc_npc_priv.h" - -struct cnxk_rte_flow_term_info { - uint16_t item_type; - uint16_t item_size; -}; - -struct roc_npc_flow *cnxk_flow_create(struct rte_eth_dev *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_destroy(struct rte_eth_dev *dev, struct roc_npc_flow *flow, - struct rte_flow_error *error); - -#endif /* __CNXK_RTE_FLOW_H__ */ diff --git a/drivers/net/cnxk/meson.build b/drivers/net/cnxk/meson.build index 83af1f4d0c..016a79b2a8 100644 --- a/drivers/net/cnxk/meson.build +++ b/drivers/net/cnxk/meson.build @@ -19,7 +19,7 @@ sources = files( 'cnxk_link.c', 'cnxk_lookup.c', 'cnxk_ptp.c', - 'cnxk_rte_flow.c', + 'cnxk_flow.c', 'cnxk_stats.c', 'cnxk_tm.c', ) @@ -28,7 +28,7 @@ sources = files( sources += files( 'cn9k_ethdev.c', 'cn9k_ethdev_sec.c', - 'cn9k_rte_flow.c', + 'cn9k_flow.c', 'cn9k_rx_select.c', 'cn9k_tx_select.c', ) @@ -107,7 +107,7 @@ sources += files( sources += files( 'cn10k_ethdev.c', 'cn10k_ethdev_sec.c', - 'cn10k_rte_flow.c', + 'cn10k_flow.c', 'cn10k_rx_select.c', 'cn10k_tx_select.c', )