From: Ajit Khaparde <ajit.khaparde@broadcom.com>
To: dev@dpdk.org
Cc: ferruh.yigit@intel.com, thomas@monjalon.net,
Randy Schacher <stuart.schacher@broadcom.com>,
Farah Smith <farah.smith@broadcom.com>,
Shahaji Bhosle <sbhosle@broadcom.com>
Subject: [PATCH v4 04/11] net/bnxt: update Truflow core
Date: Wed, 28 Jun 2023 09:29:20 -0700 [thread overview]
Message-ID: <20230628162927.92858-5-ajit.khaparde@broadcom.com> (raw)
In-Reply-To: <20230628162927.92858-1-ajit.khaparde@broadcom.com>
[-- Attachment #1: Type: text/plain, Size: 303760 bytes --]
From: Randy Schacher <stuart.schacher@broadcom.com>
Update TruFlow core code to:
- Add shared session management
- Add SRAM session management
- Add dynamic TCAM management
- Add shared TCAM session management
- Add Hot Upgrade support
- Update copyright year
Signed-off-by: Randy Schacher <stuart.schacher@broadcom.com>
Signed-off-by: Farah Smith <farah.smith@broadcom.com>
Reviewed-by: Shahaji Bhosle <sbhosle@broadcom.com>
Reviewed-by: Ajit Khaparde <ajit.khaparde@broadcom.com>
---
drivers/net/bnxt/bnxt.h | 1 -
drivers/net/bnxt/bnxt_irq.h | 1 -
drivers/net/bnxt/bnxt_nvm_defs.h | 1 -
drivers/net/bnxt/bnxt_ring.h | 1 -
drivers/net/bnxt/bnxt_rxr.h | 1 -
drivers/net/bnxt/bnxt_txr.h | 1 -
drivers/net/bnxt/bnxt_util.h | 1 -
drivers/net/bnxt/tf_core/cfa_resource_types.h | 2 -
drivers/net/bnxt/tf_core/cfa_tcam_mgr.c | 2116 +++++++++++++++++
drivers/net/bnxt/tf_core/cfa_tcam_mgr.h | 523 ++++
.../net/bnxt/tf_core/cfa_tcam_mgr_device.h | 101 +
.../net/bnxt/tf_core/cfa_tcam_mgr_hwop_msg.c | 201 ++
.../net/bnxt/tf_core/cfa_tcam_mgr_hwop_msg.h | 28 +
drivers/net/bnxt/tf_core/cfa_tcam_mgr_p4.c | 921 +++++++
drivers/net/bnxt/tf_core/cfa_tcam_mgr_p4.h | 20 +
drivers/net/bnxt/tf_core/cfa_tcam_mgr_p58.c | 926 ++++++++
drivers/net/bnxt/tf_core/cfa_tcam_mgr_p58.h | 20 +
drivers/net/bnxt/tf_core/cfa_tcam_mgr_sbmp.h | 126 +
.../net/bnxt/tf_core/cfa_tcam_mgr_session.c | 377 +++
.../net/bnxt/tf_core/cfa_tcam_mgr_session.h | 54 +
drivers/net/bnxt/tf_core/meson.build | 36 +-
drivers/net/bnxt/tf_core/tf_core.c | 54 +-
drivers/net/bnxt/tf_core/tf_core.h | 97 +-
drivers/net/bnxt/tf_core/tf_device.c | 18 +-
drivers/net/bnxt/tf_core/tf_device.h | 2 +-
drivers/net/bnxt/tf_core/tf_device_p4.c | 14 +-
drivers/net/bnxt/tf_core/tf_device_p58.c | 84 +-
drivers/net/bnxt/tf_core/tf_em_common.c | 2 +-
drivers/net/bnxt/tf_core/tf_em_internal.c | 10 +-
drivers/net/bnxt/tf_core/tf_identifier.c | 1 +
drivers/net/bnxt/tf_core/tf_if_tbl.c | 59 +-
drivers/net/bnxt/tf_core/tf_msg.c | 217 +-
drivers/net/bnxt/tf_core/tf_msg.h | 38 +-
drivers/net/bnxt/tf_core/tf_rm.c | 117 +-
drivers/net/bnxt/tf_core/tf_session.c | 112 +-
drivers/net/bnxt/tf_core/tf_session.h | 65 +-
drivers/net/bnxt/tf_core/tf_sram_mgr.c | 117 +-
drivers/net/bnxt/tf_core/tf_sram_mgr.h | 22 +-
drivers/net/bnxt/tf_core/tf_tbl.c | 8 +-
drivers/net/bnxt/tf_core/tf_tbl_sram.c | 25 +-
drivers/net/bnxt/tf_core/tf_tcam.c | 226 +-
drivers/net/bnxt/tf_core/tf_tcam_mgr_msg.c | 286 +++
drivers/net/bnxt/tf_core/tf_tcam_mgr_msg.h | 49 +
drivers/net/bnxt/tf_core/tf_tcam_shared.c | 1146 +--------
drivers/net/bnxt/tf_core/tf_tcam_shared.h | 3 +-
drivers/net/bnxt/tf_ulp/bnxt_ulp.c | 8 +-
46 files changed, 6686 insertions(+), 1552 deletions(-)
create mode 100644 drivers/net/bnxt/tf_core/cfa_tcam_mgr.c
create mode 100644 drivers/net/bnxt/tf_core/cfa_tcam_mgr.h
create mode 100644 drivers/net/bnxt/tf_core/cfa_tcam_mgr_device.h
create mode 100644 drivers/net/bnxt/tf_core/cfa_tcam_mgr_hwop_msg.c
create mode 100644 drivers/net/bnxt/tf_core/cfa_tcam_mgr_hwop_msg.h
create mode 100644 drivers/net/bnxt/tf_core/cfa_tcam_mgr_p4.c
create mode 100644 drivers/net/bnxt/tf_core/cfa_tcam_mgr_p4.h
create mode 100644 drivers/net/bnxt/tf_core/cfa_tcam_mgr_p58.c
create mode 100644 drivers/net/bnxt/tf_core/cfa_tcam_mgr_p58.h
create mode 100644 drivers/net/bnxt/tf_core/cfa_tcam_mgr_sbmp.h
create mode 100644 drivers/net/bnxt/tf_core/cfa_tcam_mgr_session.c
create mode 100644 drivers/net/bnxt/tf_core/cfa_tcam_mgr_session.h
create mode 100644 drivers/net/bnxt/tf_core/tf_tcam_mgr_msg.c
create mode 100644 drivers/net/bnxt/tf_core/tf_tcam_mgr_msg.h
diff --git a/drivers/net/bnxt/bnxt.h b/drivers/net/bnxt/bnxt.h
index 48bd8f2418..2bccdec7e0 100644
--- a/drivers/net/bnxt/bnxt.h
+++ b/drivers/net/bnxt/bnxt.h
@@ -1044,5 +1044,4 @@ int bnxt_flow_ops_get_op(struct rte_eth_dev *dev,
int bnxt_dev_start_op(struct rte_eth_dev *eth_dev);
int bnxt_dev_stop_op(struct rte_eth_dev *eth_dev);
void bnxt_handle_vf_cfg_change(void *arg);
-
#endif
diff --git a/drivers/net/bnxt/bnxt_irq.h b/drivers/net/bnxt/bnxt_irq.h
index e498578968..e2d61bae7a 100644
--- a/drivers/net/bnxt/bnxt_irq.h
+++ b/drivers/net/bnxt/bnxt_irq.h
@@ -20,5 +20,4 @@ void bnxt_enable_int(struct bnxt *bp);
int bnxt_setup_int(struct bnxt *bp);
int bnxt_request_int(struct bnxt *bp);
void bnxt_int_handler(void *param);
-
#endif
diff --git a/drivers/net/bnxt/bnxt_nvm_defs.h b/drivers/net/bnxt/bnxt_nvm_defs.h
index f5ac4e8c84..57ddefa7a1 100644
--- a/drivers/net/bnxt/bnxt_nvm_defs.h
+++ b/drivers/net/bnxt/bnxt_nvm_defs.h
@@ -66,5 +66,4 @@ enum bnxnvm_pkglog_field_index {
BNX_PKG_LOG_FIELD_IDX_INSTALLED_ITEMS = 5,
BNX_PKG_LOG_FIELD_IDX_INSTALLED_MASK = 6
};
-
#endif /* Don't add anything after this line */
diff --git a/drivers/net/bnxt/bnxt_ring.h b/drivers/net/bnxt/bnxt_ring.h
index 3d747aba54..baa60b2627 100644
--- a/drivers/net/bnxt/bnxt_ring.h
+++ b/drivers/net/bnxt/bnxt_ring.h
@@ -142,5 +142,4 @@ static inline void bnxt_db_cq(struct bnxt_cp_ring_info *cpr)
B_CP_DIS_DB(cpr, cp_raw_cons);
}
}
-
#endif
diff --git a/drivers/net/bnxt/bnxt_rxr.h b/drivers/net/bnxt/bnxt_rxr.h
index e132166a18..8e722b7bf0 100644
--- a/drivers/net/bnxt/bnxt_rxr.h
+++ b/drivers/net/bnxt/bnxt_rxr.h
@@ -386,5 +386,4 @@ bnxt_parse_pkt_type_v2(struct rte_mbuf *mbuf,
mbuf->packet_type = pkt_type;
}
-
#endif /* _BNXT_RXR_H_ */
diff --git a/drivers/net/bnxt/bnxt_txr.h b/drivers/net/bnxt/bnxt_txr.h
index e11343c082..75456df5bd 100644
--- a/drivers/net/bnxt/bnxt_txr.h
+++ b/drivers/net/bnxt/bnxt_txr.h
@@ -90,5 +90,4 @@ int bnxt_flush_tx_cmp(struct bnxt_cp_ring_info *cpr);
TX_BD_LONG_LFLAGS_IP_CHKSUM)
#define TX_BD_FLG_TIP_TCP_UDP_CHKSUM (TX_BD_LONG_LFLAGS_TCP_UDP_CHKSUM | \
TX_BD_LONG_LFLAGS_T_IP_CHKSUM)
-
#endif
diff --git a/drivers/net/bnxt/bnxt_util.h b/drivers/net/bnxt/bnxt_util.h
index 3437dc75ae..7f5b4c160e 100644
--- a/drivers/net/bnxt/bnxt_util.h
+++ b/drivers/net/bnxt/bnxt_util.h
@@ -17,5 +17,4 @@
int bnxt_check_zero_bytes(const uint8_t *bytes, int len);
void bnxt_eth_hw_addr_random(uint8_t *mac_addr);
-
#endif /* _BNXT_UTIL_H_ */
diff --git a/drivers/net/bnxt/tf_core/cfa_resource_types.h b/drivers/net/bnxt/tf_core/cfa_resource_types.h
index 874d7b834f..8431c778e4 100644
--- a/drivers/net/bnxt/tf_core/cfa_resource_types.h
+++ b/drivers/net/bnxt/tf_core/cfa_resource_types.h
@@ -63,7 +63,6 @@
#define CFA_RESOURCE_TYPE_P59_VEB_TCAM 0x18UL
#define CFA_RESOURCE_TYPE_P59_LAST CFA_RESOURCE_TYPE_P59_VEB_TCAM
-
/* Meter */
#define CFA_RESOURCE_TYPE_P58_METER 0x0UL
/* SRAM_Bank_0 */
@@ -184,7 +183,6 @@
#define CFA_RESOURCE_TYPE_P45_TBL_SCOPE 0x23UL
#define CFA_RESOURCE_TYPE_P45_LAST CFA_RESOURCE_TYPE_P45_TBL_SCOPE
-
/* Multicast Group */
#define CFA_RESOURCE_TYPE_P4_MCG 0x0UL
/* Encap 8 byte record */
diff --git a/drivers/net/bnxt/tf_core/cfa_tcam_mgr.c b/drivers/net/bnxt/tf_core/cfa_tcam_mgr.c
new file mode 100644
index 0000000000..f26d93e7a9
--- /dev/null
+++ b/drivers/net/bnxt/tf_core/cfa_tcam_mgr.c
@@ -0,0 +1,2116 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2021-2023 Broadcom
+ * All rights reserved.
+ */
+
+#include <inttypes.h>
+#include <signal.h>
+
+#include "hcapi_cfa_defs.h"
+
+#include "tfp.h"
+#include "tf_session.h"
+#include "tf_util.h"
+#include "cfa_tcam_mgr.h"
+#include "cfa_tcam_mgr_hwop_msg.h"
+#include "cfa_tcam_mgr_device.h"
+#include "cfa_tcam_mgr_session.h"
+#include "cfa_tcam_mgr_p58.h"
+#include "cfa_tcam_mgr_p4.h"
+
+#define TF_TCAM_SLICE_INVALID (-1)
+
+/*
+ * The following macros are for setting the entry status in a row entry.
+ * row is (struct cfa_tcam_mgr_table_rows_0 *)
+ */
+#define ROW_ENTRY_INUSE(row, entry) ((row)->entry_inuse & (1U << (entry)))
+#define ROW_ENTRY_SET(row, entry) ((row)->entry_inuse |= (1U << (entry)))
+#define ROW_ENTRY_CLEAR(row, entry) ((row)->entry_inuse &= ~(1U << (entry)))
+#define ROW_INUSE(row) ((row)->entry_inuse != 0)
+
+static struct cfa_tcam_mgr_entry_data *entry_data[TF_TCAM_MAX_SESSIONS];
+
+static int global_data_initialized[TF_TCAM_MAX_SESSIONS];
+int cfa_tcam_mgr_max_entries[TF_TCAM_MAX_SESSIONS];
+
+struct cfa_tcam_mgr_table_data
+cfa_tcam_mgr_tables[TF_TCAM_MAX_SESSIONS][TF_DIR_MAX][CFA_TCAM_MGR_TBL_TYPE_MAX];
+
+static int physical_table_types[CFA_TCAM_MGR_TBL_TYPE_MAX] = {
+ [CFA_TCAM_MGR_TBL_TYPE_L2_CTXT_TCAM_HIGH_APPS] =
+ TF_TCAM_TBL_TYPE_L2_CTXT_TCAM_HIGH,
+ [CFA_TCAM_MGR_TBL_TYPE_L2_CTXT_TCAM_LOW_APPS] =
+ TF_TCAM_TBL_TYPE_L2_CTXT_TCAM_LOW,
+ [CFA_TCAM_MGR_TBL_TYPE_PROF_TCAM_APPS] =
+ TF_TCAM_TBL_TYPE_PROF_TCAM,
+ [CFA_TCAM_MGR_TBL_TYPE_WC_TCAM_APPS] =
+ TF_TCAM_TBL_TYPE_WC_TCAM,
+ [CFA_TCAM_MGR_TBL_TYPE_SP_TCAM_APPS] =
+ TF_TCAM_TBL_TYPE_SP_TCAM,
+ [CFA_TCAM_MGR_TBL_TYPE_CT_RULE_TCAM_APPS] =
+ TF_TCAM_TBL_TYPE_CT_RULE_TCAM,
+ [CFA_TCAM_MGR_TBL_TYPE_VEB_TCAM_APPS] =
+ TF_TCAM_TBL_TYPE_VEB_TCAM,
+ [CFA_TCAM_MGR_TBL_TYPE_WC_TCAM_HIGH_APPS] =
+ TF_TCAM_TBL_TYPE_WC_TCAM_HIGH,
+ [CFA_TCAM_MGR_TBL_TYPE_WC_TCAM_LOW_APPS] =
+ TF_TCAM_TBL_TYPE_WC_TCAM_LOW,
+};
+
+int
+cfa_tcam_mgr_get_phys_table_type(enum cfa_tcam_mgr_tbl_type type)
+{
+ if (type >= CFA_TCAM_MGR_TBL_TYPE_MAX)
+ assert(0);
+ else
+ return physical_table_types[type];
+}
+
+const char *
+cfa_tcam_mgr_tbl_2_str(enum cfa_tcam_mgr_tbl_type tcam_type)
+{
+ switch (tcam_type) {
+ case CFA_TCAM_MGR_TBL_TYPE_L2_CTXT_TCAM_HIGH_AFM:
+ return "l2_ctxt_tcam_high AFM";
+ case CFA_TCAM_MGR_TBL_TYPE_L2_CTXT_TCAM_HIGH_APPS:
+ return "l2_ctxt_tcam_high Apps";
+ case CFA_TCAM_MGR_TBL_TYPE_L2_CTXT_TCAM_LOW_AFM:
+ return "l2_ctxt_tcam_low AFM";
+ case CFA_TCAM_MGR_TBL_TYPE_L2_CTXT_TCAM_LOW_APPS:
+ return "l2_ctxt_tcam_low Apps";
+ case CFA_TCAM_MGR_TBL_TYPE_PROF_TCAM_AFM:
+ return "prof_tcam AFM";
+ case CFA_TCAM_MGR_TBL_TYPE_PROF_TCAM_APPS:
+ return "prof_tcam Apps";
+ case CFA_TCAM_MGR_TBL_TYPE_WC_TCAM_AFM:
+ return "wc_tcam AFM";
+ case CFA_TCAM_MGR_TBL_TYPE_WC_TCAM_APPS:
+ return "wc_tcam Apps";
+ case CFA_TCAM_MGR_TBL_TYPE_VEB_TCAM_AFM:
+ return "veb_tcam AFM";
+ case CFA_TCAM_MGR_TBL_TYPE_VEB_TCAM_APPS:
+ return "veb_tcam Apps";
+ case CFA_TCAM_MGR_TBL_TYPE_SP_TCAM_AFM:
+ return "sp_tcam AFM";
+ case CFA_TCAM_MGR_TBL_TYPE_SP_TCAM_APPS:
+ return "sp_tcam Apps";
+ case CFA_TCAM_MGR_TBL_TYPE_CT_RULE_TCAM_AFM:
+ return "ct_rule_tcam AFM";
+ case CFA_TCAM_MGR_TBL_TYPE_CT_RULE_TCAM_APPS:
+ return "ct_rule_tcam Apps";
+ case CFA_TCAM_MGR_TBL_TYPE_WC_TCAM_HIGH_AFM:
+ return "wc_tcam_high AFM";
+ case CFA_TCAM_MGR_TBL_TYPE_WC_TCAM_HIGH_APPS:
+ return "wc_tcam_high Apps";
+ case CFA_TCAM_MGR_TBL_TYPE_WC_TCAM_LOW_AFM:
+ return "wc_tcam_low AFM";
+ case CFA_TCAM_MGR_TBL_TYPE_WC_TCAM_LOW_APPS:
+ return "wc_tcam_low Apps";
+ default:
+ return "Invalid tcam table type";
+ }
+}
+
+/* key_size and slice_width are in bytes */
+static int
+cfa_tcam_mgr_get_num_slices(unsigned int key_size, unsigned int slice_width)
+{
+ int num_slices = 0;
+
+ if (key_size == 0)
+ return -CFA_TCAM_MGR_ERR_CODE(INVAL);
+
+ num_slices = ((key_size - 1U) / slice_width) + 1U;
+ /* Round up to next highest power of 2 */
+ /* This is necessary since, for example, 3 slices is not a valid entry
+ * width.
+ */
+ num_slices--;
+ /* Repeat to maximum number of bits actually used */
+ /* This fills in all the bits. */
+ num_slices |= num_slices >> 1;
+ num_slices |= num_slices >> 2;
+ num_slices |= num_slices >> 4;
+ /*
+ * If the maximum number of slices that are supported by the HW
+ * increases, then additional shifts are needed.
+ */
+ num_slices++;
+ return num_slices;
+}
+
+static struct cfa_tcam_mgr_entry_data *
+cfa_tcam_mgr_entry_get(int sess_idx, uint16_t id)
+{
+ if (id > cfa_tcam_mgr_max_entries[sess_idx])
+ return NULL;
+
+ return &entry_data[sess_idx][id];
+}
+
+/* Insert an entry into the entry table */
+static int
+cfa_tcam_mgr_entry_insert(int sess_idx, uint16_t id,
+ struct cfa_tcam_mgr_entry_data *entry)
+{
+ if (id > cfa_tcam_mgr_max_entries[sess_idx])
+ return -CFA_TCAM_MGR_ERR_CODE(INVAL);
+
+ memcpy(&entry_data[sess_idx][id], entry,
+ sizeof(entry_data[sess_idx][id]));
+
+ return 0;
+}
+
+/* Delete an entry from the entry table */
+static int
+cfa_tcam_mgr_entry_delete(int sess_idx, uint16_t id)
+{
+ if (id > cfa_tcam_mgr_max_entries[sess_idx])
+ return -CFA_TCAM_MGR_ERR_CODE(INVAL);
+
+ memset(&entry_data[sess_idx][id], 0, sizeof(entry_data[sess_idx][id]));
+
+ return 0;
+}
+
+/* Returns the size of the row structure taking into account how many slices a
+ * TCAM supports.
+ */
+static int
+cfa_tcam_mgr_row_size_get(int sess_idx, enum tf_dir dir,
+ enum cfa_tcam_mgr_tbl_type type)
+{
+ return sizeof(struct cfa_tcam_mgr_table_rows_0) +
+ (cfa_tcam_mgr_tables[sess_idx][dir][type].max_slices *
+ sizeof(((struct cfa_tcam_mgr_table_rows_0 *)0)->entries[0]));
+}
+
+static void *
+cfa_tcam_mgr_row_ptr_get(void *base, int index, int row_size)
+{
+ return (uint8_t *)base + (index * row_size);
+}
+
+/*
+ * Searches a table to find the direction and type of an entry.
+ */
+static int
+cfa_tcam_mgr_entry_find_in_table(int sess_idx, int id, enum tf_dir dir,
+ enum cfa_tcam_mgr_tbl_type type)
+{
+ struct cfa_tcam_mgr_table_data *table_data;
+ struct cfa_tcam_mgr_table_rows_0 *row;
+ int max_slices, row_idx, row_size, slice;
+
+ table_data = &cfa_tcam_mgr_tables[sess_idx][dir][type];
+ if (table_data->max_entries > 0 &&
+ table_data->hcapi_type > 0) {
+ max_slices = table_data->max_slices;
+ row_size = cfa_tcam_mgr_row_size_get(sess_idx, dir, type);
+ for (row_idx = table_data->start_row;
+ row_idx <= table_data->end_row;
+ row_idx++) {
+ row = cfa_tcam_mgr_row_ptr_get(table_data->tcam_rows,
+ row_idx, row_size);
+ if (!ROW_INUSE(row))
+ continue;
+ for (slice = 0;
+ slice < (max_slices / row->entry_size);
+ slice++) {
+ if (!ROW_ENTRY_INUSE(row, slice))
+ continue;
+ if (row->entries[slice] == id)
+ return 0;
+ }
+ }
+ }
+
+ return -CFA_TCAM_MGR_ERR_CODE(NOENT);
+}
+
+/*
+ * Searches all the tables to find the direction and type of an entry.
+ */
+static int
+cfa_tcam_mgr_entry_find(int sess_idx, int id, enum tf_dir *tbl_dir,
+ enum cfa_tcam_mgr_tbl_type *tbl_type)
+{
+ enum tf_dir dir;
+ enum cfa_tcam_mgr_tbl_type type;
+ int rc = -CFA_TCAM_MGR_ERR_CODE(NOENT);
+
+ for (dir = TF_DIR_RX; dir < ARRAY_SIZE(cfa_tcam_mgr_tables[sess_idx]); dir++) {
+ for (type = CFA_TCAM_MGR_TBL_TYPE_START;
+ type < ARRAY_SIZE(cfa_tcam_mgr_tables[sess_idx][dir]);
+ type++) {
+ rc = cfa_tcam_mgr_entry_find_in_table(sess_idx, id, dir, type);
+ if (rc == 0) {
+ *tbl_dir = dir;
+ *tbl_type = type;
+ return rc;
+ }
+ }
+ }
+
+ return rc;
+}
+
+static int
+cfa_tcam_mgr_row_is_entry_free(struct cfa_tcam_mgr_table_rows_0 *row,
+ int max_slices,
+ int key_slices)
+{
+ int j;
+
+ if (ROW_INUSE(row) &&
+ row->entry_size == key_slices) {
+ for (j = 0; j < (max_slices / row->entry_size); j++) {
+ if (!ROW_ENTRY_INUSE(row, j))
+ return j;
+ }
+ }
+ return -1;
+}
+
+static int
+cfa_tcam_mgr_entry_move(int sess_idx, struct cfa_tcam_mgr_context *context,
+ enum tf_dir dir, enum cfa_tcam_mgr_tbl_type type,
+ int entry_id,
+ struct cfa_tcam_mgr_table_data *table_data,
+ int dest_row_index, int dest_row_slice,
+ struct cfa_tcam_mgr_table_rows_0 *dest_row,
+ int source_row_index,
+ struct cfa_tcam_mgr_table_rows_0 *source_row,
+ bool free_source_entry)
+{
+ struct cfa_tcam_mgr_get_parms gparms = { 0 };
+ struct cfa_tcam_mgr_set_parms sparms = { 0 };
+ struct cfa_tcam_mgr_free_parms fparms = { 0 };
+ struct cfa_tcam_mgr_entry_data *entry;
+ uint8_t key[CFA_TCAM_MGR_MAX_KEY_SIZE];
+ uint8_t mask[CFA_TCAM_MGR_MAX_KEY_SIZE];
+ uint8_t result[CFA_TCAM_MGR_MAX_KEY_SIZE];
+
+ int j, rc;
+
+ entry = cfa_tcam_mgr_entry_get(sess_idx, entry_id);
+ if (entry == NULL)
+ return -1;
+
+ gparms.dir = dir;
+ gparms.type = type;
+ gparms.hcapi_type = table_data->hcapi_type;
+ gparms.key = key;
+ gparms.mask = mask;
+ gparms.result = result;
+ gparms.id = source_row->entries[entry->slice];
+ gparms.key_size = sizeof(key);
+ gparms.result_size = sizeof(result);
+
+ rc = cfa_tcam_mgr_entry_get_msg(sess_idx, context, &gparms,
+ source_row_index,
+ entry->slice * source_row->entry_size,
+ table_data->max_slices);
+ if (rc != 0)
+ return rc;
+
+ sparms.dir = dir;
+ sparms.type = type;
+ sparms.hcapi_type = table_data->hcapi_type;
+ sparms.key = key;
+ sparms.mask = mask;
+ sparms.result = result;
+ sparms.id = gparms.id;
+ sparms.key_size = gparms.key_size;
+ sparms.result_size = gparms.result_size;
+
+ /* Slice in destination row not specified. Find first free slice. */
+ if (dest_row_slice < 0)
+ for (j = 0;
+ j < (table_data->max_slices / dest_row->entry_size);
+ j++) {
+ if (!ROW_ENTRY_INUSE(dest_row, j)) {
+ dest_row_slice = j;
+ break;
+ }
+ }
+
+ /* If no free slice found, return error. */
+ if (dest_row_slice < 0)
+ return -CFA_TCAM_MGR_ERR_CODE(PERM);
+
+ rc = cfa_tcam_mgr_entry_set_msg(sess_idx, context, &sparms,
+ dest_row_index,
+ dest_row_slice * dest_row->entry_size,
+ table_data->max_slices);
+ if (rc != 0)
+ return rc;
+
+ if (free_source_entry) {
+ fparms.dir = dir;
+ fparms.type = type;
+ fparms.hcapi_type = table_data->hcapi_type;
+ rc = cfa_tcam_mgr_entry_free_msg(sess_idx, context, &fparms,
+ source_row_index,
+ entry->slice *
+ dest_row->entry_size,
+ table_data->row_width /
+ table_data->max_slices *
+ source_row->entry_size,
+ table_data->result_size,
+ table_data->max_slices);
+ if (rc != 0) {
+ CFA_TCAM_MGR_LOG_DIR_TYPE(ERR,
+ dir, type,
+ "Failed to free entry ID %d at"
+ " row %d, slice %d for sess_idx %d. rc: %d.\n",
+ gparms.id,
+ source_row_index,
+ entry->slice,
+ sess_idx,
+ -rc);
+ }
+ }
+
+ ROW_ENTRY_SET(dest_row, dest_row_slice);
+ dest_row->entries[dest_row_slice] = entry_id;
+ ROW_ENTRY_CLEAR(source_row, entry->slice);
+ entry->row = dest_row_index;
+ entry->slice = dest_row_slice;
+
+ return 0;
+}
+
+static int
+cfa_tcam_mgr_row_move(int sess_idx, struct cfa_tcam_mgr_context *context,
+ enum tf_dir dir, enum cfa_tcam_mgr_tbl_type type,
+ struct cfa_tcam_mgr_table_data *table_data,
+ int dest_row_index,
+ struct cfa_tcam_mgr_table_rows_0 *dest_row,
+ int source_row_index,
+ struct cfa_tcam_mgr_table_rows_0 *source_row)
+{
+ struct cfa_tcam_mgr_free_parms fparms = { 0 };
+ int j, rc;
+
+ dest_row->priority = source_row->priority;
+ dest_row->entry_size = source_row->entry_size;
+ dest_row->entry_inuse = 0;
+
+ fparms.dir = dir;
+ fparms.type = type;
+ fparms.hcapi_type = table_data->hcapi_type;
+
+ for (j = 0;
+ j < (table_data->max_slices / source_row->entry_size);
+ j++) {
+ if (ROW_ENTRY_INUSE(source_row, j)) {
+ cfa_tcam_mgr_entry_move(sess_idx, context, dir, type,
+ source_row->entries[j],
+ table_data,
+ dest_row_index, j, dest_row,
+ source_row_index, source_row,
+ true);
+ } else {
+ /* Slice not in use, write an empty slice. */
+ rc = cfa_tcam_mgr_entry_free_msg(sess_idx, context, &fparms,
+ dest_row_index,
+ j *
+ dest_row->entry_size,
+ table_data->row_width /
+ table_data->max_slices *
+ dest_row->entry_size,
+ table_data->result_size,
+ table_data->max_slices);
+ if (rc != 0)
+ return rc;
+ }
+ }
+
+ return 0;
+}
+
+/* Install entry into in-memory tables, not into TCAM (yet). */
+static void
+cfa_tcam_mgr_row_entry_install(int sess_idx,
+ struct cfa_tcam_mgr_table_rows_0 *row,
+ struct cfa_tcam_mgr_alloc_parms *parms,
+ struct cfa_tcam_mgr_entry_data *entry,
+ uint16_t id,
+ int key_slices,
+ int row_index, int slice)
+{
+ if (global_data_initialized[sess_idx] == 0) {
+ CFA_TCAM_MGR_LOG(INFO, "PANIC: No TCAM data created for sess_idx %d\n",
+ sess_idx);
+ return;
+ }
+
+ if (slice == TF_TCAM_SLICE_INVALID) {
+ slice = 0;
+ row->entry_size = key_slices;
+ row->priority = parms->priority;
+ }
+
+ ROW_ENTRY_SET(row, slice);
+ row->entries[slice] = id;
+ entry->row = row_index;
+ entry->slice = slice;
+}
+
+/* Finds an empty row that can be used and reserve for entry. If necessary,
+ * entries will be shuffled in order to make room.
+ */
+static struct cfa_tcam_mgr_table_rows_0 *
+cfa_tcam_mgr_empty_row_alloc(int sess_idx, struct cfa_tcam_mgr_context *context,
+ struct cfa_tcam_mgr_alloc_parms *parms,
+ struct cfa_tcam_mgr_entry_data *entry,
+ uint16_t id,
+ int key_slices)
+{
+ struct cfa_tcam_mgr_table_rows_0 *tcam_rows;
+ struct cfa_tcam_mgr_table_rows_0 *from_row;
+ struct cfa_tcam_mgr_table_rows_0 *to_row;
+ struct cfa_tcam_mgr_table_rows_0 *row;
+ struct cfa_tcam_mgr_table_data *table_data;
+ int i, max_slices, row_size;
+ int to_row_idx, from_row_idx, slice, start_row, end_row;
+ int empty_row = -1;
+ int target_row = -1;
+
+ table_data = &cfa_tcam_mgr_tables[sess_idx][parms->dir][parms->type];
+
+ start_row = table_data->start_row;
+ end_row = table_data->end_row;
+ max_slices = table_data->max_slices;
+ tcam_rows = table_data->tcam_rows;
+
+ row_size = cfa_tcam_mgr_row_size_get(sess_idx, parms->dir, parms->type);
+
+ /*
+ * First check for partially used entries, but only if the key needs
+ * fewer slices than there are in a row.
+ */
+ if (key_slices < max_slices) {
+ for (i = start_row; i <= end_row; i++) {
+ row = cfa_tcam_mgr_row_ptr_get(tcam_rows, i, row_size);
+ if (!ROW_INUSE(row))
+ continue;
+ if (row->priority < parms->priority)
+ break;
+ if (row->priority > parms->priority)
+ continue;
+ slice = cfa_tcam_mgr_row_is_entry_free(row,
+ max_slices,
+ key_slices);
+ if (slice >= 0) {
+ cfa_tcam_mgr_row_entry_install(sess_idx, row, parms,
+ entry, id,
+ key_slices,
+ i, slice);
+ return row;
+ }
+ }
+ }
+
+ /* No partially used rows available. Find an empty row, if any. */
+
+ /*
+ * All max priority entries are placed in the beginning of the TCAM. It
+ * should not be necessary to shuffle any of these entries. All other
+ * priorities are placed from the end of the TCAM and may require
+ * shuffling.
+ */
+ if (parms->priority == TF_TCAM_PRIORITY_MAX) {
+ /* Handle max priority first. */
+ for (i = start_row; i <= end_row; i++) {
+ row = cfa_tcam_mgr_row_ptr_get(tcam_rows, i, row_size);
+ if (!ROW_INUSE(row)) {
+ cfa_tcam_mgr_row_entry_install(sess_idx,
+ row, parms,
+ entry,
+ id, key_slices,
+ i,
+ TF_TCAM_SLICE_INVALID);
+ return row;
+ }
+ if (row->priority < parms->priority) {
+ /*
+ * No free entries before priority change, table
+ * is full.
+ */
+ return NULL;
+ }
+ }
+ /* No free entries found, table is full. */
+ return NULL;
+ }
+
+ /* Use the highest available entry */
+ for (i = end_row; i >= start_row; i--) {
+ row = cfa_tcam_mgr_row_ptr_get(tcam_rows, i, row_size);
+ if (!ROW_INUSE(row)) {
+ empty_row = i;
+ break;
+ }
+
+ if (row->priority > parms->priority &&
+ target_row < 0)
+ target_row = i;
+ }
+
+ if (empty_row < 0) {
+ /* No free entries found, table is full. */
+ return NULL;
+ }
+
+ if (target_row < 0) {
+ /*
+ * Did not find a row with higher priority before unused row so
+ * just install new entry in empty_row.
+ */
+ row = cfa_tcam_mgr_row_ptr_get(tcam_rows, empty_row, row_size);
+ cfa_tcam_mgr_row_entry_install(sess_idx, row, parms, entry, id,
+ key_slices, empty_row,
+ TF_TCAM_SLICE_INVALID);
+ return row;
+ }
+
+ to_row_idx = empty_row;
+ to_row = cfa_tcam_mgr_row_ptr_get(tcam_rows, to_row_idx, row_size);
+ while (to_row_idx < target_row) {
+ from_row_idx = to_row_idx + 1;
+ from_row = cfa_tcam_mgr_row_ptr_get(tcam_rows, from_row_idx,
+ row_size);
+ /*
+ * Find the highest row with the same priority as the initial
+ * source row (from_row). It's only necessary to copy one row
+ * of each priority.
+ */
+ for (i = from_row_idx + 1; i <= target_row; i++) {
+ row = cfa_tcam_mgr_row_ptr_get(tcam_rows, i, row_size);
+ if (row->priority != from_row->priority)
+ break;
+ from_row_idx = i;
+ from_row = row;
+ }
+ cfa_tcam_mgr_row_move(sess_idx, context, parms->dir, parms->type,
+ table_data, to_row_idx, to_row,
+ from_row_idx, from_row);
+ to_row = from_row;
+ to_row_idx = from_row_idx;
+ }
+ to_row = cfa_tcam_mgr_row_ptr_get(tcam_rows, target_row, row_size);
+ memset(to_row, 0, row_size);
+ cfa_tcam_mgr_row_entry_install(sess_idx, to_row, parms, entry, id,
+ key_slices, target_row,
+ TF_TCAM_SLICE_INVALID);
+
+ return row;
+}
+
+/*
+ * This function will combine rows when possible to result in the fewest rows
+ * used necessary for the entries that are installed.
+ */
+static void
+cfa_tcam_mgr_rows_combine(int sess_idx, struct cfa_tcam_mgr_context *context,
+ struct cfa_tcam_mgr_free_parms *parms,
+ struct cfa_tcam_mgr_table_data *table_data,
+ int changed_row_index)
+{
+ struct cfa_tcam_mgr_table_rows_0 *from_row = NULL;
+ struct cfa_tcam_mgr_table_rows_0 *to_row;
+ struct cfa_tcam_mgr_table_rows_0 *tcam_rows;
+ int i, j, row_size;
+ int to_row_idx, from_row_idx, start_row, end_row, max_slices;
+ bool entry_moved = false;
+
+ start_row = table_data->start_row;
+ end_row = table_data->end_row;
+ max_slices = table_data->max_slices;
+ tcam_rows = table_data->tcam_rows;
+
+ row_size = cfa_tcam_mgr_row_size_get(sess_idx, parms->dir, parms->type);
+
+ from_row_idx = changed_row_index;
+ from_row = cfa_tcam_mgr_row_ptr_get(tcam_rows, from_row_idx, row_size);
+
+ if (ROW_INUSE(from_row)) {
+ /*
+ * Row is still in partial use. See if remaining entry(s) can
+ * be moved to free up a row.
+ */
+ for (i = 0; i < (max_slices / from_row->entry_size); i++) {
+ if (!ROW_ENTRY_INUSE(from_row, i))
+ continue;
+ for (to_row_idx = end_row;
+ to_row_idx >= start_row;
+ to_row_idx--) {
+ to_row = cfa_tcam_mgr_row_ptr_get(tcam_rows,
+ to_row_idx,
+ row_size);
+ if (!ROW_INUSE(to_row))
+ continue;
+ if (to_row->priority > from_row->priority)
+ break;
+ if (to_row->priority != from_row->priority)
+ continue;
+ if (to_row->entry_size != from_row->entry_size)
+ continue;
+ if (to_row_idx == changed_row_index)
+ continue;
+ for (j = 0;
+ j < (max_slices / to_row->entry_size);
+ j++) {
+ if (!ROW_ENTRY_INUSE(to_row, j)) {
+ cfa_tcam_mgr_entry_move
+ (sess_idx,
+ context,
+ parms->dir,
+ parms->type,
+ from_row->entries[i],
+ table_data,
+ to_row_idx,
+ -1, to_row,
+ from_row_idx,
+ from_row,
+ true);
+ entry_moved = true;
+ break;
+ }
+ }
+ if (entry_moved)
+ break;
+ }
+ if (ROW_INUSE(from_row))
+ entry_moved = false;
+ else
+ break;
+ }
+ }
+}
+
+/*
+ * This function will ensure that all rows, except those of the highest
+ * priority, at the end of the table. When this function is finished, all the
+ * empty rows should be between the highest priority rows at the beginning of
+ * the table and the rest of the rows with lower priorities.
+ */
+/*
+ * Will need to free the row left newly empty as a result of moving.
+ *
+ * Return row to free to caller. If new_row_to_free < 0, then no new row to
+ * free.
+ */
+static void
+cfa_tcam_mgr_rows_compact(int sess_idx, struct cfa_tcam_mgr_context *context,
+ struct cfa_tcam_mgr_free_parms *parms,
+ struct cfa_tcam_mgr_table_data *table_data,
+ int *new_row_to_free,
+ int changed_row_index)
+{
+ struct cfa_tcam_mgr_table_rows_0 *from_row = NULL;
+ struct cfa_tcam_mgr_table_rows_0 *to_row;
+ struct cfa_tcam_mgr_table_rows_0 *row;
+ struct cfa_tcam_mgr_table_rows_0 *tcam_rows;
+ int i, row_size, priority;
+ int to_row_idx = 0, from_row_idx = 0, start_row = 0, end_row = 0;
+
+ *new_row_to_free = -1;
+
+ start_row = table_data->start_row;
+ end_row = table_data->end_row;
+ tcam_rows = table_data->tcam_rows;
+
+ row_size = cfa_tcam_mgr_row_size_get(sess_idx, parms->dir, parms->type);
+
+ /*
+ * The row is no longer in use, so see if rows need to be moved in order
+ * to not leave any gaps.
+ */
+ to_row_idx = changed_row_index;
+ to_row = cfa_tcam_mgr_row_ptr_get(tcam_rows, to_row_idx, row_size);
+
+ priority = to_row->priority;
+ if (priority == TF_TCAM_PRIORITY_MAX) {
+ if (changed_row_index == end_row)
+ /*
+ * Nothing to move - the last row in the TCAM is being
+ * deleted.
+ */
+ return;
+ for (i = changed_row_index + 1; i <= end_row; i++) {
+ row = cfa_tcam_mgr_row_ptr_get(tcam_rows, i, row_size);
+ if (!ROW_INUSE(row))
+ break;
+
+ if (row->priority < priority)
+ break;
+
+ from_row = row;
+ from_row_idx = i;
+ }
+ } else {
+ if (changed_row_index == start_row)
+ /*
+ * Nothing to move - the first row in the TCAM is being
+ * deleted.
+ */
+ return;
+ for (i = changed_row_index - 1; i >= start_row; i--) {
+ row = cfa_tcam_mgr_row_ptr_get(tcam_rows, i, row_size);
+ if (!ROW_INUSE(row))
+ break;
+
+ if (row->priority > priority) {
+ /* Don't move the highest priority rows. */
+ if (row->priority == TF_TCAM_PRIORITY_MAX)
+ break;
+ /*
+ * If from_row is NULL, that means that there
+ * were no rows of the deleted priority.
+ * Nothing to move yet.
+ *
+ * If from_row is not NULL, then it is the last
+ * row with the same priority and must be moved
+ * to fill the newly empty (by free or by move)
+ * row.
+ */
+ if (from_row != NULL) {
+ cfa_tcam_mgr_row_move(sess_idx, context,
+ parms->dir,
+ parms->type,
+ table_data,
+ to_row_idx, to_row,
+ from_row_idx,
+ from_row);
+ *new_row_to_free = from_row_idx;
+ to_row = from_row;
+ to_row_idx = from_row_idx;
+ }
+
+ priority = row->priority;
+ }
+ from_row = row;
+ from_row_idx = i;
+ }
+ }
+
+ if (from_row != NULL) {
+ cfa_tcam_mgr_row_move(sess_idx, context, parms->dir, parms->type,
+ table_data,
+ to_row_idx, to_row,
+ from_row_idx, from_row);
+ *new_row_to_free = from_row_idx;
+ }
+}
+
+/*
+ * This function is to set table limits for the logical TCAM tables.
+ */
+static int
+cfa_tcam_mgr_table_limits_set(int sess_idx, struct cfa_tcam_mgr_init_parms *parms)
+{
+ struct cfa_tcam_mgr_table_data *table_data;
+ unsigned int dir, type;
+ int start, stride;
+
+ if (parms == NULL)
+ return 0;
+
+ for (dir = 0; dir < ARRAY_SIZE(cfa_tcam_mgr_tables[sess_idx]); dir++)
+ for (type = 0;
+ type < ARRAY_SIZE(cfa_tcam_mgr_tables[sess_idx][dir]);
+ type++) {
+ table_data = &cfa_tcam_mgr_tables[sess_idx][dir][type];
+ /*
+ * If num_rows is zero, then TCAM Manager did not
+ * allocate any row storage for that table so cannot
+ * manage it.
+ */
+ if (table_data->num_rows == 0)
+ continue;
+ start = parms->resc[dir][type].start;
+ stride = parms->resc[dir][type].stride;
+ if (start % table_data->max_slices > 0) {
+ CFA_TCAM_MGR_LOG_DIR_TYPE(ERR, dir, type,
+ "Start of resources (%d) for table (%d) "
+ "does not begin on row boundary.\n",
+ start, sess_idx);
+ CFA_TCAM_MGR_LOG_DIR(ERR, dir,
+ "Start is %d, number of slices "
+ "is %d.\n",
+ start,
+ table_data->max_slices);
+ return -CFA_TCAM_MGR_ERR_CODE(INVAL);
+ }
+ if (stride % table_data->max_slices > 0) {
+ CFA_TCAM_MGR_LOG_DIR_TYPE(ERR, dir, type,
+ "Stride of resources (%d) for table (%d)"
+ " does not end on row boundary.\n",
+ stride, sess_idx);
+ CFA_TCAM_MGR_LOG_DIR(ERR, dir,
+ "Stride is %d, number of "
+ "slices is %d.\n",
+ stride,
+ table_data->max_slices);
+ return -CFA_TCAM_MGR_ERR_CODE(INVAL);
+ }
+ if (stride == 0) {
+ table_data->start_row = 0;
+ table_data->end_row = 0;
+ table_data->max_entries = 0;
+ } else {
+ table_data->start_row = start /
+ table_data->max_slices;
+ table_data->end_row = table_data->start_row +
+ (stride / table_data->max_slices) - 1;
+ table_data->max_entries =
+ table_data->max_slices *
+ (table_data->end_row -
+ table_data->start_row + 1);
+ }
+ }
+
+ return 0;
+}
+
+int
+cfa_tcam_mgr_init(int sess_idx, enum cfa_tcam_mgr_device_type type,
+ struct cfa_tcam_mgr_init_parms *parms)
+{
+ struct cfa_tcam_mgr_table_data *table_data;
+ unsigned int dir, tbl_type;
+ int rc;
+
+ switch (type) {
+ case CFA_TCAM_MGR_DEVICE_TYPE_P4:
+ case CFA_TCAM_MGR_DEVICE_TYPE_SR:
+ rc = cfa_tcam_mgr_init_p4(sess_idx, &entry_data[sess_idx]);
+ break;
+ case CFA_TCAM_MGR_DEVICE_TYPE_P5:
+ rc = cfa_tcam_mgr_init_p58(sess_idx, &entry_data[sess_idx]);
+ break;
+ default:
+ CFA_TCAM_MGR_LOG(ERR, "No such device %d for sess_idx %d\n",
+ type, sess_idx);
+ return -CFA_TCAM_MGR_ERR_CODE(NODEV);
+ }
+ if (rc < 0)
+ return rc;
+
+ rc = cfa_tcam_mgr_table_limits_set(sess_idx, parms);
+ if (rc < 0)
+ return rc;
+
+ /* Now calculate the max entries per table and global max entries based
+ * on the updated table limits.
+ */
+ for (dir = 0; dir < ARRAY_SIZE(cfa_tcam_mgr_tables[sess_idx]); dir++)
+ for (tbl_type = 0;
+ tbl_type < ARRAY_SIZE(cfa_tcam_mgr_tables[sess_idx][dir]);
+ tbl_type++) {
+ table_data = &cfa_tcam_mgr_tables[sess_idx][dir][tbl_type];
+ /*
+ * If num_rows is zero, then TCAM Manager did not
+ * allocate any row storage for that table so cannot
+ * manage it.
+ */
+ if (table_data->num_rows == 0) {
+ table_data->start_row = 0;
+ table_data->end_row = 0;
+ table_data->max_entries = 0;
+ } else if (table_data->end_row >=
+ table_data->num_rows) {
+ CFA_TCAM_MGR_LOG_DIR_TYPE(EMERG, dir, tbl_type,
+ "End row is out of "
+ "range (%d >= %d) for sess_idx %d\n",
+ table_data->end_row,
+ table_data->num_rows,
+ sess_idx);
+ return -CFA_TCAM_MGR_ERR_CODE(FAULT);
+ } else if (table_data->max_entries == 0 &&
+ table_data->start_row == 0 &&
+ table_data->end_row == 0) {
+ /* Nothing to do */
+ } else {
+ table_data->max_entries =
+ table_data->max_slices *
+ (table_data->end_row -
+ table_data->start_row + 1);
+ }
+ cfa_tcam_mgr_max_entries[sess_idx] += table_data->max_entries;
+ }
+
+ rc = cfa_tcam_mgr_hwops_init(type);
+ if (rc < 0)
+ return rc;
+
+ rc = cfa_tcam_mgr_session_init(sess_idx, type);
+ if (rc < 0)
+ return rc;
+
+ global_data_initialized[sess_idx] = 1;
+
+ if (parms != NULL)
+ parms->max_entries = cfa_tcam_mgr_max_entries[sess_idx];
+
+ CFA_TCAM_MGR_LOG(INFO, "Global TCAM table initialized for sess_idx %d.\n",
+ sess_idx);
+
+ return 0;
+}
+
+int
+cfa_tcam_mgr_qcaps(struct cfa_tcam_mgr_context *context __rte_unused,
+ struct cfa_tcam_mgr_qcaps_parms *parms)
+{
+ unsigned int type;
+ int rc, sess_idx;
+ uint32_t session_id;
+
+ CFA_TCAM_MGR_CHECK_PARMS2(context, parms);
+
+ rc = cfa_tcam_mgr_get_session_from_context(context, &session_id);
+ if (rc < 0)
+ return rc;
+
+ sess_idx = cfa_tcam_mgr_session_find(session_id);
+ if (sess_idx < 0) {
+ CFA_TCAM_MGR_LOG_0(ERR, "Session not found.\n");
+ return sess_idx;
+ }
+
+ if (global_data_initialized[sess_idx] == 0) {
+ CFA_TCAM_MGR_LOG(ERR, "PANIC: No TCAM data created for sess_idx %d\n",
+ sess_idx);
+ return -CFA_TCAM_MGR_ERR_CODE(PERM);
+ }
+
+ /*
+ * This code will indicate if TCAM Manager is managing a logical TCAM
+ * table or not. If not, then the physical TCAM will have to be
+ * accessed using the traditional methods.
+ */
+ parms->rx_tcam_supported = 0;
+ parms->tx_tcam_supported = 0;
+ for (type = 0; type < CFA_TCAM_MGR_TBL_TYPE_MAX; type++) {
+ if (cfa_tcam_mgr_tables[sess_idx][TF_DIR_RX][type].max_entries > 0 &&
+ cfa_tcam_mgr_tables[sess_idx][TF_DIR_RX][type].hcapi_type > 0)
+ parms->rx_tcam_supported |= 1 << cfa_tcam_mgr_get_phys_table_type(type);
+ if (cfa_tcam_mgr_tables[sess_idx][TF_DIR_TX][type].max_entries > 0 &&
+ cfa_tcam_mgr_tables[sess_idx][TF_DIR_TX][type].hcapi_type > 0)
+ parms->tx_tcam_supported |= 1 << cfa_tcam_mgr_get_phys_table_type(type);
+ }
+
+ return 0;
+}
+
+/*
+ * Manipulate the tables to split the WC TCAM into HIGH and LOW ranges
+ * and also update the sizes in the tcam count array
+ */
+static int
+cfa_tcam_mgr_shared_wc_bind(uint32_t sess_idx, bool dual_ha_app,
+ uint16_t tcam_cnt[][CFA_TCAM_MGR_TBL_TYPE_MAX])
+{
+ uint16_t start_row, end_row, max_entries, slices;
+ uint16_t num_pools = dual_ha_app ? 4 : 2;
+ enum tf_dir dir;
+ int rc;
+
+ for (dir = 0; dir < TF_DIR_MAX; dir++) {
+ rc = cfa_tcam_mgr_tables_get(sess_idx, dir,
+ CFA_TCAM_MGR_TBL_TYPE_WC_TCAM_APPS,
+ &start_row, &end_row, &max_entries, &slices);
+ if (rc)
+ return rc;
+ if (max_entries) {
+ rc = cfa_tcam_mgr_tables_set(sess_idx, dir,
+ CFA_TCAM_MGR_TBL_TYPE_WC_TCAM_HIGH_APPS,
+ start_row,
+ start_row +
+ ((max_entries / slices) / num_pools) - 1,
+ max_entries / num_pools);
+ if (rc)
+ return rc;
+ rc = cfa_tcam_mgr_tables_set(sess_idx, dir,
+ CFA_TCAM_MGR_TBL_TYPE_WC_TCAM_LOW_APPS,
+ start_row +
+ ((max_entries / slices) / num_pools),
+ start_row +
+ (max_entries / slices) - 1,
+ max_entries / num_pools);
+ if (rc)
+ return rc;
+ rc = cfa_tcam_mgr_tables_set(sess_idx, dir,
+ CFA_TCAM_MGR_TBL_TYPE_WC_TCAM_APPS,
+ 0, 0, 0);
+ if (rc)
+ return rc;
+ tcam_cnt[dir][CFA_TCAM_MGR_TBL_TYPE_WC_TCAM_HIGH_APPS] =
+ max_entries / num_pools;
+ tcam_cnt[dir][CFA_TCAM_MGR_TBL_TYPE_WC_TCAM_LOW_APPS] =
+ max_entries / num_pools;
+ tcam_cnt[dir][CFA_TCAM_MGR_TBL_TYPE_WC_TCAM_APPS] = 0;
+ }
+ }
+
+ return 0;
+}
+
+int
+cfa_tcam_mgr_bind(struct cfa_tcam_mgr_context *context,
+ struct cfa_tcam_mgr_cfg_parms *parms)
+{
+ struct cfa_tcam_mgr_table_data *table_data;
+ struct tf_dev_info *dev;
+ unsigned int dir;
+ int rc, sess_idx;
+ uint32_t session_id;
+ struct tf_session *tfs;
+ unsigned int type;
+ int prev_max_entries;
+ int start, stride;
+ enum cfa_tcam_mgr_device_type device_type;
+
+ CFA_TCAM_MGR_CHECK_PARMS2(context, parms);
+
+ /* Retrieve the session information */
+ rc = tf_session_get_session_internal(context->tfp, &tfs);
+ if (rc)
+ return rc;
+
+ /* Retrieve the device information */
+ rc = tf_session_get_device(tfs, &dev);
+ if (rc)
+ return rc;
+
+ switch (dev->type) {
+ case TF_DEVICE_TYPE_P4:
+ device_type = CFA_TCAM_MGR_DEVICE_TYPE_P4;
+ break;
+ case TF_DEVICE_TYPE_SR:
+ device_type = CFA_TCAM_MGR_DEVICE_TYPE_SR;
+ break;
+ case TF_DEVICE_TYPE_P5:
+ device_type = CFA_TCAM_MGR_DEVICE_TYPE_P5;
+ break;
+ default:
+ CFA_TCAM_MGR_LOG(ERR, "No such device %d\n", dev->type);
+ return -CFA_TCAM_MGR_ERR_CODE(NODEV);
+ }
+
+ rc = cfa_tcam_mgr_get_session_from_context(context, &session_id);
+ if (rc < 0)
+ return rc;
+
+ sess_idx = cfa_tcam_mgr_session_add(session_id);
+ if (sess_idx < 0)
+ return sess_idx;
+
+ if (global_data_initialized[sess_idx] == 0) {
+ rc = cfa_tcam_mgr_init(sess_idx, device_type, NULL);
+ if (rc < 0)
+ return rc;
+ }
+
+ if (parms->num_elements != ARRAY_SIZE(cfa_tcam_mgr_tables[sess_idx][dir])) {
+ CFA_TCAM_MGR_LOG(ERR,
+ "Session element count (%d) differs "
+ "from table count (%zu) for sess_idx %d.\n",
+ parms->num_elements,
+ ARRAY_SIZE(cfa_tcam_mgr_tables[sess_idx][dir]),
+ sess_idx);
+ return -CFA_TCAM_MGR_ERR_CODE(INVAL);
+ }
+
+ /*
+ * Only managing one session. resv_res contains the resources allocated
+ * to this session by the resource manager. Update the limits on TCAMs.
+ */
+ for (dir = 0; dir < ARRAY_SIZE(cfa_tcam_mgr_tables[sess_idx]); dir++) {
+ for (type = 0;
+ type < ARRAY_SIZE(cfa_tcam_mgr_tables[sess_idx][dir]);
+ type++) {
+ table_data = &cfa_tcam_mgr_tables[sess_idx][dir][type];
+ prev_max_entries = table_data->max_entries;
+ /*
+ * In AFM logical tables, max_entries is initialized to
+ * zero. These logical tables are not used when TCAM
+ * Manager is in the core so skip.
+ */
+ if (prev_max_entries == 0)
+ continue;
+ start = parms->resv_res[dir][type].start;
+ stride = parms->resv_res[dir][type].stride;
+ if (start % table_data->max_slices > 0) {
+ CFA_TCAM_MGR_LOG_DIR_TYPE(ERR, dir, type,
+ "Start of resources (%d) for table(%d) "
+ "does not begin on row boundary.\n",
+ start, sess_idx);
+ CFA_TCAM_MGR_LOG_DIR(ERR, dir,
+ "Start is %d, number of slices "
+ "is %d.\n",
+ start,
+ table_data->max_slices);
+ (void)cfa_tcam_mgr_session_free(session_id, context);
+ return -CFA_TCAM_MGR_ERR_CODE(INVAL);
+ }
+ if (stride % table_data->max_slices > 0) {
+ CFA_TCAM_MGR_LOG_DIR_TYPE(ERR, dir, type,
+ "Stride of resources (%d) for table(%d) "
+ "does not end on row boundary.\n",
+ stride, sess_idx);
+ CFA_TCAM_MGR_LOG_DIR(ERR, dir,
+ "Stride is %d, number of "
+ "slices is %d.\n",
+ stride,
+ table_data->max_slices);
+ (void)cfa_tcam_mgr_session_free(session_id, context);
+ return -CFA_TCAM_MGR_ERR_CODE(INVAL);
+ }
+ if (stride == 0) {
+ table_data->start_row = 0;
+ table_data->end_row = 0;
+ table_data->max_entries = 0;
+ } else {
+ table_data->start_row = start /
+ table_data->max_slices;
+ table_data->end_row = table_data->start_row +
+ (stride / table_data->max_slices) - 1;
+ table_data->max_entries =
+ table_data->max_slices *
+ (table_data->end_row -
+ table_data->start_row + 1);
+ }
+ cfa_tcam_mgr_max_entries[sess_idx] += (table_data->max_entries -
+ prev_max_entries);
+ }
+ }
+
+ if (tf_session_is_shared_hotup_session(tfs)) {
+ rc = cfa_tcam_mgr_shared_wc_bind(sess_idx, false, parms->tcam_cnt);
+ if (rc) {
+ (void)cfa_tcam_mgr_session_free(session_id, context);
+ return rc;
+ }
+ }
+
+ rc = cfa_tcam_mgr_session_cfg(session_id, parms->tcam_cnt);
+ if (rc < 0) {
+ (void)cfa_tcam_mgr_session_free(session_id, context);
+ return rc;
+ }
+
+ return 0;
+}
+
+int
+cfa_tcam_mgr_unbind(struct cfa_tcam_mgr_context *context)
+{
+ int rc, sess_idx;
+ uint32_t session_id;
+
+ CFA_TCAM_MGR_CHECK_PARMS1(context);
+
+ rc = cfa_tcam_mgr_get_session_from_context(context, &session_id);
+ if (rc < 0)
+ return rc;
+
+ sess_idx = cfa_tcam_mgr_session_find(session_id);
+ if (sess_idx < 0) {
+ CFA_TCAM_MGR_LOG_0(ERR, "Session not found.\n");
+ return sess_idx;
+ }
+
+ if (global_data_initialized[sess_idx] == 0) {
+ CFA_TCAM_MGR_LOG(INFO, "PANIC: No TCAM data created for sess_idx %d\n",
+ sess_idx);
+ return -CFA_TCAM_MGR_ERR_CODE(PERM);
+ }
+
+ (void)cfa_tcam_mgr_session_free(session_id, context);
+
+ global_data_initialized[sess_idx] = 0;
+ return 0;
+}
+
+int
+cfa_tcam_mgr_alloc(struct cfa_tcam_mgr_context *context,
+ struct cfa_tcam_mgr_alloc_parms *parms)
+{
+ struct cfa_tcam_mgr_entry_data entry;
+ struct cfa_tcam_mgr_table_rows_0 *row;
+ struct cfa_tcam_mgr_table_data *table_data;
+ int dir, tbl_type;
+ int key_slices, rc, sess_idx;
+ int new_entry_id;
+ uint32_t session_id;
+
+ CFA_TCAM_MGR_CHECK_PARMS2(context, parms);
+
+ dir = parms->dir;
+ tbl_type = parms->type;
+
+ if (dir >= TF_DIR_MAX) {
+ CFA_TCAM_MGR_LOG(ERR, "Invalid direction: %d.\n", dir);
+ return -CFA_TCAM_MGR_ERR_CODE(INVAL);
+ }
+
+ if (tbl_type >= CFA_TCAM_MGR_TBL_TYPE_MAX) {
+ CFA_TCAM_MGR_LOG_DIR(ERR, dir,
+ "Invalid table type: %d.\n",
+ tbl_type);
+ return -CFA_TCAM_MGR_ERR_CODE(INVAL);
+ }
+
+#if TF_TCAM_PRIORITY_MAX < UINT16_MAX
+ if (parms->priority > TF_TCAM_PRIORITY_MAX) {
+ CFA_TCAM_MGR_LOG_DIR(ERR, dir,
+ "Priority (%u) out of range (%u -%u).\n",
+ parms->priority,
+ TF_TCAM_PRIORITY_MIN,
+ TF_TCAM_PRIORITY_MAX);
+ }
+#endif
+
+ /* Check for session limits */
+ rc = cfa_tcam_mgr_get_session_from_context(context, &session_id);
+ if (rc < 0)
+ return rc;
+
+ sess_idx = cfa_tcam_mgr_session_find(session_id);
+ if (sess_idx < 0) {
+ CFA_TCAM_MGR_LOG(ERR, "Session 0x%08x not found.\n",
+ session_id);
+ return -CFA_TCAM_MGR_ERR_CODE(NODEV);
+ }
+
+ if (global_data_initialized[sess_idx] == 0) {
+ CFA_TCAM_MGR_LOG(ERR, "PANIC: No TCAM data created for sess_idx %d\n",
+ sess_idx);
+ return -CFA_TCAM_MGR_ERR_CODE(PERM);
+ }
+
+ table_data = &cfa_tcam_mgr_tables[sess_idx][dir][tbl_type];
+
+ if (parms->key_size == 0 ||
+ parms->key_size > table_data->row_width) {
+ CFA_TCAM_MGR_LOG_DIR(ERR, dir,
+ "Invalid key size:%d (range 1-%d) sess_idx %d.\n",
+ parms->key_size,
+ table_data->row_width,
+ sess_idx);
+ return -CFA_TCAM_MGR_ERR_CODE(INVAL);
+ }
+
+ /* Check global limits */
+ if (table_data->used_entries >=
+ table_data->max_entries) {
+ CFA_TCAM_MGR_LOG_DIR_TYPE(ERR, dir, tbl_type,
+ "Table full sess_idx %d.\n",
+ sess_idx);
+ return -CFA_TCAM_MGR_ERR_CODE(NOSPC);
+ }
+
+ /* There is room, now increment counts and allocate an entry. */
+ new_entry_id = cfa_tcam_mgr_session_entry_alloc(session_id,
+ parms->dir,
+ parms->type);
+ if (new_entry_id < 0)
+ return new_entry_id;
+
+ memset(&entry, 0, sizeof(entry));
+ entry.ref_cnt++;
+
+ key_slices = cfa_tcam_mgr_get_num_slices(parms->key_size,
+ (table_data->row_width /
+ table_data->max_slices));
+
+ row = cfa_tcam_mgr_empty_row_alloc(sess_idx, context, parms, &entry,
+ new_entry_id, key_slices);
+ if (row == NULL) {
+ CFA_TCAM_MGR_LOG_DIR_TYPE(ERR, parms->dir, parms->type,
+ "Table full (HW) sess_idx %d.\n",
+ sess_idx);
+ (void)cfa_tcam_mgr_session_entry_free(session_id, new_entry_id,
+ parms->dir, parms->type);
+ return -CFA_TCAM_MGR_ERR_CODE(NOSPC);
+ }
+
+ memcpy(&entry_data[sess_idx][new_entry_id],
+ &entry,
+ sizeof(entry_data[sess_idx][new_entry_id]));
+ table_data->used_entries += 1;
+
+ cfa_tcam_mgr_entry_insert(sess_idx, new_entry_id, &entry);
+
+ parms->id = new_entry_id;
+
+ return 0;
+}
+
+int
+cfa_tcam_mgr_free(struct cfa_tcam_mgr_context *context,
+ struct cfa_tcam_mgr_free_parms *parms)
+{
+ struct cfa_tcam_mgr_entry_data *entry;
+ struct cfa_tcam_mgr_table_rows_0 *row;
+ struct cfa_tcam_mgr_table_data *table_data;
+ int row_size, rc, sess_idx, new_row_to_free;
+ uint32_t session_id;
+ uint16_t id;
+
+ CFA_TCAM_MGR_CHECK_PARMS2(context, parms);
+
+ rc = cfa_tcam_mgr_get_session_from_context(context, &session_id);
+ if (rc < 0)
+ return rc;
+
+ sess_idx = cfa_tcam_mgr_session_find(session_id);
+ if (sess_idx < 0) {
+ CFA_TCAM_MGR_LOG(ERR, "Session 0x%08x not found.\n",
+ session_id);
+ return sess_idx;
+ }
+
+ if (global_data_initialized[sess_idx] == 0) {
+ CFA_TCAM_MGR_LOG(INFO, "PANIC: No TCAM data created for sess_idx %d\n",
+ sess_idx);
+ return -CFA_TCAM_MGR_ERR_CODE(PERM);
+ }
+
+ id = parms->id;
+ entry = cfa_tcam_mgr_entry_get(sess_idx, id);
+ if (entry == NULL) {
+ CFA_TCAM_MGR_LOG(INFO, "Entry %d not found for sess_idx %d.\n",
+ id, sess_idx);
+ return -CFA_TCAM_MGR_ERR_CODE(INVAL);
+ }
+
+ if (entry->ref_cnt == 0) {
+ CFA_TCAM_MGR_LOG(ERR, "Entry %d not in use for sess_idx %d.\n",
+ id, sess_idx);
+ return -CFA_TCAM_MGR_ERR_CODE(INVAL);
+ }
+
+ /*
+ * If the TCAM type is CFA_TCAM_MGR_TBL_TYPE_MAX, that implies that the
+ * caller does not know the table or direction of the entry and TCAM
+ * Manager must search the tables to find out which table has the entry
+ * installed.
+ *
+ * This would be the case if RM has informed TCAM Mgr that an entry must
+ * be freed. Clients (sessions, AFM) should always know the type and
+ * direction of the table where an entry is installed.
+ */
+ if (parms->type == CFA_TCAM_MGR_TBL_TYPE_MAX) {
+ /* Need to search for the entry in the tables */
+ rc = cfa_tcam_mgr_entry_find(sess_idx, id, &parms->dir, &parms->type);
+ if (rc < 0) {
+ CFA_TCAM_MGR_LOG(ERR, "Entry %d not in tables for sess_idx %d.\n",
+ id, sess_idx);
+ return rc;
+ }
+ }
+
+ table_data = &cfa_tcam_mgr_tables[sess_idx][parms->dir][parms->type];
+ parms->hcapi_type = table_data->hcapi_type;
+
+ row_size = cfa_tcam_mgr_row_size_get(sess_idx, parms->dir, parms->type);
+
+ row = cfa_tcam_mgr_row_ptr_get(table_data->tcam_rows, entry->row,
+ row_size);
+
+ entry->ref_cnt--;
+
+ (void)cfa_tcam_mgr_session_entry_free(session_id, id,
+ parms->dir, parms->type);
+
+ if (entry->ref_cnt == 0) {
+ cfa_tcam_mgr_entry_free_msg(sess_idx, context, parms,
+ entry->row,
+ entry->slice * row->entry_size,
+ table_data->row_width /
+ table_data->max_slices *
+ row->entry_size,
+ table_data->result_size,
+ table_data->max_slices);
+ ROW_ENTRY_CLEAR(row, entry->slice);
+
+ new_row_to_free = entry->row;
+ cfa_tcam_mgr_rows_combine(sess_idx, context, parms, table_data,
+ new_row_to_free);
+
+ if (!ROW_INUSE(row)) {
+ cfa_tcam_mgr_rows_compact(sess_idx, context,
+ parms, table_data,
+ &new_row_to_free,
+ new_row_to_free);
+ if (new_row_to_free >= 0)
+ cfa_tcam_mgr_entry_free_msg(sess_idx, context, parms,
+ new_row_to_free, 0,
+ table_data->row_width,
+ table_data->result_size,
+ table_data->max_slices);
+ }
+
+ cfa_tcam_mgr_entry_delete(sess_idx, id);
+ table_data->used_entries -= 1;
+ }
+
+ return 0;
+}
+
+int
+cfa_tcam_mgr_set(struct cfa_tcam_mgr_context *context,
+ struct cfa_tcam_mgr_set_parms *parms)
+{
+ struct cfa_tcam_mgr_entry_data *entry;
+ struct cfa_tcam_mgr_table_rows_0 *row;
+ struct cfa_tcam_mgr_table_data *table_data;
+ int rc;
+ int row_size, sess_idx;
+ int entry_size_in_bytes;
+ uint32_t session_id;
+
+ CFA_TCAM_MGR_CHECK_PARMS2(context, parms);
+
+ rc = cfa_tcam_mgr_get_session_from_context(context, &session_id);
+ if (rc < 0)
+ return rc;
+
+ sess_idx = cfa_tcam_mgr_session_find(session_id);
+ if (sess_idx < 0) {
+ CFA_TCAM_MGR_LOG(ERR, "Session 0x%08x not found.\n",
+ session_id);
+ return sess_idx;
+ }
+
+ if (global_data_initialized[sess_idx] == 0) {
+ CFA_TCAM_MGR_LOG(ERR, "PANIC: No TCAM data created for sess_idx %d\n",
+ sess_idx);
+ return -CFA_TCAM_MGR_ERR_CODE(PERM);
+ }
+
+ entry = cfa_tcam_mgr_entry_get(sess_idx, parms->id);
+ if (entry == NULL) {
+ CFA_TCAM_MGR_LOG(ERR, "Entry %d not found for sess_idx %d.\n",
+ parms->id, sess_idx);
+ return -CFA_TCAM_MGR_ERR_CODE(INVAL);
+ }
+
+ table_data = &cfa_tcam_mgr_tables[sess_idx][parms->dir][parms->type];
+ parms->hcapi_type = table_data->hcapi_type;
+
+ row_size = cfa_tcam_mgr_row_size_get(sess_idx, parms->dir, parms->type);
+ row = cfa_tcam_mgr_row_ptr_get(table_data->tcam_rows, entry->row,
+ row_size);
+
+ entry_size_in_bytes = table_data->row_width /
+ table_data->max_slices *
+ row->entry_size;
+ if (parms->key_size != entry_size_in_bytes) {
+ CFA_TCAM_MGR_LOG(ERR,
+ "Key size(%d) is different from entry "
+ "size(%d).\n",
+ parms->key_size,
+ entry_size_in_bytes);
+ return -CFA_TCAM_MGR_ERR_CODE(INVAL);
+ }
+
+ rc = cfa_tcam_mgr_entry_set_msg(sess_idx, context, parms,
+ entry->row,
+ entry->slice * row->entry_size,
+ table_data->max_slices);
+ if (rc < 0) {
+ CFA_TCAM_MGR_LOG_0(ERR, "Failed to set TCAM data.\n");
+ return rc;
+ }
+
+ return 0;
+}
+
+int
+cfa_tcam_mgr_get(struct cfa_tcam_mgr_context *context __rte_unused,
+ struct cfa_tcam_mgr_get_parms *parms)
+{
+ struct cfa_tcam_mgr_entry_data *entry;
+ struct cfa_tcam_mgr_table_rows_0 *row;
+ struct cfa_tcam_mgr_table_data *table_data;
+ int rc;
+ int row_size, sess_idx;
+ uint32_t session_id;
+
+ CFA_TCAM_MGR_CHECK_PARMS2(context, parms);
+
+ rc = cfa_tcam_mgr_get_session_from_context(context, &session_id);
+ if (rc < 0)
+ return rc;
+
+ sess_idx = cfa_tcam_mgr_session_find(session_id);
+ if (sess_idx < 0) {
+ CFA_TCAM_MGR_LOG(ERR, "Session 0x%08x not found.\n",
+ session_id);
+ return sess_idx;
+ }
+
+ if (global_data_initialized[sess_idx] == 0) {
+ CFA_TCAM_MGR_LOG(ERR, "PANIC: No TCAM data created for sess_idx %d\n",
+ sess_idx);
+ return -CFA_TCAM_MGR_ERR_CODE(PERM);
+ }
+
+ entry = cfa_tcam_mgr_entry_get(sess_idx, parms->id);
+ if (entry == NULL) {
+ CFA_TCAM_MGR_LOG(ERR, "Entry %d not found.\n", parms->id);
+ return -CFA_TCAM_MGR_ERR_CODE(INVAL);
+ }
+
+ table_data = &cfa_tcam_mgr_tables[sess_idx][parms->dir][parms->type];
+ parms->hcapi_type = table_data->hcapi_type;
+
+ row_size = cfa_tcam_mgr_row_size_get(sess_idx, parms->dir, parms->type);
+ row = cfa_tcam_mgr_row_ptr_get(table_data->tcam_rows, entry->row,
+ row_size);
+
+ rc = cfa_tcam_mgr_entry_get_msg(sess_idx, context, parms,
+ entry->row,
+ entry->slice * row->entry_size,
+ table_data->max_slices);
+ if (rc < 0) {
+ CFA_TCAM_MGR_LOG_0(ERR, "Failed to read from TCAM.\n");
+ return rc;
+ }
+
+ return 0;
+}
+
+int cfa_tcam_mgr_shared_clear(struct cfa_tcam_mgr_context *context,
+ struct cfa_tcam_mgr_shared_clear_parms *parms)
+{
+ int rc;
+ uint16_t row, slice = 0;
+ int sess_idx;
+ uint32_t session_id;
+ struct cfa_tcam_mgr_free_parms fparms;
+ struct cfa_tcam_mgr_table_data *table_data;
+ uint16_t start_row, end_row, max_entries, max_slices;
+
+ CFA_TCAM_MGR_CHECK_PARMS2(context, parms);
+
+ rc = cfa_tcam_mgr_get_session_from_context(context, &session_id);
+ if (rc < 0)
+ return rc;
+
+ sess_idx = cfa_tcam_mgr_session_find(session_id);
+ if (sess_idx < 0) {
+ CFA_TCAM_MGR_LOG(ERR, "Session 0x%08x not found.\n",
+ session_id);
+ return sess_idx;
+ }
+
+ if (global_data_initialized[sess_idx] == 0) {
+ CFA_TCAM_MGR_LOG(ERR, "PANIC: No TCAM data created for sess_idx %d\n",
+ sess_idx);
+ return -CFA_TCAM_MGR_ERR_CODE(PERM);
+ }
+
+ table_data = &cfa_tcam_mgr_tables[sess_idx][parms->dir][parms->type];
+ fparms.dir = parms->dir;
+ fparms.type = parms->type;
+ fparms.hcapi_type = table_data->hcapi_type;
+ fparms.id = 0;
+
+ rc = cfa_tcam_mgr_tables_get(sess_idx, parms->dir, parms->type,
+ &start_row, &end_row, &max_entries, &max_slices);
+ if (rc)
+ return rc;
+
+ for (row = start_row; row <= end_row; row++) {
+ cfa_tcam_mgr_entry_free_msg(sess_idx, context, &fparms,
+ row,
+ slice,
+ table_data->row_width,
+ table_data->result_size,
+ table_data->max_slices);
+ }
+ return rc;
+}
+
+static void
+cfa_tcam_mgr_mv_used_entries_cnt(int sess_idx, enum tf_dir dir,
+ struct cfa_tcam_mgr_table_data *dst_table_data,
+ struct cfa_tcam_mgr_table_data *src_table_data)
+{
+ dst_table_data->used_entries++;
+ src_table_data->used_entries--;
+
+ cfa_tcam_mgr_mv_session_used_entries_cnt(sess_idx, dir,
+ CFA_TCAM_MGR_TBL_TYPE_WC_TCAM_LOW_APPS,
+ CFA_TCAM_MGR_TBL_TYPE_WC_TCAM_HIGH_APPS);
+}
+
+/*
+ * Move HI WC TCAM entries to LOW TCAM region for HA
+ * This happens when secondary is becoming primary
+ */
+static int
+cfa_tcam_mgr_shared_entry_move(int sess_idx, struct cfa_tcam_mgr_context *context,
+ enum tf_dir dir, enum cfa_tcam_mgr_tbl_type type,
+ int entry_id,
+ struct cfa_tcam_mgr_table_data *dst_table_data,
+ struct cfa_tcam_mgr_table_data *table_data,
+ int dst_row_index, int dst_row_slice,
+ struct cfa_tcam_mgr_table_rows_0 *dst_row,
+ int src_row_index,
+ struct cfa_tcam_mgr_table_rows_0 *src_row)
+{
+ struct cfa_tcam_mgr_get_parms gparms = { 0 };
+ struct cfa_tcam_mgr_set_parms sparms = { 0 };
+ struct cfa_tcam_mgr_free_parms fparms = { 0 };
+ struct cfa_tcam_mgr_entry_data *entry;
+ uint8_t key[CFA_TCAM_MGR_MAX_KEY_SIZE];
+ uint8_t mask[CFA_TCAM_MGR_MAX_KEY_SIZE];
+ uint8_t result[CFA_TCAM_MGR_MAX_KEY_SIZE];
+
+ int rc;
+
+ entry = cfa_tcam_mgr_entry_get(sess_idx, entry_id);
+ if (entry == NULL)
+ return -1;
+
+ gparms.dir = dir;
+ gparms.type = type;
+ gparms.hcapi_type = table_data->hcapi_type;
+ gparms.key = key;
+ gparms.mask = mask;
+ gparms.result = result;
+ gparms.id = src_row->entries[entry->slice];
+ gparms.key_size = sizeof(key);
+ gparms.result_size = sizeof(result);
+
+ rc = cfa_tcam_mgr_entry_get_msg(sess_idx, context, &gparms,
+ src_row_index,
+ entry->slice * src_row->entry_size,
+ table_data->max_slices);
+ if (rc != 0)
+ return rc;
+
+ sparms.dir = dir;
+ sparms.type = CFA_TCAM_MGR_TBL_TYPE_WC_TCAM_LOW_APPS;
+ sparms.hcapi_type = table_data->hcapi_type;
+ sparms.key = key;
+ sparms.mask = mask;
+ sparms.result = result;
+ sparms.id = gparms.id;
+ sparms.key_size = gparms.key_size;
+ sparms.result_size = gparms.result_size;
+
+ rc = cfa_tcam_mgr_entry_set_msg(sess_idx, context, &sparms,
+ dst_row_index,
+ dst_row_slice * dst_row->entry_size,
+ table_data->max_slices);
+ if (rc != 0)
+ return rc;
+
+ fparms.dir = dir;
+ fparms.type = type;
+ fparms.hcapi_type = table_data->hcapi_type;
+ rc = cfa_tcam_mgr_entry_free_msg(sess_idx, context, &fparms,
+ src_row_index,
+ entry->slice *
+ dst_row->entry_size,
+ table_data->row_width /
+ table_data->max_slices *
+ src_row->entry_size,
+ table_data->result_size,
+ table_data->max_slices);
+ if (rc != 0) {
+ CFA_TCAM_MGR_LOG_DIR_TYPE(ERR,
+ dir, type,
+ "Failed to free entry ID %d at"
+ " row %d, slice %d for sess_idx %d. rc: %d.\n",
+ gparms.id,
+ src_row_index,
+ entry->slice,
+ sess_idx,
+ -rc);
+ }
+
+#ifdef CFA_TCAM_MGR_TRACING
+ CFA_TCAM_MGR_TRACE(INFO, "Moved entry %d from row %d, slice %d to "
+ "row %d, slice %d.\n",
+ entry_id, src_row_index, entry->slice,
+ dst_row_index, dst_row_slice);
+#endif
+
+ ROW_ENTRY_SET(dst_row, dst_row_slice);
+ dst_row->entries[dst_row_slice] = entry_id;
+ dst_row->entry_size = src_row->entry_size;
+ dst_row->priority = src_row->priority;
+ ROW_ENTRY_CLEAR(src_row, entry->slice);
+ entry->row = dst_row_index;
+ entry->slice = dst_row_slice;
+
+ cfa_tcam_mgr_mv_used_entries_cnt(sess_idx, dir, dst_table_data, table_data);
+
+#ifdef CFA_TCAM_MGR_TRACING
+ cfa_tcam_mgr_rows_dump(sess_idx, dir, type);
+ cfa_tcam_mgr_rows_dump(sess_idx, dir, CFA_TCAM_MGR_TBL_TYPE_WC_TCAM_LOW_APPS);
+#endif
+
+ return 0;
+}
+
+int cfa_tcam_mgr_shared_move(struct cfa_tcam_mgr_context *context,
+ struct cfa_tcam_mgr_shared_move_parms *parms)
+{
+ int rc;
+ int sess_idx;
+ uint32_t session_id;
+ uint16_t src_row, dst_row, row_size, slice;
+ struct cfa_tcam_mgr_table_rows_0 *src_table_row;
+ struct cfa_tcam_mgr_table_rows_0 *dst_table_row;
+ struct cfa_tcam_mgr_table_data *src_table_data;
+ struct cfa_tcam_mgr_table_data *dst_table_data;
+
+ CFA_TCAM_MGR_CHECK_PARMS2(context, parms);
+
+ rc = cfa_tcam_mgr_get_session_from_context(context, &session_id);
+ if (rc < 0)
+ return rc;
+
+ sess_idx = cfa_tcam_mgr_session_find(session_id);
+ if (sess_idx < 0) {
+ CFA_TCAM_MGR_LOG(ERR, "Session 0x%08x not found.\n",
+ session_id);
+ return sess_idx;
+ }
+
+ if (global_data_initialized[sess_idx] == 0) {
+ CFA_TCAM_MGR_LOG(ERR, "PANIC: No TCAM data created for sess_idx %d\n",
+ sess_idx);
+ return -CFA_TCAM_MGR_ERR_CODE(PERM);
+ }
+
+ src_table_data =
+ &cfa_tcam_mgr_tables[sess_idx][parms->dir][CFA_TCAM_MGR_TBL_TYPE_WC_TCAM_HIGH_APPS];
+ dst_table_data =
+ &cfa_tcam_mgr_tables[sess_idx][parms->dir][CFA_TCAM_MGR_TBL_TYPE_WC_TCAM_LOW_APPS];
+
+ row_size =
+ cfa_tcam_mgr_row_size_get(sess_idx,
+ parms->dir,
+ CFA_TCAM_MGR_TBL_TYPE_WC_TCAM_HIGH_APPS);
+
+ for (src_row = src_table_data->start_row,
+ dst_row = dst_table_data->start_row;
+ src_row <= src_table_data->end_row;
+ src_row++, dst_row++) {
+ src_table_row = cfa_tcam_mgr_row_ptr_get(src_table_data->tcam_rows,
+ src_row, row_size);
+ dst_table_row = cfa_tcam_mgr_row_ptr_get(dst_table_data->tcam_rows,
+ dst_row, row_size);
+ if (ROW_INUSE(src_table_row)) {
+ for (slice = 0;
+ slice < src_table_data->max_slices / src_table_row->entry_size;
+ slice++) {
+ if (ROW_ENTRY_INUSE(src_table_row, slice)) {
+#ifdef CFA_TCAM_MGR_TRACING
+ CFA_TCAM_MGR_TRACE(INFO, "Move entry id %d "
+ "from src_row %d, slice %d "
+ "to dst_row %d, slice %d.\n",
+ src_table_row->entries[slice],
+ src_row, slice,
+ dst_row, slice);
+#endif
+ rc = cfa_tcam_mgr_shared_entry_move(sess_idx,
+ context,
+ parms->dir,
+ CFA_TCAM_MGR_TBL_TYPE_WC_TCAM_HIGH_APPS,
+ src_table_row->entries[slice],
+ dst_table_data,
+ src_table_data,
+ dst_row, slice,
+ dst_table_row,
+ src_row,
+ src_table_row);
+ }
+ }
+ }
+ }
+
+ return rc;
+}
+
+static void
+cfa_tcam_mgr_tbl_get(int sess_idx, enum tf_dir dir,
+ enum cfa_tcam_mgr_tbl_type type,
+ uint16_t *start_row,
+ uint16_t *end_row,
+ uint16_t *max_entries,
+ uint16_t *slices)
+{
+ struct cfa_tcam_mgr_table_data *table_data =
+ &cfa_tcam_mgr_tables[sess_idx][dir][type];
+
+ /* Get start, end and max for tcam type*/
+ *start_row = table_data->start_row;
+ *end_row = table_data->end_row;
+ *max_entries = table_data->max_entries;
+ *slices = table_data->max_slices;
+}
+
+int
+cfa_tcam_mgr_tables_get(int sess_idx, enum tf_dir dir,
+ enum cfa_tcam_mgr_tbl_type type,
+ uint16_t *start_row,
+ uint16_t *end_row,
+ uint16_t *max_entries,
+ uint16_t *slices)
+{
+ CFA_TCAM_MGR_CHECK_PARMS3(start_row, end_row, max_entries);
+
+ if (global_data_initialized[sess_idx] == 0) {
+ CFA_TCAM_MGR_LOG(ERR, "PANIC: TCAM not initialized for sess_idx %d.\n",
+ sess_idx);
+ return -CFA_TCAM_MGR_ERR_CODE(INVAL);
+ }
+
+ if (dir >= TF_DIR_MAX) {
+ CFA_TCAM_MGR_LOG(ERR, "Must specify valid dir (0-%d) forsess_idx %d.\n",
+ TF_DIR_MAX - 1, sess_idx);
+ return -CFA_TCAM_MGR_ERR_CODE(INVAL);
+ }
+
+ if (type >= CFA_TCAM_MGR_TBL_TYPE_MAX) {
+ CFA_TCAM_MGR_LOG(ERR, "Must specify valid tbl type (0-%d) forsess_idx %d.\n",
+ CFA_TCAM_MGR_TBL_TYPE_MAX - 1, sess_idx);
+ return -CFA_TCAM_MGR_ERR_CODE(INVAL);
+ }
+
+ cfa_tcam_mgr_tbl_get(sess_idx, dir,
+ type,
+ start_row,
+ end_row,
+ max_entries,
+ slices);
+ return 0;
+}
+
+static void
+cfa_tcam_mgr_tbl_set(int sess_idx, enum tf_dir dir,
+ enum cfa_tcam_mgr_tbl_type type,
+ uint16_t start_row,
+ uint16_t end_row,
+ uint16_t max_entries)
+{
+ struct cfa_tcam_mgr_table_data *table_data =
+ &cfa_tcam_mgr_tables[sess_idx][dir][type];
+
+ /* Update start, end and max for tcam type*/
+ table_data->start_row = start_row;
+ table_data->end_row = end_row;
+ table_data->max_entries = max_entries;
+}
+
+int
+cfa_tcam_mgr_tables_set(int sess_idx, enum tf_dir dir,
+ enum cfa_tcam_mgr_tbl_type type,
+ uint16_t start_row,
+ uint16_t end_row,
+ uint16_t max_entries)
+{
+ if (global_data_initialized[sess_idx] == 0) {
+ CFA_TCAM_MGR_LOG(ERR, "PANIC: TCAM not initialized for sess_idx %d.\n",
+ sess_idx);
+ return -CFA_TCAM_MGR_ERR_CODE(INVAL);
+ }
+
+ if (dir >= TF_DIR_MAX) {
+ CFA_TCAM_MGR_LOG(ERR, "Must specify valid dir (0-%d) forsess_idx %d.\n",
+ TF_DIR_MAX - 1, sess_idx);
+ return -CFA_TCAM_MGR_ERR_CODE(INVAL);
+ }
+
+ if (type >= CFA_TCAM_MGR_TBL_TYPE_MAX) {
+ CFA_TCAM_MGR_LOG(ERR, "Must specify valid tbl type (0-%d) forsess_idx %d.\n",
+ CFA_TCAM_MGR_TBL_TYPE_MAX - 1, sess_idx);
+ return -CFA_TCAM_MGR_ERR_CODE(INVAL);
+ }
+
+ cfa_tcam_mgr_tbl_set(sess_idx, dir,
+ type,
+ start_row,
+ end_row,
+ max_entries);
+ return 0;
+}
+
+void
+cfa_tcam_mgr_rows_dump(int sess_idx, enum tf_dir dir,
+ enum cfa_tcam_mgr_tbl_type type)
+{
+ struct cfa_tcam_mgr_table_data *table_data;
+ struct cfa_tcam_mgr_table_rows_0 *table_row;
+ int i, row, row_size;
+ bool row_found = false;
+ bool empty_row = false;
+
+ if (global_data_initialized[sess_idx] == 0) {
+ printf("PANIC: TCAM not initialized for sess_idx %d.\n", sess_idx);
+ return;
+ }
+
+ if (dir >= TF_DIR_MAX) {
+ printf("Must specify a valid direction (0-%d).\n",
+ TF_DIR_MAX - 1);
+ return;
+ }
+ if (type >= CFA_TCAM_MGR_TBL_TYPE_MAX) {
+ printf("Must specify a valid type (0-%d).\n",
+ CFA_TCAM_MGR_TBL_TYPE_MAX - 1);
+ return;
+ }
+
+ table_data = &cfa_tcam_mgr_tables[sess_idx][dir][type];
+ row_size = cfa_tcam_mgr_row_size_get(sess_idx, dir, type);
+
+ printf("\nTCAM Rows:\n");
+ printf("Rows for direction %s, Logical table type %s\n",
+ tf_dir_2_str(dir), cfa_tcam_mgr_tbl_2_str(type));
+ printf("Managed rows %d-%d for sess_idx %d:\n",
+ table_data->start_row, table_data->end_row, sess_idx);
+
+ printf("Index Pri Size Entry IDs\n");
+ printf(" Sl 0");
+ for (i = 1; i < table_data->max_slices; i++)
+ printf(" Sl %d", i);
+ printf("\n");
+ for (row = table_data->start_row; row <= table_data->end_row; row++) {
+ table_row = cfa_tcam_mgr_row_ptr_get(table_data->tcam_rows, row,
+ row_size);
+ if (ROW_INUSE(table_row)) {
+ empty_row = false;
+ printf("%5u %5u %4u",
+ row,
+ TF_TCAM_PRIORITY_MAX - table_row->priority - 1,
+ table_row->entry_size);
+ for (i = 0;
+ i < table_data->max_slices / table_row->entry_size;
+ i++) {
+ if (ROW_ENTRY_INUSE(table_row, i))
+ printf(" %5u", table_row->entries[i]);
+ else
+ printf(" x");
+ }
+ printf("\n");
+ row_found = true;
+ } else if (!empty_row) {
+ empty_row = true;
+ printf("\n");
+ }
+ }
+
+ if (!row_found)
+ printf("No rows in use.\n");
+}
+
+static void
+cfa_tcam_mgr_table_dump(int sess_idx, enum tf_dir dir,
+ enum cfa_tcam_mgr_tbl_type type)
+{
+ struct cfa_tcam_mgr_table_data *table_data =
+ &cfa_tcam_mgr_tables[sess_idx][dir][type];
+
+ printf("%3s %-22s %5u %5u %5u %5u %6u %7u %2u\n",
+ tf_dir_2_str(dir),
+ cfa_tcam_mgr_tbl_2_str(type),
+ table_data->row_width,
+ table_data->num_rows,
+ table_data->start_row,
+ table_data->end_row,
+ table_data->max_entries,
+ table_data->used_entries,
+ table_data->max_slices);
+}
+
+#define TABLE_DUMP_HEADER \
+ "Dir Table Width Rows Start End " \
+ "MaxEnt UsedEnt Slices\n"
+
+void
+cfa_tcam_mgr_tables_dump(int sess_idx, enum tf_dir dir,
+ enum cfa_tcam_mgr_tbl_type type)
+{
+ if (global_data_initialized[sess_idx] == 0) {
+ printf("PANIC: TCAM not initialized for sess_idx %d.\n", sess_idx);
+ return;
+ }
+
+ printf("\nTCAM Table(s) for sess_idx %d:\n", sess_idx);
+ printf(TABLE_DUMP_HEADER);
+ if (dir >= TF_DIR_MAX) {
+ /* Iterate over all directions */
+ for (dir = 0; dir < TF_DIR_MAX; dir++) {
+ if (type >= CFA_TCAM_MGR_TBL_TYPE_MAX) {
+ /* Iterate over all types */
+ for (type = 0;
+ type < CFA_TCAM_MGR_TBL_TYPE_MAX;
+ type++) {
+ cfa_tcam_mgr_table_dump(sess_idx, dir, type);
+ }
+ } else {
+ /* Display a specific type */
+ cfa_tcam_mgr_table_dump(sess_idx, dir, type);
+ }
+ }
+ } else if (type >= CFA_TCAM_MGR_TBL_TYPE_MAX) {
+ /* Iterate over all types for a direction */
+ for (type = 0; type < CFA_TCAM_MGR_TBL_TYPE_MAX; type++)
+ cfa_tcam_mgr_table_dump(sess_idx, dir, type);
+ } else {
+ /* Display a specific direction and type */
+ cfa_tcam_mgr_table_dump(sess_idx, dir, type);
+ }
+}
+
+#define ENTRY_DUMP_HEADER "Entry RefCnt Row Slice\n"
+
+void
+cfa_tcam_mgr_entries_dump(int sess_idx)
+{
+ struct cfa_tcam_mgr_entry_data *entry;
+ bool entry_found = false;
+ uint16_t id;
+
+ if (global_data_initialized[sess_idx] == 0) {
+ CFA_TCAM_MGR_LOG(INFO, "PANIC: No TCAM data created for sess_idx %d\n",
+ sess_idx);
+ return;
+ }
+
+ printf("\nGlobal Maximum Entries: %d\n\n",
+ cfa_tcam_mgr_max_entries[sess_idx]);
+ printf("TCAM Entry Table:\n");
+ for (id = 0; id < cfa_tcam_mgr_max_entries[sess_idx]; id++) {
+ if (entry_data[sess_idx][id].ref_cnt > 0) {
+ entry = &entry_data[sess_idx][id];
+ if (!entry_found)
+ printf(ENTRY_DUMP_HEADER);
+ printf("%5u %5u %5u %5u",
+ id, entry->ref_cnt,
+ entry->row, entry->slice);
+ printf("\n");
+ entry_found = true;
+ }
+ }
+
+ if (!entry_found)
+ printf("No entries found.\n");
+}
diff --git a/drivers/net/bnxt/tf_core/cfa_tcam_mgr.h b/drivers/net/bnxt/tf_core/cfa_tcam_mgr.h
new file mode 100644
index 0000000000..40bfe8e225
--- /dev/null
+++ b/drivers/net/bnxt/tf_core/cfa_tcam_mgr.h
@@ -0,0 +1,523 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2021-2023 Broadcom
+ * All rights reserved.
+ */
+
+#ifndef _CFA_TCAM_MGR_H_
+#define _CFA_TCAM_MGR_H_
+
+#include <errno.h>
+#include "rte_common.h"
+#include "hsi_struct_def_dpdk.h"
+#include "tf_core.h"
+
+#ifndef __rte_unused
+#define __rte_unused __attribute__((unused))
+#endif
+
+/**
+ * The TCAM module provides processing of Internal TCAM types.
+ */
+
+#ifndef TF_TCAM_MAX_SESSIONS
+#define TF_TCAM_MAX_SESSIONS 16
+#endif
+
+#define ENTRY_ID_INVALID UINT16_MAX
+
+#define TF_TCAM_PRIORITY_MIN 0
+#define TF_TCAM_PRIORITY_MAX UINT16_MAX
+
+#ifndef ARRAY_SIZE
+#define ARRAY_SIZE(_array) (sizeof(_array) / sizeof(_array[0]))
+#endif
+
+/* Use TFP_DRV_LOG definition in tfp.h */
+#define CFA_TCAM_MGR_LOG(level, fmt, args...) \
+ TFP_DRV_LOG(level, fmt, ## args)
+#define CFA_TCAM_MGR_LOG_DIR(level, dir, fmt, args...) \
+ TFP_DRV_LOG(level, "%s: " fmt, tf_dir_2_str(dir), ## args)
+#define CFA_TCAM_MGR_LOG_DIR_TYPE(level, dir, type, fmt, args...) \
+ TFP_DRV_LOG(level, "%s: %s " fmt, tf_dir_2_str(dir), \
+ cfa_tcam_mgr_tbl_2_str(type), ## args)
+
+#define CFA_TCAM_MGR_LOG_0(level, fmt) \
+ TFP_DRV_LOG(level, fmt)
+#define CFA_TCAM_MGR_LOG_DIR_0(level, dir, fmt) \
+ TFP_DRV_LOG(level, "%s: " fmt, tf_dir_2_str(dir))
+#define CFA_TCAM_MGR_LOG_DIR_TYPE_0(level, dir, type, fmt) \
+ TFP_DRV_LOG(level, "%s: %s " fmt, tf_dir_2_str(dir), \
+ cfa_tcam_mgr_tbl_2_str(type))
+
+#define CFA_TCAM_MGR_ERR_CODE(type) E ## type
+
+/**
+ * Checks 1 parameter against NULL.
+ */
+#define CFA_TCAM_MGR_CHECK_PARMS1(parms) do { \
+ if ((parms) == NULL) { \
+ CFA_TCAM_MGR_LOG_0(ERR, "Invalid Argument(s)\n"); \
+ return -CFA_TCAM_MGR_ERR_CODE(INVAL); \
+ } \
+ } while (0)
+
+/**
+ * Checks 2 parameters against NULL.
+ */
+#define CFA_TCAM_MGR_CHECK_PARMS2(parms1, parms2) do { \
+ if ((parms1) == NULL || (parms2) == NULL) { \
+ CFA_TCAM_MGR_LOG_0(ERR, "Invalid Argument(s)\n"); \
+ return -CFA_TCAM_MGR_ERR_CODE(INVAL); \
+ } \
+ } while (0)
+
+/**
+ * Checks 3 parameters against NULL.
+ */
+#define CFA_TCAM_MGR_CHECK_PARMS3(parms1, parms2, parms3) do { \
+ if ((parms1) == NULL || \
+ (parms2) == NULL || \
+ (parms3) == NULL) { \
+ CFA_TCAM_MGR_LOG_0(ERR, "Invalid Argument(s)\n"); \
+ return -CFA_TCAM_MGR_ERR_CODE(INVAL); \
+ } \
+ } while (0)
+
+enum cfa_tcam_mgr_tbl_type {
+ /* Logical TCAM tables */
+ CFA_TCAM_MGR_TBL_TYPE_START,
+ CFA_TCAM_MGR_TBL_TYPE_L2_CTXT_TCAM_HIGH_AFM =
+ CFA_TCAM_MGR_TBL_TYPE_START,
+ CFA_TCAM_MGR_TBL_TYPE_L2_CTXT_TCAM_HIGH_APPS,
+ CFA_TCAM_MGR_TBL_TYPE_L2_CTXT_TCAM_LOW_AFM,
+ CFA_TCAM_MGR_TBL_TYPE_L2_CTXT_TCAM_LOW_APPS,
+ CFA_TCAM_MGR_TBL_TYPE_PROF_TCAM_AFM,
+ CFA_TCAM_MGR_TBL_TYPE_PROF_TCAM_APPS,
+ CFA_TCAM_MGR_TBL_TYPE_WC_TCAM_AFM,
+ CFA_TCAM_MGR_TBL_TYPE_WC_TCAM_APPS,
+ CFA_TCAM_MGR_TBL_TYPE_SP_TCAM_AFM,
+ CFA_TCAM_MGR_TBL_TYPE_SP_TCAM_APPS,
+ CFA_TCAM_MGR_TBL_TYPE_CT_RULE_TCAM_AFM,
+ CFA_TCAM_MGR_TBL_TYPE_CT_RULE_TCAM_APPS,
+ CFA_TCAM_MGR_TBL_TYPE_VEB_TCAM_AFM,
+ CFA_TCAM_MGR_TBL_TYPE_VEB_TCAM_APPS,
+ CFA_TCAM_MGR_TBL_TYPE_WC_TCAM_HIGH_AFM,
+ CFA_TCAM_MGR_TBL_TYPE_WC_TCAM_HIGH_APPS,
+ CFA_TCAM_MGR_TBL_TYPE_WC_TCAM_LOW_AFM,
+ CFA_TCAM_MGR_TBL_TYPE_WC_TCAM_LOW_APPS,
+ CFA_TCAM_MGR_TBL_TYPE_MAX
+};
+
+enum cfa_tcam_mgr_device_type {
+ CFA_TCAM_MGR_DEVICE_TYPE_P4 = 0,
+ CFA_TCAM_MGR_DEVICE_TYPE_SR,
+ CFA_TCAM_MGR_DEVICE_TYPE_P5,
+ CFA_TCAM_MGR_DEVICE_TYPE_MAX
+};
+
+struct cfa_tcam_mgr_context {
+ struct tf *tfp;
+};
+
+/**
+ * TCAM Manager initialization parameters
+ */
+struct cfa_tcam_mgr_init_parms {
+ /**
+ * [in] TCAM resources reserved
+ * type element is not used.
+ */
+ struct tf_rm_resc_entry resc[TF_DIR_MAX][CFA_TCAM_MGR_TBL_TYPE_MAX];
+ /**
+ * [out] maximum number of entries available.
+ */
+ uint32_t max_entries;
+};
+
+/**
+ * TCAM Manager initialization parameters
+ */
+struct cfa_tcam_mgr_qcaps_parms {
+ /**
+ * [out] Bitmasks. Set if TCAM Manager is managing a logical TCAM.
+ * Each bitmask is indexed by logical TCAM table ID.
+ */
+ uint32_t rx_tcam_supported;
+ uint32_t tx_tcam_supported;
+};
+
+/**
+ * TCAM Manager configuration parameters
+ */
+struct cfa_tcam_mgr_cfg_parms {
+ /**
+ * [in] Number of tcam types in each of the configuration arrays
+ */
+ uint16_t num_elements;
+ /**
+ * [in] Session resource allocations
+ */
+ uint16_t tcam_cnt[TF_DIR_MAX][CFA_TCAM_MGR_TBL_TYPE_MAX];
+
+ /**
+ * [in] TCAM Locations reserved
+ */
+ struct tf_rm_resc_entry (*resv_res)[CFA_TCAM_MGR_TBL_TYPE_MAX];
+};
+
+/**
+ * TCAM Manager allocation parameters
+ */
+struct cfa_tcam_mgr_alloc_parms {
+ /**
+ * [in] Receive or transmit direction
+ */
+ enum tf_dir dir;
+ /**
+ * [in] Type of the allocation
+ */
+ enum cfa_tcam_mgr_tbl_type type;
+ /**
+ * [in] Type of HCAPI
+ */
+ uint16_t hcapi_type;
+ /**
+ * [in] key size (bytes)
+ */
+ uint16_t key_size;
+ /**
+ * [in] Priority of entry requested (definition TBD)
+ */
+ uint16_t priority;
+ /**
+ * [out] Id of allocated entry or found entry (if search_enable)
+ */
+ uint16_t id;
+};
+
+/**
+ * TCAM Manager free parameters
+ */
+struct cfa_tcam_mgr_free_parms {
+ /**
+ * [in] Receive or transmit direction
+ */
+ enum tf_dir dir;
+ /**
+ * [in] Type of the allocation
+ * If the type is not known, set the type to CFA_TCAM_MGR_TBL_TYPE_MAX.
+ */
+ enum cfa_tcam_mgr_tbl_type type;
+ /**
+ * [in] Type of HCAPI
+ */
+ uint16_t hcapi_type;
+ /**
+ * [in] Entry ID to free
+ */
+ uint16_t id;
+};
+
+/**
+ * TCAM Manager set parameters
+ */
+struct cfa_tcam_mgr_set_parms {
+ /**
+ * [in] Receive or transmit direction
+ */
+ enum tf_dir dir;
+ /**
+ * [in] Type of object to set
+ */
+ enum cfa_tcam_mgr_tbl_type type;
+ /**
+ * [in] Type of HCAPI
+ */
+ uint16_t hcapi_type;
+ /**
+ * [in] Entry ID to write to
+ */
+ uint16_t id;
+ /**
+ * [in] array containing key
+ */
+ uint8_t *key;
+ /**
+ * [in] array containing mask fields
+ */
+ uint8_t *mask;
+ /**
+ * [in] key size (bytes)
+ */
+ uint16_t key_size;
+ /**
+ * [in] array containing result
+ */
+ uint8_t *result;
+ /**
+ * [in] result size (bytes)
+ */
+ uint16_t result_size;
+};
+
+/**
+ * TCAM Manager get parameters
+ */
+struct cfa_tcam_mgr_get_parms {
+ /**
+ * [in] Receive or transmit direction
+ */
+ enum tf_dir dir;
+ /**
+ * [in] Type of object to get
+ */
+ enum cfa_tcam_mgr_tbl_type type;
+ /**
+ * [in] Type of HCAPI
+ */
+ uint16_t hcapi_type;
+ /**
+ * [in] Entry ID to read
+ */
+ uint16_t id;
+ /**
+ * [out] array containing key
+ */
+ uint8_t *key;
+ /**
+ * [out] array containing mask fields
+ */
+ uint8_t *mask;
+ /**
+ * [out] key size (bytes)
+ */
+ uint16_t key_size;
+ /**
+ * [out] array containing result
+ */
+ uint8_t *result;
+ /**
+ * [out] result size (bytes)
+ */
+ uint16_t result_size;
+};
+
+/**
+ * cfa_tcam_mgr_shared_clear_parms parameter definition
+ */
+struct cfa_tcam_mgr_shared_clear_parms {
+ /**
+ * [in] receive or transmit direction
+ */
+ enum tf_dir dir;
+ /**
+ * [in] TCAM table type
+ */
+ enum cfa_tcam_mgr_tbl_type type;
+};
+
+/**
+ * cfa_tcam_mgr_shared_move_parms parameter definition
+ */
+struct cfa_tcam_mgr_shared_move_parms {
+ /**
+ * [in] receive or transmit direction
+ */
+ enum tf_dir dir;
+ /**
+ * [in] TCAM table type
+ */
+ enum cfa_tcam_mgr_tbl_type type;
+};
+
+/**
+ * @page tcam TCAM Manager
+ *
+ * @ref cfa_tcam_mgr_init
+ *
+ * @ref cfa_tcam_mgr_get_phys_table_type
+ *
+ * @ref cfa_tcam_mgr_bind
+ *
+ * @ref cfa_tcam_mgr_unbind
+ *
+ * @ref cfa_tcam_mgr_alloc
+ *
+ * @ref cfa_tcam_mgr_free
+ *
+ * @ref cfa_tcam_mgr_set
+ *
+ * @ref cfa_tcam_mgr_get
+ *
+ */
+
+const char *
+cfa_tcam_mgr_tbl_2_str(enum cfa_tcam_mgr_tbl_type tcam_type);
+
+/**
+ * Initializes the TCAM Manager
+ *
+ * [in] type
+ * Device type
+ *
+ * Returns
+ * - (0) if successful.
+ * - (<0) on failure.
+ */
+int
+cfa_tcam_mgr_init(int sess_idx, enum cfa_tcam_mgr_device_type type,
+ struct cfa_tcam_mgr_init_parms *parms);
+
+/**
+ * Returns the physical TCAM table that a logical TCAM table uses.
+ *
+ * [in] type
+ * Logical table type
+ *
+ * Returns
+ * - (tf_tcam_tbl_type) if successful.
+ * - (<0) on failure.
+ */
+int
+cfa_tcam_mgr_get_phys_table_type(enum cfa_tcam_mgr_tbl_type type);
+
+/**
+ * Queries the capabilities of TCAM Manager.
+ *
+ * [in] context
+ * Pointer to context information
+ *
+ * [out] parms
+ * Pointer to parameters to be returned
+ *
+ * Returns
+ * - (0) if successful.
+ * - (<0) on failure.
+ */
+int
+cfa_tcam_mgr_qcaps(struct cfa_tcam_mgr_context *context __rte_unused,
+ struct cfa_tcam_mgr_qcaps_parms *parms);
+
+/**
+ * Initializes the TCAM module with the requested DBs. Must be
+ * invoked as the first thing before any of the access functions.
+ *
+ * [in] context
+ * Pointer to context information
+ *
+ * [in] parms
+ * Pointer to parameters
+ *
+ * Returns
+ * - (0) if successful.
+ * - (-EINVAL) on failure.
+ */
+int cfa_tcam_mgr_bind(struct cfa_tcam_mgr_context *context,
+ struct cfa_tcam_mgr_cfg_parms *parms);
+
+/**
+ * Cleans up the private DBs and releases all the data.
+ *
+ * [in] context
+ * Pointer to context information
+ *
+ * [in] parms
+ * Pointer to parameters
+ *
+ * Returns
+ * - (0) if successful.
+ * - (-EINVAL) on failure.
+ */
+int cfa_tcam_mgr_unbind(struct cfa_tcam_mgr_context *context);
+
+/**
+ * Allocates the requested tcam type from the internal RM DB.
+ *
+ * [in] context
+ * Pointer to context information
+ *
+ * [in] parms
+ * Pointer to parameters
+ *
+ * Returns
+ * - (0) if successful.
+ * - (-EINVAL) on failure.
+ */
+int cfa_tcam_mgr_alloc(struct cfa_tcam_mgr_context *context,
+ struct cfa_tcam_mgr_alloc_parms *parms);
+
+/**
+ * Free's the requested table type and returns it to the DB.
+ * If refcount goes to 0 then it is returned to the table type DB.
+ *
+ * [in] context
+ * Pointer to context information
+ *
+ * [in] parms
+ * Pointer to parameters
+ *
+ * Returns
+ * - (0) if successful.
+ * - (-EINVAL) on failure.
+ */
+int cfa_tcam_mgr_free(struct cfa_tcam_mgr_context *context,
+ struct cfa_tcam_mgr_free_parms *parms);
+
+/**
+ * Configures the requested element by sending a firmware request which
+ * then installs it into the device internal structures.
+ *
+ * [in] context
+ * Pointer to context information
+ *
+ * [in] parms
+ * Pointer to parameters
+ *
+ * Returns
+ * - (0) if successful.
+ * - (-EINVAL) on failure.
+ */
+int cfa_tcam_mgr_set(struct cfa_tcam_mgr_context *context,
+ struct cfa_tcam_mgr_set_parms *parms);
+
+/**
+ * Retrieves the requested element by sending a firmware request to get
+ * the element.
+ *
+ * [in] context
+ * Pointer to context information
+ *
+ * [in] parms
+ * Pointer to parameters
+ *
+ * Returns
+ * - (0) if successful.
+ * - (-EINVAL) on failure.
+ */
+int cfa_tcam_mgr_get(struct cfa_tcam_mgr_context *context,
+ struct cfa_tcam_mgr_get_parms *parms);
+
+int
+cfa_tcam_mgr_tables_get(int sess_idx, enum tf_dir dir,
+ enum cfa_tcam_mgr_tbl_type type,
+ uint16_t *start_row,
+ uint16_t *end_row,
+ uint16_t *max_entries,
+ uint16_t *slices);
+int
+cfa_tcam_mgr_tables_set(int sess_idx, enum tf_dir dir,
+ enum cfa_tcam_mgr_tbl_type type,
+ uint16_t start_row,
+ uint16_t end_row,
+ uint16_t max_entries);
+
+int cfa_tcam_mgr_shared_clear(struct cfa_tcam_mgr_context *context,
+ struct cfa_tcam_mgr_shared_clear_parms *parms);
+
+int cfa_tcam_mgr_shared_move(struct cfa_tcam_mgr_context *context,
+ struct cfa_tcam_mgr_shared_move_parms *parms);
+
+void cfa_tcam_mgr_rows_dump(int sess_idx, enum tf_dir dir, enum cfa_tcam_mgr_tbl_type type);
+void cfa_tcam_mgr_tables_dump(int sess_idx, enum tf_dir dir, enum cfa_tcam_mgr_tbl_type type);
+void cfa_tcam_mgr_entries_dump(int sess_idx);
+#endif /* _CFA_TCAM_MGR_H */
diff --git a/drivers/net/bnxt/tf_core/cfa_tcam_mgr_device.h b/drivers/net/bnxt/tf_core/cfa_tcam_mgr_device.h
new file mode 100644
index 0000000000..6ab9b5e118
--- /dev/null
+++ b/drivers/net/bnxt/tf_core/cfa_tcam_mgr_device.h
@@ -0,0 +1,101 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2021-2023 Broadcom
+ * All rights reserved.
+ */
+
+#ifndef CFA_TCAM_MGR_DEVICE_H
+#define CFA_TCAM_MGR_DEVICE_H
+
+#include <inttypes.h>
+#include "cfa_tcam_mgr.h"
+
+/*
+ * This identifier is to be used for one-off variable sizes. Do not use it for
+ * sizing keys in an array.
+ */
+#define CFA_TCAM_MGR_MAX_KEY_SIZE 96
+
+/* Note that this macro's arguments are not macro expanded due to
+ * concatenation.
+ */
+#define TF_TCAM_TABLE_ROWS_DEF(_slices) \
+ struct cfa_tcam_mgr_table_rows_ ## _slices { \
+ uint16_t priority; \
+ uint8_t entry_size; /* Slices per entry */ \
+ uint8_t entry_inuse; /* bit[entry] set if in use */ \
+ uint16_t entries[_slices]; \
+ }
+
+/*
+ * Have to explicitly declare this struct since some compilers don't accept the
+ * GNU C extension of zero length arrays.
+ */
+struct cfa_tcam_mgr_table_rows_0 {
+ uint16_t priority;
+ uint8_t entry_size; /* Slices per entry */
+ uint8_t entry_inuse; /* bit[entry] set if in use */
+ uint16_t entries[];
+};
+
+TF_TCAM_TABLE_ROWS_DEF(1);
+TF_TCAM_TABLE_ROWS_DEF(2);
+TF_TCAM_TABLE_ROWS_DEF(4);
+TF_TCAM_TABLE_ROWS_DEF(8);
+
+#define TF_TCAM_MAX_ENTRIES (L2_CTXT_TCAM_RX_MAX_ENTRIES + \
+ L2_CTXT_TCAM_TX_MAX_ENTRIES + \
+ PROF_TCAM_RX_MAX_ENTRIES + \
+ PROF_TCAM_TX_MAX_ENTRIES + \
+ WC_TCAM_RX_MAX_ENTRIES + \
+ WC_TCAM_TX_MAX_ENTRIES + \
+ SP_TCAM_RX_MAX_ENTRIES + \
+ SP_TCAM_TX_MAX_ENTRIES + \
+ CT_RULE_TCAM_RX_MAX_ENTRIES + \
+ CT_RULE_TCAM_TX_MAX_ENTRIES + \
+ VEB_TCAM_RX_MAX_ENTRIES + \
+ VEB_TCAM_TX_MAX_ENTRIES)
+
+struct cfa_tcam_mgr_entry_data {
+ uint16_t row;
+ uint8_t slice;
+ uint8_t ref_cnt;
+};
+
+struct cfa_tcam_mgr_table_data {
+ struct cfa_tcam_mgr_table_rows_0 *tcam_rows;
+ uint16_t hcapi_type;
+ uint16_t num_rows; /* Rows in physical TCAM */
+ uint16_t start_row; /* Where the logical TCAM starts */
+ uint16_t end_row; /* Where the logical TCAM ends */
+ uint16_t max_entries;
+ uint16_t used_entries;
+ uint8_t row_width; /* bytes */
+ uint8_t result_size; /* bytes */
+ uint8_t max_slices;
+};
+
+extern int cfa_tcam_mgr_max_entries[TF_TCAM_MAX_SESSIONS];
+
+extern struct cfa_tcam_mgr_table_data
+cfa_tcam_mgr_tables[TF_TCAM_MAX_SESSIONS][TF_DIR_MAX][CFA_TCAM_MGR_TBL_TYPE_MAX];
+
+/* HW OP definitions begin here */
+typedef int (*cfa_tcam_mgr_hwop_set_func_t)(int sess_idx,
+ struct cfa_tcam_mgr_set_parms
+ *parms, int row, int slice,
+ int max_slices);
+typedef int (*cfa_tcam_mgr_hwop_get_func_t)(int sess_idx,
+ struct cfa_tcam_mgr_get_parms
+ *parms, int row, int slice,
+ int max_slices);
+typedef int (*cfa_tcam_mgr_hwop_free_func_t)(int sess_idx,
+ struct cfa_tcam_mgr_free_parms
+ *parms, int row, int slice,
+ int max_slices);
+
+struct cfa_tcam_mgr_hwops_funcs {
+ cfa_tcam_mgr_hwop_set_func_t set;
+ cfa_tcam_mgr_hwop_get_func_t get;
+ cfa_tcam_mgr_hwop_free_func_t free;
+};
+#endif /* CFA_TCAM_MGR_DEVICE_H */
diff --git a/drivers/net/bnxt/tf_core/cfa_tcam_mgr_hwop_msg.c b/drivers/net/bnxt/tf_core/cfa_tcam_mgr_hwop_msg.c
new file mode 100644
index 0000000000..0fb5563cc3
--- /dev/null
+++ b/drivers/net/bnxt/tf_core/cfa_tcam_mgr_hwop_msg.c
@@ -0,0 +1,201 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2021-2023 Broadcom
+ * All rights reserved.
+ */
+
+/*
+ * This file will "do the right thing" for each of the primitives set, get and
+ * free. The TCAM manager is running in the core, so the tables will be cached.
+ * Set and free messages will also be sent to the firmware. Instead of sending
+ * get messages, the entry will be read from the cached copy thus saving a
+ * firmware message.
+ */
+
+#include "tf_tcam.h"
+#include "hcapi_cfa_defs.h"
+#include "cfa_tcam_mgr.h"
+#include "cfa_tcam_mgr_hwop_msg.h"
+#include "cfa_tcam_mgr_device.h"
+#include "cfa_tcam_mgr_p58.h"
+#include "cfa_tcam_mgr_p4.h"
+#include "tf_session.h"
+#include "tf_msg.h"
+#include "tfp.h"
+#include "tf_util.h"
+
+/*
+ * The free hwop will free more than a single slice so cannot be used.
+ */
+struct cfa_tcam_mgr_hwops_funcs hwop_funcs;
+
+int
+cfa_tcam_mgr_hwops_init(enum cfa_tcam_mgr_device_type type)
+{
+ switch (type) {
+ case CFA_TCAM_MGR_DEVICE_TYPE_P4:
+ case CFA_TCAM_MGR_DEVICE_TYPE_SR:
+ return cfa_tcam_mgr_hwops_get_funcs_p4(&hwop_funcs);
+ case CFA_TCAM_MGR_DEVICE_TYPE_P5:
+ return cfa_tcam_mgr_hwops_get_funcs_p58(&hwop_funcs);
+ default:
+ CFA_TCAM_MGR_LOG(ERR, "No such device\n");
+ return -CFA_TCAM_MGR_ERR_CODE(NODEV);
+ }
+}
+
+/*
+ * This is the glue between the TCAM manager and the firmware HW operations. It
+ * is intended to abstract out the location of the TCAM manager so that the TCAM
+ * manager code will be the same whether or not it is actually using the
+ * firmware.
+ */
+
+int
+cfa_tcam_mgr_entry_set_msg(int sess_idx, struct cfa_tcam_mgr_context *context
+ __rte_unused,
+ struct cfa_tcam_mgr_set_parms *parms,
+ int row, int slice,
+ int max_slices __rte_unused)
+{
+ cfa_tcam_mgr_hwop_set_func_t set_func;
+
+ set_func = hwop_funcs.set;
+ if (set_func == NULL)
+ return -CFA_TCAM_MGR_ERR_CODE(PERM);
+
+ struct tf_tcam_set_parms sparms;
+ struct tf_session *tfs;
+ struct tf_dev_info *dev;
+ int rc;
+ enum tf_tcam_tbl_type type =
+ cfa_tcam_mgr_get_phys_table_type(parms->type);
+
+ /* Retrieve the session information */
+ rc = tf_session_get_session_internal(context->tfp, &tfs);
+ if (rc)
+ return rc;
+
+ /* Retrieve the device information */
+ rc = tf_session_get_device(tfs, &dev);
+ if (rc)
+ return rc;
+
+ memset(&sparms, 0, sizeof(sparms));
+ sparms.dir = parms->dir;
+ sparms.type = type;
+ sparms.hcapi_type = parms->hcapi_type;
+ sparms.idx = (row * max_slices) + slice;
+ sparms.key = parms->key;
+ sparms.mask = parms->mask;
+ sparms.key_size = parms->key_size;
+ sparms.result = parms->result;
+ sparms.result_size = parms->result_size;
+
+ rc = tf_msg_tcam_entry_set(context->tfp, dev, &sparms);
+ if (rc) {
+ /* Log error */
+ CFA_TCAM_MGR_LOG_DIR_TYPE(ERR, parms->dir, parms->type,
+ "Entry %d set failed, rc:%d\n",
+ parms->id, -rc);
+ return rc;
+ }
+
+ return set_func(sess_idx, parms, row, slice, max_slices);
+}
+
+int
+cfa_tcam_mgr_entry_get_msg(int sess_idx, struct cfa_tcam_mgr_context *context
+ __rte_unused,
+ struct cfa_tcam_mgr_get_parms *parms,
+ int row, int slice,
+ int max_slices __rte_unused)
+{
+ cfa_tcam_mgr_hwop_get_func_t get_func;
+
+ get_func = hwop_funcs.get;
+ if (get_func == NULL)
+ return -CFA_TCAM_MGR_ERR_CODE(PERM);
+
+ return get_func(sess_idx, parms, row, slice, max_slices);
+}
+
+int
+cfa_tcam_mgr_entry_free_msg(int sess_idx, struct cfa_tcam_mgr_context *context
+ __rte_unused,
+ struct cfa_tcam_mgr_free_parms *parms,
+ int row, int slice,
+ int key_size,
+ int result_size,
+ int max_slices)
+{
+ cfa_tcam_mgr_hwop_free_func_t free_func;
+
+ free_func = hwop_funcs.free;
+ if (free_func == NULL)
+ return -CFA_TCAM_MGR_ERR_CODE(PERM);
+
+ struct tf_dev_info *dev;
+ struct tf_session *tfs;
+ int rc;
+ enum tf_tcam_tbl_type type =
+ cfa_tcam_mgr_get_phys_table_type(parms->type);
+
+ /* Free will clear an entire row. */
+ /* Use set message to clear an individual entry */
+ struct tf_tcam_set_parms sparms;
+ uint8_t key[CFA_TCAM_MGR_MAX_KEY_SIZE] = { 0 };
+ uint8_t mask[CFA_TCAM_MGR_MAX_KEY_SIZE] = { 0 };
+
+ /* Retrieve the session information */
+ rc = tf_session_get_session_internal(context->tfp, &tfs);
+ if (rc)
+ return rc;
+
+ /* Retrieve the device information */
+ rc = tf_session_get_device(tfs, &dev);
+ if (rc)
+ return rc;
+
+ if (key_size > CFA_TCAM_MGR_MAX_KEY_SIZE) {
+ CFA_TCAM_MGR_LOG_DIR_TYPE(ERR, parms->dir, parms->type,
+ "Entry %d key size is %d greater than:%d\n",
+ parms->id, key_size,
+ CFA_TCAM_MGR_MAX_KEY_SIZE);
+ return -EINVAL;
+ }
+
+ if (result_size > CFA_TCAM_MGR_MAX_KEY_SIZE) {
+ CFA_TCAM_MGR_LOG_DIR_TYPE(ERR, parms->dir, parms->type,
+ "Entry %d result size is %d greater than:%d\n",
+ parms->id, result_size,
+ CFA_TCAM_MGR_MAX_KEY_SIZE);
+ return -EINVAL;
+ }
+
+ memset(&sparms, 0, sizeof(sparms));
+ memset(&key, 0, sizeof(key));
+ memset(&mask, 0xff, sizeof(mask));
+
+ sparms.dir = parms->dir;
+ sparms.type = type;
+ sparms.hcapi_type = parms->hcapi_type;
+ sparms.key = key;
+ sparms.mask = mask;
+ sparms.result = key;
+ sparms.idx = (row * max_slices) + slice;
+ sparms.key_size = key_size;
+ sparms.result_size = result_size;
+
+ rc = tf_msg_tcam_entry_set(context->tfp, dev, &sparms);
+ if (rc) {
+ /* Log error */
+ CFA_TCAM_MGR_LOG_DIR_TYPE(ERR, parms->dir, parms->type,
+ "Row %d, slice %d set failed, "
+ "rc:%d.\n",
+ row,
+ slice,
+ rc);
+ return rc;
+ }
+ return free_func(sess_idx, parms, row, slice, max_slices);
+}
diff --git a/drivers/net/bnxt/tf_core/cfa_tcam_mgr_hwop_msg.h b/drivers/net/bnxt/tf_core/cfa_tcam_mgr_hwop_msg.h
new file mode 100644
index 0000000000..f7ba625c07
--- /dev/null
+++ b/drivers/net/bnxt/tf_core/cfa_tcam_mgr_hwop_msg.h
@@ -0,0 +1,28 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2021-2023 Broadcom
+ * All rights reserved.
+ */
+
+#ifndef CFA_TCAM_MGR_HWOP_MSG_H
+#define CFA_TCAM_MGR_HWOP_MSG_H
+
+int
+cfa_tcam_mgr_hwops_init(enum cfa_tcam_mgr_device_type type);
+
+int
+cfa_tcam_mgr_entry_set_msg(int sess_idx,
+ struct cfa_tcam_mgr_context *context,
+ struct cfa_tcam_mgr_set_parms *parms,
+ int row, int slice, int max_slices);
+int
+cfa_tcam_mgr_entry_get_msg(int sess_idx,
+ struct cfa_tcam_mgr_context *context,
+ struct cfa_tcam_mgr_get_parms *parms,
+ int row, int slice, int max_slices);
+int
+cfa_tcam_mgr_entry_free_msg(int sess_idx,
+ struct cfa_tcam_mgr_context *context,
+ struct cfa_tcam_mgr_free_parms *parms,
+ int row, int slice, int key_size,
+ int result_size, int max_slices);
+#endif /* CFA_TCAM_MGR_HWOP_MSG_H */
diff --git a/drivers/net/bnxt/tf_core/cfa_tcam_mgr_p4.c b/drivers/net/bnxt/tf_core/cfa_tcam_mgr_p4.c
new file mode 100644
index 0000000000..63c84c5938
--- /dev/null
+++ b/drivers/net/bnxt/tf_core/cfa_tcam_mgr_p4.c
@@ -0,0 +1,921 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2021-2023 Broadcom
+ * All rights reserved.
+ */
+
+#include "hcapi_cfa_defs.h"
+
+#include "cfa_tcam_mgr.h"
+#include "cfa_tcam_mgr_p4.h"
+#include "cfa_tcam_mgr_device.h"
+#include "cfa_resource_types.h"
+#include "tfp.h"
+#include "assert.h"
+#include "tf_util.h"
+
+/*
+ * Sizings of the TCAMs on P4
+ */
+
+#define MAX_ROW_WIDTH 48
+#define MAX_RESULT_SIZE 8
+
+#if MAX_ROW_WIDTH > CFA_TCAM_MGR_MAX_KEY_SIZE
+#error MAX_ROW_WIDTH > CFA_TCAM_MGR_MAX_KEY_SIZE
+#endif
+
+/*
+ * TCAM definitions
+ *
+ * These define the TCAMs in HW.
+ *
+ * Note: Set xxx_TCAM_[R|T]X_NUM_ROWS to zero if a TCAM is either not supported
+ * by HW or not supported by TCAM Manager.
+ */
+
+/** L2 Context TCAM */
+#define L2_CTXT_TCAM_RX_MAX_SLICES 1
+#define L2_CTXT_TCAM_RX_ROW_WIDTH TF_BITS2BYTES_WORD_ALIGN(167)
+#define L2_CTXT_TCAM_RX_NUM_ROWS 1024
+#define L2_CTXT_TCAM_RX_MAX_ENTRIES (L2_CTXT_TCAM_RX_MAX_SLICES * \
+ L2_CTXT_TCAM_RX_NUM_ROWS)
+#define L2_CTXT_TCAM_RX_RESULT_SIZE 8
+
+#define L2_CTXT_TCAM_TX_MAX_SLICES L2_CTXT_TCAM_RX_MAX_SLICES
+#define L2_CTXT_TCAM_TX_ROW_WIDTH L2_CTXT_TCAM_RX_ROW_WIDTH
+#define L2_CTXT_TCAM_TX_NUM_ROWS L2_CTXT_TCAM_RX_NUM_ROWS
+#define L2_CTXT_TCAM_TX_MAX_ENTRIES L2_CTXT_TCAM_RX_MAX_ENTRIES
+#define L2_CTXT_TCAM_TX_RESULT_SIZE L2_CTXT_TCAM_RX_RESULT_SIZE
+
+/** Profile TCAM */
+#define PROF_TCAM_RX_MAX_SLICES 1
+#define PROF_TCAM_RX_ROW_WIDTH TF_BITS2BYTES_WORD_ALIGN(81)
+#define PROF_TCAM_RX_NUM_ROWS 1024
+#define PROF_TCAM_RX_MAX_ENTRIES (PROF_TCAM_RX_MAX_SLICES * \
+ PROF_TCAM_RX_NUM_ROWS)
+#define PROF_TCAM_RX_RESULT_SIZE 8
+
+#define PROF_TCAM_TX_MAX_SLICES PROF_TCAM_RX_MAX_SLICES
+#define PROF_TCAM_TX_ROW_WIDTH PROF_TCAM_RX_ROW_WIDTH
+#define PROF_TCAM_TX_NUM_ROWS PROF_TCAM_RX_NUM_ROWS
+#define PROF_TCAM_TX_MAX_ENTRIES PROF_TCAM_RX_MAX_ENTRIES
+#define PROF_TCAM_TX_RESULT_SIZE PROF_TCAM_RX_RESULT_SIZE
+
+/** Wildcard TCAM */
+#define WC_TCAM_RX_MAX_SLICES 4
+/* 82 bits per slice */
+#define WC_TCAM_RX_ROW_WIDTH (TF_BITS2BYTES_WORD_ALIGN(82) * \
+ WC_TCAM_RX_MAX_SLICES)
+#define WC_TCAM_RX_NUM_ROWS 256
+#define WC_TCAM_RX_MAX_ENTRIES (WC_TCAM_RX_MAX_SLICES * WC_TCAM_RX_NUM_ROWS)
+#define WC_TCAM_RX_RESULT_SIZE 4
+
+#define WC_TCAM_TX_MAX_SLICES WC_TCAM_RX_MAX_SLICES
+#define WC_TCAM_TX_ROW_WIDTH WC_TCAM_RX_ROW_WIDTH
+#define WC_TCAM_TX_NUM_ROWS WC_TCAM_RX_NUM_ROWS
+#define WC_TCAM_TX_MAX_ENTRIES WC_TCAM_RX_MAX_ENTRIES
+#define WC_TCAM_TX_RESULT_SIZE WC_TCAM_RX_RESULT_SIZE
+
+/** Source Properties TCAM */
+#define SP_TCAM_RX_MAX_SLICES 1
+#define SP_TCAM_RX_ROW_WIDTH TF_BITS2BYTES_WORD_ALIGN(89)
+#define SP_TCAM_RX_NUM_ROWS 512
+#define SP_TCAM_RX_MAX_ENTRIES (SP_TCAM_RX_MAX_SLICES * SP_TCAM_RX_NUM_ROWS)
+#define SP_TCAM_RX_RESULT_SIZE 8
+
+#define SP_TCAM_TX_MAX_SLICES SP_TCAM_RX_MAX_SLICES
+#define SP_TCAM_TX_ROW_WIDTH SP_TCAM_RX_ROW_WIDTH
+#define SP_TCAM_TX_NUM_ROWS SP_TCAM_RX_NUM_ROWS
+#define SP_TCAM_TX_MAX_ENTRIES SP_TCAM_RX_MAX_ENTRIES
+#define SP_TCAM_TX_RESULT_SIZE SP_TCAM_RX_RESULT_SIZE
+
+/** Connection Tracking Rule TCAM */
+#define CT_RULE_TCAM_RX_MAX_SLICES 1
+#define CT_RULE_TCAM_RX_ROW_WIDTH TF_BITS2BYTES_WORD_ALIGN(16)
+#define CT_RULE_TCAM_RX_NUM_ROWS 0
+#define CT_RULE_TCAM_RX_MAX_ENTRIES (CT_RULE_TCAM_RX_MAX_SLICES * \
+ CT_RULE_TCAM_RX_NUM_ROWS)
+#define CT_RULE_TCAM_RX_RESULT_SIZE 8
+
+#define CT_RULE_TCAM_TX_MAX_SLICES CT_RULE_TCAM_RX_MAX_SLICES
+#define CT_RULE_TCAM_TX_ROW_WIDTH CT_RULE_TCAM_RX_ROW_WIDTH
+#define CT_RULE_TCAM_TX_NUM_ROWS CT_RULE_TCAM_RX_NUM_ROWS
+#define CT_RULE_TCAM_TX_MAX_ENTRIES CT_RULE_TCAM_RX_MAX_ENTRIES
+#define CT_RULE_TCAM_TX_RESULT_SIZE CT_RULE_TCAM_RX_RESULT_SIZE
+
+/** Virtual Edge Bridge TCAM */
+#define VEB_TCAM_RX_MAX_SLICES 1
+#define VEB_TCAM_RX_ROW_WIDTH TF_BITS2BYTES_WORD_ALIGN(78)
+/* Tx only */
+#define VEB_TCAM_RX_NUM_ROWS 0
+#define VEB_TCAM_RX_MAX_ENTRIES (VEB_TCAM_RX_MAX_SLICES * VEB_TCAM_RX_NUM_ROWS)
+#define VEB_TCAM_RX_RESULT_SIZE 8
+
+#define VEB_TCAM_TX_MAX_SLICES VEB_TCAM_RX_MAX_SLICES
+#define VEB_TCAM_TX_ROW_WIDTH VEB_TCAM_RX_ROW_WIDTH
+#define VEB_TCAM_TX_NUM_ROWS 1024
+#define VEB_TCAM_TX_MAX_ENTRIES (VEB_TCAM_TX_MAX_SLICES * VEB_TCAM_TX_NUM_ROWS)
+#define VEB_TCAM_TX_RESULT_SIZE VEB_TCAM_RX_RESULT_SIZE
+
+/* Declare the table rows for each table here. If new tables are added to the
+ * enum tf_tcam_tbl_type, then new declarations will be needed here.
+ *
+ * The numeric suffix of the structure type indicates how many slices a
+ * particular TCAM supports.
+ *
+ * Array sizes have 1 added to avoid zero length arrays.
+ */
+
+static struct cfa_tcam_mgr_table_rows_1
+ cfa_tcam_mgr_table_rows_L2_CTXT_TCAM_RX[TF_TCAM_MAX_SESSIONS][L2_CTXT_TCAM_RX_NUM_ROWS + 1];
+static struct cfa_tcam_mgr_table_rows_1
+ cfa_tcam_mgr_table_rows_L2_CTXT_TCAM_TX[TF_TCAM_MAX_SESSIONS][L2_CTXT_TCAM_TX_NUM_ROWS + 1];
+static struct cfa_tcam_mgr_table_rows_1
+ cfa_tcam_mgr_table_rows_PROF_TCAM_RX[TF_TCAM_MAX_SESSIONS][PROF_TCAM_RX_NUM_ROWS + 1];
+static struct cfa_tcam_mgr_table_rows_1
+ cfa_tcam_mgr_table_rows_PROF_TCAM_TX[TF_TCAM_MAX_SESSIONS][PROF_TCAM_TX_NUM_ROWS + 1];
+static struct cfa_tcam_mgr_table_rows_4
+ cfa_tcam_mgr_table_rows_WC_TCAM_RX[TF_TCAM_MAX_SESSIONS][WC_TCAM_RX_NUM_ROWS + 1];
+static struct cfa_tcam_mgr_table_rows_4
+ cfa_tcam_mgr_table_rows_WC_TCAM_TX[TF_TCAM_MAX_SESSIONS][WC_TCAM_TX_NUM_ROWS + 1];
+static struct cfa_tcam_mgr_table_rows_1
+ cfa_tcam_mgr_table_rows_SP_TCAM_RX[TF_TCAM_MAX_SESSIONS][SP_TCAM_RX_NUM_ROWS + 1];
+static struct cfa_tcam_mgr_table_rows_1
+ cfa_tcam_mgr_table_rows_SP_TCAM_TX[TF_TCAM_MAX_SESSIONS][SP_TCAM_TX_NUM_ROWS + 1];
+static struct cfa_tcam_mgr_table_rows_1
+ cfa_tcam_mgr_table_rows_CT_RULE_TCAM_RX[TF_TCAM_MAX_SESSIONS][CT_RULE_TCAM_RX_NUM_ROWS + 1];
+static struct cfa_tcam_mgr_table_rows_1
+ cfa_tcam_mgr_table_rows_CT_RULE_TCAM_TX[TF_TCAM_MAX_SESSIONS][CT_RULE_TCAM_TX_NUM_ROWS + 1];
+static struct cfa_tcam_mgr_table_rows_1
+ cfa_tcam_mgr_table_rows_VEB_TCAM_RX[TF_TCAM_MAX_SESSIONS][VEB_TCAM_RX_NUM_ROWS + 1];
+static struct cfa_tcam_mgr_table_rows_1
+ cfa_tcam_mgr_table_rows_VEB_TCAM_TX[TF_TCAM_MAX_SESSIONS][VEB_TCAM_TX_NUM_ROWS + 1];
+static struct cfa_tcam_mgr_table_rows_4
+ cfa_tcam_mgr_table_rows_WC_TCAM_RX_HIGH[TF_TCAM_MAX_SESSIONS][WC_TCAM_RX_NUM_ROWS + 1];
+static struct cfa_tcam_mgr_table_rows_4
+ cfa_tcam_mgr_table_rows_WC_TCAM_RX_LOW[TF_TCAM_MAX_SESSIONS][WC_TCAM_RX_NUM_ROWS + 1];
+static struct cfa_tcam_mgr_table_rows_4
+ cfa_tcam_mgr_table_rows_WC_TCAM_TX_HIGH[TF_TCAM_MAX_SESSIONS][WC_TCAM_TX_NUM_ROWS + 1];
+static struct cfa_tcam_mgr_table_rows_4
+ cfa_tcam_mgr_table_rows_WC_TCAM_TX_LOW[TF_TCAM_MAX_SESSIONS][WC_TCAM_TX_NUM_ROWS + 1];
+
+struct cfa_tcam_mgr_table_data
+cfa_tcam_mgr_tables_p4[TF_DIR_MAX][CFA_TCAM_MGR_TBL_TYPE_MAX] = {
+ { /* RX */
+ { /* High AFM */
+ .max_slices = L2_CTXT_TCAM_RX_MAX_SLICES,
+ .row_width = L2_CTXT_TCAM_RX_ROW_WIDTH,
+ .num_rows = L2_CTXT_TCAM_RX_NUM_ROWS,
+ .start_row = 0,
+ .end_row = 0,
+ .max_entries = 0,
+ .result_size = L2_CTXT_TCAM_RX_RESULT_SIZE,
+ .hcapi_type = CFA_RESOURCE_TYPE_P4_L2_CTXT_TCAM_HIGH,
+ },
+ { /* High APPS */
+ .max_slices = L2_CTXT_TCAM_RX_MAX_SLICES,
+ .row_width = L2_CTXT_TCAM_RX_ROW_WIDTH,
+ .num_rows = L2_CTXT_TCAM_RX_NUM_ROWS,
+ .start_row = 0,
+ .end_row = (L2_CTXT_TCAM_RX_NUM_ROWS / 2) - 1,
+ .max_entries = (L2_CTXT_TCAM_RX_MAX_ENTRIES / 2),
+ .result_size = L2_CTXT_TCAM_RX_RESULT_SIZE,
+ .hcapi_type = CFA_RESOURCE_TYPE_P4_L2_CTXT_TCAM_HIGH,
+ },
+ { /* Low AFM */
+ .max_slices = L2_CTXT_TCAM_RX_MAX_SLICES,
+ .row_width = L2_CTXT_TCAM_RX_ROW_WIDTH,
+ .num_rows = L2_CTXT_TCAM_RX_NUM_ROWS,
+ .start_row = 0,
+ .end_row = 0,
+ .max_entries = 0,
+ .result_size = L2_CTXT_TCAM_RX_RESULT_SIZE,
+ .hcapi_type = CFA_RESOURCE_TYPE_P4_L2_CTXT_TCAM_LOW,
+ },
+ { /* Low APPS */
+ .max_slices = L2_CTXT_TCAM_RX_MAX_SLICES,
+ .row_width = L2_CTXT_TCAM_RX_ROW_WIDTH,
+ .num_rows = L2_CTXT_TCAM_RX_NUM_ROWS,
+ .start_row = (L2_CTXT_TCAM_RX_NUM_ROWS / 2),
+ .end_row = L2_CTXT_TCAM_RX_NUM_ROWS - 1,
+ .max_entries = (L2_CTXT_TCAM_RX_MAX_ENTRIES / 2),
+ .result_size = L2_CTXT_TCAM_RX_RESULT_SIZE,
+ .hcapi_type = CFA_RESOURCE_TYPE_P4_L2_CTXT_TCAM_LOW,
+ },
+ { /* AFM */
+ .max_slices = PROF_TCAM_RX_MAX_SLICES,
+ .row_width = PROF_TCAM_RX_ROW_WIDTH,
+ .num_rows = PROF_TCAM_RX_NUM_ROWS,
+ .start_row = 0,
+ .end_row = 0,
+ .max_entries = 0,
+ .result_size = PROF_TCAM_RX_RESULT_SIZE,
+ .hcapi_type = CFA_RESOURCE_TYPE_P4_PROF_TCAM,
+ },
+ { /* APPS */
+ .max_slices = PROF_TCAM_RX_MAX_SLICES,
+ .row_width = PROF_TCAM_RX_ROW_WIDTH,
+ .num_rows = PROF_TCAM_RX_NUM_ROWS,
+ .start_row = 0,
+ .end_row = PROF_TCAM_RX_NUM_ROWS - 1,
+ .max_entries = PROF_TCAM_RX_MAX_ENTRIES,
+ .result_size = PROF_TCAM_RX_RESULT_SIZE,
+ .hcapi_type = CFA_RESOURCE_TYPE_P4_PROF_TCAM,
+ },
+ { /* AFM */
+ .max_slices = WC_TCAM_RX_MAX_SLICES,
+ .row_width = WC_TCAM_RX_ROW_WIDTH,
+ .num_rows = WC_TCAM_RX_NUM_ROWS,
+ .start_row = 0,
+ .end_row = 0,
+ .max_entries = 0,
+ .result_size = WC_TCAM_RX_RESULT_SIZE,
+ .hcapi_type = CFA_RESOURCE_TYPE_P4_WC_TCAM,
+ },
+ { /* APPS */
+ .max_slices = WC_TCAM_RX_MAX_SLICES,
+ .row_width = WC_TCAM_RX_ROW_WIDTH,
+ .num_rows = WC_TCAM_RX_NUM_ROWS,
+ .start_row = 0,
+ .end_row = WC_TCAM_RX_NUM_ROWS - 1,
+ .max_entries = WC_TCAM_RX_MAX_ENTRIES,
+ .result_size = WC_TCAM_RX_RESULT_SIZE,
+ .hcapi_type = CFA_RESOURCE_TYPE_P4_WC_TCAM,
+ },
+ { /* AFM */
+ .max_slices = SP_TCAM_RX_MAX_SLICES,
+ .row_width = SP_TCAM_RX_ROW_WIDTH,
+ .num_rows = SP_TCAM_RX_NUM_ROWS,
+ .start_row = 0,
+ .end_row = 0,
+ .max_entries = 0,
+ .result_size = SP_TCAM_RX_RESULT_SIZE,
+ .hcapi_type = CFA_RESOURCE_TYPE_P4_SP_TCAM,
+ },
+ { /* APPS */
+ .max_slices = SP_TCAM_RX_MAX_SLICES,
+ .row_width = SP_TCAM_RX_ROW_WIDTH,
+ .num_rows = SP_TCAM_RX_NUM_ROWS,
+ .start_row = 0,
+ .end_row = SP_TCAM_RX_NUM_ROWS - 1,
+ .max_entries = SP_TCAM_RX_MAX_ENTRIES,
+ .result_size = SP_TCAM_RX_RESULT_SIZE,
+ .hcapi_type = CFA_RESOURCE_TYPE_P4_SP_TCAM,
+ },
+ { /* AFM */
+ .max_slices = CT_RULE_TCAM_RX_MAX_SLICES,
+ .row_width = CT_RULE_TCAM_RX_ROW_WIDTH,
+ .num_rows = CT_RULE_TCAM_RX_NUM_ROWS,
+ .start_row = 0,
+ .end_row = 0,
+ .max_entries = 0,
+ .result_size = CT_RULE_TCAM_RX_RESULT_SIZE,
+ },
+ { /* APPS */
+ .max_slices = CT_RULE_TCAM_RX_MAX_SLICES,
+ .row_width = CT_RULE_TCAM_RX_ROW_WIDTH,
+ .num_rows = CT_RULE_TCAM_RX_NUM_ROWS,
+ .start_row = 0,
+#if CT_RULE_TCAM_RX_NUM_ROWS > 0
+ .end_row = CT_RULE_TCAM_RX_NUM_ROWS - 1,
+#else
+ .end_row = CT_RULE_TCAM_RX_NUM_ROWS,
+#endif
+ .max_entries = CT_RULE_TCAM_RX_MAX_ENTRIES,
+ .result_size = CT_RULE_TCAM_RX_RESULT_SIZE,
+ },
+ { /* AFM */
+ .max_slices = VEB_TCAM_RX_MAX_SLICES,
+ .row_width = VEB_TCAM_RX_ROW_WIDTH,
+ .num_rows = VEB_TCAM_RX_NUM_ROWS,
+ .start_row = 0,
+ .end_row = 0,
+ .max_entries = 0,
+ .result_size = VEB_TCAM_RX_RESULT_SIZE,
+ },
+ { /* APPS */
+ .max_slices = VEB_TCAM_RX_MAX_SLICES,
+ .row_width = VEB_TCAM_RX_ROW_WIDTH,
+ .num_rows = VEB_TCAM_RX_NUM_ROWS,
+ .start_row = 0,
+#if VEB_TCAM_RX_NUM_ROWS > 0
+ .end_row = VEB_TCAM_RX_NUM_ROWS - 1,
+#else
+ .end_row = VEB_TCAM_RX_NUM_ROWS,
+#endif
+ .max_entries = VEB_TCAM_RX_MAX_ENTRIES,
+ .result_size = VEB_TCAM_RX_RESULT_SIZE,
+ },
+ { /* AFM */
+ .max_slices = WC_TCAM_RX_MAX_SLICES,
+ .row_width = WC_TCAM_RX_ROW_WIDTH,
+ .num_rows = WC_TCAM_RX_NUM_ROWS,
+ .start_row = 0,
+ .end_row = 0,
+ .max_entries = 0,
+ .result_size = WC_TCAM_RX_RESULT_SIZE,
+ .hcapi_type = CFA_RESOURCE_TYPE_P4_WC_TCAM,
+ },
+ { /* APPS */
+ .max_slices = WC_TCAM_RX_MAX_SLICES,
+ .row_width = WC_TCAM_RX_ROW_WIDTH,
+ .num_rows = WC_TCAM_RX_NUM_ROWS,
+ .start_row = 0,
+ .end_row = WC_TCAM_RX_NUM_ROWS - 1,
+ .max_entries = WC_TCAM_RX_MAX_ENTRIES,
+ .result_size = WC_TCAM_RX_RESULT_SIZE,
+ .hcapi_type = CFA_RESOURCE_TYPE_P4_WC_TCAM,
+ },
+ { /* AFM */
+ .max_slices = WC_TCAM_RX_MAX_SLICES,
+ .row_width = WC_TCAM_RX_ROW_WIDTH,
+ .num_rows = WC_TCAM_RX_NUM_ROWS,
+ .start_row = 0,
+ .end_row = 0,
+ .max_entries = 0,
+ .result_size = WC_TCAM_RX_RESULT_SIZE,
+ .hcapi_type = CFA_RESOURCE_TYPE_P4_WC_TCAM,
+ },
+ { /* APPS */
+ .max_slices = WC_TCAM_RX_MAX_SLICES,
+ .row_width = WC_TCAM_RX_ROW_WIDTH,
+ .num_rows = WC_TCAM_RX_NUM_ROWS,
+ .start_row = 0,
+ .end_row = WC_TCAM_RX_NUM_ROWS - 1,
+ .max_entries = WC_TCAM_RX_MAX_ENTRIES,
+ .result_size = WC_TCAM_RX_RESULT_SIZE,
+ .hcapi_type = CFA_RESOURCE_TYPE_P4_WC_TCAM,
+ },
+ },
+ { /* TX */
+ { /* AFM */
+ .max_slices = L2_CTXT_TCAM_TX_MAX_SLICES,
+ .row_width = L2_CTXT_TCAM_TX_ROW_WIDTH,
+ .num_rows = L2_CTXT_TCAM_TX_NUM_ROWS,
+ .start_row = 0,
+ .end_row = 0,
+ .max_entries = 0,
+ .result_size = L2_CTXT_TCAM_TX_RESULT_SIZE,
+ .hcapi_type = CFA_RESOURCE_TYPE_P4_L2_CTXT_TCAM_HIGH,
+ },
+ { /* APPS */
+ .max_slices = L2_CTXT_TCAM_TX_MAX_SLICES,
+ .row_width = L2_CTXT_TCAM_TX_ROW_WIDTH,
+ .num_rows = L2_CTXT_TCAM_TX_NUM_ROWS,
+ .start_row = 0,
+ .end_row = (L2_CTXT_TCAM_TX_NUM_ROWS / 2) - 1,
+ .max_entries = (L2_CTXT_TCAM_TX_MAX_ENTRIES / 2),
+ .result_size = L2_CTXT_TCAM_TX_RESULT_SIZE,
+ .hcapi_type = CFA_RESOURCE_TYPE_P4_L2_CTXT_TCAM_HIGH,
+ },
+ { /* AFM */
+ .max_slices = L2_CTXT_TCAM_TX_MAX_SLICES,
+ .row_width = L2_CTXT_TCAM_TX_ROW_WIDTH,
+ .num_rows = L2_CTXT_TCAM_TX_NUM_ROWS,
+ .start_row = 0,
+ .end_row = 0,
+ .max_entries = 0,
+ .result_size = L2_CTXT_TCAM_TX_RESULT_SIZE,
+ .hcapi_type = CFA_RESOURCE_TYPE_P4_L2_CTXT_TCAM_LOW,
+ },
+ { /* APPS */
+ .max_slices = L2_CTXT_TCAM_TX_MAX_SLICES,
+ .row_width = L2_CTXT_TCAM_TX_ROW_WIDTH,
+ .num_rows = L2_CTXT_TCAM_TX_NUM_ROWS,
+ .start_row = (L2_CTXT_TCAM_TX_NUM_ROWS / 2),
+ .end_row = L2_CTXT_TCAM_TX_NUM_ROWS - 1,
+ .max_entries = (L2_CTXT_TCAM_TX_MAX_ENTRIES / 2),
+ .result_size = L2_CTXT_TCAM_TX_RESULT_SIZE,
+ .hcapi_type = CFA_RESOURCE_TYPE_P4_L2_CTXT_TCAM_LOW,
+ },
+ { /* AFM */
+ .max_slices = PROF_TCAM_TX_MAX_SLICES,
+ .row_width = PROF_TCAM_TX_ROW_WIDTH,
+ .num_rows = PROF_TCAM_TX_NUM_ROWS,
+ .start_row = 0,
+ .end_row = 0,
+ .max_entries = 0,
+ .result_size = PROF_TCAM_TX_RESULT_SIZE,
+ .hcapi_type = CFA_RESOURCE_TYPE_P4_PROF_TCAM,
+ },
+ { /* APPS */
+ .max_slices = PROF_TCAM_TX_MAX_SLICES,
+ .row_width = PROF_TCAM_TX_ROW_WIDTH,
+ .num_rows = PROF_TCAM_TX_NUM_ROWS,
+ .start_row = 0,
+ .end_row = PROF_TCAM_TX_NUM_ROWS - 1,
+ .max_entries = PROF_TCAM_TX_MAX_ENTRIES,
+ .result_size = PROF_TCAM_TX_RESULT_SIZE,
+ .hcapi_type = CFA_RESOURCE_TYPE_P4_PROF_TCAM,
+ },
+ { /* AFM */
+ .max_slices = WC_TCAM_TX_MAX_SLICES,
+ .row_width = WC_TCAM_TX_ROW_WIDTH,
+ .num_rows = WC_TCAM_TX_NUM_ROWS,
+ .start_row = 0,
+ .end_row = 0,
+ .max_entries = 0,
+ .result_size = WC_TCAM_TX_RESULT_SIZE,
+ .hcapi_type = CFA_RESOURCE_TYPE_P4_WC_TCAM,
+ },
+ { /* APPS */
+ .max_slices = WC_TCAM_TX_MAX_SLICES,
+ .row_width = WC_TCAM_TX_ROW_WIDTH,
+ .num_rows = WC_TCAM_TX_NUM_ROWS,
+ .start_row = 0,
+ .end_row = WC_TCAM_TX_NUM_ROWS - 1,
+ .max_entries = WC_TCAM_TX_MAX_ENTRIES,
+ .result_size = WC_TCAM_TX_RESULT_SIZE,
+ .hcapi_type = CFA_RESOURCE_TYPE_P4_WC_TCAM,
+ },
+ { /* AFM */
+ .max_slices = SP_TCAM_TX_MAX_SLICES,
+ .row_width = SP_TCAM_TX_ROW_WIDTH,
+ .num_rows = SP_TCAM_TX_NUM_ROWS,
+ .start_row = 0,
+ .end_row = 0,
+ .max_entries = 0,
+ .result_size = SP_TCAM_TX_RESULT_SIZE,
+ .hcapi_type = CFA_RESOURCE_TYPE_P4_SP_TCAM,
+ },
+ { /* APPS */
+ .max_slices = SP_TCAM_TX_MAX_SLICES,
+ .row_width = SP_TCAM_TX_ROW_WIDTH,
+ .num_rows = SP_TCAM_TX_NUM_ROWS,
+ .start_row = 0,
+ .end_row = SP_TCAM_TX_NUM_ROWS - 1,
+ .max_entries = SP_TCAM_TX_MAX_ENTRIES,
+ .result_size = SP_TCAM_TX_RESULT_SIZE,
+ .hcapi_type = CFA_RESOURCE_TYPE_P4_SP_TCAM,
+ },
+ { /* AFM */
+ .max_slices = CT_RULE_TCAM_TX_MAX_SLICES,
+ .row_width = CT_RULE_TCAM_TX_ROW_WIDTH,
+ .num_rows = CT_RULE_TCAM_TX_NUM_ROWS,
+ .start_row = 0,
+ .end_row = 0,
+ .max_entries = 0,
+ .result_size = CT_RULE_TCAM_RX_RESULT_SIZE,
+ },
+ { /* APPS */
+ .max_slices = CT_RULE_TCAM_TX_MAX_SLICES,
+ .row_width = CT_RULE_TCAM_TX_ROW_WIDTH,
+ .num_rows = CT_RULE_TCAM_TX_NUM_ROWS,
+ .start_row = 0,
+#if CT_RULE_TCAM_TX_NUM_ROWS > 0
+ .end_row = CT_RULE_TCAM_TX_NUM_ROWS - 1,
+#else
+ .end_row = CT_RULE_TCAM_TX_NUM_ROWS,
+#endif
+ .max_entries = CT_RULE_TCAM_TX_MAX_ENTRIES,
+ .result_size = CT_RULE_TCAM_RX_RESULT_SIZE,
+ },
+ { /* AFM */
+ .max_slices = VEB_TCAM_TX_MAX_SLICES,
+ .row_width = VEB_TCAM_TX_ROW_WIDTH,
+ .num_rows = VEB_TCAM_TX_NUM_ROWS,
+ .start_row = 0,
+ .end_row = 0,
+ .max_entries = 0,
+ .result_size = VEB_TCAM_RX_RESULT_SIZE,
+ },
+ { /* APPS */
+ .max_slices = VEB_TCAM_TX_MAX_SLICES,
+ .row_width = VEB_TCAM_TX_ROW_WIDTH,
+ .num_rows = VEB_TCAM_TX_NUM_ROWS,
+ .start_row = 0,
+ .end_row = VEB_TCAM_TX_NUM_ROWS - 1,
+ .max_entries = VEB_TCAM_TX_MAX_ENTRIES,
+ .result_size = VEB_TCAM_RX_RESULT_SIZE,
+ },
+ { /* AFM */
+ .max_slices = WC_TCAM_TX_MAX_SLICES,
+ .row_width = WC_TCAM_TX_ROW_WIDTH,
+ .num_rows = WC_TCAM_TX_NUM_ROWS,
+ .start_row = 0,
+ .end_row = 0,
+ .max_entries = 0,
+ .result_size = WC_TCAM_TX_RESULT_SIZE,
+ .hcapi_type = CFA_RESOURCE_TYPE_P4_WC_TCAM,
+ },
+ { /* APPS */
+ .max_slices = WC_TCAM_TX_MAX_SLICES,
+ .row_width = WC_TCAM_TX_ROW_WIDTH,
+ .num_rows = WC_TCAM_TX_NUM_ROWS,
+ .start_row = 0,
+ .end_row = WC_TCAM_TX_NUM_ROWS - 1,
+ .max_entries = WC_TCAM_TX_MAX_ENTRIES,
+ .result_size = WC_TCAM_TX_RESULT_SIZE,
+ .hcapi_type = CFA_RESOURCE_TYPE_P4_WC_TCAM,
+ },
+ { /* AFM */
+ .max_slices = WC_TCAM_TX_MAX_SLICES,
+ .row_width = WC_TCAM_TX_ROW_WIDTH,
+ .num_rows = WC_TCAM_TX_NUM_ROWS,
+ .start_row = 0,
+ .end_row = 0,
+ .max_entries = 0,
+ .result_size = WC_TCAM_TX_RESULT_SIZE,
+ .hcapi_type = CFA_RESOURCE_TYPE_P4_WC_TCAM,
+ },
+ { /* APPS */
+ .max_slices = WC_TCAM_TX_MAX_SLICES,
+ .row_width = WC_TCAM_TX_ROW_WIDTH,
+ .num_rows = WC_TCAM_TX_NUM_ROWS,
+ .start_row = 0,
+ .end_row = WC_TCAM_TX_NUM_ROWS - 1,
+ .max_entries = WC_TCAM_TX_MAX_ENTRIES,
+ .result_size = WC_TCAM_TX_RESULT_SIZE,
+ .hcapi_type = CFA_RESOURCE_TYPE_P4_WC_TCAM,
+ },
+ },
+};
+
+static struct cfa_tcam_mgr_entry_data entry_data_p4[TF_TCAM_MAX_SESSIONS][TF_TCAM_MAX_ENTRIES];
+
+static struct sbmp session_bmp_p4[TF_TCAM_MAX_SESSIONS][TF_TCAM_MAX_ENTRIES];
+
+int
+cfa_tcam_mgr_sess_table_get_p4(int sess_idx, struct sbmp **session_bmp)
+{
+ *session_bmp = session_bmp_p4[sess_idx];
+ return 0;
+}
+
+int
+cfa_tcam_mgr_init_p4(int sess_idx, struct cfa_tcam_mgr_entry_data **global_entry_data)
+{
+ int max_row_width = 0;
+ int max_result_size = 0;
+ int dir, type;
+
+ *global_entry_data = entry_data_p4[sess_idx];
+
+ memcpy(&cfa_tcam_mgr_tables[sess_idx],
+ &cfa_tcam_mgr_tables_p4,
+ sizeof(cfa_tcam_mgr_tables[sess_idx]));
+
+ cfa_tcam_mgr_tables[sess_idx][TF_DIR_RX]
+ [CFA_TCAM_MGR_TBL_TYPE_L2_CTXT_TCAM_HIGH_AFM].tcam_rows =
+ (struct cfa_tcam_mgr_table_rows_0 *)
+ &cfa_tcam_mgr_table_rows_L2_CTXT_TCAM_RX[sess_idx];
+ cfa_tcam_mgr_tables[sess_idx][TF_DIR_RX]
+ [CFA_TCAM_MGR_TBL_TYPE_L2_CTXT_TCAM_HIGH_APPS].tcam_rows =
+ (struct cfa_tcam_mgr_table_rows_0 *)
+ &cfa_tcam_mgr_table_rows_L2_CTXT_TCAM_RX[sess_idx];
+
+ cfa_tcam_mgr_tables[sess_idx][TF_DIR_TX]
+ [CFA_TCAM_MGR_TBL_TYPE_L2_CTXT_TCAM_HIGH_AFM].tcam_rows =
+ (struct cfa_tcam_mgr_table_rows_0 *)
+ &cfa_tcam_mgr_table_rows_L2_CTXT_TCAM_TX[sess_idx];
+ cfa_tcam_mgr_tables[sess_idx][TF_DIR_TX]
+ [CFA_TCAM_MGR_TBL_TYPE_L2_CTXT_TCAM_HIGH_APPS].tcam_rows =
+ (struct cfa_tcam_mgr_table_rows_0 *)
+ &cfa_tcam_mgr_table_rows_L2_CTXT_TCAM_TX[sess_idx];
+
+ cfa_tcam_mgr_tables[sess_idx][TF_DIR_RX]
+ [CFA_TCAM_MGR_TBL_TYPE_L2_CTXT_TCAM_LOW_AFM].tcam_rows =
+ (struct cfa_tcam_mgr_table_rows_0 *)
+ &cfa_tcam_mgr_table_rows_L2_CTXT_TCAM_RX[sess_idx];
+ cfa_tcam_mgr_tables[sess_idx][TF_DIR_RX]
+ [CFA_TCAM_MGR_TBL_TYPE_L2_CTXT_TCAM_LOW_APPS].tcam_rows =
+ (struct cfa_tcam_mgr_table_rows_0 *)
+ &cfa_tcam_mgr_table_rows_L2_CTXT_TCAM_RX[sess_idx];
+
+ cfa_tcam_mgr_tables[sess_idx][TF_DIR_TX]
+ [CFA_TCAM_MGR_TBL_TYPE_L2_CTXT_TCAM_LOW_AFM].tcam_rows =
+ (struct cfa_tcam_mgr_table_rows_0 *)
+ &cfa_tcam_mgr_table_rows_L2_CTXT_TCAM_TX[sess_idx];
+ cfa_tcam_mgr_tables[sess_idx][TF_DIR_TX]
+ [CFA_TCAM_MGR_TBL_TYPE_L2_CTXT_TCAM_LOW_APPS].tcam_rows =
+ (struct cfa_tcam_mgr_table_rows_0 *)
+ &cfa_tcam_mgr_table_rows_L2_CTXT_TCAM_TX[sess_idx];
+
+ cfa_tcam_mgr_tables[sess_idx][TF_DIR_RX]
+ [CFA_TCAM_MGR_TBL_TYPE_PROF_TCAM_AFM].tcam_rows =
+ (struct cfa_tcam_mgr_table_rows_0 *)
+ &cfa_tcam_mgr_table_rows_PROF_TCAM_RX[sess_idx];
+ cfa_tcam_mgr_tables[sess_idx][TF_DIR_RX]
+ [CFA_TCAM_MGR_TBL_TYPE_PROF_TCAM_APPS].tcam_rows =
+ (struct cfa_tcam_mgr_table_rows_0 *)
+ &cfa_tcam_mgr_table_rows_PROF_TCAM_RX[sess_idx];
+
+ cfa_tcam_mgr_tables[sess_idx][TF_DIR_TX]
+ [CFA_TCAM_MGR_TBL_TYPE_PROF_TCAM_AFM].tcam_rows =
+ (struct cfa_tcam_mgr_table_rows_0 *)
+ &cfa_tcam_mgr_table_rows_PROF_TCAM_TX[sess_idx];
+ cfa_tcam_mgr_tables[sess_idx][TF_DIR_TX]
+ [CFA_TCAM_MGR_TBL_TYPE_PROF_TCAM_APPS].tcam_rows =
+ (struct cfa_tcam_mgr_table_rows_0 *)
+ &cfa_tcam_mgr_table_rows_PROF_TCAM_TX[sess_idx];
+
+ cfa_tcam_mgr_tables[sess_idx][TF_DIR_RX]
+ [CFA_TCAM_MGR_TBL_TYPE_WC_TCAM_AFM].tcam_rows =
+ (struct cfa_tcam_mgr_table_rows_0 *)
+ &cfa_tcam_mgr_table_rows_WC_TCAM_RX[sess_idx];
+ cfa_tcam_mgr_tables[sess_idx][TF_DIR_RX]
+ [CFA_TCAM_MGR_TBL_TYPE_WC_TCAM_APPS].tcam_rows =
+ (struct cfa_tcam_mgr_table_rows_0 *)
+ &cfa_tcam_mgr_table_rows_WC_TCAM_RX[sess_idx];
+
+ cfa_tcam_mgr_tables[sess_idx][TF_DIR_TX]
+ [CFA_TCAM_MGR_TBL_TYPE_WC_TCAM_AFM].tcam_rows =
+ (struct cfa_tcam_mgr_table_rows_0 *)
+ &cfa_tcam_mgr_table_rows_WC_TCAM_TX[sess_idx];
+ cfa_tcam_mgr_tables[sess_idx][TF_DIR_TX]
+ [CFA_TCAM_MGR_TBL_TYPE_WC_TCAM_APPS].tcam_rows =
+ (struct cfa_tcam_mgr_table_rows_0 *)
+ &cfa_tcam_mgr_table_rows_WC_TCAM_TX[sess_idx];
+
+ cfa_tcam_mgr_tables[sess_idx][TF_DIR_RX]
+ [CFA_TCAM_MGR_TBL_TYPE_SP_TCAM_AFM].tcam_rows =
+ (struct cfa_tcam_mgr_table_rows_0 *)
+ &cfa_tcam_mgr_table_rows_SP_TCAM_RX[sess_idx];
+ cfa_tcam_mgr_tables[sess_idx][TF_DIR_RX]
+ [CFA_TCAM_MGR_TBL_TYPE_SP_TCAM_APPS].tcam_rows =
+ (struct cfa_tcam_mgr_table_rows_0 *)
+ &cfa_tcam_mgr_table_rows_SP_TCAM_RX[sess_idx];
+
+ cfa_tcam_mgr_tables[sess_idx][TF_DIR_TX]
+ [CFA_TCAM_MGR_TBL_TYPE_SP_TCAM_AFM].tcam_rows =
+ (struct cfa_tcam_mgr_table_rows_0 *)
+ &cfa_tcam_mgr_table_rows_SP_TCAM_TX[sess_idx];
+ cfa_tcam_mgr_tables[sess_idx][TF_DIR_TX]
+ [CFA_TCAM_MGR_TBL_TYPE_SP_TCAM_APPS].tcam_rows =
+ (struct cfa_tcam_mgr_table_rows_0 *)
+ &cfa_tcam_mgr_table_rows_SP_TCAM_TX[sess_idx];
+
+ cfa_tcam_mgr_tables[sess_idx][TF_DIR_RX]
+ [CFA_TCAM_MGR_TBL_TYPE_CT_RULE_TCAM_AFM].tcam_rows =
+ (struct cfa_tcam_mgr_table_rows_0 *)
+ &cfa_tcam_mgr_table_rows_CT_RULE_TCAM_RX[sess_idx];
+ cfa_tcam_mgr_tables[sess_idx][TF_DIR_RX]
+ [CFA_TCAM_MGR_TBL_TYPE_CT_RULE_TCAM_APPS].tcam_rows =
+ (struct cfa_tcam_mgr_table_rows_0 *)
+ &cfa_tcam_mgr_table_rows_CT_RULE_TCAM_RX[sess_idx];
+
+ cfa_tcam_mgr_tables[sess_idx][TF_DIR_TX]
+ [CFA_TCAM_MGR_TBL_TYPE_CT_RULE_TCAM_AFM].tcam_rows =
+ (struct cfa_tcam_mgr_table_rows_0 *)
+ &cfa_tcam_mgr_table_rows_CT_RULE_TCAM_TX[sess_idx];
+ cfa_tcam_mgr_tables[sess_idx][TF_DIR_TX]
+ [CFA_TCAM_MGR_TBL_TYPE_CT_RULE_TCAM_APPS].tcam_rows =
+ (struct cfa_tcam_mgr_table_rows_0 *)
+ &cfa_tcam_mgr_table_rows_CT_RULE_TCAM_TX[sess_idx];
+
+ cfa_tcam_mgr_tables[sess_idx][TF_DIR_RX]
+ [CFA_TCAM_MGR_TBL_TYPE_VEB_TCAM_AFM].tcam_rows =
+ (struct cfa_tcam_mgr_table_rows_0 *)
+ &cfa_tcam_mgr_table_rows_VEB_TCAM_RX[sess_idx];
+ cfa_tcam_mgr_tables[sess_idx][TF_DIR_RX]
+ [CFA_TCAM_MGR_TBL_TYPE_VEB_TCAM_APPS].tcam_rows =
+ (struct cfa_tcam_mgr_table_rows_0 *)
+ &cfa_tcam_mgr_table_rows_VEB_TCAM_RX[sess_idx];
+
+ cfa_tcam_mgr_tables[sess_idx][TF_DIR_TX]
+ [CFA_TCAM_MGR_TBL_TYPE_VEB_TCAM_AFM].tcam_rows =
+ (struct cfa_tcam_mgr_table_rows_0 *)
+ &cfa_tcam_mgr_table_rows_VEB_TCAM_TX[sess_idx];
+ cfa_tcam_mgr_tables[sess_idx][TF_DIR_TX]
+ [CFA_TCAM_MGR_TBL_TYPE_VEB_TCAM_APPS].tcam_rows =
+ (struct cfa_tcam_mgr_table_rows_0 *)
+ &cfa_tcam_mgr_table_rows_VEB_TCAM_TX[sess_idx];
+ cfa_tcam_mgr_tables[sess_idx][TF_DIR_RX]
+ [CFA_TCAM_MGR_TBL_TYPE_WC_TCAM_HIGH_AFM].tcam_rows =
+ (struct cfa_tcam_mgr_table_rows_0 *)
+ &cfa_tcam_mgr_table_rows_WC_TCAM_RX_HIGH[sess_idx];
+ cfa_tcam_mgr_tables[sess_idx][TF_DIR_RX]
+ [CFA_TCAM_MGR_TBL_TYPE_WC_TCAM_HIGH_APPS].tcam_rows =
+ (struct cfa_tcam_mgr_table_rows_0 *)
+ &cfa_tcam_mgr_table_rows_WC_TCAM_RX_HIGH[sess_idx];
+
+ cfa_tcam_mgr_tables[sess_idx][TF_DIR_TX]
+ [CFA_TCAM_MGR_TBL_TYPE_WC_TCAM_HIGH_AFM].tcam_rows =
+ (struct cfa_tcam_mgr_table_rows_0 *)
+ &cfa_tcam_mgr_table_rows_WC_TCAM_TX_HIGH[sess_idx];
+ cfa_tcam_mgr_tables[sess_idx][TF_DIR_TX]
+ [CFA_TCAM_MGR_TBL_TYPE_WC_TCAM_HIGH_APPS].tcam_rows =
+ (struct cfa_tcam_mgr_table_rows_0 *)
+ &cfa_tcam_mgr_table_rows_WC_TCAM_TX_HIGH[sess_idx];
+
+ cfa_tcam_mgr_tables[sess_idx][TF_DIR_RX]
+ [CFA_TCAM_MGR_TBL_TYPE_WC_TCAM_LOW_AFM].tcam_rows =
+ (struct cfa_tcam_mgr_table_rows_0 *)
+ &cfa_tcam_mgr_table_rows_WC_TCAM_RX_LOW[sess_idx];
+ cfa_tcam_mgr_tables[sess_idx][TF_DIR_RX]
+ [CFA_TCAM_MGR_TBL_TYPE_WC_TCAM_LOW_APPS].tcam_rows =
+ (struct cfa_tcam_mgr_table_rows_0 *)
+ &cfa_tcam_mgr_table_rows_WC_TCAM_RX_LOW[sess_idx];
+
+ cfa_tcam_mgr_tables[sess_idx][TF_DIR_TX]
+ [CFA_TCAM_MGR_TBL_TYPE_WC_TCAM_LOW_AFM].tcam_rows =
+ (struct cfa_tcam_mgr_table_rows_0 *)
+ &cfa_tcam_mgr_table_rows_WC_TCAM_TX_LOW[sess_idx];
+ cfa_tcam_mgr_tables[sess_idx][TF_DIR_TX]
+ [CFA_TCAM_MGR_TBL_TYPE_WC_TCAM_LOW_APPS].tcam_rows =
+ (struct cfa_tcam_mgr_table_rows_0 *)
+ &cfa_tcam_mgr_table_rows_WC_TCAM_TX_LOW[sess_idx];
+
+ for (dir = 0; dir < TF_DIR_MAX; dir++) {
+ for (type = 0; type < CFA_TCAM_MGR_TBL_TYPE_MAX; type++) {
+ if (cfa_tcam_mgr_tables[sess_idx][dir][type].row_width >
+ max_row_width)
+ max_row_width =
+ cfa_tcam_mgr_tables[sess_idx][dir][type].row_width;
+ if (cfa_tcam_mgr_tables[sess_idx][dir][type].result_size >
+ max_result_size)
+ max_result_size =
+ cfa_tcam_mgr_tables[sess_idx][dir][type].result_size;
+ }
+ }
+
+ if (max_row_width != MAX_ROW_WIDTH) {
+ CFA_TCAM_MGR_LOG(ERR,
+ "MAX_ROW_WIDTH (%d) does not match actual "
+ "value (%d).\n",
+ MAX_ROW_WIDTH,
+ max_row_width);
+ return -CFA_TCAM_MGR_ERR_CODE(INVAL);
+ }
+ if (max_result_size != MAX_RESULT_SIZE) {
+ CFA_TCAM_MGR_LOG(ERR,
+ "MAX_RESULT_SIZE (%d) does not match actual "
+ "value (%d).\n",
+ MAX_RESULT_SIZE,
+ max_result_size);
+ return -CFA_TCAM_MGR_ERR_CODE(INVAL);
+ }
+ return 0;
+}
+
+/* HW OP declarations begin here */
+struct cfa_tcam_mgr_TCAM_row_data {
+ int key_size;
+ int result_size;
+ uint8_t key[MAX_ROW_WIDTH];
+ uint8_t mask[MAX_ROW_WIDTH];
+ uint8_t result[MAX_RESULT_SIZE];
+};
+
+/* These macros are only needed to avoid exceeding 80 columns */
+#define L2_CTXT_RX_MAX_ROWS \
+ (L2_CTXT_TCAM_RX_MAX_SLICES * L2_CTXT_TCAM_RX_NUM_ROWS)
+#define PROF_RX_MAX_ROWS (PROF_TCAM_RX_MAX_SLICES * PROF_TCAM_RX_NUM_ROWS)
+#define WC_RX_MAX_ROWS (WC_TCAM_RX_MAX_SLICES * WC_TCAM_RX_NUM_ROWS)
+#define SP_RX_MAX_ROWS (SP_TCAM_RX_MAX_SLICES * SP_TCAM_RX_NUM_ROWS)
+#define CT_RULE_RX_MAX_ROWS \
+ (CT_RULE_TCAM_RX_MAX_SLICES * CT_RULE_TCAM_RX_NUM_ROWS)
+#define VEB_RX_MAX_ROWS (VEB_TCAM_RX_MAX_SLICES * VEB_TCAM_RX_NUM_ROWS)
+
+#define L2_CTXT_TX_MAX_ROWS \
+ (L2_CTXT_TCAM_TX_MAX_SLICES * L2_CTXT_TCAM_TX_NUM_ROWS)
+#define PROF_TX_MAX_ROWS (PROF_TCAM_TX_MAX_SLICES * PROF_TCAM_TX_NUM_ROWS)
+#define WC_TX_MAX_ROWS (WC_TCAM_TX_MAX_SLICES * WC_TCAM_TX_NUM_ROWS)
+#define SP_TX_MAX_ROWS (SP_TCAM_TX_MAX_SLICES * SP_TCAM_TX_NUM_ROWS)
+#define CT_RULE_TX_MAX_ROWS \
+ (CT_RULE_TCAM_TX_MAX_SLICES * CT_RULE_TCAM_TX_NUM_ROWS)
+#define VEB_TX_MAX_ROWS (VEB_TCAM_TX_MAX_SLICES * VEB_TCAM_TX_NUM_ROWS)
+
+static int cfa_tcam_mgr_max_rows[TF_TCAM_TBL_TYPE_MAX] = {
+ L2_CTXT_RX_MAX_ROWS,
+ L2_CTXT_RX_MAX_ROWS,
+ PROF_RX_MAX_ROWS,
+ WC_RX_MAX_ROWS,
+ SP_RX_MAX_ROWS,
+ CT_RULE_RX_MAX_ROWS,
+ VEB_RX_MAX_ROWS,
+ WC_RX_MAX_ROWS,
+ WC_RX_MAX_ROWS
+};
+static struct cfa_tcam_mgr_TCAM_row_data
+ cfa_tcam_mgr_L2_CTXT_TCAM_RX_row_data[TF_TCAM_MAX_SESSIONS][L2_CTXT_RX_MAX_ROWS];
+static struct cfa_tcam_mgr_TCAM_row_data
+ cfa_tcam_mgr_PROF_TCAM_RX_row_data[TF_TCAM_MAX_SESSIONS][PROF_RX_MAX_ROWS];
+static struct cfa_tcam_mgr_TCAM_row_data
+ cfa_tcam_mgr_WC_TCAM_RX_row_data[TF_TCAM_MAX_SESSIONS][WC_RX_MAX_ROWS];
+static struct cfa_tcam_mgr_TCAM_row_data
+ cfa_tcam_mgr_SP_TCAM_RX_row_data[TF_TCAM_MAX_SESSIONS][SP_RX_MAX_ROWS];
+static struct cfa_tcam_mgr_TCAM_row_data
+ cfa_tcam_mgr_CT_RULE_TCAM_RX_row_data[TF_TCAM_MAX_SESSIONS][CT_RULE_RX_MAX_ROWS];
+static struct cfa_tcam_mgr_TCAM_row_data
+ cfa_tcam_mgr_VEB_TCAM_RX_row_data[TF_TCAM_MAX_SESSIONS][VEB_RX_MAX_ROWS];
+static struct cfa_tcam_mgr_TCAM_row_data
+ cfa_tcam_mgr_WC_TCAM_RX_row_data[TF_TCAM_MAX_SESSIONS][WC_RX_MAX_ROWS];
+
+static struct cfa_tcam_mgr_TCAM_row_data
+ cfa_tcam_mgr_L2_CTXT_TCAM_TX_row_data[TF_TCAM_MAX_SESSIONS][L2_CTXT_TX_MAX_ROWS];
+static struct cfa_tcam_mgr_TCAM_row_data
+ cfa_tcam_mgr_PROF_TCAM_TX_row_data[TF_TCAM_MAX_SESSIONS][PROF_TX_MAX_ROWS];
+static struct cfa_tcam_mgr_TCAM_row_data
+ cfa_tcam_mgr_WC_TCAM_TX_row_data[TF_TCAM_MAX_SESSIONS][WC_TX_MAX_ROWS];
+static struct cfa_tcam_mgr_TCAM_row_data
+ cfa_tcam_mgr_SP_TCAM_TX_row_data[TF_TCAM_MAX_SESSIONS][SP_TX_MAX_ROWS];
+static struct cfa_tcam_mgr_TCAM_row_data
+ cfa_tcam_mgr_CT_RULE_TCAM_TX_row_data[TF_TCAM_MAX_SESSIONS][CT_RULE_TX_MAX_ROWS];
+static struct cfa_tcam_mgr_TCAM_row_data
+ cfa_tcam_mgr_VEB_TCAM_TX_row_data[TF_TCAM_MAX_SESSIONS][VEB_TX_MAX_ROWS];
+static struct cfa_tcam_mgr_TCAM_row_data
+ cfa_tcam_mgr_WC_TCAM_TX_row_data[TF_TCAM_MAX_SESSIONS][WC_TX_MAX_ROWS];
+
+static struct cfa_tcam_mgr_TCAM_row_data *
+row_tables[TF_DIR_MAX][TF_TCAM_TBL_TYPE_MAX] = {
+ {
+ cfa_tcam_mgr_L2_CTXT_TCAM_RX_row_data[0],
+ cfa_tcam_mgr_L2_CTXT_TCAM_RX_row_data[0],
+ cfa_tcam_mgr_PROF_TCAM_RX_row_data[0],
+ cfa_tcam_mgr_WC_TCAM_RX_row_data[0],
+ cfa_tcam_mgr_SP_TCAM_RX_row_data[0],
+ cfa_tcam_mgr_CT_RULE_TCAM_RX_row_data[0],
+ cfa_tcam_mgr_VEB_TCAM_RX_row_data[0],
+ cfa_tcam_mgr_WC_TCAM_RX_row_data[0],
+ cfa_tcam_mgr_WC_TCAM_RX_row_data[0],
+ },
+ {
+ cfa_tcam_mgr_L2_CTXT_TCAM_TX_row_data[0],
+ cfa_tcam_mgr_L2_CTXT_TCAM_TX_row_data[0],
+ cfa_tcam_mgr_PROF_TCAM_TX_row_data[0],
+ cfa_tcam_mgr_WC_TCAM_TX_row_data[0],
+ cfa_tcam_mgr_SP_TCAM_TX_row_data[0],
+ cfa_tcam_mgr_CT_RULE_TCAM_TX_row_data[0],
+ cfa_tcam_mgr_VEB_TCAM_TX_row_data[0],
+ cfa_tcam_mgr_WC_TCAM_TX_row_data[0],
+ cfa_tcam_mgr_WC_TCAM_TX_row_data[0],
+ }
+};
+
+static int cfa_tcam_mgr_get_max_rows(enum tf_tcam_tbl_type type)
+{
+ if (type >= TF_TCAM_TBL_TYPE_MAX)
+ assert(0);
+ else
+ return cfa_tcam_mgr_max_rows[type];
+}
+
+static int cfa_tcam_mgr_hwop_set(int sess_idx,
+ struct cfa_tcam_mgr_set_parms *parms, int row,
+ int slice, int max_slices)
+{
+ struct cfa_tcam_mgr_TCAM_row_data *this_table;
+ struct cfa_tcam_mgr_TCAM_row_data *this_row;
+ this_table = row_tables[parms->dir]
+ [cfa_tcam_mgr_get_phys_table_type(parms->type)];
+ this_table += (sess_idx *
+ cfa_tcam_mgr_get_max_rows(cfa_tcam_mgr_get_phys_table_type(parms->type)));
+ this_row = &this_table[row * max_slices + slice];
+ this_row->key_size = parms->key_size;
+ memcpy(&this_row->key, parms->key, parms->key_size);
+ memcpy(&this_row->mask, parms->mask, parms->key_size);
+ this_row->result_size = parms->result_size;
+ if (parms->result != ((void *)0))
+ memcpy(&this_row->result, parms->result, parms->result_size);
+ return 0;
+};
+
+static int cfa_tcam_mgr_hwop_get(int sess_idx,
+ struct cfa_tcam_mgr_get_parms *parms, int row,
+ int slice, int max_slices)
+{
+ struct cfa_tcam_mgr_TCAM_row_data *this_table;
+ struct cfa_tcam_mgr_TCAM_row_data *this_row;
+ this_table = row_tables[parms->dir]
+ [cfa_tcam_mgr_get_phys_table_type(parms->type)];
+ this_table += (sess_idx *
+ cfa_tcam_mgr_get_max_rows(cfa_tcam_mgr_get_phys_table_type(parms->type)));
+ this_row = &this_table[row * max_slices + slice];
+ parms->key_size = this_row->key_size;
+ parms->result_size = this_row->result_size;
+ if (parms->key != ((void *)0))
+ memcpy(parms->key, &this_row->key, parms->key_size);
+ if (parms->mask != ((void *)0))
+ memcpy(parms->mask, &this_row->mask, parms->key_size);
+ if (parms->result != ((void *)0))
+ memcpy(parms->result, &this_row->result, parms->result_size);
+ return 0;
+};
+
+static int cfa_tcam_mgr_hwop_free(int sess_idx,
+ struct cfa_tcam_mgr_free_parms *parms,
+ int row, int slice, int max_slices)
+{
+ struct cfa_tcam_mgr_TCAM_row_data *this_table;
+ struct cfa_tcam_mgr_TCAM_row_data *this_row;
+ this_table = row_tables[parms->dir]
+ [cfa_tcam_mgr_get_phys_table_type(parms->type)];
+ this_table += (sess_idx *
+ cfa_tcam_mgr_get_max_rows(cfa_tcam_mgr_get_phys_table_type(parms->type)));
+ this_row = &this_table[row * max_slices + slice];
+ memset(&this_row->key, 0, sizeof(this_row->key));
+ memset(&this_row->mask, 0, sizeof(this_row->mask));
+ memset(&this_row->result, 0, sizeof(this_row->result));
+ this_row->key_size = 0;
+ this_row->result_size = 0;
+ return 0;
+};
+
+int cfa_tcam_mgr_hwops_get_funcs_p4(struct cfa_tcam_mgr_hwops_funcs *hwop_funcs)
+{
+ hwop_funcs->set = cfa_tcam_mgr_hwop_set;
+ hwop_funcs->get = cfa_tcam_mgr_hwop_get;
+ hwop_funcs->free = cfa_tcam_mgr_hwop_free;
+ return 0;
+}
diff --git a/drivers/net/bnxt/tf_core/cfa_tcam_mgr_p4.h b/drivers/net/bnxt/tf_core/cfa_tcam_mgr_p4.h
new file mode 100644
index 0000000000..3ca59b2aeb
--- /dev/null
+++ b/drivers/net/bnxt/tf_core/cfa_tcam_mgr_p4.h
@@ -0,0 +1,20 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2021-2023 Broadcom
+ * All rights reserved.
+ */
+
+#ifndef CFA_TCAM_MGR_P4_H
+#define CFA_TCAM_MGR_P4_H
+
+#include "cfa_tcam_mgr_device.h"
+#include "cfa_tcam_mgr_sbmp.h"
+
+int
+cfa_tcam_mgr_init_p4(int sess_idx, struct cfa_tcam_mgr_entry_data **global_entry_data);
+
+int
+cfa_tcam_mgr_sess_table_get_p4(int sess_idx, struct sbmp **session_bmp);
+
+int
+cfa_tcam_mgr_hwops_get_funcs_p4(struct cfa_tcam_mgr_hwops_funcs *hwop_funcs);
+#endif /* CFA_TCAM_MGR_P4_H */
diff --git a/drivers/net/bnxt/tf_core/cfa_tcam_mgr_p58.c b/drivers/net/bnxt/tf_core/cfa_tcam_mgr_p58.c
new file mode 100644
index 0000000000..c9a04dc4e9
--- /dev/null
+++ b/drivers/net/bnxt/tf_core/cfa_tcam_mgr_p58.c
@@ -0,0 +1,926 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2021-2023 Broadcom
+ * All rights reserved.
+ */
+
+#include "hcapi_cfa_defs.h"
+
+#include "cfa_tcam_mgr.h"
+#include "cfa_tcam_mgr_p58.h"
+#include "cfa_tcam_mgr.h"
+#include "cfa_tcam_mgr_device.h"
+#include "cfa_resource_types.h"
+#include "tfp.h"
+#include "assert.h"
+#include "tf_util.h"
+
+/*
+ * Sizings of the TCAMs on P5
+ */
+
+#define MAX_ROW_WIDTH 96
+#define MAX_RESULT_SIZE 8
+
+#if MAX_ROW_WIDTH > CFA_TCAM_MGR_MAX_KEY_SIZE
+#error MAX_ROW_WIDTH > CFA_TCAM_MGR_MAX_KEY_SIZE
+#endif
+
+/*
+ * TCAM definitions
+ *
+ * These define the TCAMs in HW.
+ *
+ * Note: Set xxx_TCAM_[R|T]X_NUM_ROWS to zero if a TCAM is either not supported
+ * by HW or not supported by TCAM Manager.
+ */
+
+/** L2 Context TCAM */
+#define L2_CTXT_TCAM_RX_MAX_SLICES 1
+#define L2_CTXT_TCAM_RX_ROW_WIDTH TF_BITS2BYTES_64B_WORD_ALIGN(214)
+#define L2_CTXT_TCAM_RX_NUM_ROWS 1024
+#define L2_CTXT_TCAM_RX_MAX_ENTRIES (L2_CTXT_TCAM_RX_MAX_SLICES * \
+ L2_CTXT_TCAM_RX_NUM_ROWS)
+#define L2_CTXT_TCAM_RX_RESULT_SIZE 8
+
+#define L2_CTXT_TCAM_TX_MAX_SLICES L2_CTXT_TCAM_RX_MAX_SLICES
+#define L2_CTXT_TCAM_TX_ROW_WIDTH L2_CTXT_TCAM_RX_ROW_WIDTH
+#define L2_CTXT_TCAM_TX_NUM_ROWS L2_CTXT_TCAM_RX_NUM_ROWS
+#define L2_CTXT_TCAM_TX_MAX_ENTRIES L2_CTXT_TCAM_RX_MAX_ENTRIES
+#define L2_CTXT_TCAM_TX_RESULT_SIZE L2_CTXT_TCAM_RX_RESULT_SIZE
+
+/** Profile TCAM */
+#define PROF_TCAM_RX_MAX_SLICES 1
+#define PROF_TCAM_RX_ROW_WIDTH TF_BITS2BYTES_64B_WORD_ALIGN(94)
+#define PROF_TCAM_RX_NUM_ROWS 256
+#define PROF_TCAM_RX_MAX_ENTRIES (PROF_TCAM_RX_MAX_SLICES * \
+ PROF_TCAM_RX_NUM_ROWS)
+#define PROF_TCAM_RX_RESULT_SIZE 8
+
+#define PROF_TCAM_TX_MAX_SLICES PROF_TCAM_RX_MAX_SLICES
+#define PROF_TCAM_TX_ROW_WIDTH PROF_TCAM_RX_ROW_WIDTH
+#define PROF_TCAM_TX_NUM_ROWS PROF_TCAM_RX_NUM_ROWS
+#define PROF_TCAM_TX_MAX_ENTRIES PROF_TCAM_RX_MAX_ENTRIES
+#define PROF_TCAM_TX_RESULT_SIZE PROF_TCAM_RX_RESULT_SIZE
+
+/** Wildcard TCAM */
+#define WC_TCAM_RX_MAX_SLICES 4
+/* 162 bits per slice */
+#define WC_TCAM_RX_ROW_WIDTH (TF_BITS2BYTES_64B_WORD_ALIGN(162) * \
+ WC_TCAM_RX_MAX_SLICES)
+#define WC_TCAM_RX_NUM_ROWS 2048
+#define WC_TCAM_RX_MAX_ENTRIES (WC_TCAM_RX_MAX_SLICES * WC_TCAM_RX_NUM_ROWS)
+#define WC_TCAM_RX_RESULT_SIZE 8
+
+#define WC_TCAM_TX_MAX_SLICES WC_TCAM_RX_MAX_SLICES
+#define WC_TCAM_TX_ROW_WIDTH WC_TCAM_RX_ROW_WIDTH
+#define WC_TCAM_TX_NUM_ROWS WC_TCAM_RX_NUM_ROWS
+#define WC_TCAM_TX_MAX_ENTRIES WC_TCAM_RX_MAX_ENTRIES
+#define WC_TCAM_TX_RESULT_SIZE WC_TCAM_RX_RESULT_SIZE
+
+/** Source Properties TCAM */
+#define SP_TCAM_RX_MAX_SLICES 1
+#define SP_TCAM_RX_ROW_WIDTH TF_BITS2BYTES_64B_WORD_ALIGN(89)
+#define SP_TCAM_RX_NUM_ROWS 0
+#define SP_TCAM_RX_MAX_ENTRIES (SP_TCAM_RX_MAX_SLICES * SP_TCAM_RX_NUM_ROWS)
+#define SP_TCAM_RX_RESULT_SIZE 8
+
+#define SP_TCAM_TX_MAX_SLICES SP_TCAM_RX_MAX_SLICES
+#define SP_TCAM_TX_ROW_WIDTH SP_TCAM_RX_ROW_WIDTH
+#define SP_TCAM_TX_NUM_ROWS SP_TCAM_RX_NUM_ROWS
+#define SP_TCAM_TX_MAX_ENTRIES SP_TCAM_RX_MAX_ENTRIES
+#define SP_TCAM_TX_RESULT_SIZE SP_TCAM_RX_RESULT_SIZE
+
+/** Connection Tracking Rule TCAM */
+#define CT_RULE_TCAM_RX_MAX_SLICES 1
+#define CT_RULE_TCAM_RX_ROW_WIDTH TF_BITS2BYTES_64B_WORD_ALIGN(16)
+#define CT_RULE_TCAM_RX_NUM_ROWS 0
+#define CT_RULE_TCAM_RX_MAX_ENTRIES (CT_RULE_TCAM_RX_MAX_SLICES * \
+ CT_RULE_TCAM_RX_NUM_ROWS)
+#define CT_RULE_TCAM_RX_RESULT_SIZE 8
+
+#define CT_RULE_TCAM_TX_MAX_SLICES CT_RULE_TCAM_RX_MAX_SLICES
+#define CT_RULE_TCAM_TX_ROW_WIDTH CT_RULE_TCAM_RX_ROW_WIDTH
+#define CT_RULE_TCAM_TX_NUM_ROWS CT_RULE_TCAM_RX_NUM_ROWS
+#define CT_RULE_TCAM_TX_MAX_ENTRIES CT_RULE_TCAM_RX_MAX_ENTRIES
+#define CT_RULE_TCAM_TX_RESULT_SIZE CT_RULE_TCAM_RX_RESULT_SIZE
+
+/** Virtual Edge Bridge TCAM */
+#define VEB_TCAM_RX_MAX_SLICES 1
+#define VEB_TCAM_RX_ROW_WIDTH TF_BITS2BYTES_WORD_ALIGN(79)
+/* Tx only */
+#define VEB_TCAM_RX_NUM_ROWS 0
+#define VEB_TCAM_RX_MAX_ENTRIES (VEB_TCAM_RX_MAX_SLICES * VEB_TCAM_RX_NUM_ROWS)
+#define VEB_TCAM_RX_RESULT_SIZE 8
+
+#define VEB_TCAM_TX_MAX_SLICES VEB_TCAM_RX_MAX_SLICES
+#define VEB_TCAM_TX_ROW_WIDTH VEB_TCAM_RX_ROW_WIDTH
+#define VEB_TCAM_TX_NUM_ROWS 1024
+#define VEB_TCAM_TX_MAX_ENTRIES (VEB_TCAM_TX_MAX_SLICES * VEB_TCAM_TX_NUM_ROWS)
+#define VEB_TCAM_TX_RESULT_SIZE VEB_TCAM_RX_RESULT_SIZE
+
+/* Declare the table rows for each table here. If new tables are added to the
+ * enum tf_tcam_tbl_type, then new declarations will be needed here.
+ *
+ * The numeric suffix of the structure type indicates how many slices a
+ * particular TCAM supports.
+ *
+ * Array sizes have 1 added to avoid zero length arrays.
+ */
+
+static struct cfa_tcam_mgr_table_rows_1
+ cfa_tcam_mgr_table_rows_L2_CTXT_TCAM_RX[TF_TCAM_MAX_SESSIONS][L2_CTXT_TCAM_RX_NUM_ROWS + 1];
+static struct cfa_tcam_mgr_table_rows_1
+ cfa_tcam_mgr_table_rows_L2_CTXT_TCAM_TX[TF_TCAM_MAX_SESSIONS][L2_CTXT_TCAM_TX_NUM_ROWS + 1];
+static struct cfa_tcam_mgr_table_rows_1
+ cfa_tcam_mgr_table_rows_PROF_TCAM_RX[TF_TCAM_MAX_SESSIONS][PROF_TCAM_RX_NUM_ROWS + 1];
+static struct cfa_tcam_mgr_table_rows_1
+ cfa_tcam_mgr_table_rows_PROF_TCAM_TX[TF_TCAM_MAX_SESSIONS][PROF_TCAM_TX_NUM_ROWS + 1];
+static struct cfa_tcam_mgr_table_rows_4
+ cfa_tcam_mgr_table_rows_WC_TCAM_RX[TF_TCAM_MAX_SESSIONS][WC_TCAM_RX_NUM_ROWS + 1];
+static struct cfa_tcam_mgr_table_rows_4
+ cfa_tcam_mgr_table_rows_WC_TCAM_TX[TF_TCAM_MAX_SESSIONS][WC_TCAM_TX_NUM_ROWS + 1];
+static struct cfa_tcam_mgr_table_rows_1
+ cfa_tcam_mgr_table_rows_SP_TCAM_RX[TF_TCAM_MAX_SESSIONS][SP_TCAM_RX_NUM_ROWS + 1];
+static struct cfa_tcam_mgr_table_rows_1
+ cfa_tcam_mgr_table_rows_SP_TCAM_TX[TF_TCAM_MAX_SESSIONS][SP_TCAM_TX_NUM_ROWS + 1];
+static struct cfa_tcam_mgr_table_rows_1
+ cfa_tcam_mgr_table_rows_CT_RULE_TCAM_RX[TF_TCAM_MAX_SESSIONS][CT_RULE_TCAM_RX_NUM_ROWS + 1];
+static struct cfa_tcam_mgr_table_rows_1
+ cfa_tcam_mgr_table_rows_CT_RULE_TCAM_TX[TF_TCAM_MAX_SESSIONS][CT_RULE_TCAM_TX_NUM_ROWS + 1];
+static struct cfa_tcam_mgr_table_rows_1
+ cfa_tcam_mgr_table_rows_VEB_TCAM_RX[TF_TCAM_MAX_SESSIONS][VEB_TCAM_RX_NUM_ROWS + 1];
+static struct cfa_tcam_mgr_table_rows_1
+ cfa_tcam_mgr_table_rows_VEB_TCAM_TX[TF_TCAM_MAX_SESSIONS][VEB_TCAM_TX_NUM_ROWS + 1];
+static struct cfa_tcam_mgr_table_rows_4
+ cfa_tcam_mgr_table_rows_WC_TCAM_RX_HIGH[TF_TCAM_MAX_SESSIONS][WC_TCAM_RX_NUM_ROWS + 1];
+static struct cfa_tcam_mgr_table_rows_4
+ cfa_tcam_mgr_table_rows_WC_TCAM_RX_LOW[TF_TCAM_MAX_SESSIONS][WC_TCAM_RX_NUM_ROWS + 1];
+static struct cfa_tcam_mgr_table_rows_4
+ cfa_tcam_mgr_table_rows_WC_TCAM_TX_HIGH[TF_TCAM_MAX_SESSIONS][WC_TCAM_TX_NUM_ROWS + 1];
+static struct cfa_tcam_mgr_table_rows_4
+ cfa_tcam_mgr_table_rows_WC_TCAM_TX_LOW[TF_TCAM_MAX_SESSIONS][WC_TCAM_TX_NUM_ROWS + 1];
+
+struct cfa_tcam_mgr_table_data
+cfa_tcam_mgr_tables_p58[TF_DIR_MAX][CFA_TCAM_MGR_TBL_TYPE_MAX] = {
+ { /* RX */
+ { /* High AFM */
+ .max_slices = L2_CTXT_TCAM_RX_MAX_SLICES,
+ .row_width = L2_CTXT_TCAM_RX_ROW_WIDTH,
+ .num_rows = 0,
+ .start_row = 0,
+ .end_row = 0,
+ .max_entries = 0,
+ .result_size = L2_CTXT_TCAM_RX_RESULT_SIZE,
+ .hcapi_type = CFA_RESOURCE_TYPE_P58_L2_CTXT_TCAM_HIGH,
+ },
+ { /* High APPS */
+ .max_slices = L2_CTXT_TCAM_RX_MAX_SLICES,
+ .row_width = L2_CTXT_TCAM_RX_ROW_WIDTH,
+ .num_rows = L2_CTXT_TCAM_RX_NUM_ROWS,
+ .start_row = 0,
+ .end_row = (L2_CTXT_TCAM_RX_NUM_ROWS / 2) - 1,
+ .max_entries = (L2_CTXT_TCAM_RX_MAX_ENTRIES / 2),
+ .result_size = L2_CTXT_TCAM_RX_RESULT_SIZE,
+ .hcapi_type = CFA_RESOURCE_TYPE_P58_L2_CTXT_TCAM_HIGH,
+ },
+ { /* Low AFM */
+ .max_slices = L2_CTXT_TCAM_RX_MAX_SLICES,
+ .row_width = L2_CTXT_TCAM_RX_ROW_WIDTH,
+ .num_rows = 0,
+ .start_row = 0,
+ .end_row = 0,
+ .max_entries = 0,
+ .result_size = L2_CTXT_TCAM_RX_RESULT_SIZE,
+ .hcapi_type = CFA_RESOURCE_TYPE_P58_L2_CTXT_TCAM_LOW,
+ },
+ { /* Low APPS */
+ .max_slices = L2_CTXT_TCAM_RX_MAX_SLICES,
+ .row_width = L2_CTXT_TCAM_RX_ROW_WIDTH,
+ .num_rows = L2_CTXT_TCAM_RX_NUM_ROWS,
+ .start_row = (L2_CTXT_TCAM_RX_NUM_ROWS / 2),
+ .end_row = L2_CTXT_TCAM_RX_NUM_ROWS - 1,
+ .max_entries = (L2_CTXT_TCAM_RX_MAX_ENTRIES / 2),
+ .result_size = L2_CTXT_TCAM_RX_RESULT_SIZE,
+ .hcapi_type = CFA_RESOURCE_TYPE_P58_L2_CTXT_TCAM_LOW,
+ },
+ { /* AFM */
+ .max_slices = PROF_TCAM_RX_MAX_SLICES,
+ .row_width = PROF_TCAM_RX_ROW_WIDTH,
+ .num_rows = 0,
+ .start_row = 0,
+ .end_row = 0,
+ .max_entries = 0,
+ .result_size = PROF_TCAM_RX_RESULT_SIZE,
+ .hcapi_type = CFA_RESOURCE_TYPE_P58_PROF_TCAM,
+ },
+ { /* APPS */
+ .max_slices = PROF_TCAM_RX_MAX_SLICES,
+ .row_width = PROF_TCAM_RX_ROW_WIDTH,
+ .num_rows = PROF_TCAM_RX_NUM_ROWS,
+ .start_row = 0,
+ .end_row = PROF_TCAM_RX_NUM_ROWS - 1,
+ .max_entries = PROF_TCAM_RX_MAX_ENTRIES,
+ .result_size = PROF_TCAM_RX_RESULT_SIZE,
+ .hcapi_type = CFA_RESOURCE_TYPE_P58_PROF_TCAM,
+ },
+ { /* AFM */
+ .max_slices = WC_TCAM_RX_MAX_SLICES,
+ .row_width = WC_TCAM_RX_ROW_WIDTH,
+ .num_rows = WC_TCAM_RX_NUM_ROWS,
+ .start_row = 0,
+ .end_row = 0,
+ .max_entries = 0,
+ .result_size = WC_TCAM_RX_RESULT_SIZE,
+ .hcapi_type = CFA_RESOURCE_TYPE_P58_WC_TCAM,
+ },
+ { /* APPS */
+ .max_slices = WC_TCAM_RX_MAX_SLICES,
+ .row_width = WC_TCAM_RX_ROW_WIDTH,
+ .num_rows = WC_TCAM_RX_NUM_ROWS,
+ .start_row = 0,
+ .end_row = WC_TCAM_RX_NUM_ROWS - 1,
+ .max_entries = WC_TCAM_RX_MAX_ENTRIES,
+ .result_size = WC_TCAM_RX_RESULT_SIZE,
+ .hcapi_type = CFA_RESOURCE_TYPE_P58_WC_TCAM,
+ },
+ { /* AFM */
+ .max_slices = SP_TCAM_RX_MAX_SLICES,
+ .row_width = SP_TCAM_RX_ROW_WIDTH,
+ .num_rows = 0,
+ .start_row = 0,
+ .end_row = 0,
+ .max_entries = 0,
+ .result_size = SP_TCAM_RX_RESULT_SIZE,
+ },
+ { /* APPS */
+ .max_slices = SP_TCAM_RX_MAX_SLICES,
+ .row_width = SP_TCAM_RX_ROW_WIDTH,
+ .num_rows = SP_TCAM_RX_NUM_ROWS,
+ .start_row = 0,
+ .end_row = SP_TCAM_RX_NUM_ROWS - 1,
+ .max_entries = SP_TCAM_RX_MAX_ENTRIES,
+ .result_size = SP_TCAM_RX_RESULT_SIZE,
+ },
+ { /* AFM */
+ .max_slices = CT_RULE_TCAM_RX_MAX_SLICES,
+ .row_width = CT_RULE_TCAM_RX_ROW_WIDTH,
+ .num_rows = CT_RULE_TCAM_RX_NUM_ROWS,
+ .start_row = 0,
+ .end_row = 0,
+ .max_entries = 0,
+ .result_size = CT_RULE_TCAM_RX_RESULT_SIZE,
+ },
+ { /* APPS */
+ .max_slices = CT_RULE_TCAM_RX_MAX_SLICES,
+ .row_width = CT_RULE_TCAM_RX_ROW_WIDTH,
+ .num_rows = CT_RULE_TCAM_RX_NUM_ROWS,
+ .start_row = 0,
+#if CT_RULE_TCAM_RX_NUM_ROWS > 0
+ .end_row = CT_RULE_TCAM_RX_NUM_ROWS - 1,
+#else
+ .end_row = CT_RULE_TCAM_RX_NUM_ROWS,
+#endif
+ .max_entries = CT_RULE_TCAM_RX_MAX_ENTRIES,
+ .result_size = CT_RULE_TCAM_RX_RESULT_SIZE,
+ },
+ { /* AFM */
+ .max_slices = VEB_TCAM_RX_MAX_SLICES,
+ .row_width = VEB_TCAM_RX_ROW_WIDTH,
+ .num_rows = VEB_TCAM_RX_NUM_ROWS,
+ .start_row = 0,
+ .end_row = 0,
+ .max_entries = 0,
+ .result_size = VEB_TCAM_RX_RESULT_SIZE,
+ .hcapi_type = CFA_RESOURCE_TYPE_P58_VEB_TCAM,
+ },
+ { /* APPS */
+ .max_slices = VEB_TCAM_RX_MAX_SLICES,
+ .row_width = VEB_TCAM_RX_ROW_WIDTH,
+ .num_rows = VEB_TCAM_RX_NUM_ROWS,
+ .start_row = 0,
+#if VEB_TCAM_RX_NUM_ROWS > 0
+ .end_row = VEB_TCAM_RX_NUM_ROWS - 1,
+#else
+ .end_row = VEB_TCAM_RX_NUM_ROWS,
+#endif
+ .max_entries = VEB_TCAM_RX_MAX_ENTRIES,
+ .result_size = VEB_TCAM_RX_RESULT_SIZE,
+ .hcapi_type = CFA_RESOURCE_TYPE_P58_VEB_TCAM,
+ },
+ { /* AFM */
+ .max_slices = WC_TCAM_RX_MAX_SLICES,
+ .row_width = WC_TCAM_RX_ROW_WIDTH,
+ .num_rows = WC_TCAM_RX_NUM_ROWS,
+ .start_row = 0,
+ .end_row = 0,
+ .max_entries = 0,
+ .result_size = WC_TCAM_RX_RESULT_SIZE,
+ .hcapi_type = CFA_RESOURCE_TYPE_P58_WC_TCAM,
+ },
+ { /* APPS */
+ .max_slices = WC_TCAM_RX_MAX_SLICES,
+ .row_width = WC_TCAM_RX_ROW_WIDTH,
+ .num_rows = WC_TCAM_RX_NUM_ROWS,
+ .start_row = 0,
+ .end_row = WC_TCAM_RX_NUM_ROWS - 1,
+ .max_entries = WC_TCAM_RX_MAX_ENTRIES,
+ .result_size = WC_TCAM_RX_RESULT_SIZE,
+ .hcapi_type = CFA_RESOURCE_TYPE_P58_WC_TCAM,
+ },
+ { /* AFM */
+ .max_slices = WC_TCAM_RX_MAX_SLICES,
+ .row_width = WC_TCAM_RX_ROW_WIDTH,
+ .num_rows = WC_TCAM_RX_NUM_ROWS,
+ .start_row = 0,
+ .end_row = 0,
+ .max_entries = 0,
+ .result_size = WC_TCAM_RX_RESULT_SIZE,
+ .hcapi_type = CFA_RESOURCE_TYPE_P58_WC_TCAM,
+ },
+ { /* APPS */
+ .max_slices = WC_TCAM_RX_MAX_SLICES,
+ .row_width = WC_TCAM_RX_ROW_WIDTH,
+ .num_rows = WC_TCAM_RX_NUM_ROWS,
+ .start_row = 0,
+ .end_row = WC_TCAM_RX_NUM_ROWS - 1,
+ .max_entries = WC_TCAM_RX_MAX_ENTRIES,
+ .result_size = WC_TCAM_RX_RESULT_SIZE,
+ .hcapi_type = CFA_RESOURCE_TYPE_P58_WC_TCAM,
+ },
+ },
+ { /* TX */
+ { /* AFM */
+ .max_slices = L2_CTXT_TCAM_TX_MAX_SLICES,
+ .row_width = L2_CTXT_TCAM_TX_ROW_WIDTH,
+ .num_rows = L2_CTXT_TCAM_TX_NUM_ROWS,
+ .start_row = 0,
+ .end_row = 0,
+ .max_entries = 0,
+ .result_size = L2_CTXT_TCAM_TX_RESULT_SIZE,
+ .hcapi_type = CFA_RESOURCE_TYPE_P58_L2_CTXT_TCAM_HIGH,
+ },
+ { /* APPS */
+ .max_slices = L2_CTXT_TCAM_TX_MAX_SLICES,
+ .row_width = L2_CTXT_TCAM_TX_ROW_WIDTH,
+ .num_rows = L2_CTXT_TCAM_TX_NUM_ROWS,
+ .start_row = 0,
+ .end_row = (L2_CTXT_TCAM_TX_NUM_ROWS / 2) - 1,
+ .max_entries = (L2_CTXT_TCAM_TX_MAX_ENTRIES / 2),
+ .result_size = L2_CTXT_TCAM_TX_RESULT_SIZE,
+ .hcapi_type = CFA_RESOURCE_TYPE_P58_L2_CTXT_TCAM_HIGH,
+ },
+ { /* AFM */
+ .max_slices = L2_CTXT_TCAM_TX_MAX_SLICES,
+ .row_width = L2_CTXT_TCAM_TX_ROW_WIDTH,
+ .num_rows = L2_CTXT_TCAM_TX_NUM_ROWS,
+ .start_row = 0,
+ .end_row = 0,
+ .max_entries = 0,
+ .result_size = L2_CTXT_TCAM_TX_RESULT_SIZE,
+ .hcapi_type = CFA_RESOURCE_TYPE_P58_L2_CTXT_TCAM_LOW,
+ },
+ { /* APPS */
+ .max_slices = L2_CTXT_TCAM_TX_MAX_SLICES,
+ .row_width = L2_CTXT_TCAM_TX_ROW_WIDTH,
+ .num_rows = L2_CTXT_TCAM_TX_NUM_ROWS,
+ .start_row = (L2_CTXT_TCAM_TX_NUM_ROWS / 2),
+ .end_row = L2_CTXT_TCAM_TX_NUM_ROWS - 1,
+ .max_entries = (L2_CTXT_TCAM_TX_MAX_ENTRIES / 2),
+ .result_size = L2_CTXT_TCAM_TX_RESULT_SIZE,
+ .hcapi_type = CFA_RESOURCE_TYPE_P58_L2_CTXT_TCAM_LOW,
+ },
+ { /* AFM */
+ .max_slices = PROF_TCAM_TX_MAX_SLICES,
+ .row_width = PROF_TCAM_TX_ROW_WIDTH,
+ .num_rows = PROF_TCAM_TX_NUM_ROWS,
+ .start_row = 0,
+ .end_row = 0,
+ .max_entries = 0,
+ .result_size = PROF_TCAM_TX_RESULT_SIZE,
+ .hcapi_type = CFA_RESOURCE_TYPE_P58_PROF_TCAM,
+ },
+ { /* APPS */
+ .max_slices = PROF_TCAM_TX_MAX_SLICES,
+ .row_width = PROF_TCAM_TX_ROW_WIDTH,
+ .num_rows = PROF_TCAM_TX_NUM_ROWS,
+ .start_row = 0,
+ .end_row = PROF_TCAM_TX_NUM_ROWS - 1,
+ .max_entries = PROF_TCAM_TX_MAX_ENTRIES,
+ .result_size = PROF_TCAM_TX_RESULT_SIZE,
+ .hcapi_type = CFA_RESOURCE_TYPE_P58_PROF_TCAM,
+ },
+ { /* AFM */
+ .max_slices = WC_TCAM_TX_MAX_SLICES,
+ .row_width = WC_TCAM_TX_ROW_WIDTH,
+ .num_rows = WC_TCAM_TX_NUM_ROWS,
+ .start_row = 0,
+ .end_row = 0,
+ .max_entries = 0,
+ .result_size = WC_TCAM_TX_RESULT_SIZE,
+ .hcapi_type = CFA_RESOURCE_TYPE_P58_WC_TCAM,
+ },
+ { /* APPS */
+ .max_slices = WC_TCAM_TX_MAX_SLICES,
+ .row_width = WC_TCAM_TX_ROW_WIDTH,
+ .num_rows = WC_TCAM_TX_NUM_ROWS,
+ .start_row = 0,
+ .end_row = WC_TCAM_TX_NUM_ROWS - 1,
+ .max_entries = WC_TCAM_TX_MAX_ENTRIES,
+ .result_size = WC_TCAM_TX_RESULT_SIZE,
+ .hcapi_type = CFA_RESOURCE_TYPE_P58_WC_TCAM,
+ },
+ { /* AFM */
+ .max_slices = SP_TCAM_TX_MAX_SLICES,
+ .row_width = SP_TCAM_TX_ROW_WIDTH,
+ .num_rows = SP_TCAM_TX_NUM_ROWS,
+ .start_row = 0,
+ .end_row = 0,
+ .max_entries = 0,
+ .result_size = SP_TCAM_TX_RESULT_SIZE,
+ },
+ { /* APPS */
+ .max_slices = SP_TCAM_TX_MAX_SLICES,
+ .row_width = SP_TCAM_TX_ROW_WIDTH,
+ .num_rows = SP_TCAM_TX_NUM_ROWS,
+ .start_row = 0,
+ .end_row = SP_TCAM_TX_NUM_ROWS - 1,
+ .max_entries = SP_TCAM_TX_MAX_ENTRIES,
+ .result_size = SP_TCAM_TX_RESULT_SIZE,
+ },
+ { /* AFM */
+ .max_slices = CT_RULE_TCAM_TX_MAX_SLICES,
+ .row_width = CT_RULE_TCAM_TX_ROW_WIDTH,
+ .num_rows = CT_RULE_TCAM_TX_NUM_ROWS,
+ .start_row = 0,
+ .end_row = 0,
+ .max_entries = 0,
+ .result_size = CT_RULE_TCAM_RX_RESULT_SIZE,
+ },
+ { /* APPS */
+ .max_slices = CT_RULE_TCAM_TX_MAX_SLICES,
+ .row_width = CT_RULE_TCAM_TX_ROW_WIDTH,
+ .num_rows = CT_RULE_TCAM_TX_NUM_ROWS,
+ .start_row = 0,
+#if CT_RULE_TCAM_TX_NUM_ROWS > 0
+ .end_row = CT_RULE_TCAM_TX_NUM_ROWS - 1,
+#else
+ .end_row = CT_RULE_TCAM_TX_NUM_ROWS,
+#endif
+ .max_entries = CT_RULE_TCAM_TX_MAX_ENTRIES,
+ .result_size = CT_RULE_TCAM_RX_RESULT_SIZE,
+ },
+ { /* AFM */
+ .max_slices = VEB_TCAM_TX_MAX_SLICES,
+ .row_width = VEB_TCAM_TX_ROW_WIDTH,
+ .num_rows = VEB_TCAM_TX_NUM_ROWS,
+ .start_row = 0,
+ .end_row = 0,
+ .max_entries = 0,
+ .result_size = VEB_TCAM_RX_RESULT_SIZE,
+ .hcapi_type = CFA_RESOURCE_TYPE_P58_VEB_TCAM,
+ },
+ { /* APPS */
+ .max_slices = VEB_TCAM_TX_MAX_SLICES,
+ .row_width = VEB_TCAM_TX_ROW_WIDTH,
+ .num_rows = VEB_TCAM_TX_NUM_ROWS,
+ .start_row = 0,
+ .end_row = VEB_TCAM_TX_NUM_ROWS - 1,
+ .max_entries = VEB_TCAM_TX_MAX_ENTRIES,
+ .result_size = VEB_TCAM_RX_RESULT_SIZE,
+ .hcapi_type = CFA_RESOURCE_TYPE_P58_VEB_TCAM,
+ },
+ { /* AFM */
+ .max_slices = WC_TCAM_TX_MAX_SLICES,
+ .row_width = WC_TCAM_TX_ROW_WIDTH,
+ .num_rows = WC_TCAM_TX_NUM_ROWS,
+ .start_row = 0,
+ .end_row = 0,
+ .max_entries = 0,
+ .result_size = WC_TCAM_TX_RESULT_SIZE,
+ .hcapi_type = CFA_RESOURCE_TYPE_P58_WC_TCAM,
+ },
+ { /* APPS */
+ .max_slices = WC_TCAM_TX_MAX_SLICES,
+ .row_width = WC_TCAM_TX_ROW_WIDTH,
+ .num_rows = WC_TCAM_TX_NUM_ROWS,
+ .start_row = 0,
+ .end_row = WC_TCAM_TX_NUM_ROWS - 1,
+ .max_entries = WC_TCAM_TX_MAX_ENTRIES,
+ .result_size = WC_TCAM_TX_RESULT_SIZE,
+ .hcapi_type = CFA_RESOURCE_TYPE_P58_WC_TCAM,
+ },
+ { /* AFM */
+ .max_slices = WC_TCAM_TX_MAX_SLICES,
+ .row_width = WC_TCAM_TX_ROW_WIDTH,
+ .num_rows = WC_TCAM_TX_NUM_ROWS,
+ .start_row = 0,
+ .end_row = 0,
+ .max_entries = 0,
+ .result_size = WC_TCAM_TX_RESULT_SIZE,
+ .hcapi_type = CFA_RESOURCE_TYPE_P58_WC_TCAM,
+ },
+ { /* APPS */
+ .max_slices = WC_TCAM_TX_MAX_SLICES,
+ .row_width = WC_TCAM_TX_ROW_WIDTH,
+ .num_rows = WC_TCAM_TX_NUM_ROWS,
+ .start_row = 0,
+ .end_row = WC_TCAM_TX_NUM_ROWS - 1,
+ .max_entries = WC_TCAM_TX_MAX_ENTRIES,
+ .result_size = WC_TCAM_TX_RESULT_SIZE,
+ .hcapi_type = CFA_RESOURCE_TYPE_P58_WC_TCAM,
+ },
+ },
+};
+
+static struct cfa_tcam_mgr_entry_data entry_data_p58[TF_TCAM_MAX_SESSIONS][TF_TCAM_MAX_ENTRIES];
+
+static struct sbmp session_bmp_p58[TF_TCAM_MAX_SESSIONS][TF_TCAM_MAX_ENTRIES];
+
+int
+cfa_tcam_mgr_sess_table_get_p58(int sess_idx, struct sbmp **session_bmp)
+{
+ *session_bmp = session_bmp_p58[sess_idx];
+ return 0;
+}
+
+int
+cfa_tcam_mgr_init_p58(int sess_idx, struct cfa_tcam_mgr_entry_data **global_entry_data)
+{
+ int max_row_width = 0;
+ int max_result_size = 0;
+ int dir, type;
+
+ *global_entry_data = entry_data_p58[sess_idx];
+
+ memcpy(&cfa_tcam_mgr_tables[sess_idx],
+ &cfa_tcam_mgr_tables_p58,
+ sizeof(cfa_tcam_mgr_tables[sess_idx]));
+
+ cfa_tcam_mgr_tables[sess_idx][TF_DIR_RX]
+ [CFA_TCAM_MGR_TBL_TYPE_L2_CTXT_TCAM_HIGH_AFM].tcam_rows =
+ (struct cfa_tcam_mgr_table_rows_0 *)
+ &cfa_tcam_mgr_table_rows_L2_CTXT_TCAM_RX[sess_idx];
+ cfa_tcam_mgr_tables[sess_idx][TF_DIR_RX]
+ [CFA_TCAM_MGR_TBL_TYPE_L2_CTXT_TCAM_HIGH_APPS].tcam_rows =
+ (struct cfa_tcam_mgr_table_rows_0 *)
+ &cfa_tcam_mgr_table_rows_L2_CTXT_TCAM_RX[sess_idx];
+
+ cfa_tcam_mgr_tables[sess_idx][TF_DIR_TX]
+ [CFA_TCAM_MGR_TBL_TYPE_L2_CTXT_TCAM_HIGH_AFM].tcam_rows =
+ (struct cfa_tcam_mgr_table_rows_0 *)
+ &cfa_tcam_mgr_table_rows_L2_CTXT_TCAM_TX[sess_idx];
+ cfa_tcam_mgr_tables[sess_idx][TF_DIR_TX]
+ [CFA_TCAM_MGR_TBL_TYPE_L2_CTXT_TCAM_HIGH_APPS].tcam_rows =
+ (struct cfa_tcam_mgr_table_rows_0 *)
+ &cfa_tcam_mgr_table_rows_L2_CTXT_TCAM_TX[sess_idx];
+
+ cfa_tcam_mgr_tables[sess_idx][TF_DIR_RX]
+ [CFA_TCAM_MGR_TBL_TYPE_L2_CTXT_TCAM_LOW_AFM].tcam_rows =
+ (struct cfa_tcam_mgr_table_rows_0 *)
+ &cfa_tcam_mgr_table_rows_L2_CTXT_TCAM_RX[sess_idx];
+ cfa_tcam_mgr_tables[sess_idx][TF_DIR_RX]
+ [CFA_TCAM_MGR_TBL_TYPE_L2_CTXT_TCAM_LOW_APPS].tcam_rows =
+ (struct cfa_tcam_mgr_table_rows_0 *)
+ &cfa_tcam_mgr_table_rows_L2_CTXT_TCAM_RX[sess_idx];
+
+ cfa_tcam_mgr_tables[sess_idx][TF_DIR_TX]
+ [CFA_TCAM_MGR_TBL_TYPE_L2_CTXT_TCAM_LOW_AFM].tcam_rows =
+ (struct cfa_tcam_mgr_table_rows_0 *)
+ &cfa_tcam_mgr_table_rows_L2_CTXT_TCAM_TX[sess_idx];
+ cfa_tcam_mgr_tables[sess_idx][TF_DIR_TX]
+ [CFA_TCAM_MGR_TBL_TYPE_L2_CTXT_TCAM_LOW_APPS].tcam_rows =
+ (struct cfa_tcam_mgr_table_rows_0 *)
+ &cfa_tcam_mgr_table_rows_L2_CTXT_TCAM_TX[sess_idx];
+
+ cfa_tcam_mgr_tables[sess_idx][TF_DIR_RX]
+ [CFA_TCAM_MGR_TBL_TYPE_PROF_TCAM_AFM].tcam_rows =
+ (struct cfa_tcam_mgr_table_rows_0 *)
+ &cfa_tcam_mgr_table_rows_PROF_TCAM_RX[sess_idx];
+ cfa_tcam_mgr_tables[sess_idx][TF_DIR_RX]
+ [CFA_TCAM_MGR_TBL_TYPE_PROF_TCAM_APPS].tcam_rows =
+ (struct cfa_tcam_mgr_table_rows_0 *)
+ &cfa_tcam_mgr_table_rows_PROF_TCAM_RX[sess_idx];
+
+ cfa_tcam_mgr_tables[sess_idx][TF_DIR_TX]
+ [CFA_TCAM_MGR_TBL_TYPE_PROF_TCAM_AFM].tcam_rows =
+ (struct cfa_tcam_mgr_table_rows_0 *)
+ &cfa_tcam_mgr_table_rows_PROF_TCAM_TX[sess_idx];
+ cfa_tcam_mgr_tables[sess_idx][TF_DIR_TX]
+ [CFA_TCAM_MGR_TBL_TYPE_PROF_TCAM_APPS].tcam_rows =
+ (struct cfa_tcam_mgr_table_rows_0 *)
+ &cfa_tcam_mgr_table_rows_PROF_TCAM_TX[sess_idx];
+
+ cfa_tcam_mgr_tables[sess_idx][TF_DIR_RX]
+ [CFA_TCAM_MGR_TBL_TYPE_WC_TCAM_AFM].tcam_rows =
+ (struct cfa_tcam_mgr_table_rows_0 *)
+ &cfa_tcam_mgr_table_rows_WC_TCAM_RX[sess_idx];
+ cfa_tcam_mgr_tables[sess_idx][TF_DIR_RX]
+ [CFA_TCAM_MGR_TBL_TYPE_WC_TCAM_APPS].tcam_rows =
+ (struct cfa_tcam_mgr_table_rows_0 *)
+ &cfa_tcam_mgr_table_rows_WC_TCAM_RX[sess_idx];
+
+ cfa_tcam_mgr_tables[sess_idx][TF_DIR_TX]
+ [CFA_TCAM_MGR_TBL_TYPE_WC_TCAM_AFM].tcam_rows =
+ (struct cfa_tcam_mgr_table_rows_0 *)
+ &cfa_tcam_mgr_table_rows_WC_TCAM_TX[sess_idx];
+ cfa_tcam_mgr_tables[sess_idx][TF_DIR_TX]
+ [CFA_TCAM_MGR_TBL_TYPE_WC_TCAM_APPS].tcam_rows =
+ (struct cfa_tcam_mgr_table_rows_0 *)
+ &cfa_tcam_mgr_table_rows_WC_TCAM_TX[sess_idx];
+
+ cfa_tcam_mgr_tables[sess_idx][TF_DIR_RX]
+ [CFA_TCAM_MGR_TBL_TYPE_SP_TCAM_AFM].tcam_rows =
+ (struct cfa_tcam_mgr_table_rows_0 *)
+ &cfa_tcam_mgr_table_rows_SP_TCAM_RX[sess_idx];
+ cfa_tcam_mgr_tables[sess_idx][TF_DIR_RX]
+ [CFA_TCAM_MGR_TBL_TYPE_SP_TCAM_APPS].tcam_rows =
+ (struct cfa_tcam_mgr_table_rows_0 *)
+ &cfa_tcam_mgr_table_rows_SP_TCAM_RX[sess_idx];
+
+ cfa_tcam_mgr_tables[sess_idx][TF_DIR_TX]
+ [CFA_TCAM_MGR_TBL_TYPE_SP_TCAM_AFM].tcam_rows =
+ (struct cfa_tcam_mgr_table_rows_0 *)
+ &cfa_tcam_mgr_table_rows_SP_TCAM_TX[sess_idx];
+ cfa_tcam_mgr_tables[sess_idx][TF_DIR_TX]
+ [CFA_TCAM_MGR_TBL_TYPE_SP_TCAM_APPS].tcam_rows =
+ (struct cfa_tcam_mgr_table_rows_0 *)
+ &cfa_tcam_mgr_table_rows_SP_TCAM_TX[sess_idx];
+
+ cfa_tcam_mgr_tables[sess_idx][TF_DIR_RX]
+ [CFA_TCAM_MGR_TBL_TYPE_CT_RULE_TCAM_AFM].tcam_rows =
+ (struct cfa_tcam_mgr_table_rows_0 *)
+ &cfa_tcam_mgr_table_rows_CT_RULE_TCAM_RX[sess_idx];
+ cfa_tcam_mgr_tables[sess_idx][TF_DIR_RX]
+ [CFA_TCAM_MGR_TBL_TYPE_CT_RULE_TCAM_APPS].tcam_rows =
+ (struct cfa_tcam_mgr_table_rows_0 *)
+ &cfa_tcam_mgr_table_rows_CT_RULE_TCAM_RX[sess_idx];
+
+ cfa_tcam_mgr_tables[sess_idx][TF_DIR_TX]
+ [CFA_TCAM_MGR_TBL_TYPE_CT_RULE_TCAM_AFM].tcam_rows =
+ (struct cfa_tcam_mgr_table_rows_0 *)
+ &cfa_tcam_mgr_table_rows_CT_RULE_TCAM_TX[sess_idx];
+ cfa_tcam_mgr_tables[sess_idx][TF_DIR_TX]
+ [CFA_TCAM_MGR_TBL_TYPE_CT_RULE_TCAM_APPS].tcam_rows =
+ (struct cfa_tcam_mgr_table_rows_0 *)
+ &cfa_tcam_mgr_table_rows_CT_RULE_TCAM_TX[sess_idx];
+
+ cfa_tcam_mgr_tables[sess_idx][TF_DIR_RX]
+ [CFA_TCAM_MGR_TBL_TYPE_VEB_TCAM_AFM].tcam_rows =
+ (struct cfa_tcam_mgr_table_rows_0 *)
+ &cfa_tcam_mgr_table_rows_VEB_TCAM_RX[sess_idx];
+ cfa_tcam_mgr_tables[sess_idx][TF_DIR_RX]
+ [CFA_TCAM_MGR_TBL_TYPE_VEB_TCAM_APPS].tcam_rows =
+ (struct cfa_tcam_mgr_table_rows_0 *)
+ &cfa_tcam_mgr_table_rows_VEB_TCAM_RX[sess_idx];
+
+ cfa_tcam_mgr_tables[sess_idx][TF_DIR_TX]
+ [CFA_TCAM_MGR_TBL_TYPE_VEB_TCAM_AFM].tcam_rows =
+ (struct cfa_tcam_mgr_table_rows_0 *)
+ &cfa_tcam_mgr_table_rows_VEB_TCAM_TX[sess_idx];
+ cfa_tcam_mgr_tables[sess_idx][TF_DIR_TX]
+ [CFA_TCAM_MGR_TBL_TYPE_VEB_TCAM_APPS].tcam_rows =
+ (struct cfa_tcam_mgr_table_rows_0 *)
+ &cfa_tcam_mgr_table_rows_VEB_TCAM_TX[sess_idx];
+
+ cfa_tcam_mgr_tables[sess_idx][TF_DIR_RX]
+ [CFA_TCAM_MGR_TBL_TYPE_WC_TCAM_HIGH_AFM].tcam_rows =
+ (struct cfa_tcam_mgr_table_rows_0 *)
+ &cfa_tcam_mgr_table_rows_WC_TCAM_RX_HIGH[sess_idx];
+ cfa_tcam_mgr_tables[sess_idx][TF_DIR_RX]
+ [CFA_TCAM_MGR_TBL_TYPE_WC_TCAM_HIGH_APPS].tcam_rows =
+ (struct cfa_tcam_mgr_table_rows_0 *)
+ &cfa_tcam_mgr_table_rows_WC_TCAM_RX_HIGH[sess_idx];
+
+ cfa_tcam_mgr_tables[sess_idx][TF_DIR_TX]
+ [CFA_TCAM_MGR_TBL_TYPE_WC_TCAM_HIGH_AFM].tcam_rows =
+ (struct cfa_tcam_mgr_table_rows_0 *)
+ &cfa_tcam_mgr_table_rows_WC_TCAM_TX_HIGH[sess_idx];
+ cfa_tcam_mgr_tables[sess_idx][TF_DIR_TX]
+ [CFA_TCAM_MGR_TBL_TYPE_WC_TCAM_HIGH_APPS].tcam_rows =
+ (struct cfa_tcam_mgr_table_rows_0 *)
+ &cfa_tcam_mgr_table_rows_WC_TCAM_TX_HIGH[sess_idx];
+
+ cfa_tcam_mgr_tables[sess_idx][TF_DIR_RX]
+ [CFA_TCAM_MGR_TBL_TYPE_WC_TCAM_LOW_AFM].tcam_rows =
+ (struct cfa_tcam_mgr_table_rows_0 *)
+ &cfa_tcam_mgr_table_rows_WC_TCAM_RX_LOW[sess_idx];
+ cfa_tcam_mgr_tables[sess_idx][TF_DIR_RX]
+ [CFA_TCAM_MGR_TBL_TYPE_WC_TCAM_LOW_APPS].tcam_rows =
+ (struct cfa_tcam_mgr_table_rows_0 *)
+ &cfa_tcam_mgr_table_rows_WC_TCAM_RX_LOW[sess_idx];
+
+ cfa_tcam_mgr_tables[sess_idx][TF_DIR_TX]
+ [CFA_TCAM_MGR_TBL_TYPE_WC_TCAM_LOW_AFM].tcam_rows =
+ (struct cfa_tcam_mgr_table_rows_0 *)
+ &cfa_tcam_mgr_table_rows_WC_TCAM_TX_LOW[sess_idx];
+ cfa_tcam_mgr_tables[sess_idx][TF_DIR_TX]
+ [CFA_TCAM_MGR_TBL_TYPE_WC_TCAM_LOW_APPS].tcam_rows =
+ (struct cfa_tcam_mgr_table_rows_0 *)
+ &cfa_tcam_mgr_table_rows_WC_TCAM_TX_LOW[sess_idx];
+
+ for (dir = 0; dir < TF_DIR_MAX; dir++) {
+ for (type = 0; type < CFA_TCAM_MGR_TBL_TYPE_MAX; type++) {
+ if (cfa_tcam_mgr_tables[sess_idx][dir][type].row_width >
+ max_row_width)
+ max_row_width =
+ cfa_tcam_mgr_tables[sess_idx][dir][type].row_width;
+ if (cfa_tcam_mgr_tables[sess_idx][dir][type].result_size >
+ max_result_size)
+ max_result_size =
+ cfa_tcam_mgr_tables[sess_idx][dir][type].result_size;
+ }
+ }
+
+ if (max_row_width != MAX_ROW_WIDTH) {
+ CFA_TCAM_MGR_LOG(ERR,
+ "MAX_ROW_WIDTH (%d) does not match actual "
+ "value (%d).\n",
+ MAX_ROW_WIDTH,
+ max_row_width);
+ return -CFA_TCAM_MGR_ERR_CODE(INVAL);
+ }
+ if (max_result_size != MAX_RESULT_SIZE) {
+ CFA_TCAM_MGR_LOG(ERR,
+ "MAX_RESULT_SIZE (%d) does not match actual "
+ "value (%d).\n",
+ MAX_RESULT_SIZE,
+ max_result_size);
+ return -CFA_TCAM_MGR_ERR_CODE(INVAL);
+ }
+ return 0;
+}
+
+/* HW OP declarations begin here */
+
+struct cfa_tcam_mgr_TCAM_row_data {
+ int key_size;
+ int result_size;
+ uint8_t key[MAX_ROW_WIDTH];
+ uint8_t mask[MAX_ROW_WIDTH];
+ uint8_t result[MAX_RESULT_SIZE];
+};
+
+/* These macros are only needed to avoid exceeding 80 columns */
+#define L2_CTXT_RX_MAX_ROWS \
+ (L2_CTXT_TCAM_RX_MAX_SLICES * L2_CTXT_TCAM_RX_NUM_ROWS)
+#define PROF_RX_MAX_ROWS (PROF_TCAM_RX_MAX_SLICES * PROF_TCAM_RX_NUM_ROWS)
+#define WC_RX_MAX_ROWS (WC_TCAM_RX_MAX_SLICES * WC_TCAM_RX_NUM_ROWS)
+#define SP_RX_MAX_ROWS (SP_TCAM_RX_MAX_SLICES * SP_TCAM_RX_NUM_ROWS)
+#define CT_RULE_RX_MAX_ROWS \
+ (CT_RULE_TCAM_RX_MAX_SLICES * CT_RULE_TCAM_RX_NUM_ROWS)
+#define VEB_RX_MAX_ROWS (VEB_TCAM_RX_MAX_SLICES * VEB_TCAM_RX_NUM_ROWS)
+
+#define L2_CTXT_TX_MAX_ROWS \
+ (L2_CTXT_TCAM_TX_MAX_SLICES * L2_CTXT_TCAM_TX_NUM_ROWS)
+#define PROF_TX_MAX_ROWS (PROF_TCAM_TX_MAX_SLICES * PROF_TCAM_TX_NUM_ROWS)
+#define WC_TX_MAX_ROWS (WC_TCAM_TX_MAX_SLICES * WC_TCAM_TX_NUM_ROWS)
+#define SP_TX_MAX_ROWS (SP_TCAM_TX_MAX_SLICES * SP_TCAM_TX_NUM_ROWS)
+#define CT_RULE_TX_MAX_ROWS \
+ (CT_RULE_TCAM_TX_MAX_SLICES * CT_RULE_TCAM_TX_NUM_ROWS)
+#define VEB_TX_MAX_ROWS (VEB_TCAM_TX_MAX_SLICES * VEB_TCAM_TX_NUM_ROWS)
+
+static int cfa_tcam_mgr_max_rows[TF_TCAM_TBL_TYPE_MAX] = {
+ L2_CTXT_RX_MAX_ROWS,
+ L2_CTXT_RX_MAX_ROWS,
+ PROF_RX_MAX_ROWS,
+ WC_RX_MAX_ROWS,
+ SP_RX_MAX_ROWS,
+ CT_RULE_RX_MAX_ROWS,
+ VEB_RX_MAX_ROWS,
+ WC_RX_MAX_ROWS,
+ WC_RX_MAX_ROWS
+};
+
+static struct cfa_tcam_mgr_TCAM_row_data
+ cfa_tcam_mgr_L2_CTXT_TCAM_RX_row_data[TF_TCAM_MAX_SESSIONS][L2_CTXT_RX_MAX_ROWS];
+static struct cfa_tcam_mgr_TCAM_row_data
+ cfa_tcam_mgr_PROF_TCAM_RX_row_data[TF_TCAM_MAX_SESSIONS][PROF_RX_MAX_ROWS];
+static struct cfa_tcam_mgr_TCAM_row_data
+ cfa_tcam_mgr_WC_TCAM_RX_row_data[TF_TCAM_MAX_SESSIONS][WC_RX_MAX_ROWS];
+static struct cfa_tcam_mgr_TCAM_row_data
+ cfa_tcam_mgr_SP_TCAM_RX_row_data[TF_TCAM_MAX_SESSIONS][SP_RX_MAX_ROWS];
+static struct cfa_tcam_mgr_TCAM_row_data
+ cfa_tcam_mgr_CT_RULE_TCAM_RX_row_data[TF_TCAM_MAX_SESSIONS][CT_RULE_RX_MAX_ROWS];
+static struct cfa_tcam_mgr_TCAM_row_data
+ cfa_tcam_mgr_VEB_TCAM_RX_row_data[TF_TCAM_MAX_SESSIONS][VEB_RX_MAX_ROWS];
+static struct cfa_tcam_mgr_TCAM_row_data
+ cfa_tcam_mgr_WC_TCAM_RX_row_data[TF_TCAM_MAX_SESSIONS][WC_RX_MAX_ROWS];
+
+static struct cfa_tcam_mgr_TCAM_row_data
+ cfa_tcam_mgr_L2_CTXT_TCAM_TX_row_data[TF_TCAM_MAX_SESSIONS][L2_CTXT_TX_MAX_ROWS];
+static struct cfa_tcam_mgr_TCAM_row_data
+ cfa_tcam_mgr_PROF_TCAM_TX_row_data[TF_TCAM_MAX_SESSIONS][PROF_TX_MAX_ROWS];
+static struct cfa_tcam_mgr_TCAM_row_data
+ cfa_tcam_mgr_WC_TCAM_TX_row_data[TF_TCAM_MAX_SESSIONS][WC_TX_MAX_ROWS];
+static struct cfa_tcam_mgr_TCAM_row_data
+ cfa_tcam_mgr_SP_TCAM_TX_row_data[TF_TCAM_MAX_SESSIONS][SP_TX_MAX_ROWS];
+static struct cfa_tcam_mgr_TCAM_row_data
+ cfa_tcam_mgr_CT_RULE_TCAM_TX_row_data[TF_TCAM_MAX_SESSIONS][CT_RULE_TX_MAX_ROWS];
+static struct cfa_tcam_mgr_TCAM_row_data
+ cfa_tcam_mgr_VEB_TCAM_TX_row_data[TF_TCAM_MAX_SESSIONS][VEB_TX_MAX_ROWS];
+static struct cfa_tcam_mgr_TCAM_row_data
+ cfa_tcam_mgr_WC_TCAM_TX_row_data[TF_TCAM_MAX_SESSIONS][WC_TX_MAX_ROWS];
+
+static struct cfa_tcam_mgr_TCAM_row_data *
+row_tables[TF_DIR_MAX][TF_TCAM_TBL_TYPE_MAX] = {
+ {
+ cfa_tcam_mgr_L2_CTXT_TCAM_RX_row_data[0],
+ cfa_tcam_mgr_L2_CTXT_TCAM_RX_row_data[0],
+ cfa_tcam_mgr_PROF_TCAM_RX_row_data[0],
+ cfa_tcam_mgr_WC_TCAM_RX_row_data[0],
+ cfa_tcam_mgr_SP_TCAM_RX_row_data[0],
+ cfa_tcam_mgr_CT_RULE_TCAM_RX_row_data[0],
+ cfa_tcam_mgr_VEB_TCAM_RX_row_data[0],
+ cfa_tcam_mgr_WC_TCAM_RX_row_data[0],
+ cfa_tcam_mgr_WC_TCAM_RX_row_data[0],
+ },
+ {
+ cfa_tcam_mgr_L2_CTXT_TCAM_TX_row_data[0],
+ cfa_tcam_mgr_L2_CTXT_TCAM_TX_row_data[0],
+ cfa_tcam_mgr_PROF_TCAM_TX_row_data[0],
+ cfa_tcam_mgr_WC_TCAM_TX_row_data[0],
+ cfa_tcam_mgr_SP_TCAM_TX_row_data[0],
+ cfa_tcam_mgr_CT_RULE_TCAM_TX_row_data[0],
+ cfa_tcam_mgr_VEB_TCAM_TX_row_data[0],
+ cfa_tcam_mgr_WC_TCAM_TX_row_data[0],
+ cfa_tcam_mgr_WC_TCAM_TX_row_data[0],
+ }
+};
+
+static int cfa_tcam_mgr_get_max_rows(enum tf_tcam_tbl_type type)
+{
+ if (type >= TF_TCAM_TBL_TYPE_MAX)
+ assert(0);
+ else
+ return cfa_tcam_mgr_max_rows[type];
+}
+
+static int cfa_tcam_mgr_hwop_set(int sess_idx,
+ struct cfa_tcam_mgr_set_parms *parms, int row,
+ int slice, int max_slices)
+{
+ struct cfa_tcam_mgr_TCAM_row_data *this_table;
+ struct cfa_tcam_mgr_TCAM_row_data *this_row;
+ this_table = row_tables[parms->dir]
+ [cfa_tcam_mgr_get_phys_table_type(parms->type)];
+ this_table += (sess_idx *
+ cfa_tcam_mgr_get_max_rows(cfa_tcam_mgr_get_phys_table_type(parms->type)));
+ this_row = &this_table[row * max_slices + slice];
+ this_row->key_size = parms->key_size;
+ memcpy(&this_row->key, parms->key, parms->key_size);
+ memcpy(&this_row->mask, parms->mask, parms->key_size);
+ this_row->result_size = parms->result_size;
+ if (parms->result != ((void *)0))
+ memcpy(&this_row->result, parms->result, parms->result_size);
+ return 0;
+};
+
+static int cfa_tcam_mgr_hwop_get(int sess_idx,
+ struct cfa_tcam_mgr_get_parms *parms, int row,
+ int slice, int max_slices)
+{
+ struct cfa_tcam_mgr_TCAM_row_data *this_table;
+ struct cfa_tcam_mgr_TCAM_row_data *this_row;
+ this_table = row_tables[parms->dir]
+ [cfa_tcam_mgr_get_phys_table_type(parms->type)];
+ this_table += (sess_idx *
+ cfa_tcam_mgr_get_max_rows(cfa_tcam_mgr_get_phys_table_type(parms->type)));
+ this_row = &this_table[row * max_slices + slice];
+ parms->key_size = this_row->key_size;
+ parms->result_size = this_row->result_size;
+ if (parms->key != ((void *)0))
+ memcpy(parms->key, &this_row->key, parms->key_size);
+ if (parms->mask != ((void *)0))
+ memcpy(parms->mask, &this_row->mask, parms->key_size);
+ if (parms->result != ((void *)0))
+ memcpy(parms->result, &this_row->result, parms->result_size);
+ return 0;
+};
+
+static int cfa_tcam_mgr_hwop_free(int sess_idx,
+ struct cfa_tcam_mgr_free_parms *parms,
+ int row, int slice, int max_slices)
+{
+ struct cfa_tcam_mgr_TCAM_row_data *this_table;
+ struct cfa_tcam_mgr_TCAM_row_data *this_row;
+ this_table = row_tables[parms->dir]
+ [cfa_tcam_mgr_get_phys_table_type(parms->type)];
+ this_table += (sess_idx *
+ cfa_tcam_mgr_get_max_rows(cfa_tcam_mgr_get_phys_table_type(parms->type)));
+ this_row = &this_table[row * max_slices + slice];
+ memset(&this_row->key, 0, sizeof(this_row->key));
+ memset(&this_row->mask, 0, sizeof(this_row->mask));
+ memset(&this_row->result, 0, sizeof(this_row->result));
+ this_row->key_size = 0;
+ this_row->result_size = 0;
+ return 0;
+};
+
+int cfa_tcam_mgr_hwops_get_funcs_p58(struct cfa_tcam_mgr_hwops_funcs
+ *hwop_funcs)
+{
+ hwop_funcs->set = cfa_tcam_mgr_hwop_set;
+ hwop_funcs->get = cfa_tcam_mgr_hwop_get;
+ hwop_funcs->free = cfa_tcam_mgr_hwop_free;
+ return 0;
+}
diff --git a/drivers/net/bnxt/tf_core/cfa_tcam_mgr_p58.h b/drivers/net/bnxt/tf_core/cfa_tcam_mgr_p58.h
new file mode 100644
index 0000000000..7640f91911
--- /dev/null
+++ b/drivers/net/bnxt/tf_core/cfa_tcam_mgr_p58.h
@@ -0,0 +1,20 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2021-2023 Broadcom
+ * All rights reserved.
+ */
+
+#ifndef CFA_TCAM_MGR_P58_H
+#define CFA_TCAM_MGR_P58_H
+
+#include "cfa_tcam_mgr_device.h"
+#include "cfa_tcam_mgr_sbmp.h"
+
+int
+cfa_tcam_mgr_init_p58(int sess_idx, struct cfa_tcam_mgr_entry_data **global_entry_data);
+
+int
+cfa_tcam_mgr_sess_table_get_p58(int sess_idx, struct sbmp **session_bmp);
+
+int
+cfa_tcam_mgr_hwops_get_funcs_p58(struct cfa_tcam_mgr_hwops_funcs *hwop_funcs);
+#endif /* CFA_TCAM_MGR_P58_H */
diff --git a/drivers/net/bnxt/tf_core/cfa_tcam_mgr_sbmp.h b/drivers/net/bnxt/tf_core/cfa_tcam_mgr_sbmp.h
new file mode 100644
index 0000000000..6ad158abe8
--- /dev/null
+++ b/drivers/net/bnxt/tf_core/cfa_tcam_mgr_sbmp.h
@@ -0,0 +1,126 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2021-2023 Broadcom
+ * All rights reserved.
+ */
+
+#ifndef CFA_TCAM_MGR_SBMP_H
+#define CFA_TCAM_MGR_SBMP_H
+
+#include <inttypes.h>
+
+#include "cfa_tcam_mgr.h"
+
+#define SBMP_SESSION_MAX TF_TCAM_MAX_SESSIONS
+#if SBMP_SESSION_MAX <= 16
+#define SBMP_WORD_WIDTH 16
+#else
+#define SBMP_WORD_WIDTH 32
+#endif
+
+#define SBMP_WIDTH (((SBMP_SESSION_MAX + SBMP_WORD_WIDTH - 1) / \
+ SBMP_WORD_WIDTH) * SBMP_WORD_WIDTH)
+#define SBMP_WORD_MAX ((SBMP_WIDTH + SBMP_WORD_WIDTH - 1) / SBMP_WORD_WIDTH)
+
+struct sbmp {
+#if SBMP_WORD_WIDTH == 16
+ uint16_t bits[SBMP_WORD_MAX];
+#elif SBMP_WORD_WIDTH == 32
+ uint32_t bits[SBMP_WORD_MAX];
+#else
+ uint64_t bits[SBMP_WORD_MAX];
+#endif
+};
+
+#define SBMP_WORD_GET(bm, word) ((bm).bits[(word)])
+
+#if SBMP_WORD_MAX == 1
+#define SBMP_WENT(session) (0)
+#define SBMP_WBIT(session) (1U << (session))
+#define SBMP_CLEAR(bm) (SBMP_WORD_GET(bm, 0) = 0)
+#define SBMP_IS_NULL(bm) (SBMP_WORD_GET(bm, 0) == 0)
+#define SBMP_COUNT(bm, count) \
+ (count = __builtin_popcount(SBMP_WORD_GET(bm, 0)))
+#elif SBMP_WORD_MAX == 2
+#define SBMP_WENT(session) ((session) / SBMP_WORD_WIDTH)
+#define SBMP_WBIT(session) (1U << ((session) % SBMP_WORD_WIDTH))
+#define SBMP_CLEAR(bm) \
+ do { \
+ typeof(bm) *_bm = &(bm); \
+ SBMP_WORD_GET(*_bm, 0) = SBMP_WORD_GET(*_bm, 1) = 0; \
+ } while (0)
+#define SBMP_IS_NULL(bm) \
+ (SBMP_WORD_GET(bm, 0) == 0 && SBMP_WORD_GET(bm, 1) == 0)
+#define SBMP_COUNT(bm, count) \
+ do { \
+ typeof(bm) *_bm = &(bm); \
+ count = __builtin_popcount(SBMP_WORD_GET(*_bm, 0)) + \
+ __builtin_popcount(SBMP_WORD_GET(*_bm, 1))); \
+ } while (0)
+#elif SBMP_WORD_MAX == 3
+#define SBMP_WENT(session) ((session) / SBMP_WORD_WIDTH)
+#define SBMP_WBIT(session) (1U << ((session) % SBMP_WORD_WIDTH))
+#define SBMP_CLEAR(bm) \
+ do { \
+ typeof(bm) *_bm = &(bm); \
+ SBMP_WORD_GET(*_bm, 0) = SBMP_WORD_GET(*_bm, 1) = \
+ SBMP_WORD_GET(*_bm, 2) = 0; \
+ } while (0)
+#define SBMP_IS_NULL(bm) \
+ (SBMP_WORD_GET(bm, 0) == 0 && SBMP_WORD_GET(bm, 1) == 0 && \
+ SBMP_WORD_GET(bm, 2) == 0)
+#define SBMP_COUNT(bm, count) \
+ do { \
+ typeof(bm) *_bm = &(bm); \
+ count = __builtin_popcount(SBMP_WORD_GET(*_bm, 0)) + \
+ __builtin_popcount(SBMP_WORD_GET(*_bm, 1)) + \
+ __builtin_popcount(SBMP_WORD_GET(*_bm, 2)); \
+ } while (0)
+#else /* SBMP_WORD_MAX > 3 */
+#define SBMP_WENT(session) ((session) / SBMP_WORD_WIDTH)
+#define SBMP_WBIT(session) (1U << ((session) % SBMP_WORD_WIDTH))
+#define SBMP_CLEAR(bm) \
+ do { \
+ typeof(bm) *_bm = &(bm); \
+ int _w; \
+ for (_w = 0; _w < SBMP_WORD_MAX; _w++) { \
+ SBMP_WORD_GET(*_bm, _w) = 0; \
+ } \
+ } while (0)
+#define SBMP_IS_NULL(bm) (sbmp_bmnull(&(bm)))
+#define SBMP_COUNT(bm, count) \
+ do { \
+ typeof(bm) *_bm = &(bm); \
+ int _count, _w; \
+ _count = 0; \
+ for (_w = 0; _w < SBMP_WORD_MAX; _w++) { \
+ _count += __builtin_popcount(SBMP_WORD_GET(*_bm, _w)); \
+ } \
+ count = _count; \
+ } while (0)
+
+/* Only needed if SBMP_WORD_MAX > 3 */
+static int
+sbmp_bmnull(struct ebmp *bmp)
+{
+ int i;
+
+ for (i = 0; i < SBMP_WORD_MAX; i++) {
+ if (SBMP_WORD_GET(*bmp, i) != 0)
+ return 0;
+ }
+ return 1;
+}
+#endif
+
+/* generics that use the previously defined helpers */
+#define SBMP_NOT_NULL(bm) (!SBMP_IS_NULL(bm))
+
+#define SBMP_ENTRY(bm, session) \
+ (SBMP_WORD_GET(bm, SBMP_WENT(session)))
+#define SBMP_MEMBER(bm, session) \
+ ((SBMP_ENTRY(bm, session) & SBMP_WBIT(session)) != 0)
+#define SBMP_SESSION_ADD(bm, session) \
+ (SBMP_ENTRY(bm, session) |= SBMP_WBIT(session))
+#define SBMP_SESSION_REMOVE(bm, session) \
+ (SBMP_ENTRY(bm, session) &= ~SBMP_WBIT(session))
+#endif /* CFA_TCAM_MGR_SBMP_H */
diff --git a/drivers/net/bnxt/tf_core/cfa_tcam_mgr_session.c b/drivers/net/bnxt/tf_core/cfa_tcam_mgr_session.c
new file mode 100644
index 0000000000..3d085bc69e
--- /dev/null
+++ b/drivers/net/bnxt/tf_core/cfa_tcam_mgr_session.c
@@ -0,0 +1,377 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2021-2023 Broadcom
+ * All rights reserved.
+ */
+
+#include <inttypes.h>
+#include "hcapi_cfa_defs.h"
+#include "tf_util.h"
+#include "cfa_tcam_mgr.h"
+#include "cfa_tcam_mgr_device.h"
+#include "cfa_tcam_mgr_session.h"
+#include "cfa_tcam_mgr_sbmp.h"
+#include "tfp.h"
+#include "cfa_tcam_mgr_p58.h"
+#include "cfa_tcam_mgr_p4.h"
+
+struct cfa_tcam_mgr_session_data {
+ uint32_t session_id;
+ /* The following are per-session values */
+ uint16_t max_entries[TF_DIR_MAX][CFA_TCAM_MGR_TBL_TYPE_MAX];
+ uint16_t used_entries[TF_DIR_MAX][CFA_TCAM_MGR_TBL_TYPE_MAX];
+};
+
+static struct cfa_tcam_mgr_session_data session_data[TF_TCAM_MAX_SESSIONS];
+
+static uint16_t last_entry_id;
+
+static struct sbmp *session_bmp[TF_TCAM_MAX_SESSIONS];
+
+int
+cfa_tcam_mgr_session_init(int sess_idx, enum cfa_tcam_mgr_device_type type)
+{
+ int rc;
+
+ switch (type) {
+ case CFA_TCAM_MGR_DEVICE_TYPE_P4:
+ case CFA_TCAM_MGR_DEVICE_TYPE_SR:
+ rc = cfa_tcam_mgr_sess_table_get_p4(sess_idx, &session_bmp[sess_idx]);
+ break;
+ case CFA_TCAM_MGR_DEVICE_TYPE_P5:
+ rc = cfa_tcam_mgr_sess_table_get_p58(sess_idx, &session_bmp[sess_idx]);
+ break;
+ default:
+ CFA_TCAM_MGR_LOG(ERR, "No such device %d\n", type);
+ rc = -CFA_TCAM_MGR_ERR_CODE(NODEV);
+ }
+
+ return rc;
+}
+
+int
+cfa_tcam_mgr_get_session_from_context(struct cfa_tcam_mgr_context *context,
+ uint32_t *session_id)
+{
+ if (context == NULL) {
+ CFA_TCAM_MGR_LOG_0(ERR, "context passed as NULL pointer.\n");
+ return -CFA_TCAM_MGR_ERR_CODE(INVAL);
+ }
+
+ *session_id = context->tfp->session->session_id.id;
+ return 0;
+}
+
+int
+cfa_tcam_mgr_session_find(unsigned int session_id)
+{
+ unsigned int sess_idx;
+
+ for (sess_idx = 0; sess_idx < ARRAY_SIZE(session_data); sess_idx++) {
+ if (session_data[sess_idx].session_id == session_id)
+ return sess_idx;
+ }
+
+ return -CFA_TCAM_MGR_ERR_CODE(INVAL);
+}
+
+int
+cfa_tcam_mgr_session_add(unsigned int session_id)
+{
+ int sess_idx;
+
+ sess_idx = cfa_tcam_mgr_session_find(session_id);
+ if (sess_idx >= 0) {
+ CFA_TCAM_MGR_LOG_0(ERR, "Session is already bound.\n");
+ return -CFA_TCAM_MGR_ERR_CODE(BUSY);
+ }
+
+ /* Session not found in table, find first empty entry. */
+ for (sess_idx = 0;
+ sess_idx < (signed int)ARRAY_SIZE(session_data);
+ sess_idx++) {
+ if (session_data[sess_idx].session_id == 0)
+ break;
+ }
+
+ if (sess_idx >= (signed int)ARRAY_SIZE(session_data)) {
+ /* No room in the session table */
+ CFA_TCAM_MGR_LOG_0(ERR, "Session table is full.\n");
+ return -CFA_TCAM_MGR_ERR_CODE(NOMEM);
+ }
+
+ session_data[sess_idx].session_id = session_id;
+
+ return sess_idx;
+}
+
+int
+cfa_tcam_mgr_session_free(unsigned int session_id,
+ struct cfa_tcam_mgr_context *context)
+{
+ struct cfa_tcam_mgr_free_parms free_parms;
+ int entry_id;
+ int sess_idx = cfa_tcam_mgr_session_find(session_id);
+
+ if (sess_idx < 0)
+ return sess_idx;
+
+ memset(&free_parms, 0, sizeof(free_parms));
+ /* Since we are freeing all pending TCAM entries (which is typically
+ * done during tcam_unbind), we don't know the type of each entry.
+ * So we set the type to MAX as a hint to cfa_tcam_mgr_free() to
+ * figure out the actual type. We need to set it through each
+ * iteration in the loop below; otherwise, the type determined for
+ * the first entry would be used for subsequent entries that may or
+ * may not be of the same type, resulting in errors.
+ */
+ for (entry_id = 0; entry_id < cfa_tcam_mgr_max_entries[sess_idx]; entry_id++) {
+ if (SBMP_MEMBER(session_bmp[sess_idx][entry_id], sess_idx)) {
+ SBMP_SESSION_REMOVE(session_bmp[sess_idx][entry_id], sess_idx);
+
+ free_parms.id = entry_id;
+ free_parms.type = CFA_TCAM_MGR_TBL_TYPE_MAX;
+ cfa_tcam_mgr_free(context, &free_parms);
+ }
+ }
+
+ memset(&session_data[sess_idx], 0, sizeof(session_data[sess_idx]));
+ return 0;
+}
+
+int
+cfa_tcam_mgr_session_cfg(unsigned int session_id,
+ uint16_t tcam_cnt[][CFA_TCAM_MGR_TBL_TYPE_MAX])
+{
+ struct cfa_tcam_mgr_table_data *table_data;
+ struct cfa_tcam_mgr_session_data *session_entry;
+ unsigned int dir, type;
+ int sess_idx = cfa_tcam_mgr_session_find(session_id);
+ uint16_t requested_cnt;
+
+ if (sess_idx < 0)
+ return sess_idx;
+
+ session_entry = &session_data[sess_idx];
+
+ /* Validate session request */
+ for (dir = 0; dir < ARRAY_SIZE(cfa_tcam_mgr_tables[sess_idx]); dir++) {
+ for (type = 0;
+ type < ARRAY_SIZE(cfa_tcam_mgr_tables[sess_idx][dir]);
+ type++) {
+ table_data = &cfa_tcam_mgr_tables[sess_idx][dir][type];
+ requested_cnt = tcam_cnt[dir][type];
+ /*
+ * Only check if table supported (max_entries > 0).
+ */
+ if (table_data->max_entries > 0 &&
+ requested_cnt > table_data->max_entries) {
+ CFA_TCAM_MGR_LOG_DIR_TYPE(ERR, dir, type,
+ "Requested %d, available %d.\n",
+ requested_cnt,
+ table_data->max_entries);
+ return -CFA_TCAM_MGR_ERR_CODE(NOSPC);
+ }
+ }
+ }
+
+ memcpy(session_entry->max_entries, tcam_cnt,
+ sizeof(session_entry->max_entries));
+ return 0;
+}
+
+void
+cfa_tcam_mgr_mv_session_used_entries_cnt(int sess_idx, enum tf_dir dir,
+ enum cfa_tcam_mgr_tbl_type dst_type,
+ enum cfa_tcam_mgr_tbl_type src_type)
+{
+ session_data[sess_idx].used_entries[dir][dst_type]++;
+ session_data[sess_idx].used_entries[dir][src_type]--;
+}
+
+int
+cfa_tcam_mgr_session_entry_alloc(unsigned int session_id,
+ enum tf_dir dir,
+ enum cfa_tcam_mgr_tbl_type type)
+{
+ int sess_idx;
+
+ sess_idx = cfa_tcam_mgr_session_find(session_id);
+ if (sess_idx < 0) {
+ CFA_TCAM_MGR_LOG_0(ERR, "Session not found.\n");
+ return -CFA_TCAM_MGR_ERR_CODE(NODEV);
+ }
+
+ if (session_data[sess_idx].used_entries[dir][type] >=
+ session_data[sess_idx].max_entries[dir][type]) {
+ CFA_TCAM_MGR_LOG_0(ERR, "Table full (session).\n");
+ return -CFA_TCAM_MGR_ERR_CODE(NOSPC);
+ }
+
+ do {
+ last_entry_id++;
+ if (cfa_tcam_mgr_max_entries[sess_idx] <= last_entry_id)
+ last_entry_id = 0;
+ } while (!SBMP_IS_NULL(session_bmp[sess_idx][last_entry_id]));
+
+ SBMP_SESSION_ADD(session_bmp[sess_idx][last_entry_id], sess_idx);
+
+ session_data[sess_idx].used_entries[dir][type] += 1;
+
+ return last_entry_id;
+}
+
+int
+cfa_tcam_mgr_session_entry_free(unsigned int session_id,
+ unsigned int entry_id,
+ enum tf_dir dir,
+ enum cfa_tcam_mgr_tbl_type type)
+{
+ int sess_idx;
+
+ sess_idx = cfa_tcam_mgr_session_find(session_id);
+ if (sess_idx < 0) {
+ CFA_TCAM_MGR_LOG_0(ERR, "Session not found.\n");
+ return -CFA_TCAM_MGR_ERR_CODE(NODEV);
+ }
+
+ SBMP_SESSION_REMOVE(session_bmp[sess_idx][entry_id], sess_idx);
+ session_data[sess_idx].used_entries[dir][type] -= 1;
+
+ return 0;
+}
+
+#if SBMP_WORD_WIDTH == 16
+#define SBMP_FORMAT PRIX16
+#define SBMP_PRECISION "4"
+#elif SBMP_WORD_WIDTH == 32
+#define SBMP_FORMAT PRIX32
+#define SBMP_PRECISION "8"
+#elif SBMP_WORD_WIDTH == 64
+#define SBMP_FORMAT PRIX64
+#define SBMP_PRECISION "16"
+#else
+#error "Invalid value for SBMP_WORD_WIDTH."
+#endif
+
+static void
+cfa_tcam_mgr_session_bitmap_print(struct sbmp *session_bmp)
+{
+ unsigned int i;
+
+ printf("0x");
+ for (i = 0;
+ i < ARRAY_SIZE(session_bmp->bits);
+ i++) {
+ printf("%0" SBMP_PRECISION SBMP_FORMAT,
+ session_bmp->bits[i]);
+ }
+}
+
+#define SESSION_DUMP_HEADER_1 " RX TX\n"
+#define SESSION_DUMP_HEADER_2 \
+ " Max Used Max Used\n"
+
+static void
+cfa_tcam_mgr_session_printf(struct cfa_tcam_mgr_session_data *session,
+ enum cfa_tcam_mgr_tbl_type tbl_type)
+{
+ printf("%-22s: %5u %5u %5u %5u\n",
+ cfa_tcam_mgr_tbl_2_str(tbl_type),
+ session->max_entries[TF_DIR_RX][tbl_type],
+ session->used_entries[TF_DIR_RX][tbl_type],
+ session->max_entries[TF_DIR_TX][tbl_type],
+ session->used_entries[TF_DIR_TX][tbl_type]);
+}
+
+void
+cfa_tcam_mgr_sessions_dump(void)
+{
+ struct cfa_tcam_mgr_session_data *session;
+ unsigned int sess_idx;
+ bool sess_found = false;
+ enum cfa_tcam_mgr_tbl_type tbl_type;
+
+ printf("\nTCAM Sessions Table:\n");
+ for (sess_idx = 0; sess_idx < ARRAY_SIZE(session_data); sess_idx++) {
+ if (session_data[sess_idx].session_id != 0) {
+ session = &session_data[sess_idx];
+ if (!sess_found) {
+ printf(SESSION_DUMP_HEADER_1);
+ printf(SESSION_DUMP_HEADER_2);
+ }
+ printf("Session 0x%08x:\n",
+ session->session_id);
+ for (tbl_type = CFA_TCAM_MGR_TBL_TYPE_START;
+ tbl_type < CFA_TCAM_MGR_TBL_TYPE_MAX;
+ tbl_type++) {
+ cfa_tcam_mgr_session_printf(session, tbl_type);
+ }
+ sess_found = true;
+ }
+ }
+
+ if (!sess_found)
+ printf("No sessions found.\n");
+}
+
+/* This dumps all the sessions using an entry */
+void
+cfa_tcam_mgr_entry_sessions_dump(int sess_idx, uint16_t id)
+{
+ bool session_found = false;
+
+ if (id >= cfa_tcam_mgr_max_entries[sess_idx]) {
+ printf("Entry ID %u out of range for sess_idx %d. Max ID %u.\n",
+ id, sess_idx, cfa_tcam_mgr_max_entries[sess_idx] - 1);
+ return;
+ }
+
+ if (!SBMP_IS_NULL(session_bmp[sess_idx][id])) {
+ printf("Sessions using entry ID %u:\n", id);
+ for (sess_idx = 0; sess_idx < SBMP_SESSION_MAX; sess_idx++)
+ if (SBMP_MEMBER(session_bmp[sess_idx][id], (sess_idx))) {
+ if (session_data[sess_idx].session_id != 0) {
+ printf("0x%08x (index %d)\n",
+ session_data[sess_idx].session_id,
+ sess_idx);
+ session_found = true;
+ } else {
+ printf("Error! Entry ID %u used by "
+ "session index %d which is not "
+ "in use.\n",
+ id, sess_idx);
+ }
+ }
+ if (!session_found)
+ printf("No sessions using entry ID %u.\n", id);
+ } else {
+ printf("Entry ID %u not in use.\n",
+ id);
+ return;
+ }
+}
+
+/* This dumps all the entries in use by any session */
+void
+cfa_tcam_mgr_session_entries_dump(int sess_idx)
+{
+ bool entry_found = false;
+ uint16_t id;
+
+ printf("\nGlobal Maximum Entries for sess_idx %d: %d\n\n",
+ sess_idx, cfa_tcam_mgr_max_entries[sess_idx]);
+ printf("TCAM Session Entry Table:\n");
+ for (id = 0; id < cfa_tcam_mgr_max_entries[sess_idx]; id++) {
+ if (!SBMP_IS_NULL(session_bmp[sess_idx][id])) {
+ if (!entry_found)
+ printf(" EID Session bitmap\n");
+ printf("%5u ", id);
+ cfa_tcam_mgr_session_bitmap_print(&session_bmp[sess_idx][id]);
+ printf("\n");
+ entry_found = true;
+ }
+ }
+
+ if (!entry_found)
+ printf("No entries found.\n");
+}
diff --git a/drivers/net/bnxt/tf_core/cfa_tcam_mgr_session.h b/drivers/net/bnxt/tf_core/cfa_tcam_mgr_session.h
new file mode 100644
index 0000000000..69311b7e1d
--- /dev/null
+++ b/drivers/net/bnxt/tf_core/cfa_tcam_mgr_session.h
@@ -0,0 +1,54 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2019-2023 Broadcom
+ * All rights reserved.
+ */
+
+#ifndef CFA_TCAM_MGR_SESSION_H
+#define CFA_TCAM_MGR_SESSION_H
+
+#include <inttypes.h>
+#include "cfa_tcam_mgr.h"
+
+int
+cfa_tcam_mgr_session_init(int sess_idx, enum cfa_tcam_mgr_device_type type);
+
+int
+cfa_tcam_mgr_get_session_from_context(struct cfa_tcam_mgr_context *context,
+ uint32_t *session_id);
+
+int
+cfa_tcam_mgr_session_find(unsigned int session_id);
+
+int
+cfa_tcam_mgr_session_add(unsigned int session_id);
+
+int
+cfa_tcam_mgr_session_free(unsigned int session_id,
+ struct cfa_tcam_mgr_context *context);
+
+int
+cfa_tcam_mgr_session_cfg(unsigned int session_id,
+ uint16_t tcam_cnt[][CFA_TCAM_MGR_TBL_TYPE_MAX]);
+
+int
+cfa_tcam_mgr_session_entry_alloc(unsigned int session_id,
+ enum tf_dir dir,
+ enum cfa_tcam_mgr_tbl_type type);
+int
+cfa_tcam_mgr_session_entry_free(unsigned int session_id,
+ unsigned int entry_id,
+ enum tf_dir dir,
+ enum cfa_tcam_mgr_tbl_type type);
+
+void
+cfa_tcam_mgr_sessions_dump(void);
+void
+cfa_tcam_mgr_entry_sessions_dump(int sess_idx, uint16_t id);
+void
+cfa_tcam_mgr_session_entries_dump(int sess_idx);
+
+void
+cfa_tcam_mgr_mv_session_used_entries_cnt(int sess_idx, enum tf_dir dir,
+ enum cfa_tcam_mgr_tbl_type dst_type,
+ enum cfa_tcam_mgr_tbl_type src_type);
+#endif /* CFA_TCAM_MGR_SESSION_H */
diff --git a/drivers/net/bnxt/tf_core/meson.build b/drivers/net/bnxt/tf_core/meson.build
index f812e471d1..ae44aa34cf 100644
--- a/drivers/net/bnxt/tf_core/meson.build
+++ b/drivers/net/bnxt/tf_core/meson.build
@@ -1,36 +1,42 @@
# SPDX-License-Identifier: BSD-3-Clause
# Copyright(c) 2018 Intel Corporation
-# Copyright(c) 2021 Broadcom
+# Copyright(c) 2023 Broadcom
#Include the folder for headers
includes += include_directories('.')
#Add the source files
sources += files(
- 'tf_core.c',
'bitalloc.c',
- 'tf_msg.c',
- 'll.c',
+ 'cfa_tcam_mgr.c',
+ 'cfa_tcam_mgr_hwop_msg.c',
+ 'cfa_tcam_mgr_p4.c',
+ 'cfa_tcam_mgr_p58.c',
+ 'cfa_tcam_mgr_session.c',
'dpool.c',
+ 'll.c',
'rand.c',
'stack.c',
- 'tf_rm.c',
- 'tf_tbl.c',
- 'tf_tbl_sram.c',
- 'tf_sram_mgr.c',
+ 'tf_core.c',
+ 'tf_device.c',
+ 'tf_device_p4.c',
+ 'tf_device_p58.c',
'tf_em_common.c',
+ 'tf_em_hash_internal.c',
'tf_em_host.c',
'tf_em_internal.c',
- 'tf_em_hash_internal.c',
- 'tfp.c',
- 'tf_util.c',
- 'tf_device.c',
- 'tf_device_p4.c',
'tf_global_cfg.c',
+ 'tf_hash.c',
'tf_identifier.c',
'tf_if_tbl.c',
+ 'tf_msg.c',
+ 'tfp.c',
+ 'tf_rm.c',
'tf_session.c',
+ 'tf_sram_mgr.c',
+ 'tf_tbl.c',
+ 'tf_tbl_sram.c',
'tf_tcam.c',
+ 'tf_tcam_mgr_msg.c',
'tf_tcam_shared.c',
- 'tf_hash.c',
- 'tf_device_p58.c')
+ 'tf_util.c')
diff --git a/drivers/net/bnxt/tf_core/tf_core.c b/drivers/net/bnxt/tf_core/tf_core.c
index 038e439101..3a812bee3a 100644
--- a/drivers/net/bnxt/tf_core/tf_core.c
+++ b/drivers/net/bnxt/tf_core/tf_core.c
@@ -1,5 +1,5 @@
/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2019-2021 Broadcom
+ * Copyright(c) 2019-2023 Broadcom
* All rights reserved.
*/
@@ -34,8 +34,8 @@ tf_open_session(struct tf *tfp,
* side. It is assumed that the Firmware will be supported if
* firmware open session succeeds.
*/
- if (parms->device_type != TF_DEVICE_TYPE_WH &&
- parms->device_type != TF_DEVICE_TYPE_THOR &&
+ if (parms->device_type != TF_DEVICE_TYPE_P4 &&
+ parms->device_type != TF_DEVICE_TYPE_P5 &&
parms->device_type != TF_DEVICE_TYPE_SR) {
TFP_DRV_LOG(ERR,
"Unsupported device type %d\n",
@@ -83,7 +83,7 @@ tf_open_session(struct tf *tfp,
return rc;
TFP_DRV_LOG(INFO,
- "domain:%d, bus:%d, device:%u\n",
+ "domain:%x, bus:%x, device:%u\n",
parms->session_id.internal.domain,
parms->session_id.internal.bus,
parms->session_id.internal.device);
@@ -176,7 +176,7 @@ tf_close_session(struct tf *tfp)
return rc;
TFP_DRV_LOG(INFO,
- "domain:%d, bus:%d, device:%d\n",
+ "domain:%d, bus:%x, device:%d\n",
cparms.session_id->internal.domain,
cparms.session_id->internal.bus,
cparms.session_id->internal.device);
@@ -742,7 +742,6 @@ tf_set_tcam_entry(struct tf *tfp,
memset(&sparms, 0, sizeof(struct tf_tcam_set_parms));
-
/* Retrieve the session information */
rc = tf_session_get_session(tfp, &tfs);
if (rc) {
@@ -790,6 +789,10 @@ tf_set_tcam_entry(struct tf *tfp,
strerror(-rc));
return rc;
}
+ TFP_DRV_LOG(DEBUG,
+ "%s: TCAM type %d set idx:%d key size %d result size %d\n",
+ tf_dir_2_str(parms->dir), sparms.type,
+ sparms.idx, sparms.key_size, sparms.result_size);
return 0;
}
@@ -807,7 +810,6 @@ tf_get_tcam_entry(struct tf *tfp __rte_unused,
memset(&gparms, 0, sizeof(struct tf_tcam_get_parms));
-
/* Retrieve the session information */
rc = tf_session_get_session(tfp, &tfs);
if (rc) {
@@ -1812,8 +1814,8 @@ int tf_get_version(struct tf *tfp,
/* This function can be called before open session, filter
* out any non-supported device types on the Core side.
*/
- if (parms->device_type != TF_DEVICE_TYPE_WH &&
- parms->device_type != TF_DEVICE_TYPE_THOR &&
+ if (parms->device_type != TF_DEVICE_TYPE_P4 &&
+ parms->device_type != TF_DEVICE_TYPE_P5 &&
parms->device_type != TF_DEVICE_TYPE_SR) {
TFP_DRV_LOG(ERR,
"Unsupported device type %d\n",
@@ -1845,7 +1847,7 @@ int tf_query_sram_resources(struct tf *tfp,
/* This function can be called before open session, filter
* out any non-supported device types on the Core side.
*/
- if (parms->device_type != TF_DEVICE_TYPE_THOR) {
+ if (parms->device_type != TF_DEVICE_TYPE_P5) {
TFP_DRV_LOG(ERR,
"Unsupported device type %d\n",
parms->device_type);
@@ -1927,7 +1929,7 @@ int tf_set_sram_policy(struct tf *tfp,
/* This function can be called before open session, filter
* out any non-supported device types on the Core side.
*/
- if (parms->device_type != TF_DEVICE_TYPE_THOR) {
+ if (parms->device_type != TF_DEVICE_TYPE_P5) {
TFP_DRV_LOG(ERR,
"Unsupported device type %d\n",
parms->device_type);
@@ -1968,7 +1970,7 @@ int tf_get_sram_policy(struct tf *tfp,
/* This function can be called before open session, filter
* out any non-supported device types on the Core side.
*/
- if (parms->device_type != TF_DEVICE_TYPE_THOR) {
+ if (parms->device_type != TF_DEVICE_TYPE_P5) {
TFP_DRV_LOG(ERR,
"Unsupported device type %d\n",
parms->device_type);
@@ -1997,3 +1999,31 @@ int tf_get_sram_policy(struct tf *tfp,
return rc;
}
+
+int tf_set_session_hotup_state(struct tf *tfp,
+ struct tf_set_session_hotup_state_parms *parms)
+{
+ int rc = 0;
+
+ TF_CHECK_PARMS1(tfp);
+
+ rc = tf_session_set_hotup_state(tfp, parms);
+ if (rc)
+ return rc;
+
+ return rc;
+}
+
+int tf_get_session_hotup_state(struct tf *tfp,
+ struct tf_get_session_hotup_state_parms *parms)
+{
+ int rc = 0;
+
+ TF_CHECK_PARMS1(tfp);
+
+ rc = tf_session_get_hotup_state(tfp, parms);
+ if (rc)
+ return rc;
+
+ return rc;
+}
diff --git a/drivers/net/bnxt/tf_core/tf_core.h b/drivers/net/bnxt/tf_core/tf_core.h
index f5fe0a9098..3da1d2a5ca 100644
--- a/drivers/net/bnxt/tf_core/tf_core.h
+++ b/drivers/net/bnxt/tf_core/tf_core.h
@@ -1,5 +1,5 @@
/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2019-2021 Broadcom
+ * Copyright(c) 2019-2023 Broadcom
* All rights reserved.
*/
@@ -112,6 +112,10 @@ enum tf_sram_bank_id {
* @ref tf_attach_session
*
* @ref tf_close_session
+ *
+ * @ref tf_get_session_info
+ *
+ * @ref tf_get_session_info
*/
/**
@@ -188,10 +192,10 @@ struct tf_session_version {
* Session supported device types
*/
enum tf_device_type {
- TF_DEVICE_TYPE_WH = 0, /**< Whitney+ */
- TF_DEVICE_TYPE_SR, /**< Stingray */
- TF_DEVICE_TYPE_THOR, /**< Thor */
- TF_DEVICE_TYPE_MAX /**< Maximum */
+ TF_DEVICE_TYPE_P4 = 0,
+ TF_DEVICE_TYPE_SR,
+ TF_DEVICE_TYPE_P5,
+ TF_DEVICE_TYPE_MAX
};
/**
@@ -286,6 +290,8 @@ enum tf_tbl_type {
TF_TBL_TYPE_ACT_ENCAP_32B,
/** Wh+/SR/TH Action Encap 64 Bytes */
TF_TBL_TYPE_ACT_ENCAP_64B,
+ /* TH Action Encap 128 Bytes */
+ TF_TBL_TYPE_ACT_ENCAP_128B,
/** WH+/SR/TH Action Source Properties SMAC */
TF_TBL_TYPE_ACT_SP_SMAC,
/** Wh+/SR/TH Action Source Properties SMAC IPv4 */
@@ -331,7 +337,7 @@ enum tf_tbl_type {
* External table type - initially 1 poolsize entries.
* All External table types are associated with a table
* scope. Internal types are not. Currently this is
- * a pool of 64B entries.
+ * a pool of 128B entries.
*/
TF_TBL_TYPE_EXT,
TF_TBL_TYPE_MAX
@@ -914,6 +920,71 @@ int tf_attach_session(struct tf *tfp,
*/
int tf_close_session(struct tf *tfp);
+/**
+ * tf_set_session_hotup_state parameter definition.
+ */
+struct tf_set_session_hotup_state_parms {
+ /**
+ * [in] the structure is used to set the state of
+ * the hotup shared session.
+ *
+ */
+ uint16_t state;
+};
+
+/**
+ * set hot upgrade shared session state
+ *
+ * This API is used to set the state of the shared session.
+ *
+ * [in] tfp
+ * Pointer to TF handle
+ *
+ * [in] parms
+ * Pointer to set hotup state parameters
+ *
+ * Returns
+ * - (0) if successful.
+ * - (-EINVAL) on failure.
+ */
+int tf_set_session_hotup_state(struct tf *tfp,
+ struct tf_set_session_hotup_state_parms *parms);
+
+/**
+ * tf_get_session_hotup_state parameter definition.
+ */
+struct tf_get_session_hotup_state_parms {
+ /**
+ * [out] the structure is used to get the state of
+ * the hotup shared session.
+ *
+ */
+ uint16_t state;
+ /**
+ * [out] get the ref_cnt of the hotup shared session.
+ *
+ */
+ uint16_t ref_cnt;
+};
+
+/**
+ * get hot upgrade shared session state
+ *
+ * This API is used to set the state of the shared session.
+ *
+ * [in] tfp
+ * Pointer to TF handle
+ *
+ * [in] parms
+ * Pointer to get hotup state parameters
+ *
+ * Returns
+ * - (0) if successful.
+ * - (-EINVAL) on failure.
+ */
+int tf_get_session_hotup_state(struct tf *tfp,
+ struct tf_get_session_hotup_state_parms *parms);
+
/**
* @page ident Identity Management
*
@@ -1192,8 +1263,6 @@ int tf_free_tbl_scope(struct tf *tfp,
*
* @ref tf_get_tcam_entry
*
- * @ref tf_free_tcam_entry
- *
* @ref tf_move_tcam_shared_entries
*
* @ref tf_clear_tcam_shared_entries
@@ -1258,7 +1327,7 @@ struct tf_search_tcam_entry_parms {
};
/**
- * search TCAM entry (experimental)
+ * search TCAM entry
*
* Search for a TCAM entry
*
@@ -1732,7 +1801,7 @@ struct tf_get_shared_tbl_increment_parms {
* tf_get_shared_tbl_increment
*
* This API is currently only required for use in the shared
- * session for Thor (p58) actions. An increment count is returned per
+ * session for P5 actions. An increment count is returned per
* type to indicate how much to increment the start by for each
* entry (see tf_resource_info)
*
@@ -1898,6 +1967,7 @@ struct tf_insert_em_entry_parms {
*/
uint64_t flow_id;
};
+
/**
* tf_delete_em_entry parameter definition
*/
@@ -1927,6 +1997,7 @@ struct tf_delete_em_entry_parms {
*/
uint64_t flow_handle;
};
+
/**
* tf_move_em_entry parameter definition
*/
@@ -1969,6 +2040,7 @@ struct tf_move_em_entry_parms {
*/
uint64_t flow_handle;
};
+
/**
* tf_search_em_entry parameter definition (Future)
*/
@@ -2108,6 +2180,7 @@ int tf_search_em_entry(struct tf *tfp,
*
* @ref tf_get_global_cfg
*/
+
/**
* Tunnel Encapsulation Offsets
*/
@@ -2121,6 +2194,7 @@ enum tf_tunnel_encap_offsets {
TF_TUNNEL_ENCAP_GRE,
TF_TUNNEL_ENCAP_FULL_GENERIC
};
+
/**
* Global Configuration Table Types
*/
@@ -2193,9 +2267,8 @@ int tf_set_global_cfg(struct tf *tfp,
* @ref tf_set_if_tbl_entry
*
* @ref tf_get_if_tbl_entry
- *
- * @ref tf_restore_if_tbl_entry
*/
+
/**
* Enumeration of TruFlow interface table types.
*/
diff --git a/drivers/net/bnxt/tf_core/tf_device.c b/drivers/net/bnxt/tf_core/tf_device.c
index 1c97218b5b..02a9ebd7b2 100644
--- a/drivers/net/bnxt/tf_core/tf_device.c
+++ b/drivers/net/bnxt/tf_core/tf_device.c
@@ -1,5 +1,5 @@
/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2019-2021 Broadcom
+ * Copyright(c) 2019-2023 Broadcom
* All rights reserved.
*/
@@ -332,7 +332,7 @@ tf_dev_unbind_p4(struct tf *tfp)
}
/**
- * Device specific bind function, THOR
+ * Device specific bind function, P5
*
* [in] tfp
* Pointer to TF handle
@@ -504,7 +504,7 @@ tf_dev_bind_p58(struct tf *tfp,
}
/**
- * Device specific unbind function, THOR
+ * Device specific unbind function, P5
*
* [in] tfp
* Pointer to TF handle
@@ -602,14 +602,14 @@ tf_dev_bind(struct tf *tfp __rte_unused,
struct tf_dev_info *dev_handle)
{
switch (type) {
- case TF_DEVICE_TYPE_WH:
+ case TF_DEVICE_TYPE_P4:
case TF_DEVICE_TYPE_SR:
dev_handle->type = type;
return tf_dev_bind_p4(tfp,
resources,
dev_handle,
wc_num_slices);
- case TF_DEVICE_TYPE_THOR:
+ case TF_DEVICE_TYPE_P5:
dev_handle->type = type;
return tf_dev_bind_p58(tfp,
resources,
@@ -627,11 +627,11 @@ tf_dev_bind_ops(enum tf_device_type type,
struct tf_dev_info *dev_handle)
{
switch (type) {
- case TF_DEVICE_TYPE_WH:
+ case TF_DEVICE_TYPE_P4:
case TF_DEVICE_TYPE_SR:
dev_handle->ops = &tf_dev_ops_p4_init;
break;
- case TF_DEVICE_TYPE_THOR:
+ case TF_DEVICE_TYPE_P5:
dev_handle->ops = &tf_dev_ops_p58_init;
break;
default:
@@ -648,10 +648,10 @@ tf_dev_unbind(struct tf *tfp,
struct tf_dev_info *dev_handle)
{
switch (dev_handle->type) {
- case TF_DEVICE_TYPE_WH:
+ case TF_DEVICE_TYPE_P4:
case TF_DEVICE_TYPE_SR:
return tf_dev_unbind_p4(tfp);
- case TF_DEVICE_TYPE_THOR:
+ case TF_DEVICE_TYPE_P5:
return tf_dev_unbind_p58(tfp);
default:
TFP_DRV_LOG(ERR,
diff --git a/drivers/net/bnxt/tf_core/tf_device.h b/drivers/net/bnxt/tf_core/tf_device.h
index 5a42180719..06c17a7212 100644
--- a/drivers/net/bnxt/tf_core/tf_device.h
+++ b/drivers/net/bnxt/tf_core/tf_device.h
@@ -1,5 +1,5 @@
/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2019-2021 Broadcom
+ * Copyright(c) 2019-2023 Broadcom
* All rights reserved.
*/
diff --git a/drivers/net/bnxt/tf_core/tf_device_p4.c b/drivers/net/bnxt/tf_core/tf_device_p4.c
index 72c6b1cde8..911ea92471 100644
--- a/drivers/net/bnxt/tf_core/tf_device_p4.c
+++ b/drivers/net/bnxt/tf_core/tf_device_p4.c
@@ -1,5 +1,5 @@
/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2019-2021 Broadcom
+ * Copyright(c) 2019-2023 Broadcom
* All rights reserved.
*/
@@ -296,11 +296,15 @@ tf_dev_p4_get_tcam_slice_info(struct tf *tfp,
return rc;
/* Single slice support */
-#define CFA_P4_WC_TCAM_SLICE_SIZE 12
-
+#define CFA_P4_WC_TCAM_SLICE_SIZE (12)
if (type == TF_TCAM_TBL_TYPE_WC_TCAM) {
- *num_slices_per_row = tfs->wc_num_slices_per_row;
- if (key_sz > *num_slices_per_row * CFA_P4_WC_TCAM_SLICE_SIZE)
+ if (key_sz <= 1 * CFA_P4_WC_TCAM_SLICE_SIZE)
+ *num_slices_per_row = TF_WC_TCAM_1_SLICE_PER_ROW;
+ else if (key_sz <= 2 * CFA_P4_WC_TCAM_SLICE_SIZE)
+ *num_slices_per_row = TF_WC_TCAM_2_SLICE_PER_ROW;
+ else if (key_sz <= 4 * CFA_P4_WC_TCAM_SLICE_SIZE)
+ *num_slices_per_row = TF_WC_TCAM_4_SLICE_PER_ROW;
+ else
return -ENOTSUP;
} else { /* for other type of tcam */
*num_slices_per_row = 1;
diff --git a/drivers/net/bnxt/tf_core/tf_device_p58.c b/drivers/net/bnxt/tf_core/tf_device_p58.c
index f8b424ebc9..6916c50fdc 100644
--- a/drivers/net/bnxt/tf_core/tf_device_p58.c
+++ b/drivers/net/bnxt/tf_core/tf_device_p58.c
@@ -1,5 +1,5 @@
/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2019-2021 Broadcom
+ * Copyright(c) 2019-2023 Broadcom
* All rights reserved.
*/
@@ -16,6 +16,7 @@
#include "tfp.h"
#include "tf_msg_common.h"
#include "tf_tbl_sram.h"
+#include "tf_util.h"
#define TF_DEV_P58_PARIF_MAX 16
#define TF_DEV_P58_PF_MASK 0xfUL
@@ -79,33 +80,39 @@ struct tf_rm_element_cfg tf_tbl_p58[TF_DIR_MAX][TF_TBL_TYPE_MAX] = {
[TF_DIR_RX][TF_TBL_TYPE_FULL_ACT_RECORD] = {
.cfg_type = TF_RM_ELEM_CFG_HCAPI_BA_PARENT,
.hcapi_type = CFA_RESOURCE_TYPE_P58_SRAM_BANK_1,
- .slices = 4,
+ .slices = 8,
},
[TF_DIR_RX][TF_TBL_TYPE_COMPACT_ACT_RECORD] = {
.cfg_type = TF_RM_ELEM_CFG_HCAPI_BA_CHILD,
.parent_subtype = TF_TBL_TYPE_FULL_ACT_RECORD,
.hcapi_type = CFA_RESOURCE_TYPE_P58_SRAM_BANK_1,
- .slices = 8,
+ .slices = 16,
},
/* Policy - Encaps in bank 2 */
[TF_DIR_RX][TF_TBL_TYPE_ACT_ENCAP_8B] = {
.cfg_type = TF_RM_ELEM_CFG_HCAPI_BA_PARENT,
.hcapi_type = CFA_RESOURCE_TYPE_P58_SRAM_BANK_2,
- .slices = 8,
+ .slices = 16,
},
[TF_DIR_RX][TF_TBL_TYPE_ACT_ENCAP_16B] = {
.cfg_type = TF_RM_ELEM_CFG_HCAPI_BA_CHILD,
.parent_subtype = TF_TBL_TYPE_ACT_ENCAP_8B,
.hcapi_type = CFA_RESOURCE_TYPE_P58_SRAM_BANK_2,
- .slices = 4,
+ .slices = 8,
},
[TF_DIR_RX][TF_TBL_TYPE_ACT_ENCAP_32B] = {
.cfg_type = TF_RM_ELEM_CFG_HCAPI_BA_CHILD,
.parent_subtype = TF_TBL_TYPE_ACT_ENCAP_8B,
.hcapi_type = CFA_RESOURCE_TYPE_P58_SRAM_BANK_2,
- .slices = 2,
+ .slices = 4,
},
[TF_DIR_RX][TF_TBL_TYPE_ACT_ENCAP_64B] = {
+ .cfg_type = TF_RM_ELEM_CFG_HCAPI_BA_CHILD,
+ .parent_subtype = TF_TBL_TYPE_ACT_ENCAP_8B,
+ .hcapi_type = CFA_RESOURCE_TYPE_P58_SRAM_BANK_2,
+ .slices = 2,
+ },
+ [TF_DIR_RX][TF_TBL_TYPE_ACT_ENCAP_128B] = {
.cfg_type = TF_RM_ELEM_CFG_HCAPI_BA_CHILD,
.parent_subtype = TF_TBL_TYPE_ACT_ENCAP_8B,
.hcapi_type = CFA_RESOURCE_TYPE_P58_SRAM_BANK_2,
@@ -116,49 +123,49 @@ struct tf_rm_element_cfg tf_tbl_p58[TF_DIR_MAX][TF_TBL_TYPE_MAX] = {
.cfg_type = TF_RM_ELEM_CFG_HCAPI_BA_CHILD,
.parent_subtype = TF_TBL_TYPE_ACT_ENCAP_8B,
.hcapi_type = CFA_RESOURCE_TYPE_P58_SRAM_BANK_2,
- .slices = 8,
+ .slices = 16,
},
[TF_DIR_RX][TF_TBL_TYPE_ACT_MODIFY_16B] = {
.cfg_type = TF_RM_ELEM_CFG_HCAPI_BA_CHILD,
.parent_subtype = TF_TBL_TYPE_ACT_ENCAP_8B,
.hcapi_type = CFA_RESOURCE_TYPE_P58_SRAM_BANK_2,
- .slices = 4,
+ .slices = 8,
},
[TF_DIR_RX][TF_TBL_TYPE_ACT_MODIFY_32B] = {
.cfg_type = TF_RM_ELEM_CFG_HCAPI_BA_CHILD,
.parent_subtype = TF_TBL_TYPE_ACT_ENCAP_8B,
.hcapi_type = CFA_RESOURCE_TYPE_P58_SRAM_BANK_2,
- .slices = 2,
+ .slices = 4,
},
[TF_DIR_RX][TF_TBL_TYPE_ACT_MODIFY_64B] = {
.cfg_type = TF_RM_ELEM_CFG_HCAPI_BA_CHILD,
.parent_subtype = TF_TBL_TYPE_ACT_ENCAP_8B,
.hcapi_type = CFA_RESOURCE_TYPE_P58_SRAM_BANK_2,
- .slices = 1,
+ .slices = 2,
},
/* Policy - SP in bank 0 */
[TF_DIR_RX][TF_TBL_TYPE_ACT_SP_SMAC] = {
.cfg_type = TF_RM_ELEM_CFG_HCAPI_BA_PARENT,
.hcapi_type = CFA_RESOURCE_TYPE_P58_SRAM_BANK_0,
- .slices = 8,
+ .slices = 16,
},
[TF_DIR_RX][TF_TBL_TYPE_ACT_SP_SMAC_IPV4] = {
.cfg_type = TF_RM_ELEM_CFG_HCAPI_BA_CHILD,
.parent_subtype = TF_TBL_TYPE_ACT_SP_SMAC,
.hcapi_type = CFA_RESOURCE_TYPE_P58_SRAM_BANK_0,
- .slices = 4,
+ .slices = 8,
},
[TF_DIR_RX][TF_TBL_TYPE_ACT_SP_SMAC_IPV6] = {
.cfg_type = TF_RM_ELEM_CFG_HCAPI_BA_CHILD,
.parent_subtype = TF_TBL_TYPE_ACT_SP_SMAC,
.hcapi_type = CFA_RESOURCE_TYPE_P58_SRAM_BANK_0,
- .slices = 2,
+ .slices = 4,
},
/* Policy - Stats in bank 3 */
[TF_DIR_RX][TF_TBL_TYPE_ACT_STATS_64] = {
.cfg_type = TF_RM_ELEM_CFG_HCAPI_BA_PARENT,
.hcapi_type = CFA_RESOURCE_TYPE_P58_SRAM_BANK_3,
- .slices = 8,
+ .slices = 16,
},
[TF_DIR_TX][TF_TBL_TYPE_EM_FKB] = {
TF_RM_ELEM_CFG_HCAPI_BA, CFA_RESOURCE_TYPE_P58_EM_FKB,
@@ -192,33 +199,39 @@ struct tf_rm_element_cfg tf_tbl_p58[TF_DIR_MAX][TF_TBL_TYPE_MAX] = {
[TF_DIR_TX][TF_TBL_TYPE_FULL_ACT_RECORD] = {
.cfg_type = TF_RM_ELEM_CFG_HCAPI_BA_PARENT,
.hcapi_type = CFA_RESOURCE_TYPE_P58_SRAM_BANK_1,
- .slices = 4,
+ .slices = 8,
},
[TF_DIR_TX][TF_TBL_TYPE_COMPACT_ACT_RECORD] = {
.cfg_type = TF_RM_ELEM_CFG_HCAPI_BA_CHILD,
.parent_subtype = TF_TBL_TYPE_FULL_ACT_RECORD,
.hcapi_type = CFA_RESOURCE_TYPE_P58_SRAM_BANK_1,
- .slices = 8,
+ .slices = 16,
},
/* Policy - Encaps in bank 2 */
[TF_DIR_TX][TF_TBL_TYPE_ACT_ENCAP_8B] = {
.cfg_type = TF_RM_ELEM_CFG_HCAPI_BA_PARENT,
.hcapi_type = CFA_RESOURCE_TYPE_P58_SRAM_BANK_2,
- .slices = 8,
+ .slices = 16,
},
[TF_DIR_TX][TF_TBL_TYPE_ACT_ENCAP_16B] = {
.cfg_type = TF_RM_ELEM_CFG_HCAPI_BA_CHILD,
.parent_subtype = TF_TBL_TYPE_ACT_ENCAP_8B,
.hcapi_type = CFA_RESOURCE_TYPE_P58_SRAM_BANK_2,
- .slices = 4,
+ .slices = 8,
},
[TF_DIR_TX][TF_TBL_TYPE_ACT_ENCAP_32B] = {
.cfg_type = TF_RM_ELEM_CFG_HCAPI_BA_CHILD,
.parent_subtype = TF_TBL_TYPE_ACT_ENCAP_8B,
.hcapi_type = CFA_RESOURCE_TYPE_P58_SRAM_BANK_2,
- .slices = 2,
+ .slices = 4,
},
[TF_DIR_TX][TF_TBL_TYPE_ACT_ENCAP_64B] = {
+ .cfg_type = TF_RM_ELEM_CFG_HCAPI_BA_CHILD,
+ .parent_subtype = TF_TBL_TYPE_ACT_ENCAP_8B,
+ .hcapi_type = CFA_RESOURCE_TYPE_P58_SRAM_BANK_2,
+ .slices = 2,
+ },
+ [TF_DIR_TX][TF_TBL_TYPE_ACT_ENCAP_128B] = {
.cfg_type = TF_RM_ELEM_CFG_HCAPI_BA_CHILD,
.parent_subtype = TF_TBL_TYPE_ACT_ENCAP_8B,
.hcapi_type = CFA_RESOURCE_TYPE_P58_SRAM_BANK_2,
@@ -229,49 +242,49 @@ struct tf_rm_element_cfg tf_tbl_p58[TF_DIR_MAX][TF_TBL_TYPE_MAX] = {
.cfg_type = TF_RM_ELEM_CFG_HCAPI_BA_CHILD,
.parent_subtype = TF_TBL_TYPE_ACT_ENCAP_8B,
.hcapi_type = CFA_RESOURCE_TYPE_P58_SRAM_BANK_2,
- .slices = 8,
+ .slices = 16,
},
[TF_DIR_TX][TF_TBL_TYPE_ACT_MODIFY_16B] = {
.cfg_type = TF_RM_ELEM_CFG_HCAPI_BA_CHILD,
.parent_subtype = TF_TBL_TYPE_ACT_ENCAP_8B,
.hcapi_type = CFA_RESOURCE_TYPE_P58_SRAM_BANK_2,
- .slices = 4,
+ .slices = 8,
},
[TF_DIR_TX][TF_TBL_TYPE_ACT_MODIFY_32B] = {
.cfg_type = TF_RM_ELEM_CFG_HCAPI_BA_CHILD,
.parent_subtype = TF_TBL_TYPE_ACT_ENCAP_8B,
.hcapi_type = CFA_RESOURCE_TYPE_P58_SRAM_BANK_2,
- .slices = 2,
+ .slices = 4,
},
[TF_DIR_TX][TF_TBL_TYPE_ACT_MODIFY_64B] = {
.cfg_type = TF_RM_ELEM_CFG_HCAPI_BA_CHILD,
.parent_subtype = TF_TBL_TYPE_ACT_ENCAP_8B,
.hcapi_type = CFA_RESOURCE_TYPE_P58_SRAM_BANK_2,
- .slices = 1,
+ .slices = 2,
},
/* Policy - SP in bank 0 */
[TF_DIR_TX][TF_TBL_TYPE_ACT_SP_SMAC] = {
.cfg_type = TF_RM_ELEM_CFG_HCAPI_BA_PARENT,
.hcapi_type = CFA_RESOURCE_TYPE_P58_SRAM_BANK_0,
- .slices = 8,
+ .slices = 16,
},
[TF_DIR_TX][TF_TBL_TYPE_ACT_SP_SMAC_IPV4] = {
.cfg_type = TF_RM_ELEM_CFG_HCAPI_BA_CHILD,
.parent_subtype = TF_TBL_TYPE_ACT_SP_SMAC,
.hcapi_type = CFA_RESOURCE_TYPE_P58_SRAM_BANK_0,
- .slices = 4,
+ .slices = 8,
},
[TF_DIR_TX][TF_TBL_TYPE_ACT_SP_SMAC_IPV6] = {
.cfg_type = TF_RM_ELEM_CFG_HCAPI_BA_CHILD,
.parent_subtype = TF_TBL_TYPE_ACT_SP_SMAC,
.hcapi_type = CFA_RESOURCE_TYPE_P58_SRAM_BANK_0,
- .slices = 2,
+ .slices = 4,
},
/* Policy - Stats in bank 3 */
[TF_DIR_TX][TF_TBL_TYPE_ACT_STATS_64] = {
.cfg_type = TF_RM_ELEM_CFG_HCAPI_BA_PARENT,
.hcapi_type = CFA_RESOURCE_TYPE_P58_SRAM_BANK_3,
- .slices = 8,
+ .slices = 16,
},
};
@@ -406,10 +419,15 @@ tf_dev_p58_get_tcam_slice_info(struct tf *tfp,
if (rc)
return rc;
-#define CFA_P58_WC_TCAM_SLICE_SIZE 24
+#define CFA_P58_WC_TCAM_SLICE_SIZE (24)
if (type == TF_TCAM_TBL_TYPE_WC_TCAM) {
- *num_slices_per_row = tfs->wc_num_slices_per_row;
- if (key_sz > *num_slices_per_row * CFA_P58_WC_TCAM_SLICE_SIZE)
+ if (key_sz <= 1 * CFA_P58_WC_TCAM_SLICE_SIZE)
+ *num_slices_per_row = TF_WC_TCAM_1_SLICE_PER_ROW;
+ else if (key_sz <= 2 * CFA_P58_WC_TCAM_SLICE_SIZE)
+ *num_slices_per_row = TF_WC_TCAM_2_SLICE_PER_ROW;
+ else if (key_sz <= 4 * CFA_P58_WC_TCAM_SLICE_SIZE)
+ *num_slices_per_row = TF_WC_TCAM_4_SLICE_PER_ROW;
+ else
return -ENOTSUP;
} else { /* for other type of tcam */
*num_slices_per_row = 1;
@@ -452,6 +470,7 @@ static int tf_dev_p58_get_shared_tbl_increment(struct tf *tfp __rte_unused,
case TF_TBL_TYPE_ACT_ENCAP_16B:
case TF_TBL_TYPE_ACT_ENCAP_32B:
case TF_TBL_TYPE_ACT_ENCAP_64B:
+ case TF_TBL_TYPE_ACT_ENCAP_128B:
case TF_TBL_TYPE_ACT_SP_SMAC:
case TF_TBL_TYPE_ACT_SP_SMAC_IPV4:
case TF_TBL_TYPE_ACT_SP_SMAC_IPV6:
@@ -461,7 +480,7 @@ static int tf_dev_p58_get_shared_tbl_increment(struct tf *tfp __rte_unused,
case TF_TBL_TYPE_ACT_MODIFY_16B:
case TF_TBL_TYPE_ACT_MODIFY_32B:
case TF_TBL_TYPE_ACT_MODIFY_64B:
- parms->increment_cnt = 8;
+ parms->increment_cnt = 16;
break;
default:
parms->increment_cnt = 1;
@@ -493,6 +512,7 @@ static bool tf_dev_p58_is_sram_managed(struct tf *tfp __rte_unused,
case TF_TBL_TYPE_ACT_ENCAP_16B:
case TF_TBL_TYPE_ACT_ENCAP_32B:
case TF_TBL_TYPE_ACT_ENCAP_64B:
+ case TF_TBL_TYPE_ACT_ENCAP_128B:
case TF_TBL_TYPE_ACT_SP_SMAC:
case TF_TBL_TYPE_ACT_SP_SMAC_IPV4:
case TF_TBL_TYPE_ACT_SP_SMAC_IPV6:
@@ -527,7 +547,7 @@ static bool tf_dev_p58_is_sram_managed(struct tf *tfp __rte_unused,
*
* [in/out] shift
* Pointer to the factor to be used as a multiplier to translate
- * between the RM units to the user address. SRAM manages 64B entries
+ * between the RM units to the user address. SRAM manages 128B entries
* Addresses must be shifted to an 8B address.
*
* Returns
diff --git a/drivers/net/bnxt/tf_core/tf_em_common.c b/drivers/net/bnxt/tf_core/tf_em_common.c
index b56b7cc188..c518150d1f 100644
--- a/drivers/net/bnxt/tf_core/tf_em_common.c
+++ b/drivers/net/bnxt/tf_core/tf_em_common.c
@@ -1000,8 +1000,8 @@ tf_em_ext_common_unbind(struct tf *tfp)
strerror(-rc));
return rc;
}
- ext_db = (struct em_ext_db *)ext_ptr;
+ ext_db = (struct em_ext_db *)ext_ptr;
if (ext_db != NULL) {
entry = ext_db->tbl_scope_ll.head;
while (entry != NULL) {
diff --git a/drivers/net/bnxt/tf_core/tf_em_internal.c b/drivers/net/bnxt/tf_core/tf_em_internal.c
index 8ea5d93672..46de63a9da 100644
--- a/drivers/net/bnxt/tf_core/tf_em_internal.c
+++ b/drivers/net/bnxt/tf_core/tf_em_internal.c
@@ -7,7 +7,6 @@
#include <rte_common.h>
#include <rte_errno.h>
#include <rte_log.h>
-
#include "tf_core.h"
#include "tf_util.h"
#include "tf_common.h"
@@ -63,7 +62,6 @@ tf_em_insert_int_entry(struct tf *tfp,
return -1;
}
-
rptr_index = index;
rc = tf_msg_insert_em_internal_entry(tfp,
parms,
@@ -75,6 +73,7 @@ tf_em_insert_int_entry(struct tf *tfp,
dpool_free(pool, index);
return -1;
}
+
TF_SET_GFID(gfid,
((rptr_index << TF_EM_INTERNAL_INDEX_SHIFT) |
rptr_entry),
@@ -95,7 +94,6 @@ tf_em_insert_int_entry(struct tf *tfp,
return 0;
}
-
/** Delete EM internal entry API
*
* returns:
@@ -253,7 +251,6 @@ tf_em_int_bind(struct tf *tfp,
return db_rc[TF_DIR_RX];
}
-
if (!tf_session_is_shared_session(tfs)) {
for (i = 0; i < TF_DIR_MAX; i++) {
iparms.rm_db = em_db->em_db[i];
@@ -335,11 +332,10 @@ tf_em_int_unbind(struct tf *tfp)
}
rc = tf_session_get_db(tfp, TF_MODULE_TYPE_EM, &em_db_ptr);
- if (rc) {
+ if (rc)
return 0;
- }
- em_db = (struct em_rm_db *)em_db_ptr;
+ em_db = (struct em_rm_db *)em_db_ptr;
for (i = 0; i < TF_DIR_MAX; i++) {
if (em_db->em_db[i] == NULL)
continue;
diff --git a/drivers/net/bnxt/tf_core/tf_identifier.c b/drivers/net/bnxt/tf_core/tf_identifier.c
index 1846675916..7d9d9595dd 100644
--- a/drivers/net/bnxt/tf_core/tf_identifier.c
+++ b/drivers/net/bnxt/tf_core/tf_identifier.c
@@ -89,6 +89,7 @@ tf_ident_unbind(struct tf *tfp)
rc = tf_session_get_db(tfp, TF_MODULE_TYPE_IDENTIFIER, &ident_db_ptr);
if (rc)
return 0;
+
ident_db = (struct ident_rm_db *)ident_db_ptr;
for (i = 0; i < TF_DIR_MAX; i++) {
diff --git a/drivers/net/bnxt/tf_core/tf_if_tbl.c b/drivers/net/bnxt/tf_core/tf_if_tbl.c
index e667d6fa6d..578d361417 100644
--- a/drivers/net/bnxt/tf_core/tf_if_tbl.c
+++ b/drivers/net/bnxt/tf_core/tf_if_tbl.c
@@ -1,5 +1,5 @@
/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2019-2021 Broadcom
+ * Copyright(c) 2019-2023 Broadcom
* All rights reserved.
*/
@@ -21,12 +21,6 @@ struct tf_if_tbl_db {
struct tf_if_tbl_cfg *if_tbl_cfg_db[TF_DIR_MAX];
};
-/**
- * Init flag, set on bind and cleared on unbind
- * TODO: Store this data in session db
- */
-static uint8_t init;
-
/**
* Convert if_tbl_type to hwrm type.
*
@@ -80,8 +74,6 @@ tf_if_tbl_bind(struct tf *tfp,
if_tbl_db->if_tbl_cfg_db[TF_DIR_TX] = parms->cfg;
tf_session_set_if_tbl_db(tfp, (void *)if_tbl_db);
- init = 1;
-
TFP_DRV_LOG(INFO,
"Table Type - initialized\n");
@@ -92,14 +84,7 @@ int
tf_if_tbl_unbind(struct tf *tfp)
{
int rc;
- struct tf_if_tbl_db *if_tbl_db_ptr;
-
- /* Bail if nothing has been initialized */
- if (!init) {
- TFP_DRV_LOG(INFO,
- "No Table DBs created\n");
- return 0;
- }
+ struct tf_if_tbl_db *if_tbl_db_ptr = NULL;
TF_CHECK_PARMS1(tfp);
@@ -108,9 +93,15 @@ tf_if_tbl_unbind(struct tf *tfp)
TFP_DRV_LOG(INFO, "No IF Table DBs initialized\n");
return 0;
}
+ /* Bail if nothing has been initialized */
+ if (!if_tbl_db_ptr) {
+ TFP_DRV_LOG(INFO,
+ "No Table DBs created\n");
+ return 0;
+ }
tfp_free((void *)if_tbl_db_ptr);
- init = 0;
+ tf_session_set_if_tbl_db(tfp, NULL);
return 0;
}
@@ -120,24 +111,24 @@ tf_if_tbl_set(struct tf *tfp,
struct tf_if_tbl_set_parms *parms)
{
int rc;
- struct tf_if_tbl_db *if_tbl_db_ptr;
+ struct tf_if_tbl_db *if_tbl_db_ptr = NULL;
struct tf_if_tbl_get_hcapi_parms hparms;
TF_CHECK_PARMS3(tfp, parms, parms->data);
- if (!init) {
- TFP_DRV_LOG(ERR,
- "%s: No Table DBs created\n",
- tf_dir_2_str(parms->dir));
- return -EINVAL;
- }
-
rc = tf_session_get_if_tbl_db(tfp, (void **)&if_tbl_db_ptr);
if (rc) {
TFP_DRV_LOG(INFO, "No IF Table DBs initialized\n");
return 0;
}
+ if (!if_tbl_db_ptr) {
+ TFP_DRV_LOG(ERR,
+ "%s: No Table DBs created\n",
+ tf_dir_2_str(parms->dir));
+ return -EINVAL;
+ }
+
/* Convert TF type to HCAPI type */
hparms.tbl_db = if_tbl_db_ptr->if_tbl_cfg_db[parms->dir];
hparms.db_index = parms->type;
@@ -163,24 +154,24 @@ tf_if_tbl_get(struct tf *tfp,
struct tf_if_tbl_get_parms *parms)
{
int rc = 0;
- struct tf_if_tbl_db *if_tbl_db_ptr;
+ struct tf_if_tbl_db *if_tbl_db_ptr = NULL;
struct tf_if_tbl_get_hcapi_parms hparms;
TF_CHECK_PARMS3(tfp, parms, parms->data);
- if (!init) {
- TFP_DRV_LOG(ERR,
- "%s: No Table DBs created\n",
- tf_dir_2_str(parms->dir));
- return -EINVAL;
- }
-
rc = tf_session_get_if_tbl_db(tfp, (void **)&if_tbl_db_ptr);
if (rc) {
TFP_DRV_LOG(INFO, "No IF Table DBs initialized\n");
return 0;
}
+ if (!if_tbl_db_ptr) {
+ TFP_DRV_LOG(ERR,
+ "%s: No Table DBs created\n",
+ tf_dir_2_str(parms->dir));
+ return -EINVAL;
+ }
+
/* Convert TF type to HCAPI type */
hparms.tbl_db = if_tbl_db_ptr->if_tbl_cfg_db[parms->dir];
hparms.db_index = parms->type;
diff --git a/drivers/net/bnxt/tf_core/tf_msg.c b/drivers/net/bnxt/tf_core/tf_msg.c
index fbc96d374c..1c66c7e01a 100644
--- a/drivers/net/bnxt/tf_core/tf_msg.c
+++ b/drivers/net/bnxt/tf_core/tf_msg.c
@@ -1,5 +1,5 @@
/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2019-2021 Broadcom
+ * Copyright(c) 2019-2023 Broadcom
* All rights reserved.
*/
@@ -47,7 +47,6 @@ static_assert(sizeof(struct hwrm_tf_global_cfg_set_input) ==
static_assert(sizeof(struct hwrm_tf_em_insert_input) ==
TF_MSG_SIZE_HWRM_TF_EM_INSERT,
"HWRM message size changed: hwrm_tf_em_insert_input");
-
#define TF_MSG_SIZE_HWRM_TF_TBL_TYPE_SET 128
static_assert(sizeof(struct hwrm_tf_tbl_type_set_input) ==
TF_MSG_SIZE_HWRM_TF_TBL_TYPE_SET,
@@ -61,13 +60,18 @@ static_assert(sizeof(struct hwrm_tf_tbl_type_set_input) ==
/**
* This is the length of shared session name "tf_share"
*/
-#define TF_SHARED_SESSION_NAME_LEN 8
+#define TF_SHARED_SESSION_NAME_LEN 9
/**
* This is the length of tcam shared session name "tf_shared-wc_tcam"
*/
#define TF_TCAM_SHARED_SESSION_NAME_LEN 17
+/**
+ * This is the length of tcam shared session name "tf_shared-poolx"
+ */
+#define TF_POOL_SHARED_SESSION_NAME_LEN 16
+
/**
* If data bigger than TF_PCI_BUF_SIZE_MAX then use DMA method
*/
@@ -135,18 +139,30 @@ tf_msg_session_open(struct bnxt *bp,
struct hwrm_tf_session_open_input req = { 0 };
struct hwrm_tf_session_open_output resp = { 0 };
struct tfp_send_msg_parms parms = { 0 };
- int name_len;
char *session_name;
char *tcam_session_name;
+ char *pool_session_name;
- /* Populate the request */
- name_len = strnlen(ctrl_chan_name, TF_SESSION_NAME_MAX);
- session_name = &ctrl_chan_name[name_len - strlen("tf_shared")];
- tcam_session_name = &ctrl_chan_name[name_len - strlen("tf_shared-wc_tcam")];
- if (!strncmp(tcam_session_name, "tf_shared-wc_tcam", strlen("tf_shared-wc_tcam")))
- tfp_memcpy(&req.session_name, tcam_session_name, TF_TCAM_SHARED_SESSION_NAME_LEN);
- else if (!strncmp(session_name, "tf_shared", strlen("tf_shared")))
- tfp_memcpy(&req.session_name, session_name, TF_SHARED_SESSION_NAME_LEN);
+ /*
+ * "tf_shared-wc_tcam" is defined for tf_fw version 1.0.0.
+ * "tf_shared-pool" is defined for version 1.0.1.
+ * "tf_shared" is used by both verions.
+ */
+ tcam_session_name = strstr(ctrl_chan_name, "tf_shared-wc_tcam");
+ pool_session_name = strstr(ctrl_chan_name, "tf_shared-pool");
+ session_name = strstr(ctrl_chan_name, "tf_shared");
+ if (tcam_session_name)
+ tfp_memcpy(&req.session_name,
+ tcam_session_name,
+ TF_TCAM_SHARED_SESSION_NAME_LEN);
+ else if (pool_session_name)
+ tfp_memcpy(&req.session_name,
+ pool_session_name,
+ TF_POOL_SHARED_SESSION_NAME_LEN);
+ else if (session_name)
+ tfp_memcpy(&req.session_name,
+ session_name,
+ TF_SHARED_SESSION_NAME_LEN);
else
tfp_memcpy(&req.session_name, ctrl_chan_name, TF_SESSION_NAME_MAX);
@@ -191,9 +207,9 @@ tf_msg_session_client_register(struct tf *tfp,
struct tfp_send_msg_parms parms = { 0 };
uint8_t fw_session_id;
struct tf_dev_info *dev;
- int name_len;
char *session_name;
char *tcam_session_name;
+ char *pool_session_name;
/* Retrieve the device information */
rc = tf_session_get_device(tfs, &dev);
@@ -214,24 +230,31 @@ tf_msg_session_client_register(struct tf *tfp,
/* Populate the request */
req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
- name_len = strnlen(ctrl_channel_name, TF_SESSION_NAME_MAX);
- session_name = &ctrl_channel_name[name_len - strlen("tf_shared")];
- tcam_session_name = &ctrl_channel_name[name_len -
- strlen("tf_shared-wc_tcam")];
- if (!strncmp(tcam_session_name,
- "tf_shared-wc_tcam",
- strlen("tf_shared-wc_tcam")))
+
+ /*
+ * "tf_shared-wc_tcam" is defined for tf_fw version 1.0.0.
+ * "tf_shared-pool" is defined for version 1.0.1.
+ * "tf_shared" is used by both verions.
+ */
+ tcam_session_name = strstr(ctrl_channel_name, "tf_shared-wc_tcam");
+ pool_session_name = strstr(ctrl_channel_name, "tf_shared-pool");
+ session_name = strstr(ctrl_channel_name, "tf_shared");
+ if (tcam_session_name)
+ tfp_memcpy(&req.session_client_name,
+ tcam_session_name,
+ TF_TCAM_SHARED_SESSION_NAME_LEN);
+ else if (pool_session_name)
tfp_memcpy(&req.session_client_name,
- tcam_session_name,
- TF_TCAM_SHARED_SESSION_NAME_LEN);
- else if (!strncmp(session_name, "tf_shared", strlen("tf_shared")))
+ pool_session_name,
+ TF_POOL_SHARED_SESSION_NAME_LEN);
+ else if (session_name)
tfp_memcpy(&req.session_client_name,
- session_name,
- TF_SHARED_SESSION_NAME_LEN);
+ session_name,
+ TF_SHARED_SESSION_NAME_LEN);
else
tfp_memcpy(&req.session_client_name,
- ctrl_channel_name,
- TF_SESSION_NAME_MAX);
+ ctrl_channel_name,
+ TF_SESSION_NAME_MAX);
parms.tf_type = HWRM_TF_SESSION_REGISTER;
parms.req_data = (uint32_t *)&req;
@@ -431,7 +454,6 @@ tf_msg_session_resc_qcaps(struct tf *tfp,
/* Post process the response */
data = (struct tf_rm_resc_req_entry *)qcaps_buf.va_addr;
-
for (i = 0; i < resp.size; i++) {
query[i].type = tfp_le_to_cpu_32(data[i].type);
query[i].min = tfp_le_to_cpu_16(data[i].min);
@@ -1757,6 +1779,7 @@ tf_msg_set_tbl_entry(struct tf *tfp,
struct hwrm_tf_tbl_type_set_input req = { 0 };
struct hwrm_tf_tbl_type_set_output resp = { 0 };
struct tfp_send_msg_parms parms = { 0 };
+ struct tf_msg_dma_buf buf = { 0 };
uint8_t fw_session_id;
struct tf_dev_info *dev;
struct tf_session *tfs;
@@ -1802,18 +1825,19 @@ tf_msg_set_tbl_entry(struct tf *tfp,
/* Check for data size conformity */
if (size > TF_MSG_TBL_TYPE_SET_DATA_SIZE) {
- rc = -EINVAL;
- TFP_DRV_LOG(ERR,
- "%s: Invalid parameters for msg type, rc:%s\n",
- tf_dir_2_str(dir),
- strerror(-rc));
- return rc;
+ /* use dma buffer */
+ req.flags |= HWRM_TF_TBL_TYPE_SET_INPUT_FLAGS_DMA;
+ rc = tf_msg_alloc_dma_buf(&buf, size);
+ if (rc)
+ goto cleanup;
+ tfp_memcpy(buf.va_addr, data, size);
+ tfp_memcpy(&req.data[0],
+ &buf.pa_addr,
+ sizeof(buf.pa_addr));
+ } else {
+ tfp_memcpy(&req.data, data, size);
}
- tfp_memcpy(&req.data,
- data,
- size);
-
parms.tf_type = HWRM_TF_TBL_TYPE_SET;
parms.req_data = (uint32_t *)&req;
parms.req_size = sizeof(req);
@@ -1823,10 +1847,10 @@ tf_msg_set_tbl_entry(struct tf *tfp,
rc = tfp_send_msg_direct(tf_session_get_bp(tfp),
&parms);
- if (rc)
- return rc;
+cleanup:
+ tf_msg_free_dma_buf(&buf);
- return 0;
+ return rc;
}
int
@@ -2325,3 +2349,114 @@ tf_msg_get_version(struct bnxt *bp,
return rc;
}
+
+int
+tf_msg_session_set_hotup_state(struct tf *tfp, uint16_t state)
+{
+ int rc;
+ struct hwrm_tf_session_hotup_state_set_input req = { 0 };
+ struct hwrm_tf_session_hotup_state_set_output resp = { 0 };
+ struct tfp_send_msg_parms parms = { 0 };
+ uint8_t fw_session_id;
+ struct tf_dev_info *dev;
+ struct tf_session *tfs;
+
+ /* Retrieve the session information */
+ rc = tf_session_get_session_internal(tfp, &tfs);
+ if (rc) {
+ TFP_DRV_LOG(ERR,
+ "Failed to lookup session, rc:%s\n",
+ strerror(-rc));
+ return rc;
+ }
+
+ /* Retrieve the device information */
+ rc = tf_session_get_device(tfs, &dev);
+ if (rc) {
+ TFP_DRV_LOG(ERR,
+ "Failed to lookup device, rc:%s\n",
+ strerror(-rc));
+ return rc;
+ }
+
+ rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
+ if (rc) {
+ TFP_DRV_LOG(ERR,
+ "Unable to lookup FW id, rc:%s\n",
+ strerror(-rc));
+ return rc;
+ }
+
+ /* Populate the request */
+ req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
+ req.state = tfp_cpu_to_le_16(state);
+
+ parms.tf_type = HWRM_TF_SESSION_HOTUP_STATE_SET;
+ parms.req_data = (uint32_t *)&req;
+ parms.req_size = sizeof(req);
+ parms.resp_data = (uint32_t *)&resp;
+ parms.resp_size = sizeof(resp);
+ parms.mailbox = dev->ops->tf_dev_get_mailbox();
+
+ rc = tfp_send_msg_direct(tf_session_get_bp(tfp),
+ &parms);
+ return rc;
+}
+
+int
+tf_msg_session_get_hotup_state(struct tf *tfp,
+ uint16_t *state,
+ uint16_t *ref_cnt)
+{
+ int rc;
+ struct hwrm_tf_session_hotup_state_get_input req = { 0 };
+ struct hwrm_tf_session_hotup_state_get_output resp = { 0 };
+ struct tfp_send_msg_parms parms = { 0 };
+ uint8_t fw_session_id;
+ struct tf_dev_info *dev;
+ struct tf_session *tfs;
+
+ /* Retrieve the session information */
+ rc = tf_session_get_session_internal(tfp, &tfs);
+ if (rc) {
+ TFP_DRV_LOG(ERR,
+ "Failed to lookup session, rc:%s\n",
+ strerror(-rc));
+ return rc;
+ }
+
+ /* Retrieve the device information */
+ rc = tf_session_get_device(tfs, &dev);
+ if (rc) {
+ TFP_DRV_LOG(ERR,
+ "Failed to lookup device, rc:%s\n",
+ strerror(-rc));
+ return rc;
+ }
+
+ rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
+ if (rc) {
+ TFP_DRV_LOG(ERR,
+ "Unable to lookup FW id, rc:%s\n",
+ strerror(-rc));
+ return rc;
+ }
+
+ /* Populate the request */
+ req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
+
+ parms.tf_type = HWRM_TF_SESSION_HOTUP_STATE_GET;
+ parms.req_data = (uint32_t *)&req;
+ parms.req_size = sizeof(req);
+ parms.resp_data = (uint32_t *)&resp;
+ parms.resp_size = sizeof(resp);
+ parms.mailbox = dev->ops->tf_dev_get_mailbox();
+
+ rc = tfp_send_msg_direct(tf_session_get_bp(tfp),
+ &parms);
+
+ *state = tfp_le_to_cpu_16(resp.state);
+ *ref_cnt = tfp_le_to_cpu_16(resp.ref_cnt);
+
+ return rc;
+}
diff --git a/drivers/net/bnxt/tf_core/tf_msg.h b/drivers/net/bnxt/tf_core/tf_msg.h
index 188b361d71..24d0ae5f43 100644
--- a/drivers/net/bnxt/tf_core/tf_msg.h
+++ b/drivers/net/bnxt/tf_core/tf_msg.h
@@ -1,5 +1,5 @@
/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2019-2021 Broadcom
+ * Copyright(c) 2019-2023 Broadcom
* All rights reserved.
*/
@@ -761,4 +761,40 @@ int
tf_msg_get_version(struct bnxt *bp,
struct tf_dev_info *dev,
struct tf_get_version_parms *parms);
+
+/**
+ * Send set hot upgrade state request to the firmware.
+ *
+ * [in] tfp
+ * Pointer to session handle
+ *
+ * [in] state
+ * Hot upgrade session state
+ *
+ * Returns:
+ * 0 on Success else internal Truflow error
+ */
+int
+tf_msg_session_set_hotup_state(struct tf *tfp,
+ uint16_t state);
+
+/**
+ * Send get hot upgrade state request to the firmware.
+ *
+ * [in] tfp
+ * Pointer to session handle
+ *
+ * [out] state
+ * Pointer to hot upgrade session state
+ *
+ * [out] ref_cnt
+ * Pointer to hot upgrade session reference count
+ *
+ * Returns:
+ * 0 on Success else internal Truflow error
+ */
+int
+tf_msg_session_get_hotup_state(struct tf *tfp,
+ uint16_t *state,
+ uint16_t *ref_cnt);
#endif /* _TF_MSG_H_ */
diff --git a/drivers/net/bnxt/tf_core/tf_rm.c b/drivers/net/bnxt/tf_core/tf_rm.c
index d2045921b9..1fccb698d0 100644
--- a/drivers/net/bnxt/tf_core/tf_rm.c
+++ b/drivers/net/bnxt/tf_core/tf_rm.c
@@ -1,15 +1,12 @@
/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2019-2021 Broadcom
+ * Copyright(c) 2019-2023 Broadcom
* All rights reserved.
*/
#include <string.h>
-
#include <rte_common.h>
#include <rte_debug.h>
-
#include <cfa_resource_types.h>
-
#include "tf_rm.h"
#include "tf_common.h"
#include "tf_util.h"
@@ -18,9 +15,6 @@
#include "tfp.h"
#include "tf_msg.h"
-/* Logging defines */
-#define TF_RM_DEBUG 0
-
/**
* Generic RM Element data type that an RM DB is build upon.
*/
@@ -210,45 +204,6 @@ tf_rm_adjust_index(struct tf_rm_element *db,
return rc;
}
-/**
- * Logs an array of found residual entries to the console.
- *
- * [in] dir
- * Receive or transmit direction
- *
- * [in] module
- * Type of Device Module
- *
- * [in] count
- * Number of entries in the residual array
- *
- * [in] residuals
- * Pointer to an array of residual entries. Array is index same as
- * the DB in which this function is used. Each entry holds residual
- * value for that entry.
- */
-#if (TF_RM_DEBUG == 1)
-static void
-tf_rm_log_residuals(enum tf_dir dir,
- enum tf_module_type module,
- uint16_t count,
- uint16_t *residuals)
-{
- int i;
-
- /* Walk the residual array and log the types that wasn't
- * cleaned up to the console.
- */
- for (i = 0; i < count; i++) {
- if (residuals[i] != 0)
- TFP_DRV_LOG(INFO,
- "%s, %s was not cleaned up, %d outstanding\n",
- tf_dir_2_str(dir),
- tf_module_subtype_2_str(module, i),
- residuals[i]);
- }
-}
-#endif /* TF_RM_DEBUG == 1 */
/**
* Performs a check of the passed in DB for any lingering elements. If
* a resource type was found to not have been cleaned up by the caller
@@ -364,12 +319,6 @@ tf_rm_check_residuals(struct tf_rm_new_db *rm_db,
*resv_size = found;
}
-#if (TF_RM_DEBUG == 1)
- tf_rm_log_residuals(rm_db->dir,
- rm_db->module,
- rm_db->num_entries,
- residuals);
-#endif
tfp_free((void *)residuals);
*resv = local_resv;
@@ -419,7 +368,7 @@ tf_rm_update_parent_reservations(struct tf *tfp,
bool shared_session)
{
int parent, child;
- const char *type_str;
+ const char *type_str = NULL;
/* Search through all the elements */
for (parent = 0; parent < num_elements; parent++) {
@@ -444,11 +393,6 @@ tf_rm_update_parent_reservations(struct tf *tfp,
dev->ops->tf_dev_get_resource_str(tfp,
cfg[parent].hcapi_type,
&type_str);
-#if (TF_RM_DEBUG == 1)
- printf("%s:%s cnt(%d) slices(%d)\n",
- type_str, tf_tbl_type_2_str(parent),
- alloc_cnt[parent], p_slices);
-#endif /* (TF_RM_DEBUG == 1) */
}
/* Search again through all the elements */
@@ -469,13 +413,7 @@ tf_rm_update_parent_reservations(struct tf *tfp,
dev->ops->tf_dev_get_resource_str(tfp,
cfg[child].hcapi_type,
&type_str);
-#if (TF_RM_DEBUG == 1)
- printf("%s:%s cnt(%d) slices(%d)\n",
- type_str,
- tf_tbl_type_2_str(child),
- alloc_cnt[child],
- c_slices);
-#endif /* (TF_RM_DEBUG == 1) */
+
/* Increment the parents combined count
* with each child's count adjusted for
* number of slices per RM alloc item.
@@ -492,10 +430,6 @@ tf_rm_update_parent_reservations(struct tf *tfp,
}
/* Save the parent count to be requested */
req_cnt[parent] = combined_cnt;
-#if (TF_RM_DEBUG == 1)
- printf("%s calculated total:%d\n\n",
- type_str, req_cnt[parent]);
-#endif /* (TF_RM_DEBUG == 1) */
}
}
return 0;
@@ -595,12 +529,6 @@ tf_rm_create_db(struct tf *tfp,
&hcapi_items);
if (hcapi_items == 0) {
-#if (TF_RM_DEBUG == 1)
- TFP_DRV_LOG(INFO,
- "%s: module: %s Empty RM DB create request\n",
- tf_dir_2_str(parms->dir),
- tf_module_2_str(parms->module));
-#endif
parms->rm_db = NULL;
return -ENOMEM;
}
@@ -746,7 +674,7 @@ tf_rm_create_db(struct tf *tfp,
rc = ba_init(db[i].pool,
resv[j].stride,
- !tf_session_is_shared_session(tfs));
+ true);
if (rc) {
TFP_DRV_LOG(ERR,
"%s: Pool init failed, type:%d:%s\n",
@@ -773,13 +701,6 @@ tf_rm_create_db(struct tf *tfp,
rm_db->module = parms->module;
*parms->rm_db = (void *)rm_db;
-#if (TF_RM_DEBUG == 1)
-
- printf("%s: module:%s\n",
- tf_dir_2_str(parms->dir),
- tf_module_2_str(parms->module));
-#endif /* (TF_RM_DEBUG == 1) */
-
tfp_free((void *)req);
tfp_free((void *)resv);
tfp_free((void *)req_cnt);
@@ -812,6 +733,7 @@ tf_rm_create_db_no_reservation(struct tf *tfp,
struct tf_rm_new_db *rm_db;
struct tf_rm_element *db;
uint32_t pool_size;
+ bool shared_session = 0;
TF_CHECK_PARMS2(tfp, parms);
@@ -841,6 +763,16 @@ tf_rm_create_db_no_reservation(struct tf *tfp,
tfp_memcpy(req_cnt, parms->alloc_cnt,
parms->num_elements * sizeof(uint16_t));
+ shared_session = tf_session_is_shared_session(tfs);
+
+ /* Update the req_cnt based upon the element configuration
+ */
+ tf_rm_update_parent_reservations(tfp, dev, parms->cfg,
+ parms->alloc_cnt,
+ parms->num_elements,
+ req_cnt,
+ shared_session);
+
/* Process capabilities against DB requirements. However, as a
* DB can hold elements that are not HCAPI we can reduce the
* req msg content by removing those out of the request yet
@@ -855,11 +787,6 @@ tf_rm_create_db_no_reservation(struct tf *tfp,
&hcapi_items);
if (hcapi_items == 0) {
- TFP_DRV_LOG(ERR,
- "%s: module:%s Empty RM DB create request\n",
- tf_dir_2_str(parms->dir),
- tf_module_2_str(parms->module));
-
parms->rm_db = NULL;
return -ENOMEM;
}
@@ -938,6 +865,7 @@ tf_rm_create_db_no_reservation(struct tf *tfp,
db[i].cfg_type = cfg->cfg_type;
db[i].hcapi_type = cfg->hcapi_type;
+ db[i].slices = cfg->slices;
/* Save the parent subtype for later use to find the pool
*/
@@ -986,7 +914,7 @@ tf_rm_create_db_no_reservation(struct tf *tfp,
rc = ba_init(db[i].pool,
resv[j].stride,
- !tf_session_is_shared_session(tfs));
+ true);
if (rc) {
TFP_DRV_LOG(ERR,
"%s: Pool init failed, type:%d:%s\n",
@@ -1013,13 +941,6 @@ tf_rm_create_db_no_reservation(struct tf *tfp,
rm_db->module = parms->module;
*parms->rm_db = (void *)rm_db;
-#if (TF_RM_DEBUG == 1)
-
- printf("%s: module:%s\n",
- tf_dir_2_str(parms->dir),
- tf_module_2_str(parms->module));
-#endif /* (TF_RM_DEBUG == 1) */
-
tfp_free((void *)req);
tfp_free((void *)resv);
tfp_free((void *)req_cnt);
@@ -1036,6 +957,7 @@ tf_rm_create_db_no_reservation(struct tf *tfp,
return -EINVAL;
}
+
int
tf_rm_free_db(struct tf *tfp,
struct tf_rm_free_db_parms *parms)
@@ -1110,6 +1032,7 @@ tf_rm_free_db(struct tf *tfp,
return rc;
}
+
/**
* Get the bit allocator pool associated with the subtype and the db
*
@@ -1388,6 +1311,7 @@ tf_rm_get_hcapi_type(struct tf_rm_get_hcapi_parms *parms)
return 0;
}
+
int
tf_rm_get_slices(struct tf_rm_get_slices_parms *parms)
{
@@ -1440,6 +1364,7 @@ tf_rm_get_inuse_count(struct tf_rm_get_inuse_count_parms *parms)
return rc;
}
+
/* Only used for table bulk get at this time
*/
int
diff --git a/drivers/net/bnxt/tf_core/tf_session.c b/drivers/net/bnxt/tf_core/tf_session.c
index d0a0916c6a..253d716572 100644
--- a/drivers/net/bnxt/tf_core/tf_session.c
+++ b/drivers/net/bnxt/tf_core/tf_session.c
@@ -1,12 +1,10 @@
/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2019-2021 Broadcom
+ * Copyright(c) 2019-2023 Broadcom
* All rights reserved.
*/
#include <string.h>
-
#include <rte_common.h>
-
#include "tf_session.h"
#include "tf_common.h"
#include "tf_msg.h"
@@ -59,8 +57,9 @@ tf_session_create(struct tf *tfp,
union tf_session_id *session_id;
struct tf_dev_info dev;
bool shared_session_creator;
- int name_len;
- char *name;
+ char *shared_name;
+ char *tcam_session_name;
+ char *pool_session_name;
TF_CHECK_PARMS2(tfp, parms);
@@ -180,16 +179,18 @@ tf_session_create(struct tf *tfp,
session->em_ext_db_handle = NULL;
/* Populate the request */
- name_len = strnlen(parms->open_cfg->ctrl_chan_name,
- TF_SESSION_NAME_MAX);
- name = &parms->open_cfg->ctrl_chan_name[name_len - strlen("tf_shared")];
- if (!strncmp(name, "tf_shared", strlen("tf_shared")))
- session->shared_session = true;
-
- name = &parms->open_cfg->ctrl_chan_name[name_len -
- strlen("tf_shared-wc_tcam")];
- if (!strncmp(name, "tf_shared-wc_tcam", strlen("tf_shared-wc_tcam")))
+ shared_name = strstr(parms->open_cfg->ctrl_chan_name, "tf_shared");
+ if (shared_name) {
session->shared_session = true;
+ /*
+ * "tf_shared-wc_tcam" is defined for tf_fw version 1.0.0.
+ * "tf_shared-pool" is defined for version 1.0.1.
+ */
+ tcam_session_name = strstr(parms->open_cfg->ctrl_chan_name, "tf_shared-wc_tcam");
+ pool_session_name = strstr(parms->open_cfg->ctrl_chan_name, "tf_shared-pool");
+ if (tcam_session_name || pool_session_name)
+ session->shared_session_hotup = true;
+ }
if (session->shared_session && shared_session_creator) {
session->shared_session_creator = true;
@@ -342,7 +343,6 @@ tf_session_client_create(struct tf *tfp,
return rc;
}
-
/**
* Destroys a Session Client on an existing Session.
*
@@ -441,7 +441,7 @@ tf_session_open_session(struct tf *tfp,
TFP_DRV_LOG(INFO,
"Session created, session_client_id:%d,"
- "session_id:0x%08x, fw_session_id:%d\n",
+ " session_id:0x%08x, fw_session_id:%d\n",
parms->open_cfg->session_client_id.id,
parms->open_cfg->session_id.id,
parms->open_cfg->session_id.internal.fw_session_id);
@@ -462,7 +462,7 @@ tf_session_open_session(struct tf *tfp,
}
TFP_DRV_LOG(INFO,
- "Session Client:%d registered on session:0x%8x\n",
+ "Session Client:%d registered on session:0x%08x\n",
scparms.session_client_id->internal.fw_session_client_id,
tfp->session->session_id.id);
}
@@ -535,6 +535,11 @@ tf_session_close_session(struct tf *tfp,
return rc;
}
+ /* Record the session we're closing so the caller knows the
+ * details.
+ */
+ *parms->session_id = tfs->session_id;
+
/* In case multiple clients we chose to close those first */
if (tfs->ref_count > 1) {
/* Linaro gcc can't static init this structure */
@@ -567,11 +572,6 @@ tf_session_close_session(struct tf *tfp,
return 0;
}
- /* Record the session we're closing so the caller knows the
- * details.
- */
- *parms->session_id = tfs->session_id;
-
rc = tf_session_get_device(tfs, &tfd);
if (rc) {
TFP_DRV_LOG(ERR,
@@ -1140,3 +1140,71 @@ tf_session_set_if_tbl_db(struct tf *tfp,
tfs->if_tbl_db_handle = if_tbl_handle;
return rc;
}
+
+int
+tf_session_set_hotup_state(struct tf *tfp,
+ struct tf_set_session_hotup_state_parms *parms)
+{
+ int rc = 0;
+ struct tf_session *tfs = NULL;
+
+ rc = tf_session_get_session(tfp, &tfs);
+ if (rc) {
+ TFP_DRV_LOG(ERR,
+ "Session lookup failed, rc:%s\n",
+ strerror(-rc));
+ return rc;
+ }
+
+ if (!tf_session_is_shared_session(tfs)) {
+ rc = -EINVAL;
+ TFP_DRV_LOG(ERR,
+ "Only shared session able to set state, rc:%s\n",
+ strerror(-rc));
+ return rc;
+ }
+
+ rc = tf_msg_session_set_hotup_state(tfp, parms->state);
+ if (rc) {
+ /* Log error */
+ TFP_DRV_LOG(ERR,
+ "Set session hot upgrade state failed, rc:%s\n",
+ strerror(-rc));
+ }
+
+ return rc;
+}
+
+int
+tf_session_get_hotup_state(struct tf *tfp,
+ struct tf_get_session_hotup_state_parms *parms)
+{
+ int rc = 0;
+ struct tf_session *tfs = NULL;
+
+ rc = tf_session_get_session(tfp, &tfs);
+ if (rc) {
+ TFP_DRV_LOG(ERR,
+ "Session lookup failed, rc:%s\n",
+ strerror(-rc));
+ return rc;
+ }
+
+ if (!tf_session_is_shared_session(tfs)) {
+ rc = -EINVAL;
+ TFP_DRV_LOG(ERR,
+ "Only shared session able to get state, rc:%s\n",
+ strerror(-rc));
+ return rc;
+ }
+
+ rc = tf_msg_session_get_hotup_state(tfp, &parms->state, &parms->ref_cnt);
+ if (rc) {
+ /* Log error */
+ TFP_DRV_LOG(ERR,
+ "Get session hot upgrade state failed, rc:%s\n",
+ strerror(-rc));
+ }
+
+ return rc;
+}
diff --git a/drivers/net/bnxt/tf_core/tf_session.h b/drivers/net/bnxt/tf_core/tf_session.h
index 5a94b941fa..9bbbccf125 100644
--- a/drivers/net/bnxt/tf_core/tf_session.h
+++ b/drivers/net/bnxt/tf_core/tf_session.h
@@ -1,5 +1,5 @@
/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2019-2021 Broadcom
+ * Copyright(c) 2019-2023 Broadcom
* All rights reserved.
*/
@@ -8,7 +8,6 @@
#include <stdint.h>
#include <stdlib.h>
-
#include "bitalloc.h"
#include "tf_core.h"
#include "tf_device.h"
@@ -48,7 +47,7 @@
*
* Shared memory containing private TruFlow session information.
* Through this structure the session can keep track of resource
- * allocations. It also holds info about Session Clients.
+ * allocations. It also holds info about Session Clients.
*
* Memory is assigned to the Truflow instance by way of
* tf_open_session. Memory is allocated and owned by i.e. ULP.
@@ -78,6 +77,11 @@ struct tf_session {
*/
bool shared_session;
+ /**
+ * Boolean controlling the split of hardware resources for hotupgrade.
+ */
+ bool shared_session_hotup;
+
/**
* This flag indicates the shared session on firmware side is created
* by this session. Some privileges may be assigned to this session.
@@ -169,6 +173,12 @@ struct tf_session {
* Number of slices per row for WC TCAM
*/
uint16_t wc_num_slices_per_row;
+
+ /**
+ * Indicates if TCAM is controlled by TCAM Manager
+ */
+ int tcam_mgr_control[TF_DIR_MAX][TF_TCAM_TBL_TYPE_MAX];
+
};
/**
@@ -276,11 +286,9 @@ struct tf_session_close_session_parms {
*
* @ref tf_session_is_shared_session
*
- * #define TF_SHARED
* @ref tf_session_get_tcam_shared_db
*
* @ref tf_session_set_tcam_shared_db
- * #endif
*
* @ref tf_session_get_sram_db
*
@@ -588,6 +596,21 @@ tf_session_is_shared_session(struct tf_session *tfs)
return tfs->shared_session;
}
+/**
+ * Check if the session is shared session for hot upgrade.
+ *
+ * [in] session, pointer to the session
+ *
+ * Returns:
+ * - true if it is shared session for hot upgrade
+ * - false if it is not shared session for hot upgrade
+ */
+static inline bool
+tf_session_is_shared_hotup_session(struct tf_session *tfs)
+{
+ return tfs->shared_session_hotup;
+}
+
/**
* Check if the session is the shared session creator
*
@@ -716,4 +739,36 @@ tf_session_set_if_tbl_db(struct tf *tfp,
int
tf_session_get_if_tbl_db(struct tf *tfp,
void **if_tbl_handle);
+
+/**
+ * Set hot upgrade session state.
+ *
+ * [in] tfp
+ * Pointer to session handle
+ *
+ * [in] parms
+ * Hot upgrade session state parms
+ *
+ * Returns:
+ * 0 on Success else internal Truflow error
+ */
+int
+tf_session_set_hotup_state(struct tf *tfp,
+ struct tf_set_session_hotup_state_parms *parms);
+
+/**
+ * Get hot upgrade session state.
+ *
+ * [in] tfp
+ * Pointer to session handle
+ *
+ * [out] parms
+ * Pointer to hot upgrade session state parms
+ *
+ * Returns:
+ * 0 on Success else internal Truflow error
+ */
+int
+tf_session_get_hotup_state(struct tf *tfp,
+ struct tf_get_session_hotup_state_parms *parms);
#endif /* _TF_SESSION_H_ */
diff --git a/drivers/net/bnxt/tf_core/tf_sram_mgr.c b/drivers/net/bnxt/tf_core/tf_sram_mgr.c
index acb3372486..87e8882fed 100644
--- a/drivers/net/bnxt/tf_core/tf_sram_mgr.c
+++ b/drivers/net/bnxt/tf_core/tf_sram_mgr.c
@@ -1,5 +1,5 @@
/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2019-2021 Broadcom
+ * Copyright(c) 2019-2023 Broadcom
* All rights reserved.
*/
#include <stdlib.h>
@@ -21,7 +21,7 @@
/**
* TF SRAM block info
*
- * Contains all the information about a particular 64B SRAM
+ * Contains all the information about a particular 128B SRAM
* block and the slices within it.
*/
struct tf_sram_block {
@@ -36,9 +36,9 @@ struct tf_sram_block {
* If a bit is set, it indicates the slice
* in the row is in use.
*/
- uint8_t in_use_mask;
+ uint16_t in_use_mask;
- /** Block id - this is a 64B offset
+ /** Block id - this is a 128B offset
*/
uint16_t block_id;
};
@@ -46,7 +46,7 @@ struct tf_sram_block {
/**
* TF SRAM block list
*
- * List of 64B SRAM blocks used for fixed size slices (8, 16, 32, 64B)
+ * List of 128B SRAM blocks used for fixed size slices (8, 16, 32, 64B, 128B)
*/
struct tf_sram_slice_list {
/** Pointer to head of linked list of blocks.
@@ -70,7 +70,6 @@ struct tf_sram_slice_list {
enum tf_sram_slice_size size;
};
-
/**
* TF SRAM bank info consists of lists of different slice sizes per bank
*/
@@ -111,6 +110,8 @@ const char
return "32B slice";
case TF_SRAM_SLICE_SIZE_64B:
return "64B slice";
+ case TF_SRAM_SLICE_SIZE_128B:
+ return "128B slice";
default:
return "Invalid slice size";
}
@@ -179,8 +180,8 @@ static void
tf_sram_offset_2_block_id(enum tf_sram_bank_id bank_id, uint16_t offset,
uint16_t *block_id, uint16_t *slice_offset)
{
- *slice_offset = offset & 0x7;
- *block_id = ((offset & ~0x7) >> 3) -
+ *slice_offset = offset & 0xf;
+ *block_id = ((offset & ~0xf) >> 3) -
tf_sram_bank_2_base_offset[bank_id];
}
@@ -232,31 +233,37 @@ tf_sram_free_slice(enum tf_sram_slice_size slice_size,
bool *block_is_empty)
{
int rc = 0;
- uint8_t shift;
- uint8_t slice_mask = 0;
+ uint16_t shift;
+ uint16_t slice_mask = 0;
TF_CHECK_PARMS2(block, block_is_empty);
switch (slice_size) {
case TF_SRAM_SLICE_SIZE_8B:
shift = slice_offset >> 0;
- assert(shift < 8);
+ assert(shift < 16);
slice_mask = 1 << shift;
break;
case TF_SRAM_SLICE_SIZE_16B:
shift = slice_offset >> 1;
- assert(shift < 4);
+ assert(shift < 8);
slice_mask = 1 << shift;
break;
case TF_SRAM_SLICE_SIZE_32B:
shift = slice_offset >> 2;
- assert(shift < 2);
+ assert(shift < 4);
slice_mask = 1 << shift;
break;
case TF_SRAM_SLICE_SIZE_64B:
+ shift = slice_offset >> 3;
+ assert(shift < 2);
+ slice_mask = 1 << shift;
+ break;
+
+ case TF_SRAM_SLICE_SIZE_128B:
default:
shift = slice_offset >> 0;
assert(shift < 1);
@@ -294,27 +301,32 @@ tf_sram_get_next_slice_in_block(struct tf_sram_block *block,
bool *block_is_full)
{
int rc, free_id = -1;
- uint8_t shift, max_slices, mask, i, full_mask;
+ uint16_t shift, max_slices, mask, i, full_mask;
TF_CHECK_PARMS3(block, slice_offset, block_is_full);
switch (slice_size) {
case TF_SRAM_SLICE_SIZE_8B:
shift = 0;
- max_slices = 8;
- full_mask = 0xff;
+ max_slices = 16;
+ full_mask = 0xffff;
break;
case TF_SRAM_SLICE_SIZE_16B:
shift = 1;
- max_slices = 4;
- full_mask = 0xf;
+ max_slices = 8;
+ full_mask = 0xff;
break;
case TF_SRAM_SLICE_SIZE_32B:
shift = 2;
+ max_slices = 4;
+ full_mask = 0xf;
+ break;
+ case TF_SRAM_SLICE_SIZE_64B:
+ shift = 3;
max_slices = 2;
full_mask = 0x3;
break;
- case TF_SRAM_SLICE_SIZE_64B:
+ case TF_SRAM_SLICE_SIZE_128B:
default:
shift = 0;
max_slices = 1;
@@ -338,7 +350,6 @@ tf_sram_get_next_slice_in_block(struct tf_sram_block *block,
else
*block_is_full = false;
-
if (free_id >= 0) {
*slice_offset = free_id << shift;
rc = 0;
@@ -362,8 +373,8 @@ tf_sram_is_slice_allocated_in_block(struct tf_sram_block *block,
bool *is_allocated)
{
int rc = 0;
- uint8_t shift;
- uint8_t slice_mask = 0;
+ uint16_t shift;
+ uint16_t slice_mask = 0;
TF_CHECK_PARMS2(block, is_allocated);
@@ -372,23 +383,29 @@ tf_sram_is_slice_allocated_in_block(struct tf_sram_block *block,
switch (slice_size) {
case TF_SRAM_SLICE_SIZE_8B:
shift = slice_offset >> 0;
- assert(shift < 8);
+ assert(shift < 16);
slice_mask = 1 << shift;
break;
case TF_SRAM_SLICE_SIZE_16B:
shift = slice_offset >> 1;
- assert(shift < 4);
+ assert(shift < 8);
slice_mask = 1 << shift;
break;
case TF_SRAM_SLICE_SIZE_32B:
shift = slice_offset >> 2;
- assert(shift < 2);
+ assert(shift < 4);
slice_mask = 1 << shift;
break;
case TF_SRAM_SLICE_SIZE_64B:
+ shift = slice_offset >> 3;
+ assert(shift < 2);
+ slice_mask = 1 << shift;
+ break;
+
+ case TF_SRAM_SLICE_SIZE_128B:
default:
shift = slice_offset >> 0;
assert(shift < 1);
@@ -416,7 +433,6 @@ tf_sram_get_block_cnt(struct tf_sram_slice_list *slice_list)
return slice_list->cnt;
}
-
/**
* Free a block data structure - does not free to the RM
*/
@@ -508,22 +524,26 @@ tf_sram_find_first_not_full_block(struct tf_sram_slice_list *slice_list,
struct tf_sram_block **first_not_full_block)
{
struct tf_sram_block *block = slice_list->head;
- uint8_t slice_mask, mask;
+ uint16_t slice_mask, mask;
switch (slice_size) {
case TF_SRAM_SLICE_SIZE_8B:
- slice_mask = 0xff;
+ slice_mask = 0xffff;
break;
case TF_SRAM_SLICE_SIZE_16B:
- slice_mask = 0xf;
+ slice_mask = 0xff;
break;
case TF_SRAM_SLICE_SIZE_32B:
- slice_mask = 0x3;
+ slice_mask = 0xf;
break;
case TF_SRAM_SLICE_SIZE_64B:
+ slice_mask = 0x3;
+ break;
+
+ case TF_SRAM_SLICE_SIZE_128B:
default:
slice_mask = 0x1;
break;
@@ -543,7 +563,7 @@ tf_sram_find_first_not_full_block(struct tf_sram_slice_list *slice_list,
static void
tf_sram_dump_block(struct tf_sram_block *block)
{
- TFP_DRV_LOG(INFO, "block_id(0x%x) in_use_mask(0x%02x)\n",
+ TFP_DRV_LOG(INFO, "block_id(0x%x) in_use_mask(0x%04x)\n",
block->block_id,
block->in_use_mask);
}
@@ -631,9 +651,10 @@ int tf_sram_mgr_alloc(void *sram_handle,
struct tf_sram *sram;
struct tf_sram_slice_list *slice_list;
uint16_t block_id, slice_offset = 0;
- uint32_t index;
+ uint32_t index, next_index;
struct tf_sram_block *block;
struct tf_rm_allocate_parms aparms = { 0 };
+ struct tf_rm_free_parms fparms = { 0 };
bool block_is_full;
uint16_t block_offset;
@@ -662,11 +683,34 @@ int tf_sram_mgr_alloc(void *sram_handle,
aparms.subtype = parms->tbl_type;
aparms.rm_db = parms->rm_db;
rc = tf_rm_allocate(&aparms);
+ if (rc)
+ return rc;
+ /* to support 128B block rows, we are allocating
+ * 2 sequential 64B blocks from RM, if they are not next to
+ * each other we are going to have issues
+ */
+ aparms.index = &next_index;
+ rc = tf_rm_allocate(&aparms);
if (rc)
return rc;
+ /* make sure we do get the next 64B block, else free the
+ * allocated indexes and return error
+ */
+ if (unlikely(index + 1 != next_index)) {
+ fparms.index = index;
+ fparms.subtype = parms->tbl_type;
+ fparms.rm_db = parms->rm_db;
+ tf_rm_free(&fparms);
+ fparms.index = next_index;
+ tf_rm_free(&fparms);
+ TFP_DRV_LOG(ERR,
+ "Could not allocate two sequential 64B blocks\n");
+ return -ENOMEM;
+ }
block_id = index;
block = tf_sram_alloc_block(slice_list, block_id);
+
} else {
/* Block exists
*/
@@ -742,7 +786,7 @@ tf_sram_mgr_free(void *sram_handle,
}
#if (STATS_CLEAR_ON_READ_SUPPORT == 0)
/* If this is a counter, clear it. In the future we need to switch to
- * using the special access registers on Thor to automatically clear on
+ * using the special access registers on P5 to automatically clear on
* read.
*/
/* If this is counter table, clear the entry on free */
@@ -794,6 +838,13 @@ tf_sram_mgr_free(void *sram_handle,
TFP_DRV_LOG(ERR, "Free block_id(%d) failed error(%s)\n",
block_id, strerror(-rc));
}
+ fparms.index = block_id + 1;
+ rc = tf_rm_free(&fparms);
+
+ if (rc) {
+ TFP_DRV_LOG(ERR, "Free next block_id(%d) failed error(%s)\n",
+ block_id + 1, strerror(-rc));
+ }
/* Free local entry regardless */
tf_sram_free_block(slice_list, block);
diff --git a/drivers/net/bnxt/tf_core/tf_sram_mgr.h b/drivers/net/bnxt/tf_core/tf_sram_mgr.h
index fc78426130..878195c404 100644
--- a/drivers/net/bnxt/tf_core/tf_sram_mgr.h
+++ b/drivers/net/bnxt/tf_core/tf_sram_mgr.h
@@ -1,5 +1,5 @@
/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2019-2021 Broadcom
+ * Copyright(c) 2019-2023 Broadcom
* All rights reserved.
*/
@@ -26,28 +26,28 @@
*/
#define STATS_CLEAR_ON_READ_SUPPORT 0
-#define TF_SRAM_MGR_BLOCK_SZ_BYTES 64
+#define TF_SRAM_MGR_BLOCK_SZ_BYTES 128
#define TF_SRAM_MGR_MIN_SLICE_BYTES 8
/**
* TF slice size.
*
- * A slice is part of a 64B row
+ * A slice is part of a 128B row
*
* Each slice is a multiple of 8B
*/
enum tf_sram_slice_size {
- TF_SRAM_SLICE_SIZE_8B, /**< 8 byte SRAM slice */
- TF_SRAM_SLICE_SIZE_16B, /**< 16 byte SRAM slice */
- TF_SRAM_SLICE_SIZE_32B, /**< 32 byte SRAM slice */
- TF_SRAM_SLICE_SIZE_64B, /**< 64 byte SRAM slice */
- TF_SRAM_SLICE_SIZE_MAX /**< slice limit */
+ TF_SRAM_SLICE_SIZE_8B, /**< 8 byte SRAM slice */
+ TF_SRAM_SLICE_SIZE_16B, /**< 16 byte SRAM slice */
+ TF_SRAM_SLICE_SIZE_32B, /**< 32 byte SRAM slice */
+ TF_SRAM_SLICE_SIZE_64B, /**< 64 byte SRAM slice */
+ TF_SRAM_SLICE_SIZE_128B, /**< 128 byte SRAM slice */
+ TF_SRAM_SLICE_SIZE_MAX /**< slice limit */
};
-
/** Initialize the SRAM slice manager
*
- * The SRAM slice manager manages slices within 64B rows. Slices are of size
+ * The SRAM slice manager manages slices within 128B rows. Slices are of size
* tf_sram_slice_size. This function provides a handle to the SRAM manager
* data.
*
@@ -181,7 +181,7 @@ struct tf_sram_mgr_free_parms {
/**
* Free an SRAM Slice
*
- * Free an SRAM slice to the indicated bank. This may result in a 64B row
+ * Free an SRAM slice to the indicated bank. This may result in a 128B row
* being returned to the RM SRAM bank pool.
*
* [in] sram_handle
diff --git a/drivers/net/bnxt/tf_core/tf_tbl.c b/drivers/net/bnxt/tf_core/tf_tbl.c
index f18e4ba346..f5f3889934 100644
--- a/drivers/net/bnxt/tf_core/tf_tbl.c
+++ b/drivers/net/bnxt/tf_core/tf_tbl.c
@@ -1,12 +1,11 @@
/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2019-2021 Broadcom
+ * Copyright(c) 2019-2023 Broadcom
* All rights reserved.
*/
/* Truflow Table APIs and supporting code */
#include <rte_common.h>
-
#include "tf_tbl.h"
#include "tf_common.h"
#include "tf_rm.h"
@@ -18,8 +17,8 @@
struct tf;
-#define TF_TBL_RM_TO_PTR(new_idx, idx, base, shift) { \
- *(new_idx) = (((idx) + (base)) << (shift)); \
+#define TF_TBL_RM_TO_PTR(new_idx, idx, base, shift) { \
+ *(new_idx) = (((idx) + (base)) << (shift)); \
}
int
@@ -98,6 +97,7 @@ tf_tbl_unbind(struct tf *tfp)
rc = tf_session_get_db(tfp, TF_MODULE_TYPE_TABLE, &tbl_db_ptr);
if (rc)
return 0;
+
tbl_db = (struct tbl_rm_db *)tbl_db_ptr;
for (i = 0; i < TF_DIR_MAX; i++) {
diff --git a/drivers/net/bnxt/tf_core/tf_tbl_sram.c b/drivers/net/bnxt/tf_core/tf_tbl_sram.c
index 567f912dfa..3a6f1c68c7 100644
--- a/drivers/net/bnxt/tf_core/tf_tbl_sram.c
+++ b/drivers/net/bnxt/tf_core/tf_tbl_sram.c
@@ -1,5 +1,5 @@
/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2019-2021 Broadcom
+ * Copyright(c) 2019-2023 Broadcom
* All rights reserved.
*/
@@ -73,11 +73,12 @@ const uint16_t tf_tbl_sram_hcapi_2_bank[CFA_RESOURCE_TYPE_P58_LAST] = {
* Translate HCAPI type to SRAM Manager bank
*/
const uint8_t tf_tbl_sram_slices_2_size[TF_TBL_SRAM_SLICES_MAX + 1] = {
- [0] = TF_SRAM_SLICE_SIZE_64B, /* if 0 slices assume 1 64B block */
- [1] = TF_SRAM_SLICE_SIZE_64B, /* 1 slice per 64B block */
- [2] = TF_SRAM_SLICE_SIZE_32B, /* 2 slices per 64B block */
- [4] = TF_SRAM_SLICE_SIZE_16B, /* 4 slices per 64B block */
- [8] = TF_SRAM_SLICE_SIZE_8B /* 8 slices per 64B block */
+ [0] = TF_SRAM_SLICE_SIZE_128B, /* if 0 slices assume 1 128B block */
+ [1] = TF_SRAM_SLICE_SIZE_128B, /* 1 slice per 128B block */
+ [2] = TF_SRAM_SLICE_SIZE_64B, /* 2 slice per 128B block */
+ [4] = TF_SRAM_SLICE_SIZE_32B, /* 4 slices per 128B block */
+ [8] = TF_SRAM_SLICE_SIZE_16B, /* 8 slices per 128B block */
+ [16] = TF_SRAM_SLICE_SIZE_8B /* 16 slices per 128B block */
};
/**
@@ -340,7 +341,7 @@ tf_tbl_sram_free(struct tf *tfp __rte_unused,
rc = tf_sram_mgr_is_allocated(sram_handle, &aparms);
if (rc || !allocated) {
TFP_DRV_LOG(ERR,
- "%s: Free of invalid entry:%s idx(%d):(%s)\n",
+ "%s: Free of invalid entry:%s idx(0x%x):(%s)\n",
tf_dir_2_str(parms->dir),
tf_tbl_type_2_str(parms->type),
parms->idx,
@@ -361,7 +362,7 @@ tf_tbl_sram_free(struct tf *tfp __rte_unused,
rc = tf_sram_mgr_free(sram_handle, &fparms);
if (rc) {
TFP_DRV_LOG(ERR,
- "%s: Failed to free entry:%s idx(%d)\n",
+ "%s: Failed to free entry:%s idx(0x%x)\n",
tf_dir_2_str(parms->dir),
tf_tbl_type_2_str(parms->type),
parms->idx);
@@ -469,7 +470,7 @@ tf_tbl_sram_set(struct tf *tfp,
if (rallocated != TF_RM_ALLOCATED_ENTRY_IN_USE) {
TFP_DRV_LOG(ERR,
- "%s, Invalid or not allocated index, type:%s, idx:%d\n",
+ "%s, Invalid or not allocated index, type:%s, idx:0x%x\n",
tf_dir_2_str(parms->dir),
tf_tbl_type_2_str(parms->type),
parms->idx);
@@ -484,7 +485,7 @@ tf_tbl_sram_set(struct tf *tfp,
rc = tf_sram_mgr_is_allocated(sram_handle, &aparms);
if (rc || !allocated) {
TFP_DRV_LOG(ERR,
- "%s: Entry not allocated:%s idx(%d):(%s)\n",
+ "%s: Entry not allocated:%s idx(0x%x):(%s)\n",
tf_dir_2_str(parms->dir),
tf_tbl_type_2_str(parms->type),
parms->idx,
@@ -587,7 +588,7 @@ tf_tbl_sram_get(struct tf *tfp,
rc = tf_sram_mgr_is_allocated(sram_handle, &aparms);
if (rc || !allocated) {
TFP_DRV_LOG(ERR,
- "%s: Entry not allocated:%s idx(%d):(%s)\n",
+ "%s: Entry not allocated:%s idx(0x%x):(%s)\n",
tf_dir_2_str(parms->dir),
tf_tbl_type_2_str(parms->type),
parms->idx,
@@ -711,7 +712,7 @@ tf_tbl_sram_bulk_get(struct tf *tfp,
rc = tf_sram_mgr_is_allocated(sram_handle, &aparms);
if (rc || !allocated) {
TFP_DRV_LOG(ERR,
- "%s: Entry not allocated:%s last_idx(%d):(%s)\n",
+ "%s: Entry not allocated:%s last_idx(0x%x):(%s)\n",
tf_dir_2_str(parms->dir),
tf_tbl_type_2_str(parms->type),
idx,
diff --git a/drivers/net/bnxt/tf_core/tf_tcam.c b/drivers/net/bnxt/tf_core/tf_tcam.c
index 1c42a6adc7..9e0671d47b 100644
--- a/drivers/net/bnxt/tf_core/tf_tcam.c
+++ b/drivers/net/bnxt/tf_core/tf_tcam.c
@@ -1,5 +1,5 @@
/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2019-2021 Broadcom
+ * Copyright(c) 2019-2023 Broadcom
* All rights reserved.
*/
@@ -14,6 +14,7 @@
#include "tfp.h"
#include "tf_session.h"
#include "tf_msg.h"
+#include "tf_tcam_mgr_msg.h"
struct tf;
@@ -23,17 +24,22 @@ tf_tcam_bind(struct tf *tfp,
{
int rc;
int db_rc[TF_DIR_MAX] = { 0 };
- int i, d;
+ int d, t;
struct tf_rm_alloc_info info;
struct tf_rm_free_db_parms fparms;
struct tf_rm_create_db_parms db_cfg;
+ struct tf_tcam_resources local_tcam_cnt[TF_DIR_MAX];
struct tf_tcam_resources *tcam_cnt;
struct tf_rm_get_alloc_info_parms ainfo;
- uint16_t num_slices = parms->wc_num_slices;
+ uint16_t num_slices = 1;
struct tf_session *tfs;
struct tf_dev_info *dev;
struct tcam_rm_db *tcam_db;
struct tfp_calloc_parms cparms;
+ struct tf_resource_info resv_res[TF_DIR_MAX][TF_TCAM_TBL_TYPE_MAX];
+ uint32_t rx_supported;
+ uint32_t tx_supported;
+ bool no_req = true;
TF_CHECK_PARMS2(tfp, parms);
@@ -47,7 +53,7 @@ tf_tcam_bind(struct tf *tfp,
if (rc)
return rc;
- if (dev->ops->tf_dev_set_tcam_slice_info == NULL) {
+ if (dev->ops->tf_dev_get_tcam_slice_info == NULL) {
rc = -EOPNOTSUPP;
TFP_DRV_LOG(ERR,
"Operation not supported, rc:%s\n",
@@ -55,18 +61,28 @@ tf_tcam_bind(struct tf *tfp,
return rc;
}
- rc = dev->ops->tf_dev_set_tcam_slice_info(tfp,
- num_slices);
+ tcam_cnt = parms->resources->tcam_cnt;
+
+ for (d = 0; d < TF_DIR_MAX; d++) {
+ for (t = 0; t < TF_TCAM_TBL_TYPE_MAX; t++) {
+ rc = dev->ops->tf_dev_get_tcam_slice_info(tfp, t, 0,
+ &num_slices);
if (rc)
return rc;
- tcam_cnt = parms->resources->tcam_cnt;
- if ((tcam_cnt[TF_DIR_RX].cnt[TF_TCAM_TBL_TYPE_WC_TCAM] % num_slices) ||
- (tcam_cnt[TF_DIR_TX].cnt[TF_TCAM_TBL_TYPE_WC_TCAM] % num_slices)) {
- TFP_DRV_LOG(ERR,
- "Requested num of WC TCAM entries has to be multiple %d\n",
- num_slices);
- return -EINVAL;
+ if (num_slices == 1)
+ continue;
+
+ if (tcam_cnt[d].cnt[t] % num_slices) {
+ TFP_DRV_LOG(ERR,
+ "%s: Requested num of %s entries "
+ "has to be multiple of %d\n",
+ tf_dir_2_str(d),
+ tf_tcam_tbl_2_str(t),
+ num_slices);
+ return -EINVAL;
+ }
+ }
}
memset(&db_cfg, 0, sizeof(db_cfg));
@@ -80,8 +96,8 @@ tf_tcam_bind(struct tf *tfp,
}
tcam_db = cparms.mem_va;
- for (i = 0; i < TF_DIR_MAX; i++)
- tcam_db->tcam_db[i] = NULL;
+ for (d = 0; d < TF_DIR_MAX; d++)
+ tcam_db->tcam_db[d] = NULL;
tf_session_set_db(tfp, TF_MODULE_TYPE_TCAM, tcam_db);
db_cfg.module = TF_MODULE_TYPE_TCAM;
@@ -90,7 +106,7 @@ tf_tcam_bind(struct tf *tfp,
for (d = 0; d < TF_DIR_MAX; d++) {
db_cfg.dir = d;
- db_cfg.alloc_cnt = parms->resources->tcam_cnt[d].cnt;
+ db_cfg.alloc_cnt = tcam_cnt[d].cnt;
db_cfg.rm_db = (void *)&tcam_db->tcam_db[d];
if (tf_session_is_shared_session(tfs) &&
(!tf_session_is_shared_session_creator(tfs)))
@@ -98,53 +114,112 @@ tf_tcam_bind(struct tf *tfp,
else
db_rc[d] = tf_rm_create_db(tfp, &db_cfg);
}
-
/* No db created */
if (db_rc[TF_DIR_RX] && db_rc[TF_DIR_TX]) {
TFP_DRV_LOG(ERR, "No TCAM DB created\n");
return db_rc[TF_DIR_RX];
}
- /* check if reserved resource for WC is multiple of num_slices */
+ /* Collect info on which entries were reserved. */
for (d = 0; d < TF_DIR_MAX; d++) {
- if (!tcam_db->tcam_db[d])
- continue;
+ for (t = 0; t < TF_TCAM_TBL_TYPE_MAX; t++) {
+ memset(&info, 0, sizeof(info));
+ if (tcam_cnt[d].cnt[t] == 0) {
+ resv_res[d][t].start = 0;
+ resv_res[d][t].stride = 0;
+ continue;
+ }
+ ainfo.rm_db = tcam_db->tcam_db[d];
+ ainfo.subtype = t;
+ ainfo.info = &info;
+ rc = tf_rm_get_info(&ainfo);
+ if (rc)
+ goto error;
+
+ rc = dev->ops->tf_dev_get_tcam_slice_info(tfp, t, 0,
+ &num_slices);
+ if (rc)
+ return rc;
+
+ if (num_slices > 1) {
+ /* check if reserved resource for is multiple of
+ * num_slices
+ */
+ if (info.entry.start % num_slices != 0 ||
+ info.entry.stride % num_slices != 0) {
+ TFP_DRV_LOG(ERR,
+ "%s: %s reserved resource"
+ " is not multiple of %d\n",
+ tf_dir_2_str(d),
+ tf_tcam_tbl_2_str(t),
+ num_slices);
+ rc = -EINVAL;
+ goto error;
+ }
+ }
+
+ resv_res[d][t].start = info.entry.start;
+ resv_res[d][t].stride = info.entry.stride;
+ }
+ }
- memset(&info, 0, sizeof(info));
- ainfo.rm_db = tcam_db->tcam_db[d];
- ainfo.subtype = TF_TCAM_TBL_TYPE_WC_TCAM;
- ainfo.info = &info;
- rc = tf_rm_get_info(&ainfo);
- if (rc)
- goto error;
-
- if (info.entry.start % num_slices != 0 ||
- info.entry.stride % num_slices != 0) {
- TFP_DRV_LOG(ERR,
- "%s: TCAM reserved resource is not multiple of %d\n",
- tf_dir_2_str(d),
- num_slices);
- rc = -EINVAL;
- goto error;
+ rc = tf_tcam_mgr_bind_msg(tfp, dev, parms, resv_res);
+ if (rc)
+ return rc;
+
+ rc = tf_tcam_mgr_qcaps_msg(tfp, dev,
+ &rx_supported, &tx_supported);
+ if (rc)
+ return rc;
+
+ for (t = 0; t < TF_TCAM_TBL_TYPE_MAX; t++) {
+ if (rx_supported & 1 << t)
+ tfs->tcam_mgr_control[TF_DIR_RX][t] = 1;
+ if (tx_supported & 1 << t)
+ tfs->tcam_mgr_control[TF_DIR_TX][t] = 1;
+ }
+
+ /*
+ * Make a local copy of tcam_cnt with only resources not managed by TCAM
+ * Manager requested.
+ */
+ memcpy(&local_tcam_cnt, tcam_cnt, sizeof(local_tcam_cnt));
+ tcam_cnt = local_tcam_cnt;
+ for (d = 0; d < TF_DIR_MAX; d++) {
+ for (t = 0; t < TF_TCAM_TBL_TYPE_MAX; t++) {
+ /* If controlled by TCAM Manager */
+ if (tfs->tcam_mgr_control[d][t])
+ tcam_cnt[d].cnt[t] = 0;
+ else if (tcam_cnt[d].cnt[t] > 0)
+ no_req = false;
}
}
- /* Initialize the TCAM manager. */
+ /* If no resources left to request */
+ if (no_req)
+ goto finished;
+
+finished:
TFP_DRV_LOG(INFO,
"TCAM - initialized\n");
return 0;
error:
- for (i = 0; i < TF_DIR_MAX; i++) {
- memset(&fparms, 0, sizeof(fparms));
- fparms.dir = i;
- fparms.rm_db = tcam_db->tcam_db[i];
- /* Ignoring return here since we are in the error case */
- (void)tf_rm_free_db(tfp, &fparms);
- tcam_db->tcam_db[i] = NULL;
+ for (d = 0; d < TF_DIR_MAX; d++) {
+ if (tcam_db->tcam_db[d] != NULL) {
+ memset(&fparms, 0, sizeof(fparms));
+ fparms.dir = d;
+ fparms.rm_db = tcam_db->tcam_db[d];
+ /*
+ * Ignoring return here since we are in the error case
+ */
+ (void)tf_rm_free_db(tfp, &fparms);
+
+ tcam_db->tcam_db[d] = NULL;
+ }
+ tcam_db->tcam_db[d] = NULL;
tf_session_set_db(tfp, TF_MODULE_TYPE_TCAM, NULL);
}
-
return rc;
}
@@ -156,27 +231,43 @@ tf_tcam_unbind(struct tf *tfp)
struct tf_rm_free_db_parms fparms;
struct tcam_rm_db *tcam_db;
void *tcam_db_ptr = NULL;
+ struct tf_session *tfs;
+ struct tf_dev_info *dev;
TF_CHECK_PARMS1(tfp);
+ /* Retrieve the session information */
+ rc = tf_session_get_session_internal(tfp, &tfs);
+ if (rc)
+ return rc;
+
+ /* Retrieve the device information */
+ rc = tf_session_get_device(tfs, &dev);
+ if (rc)
+ return rc;
rc = tf_session_get_db(tfp, TF_MODULE_TYPE_TCAM, &tcam_db_ptr);
- if (rc) {
+ if (rc)
return 0;
- }
+
tcam_db = (struct tcam_rm_db *)tcam_db_ptr;
for (i = 0; i < TF_DIR_MAX; i++) {
- if (tcam_db->tcam_db[i] == NULL)
- continue;
- memset(&fparms, 0, sizeof(fparms));
- fparms.dir = i;
- fparms.rm_db = tcam_db->tcam_db[i];
- rc = tf_rm_free_db(tfp, &fparms);
- if (rc)
- return rc;
+ if (tcam_db->tcam_db[i] != NULL) {
+ memset(&fparms, 0, sizeof(fparms));
+ fparms.dir = i;
+ fparms.rm_db = tcam_db->tcam_db[i];
+ rc = tf_rm_free_db(tfp, &fparms);
+ if (rc)
+ return rc;
+
+ tcam_db->tcam_db[i] = NULL;
+ }
- tcam_db->tcam_db[i] = NULL;
}
+ rc = tf_tcam_mgr_unbind_msg(tfp, dev);
+ if (rc)
+ return rc;
+
return 0;
}
@@ -222,6 +313,9 @@ tf_tcam_alloc(struct tf *tfp,
if (rc)
return rc;
+ /* If TCAM controlled by TCAM Manager */
+ if (tfs->tcam_mgr_control[parms->dir][parms->type])
+ return tf_tcam_mgr_alloc_msg(tfp, dev, parms);
rc = tf_session_get_db(tfp, TF_MODULE_TYPE_TCAM, &tcam_db_ptr);
if (rc) {
TFP_DRV_LOG(ERR,
@@ -251,12 +345,8 @@ tf_tcam_alloc(struct tf *tfp,
}
/* return the start index of each row */
- if (parms->priority == 0) {
if (i == 0)
parms->idx = index;
- } else {
- parms->idx = index;
- }
}
return 0;
@@ -307,6 +397,14 @@ tf_tcam_free(struct tf *tfp,
if (rc)
return rc;
+ /* If TCAM controlled by TCAM Manager */
+ if (tfs->tcam_mgr_control[parms->dir][parms->type])
+ /*
+ * If a session can have multiple references to an entry, check
+ * the reference count here before actually freeing the entry.
+ */
+ return tf_tcam_mgr_free_msg(tfp, dev, parms);
+
if (parms->idx % num_slices) {
TFP_DRV_LOG(ERR,
"%s: TCAM reserved resource is not multiple of %d\n",
@@ -429,6 +527,10 @@ tf_tcam_set(struct tf *tfp __rte_unused,
if (rc)
return rc;
+ /* If TCAM controlled by TCAM Manager */
+ if (tfs->tcam_mgr_control[parms->dir][parms->type])
+ return tf_tcam_mgr_set_msg(tfp, dev, parms);
+
rc = tf_session_get_db(tfp, TF_MODULE_TYPE_TCAM, &tcam_db_ptr);
if (rc) {
TFP_DRV_LOG(ERR,
@@ -508,6 +610,10 @@ tf_tcam_get(struct tf *tfp __rte_unused,
if (rc)
return rc;
+ /* If TCAM controlled by TCAM Manager */
+ if (tfs->tcam_mgr_control[parms->dir][parms->type])
+ return tf_tcam_mgr_get_msg(tfp, dev, parms);
+
rc = tf_session_get_db(tfp, TF_MODULE_TYPE_TCAM, &tcam_db_ptr);
if (rc) {
TFP_DRV_LOG(ERR,
diff --git a/drivers/net/bnxt/tf_core/tf_tcam_mgr_msg.c b/drivers/net/bnxt/tf_core/tf_tcam_mgr_msg.c
new file mode 100644
index 0000000000..c535f4f4f6
--- /dev/null
+++ b/drivers/net/bnxt/tf_core/tf_tcam_mgr_msg.c
@@ -0,0 +1,286 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2021-2023 Broadcom
+ * All rights reserved.
+ */
+
+#include <errno.h>
+
+#include "tfp.h"
+#include "tf_tcam.h"
+#include "cfa_tcam_mgr.h"
+#include "tf_tcam_mgr_msg.h"
+
+/*
+ * Table to convert TCAM type to logical TCAM type for applications.
+ * Index is tf_tcam_tbl_type.
+ */
+static enum cfa_tcam_mgr_tbl_type tcam_types[TF_TCAM_TBL_TYPE_MAX] = {
+ [TF_TCAM_TBL_TYPE_L2_CTXT_TCAM_HIGH] =
+ CFA_TCAM_MGR_TBL_TYPE_L2_CTXT_TCAM_HIGH_APPS,
+ [TF_TCAM_TBL_TYPE_L2_CTXT_TCAM_LOW] =
+ CFA_TCAM_MGR_TBL_TYPE_L2_CTXT_TCAM_LOW_APPS,
+ [TF_TCAM_TBL_TYPE_PROF_TCAM] =
+ CFA_TCAM_MGR_TBL_TYPE_PROF_TCAM_APPS,
+ [TF_TCAM_TBL_TYPE_WC_TCAM] =
+ CFA_TCAM_MGR_TBL_TYPE_WC_TCAM_APPS,
+ [TF_TCAM_TBL_TYPE_SP_TCAM] =
+ CFA_TCAM_MGR_TBL_TYPE_SP_TCAM_APPS,
+ [TF_TCAM_TBL_TYPE_CT_RULE_TCAM] =
+ CFA_TCAM_MGR_TBL_TYPE_CT_RULE_TCAM_APPS,
+ [TF_TCAM_TBL_TYPE_VEB_TCAM] =
+ CFA_TCAM_MGR_TBL_TYPE_VEB_TCAM_APPS,
+ [TF_TCAM_TBL_TYPE_WC_TCAM_HIGH] =
+ CFA_TCAM_MGR_TBL_TYPE_WC_TCAM_HIGH_APPS,
+ [TF_TCAM_TBL_TYPE_WC_TCAM_LOW] =
+ CFA_TCAM_MGR_TBL_TYPE_WC_TCAM_LOW_APPS,
+};
+
+static uint16_t hcapi_type[TF_TCAM_TBL_TYPE_MAX];
+
+/*
+ * This is the glue between the core tf_tcam and the TCAM manager. It is
+ * intended to abstract out the location of the TCAM manager so that the core
+ * code will be the same if the TCAM manager is in the core or in firmware.
+ *
+ * If the TCAM manager is in the core, then this file will just translate to
+ * TCAM manager APIs. If TCAM manager is in firmware, then this file will cause
+ * messages to be sent (except for bind and unbind).
+ */
+
+int
+tf_tcam_mgr_qcaps_msg(struct tf *tfp,
+ struct tf_dev_info *dev __rte_unused,
+ uint32_t *rx_tcam_supported,
+ uint32_t *tx_tcam_supported)
+{
+ struct cfa_tcam_mgr_context context;
+ struct cfa_tcam_mgr_qcaps_parms mgr_parms;
+ int rc;
+
+ context.tfp = tfp;
+ memset(&mgr_parms, 0, sizeof(mgr_parms));
+ rc = cfa_tcam_mgr_qcaps(&context, &mgr_parms);
+ if (rc >= 0) {
+ *rx_tcam_supported = mgr_parms.rx_tcam_supported;
+ *tx_tcam_supported = mgr_parms.tx_tcam_supported;
+ }
+ return rc;
+}
+
+int
+tf_tcam_mgr_bind_msg(struct tf *tfp,
+ struct tf_dev_info *dev __rte_unused,
+ struct tf_tcam_cfg_parms *parms,
+ struct tf_resource_info resv_res[][TF_TCAM_TBL_TYPE_MAX]
+ __rte_unused
+ )
+{
+ /* Common Code */
+ int type;
+
+ if (parms->num_elements != TF_TCAM_TBL_TYPE_MAX) {
+ TFP_DRV_LOG(ERR,
+ "Invalid number of elements in bind request.\n");
+ TFP_DRV_LOG(ERR,
+ "Expected %d, received %d.\n",
+ TF_TCAM_TBL_TYPE_MAX,
+ parms->num_elements);
+ return -EINVAL;
+ }
+
+ for (type = 0; type < TF_TCAM_TBL_TYPE_MAX; type++)
+ hcapi_type[type] = parms->cfg[type].hcapi_type;
+
+ struct cfa_tcam_mgr_context context;
+ struct cfa_tcam_mgr_cfg_parms mgr_parms;
+ struct tf_rm_resc_entry
+ mgr_resv_res[TF_DIR_MAX][CFA_TCAM_MGR_TBL_TYPE_MAX];
+ int dir, rc;
+
+ context.tfp = tfp;
+
+ memset(&mgr_parms, 0, sizeof(mgr_parms));
+
+ mgr_parms.num_elements = CFA_TCAM_MGR_TBL_TYPE_MAX;
+
+ /* Convert the data to logical tables */
+ for (dir = 0; dir < TF_DIR_MAX; dir++) {
+ for (type = 0; type < TF_TCAM_TBL_TYPE_MAX; type++) {
+ mgr_parms.tcam_cnt[dir][tcam_types[type]] =
+ parms->resources->tcam_cnt[dir].cnt[type];
+ mgr_resv_res[dir][tcam_types[type]].start =
+ resv_res[dir][type].start;
+ mgr_resv_res[dir][tcam_types[type]].stride =
+ resv_res[dir][type].stride;
+ }
+ }
+ mgr_parms.resv_res = mgr_resv_res;
+
+ rc = cfa_tcam_mgr_bind(&context, &mgr_parms);
+
+ return rc;
+}
+
+int
+tf_tcam_mgr_unbind_msg(struct tf *tfp,
+ struct tf_dev_info *dev __rte_unused)
+{
+ struct cfa_tcam_mgr_context context;
+
+ context.tfp = tfp;
+
+ return cfa_tcam_mgr_unbind(&context);
+}
+
+int
+tf_tcam_mgr_alloc_msg(struct tf *tfp,
+ struct tf_dev_info *dev __rte_unused,
+ struct tf_tcam_alloc_parms *parms)
+{
+ struct cfa_tcam_mgr_context context;
+ struct cfa_tcam_mgr_alloc_parms mgr_parms;
+ int rc;
+
+ if (parms->type >= TF_TCAM_TBL_TYPE_MAX) {
+ TFP_DRV_LOG(ERR,
+ "No such TCAM table %d.\n",
+ parms->type);
+ return -EINVAL;
+ }
+
+ context.tfp = tfp;
+
+ mgr_parms.dir = parms->dir;
+ mgr_parms.type = tcam_types[parms->type];
+ mgr_parms.hcapi_type = hcapi_type[parms->type];
+ mgr_parms.key_size = parms->key_size;
+ if (parms->priority > TF_TCAM_PRIORITY_MAX)
+ mgr_parms.priority = 0;
+ else
+ mgr_parms.priority = TF_TCAM_PRIORITY_MAX - parms->priority - 1;
+
+ rc = cfa_tcam_mgr_alloc(&context, &mgr_parms);
+ if (rc)
+ return rc;
+
+ parms->idx = mgr_parms.id;
+ return 0;
+}
+
+int
+tf_tcam_mgr_free_msg(struct tf *tfp,
+ struct tf_dev_info *dev __rte_unused,
+ struct tf_tcam_free_parms *parms)
+{
+ struct cfa_tcam_mgr_context context;
+ struct cfa_tcam_mgr_free_parms mgr_parms;
+
+ if (parms->type >= TF_TCAM_TBL_TYPE_MAX) {
+ TFP_DRV_LOG(ERR,
+ "No such TCAM table %d.\n",
+ parms->type);
+ return -EINVAL;
+ }
+
+ context.tfp = tfp;
+ mgr_parms.dir = parms->dir;
+ mgr_parms.type = tcam_types[parms->type];
+ mgr_parms.hcapi_type = hcapi_type[parms->type];
+ mgr_parms.id = parms->idx;
+
+ return cfa_tcam_mgr_free(&context, &mgr_parms);
+}
+
+int
+tf_tcam_mgr_set_msg(struct tf *tfp,
+ struct tf_dev_info *dev __rte_unused,
+ struct tf_tcam_set_parms *parms)
+{
+ struct cfa_tcam_mgr_context context;
+ struct cfa_tcam_mgr_set_parms mgr_parms;
+
+ if (parms->type >= TF_TCAM_TBL_TYPE_MAX) {
+ TFP_DRV_LOG(ERR,
+ "No such TCAM table %d.\n",
+ parms->type);
+ return -EINVAL;
+ }
+
+ context.tfp = tfp;
+ mgr_parms.dir = parms->dir;
+ mgr_parms.type = tcam_types[parms->type];
+ mgr_parms.hcapi_type = hcapi_type[parms->type];
+ mgr_parms.id = parms->idx;
+ mgr_parms.key = parms->key;
+ mgr_parms.mask = parms->mask;
+ mgr_parms.key_size = parms->key_size;
+ mgr_parms.result = parms->result;
+ mgr_parms.result_size = parms->result_size;
+
+ return cfa_tcam_mgr_set(&context, &mgr_parms);
+}
+
+int
+tf_tcam_mgr_get_msg(struct tf *tfp,
+ struct tf_dev_info *dev __rte_unused,
+ struct tf_tcam_get_parms *parms)
+{
+ int rc;
+ struct cfa_tcam_mgr_context context;
+ struct cfa_tcam_mgr_get_parms mgr_parms;
+
+ if (parms->type >= TF_TCAM_TBL_TYPE_MAX) {
+ TFP_DRV_LOG(ERR,
+ "No such TCAM table %d.\n",
+ parms->type);
+ return -EINVAL;
+ }
+
+ context.tfp = tfp;
+ mgr_parms.dir = parms->dir;
+ mgr_parms.type = tcam_types[parms->type];
+ mgr_parms.hcapi_type = hcapi_type[parms->type];
+ mgr_parms.id = parms->idx;
+ mgr_parms.key = parms->key;
+ mgr_parms.mask = parms->mask;
+ mgr_parms.key_size = parms->key_size;
+ mgr_parms.result = parms->result;
+ mgr_parms.result_size = parms->result_size;
+
+ rc = cfa_tcam_mgr_get(&context, &mgr_parms);
+ if (rc)
+ return rc;
+
+ parms->key_size = mgr_parms.key_size;
+ parms->result_size = mgr_parms.result_size;
+
+ return rc;
+}
+
+int
+tf_tcam_mgr_shared_clear_msg(struct tf *tfp,
+ struct tf_clear_tcam_shared_entries_parms *parms)
+{
+ struct cfa_tcam_mgr_context context;
+ struct cfa_tcam_mgr_shared_clear_parms mgr_parms;
+
+ context.tfp = tfp;
+ mgr_parms.dir = parms->dir;
+ mgr_parms.type = tcam_types[parms->tcam_tbl_type];
+
+ return cfa_tcam_mgr_shared_clear(&context, &mgr_parms);
+}
+
+int
+tf_tcam_mgr_shared_move_msg(struct tf *tfp,
+ struct tf_move_tcam_shared_entries_parms *parms)
+{
+ struct cfa_tcam_mgr_context context;
+ struct cfa_tcam_mgr_shared_move_parms mgr_parms;
+
+ context.tfp = tfp;
+ mgr_parms.dir = parms->dir;
+ mgr_parms.type = tcam_types[parms->tcam_tbl_type];
+
+ return cfa_tcam_mgr_shared_move(&context, &mgr_parms);
+}
diff --git a/drivers/net/bnxt/tf_core/tf_tcam_mgr_msg.h b/drivers/net/bnxt/tf_core/tf_tcam_mgr_msg.h
new file mode 100644
index 0000000000..8a8d136f5e
--- /dev/null
+++ b/drivers/net/bnxt/tf_core/tf_tcam_mgr_msg.h
@@ -0,0 +1,49 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2021-2023 Broadcom
+ * All rights reserved.
+ */
+
+#ifndef _TF_TCAM_MGR_MSG_H_
+#define _TF_TCAM_MGR_MSG_H_
+
+#include "tf_tcam.h"
+#include "tf_rm.h"
+
+int
+tf_tcam_mgr_qcaps_msg(struct tf *tfp,
+ struct tf_dev_info *dev __rte_unused,
+ uint32_t *rx_tcam_supported,
+ uint32_t *tx_tcam_supported);
+
+int
+tf_tcam_mgr_bind_msg(struct tf *tfp,
+ struct tf_dev_info *dev,
+ struct tf_tcam_cfg_parms *parms,
+ struct tf_resource_info resv_res[][TF_TCAM_TBL_TYPE_MAX]);
+int
+tf_tcam_mgr_unbind_msg(struct tf *tfp,
+ struct tf_dev_info *dev);
+int
+tf_tcam_mgr_alloc_msg(struct tf *tfp,
+ struct tf_dev_info *dev,
+ struct tf_tcam_alloc_parms *parms);
+int
+tf_tcam_mgr_free_msg(struct tf *tfp,
+ struct tf_dev_info *dev,
+ struct tf_tcam_free_parms *parms);
+int
+tf_tcam_mgr_set_msg(struct tf *tfp,
+ struct tf_dev_info *dev,
+ struct tf_tcam_set_parms *parms);
+int
+tf_tcam_mgr_get_msg(struct tf *tfp,
+ struct tf_dev_info *dev,
+ struct tf_tcam_get_parms *parms);
+int
+tf_tcam_mgr_shared_clear_msg(struct tf *tfp,
+ struct tf_clear_tcam_shared_entries_parms *parms);
+
+int
+tf_tcam_mgr_shared_move_msg(struct tf *tfp,
+ struct tf_move_tcam_shared_entries_parms *parms);
+#endif /* _TF_TCAM_MGR_MSG_H_ */
diff --git a/drivers/net/bnxt/tf_core/tf_tcam_shared.c b/drivers/net/bnxt/tf_core/tf_tcam_shared.c
index c120c6f577..e853f616f9 100644
--- a/drivers/net/bnxt/tf_core/tf_tcam_shared.c
+++ b/drivers/net/bnxt/tf_core/tf_tcam_shared.c
@@ -1,11 +1,13 @@
/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2019-2021 Broadcom
+ * Copyright(c) 2019-2023 Broadcom
* All rights reserved.
*/
#include <string.h>
#include <rte_common.h>
+#include "tf_core.h"
+
#include "tf_tcam_shared.h"
#include "tf_tcam.h"
#include "tf_common.h"
@@ -16,229 +18,8 @@
#include "tf_session.h"
#include "tf_msg.h"
#include "bitalloc.h"
-#include "tf_core.h"
-
-/** Shared WC TCAM pool identifiers
- */
-enum tf_tcam_shared_wc_pool_id {
- TF_TCAM_SHARED_WC_POOL_HI = 0,
- TF_TCAM_SHARED_WC_POOL_LO = 1,
- TF_TCAM_SHARED_WC_POOL_MAX = 2
-};
-
-/** Get string representation of a WC TCAM shared pool id
- */
-static const char *
-tf_pool_2_str(enum tf_tcam_shared_wc_pool_id id)
-{
- switch (id) {
- case TF_TCAM_SHARED_WC_POOL_HI:
- return "TCAM_SHARED_WC_POOL_HI";
- case TF_TCAM_SHARED_WC_POOL_LO:
- return "TCAM_SHARED_WC_POOL_LO";
- default:
- return "Invalid TCAM_SHARED_WC_POOL";
- }
-}
-
-/** The WC TCAM shared pool datastructure
- */
-struct tf_tcam_shared_wc_pool {
- /** Start and stride data */
- struct tf_resource_info info;
- /** bitalloc pool */
- struct bitalloc *pool;
-};
-
-struct tf_tcam_shared_wc_pools {
- struct tf_tcam_shared_wc_pool db[TF_DIR_MAX][TF_TCAM_SHARED_WC_POOL_MAX];
-};
-
-/** The WC TCAM shared pool declarations
- */
-/* struct tf_tcam_shared_wc_pool tcam_shared_wc[TF_DIR_MAX][TF_TCAM_SHARED_WC_POOL_MAX]; */
-
-static int
-tf_tcam_shared_create_db(struct tf_tcam_shared_wc_pools **db)
-{
- struct tfp_calloc_parms cparms;
- int rc = 0;
-
- cparms.nitems = 1;
- cparms.alignment = 0;
- cparms.size = sizeof(struct tf_tcam_shared_wc_pools);
- rc = tfp_calloc(&cparms);
- if (rc) {
- TFP_DRV_LOG(ERR,
- "TCAM shared db allocation failed (%s)\n",
- strerror(-rc));
- return rc;
- }
- *db = cparms.mem_va;
-
- return rc;
-}
-
-/** Create a WC TCAM shared pool
- */
-static int
-tf_tcam_shared_create_wc_pool(int dir,
- enum tf_tcam_shared_wc_pool_id id,
- int start,
- int stride,
- struct tf_tcam_shared_wc_pools *tcam_shared_wc)
-{
- int rc = 0;
- bool free = true;
- struct tfp_calloc_parms cparms;
- uint32_t pool_size;
-
- /* Create pool */
- pool_size = (BITALLOC_SIZEOF(stride) / sizeof(struct bitalloc));
- cparms.nitems = pool_size;
- cparms.alignment = 0;
- cparms.size = sizeof(struct bitalloc);
- rc = tfp_calloc(&cparms);
- if (rc) {
- TFP_DRV_LOG(ERR,
- "%s: pool memory alloc failed %s:%s\n",
- tf_dir_2_str(dir), tf_pool_2_str(id),
- strerror(-rc));
- return rc;
- }
- tcam_shared_wc->db[dir][id].pool = (struct bitalloc *)cparms.mem_va;
-
- rc = ba_init(tcam_shared_wc->db[dir][id].pool,
- stride,
- free);
-
- if (rc) {
- TFP_DRV_LOG(ERR,
- "%s: pool bitalloc failed %s\n",
- tf_dir_2_str(dir), tf_pool_2_str(id));
- return rc;
- }
-
- tcam_shared_wc->db[dir][id].info.start = start;
- tcam_shared_wc->db[dir][id].info.stride = stride;
-
- return rc;
-}
-/** Free a WC TCAM shared pool
- */
-static int
-tf_tcam_shared_free_wc_pool(int dir,
- enum tf_tcam_shared_wc_pool_id id,
- struct tf_tcam_shared_wc_pools *tcam_shared_wc)
-{
- int rc = 0;
- TF_CHECK_PARMS1(tcam_shared_wc);
-
- tcam_shared_wc->db[dir][id].info.start = 0;
- tcam_shared_wc->db[dir][id].info.stride = 0;
-
- if (tcam_shared_wc->db[dir][id].pool)
- tfp_free((void *)tcam_shared_wc->db[dir][id].pool);
- return rc;
-}
-
-/** Get the number of WC TCAM slices allocated during 1 allocation/free
- */
-static int
-tf_tcam_shared_get_slices(struct tf *tfp,
- struct tf_dev_info *dev,
- uint16_t *num_slices)
-{
- int rc;
-
- if (dev->ops->tf_dev_get_tcam_slice_info == NULL) {
- rc = -EOPNOTSUPP;
- TFP_DRV_LOG(ERR,
- "Operation not supported, rc:%s\n", strerror(-rc));
- return rc;
- }
- rc = dev->ops->tf_dev_get_tcam_slice_info(tfp,
- TF_TCAM_TBL_TYPE_WC_TCAM,
- 0,
- num_slices);
- return rc;
-}
-
-static bool
-tf_tcam_db_valid(struct tf *tfp,
- enum tf_dir dir)
-{
- struct tcam_rm_db *tcam_db;
- void *tcam_db_ptr = NULL;
- int rc;
-
- TF_CHECK_PARMS1(tfp);
-
- rc = tf_session_get_db(tfp, TF_MODULE_TYPE_TCAM, &tcam_db_ptr);
- if (rc)
- return false;
-
- tcam_db = (struct tcam_rm_db *)tcam_db_ptr;
-
- if (tcam_db->tcam_db[dir])
- return true;
-
- return false;
-}
-
-static int
-tf_tcam_shared_get_rm_info(struct tf *tfp,
- enum tf_dir dir,
- uint16_t *hcapi_type,
- struct tf_rm_alloc_info *info)
-{
- int rc;
- struct tcam_rm_db *tcam_db;
- void *tcam_db_ptr = NULL;
- struct tf_rm_get_alloc_info_parms ainfo;
- struct tf_rm_get_hcapi_parms hparms;
-
- TF_CHECK_PARMS3(tfp, hcapi_type, info);
-
- rc = tf_session_get_db(tfp, TF_MODULE_TYPE_TCAM, &tcam_db_ptr);
- if (rc) {
- TFP_DRV_LOG(INFO,
- "Tcam_db is not initialized, rc:%s\n",
- strerror(-rc));
- return 0;
- }
- tcam_db = (struct tcam_rm_db *)tcam_db_ptr;
-
- /* Convert TF type to HCAPI RM type */
- memset(&hparms, 0, sizeof(hparms));
- hparms.rm_db = tcam_db->tcam_db[dir];
- hparms.subtype = TF_TCAM_TBL_TYPE_WC_TCAM;
- hparms.hcapi_type = hcapi_type;
-
- rc = tf_rm_get_hcapi_type(&hparms);
- if (rc) {
- TFP_DRV_LOG(ERR,
- "%s: Get RM hcapi type failed %s\n",
- tf_dir_2_str(dir),
- strerror(-rc));
- return rc;
- }
-
- memset(info, 0, sizeof(struct tf_rm_alloc_info));
- ainfo.rm_db = tcam_db->tcam_db[dir];
- ainfo.subtype = TF_TCAM_TBL_TYPE_WC_TCAM;
- ainfo.info = info;
-
- rc = tf_rm_get_info(&ainfo);
- if (rc) {
- TFP_DRV_LOG(ERR,
- "%s: TCAM rm info get failed %s\n",
- tf_dir_2_str(dir),
- strerror(-rc));
- return rc;
- }
- return rc;
-}
+#include "tf_rm.h"
+#include "tf_tcam_mgr_msg.h"
/**
* tf_tcam_shared_bind
@@ -247,92 +28,15 @@ int
tf_tcam_shared_bind(struct tf *tfp,
struct tf_tcam_cfg_parms *parms)
{
- int rc, dir;
- struct tf_session *tfs;
- struct tf_dev_info *dev;
- struct tf_rm_alloc_info info;
- uint16_t start, stride;
- uint16_t num_slices;
- uint16_t hcapi_type;
- struct tf_tcam_shared_wc_pools *tcam_shared_wc = NULL;
+ int rc;
TF_CHECK_PARMS2(tfp, parms);
/* Perform normal bind
*/
rc = tf_tcam_bind(tfp, parms);
- if (rc)
- return rc;
-
- /* After the normal TCAM bind, if this is a shared session
- * create all required databases for the WC_HI and WC_LO pools
- */
- rc = tf_session_get_session_internal(tfp, &tfs);
- if (rc) {
- TFP_DRV_LOG(ERR,
- "Session access failure: %s\n", strerror(-rc));
- return rc;
- }
- if (tf_session_is_shared_session(tfs)) {
- /* Retrieve the device information */
- rc = tf_session_get_device(tfs, &dev);
- if (rc)
- return rc;
-
- tf_tcam_shared_create_db(&tcam_shared_wc);
-
-
- /* If there are WC TCAM entries, create 2 pools each with 1/2
- * the total number of entries
- */
- for (dir = 0; dir < TF_DIR_MAX; dir++) {
- if (!tf_tcam_db_valid(tfp, dir))
- continue;
-
- rc = tf_tcam_shared_get_rm_info(tfp,
- dir,
- &hcapi_type,
- &info);
- if (rc) {
- TFP_DRV_LOG(ERR,
- "%s: TCAM rm info get failed\n",
- tf_dir_2_str(dir));
- goto done;
- }
-
- start = info.entry.start;
- stride = info.entry.stride / 2;
-
- tf_tcam_shared_create_wc_pool(dir,
- TF_TCAM_SHARED_WC_POOL_HI,
- start,
- stride,
- tcam_shared_wc);
-
- start += stride;
- tf_tcam_shared_create_wc_pool(dir,
- TF_TCAM_SHARED_WC_POOL_LO,
- start,
- stride,
- tcam_shared_wc);
-
- tf_session_set_tcam_shared_db(tfp, (void *)tcam_shared_wc);
- }
-
- rc = tf_tcam_shared_get_slices(tfp,
- dev,
- &num_slices);
- if (rc)
- return rc;
-
- if (num_slices > 1) {
- TFP_DRV_LOG(ERR,
- "Only single slice supported\n");
- return -EOPNOTSUPP;
- }
- }
-done:
return rc;
+
}
/**
* tf_tcam_shared_unbind
@@ -340,132 +44,10 @@ tf_tcam_shared_bind(struct tf *tfp,
int
tf_tcam_shared_unbind(struct tf *tfp)
{
- int rc, dir;
- struct tf_dev_info *dev;
- struct tf_session *tfs;
- void *tcam_shared_db_ptr = NULL;
- struct tf_tcam_shared_wc_pools *tcam_shared_wc;
- enum tf_tcam_shared_wc_pool_id pool_id;
- struct tf_tcam_free_parms parms;
- struct bitalloc *pool;
- uint16_t start;
- int log_idx, phy_idx;
- uint16_t hcapi_type;
- struct tf_rm_alloc_info info;
- int i, pool_cnt;
+ int rc;
TF_CHECK_PARMS1(tfp);
- /* Retrieve the session information */
- rc = tf_session_get_session_internal(tfp, &tfs);
- if (rc)
- return rc;
-
- /* If not the shared session, call the normal
- * tcam unbind and exit
- */
- if (!tf_session_is_shared_session(tfs)) {
- rc = tf_tcam_unbind(tfp);
- return rc;
- }
-
- /* We must be a shared session, get the database
- */
- rc = tf_session_get_tcam_shared_db(tfp,
- (void *)&tcam_shared_db_ptr);
- if (rc) {
- TFP_DRV_LOG(ERR,
- "Failed to get tcam_shared_db, rc:%s\n",
- strerror(-rc));
- return rc;
- }
-
- tcam_shared_wc =
- (struct tf_tcam_shared_wc_pools *)tcam_shared_db_ptr;
-
-
- /* Get the device
- */
- rc = tf_session_get_device(tfs, &dev);
- if (rc)
- return rc;
-
-
- /* If there are WC TCAM entries allocated, free them
- */
- for (dir = 0; dir < TF_DIR_MAX; dir++) {
- /* If the database is invalid, skip
- */
- if (!tf_tcam_db_valid(tfp, dir))
- continue;
-
- rc = tf_tcam_shared_get_rm_info(tfp,
- dir,
- &hcapi_type,
- &info);
- if (rc) {
- TFP_DRV_LOG(ERR,
- "%s: TCAM shared rm info get failed\n",
- tf_dir_2_str(dir));
- return rc;
- }
-
- for (pool_id = TF_TCAM_SHARED_WC_POOL_HI;
- pool_id < TF_TCAM_SHARED_WC_POOL_MAX;
- pool_id++) {
- pool = tcam_shared_wc->db[dir][pool_id].pool;
- start = tcam_shared_wc->db[dir][pool_id].info.start;
- pool_cnt = ba_inuse_count(pool);
-
- if (pool_cnt) {
- TFP_DRV_LOG(INFO,
- "%s: %s: %d residuals found, freeing\n",
- tf_dir_2_str(dir),
- tf_pool_2_str(pool_id),
- pool_cnt);
- }
-
- log_idx = 0;
-
- for (i = 0; i < pool_cnt; i++) {
- log_idx = ba_find_next_inuse(pool, log_idx);
-
- if (log_idx < 0) {
- TFP_DRV_LOG(ERR,
- "Expected a found %s entry %d\n",
- tf_pool_2_str(pool_id),
- i);
- /* attempt normal unbind
- */
- goto done;
- }
- phy_idx = start + log_idx;
-
- parms.type = TF_TCAM_TBL_TYPE_WC_TCAM;
- parms.hcapi_type = hcapi_type;
- parms.idx = phy_idx;
- parms.dir = dir;
- rc = tf_msg_tcam_entry_free(tfp, dev, &parms);
- if (rc) {
- /* Log error */
- TFP_DRV_LOG(ERR,
- "%s: %s: %d free failed, rc:%s\n",
- tf_dir_2_str(parms.dir),
- tf_tcam_tbl_2_str(parms.type),
- phy_idx,
- strerror(-rc));
- return rc;
- }
- }
- /* Free the pool once all the entries
- * have been cleared
- */
- tf_tcam_shared_free_wc_pool(dir,
- pool_id,
- tcam_shared_wc);
- }
- }
-done:
rc = tf_tcam_unbind(tfp);
return rc;
}
@@ -478,79 +60,11 @@ tf_tcam_shared_alloc(struct tf *tfp,
struct tf_tcam_alloc_parms *parms)
{
int rc;
- struct tf_session *tfs;
- struct tf_dev_info *dev;
- int log_idx;
- struct bitalloc *pool;
- enum tf_tcam_shared_wc_pool_id id;
- struct tf_tcam_shared_wc_pools *tcam_shared_wc;
- void *tcam_shared_db_ptr = NULL;
TF_CHECK_PARMS2(tfp, parms);
- /* Retrieve the session information */
- rc = tf_session_get_session_internal(tfp, &tfs);
- if (rc)
- return rc;
-
- /* If we aren't the shared session or the type is
- * not one of the special WC TCAM types, call the normal
- * allocation.
- */
- if (!tf_session_is_shared_session(tfs) ||
- (parms->type != TF_TCAM_TBL_TYPE_WC_TCAM_HIGH &&
- parms->type != TF_TCAM_TBL_TYPE_WC_TCAM_LOW)) {
- /* Perform normal alloc
- */
- rc = tf_tcam_alloc(tfp, parms);
- return rc;
- }
-
- if (!tf_tcam_db_valid(tfp, parms->dir)) {
- TFP_DRV_LOG(ERR,
- "%s: tcam shared pool doesn't exist\n",
- tf_dir_2_str(parms->dir));
- return -ENOMEM;
- }
-
- rc = tf_session_get_tcam_shared_db(tfp, (void *)&tcam_shared_db_ptr);
- if (rc) {
- TFP_DRV_LOG(ERR,
- "Failed to get tcam_shared_db from session, rc:%s\n",
- strerror(-rc));
- return rc;
- }
- tcam_shared_wc = (struct tf_tcam_shared_wc_pools *)tcam_shared_db_ptr;
-
- if (parms->type == TF_TCAM_TBL_TYPE_WC_TCAM_HIGH)
- id = TF_TCAM_SHARED_WC_POOL_HI;
- else
- id = TF_TCAM_SHARED_WC_POOL_LO;
-
- /* Retrieve the device information */
- rc = tf_session_get_device(tfs, &dev);
- if (rc)
- return rc;
-
- pool = tcam_shared_wc->db[parms->dir][id].pool;
-
- /*
- * priority 0: allocate from top of the tcam i.e. high
- * priority !0: allocate index from bottom i.e lowest
- */
- if (parms->priority)
- log_idx = ba_alloc_reverse(pool);
- else
- log_idx = ba_alloc(pool);
- if (log_idx == BA_FAIL) {
- TFP_DRV_LOG(ERR,
- "%s: Allocation failed, rc:%s\n",
- tf_dir_2_str(parms->dir),
- strerror(ENOMEM));
- return -ENOMEM;
- }
- parms->idx = log_idx;
- return 0;
+ rc = tf_tcam_alloc(tfp, parms);
+ return rc;
}
int
@@ -558,118 +72,11 @@ tf_tcam_shared_free(struct tf *tfp,
struct tf_tcam_free_parms *parms)
{
int rc;
- struct tf_session *tfs;
- struct tf_dev_info *dev;
- int allocated = 0;
- uint16_t start;
- int phy_idx;
- struct bitalloc *pool;
- enum tf_tcam_shared_wc_pool_id id;
- struct tf_tcam_free_parms nparms;
- uint16_t hcapi_type;
- struct tf_rm_alloc_info info;
- void *tcam_shared_db_ptr = NULL;
- struct tf_tcam_shared_wc_pools *tcam_shared_wc;
TF_CHECK_PARMS2(tfp, parms);
- /* Retrieve the session information */
- rc = tf_session_get_session_internal(tfp, &tfs);
- if (rc)
- return rc;
-
- /* If we aren't the shared session or the type is
- * not one of the special WC TCAM types, call the normal
- * allocation.
- */
- if (!tf_session_is_shared_session(tfs) ||
- (parms->type != TF_TCAM_TBL_TYPE_WC_TCAM_HIGH &&
- parms->type != TF_TCAM_TBL_TYPE_WC_TCAM_LOW)) {
- /* Perform normal free
- */
- rc = tf_tcam_free(tfp, parms);
- return rc;
- }
-
- if (!tf_tcam_db_valid(tfp, parms->dir)) {
- TFP_DRV_LOG(ERR,
- "%s: tcam shared pool doesn't exist\n",
- tf_dir_2_str(parms->dir));
- return -ENOMEM;
- }
-
- rc = tf_session_get_tcam_shared_db(tfp, (void *)&tcam_shared_db_ptr);
- if (rc) {
- TFP_DRV_LOG(ERR,
- "Failed to get tcam_shared_db from session, rc:%s\n",
- strerror(-rc));
- return rc;
- }
- tcam_shared_wc = (struct tf_tcam_shared_wc_pools *)tcam_shared_db_ptr;
-
-
- if (parms->type == TF_TCAM_TBL_TYPE_WC_TCAM_HIGH)
- id = TF_TCAM_SHARED_WC_POOL_HI;
- else
- id = TF_TCAM_SHARED_WC_POOL_LO;
-
- /* Retrieve the device information */
- rc = tf_session_get_device(tfs, &dev);
- if (rc)
- return rc;
-
- rc = tf_tcam_shared_get_rm_info(tfp,
- parms->dir,
- &hcapi_type,
- &info);
- if (rc) {
- TFP_DRV_LOG(ERR,
- "%s: TCAM rm info get failed\n",
- tf_dir_2_str(parms->dir));
- return rc;
- }
-
- pool = tcam_shared_wc->db[parms->dir][id].pool;
- start = tcam_shared_wc->db[parms->dir][id].info.start;
-
- phy_idx = parms->idx + start;
- allocated = ba_inuse(pool, parms->idx);
-
- if (allocated != TF_RM_ALLOCATED_ENTRY_IN_USE) {
- TFP_DRV_LOG(ERR,
- "%s: Entry already free, type:%d, idx:%d\n",
- tf_dir_2_str(parms->dir), parms->type, parms->idx);
- return -EINVAL;
- }
-
- rc = ba_free(pool, parms->idx);
- if (rc) {
- TFP_DRV_LOG(ERR,
- "%s: Free failed, type:%s, idx:%d\n",
- tf_dir_2_str(parms->dir),
- tf_tcam_tbl_2_str(parms->type),
- parms->idx);
- return rc;
- }
-
- /* Override HI/LO type with parent WC TCAM type */
- nparms = *parms;
- nparms.type = TF_TCAM_TBL_TYPE_WC_TCAM;
- nparms.hcapi_type = hcapi_type;
- nparms.idx = phy_idx;
-
- rc = tf_msg_tcam_entry_free(tfp, dev, &nparms);
- if (rc) {
- /* Log error */
- TFP_DRV_LOG(ERR,
- "%s: %s: log%d free failed, rc:%s\n",
- tf_dir_2_str(nparms.dir),
- tf_tcam_tbl_2_str(nparms.type),
- phy_idx,
- strerror(-rc));
- return rc;
- }
- return 0;
+ rc = tf_tcam_free(tfp, parms);
+ return rc;
}
int
@@ -677,109 +84,11 @@ tf_tcam_shared_set(struct tf *tfp __rte_unused,
struct tf_tcam_set_parms *parms __rte_unused)
{
int rc;
- struct tf_session *tfs;
- struct tf_dev_info *dev;
- int allocated = 0;
- int phy_idx, log_idx;
- struct tf_tcam_set_parms nparms;
- struct bitalloc *pool;
- uint16_t start;
- enum tf_tcam_shared_wc_pool_id id;
- uint16_t hcapi_type;
- struct tf_rm_alloc_info info;
- struct tf_tcam_shared_wc_pools *tcam_shared_wc;
- void *tcam_shared_db_ptr = NULL;
-
TF_CHECK_PARMS2(tfp, parms);
- /* Retrieve the session information */
- rc = tf_session_get_session_internal(tfp, &tfs);
- if (rc)
- return rc;
-
- /* If we aren't the shared session or one of our
- * special types
- */
- if (!tf_session_is_shared_session(tfs) ||
- (parms->type != TF_TCAM_TBL_TYPE_WC_TCAM_HIGH &&
- parms->type != TF_TCAM_TBL_TYPE_WC_TCAM_LOW)) {
- /* Perform normal set and exit
- */
- rc = tf_tcam_set(tfp, parms);
- return rc;
- }
-
- if (!tf_tcam_db_valid(tfp, parms->dir)) {
- TFP_DRV_LOG(ERR,
- "%s: tcam shared pool doesn't exist\n",
- tf_dir_2_str(parms->dir));
- return -ENOMEM;
- }
-
- /* Retrieve the device information */
- rc = tf_session_get_device(tfs, &dev);
- if (rc)
- return rc;
-
- if (parms->type == TF_TCAM_TBL_TYPE_WC_TCAM_HIGH)
- id = TF_TCAM_SHARED_WC_POOL_HI;
- else
- id = TF_TCAM_SHARED_WC_POOL_LO;
-
- rc = tf_session_get_tcam_shared_db(tfp, (void *)&tcam_shared_db_ptr);
- if (rc) {
- TFP_DRV_LOG(ERR,
- "Failed to get tcam_shared_db from session, rc:%s\n",
- strerror(-rc));
- return rc;
- }
- tcam_shared_wc = (struct tf_tcam_shared_wc_pools *)tcam_shared_db_ptr;
-
- pool = tcam_shared_wc->db[parms->dir][id].pool;
- start = tcam_shared_wc->db[parms->dir][id].info.start;
-
- log_idx = parms->idx;
- phy_idx = parms->idx + start;
- allocated = ba_inuse(pool, parms->idx);
-
- if (allocated != TF_RM_ALLOCATED_ENTRY_IN_USE) {
- TFP_DRV_LOG(ERR,
- "%s: Entry is not allocated, type:%d, logid:%d\n",
- tf_dir_2_str(parms->dir), parms->type, log_idx);
- return -EINVAL;
- }
-
- rc = tf_tcam_shared_get_rm_info(tfp,
- parms->dir,
- &hcapi_type,
- &info);
- if (rc)
- return rc;
-
- /* Override HI/LO type with parent WC TCAM type */
- nparms.hcapi_type = hcapi_type;
- nparms.dir = parms->dir;
- nparms.type = TF_TCAM_TBL_TYPE_WC_TCAM;
- nparms.idx = phy_idx;
- nparms.key = parms->key;
- nparms.mask = parms->mask;
- nparms.key_size = parms->key_size;
- nparms.result = parms->result;
- nparms.result_size = parms->result_size;
-
- rc = tf_msg_tcam_entry_set(tfp, dev, &nparms);
- if (rc) {
- /* Log error */
- TFP_DRV_LOG(ERR,
- "%s: %s: phy entry %d set failed, rc:%s",
- tf_dir_2_str(parms->dir),
- tf_tcam_tbl_2_str(nparms.type),
- phy_idx,
- strerror(-rc));
- return rc;
- }
- return 0;
+ rc = tf_tcam_set(tfp, parms);
+ return rc;
}
int
@@ -787,226 +96,10 @@ tf_tcam_shared_get(struct tf *tfp __rte_unused,
struct tf_tcam_get_parms *parms)
{
int rc;
- struct tf_session *tfs;
- struct tf_dev_info *dev;
- int allocated = 0;
- int phy_idx, log_idx;
- struct tf_tcam_get_parms nparms;
- struct bitalloc *pool;
- uint16_t start;
- enum tf_tcam_shared_wc_pool_id id;
- uint16_t hcapi_type;
- struct tf_rm_alloc_info info;
- struct tf_tcam_shared_wc_pools *tcam_shared_wc;
- void *tcam_shared_db_ptr = NULL;
TF_CHECK_PARMS2(tfp, parms);
- /* Retrieve the session information */
- rc = tf_session_get_session_internal(tfp, &tfs);
- if (rc)
- return rc;
-
- /* If we aren't the shared session or one of our
- * special types
- */
- if (!tf_session_is_shared_session(tfs) ||
- (parms->type != TF_TCAM_TBL_TYPE_WC_TCAM_HIGH &&
- parms->type != TF_TCAM_TBL_TYPE_WC_TCAM_LOW)) {
- /* Perform normal get and exit
- */
- rc = tf_tcam_get(tfp, parms);
- return rc;
- }
-
- if (!tf_tcam_db_valid(tfp, parms->dir)) {
- TFP_DRV_LOG(ERR,
- "%s: tcam shared pool doesn't exist\n",
- tf_dir_2_str(parms->dir));
- return -ENOMEM;
- }
-
- /* Retrieve the device information */
- rc = tf_session_get_device(tfs, &dev);
- if (rc)
- return rc;
- if (parms->type == TF_TCAM_TBL_TYPE_WC_TCAM_HIGH)
- id = TF_TCAM_SHARED_WC_POOL_HI;
- else
- id = TF_TCAM_SHARED_WC_POOL_LO;
-
-
- rc = tf_session_get_tcam_shared_db(tfp, (void *)&tcam_shared_db_ptr);
- if (rc) {
- TFP_DRV_LOG(ERR,
- "Failed to get tcam_shared_db from session, rc:%s\n",
- strerror(-rc));
- return rc;
- }
- tcam_shared_wc = (struct tf_tcam_shared_wc_pools *)tcam_shared_db_ptr;
-
- pool = tcam_shared_wc->db[parms->dir][id].pool;
- start = tcam_shared_wc->db[parms->dir][id].info.start;
-
- log_idx = parms->idx;
- phy_idx = parms->idx + start;
- allocated = ba_inuse(pool, parms->idx);
-
- if (allocated != TF_RM_ALLOCATED_ENTRY_IN_USE) {
- TFP_DRV_LOG(ERR,
- "%s: Entry is not allocated, type:%d, logid:%d\n",
- tf_dir_2_str(parms->dir), parms->type, log_idx);
- return -EINVAL;
- }
-
- rc = tf_tcam_shared_get_rm_info(tfp,
- parms->dir,
- &hcapi_type,
- &info);
- if (rc)
- return rc;
-
- /* Override HI/LO type with parent WC TCAM type */
- nparms = *parms;
- nparms.type = TF_TCAM_TBL_TYPE_WC_TCAM;
- nparms.hcapi_type = hcapi_type;
- nparms.idx = phy_idx;
-
- rc = tf_msg_tcam_entry_get(tfp, dev, &nparms);
- if (rc) {
- /* Log error */
- TFP_DRV_LOG(ERR,
- "%s: %s: Entry %d set failed, rc:%s",
- tf_dir_2_str(nparms.dir),
- tf_tcam_tbl_2_str(nparms.type),
- nparms.idx,
- strerror(-rc));
- return rc;
- }
- return 0;
-}
-
-/* Normally, device specific code wouldn't reside here, it belongs
- * in a separate device specific function in tf_device_pxx.c.
- * But this code is placed here as it is not a long term solution
- * and we would like to have this code centrally located for easy
- * removal
- */
-#define TF_TCAM_SHARED_KEY_SLICE_SZ_BYTES_P4 12
-#define TF_TCAM_SHARED_REMAP_SZ_BYTES_P4 4
-#define TF_TCAM_SHARED_KEY_SLICE_SZ_BYTES_P58 24
-#define TF_TCAM_SHARED_REMAP_SZ_BYTES_P58 8
-
-/* Temporary builder defines pulled in here and adjusted
- * for max WC TCAM values
- */
-union tf_tmp_field_obj {
- uint32_t words[(TF_TCAM_SHARED_REMAP_SZ_BYTES_P58 + 3) / 4];
- uint8_t bytes[TF_TCAM_SHARED_REMAP_SZ_BYTES_P58];
-};
-
-union tf_tmp_key {
- uint32_t words[(TF_TCAM_SHARED_KEY_SLICE_SZ_BYTES_P58 + 3) / 4];
- uint8_t bytes[TF_TCAM_SHARED_KEY_SLICE_SZ_BYTES_P58];
-};
-
-/** p58 has an enable bit, p4 does not
- */
-#define TF_TCAM_SHARED_ENTRY_ENABLE 0x8
-
-/** Move a WC TCAM entry from the high offset to the same low offset
- */
-static int
-tf_tcam_shared_move_entry(struct tf *tfp,
- struct tf_dev_info *dev,
- uint16_t hcapi_type,
- enum tf_dir dir,
- int sphy_idx,
- int dphy_idx,
- int key_sz_bytes,
- int remap_sz_bytes,
- bool set_enable_bit)
-{
- int rc = 0;
- struct tf_tcam_get_parms gparms;
- struct tf_tcam_set_parms sparms;
- struct tf_tcam_free_parms fparms;
- union tf_tmp_key tcam_key_obj;
- union tf_tmp_key tcam_key_msk_obj;
- union tf_tmp_field_obj tcam_remap_obj;
-
- memset(&tcam_key_obj, 0, sizeof(tcam_key_obj));
- memset(&tcam_key_msk_obj, 0, sizeof(tcam_key_msk_obj));
- memset(&tcam_remap_obj, 0, sizeof(tcam_remap_obj));
- memset(&gparms, 0, sizeof(gparms));
-
- gparms.hcapi_type = hcapi_type;
- gparms.dir = dir;
- gparms.type = TF_TCAM_TBL_TYPE_WC_TCAM;
- gparms.idx = sphy_idx;
- gparms.key = (uint8_t *)&tcam_key_obj;
- gparms.key_size = key_sz_bytes;
- gparms.mask = (uint8_t *)&tcam_key_msk_obj;
- gparms.result = (uint8_t *)&tcam_remap_obj;
- gparms.result_size = remap_sz_bytes;
-
- rc = tf_msg_tcam_entry_get(tfp, dev, &gparms);
- if (rc) {
- /* Log error */
- TFP_DRV_LOG(ERR,
- "%s: %s: phyid(%d) get failed, rc:%s\n",
- tf_tcam_tbl_2_str(gparms.type),
- tf_dir_2_str(dir),
- gparms.idx,
- strerror(-rc));
- return rc;
- }
-
- if (set_enable_bit)
- tcam_key_obj.bytes[0] |= TF_TCAM_SHARED_ENTRY_ENABLE;
-
- /* Override HI/LO type with parent WC TCAM type */
- sparms.hcapi_type = hcapi_type;
- sparms.dir = dir;
- sparms.type = TF_TCAM_TBL_TYPE_WC_TCAM;
- sparms.idx = dphy_idx;
- sparms.key = gparms.key;
- sparms.mask = gparms.mask;
- sparms.key_size = key_sz_bytes;
- sparms.result = gparms.result;
- sparms.result_size = remap_sz_bytes;
-
- rc = tf_msg_tcam_entry_set(tfp, dev, &sparms);
- if (rc) {
- /* Log error */
- TFP_DRV_LOG(ERR,
- "%s: %s phyid(%d/0x%x) set failed, rc:%s\n",
- tf_tcam_tbl_2_str(sparms.type),
- tf_dir_2_str(dir),
- sparms.idx,
- sparms.idx,
- strerror(-rc));
- return rc;
- }
-
- /* Override HI/LO type with parent WC TCAM type */
- fparms.dir = dir;
- fparms.type = TF_TCAM_TBL_TYPE_WC_TCAM;
- fparms.hcapi_type = hcapi_type;
- fparms.idx = sphy_idx;
-
- rc = tf_msg_tcam_entry_free(tfp, dev, &fparms);
- if (rc) {
- /* Log error */
- TFP_DRV_LOG(ERR,
- "%s: %s: phyid(%d/0x%x) free failed, rc:%s\n",
- tf_dir_2_str(dir),
- tf_tcam_tbl_2_str(fparms.type),
- sphy_idx,
- sphy_idx,
- strerror(-rc));
- return rc;
- }
+ rc = tf_tcam_get(tfp, parms);
return rc;
}
@@ -1015,23 +108,10 @@ tf_tcam_shared_move_entry(struct tf *tfp,
*/
static
int tf_tcam_shared_move(struct tf *tfp,
- struct tf_move_tcam_shared_entries_parms *parms,
- int key_sz_bytes,
- int remap_sz_bytes,
- bool set_enable_bit)
+ struct tf_move_tcam_shared_entries_parms *parms)
{
- int rc;
struct tf_session *tfs;
- struct tf_dev_info *dev;
- int log_idx;
- struct bitalloc *hi_pool, *lo_pool;
- uint16_t hi_start, lo_start;
- enum tf_tcam_shared_wc_pool_id hi_id, lo_id;
- uint16_t hcapi_type;
- struct tf_rm_alloc_info info;
- int hi_cnt, i;
- struct tf_tcam_shared_wc_pools *tcam_shared_wc;
- void *tcam_shared_db_ptr = NULL;
+ int rc;
TF_CHECK_PARMS2(tfp, parms);
@@ -1052,104 +132,7 @@ int tf_tcam_shared_move(struct tf *tfp,
return -EOPNOTSUPP;
}
- if (!tf_tcam_db_valid(tfp, parms->dir)) {
- TFP_DRV_LOG(ERR,
- "%s: tcam shared pool doesn't exist\n",
- tf_dir_2_str(parms->dir));
- return -ENOMEM;
- }
-
- /* Retrieve the device information */
- rc = tf_session_get_device(tfs, &dev);
- if (rc) {
- /* TODO print amazing error */
- return rc;
- }
-
- rc = tf_tcam_shared_get_rm_info(tfp,
- parms->dir,
- &hcapi_type,
- &info);
- if (rc) {
- TFP_DRV_LOG(ERR,
- "%s: TCAM rm info get failed\n",
- tf_dir_2_str(parms->dir));
- return rc;
- }
-
- rc = tf_session_get_tcam_shared_db(tfp, (void *)&tcam_shared_db_ptr);
- if (rc) {
- TFP_DRV_LOG(ERR,
- "Failed to get tcam_shared_db from session, rc:%s\n",
- strerror(-rc));
- return rc;
- }
- tcam_shared_wc = (struct tf_tcam_shared_wc_pools *)tcam_shared_db_ptr;
-
- hi_id = TF_TCAM_SHARED_WC_POOL_HI;
- hi_pool = tcam_shared_wc->db[parms->dir][hi_id].pool;
- hi_start = tcam_shared_wc->db[parms->dir][hi_id].info.start;
-
- lo_id = TF_TCAM_SHARED_WC_POOL_LO;
- lo_pool = tcam_shared_wc->db[parms->dir][lo_id].pool;
- lo_start = tcam_shared_wc->db[parms->dir][lo_id].info.start;
-
- if (hi_pool == NULL || lo_pool == NULL)
- return -ENOMEM;
-
- /* Get the total count of in use entries in the high pool
- */
- hi_cnt = ba_inuse_count(hi_pool);
-
- /* Copy each valid entry to the same low pool logical offset
- */
- log_idx = 0;
-
- for (i = 0; i < hi_cnt; i++) {
- /* Find next free index starting from where we left off
- */
- log_idx = ba_find_next_inuse(hi_pool, log_idx);
- if (log_idx < 0) {
- TFP_DRV_LOG(ERR,
- "Expected a found %s entry %d\n",
- tf_pool_2_str(hi_id),
- i);
- goto done;
- }
- /* The user should have never allocated from the low
- * pool because the move only happens when switching
- * from the high to the low pool
- */
- if (ba_alloc_index(lo_pool, log_idx) < 0) {
- TFP_DRV_LOG(ERR,
- "Warning %s index %d already allocated\n",
- tf_pool_2_str(lo_id),
- i);
-
- /* Since already allocated, continue with move
- */
- }
-
- rc = tf_tcam_shared_move_entry(tfp, dev,
- hcapi_type,
- parms->dir,
- hi_start + log_idx,
- lo_start + log_idx,
- key_sz_bytes,
- remap_sz_bytes,
- set_enable_bit);
- if (rc) {
- TFP_DRV_LOG(ERR,
- "%s: Move error %s to %s index %d\n",
- tf_dir_2_str(parms->dir),
- tf_pool_2_str(hi_id),
- tf_pool_2_str(lo_id),
- i);
- goto done;
- }
- ba_free(hi_pool, log_idx);
- }
-done:
+ rc = tf_tcam_mgr_shared_move_msg(tfp, parms);
return rc;
}
@@ -1159,24 +142,17 @@ tf_tcam_shared_move_p4(struct tf *tfp,
{
int rc = 0;
rc = tf_tcam_shared_move(tfp,
- parms,
- TF_TCAM_SHARED_KEY_SLICE_SZ_BYTES_P4,
- TF_TCAM_SHARED_REMAP_SZ_BYTES_P4,
- false); /* no enable bit */
+ parms);
return rc;
}
-
int
tf_tcam_shared_move_p58(struct tf *tfp,
struct tf_move_tcam_shared_entries_parms *parms)
{
int rc = 0;
rc = tf_tcam_shared_move(tfp,
- parms,
- TF_TCAM_SHARED_KEY_SLICE_SZ_BYTES_P58,
- TF_TCAM_SHARED_REMAP_SZ_BYTES_P58,
- true); /* set enable bit */
+ parms);
return rc;
}
@@ -1186,16 +162,6 @@ tf_tcam_shared_clear(struct tf *tfp,
{
int rc = 0;
struct tf_session *tfs;
- struct tf_dev_info *dev;
- uint16_t start;
- int phy_idx;
- enum tf_tcam_shared_wc_pool_id id;
- struct tf_tcam_free_parms nparms;
- uint16_t hcapi_type;
- struct tf_rm_alloc_info info;
- void *tcam_shared_db_ptr = NULL;
- struct tf_tcam_shared_wc_pools *tcam_shared_wc;
- int i, cnt;
TF_CHECK_PARMS2(tfp, parms);
@@ -1209,74 +175,6 @@ tf_tcam_shared_clear(struct tf *tfp,
parms->tcam_tbl_type != TF_TCAM_TBL_TYPE_WC_TCAM_LOW))
return -EOPNOTSUPP;
- if (!tf_tcam_db_valid(tfp, parms->dir)) {
- TFP_DRV_LOG(ERR,
- "%s: tcam shared pool doesn't exist\n",
- tf_dir_2_str(parms->dir));
- return -ENOMEM;
- }
-
- rc = tf_session_get_tcam_shared_db(tfp, (void *)&tcam_shared_db_ptr);
- if (rc) {
- TFP_DRV_LOG(ERR,
- "Failed to get tcam_shared_db from session, rc:%s\n",
- strerror(-rc));
- return rc;
- }
- tcam_shared_wc = (struct tf_tcam_shared_wc_pools *)tcam_shared_db_ptr;
-
-
- if (parms->tcam_tbl_type == TF_TCAM_TBL_TYPE_WC_TCAM_HIGH)
- id = TF_TCAM_SHARED_WC_POOL_HI;
- else
- id = TF_TCAM_SHARED_WC_POOL_LO;
-
-
- /* Retrieve the device information */
- rc = tf_session_get_device(tfs, &dev);
- if (rc)
- return rc;
-
- rc = tf_tcam_shared_get_rm_info(tfp,
- parms->dir,
- &hcapi_type,
- &info);
- if (rc) {
- TFP_DRV_LOG(ERR,
- "%s: TCAM rm info get failed\n",
- tf_dir_2_str(parms->dir));
- return rc;
- }
-
- start = tcam_shared_wc->db[parms->dir][id].info.start;
- cnt = tcam_shared_wc->db[parms->dir][id].info.stride;
-
- /* Override HI/LO type with parent WC TCAM type */
- nparms.dir = parms->dir;
- nparms.type = TF_TCAM_TBL_TYPE_WC_TCAM;
- nparms.hcapi_type = hcapi_type;
-
- for (i = 0; i < cnt; i++) {
- phy_idx = start + i;
- nparms.idx = phy_idx;
-
- /* Clear entry */
- rc = tf_msg_tcam_entry_free(tfp, dev, &nparms);
- if (rc) {
- /* Log error */
- TFP_DRV_LOG(ERR,
- "%s: %s: log%d free failed, rc:%s\n",
- tf_dir_2_str(nparms.dir),
- tf_tcam_tbl_2_str(nparms.type),
- phy_idx,
- strerror(-rc));
- return rc;
- }
- }
-
- TFP_DRV_LOG(DEBUG,
- "%s: TCAM shared clear pool(%s)\n",
- tf_dir_2_str(nparms.dir),
- tf_pool_2_str(id));
- return 0;
+ rc = tf_tcam_mgr_shared_clear_msg(tfp, parms);
+ return rc;
}
diff --git a/drivers/net/bnxt/tf_core/tf_tcam_shared.h b/drivers/net/bnxt/tf_core/tf_tcam_shared.h
index 524631f262..e25babcd18 100644
--- a/drivers/net/bnxt/tf_core/tf_tcam_shared.h
+++ b/drivers/net/bnxt/tf_core/tf_tcam_shared.h
@@ -1,5 +1,5 @@
/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2019-2021 Broadcom
+ * Copyright(c) 2019-2023 Broadcom
* All rights reserved.
*/
@@ -129,7 +129,6 @@ int tf_tcam_shared_set(struct tf *tfp,
int tf_tcam_shared_get(struct tf *tfp,
struct tf_tcam_get_parms *parms);
-
/**
* Moves entries from the WC_TCAM_HI to the WC_TCAM_LO shared pools
* for the P4 device.
diff --git a/drivers/net/bnxt/tf_ulp/bnxt_ulp.c b/drivers/net/bnxt/tf_ulp/bnxt_ulp.c
index 1bb38399e4..8513ee06a9 100644
--- a/drivers/net/bnxt/tf_ulp/bnxt_ulp.c
+++ b/drivers/net/bnxt/tf_ulp/bnxt_ulp.c
@@ -448,13 +448,13 @@ ulp_ctx_shared_session_open(struct bnxt *bp,
switch (ulp_dev_id) {
case BNXT_ULP_DEVICE_ID_WH_PLUS:
- parms.device_type = TF_DEVICE_TYPE_WH;
+ parms.device_type = TF_DEVICE_TYPE_P5;
break;
case BNXT_ULP_DEVICE_ID_STINGRAY:
parms.device_type = TF_DEVICE_TYPE_SR;
break;
case BNXT_ULP_DEVICE_ID_THOR:
- parms.device_type = TF_DEVICE_TYPE_THOR;
+ parms.device_type = TF_DEVICE_TYPE_P4;
break;
default:
BNXT_TF_DBG(ERR, "Unable to determine dev for opening session.\n");
@@ -563,13 +563,13 @@ ulp_ctx_session_open(struct bnxt *bp,
switch (ulp_dev_id) {
case BNXT_ULP_DEVICE_ID_WH_PLUS:
- params.device_type = TF_DEVICE_TYPE_WH;
+ params.device_type = TF_DEVICE_TYPE_P5;
break;
case BNXT_ULP_DEVICE_ID_STINGRAY:
params.device_type = TF_DEVICE_TYPE_SR;
break;
case BNXT_ULP_DEVICE_ID_THOR:
- params.device_type = TF_DEVICE_TYPE_THOR;
+ params.device_type = TF_DEVICE_TYPE_P4;
break;
default:
BNXT_TF_DBG(ERR, "Unable to determine device for opening session.\n");
--
2.39.2 (Apple Git-143)
[-- Attachment #2: S/MIME Cryptographic Signature --]
[-- Type: application/pkcs7-signature, Size: 4218 bytes --]
next prev parent reply other threads:[~2023-06-28 16:31 UTC|newest]
Thread overview: 30+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-05-04 17:36 [PATCH v3 00/11] sync Truflow support with latest release Ajit Khaparde
2023-05-04 17:36 ` [PATCH v3 01/11] net/bnxt: remove deprecated features Ajit Khaparde
2023-05-04 17:36 ` [PATCH v3 02/11] net/bnxt: update bnxt hsi structure Ajit Khaparde
2023-05-04 17:36 ` [PATCH v3 03/11] net/bnxt: update copyright date and cleanup whitespace Ajit Khaparde
2023-05-04 17:36 ` [PATCH v3 04/11] net/bnxt: update Truflow core Ajit Khaparde
2023-06-10 18:32 ` Thomas Monjalon
2023-06-28 16:29 ` [PATCH v4 00/11] sync Truflow support with latest release Ajit Khaparde
2023-06-28 16:29 ` [PATCH v4 01/11] net/bnxt: remove deprecated features Ajit Khaparde
2023-06-28 16:29 ` [PATCH v4 02/11] net/bnxt: update bnxt hsi structure Ajit Khaparde
2023-06-28 16:29 ` [PATCH v4 03/11] net/bnxt: update copyright date and cleanup whitespace Ajit Khaparde
2023-06-28 16:29 ` Ajit Khaparde [this message]
2023-06-28 16:29 ` [PATCH v4 05/11] net/bnxt: update ULP shared session support Ajit Khaparde
2023-06-28 16:29 ` [PATCH v4 06/11] net/bnxt: add RSS and Queue action in TruFLow Ajit Khaparde
2023-06-28 16:29 ` [PATCH v4 07/11] net/bnxt: add support for rte meter Ajit Khaparde
2023-06-28 16:29 ` [PATCH v4 08/11] net/bnxt: update PTP support on Thor Ajit Khaparde
2023-06-28 16:29 ` [PATCH v4 09/11] net/bnxt: fix multi-root card support Ajit Khaparde
2023-06-28 16:29 ` [PATCH v4 10/11] net/bnxt: add support for eCPRI packet parsing Ajit Khaparde
2023-06-28 16:29 ` [PATCH v4 11/11] net/bnxt: set RSS config based on RSS mode Ajit Khaparde
2023-06-28 16:35 ` [PATCH v3 04/11] net/bnxt: update Truflow core Ajit Khaparde
2023-06-28 19:07 ` Thomas Monjalon
2023-06-29 4:30 ` Ajit Khaparde
2023-06-30 12:16 ` Ajit Khaparde
2023-05-04 17:36 ` [PATCH v3 05/11] net/bnxt: update ULP shared session support Ajit Khaparde
2023-05-04 17:36 ` [PATCH v3 06/11] net/bnxt: add RSS and Queue action in TruFLow Ajit Khaparde
2023-05-04 17:36 ` [PATCH v3 07/11] net/bnxt: add support for rte meter Ajit Khaparde
2023-05-04 17:36 ` [PATCH v3 08/11] net/bnxt: update PTP support on Thor Ajit Khaparde
2023-05-04 17:36 ` [PATCH v3 09/11] net/bnxt: fix multi-root card support Ajit Khaparde
2023-05-04 17:36 ` [PATCH v3 10/11] net/bnxt: add support for eCPRI packet parsing Ajit Khaparde
2023-05-04 17:36 ` [PATCH v3 11/11] net/bnxt: set RSS config based on RSS mode Ajit Khaparde
2023-05-10 17:16 ` [PATCH v3 00/11] sync Truflow support with latest release Ajit Khaparde
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20230628162927.92858-5-ajit.khaparde@broadcom.com \
--to=ajit.khaparde@broadcom.com \
--cc=dev@dpdk.org \
--cc=farah.smith@broadcom.com \
--cc=ferruh.yigit@intel.com \
--cc=sbhosle@broadcom.com \
--cc=stuart.schacher@broadcom.com \
--cc=thomas@monjalon.net \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).