[v2,17/51] net/bnxt: implement support for TCAM access

Message ID 20200701065212.41391-18-ajit.khaparde@broadcom.com (mailing list archive)
State Changes Requested, archived
Delegated to: Ajit Khaparde
Headers
Series add features for host-based flow management |

Checks

Context Check Description
ci/checkpatch success coding style OK
ci/Intel-compilation fail Compilation issues

Commit Message

Ajit Khaparde July 1, 2020, 6:51 a.m. UTC
  From: Jay Ding <jay.ding@broadcom.com>

Implement TCAM alloc, free, bind, and unbind functions
Update tf_core, tf_msg, etc.

Signed-off-by: Jay Ding <jay.ding@broadcom.com>
Signed-off-by: Venkat Duvvuru <venkatkumar.duvvuru@broadcom.com>
Reviewed-by: Randy Schacher <stuart.schacher@broadcom.com>
Reviewed-by: Ajit Khaparde <ajit.khaparde@broadcom.com>
---
 drivers/net/bnxt/tf_core/tf_core.c      | 258 ++++++++++-----------
 drivers/net/bnxt/tf_core/tf_device.h    |  14 +-
 drivers/net/bnxt/tf_core/tf_device_p4.c |  25 ++-
 drivers/net/bnxt/tf_core/tf_msg.c       |  31 +--
 drivers/net/bnxt/tf_core/tf_msg.h       |   4 +-
 drivers/net/bnxt/tf_core/tf_tcam.c      | 285 +++++++++++++++++++++++-
 drivers/net/bnxt/tf_core/tf_tcam.h      |  66 ++++--
 7 files changed, 480 insertions(+), 203 deletions(-)
  

Patch

diff --git a/drivers/net/bnxt/tf_core/tf_core.c b/drivers/net/bnxt/tf_core/tf_core.c
index 648d0d1bd..29522c66e 100644
--- a/drivers/net/bnxt/tf_core/tf_core.c
+++ b/drivers/net/bnxt/tf_core/tf_core.c
@@ -19,43 +19,6 @@ 
 #include "tf_common.h"
 #include "hwrm_tf.h"
 
-static int tf_check_tcam_entry(enum tf_tcam_tbl_type tcam_tbl_type,
-			       enum tf_device_type device,
-			       uint16_t key_sz_in_bits,
-			       uint16_t *num_slice_per_row)
-{
-	uint16_t key_bytes;
-	uint16_t slice_sz = 0;
-
-#define CFA_P4_WC_TCAM_SLICES_PER_ROW 2
-#define CFA_P4_WC_TCAM_SLICE_SIZE     12
-
-	if (tcam_tbl_type == TF_TCAM_TBL_TYPE_WC_TCAM) {
-		key_bytes = TF_BITS2BYTES_WORD_ALIGN(key_sz_in_bits);
-		if (device == TF_DEVICE_TYPE_WH) {
-			slice_sz = CFA_P4_WC_TCAM_SLICE_SIZE;
-			*num_slice_per_row = CFA_P4_WC_TCAM_SLICES_PER_ROW;
-		} else {
-			TFP_DRV_LOG(ERR,
-				    "Unsupported device type %d\n",
-				    device);
-			return -ENOTSUP;
-		}
-
-		if (key_bytes > *num_slice_per_row * slice_sz) {
-			TFP_DRV_LOG(ERR,
-				    "%s: Key size %d is not supported\n",
-				    tf_tcam_tbl_2_str(tcam_tbl_type),
-				    key_bytes);
-			return -ENOTSUP;
-		}
-	} else { /* for other type of tcam */
-		*num_slice_per_row = 1;
-	}
-
-	return 0;
-}
-
 /**
  * Create EM Tbl pool of memory indexes.
  *
@@ -918,49 +881,56 @@  tf_alloc_tcam_entry(struct tf *tfp,
 		    struct tf_alloc_tcam_entry_parms *parms)
 {
 	int rc;
-	int index;
 	struct tf_session *tfs;
-	struct bitalloc *session_pool;
-	uint16_t num_slice_per_row;
-
-	/* TEMP, due to device design. When tcam is modularized device
-	 * should be retrieved from the session
-	 */
-	enum tf_device_type device_type;
-	/* TEMP */
-	device_type = TF_DEVICE_TYPE_WH;
+	struct tf_dev_info *dev;
+	struct tf_tcam_alloc_parms aparms = { 0 };
 
-	TF_CHECK_PARMS_SESSION(tfp, parms);
+	TF_CHECK_PARMS2(tfp, parms);
 
-	tfs = (struct tf_session *)(tfp->session->core_data);
+	/* Retrieve the session information */
+	rc = tf_session_get_session(tfp, &tfs);
+	if (rc) {
+		TFP_DRV_LOG(ERR,
+			    "%s: Failed to lookup session, rc:%s\n",
+			    tf_dir_2_str(parms->dir),
+			    strerror(-rc));
+		return rc;
+	}
 
-	rc = tf_check_tcam_entry(parms->tcam_tbl_type,
-				 device_type,
-				 parms->key_sz_in_bits,
-				 &num_slice_per_row);
-	/* Error logging handled by tf_check_tcam_entry */
-	if (rc)
+	/* Retrieve the device information */
+	rc = tf_session_get_device(tfs, &dev);
+	if (rc) {
+		TFP_DRV_LOG(ERR,
+			    "%s: Failed to lookup device, rc:%s\n",
+			    tf_dir_2_str(parms->dir),
+			    strerror(-rc));
 		return rc;
+	}
 
-	rc = tf_rm_lookup_tcam_type_pool(tfs,
-					 parms->dir,
-					 parms->tcam_tbl_type,
-					 &session_pool);
-	/* Error logging handled by tf_rm_lookup_tcam_type_pool */
-	if (rc)
+	if (dev->ops->tf_dev_alloc_tcam == NULL) {
+		rc = -EOPNOTSUPP;
+		TFP_DRV_LOG(ERR,
+			    "%s: Operation not supported, rc:%s\n",
+			    tf_dir_2_str(parms->dir),
+			    strerror(-rc));
 		return rc;
+	}
 
-	index = ba_alloc(session_pool);
-	if (index == BA_FAIL) {
-		TFP_DRV_LOG(ERR, "%s: %s: No resource available\n",
+	aparms.dir = parms->dir;
+	aparms.type = parms->tcam_tbl_type;
+	aparms.key_size = TF_BITS2BYTES_WORD_ALIGN(parms->key_sz_in_bits);
+	aparms.priority = parms->priority;
+	rc = dev->ops->tf_dev_alloc_tcam(tfp, &aparms);
+	if (rc) {
+		TFP_DRV_LOG(ERR,
+			    "%s: TCAM allocation failed, rc:%s\n",
 			    tf_dir_2_str(parms->dir),
-			    tf_tcam_tbl_2_str(parms->tcam_tbl_type));
-		return -ENOMEM;
+			    strerror(-rc));
+		return rc;
 	}
 
-	index *= num_slice_per_row;
+	parms->idx = aparms.idx;
 
-	parms->idx = index;
 	return 0;
 }
 
@@ -969,55 +939,60 @@  tf_set_tcam_entry(struct tf *tfp,
 		  struct tf_set_tcam_entry_parms *parms)
 {
 	int rc;
-	int id;
-	int index;
 	struct tf_session *tfs;
-	struct bitalloc *session_pool;
-	uint16_t num_slice_per_row;
-
-	/* TEMP, due to device design. When tcam is modularized device
-	 * should be retrieved from the session
-	 */
-	enum tf_device_type device_type;
-	/* TEMP */
-	device_type = TF_DEVICE_TYPE_WH;
+	struct tf_dev_info *dev;
+	struct tf_tcam_set_parms sparms = { 0 };
 
-	TF_CHECK_PARMS_SESSION(tfp, parms);
+	TF_CHECK_PARMS2(tfp, parms);
 
-	tfs = (struct tf_session *)(tfp->session->core_data);
+	/* Retrieve the session information */
+	rc = tf_session_get_session(tfp, &tfs);
+	if (rc) {
+		TFP_DRV_LOG(ERR,
+			    "%s: Failed to lookup session, rc:%s\n",
+			    tf_dir_2_str(parms->dir),
+			    strerror(-rc));
+		return rc;
+	}
 
-	rc = tf_check_tcam_entry(parms->tcam_tbl_type,
-				 device_type,
-				 parms->key_sz_in_bits,
-				 &num_slice_per_row);
-	/* Error logging handled by tf_check_tcam_entry */
-	if (rc)
+	/* Retrieve the device information */
+	rc = tf_session_get_device(tfs, &dev);
+	if (rc) {
+		TFP_DRV_LOG(ERR,
+			    "%s: Failed to lookup device, rc:%s\n",
+			    tf_dir_2_str(parms->dir),
+			    strerror(-rc));
 		return rc;
+	}
 
-	rc = tf_rm_lookup_tcam_type_pool(tfs,
-					 parms->dir,
-					 parms->tcam_tbl_type,
-					 &session_pool);
-	/* Error logging handled by tf_rm_lookup_tcam_type_pool */
-	if (rc)
+	if (dev->ops->tf_dev_set_tcam == NULL) {
+		rc = -EOPNOTSUPP;
+		TFP_DRV_LOG(ERR,
+			    "%s: Operation not supported, rc:%s\n",
+			    tf_dir_2_str(parms->dir),
+			    strerror(-rc));
 		return rc;
+	}
 
-	/* Verify that the entry has been previously allocated */
-	index = parms->idx / num_slice_per_row;
+	sparms.dir = parms->dir;
+	sparms.type = parms->tcam_tbl_type;
+	sparms.idx = parms->idx;
+	sparms.key = parms->key;
+	sparms.mask = parms->mask;
+	sparms.key_size = TF_BITS2BYTES_WORD_ALIGN(parms->key_sz_in_bits);
+	sparms.result = parms->result;
+	sparms.result_size = TF_BITS2BYTES_WORD_ALIGN(parms->result_sz_in_bits);
 
-	id = ba_inuse(session_pool, index);
-	if (id != 1) {
+	rc = dev->ops->tf_dev_set_tcam(tfp, &sparms);
+	if (rc) {
 		TFP_DRV_LOG(ERR,
-		   "%s: %s: Invalid or not allocated index, idx:%d\n",
-		   tf_dir_2_str(parms->dir),
-		   tf_tcam_tbl_2_str(parms->tcam_tbl_type),
-		   parms->idx);
-		return -EINVAL;
+			    "%s: TCAM set failed, rc:%s\n",
+			    tf_dir_2_str(parms->dir),
+			    strerror(-rc));
+		return rc;
 	}
 
-	rc = tf_msg_tcam_entry_set(tfp, parms);
-
-	return rc;
+	return 0;
 }
 
 int
@@ -1033,59 +1008,52 @@  tf_free_tcam_entry(struct tf *tfp,
 		   struct tf_free_tcam_entry_parms *parms)
 {
 	int rc;
-	int index;
 	struct tf_session *tfs;
-	struct bitalloc *session_pool;
-	uint16_t num_slice_per_row = 1;
-
-	/* TEMP, due to device design. When tcam is modularized device
-	 * should be retrieved from the session
-	 */
-	enum tf_device_type device_type;
-	/* TEMP */
-	device_type = TF_DEVICE_TYPE_WH;
+	struct tf_dev_info *dev;
+	struct tf_tcam_free_parms fparms = { 0 };
 
-	TF_CHECK_PARMS_SESSION(tfp, parms);
-	tfs = (struct tf_session *)(tfp->session->core_data);
+	TF_CHECK_PARMS2(tfp, parms);
 
-	rc = tf_check_tcam_entry(parms->tcam_tbl_type,
-				 device_type,
-				 0,
-				 &num_slice_per_row);
-	/* Error logging handled by tf_check_tcam_entry */
-	if (rc)
+	/* Retrieve the session information */
+	rc = tf_session_get_session(tfp, &tfs);
+	if (rc) {
+		TFP_DRV_LOG(ERR,
+			    "%s: Failed to lookup session, rc:%s\n",
+			    tf_dir_2_str(parms->dir),
+			    strerror(-rc));
 		return rc;
+	}
 
-	rc = tf_rm_lookup_tcam_type_pool(tfs,
-					 parms->dir,
-					 parms->tcam_tbl_type,
-					 &session_pool);
-	/* Error logging handled by tf_rm_lookup_tcam_type_pool */
-	if (rc)
+	/* Retrieve the device information */
+	rc = tf_session_get_device(tfs, &dev);
+	if (rc) {
+		TFP_DRV_LOG(ERR,
+			    "%s: Failed to lookup device, rc:%s\n",
+			    tf_dir_2_str(parms->dir),
+			    strerror(-rc));
 		return rc;
+	}
 
-	index = parms->idx / num_slice_per_row;
-
-	rc = ba_inuse(session_pool, index);
-	if (rc == BA_FAIL || rc == BA_ENTRY_FREE) {
-		TFP_DRV_LOG(ERR, "%s: %s: Entry %d already free",
+	if (dev->ops->tf_dev_free_tcam == NULL) {
+		rc = -EOPNOTSUPP;
+		TFP_DRV_LOG(ERR,
+			    "%s: Operation not supported, rc:%s\n",
 			    tf_dir_2_str(parms->dir),
-			    tf_tcam_tbl_2_str(parms->tcam_tbl_type),
-			    index);
-		return -EINVAL;
+			    strerror(-rc));
+		return rc;
 	}
 
-	ba_free(session_pool, index);
-
-	rc = tf_msg_tcam_entry_free(tfp, parms);
+	fparms.dir = parms->dir;
+	fparms.type = parms->tcam_tbl_type;
+	fparms.idx = parms->idx;
+	rc = dev->ops->tf_dev_free_tcam(tfp, &fparms);
 	if (rc) {
-		/* Log error */
-		TFP_DRV_LOG(ERR, "%s: %s: Entry %d free failed with err %s",
+		TFP_DRV_LOG(ERR,
+			    "%s: TCAM allocation failed, rc:%s\n",
 			    tf_dir_2_str(parms->dir),
-			    tf_tcam_tbl_2_str(parms->tcam_tbl_type),
-			    parms->idx,
 			    strerror(-rc));
+		return rc;
 	}
 
-	return rc;
+	return 0;
 }
diff --git a/drivers/net/bnxt/tf_core/tf_device.h b/drivers/net/bnxt/tf_core/tf_device.h
index 1501b20d9..32d9a5442 100644
--- a/drivers/net/bnxt/tf_core/tf_device.h
+++ b/drivers/net/bnxt/tf_core/tf_device.h
@@ -116,8 +116,11 @@  struct tf_dev_ops {
 	 * [in] tfp
 	 *   Pointer to TF handle
 	 *
-	 * [out] slice_size
-	 *   Pointer to slice size the device supports
+	 * [in] type
+	 *   TCAM table type
+	 *
+	 * [in] key_sz
+	 *   Key size
 	 *
 	 * [out] num_slices_per_row
 	 *   Pointer to number of slices per row the device supports
@@ -126,9 +129,10 @@  struct tf_dev_ops {
 	 *   - (0) if successful.
 	 *   - (-EINVAL) on failure.
 	 */
-	int (*tf_dev_get_wc_tcam_slices)(struct tf *tfp,
-					 uint16_t *slice_size,
-					 uint16_t *num_slices_per_row);
+	int (*tf_dev_get_tcam_slice_info)(struct tf *tfp,
+					  enum tf_tcam_tbl_type type,
+					  uint16_t key_sz,
+					  uint16_t *num_slices_per_row);
 
 	/**
 	 * Allocation of an identifier element.
diff --git a/drivers/net/bnxt/tf_core/tf_device_p4.c b/drivers/net/bnxt/tf_core/tf_device_p4.c
index f4bd95f1c..77fb693dd 100644
--- a/drivers/net/bnxt/tf_core/tf_device_p4.c
+++ b/drivers/net/bnxt/tf_core/tf_device_p4.c
@@ -56,18 +56,21 @@  tf_dev_p4_get_max_types(struct tf *tfp __rte_unused,
  *   - (-EINVAL) on failure.
  */
 static int
-tf_dev_p4_get_wc_tcam_slices(struct tf *tfp __rte_unused,
-			     uint16_t *slice_size,
-			     uint16_t *num_slices_per_row)
+tf_dev_p4_get_tcam_slice_info(struct tf *tfp __rte_unused,
+			      enum tf_tcam_tbl_type type,
+			      uint16_t key_sz,
+			      uint16_t *num_slices_per_row)
 {
-#define CFA_P4_WC_TCAM_SLICE_SIZE       12
-#define CFA_P4_WC_TCAM_SLICES_PER_ROW    2
+#define CFA_P4_WC_TCAM_SLICES_PER_ROW 2
+#define CFA_P4_WC_TCAM_SLICE_SIZE     12
 
-	if (slice_size == NULL || num_slices_per_row == NULL)
-		return -EINVAL;
-
-	*slice_size = CFA_P4_WC_TCAM_SLICE_SIZE;
-	*num_slices_per_row = CFA_P4_WC_TCAM_SLICES_PER_ROW;
+	if (type == TF_TCAM_TBL_TYPE_WC_TCAM) {
+		*num_slices_per_row = CFA_P4_WC_TCAM_SLICES_PER_ROW;
+		if (key_sz > *num_slices_per_row * CFA_P4_WC_TCAM_SLICE_SIZE)
+			return -ENOTSUP;
+	} else { /* for other type of tcam */
+		*num_slices_per_row = 1;
+	}
 
 	return 0;
 }
@@ -77,7 +80,7 @@  tf_dev_p4_get_wc_tcam_slices(struct tf *tfp __rte_unused,
  */
 const struct tf_dev_ops tf_dev_ops_p4 = {
 	.tf_dev_get_max_types = tf_dev_p4_get_max_types,
-	.tf_dev_get_wc_tcam_slices = tf_dev_p4_get_wc_tcam_slices,
+	.tf_dev_get_tcam_slice_info = tf_dev_p4_get_tcam_slice_info,
 	.tf_dev_alloc_ident = tf_ident_alloc,
 	.tf_dev_free_ident = tf_ident_free,
 	.tf_dev_alloc_tbl = tf_tbl_alloc,
diff --git a/drivers/net/bnxt/tf_core/tf_msg.c b/drivers/net/bnxt/tf_core/tf_msg.c
index 60274eb35..b50e1d48c 100644
--- a/drivers/net/bnxt/tf_core/tf_msg.c
+++ b/drivers/net/bnxt/tf_core/tf_msg.c
@@ -9,6 +9,7 @@ 
 #include <string.h>
 
 #include "tf_msg_common.h"
+#include "tf_device.h"
 #include "tf_msg.h"
 #include "tf_util.h"
 #include "tf_session.h"
@@ -1480,27 +1481,19 @@  tf_msg_bulk_get_tbl_entry(struct tf *tfp,
 	return tfp_le_to_cpu_32(parms.tf_resp_code);
 }
 
-#define TF_BYTES_PER_SLICE(tfp) 12
-#define NUM_SLICES(tfp, bytes) \
-	(((bytes) + TF_BYTES_PER_SLICE(tfp) - 1) / TF_BYTES_PER_SLICE(tfp))
-
 int
 tf_msg_tcam_entry_set(struct tf *tfp,
-		      struct tf_set_tcam_entry_parms *parms)
+		      struct tf_tcam_set_parms *parms)
 {
 	int rc;
 	struct tfp_send_msg_parms mparms = { 0 };
 	struct hwrm_tf_tcam_set_input req = { 0 };
 	struct hwrm_tf_tcam_set_output resp = { 0 };
-	uint16_t key_bytes =
-		TF_BITS2BYTES_WORD_ALIGN(parms->key_sz_in_bits);
-	uint16_t result_bytes =
-		TF_BITS2BYTES_WORD_ALIGN(parms->result_sz_in_bits);
 	struct tf_msg_dma_buf buf = { 0 };
 	uint8_t *data = NULL;
 	int data_size = 0;
 
-	rc = tf_tcam_tbl_2_hwrm(parms->tcam_tbl_type, &req.type);
+	rc = tf_tcam_tbl_2_hwrm(parms->type, &req.type);
 	if (rc != 0)
 		return rc;
 
@@ -1508,11 +1501,11 @@  tf_msg_tcam_entry_set(struct tf *tfp,
 	if (parms->dir == TF_DIR_TX)
 		req.flags |= HWRM_TF_TCAM_SET_INPUT_FLAGS_DIR_TX;
 
-	req.key_size = key_bytes;
-	req.mask_offset = key_bytes;
+	req.key_size = parms->key_size;
+	req.mask_offset = parms->key_size;
 	/* Result follows after key and mask, thus multiply by 2 */
-	req.result_offset = 2 * key_bytes;
-	req.result_size = result_bytes;
+	req.result_offset = 2 * parms->key_size;
+	req.result_size = parms->result_size;
 	data_size = 2 * req.key_size + req.result_size;
 
 	if (data_size <= TF_PCI_BUF_SIZE_MAX) {
@@ -1530,9 +1523,9 @@  tf_msg_tcam_entry_set(struct tf *tfp,
 			   sizeof(buf.pa_addr));
 	}
 
-	tfp_memcpy(&data[0], parms->key, key_bytes);
-	tfp_memcpy(&data[key_bytes], parms->mask, key_bytes);
-	tfp_memcpy(&data[req.result_offset], parms->result, result_bytes);
+	tfp_memcpy(&data[0], parms->key, parms->key_size);
+	tfp_memcpy(&data[parms->key_size], parms->mask, parms->key_size);
+	tfp_memcpy(&data[req.result_offset], parms->result, parms->result_size);
 
 	mparms.tf_type = HWRM_TF_TCAM_SET;
 	mparms.req_data = (uint32_t *)&req;
@@ -1554,7 +1547,7 @@  tf_msg_tcam_entry_set(struct tf *tfp,
 
 int
 tf_msg_tcam_entry_free(struct tf *tfp,
-		       struct tf_free_tcam_entry_parms *in_parms)
+		       struct tf_tcam_free_parms *in_parms)
 {
 	int rc;
 	struct hwrm_tf_tcam_free_input req =  { 0 };
@@ -1562,7 +1555,7 @@  tf_msg_tcam_entry_free(struct tf *tfp,
 	struct tfp_send_msg_parms parms = { 0 };
 
 	/* Populate the request */
-	rc = tf_tcam_tbl_2_hwrm(in_parms->tcam_tbl_type, &req.type);
+	rc = tf_tcam_tbl_2_hwrm(in_parms->type, &req.type);
 	if (rc != 0)
 		return rc;
 
diff --git a/drivers/net/bnxt/tf_core/tf_msg.h b/drivers/net/bnxt/tf_core/tf_msg.h
index 1dad2b9fb..a3e0f7bba 100644
--- a/drivers/net/bnxt/tf_core/tf_msg.h
+++ b/drivers/net/bnxt/tf_core/tf_msg.h
@@ -247,7 +247,7 @@  int tf_msg_em_op(struct tf *tfp,
  *  0 on Success else internal Truflow error
  */
 int tf_msg_tcam_entry_set(struct tf *tfp,
-			  struct tf_set_tcam_entry_parms *parms);
+			  struct tf_tcam_set_parms *parms);
 
 /**
  * Sends tcam entry 'free' to the Firmware.
@@ -262,7 +262,7 @@  int tf_msg_tcam_entry_set(struct tf *tfp,
  *  0 on Success else internal Truflow error
  */
 int tf_msg_tcam_entry_free(struct tf *tfp,
-			   struct tf_free_tcam_entry_parms *parms);
+			   struct tf_tcam_free_parms *parms);
 
 /**
  * Sends Set message of a Table Type element to the firmware.
diff --git a/drivers/net/bnxt/tf_core/tf_tcam.c b/drivers/net/bnxt/tf_core/tf_tcam.c
index 3ad99dd0d..b9dba5323 100644
--- a/drivers/net/bnxt/tf_core/tf_tcam.c
+++ b/drivers/net/bnxt/tf_core/tf_tcam.c
@@ -3,16 +3,24 @@ 
  * All rights reserved.
  */
 
+#include <string.h>
 #include <rte_common.h>
 
 #include "tf_tcam.h"
+#include "tf_common.h"
+#include "tf_util.h"
+#include "tf_rm_new.h"
+#include "tf_device.h"
+#include "tfp.h"
+#include "tf_session.h"
+#include "tf_msg.h"
 
 struct tf;
 
 /**
  * TCAM DBs.
  */
-/* static void *tcam_db[TF_DIR_MAX]; */
+static void *tcam_db[TF_DIR_MAX];
 
 /**
  * TCAM Shadow DBs
@@ -22,7 +30,7 @@  struct tf;
 /**
  * Init flag, set on bind and cleared on unbind
  */
-/* static uint8_t init; */
+static uint8_t init;
 
 /**
  * Shadow init flag, set on bind and cleared on unbind
@@ -33,19 +41,131 @@  int
 tf_tcam_bind(struct tf *tfp __rte_unused,
 	     struct tf_tcam_cfg_parms *parms __rte_unused)
 {
+	int rc;
+	int i;
+	struct tf_rm_create_db_parms db_cfg = { 0 };
+
+	TF_CHECK_PARMS2(tfp, parms);
+
+	if (init) {
+		TFP_DRV_LOG(ERR,
+			    "TCAM already initialized\n");
+		return -EINVAL;
+	}
+
+	db_cfg.num_elements = parms->num_elements;
+
+	for (i = 0; i < TF_DIR_MAX; i++) {
+		db_cfg.dir = i;
+		db_cfg.num_elements = parms->num_elements;
+		db_cfg.cfg = parms->cfg;
+		db_cfg.alloc_num = parms->resources->tcam_tbl_cnt[i];
+		db_cfg.rm_db = tcam_db[i];
+		rc = tf_rm_create_db(tfp, &db_cfg);
+		if (rc) {
+			TFP_DRV_LOG(ERR,
+				    "%s: TCAM DB creation failed\n",
+				    tf_dir_2_str(i));
+			return rc;
+		}
+	}
+
+	init = 1;
+
 	return 0;
 }
 
 int
 tf_tcam_unbind(struct tf *tfp __rte_unused)
 {
+	int rc;
+	int i;
+	struct tf_rm_free_db_parms fparms = { 0 };
+
+	TF_CHECK_PARMS1(tfp);
+
+	/* Bail if nothing has been initialized done silent as to
+	 * allow for creation cleanup.
+	 */
+	if (!init)
+		return -EINVAL;
+
+	for (i = 0; i < TF_DIR_MAX; i++) {
+		fparms.dir = i;
+		fparms.rm_db = tcam_db[i];
+		rc = tf_rm_free_db(tfp, &fparms);
+		if (rc)
+			return rc;
+
+		tcam_db[i] = NULL;
+	}
+
+	init = 0;
+
 	return 0;
 }
 
 int
-tf_tcam_alloc(struct tf *tfp __rte_unused,
-	      struct tf_tcam_alloc_parms *parms __rte_unused)
+tf_tcam_alloc(struct tf *tfp,
+	      struct tf_tcam_alloc_parms *parms)
 {
+	int rc;
+	struct tf_session *tfs;
+	struct tf_dev_info *dev;
+	struct tf_rm_allocate_parms aparms = { 0 };
+	uint16_t num_slice_per_row = 1;
+
+	TF_CHECK_PARMS2(tfp, parms);
+
+	if (!init) {
+		TFP_DRV_LOG(ERR,
+			    "%s: No TCAM DBs created\n",
+			    tf_dir_2_str(parms->dir));
+		return -EINVAL;
+	}
+
+	/* Retrieve the session information */
+	rc = tf_session_get_session(tfp, &tfs);
+	if (rc)
+		return rc;
+
+	/* Retrieve the device information */
+	rc = tf_session_get_device(tfs, &dev);
+	if (rc)
+		return rc;
+
+	if (dev->ops->tf_dev_get_tcam_slice_info == NULL) {
+		rc = -EOPNOTSUPP;
+		TFP_DRV_LOG(ERR,
+			    "%s: Operation not supported, rc:%s\n",
+			    tf_dir_2_str(parms->dir),
+			    strerror(-rc));
+		return rc;
+	}
+
+	/* Need to retrieve row size etc */
+	rc = dev->ops->tf_dev_get_tcam_slice_info(tfp,
+						  parms->type,
+						  parms->key_size,
+						  &num_slice_per_row);
+	if (rc)
+		return rc;
+
+	/* Allocate requested element */
+	aparms.rm_db = tcam_db[parms->dir];
+	aparms.db_index = parms->type;
+	aparms.index = (uint32_t *)&parms->idx;
+	rc = tf_rm_allocate(&aparms);
+	if (rc) {
+		TFP_DRV_LOG(ERR,
+			    "%s: Failed tcam, type:%d\n",
+			    tf_dir_2_str(parms->dir),
+			    parms->type);
+		return rc;
+	}
+
+	parms->idx *= num_slice_per_row;
+
 	return 0;
 }
 
@@ -53,6 +173,92 @@  int
 tf_tcam_free(struct tf *tfp __rte_unused,
 	     struct tf_tcam_free_parms *parms __rte_unused)
 {
+	int rc;
+	struct tf_session *tfs;
+	struct tf_dev_info *dev;
+	struct tf_rm_is_allocated_parms aparms = { 0 };
+	struct tf_rm_free_parms fparms = { 0 };
+	uint16_t num_slice_per_row = 1;
+	int allocated = 0;
+
+	TF_CHECK_PARMS2(tfp, parms);
+
+	if (!init) {
+		TFP_DRV_LOG(ERR,
+			    "%s: No TCAM DBs created\n",
+			    tf_dir_2_str(parms->dir));
+		return -EINVAL;
+	}
+
+	/* Retrieve the session information */
+	rc = tf_session_get_session(tfp, &tfs);
+	if (rc)
+		return rc;
+
+	/* Retrieve the device information */
+	rc = tf_session_get_device(tfs, &dev);
+	if (rc)
+		return rc;
+
+	if (dev->ops->tf_dev_get_tcam_slice_info == NULL) {
+		rc = -EOPNOTSUPP;
+		TFP_DRV_LOG(ERR,
+			    "%s: Operation not supported, rc:%s\n",
+			    tf_dir_2_str(parms->dir),
+			    strerror(-rc));
+		return rc;
+	}
+
+	/* Need to retrieve row size etc */
+	rc = dev->ops->tf_dev_get_tcam_slice_info(tfp,
+						  parms->type,
+						  0,
+						  &num_slice_per_row);
+	if (rc)
+		return rc;
+
+	/* Check if element is in use */
+	aparms.rm_db = tcam_db[parms->dir];
+	aparms.db_index = parms->type;
+	aparms.index = parms->idx / num_slice_per_row;
+	aparms.allocated = &allocated;
+	rc = tf_rm_is_allocated(&aparms);
+	if (rc)
+		return rc;
+
+	if (!allocated) {
+		TFP_DRV_LOG(ERR,
+			    "%s: Entry already free, type:%d, index:%d\n",
+			    tf_dir_2_str(parms->dir),
+			    parms->type,
+			    parms->idx);
+		return rc;
+	}
+
+	/* Free requested element */
+	fparms.rm_db = tcam_db[parms->dir];
+	fparms.db_index = parms->type;
+	fparms.index = parms->idx / num_slice_per_row;
+	rc = tf_rm_free(&fparms);
+	if (rc) {
+		TFP_DRV_LOG(ERR,
+			    "%s: Free failed, type:%d, index:%d\n",
+			    tf_dir_2_str(parms->dir),
+			    parms->type,
+			    parms->idx);
+		return rc;
+	}
+
+	rc = tf_msg_tcam_entry_free(tfp, parms);
+	if (rc) {
+		/* Log error */
+		TFP_DRV_LOG(ERR, "%s: %s: Entry %d free failed with err %s",
+			    tf_dir_2_str(parms->dir),
+			    tf_tcam_tbl_2_str(parms->type),
+			    parms->idx,
+			    strerror(-rc));
+	}
+
 	return 0;
 }
 
@@ -67,6 +273,77 @@  int
 tf_tcam_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;
+	struct tf_rm_is_allocated_parms aparms = { 0 };
+	uint16_t num_slice_per_row = 1;
+	int allocated = 0;
+
+	TF_CHECK_PARMS2(tfp, parms);
+
+	if (!init) {
+		TFP_DRV_LOG(ERR,
+			    "%s: No TCAM DBs created\n",
+			    tf_dir_2_str(parms->dir));
+		return -EINVAL;
+	}
+
+	/* Retrieve the session information */
+	rc = tf_session_get_session(tfp, &tfs);
+	if (rc)
+		return rc;
+
+	/* Retrieve the device information */
+	rc = tf_session_get_device(tfs, &dev);
+	if (rc)
+		return rc;
+
+	if (dev->ops->tf_dev_get_tcam_slice_info == NULL) {
+		rc = -EOPNOTSUPP;
+		TFP_DRV_LOG(ERR,
+			    "%s: Operation not supported, rc:%s\n",
+			    tf_dir_2_str(parms->dir),
+			    strerror(-rc));
+		return rc;
+	}
+
+	/* Need to retrieve row size etc */
+	rc = dev->ops->tf_dev_get_tcam_slice_info(tfp,
+						  parms->type,
+						  parms->key_size,
+						  &num_slice_per_row);
+	if (rc)
+		return rc;
+
+	/* Check if element is in use */
+	aparms.rm_db = tcam_db[parms->dir];
+	aparms.db_index = parms->type;
+	aparms.index = parms->idx / num_slice_per_row;
+	aparms.allocated = &allocated;
+	rc = tf_rm_is_allocated(&aparms);
+	if (rc)
+		return rc;
+
+	if (!allocated) {
+		TFP_DRV_LOG(ERR,
+			    "%s: Entry is not allocated, type:%d, index:%d\n",
+			    tf_dir_2_str(parms->dir),
+			    parms->type,
+			    parms->idx);
+		return rc;
+	}
+
+	rc = tf_msg_tcam_entry_set(tfp, parms);
+	if (rc) {
+		/* Log error */
+		TFP_DRV_LOG(ERR, "%s: %s: Entry %d free failed with err %s",
+			    tf_dir_2_str(parms->dir),
+			    tf_tcam_tbl_2_str(parms->type),
+			    parms->idx,
+			    strerror(-rc));
+	}
+
 	return 0;
 }
 
diff --git a/drivers/net/bnxt/tf_core/tf_tcam.h b/drivers/net/bnxt/tf_core/tf_tcam.h
index 68c25eb1b..67c3bcb49 100644
--- a/drivers/net/bnxt/tf_core/tf_tcam.h
+++ b/drivers/net/bnxt/tf_core/tf_tcam.h
@@ -50,10 +50,18 @@  struct tf_tcam_alloc_parms {
 	 * [in] Type of the allocation
 	 */
 	enum tf_tcam_tbl_type type;
+	/**
+	 * [in] key size
+	 */
+	uint16_t key_size;
+	/**
+	 * [in] Priority of entry requested (definition TBD)
+	 */
+	uint32_t priority;
 	/**
 	 * [out] Idx of allocated entry or found entry (if search_enable)
 	 */
-	uint32_t idx;
+	uint16_t idx;
 };
 
 /**
@@ -71,7 +79,7 @@  struct tf_tcam_free_parms {
 	/**
 	 * [in] Index to free
 	 */
-	uint32_t idx;
+	uint16_t idx;
 	/**
 	 * [out] Reference count after free, only valid if session has been
 	 * created with shadow_copy.
@@ -90,7 +98,7 @@  struct tf_tcam_alloc_search_parms {
 	/**
 	 * [in] TCAM table type
 	 */
-	enum tf_tcam_tbl_type tcam_tbl_type;
+	enum tf_tcam_tbl_type type;
 	/**
 	 * [in] Enable search for matching entry
 	 */
@@ -100,9 +108,9 @@  struct tf_tcam_alloc_search_parms {
 	 */
 	uint8_t *key;
 	/**
-	 * [in] key size in bits (if search)
+	 * [in] key size (if search)
 	 */
-	uint16_t key_sz_in_bits;
+	uint16_t key_size;
 	/**
 	 * [in] Mask data to match on (if search)
 	 */
@@ -139,17 +147,29 @@  struct tf_tcam_set_parms {
 	 */
 	enum tf_tcam_tbl_type type;
 	/**
-	 * [in] Entry data
+	 * [in] Entry index to write to
 	 */
-	uint8_t *data;
+	uint32_t idx;
 	/**
-	 * [in] Entry size
+	 * [in] array containing key
 	 */
-	uint16_t data_sz_in_bytes;
+	uint8_t *key;
 	/**
-	 * [in] Entry index to write to
+	 * [in] array containing mask fields
 	 */
-	uint32_t idx;
+	uint8_t *mask;
+	/**
+	 * [in] key size
+	 */
+	uint16_t key_size;
+	/**
+	 * [in] array containing result
+	 */
+	uint8_t *result;
+	/**
+	 * [in] result size
+	 */
+	uint16_t result_size;
 };
 
 /**
@@ -165,17 +185,29 @@  struct tf_tcam_get_parms {
 	 */
 	enum tf_tcam_tbl_type type;
 	/**
-	 * [out] Entry data
+	 * [in] Entry index to read
 	 */
-	uint8_t *data;
+	uint32_t idx;
 	/**
-	 * [out] Entry size
+	 * [out] array containing key
 	 */
-	uint16_t data_sz_in_bytes;
+	uint8_t *key;
 	/**
-	 * [in] Entry index to read
+	 * [out] array containing mask fields
 	 */
-	uint32_t idx;
+	uint8_t *mask;
+	/**
+	 * [out] key size
+	 */
+	uint16_t key_size;
+	/**
+	 * [out] array containing result
+	 */
+	uint8_t *result;
+	/**
+	 * [out] result size
+	 */
+	uint16_t result_size;
 };
 
 /**