* [dpdk-dev] [PATCH 2/2] net/cnxk: support rte flow on cn20k
2024-10-21 4:01 [dpdk-dev] [PATCH 1/2] common/cnxk: support NPC flow on cn20k psatheesh
@ 2024-10-21 4:01 ` psatheesh
2024-10-21 17:09 ` Stephen Hemminger
2024-10-29 7:31 ` [dpdk-dev] [PATCH v2 1/2] common/cnxk: support NPC " psatheesh
2024-11-12 9:58 ` [dpdk-dev] [PATCH v3 1/2] common/cnxk: support NPC " psatheesh
2 siblings, 1 reply; 8+ messages in thread
From: psatheesh @ 2024-10-21 4:01 UTC (permalink / raw)
To: Nithin Dabilpuram, Kiran Kumar K, Sunil Kumar Kori, Satha Rao,
Harman Kalra
Cc: dev, Satheesh Paul
From: Satheesh Paul <psatheesh@marvell.com>
Support for rte flow in cn20k.
Signed-off-by: Satheesh Paul <psatheesh@marvell.com>
Reviewed-by: Kiran Kumar K <kirankumark@marvell.com>
---
drivers/net/cnxk/cn10k_ethdev.c | 8 +-
drivers/net/cnxk/cn10k_flow.h | 21 --
drivers/net/cnxk/cn20k_ethdev.c | 4 +
drivers/net/cnxk/cnxk_ethdev_devargs.c | 10 +-
drivers/net/cnxk/cnxk_flow.c | 10 +-
drivers/net/cnxk/cnxk_flow_wrapper.c | 303 +++++++++++++++++++++++++
drivers/net/cnxk/cnxk_flow_wrapper.h | 21 ++
drivers/net/cnxk/meson.build | 10 +-
8 files changed, 355 insertions(+), 32 deletions(-)
delete mode 100644 drivers/net/cnxk/cn10k_flow.h
create mode 100644 drivers/net/cnxk/cnxk_flow_wrapper.c
create mode 100644 drivers/net/cnxk/cnxk_flow_wrapper.h
diff --git a/drivers/net/cnxk/cn10k_ethdev.c b/drivers/net/cnxk/cn10k_ethdev.c
index fbb9b09062..a4b3d56c61 100644
--- a/drivers/net/cnxk/cn10k_ethdev.c
+++ b/drivers/net/cnxk/cn10k_ethdev.c
@@ -2,9 +2,9 @@
* Copyright(C) 2021 Marvell.
*/
#include "cn10k_ethdev.h"
-#include "cn10k_flow.h"
#include "cn10k_rx.h"
#include "cn10k_tx.h"
+#include "cnxk_flow_wrapper.h"
static uint16_t
nix_rx_offload_flags(struct rte_eth_dev *eth_dev)
@@ -913,9 +913,9 @@ npc_flow_ops_override(void)
init_once = 1;
/* Update platform specific ops */
- cnxk_flow_ops.create = cn10k_flow_create;
- cnxk_flow_ops.destroy = cn10k_flow_destroy;
- cnxk_flow_ops.info_get = cn10k_flow_info_get;
+ cnxk_flow_ops.create = cnxk_flow_create_wrapper;
+ cnxk_flow_ops.destroy = cnxk_flow_destroy_wrapper;
+ cnxk_flow_ops.info_get = cnxk_flow_info_get_wrapper;
}
static int
diff --git a/drivers/net/cnxk/cn10k_flow.h b/drivers/net/cnxk/cn10k_flow.h
deleted file mode 100644
index 316b74e6a6..0000000000
--- a/drivers/net/cnxk/cn10k_flow.h
+++ /dev/null
@@ -1,21 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(C) 2020 Marvell.
- */
-#ifndef __CN10K_RTE_FLOW_H__
-#define __CN10K_RTE_FLOW_H__
-
-#include <rte_flow_driver.h>
-
-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);
-
-int cn10k_flow_info_get(struct rte_eth_dev *dev, struct rte_flow_port_info *port_info,
- struct rte_flow_queue_info *queue_info, struct rte_flow_error *err);
-
-#define CN10K_NPC_COUNTERS_MAX 512
-
-#endif /* __CN10K_RTE_FLOW_H__ */
diff --git a/drivers/net/cnxk/cn20k_ethdev.c b/drivers/net/cnxk/cn20k_ethdev.c
index 37c372d80f..e74dd88172 100644
--- a/drivers/net/cnxk/cn20k_ethdev.c
+++ b/drivers/net/cnxk/cn20k_ethdev.c
@@ -4,6 +4,7 @@
#include "cn20k_ethdev.h"
#include "cn20k_rx.h"
#include "cn20k_tx.h"
+#include "cnxk_flow_wrapper.h"
static uint16_t
nix_rx_offload_flags(struct rte_eth_dev *eth_dev)
@@ -867,6 +868,9 @@ npc_flow_ops_override(void)
init_once = 1;
/* Update platform specific ops */
+ cnxk_flow_ops.create = cnxk_flow_create_wrapper;
+ cnxk_flow_ops.destroy = cnxk_flow_destroy_wrapper;
+ cnxk_flow_ops.info_get = cnxk_flow_info_get_wrapper;
}
static int
diff --git a/drivers/net/cnxk/cnxk_ethdev_devargs.c b/drivers/net/cnxk/cnxk_ethdev_devargs.c
index 5bd50bb9a1..bdf5d88b92 100644
--- a/drivers/net/cnxk/cnxk_ethdev_devargs.c
+++ b/drivers/net/cnxk/cnxk_ethdev_devargs.c
@@ -88,8 +88,7 @@ parse_flow_max_priority(const char *key, const char *value, void *extra_args)
val = atoi(value);
- /* Limit the max priority to 32 */
- if (val < 1 || val > 32)
+ if (val < 1 || val > ROC_NPC_MAX_MCAM_PRIORITY)
return -EINVAL;
*(uint16_t *)extra_args = val;
@@ -390,7 +389,12 @@ cnxk_ethdev_parse_devargs(struct rte_devargs *devargs, struct cnxk_eth_dev *dev)
dev->nix.meta_buf_sz = meta_buf_sz;
dev->npc.flow_prealloc_size = flow_prealloc_size;
- dev->npc.flow_max_priority = flow_max_priority;
+
+ if (roc_model_is_cn20k())
+ dev->npc.flow_max_priority = ROC_NPC_MAX_MCAM_PRIORITY;
+ else
+ dev->npc.flow_max_priority = flow_max_priority;
+
dev->npc.switch_header_type = switch_header_type;
dev->npc.sdp_channel = sdp_chan.channel;
dev->npc.sdp_channel_mask = sdp_chan.mask;
diff --git a/drivers/net/cnxk/cnxk_flow.c b/drivers/net/cnxk/cnxk_flow.c
index d3c20e8315..887dd8f911 100644
--- a/drivers/net/cnxk/cnxk_flow.c
+++ b/drivers/net/cnxk/cnxk_flow.c
@@ -990,10 +990,14 @@ cnxk_flow_query_common(struct rte_eth_dev *eth_dev, struct rte_flow *flow,
npc = &rep_dev->parent_dev->npc;
}
- if (in_flow->use_pre_alloc)
+ if (in_flow->use_pre_alloc) {
rc = roc_npc_inl_mcam_read_counter(in_flow->ctr_id, &query->hits);
- else
- rc = roc_npc_mcam_read_counter(npc, in_flow->ctr_id, &query->hits);
+ } else {
+ if (roc_model_is_cn20k())
+ rc = roc_npc_mcam_get_stats(npc, in_flow, &query->hits);
+ else
+ rc = roc_npc_mcam_read_counter(npc, in_flow->ctr_id, &query->hits);
+ }
if (rc != 0) {
errcode = EIO;
errmsg = "Error reading flow counter";
diff --git a/drivers/net/cnxk/cnxk_flow_wrapper.c b/drivers/net/cnxk/cnxk_flow_wrapper.c
new file mode 100644
index 0000000000..af2eee7266
--- /dev/null
+++ b/drivers/net/cnxk/cnxk_flow_wrapper.c
@@ -0,0 +1,303 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(C) 2024 Marvell.
+ */
+
+#ifdef CNXK_PLATFORM_CN10K
+#include "cn10k_ethdev.h"
+#include "cn10k_rx.h"
+#endif
+#ifdef CNXK_PLATFORM_CN20K
+#include "cn20k_ethdev.h"
+#include "cn20k_rx.h"
+#endif
+#include "cnxk_ethdev_mcs.h"
+#include "cnxk_flow_wrapper.h"
+#include <cnxk_flow.h>
+
+static void
+cnxk_eth_set_rx_function(struct rte_eth_dev *eth_dev)
+{
+ RTE_SET_USED(eth_dev);
+#ifdef CNXK_PLATFORM_CN10K
+ cn10k_eth_set_rx_function(eth_dev);
+#endif
+#ifdef CNXK_PLATFORM_CN20K
+ cn20k_eth_set_rx_function(eth_dev);
+#endif
+}
+
+static int
+cnxk_mtr_connect(struct rte_eth_dev *eth_dev, uint32_t mtr_id)
+{
+ return nix_mtr_connect(eth_dev, mtr_id);
+}
+
+static int
+cnxk_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
+cnxk_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
+cnxk_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 *
+cnxk_flow_create_wrapper(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;
+ struct roc_npc *npc = &dev->npc;
+ struct roc_npc_flow *flow;
+ void *mcs_flow = NULL;
+ int vtag_actions = 0;
+ uint32_t req_act = 0;
+ int mark_actions;
+ 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 = cnxk_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 = cnxk_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;
+ }
+ }
+
+ if (actions[0].type == RTE_FLOW_ACTION_TYPE_SECURITY &&
+ cnxk_eth_macsec_sess_get_by_sess(dev, actions[0].conf) != NULL) {
+ rc = cnxk_mcs_flow_configure(eth_dev, attr, pattern, actions, error, &mcs_flow);
+ if (rc) {
+ rte_flow_error_set(error, rc, RTE_FLOW_ERROR_TYPE_ACTION, NULL,
+ "Failed to configure mcs flow");
+ return NULL;
+ }
+ return (struct rte_flow *)mcs_flow;
+ }
+
+ 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)
+ cnxk_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;
+ cnxk_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;
+ cnxk_eth_set_rx_function(eth_dev);
+ }
+
+ return (struct rte_flow *)flow;
+}
+
+int
+cnxk_flow_info_get_wrapper(struct rte_eth_dev *dev, struct rte_flow_port_info *port_info,
+ struct rte_flow_queue_info *queue_info, struct rte_flow_error *err)
+{
+ RTE_SET_USED(dev);
+ RTE_SET_USED(err);
+
+ memset(port_info, 0, sizeof(*port_info));
+ memset(queue_info, 0, sizeof(*queue_info));
+
+ port_info->max_nb_counters = CNXK_NPC_COUNTERS_MAX;
+ port_info->max_nb_meters = CNXK_NIX_MTR_COUNT_MAX;
+
+ return 0;
+}
+
+int
+cnxk_flow_destroy_wrapper(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);
+ struct roc_npc *npc = &dev->npc;
+ int vtag_actions = 0;
+ int mark_actions;
+ uint16_t match_id;
+ uint32_t mtr_id;
+ int rc;
+
+ match_id = (flow->npc_action >> NPC_RX_ACT_MATCH_OFFSET) & NPC_RX_ACT_MATCH_MASK;
+ if (match_id) {
+ mark_actions = roc_npc_mark_actions_sub_return(npc, 1);
+ if (mark_actions == 0) {
+ dev->rx_offload_flags &= ~NIX_RX_OFFLOAD_MARK_UPDATE_F;
+ cnxk_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;
+ cnxk_eth_set_rx_function(eth_dev);
+ }
+ }
+ }
+
+ if (cnxk_eth_macsec_sess_get_by_sess(dev, (void *)flow) != NULL) {
+ rc = cnxk_mcs_flow_destroy(dev, (void *)flow);
+ if (rc < 0)
+ rte_flow_error_set(error, rc, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
+ "Failed to free mcs flow");
+ return rc;
+ }
+
+ mtr_id = flow->mtr_id;
+ rc = cnxk_flow_destroy(eth_dev, flow, error);
+ if (!rc && mtr_id != ROC_NIX_MTR_ID_INVALID) {
+ rc = cnxk_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/cnxk_flow_wrapper.h b/drivers/net/cnxk/cnxk_flow_wrapper.h
new file mode 100644
index 0000000000..506293dd51
--- /dev/null
+++ b/drivers/net/cnxk/cnxk_flow_wrapper.h
@@ -0,0 +1,21 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(C) 2020 Marvell.
+ */
+#ifndef __CNXK_FLOW_WRAPPER_H__
+#define __CNXK_FLOW_WRAPPER_H__
+
+#include <rte_flow_driver.h>
+
+struct rte_flow *cnxk_flow_create_wrapper(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_wrapper(struct rte_eth_dev *dev, struct rte_flow *flow,
+ struct rte_flow_error *error);
+
+int cnxk_flow_info_get_wrapper(struct rte_eth_dev *dev, struct rte_flow_port_info *port_info,
+ struct rte_flow_queue_info *queue_info, struct rte_flow_error *err);
+
+#define CNXK_NPC_COUNTERS_MAX 512
+
+#endif /* __CNXK_FLOW_WRAPPER_H__ */
diff --git a/drivers/net/cnxk/meson.build b/drivers/net/cnxk/meson.build
index fcf48f600a..5b9e06e535 100644
--- a/drivers/net/cnxk/meson.build
+++ b/drivers/net/cnxk/meson.build
@@ -18,6 +18,13 @@ if soc_type != 'cn9k' and soc_type != 'cn10k' and soc_type != 'cn20k'
soc_type = 'all'
endif
+if soc_type == 'cn10k' or soc_type == 'all'
+ dpdk_conf.set('CNXK_PLATFORM_CN10K', 1)
+elif soc_type == 'cn20k'
+ dpdk_conf.set('CNXK_PLATFORM_CN20K', 1)
+endif
+
+
sources = files(
'cnxk_ethdev.c',
'cnxk_ethdev_cman.c',
@@ -146,9 +153,9 @@ if soc_type == 'cn10k' or soc_type == 'all'
sources += files(
'cn10k_ethdev.c',
'cn10k_ethdev_sec.c',
- 'cn10k_flow.c',
'cn10k_rx_select.c',
'cn10k_tx_select.c',
+ 'cnxk_flow_wrapper.c',
)
if host_machine.cpu_family().startswith('aarch') and not disable_template
@@ -238,6 +245,7 @@ sources += files(
'cn20k_ethdev.c',
'cn20k_rx_select.c',
'cn20k_tx_select.c',
+ 'cnxk_flow_wrapper.c',
)
if host_machine.cpu_family().startswith('aarch') and not disable_template
--
2.39.2
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [dpdk-dev] [PATCH 2/2] net/cnxk: support rte flow on cn20k
2024-10-21 4:01 ` [dpdk-dev] [PATCH 2/2] net/cnxk: support rte " psatheesh
@ 2024-10-21 17:09 ` Stephen Hemminger
0 siblings, 0 replies; 8+ messages in thread
From: Stephen Hemminger @ 2024-10-21 17:09 UTC (permalink / raw)
To: psatheesh
Cc: Nithin Dabilpuram, Kiran Kumar K, Sunil Kumar Kori, Satha Rao,
Harman Kalra, dev
On Mon, 21 Oct 2024 09:31:44 +0530
<psatheesh@marvell.com> wrote:
> From: Satheesh Paul <psatheesh@marvell.com>
>
> Support for rte flow in cn20k.
>
> Signed-off-by: Satheesh Paul <psatheesh@marvell.com>
> Reviewed-by: Kiran Kumar K <kirankumark@marvell.com>
> ---
> drivers/net/cnxk/cn10k_ethdev.c | 8 +-
> drivers/net/cnxk/cn10k_flow.h | 21 --
> drivers/net/cnxk/cn20k_ethdev.c | 4 +
> drivers/net/cnxk/cnxk_ethdev_devargs.c | 10 +-
> drivers/net/cnxk/cnxk_flow.c | 10 +-
> drivers/net/cnxk/cnxk_flow_wrapper.c | 303 +++++++++++++++++++++++++
> drivers/net/cnxk/cnxk_flow_wrapper.h | 21 ++
> drivers/net/cnxk/meson.build | 10 +-
> 8 files changed, 355 insertions(+), 32 deletions(-)
> delete mode 100644 drivers/net/cnxk/cn10k_flow.h
> create mode 100644 drivers/net/cnxk/cnxk_flow_wrapper.c
> create mode 100644 drivers/net/cnxk/cnxk_flow_wrapper.h
Compiler erorrs.
*Build Failed #2:
OS: RHEL94-64
Target: x86_64-native-linuxapp-gcc
FAILED: drivers/libtmp_rte_common_cnxk.a.p/common_cnxk_roc_npc_mcam.c.o
gcc -Idrivers/libtmp_rte_common_cnxk.a.p -Idrivers -I../drivers -Idrivers/common/cnxk -I../drivers/common/cnxk -Idrivers/bus/pci -I../drivers/bus/pci -Ilib/net -I../lib/net -Ilib/ethdev -I../lib/ethdev -Ilib/meter -I../lib/meter -I. -I.. -Iconfig -I../config -Ilib/eal/include -I../lib/eal/include -Ilib/eal/linux/include -I../lib/eal/linux/include -Ilib/eal/x86/include -I../lib/eal/x86/include -Ilib/eal/common -I../lib/eal/common -Ilib/eal -I../lib/eal -Ilib/kvargs -I../lib/kvargs -Ilib/log -I../lib/log -Ilib/metrics -I../lib/metrics -Ilib/telemetry -I../lib/telemetry -Ilib/pci -I../lib/pci -I../drivers/bus/pci/linux -Ilib/mbuf -I../lib/mbuf -Ilib/mempool -I../lib/mempool -Ilib/ring -I../lib/ring -Ilib/security -I../lib/security -Ilib/cryptodev -I../lib/cryptodev -Ilib/rcu -I../lib/rcu -fdiagnostics-color=always -D_FILE_OFFSET_BITS=64 -Wall -Winvalid-pch -Wextra -Werror -std=c11 -O3 -include rte_config.h -Wcast-qual -Wdeprecated -Wformat -Wformat-nonliteral -Wformat-security -Wmissing-declarations -Wmissing-prototypes -Wnested-externs -Wold-style-definition -Wpointer-arith -Wsign-compare -Wstrict-prototypes -Wundef -Wwrite-strings -Wno-address-of-packed-member -Wno-packed-not-aligned -Wno-missing-field-initializers -Wno-zero-length-bounds -D_GNU_SOURCE -fPIC -march=native -mrtm -DALLOW_EXPERIMENTAL_API -DALLOW_INTERNAL_API -Wno-format-truncation -DRTE_LOG_DEFAULT_LOGTYPE=pmd.common.cnxk -MD -MQ drivers/libtmp_rte_common_cnxk.a.p/common_cnxk_roc_npc_mcam.c.o -MF drivers/libtmp_rte_common_cnxk.a.p/common_cnxk_roc_npc_mcam.c.o.d -o drivers/libtmp_rte_common_cnxk.a.p/common_cnxk_roc_npc_mcam.c.o -c ../drivers/common/cnxk/roc_npc_mcam.c
../drivers/common/cnxk/roc_npc_mcam.c: In function ‘npc_mcam_write_entry’:
../drivers/common/cnxk/roc_npc_mcam.c:520:70: error: iteration 7 invokes undefined behavior [-Werror=aggressive-loop-optimizations]
520 | cn20k_req->entry_data.kw[i] = mcam->mcam_data[i];
| ~~~~~~~~~~~~~~~^~~
../drivers/common/cnxk/roc_npc_mcam.c:519:31: note: within this loop
519 | for (i = 0; i < NPC_CN20K_MCAM_KEY_X4_WORDS; i++) {
cc1: all warnings being treated as errors
[794/3044] Compiling C object drivers/libtmp_rte_common_cnxk.a.p/common_cnxk_roc_tim.c.o
[795/3044] Compiling C object drivers/libtmp_rte_common_cnxk.a.p/common_cnxk_roc_utils.c.o
[796/3044] Compiling C object drivers/libtmp_rte_common_cnxk.a.p/common_cnxk_roc_tim_irq.c.o
[797/3044] Compiling C object drivers/libtmp_rte_common_cnxk.a.p/common_cnxk_cnxk_telemetry_bphy.c.o
[798/3044] Compiling C object drivers/libtmp_rte_common_cnxk.a.p/common_cnxk_cnxk_telemetry_npa.c.o
[799/3044] Compiling C object drivers/libtmp_rte_common_cnxk.a.p/common_cnxk_roc_ree.c.o
[800/3044] Compiling C object drivers/libtmp_rte_common_cnxk.a.p/common_cnxk_cnxk_utils.c.o
[801/3044] Compiling C object drivers/libtmp_rte_common_cnxk.a.p/common_cnxk_cnxk_security.c.o
[802/3044] Compiling C object drivers/libtmp_rte_common_cnxk.a.p/common_cnxk_cnxk_telemetry_nix.c.o
ninja: build stopped
^ permalink raw reply [flat|nested] 8+ messages in thread
* [dpdk-dev] [PATCH v2 1/2] common/cnxk: support NPC flow on cn20k
2024-10-21 4:01 [dpdk-dev] [PATCH 1/2] common/cnxk: support NPC flow on cn20k psatheesh
2024-10-21 4:01 ` [dpdk-dev] [PATCH 2/2] net/cnxk: support rte " psatheesh
@ 2024-10-29 7:31 ` psatheesh
2024-10-29 7:31 ` [dpdk-dev] [PATCH v2 2/2] net/cnxk: support rte " psatheesh
2024-11-12 9:58 ` [dpdk-dev] [PATCH v3 1/2] common/cnxk: support NPC " psatheesh
2 siblings, 1 reply; 8+ messages in thread
From: psatheesh @ 2024-10-29 7:31 UTC (permalink / raw)
To: Nithin Dabilpuram, Kiran Kumar K, Sunil Kumar Kori, Satha Rao,
Harman Kalra
Cc: dev, Satheesh Paul
From: Satheesh Paul <psatheesh@marvell.com>
ROC changes to support NPC flow on cn20k.
Signed-off-by: Satheesh Paul <psatheesh@marvell.com>
Reviewed-by: Kiran Kumar K <kirankumark@marvell.com>
---
v2:
* Fixed generic platform compiler error.
drivers/common/cnxk/roc_mbox.h | 144 +++++-
drivers/common/cnxk/roc_nix.h | 18 +-
drivers/common/cnxk/roc_nix_mcast.c | 40 +-
drivers/common/cnxk/roc_nix_vlan.c | 66 ++-
drivers/common/cnxk/roc_npc.c | 58 ++-
drivers/common/cnxk/roc_npc.h | 59 ++-
drivers/common/cnxk/roc_npc_mcam.c | 602 +++++++++++++++++++-----
drivers/common/cnxk/roc_npc_mcam_dump.c | 279 +++++++++--
drivers/common/cnxk/roc_npc_priv.h | 91 ++--
drivers/common/cnxk/roc_npc_utils.c | 340 ++++++++++---
drivers/common/cnxk/version.map | 1 +
11 files changed, 1325 insertions(+), 373 deletions(-)
diff --git a/drivers/common/cnxk/roc_mbox.h b/drivers/common/cnxk/roc_mbox.h
index 0864c0e8c0..cc96ca76a1 100644
--- a/drivers/common/cnxk/roc_mbox.h
+++ b/drivers/common/cnxk/roc_mbox.h
@@ -234,6 +234,22 @@ struct mbox_msghdr {
npc_get_field_hash_info_req, npc_get_field_hash_info_rsp) \
M(NPC_MCAM_GET_HIT_STATUS, 0x6015, npc_mcam_get_hit_status, \
npc_mcam_get_hit_status_req, npc_mcam_get_hit_status_rsp) \
+ M(NPC_MCAM_DEFRAG, 0x6016, npc_defrag, msg_req, msg_rsp) \
+ M(NPC_CN20K_GET_KEX_CFG, 0x6017, npc_cn20k_get_kex_cfg, msg_req, \
+ npc_cn20k_get_kex_cfg_rsp) \
+ M(NPC_CN20K_MCAM_GET_FREE_COUNT, 0x6018, npc_cn20k_get_free_count, \
+ msg_req, npc_cn20k_get_free_count_rsp) \
+ M(NPC_CN20K_MCAM_WRITE_ENTRY, 0x6019, npc_cn20k_mcam_write_entry, \
+ npc_cn20k_mcam_write_entry_req, msg_rsp) \
+ M(NPC_CN20K_MCAM_ALLOC_AND_WRITE_ENTRY, 0x601a, \
+ npc_cn20k_mcam_alloc_and_write_entry, \
+ npc_cn20k_mcam_alloc_and_write_entry_req, \
+ npc_mcam_alloc_and_write_entry_rsp) \
+ M(NPC_CN20K_MCAM_READ_ENTRY, 0x601b, npc_cn20k_mcam_read_entry, \
+ npc_mcam_read_entry_req, npc_cn20k_mcam_read_entry_rsp) \
+ M(NPC_CN20K_MCAM_READ_BASE_RULE, 0x601c, \
+ npc_cn20k_read_base_steer_rule, msg_req, \
+ npc_cn20k_mcam_read_base_rule_rsp) \
/* NIX mbox IDs (range 0x8000 - 0xFFFF) */ \
M(NIX_LF_ALLOC, 0x8000, nix_lf_alloc, nix_lf_alloc_req, \
nix_lf_alloc_rsp) \
@@ -635,7 +651,7 @@ struct cgx_mac_addr_add_req {
*/
struct cgx_mac_addr_add_rsp {
struct mbox_msghdr hdr;
- uint8_t __io index;
+ uint32_t __io index;
};
/* Structure for requesting the operation to
@@ -643,7 +659,7 @@ struct cgx_mac_addr_add_rsp {
*/
struct cgx_mac_addr_del_req {
struct mbox_msghdr hdr;
- uint8_t __io index;
+ uint32_t __io index;
};
/* Structure for response against the operation to
@@ -651,7 +667,7 @@ struct cgx_mac_addr_del_req {
*/
struct cgx_max_dmac_entries_get_rsp {
struct mbox_msghdr hdr;
- uint8_t __io max_dmac_filters;
+ uint32_t __io max_dmac_filters;
};
struct cgx_link_user_info {
@@ -2431,6 +2447,14 @@ enum npc_af_status {
NPC_MCAM_ALLOC_FAILED = -703,
NPC_MCAM_PERM_DENIED = -704,
NPC_AF_ERR_HIGIG_CONFIG_FAIL = -705,
+ NPC_AF_ERR_HIGIG_NOT_SUPPORTED = -706,
+ NPC_FLOW_INTF_INVALID = -707,
+ NPC_FLOW_CHAN_INVALID = -708,
+ NPC_FLOW_NO_NIXLF = -709,
+ NPC_FLOW_NOT_SUPPORTED = -710,
+ NPC_FLOW_VF_PERM_DENIED = -711,
+ NPC_FLOW_VF_NOT_INIT = -712,
+ NPC_FLOW_VF_OVERLAP = -713,
};
struct npc_mcam_alloc_entry_req {
@@ -2440,9 +2464,12 @@ struct npc_mcam_alloc_entry_req {
#define NPC_MCAM_ANY_PRIO 0
#define NPC_MCAM_LOWER_PRIO 1
#define NPC_MCAM_HIGHER_PRIO 2
- uint8_t __io priority; /* Lower or higher w.r.t ref_entry */
+ uint8_t __io ref_priority; /* Lower or higher w.r.t ref_entry */
uint16_t __io ref_entry;
uint16_t __io count; /* Number of entries requested */
+ uint8_t __io kw_type; /* Key type */
+ uint8_t __io virt; /* Request virtual index */
+ uint16_t __io rsvd[16]; /* Reserved */
};
struct npc_mcam_alloc_entry_rsp {
@@ -2454,6 +2481,7 @@ struct npc_mcam_alloc_entry_rsp {
uint16_t __io count; /* Number of entries allocated */
uint16_t __io free_count; /* Number of entries available */
uint16_t __io entry_list[NPC_MAX_NONCONTIG_ENTRIES];
+ uint16_t __io rsvd[16]; /* Reserved */
};
struct npc_mcam_free_entry_req {
@@ -2480,6 +2508,26 @@ struct npc_mcam_write_entry_req {
uint8_t __io set_cntr; /* Set counter for this entry ? */
};
+struct cn20k_mcam_entry {
+#define NPC_CN20K_MAX_KWS_IN_KEY 8 /* Number of keywords in max keywidth */
+ uint64_t __io kw[NPC_CN20K_MAX_KWS_IN_KEY];
+ uint64_t __io kw_mask[NPC_CN20K_MAX_KWS_IN_KEY];
+ uint64_t __io action;
+ uint64_t __io vtag_action;
+};
+
+struct npc_cn20k_mcam_write_entry_req {
+ struct mbox_msghdr hdr;
+ struct cn20k_mcam_entry entry_data;
+ uint16_t __io entry; /* MCAM entry to write this match key */
+ uint16_t __io cntr; /* Counter for this MCAM entry */
+ uint8_t __io intf; /* Rx or Tx interface */
+ uint8_t __io enable_entry; /* Enable this MCAM entry ? */
+ uint8_t __io hw_prio; /* hardware priority, valid for cn20k */
+ uint8_t __io req_kw_type; /* Type of kw which should be written */
+ uint64_t __io reserved; /* reserved for future use */
+};
+
/* Enable/Disable a given entry */
struct npc_mcam_ena_dis_entry_req {
struct mbox_msghdr hdr;
@@ -2539,12 +2587,25 @@ struct npc_mcam_alloc_and_write_entry_req {
struct mbox_msghdr hdr;
struct mcam_entry entry_data;
uint16_t __io ref_entry;
- uint8_t __io priority; /* Lower or higher w.r.t ref_entry */
+ uint8_t __io ref_priority; /* Lower or higher w.r.t ref_entry */
uint8_t __io intf; /* Rx or Tx interface */
uint8_t __io enable_entry; /* Enable this MCAM entry ? */
uint8_t __io alloc_cntr; /* Allocate counter and map ? */
};
+struct npc_cn20k_mcam_alloc_and_write_entry_req {
+ struct mbox_msghdr hdr;
+ struct cn20k_mcam_entry entry_data;
+ uint16_t __io ref_entry;
+ uint8_t __io ref_prio; /* Lower or higher w.r.t ref_entry */
+ uint8_t __io intf; /* Rx or Tx interface */
+ uint8_t __io enable_entry; /* Enable this MCAM entry ? */
+ uint8_t __io hw_prio; /* hardware priority, valid for cn20k */
+ uint8_t __io virt; /* Allocate virtual index */
+ uint8_t __io req_kw_type; /* Key type to be written */
+ uint16_t __io reserved[4]; /* reserved for future use */
+};
+
struct npc_mcam_alloc_and_write_entry_rsp {
struct mbox_msghdr hdr;
uint16_t __io entry;
@@ -2571,6 +2632,48 @@ struct npc_get_kex_cfg_rsp {
uint8_t __io mkex_pfl_name[MKEX_NAME_LEN];
};
+struct npc_delete_flow_rsp {
+ struct mbox_msghdr hdr;
+ uint16_t __io cntr_val;
+};
+
+/* Available entries to use */
+struct npc_cn20k_get_free_count_rsp {
+ struct mbox_msghdr hdr;
+ int __io free_x2;
+ int __io free_x4;
+ int __io free_subbanks;
+};
+
+struct npc_cn20k_get_kex_cfg_rsp {
+ struct mbox_msghdr hdr;
+ uint64_t __io rx_keyx_cfg; /* NPC_AF_INTF(0)_KEX_CFG */
+ uint64_t __io tx_keyx_cfg; /* NPC_AF_INTF(1)_KEX_CFG */
+#define NPC_MAX_EXTRACTOR 24
+ /* MKEX Extractor data */
+ uint64_t __io intf_extr[NPC_MAX_INTF][NPC_MAX_EXTRACTOR];
+ /* KEX configuration per extractor */
+ uint64_t __io intf_extr_lt[NPC_MAX_INTF][NPC_MAX_EXTRACTOR][NPC_MAX_LT];
+#define MKEX_NAME_LEN 128
+ uint8_t __io mkex_pfl_name[MKEX_NAME_LEN];
+};
+
+struct npc_get_field_hash_info_req {
+ struct mbox_msghdr hdr;
+ uint8_t intf;
+};
+
+struct npc_get_field_hash_info_rsp {
+ struct mbox_msghdr hdr;
+ uint64_t __io secret_key[3];
+#define NPC_MAX_HASH 2
+#define NPC_MAX_HASH_MASK 2
+ /* NPC_AF_INTF(0..1)_HASH(0..1)_MASK(0..1) */
+ uint64_t __io hash_mask[NPC_MAX_INTF][NPC_MAX_HASH][NPC_MAX_HASH_MASK];
+ /* NPC_AF_INTF(0..1)_HASH(0..1)_RESULT_CTRL */
+ uint64_t __io hash_ctrl[NPC_MAX_INTF][NPC_MAX_HASH];
+};
+
enum header_fields {
NPC_DMAC,
NPC_SMAC,
@@ -2660,6 +2763,8 @@ struct npc_install_flow_req {
uint8_t __io vtag1_op;
/* old counter value */
uint16_t __io cntr_val;
+ /* hardware priority, supported for cn20k */
+ uint8_t __io hw_prio;
};
struct npc_install_flow_rsp {
@@ -2690,11 +2795,24 @@ struct npc_mcam_read_entry_rsp {
uint8_t __io enable;
};
+struct npc_cn20k_mcam_read_entry_rsp {
+ struct mbox_msghdr hdr;
+ struct cn20k_mcam_entry entry_data;
+ uint8_t __io intf;
+ uint8_t __io enable;
+ uint8_t __io hw_prio; /* valid for cn20k */
+};
+
struct npc_mcam_read_base_rule_rsp {
struct mbox_msghdr hdr;
struct mcam_entry entry_data;
};
+struct npc_cn20k_mcam_read_base_rule_rsp {
+ struct mbox_msghdr hdr;
+ struct cn20k_mcam_entry entry;
+};
+
struct npc_mcam_get_stats_req {
struct mbox_msghdr hdr;
uint16_t __io entry; /* mcam entry */
@@ -2774,22 +2892,6 @@ enum tim_gpio_edge {
TIM_GPIO_INVALID,
};
-struct npc_get_field_hash_info_req {
- struct mbox_msghdr hdr;
- uint8_t intf;
-};
-
-struct npc_get_field_hash_info_rsp {
- struct mbox_msghdr hdr;
- uint64_t __io secret_key[3];
-#define NPC_MAX_HASH 2
-#define NPC_MAX_HASH_MASK 2
- /* NPC_AF_INTF(0..1)_HASH(0..1)_MASK(0..1) */
- uint64_t __io hash_mask[NPC_MAX_INTF][NPC_MAX_HASH][NPC_MAX_HASH_MASK];
- /* NPC_AF_INTF(0..1)_HASH(0..1)_RESULT_CTRL */
- uint64_t __io hash_ctrl[NPC_MAX_INTF][NPC_MAX_HASH];
-};
-
enum ptp_op {
PTP_OP_ADJFINE = 0, /* adjfine(req.scaled_ppm); */
PTP_OP_GET_CLOCK = 1, /* rsp.clk = get_clock() */
diff --git a/drivers/common/cnxk/roc_nix.h b/drivers/common/cnxk/roc_nix.h
index f213823b9b..15823ab16c 100644
--- a/drivers/common/cnxk/roc_nix.h
+++ b/drivers/common/cnxk/roc_nix.h
@@ -983,15 +983,11 @@ bool __roc_api roc_nix_ptp_is_enable(struct roc_nix *roc_nix);
/* VLAN */
int __roc_api
roc_nix_vlan_mcam_entry_read(struct roc_nix *roc_nix, uint32_t index,
- struct npc_mcam_read_entry_rsp **rsp);
-int __roc_api roc_nix_vlan_mcam_entry_write(struct roc_nix *roc_nix,
- uint32_t index,
- struct mcam_entry *entry,
+ void **rsp);
+int __roc_api roc_nix_vlan_mcam_entry_write(struct roc_nix *roc_nix, uint32_t index, void *entry,
uint8_t intf, uint8_t enable);
-int __roc_api roc_nix_vlan_mcam_entry_alloc_and_write(struct roc_nix *roc_nix,
- struct mcam_entry *entry,
- uint8_t intf,
- uint8_t priority,
+int __roc_api roc_nix_vlan_mcam_entry_alloc_and_write(struct roc_nix *roc_nix, void *entry,
+ uint8_t intf, uint8_t priority,
uint8_t ref_entry);
int __roc_api roc_nix_vlan_mcam_entry_free(struct roc_nix *roc_nix,
uint32_t index);
@@ -1012,10 +1008,8 @@ int __roc_api roc_nix_mcast_mcam_entry_alloc(struct roc_nix *roc_nix,
uint16_t index[]);
int __roc_api roc_nix_mcast_mcam_entry_free(struct roc_nix *roc_nix,
uint32_t index);
-int __roc_api roc_nix_mcast_mcam_entry_write(struct roc_nix *roc_nix,
- struct mcam_entry *entry,
- uint32_t index, uint8_t intf,
- uint64_t action);
+int __roc_api roc_nix_mcast_mcam_entry_write(struct roc_nix *roc_nix, void *entry, uint32_t index,
+ uint8_t intf, uint64_t action);
int __roc_api roc_nix_mcast_mcam_entry_ena_dis(struct roc_nix *roc_nix, uint32_t index,
bool enable);
int __roc_api roc_nix_mcast_list_setup(struct mbox *mbox, uint8_t intf, int nb_entries,
diff --git a/drivers/common/cnxk/roc_nix_mcast.c b/drivers/common/cnxk/roc_nix_mcast.c
index 615014e820..eab4bde743 100644
--- a/drivers/common/cnxk/roc_nix_mcast.c
+++ b/drivers/common/cnxk/roc_nix_mcast.c
@@ -19,7 +19,7 @@ roc_nix_mcast_mcam_entry_alloc(struct roc_nix *roc_nix, uint16_t nb_entries,
req = mbox_alloc_msg_npc_mcam_alloc_entry(mbox);
if (req == NULL)
goto exit;
- req->priority = priority;
+ req->ref_priority = priority;
req->count = nb_entries;
rc = mbox_process_msg(mbox, (void *)&rsp);
@@ -56,24 +56,38 @@ roc_nix_mcast_mcam_entry_free(struct roc_nix *roc_nix, uint32_t index)
}
int
-roc_nix_mcast_mcam_entry_write(struct roc_nix *roc_nix,
- struct mcam_entry *entry, uint32_t index,
- uint8_t intf, uint64_t action)
+roc_nix_mcast_mcam_entry_write(struct roc_nix *roc_nix, void *entry, uint32_t index, uint8_t intf,
+ uint64_t action)
{
struct nix *nix = roc_nix_to_nix_priv(roc_nix);
struct dev *dev = &nix->dev;
struct mbox *mbox = mbox_get(dev->mbox);
- struct npc_mcam_write_entry_req *req;
int rc = -ENOSPC;
- req = mbox_alloc_msg_npc_mcam_write_entry(mbox);
- if (req == NULL)
- goto exit;
- req->entry = index;
- req->intf = intf;
- req->enable_entry = true;
- mbox_memcpy(&req->entry_data, entry, sizeof(struct mcam_entry));
- req->entry_data.action = action;
+ if (roc_model_is_cn20k()) {
+ struct npc_cn20k_mcam_write_entry_req *req;
+
+ req = mbox_alloc_msg_npc_cn20k_mcam_write_entry(mbox);
+ if (req == NULL)
+ goto exit;
+ req->entry = index;
+ req->intf = intf;
+ req->enable_entry = true;
+ mbox_memcpy(&req->entry_data, entry, sizeof(struct cn20k_mcam_entry));
+ req->entry_data.action = action;
+
+ } else {
+ struct npc_mcam_write_entry_req *req;
+
+ req = mbox_alloc_msg_npc_mcam_write_entry(mbox);
+ if (req == NULL)
+ goto exit;
+ req->entry = index;
+ req->intf = intf;
+ req->enable_entry = true;
+ mbox_memcpy(&req->entry_data, entry, sizeof(struct mcam_entry));
+ req->entry_data.action = action;
+ }
rc = mbox_process(mbox);
exit:
diff --git a/drivers/common/cnxk/roc_nix_vlan.c b/drivers/common/cnxk/roc_nix_vlan.c
index db218593ad..16100eb5d6 100644
--- a/drivers/common/cnxk/roc_nix_vlan.c
+++ b/drivers/common/cnxk/roc_nix_vlan.c
@@ -7,7 +7,7 @@
int
roc_nix_vlan_mcam_entry_read(struct roc_nix *roc_nix, uint32_t index,
- struct npc_mcam_read_entry_rsp **rsp)
+ void **rsp)
{
struct nix *nix = roc_nix_to_nix_priv(roc_nix);
struct dev *dev = &nix->dev;
@@ -27,24 +27,34 @@ roc_nix_vlan_mcam_entry_read(struct roc_nix *roc_nix, uint32_t index,
}
int
-roc_nix_vlan_mcam_entry_write(struct roc_nix *roc_nix, uint32_t index,
- struct mcam_entry *entry, uint8_t intf,
+roc_nix_vlan_mcam_entry_write(struct roc_nix *roc_nix, uint32_t index, void *entry, uint8_t intf,
uint8_t enable)
{
struct nix *nix = roc_nix_to_nix_priv(roc_nix);
struct dev *dev = &nix->dev;
struct mbox *mbox = mbox_get(dev->mbox);
struct npc_mcam_write_entry_req *req;
+ struct npc_cn20k_mcam_write_entry_req *cn20k_req;
struct msghdr *rsp;
int rc = -ENOSPC;
- req = mbox_alloc_msg_npc_mcam_write_entry(mbox);
- if (req == NULL)
- goto exit;
- req->entry = index;
- req->intf = intf;
- req->enable_entry = enable;
- mbox_memcpy(&req->entry_data, entry, sizeof(struct mcam_entry));
+ if (roc_model_is_cn20k()) {
+ cn20k_req = mbox_alloc_msg_npc_cn20k_mcam_write_entry(mbox);
+ if (cn20k_req == NULL)
+ goto exit;
+ cn20k_req->entry = index;
+ cn20k_req->intf = intf;
+ cn20k_req->enable_entry = enable;
+ mbox_memcpy(&cn20k_req->entry_data, entry, sizeof(struct cn20k_mcam_entry));
+ } else {
+ req = mbox_alloc_msg_npc_mcam_write_entry(mbox);
+ if (req == NULL)
+ goto exit;
+ req->entry = index;
+ req->intf = intf;
+ req->enable_entry = enable;
+ mbox_memcpy(&req->entry_data, entry, sizeof(struct mcam_entry));
+ }
rc = mbox_process_msg(mbox, (void *)&rsp);
exit:
@@ -53,25 +63,39 @@ roc_nix_vlan_mcam_entry_write(struct roc_nix *roc_nix, uint32_t index,
}
int
-roc_nix_vlan_mcam_entry_alloc_and_write(struct roc_nix *roc_nix,
- struct mcam_entry *entry, uint8_t intf,
+roc_nix_vlan_mcam_entry_alloc_and_write(struct roc_nix *roc_nix, void *entry, uint8_t intf,
uint8_t priority, uint8_t ref_entry)
{
- struct npc_mcam_alloc_and_write_entry_req *req;
struct npc_mcam_alloc_and_write_entry_rsp *rsp;
struct nix *nix = roc_nix_to_nix_priv(roc_nix);
struct dev *dev = &nix->dev;
struct mbox *mbox = mbox_get(dev->mbox);
int rc = -ENOSPC;
- req = mbox_alloc_msg_npc_mcam_alloc_and_write_entry(mbox);
- if (req == NULL)
- goto exit;
- req->priority = priority;
- req->ref_entry = ref_entry;
- req->intf = intf;
- req->enable_entry = true;
- mbox_memcpy(&req->entry_data, entry, sizeof(struct mcam_entry));
+ if (roc_model_is_cn20k()) {
+ struct npc_cn20k_mcam_alloc_and_write_entry_req *req;
+
+ req = mbox_alloc_msg_npc_cn20k_mcam_alloc_and_write_entry(mbox);
+ if (req == NULL)
+ goto exit;
+ req->ref_prio = priority;
+ req->ref_entry = ref_entry;
+ req->intf = intf;
+ req->enable_entry = true;
+ mbox_memcpy(&req->entry_data, entry, sizeof(struct cn20k_mcam_entry));
+
+ } else {
+ struct npc_mcam_alloc_and_write_entry_req *req;
+
+ req = mbox_alloc_msg_npc_mcam_alloc_and_write_entry(mbox);
+ if (req == NULL)
+ goto exit;
+ req->ref_priority = priority;
+ req->ref_entry = ref_entry;
+ req->intf = intf;
+ req->enable_entry = true;
+ mbox_memcpy(&req->entry_data, entry, sizeof(struct mcam_entry));
+ }
rc = mbox_process_msg(mbox, (void *)&rsp);
if (rc)
diff --git a/drivers/common/cnxk/roc_npc.c b/drivers/common/cnxk/roc_npc.c
index 53f278c764..138f12f6d8 100644
--- a/drivers/common/cnxk/roc_npc.c
+++ b/drivers/common/cnxk/roc_npc.c
@@ -100,6 +100,14 @@ roc_npc_mcam_read_counter(struct roc_npc *roc_npc, uint32_t ctr_id, uint64_t *co
return npc_mcam_read_counter(npc->mbox, ctr_id, count);
}
+int
+roc_npc_mcam_get_stats(struct roc_npc *roc_npc, struct roc_npc_flow *flow, uint64_t *count)
+{
+ struct npc *npc = roc_npc_to_npc_priv(roc_npc);
+
+ return npc_mcam_get_stats(npc->mbox, flow, count);
+}
+
int
roc_npc_mcam_clear_counter(struct roc_npc *roc_npc, uint32_t ctr_id)
{
@@ -221,7 +229,9 @@ roc_npc_get_low_priority_mcam(struct roc_npc *roc_npc)
{
struct npc *npc = roc_npc_to_npc_priv(roc_npc);
- if (roc_model_is_cn10k())
+ if (roc_model_is_cn20k())
+ return (npc->mcam_entries - NPC_MCAME_RESVD_10XX - 1);
+ else if (roc_model_is_cn10k())
return (npc->mcam_entries - NPC_MCAME_RESVD_10XX - 1);
else if (roc_model_is_cn98xx())
return (npc->mcam_entries - NPC_MCAME_RESVD_98XX - 1);
@@ -235,7 +245,9 @@ npc_mcam_tot_entries(void)
/* FIXME: change to reading in AF from NPC_AF_CONST1/2
* MCAM_BANK_DEPTH(_EXT) * MCAM_BANKS
*/
- if (roc_model_is_cn10k() || roc_model_is_cn98xx())
+ if (roc_model_is_cn20k())
+ return 2 * 8192; /* MCAM_BANKS = 2, BANK_DEPTH_EXT = 8192 */
+ else if (roc_model_is_cn10k() || roc_model_is_cn98xx())
return 16 * 1024; /* MCAM_BANKS = 4, BANK_DEPTH_EXT = 4096 */
else
return 4 * 1024; /* MCAM_BANKS = 4, BANK_DEPTH_EXT = 1024 */
@@ -311,6 +323,7 @@ roc_npc_init(struct roc_npc *roc_npc)
npc->mcam_entries = npc_mcam_tot_entries() >> npc->keyw[NPC_MCAM_RX];
nix->exact_match_ena = npc->exact_match_ena;
+ roc_npc->max_entries = npc->mcam_entries;
/* Free, free_rev, live and live_rev entries */
bmap_sz = plt_bitmap_get_memory_footprint(npc->mcam_entries);
@@ -1856,9 +1869,7 @@ roc_npc_flow_dump(FILE *file, struct roc_npc *roc_npc, int rep_port_id)
int
roc_npc_mcam_merge_base_steering_rule(struct roc_npc *roc_npc, struct roc_npc_flow *flow)
{
- struct npc_mcam_read_base_rule_rsp *base_rule_rsp;
struct npc *npc = roc_npc_to_npc_priv(roc_npc);
- struct mcam_entry *base_entry;
struct mbox *mbox = mbox_get(npc->mbox);
int idx, rc;
@@ -1868,17 +1879,36 @@ roc_npc_mcam_merge_base_steering_rule(struct roc_npc *roc_npc, struct roc_npc_fl
}
(void)mbox_alloc_msg_npc_read_base_steer_rule(mbox);
- rc = mbox_process_msg(mbox, (void *)&base_rule_rsp);
- if (rc) {
- plt_err("Failed to fetch VF's base MCAM entry");
- goto exit;
- }
- base_entry = &base_rule_rsp->entry_data;
- for (idx = 0; idx < ROC_NPC_MAX_MCAM_WIDTH_DWORDS; idx++) {
- flow->mcam_data[idx] |= base_entry->kw[idx];
- flow->mcam_mask[idx] |= base_entry->kw_mask[idx];
- }
+ if (roc_model_is_cn20k()) {
+ struct npc_cn20k_mcam_read_base_rule_rsp *base_rule_rsp;
+ struct cn20k_mcam_entry *base_entry;
+ rc = mbox_process_msg(mbox, (void *)&base_rule_rsp);
+ if (rc) {
+ plt_err("Failed to fetch VF's base MCAM entry");
+ goto exit;
+ }
+ base_entry = &base_rule_rsp->entry;
+ for (idx = 0; idx < ROC_NPC_MAX_MCAM_WIDTH_DWORDS; idx++) {
+ flow->mcam_data[idx] |= base_entry->kw[idx];
+ flow->mcam_mask[idx] |= base_entry->kw_mask[idx];
+ }
+
+ } else {
+ struct npc_mcam_read_base_rule_rsp *base_rule_rsp;
+ struct mcam_entry *base_entry;
+
+ rc = mbox_process_msg(mbox, (void *)&base_rule_rsp);
+ if (rc) {
+ plt_err("Failed to fetch VF's base MCAM entry");
+ goto exit;
+ }
+ base_entry = &base_rule_rsp->entry_data;
+ for (idx = 0; idx < ROC_NPC_MAX_MCAM_WIDTH_DWORDS; idx++) {
+ flow->mcam_data[idx] |= base_entry->kw[idx];
+ flow->mcam_mask[idx] |= base_entry->kw_mask[idx];
+ }
+ }
rc = 0;
exit:
mbox_put(mbox);
diff --git a/drivers/common/cnxk/roc_npc.h b/drivers/common/cnxk/roc_npc.h
index bf8c65aa9c..b96862e054 100644
--- a/drivers/common/cnxk/roc_npc.h
+++ b/drivers/common/cnxk/roc_npc.h
@@ -305,52 +305,58 @@ struct roc_npc_spi_to_sa_action_info {
};
struct mbox;
-
struct roc_npc_flow {
uint8_t nix_intf;
uint8_t enable;
- uint32_t mcam_id;
uint8_t use_ctr;
+ bool is_validate;
+ uint32_t mcam_id;
+ uint16_t tx_pf_func;
+ bool has_age_action;
+ bool rep_act_rep;
int32_t ctr_id;
uint32_t priority;
uint32_t mtr_id;
+#if defined(ROC_PLATFORM_CN20K)
+#define ROC_NPC_MAX_MCAM_WIDTH_DWORDS 8
+#define ROC_NPC_MAX_MCAM_PRIORITY 123
+#else
#define ROC_NPC_MAX_MCAM_WIDTH_DWORDS 7
+#define ROC_NPC_MAX_MCAM_PRIORITY 32
+#endif
/* Contiguous match string */
uint64_t mcam_data[ROC_NPC_MAX_MCAM_WIDTH_DWORDS];
uint64_t mcam_mask[ROC_NPC_MAX_MCAM_WIDTH_DWORDS];
uint64_t npc_action;
uint64_t vtag_action;
bool vtag_insert_enabled;
- uint8_t vtag_insert_count;
+ int8_t vtag_insert_count;
#define ROC_NPC_MAX_FLOW_PATTERNS 32
struct roc_npc_flow_dump_data dump_data[ROC_NPC_MAX_FLOW_PATTERNS];
uint16_t num_patterns;
struct roc_npc_spi_to_sa_action_info spi_to_sa_info;
- uint16_t tx_pf_func;
- bool is_validate;
uint16_t match_id;
uint8_t is_inline_dev;
bool use_pre_alloc;
uint64_t timeout_cycles;
void *age_context;
- uint32_t timeout;
- bool has_age_action;
- uint16_t rep_pf_func;
uint16_t rep_act_pf_func;
- bool rep_act_rep;
+ bool is_rep_vf;
+ bool has_rep;
+ bool is_sampling_rule;
+ uint16_t rep_pf_func;
+#define ROC_NPC_MIRROR_LIST_SIZE 2
+ uint16_t mcast_pf_funcs[ROC_NPC_MIRROR_LIST_SIZE];
uint16_t rep_channel;
struct mbox *rep_mbox;
- bool has_rep;
- bool is_rep_vf;
struct npc *rep_npc;
int port_id;
- bool is_sampling_rule;
+ uint16_t mcast_channels[ROC_NPC_MIRROR_LIST_SIZE];
uint32_t recv_queue;
uint32_t mcast_grp_index;
uint32_t mce_start_index;
-#define ROC_NPC_MIRROR_LIST_SIZE 2
- uint16_t mcast_pf_funcs[ROC_NPC_MIRROR_LIST_SIZE];
- uint16_t mcast_channels[ROC_NPC_MIRROR_LIST_SIZE];
+ uint8_t key_type;
+ uint32_t timeout;
TAILQ_ENTRY(roc_npc_flow) next;
};
@@ -400,33 +406,34 @@ struct roc_npc {
struct roc_nix *roc_nix;
uint8_t switch_header_type;
uint8_t pre_l2_size_offset; /**< Offset with in header that holds
- * size of custom header
- */
+ * size of custom header
+ */
uint8_t pre_l2_size_offset_mask; /**< Offset mask with in header
- * that holds size of custom header
- */
+ * that holds size of custom header
+ */
uint8_t pre_l2_size_shift_dir; /**< Shift direction to calculate size
- */
+ */
uint16_t flow_prealloc_size;
uint16_t flow_max_priority;
uint16_t channel;
uint16_t pf_func;
+ bool is_sdp_mask_set;
+ bool rep_act_rep;
+ uint16_t sdp_channel_mask;
uint64_t kex_capability;
uint64_t rx_parse_nibble;
/* Parsed RSS Flowkey cfg for current flow being created */
uint32_t flowkey_cfg_state;
- bool is_sdp_mask_set;
+ uint32_t max_entries;
+ uint16_t rep_act_pf_func;
uint16_t sdp_channel;
- uint16_t sdp_channel_mask;
struct roc_npc_flow_age flow_age;
struct roc_npc *rep_npc;
uint16_t rep_pf_func;
uint16_t rep_rx_channel;
- uint16_t rep_act_pf_func;
- bool rep_act_rep;
int rep_port_id;
-#define ROC_NPC_MEM_SZ (6 * 1024)
+#define ROC_NPC_MEM_SZ (20 * 1024)
uint8_t reserved[ROC_NPC_MEM_SZ];
} __plt_cache_aligned;
@@ -482,4 +489,6 @@ int __roc_api roc_npc_mcam_move(struct roc_npc *roc_npc, uint16_t old_ent, uint1
void *__roc_api roc_npc_aged_flow_ctx_get(struct roc_npc *roc_npc, uint32_t mcam_id);
void __roc_api roc_npc_sdp_channel_get(struct roc_npc *roc_npc, uint16_t *chan_base,
uint16_t *chan_mask);
+int __roc_api roc_npc_mcam_get_stats(struct roc_npc *roc_npc, struct roc_npc_flow *flow,
+ uint64_t *count);
#endif /* _ROC_NPC_H_ */
diff --git a/drivers/common/cnxk/roc_npc_mcam.c b/drivers/common/cnxk/roc_npc_mcam.c
index cdb9db1383..412b2611b7 100644
--- a/drivers/common/cnxk/roc_npc_mcam.c
+++ b/drivers/common/cnxk/roc_npc_mcam.c
@@ -11,6 +11,10 @@ npc_mcam_alloc_counter(struct mbox *mbox, uint16_t *ctr)
struct npc_mcam_alloc_counter_rsp *rsp;
int rc = -ENOSPC;
+ /* For CN20K, counters are enabled by default */
+ if (roc_model_is_cn20k())
+ return 0;
+
req = mbox_alloc_msg_npc_mcam_alloc_counter(mbox_get(mbox));
if (req == NULL)
goto exit;
@@ -30,6 +34,9 @@ npc_mcam_free_counter(struct mbox *mbox, uint16_t ctr_id)
struct npc_mcam_oper_counter_req *req;
int rc = -ENOSPC;
+ if (roc_model_is_cn20k())
+ return 0;
+
req = mbox_alloc_msg_npc_mcam_free_counter(mbox_get(mbox));
if (req == NULL)
goto exit;
@@ -40,6 +47,30 @@ npc_mcam_free_counter(struct mbox *mbox, uint16_t ctr_id)
return rc;
}
+int
+npc_mcam_get_stats(struct mbox *mbox, struct roc_npc_flow *flow, uint64_t *count)
+{
+ struct npc_mcam_get_stats_req *req;
+ struct npc_mcam_get_stats_rsp *rsp;
+ int rc = -ENOSPC;
+
+ /* valid only for cn20k */
+ if (!roc_model_is_cn20k())
+ return 0;
+
+ req = mbox_alloc_msg_npc_mcam_entry_stats(mbox_get(mbox));
+ if (req == NULL)
+ goto exit;
+ req->entry = flow->mcam_id;
+ rc = mbox_process_msg(mbox, (void *)&rsp);
+ if (rc)
+ goto exit;
+ *count = rsp->stat;
+exit:
+ mbox_put(mbox);
+ return rc;
+}
+
int
npc_mcam_read_counter(struct mbox *mbox, uint32_t ctr_id, uint64_t *count)
{
@@ -47,6 +78,9 @@ npc_mcam_read_counter(struct mbox *mbox, uint32_t ctr_id, uint64_t *count)
struct npc_mcam_oper_counter_rsp *rsp;
int rc = -ENOSPC;
+ if (roc_model_is_cn20k())
+ return 0;
+
req = mbox_alloc_msg_npc_mcam_counter_stats(mbox_get(mbox));
if (req == NULL)
goto exit;
@@ -66,6 +100,9 @@ npc_mcam_clear_counter(struct mbox *mbox, uint32_t ctr_id)
struct npc_mcam_oper_counter_req *req;
int rc = -ENOSPC;
+ if (roc_model_is_cn20k())
+ return 0;
+
req = mbox_alloc_msg_npc_mcam_clear_counter(mbox_get(mbox));
if (req == NULL)
goto exit;
@@ -132,16 +169,53 @@ npc_lid_lt_in_kex(struct npc *npc, uint8_t lid, uint8_t lt)
struct npc_xtract_info *x_info;
int i;
- for (i = 0; i < NPC_MAX_LD; i++) {
- x_info = &npc->prx_dxcfg[NIX_INTF_RX][lid][lt].xtract[i];
- /* Check for LDATA */
- if (x_info->enable && x_info->len > 0)
- return true;
+ if (!roc_model_is_cn20k()) {
+ for (i = 0; i < NPC_MAX_LD; i++) {
+ x_info = &npc->prx_dxcfg[NIX_INTF_RX][lid][lt].xtract[i];
+ /* Check for LDATA */
+ if (x_info->enable && x_info->len > 0)
+ return true;
+ }
+ } else {
+ for (i = 0; i < NPC_MAX_EXTRACTOR; i++) {
+ union npc_kex_ldata_flags_cfg *lid_info = &npc->lid_cfg[NIX_INTF_RX][i];
+
+ if (lid_info->s.lid != lid)
+ continue;
+ x_info = &npc->prx_dxcfg_cn20k[NIX_INTF_RX][i][lt].xtract;
+ /* Check for LDATA */
+ if (x_info->enable && x_info->len > 0)
+ return true;
+ }
}
return false;
}
+static void
+npc_construct_ldata_mask_cn20k(struct npc *npc, struct plt_bitmap *bmap, uint8_t lid, uint8_t lt)
+{
+ struct npc_xtract_info *x_info;
+ int hdr_off, keylen;
+ int i, j;
+
+ for (i = 0; i < NPC_MAX_EXTRACTOR; i++) {
+ union npc_kex_ldata_flags_cfg *lid_conf = &npc->lid_cfg[NIX_INTF_RX][i];
+
+ if (lid_conf->s.lid != lid)
+ continue;
+
+ x_info = &npc->prx_dxcfg_cn20k[NIX_INTF_RX][i][lt].xtract;
+ if (x_info->enable == 0)
+ continue;
+
+ hdr_off = x_info->hdr_off * 8;
+ keylen = x_info->len * 8;
+ for (j = hdr_off; j < (hdr_off + keylen); j++)
+ plt_bitmap_set(bmap, j);
+ }
+}
+
static void
npc_construct_ldata_mask(struct npc *npc, struct plt_bitmap *bmap, uint8_t lid, uint8_t lt,
uint8_t ld)
@@ -220,8 +294,12 @@ npc_is_kex_enabled(struct npc *npc, uint8_t lid, uint8_t lt, int offset, int len
return false;
}
- npc_construct_ldata_mask(npc, bmap, lid, lt, 0);
- npc_construct_ldata_mask(npc, bmap, lid, lt, 1);
+ if (!roc_model_is_cn20k()) {
+ npc_construct_ldata_mask(npc, bmap, lid, lt, 0);
+ npc_construct_ldata_mask(npc, bmap, lid, lt, 1);
+ } else {
+ npc_construct_ldata_mask_cn20k(npc, bmap, lid, lt);
+ }
for (i = offset; i < (offset + len); i++) {
if (plt_bitmap_get(bmap, i) != 0x1) {
@@ -330,7 +408,7 @@ npc_mcam_alloc_entries(struct mbox *mbox, int ref_mcam, int *alloc_entry, int re
goto exit;
req->contig = is_conti;
req->count = req_count;
- req->priority = prio;
+ req->ref_priority = prio;
req->ref_entry = ref_mcam;
rc = mbox_process_msg(mbox, (void *)&rsp);
@@ -349,11 +427,11 @@ npc_mcam_alloc_entries(struct mbox *mbox, int ref_mcam, int *alloc_entry, int re
int
npc_mcam_alloc_entry(struct npc *npc, struct roc_npc_flow *mcam, struct roc_npc_flow *ref_mcam,
- int prio, int *resp_count)
+ uint8_t prio, int *resp_count)
{
+ struct mbox *mbox = mbox_get(npc->mbox);
struct npc_mcam_alloc_entry_req *req;
struct npc_mcam_alloc_entry_rsp *rsp;
- struct mbox *mbox = mbox_get(npc->mbox);
int rc = -ENOSPC;
req = mbox_alloc_msg_npc_mcam_alloc_entry(mbox);
@@ -361,16 +439,16 @@ npc_mcam_alloc_entry(struct npc *npc, struct roc_npc_flow *mcam, struct roc_npc_
goto exit;
req->contig = 1;
req->count = 1;
- req->priority = prio;
- req->ref_entry = ref_mcam->mcam_id;
-
+ req->ref_priority = prio;
+ req->ref_entry = ref_mcam ? ref_mcam->mcam_id : 0;
+ req->kw_type = mcam->key_type;
rc = mbox_process_msg(mbox, (void *)&rsp);
if (rc)
goto exit;
- memset(mcam, 0, sizeof(struct roc_npc_flow));
mcam->mcam_id = rsp->entry;
- mcam->nix_intf = ref_mcam->nix_intf;
+ mcam->nix_intf = ref_mcam ? ref_mcam->nix_intf : 0;
*resp_count = rsp->count;
+
rc = 0;
exit:
mbox_put(mbox);
@@ -403,6 +481,7 @@ int
npc_mcam_write_entry(struct mbox *mbox, struct roc_npc_flow *mcam)
{
struct npc_mcam_write_entry_req *req;
+ struct npc_cn20k_mcam_write_entry_req *cn20k_req;
struct mbox_msghdr *rsp;
int rc = -ENOSPC;
uint16_t ctr = 0;
@@ -419,33 +498,121 @@ npc_mcam_write_entry(struct mbox *mbox, struct roc_npc_flow *mcam)
return rc;
}
- req = mbox_alloc_msg_npc_mcam_write_entry(mbox_get(mbox));
- if (req == NULL) {
- mbox_put(mbox);
+ if (roc_model_is_cn20k()) {
+ cn20k_req = mbox_alloc_msg_npc_cn20k_mcam_write_entry(mbox_get(mbox));
+ if (cn20k_req == NULL) {
+ mbox_put(mbox);
+ if (mcam->use_ctr)
+ npc_mcam_free_counter(mbox, ctr);
+
+ return rc;
+ }
+ cn20k_req->entry = mcam->mcam_id;
+ cn20k_req->intf = mcam->nix_intf;
+ cn20k_req->enable_entry = mcam->enable;
+ cn20k_req->entry_data.action = mcam->npc_action;
+ cn20k_req->entry_data.vtag_action = mcam->vtag_action;
+ cn20k_req->hw_prio = mcam->priority;
if (mcam->use_ctr)
- npc_mcam_free_counter(mbox, ctr);
+ cn20k_req->cntr = mcam->ctr_id;
- return rc;
- }
- req->entry = mcam->mcam_id;
- req->intf = mcam->nix_intf;
- req->enable_entry = mcam->enable;
- req->entry_data.action = mcam->npc_action;
- req->entry_data.vtag_action = mcam->vtag_action;
- if (mcam->use_ctr) {
- req->set_cntr = 1;
- req->cntr = mcam->ctr_id;
- }
+ for (i = 0; i < NPC_MCAM_KEY_X4_WORDS; i++) {
+ cn20k_req->entry_data.kw[i] = mcam->mcam_data[i];
+ cn20k_req->entry_data.kw_mask[i] = mcam->mcam_mask[i];
+ }
+ } else {
+ req = mbox_alloc_msg_npc_mcam_write_entry(mbox_get(mbox));
+ if (req == NULL) {
+ mbox_put(mbox);
+ if (mcam->use_ctr)
+ npc_mcam_free_counter(mbox, ctr);
- for (i = 0; i < NPC_MCAM_KEY_X4_WORDS; i++) {
- req->entry_data.kw[i] = mcam->mcam_data[i];
- req->entry_data.kw_mask[i] = mcam->mcam_mask[i];
+ return rc;
+ }
+ req->entry = mcam->mcam_id;
+ req->intf = mcam->nix_intf;
+ req->enable_entry = mcam->enable;
+ req->entry_data.action = mcam->npc_action;
+ req->entry_data.vtag_action = mcam->vtag_action;
+ if (mcam->use_ctr) {
+ req->set_cntr = 1;
+ req->cntr = mcam->ctr_id;
+ }
+
+ for (i = 0; i < NPC_MCAM_KEY_X4_WORDS; i++) {
+ req->entry_data.kw[i] = mcam->mcam_data[i];
+ req->entry_data.kw_mask[i] = mcam->mcam_mask[i];
+ }
}
rc = mbox_process_msg(mbox, (void *)&rsp);
mbox_put(mbox);
return rc;
}
+static void
+npc_mcam_kex_cfg_dump(struct npc_cn20k_get_kex_cfg_rsp *kex_rsp)
+{
+ for (int i = 0; i < NPC_MAX_INTF; i++) {
+ for (int j = 0; j < NPC_MAX_EXTRACTOR; j++) {
+ if (kex_rsp->intf_extr[i][j] == 0)
+ continue;
+ plt_info("Intf %d, Extr %d: 0x%" PRIx64, i, j, kex_rsp->intf_extr[i][j]);
+ }
+ }
+
+ for (int i = 0; i < NPC_MAX_INTF; i++) {
+ for (int j = 0; j < NPC_MAX_EXTRACTOR; j++) {
+ for (int k = 0; k < NPC_MAX_LT; k++) {
+ if (kex_rsp->intf_extr_lt[i][j][k] == 0)
+ continue;
+ plt_info("Intf %d, Extr %d, LT %d: 0x%" PRIx64, i, j, k,
+ kex_rsp->intf_extr_lt[i][j][k]);
+ }
+ }
+ }
+}
+
+static void
+npc_mcam_process_mkex_cfg_cn20k(struct npc *npc, struct npc_cn20k_get_kex_cfg_rsp *kex_rsp)
+{
+ volatile uint64_t(*q)[NPC_MAX_INTF][NPC_MAX_EXTRACTOR][NPC_MAX_LT];
+ volatile uint64_t(*d)[NPC_MAX_INTF][NPC_MAX_EXTRACTOR];
+ struct npc_xtract_info *x_info = NULL;
+ union npc_kex_ldata_flags_cfg *ld_info = NULL;
+ int ex, lt, ix;
+ npc_dxcfg_cn20k_t *p;
+ npc_lid_cn20k_t *l;
+ uint64_t keyw;
+ uint64_t val;
+
+ npc->keyx_supp_nmask[NPC_MCAM_RX] = kex_rsp->rx_keyx_cfg & 0x7fffffffULL;
+ npc->keyx_supp_nmask[NPC_MCAM_TX] = kex_rsp->tx_keyx_cfg & 0x7fffffffULL;
+ npc->keyx_len[NPC_MCAM_RX] = npc_supp_key_len(npc->keyx_supp_nmask[NPC_MCAM_RX]);
+ npc->keyx_len[NPC_MCAM_TX] = npc_supp_key_len(npc->keyx_supp_nmask[NPC_MCAM_TX]);
+
+ keyw = (kex_rsp->rx_keyx_cfg >> 32) & 0x7ULL;
+ npc->keyw[NPC_MCAM_RX] = keyw;
+ keyw = (kex_rsp->tx_keyx_cfg >> 32) & 0x7ULL;
+ npc->keyw[NPC_MCAM_TX] = keyw;
+
+ p = &npc->prx_dxcfg_cn20k;
+ l = &npc->lid_cfg;
+ q = (volatile uint64_t(*)[][NPC_MAX_EXTRACTOR][NPC_MAX_LT])(&kex_rsp->intf_extr_lt);
+ d = (volatile uint64_t(*)[][NPC_MAX_EXTRACTOR])(&kex_rsp->intf_extr);
+ for (ix = 0; ix < NPC_MAX_INTF; ix++) {
+ for (ex = 0; ex < NPC_MAX_EXTRACTOR; ex++) {
+ val = (*d)[ix][ex];
+ ld_info = &(*l)[ix][ex];
+ ld_info->s.lid = (val & 0x7);
+ for (lt = 0; lt < NPC_MAX_LT; lt++) {
+ x_info = &(*p)[ix][ex][lt].xtract;
+ val = (*q)[ix][ex][lt];
+ npc_update_kex_info(x_info, val);
+ }
+ }
+ }
+}
+
static void
npc_mcam_process_mkex_cfg(struct npc *npc, struct npc_get_kex_cfg_rsp *kex_rsp)
{
@@ -522,20 +689,38 @@ int
npc_mcam_fetch_kex_cfg(struct npc *npc)
{
struct npc_get_kex_cfg_rsp *kex_rsp;
+ struct npc_cn20k_get_kex_cfg_rsp *kex_rsp_20k;
struct mbox *mbox = mbox_get(npc->mbox);
int rc = 0;
- mbox_alloc_msg_npc_get_kex_cfg(mbox);
- rc = mbox_process_msg(mbox, (void *)&kex_rsp);
- if (rc) {
- plt_err("Failed to fetch NPC KEX config");
- goto done;
- }
- mbox_memcpy((char *)npc->profile_name, kex_rsp->mkex_pfl_name, MKEX_NAME_LEN);
+ if (!roc_model_is_cn20k()) {
+ mbox_alloc_msg_npc_get_kex_cfg(mbox);
+ rc = mbox_process_msg(mbox, (void *)&kex_rsp);
+ if (rc) {
+ plt_err("Failed to fetch NPC KEX config");
+ goto done;
+ }
- npc->exact_match_ena = (kex_rsp->rx_keyx_cfg >> 40) & 0xF;
- npc_mcam_process_mkex_cfg(npc, kex_rsp);
+ mbox_memcpy((char *)npc->profile_name, kex_rsp->mkex_pfl_name, MKEX_NAME_LEN);
+
+ npc->exact_match_ena = (kex_rsp->rx_keyx_cfg >> 40) & 0xF;
+ npc_mcam_process_mkex_cfg(npc, kex_rsp);
+ } else {
+ mbox_alloc_msg_npc_cn20k_get_kex_cfg(mbox);
+ rc = mbox_process_msg(mbox, (void *)&kex_rsp_20k);
+ if (rc) {
+ plt_err("Failed to fetch NPC KEX config");
+ goto done;
+ }
+
+ mbox_memcpy((char *)npc->profile_name, kex_rsp_20k->mkex_pfl_name, MKEX_NAME_LEN);
+
+ npc->exact_match_ena = (kex_rsp_20k->rx_keyx_cfg >> 40) & 0xF;
+ npc_mcam_process_mkex_cfg_cn20k(npc, kex_rsp_20k);
+ if (npc->enable_debug)
+ npc_mcam_kex_cfg_dump(kex_rsp_20k);
+ }
done:
mbox_put(mbox);
@@ -543,7 +728,7 @@ npc_mcam_fetch_kex_cfg(struct npc *npc)
}
static void
-npc_mcam_set_channel(struct roc_npc_flow *flow, struct npc_mcam_write_entry_req *req,
+npc_mcam_set_channel(struct roc_npc_flow *flow, struct npc_cn20k_mcam_write_entry_req *req,
uint16_t channel, uint16_t chan_mask, bool is_second_pass)
{
uint16_t chan = 0, mask = 0;
@@ -552,6 +737,7 @@ npc_mcam_set_channel(struct roc_npc_flow *flow, struct npc_mcam_write_entry_req
req->entry_data.kw_mask[0] &= ~(GENMASK(11, 0));
flow->mcam_data[0] &= ~(GENMASK(11, 0));
flow->mcam_mask[0] &= ~(GENMASK(11, 0));
+
chan = channel;
mask = chan_mask;
@@ -579,11 +765,12 @@ npc_mcam_set_channel(struct roc_npc_flow *flow, struct npc_mcam_write_entry_req
flow->mcam_mask[0] |= (uint64_t)mask;
}
+#define NPC_PF_FUNC_WIDTH 2
+#define NPC_KEX_PF_FUNC_MASK 0xFFFF
+
static int
npc_mcam_set_pf_func(struct npc *npc, struct roc_npc_flow *flow, uint16_t pf_func)
{
-#define NPC_PF_FUNC_WIDTH 2
-#define NPC_KEX_PF_FUNC_MASK 0xFFFF
uint16_t nr_bytes, hdr_offset, key_offset, pf_func_offset;
uint8_t *flow_mcam_data, *flow_mcam_mask;
struct npc_lid_lt_xtract_info *xinfo;
@@ -618,10 +805,48 @@ npc_mcam_set_pf_func(struct npc *npc, struct roc_npc_flow *flow, uint16_t pf_fun
return 0;
}
+static int
+npc_mcam_set_pf_func_cn20k(struct npc *npc, struct roc_npc_flow *flow, uint16_t pf_func)
+{
+ uint16_t nr_bytes, hdr_offset, key_offset, pf_func_offset;
+ struct npc_lid_lt_xtract_info_cn20k *xinfo;
+ uint8_t *flow_mcam_data, *flow_mcam_mask;
+ bool pffunc_found = false;
+ uint16_t mask = 0xFFFF;
+ int i;
+
+ flow_mcam_data = (uint8_t *)flow->mcam_data;
+ flow_mcam_mask = (uint8_t *)flow->mcam_mask;
+
+ xinfo = npc->prx_dxcfg_cn20k[NIX_INTF_TX][NPC_LID_LA];
+
+ for (i = 0; i < NPC_MAX_LT; i++) {
+ nr_bytes = xinfo[i].xtract.len;
+ hdr_offset = xinfo[i].xtract.hdr_off;
+ key_offset = xinfo[i].xtract.key_off;
+
+ if (hdr_offset > 0 || nr_bytes < NPC_PF_FUNC_WIDTH)
+ continue;
+ else
+ pffunc_found = true;
+
+ pf_func_offset = key_offset + nr_bytes - NPC_PF_FUNC_WIDTH;
+ memcpy((void *)&flow_mcam_data[pf_func_offset], (uint8_t *)&pf_func,
+ NPC_PF_FUNC_WIDTH);
+ memcpy((void *)&flow_mcam_mask[pf_func_offset], (uint8_t *)&mask,
+ NPC_PF_FUNC_WIDTH);
+ }
+ if (!pffunc_found)
+ return -EINVAL;
+
+ return 0;
+}
+
int
npc_mcam_alloc_and_write(struct npc *npc, struct roc_npc_flow *flow, struct npc_parse_state *pst)
{
- struct npc_mcam_write_entry_req *req;
+ struct npc_cn20k_mcam_write_entry_req *cn20k_req;
+ struct npc_cn20k_mcam_write_entry_req req;
struct nix_inl_dev *inl_dev = NULL;
struct mbox *mbox = npc->mbox;
struct mbox_msghdr *rsp;
@@ -655,6 +880,12 @@ npc_mcam_alloc_and_write(struct npc *npc, struct roc_npc_flow *flow, struct npc_
return rc;
}
+ if (roc_model_is_cn20k()) {
+ req.hw_prio = flow->priority;
+ flow->key_type = npc_get_key_type(npc, flow);
+ req.req_kw_type = flow->key_type;
+ }
+
if (flow->nix_intf == NIX_INTF_RX && flow->is_inline_dev && inl_dev &&
inl_dev->ipsec_index && inl_dev->is_multi_channel) {
if (inl_dev->curr_ipsec_idx >= inl_dev->alloc_ipsec_rules)
@@ -672,14 +903,17 @@ npc_mcam_alloc_and_write(struct npc *npc, struct roc_npc_flow *flow, struct npc_
}
if (flow->nix_intf == NIX_INTF_TX) {
- uint16_t pf_func = flow->tx_pf_func;
+ uint16_t pffunc = flow->tx_pf_func;
if (flow->has_rep)
- pf_func = flow->rep_pf_func;
+ pffunc = flow->rep_pf_func;
- pf_func = plt_cpu_to_be_16(pf_func);
+ pffunc = plt_cpu_to_be_16(pffunc);
- rc = npc_mcam_set_pf_func(npc, flow, pf_func);
+ if (roc_model_is_cn20k())
+ rc = npc_mcam_set_pf_func_cn20k(npc, flow, pffunc);
+ else
+ rc = npc_mcam_set_pf_func(npc, flow, pffunc);
if (rc)
return rc;
}
@@ -708,20 +942,14 @@ npc_mcam_alloc_and_write(struct npc *npc, struct roc_npc_flow *flow, struct npc_
}
}
- req = mbox_alloc_msg_npc_mcam_write_entry(mbox_get(mbox));
- if (req == NULL) {
- rc = -ENOSPC;
- goto exit;
- }
- req->set_cntr = flow->use_ctr;
- req->cntr = flow->ctr_id;
- req->entry = entry;
+ req.cntr = flow->ctr_id;
+ req.entry = entry;
- req->intf = (flow->nix_intf == NIX_INTF_RX) ? NPC_MCAM_RX : NPC_MCAM_TX;
- req->enable_entry = 1;
+ req.intf = (flow->nix_intf == NIX_INTF_RX) ? NPC_MCAM_RX : NPC_MCAM_TX;
+ req.enable_entry = 1;
if (flow->nix_intf == NIX_INTF_RX)
flow->npc_action |= (uint64_t)flow->recv_queue << 20;
- req->entry_data.action = flow->npc_action;
+ req.entry_data.action = flow->npc_action;
/*
* Driver sets vtag action on per interface basis, not
@@ -735,38 +963,38 @@ npc_mcam_alloc_and_write(struct npc *npc, struct roc_npc_flow *flow, struct npc_
*
* Second approach is used now.
*/
- req->entry_data.vtag_action = flow->vtag_action;
+ req.entry_data.vtag_action = flow->vtag_action;
for (idx = 0; idx < ROC_NPC_MAX_MCAM_WIDTH_DWORDS; idx++) {
- req->entry_data.kw[idx] = flow->mcam_data[idx];
- req->entry_data.kw_mask[idx] = flow->mcam_mask[idx];
+ req.entry_data.kw[idx] = flow->mcam_data[idx];
+ req.entry_data.kw_mask[idx] = flow->mcam_mask[idx];
}
if (flow->nix_intf == NIX_INTF_RX) {
if (inl_dev && inl_dev->is_multi_channel &&
(flow->npc_action & NIX_RX_ACTIONOP_UCAST_IPSEC)) {
pf_func = nix_inl_dev_pffunc_get();
- req->entry_data.action &= ~(GENMASK(19, 4));
- req->entry_data.action |= (uint64_t)pf_func << 4;
+ req.entry_data.action &= ~(GENMASK(19, 4));
+ req.entry_data.action |= (uint64_t)pf_func << 4;
flow->npc_action &= ~(GENMASK(19, 4));
flow->npc_action |= (uint64_t)pf_func << 4;
- npc_mcam_set_channel(flow, req, inl_dev->channel, inl_dev->chan_mask,
+ npc_mcam_set_channel(flow, &req, inl_dev->channel, inl_dev->chan_mask,
false);
} else if (flow->has_rep) {
pf_func = (flow->rep_act_pf_func == 0) ? flow->rep_pf_func :
flow->rep_act_pf_func;
- req->entry_data.action &= ~(GENMASK(19, 4));
- req->entry_data.action |= (uint64_t)pf_func << 4;
+ req.entry_data.action &= ~(GENMASK(19, 4));
+ req.entry_data.action |= (uint64_t)pf_func << 4;
flow->npc_action &= ~(GENMASK(19, 4));
flow->npc_action |= (uint64_t)pf_func << 4;
- npc_mcam_set_channel(flow, req, flow->rep_channel, (BIT_ULL(12) - 1),
+ npc_mcam_set_channel(flow, &req, flow->rep_channel, (BIT_ULL(12) - 1),
false);
} else if (npc->is_sdp_link) {
- npc_mcam_set_channel(flow, req, npc->sdp_channel, npc->sdp_channel_mask,
+ npc_mcam_set_channel(flow, &req, npc->sdp_channel, npc->sdp_channel_mask,
pst->is_second_pass_rule);
} else {
- npc_mcam_set_channel(flow, req, npc->channel, (BIT_ULL(12) - 1),
+ npc_mcam_set_channel(flow, &req, npc->channel, (BIT_ULL(12) - 1),
pst->is_second_pass_rule);
}
/*
@@ -779,25 +1007,66 @@ npc_mcam_alloc_and_write(struct npc *npc, struct roc_npc_flow *flow, struct npc_
la_offset *= 4;
mask = ~((0xfULL << la_offset));
- req->entry_data.kw[0] &= mask;
- req->entry_data.kw_mask[0] &= mask;
+ req.entry_data.kw[0] &= mask;
+ req.entry_data.kw_mask[0] &= mask;
flow->mcam_data[0] &= mask;
flow->mcam_mask[0] &= mask;
if (pst->is_second_pass_rule) {
- req->entry_data.kw[0] |= ((uint64_t)NPC_LT_LA_CPT_HDR) << la_offset;
- req->entry_data.kw_mask[0] |= (0xFULL << la_offset);
+ req.entry_data.kw[0] |= ((uint64_t)NPC_LT_LA_CPT_HDR) << la_offset;
+ req.entry_data.kw_mask[0] |= (0xFULL << la_offset);
flow->mcam_data[0] |= ((uint64_t)NPC_LT_LA_CPT_HDR) << la_offset;
flow->mcam_mask[0] |= (0xFULL << la_offset);
} else {
/* Mask ltype ETHER (0x2) and CPT_HDR (0xa) */
- req->entry_data.kw[0] |= (0x2ULL << la_offset);
- req->entry_data.kw_mask[0] |= (0x7ULL << la_offset);
+ req.entry_data.kw[0] |= (0x2ULL << la_offset);
+ req.entry_data.kw_mask[0] |= (0x7ULL << la_offset);
flow->mcam_data[0] |= (0x2ULL << la_offset);
flow->mcam_mask[0] |= (0x7ULL << la_offset);
}
}
}
+ if (roc_model_is_cn20k()) {
+ cn20k_req = mbox_alloc_msg_npc_cn20k_mcam_write_entry(mbox_get(mbox));
+ if (cn20k_req == NULL) {
+ mbox_put(mbox);
+ if (flow->use_ctr)
+ npc_mcam_free_counter(mbox, ctr);
+
+ return rc;
+ }
+ cn20k_req->entry = req.entry;
+ cn20k_req->intf = req.intf;
+ cn20k_req->enable_entry = req.enable_entry;
+ cn20k_req->entry_data.action = req.entry_data.action;
+ cn20k_req->entry_data.vtag_action = req.entry_data.vtag_action;
+ cn20k_req->hw_prio = req.hw_prio;
+ cn20k_req->req_kw_type = req.req_kw_type;
+ if (flow->use_ctr)
+ cn20k_req->cntr = req.cntr;
+
+ mbox_memcpy(&cn20k_req->entry_data, &req.entry_data,
+ sizeof(struct cn20k_mcam_entry));
+ } else {
+ struct npc_mcam_write_entry_req *req_leg;
+
+ req_leg = mbox_alloc_msg_npc_mcam_write_entry(mbox_get(mbox));
+ if (req_leg == NULL) {
+ rc = -ENOSPC;
+ goto exit;
+ }
+ for (idx = 0; idx < NPC_MAX_KWS_IN_KEY; idx++) {
+ req_leg->entry_data.kw[idx] = req.entry_data.kw[idx];
+ req_leg->entry_data.kw_mask[idx] = req.entry_data.kw_mask[idx];
+ }
+ req_leg->entry = req.entry;
+ req_leg->intf = req.intf;
+ req_leg->enable_entry = req.enable_entry;
+ req_leg->cntr = req.cntr;
+ req_leg->entry_data.action = req.entry_data.action;
+ req_leg->entry_data.vtag_action = req.entry_data.vtag_action;
+ req_leg->set_cntr = flow->use_ctr;
+ }
rc = mbox_process_msg(mbox, (void *)&rsp);
if (rc != 0)
goto exit;
@@ -810,7 +1079,7 @@ npc_mcam_alloc_and_write(struct npc *npc, struct roc_npc_flow *flow, struct npc_
exit:
mbox_put(mbox);
- if (rc)
+ if (rc && flow->is_sampling_rule)
roc_nix_mcast_list_free(npc->mbox, flow->mcast_grp_index);
return rc;
}
@@ -821,9 +1090,14 @@ npc_set_vlan_ltype(struct npc_parse_state *pst)
uint64_t val, mask;
uint8_t lb_offset;
- lb_offset =
- plt_popcount32(pst->npc->keyx_supp_nmask[pst->nix_intf] &
- ((1ULL << NPC_LTYPE_LB_OFFSET) - 1));
+ if (roc_model_is_cn20k()) {
+ lb_offset = plt_popcount32(pst->npc->keyx_supp_nmask[pst->nix_intf] &
+ ((1ULL << NPC_CN20K_LTYPE_LB_OFFSET) - 1));
+
+ } else {
+ lb_offset = plt_popcount32(pst->npc->keyx_supp_nmask[pst->nix_intf] &
+ ((1ULL << NPC_LTYPE_LB_OFFSET) - 1));
+ }
lb_offset *= 4;
mask = ~((0xfULL << lb_offset));
@@ -843,9 +1117,14 @@ npc_set_ipv6ext_ltype_mask(struct npc_parse_state *pst)
uint8_t lc_offset, lcflag_offset;
uint64_t val, mask;
- lc_offset =
- plt_popcount32(pst->npc->keyx_supp_nmask[pst->nix_intf] &
- ((1ULL << NPC_LTYPE_LC_OFFSET) - 1));
+ if (roc_model_is_cn20k()) {
+ lc_offset = plt_popcount32(pst->npc->keyx_supp_nmask[pst->nix_intf] &
+ ((1ULL << NPC_CN20K_LTYPE_LC_OFFSET) - 1));
+
+ } else {
+ lc_offset = plt_popcount32(pst->npc->keyx_supp_nmask[pst->nix_intf] &
+ ((1ULL << NPC_LTYPE_LC_OFFSET) - 1));
+ }
lc_offset *= 4;
mask = ~((0xfULL << lc_offset));
@@ -867,8 +1146,14 @@ npc_set_ipv6ext_ltype_mask(struct npc_parse_state *pst)
* zero in LFLAG.
*/
if (pst->npc->keyx_supp_nmask[pst->nix_intf] & (1ULL << NPC_LFLAG_LC_OFFSET)) {
- lcflag_offset = plt_popcount32(pst->npc->keyx_supp_nmask[pst->nix_intf] &
- ((1ULL << NPC_LFLAG_LC_OFFSET) - 1));
+ if (roc_model_is_cn20k()) {
+ lcflag_offset = plt_popcount32(pst->npc->keyx_supp_nmask[pst->nix_intf] &
+ ((1ULL << NPC_CN20K_LFLAG_LC_OFFSET) - 1));
+
+ } else {
+ lcflag_offset = plt_popcount32(pst->npc->keyx_supp_nmask[pst->nix_intf] &
+ ((1ULL << NPC_LFLAG_LC_OFFSET) - 1));
+ }
lcflag_offset *= 4;
mask = (0xfULL << lcflag_offset);
@@ -881,14 +1166,12 @@ npc_set_ipv6ext_ltype_mask(struct npc_parse_state *pst)
int
npc_program_mcam(struct npc *npc, struct npc_parse_state *pst, bool mcam_alloc)
{
- struct npc_mcam_read_base_rule_rsp *base_rule_rsp;
/* This is non-LDATA part in search key */
uint64_t key_data[2] = {0ULL, 0ULL};
uint64_t key_mask[2] = {0ULL, 0ULL};
int key_len, bit = 0, index, rc = 0;
struct nix_inl_dev *inl_dev = NULL;
int intf = pst->flow->nix_intf;
- struct mcam_entry *base_entry;
bool skip_base_rule = false;
int off, idx, data_off = 0;
uint8_t lid, mask, data;
@@ -908,40 +1191,79 @@ npc_program_mcam(struct npc *npc, struct npc_parse_state *pst, bool mcam_alloc)
data_off *= 4;
index = 0;
- for (lid = 0; lid < NPC_MAX_LID; lid++) {
- /* Offset in key */
- off = NPC_PARSE_KEX_S_LID_OFFSET(lid);
- lt = pst->lt[lid] & 0xf;
- flags = pst->flags[lid] & 0xff;
+ if (!roc_model_is_cn20k()) {
+ for (lid = 0; lid < NPC_MAX_LID; lid++) {
+ /* Offset in key */
+ off = NPC_PARSE_KEX_S_LID_OFFSET(lid);
+ lt = pst->lt[lid] & 0xf;
+ flags = pst->flags[lid] & 0xff;
- /* NPC_LAYER_KEX_S */
- layer_info = ((npc->keyx_supp_nmask[intf] >> off) & 0x7);
+ /* NPC_LAYER_KEX_S */
+ layer_info = ((npc->keyx_supp_nmask[intf] >> off) & 0x7);
+ if (!layer_info)
+ continue;
- if (layer_info) {
for (idx = 0; idx <= 2; idx++) {
- if (layer_info & (1 << idx)) {
- if (idx == 2) {
- data = lt;
- mask = 0xf;
- } else if (idx == 1) {
- data = ((flags >> 4) & 0xf);
- mask = ((flags >> 4) & 0xf);
- } else {
- data = (flags & 0xf);
- mask = (flags & 0xf);
- }
-
- if (data_off >= 64) {
- data_off = 0;
- index++;
- }
- key_data[index] |= ((uint64_t)data << data_off);
-
- if (lt == 0)
- mask = 0;
- key_mask[index] |= ((uint64_t)mask << data_off);
- data_off += 4;
+ if (!(layer_info & (1 << idx)))
+ continue;
+
+ if (idx == 2) {
+ data = lt;
+ mask = 0xf;
+ } else if (idx == 1) {
+ data = ((flags >> 4) & 0xf);
+ mask = ((flags >> 4) & 0xf);
+ } else {
+ data = (flags & 0xf);
+ mask = (flags & 0xf);
+ }
+
+ if (data_off >= 64) {
+ data_off = 0;
+ index++;
}
+ key_data[index] |= ((uint64_t)data << data_off);
+
+ if (lt == 0)
+ mask = 0;
+ key_mask[index] |= ((uint64_t)mask << data_off);
+ data_off += 4;
+ }
+ }
+ } else {
+ for (lid = 0; lid < NPC_MAX_LID; lid++) {
+ /* Offset in key */
+ off = NPC_PARSE_KEX_S_LID_OFFSET_CN20K(lid);
+ lt = pst->lt[lid] & 0xf;
+ flags = pst->flags[lid] & 0xf;
+
+ /* NPC_LAYER_KEX_S */
+ layer_info = ((npc->keyx_supp_nmask[intf] >> off) & 0x3);
+ if (!layer_info)
+ continue;
+
+ for (idx = 0; idx <= 1; idx++) {
+ if (!(layer_info & (1 << idx)))
+ continue;
+
+ if (idx == 1) {
+ data = lt;
+ mask = 0xf;
+ } else {
+ data = (flags & 0xf);
+ mask = (flags & 0xf);
+ }
+
+ if (data_off >= 64) {
+ data_off = 0;
+ index++;
+ }
+ key_data[index] |= ((uint64_t)data << data_off);
+
+ if (lt == 0)
+ mask = 0;
+ key_mask[index] |= ((uint64_t)mask << data_off);
+ data_off += 4;
}
}
}
@@ -971,17 +1293,39 @@ npc_program_mcam(struct npc *npc, struct npc_parse_state *pst, bool mcam_alloc)
else
mbox = mbox_get(npc->mbox);
(void)mbox_alloc_msg_npc_read_base_steer_rule(mbox);
- rc = mbox_process_msg(mbox, (void *)&base_rule_rsp);
- if (rc) {
+ if (roc_model_is_cn20k()) {
+ struct npc_cn20k_mcam_read_base_rule_rsp *base_rule_rsp;
+ struct cn20k_mcam_entry *base_entry;
+
+ rc = mbox_process_msg(mbox, (void *)&base_rule_rsp);
+ if (rc) {
+ mbox_put(mbox);
+ plt_err("Failed to fetch VF's base MCAM entry");
+ return rc;
+ }
mbox_put(mbox);
- plt_err("Failed to fetch VF's base MCAM entry");
- return rc;
- }
- mbox_put(mbox);
- base_entry = &base_rule_rsp->entry_data;
- for (idx = 0; idx < ROC_NPC_MAX_MCAM_WIDTH_DWORDS; idx++) {
- pst->flow->mcam_data[idx] |= base_entry->kw[idx];
- pst->flow->mcam_mask[idx] |= base_entry->kw_mask[idx];
+ base_entry = &base_rule_rsp->entry;
+ for (idx = 0; idx < ROC_NPC_MAX_MCAM_WIDTH_DWORDS; idx++) {
+ pst->flow->mcam_data[idx] |= base_entry->kw[idx];
+ pst->flow->mcam_mask[idx] |= base_entry->kw_mask[idx];
+ }
+
+ } else {
+ struct npc_mcam_read_base_rule_rsp *base_rule_rsp;
+ struct mcam_entry *base_entry;
+
+ rc = mbox_process_msg(mbox, (void *)&base_rule_rsp);
+ if (rc) {
+ mbox_put(mbox);
+ plt_err("Failed to fetch VF's base MCAM entry");
+ return rc;
+ }
+ mbox_put(mbox);
+ base_entry = &base_rule_rsp->entry_data;
+ for (idx = 0; idx < ROC_NPC_MAX_MCAM_WIDTH_DWORDS; idx++) {
+ pst->flow->mcam_data[idx] |= base_entry->kw[idx];
+ pst->flow->mcam_mask[idx] |= base_entry->kw_mask[idx];
+ }
}
}
diff --git a/drivers/common/cnxk/roc_npc_mcam_dump.c b/drivers/common/cnxk/roc_npc_mcam_dump.c
index ebd2dd69c2..bedf6db37c 100644
--- a/drivers/common/cnxk/roc_npc_mcam_dump.c
+++ b/drivers/common/cnxk/roc_npc_mcam_dump.c
@@ -35,6 +35,33 @@
#define NIX_TX_VTAGACT_VTAG1_OP_MASK GENMASK(45, 44)
#define NIX_TX_VTAGACT_VTAG1_DEF_MASK GENMASK(57, 48)
+union npc_rx_parse_nibble_cn20k_u {
+ struct {
+ uint64_t chan : 3;
+ uint64_t errlev : 1;
+ uint64_t errcode : 2;
+ uint64_t l2l3bm : 1;
+ uint64_t laflags : 1;
+ uint64_t latype : 1;
+ uint64_t lbflags : 1;
+ uint64_t lbtype : 1;
+ uint64_t lcflags : 1;
+ uint64_t lctype : 1;
+ uint64_t ldflags : 1;
+ uint64_t ldtype : 1;
+ uint64_t leflags : 1;
+ uint64_t letype : 1;
+ uint64_t lfflags : 1;
+ uint64_t lftype : 1;
+ uint64_t lgflags : 1;
+ uint64_t lgtype : 1;
+ uint64_t lhflags : 1;
+ uint64_t lhtype : 1;
+ uint64_t reserved : 41;
+ } s __plt_packed;
+ uint64_t u;
+};
+
struct npc_rx_parse_nibble_s {
uint16_t chan : 3;
uint16_t errlev : 1;
@@ -181,8 +208,135 @@ npc_get_nibbles(struct roc_npc_flow *flow, uint16_t size, uint32_t bit_offset)
}
static void
-npc_flow_print_parse_nibbles(FILE *file, struct roc_npc_flow *flow,
- uint64_t parse_nibbles)
+npc_flow_print_parse_nibbles_cn20k(FILE *file, struct roc_npc_flow *flow, uint64_t parse_nibbles)
+{
+ union npc_rx_parse_nibble_cn20k_u rx_parse;
+ uint32_t data, offset = 0;
+
+ rx_parse.u = parse_nibbles;
+
+ if (rx_parse.s.chan) {
+ data = npc_get_nibbles(flow, 3, offset);
+ fprintf(file, "\tNPC_PARSE_NIBBLE_CHAN:%#03X\n", data);
+ offset += 12;
+ }
+
+ if (rx_parse.s.errlev) {
+ data = npc_get_nibbles(flow, 1, offset);
+ fprintf(file, "\tNPC_PARSE_NIBBLE_ERRLEV:%#X\n", data);
+ offset += 4;
+ }
+
+ if (rx_parse.s.errcode) {
+ data = npc_get_nibbles(flow, 2, offset);
+ fprintf(file, "\tNPC_PARSE_NIBBLE_ERRCODE:%#02X\n", data);
+ offset += 8;
+ }
+
+ if (rx_parse.s.l2l3bm) {
+ data = npc_get_nibbles(flow, 1, offset);
+ fprintf(file, "\tNPC_PARSE_NIBBLE_L2L3_BCAST:%#X\n", data);
+ offset += 4;
+ }
+
+ if (rx_parse.s.laflags) {
+ data = npc_get_nibbles(flow, 1, offset);
+ fprintf(file, "\tNPC_PARSE_NIBBLE_LA_FLAGS:%#02X\n", data);
+ offset += 8;
+ }
+
+ if (rx_parse.s.latype) {
+ data = npc_get_nibbles(flow, 1, offset);
+ fprintf(file, "\tNPC_PARSE_NIBBLE_LA_LTYPE:%s\n", ltype_str[NPC_LID_LA][data]);
+ offset += 4;
+ }
+
+ if (rx_parse.s.lbflags) {
+ data = npc_get_nibbles(flow, 1, offset);
+ fprintf(file, "\tNPC_PARSE_NIBBLE_LB_FLAGS:%#02X\n", data);
+ offset += 8;
+ }
+
+ if (rx_parse.s.lbtype) {
+ data = npc_get_nibbles(flow, 1, offset);
+ fprintf(file, "\tNPC_PARSE_NIBBLE_LB_LTYPE:%s\n", ltype_str[NPC_LID_LB][data]);
+ offset += 4;
+ }
+
+ if (rx_parse.s.lcflags) {
+ data = npc_get_nibbles(flow, 1, offset);
+ fprintf(file, "\tNPC_PARSE_NIBBLE_LC_FLAGS:%#02X\n", data);
+ offset += 8;
+ }
+
+ if (rx_parse.s.lctype) {
+ data = npc_get_nibbles(flow, 1, offset);
+ fprintf(file, "\tNPC_PARSE_NIBBLE_LC_LTYPE:%s\n", ltype_str[NPC_LID_LC][data]);
+ offset += 4;
+ }
+
+ if (rx_parse.s.ldflags) {
+ data = npc_get_nibbles(flow, 1, offset);
+ fprintf(file, "\tNPC_PARSE_NIBBLE_LD_FLAGS:%#02X\n", data);
+ offset += 8;
+ }
+
+ if (rx_parse.s.ldtype) {
+ data = npc_get_nibbles(flow, 1, offset);
+ fprintf(file, "\tNPC_PARSE_NIBBLE_LD_LTYPE:%s\n", ltype_str[NPC_LID_LD][data]);
+ offset += 4;
+ }
+
+ if (rx_parse.s.leflags) {
+ data = npc_get_nibbles(flow, 1, offset);
+ fprintf(file, "\tNPC_PARSE_NIBBLE_LE_FLAGS:%#02X\n", data);
+ offset += 8;
+ }
+
+ if (rx_parse.s.letype) {
+ data = npc_get_nibbles(flow, 1, offset);
+ fprintf(file, "\tNPC_PARSE_NIBBLE_LE_LTYPE:%s\n", ltype_str[NPC_LID_LE][data]);
+ offset += 4;
+ }
+
+ if (rx_parse.s.lfflags) {
+ data = npc_get_nibbles(flow, 1, offset);
+ fprintf(file, "\tNPC_PARSE_NIBBLE_LF_FLAGS:%#02X\n", data);
+ offset += 8;
+ }
+
+ if (rx_parse.s.lftype) {
+ data = npc_get_nibbles(flow, 1, offset);
+ fprintf(file, "\tNPC_PARSE_NIBBLE_LF_LTYPE:%s\n", ltype_str[NPC_LID_LF][data]);
+ offset += 4;
+ }
+
+ if (rx_parse.s.lgflags) {
+ data = npc_get_nibbles(flow, 1, offset);
+ fprintf(file, "\tNPC_PARSE_NIBBLE_LG_FLAGS:%#02X\n", data);
+ offset += 8;
+ }
+
+ if (rx_parse.s.lgtype) {
+ data = npc_get_nibbles(flow, 1, offset);
+ fprintf(file, "\tNPC_PARSE_NIBBLE_LG_LTYPE:%s\n", ltype_str[NPC_LID_LG][data]);
+ offset += 4;
+ }
+
+ if (rx_parse.s.lhflags) {
+ data = npc_get_nibbles(flow, 1, offset);
+ fprintf(file, "\tNPC_PARSE_NIBBLE_LH_FLAGS:%#02X\n", data);
+ }
+
+ if (rx_parse.s.lhtype) {
+ data = npc_get_nibbles(flow, 1, offset);
+ fprintf(file, "\tNPC_PARSE_NIBBLE_LH_LTYPE:%s\n", ltype_str[NPC_LID_LH][data]);
+ offset += 4;
+ }
+}
+
+static void
+npc_flow_print_parse_nibbles_legacy(FILE *file, struct roc_npc_flow *flow, uint64_t parse_nibbles)
{
struct npc_rx_parse_nibble_s *rx_parse;
uint32_t data, offset = 0;
@@ -221,8 +375,7 @@ npc_flow_print_parse_nibbles(FILE *file, struct roc_npc_flow *flow,
if (rx_parse->latype) {
data = npc_get_nibbles(flow, 1, offset);
- fprintf(file, "\tNPC_PARSE_NIBBLE_LA_LTYPE:%s\n",
- ltype_str[NPC_LID_LA][data]);
+ fprintf(file, "\tNPC_PARSE_NIBBLE_LA_LTYPE:%s\n", ltype_str[NPC_LID_LA][data]);
offset += 4;
}
@@ -234,8 +387,7 @@ npc_flow_print_parse_nibbles(FILE *file, struct roc_npc_flow *flow,
if (rx_parse->lbtype) {
data = npc_get_nibbles(flow, 1, offset);
- fprintf(file, "\tNPC_PARSE_NIBBLE_LB_LTYPE:%s\n",
- ltype_str[NPC_LID_LB][data]);
+ fprintf(file, "\tNPC_PARSE_NIBBLE_LB_LTYPE:%s\n", ltype_str[NPC_LID_LB][data]);
offset += 4;
}
@@ -247,8 +399,7 @@ npc_flow_print_parse_nibbles(FILE *file, struct roc_npc_flow *flow,
if (rx_parse->lctype) {
data = npc_get_nibbles(flow, 1, offset);
- fprintf(file, "\tNPC_PARSE_NIBBLE_LC_LTYPE:%s\n",
- ltype_str[NPC_LID_LC][data]);
+ fprintf(file, "\tNPC_PARSE_NIBBLE_LC_LTYPE:%s\n", ltype_str[NPC_LID_LC][data]);
offset += 4;
}
@@ -260,8 +411,7 @@ npc_flow_print_parse_nibbles(FILE *file, struct roc_npc_flow *flow,
if (rx_parse->ldtype) {
data = npc_get_nibbles(flow, 1, offset);
- fprintf(file, "\tNPC_PARSE_NIBBLE_LD_LTYPE:%s\n",
- ltype_str[NPC_LID_LD][data]);
+ fprintf(file, "\tNPC_PARSE_NIBBLE_LD_LTYPE:%s\n", ltype_str[NPC_LID_LD][data]);
offset += 4;
}
@@ -273,8 +423,7 @@ npc_flow_print_parse_nibbles(FILE *file, struct roc_npc_flow *flow,
if (rx_parse->letype) {
data = npc_get_nibbles(flow, 1, offset);
- fprintf(file, "\tNPC_PARSE_NIBBLE_LE_LTYPE:%s\n",
- ltype_str[NPC_LID_LE][data]);
+ fprintf(file, "\tNPC_PARSE_NIBBLE_LE_LTYPE:%s\n", ltype_str[NPC_LID_LE][data]);
offset += 4;
}
@@ -286,8 +435,7 @@ npc_flow_print_parse_nibbles(FILE *file, struct roc_npc_flow *flow,
if (rx_parse->lftype) {
data = npc_get_nibbles(flow, 1, offset);
- fprintf(file, "\tNPC_PARSE_NIBBLE_LF_LTYPE:%s\n",
- ltype_str[NPC_LID_LF][data]);
+ fprintf(file, "\tNPC_PARSE_NIBBLE_LF_LTYPE:%s\n", ltype_str[NPC_LID_LF][data]);
offset += 4;
}
@@ -299,8 +447,7 @@ npc_flow_print_parse_nibbles(FILE *file, struct roc_npc_flow *flow,
if (rx_parse->lgtype) {
data = npc_get_nibbles(flow, 1, offset);
- fprintf(file, "\tNPC_PARSE_NIBBLE_LG_LTYPE:%s\n",
- ltype_str[NPC_LID_LG][data]);
+ fprintf(file, "\tNPC_PARSE_NIBBLE_LG_LTYPE:%s\n", ltype_str[NPC_LID_LG][data]);
offset += 4;
}
@@ -311,15 +458,14 @@ npc_flow_print_parse_nibbles(FILE *file, struct roc_npc_flow *flow,
if (rx_parse->lhtype) {
data = npc_get_nibbles(flow, 1, offset);
- fprintf(file, "\tNPC_PARSE_NIBBLE_LH_LTYPE:%s\n",
- ltype_str[NPC_LID_LH][data]);
+ fprintf(file, "\tNPC_PARSE_NIBBLE_LH_LTYPE:%s\n", ltype_str[NPC_LID_LH][data]);
offset += 4;
}
}
static void
-npc_flow_print_xtractinfo(FILE *file, struct npc_xtract_info *lfinfo,
- struct roc_npc_flow *flow, int lid, int lt)
+npc_flow_print_xtractinfo(FILE *file, struct npc_xtract_info *lfinfo, struct roc_npc_flow *flow,
+ int lid, int lt)
{
uint8_t *datastart, *maskstart;
int i;
@@ -374,6 +520,7 @@ static void
npc_flow_dump_patterns(FILE *file, struct npc *npc, struct roc_npc_flow *flow)
{
struct npc_lid_lt_xtract_info *lt_xinfo;
+ struct npc_lid_lt_xtract_info_cn20k *lt_xinfo_cn20k;
struct npc_xtract_info *xinfo;
uint32_t intf, lid, ld, i;
uint64_t parse_nibbles;
@@ -381,19 +528,37 @@ npc_flow_dump_patterns(FILE *file, struct npc *npc, struct roc_npc_flow *flow)
intf = flow->nix_intf;
parse_nibbles = npc->keyx_supp_nmask[intf];
- npc_flow_print_parse_nibbles(file, flow, parse_nibbles);
-
- for (i = 0; i < flow->num_patterns; i++) {
- lid = flow->dump_data[i].lid;
- ltype = flow->dump_data[i].ltype;
- lt_xinfo = &npc->prx_dxcfg[intf][lid][ltype];
-
- for (ld = 0; ld < NPC_MAX_LD; ld++) {
- xinfo = <_xinfo->xtract[ld];
- if (!xinfo->enable)
- continue;
- npc_flow_print_item(file, npc, xinfo, flow, intf, lid,
- ltype, ld);
+ if (roc_model_is_cn20k()) {
+ npc_flow_print_parse_nibbles_cn20k(file, flow, parse_nibbles);
+ for (i = 0; i < flow->num_patterns; i++) {
+ lid = flow->dump_data[i].lid;
+ ltype = flow->dump_data[i].ltype;
+ for (int j = 0; j < NPC_MAX_EXTRACTOR; j++) {
+ union npc_kex_ldata_flags_cfg *lid_info =
+ &npc->lid_cfg[NIX_INTF_RX][j];
+ if (lid_info->s.lid != lid)
+ continue;
+ lt_xinfo_cn20k = &npc->prx_dxcfg_cn20k[intf][j][ltype];
+ xinfo = <_xinfo_cn20k->xtract;
+ if (!xinfo->enable)
+ continue;
+ npc_flow_print_item(file, npc, xinfo, flow, intf, lid, ltype, j);
+ }
+ }
+ } else {
+ npc_flow_print_parse_nibbles_legacy(file, flow, parse_nibbles);
+
+ for (i = 0; i < flow->num_patterns; i++) {
+ lid = flow->dump_data[i].lid;
+ ltype = flow->dump_data[i].ltype;
+ lt_xinfo = &npc->prx_dxcfg[intf][lid][ltype];
+
+ for (ld = 0; ld < NPC_MAX_LD; ld++) {
+ xinfo = <_xinfo->xtract[ld];
+ if (!xinfo->enable)
+ continue;
+ npc_flow_print_item(file, npc, xinfo, flow, intf, lid, ltype, ld);
+ }
}
}
}
@@ -645,7 +810,6 @@ npc_flow_hw_mcam_entry_dump(FILE *file, struct npc *npc, struct roc_npc_flow *fl
uint64_t mcam_data[ROC_NPC_MAX_MCAM_WIDTH_DWORDS];
uint64_t mcam_mask[ROC_NPC_MAX_MCAM_WIDTH_DWORDS];
struct npc_mcam_read_entry_req *mcam_read_req;
- struct npc_mcam_read_entry_rsp *mcam_read_rsp;
struct nix_inl_dev *inl_dev = NULL;
struct idev_cfg *idev;
struct mbox *mbox;
@@ -669,17 +833,34 @@ npc_flow_hw_mcam_entry_dump(FILE *file, struct npc *npc, struct roc_npc_flow *fl
}
mcam_read_req->entry = flow->mcam_id;
- rc = mbox_process_msg(mbox, (void *)&mcam_read_rsp);
- if (rc) {
- mbox_put(mbox);
- plt_err("Failed to fetch MCAM entry:%d", flow->mcam_id);
- return;
- }
- mbox_memcpy(mcam_data, mcam_read_rsp->entry_data.kw, sizeof(mcam_data));
- mbox_memcpy(mcam_mask, mcam_read_rsp->entry_data.kw_mask, sizeof(mcam_data));
- enabled = mcam_read_rsp->enable;
+ if (roc_model_is_cn20k()) {
+ struct npc_cn20k_mcam_read_entry_rsp *mcam_read_rsp;
+
+ rc = mbox_process_msg(mbox, (void *)&mcam_read_rsp);
+ if (rc) {
+ mbox_put(mbox);
+ plt_err("Failed to fetch MCAM entry:%d", flow->mcam_id);
+ return;
+ }
+
+ mbox_memcpy(mcam_data, mcam_read_rsp->entry_data.kw, sizeof(mcam_data));
+ mbox_memcpy(mcam_mask, mcam_read_rsp->entry_data.kw_mask, sizeof(mcam_data));
+ enabled = mcam_read_rsp->enable;
+ } else {
+ struct npc_mcam_read_entry_rsp *mcam_read_rsp;
+ rc = mbox_process_msg(mbox, (void *)&mcam_read_rsp);
+ if (rc) {
+ mbox_put(mbox);
+ plt_err("Failed to fetch MCAM entry:%d", flow->mcam_id);
+ return;
+ }
+
+ mbox_memcpy(mcam_data, mcam_read_rsp->entry_data.kw, sizeof(mcam_data));
+ mbox_memcpy(mcam_mask, mcam_read_rsp->entry_data.kw_mask, sizeof(mcam_data));
+ enabled = mcam_read_rsp->enable;
+ }
fprintf(file, "HW MCAM Data :\n");
for (i = 0; i < ROC_NPC_MAX_MCAM_WIDTH_DWORDS; i++) {
@@ -702,14 +883,18 @@ roc_npc_flow_mcam_dump(FILE *file, struct roc_npc *roc_npc, struct roc_npc_flow
fprintf(file, "MCAM Index:%d\n", flow->mcam_id);
if (flow->ctr_id != NPC_COUNTER_NONE && flow->use_ctr) {
- if (flow->use_pre_alloc)
+ if (flow->use_pre_alloc) {
rc = roc_npc_inl_mcam_read_counter(flow->ctr_id, &count);
- else
- rc = roc_npc_mcam_read_counter(roc_npc, flow->ctr_id, &count);
+ } else {
+ if (roc_model_is_cn20k())
+ rc = roc_npc_mcam_get_stats(roc_npc, flow, &count);
+ else
+ rc = roc_npc_mcam_read_counter(roc_npc, flow->ctr_id, &count);
+ }
if (rc)
return;
- fprintf(file, "Hit count: %" PRIu64 "\n", count);
+ fprintf(file, "Counter_id = 0x%x, Hit count: %" PRIu64 "\n", flow->ctr_id, count);
}
fprintf(file, "Interface :%s (%d)\n", intf_str[flow->nix_intf], flow->nix_intf);
diff --git a/drivers/common/cnxk/roc_npc_priv.h b/drivers/common/cnxk/roc_npc_priv.h
index e08a34d146..b7d726caa1 100644
--- a/drivers/common/cnxk/roc_npc_priv.h
+++ b/drivers/common/cnxk/roc_npc_priv.h
@@ -30,6 +30,10 @@
((((lid) - (NPC_LID_LA)) * NPC_LAYER_KEYX_SZ) + \
NPC_PARSE_KEX_S_LA_OFFSET)
+#define NPC_LAYER_KEYX_SZ_CN20K (2)
+#define NPC_PARSE_KEX_S_LID_OFFSET_CN20K(lid) \
+ ((((lid) - (NPC_LID_LA)) * NPC_LAYER_KEYX_SZ_CN20K) + NPC_PARSE_KEX_S_LA_OFFSET)
+
/* This mark value indicates flag action */
#define NPC_FLOW_FLAG_VAL (0xffff)
@@ -43,7 +47,11 @@
#define NPC_MCAM_KEX_FIELD_MAX 23
#define NPC_MCAM_MAX_PROTO_FIELDS (NPC_MCAM_KEX_FIELD_MAX + 1)
-#define NPC_MCAM_KEY_X4_WORDS 7 /* Number of 64-bit words */
+#if defined(ROC_PLATFORM_CN20K)
+#define NPC_MCAM_KEY_X4_WORDS 8 /* Number of 64-bit words */
+#else
+#define NPC_MCAM_KEY_X4_WORDS 7 /* Number of 64-bit words */
+#endif
#define NPC_RVUPF_MAX_9XXX 0x10 /* HRM: RVU_PRIV_CONST */
#define NPC_RVUPF_MAX_98XX 0x18 /* HRM: RVU_PRIV_CONST */
@@ -77,6 +85,16 @@
#define NPC_LFLAG_LC_OFFSET (NPC_LTYPE_OFFSET_START + 6)
#define NPC_LTYPE_LC_OFFSET (NPC_LTYPE_OFFSET_START + 8)
+/* LB OFFSET : START + LA (1b flags + 1b ltype) + LB (1b flags) */
+#define NPC_CN20K_LTYPE_LB_OFFSET (NPC_LTYPE_OFFSET_START + 3)
+#define NPC_CN20K_LFLAG_LB_OFFSET (NPC_LTYPE_OFFSET_START + 2)
+
+/* LC OFFSET : START + LA (1b flags + 1b ltype) + LB (1b flags + 1b ltype) + LC
+ * (1b flags)
+ */
+#define NPC_CN20K_LFLAG_LC_OFFSET (NPC_LTYPE_OFFSET_START + 4)
+#define NPC_CN20K_LTYPE_LC_OFFSET (NPC_LTYPE_OFFSET_START + 5)
+
#define CN10K_SDP_CH_START 0x80
#define CN10K_SDP_CH_MASK 0xF80
@@ -176,9 +194,9 @@ struct npc_parse_item_info {
const void *def_mask; /* default mask */
void *hw_mask; /* hardware supported mask */
int len; /* length of item */
+ uint8_t hw_hdr_len; /* Extra data len at each layer*/
const void *spec; /* spec to use, NULL implies match any */
const void *mask; /* mask to use */
- uint8_t hw_hdr_len; /* Extra data len at each layer*/
};
struct npc_parse_state {
@@ -192,16 +210,16 @@ struct npc_parse_state {
uint8_t layer_mask;
uint8_t lt[NPC_MAX_LID];
uint8_t flags[NPC_MAX_LID];
+ bool has_eth_type;
+ bool is_second_pass_rule;
+ bool set_ipv6ext_ltype_mask;
+ /* adjust ltype in MCAM to match at least one vlan */
+ bool set_vlan_ltype_mask;
uint8_t *mcam_data; /* point to flow->mcam_data + key_len */
uint8_t *mcam_mask; /* point to flow->mcam_mask + key_len */
bool is_vf;
- /* adjust ltype in MCAM to match at least one vlan */
- bool set_vlan_ltype_mask;
- bool set_ipv6ext_ltype_mask;
- bool is_second_pass_rule;
- bool has_eth_type;
- uint16_t nb_tx_queues;
uint16_t dst_pf_func;
+ uint16_t nb_tx_queues;
};
enum npc_kpu_parser_flag {
@@ -340,6 +358,14 @@ struct npc_lid_lt_xtract_info {
struct npc_xtract_info xtract[NPC_MAX_LD];
};
+struct npc_lid_lt_xtract_info_cn20k {
+ /* Info derived from parser configuration */
+ uint16_t npc_proto; /* Network protocol identified */
+ uint8_t valid_flags_mask; /* Flags applicable */
+ uint8_t is_terminating : 1; /* No more parsing */
+ struct npc_xtract_info xtract;
+};
+
union npc_kex_ldata_flags_cfg {
struct {
uint64_t lid : 3;
@@ -349,6 +375,11 @@ union npc_kex_ldata_flags_cfg {
uint64_t i;
};
+#define NPC_MAX_EXTRACTTORS 24
+typedef struct npc_lid_lt_xtract_info_cn20k npc_dxcfg_cn20k_t[NPC_MAX_INTF][NPC_MAX_EXTRACTTORS]
+ [NPC_MAX_LT];
+typedef union npc_kex_ldata_flags_cfg npc_lid_cn20k_t[NPC_MAX_INTF][NPC_MAX_EXTRACTTORS];
+
typedef struct npc_lid_lt_xtract_info npc_dxcfg_t[NPC_MAX_INTF][NPC_MAX_LID]
[NPC_MAX_LT];
typedef struct npc_lid_lt_xtract_info npc_fxcfg_t[NPC_MAX_INTF][NPC_MAX_LD]
@@ -387,33 +418,36 @@ TAILQ_HEAD(npc_age_flow_list_head, npc_age_flow_entry);
struct npc {
struct mbox *mbox; /* Mbox */
- uint32_t keyx_supp_nmask[NPC_MAX_INTF]; /* nibble mask */
+ uint64_t keyx_supp_nmask[NPC_MAX_INTF]; /* nibble mask */
uint8_t hash_extract_cap; /* hash extract support */
uint8_t profile_name[MKEX_NAME_LEN]; /* KEX profile name */
- uint32_t keyx_len[NPC_MAX_INTF]; /* per intf key len in bits */
- uint32_t datax_len[NPC_MAX_INTF]; /* per intf data len in bits */
- uint32_t keyw[NPC_MAX_INTF]; /* max key + data len bits */
- uint32_t mcam_entries; /* mcam entries supported */
- uint16_t channel; /* RX Channel number */
bool is_sdp_link;
+ uint16_t channel; /* RX Channel number */
+ uint32_t keyx_len[NPC_MAX_INTF]; /* per intf key len in bits */
+ uint32_t datax_len[NPC_MAX_INTF]; /* per intf data len in bits */
+ uint32_t keyw[NPC_MAX_INTF]; /* max key + data len bits */
+ uint32_t mcam_entries; /* mcam entries supported */
+ uint16_t switch_header_type; /* Supported switch header type */
+ uint16_t flow_max_priority; /* Max priority for flow */
uint16_t sdp_channel;
uint16_t sdp_channel_mask;
- uint32_t rss_grps; /* rss groups supported */
- uint16_t flow_prealloc_size; /* Pre allocated mcam size */
- uint16_t flow_max_priority; /* Max priority for flow */
- uint16_t switch_header_type; /* Supported switch header type */
+ uint32_t rss_grps; /* rss groups supported */
+ uint16_t flow_prealloc_size; /* Pre allocated mcam size */
+ uint8_t exact_match_ena;
+ uint16_t pf_func; /* pf_func of device */
uint32_t mark_actions;
- uint32_t vtag_strip_actions; /* vtag insert/strip actions */
- uint16_t pf_func; /* pf_func of device */
- npc_dxcfg_t prx_dxcfg; /* intf, lid, lt, extract */
- npc_fxcfg_t prx_fxcfg; /* Flag extract */
- npc_ld_flags_t prx_lfcfg; /* KEX LD_Flags CFG */
+ uint32_t vtag_strip_actions; /* vtag insert/strip actions */
+ npc_dxcfg_t prx_dxcfg; /* intf, lid, lt, extract */
+ npc_dxcfg_cn20k_t prx_dxcfg_cn20k; /* intf, ext, lt, extract */
+ npc_lid_cn20k_t lid_cfg; /* KEX LD_Flags CFG */
+ npc_fxcfg_t prx_fxcfg; /* Flag extract */
+ npc_ld_flags_t prx_lfcfg; /* KEX LD_Flags CFG */
struct npc_flow_list *flow_list;
struct npc_prio_flow_list_head *prio_flow_list;
struct npc_age_flow_list_head age_flow_list;
struct plt_bitmap *rss_grp_entries;
struct npc_flow_list ipsec_list;
- uint8_t exact_match_ena;
+ uint8_t enable_debug;
};
#define NPC_HASH_FIELD_LEN 16
@@ -432,6 +466,7 @@ roc_npc_to_npc_priv(struct roc_npc *npc)
return (struct npc *)npc->reserved;
}
+int npc_mcam_get_stats(struct mbox *mbox, struct roc_npc_flow *flow, uint64_t *count);
int npc_mcam_alloc_counter(struct mbox *mbox, uint16_t *ctr);
int npc_mcam_free_counter(struct mbox *mbox, uint16_t ctr_id);
int npc_mcam_read_counter(struct mbox *mbox, uint32_t ctr_id, uint64_t *count);
@@ -440,9 +475,10 @@ int npc_mcam_free_entry(struct mbox *mbox, uint32_t entry);
int npc_mcam_free_all_entries(struct npc *npc);
int npc_mcam_alloc_and_write(struct npc *npc, struct roc_npc_flow *flow,
struct npc_parse_state *pst);
-int npc_mcam_alloc_entry(struct npc *npc, struct roc_npc_flow *mcam,
- struct roc_npc_flow *ref_mcam, int prio,
- int *resp_count);
+int npc_mcam_alloc_entry(struct npc *npc, struct roc_npc_flow *mcam, struct roc_npc_flow *ref_mcam,
+ uint8_t prio, int *resp_count);
+int npc_mcam_alloc_entry_cn20k(struct npc *npc, struct roc_npc_flow *mcam, int *resp_count);
+
int npc_mcam_alloc_entries(struct mbox *mbox, int ref_mcam, int *alloc_entry, int req_count,
int prio, int *resp_count, bool is_conti);
@@ -453,6 +489,7 @@ int npc_update_parse_state(struct npc_parse_state *pst, struct npc_parse_item_in
int lt, uint8_t flags);
void npc_get_hw_supp_mask(struct npc_parse_state *pst, struct npc_parse_item_info *info, int lid,
int lt);
+uint8_t npc_get_key_type(struct npc *npc, struct roc_npc_flow *flow);
int npc_mask_is_supported(const char *mask, const char *hw_mask, int len);
int npc_parse_item_basic(const struct roc_npc_item_info *item, struct npc_parse_item_info *info);
int npc_parse_meta_items(struct npc_parse_state *pst);
diff --git a/drivers/common/cnxk/roc_npc_utils.c b/drivers/common/cnxk/roc_npc_utils.c
index a507df994f..75d3b0702c 100644
--- a/drivers/common/cnxk/roc_npc_utils.c
+++ b/drivers/common/cnxk/roc_npc_utils.c
@@ -4,6 +4,36 @@
#include "roc_api.h"
#include "roc_priv.h"
+enum npc_mcam_cn20k_key_width {
+ NPC_CN20K_MCAM_KEY_X1 = 0,
+ NPC_CN20K_MCAM_KEY_DYN = NPC_CN20K_MCAM_KEY_X1,
+ NPC_CN20K_MCAM_KEY_X2,
+ NPC_CN20K_MCAM_KEY_X4,
+ NPC_CN20K_MCAM_KEY_MAX,
+};
+
+uint8_t
+npc_get_key_type(struct npc *npc, struct roc_npc_flow *flow)
+{
+ int i;
+
+ /* KEX is configured just for X2 */
+ if (npc->keyw[ROC_NPC_INTF_RX] == 1)
+ return NPC_CN20K_MCAM_KEY_X2;
+
+ /* KEX is configured just for X4 */
+ if (npc->keyw[ROC_NPC_INTF_RX] == 2)
+ return NPC_CN20K_MCAM_KEY_X4;
+
+ /* KEX is configured for both X2 and X4 */
+ /* Check mask for upper 256 bits. if mask is set, then it is X4 entry */
+ for (i = 4; i < ROC_NPC_MAX_MCAM_WIDTH_DWORDS; i++) {
+ if (flow->mcam_mask[i] != 0)
+ return NPC_CN20K_MCAM_KEY_X4;
+ }
+ return NPC_CN20K_MCAM_KEY_X2;
+}
+
static void
npc_prep_mcam_ldata(uint8_t *ptr, const uint8_t *data, int len)
{
@@ -67,8 +97,9 @@ npc_ipv6_hash_mask_get(struct npc_xtract_info *xinfo, struct npc_parse_item_info
memset(&hw_mask[offset], 0xFF, NPC_HASH_FIELD_LEN);
}
-void
-npc_get_hw_supp_mask(struct npc_parse_state *pst, struct npc_parse_item_info *info, int lid, int lt)
+static void
+npc_get_hw_supp_mask_legacy(struct npc_parse_state *pst, struct npc_parse_item_info *info, int lid,
+ int lt)
{
struct npc_xtract_info *xinfo, *lfinfo;
char *hw_mask = info->hw_mask;
@@ -101,6 +132,40 @@ npc_get_hw_supp_mask(struct npc_parse_state *pst, struct npc_parse_item_info *in
}
}
+static void
+npc_get_hw_supp_mask_o20k(struct npc_parse_state *pst, struct npc_parse_item_info *info, int lid,
+ int lt)
+{
+ struct npc_xtract_info *xinfo;
+ union npc_kex_ldata_flags_cfg *lid_info;
+ char *hw_mask = info->hw_mask;
+ int ex;
+ int intf;
+
+ intf = pst->nix_intf;
+ memset(hw_mask, 0, info->len);
+ for (ex = 0; ex < NPC_MAX_EXTRACTTORS; ex++) {
+ lid_info = &pst->npc->lid_cfg[intf][ex];
+ if (lid_info->s.lid != lid)
+ continue;
+ xinfo = &pst->npc->prx_dxcfg_cn20k[intf][ex][lt].xtract;
+
+ if (pst->npc->hash_extract_cap && xinfo->use_hash)
+ npc_ipv6_hash_mask_get(xinfo, info);
+ else
+ npc_set_hw_mask(info, xinfo, hw_mask);
+ }
+}
+
+void
+npc_get_hw_supp_mask(struct npc_parse_state *pst, struct npc_parse_item_info *info, int lid, int lt)
+{
+ if (!roc_model_is_cn20k())
+ return npc_get_hw_supp_mask_legacy(pst, info, lid, lt);
+ else
+ return npc_get_hw_supp_mask_o20k(pst, info, lid, lt);
+}
+
inline int
npc_mask_is_supported(const char *mask, const char *hw_mask, int len)
{
@@ -381,10 +446,10 @@ npc_hash_field_get(struct npc_xtract_info *xinfo, const struct roc_npc_flow_item
return 1;
}
-int
-npc_process_ipv6_field_hash(const struct roc_npc_flow_item_ipv6 *ipv6_spec,
- const struct roc_npc_flow_item_ipv6 *ipv6_mask,
- struct npc_parse_state *pst, uint8_t ltype)
+static int
+npc_process_ipv6_field_hash_legacy(const struct roc_npc_flow_item_ipv6 *ipv6_spec,
+ const struct roc_npc_flow_item_ipv6 *ipv6_mask,
+ struct npc_parse_state *pst, uint8_t ltype)
{
struct npc_lid_lt_xtract_info *lid_lt_xinfo;
uint8_t hash_field[ROC_IPV6_ADDR_LEN];
@@ -421,9 +486,64 @@ npc_process_ipv6_field_hash(const struct roc_npc_flow_item_ipv6 *ipv6_spec,
return 0;
}
+static int
+npc_process_ipv6_field_hash_o20k(const struct roc_npc_flow_item_ipv6 *ipv6_spec,
+ const struct roc_npc_flow_item_ipv6 *ipv6_mask,
+ struct npc_parse_state *pst, uint8_t ltype)
+{
+ struct npc_lid_lt_xtract_info_cn20k *lid_lt_xinfo;
+ union npc_kex_ldata_flags_cfg *lid_cfg;
+ uint8_t hash_field[ROC_IPV6_ADDR_LEN];
+ struct npc_xtract_info *xinfo;
+ struct roc_ipv6_hdr ipv6_buf;
+ uint32_t hash = 0, mask;
+ int intf, i, rc = 0;
+
+ memset(&ipv6_buf, 0, sizeof(ipv6_buf));
+ memset(hash_field, 0, sizeof(hash_field));
+
+ intf = pst->nix_intf;
+ for (i = 0; i < NPC_MAX_EXTRACTTORS; i++) {
+ lid_cfg = &pst->npc->lid_cfg[intf][i];
+ if (lid_cfg->s.lid != NPC_LID_LC)
+ continue;
+ lid_lt_xinfo = &pst->npc->prx_dxcfg_cn20k[intf][NPC_LID_LC][ltype];
+
+ xinfo = &lid_lt_xinfo->xtract;
+ if (!xinfo->use_hash)
+ continue;
+
+ rc = npc_hash_field_get(xinfo, ipv6_spec, ipv6_mask, hash_field);
+ if (rc == 0)
+ continue;
+
+ rc = npc_ipv6_field_hash_get(pst->npc, (const uint32_t *)hash_field, intf, i,
+ &hash);
+ if (rc)
+ return rc;
+
+ mask = GENMASK(31, 0);
+ memcpy(pst->mcam_mask + xinfo->key_off, (uint8_t *)&mask, 4);
+ memcpy(pst->mcam_data + xinfo->key_off, (uint8_t *)&hash, 4);
+ }
+
+ return 0;
+}
+
int
-npc_update_parse_state(struct npc_parse_state *pst, struct npc_parse_item_info *info, int lid,
- int lt, uint8_t flags)
+npc_process_ipv6_field_hash(const struct roc_npc_flow_item_ipv6 *ipv6_spec,
+ const struct roc_npc_flow_item_ipv6 *ipv6_mask,
+ struct npc_parse_state *pst, uint8_t ltype)
+{
+ if (!roc_model_is_cn20k())
+ return npc_process_ipv6_field_hash_legacy(ipv6_spec, ipv6_mask, pst, ltype);
+ else
+ return npc_process_ipv6_field_hash_o20k(ipv6_spec, ipv6_mask, pst, ltype);
+}
+
+static int
+npc_update_parse_state_legacy(struct npc_parse_state *pst, struct npc_parse_item_info *info,
+ int lid, int lt, uint8_t flags)
{
struct npc_lid_lt_xtract_info *xinfo;
struct roc_npc_flow_dump_data *dump;
@@ -461,8 +581,7 @@ npc_update_parse_state(struct npc_parse_state *pst, struct npc_parse_item_info *
if (lf_cfg == lid) {
for (j = 0; j < NPC_MAX_LFL; j++) {
lfinfo = pst->npc->prx_fxcfg[intf][i][j].xtract;
- rc = npc_update_extraction_data(pst, info,
- &lfinfo[0]);
+ rc = npc_update_extraction_data(pst, info, &lfinfo[0]);
if (rc != 0)
return rc;
@@ -480,42 +599,127 @@ npc_update_parse_state(struct npc_parse_state *pst, struct npc_parse_item_info *
return 0;
}
+static int
+npc_update_parse_state_o20(struct npc_parse_state *pst, struct npc_parse_item_info *info, int lid,
+ int lt, uint8_t flags)
+{
+ struct npc_lid_lt_xtract_info_cn20k *xinfo;
+ union npc_kex_ldata_flags_cfg *lid_cfg;
+ struct roc_npc_flow_dump_data *dump;
+ int intf;
+ int i, rc = 0;
+
+ pst->layer_mask |= lid;
+ pst->lt[lid] = lt;
+ pst->flags[lid] = flags;
+
+ intf = pst->nix_intf;
+ if (info->spec == NULL)
+ goto done;
+
+ for (i = 0; i < NPC_MAX_EXTRACTTORS; i++) {
+ lid_cfg = &pst->npc->lid_cfg[intf][i];
+ if (lid_cfg->s.lid != lid)
+ continue;
+ xinfo = &pst->npc->prx_dxcfg_cn20k[intf][i][lt];
+ if (xinfo->is_terminating)
+ pst->terminate = 1;
+
+ if (xinfo->xtract.use_hash)
+ continue;
+ rc = npc_update_extraction_data(pst, info, &xinfo->xtract);
+ if (rc != 0)
+ return rc;
+ }
+
+done:
+ dump = &pst->flow->dump_data[pst->flow->num_patterns++];
+ dump->lid = lid;
+ dump->ltype = lt;
+ pst->pattern++;
+ return 0;
+}
+
+int
+npc_update_parse_state(struct npc_parse_state *pst, struct npc_parse_item_info *info, int lid,
+ int lt, uint8_t flags)
+{
+ if (roc_model_is_cn20k())
+ return npc_update_parse_state_o20(pst, info, lid, lt, flags);
+ else
+ return npc_update_parse_state_legacy(pst, info, lid, lt, flags);
+}
+
int
npc_mcam_init(struct npc *npc, struct roc_npc_flow *flow, int mcam_id)
{
- struct npc_mcam_write_entry_req *req;
- struct npc_mcam_write_entry_rsq *rsp;
+ struct msg_rsp *rsp;
struct mbox *mbox = mbox_get(npc->mbox);
int rc = 0, idx;
- req = mbox_alloc_msg_npc_mcam_write_entry(mbox);
- if (req == NULL) {
- rc = -ENOSPC;
- goto exit;
- }
- req->set_cntr = 0;
- req->cntr = 0;
- req->entry = mcam_id;
-
- req->intf = (flow->nix_intf == NIX_INTF_RX) ? NPC_MCAM_RX : NPC_MCAM_TX;
- req->enable_entry = 1;
- req->entry_data.action = flow->npc_action;
- req->entry_data.vtag_action = flow->vtag_action;
-
- for (idx = 0; idx < ROC_NPC_MAX_MCAM_WIDTH_DWORDS; idx++) {
- req->entry_data.kw[idx] = 0x0;
- req->entry_data.kw_mask[idx] = 0x0;
- }
+ if (roc_model_is_cn20k()) {
+ struct npc_cn20k_mcam_write_entry_req *req;
+
+ req = mbox_alloc_msg_npc_cn20k_mcam_write_entry(mbox);
+ if (req == NULL) {
+ rc = -ENOSPC;
+ goto exit;
+ }
+ req->cntr = 0;
+ req->entry = mcam_id;
+
+ req->intf = (flow->nix_intf == NIX_INTF_RX) ? NPC_MCAM_RX : NPC_MCAM_TX;
+ req->enable_entry = 1;
+ req->entry_data.action = flow->npc_action;
+ req->entry_data.vtag_action = flow->vtag_action;
+
+ for (idx = 0; idx < ROC_NPC_MAX_MCAM_WIDTH_DWORDS; idx++) {
+ req->entry_data.kw[idx] = 0x0;
+ req->entry_data.kw_mask[idx] = 0x0;
+ }
+
+ if (flow->nix_intf == NIX_INTF_RX) {
+ req->entry_data.kw[0] |= (uint64_t)npc->channel;
+ req->entry_data.kw_mask[0] |= (BIT_ULL(12) - 1);
+ } else {
+ uint16_t pf_func = (flow->npc_action >> 4) & 0xffff;
- if (flow->nix_intf == NIX_INTF_RX) {
- req->entry_data.kw[0] |= (uint64_t)npc->channel;
- req->entry_data.kw_mask[0] |= (BIT_ULL(12) - 1);
+ pf_func = plt_cpu_to_be_16(pf_func);
+ req->entry_data.kw[0] |= ((uint64_t)pf_func << 32);
+ req->entry_data.kw_mask[0] |= ((uint64_t)0xffff << 32);
+ }
} else {
- uint16_t pf_func = (flow->npc_action >> 4) & 0xffff;
+ struct npc_mcam_write_entry_req *req;
+
+ req = mbox_alloc_msg_npc_mcam_write_entry(mbox);
+ if (req == NULL) {
+ rc = -ENOSPC;
+ goto exit;
+ }
+ req->set_cntr = 0;
+ req->cntr = 0;
+ req->entry = mcam_id;
+
+ req->intf = (flow->nix_intf == NIX_INTF_RX) ? NPC_MCAM_RX : NPC_MCAM_TX;
+ req->enable_entry = 1;
+ req->entry_data.action = flow->npc_action;
+ req->entry_data.vtag_action = flow->vtag_action;
+
+ for (idx = 0; idx < ROC_NPC_MAX_MCAM_WIDTH_DWORDS; idx++) {
+ req->entry_data.kw[idx] = 0x0;
+ req->entry_data.kw_mask[idx] = 0x0;
+ }
+
+ if (flow->nix_intf == NIX_INTF_RX) {
+ req->entry_data.kw[0] |= (uint64_t)npc->channel;
+ req->entry_data.kw_mask[0] |= (BIT_ULL(12) - 1);
+ } else {
+ uint16_t pf_func = (flow->npc_action >> 4) & 0xffff;
- pf_func = plt_cpu_to_be_16(pf_func);
- req->entry_data.kw[0] |= ((uint64_t)pf_func << 32);
- req->entry_data.kw_mask[0] |= ((uint64_t)0xffff << 32);
+ pf_func = plt_cpu_to_be_16(pf_func);
+ req->entry_data.kw[0] |= ((uint64_t)pf_func << 32);
+ req->entry_data.kw_mask[0] |= ((uint64_t)0xffff << 32);
+ }
}
rc = mbox_process_msg(mbox, (void *)&rsp);
@@ -783,13 +987,12 @@ npc_insert_into_flow_list(struct npc *npc, struct npc_prio_flow_entry *entry)
}
static int
-npc_allocate_mcam_entry(struct mbox *mbox, int prio,
- struct npc_mcam_alloc_entry_rsp *rsp_local,
- int ref_entry)
+npc_allocate_mcam_entry(struct mbox *mbox, int prio, struct npc_mcam_alloc_entry_rsp *rsp_local,
+ int ref_entry, uint8_t kw_type)
{
- struct npc_mcam_alloc_entry_rsp *rsp_cmd;
- struct npc_mcam_alloc_entry_req *req;
struct npc_mcam_alloc_entry_rsp *rsp;
+ struct npc_mcam_alloc_entry_req *req;
+
int rc = -ENOSPC;
req = mbox_alloc_msg_npc_mcam_alloc_entry(mbox_get(mbox));
@@ -797,20 +1000,20 @@ npc_allocate_mcam_entry(struct mbox *mbox, int prio,
goto exit;
req->contig = 1;
req->count = 1;
- req->priority = prio;
+ req->ref_priority = prio;
req->ref_entry = ref_entry;
+ req->kw_type = kw_type;
- rc = mbox_process_msg(mbox, (void *)&rsp_cmd);
+ rc = mbox_process_msg(mbox, (void *)&rsp);
if (rc)
goto exit;
- if (!rsp_cmd->count) {
+ if (!rsp->count) {
rc = -ENOSPC;
goto exit;
}
- mbox_memcpy(rsp_local, rsp_cmd, sizeof(*rsp));
-
+ mbox_memcpy(rsp_local, rsp, sizeof(*rsp));
rc = 0;
exit:
mbox_put(mbox);
@@ -854,8 +1057,7 @@ npc_find_mcam_ref_entry(struct roc_npc_flow *flow, struct npc *npc, int *prio,
}
static int
-npc_alloc_mcam_by_ref_entry(struct mbox *mbox, struct roc_npc_flow *flow,
- struct npc *npc,
+npc_alloc_mcam_by_ref_entry(struct mbox *mbox, struct roc_npc_flow *flow, struct npc *npc,
struct npc_mcam_alloc_entry_rsp *rsp_local)
{
int prio, ref_entry = 0, rc = 0, dir = NPC_MCAM_LOWER_PRIO;
@@ -863,7 +1065,7 @@ npc_alloc_mcam_by_ref_entry(struct mbox *mbox, struct roc_npc_flow *flow,
retry:
npc_find_mcam_ref_entry(flow, npc, &prio, &ref_entry, dir);
- rc = npc_allocate_mcam_entry(mbox, prio, rsp_local, ref_entry);
+ rc = npc_allocate_mcam_entry(mbox, prio, rsp_local, ref_entry, flow->key_type);
if (rc && !retry_done) {
plt_npc_dbg(
"npc: Failed to allocate lower priority entry. Retrying for higher priority");
@@ -879,32 +1081,42 @@ npc_alloc_mcam_by_ref_entry(struct mbox *mbox, struct roc_npc_flow *flow,
}
int
-npc_get_free_mcam_entry(struct mbox *mbox, struct roc_npc_flow *flow,
- struct npc *npc)
+npc_get_free_mcam_entry(struct mbox *mbox, struct roc_npc_flow *flow, struct npc *npc)
{
struct npc_mcam_alloc_entry_rsp rsp_local;
struct npc_prio_flow_entry *new_entry;
int rc = 0;
- rc = npc_alloc_mcam_by_ref_entry(mbox, flow, npc, &rsp_local);
-
- if (rc)
- return rc;
-
new_entry = plt_zmalloc(sizeof(*new_entry), 0);
if (!new_entry)
return -ENOSPC;
- new_entry->flow = flow;
+ if (roc_model_is_cn20k()) {
+ rc = npc_allocate_mcam_entry(mbox, NPC_MCAM_ANY_PRIO, &rsp_local, 0,
+ flow->key_type);
+ if (rc) {
+ plt_npc_dbg("npc: failed to allocate MCAM entry.");
+ return rc;
+ }
+
+ new_entry->flow = flow;
+ } else {
+ rc = npc_alloc_mcam_by_ref_entry(mbox, flow, npc, &rsp_local);
- plt_npc_dbg("kernel allocated MCAM entry %d", rsp_local.entry);
+ if (rc)
+ return rc;
- rc = npc_sort_mcams_by_user_prio_level(mbox, new_entry, npc,
- &rsp_local);
- if (rc)
- goto err;
+ new_entry->flow = flow;
+
+ plt_npc_dbg("kernel allocated MCAM entry %d", rsp_local.entry);
+
+ rc = npc_sort_mcams_by_user_prio_level(mbox, new_entry, npc, &rsp_local);
+ if (rc)
+ goto err;
+
+ plt_npc_dbg("allocated MCAM entry after sorting %d", rsp_local.entry);
+ }
- plt_npc_dbg("allocated MCAM entry after sorting %d", rsp_local.entry);
flow->mcam_id = rsp_local.entry;
npc_insert_into_flow_list(npc, new_entry);
diff --git a/drivers/common/cnxk/version.map b/drivers/common/cnxk/version.map
index 935be3584c..27c6e8ed0e 100644
--- a/drivers/common/cnxk/version.map
+++ b/drivers/common/cnxk/version.map
@@ -482,6 +482,7 @@ INTERNAL {
roc_npc_mcam_free_counter;
roc_npc_mcam_free;
roc_npc_mcam_free_entry;
+ roc_npc_mcam_get_stats;
roc_npc_mcam_init;
roc_npc_mcam_move;
roc_npc_mcam_merge_base_steering_rule;
--
2.39.2
^ permalink raw reply [flat|nested] 8+ messages in thread
* [dpdk-dev] [PATCH v2 2/2] net/cnxk: support rte flow on cn20k
2024-10-29 7:31 ` [dpdk-dev] [PATCH v2 1/2] common/cnxk: support NPC " psatheesh
@ 2024-10-29 7:31 ` psatheesh
2024-11-04 11:29 ` Jerin Jacob
0 siblings, 1 reply; 8+ messages in thread
From: psatheesh @ 2024-10-29 7:31 UTC (permalink / raw)
To: Nithin Dabilpuram, Kiran Kumar K, Sunil Kumar Kori, Satha Rao,
Harman Kalra
Cc: dev, Satheesh Paul
From: Satheesh Paul <psatheesh@marvell.com>
Support for rte flow in cn20k.
Signed-off-by: Satheesh Paul <psatheesh@marvell.com>
Reviewed-by: Kiran Kumar K <kirankumark@marvell.com>
---
drivers/net/cnxk/cn10k_ethdev.c | 8 +-
drivers/net/cnxk/cn10k_flow.h | 21 --
drivers/net/cnxk/cn20k_ethdev.c | 4 +
drivers/net/cnxk/cnxk_ethdev_devargs.c | 10 +-
drivers/net/cnxk/cnxk_flow.c | 10 +-
drivers/net/cnxk/cnxk_flow_wrapper.c | 303 +++++++++++++++++++++++++
drivers/net/cnxk/cnxk_flow_wrapper.h | 21 ++
drivers/net/cnxk/meson.build | 10 +-
8 files changed, 355 insertions(+), 32 deletions(-)
delete mode 100644 drivers/net/cnxk/cn10k_flow.h
create mode 100644 drivers/net/cnxk/cnxk_flow_wrapper.c
create mode 100644 drivers/net/cnxk/cnxk_flow_wrapper.h
diff --git a/drivers/net/cnxk/cn10k_ethdev.c b/drivers/net/cnxk/cn10k_ethdev.c
index fbb9b09062..a4b3d56c61 100644
--- a/drivers/net/cnxk/cn10k_ethdev.c
+++ b/drivers/net/cnxk/cn10k_ethdev.c
@@ -2,9 +2,9 @@
* Copyright(C) 2021 Marvell.
*/
#include "cn10k_ethdev.h"
-#include "cn10k_flow.h"
#include "cn10k_rx.h"
#include "cn10k_tx.h"
+#include "cnxk_flow_wrapper.h"
static uint16_t
nix_rx_offload_flags(struct rte_eth_dev *eth_dev)
@@ -913,9 +913,9 @@ npc_flow_ops_override(void)
init_once = 1;
/* Update platform specific ops */
- cnxk_flow_ops.create = cn10k_flow_create;
- cnxk_flow_ops.destroy = cn10k_flow_destroy;
- cnxk_flow_ops.info_get = cn10k_flow_info_get;
+ cnxk_flow_ops.create = cnxk_flow_create_wrapper;
+ cnxk_flow_ops.destroy = cnxk_flow_destroy_wrapper;
+ cnxk_flow_ops.info_get = cnxk_flow_info_get_wrapper;
}
static int
diff --git a/drivers/net/cnxk/cn10k_flow.h b/drivers/net/cnxk/cn10k_flow.h
deleted file mode 100644
index 316b74e6a6..0000000000
--- a/drivers/net/cnxk/cn10k_flow.h
+++ /dev/null
@@ -1,21 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(C) 2020 Marvell.
- */
-#ifndef __CN10K_RTE_FLOW_H__
-#define __CN10K_RTE_FLOW_H__
-
-#include <rte_flow_driver.h>
-
-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);
-
-int cn10k_flow_info_get(struct rte_eth_dev *dev, struct rte_flow_port_info *port_info,
- struct rte_flow_queue_info *queue_info, struct rte_flow_error *err);
-
-#define CN10K_NPC_COUNTERS_MAX 512
-
-#endif /* __CN10K_RTE_FLOW_H__ */
diff --git a/drivers/net/cnxk/cn20k_ethdev.c b/drivers/net/cnxk/cn20k_ethdev.c
index 37c372d80f..e74dd88172 100644
--- a/drivers/net/cnxk/cn20k_ethdev.c
+++ b/drivers/net/cnxk/cn20k_ethdev.c
@@ -4,6 +4,7 @@
#include "cn20k_ethdev.h"
#include "cn20k_rx.h"
#include "cn20k_tx.h"
+#include "cnxk_flow_wrapper.h"
static uint16_t
nix_rx_offload_flags(struct rte_eth_dev *eth_dev)
@@ -867,6 +868,9 @@ npc_flow_ops_override(void)
init_once = 1;
/* Update platform specific ops */
+ cnxk_flow_ops.create = cnxk_flow_create_wrapper;
+ cnxk_flow_ops.destroy = cnxk_flow_destroy_wrapper;
+ cnxk_flow_ops.info_get = cnxk_flow_info_get_wrapper;
}
static int
diff --git a/drivers/net/cnxk/cnxk_ethdev_devargs.c b/drivers/net/cnxk/cnxk_ethdev_devargs.c
index 5bd50bb9a1..bdf5d88b92 100644
--- a/drivers/net/cnxk/cnxk_ethdev_devargs.c
+++ b/drivers/net/cnxk/cnxk_ethdev_devargs.c
@@ -88,8 +88,7 @@ parse_flow_max_priority(const char *key, const char *value, void *extra_args)
val = atoi(value);
- /* Limit the max priority to 32 */
- if (val < 1 || val > 32)
+ if (val < 1 || val > ROC_NPC_MAX_MCAM_PRIORITY)
return -EINVAL;
*(uint16_t *)extra_args = val;
@@ -390,7 +389,12 @@ cnxk_ethdev_parse_devargs(struct rte_devargs *devargs, struct cnxk_eth_dev *dev)
dev->nix.meta_buf_sz = meta_buf_sz;
dev->npc.flow_prealloc_size = flow_prealloc_size;
- dev->npc.flow_max_priority = flow_max_priority;
+
+ if (roc_model_is_cn20k())
+ dev->npc.flow_max_priority = ROC_NPC_MAX_MCAM_PRIORITY;
+ else
+ dev->npc.flow_max_priority = flow_max_priority;
+
dev->npc.switch_header_type = switch_header_type;
dev->npc.sdp_channel = sdp_chan.channel;
dev->npc.sdp_channel_mask = sdp_chan.mask;
diff --git a/drivers/net/cnxk/cnxk_flow.c b/drivers/net/cnxk/cnxk_flow.c
index e42e2f8deb..4a32c11765 100644
--- a/drivers/net/cnxk/cnxk_flow.c
+++ b/drivers/net/cnxk/cnxk_flow.c
@@ -1083,10 +1083,14 @@ cnxk_flow_query_common(struct rte_eth_dev *eth_dev, struct rte_flow *flow,
npc = &rep_dev->parent_dev->npc;
}
- if (in_flow->use_pre_alloc)
+ if (in_flow->use_pre_alloc) {
rc = roc_npc_inl_mcam_read_counter(in_flow->ctr_id, &query->hits);
- else
- rc = roc_npc_mcam_read_counter(npc, in_flow->ctr_id, &query->hits);
+ } else {
+ if (roc_model_is_cn20k())
+ rc = roc_npc_mcam_get_stats(npc, in_flow, &query->hits);
+ else
+ rc = roc_npc_mcam_read_counter(npc, in_flow->ctr_id, &query->hits);
+ }
if (rc != 0) {
errcode = EIO;
errmsg = "Error reading flow counter";
diff --git a/drivers/net/cnxk/cnxk_flow_wrapper.c b/drivers/net/cnxk/cnxk_flow_wrapper.c
new file mode 100644
index 0000000000..af2eee7266
--- /dev/null
+++ b/drivers/net/cnxk/cnxk_flow_wrapper.c
@@ -0,0 +1,303 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(C) 2024 Marvell.
+ */
+
+#ifdef CNXK_PLATFORM_CN10K
+#include "cn10k_ethdev.h"
+#include "cn10k_rx.h"
+#endif
+#ifdef CNXK_PLATFORM_CN20K
+#include "cn20k_ethdev.h"
+#include "cn20k_rx.h"
+#endif
+#include "cnxk_ethdev_mcs.h"
+#include "cnxk_flow_wrapper.h"
+#include <cnxk_flow.h>
+
+static void
+cnxk_eth_set_rx_function(struct rte_eth_dev *eth_dev)
+{
+ RTE_SET_USED(eth_dev);
+#ifdef CNXK_PLATFORM_CN10K
+ cn10k_eth_set_rx_function(eth_dev);
+#endif
+#ifdef CNXK_PLATFORM_CN20K
+ cn20k_eth_set_rx_function(eth_dev);
+#endif
+}
+
+static int
+cnxk_mtr_connect(struct rte_eth_dev *eth_dev, uint32_t mtr_id)
+{
+ return nix_mtr_connect(eth_dev, mtr_id);
+}
+
+static int
+cnxk_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
+cnxk_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
+cnxk_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 *
+cnxk_flow_create_wrapper(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;
+ struct roc_npc *npc = &dev->npc;
+ struct roc_npc_flow *flow;
+ void *mcs_flow = NULL;
+ int vtag_actions = 0;
+ uint32_t req_act = 0;
+ int mark_actions;
+ 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 = cnxk_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 = cnxk_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;
+ }
+ }
+
+ if (actions[0].type == RTE_FLOW_ACTION_TYPE_SECURITY &&
+ cnxk_eth_macsec_sess_get_by_sess(dev, actions[0].conf) != NULL) {
+ rc = cnxk_mcs_flow_configure(eth_dev, attr, pattern, actions, error, &mcs_flow);
+ if (rc) {
+ rte_flow_error_set(error, rc, RTE_FLOW_ERROR_TYPE_ACTION, NULL,
+ "Failed to configure mcs flow");
+ return NULL;
+ }
+ return (struct rte_flow *)mcs_flow;
+ }
+
+ 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)
+ cnxk_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;
+ cnxk_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;
+ cnxk_eth_set_rx_function(eth_dev);
+ }
+
+ return (struct rte_flow *)flow;
+}
+
+int
+cnxk_flow_info_get_wrapper(struct rte_eth_dev *dev, struct rte_flow_port_info *port_info,
+ struct rte_flow_queue_info *queue_info, struct rte_flow_error *err)
+{
+ RTE_SET_USED(dev);
+ RTE_SET_USED(err);
+
+ memset(port_info, 0, sizeof(*port_info));
+ memset(queue_info, 0, sizeof(*queue_info));
+
+ port_info->max_nb_counters = CNXK_NPC_COUNTERS_MAX;
+ port_info->max_nb_meters = CNXK_NIX_MTR_COUNT_MAX;
+
+ return 0;
+}
+
+int
+cnxk_flow_destroy_wrapper(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);
+ struct roc_npc *npc = &dev->npc;
+ int vtag_actions = 0;
+ int mark_actions;
+ uint16_t match_id;
+ uint32_t mtr_id;
+ int rc;
+
+ match_id = (flow->npc_action >> NPC_RX_ACT_MATCH_OFFSET) & NPC_RX_ACT_MATCH_MASK;
+ if (match_id) {
+ mark_actions = roc_npc_mark_actions_sub_return(npc, 1);
+ if (mark_actions == 0) {
+ dev->rx_offload_flags &= ~NIX_RX_OFFLOAD_MARK_UPDATE_F;
+ cnxk_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;
+ cnxk_eth_set_rx_function(eth_dev);
+ }
+ }
+ }
+
+ if (cnxk_eth_macsec_sess_get_by_sess(dev, (void *)flow) != NULL) {
+ rc = cnxk_mcs_flow_destroy(dev, (void *)flow);
+ if (rc < 0)
+ rte_flow_error_set(error, rc, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
+ "Failed to free mcs flow");
+ return rc;
+ }
+
+ mtr_id = flow->mtr_id;
+ rc = cnxk_flow_destroy(eth_dev, flow, error);
+ if (!rc && mtr_id != ROC_NIX_MTR_ID_INVALID) {
+ rc = cnxk_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/cnxk_flow_wrapper.h b/drivers/net/cnxk/cnxk_flow_wrapper.h
new file mode 100644
index 0000000000..506293dd51
--- /dev/null
+++ b/drivers/net/cnxk/cnxk_flow_wrapper.h
@@ -0,0 +1,21 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(C) 2020 Marvell.
+ */
+#ifndef __CNXK_FLOW_WRAPPER_H__
+#define __CNXK_FLOW_WRAPPER_H__
+
+#include <rte_flow_driver.h>
+
+struct rte_flow *cnxk_flow_create_wrapper(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_wrapper(struct rte_eth_dev *dev, struct rte_flow *flow,
+ struct rte_flow_error *error);
+
+int cnxk_flow_info_get_wrapper(struct rte_eth_dev *dev, struct rte_flow_port_info *port_info,
+ struct rte_flow_queue_info *queue_info, struct rte_flow_error *err);
+
+#define CNXK_NPC_COUNTERS_MAX 512
+
+#endif /* __CNXK_FLOW_WRAPPER_H__ */
diff --git a/drivers/net/cnxk/meson.build b/drivers/net/cnxk/meson.build
index 32ff8aadc0..e77ceb8efc 100644
--- a/drivers/net/cnxk/meson.build
+++ b/drivers/net/cnxk/meson.build
@@ -18,6 +18,13 @@ if soc_type != 'cn9k' and soc_type != 'cn10k' and soc_type != 'cn20k'
soc_type = 'all'
endif
+if soc_type == 'cn10k' or soc_type == 'all'
+ dpdk_conf.set('CNXK_PLATFORM_CN10K', 1)
+elif soc_type == 'cn20k'
+ dpdk_conf.set('CNXK_PLATFORM_CN20K', 1)
+endif
+
+
sources = files(
'cnxk_ethdev.c',
'cnxk_ethdev_cman.c',
@@ -146,9 +153,9 @@ if soc_type == 'cn10k' or soc_type == 'all'
sources += files(
'cn10k_ethdev.c',
'cn10k_ethdev_sec.c',
- 'cn10k_flow.c',
'cn10k_rx_select.c',
'cn10k_tx_select.c',
+ 'cnxk_flow_wrapper.c',
)
if host_machine.cpu_family().startswith('aarch') and not disable_template
@@ -238,6 +245,7 @@ sources += files(
'cn20k_ethdev.c',
'cn20k_rx_select.c',
'cn20k_tx_select.c',
+ 'cnxk_flow_wrapper.c',
)
if host_machine.cpu_family().startswith('aarch') and not disable_template
--
2.39.2
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [dpdk-dev] [PATCH v2 2/2] net/cnxk: support rte flow on cn20k
2024-10-29 7:31 ` [dpdk-dev] [PATCH v2 2/2] net/cnxk: support rte " psatheesh
@ 2024-11-04 11:29 ` Jerin Jacob
0 siblings, 0 replies; 8+ messages in thread
From: Jerin Jacob @ 2024-11-04 11:29 UTC (permalink / raw)
To: psatheesh
Cc: Nithin Dabilpuram, Kiran Kumar K, Sunil Kumar Kori, Satha Rao,
Harman Kalra, dev
On Tue, Oct 29, 2024 at 1:01 PM <psatheesh@marvell.com> wrote:
>
> From: Satheesh Paul <psatheesh@marvell.com>
>
> Support for rte flow in cn20k.
>
> Signed-off-by: Satheesh Paul <psatheesh@marvell.com>
> Reviewed-by: Kiran Kumar K <kirankumark@marvell.com>
> index 0000000000..af2eee7266
> --- /dev/null
> +++ b/drivers/net/cnxk/cnxk_flow_wrapper.c
> @@ -0,0 +1,303 @@
> +/* SPDX-License-Identifier: BSD-3-Clause
> + * Copyright(C) 2024 Marvell.
> + */
> +
> +#ifdef CNXK_PLATFORM_CN10K
> +#include "cn10k_ethdev.h"
> +#include "cn10k_rx.h"
> +#endif
> +#ifdef CNXK_PLATFORM_CN20K
> +#include "cn20k_ethdev.h"
> +#include "cn20k_rx.h"
> +#endif
> +#include "cnxk_ethdev_mcs.h"
> +#include "cnxk_flow_wrapper.h"
> +#include <cnxk_flow.h>
> +
> +static void
> +cnxk_eth_set_rx_function(struct rte_eth_dev *eth_dev)
> +{
> + RTE_SET_USED(eth_dev);
> +#ifdef CNXK_PLATFORM_CN10K
> + cn10k_eth_set_rx_function(eth_dev);
> +#endif
> +#ifdef CNXK_PLATFORM_CN20K
> + cn20k_eth_set_rx_function(eth_dev);
> +#endif
Please work to remove compile time macros
^ permalink raw reply [flat|nested] 8+ messages in thread
* [dpdk-dev] [PATCH v3 1/2] common/cnxk: support NPC flow on cn20k
2024-10-21 4:01 [dpdk-dev] [PATCH 1/2] common/cnxk: support NPC flow on cn20k psatheesh
2024-10-21 4:01 ` [dpdk-dev] [PATCH 2/2] net/cnxk: support rte " psatheesh
2024-10-29 7:31 ` [dpdk-dev] [PATCH v2 1/2] common/cnxk: support NPC " psatheesh
@ 2024-11-12 9:58 ` psatheesh
2024-11-12 9:58 ` [dpdk-dev] [PATCH v3 2/2] net/cnxk: support rte " psatheesh
2 siblings, 1 reply; 8+ messages in thread
From: psatheesh @ 2024-11-12 9:58 UTC (permalink / raw)
To: Nithin Dabilpuram, Kiran Kumar K, Sunil Kumar Kori, Satha Rao,
Harman Kalra
Cc: dev, Satheesh Paul
From: Satheesh Paul <psatheesh@marvell.com>
ROC changes to support NPC flow on cn20k.
Signed-off-by: Satheesh Paul <psatheesh@marvell.com>
Reviewed-by: Kiran Kumar K <kirankumark@marvell.com>
---
v2:
* Fixed generic platform compiler error.
v3:
* Removed compile time macros.
drivers/common/cnxk/roc_mbox.h | 144 +++++-
drivers/common/cnxk/roc_nix.h | 18 +-
drivers/common/cnxk/roc_nix_mcast.c | 40 +-
drivers/common/cnxk/roc_nix_vlan.c | 66 ++-
drivers/common/cnxk/roc_npc.c | 58 ++-
drivers/common/cnxk/roc_npc.h | 59 ++-
drivers/common/cnxk/roc_npc_mcam.c | 602 +++++++++++++++++++-----
drivers/common/cnxk/roc_npc_mcam_dump.c | 279 +++++++++--
drivers/common/cnxk/roc_npc_priv.h | 91 ++--
drivers/common/cnxk/roc_npc_utils.c | 340 ++++++++++---
drivers/common/cnxk/version.map | 1 +
11 files changed, 1325 insertions(+), 373 deletions(-)
diff --git a/drivers/common/cnxk/roc_mbox.h b/drivers/common/cnxk/roc_mbox.h
index e7a916d61c..5328fd768e 100644
--- a/drivers/common/cnxk/roc_mbox.h
+++ b/drivers/common/cnxk/roc_mbox.h
@@ -236,6 +236,22 @@ struct mbox_msghdr {
npc_get_field_hash_info_req, npc_get_field_hash_info_rsp) \
M(NPC_MCAM_GET_HIT_STATUS, 0x6015, npc_mcam_get_hit_status, \
npc_mcam_get_hit_status_req, npc_mcam_get_hit_status_rsp) \
+ M(NPC_MCAM_DEFRAG, 0x6016, npc_defrag, msg_req, msg_rsp) \
+ M(NPC_CN20K_GET_KEX_CFG, 0x6017, npc_cn20k_get_kex_cfg, msg_req, \
+ npc_cn20k_get_kex_cfg_rsp) \
+ M(NPC_CN20K_MCAM_GET_FREE_COUNT, 0x6018, npc_cn20k_get_free_count, \
+ msg_req, npc_cn20k_get_free_count_rsp) \
+ M(NPC_CN20K_MCAM_WRITE_ENTRY, 0x6019, npc_cn20k_mcam_write_entry, \
+ npc_cn20k_mcam_write_entry_req, msg_rsp) \
+ M(NPC_CN20K_MCAM_ALLOC_AND_WRITE_ENTRY, 0x601a, \
+ npc_cn20k_mcam_alloc_and_write_entry, \
+ npc_cn20k_mcam_alloc_and_write_entry_req, \
+ npc_mcam_alloc_and_write_entry_rsp) \
+ M(NPC_CN20K_MCAM_READ_ENTRY, 0x601b, npc_cn20k_mcam_read_entry, \
+ npc_mcam_read_entry_req, npc_cn20k_mcam_read_entry_rsp) \
+ M(NPC_CN20K_MCAM_READ_BASE_RULE, 0x601c, \
+ npc_cn20k_read_base_steer_rule, msg_req, \
+ npc_cn20k_mcam_read_base_rule_rsp) \
/* NIX mbox IDs (range 0x8000 - 0xFFFF) */ \
M(NIX_LF_ALLOC, 0x8000, nix_lf_alloc, nix_lf_alloc_req, \
nix_lf_alloc_rsp) \
@@ -637,7 +653,7 @@ struct cgx_mac_addr_add_req {
*/
struct cgx_mac_addr_add_rsp {
struct mbox_msghdr hdr;
- uint8_t __io index;
+ uint32_t __io index;
};
/* Structure for requesting the operation to
@@ -645,7 +661,7 @@ struct cgx_mac_addr_add_rsp {
*/
struct cgx_mac_addr_del_req {
struct mbox_msghdr hdr;
- uint8_t __io index;
+ uint32_t __io index;
};
/* Structure for response against the operation to
@@ -653,7 +669,7 @@ struct cgx_mac_addr_del_req {
*/
struct cgx_max_dmac_entries_get_rsp {
struct mbox_msghdr hdr;
- uint8_t __io max_dmac_filters;
+ uint32_t __io max_dmac_filters;
};
struct cgx_link_user_info {
@@ -2433,6 +2449,14 @@ enum npc_af_status {
NPC_MCAM_ALLOC_FAILED = -703,
NPC_MCAM_PERM_DENIED = -704,
NPC_AF_ERR_HIGIG_CONFIG_FAIL = -705,
+ NPC_AF_ERR_HIGIG_NOT_SUPPORTED = -706,
+ NPC_FLOW_INTF_INVALID = -707,
+ NPC_FLOW_CHAN_INVALID = -708,
+ NPC_FLOW_NO_NIXLF = -709,
+ NPC_FLOW_NOT_SUPPORTED = -710,
+ NPC_FLOW_VF_PERM_DENIED = -711,
+ NPC_FLOW_VF_NOT_INIT = -712,
+ NPC_FLOW_VF_OVERLAP = -713,
};
struct npc_mcam_alloc_entry_req {
@@ -2442,9 +2466,12 @@ struct npc_mcam_alloc_entry_req {
#define NPC_MCAM_ANY_PRIO 0
#define NPC_MCAM_LOWER_PRIO 1
#define NPC_MCAM_HIGHER_PRIO 2
- uint8_t __io priority; /* Lower or higher w.r.t ref_entry */
+ uint8_t __io ref_priority; /* Lower or higher w.r.t ref_entry */
uint16_t __io ref_entry;
uint16_t __io count; /* Number of entries requested */
+ uint8_t __io kw_type; /* Key type */
+ uint8_t __io virt; /* Request virtual index */
+ uint16_t __io rsvd[16]; /* Reserved */
};
struct npc_mcam_alloc_entry_rsp {
@@ -2456,6 +2483,7 @@ struct npc_mcam_alloc_entry_rsp {
uint16_t __io count; /* Number of entries allocated */
uint16_t __io free_count; /* Number of entries available */
uint16_t __io entry_list[NPC_MAX_NONCONTIG_ENTRIES];
+ uint16_t __io rsvd[16]; /* Reserved */
};
struct npc_mcam_free_entry_req {
@@ -2482,6 +2510,26 @@ struct npc_mcam_write_entry_req {
uint8_t __io set_cntr; /* Set counter for this entry ? */
};
+struct cn20k_mcam_entry {
+#define NPC_CN20K_MAX_KWS_IN_KEY 8 /* Number of keywords in max keywidth */
+ uint64_t __io kw[NPC_CN20K_MAX_KWS_IN_KEY];
+ uint64_t __io kw_mask[NPC_CN20K_MAX_KWS_IN_KEY];
+ uint64_t __io action;
+ uint64_t __io vtag_action;
+};
+
+struct npc_cn20k_mcam_write_entry_req {
+ struct mbox_msghdr hdr;
+ struct cn20k_mcam_entry entry_data;
+ uint16_t __io entry; /* MCAM entry to write this match key */
+ uint16_t __io cntr; /* Counter for this MCAM entry */
+ uint8_t __io intf; /* Rx or Tx interface */
+ uint8_t __io enable_entry; /* Enable this MCAM entry ? */
+ uint8_t __io hw_prio; /* hardware priority, valid for cn20k */
+ uint8_t __io req_kw_type; /* Type of kw which should be written */
+ uint64_t __io reserved; /* reserved for future use */
+};
+
/* Enable/Disable a given entry */
struct npc_mcam_ena_dis_entry_req {
struct mbox_msghdr hdr;
@@ -2541,12 +2589,25 @@ struct npc_mcam_alloc_and_write_entry_req {
struct mbox_msghdr hdr;
struct mcam_entry entry_data;
uint16_t __io ref_entry;
- uint8_t __io priority; /* Lower or higher w.r.t ref_entry */
+ uint8_t __io ref_priority; /* Lower or higher w.r.t ref_entry */
uint8_t __io intf; /* Rx or Tx interface */
uint8_t __io enable_entry; /* Enable this MCAM entry ? */
uint8_t __io alloc_cntr; /* Allocate counter and map ? */
};
+struct npc_cn20k_mcam_alloc_and_write_entry_req {
+ struct mbox_msghdr hdr;
+ struct cn20k_mcam_entry entry_data;
+ uint16_t __io ref_entry;
+ uint8_t __io ref_prio; /* Lower or higher w.r.t ref_entry */
+ uint8_t __io intf; /* Rx or Tx interface */
+ uint8_t __io enable_entry; /* Enable this MCAM entry ? */
+ uint8_t __io hw_prio; /* hardware priority, valid for cn20k */
+ uint8_t __io virt; /* Allocate virtual index */
+ uint8_t __io req_kw_type; /* Key type to be written */
+ uint16_t __io reserved[4]; /* reserved for future use */
+};
+
struct npc_mcam_alloc_and_write_entry_rsp {
struct mbox_msghdr hdr;
uint16_t __io entry;
@@ -2573,6 +2634,48 @@ struct npc_get_kex_cfg_rsp {
uint8_t __io mkex_pfl_name[MKEX_NAME_LEN];
};
+struct npc_delete_flow_rsp {
+ struct mbox_msghdr hdr;
+ uint16_t __io cntr_val;
+};
+
+/* Available entries to use */
+struct npc_cn20k_get_free_count_rsp {
+ struct mbox_msghdr hdr;
+ int __io free_x2;
+ int __io free_x4;
+ int __io free_subbanks;
+};
+
+struct npc_cn20k_get_kex_cfg_rsp {
+ struct mbox_msghdr hdr;
+ uint64_t __io rx_keyx_cfg; /* NPC_AF_INTF(0)_KEX_CFG */
+ uint64_t __io tx_keyx_cfg; /* NPC_AF_INTF(1)_KEX_CFG */
+#define NPC_MAX_EXTRACTOR 24
+ /* MKEX Extractor data */
+ uint64_t __io intf_extr[NPC_MAX_INTF][NPC_MAX_EXTRACTOR];
+ /* KEX configuration per extractor */
+ uint64_t __io intf_extr_lt[NPC_MAX_INTF][NPC_MAX_EXTRACTOR][NPC_MAX_LT];
+#define MKEX_NAME_LEN 128
+ uint8_t __io mkex_pfl_name[MKEX_NAME_LEN];
+};
+
+struct npc_get_field_hash_info_req {
+ struct mbox_msghdr hdr;
+ uint8_t intf;
+};
+
+struct npc_get_field_hash_info_rsp {
+ struct mbox_msghdr hdr;
+ uint64_t __io secret_key[3];
+#define NPC_MAX_HASH 2
+#define NPC_MAX_HASH_MASK 2
+ /* NPC_AF_INTF(0..1)_HASH(0..1)_MASK(0..1) */
+ uint64_t __io hash_mask[NPC_MAX_INTF][NPC_MAX_HASH][NPC_MAX_HASH_MASK];
+ /* NPC_AF_INTF(0..1)_HASH(0..1)_RESULT_CTRL */
+ uint64_t __io hash_ctrl[NPC_MAX_INTF][NPC_MAX_HASH];
+};
+
enum header_fields {
NPC_DMAC,
NPC_SMAC,
@@ -2662,6 +2765,8 @@ struct npc_install_flow_req {
uint8_t __io vtag1_op;
/* old counter value */
uint16_t __io cntr_val;
+ /* hardware priority, supported for cn20k */
+ uint8_t __io hw_prio;
};
struct npc_install_flow_rsp {
@@ -2692,11 +2797,24 @@ struct npc_mcam_read_entry_rsp {
uint8_t __io enable;
};
+struct npc_cn20k_mcam_read_entry_rsp {
+ struct mbox_msghdr hdr;
+ struct cn20k_mcam_entry entry_data;
+ uint8_t __io intf;
+ uint8_t __io enable;
+ uint8_t __io hw_prio; /* valid for cn20k */
+};
+
struct npc_mcam_read_base_rule_rsp {
struct mbox_msghdr hdr;
struct mcam_entry entry_data;
};
+struct npc_cn20k_mcam_read_base_rule_rsp {
+ struct mbox_msghdr hdr;
+ struct cn20k_mcam_entry entry;
+};
+
struct npc_mcam_get_stats_req {
struct mbox_msghdr hdr;
uint16_t __io entry; /* mcam entry */
@@ -2776,22 +2894,6 @@ enum tim_gpio_edge {
TIM_GPIO_INVALID,
};
-struct npc_get_field_hash_info_req {
- struct mbox_msghdr hdr;
- uint8_t intf;
-};
-
-struct npc_get_field_hash_info_rsp {
- struct mbox_msghdr hdr;
- uint64_t __io secret_key[3];
-#define NPC_MAX_HASH 2
-#define NPC_MAX_HASH_MASK 2
- /* NPC_AF_INTF(0..1)_HASH(0..1)_MASK(0..1) */
- uint64_t __io hash_mask[NPC_MAX_INTF][NPC_MAX_HASH][NPC_MAX_HASH_MASK];
- /* NPC_AF_INTF(0..1)_HASH(0..1)_RESULT_CTRL */
- uint64_t __io hash_ctrl[NPC_MAX_INTF][NPC_MAX_HASH];
-};
-
enum ptp_op {
PTP_OP_ADJFINE = 0, /* adjfine(req.scaled_ppm); */
PTP_OP_GET_CLOCK = 1, /* rsp.clk = get_clock() */
diff --git a/drivers/common/cnxk/roc_nix.h b/drivers/common/cnxk/roc_nix.h
index f213823b9b..15823ab16c 100644
--- a/drivers/common/cnxk/roc_nix.h
+++ b/drivers/common/cnxk/roc_nix.h
@@ -983,15 +983,11 @@ bool __roc_api roc_nix_ptp_is_enable(struct roc_nix *roc_nix);
/* VLAN */
int __roc_api
roc_nix_vlan_mcam_entry_read(struct roc_nix *roc_nix, uint32_t index,
- struct npc_mcam_read_entry_rsp **rsp);
-int __roc_api roc_nix_vlan_mcam_entry_write(struct roc_nix *roc_nix,
- uint32_t index,
- struct mcam_entry *entry,
+ void **rsp);
+int __roc_api roc_nix_vlan_mcam_entry_write(struct roc_nix *roc_nix, uint32_t index, void *entry,
uint8_t intf, uint8_t enable);
-int __roc_api roc_nix_vlan_mcam_entry_alloc_and_write(struct roc_nix *roc_nix,
- struct mcam_entry *entry,
- uint8_t intf,
- uint8_t priority,
+int __roc_api roc_nix_vlan_mcam_entry_alloc_and_write(struct roc_nix *roc_nix, void *entry,
+ uint8_t intf, uint8_t priority,
uint8_t ref_entry);
int __roc_api roc_nix_vlan_mcam_entry_free(struct roc_nix *roc_nix,
uint32_t index);
@@ -1012,10 +1008,8 @@ int __roc_api roc_nix_mcast_mcam_entry_alloc(struct roc_nix *roc_nix,
uint16_t index[]);
int __roc_api roc_nix_mcast_mcam_entry_free(struct roc_nix *roc_nix,
uint32_t index);
-int __roc_api roc_nix_mcast_mcam_entry_write(struct roc_nix *roc_nix,
- struct mcam_entry *entry,
- uint32_t index, uint8_t intf,
- uint64_t action);
+int __roc_api roc_nix_mcast_mcam_entry_write(struct roc_nix *roc_nix, void *entry, uint32_t index,
+ uint8_t intf, uint64_t action);
int __roc_api roc_nix_mcast_mcam_entry_ena_dis(struct roc_nix *roc_nix, uint32_t index,
bool enable);
int __roc_api roc_nix_mcast_list_setup(struct mbox *mbox, uint8_t intf, int nb_entries,
diff --git a/drivers/common/cnxk/roc_nix_mcast.c b/drivers/common/cnxk/roc_nix_mcast.c
index 615014e820..eab4bde743 100644
--- a/drivers/common/cnxk/roc_nix_mcast.c
+++ b/drivers/common/cnxk/roc_nix_mcast.c
@@ -19,7 +19,7 @@ roc_nix_mcast_mcam_entry_alloc(struct roc_nix *roc_nix, uint16_t nb_entries,
req = mbox_alloc_msg_npc_mcam_alloc_entry(mbox);
if (req == NULL)
goto exit;
- req->priority = priority;
+ req->ref_priority = priority;
req->count = nb_entries;
rc = mbox_process_msg(mbox, (void *)&rsp);
@@ -56,24 +56,38 @@ roc_nix_mcast_mcam_entry_free(struct roc_nix *roc_nix, uint32_t index)
}
int
-roc_nix_mcast_mcam_entry_write(struct roc_nix *roc_nix,
- struct mcam_entry *entry, uint32_t index,
- uint8_t intf, uint64_t action)
+roc_nix_mcast_mcam_entry_write(struct roc_nix *roc_nix, void *entry, uint32_t index, uint8_t intf,
+ uint64_t action)
{
struct nix *nix = roc_nix_to_nix_priv(roc_nix);
struct dev *dev = &nix->dev;
struct mbox *mbox = mbox_get(dev->mbox);
- struct npc_mcam_write_entry_req *req;
int rc = -ENOSPC;
- req = mbox_alloc_msg_npc_mcam_write_entry(mbox);
- if (req == NULL)
- goto exit;
- req->entry = index;
- req->intf = intf;
- req->enable_entry = true;
- mbox_memcpy(&req->entry_data, entry, sizeof(struct mcam_entry));
- req->entry_data.action = action;
+ if (roc_model_is_cn20k()) {
+ struct npc_cn20k_mcam_write_entry_req *req;
+
+ req = mbox_alloc_msg_npc_cn20k_mcam_write_entry(mbox);
+ if (req == NULL)
+ goto exit;
+ req->entry = index;
+ req->intf = intf;
+ req->enable_entry = true;
+ mbox_memcpy(&req->entry_data, entry, sizeof(struct cn20k_mcam_entry));
+ req->entry_data.action = action;
+
+ } else {
+ struct npc_mcam_write_entry_req *req;
+
+ req = mbox_alloc_msg_npc_mcam_write_entry(mbox);
+ if (req == NULL)
+ goto exit;
+ req->entry = index;
+ req->intf = intf;
+ req->enable_entry = true;
+ mbox_memcpy(&req->entry_data, entry, sizeof(struct mcam_entry));
+ req->entry_data.action = action;
+ }
rc = mbox_process(mbox);
exit:
diff --git a/drivers/common/cnxk/roc_nix_vlan.c b/drivers/common/cnxk/roc_nix_vlan.c
index db218593ad..16100eb5d6 100644
--- a/drivers/common/cnxk/roc_nix_vlan.c
+++ b/drivers/common/cnxk/roc_nix_vlan.c
@@ -7,7 +7,7 @@
int
roc_nix_vlan_mcam_entry_read(struct roc_nix *roc_nix, uint32_t index,
- struct npc_mcam_read_entry_rsp **rsp)
+ void **rsp)
{
struct nix *nix = roc_nix_to_nix_priv(roc_nix);
struct dev *dev = &nix->dev;
@@ -27,24 +27,34 @@ roc_nix_vlan_mcam_entry_read(struct roc_nix *roc_nix, uint32_t index,
}
int
-roc_nix_vlan_mcam_entry_write(struct roc_nix *roc_nix, uint32_t index,
- struct mcam_entry *entry, uint8_t intf,
+roc_nix_vlan_mcam_entry_write(struct roc_nix *roc_nix, uint32_t index, void *entry, uint8_t intf,
uint8_t enable)
{
struct nix *nix = roc_nix_to_nix_priv(roc_nix);
struct dev *dev = &nix->dev;
struct mbox *mbox = mbox_get(dev->mbox);
struct npc_mcam_write_entry_req *req;
+ struct npc_cn20k_mcam_write_entry_req *cn20k_req;
struct msghdr *rsp;
int rc = -ENOSPC;
- req = mbox_alloc_msg_npc_mcam_write_entry(mbox);
- if (req == NULL)
- goto exit;
- req->entry = index;
- req->intf = intf;
- req->enable_entry = enable;
- mbox_memcpy(&req->entry_data, entry, sizeof(struct mcam_entry));
+ if (roc_model_is_cn20k()) {
+ cn20k_req = mbox_alloc_msg_npc_cn20k_mcam_write_entry(mbox);
+ if (cn20k_req == NULL)
+ goto exit;
+ cn20k_req->entry = index;
+ cn20k_req->intf = intf;
+ cn20k_req->enable_entry = enable;
+ mbox_memcpy(&cn20k_req->entry_data, entry, sizeof(struct cn20k_mcam_entry));
+ } else {
+ req = mbox_alloc_msg_npc_mcam_write_entry(mbox);
+ if (req == NULL)
+ goto exit;
+ req->entry = index;
+ req->intf = intf;
+ req->enable_entry = enable;
+ mbox_memcpy(&req->entry_data, entry, sizeof(struct mcam_entry));
+ }
rc = mbox_process_msg(mbox, (void *)&rsp);
exit:
@@ -53,25 +63,39 @@ roc_nix_vlan_mcam_entry_write(struct roc_nix *roc_nix, uint32_t index,
}
int
-roc_nix_vlan_mcam_entry_alloc_and_write(struct roc_nix *roc_nix,
- struct mcam_entry *entry, uint8_t intf,
+roc_nix_vlan_mcam_entry_alloc_and_write(struct roc_nix *roc_nix, void *entry, uint8_t intf,
uint8_t priority, uint8_t ref_entry)
{
- struct npc_mcam_alloc_and_write_entry_req *req;
struct npc_mcam_alloc_and_write_entry_rsp *rsp;
struct nix *nix = roc_nix_to_nix_priv(roc_nix);
struct dev *dev = &nix->dev;
struct mbox *mbox = mbox_get(dev->mbox);
int rc = -ENOSPC;
- req = mbox_alloc_msg_npc_mcam_alloc_and_write_entry(mbox);
- if (req == NULL)
- goto exit;
- req->priority = priority;
- req->ref_entry = ref_entry;
- req->intf = intf;
- req->enable_entry = true;
- mbox_memcpy(&req->entry_data, entry, sizeof(struct mcam_entry));
+ if (roc_model_is_cn20k()) {
+ struct npc_cn20k_mcam_alloc_and_write_entry_req *req;
+
+ req = mbox_alloc_msg_npc_cn20k_mcam_alloc_and_write_entry(mbox);
+ if (req == NULL)
+ goto exit;
+ req->ref_prio = priority;
+ req->ref_entry = ref_entry;
+ req->intf = intf;
+ req->enable_entry = true;
+ mbox_memcpy(&req->entry_data, entry, sizeof(struct cn20k_mcam_entry));
+
+ } else {
+ struct npc_mcam_alloc_and_write_entry_req *req;
+
+ req = mbox_alloc_msg_npc_mcam_alloc_and_write_entry(mbox);
+ if (req == NULL)
+ goto exit;
+ req->ref_priority = priority;
+ req->ref_entry = ref_entry;
+ req->intf = intf;
+ req->enable_entry = true;
+ mbox_memcpy(&req->entry_data, entry, sizeof(struct mcam_entry));
+ }
rc = mbox_process_msg(mbox, (void *)&rsp);
if (rc)
diff --git a/drivers/common/cnxk/roc_npc.c b/drivers/common/cnxk/roc_npc.c
index 53f278c764..138f12f6d8 100644
--- a/drivers/common/cnxk/roc_npc.c
+++ b/drivers/common/cnxk/roc_npc.c
@@ -100,6 +100,14 @@ roc_npc_mcam_read_counter(struct roc_npc *roc_npc, uint32_t ctr_id, uint64_t *co
return npc_mcam_read_counter(npc->mbox, ctr_id, count);
}
+int
+roc_npc_mcam_get_stats(struct roc_npc *roc_npc, struct roc_npc_flow *flow, uint64_t *count)
+{
+ struct npc *npc = roc_npc_to_npc_priv(roc_npc);
+
+ return npc_mcam_get_stats(npc->mbox, flow, count);
+}
+
int
roc_npc_mcam_clear_counter(struct roc_npc *roc_npc, uint32_t ctr_id)
{
@@ -221,7 +229,9 @@ roc_npc_get_low_priority_mcam(struct roc_npc *roc_npc)
{
struct npc *npc = roc_npc_to_npc_priv(roc_npc);
- if (roc_model_is_cn10k())
+ if (roc_model_is_cn20k())
+ return (npc->mcam_entries - NPC_MCAME_RESVD_10XX - 1);
+ else if (roc_model_is_cn10k())
return (npc->mcam_entries - NPC_MCAME_RESVD_10XX - 1);
else if (roc_model_is_cn98xx())
return (npc->mcam_entries - NPC_MCAME_RESVD_98XX - 1);
@@ -235,7 +245,9 @@ npc_mcam_tot_entries(void)
/* FIXME: change to reading in AF from NPC_AF_CONST1/2
* MCAM_BANK_DEPTH(_EXT) * MCAM_BANKS
*/
- if (roc_model_is_cn10k() || roc_model_is_cn98xx())
+ if (roc_model_is_cn20k())
+ return 2 * 8192; /* MCAM_BANKS = 2, BANK_DEPTH_EXT = 8192 */
+ else if (roc_model_is_cn10k() || roc_model_is_cn98xx())
return 16 * 1024; /* MCAM_BANKS = 4, BANK_DEPTH_EXT = 4096 */
else
return 4 * 1024; /* MCAM_BANKS = 4, BANK_DEPTH_EXT = 1024 */
@@ -311,6 +323,7 @@ roc_npc_init(struct roc_npc *roc_npc)
npc->mcam_entries = npc_mcam_tot_entries() >> npc->keyw[NPC_MCAM_RX];
nix->exact_match_ena = npc->exact_match_ena;
+ roc_npc->max_entries = npc->mcam_entries;
/* Free, free_rev, live and live_rev entries */
bmap_sz = plt_bitmap_get_memory_footprint(npc->mcam_entries);
@@ -1856,9 +1869,7 @@ roc_npc_flow_dump(FILE *file, struct roc_npc *roc_npc, int rep_port_id)
int
roc_npc_mcam_merge_base_steering_rule(struct roc_npc *roc_npc, struct roc_npc_flow *flow)
{
- struct npc_mcam_read_base_rule_rsp *base_rule_rsp;
struct npc *npc = roc_npc_to_npc_priv(roc_npc);
- struct mcam_entry *base_entry;
struct mbox *mbox = mbox_get(npc->mbox);
int idx, rc;
@@ -1868,17 +1879,36 @@ roc_npc_mcam_merge_base_steering_rule(struct roc_npc *roc_npc, struct roc_npc_fl
}
(void)mbox_alloc_msg_npc_read_base_steer_rule(mbox);
- rc = mbox_process_msg(mbox, (void *)&base_rule_rsp);
- if (rc) {
- plt_err("Failed to fetch VF's base MCAM entry");
- goto exit;
- }
- base_entry = &base_rule_rsp->entry_data;
- for (idx = 0; idx < ROC_NPC_MAX_MCAM_WIDTH_DWORDS; idx++) {
- flow->mcam_data[idx] |= base_entry->kw[idx];
- flow->mcam_mask[idx] |= base_entry->kw_mask[idx];
- }
+ if (roc_model_is_cn20k()) {
+ struct npc_cn20k_mcam_read_base_rule_rsp *base_rule_rsp;
+ struct cn20k_mcam_entry *base_entry;
+ rc = mbox_process_msg(mbox, (void *)&base_rule_rsp);
+ if (rc) {
+ plt_err("Failed to fetch VF's base MCAM entry");
+ goto exit;
+ }
+ base_entry = &base_rule_rsp->entry;
+ for (idx = 0; idx < ROC_NPC_MAX_MCAM_WIDTH_DWORDS; idx++) {
+ flow->mcam_data[idx] |= base_entry->kw[idx];
+ flow->mcam_mask[idx] |= base_entry->kw_mask[idx];
+ }
+
+ } else {
+ struct npc_mcam_read_base_rule_rsp *base_rule_rsp;
+ struct mcam_entry *base_entry;
+
+ rc = mbox_process_msg(mbox, (void *)&base_rule_rsp);
+ if (rc) {
+ plt_err("Failed to fetch VF's base MCAM entry");
+ goto exit;
+ }
+ base_entry = &base_rule_rsp->entry_data;
+ for (idx = 0; idx < ROC_NPC_MAX_MCAM_WIDTH_DWORDS; idx++) {
+ flow->mcam_data[idx] |= base_entry->kw[idx];
+ flow->mcam_mask[idx] |= base_entry->kw_mask[idx];
+ }
+ }
rc = 0;
exit:
mbox_put(mbox);
diff --git a/drivers/common/cnxk/roc_npc.h b/drivers/common/cnxk/roc_npc.h
index bf8c65aa9c..b96862e054 100644
--- a/drivers/common/cnxk/roc_npc.h
+++ b/drivers/common/cnxk/roc_npc.h
@@ -305,52 +305,58 @@ struct roc_npc_spi_to_sa_action_info {
};
struct mbox;
-
struct roc_npc_flow {
uint8_t nix_intf;
uint8_t enable;
- uint32_t mcam_id;
uint8_t use_ctr;
+ bool is_validate;
+ uint32_t mcam_id;
+ uint16_t tx_pf_func;
+ bool has_age_action;
+ bool rep_act_rep;
int32_t ctr_id;
uint32_t priority;
uint32_t mtr_id;
+#if defined(ROC_PLATFORM_CN20K)
+#define ROC_NPC_MAX_MCAM_WIDTH_DWORDS 8
+#define ROC_NPC_MAX_MCAM_PRIORITY 123
+#else
#define ROC_NPC_MAX_MCAM_WIDTH_DWORDS 7
+#define ROC_NPC_MAX_MCAM_PRIORITY 32
+#endif
/* Contiguous match string */
uint64_t mcam_data[ROC_NPC_MAX_MCAM_WIDTH_DWORDS];
uint64_t mcam_mask[ROC_NPC_MAX_MCAM_WIDTH_DWORDS];
uint64_t npc_action;
uint64_t vtag_action;
bool vtag_insert_enabled;
- uint8_t vtag_insert_count;
+ int8_t vtag_insert_count;
#define ROC_NPC_MAX_FLOW_PATTERNS 32
struct roc_npc_flow_dump_data dump_data[ROC_NPC_MAX_FLOW_PATTERNS];
uint16_t num_patterns;
struct roc_npc_spi_to_sa_action_info spi_to_sa_info;
- uint16_t tx_pf_func;
- bool is_validate;
uint16_t match_id;
uint8_t is_inline_dev;
bool use_pre_alloc;
uint64_t timeout_cycles;
void *age_context;
- uint32_t timeout;
- bool has_age_action;
- uint16_t rep_pf_func;
uint16_t rep_act_pf_func;
- bool rep_act_rep;
+ bool is_rep_vf;
+ bool has_rep;
+ bool is_sampling_rule;
+ uint16_t rep_pf_func;
+#define ROC_NPC_MIRROR_LIST_SIZE 2
+ uint16_t mcast_pf_funcs[ROC_NPC_MIRROR_LIST_SIZE];
uint16_t rep_channel;
struct mbox *rep_mbox;
- bool has_rep;
- bool is_rep_vf;
struct npc *rep_npc;
int port_id;
- bool is_sampling_rule;
+ uint16_t mcast_channels[ROC_NPC_MIRROR_LIST_SIZE];
uint32_t recv_queue;
uint32_t mcast_grp_index;
uint32_t mce_start_index;
-#define ROC_NPC_MIRROR_LIST_SIZE 2
- uint16_t mcast_pf_funcs[ROC_NPC_MIRROR_LIST_SIZE];
- uint16_t mcast_channels[ROC_NPC_MIRROR_LIST_SIZE];
+ uint8_t key_type;
+ uint32_t timeout;
TAILQ_ENTRY(roc_npc_flow) next;
};
@@ -400,33 +406,34 @@ struct roc_npc {
struct roc_nix *roc_nix;
uint8_t switch_header_type;
uint8_t pre_l2_size_offset; /**< Offset with in header that holds
- * size of custom header
- */
+ * size of custom header
+ */
uint8_t pre_l2_size_offset_mask; /**< Offset mask with in header
- * that holds size of custom header
- */
+ * that holds size of custom header
+ */
uint8_t pre_l2_size_shift_dir; /**< Shift direction to calculate size
- */
+ */
uint16_t flow_prealloc_size;
uint16_t flow_max_priority;
uint16_t channel;
uint16_t pf_func;
+ bool is_sdp_mask_set;
+ bool rep_act_rep;
+ uint16_t sdp_channel_mask;
uint64_t kex_capability;
uint64_t rx_parse_nibble;
/* Parsed RSS Flowkey cfg for current flow being created */
uint32_t flowkey_cfg_state;
- bool is_sdp_mask_set;
+ uint32_t max_entries;
+ uint16_t rep_act_pf_func;
uint16_t sdp_channel;
- uint16_t sdp_channel_mask;
struct roc_npc_flow_age flow_age;
struct roc_npc *rep_npc;
uint16_t rep_pf_func;
uint16_t rep_rx_channel;
- uint16_t rep_act_pf_func;
- bool rep_act_rep;
int rep_port_id;
-#define ROC_NPC_MEM_SZ (6 * 1024)
+#define ROC_NPC_MEM_SZ (20 * 1024)
uint8_t reserved[ROC_NPC_MEM_SZ];
} __plt_cache_aligned;
@@ -482,4 +489,6 @@ int __roc_api roc_npc_mcam_move(struct roc_npc *roc_npc, uint16_t old_ent, uint1
void *__roc_api roc_npc_aged_flow_ctx_get(struct roc_npc *roc_npc, uint32_t mcam_id);
void __roc_api roc_npc_sdp_channel_get(struct roc_npc *roc_npc, uint16_t *chan_base,
uint16_t *chan_mask);
+int __roc_api roc_npc_mcam_get_stats(struct roc_npc *roc_npc, struct roc_npc_flow *flow,
+ uint64_t *count);
#endif /* _ROC_NPC_H_ */
diff --git a/drivers/common/cnxk/roc_npc_mcam.c b/drivers/common/cnxk/roc_npc_mcam.c
index cdb9db1383..412b2611b7 100644
--- a/drivers/common/cnxk/roc_npc_mcam.c
+++ b/drivers/common/cnxk/roc_npc_mcam.c
@@ -11,6 +11,10 @@ npc_mcam_alloc_counter(struct mbox *mbox, uint16_t *ctr)
struct npc_mcam_alloc_counter_rsp *rsp;
int rc = -ENOSPC;
+ /* For CN20K, counters are enabled by default */
+ if (roc_model_is_cn20k())
+ return 0;
+
req = mbox_alloc_msg_npc_mcam_alloc_counter(mbox_get(mbox));
if (req == NULL)
goto exit;
@@ -30,6 +34,9 @@ npc_mcam_free_counter(struct mbox *mbox, uint16_t ctr_id)
struct npc_mcam_oper_counter_req *req;
int rc = -ENOSPC;
+ if (roc_model_is_cn20k())
+ return 0;
+
req = mbox_alloc_msg_npc_mcam_free_counter(mbox_get(mbox));
if (req == NULL)
goto exit;
@@ -40,6 +47,30 @@ npc_mcam_free_counter(struct mbox *mbox, uint16_t ctr_id)
return rc;
}
+int
+npc_mcam_get_stats(struct mbox *mbox, struct roc_npc_flow *flow, uint64_t *count)
+{
+ struct npc_mcam_get_stats_req *req;
+ struct npc_mcam_get_stats_rsp *rsp;
+ int rc = -ENOSPC;
+
+ /* valid only for cn20k */
+ if (!roc_model_is_cn20k())
+ return 0;
+
+ req = mbox_alloc_msg_npc_mcam_entry_stats(mbox_get(mbox));
+ if (req == NULL)
+ goto exit;
+ req->entry = flow->mcam_id;
+ rc = mbox_process_msg(mbox, (void *)&rsp);
+ if (rc)
+ goto exit;
+ *count = rsp->stat;
+exit:
+ mbox_put(mbox);
+ return rc;
+}
+
int
npc_mcam_read_counter(struct mbox *mbox, uint32_t ctr_id, uint64_t *count)
{
@@ -47,6 +78,9 @@ npc_mcam_read_counter(struct mbox *mbox, uint32_t ctr_id, uint64_t *count)
struct npc_mcam_oper_counter_rsp *rsp;
int rc = -ENOSPC;
+ if (roc_model_is_cn20k())
+ return 0;
+
req = mbox_alloc_msg_npc_mcam_counter_stats(mbox_get(mbox));
if (req == NULL)
goto exit;
@@ -66,6 +100,9 @@ npc_mcam_clear_counter(struct mbox *mbox, uint32_t ctr_id)
struct npc_mcam_oper_counter_req *req;
int rc = -ENOSPC;
+ if (roc_model_is_cn20k())
+ return 0;
+
req = mbox_alloc_msg_npc_mcam_clear_counter(mbox_get(mbox));
if (req == NULL)
goto exit;
@@ -132,16 +169,53 @@ npc_lid_lt_in_kex(struct npc *npc, uint8_t lid, uint8_t lt)
struct npc_xtract_info *x_info;
int i;
- for (i = 0; i < NPC_MAX_LD; i++) {
- x_info = &npc->prx_dxcfg[NIX_INTF_RX][lid][lt].xtract[i];
- /* Check for LDATA */
- if (x_info->enable && x_info->len > 0)
- return true;
+ if (!roc_model_is_cn20k()) {
+ for (i = 0; i < NPC_MAX_LD; i++) {
+ x_info = &npc->prx_dxcfg[NIX_INTF_RX][lid][lt].xtract[i];
+ /* Check for LDATA */
+ if (x_info->enable && x_info->len > 0)
+ return true;
+ }
+ } else {
+ for (i = 0; i < NPC_MAX_EXTRACTOR; i++) {
+ union npc_kex_ldata_flags_cfg *lid_info = &npc->lid_cfg[NIX_INTF_RX][i];
+
+ if (lid_info->s.lid != lid)
+ continue;
+ x_info = &npc->prx_dxcfg_cn20k[NIX_INTF_RX][i][lt].xtract;
+ /* Check for LDATA */
+ if (x_info->enable && x_info->len > 0)
+ return true;
+ }
}
return false;
}
+static void
+npc_construct_ldata_mask_cn20k(struct npc *npc, struct plt_bitmap *bmap, uint8_t lid, uint8_t lt)
+{
+ struct npc_xtract_info *x_info;
+ int hdr_off, keylen;
+ int i, j;
+
+ for (i = 0; i < NPC_MAX_EXTRACTOR; i++) {
+ union npc_kex_ldata_flags_cfg *lid_conf = &npc->lid_cfg[NIX_INTF_RX][i];
+
+ if (lid_conf->s.lid != lid)
+ continue;
+
+ x_info = &npc->prx_dxcfg_cn20k[NIX_INTF_RX][i][lt].xtract;
+ if (x_info->enable == 0)
+ continue;
+
+ hdr_off = x_info->hdr_off * 8;
+ keylen = x_info->len * 8;
+ for (j = hdr_off; j < (hdr_off + keylen); j++)
+ plt_bitmap_set(bmap, j);
+ }
+}
+
static void
npc_construct_ldata_mask(struct npc *npc, struct plt_bitmap *bmap, uint8_t lid, uint8_t lt,
uint8_t ld)
@@ -220,8 +294,12 @@ npc_is_kex_enabled(struct npc *npc, uint8_t lid, uint8_t lt, int offset, int len
return false;
}
- npc_construct_ldata_mask(npc, bmap, lid, lt, 0);
- npc_construct_ldata_mask(npc, bmap, lid, lt, 1);
+ if (!roc_model_is_cn20k()) {
+ npc_construct_ldata_mask(npc, bmap, lid, lt, 0);
+ npc_construct_ldata_mask(npc, bmap, lid, lt, 1);
+ } else {
+ npc_construct_ldata_mask_cn20k(npc, bmap, lid, lt);
+ }
for (i = offset; i < (offset + len); i++) {
if (plt_bitmap_get(bmap, i) != 0x1) {
@@ -330,7 +408,7 @@ npc_mcam_alloc_entries(struct mbox *mbox, int ref_mcam, int *alloc_entry, int re
goto exit;
req->contig = is_conti;
req->count = req_count;
- req->priority = prio;
+ req->ref_priority = prio;
req->ref_entry = ref_mcam;
rc = mbox_process_msg(mbox, (void *)&rsp);
@@ -349,11 +427,11 @@ npc_mcam_alloc_entries(struct mbox *mbox, int ref_mcam, int *alloc_entry, int re
int
npc_mcam_alloc_entry(struct npc *npc, struct roc_npc_flow *mcam, struct roc_npc_flow *ref_mcam,
- int prio, int *resp_count)
+ uint8_t prio, int *resp_count)
{
+ struct mbox *mbox = mbox_get(npc->mbox);
struct npc_mcam_alloc_entry_req *req;
struct npc_mcam_alloc_entry_rsp *rsp;
- struct mbox *mbox = mbox_get(npc->mbox);
int rc = -ENOSPC;
req = mbox_alloc_msg_npc_mcam_alloc_entry(mbox);
@@ -361,16 +439,16 @@ npc_mcam_alloc_entry(struct npc *npc, struct roc_npc_flow *mcam, struct roc_npc_
goto exit;
req->contig = 1;
req->count = 1;
- req->priority = prio;
- req->ref_entry = ref_mcam->mcam_id;
-
+ req->ref_priority = prio;
+ req->ref_entry = ref_mcam ? ref_mcam->mcam_id : 0;
+ req->kw_type = mcam->key_type;
rc = mbox_process_msg(mbox, (void *)&rsp);
if (rc)
goto exit;
- memset(mcam, 0, sizeof(struct roc_npc_flow));
mcam->mcam_id = rsp->entry;
- mcam->nix_intf = ref_mcam->nix_intf;
+ mcam->nix_intf = ref_mcam ? ref_mcam->nix_intf : 0;
*resp_count = rsp->count;
+
rc = 0;
exit:
mbox_put(mbox);
@@ -403,6 +481,7 @@ int
npc_mcam_write_entry(struct mbox *mbox, struct roc_npc_flow *mcam)
{
struct npc_mcam_write_entry_req *req;
+ struct npc_cn20k_mcam_write_entry_req *cn20k_req;
struct mbox_msghdr *rsp;
int rc = -ENOSPC;
uint16_t ctr = 0;
@@ -419,33 +498,121 @@ npc_mcam_write_entry(struct mbox *mbox, struct roc_npc_flow *mcam)
return rc;
}
- req = mbox_alloc_msg_npc_mcam_write_entry(mbox_get(mbox));
- if (req == NULL) {
- mbox_put(mbox);
+ if (roc_model_is_cn20k()) {
+ cn20k_req = mbox_alloc_msg_npc_cn20k_mcam_write_entry(mbox_get(mbox));
+ if (cn20k_req == NULL) {
+ mbox_put(mbox);
+ if (mcam->use_ctr)
+ npc_mcam_free_counter(mbox, ctr);
+
+ return rc;
+ }
+ cn20k_req->entry = mcam->mcam_id;
+ cn20k_req->intf = mcam->nix_intf;
+ cn20k_req->enable_entry = mcam->enable;
+ cn20k_req->entry_data.action = mcam->npc_action;
+ cn20k_req->entry_data.vtag_action = mcam->vtag_action;
+ cn20k_req->hw_prio = mcam->priority;
if (mcam->use_ctr)
- npc_mcam_free_counter(mbox, ctr);
+ cn20k_req->cntr = mcam->ctr_id;
- return rc;
- }
- req->entry = mcam->mcam_id;
- req->intf = mcam->nix_intf;
- req->enable_entry = mcam->enable;
- req->entry_data.action = mcam->npc_action;
- req->entry_data.vtag_action = mcam->vtag_action;
- if (mcam->use_ctr) {
- req->set_cntr = 1;
- req->cntr = mcam->ctr_id;
- }
+ for (i = 0; i < NPC_MCAM_KEY_X4_WORDS; i++) {
+ cn20k_req->entry_data.kw[i] = mcam->mcam_data[i];
+ cn20k_req->entry_data.kw_mask[i] = mcam->mcam_mask[i];
+ }
+ } else {
+ req = mbox_alloc_msg_npc_mcam_write_entry(mbox_get(mbox));
+ if (req == NULL) {
+ mbox_put(mbox);
+ if (mcam->use_ctr)
+ npc_mcam_free_counter(mbox, ctr);
- for (i = 0; i < NPC_MCAM_KEY_X4_WORDS; i++) {
- req->entry_data.kw[i] = mcam->mcam_data[i];
- req->entry_data.kw_mask[i] = mcam->mcam_mask[i];
+ return rc;
+ }
+ req->entry = mcam->mcam_id;
+ req->intf = mcam->nix_intf;
+ req->enable_entry = mcam->enable;
+ req->entry_data.action = mcam->npc_action;
+ req->entry_data.vtag_action = mcam->vtag_action;
+ if (mcam->use_ctr) {
+ req->set_cntr = 1;
+ req->cntr = mcam->ctr_id;
+ }
+
+ for (i = 0; i < NPC_MCAM_KEY_X4_WORDS; i++) {
+ req->entry_data.kw[i] = mcam->mcam_data[i];
+ req->entry_data.kw_mask[i] = mcam->mcam_mask[i];
+ }
}
rc = mbox_process_msg(mbox, (void *)&rsp);
mbox_put(mbox);
return rc;
}
+static void
+npc_mcam_kex_cfg_dump(struct npc_cn20k_get_kex_cfg_rsp *kex_rsp)
+{
+ for (int i = 0; i < NPC_MAX_INTF; i++) {
+ for (int j = 0; j < NPC_MAX_EXTRACTOR; j++) {
+ if (kex_rsp->intf_extr[i][j] == 0)
+ continue;
+ plt_info("Intf %d, Extr %d: 0x%" PRIx64, i, j, kex_rsp->intf_extr[i][j]);
+ }
+ }
+
+ for (int i = 0; i < NPC_MAX_INTF; i++) {
+ for (int j = 0; j < NPC_MAX_EXTRACTOR; j++) {
+ for (int k = 0; k < NPC_MAX_LT; k++) {
+ if (kex_rsp->intf_extr_lt[i][j][k] == 0)
+ continue;
+ plt_info("Intf %d, Extr %d, LT %d: 0x%" PRIx64, i, j, k,
+ kex_rsp->intf_extr_lt[i][j][k]);
+ }
+ }
+ }
+}
+
+static void
+npc_mcam_process_mkex_cfg_cn20k(struct npc *npc, struct npc_cn20k_get_kex_cfg_rsp *kex_rsp)
+{
+ volatile uint64_t(*q)[NPC_MAX_INTF][NPC_MAX_EXTRACTOR][NPC_MAX_LT];
+ volatile uint64_t(*d)[NPC_MAX_INTF][NPC_MAX_EXTRACTOR];
+ struct npc_xtract_info *x_info = NULL;
+ union npc_kex_ldata_flags_cfg *ld_info = NULL;
+ int ex, lt, ix;
+ npc_dxcfg_cn20k_t *p;
+ npc_lid_cn20k_t *l;
+ uint64_t keyw;
+ uint64_t val;
+
+ npc->keyx_supp_nmask[NPC_MCAM_RX] = kex_rsp->rx_keyx_cfg & 0x7fffffffULL;
+ npc->keyx_supp_nmask[NPC_MCAM_TX] = kex_rsp->tx_keyx_cfg & 0x7fffffffULL;
+ npc->keyx_len[NPC_MCAM_RX] = npc_supp_key_len(npc->keyx_supp_nmask[NPC_MCAM_RX]);
+ npc->keyx_len[NPC_MCAM_TX] = npc_supp_key_len(npc->keyx_supp_nmask[NPC_MCAM_TX]);
+
+ keyw = (kex_rsp->rx_keyx_cfg >> 32) & 0x7ULL;
+ npc->keyw[NPC_MCAM_RX] = keyw;
+ keyw = (kex_rsp->tx_keyx_cfg >> 32) & 0x7ULL;
+ npc->keyw[NPC_MCAM_TX] = keyw;
+
+ p = &npc->prx_dxcfg_cn20k;
+ l = &npc->lid_cfg;
+ q = (volatile uint64_t(*)[][NPC_MAX_EXTRACTOR][NPC_MAX_LT])(&kex_rsp->intf_extr_lt);
+ d = (volatile uint64_t(*)[][NPC_MAX_EXTRACTOR])(&kex_rsp->intf_extr);
+ for (ix = 0; ix < NPC_MAX_INTF; ix++) {
+ for (ex = 0; ex < NPC_MAX_EXTRACTOR; ex++) {
+ val = (*d)[ix][ex];
+ ld_info = &(*l)[ix][ex];
+ ld_info->s.lid = (val & 0x7);
+ for (lt = 0; lt < NPC_MAX_LT; lt++) {
+ x_info = &(*p)[ix][ex][lt].xtract;
+ val = (*q)[ix][ex][lt];
+ npc_update_kex_info(x_info, val);
+ }
+ }
+ }
+}
+
static void
npc_mcam_process_mkex_cfg(struct npc *npc, struct npc_get_kex_cfg_rsp *kex_rsp)
{
@@ -522,20 +689,38 @@ int
npc_mcam_fetch_kex_cfg(struct npc *npc)
{
struct npc_get_kex_cfg_rsp *kex_rsp;
+ struct npc_cn20k_get_kex_cfg_rsp *kex_rsp_20k;
struct mbox *mbox = mbox_get(npc->mbox);
int rc = 0;
- mbox_alloc_msg_npc_get_kex_cfg(mbox);
- rc = mbox_process_msg(mbox, (void *)&kex_rsp);
- if (rc) {
- plt_err("Failed to fetch NPC KEX config");
- goto done;
- }
- mbox_memcpy((char *)npc->profile_name, kex_rsp->mkex_pfl_name, MKEX_NAME_LEN);
+ if (!roc_model_is_cn20k()) {
+ mbox_alloc_msg_npc_get_kex_cfg(mbox);
+ rc = mbox_process_msg(mbox, (void *)&kex_rsp);
+ if (rc) {
+ plt_err("Failed to fetch NPC KEX config");
+ goto done;
+ }
- npc->exact_match_ena = (kex_rsp->rx_keyx_cfg >> 40) & 0xF;
- npc_mcam_process_mkex_cfg(npc, kex_rsp);
+ mbox_memcpy((char *)npc->profile_name, kex_rsp->mkex_pfl_name, MKEX_NAME_LEN);
+
+ npc->exact_match_ena = (kex_rsp->rx_keyx_cfg >> 40) & 0xF;
+ npc_mcam_process_mkex_cfg(npc, kex_rsp);
+ } else {
+ mbox_alloc_msg_npc_cn20k_get_kex_cfg(mbox);
+ rc = mbox_process_msg(mbox, (void *)&kex_rsp_20k);
+ if (rc) {
+ plt_err("Failed to fetch NPC KEX config");
+ goto done;
+ }
+
+ mbox_memcpy((char *)npc->profile_name, kex_rsp_20k->mkex_pfl_name, MKEX_NAME_LEN);
+
+ npc->exact_match_ena = (kex_rsp_20k->rx_keyx_cfg >> 40) & 0xF;
+ npc_mcam_process_mkex_cfg_cn20k(npc, kex_rsp_20k);
+ if (npc->enable_debug)
+ npc_mcam_kex_cfg_dump(kex_rsp_20k);
+ }
done:
mbox_put(mbox);
@@ -543,7 +728,7 @@ npc_mcam_fetch_kex_cfg(struct npc *npc)
}
static void
-npc_mcam_set_channel(struct roc_npc_flow *flow, struct npc_mcam_write_entry_req *req,
+npc_mcam_set_channel(struct roc_npc_flow *flow, struct npc_cn20k_mcam_write_entry_req *req,
uint16_t channel, uint16_t chan_mask, bool is_second_pass)
{
uint16_t chan = 0, mask = 0;
@@ -552,6 +737,7 @@ npc_mcam_set_channel(struct roc_npc_flow *flow, struct npc_mcam_write_entry_req
req->entry_data.kw_mask[0] &= ~(GENMASK(11, 0));
flow->mcam_data[0] &= ~(GENMASK(11, 0));
flow->mcam_mask[0] &= ~(GENMASK(11, 0));
+
chan = channel;
mask = chan_mask;
@@ -579,11 +765,12 @@ npc_mcam_set_channel(struct roc_npc_flow *flow, struct npc_mcam_write_entry_req
flow->mcam_mask[0] |= (uint64_t)mask;
}
+#define NPC_PF_FUNC_WIDTH 2
+#define NPC_KEX_PF_FUNC_MASK 0xFFFF
+
static int
npc_mcam_set_pf_func(struct npc *npc, struct roc_npc_flow *flow, uint16_t pf_func)
{
-#define NPC_PF_FUNC_WIDTH 2
-#define NPC_KEX_PF_FUNC_MASK 0xFFFF
uint16_t nr_bytes, hdr_offset, key_offset, pf_func_offset;
uint8_t *flow_mcam_data, *flow_mcam_mask;
struct npc_lid_lt_xtract_info *xinfo;
@@ -618,10 +805,48 @@ npc_mcam_set_pf_func(struct npc *npc, struct roc_npc_flow *flow, uint16_t pf_fun
return 0;
}
+static int
+npc_mcam_set_pf_func_cn20k(struct npc *npc, struct roc_npc_flow *flow, uint16_t pf_func)
+{
+ uint16_t nr_bytes, hdr_offset, key_offset, pf_func_offset;
+ struct npc_lid_lt_xtract_info_cn20k *xinfo;
+ uint8_t *flow_mcam_data, *flow_mcam_mask;
+ bool pffunc_found = false;
+ uint16_t mask = 0xFFFF;
+ int i;
+
+ flow_mcam_data = (uint8_t *)flow->mcam_data;
+ flow_mcam_mask = (uint8_t *)flow->mcam_mask;
+
+ xinfo = npc->prx_dxcfg_cn20k[NIX_INTF_TX][NPC_LID_LA];
+
+ for (i = 0; i < NPC_MAX_LT; i++) {
+ nr_bytes = xinfo[i].xtract.len;
+ hdr_offset = xinfo[i].xtract.hdr_off;
+ key_offset = xinfo[i].xtract.key_off;
+
+ if (hdr_offset > 0 || nr_bytes < NPC_PF_FUNC_WIDTH)
+ continue;
+ else
+ pffunc_found = true;
+
+ pf_func_offset = key_offset + nr_bytes - NPC_PF_FUNC_WIDTH;
+ memcpy((void *)&flow_mcam_data[pf_func_offset], (uint8_t *)&pf_func,
+ NPC_PF_FUNC_WIDTH);
+ memcpy((void *)&flow_mcam_mask[pf_func_offset], (uint8_t *)&mask,
+ NPC_PF_FUNC_WIDTH);
+ }
+ if (!pffunc_found)
+ return -EINVAL;
+
+ return 0;
+}
+
int
npc_mcam_alloc_and_write(struct npc *npc, struct roc_npc_flow *flow, struct npc_parse_state *pst)
{
- struct npc_mcam_write_entry_req *req;
+ struct npc_cn20k_mcam_write_entry_req *cn20k_req;
+ struct npc_cn20k_mcam_write_entry_req req;
struct nix_inl_dev *inl_dev = NULL;
struct mbox *mbox = npc->mbox;
struct mbox_msghdr *rsp;
@@ -655,6 +880,12 @@ npc_mcam_alloc_and_write(struct npc *npc, struct roc_npc_flow *flow, struct npc_
return rc;
}
+ if (roc_model_is_cn20k()) {
+ req.hw_prio = flow->priority;
+ flow->key_type = npc_get_key_type(npc, flow);
+ req.req_kw_type = flow->key_type;
+ }
+
if (flow->nix_intf == NIX_INTF_RX && flow->is_inline_dev && inl_dev &&
inl_dev->ipsec_index && inl_dev->is_multi_channel) {
if (inl_dev->curr_ipsec_idx >= inl_dev->alloc_ipsec_rules)
@@ -672,14 +903,17 @@ npc_mcam_alloc_and_write(struct npc *npc, struct roc_npc_flow *flow, struct npc_
}
if (flow->nix_intf == NIX_INTF_TX) {
- uint16_t pf_func = flow->tx_pf_func;
+ uint16_t pffunc = flow->tx_pf_func;
if (flow->has_rep)
- pf_func = flow->rep_pf_func;
+ pffunc = flow->rep_pf_func;
- pf_func = plt_cpu_to_be_16(pf_func);
+ pffunc = plt_cpu_to_be_16(pffunc);
- rc = npc_mcam_set_pf_func(npc, flow, pf_func);
+ if (roc_model_is_cn20k())
+ rc = npc_mcam_set_pf_func_cn20k(npc, flow, pffunc);
+ else
+ rc = npc_mcam_set_pf_func(npc, flow, pffunc);
if (rc)
return rc;
}
@@ -708,20 +942,14 @@ npc_mcam_alloc_and_write(struct npc *npc, struct roc_npc_flow *flow, struct npc_
}
}
- req = mbox_alloc_msg_npc_mcam_write_entry(mbox_get(mbox));
- if (req == NULL) {
- rc = -ENOSPC;
- goto exit;
- }
- req->set_cntr = flow->use_ctr;
- req->cntr = flow->ctr_id;
- req->entry = entry;
+ req.cntr = flow->ctr_id;
+ req.entry = entry;
- req->intf = (flow->nix_intf == NIX_INTF_RX) ? NPC_MCAM_RX : NPC_MCAM_TX;
- req->enable_entry = 1;
+ req.intf = (flow->nix_intf == NIX_INTF_RX) ? NPC_MCAM_RX : NPC_MCAM_TX;
+ req.enable_entry = 1;
if (flow->nix_intf == NIX_INTF_RX)
flow->npc_action |= (uint64_t)flow->recv_queue << 20;
- req->entry_data.action = flow->npc_action;
+ req.entry_data.action = flow->npc_action;
/*
* Driver sets vtag action on per interface basis, not
@@ -735,38 +963,38 @@ npc_mcam_alloc_and_write(struct npc *npc, struct roc_npc_flow *flow, struct npc_
*
* Second approach is used now.
*/
- req->entry_data.vtag_action = flow->vtag_action;
+ req.entry_data.vtag_action = flow->vtag_action;
for (idx = 0; idx < ROC_NPC_MAX_MCAM_WIDTH_DWORDS; idx++) {
- req->entry_data.kw[idx] = flow->mcam_data[idx];
- req->entry_data.kw_mask[idx] = flow->mcam_mask[idx];
+ req.entry_data.kw[idx] = flow->mcam_data[idx];
+ req.entry_data.kw_mask[idx] = flow->mcam_mask[idx];
}
if (flow->nix_intf == NIX_INTF_RX) {
if (inl_dev && inl_dev->is_multi_channel &&
(flow->npc_action & NIX_RX_ACTIONOP_UCAST_IPSEC)) {
pf_func = nix_inl_dev_pffunc_get();
- req->entry_data.action &= ~(GENMASK(19, 4));
- req->entry_data.action |= (uint64_t)pf_func << 4;
+ req.entry_data.action &= ~(GENMASK(19, 4));
+ req.entry_data.action |= (uint64_t)pf_func << 4;
flow->npc_action &= ~(GENMASK(19, 4));
flow->npc_action |= (uint64_t)pf_func << 4;
- npc_mcam_set_channel(flow, req, inl_dev->channel, inl_dev->chan_mask,
+ npc_mcam_set_channel(flow, &req, inl_dev->channel, inl_dev->chan_mask,
false);
} else if (flow->has_rep) {
pf_func = (flow->rep_act_pf_func == 0) ? flow->rep_pf_func :
flow->rep_act_pf_func;
- req->entry_data.action &= ~(GENMASK(19, 4));
- req->entry_data.action |= (uint64_t)pf_func << 4;
+ req.entry_data.action &= ~(GENMASK(19, 4));
+ req.entry_data.action |= (uint64_t)pf_func << 4;
flow->npc_action &= ~(GENMASK(19, 4));
flow->npc_action |= (uint64_t)pf_func << 4;
- npc_mcam_set_channel(flow, req, flow->rep_channel, (BIT_ULL(12) - 1),
+ npc_mcam_set_channel(flow, &req, flow->rep_channel, (BIT_ULL(12) - 1),
false);
} else if (npc->is_sdp_link) {
- npc_mcam_set_channel(flow, req, npc->sdp_channel, npc->sdp_channel_mask,
+ npc_mcam_set_channel(flow, &req, npc->sdp_channel, npc->sdp_channel_mask,
pst->is_second_pass_rule);
} else {
- npc_mcam_set_channel(flow, req, npc->channel, (BIT_ULL(12) - 1),
+ npc_mcam_set_channel(flow, &req, npc->channel, (BIT_ULL(12) - 1),
pst->is_second_pass_rule);
}
/*
@@ -779,25 +1007,66 @@ npc_mcam_alloc_and_write(struct npc *npc, struct roc_npc_flow *flow, struct npc_
la_offset *= 4;
mask = ~((0xfULL << la_offset));
- req->entry_data.kw[0] &= mask;
- req->entry_data.kw_mask[0] &= mask;
+ req.entry_data.kw[0] &= mask;
+ req.entry_data.kw_mask[0] &= mask;
flow->mcam_data[0] &= mask;
flow->mcam_mask[0] &= mask;
if (pst->is_second_pass_rule) {
- req->entry_data.kw[0] |= ((uint64_t)NPC_LT_LA_CPT_HDR) << la_offset;
- req->entry_data.kw_mask[0] |= (0xFULL << la_offset);
+ req.entry_data.kw[0] |= ((uint64_t)NPC_LT_LA_CPT_HDR) << la_offset;
+ req.entry_data.kw_mask[0] |= (0xFULL << la_offset);
flow->mcam_data[0] |= ((uint64_t)NPC_LT_LA_CPT_HDR) << la_offset;
flow->mcam_mask[0] |= (0xFULL << la_offset);
} else {
/* Mask ltype ETHER (0x2) and CPT_HDR (0xa) */
- req->entry_data.kw[0] |= (0x2ULL << la_offset);
- req->entry_data.kw_mask[0] |= (0x7ULL << la_offset);
+ req.entry_data.kw[0] |= (0x2ULL << la_offset);
+ req.entry_data.kw_mask[0] |= (0x7ULL << la_offset);
flow->mcam_data[0] |= (0x2ULL << la_offset);
flow->mcam_mask[0] |= (0x7ULL << la_offset);
}
}
}
+ if (roc_model_is_cn20k()) {
+ cn20k_req = mbox_alloc_msg_npc_cn20k_mcam_write_entry(mbox_get(mbox));
+ if (cn20k_req == NULL) {
+ mbox_put(mbox);
+ if (flow->use_ctr)
+ npc_mcam_free_counter(mbox, ctr);
+
+ return rc;
+ }
+ cn20k_req->entry = req.entry;
+ cn20k_req->intf = req.intf;
+ cn20k_req->enable_entry = req.enable_entry;
+ cn20k_req->entry_data.action = req.entry_data.action;
+ cn20k_req->entry_data.vtag_action = req.entry_data.vtag_action;
+ cn20k_req->hw_prio = req.hw_prio;
+ cn20k_req->req_kw_type = req.req_kw_type;
+ if (flow->use_ctr)
+ cn20k_req->cntr = req.cntr;
+
+ mbox_memcpy(&cn20k_req->entry_data, &req.entry_data,
+ sizeof(struct cn20k_mcam_entry));
+ } else {
+ struct npc_mcam_write_entry_req *req_leg;
+
+ req_leg = mbox_alloc_msg_npc_mcam_write_entry(mbox_get(mbox));
+ if (req_leg == NULL) {
+ rc = -ENOSPC;
+ goto exit;
+ }
+ for (idx = 0; idx < NPC_MAX_KWS_IN_KEY; idx++) {
+ req_leg->entry_data.kw[idx] = req.entry_data.kw[idx];
+ req_leg->entry_data.kw_mask[idx] = req.entry_data.kw_mask[idx];
+ }
+ req_leg->entry = req.entry;
+ req_leg->intf = req.intf;
+ req_leg->enable_entry = req.enable_entry;
+ req_leg->cntr = req.cntr;
+ req_leg->entry_data.action = req.entry_data.action;
+ req_leg->entry_data.vtag_action = req.entry_data.vtag_action;
+ req_leg->set_cntr = flow->use_ctr;
+ }
rc = mbox_process_msg(mbox, (void *)&rsp);
if (rc != 0)
goto exit;
@@ -810,7 +1079,7 @@ npc_mcam_alloc_and_write(struct npc *npc, struct roc_npc_flow *flow, struct npc_
exit:
mbox_put(mbox);
- if (rc)
+ if (rc && flow->is_sampling_rule)
roc_nix_mcast_list_free(npc->mbox, flow->mcast_grp_index);
return rc;
}
@@ -821,9 +1090,14 @@ npc_set_vlan_ltype(struct npc_parse_state *pst)
uint64_t val, mask;
uint8_t lb_offset;
- lb_offset =
- plt_popcount32(pst->npc->keyx_supp_nmask[pst->nix_intf] &
- ((1ULL << NPC_LTYPE_LB_OFFSET) - 1));
+ if (roc_model_is_cn20k()) {
+ lb_offset = plt_popcount32(pst->npc->keyx_supp_nmask[pst->nix_intf] &
+ ((1ULL << NPC_CN20K_LTYPE_LB_OFFSET) - 1));
+
+ } else {
+ lb_offset = plt_popcount32(pst->npc->keyx_supp_nmask[pst->nix_intf] &
+ ((1ULL << NPC_LTYPE_LB_OFFSET) - 1));
+ }
lb_offset *= 4;
mask = ~((0xfULL << lb_offset));
@@ -843,9 +1117,14 @@ npc_set_ipv6ext_ltype_mask(struct npc_parse_state *pst)
uint8_t lc_offset, lcflag_offset;
uint64_t val, mask;
- lc_offset =
- plt_popcount32(pst->npc->keyx_supp_nmask[pst->nix_intf] &
- ((1ULL << NPC_LTYPE_LC_OFFSET) - 1));
+ if (roc_model_is_cn20k()) {
+ lc_offset = plt_popcount32(pst->npc->keyx_supp_nmask[pst->nix_intf] &
+ ((1ULL << NPC_CN20K_LTYPE_LC_OFFSET) - 1));
+
+ } else {
+ lc_offset = plt_popcount32(pst->npc->keyx_supp_nmask[pst->nix_intf] &
+ ((1ULL << NPC_LTYPE_LC_OFFSET) - 1));
+ }
lc_offset *= 4;
mask = ~((0xfULL << lc_offset));
@@ -867,8 +1146,14 @@ npc_set_ipv6ext_ltype_mask(struct npc_parse_state *pst)
* zero in LFLAG.
*/
if (pst->npc->keyx_supp_nmask[pst->nix_intf] & (1ULL << NPC_LFLAG_LC_OFFSET)) {
- lcflag_offset = plt_popcount32(pst->npc->keyx_supp_nmask[pst->nix_intf] &
- ((1ULL << NPC_LFLAG_LC_OFFSET) - 1));
+ if (roc_model_is_cn20k()) {
+ lcflag_offset = plt_popcount32(pst->npc->keyx_supp_nmask[pst->nix_intf] &
+ ((1ULL << NPC_CN20K_LFLAG_LC_OFFSET) - 1));
+
+ } else {
+ lcflag_offset = plt_popcount32(pst->npc->keyx_supp_nmask[pst->nix_intf] &
+ ((1ULL << NPC_LFLAG_LC_OFFSET) - 1));
+ }
lcflag_offset *= 4;
mask = (0xfULL << lcflag_offset);
@@ -881,14 +1166,12 @@ npc_set_ipv6ext_ltype_mask(struct npc_parse_state *pst)
int
npc_program_mcam(struct npc *npc, struct npc_parse_state *pst, bool mcam_alloc)
{
- struct npc_mcam_read_base_rule_rsp *base_rule_rsp;
/* This is non-LDATA part in search key */
uint64_t key_data[2] = {0ULL, 0ULL};
uint64_t key_mask[2] = {0ULL, 0ULL};
int key_len, bit = 0, index, rc = 0;
struct nix_inl_dev *inl_dev = NULL;
int intf = pst->flow->nix_intf;
- struct mcam_entry *base_entry;
bool skip_base_rule = false;
int off, idx, data_off = 0;
uint8_t lid, mask, data;
@@ -908,40 +1191,79 @@ npc_program_mcam(struct npc *npc, struct npc_parse_state *pst, bool mcam_alloc)
data_off *= 4;
index = 0;
- for (lid = 0; lid < NPC_MAX_LID; lid++) {
- /* Offset in key */
- off = NPC_PARSE_KEX_S_LID_OFFSET(lid);
- lt = pst->lt[lid] & 0xf;
- flags = pst->flags[lid] & 0xff;
+ if (!roc_model_is_cn20k()) {
+ for (lid = 0; lid < NPC_MAX_LID; lid++) {
+ /* Offset in key */
+ off = NPC_PARSE_KEX_S_LID_OFFSET(lid);
+ lt = pst->lt[lid] & 0xf;
+ flags = pst->flags[lid] & 0xff;
- /* NPC_LAYER_KEX_S */
- layer_info = ((npc->keyx_supp_nmask[intf] >> off) & 0x7);
+ /* NPC_LAYER_KEX_S */
+ layer_info = ((npc->keyx_supp_nmask[intf] >> off) & 0x7);
+ if (!layer_info)
+ continue;
- if (layer_info) {
for (idx = 0; idx <= 2; idx++) {
- if (layer_info & (1 << idx)) {
- if (idx == 2) {
- data = lt;
- mask = 0xf;
- } else if (idx == 1) {
- data = ((flags >> 4) & 0xf);
- mask = ((flags >> 4) & 0xf);
- } else {
- data = (flags & 0xf);
- mask = (flags & 0xf);
- }
-
- if (data_off >= 64) {
- data_off = 0;
- index++;
- }
- key_data[index] |= ((uint64_t)data << data_off);
-
- if (lt == 0)
- mask = 0;
- key_mask[index] |= ((uint64_t)mask << data_off);
- data_off += 4;
+ if (!(layer_info & (1 << idx)))
+ continue;
+
+ if (idx == 2) {
+ data = lt;
+ mask = 0xf;
+ } else if (idx == 1) {
+ data = ((flags >> 4) & 0xf);
+ mask = ((flags >> 4) & 0xf);
+ } else {
+ data = (flags & 0xf);
+ mask = (flags & 0xf);
+ }
+
+ if (data_off >= 64) {
+ data_off = 0;
+ index++;
}
+ key_data[index] |= ((uint64_t)data << data_off);
+
+ if (lt == 0)
+ mask = 0;
+ key_mask[index] |= ((uint64_t)mask << data_off);
+ data_off += 4;
+ }
+ }
+ } else {
+ for (lid = 0; lid < NPC_MAX_LID; lid++) {
+ /* Offset in key */
+ off = NPC_PARSE_KEX_S_LID_OFFSET_CN20K(lid);
+ lt = pst->lt[lid] & 0xf;
+ flags = pst->flags[lid] & 0xf;
+
+ /* NPC_LAYER_KEX_S */
+ layer_info = ((npc->keyx_supp_nmask[intf] >> off) & 0x3);
+ if (!layer_info)
+ continue;
+
+ for (idx = 0; idx <= 1; idx++) {
+ if (!(layer_info & (1 << idx)))
+ continue;
+
+ if (idx == 1) {
+ data = lt;
+ mask = 0xf;
+ } else {
+ data = (flags & 0xf);
+ mask = (flags & 0xf);
+ }
+
+ if (data_off >= 64) {
+ data_off = 0;
+ index++;
+ }
+ key_data[index] |= ((uint64_t)data << data_off);
+
+ if (lt == 0)
+ mask = 0;
+ key_mask[index] |= ((uint64_t)mask << data_off);
+ data_off += 4;
}
}
}
@@ -971,17 +1293,39 @@ npc_program_mcam(struct npc *npc, struct npc_parse_state *pst, bool mcam_alloc)
else
mbox = mbox_get(npc->mbox);
(void)mbox_alloc_msg_npc_read_base_steer_rule(mbox);
- rc = mbox_process_msg(mbox, (void *)&base_rule_rsp);
- if (rc) {
+ if (roc_model_is_cn20k()) {
+ struct npc_cn20k_mcam_read_base_rule_rsp *base_rule_rsp;
+ struct cn20k_mcam_entry *base_entry;
+
+ rc = mbox_process_msg(mbox, (void *)&base_rule_rsp);
+ if (rc) {
+ mbox_put(mbox);
+ plt_err("Failed to fetch VF's base MCAM entry");
+ return rc;
+ }
mbox_put(mbox);
- plt_err("Failed to fetch VF's base MCAM entry");
- return rc;
- }
- mbox_put(mbox);
- base_entry = &base_rule_rsp->entry_data;
- for (idx = 0; idx < ROC_NPC_MAX_MCAM_WIDTH_DWORDS; idx++) {
- pst->flow->mcam_data[idx] |= base_entry->kw[idx];
- pst->flow->mcam_mask[idx] |= base_entry->kw_mask[idx];
+ base_entry = &base_rule_rsp->entry;
+ for (idx = 0; idx < ROC_NPC_MAX_MCAM_WIDTH_DWORDS; idx++) {
+ pst->flow->mcam_data[idx] |= base_entry->kw[idx];
+ pst->flow->mcam_mask[idx] |= base_entry->kw_mask[idx];
+ }
+
+ } else {
+ struct npc_mcam_read_base_rule_rsp *base_rule_rsp;
+ struct mcam_entry *base_entry;
+
+ rc = mbox_process_msg(mbox, (void *)&base_rule_rsp);
+ if (rc) {
+ mbox_put(mbox);
+ plt_err("Failed to fetch VF's base MCAM entry");
+ return rc;
+ }
+ mbox_put(mbox);
+ base_entry = &base_rule_rsp->entry_data;
+ for (idx = 0; idx < ROC_NPC_MAX_MCAM_WIDTH_DWORDS; idx++) {
+ pst->flow->mcam_data[idx] |= base_entry->kw[idx];
+ pst->flow->mcam_mask[idx] |= base_entry->kw_mask[idx];
+ }
}
}
diff --git a/drivers/common/cnxk/roc_npc_mcam_dump.c b/drivers/common/cnxk/roc_npc_mcam_dump.c
index ebd2dd69c2..bedf6db37c 100644
--- a/drivers/common/cnxk/roc_npc_mcam_dump.c
+++ b/drivers/common/cnxk/roc_npc_mcam_dump.c
@@ -35,6 +35,33 @@
#define NIX_TX_VTAGACT_VTAG1_OP_MASK GENMASK(45, 44)
#define NIX_TX_VTAGACT_VTAG1_DEF_MASK GENMASK(57, 48)
+union npc_rx_parse_nibble_cn20k_u {
+ struct {
+ uint64_t chan : 3;
+ uint64_t errlev : 1;
+ uint64_t errcode : 2;
+ uint64_t l2l3bm : 1;
+ uint64_t laflags : 1;
+ uint64_t latype : 1;
+ uint64_t lbflags : 1;
+ uint64_t lbtype : 1;
+ uint64_t lcflags : 1;
+ uint64_t lctype : 1;
+ uint64_t ldflags : 1;
+ uint64_t ldtype : 1;
+ uint64_t leflags : 1;
+ uint64_t letype : 1;
+ uint64_t lfflags : 1;
+ uint64_t lftype : 1;
+ uint64_t lgflags : 1;
+ uint64_t lgtype : 1;
+ uint64_t lhflags : 1;
+ uint64_t lhtype : 1;
+ uint64_t reserved : 41;
+ } s __plt_packed;
+ uint64_t u;
+};
+
struct npc_rx_parse_nibble_s {
uint16_t chan : 3;
uint16_t errlev : 1;
@@ -181,8 +208,135 @@ npc_get_nibbles(struct roc_npc_flow *flow, uint16_t size, uint32_t bit_offset)
}
static void
-npc_flow_print_parse_nibbles(FILE *file, struct roc_npc_flow *flow,
- uint64_t parse_nibbles)
+npc_flow_print_parse_nibbles_cn20k(FILE *file, struct roc_npc_flow *flow, uint64_t parse_nibbles)
+{
+ union npc_rx_parse_nibble_cn20k_u rx_parse;
+ uint32_t data, offset = 0;
+
+ rx_parse.u = parse_nibbles;
+
+ if (rx_parse.s.chan) {
+ data = npc_get_nibbles(flow, 3, offset);
+ fprintf(file, "\tNPC_PARSE_NIBBLE_CHAN:%#03X\n", data);
+ offset += 12;
+ }
+
+ if (rx_parse.s.errlev) {
+ data = npc_get_nibbles(flow, 1, offset);
+ fprintf(file, "\tNPC_PARSE_NIBBLE_ERRLEV:%#X\n", data);
+ offset += 4;
+ }
+
+ if (rx_parse.s.errcode) {
+ data = npc_get_nibbles(flow, 2, offset);
+ fprintf(file, "\tNPC_PARSE_NIBBLE_ERRCODE:%#02X\n", data);
+ offset += 8;
+ }
+
+ if (rx_parse.s.l2l3bm) {
+ data = npc_get_nibbles(flow, 1, offset);
+ fprintf(file, "\tNPC_PARSE_NIBBLE_L2L3_BCAST:%#X\n", data);
+ offset += 4;
+ }
+
+ if (rx_parse.s.laflags) {
+ data = npc_get_nibbles(flow, 1, offset);
+ fprintf(file, "\tNPC_PARSE_NIBBLE_LA_FLAGS:%#02X\n", data);
+ offset += 8;
+ }
+
+ if (rx_parse.s.latype) {
+ data = npc_get_nibbles(flow, 1, offset);
+ fprintf(file, "\tNPC_PARSE_NIBBLE_LA_LTYPE:%s\n", ltype_str[NPC_LID_LA][data]);
+ offset += 4;
+ }
+
+ if (rx_parse.s.lbflags) {
+ data = npc_get_nibbles(flow, 1, offset);
+ fprintf(file, "\tNPC_PARSE_NIBBLE_LB_FLAGS:%#02X\n", data);
+ offset += 8;
+ }
+
+ if (rx_parse.s.lbtype) {
+ data = npc_get_nibbles(flow, 1, offset);
+ fprintf(file, "\tNPC_PARSE_NIBBLE_LB_LTYPE:%s\n", ltype_str[NPC_LID_LB][data]);
+ offset += 4;
+ }
+
+ if (rx_parse.s.lcflags) {
+ data = npc_get_nibbles(flow, 1, offset);
+ fprintf(file, "\tNPC_PARSE_NIBBLE_LC_FLAGS:%#02X\n", data);
+ offset += 8;
+ }
+
+ if (rx_parse.s.lctype) {
+ data = npc_get_nibbles(flow, 1, offset);
+ fprintf(file, "\tNPC_PARSE_NIBBLE_LC_LTYPE:%s\n", ltype_str[NPC_LID_LC][data]);
+ offset += 4;
+ }
+
+ if (rx_parse.s.ldflags) {
+ data = npc_get_nibbles(flow, 1, offset);
+ fprintf(file, "\tNPC_PARSE_NIBBLE_LD_FLAGS:%#02X\n", data);
+ offset += 8;
+ }
+
+ if (rx_parse.s.ldtype) {
+ data = npc_get_nibbles(flow, 1, offset);
+ fprintf(file, "\tNPC_PARSE_NIBBLE_LD_LTYPE:%s\n", ltype_str[NPC_LID_LD][data]);
+ offset += 4;
+ }
+
+ if (rx_parse.s.leflags) {
+ data = npc_get_nibbles(flow, 1, offset);
+ fprintf(file, "\tNPC_PARSE_NIBBLE_LE_FLAGS:%#02X\n", data);
+ offset += 8;
+ }
+
+ if (rx_parse.s.letype) {
+ data = npc_get_nibbles(flow, 1, offset);
+ fprintf(file, "\tNPC_PARSE_NIBBLE_LE_LTYPE:%s\n", ltype_str[NPC_LID_LE][data]);
+ offset += 4;
+ }
+
+ if (rx_parse.s.lfflags) {
+ data = npc_get_nibbles(flow, 1, offset);
+ fprintf(file, "\tNPC_PARSE_NIBBLE_LF_FLAGS:%#02X\n", data);
+ offset += 8;
+ }
+
+ if (rx_parse.s.lftype) {
+ data = npc_get_nibbles(flow, 1, offset);
+ fprintf(file, "\tNPC_PARSE_NIBBLE_LF_LTYPE:%s\n", ltype_str[NPC_LID_LF][data]);
+ offset += 4;
+ }
+
+ if (rx_parse.s.lgflags) {
+ data = npc_get_nibbles(flow, 1, offset);
+ fprintf(file, "\tNPC_PARSE_NIBBLE_LG_FLAGS:%#02X\n", data);
+ offset += 8;
+ }
+
+ if (rx_parse.s.lgtype) {
+ data = npc_get_nibbles(flow, 1, offset);
+ fprintf(file, "\tNPC_PARSE_NIBBLE_LG_LTYPE:%s\n", ltype_str[NPC_LID_LG][data]);
+ offset += 4;
+ }
+
+ if (rx_parse.s.lhflags) {
+ data = npc_get_nibbles(flow, 1, offset);
+ fprintf(file, "\tNPC_PARSE_NIBBLE_LH_FLAGS:%#02X\n", data);
+ }
+
+ if (rx_parse.s.lhtype) {
+ data = npc_get_nibbles(flow, 1, offset);
+ fprintf(file, "\tNPC_PARSE_NIBBLE_LH_LTYPE:%s\n", ltype_str[NPC_LID_LH][data]);
+ offset += 4;
+ }
+}
+
+static void
+npc_flow_print_parse_nibbles_legacy(FILE *file, struct roc_npc_flow *flow, uint64_t parse_nibbles)
{
struct npc_rx_parse_nibble_s *rx_parse;
uint32_t data, offset = 0;
@@ -221,8 +375,7 @@ npc_flow_print_parse_nibbles(FILE *file, struct roc_npc_flow *flow,
if (rx_parse->latype) {
data = npc_get_nibbles(flow, 1, offset);
- fprintf(file, "\tNPC_PARSE_NIBBLE_LA_LTYPE:%s\n",
- ltype_str[NPC_LID_LA][data]);
+ fprintf(file, "\tNPC_PARSE_NIBBLE_LA_LTYPE:%s\n", ltype_str[NPC_LID_LA][data]);
offset += 4;
}
@@ -234,8 +387,7 @@ npc_flow_print_parse_nibbles(FILE *file, struct roc_npc_flow *flow,
if (rx_parse->lbtype) {
data = npc_get_nibbles(flow, 1, offset);
- fprintf(file, "\tNPC_PARSE_NIBBLE_LB_LTYPE:%s\n",
- ltype_str[NPC_LID_LB][data]);
+ fprintf(file, "\tNPC_PARSE_NIBBLE_LB_LTYPE:%s\n", ltype_str[NPC_LID_LB][data]);
offset += 4;
}
@@ -247,8 +399,7 @@ npc_flow_print_parse_nibbles(FILE *file, struct roc_npc_flow *flow,
if (rx_parse->lctype) {
data = npc_get_nibbles(flow, 1, offset);
- fprintf(file, "\tNPC_PARSE_NIBBLE_LC_LTYPE:%s\n",
- ltype_str[NPC_LID_LC][data]);
+ fprintf(file, "\tNPC_PARSE_NIBBLE_LC_LTYPE:%s\n", ltype_str[NPC_LID_LC][data]);
offset += 4;
}
@@ -260,8 +411,7 @@ npc_flow_print_parse_nibbles(FILE *file, struct roc_npc_flow *flow,
if (rx_parse->ldtype) {
data = npc_get_nibbles(flow, 1, offset);
- fprintf(file, "\tNPC_PARSE_NIBBLE_LD_LTYPE:%s\n",
- ltype_str[NPC_LID_LD][data]);
+ fprintf(file, "\tNPC_PARSE_NIBBLE_LD_LTYPE:%s\n", ltype_str[NPC_LID_LD][data]);
offset += 4;
}
@@ -273,8 +423,7 @@ npc_flow_print_parse_nibbles(FILE *file, struct roc_npc_flow *flow,
if (rx_parse->letype) {
data = npc_get_nibbles(flow, 1, offset);
- fprintf(file, "\tNPC_PARSE_NIBBLE_LE_LTYPE:%s\n",
- ltype_str[NPC_LID_LE][data]);
+ fprintf(file, "\tNPC_PARSE_NIBBLE_LE_LTYPE:%s\n", ltype_str[NPC_LID_LE][data]);
offset += 4;
}
@@ -286,8 +435,7 @@ npc_flow_print_parse_nibbles(FILE *file, struct roc_npc_flow *flow,
if (rx_parse->lftype) {
data = npc_get_nibbles(flow, 1, offset);
- fprintf(file, "\tNPC_PARSE_NIBBLE_LF_LTYPE:%s\n",
- ltype_str[NPC_LID_LF][data]);
+ fprintf(file, "\tNPC_PARSE_NIBBLE_LF_LTYPE:%s\n", ltype_str[NPC_LID_LF][data]);
offset += 4;
}
@@ -299,8 +447,7 @@ npc_flow_print_parse_nibbles(FILE *file, struct roc_npc_flow *flow,
if (rx_parse->lgtype) {
data = npc_get_nibbles(flow, 1, offset);
- fprintf(file, "\tNPC_PARSE_NIBBLE_LG_LTYPE:%s\n",
- ltype_str[NPC_LID_LG][data]);
+ fprintf(file, "\tNPC_PARSE_NIBBLE_LG_LTYPE:%s\n", ltype_str[NPC_LID_LG][data]);
offset += 4;
}
@@ -311,15 +458,14 @@ npc_flow_print_parse_nibbles(FILE *file, struct roc_npc_flow *flow,
if (rx_parse->lhtype) {
data = npc_get_nibbles(flow, 1, offset);
- fprintf(file, "\tNPC_PARSE_NIBBLE_LH_LTYPE:%s\n",
- ltype_str[NPC_LID_LH][data]);
+ fprintf(file, "\tNPC_PARSE_NIBBLE_LH_LTYPE:%s\n", ltype_str[NPC_LID_LH][data]);
offset += 4;
}
}
static void
-npc_flow_print_xtractinfo(FILE *file, struct npc_xtract_info *lfinfo,
- struct roc_npc_flow *flow, int lid, int lt)
+npc_flow_print_xtractinfo(FILE *file, struct npc_xtract_info *lfinfo, struct roc_npc_flow *flow,
+ int lid, int lt)
{
uint8_t *datastart, *maskstart;
int i;
@@ -374,6 +520,7 @@ static void
npc_flow_dump_patterns(FILE *file, struct npc *npc, struct roc_npc_flow *flow)
{
struct npc_lid_lt_xtract_info *lt_xinfo;
+ struct npc_lid_lt_xtract_info_cn20k *lt_xinfo_cn20k;
struct npc_xtract_info *xinfo;
uint32_t intf, lid, ld, i;
uint64_t parse_nibbles;
@@ -381,19 +528,37 @@ npc_flow_dump_patterns(FILE *file, struct npc *npc, struct roc_npc_flow *flow)
intf = flow->nix_intf;
parse_nibbles = npc->keyx_supp_nmask[intf];
- npc_flow_print_parse_nibbles(file, flow, parse_nibbles);
-
- for (i = 0; i < flow->num_patterns; i++) {
- lid = flow->dump_data[i].lid;
- ltype = flow->dump_data[i].ltype;
- lt_xinfo = &npc->prx_dxcfg[intf][lid][ltype];
-
- for (ld = 0; ld < NPC_MAX_LD; ld++) {
- xinfo = <_xinfo->xtract[ld];
- if (!xinfo->enable)
- continue;
- npc_flow_print_item(file, npc, xinfo, flow, intf, lid,
- ltype, ld);
+ if (roc_model_is_cn20k()) {
+ npc_flow_print_parse_nibbles_cn20k(file, flow, parse_nibbles);
+ for (i = 0; i < flow->num_patterns; i++) {
+ lid = flow->dump_data[i].lid;
+ ltype = flow->dump_data[i].ltype;
+ for (int j = 0; j < NPC_MAX_EXTRACTOR; j++) {
+ union npc_kex_ldata_flags_cfg *lid_info =
+ &npc->lid_cfg[NIX_INTF_RX][j];
+ if (lid_info->s.lid != lid)
+ continue;
+ lt_xinfo_cn20k = &npc->prx_dxcfg_cn20k[intf][j][ltype];
+ xinfo = <_xinfo_cn20k->xtract;
+ if (!xinfo->enable)
+ continue;
+ npc_flow_print_item(file, npc, xinfo, flow, intf, lid, ltype, j);
+ }
+ }
+ } else {
+ npc_flow_print_parse_nibbles_legacy(file, flow, parse_nibbles);
+
+ for (i = 0; i < flow->num_patterns; i++) {
+ lid = flow->dump_data[i].lid;
+ ltype = flow->dump_data[i].ltype;
+ lt_xinfo = &npc->prx_dxcfg[intf][lid][ltype];
+
+ for (ld = 0; ld < NPC_MAX_LD; ld++) {
+ xinfo = <_xinfo->xtract[ld];
+ if (!xinfo->enable)
+ continue;
+ npc_flow_print_item(file, npc, xinfo, flow, intf, lid, ltype, ld);
+ }
}
}
}
@@ -645,7 +810,6 @@ npc_flow_hw_mcam_entry_dump(FILE *file, struct npc *npc, struct roc_npc_flow *fl
uint64_t mcam_data[ROC_NPC_MAX_MCAM_WIDTH_DWORDS];
uint64_t mcam_mask[ROC_NPC_MAX_MCAM_WIDTH_DWORDS];
struct npc_mcam_read_entry_req *mcam_read_req;
- struct npc_mcam_read_entry_rsp *mcam_read_rsp;
struct nix_inl_dev *inl_dev = NULL;
struct idev_cfg *idev;
struct mbox *mbox;
@@ -669,17 +833,34 @@ npc_flow_hw_mcam_entry_dump(FILE *file, struct npc *npc, struct roc_npc_flow *fl
}
mcam_read_req->entry = flow->mcam_id;
- rc = mbox_process_msg(mbox, (void *)&mcam_read_rsp);
- if (rc) {
- mbox_put(mbox);
- plt_err("Failed to fetch MCAM entry:%d", flow->mcam_id);
- return;
- }
- mbox_memcpy(mcam_data, mcam_read_rsp->entry_data.kw, sizeof(mcam_data));
- mbox_memcpy(mcam_mask, mcam_read_rsp->entry_data.kw_mask, sizeof(mcam_data));
- enabled = mcam_read_rsp->enable;
+ if (roc_model_is_cn20k()) {
+ struct npc_cn20k_mcam_read_entry_rsp *mcam_read_rsp;
+
+ rc = mbox_process_msg(mbox, (void *)&mcam_read_rsp);
+ if (rc) {
+ mbox_put(mbox);
+ plt_err("Failed to fetch MCAM entry:%d", flow->mcam_id);
+ return;
+ }
+
+ mbox_memcpy(mcam_data, mcam_read_rsp->entry_data.kw, sizeof(mcam_data));
+ mbox_memcpy(mcam_mask, mcam_read_rsp->entry_data.kw_mask, sizeof(mcam_data));
+ enabled = mcam_read_rsp->enable;
+ } else {
+ struct npc_mcam_read_entry_rsp *mcam_read_rsp;
+ rc = mbox_process_msg(mbox, (void *)&mcam_read_rsp);
+ if (rc) {
+ mbox_put(mbox);
+ plt_err("Failed to fetch MCAM entry:%d", flow->mcam_id);
+ return;
+ }
+
+ mbox_memcpy(mcam_data, mcam_read_rsp->entry_data.kw, sizeof(mcam_data));
+ mbox_memcpy(mcam_mask, mcam_read_rsp->entry_data.kw_mask, sizeof(mcam_data));
+ enabled = mcam_read_rsp->enable;
+ }
fprintf(file, "HW MCAM Data :\n");
for (i = 0; i < ROC_NPC_MAX_MCAM_WIDTH_DWORDS; i++) {
@@ -702,14 +883,18 @@ roc_npc_flow_mcam_dump(FILE *file, struct roc_npc *roc_npc, struct roc_npc_flow
fprintf(file, "MCAM Index:%d\n", flow->mcam_id);
if (flow->ctr_id != NPC_COUNTER_NONE && flow->use_ctr) {
- if (flow->use_pre_alloc)
+ if (flow->use_pre_alloc) {
rc = roc_npc_inl_mcam_read_counter(flow->ctr_id, &count);
- else
- rc = roc_npc_mcam_read_counter(roc_npc, flow->ctr_id, &count);
+ } else {
+ if (roc_model_is_cn20k())
+ rc = roc_npc_mcam_get_stats(roc_npc, flow, &count);
+ else
+ rc = roc_npc_mcam_read_counter(roc_npc, flow->ctr_id, &count);
+ }
if (rc)
return;
- fprintf(file, "Hit count: %" PRIu64 "\n", count);
+ fprintf(file, "Counter_id = 0x%x, Hit count: %" PRIu64 "\n", flow->ctr_id, count);
}
fprintf(file, "Interface :%s (%d)\n", intf_str[flow->nix_intf], flow->nix_intf);
diff --git a/drivers/common/cnxk/roc_npc_priv.h b/drivers/common/cnxk/roc_npc_priv.h
index e08a34d146..b7d726caa1 100644
--- a/drivers/common/cnxk/roc_npc_priv.h
+++ b/drivers/common/cnxk/roc_npc_priv.h
@@ -30,6 +30,10 @@
((((lid) - (NPC_LID_LA)) * NPC_LAYER_KEYX_SZ) + \
NPC_PARSE_KEX_S_LA_OFFSET)
+#define NPC_LAYER_KEYX_SZ_CN20K (2)
+#define NPC_PARSE_KEX_S_LID_OFFSET_CN20K(lid) \
+ ((((lid) - (NPC_LID_LA)) * NPC_LAYER_KEYX_SZ_CN20K) + NPC_PARSE_KEX_S_LA_OFFSET)
+
/* This mark value indicates flag action */
#define NPC_FLOW_FLAG_VAL (0xffff)
@@ -43,7 +47,11 @@
#define NPC_MCAM_KEX_FIELD_MAX 23
#define NPC_MCAM_MAX_PROTO_FIELDS (NPC_MCAM_KEX_FIELD_MAX + 1)
-#define NPC_MCAM_KEY_X4_WORDS 7 /* Number of 64-bit words */
+#if defined(ROC_PLATFORM_CN20K)
+#define NPC_MCAM_KEY_X4_WORDS 8 /* Number of 64-bit words */
+#else
+#define NPC_MCAM_KEY_X4_WORDS 7 /* Number of 64-bit words */
+#endif
#define NPC_RVUPF_MAX_9XXX 0x10 /* HRM: RVU_PRIV_CONST */
#define NPC_RVUPF_MAX_98XX 0x18 /* HRM: RVU_PRIV_CONST */
@@ -77,6 +85,16 @@
#define NPC_LFLAG_LC_OFFSET (NPC_LTYPE_OFFSET_START + 6)
#define NPC_LTYPE_LC_OFFSET (NPC_LTYPE_OFFSET_START + 8)
+/* LB OFFSET : START + LA (1b flags + 1b ltype) + LB (1b flags) */
+#define NPC_CN20K_LTYPE_LB_OFFSET (NPC_LTYPE_OFFSET_START + 3)
+#define NPC_CN20K_LFLAG_LB_OFFSET (NPC_LTYPE_OFFSET_START + 2)
+
+/* LC OFFSET : START + LA (1b flags + 1b ltype) + LB (1b flags + 1b ltype) + LC
+ * (1b flags)
+ */
+#define NPC_CN20K_LFLAG_LC_OFFSET (NPC_LTYPE_OFFSET_START + 4)
+#define NPC_CN20K_LTYPE_LC_OFFSET (NPC_LTYPE_OFFSET_START + 5)
+
#define CN10K_SDP_CH_START 0x80
#define CN10K_SDP_CH_MASK 0xF80
@@ -176,9 +194,9 @@ struct npc_parse_item_info {
const void *def_mask; /* default mask */
void *hw_mask; /* hardware supported mask */
int len; /* length of item */
+ uint8_t hw_hdr_len; /* Extra data len at each layer*/
const void *spec; /* spec to use, NULL implies match any */
const void *mask; /* mask to use */
- uint8_t hw_hdr_len; /* Extra data len at each layer*/
};
struct npc_parse_state {
@@ -192,16 +210,16 @@ struct npc_parse_state {
uint8_t layer_mask;
uint8_t lt[NPC_MAX_LID];
uint8_t flags[NPC_MAX_LID];
+ bool has_eth_type;
+ bool is_second_pass_rule;
+ bool set_ipv6ext_ltype_mask;
+ /* adjust ltype in MCAM to match at least one vlan */
+ bool set_vlan_ltype_mask;
uint8_t *mcam_data; /* point to flow->mcam_data + key_len */
uint8_t *mcam_mask; /* point to flow->mcam_mask + key_len */
bool is_vf;
- /* adjust ltype in MCAM to match at least one vlan */
- bool set_vlan_ltype_mask;
- bool set_ipv6ext_ltype_mask;
- bool is_second_pass_rule;
- bool has_eth_type;
- uint16_t nb_tx_queues;
uint16_t dst_pf_func;
+ uint16_t nb_tx_queues;
};
enum npc_kpu_parser_flag {
@@ -340,6 +358,14 @@ struct npc_lid_lt_xtract_info {
struct npc_xtract_info xtract[NPC_MAX_LD];
};
+struct npc_lid_lt_xtract_info_cn20k {
+ /* Info derived from parser configuration */
+ uint16_t npc_proto; /* Network protocol identified */
+ uint8_t valid_flags_mask; /* Flags applicable */
+ uint8_t is_terminating : 1; /* No more parsing */
+ struct npc_xtract_info xtract;
+};
+
union npc_kex_ldata_flags_cfg {
struct {
uint64_t lid : 3;
@@ -349,6 +375,11 @@ union npc_kex_ldata_flags_cfg {
uint64_t i;
};
+#define NPC_MAX_EXTRACTTORS 24
+typedef struct npc_lid_lt_xtract_info_cn20k npc_dxcfg_cn20k_t[NPC_MAX_INTF][NPC_MAX_EXTRACTTORS]
+ [NPC_MAX_LT];
+typedef union npc_kex_ldata_flags_cfg npc_lid_cn20k_t[NPC_MAX_INTF][NPC_MAX_EXTRACTTORS];
+
typedef struct npc_lid_lt_xtract_info npc_dxcfg_t[NPC_MAX_INTF][NPC_MAX_LID]
[NPC_MAX_LT];
typedef struct npc_lid_lt_xtract_info npc_fxcfg_t[NPC_MAX_INTF][NPC_MAX_LD]
@@ -387,33 +418,36 @@ TAILQ_HEAD(npc_age_flow_list_head, npc_age_flow_entry);
struct npc {
struct mbox *mbox; /* Mbox */
- uint32_t keyx_supp_nmask[NPC_MAX_INTF]; /* nibble mask */
+ uint64_t keyx_supp_nmask[NPC_MAX_INTF]; /* nibble mask */
uint8_t hash_extract_cap; /* hash extract support */
uint8_t profile_name[MKEX_NAME_LEN]; /* KEX profile name */
- uint32_t keyx_len[NPC_MAX_INTF]; /* per intf key len in bits */
- uint32_t datax_len[NPC_MAX_INTF]; /* per intf data len in bits */
- uint32_t keyw[NPC_MAX_INTF]; /* max key + data len bits */
- uint32_t mcam_entries; /* mcam entries supported */
- uint16_t channel; /* RX Channel number */
bool is_sdp_link;
+ uint16_t channel; /* RX Channel number */
+ uint32_t keyx_len[NPC_MAX_INTF]; /* per intf key len in bits */
+ uint32_t datax_len[NPC_MAX_INTF]; /* per intf data len in bits */
+ uint32_t keyw[NPC_MAX_INTF]; /* max key + data len bits */
+ uint32_t mcam_entries; /* mcam entries supported */
+ uint16_t switch_header_type; /* Supported switch header type */
+ uint16_t flow_max_priority; /* Max priority for flow */
uint16_t sdp_channel;
uint16_t sdp_channel_mask;
- uint32_t rss_grps; /* rss groups supported */
- uint16_t flow_prealloc_size; /* Pre allocated mcam size */
- uint16_t flow_max_priority; /* Max priority for flow */
- uint16_t switch_header_type; /* Supported switch header type */
+ uint32_t rss_grps; /* rss groups supported */
+ uint16_t flow_prealloc_size; /* Pre allocated mcam size */
+ uint8_t exact_match_ena;
+ uint16_t pf_func; /* pf_func of device */
uint32_t mark_actions;
- uint32_t vtag_strip_actions; /* vtag insert/strip actions */
- uint16_t pf_func; /* pf_func of device */
- npc_dxcfg_t prx_dxcfg; /* intf, lid, lt, extract */
- npc_fxcfg_t prx_fxcfg; /* Flag extract */
- npc_ld_flags_t prx_lfcfg; /* KEX LD_Flags CFG */
+ uint32_t vtag_strip_actions; /* vtag insert/strip actions */
+ npc_dxcfg_t prx_dxcfg; /* intf, lid, lt, extract */
+ npc_dxcfg_cn20k_t prx_dxcfg_cn20k; /* intf, ext, lt, extract */
+ npc_lid_cn20k_t lid_cfg; /* KEX LD_Flags CFG */
+ npc_fxcfg_t prx_fxcfg; /* Flag extract */
+ npc_ld_flags_t prx_lfcfg; /* KEX LD_Flags CFG */
struct npc_flow_list *flow_list;
struct npc_prio_flow_list_head *prio_flow_list;
struct npc_age_flow_list_head age_flow_list;
struct plt_bitmap *rss_grp_entries;
struct npc_flow_list ipsec_list;
- uint8_t exact_match_ena;
+ uint8_t enable_debug;
};
#define NPC_HASH_FIELD_LEN 16
@@ -432,6 +466,7 @@ roc_npc_to_npc_priv(struct roc_npc *npc)
return (struct npc *)npc->reserved;
}
+int npc_mcam_get_stats(struct mbox *mbox, struct roc_npc_flow *flow, uint64_t *count);
int npc_mcam_alloc_counter(struct mbox *mbox, uint16_t *ctr);
int npc_mcam_free_counter(struct mbox *mbox, uint16_t ctr_id);
int npc_mcam_read_counter(struct mbox *mbox, uint32_t ctr_id, uint64_t *count);
@@ -440,9 +475,10 @@ int npc_mcam_free_entry(struct mbox *mbox, uint32_t entry);
int npc_mcam_free_all_entries(struct npc *npc);
int npc_mcam_alloc_and_write(struct npc *npc, struct roc_npc_flow *flow,
struct npc_parse_state *pst);
-int npc_mcam_alloc_entry(struct npc *npc, struct roc_npc_flow *mcam,
- struct roc_npc_flow *ref_mcam, int prio,
- int *resp_count);
+int npc_mcam_alloc_entry(struct npc *npc, struct roc_npc_flow *mcam, struct roc_npc_flow *ref_mcam,
+ uint8_t prio, int *resp_count);
+int npc_mcam_alloc_entry_cn20k(struct npc *npc, struct roc_npc_flow *mcam, int *resp_count);
+
int npc_mcam_alloc_entries(struct mbox *mbox, int ref_mcam, int *alloc_entry, int req_count,
int prio, int *resp_count, bool is_conti);
@@ -453,6 +489,7 @@ int npc_update_parse_state(struct npc_parse_state *pst, struct npc_parse_item_in
int lt, uint8_t flags);
void npc_get_hw_supp_mask(struct npc_parse_state *pst, struct npc_parse_item_info *info, int lid,
int lt);
+uint8_t npc_get_key_type(struct npc *npc, struct roc_npc_flow *flow);
int npc_mask_is_supported(const char *mask, const char *hw_mask, int len);
int npc_parse_item_basic(const struct roc_npc_item_info *item, struct npc_parse_item_info *info);
int npc_parse_meta_items(struct npc_parse_state *pst);
diff --git a/drivers/common/cnxk/roc_npc_utils.c b/drivers/common/cnxk/roc_npc_utils.c
index a507df994f..75d3b0702c 100644
--- a/drivers/common/cnxk/roc_npc_utils.c
+++ b/drivers/common/cnxk/roc_npc_utils.c
@@ -4,6 +4,36 @@
#include "roc_api.h"
#include "roc_priv.h"
+enum npc_mcam_cn20k_key_width {
+ NPC_CN20K_MCAM_KEY_X1 = 0,
+ NPC_CN20K_MCAM_KEY_DYN = NPC_CN20K_MCAM_KEY_X1,
+ NPC_CN20K_MCAM_KEY_X2,
+ NPC_CN20K_MCAM_KEY_X4,
+ NPC_CN20K_MCAM_KEY_MAX,
+};
+
+uint8_t
+npc_get_key_type(struct npc *npc, struct roc_npc_flow *flow)
+{
+ int i;
+
+ /* KEX is configured just for X2 */
+ if (npc->keyw[ROC_NPC_INTF_RX] == 1)
+ return NPC_CN20K_MCAM_KEY_X2;
+
+ /* KEX is configured just for X4 */
+ if (npc->keyw[ROC_NPC_INTF_RX] == 2)
+ return NPC_CN20K_MCAM_KEY_X4;
+
+ /* KEX is configured for both X2 and X4 */
+ /* Check mask for upper 256 bits. if mask is set, then it is X4 entry */
+ for (i = 4; i < ROC_NPC_MAX_MCAM_WIDTH_DWORDS; i++) {
+ if (flow->mcam_mask[i] != 0)
+ return NPC_CN20K_MCAM_KEY_X4;
+ }
+ return NPC_CN20K_MCAM_KEY_X2;
+}
+
static void
npc_prep_mcam_ldata(uint8_t *ptr, const uint8_t *data, int len)
{
@@ -67,8 +97,9 @@ npc_ipv6_hash_mask_get(struct npc_xtract_info *xinfo, struct npc_parse_item_info
memset(&hw_mask[offset], 0xFF, NPC_HASH_FIELD_LEN);
}
-void
-npc_get_hw_supp_mask(struct npc_parse_state *pst, struct npc_parse_item_info *info, int lid, int lt)
+static void
+npc_get_hw_supp_mask_legacy(struct npc_parse_state *pst, struct npc_parse_item_info *info, int lid,
+ int lt)
{
struct npc_xtract_info *xinfo, *lfinfo;
char *hw_mask = info->hw_mask;
@@ -101,6 +132,40 @@ npc_get_hw_supp_mask(struct npc_parse_state *pst, struct npc_parse_item_info *in
}
}
+static void
+npc_get_hw_supp_mask_o20k(struct npc_parse_state *pst, struct npc_parse_item_info *info, int lid,
+ int lt)
+{
+ struct npc_xtract_info *xinfo;
+ union npc_kex_ldata_flags_cfg *lid_info;
+ char *hw_mask = info->hw_mask;
+ int ex;
+ int intf;
+
+ intf = pst->nix_intf;
+ memset(hw_mask, 0, info->len);
+ for (ex = 0; ex < NPC_MAX_EXTRACTTORS; ex++) {
+ lid_info = &pst->npc->lid_cfg[intf][ex];
+ if (lid_info->s.lid != lid)
+ continue;
+ xinfo = &pst->npc->prx_dxcfg_cn20k[intf][ex][lt].xtract;
+
+ if (pst->npc->hash_extract_cap && xinfo->use_hash)
+ npc_ipv6_hash_mask_get(xinfo, info);
+ else
+ npc_set_hw_mask(info, xinfo, hw_mask);
+ }
+}
+
+void
+npc_get_hw_supp_mask(struct npc_parse_state *pst, struct npc_parse_item_info *info, int lid, int lt)
+{
+ if (!roc_model_is_cn20k())
+ return npc_get_hw_supp_mask_legacy(pst, info, lid, lt);
+ else
+ return npc_get_hw_supp_mask_o20k(pst, info, lid, lt);
+}
+
inline int
npc_mask_is_supported(const char *mask, const char *hw_mask, int len)
{
@@ -381,10 +446,10 @@ npc_hash_field_get(struct npc_xtract_info *xinfo, const struct roc_npc_flow_item
return 1;
}
-int
-npc_process_ipv6_field_hash(const struct roc_npc_flow_item_ipv6 *ipv6_spec,
- const struct roc_npc_flow_item_ipv6 *ipv6_mask,
- struct npc_parse_state *pst, uint8_t ltype)
+static int
+npc_process_ipv6_field_hash_legacy(const struct roc_npc_flow_item_ipv6 *ipv6_spec,
+ const struct roc_npc_flow_item_ipv6 *ipv6_mask,
+ struct npc_parse_state *pst, uint8_t ltype)
{
struct npc_lid_lt_xtract_info *lid_lt_xinfo;
uint8_t hash_field[ROC_IPV6_ADDR_LEN];
@@ -421,9 +486,64 @@ npc_process_ipv6_field_hash(const struct roc_npc_flow_item_ipv6 *ipv6_spec,
return 0;
}
+static int
+npc_process_ipv6_field_hash_o20k(const struct roc_npc_flow_item_ipv6 *ipv6_spec,
+ const struct roc_npc_flow_item_ipv6 *ipv6_mask,
+ struct npc_parse_state *pst, uint8_t ltype)
+{
+ struct npc_lid_lt_xtract_info_cn20k *lid_lt_xinfo;
+ union npc_kex_ldata_flags_cfg *lid_cfg;
+ uint8_t hash_field[ROC_IPV6_ADDR_LEN];
+ struct npc_xtract_info *xinfo;
+ struct roc_ipv6_hdr ipv6_buf;
+ uint32_t hash = 0, mask;
+ int intf, i, rc = 0;
+
+ memset(&ipv6_buf, 0, sizeof(ipv6_buf));
+ memset(hash_field, 0, sizeof(hash_field));
+
+ intf = pst->nix_intf;
+ for (i = 0; i < NPC_MAX_EXTRACTTORS; i++) {
+ lid_cfg = &pst->npc->lid_cfg[intf][i];
+ if (lid_cfg->s.lid != NPC_LID_LC)
+ continue;
+ lid_lt_xinfo = &pst->npc->prx_dxcfg_cn20k[intf][NPC_LID_LC][ltype];
+
+ xinfo = &lid_lt_xinfo->xtract;
+ if (!xinfo->use_hash)
+ continue;
+
+ rc = npc_hash_field_get(xinfo, ipv6_spec, ipv6_mask, hash_field);
+ if (rc == 0)
+ continue;
+
+ rc = npc_ipv6_field_hash_get(pst->npc, (const uint32_t *)hash_field, intf, i,
+ &hash);
+ if (rc)
+ return rc;
+
+ mask = GENMASK(31, 0);
+ memcpy(pst->mcam_mask + xinfo->key_off, (uint8_t *)&mask, 4);
+ memcpy(pst->mcam_data + xinfo->key_off, (uint8_t *)&hash, 4);
+ }
+
+ return 0;
+}
+
int
-npc_update_parse_state(struct npc_parse_state *pst, struct npc_parse_item_info *info, int lid,
- int lt, uint8_t flags)
+npc_process_ipv6_field_hash(const struct roc_npc_flow_item_ipv6 *ipv6_spec,
+ const struct roc_npc_flow_item_ipv6 *ipv6_mask,
+ struct npc_parse_state *pst, uint8_t ltype)
+{
+ if (!roc_model_is_cn20k())
+ return npc_process_ipv6_field_hash_legacy(ipv6_spec, ipv6_mask, pst, ltype);
+ else
+ return npc_process_ipv6_field_hash_o20k(ipv6_spec, ipv6_mask, pst, ltype);
+}
+
+static int
+npc_update_parse_state_legacy(struct npc_parse_state *pst, struct npc_parse_item_info *info,
+ int lid, int lt, uint8_t flags)
{
struct npc_lid_lt_xtract_info *xinfo;
struct roc_npc_flow_dump_data *dump;
@@ -461,8 +581,7 @@ npc_update_parse_state(struct npc_parse_state *pst, struct npc_parse_item_info *
if (lf_cfg == lid) {
for (j = 0; j < NPC_MAX_LFL; j++) {
lfinfo = pst->npc->prx_fxcfg[intf][i][j].xtract;
- rc = npc_update_extraction_data(pst, info,
- &lfinfo[0]);
+ rc = npc_update_extraction_data(pst, info, &lfinfo[0]);
if (rc != 0)
return rc;
@@ -480,42 +599,127 @@ npc_update_parse_state(struct npc_parse_state *pst, struct npc_parse_item_info *
return 0;
}
+static int
+npc_update_parse_state_o20(struct npc_parse_state *pst, struct npc_parse_item_info *info, int lid,
+ int lt, uint8_t flags)
+{
+ struct npc_lid_lt_xtract_info_cn20k *xinfo;
+ union npc_kex_ldata_flags_cfg *lid_cfg;
+ struct roc_npc_flow_dump_data *dump;
+ int intf;
+ int i, rc = 0;
+
+ pst->layer_mask |= lid;
+ pst->lt[lid] = lt;
+ pst->flags[lid] = flags;
+
+ intf = pst->nix_intf;
+ if (info->spec == NULL)
+ goto done;
+
+ for (i = 0; i < NPC_MAX_EXTRACTTORS; i++) {
+ lid_cfg = &pst->npc->lid_cfg[intf][i];
+ if (lid_cfg->s.lid != lid)
+ continue;
+ xinfo = &pst->npc->prx_dxcfg_cn20k[intf][i][lt];
+ if (xinfo->is_terminating)
+ pst->terminate = 1;
+
+ if (xinfo->xtract.use_hash)
+ continue;
+ rc = npc_update_extraction_data(pst, info, &xinfo->xtract);
+ if (rc != 0)
+ return rc;
+ }
+
+done:
+ dump = &pst->flow->dump_data[pst->flow->num_patterns++];
+ dump->lid = lid;
+ dump->ltype = lt;
+ pst->pattern++;
+ return 0;
+}
+
+int
+npc_update_parse_state(struct npc_parse_state *pst, struct npc_parse_item_info *info, int lid,
+ int lt, uint8_t flags)
+{
+ if (roc_model_is_cn20k())
+ return npc_update_parse_state_o20(pst, info, lid, lt, flags);
+ else
+ return npc_update_parse_state_legacy(pst, info, lid, lt, flags);
+}
+
int
npc_mcam_init(struct npc *npc, struct roc_npc_flow *flow, int mcam_id)
{
- struct npc_mcam_write_entry_req *req;
- struct npc_mcam_write_entry_rsq *rsp;
+ struct msg_rsp *rsp;
struct mbox *mbox = mbox_get(npc->mbox);
int rc = 0, idx;
- req = mbox_alloc_msg_npc_mcam_write_entry(mbox);
- if (req == NULL) {
- rc = -ENOSPC;
- goto exit;
- }
- req->set_cntr = 0;
- req->cntr = 0;
- req->entry = mcam_id;
-
- req->intf = (flow->nix_intf == NIX_INTF_RX) ? NPC_MCAM_RX : NPC_MCAM_TX;
- req->enable_entry = 1;
- req->entry_data.action = flow->npc_action;
- req->entry_data.vtag_action = flow->vtag_action;
-
- for (idx = 0; idx < ROC_NPC_MAX_MCAM_WIDTH_DWORDS; idx++) {
- req->entry_data.kw[idx] = 0x0;
- req->entry_data.kw_mask[idx] = 0x0;
- }
+ if (roc_model_is_cn20k()) {
+ struct npc_cn20k_mcam_write_entry_req *req;
+
+ req = mbox_alloc_msg_npc_cn20k_mcam_write_entry(mbox);
+ if (req == NULL) {
+ rc = -ENOSPC;
+ goto exit;
+ }
+ req->cntr = 0;
+ req->entry = mcam_id;
+
+ req->intf = (flow->nix_intf == NIX_INTF_RX) ? NPC_MCAM_RX : NPC_MCAM_TX;
+ req->enable_entry = 1;
+ req->entry_data.action = flow->npc_action;
+ req->entry_data.vtag_action = flow->vtag_action;
+
+ for (idx = 0; idx < ROC_NPC_MAX_MCAM_WIDTH_DWORDS; idx++) {
+ req->entry_data.kw[idx] = 0x0;
+ req->entry_data.kw_mask[idx] = 0x0;
+ }
+
+ if (flow->nix_intf == NIX_INTF_RX) {
+ req->entry_data.kw[0] |= (uint64_t)npc->channel;
+ req->entry_data.kw_mask[0] |= (BIT_ULL(12) - 1);
+ } else {
+ uint16_t pf_func = (flow->npc_action >> 4) & 0xffff;
- if (flow->nix_intf == NIX_INTF_RX) {
- req->entry_data.kw[0] |= (uint64_t)npc->channel;
- req->entry_data.kw_mask[0] |= (BIT_ULL(12) - 1);
+ pf_func = plt_cpu_to_be_16(pf_func);
+ req->entry_data.kw[0] |= ((uint64_t)pf_func << 32);
+ req->entry_data.kw_mask[0] |= ((uint64_t)0xffff << 32);
+ }
} else {
- uint16_t pf_func = (flow->npc_action >> 4) & 0xffff;
+ struct npc_mcam_write_entry_req *req;
+
+ req = mbox_alloc_msg_npc_mcam_write_entry(mbox);
+ if (req == NULL) {
+ rc = -ENOSPC;
+ goto exit;
+ }
+ req->set_cntr = 0;
+ req->cntr = 0;
+ req->entry = mcam_id;
+
+ req->intf = (flow->nix_intf == NIX_INTF_RX) ? NPC_MCAM_RX : NPC_MCAM_TX;
+ req->enable_entry = 1;
+ req->entry_data.action = flow->npc_action;
+ req->entry_data.vtag_action = flow->vtag_action;
+
+ for (idx = 0; idx < ROC_NPC_MAX_MCAM_WIDTH_DWORDS; idx++) {
+ req->entry_data.kw[idx] = 0x0;
+ req->entry_data.kw_mask[idx] = 0x0;
+ }
+
+ if (flow->nix_intf == NIX_INTF_RX) {
+ req->entry_data.kw[0] |= (uint64_t)npc->channel;
+ req->entry_data.kw_mask[0] |= (BIT_ULL(12) - 1);
+ } else {
+ uint16_t pf_func = (flow->npc_action >> 4) & 0xffff;
- pf_func = plt_cpu_to_be_16(pf_func);
- req->entry_data.kw[0] |= ((uint64_t)pf_func << 32);
- req->entry_data.kw_mask[0] |= ((uint64_t)0xffff << 32);
+ pf_func = plt_cpu_to_be_16(pf_func);
+ req->entry_data.kw[0] |= ((uint64_t)pf_func << 32);
+ req->entry_data.kw_mask[0] |= ((uint64_t)0xffff << 32);
+ }
}
rc = mbox_process_msg(mbox, (void *)&rsp);
@@ -783,13 +987,12 @@ npc_insert_into_flow_list(struct npc *npc, struct npc_prio_flow_entry *entry)
}
static int
-npc_allocate_mcam_entry(struct mbox *mbox, int prio,
- struct npc_mcam_alloc_entry_rsp *rsp_local,
- int ref_entry)
+npc_allocate_mcam_entry(struct mbox *mbox, int prio, struct npc_mcam_alloc_entry_rsp *rsp_local,
+ int ref_entry, uint8_t kw_type)
{
- struct npc_mcam_alloc_entry_rsp *rsp_cmd;
- struct npc_mcam_alloc_entry_req *req;
struct npc_mcam_alloc_entry_rsp *rsp;
+ struct npc_mcam_alloc_entry_req *req;
+
int rc = -ENOSPC;
req = mbox_alloc_msg_npc_mcam_alloc_entry(mbox_get(mbox));
@@ -797,20 +1000,20 @@ npc_allocate_mcam_entry(struct mbox *mbox, int prio,
goto exit;
req->contig = 1;
req->count = 1;
- req->priority = prio;
+ req->ref_priority = prio;
req->ref_entry = ref_entry;
+ req->kw_type = kw_type;
- rc = mbox_process_msg(mbox, (void *)&rsp_cmd);
+ rc = mbox_process_msg(mbox, (void *)&rsp);
if (rc)
goto exit;
- if (!rsp_cmd->count) {
+ if (!rsp->count) {
rc = -ENOSPC;
goto exit;
}
- mbox_memcpy(rsp_local, rsp_cmd, sizeof(*rsp));
-
+ mbox_memcpy(rsp_local, rsp, sizeof(*rsp));
rc = 0;
exit:
mbox_put(mbox);
@@ -854,8 +1057,7 @@ npc_find_mcam_ref_entry(struct roc_npc_flow *flow, struct npc *npc, int *prio,
}
static int
-npc_alloc_mcam_by_ref_entry(struct mbox *mbox, struct roc_npc_flow *flow,
- struct npc *npc,
+npc_alloc_mcam_by_ref_entry(struct mbox *mbox, struct roc_npc_flow *flow, struct npc *npc,
struct npc_mcam_alloc_entry_rsp *rsp_local)
{
int prio, ref_entry = 0, rc = 0, dir = NPC_MCAM_LOWER_PRIO;
@@ -863,7 +1065,7 @@ npc_alloc_mcam_by_ref_entry(struct mbox *mbox, struct roc_npc_flow *flow,
retry:
npc_find_mcam_ref_entry(flow, npc, &prio, &ref_entry, dir);
- rc = npc_allocate_mcam_entry(mbox, prio, rsp_local, ref_entry);
+ rc = npc_allocate_mcam_entry(mbox, prio, rsp_local, ref_entry, flow->key_type);
if (rc && !retry_done) {
plt_npc_dbg(
"npc: Failed to allocate lower priority entry. Retrying for higher priority");
@@ -879,32 +1081,42 @@ npc_alloc_mcam_by_ref_entry(struct mbox *mbox, struct roc_npc_flow *flow,
}
int
-npc_get_free_mcam_entry(struct mbox *mbox, struct roc_npc_flow *flow,
- struct npc *npc)
+npc_get_free_mcam_entry(struct mbox *mbox, struct roc_npc_flow *flow, struct npc *npc)
{
struct npc_mcam_alloc_entry_rsp rsp_local;
struct npc_prio_flow_entry *new_entry;
int rc = 0;
- rc = npc_alloc_mcam_by_ref_entry(mbox, flow, npc, &rsp_local);
-
- if (rc)
- return rc;
-
new_entry = plt_zmalloc(sizeof(*new_entry), 0);
if (!new_entry)
return -ENOSPC;
- new_entry->flow = flow;
+ if (roc_model_is_cn20k()) {
+ rc = npc_allocate_mcam_entry(mbox, NPC_MCAM_ANY_PRIO, &rsp_local, 0,
+ flow->key_type);
+ if (rc) {
+ plt_npc_dbg("npc: failed to allocate MCAM entry.");
+ return rc;
+ }
+
+ new_entry->flow = flow;
+ } else {
+ rc = npc_alloc_mcam_by_ref_entry(mbox, flow, npc, &rsp_local);
- plt_npc_dbg("kernel allocated MCAM entry %d", rsp_local.entry);
+ if (rc)
+ return rc;
- rc = npc_sort_mcams_by_user_prio_level(mbox, new_entry, npc,
- &rsp_local);
- if (rc)
- goto err;
+ new_entry->flow = flow;
+
+ plt_npc_dbg("kernel allocated MCAM entry %d", rsp_local.entry);
+
+ rc = npc_sort_mcams_by_user_prio_level(mbox, new_entry, npc, &rsp_local);
+ if (rc)
+ goto err;
+
+ plt_npc_dbg("allocated MCAM entry after sorting %d", rsp_local.entry);
+ }
- plt_npc_dbg("allocated MCAM entry after sorting %d", rsp_local.entry);
flow->mcam_id = rsp_local.entry;
npc_insert_into_flow_list(npc, new_entry);
diff --git a/drivers/common/cnxk/version.map b/drivers/common/cnxk/version.map
index 42e9375706..4f8da55da5 100644
--- a/drivers/common/cnxk/version.map
+++ b/drivers/common/cnxk/version.map
@@ -486,6 +486,7 @@ INTERNAL {
roc_npc_mcam_free_counter;
roc_npc_mcam_free;
roc_npc_mcam_free_entry;
+ roc_npc_mcam_get_stats;
roc_npc_mcam_init;
roc_npc_mcam_move;
roc_npc_mcam_merge_base_steering_rule;
--
2.39.2
^ permalink raw reply [flat|nested] 8+ messages in thread
* [dpdk-dev] [PATCH v3 2/2] net/cnxk: support rte flow on cn20k
2024-11-12 9:58 ` [dpdk-dev] [PATCH v3 1/2] common/cnxk: support NPC " psatheesh
@ 2024-11-12 9:58 ` psatheesh
0 siblings, 0 replies; 8+ messages in thread
From: psatheesh @ 2024-11-12 9:58 UTC (permalink / raw)
To: Nithin Dabilpuram, Kiran Kumar K, Sunil Kumar Kori, Satha Rao,
Harman Kalra
Cc: dev, Satheesh Paul
From: Satheesh Paul <psatheesh@marvell.com>
Support for rte flow in cn20k.
Signed-off-by: Satheesh Paul <psatheesh@marvell.com>
Reviewed-by: Kiran Kumar K <kirankumark@marvell.com>
---
drivers/net/cnxk/cn10k_flow.c | 227 ++-----------------------
drivers/net/cnxk/cn10k_flow.h | 10 +-
drivers/net/cnxk/cn20k_ethdev.c | 4 +
drivers/net/cnxk/cn20k_flow.c | 101 +++++++++++
drivers/net/cnxk/cn20k_flow.h | 21 +++
drivers/net/cnxk/cn9k_flow.c | 2 +-
drivers/net/cnxk/cnxk_ethdev_devargs.c | 10 +-
drivers/net/cnxk/cnxk_flow.c | 18 +-
drivers/net/cnxk/cnxk_flow.h | 5 +-
drivers/net/cnxk/cnxk_flow_common.c | 214 +++++++++++++++++++++++
drivers/net/cnxk/cnxk_flow_common.h | 19 +++
drivers/net/cnxk/meson.build | 2 +
12 files changed, 396 insertions(+), 237 deletions(-)
create mode 100644 drivers/net/cnxk/cn20k_flow.c
create mode 100644 drivers/net/cnxk/cn20k_flow.h
create mode 100644 drivers/net/cnxk/cnxk_flow_common.c
create mode 100644 drivers/net/cnxk/cnxk_flow_common.h
diff --git a/drivers/net/cnxk/cn10k_flow.c b/drivers/net/cnxk/cn10k_flow.c
index db5e427362..b95fb83f08 100644
--- a/drivers/net/cnxk/cn10k_flow.c
+++ b/drivers/net/cnxk/cn10k_flow.c
@@ -1,215 +1,29 @@
/* SPDX-License-Identifier: BSD-3-Clause
* Copyright(C) 2020 Marvell.
*/
-#include "cn10k_flow.h"
+
#include "cn10k_ethdev.h"
#include "cn10k_rx.h"
#include "cnxk_ethdev_mcs.h"
+#include "cnxk_flow_common.h"
+#include <cn10k_flow.h>
#include <cnxk_flow.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[],
+ 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;
struct roc_npc *npc = &dev->npc;
struct roc_npc_flow *flow;
- void *mcs_flow = NULL;
int vtag_actions = 0;
- uint32_t req_act = 0;
int mark_actions;
- 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;
- }
- }
-
- if (actions[0].type == RTE_FLOW_ACTION_TYPE_SECURITY &&
- cnxk_eth_macsec_sess_get_by_sess(dev, actions[0].conf) != NULL) {
- rc = cnxk_mcs_flow_configure(eth_dev, attr, pattern, actions, error, &mcs_flow);
- if (rc) {
- rte_flow_error_set(error, rc, RTE_FLOW_ERROR_TYPE_ACTION, NULL,
- "Failed to configure mcs flow");
- return NULL;
- }
- return (struct rte_flow *)mcs_flow;
- }
flow = cnxk_flow_create(eth_dev, attr, pattern, actions, error);
- if (!flow) {
- if (mtr)
- nix_mtr_chain_reset(eth_dev, mtr->mtr_id);
+ if (!flow)
return NULL;
- } else {
- if (mtr)
- cn10k_mtr_connect(eth_dev, mtr->mtr_id);
- }
mark_actions = roc_npc_mark_actions_get(npc);
if (mark_actions) {
@@ -231,16 +45,7 @@ int
cn10k_flow_info_get(struct rte_eth_dev *dev, struct rte_flow_port_info *port_info,
struct rte_flow_queue_info *queue_info, struct rte_flow_error *err)
{
- RTE_SET_USED(dev);
- RTE_SET_USED(err);
-
- memset(port_info, 0, sizeof(*port_info));
- memset(queue_info, 0, sizeof(*queue_info));
-
- port_info->max_nb_counters = CN10K_NPC_COUNTERS_MAX;
- port_info->max_nb_meters = CNXK_NIX_MTR_COUNT_MAX;
-
- return 0;
+ return cnxk_flow_info_get_common(dev, port_info, queue_info, err);
}
int
@@ -250,14 +55,12 @@ cn10k_flow_destroy(struct rte_eth_dev *eth_dev, struct rte_flow *rte_flow,
struct roc_npc_flow *flow = (struct roc_npc_flow *)rte_flow;
struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
struct roc_npc *npc = &dev->npc;
- int vtag_actions = 0;
+ int vtag_actions = 0, rc = 0;
int mark_actions;
uint16_t match_id;
uint32_t mtr_id;
- int rc;
- match_id = (flow->npc_action >> NPC_RX_ACT_MATCH_OFFSET) &
- NPC_RX_ACT_MATCH_MASK;
+ match_id = (flow->npc_action >> NPC_RX_ACT_MATCH_OFFSET) & NPC_RX_ACT_MATCH_MASK;
if (match_id) {
mark_actions = roc_npc_mark_actions_sub_return(npc, 1);
if (mark_actions == 0) {
@@ -271,8 +74,7 @@ cn10k_flow_destroy(struct rte_eth_dev *eth_dev, struct rte_flow *rte_flow,
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;
+ dev->rx_offload_flags &= ~NIX_RX_OFFLOAD_VLAN_STRIP_F;
cn10k_eth_set_rx_function(eth_dev);
}
}
@@ -281,19 +83,18 @@ cn10k_flow_destroy(struct rte_eth_dev *eth_dev, struct rte_flow *rte_flow,
if (cnxk_eth_macsec_sess_get_by_sess(dev, (void *)flow) != NULL) {
rc = cnxk_mcs_flow_destroy(dev, (void *)flow);
if (rc < 0)
- rte_flow_error_set(error, rc, RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
- NULL, "Failed to free mcs flow");
+ rte_flow_error_set(error, rc, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
+ "Failed to free mcs flow");
return rc;
}
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);
+ rc = cnxk_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");
+ 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
index 316b74e6a6..c9e8c86e96 100644
--- a/drivers/net/cnxk/cn10k_flow.h
+++ b/drivers/net/cnxk/cn10k_flow.h
@@ -1,8 +1,8 @@
/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(C) 2020 Marvell.
+ * Copyright(C) 2024 Marvell.
*/
-#ifndef __CN10K_RTE_FLOW_H__
-#define __CN10K_RTE_FLOW_H__
+#ifndef __CN10K_FLOW_H__
+#define __CN10K_FLOW_H__
#include <rte_flow_driver.h>
@@ -16,6 +16,6 @@ int cn10k_flow_destroy(struct rte_eth_dev *dev, struct rte_flow *flow,
int cn10k_flow_info_get(struct rte_eth_dev *dev, struct rte_flow_port_info *port_info,
struct rte_flow_queue_info *queue_info, struct rte_flow_error *err);
-#define CN10K_NPC_COUNTERS_MAX 512
+#define CNXK_NPC_COUNTERS_MAX 512
-#endif /* __CN10K_RTE_FLOW_H__ */
+#endif /* __CN10K_FLOW_H__ */
diff --git a/drivers/net/cnxk/cn20k_ethdev.c b/drivers/net/cnxk/cn20k_ethdev.c
index 37c372d80f..4e4337a6e5 100644
--- a/drivers/net/cnxk/cn20k_ethdev.c
+++ b/drivers/net/cnxk/cn20k_ethdev.c
@@ -2,6 +2,7 @@
* Copyright(C) 2024 Marvell.
*/
#include "cn20k_ethdev.h"
+#include "cn20k_flow.h"
#include "cn20k_rx.h"
#include "cn20k_tx.h"
@@ -867,6 +868,9 @@ npc_flow_ops_override(void)
init_once = 1;
/* Update platform specific ops */
+ cnxk_flow_ops.create = cn20k_flow_create;
+ cnxk_flow_ops.destroy = cn20k_flow_destroy;
+ cnxk_flow_ops.info_get = cn20k_flow_info_get;
}
static int
diff --git a/drivers/net/cnxk/cn20k_flow.c b/drivers/net/cnxk/cn20k_flow.c
new file mode 100644
index 0000000000..fd50f516ee
--- /dev/null
+++ b/drivers/net/cnxk/cn20k_flow.c
@@ -0,0 +1,101 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(C) 2024 Marvell.
+ */
+
+#include "cn20k_ethdev.h"
+#include "cn20k_rx.h"
+#include "cnxk_ethdev_mcs.h"
+#include "cnxk_flow_common.h"
+#include <cn20k_flow.h>
+#include <cnxk_flow.h>
+
+struct rte_flow *
+cn20k_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 *npc = &dev->npc;
+ struct roc_npc_flow *flow;
+ int vtag_actions = 0;
+ int mark_actions;
+
+ 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;
+ cn20k_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;
+ cn20k_eth_set_rx_function(eth_dev);
+ }
+
+ return (struct rte_flow *)flow;
+}
+
+int
+cn20k_flow_info_get(struct rte_eth_dev *dev, struct rte_flow_port_info *port_info,
+ struct rte_flow_queue_info *queue_info, struct rte_flow_error *err)
+{
+ return cnxk_flow_info_get_common(dev, port_info, queue_info, err);
+}
+
+int
+cn20k_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);
+ struct roc_npc *npc = &dev->npc;
+ int vtag_actions = 0, rc = 0;
+ int mark_actions;
+ uint16_t match_id;
+ uint32_t mtr_id;
+
+ match_id = (flow->npc_action >> NPC_RX_ACT_MATCH_OFFSET) & NPC_RX_ACT_MATCH_MASK;
+ if (match_id) {
+ mark_actions = roc_npc_mark_actions_sub_return(npc, 1);
+ if (mark_actions == 0) {
+ dev->rx_offload_flags &= ~NIX_RX_OFFLOAD_MARK_UPDATE_F;
+ cn20k_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;
+ cn20k_eth_set_rx_function(eth_dev);
+ }
+ }
+ }
+
+ if (cnxk_eth_macsec_sess_get_by_sess(dev, (void *)flow) != NULL) {
+ rc = cnxk_mcs_flow_destroy(dev, (void *)flow);
+ if (rc < 0)
+ rte_flow_error_set(error, rc, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
+ "Failed to free mcs flow");
+ return rc;
+ }
+
+ mtr_id = flow->mtr_id;
+ rc = cnxk_flow_destroy(eth_dev, flow, error);
+ if (!rc && mtr_id != ROC_NIX_MTR_ID_INVALID) {
+ rc = cnxk_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/cn20k_flow.h b/drivers/net/cnxk/cn20k_flow.h
new file mode 100644
index 0000000000..1e4bd6214a
--- /dev/null
+++ b/drivers/net/cnxk/cn20k_flow.h
@@ -0,0 +1,21 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(C) 2024 Marvell.
+ */
+#ifndef __CN20K_FLOW_H__
+#define __CN20K_FLOW_H__
+
+#include <rte_flow_driver.h>
+
+struct rte_flow *cn20k_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 cn20k_flow_destroy(struct rte_eth_dev *dev, struct rte_flow *flow,
+ struct rte_flow_error *error);
+
+int cn20k_flow_info_get(struct rte_eth_dev *dev, struct rte_flow_port_info *port_info,
+ struct rte_flow_queue_info *queue_info, struct rte_flow_error *err);
+
+#define CNXK_NPC_COUNTERS_MAX 512
+
+#endif /* __CN20K_FLOW_H__ */
diff --git a/drivers/net/cnxk/cn9k_flow.c b/drivers/net/cnxk/cn9k_flow.c
index dc5476a189..ae4629ea69 100644
--- a/drivers/net/cnxk/cn9k_flow.c
+++ b/drivers/net/cnxk/cn9k_flow.c
@@ -18,7 +18,7 @@ cn9k_flow_create(struct rte_eth_dev *eth_dev, const struct rte_flow_attr *attr,
int vtag_actions = 0;
int mark_actions;
- flow = cnxk_flow_create(eth_dev, attr, pattern, actions, error);
+ flow = cnxk_flow_create_common(eth_dev, attr, pattern, actions, error, false);
if (!flow)
return NULL;
diff --git a/drivers/net/cnxk/cnxk_ethdev_devargs.c b/drivers/net/cnxk/cnxk_ethdev_devargs.c
index 5bd50bb9a1..bdf5d88b92 100644
--- a/drivers/net/cnxk/cnxk_ethdev_devargs.c
+++ b/drivers/net/cnxk/cnxk_ethdev_devargs.c
@@ -88,8 +88,7 @@ parse_flow_max_priority(const char *key, const char *value, void *extra_args)
val = atoi(value);
- /* Limit the max priority to 32 */
- if (val < 1 || val > 32)
+ if (val < 1 || val > ROC_NPC_MAX_MCAM_PRIORITY)
return -EINVAL;
*(uint16_t *)extra_args = val;
@@ -390,7 +389,12 @@ cnxk_ethdev_parse_devargs(struct rte_devargs *devargs, struct cnxk_eth_dev *dev)
dev->nix.meta_buf_sz = meta_buf_sz;
dev->npc.flow_prealloc_size = flow_prealloc_size;
- dev->npc.flow_max_priority = flow_max_priority;
+
+ if (roc_model_is_cn20k())
+ dev->npc.flow_max_priority = ROC_NPC_MAX_MCAM_PRIORITY;
+ else
+ dev->npc.flow_max_priority = flow_max_priority;
+
dev->npc.switch_header_type = switch_header_type;
dev->npc.sdp_channel = sdp_chan.channel;
dev->npc.sdp_channel_mask = sdp_chan.mask;
diff --git a/drivers/net/cnxk/cnxk_flow.c b/drivers/net/cnxk/cnxk_flow.c
index e42e2f8deb..fcc60cd4f0 100644
--- a/drivers/net/cnxk/cnxk_flow.c
+++ b/drivers/net/cnxk/cnxk_flow.c
@@ -977,14 +977,6 @@ cnxk_flow_create_common(struct rte_eth_dev *eth_dev, const struct rte_flow_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_common(struct rte_eth_dev *eth_dev, struct roc_npc_flow *flow,
struct rte_flow_error *error, bool is_rep)
@@ -1083,10 +1075,14 @@ cnxk_flow_query_common(struct rte_eth_dev *eth_dev, struct rte_flow *flow,
npc = &rep_dev->parent_dev->npc;
}
- if (in_flow->use_pre_alloc)
+ if (in_flow->use_pre_alloc) {
rc = roc_npc_inl_mcam_read_counter(in_flow->ctr_id, &query->hits);
- else
- rc = roc_npc_mcam_read_counter(npc, in_flow->ctr_id, &query->hits);
+ } else {
+ if (roc_model_is_cn20k())
+ rc = roc_npc_mcam_get_stats(npc, in_flow, &query->hits);
+ else
+ rc = roc_npc_mcam_read_counter(npc, in_flow->ctr_id, &query->hits);
+ }
if (rc != 0) {
errcode = EIO;
errmsg = "Error reading flow counter";
diff --git a/drivers/net/cnxk/cnxk_flow.h b/drivers/net/cnxk/cnxk_flow.h
index e51d04b2c9..80b8d2c36a 100644
--- a/drivers/net/cnxk/cnxk_flow.h
+++ b/drivers/net/cnxk/cnxk_flow.h
@@ -22,10 +22,6 @@ struct cnxk_rte_flow_action_info {
extern const struct cnxk_rte_flow_term_info term[];
-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);
@@ -46,5 +42,6 @@ int cnxk_flow_query_common(struct rte_eth_dev *eth_dev, struct rte_flow *flow,
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);
+int cnxk_mtr_destroy(struct rte_eth_dev *eth_dev, uint32_t mtr_id);
#endif /* __CNXK_RTE_FLOW_H__ */
diff --git a/drivers/net/cnxk/cnxk_flow_common.c b/drivers/net/cnxk/cnxk_flow_common.c
new file mode 100644
index 0000000000..c2a173ac8c
--- /dev/null
+++ b/drivers/net/cnxk/cnxk_flow_common.c
@@ -0,0 +1,214 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(C) 2024 Marvell.
+ */
+
+#include "cnxk_flow_common.h"
+#include "cnxk_ethdev_mcs.h"
+#include <cnxk_flow.h>
+
+static int
+cnxk_mtr_connect(struct rte_eth_dev *eth_dev, uint32_t mtr_id)
+{
+ return nix_mtr_connect(eth_dev, mtr_id);
+}
+
+int
+cnxk_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
+cnxk_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
+cnxk_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 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);
+ const struct rte_flow_action *action_rss = NULL;
+ const struct rte_flow_action_meter *mtr = NULL;
+ const struct rte_flow_action *act_q = NULL;
+ struct roc_npc_flow *flow;
+ void *mcs_flow = NULL;
+ 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 = cnxk_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 = cnxk_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;
+ }
+ }
+
+ if (actions[0].type == RTE_FLOW_ACTION_TYPE_SECURITY &&
+ cnxk_eth_macsec_sess_get_by_sess(dev, actions[0].conf) != NULL) {
+ rc = cnxk_mcs_flow_configure(eth_dev, attr, pattern, actions, error, &mcs_flow);
+ if (rc) {
+ rte_flow_error_set(error, rc, RTE_FLOW_ERROR_TYPE_ACTION, NULL,
+ "Failed to configure mcs flow");
+ return NULL;
+ }
+ return mcs_flow;
+ }
+
+ flow = cnxk_flow_create_common(eth_dev, attr, pattern, actions, error, false);
+ if (!flow) {
+ if (mtr)
+ nix_mtr_chain_reset(eth_dev, mtr->mtr_id);
+
+ return NULL;
+ } else {
+ if (mtr)
+ cnxk_mtr_connect(eth_dev, mtr->mtr_id);
+ }
+
+ return flow;
+}
+
+int
+cnxk_flow_info_get_common(struct rte_eth_dev *dev, struct rte_flow_port_info *port_info,
+ struct rte_flow_queue_info *queue_info, struct rte_flow_error *err)
+{
+ RTE_SET_USED(dev);
+ RTE_SET_USED(err);
+
+ memset(port_info, 0, sizeof(*port_info));
+ memset(queue_info, 0, sizeof(*queue_info));
+
+ port_info->max_nb_counters = CNXK_NPC_COUNTERS_MAX;
+ port_info->max_nb_meters = CNXK_NIX_MTR_COUNT_MAX;
+
+ return 0;
+}
diff --git a/drivers/net/cnxk/cnxk_flow_common.h b/drivers/net/cnxk/cnxk_flow_common.h
new file mode 100644
index 0000000000..21289d9daf
--- /dev/null
+++ b/drivers/net/cnxk/cnxk_flow_common.h
@@ -0,0 +1,19 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(C) 2024 Marvell.
+ */
+#ifndef __CNXK_FLOW_COMMON_H__
+#define __CNXK_FLOW_COMMON_H__
+
+#include <rte_flow_driver.h>
+
+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_info_get_common(struct rte_eth_dev *dev, struct rte_flow_port_info *port_info,
+ struct rte_flow_queue_info *queue_info, struct rte_flow_error *err);
+
+#define CNXK_NPC_COUNTERS_MAX 512
+
+#endif /* __CNXK_FLOW_COMMON_H__ */
diff --git a/drivers/net/cnxk/meson.build b/drivers/net/cnxk/meson.build
index 32ff8aadc0..733ee61c0a 100644
--- a/drivers/net/cnxk/meson.build
+++ b/drivers/net/cnxk/meson.build
@@ -32,6 +32,7 @@ sources = files(
'cnxk_eswitch_devargs.c',
'cnxk_eswitch_flow.c',
'cnxk_eswitch_rxtx.c',
+ 'cnxk_flow_common.c',
'cnxk_link.c',
'cnxk_lookup.c',
'cnxk_ptp.c',
@@ -236,6 +237,7 @@ if soc_type == 'cn20k' or soc_type == 'all'
# CN20K
sources += files(
'cn20k_ethdev.c',
+ 'cn20k_flow.c',
'cn20k_rx_select.c',
'cn20k_tx_select.c',
)
--
2.39.2
^ permalink raw reply [flat|nested] 8+ messages in thread