net/bnxt: support TCAM access
authorJay Ding <jay.ding@broadcom.com>
Thu, 2 Jul 2020 23:28:04 +0000 (16:28 -0700)
committerFerruh Yigit <ferruh.yigit@intel.com>
Tue, 7 Jul 2020 21:38:27 +0000 (23:38 +0200)
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
drivers/net/bnxt/tf_core/tf_device.h
drivers/net/bnxt/tf_core/tf_device_p4.c
drivers/net/bnxt/tf_core/tf_msg.c
drivers/net/bnxt/tf_core/tf_msg.h
drivers/net/bnxt/tf_core/tf_tcam.c
drivers/net/bnxt/tf_core/tf_tcam.h

index 648d0d1..29522c6 100644 (file)
 #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;
 }
index 01726c3..bbdfb15 100644 (file)
@@ -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.
index f4bd95f..77fb693 100644 (file)
@@ -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,
index 60274eb..b50e1d4 100644 (file)
@@ -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 @@ cleanup:
 
 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;
 
index 1dad2b9..a3e0f7b 100644 (file)
@@ -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.
index 3ad99dd..b9dba53 100644 (file)
@@ -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;
 }
 
index 68c25eb..67c3bcb 100644 (file)
@@ -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;
 };
 
 /**