net/mlx5: support keeping CRC on Windows
[dpdk.git] / drivers / net / bnxt / tf_ulp / ulp_gen_tbl.c
index 0a15789..7b6db7a 100644 (file)
@@ -5,9 +5,16 @@
 
 #include <rte_log.h>
 #include <rte_malloc.h>
+#include "tf_core.h"
+#include "tfp.h"
 #include "ulp_mapper.h"
 #include "ulp_flow_db.h"
 
+#ifdef RTE_LIBRTE_BNXT_TRUFLOW_DEBUG
+#include "ulp_template_debug_proto.h"
+#include "ulp_tf_debug.h"
+#endif
+
 /* Retrieve the generic table  initialization parameters for the tbl_idx */
 static struct bnxt_ulp_generic_tbl_params*
 ulp_mapper_gen_tbl_params_get(uint32_t tbl_idx)
@@ -31,6 +38,7 @@ ulp_mapper_generic_tbl_list_init(struct bnxt_ulp_mapper_data *mapper_data)
 {
        struct bnxt_ulp_generic_tbl_params *tbl;
        struct ulp_mapper_gen_tbl_list *entry;
+       struct ulp_hash_create_params cparams;
        uint32_t idx, size;
 
        /* Allocate the generic tables. */
@@ -43,27 +51,46 @@ ulp_mapper_generic_tbl_list_init(struct bnxt_ulp_mapper_data *mapper_data)
                }
                entry = &mapper_data->gen_tbl_list[idx];
                if (tbl->result_num_entries != 0) {
+                       /* assign the name */
+                       entry->gen_tbl_name = tbl->name;
                        /* add 4 bytes for reference count */
                        entry->mem_data_size = (tbl->result_num_entries + 1) *
-                               (tbl->result_byte_size + sizeof(uint32_t));
+                               (tbl->result_num_bytes + sizeof(uint32_t));
 
                        /* allocate the big chunk of memory */
                        entry->mem_data = rte_zmalloc("ulp mapper gen tbl",
                                                      entry->mem_data_size, 0);
                        if (!entry->mem_data) {
                                BNXT_TF_DBG(ERR,
-                                           "Failed to allocate gen table %d\n",
-                                           idx);
+                                           "%s:Failed to alloc gen table %d\n",
+                                           tbl->name, idx);
                                return -ENOMEM;
                        }
                        /* Populate the generic table container */
                        entry->container.num_elem = tbl->result_num_entries;
-                       entry->container.byte_data_size = tbl->result_byte_size;
+                       entry->container.byte_data_size = tbl->result_num_bytes;
                        entry->container.ref_count =
                                (uint32_t *)entry->mem_data;
                        size = sizeof(uint32_t) * (tbl->result_num_entries + 1);
                        entry->container.byte_data = &entry->mem_data[size];
                        entry->container.byte_order = tbl->result_byte_order;
+               } else {
+                       BNXT_TF_DBG(DEBUG, "%s: Unused Gen tbl entry is %d\n",
+                                   tbl->name, idx);
+                       /* return -EINVAL; */
+               }
+               if (tbl->hash_tbl_entries) {
+                       cparams.key_size = tbl->key_num_bytes;
+                       cparams.num_buckets = tbl->num_buckets;
+                       cparams.num_hash_tbl_entries = tbl->hash_tbl_entries;
+                       cparams.num_key_entries = tbl->result_num_entries;
+                       if (ulp_gen_hash_tbl_list_init(&cparams,
+                                                      &entry->hash_tbl)) {
+                               BNXT_TF_DBG(ERR,
+                                           "%s: Failed to alloc hash tbl %d\n",
+                                           tbl->name, idx);
+                               return -ENOMEM;
+                       }
                }
        }
        /* success */
@@ -91,6 +118,10 @@ ulp_mapper_generic_tbl_list_deinit(struct bnxt_ulp_mapper_data *mapper_data)
                        rte_free(tbl_list->mem_data);
                        tbl_list->mem_data = NULL;
                }
+               if (tbl_list->hash_tbl) {
+                       ulp_gen_hash_tbl_list_deinit(tbl_list->hash_tbl);
+                       tbl_list->hash_tbl = NULL;
+               }
        }
        /* success */
        return 0;
@@ -99,32 +130,21 @@ ulp_mapper_generic_tbl_list_deinit(struct bnxt_ulp_mapper_data *mapper_data)
 /*
  * Get the generic table list entry
  *
- * ulp_ctxt [in] - Ptr to ulp_context
- * tbl_idx [in] -  Table index to the generic table list
+ * tbl_list [in] - Ptr to generic table
  * key [in] - Key index to the table
  * entry [out] - output will include the entry if found
  *
  * returns 0 on success.
  */
 int32_t
-ulp_mapper_gen_tbl_entry_get(struct bnxt_ulp_context *ulp,
-                            uint32_t tbl_idx,
+ulp_mapper_gen_tbl_entry_get(struct ulp_mapper_gen_tbl_list *tbl_list,
                             uint32_t key,
                             struct ulp_mapper_gen_tbl_entry *entry)
 {
-       struct bnxt_ulp_mapper_data *mapper_data;
-       struct ulp_mapper_gen_tbl_list *tbl_list;
-
-       mapper_data = bnxt_ulp_cntxt_ptr2_mapper_data_get(ulp);
-       if (!mapper_data || tbl_idx >= BNXT_ULP_GEN_TBL_MAX_SZ ||
-           !entry) {
-               BNXT_TF_DBG(ERR, "invalid arguments %x:%x\n", tbl_idx, key);
-               return -EINVAL;
-       }
        /* populate the output and return the values */
-       tbl_list = &mapper_data->gen_tbl_list[tbl_idx];
        if (key > tbl_list->container.num_elem) {
-               BNXT_TF_DBG(ERR, "invalid key %x:%x\n", key,
+               BNXT_TF_DBG(ERR, "%s: invalid key %x:%x\n",
+                           tbl_list->gen_tbl_name, key,
                            tbl_list->container.num_elem);
                return -EINVAL;
        }
@@ -163,18 +183,19 @@ ulp_mapper_gen_tbl_idx_calculate(uint32_t res_sub_type, uint32_t dir)
 }
 
 /*
- * Set the data in the generic table entry
+ * Set the data in the generic table entry, Data is in Big endian format
  *
  * entry [in] - generic table entry
- * offset [in] - The offset in bits where the data has to be set
  * len [in] - The length of the data in bits to be set
  * data [in] - pointer to the data to be used for setting the value.
+ * data_size [in] - length of the data pointer in bytes.
  *
  * returns 0 on success
  */
 int32_t
 ulp_mapper_gen_tbl_entry_data_set(struct ulp_mapper_gen_tbl_entry *entry,
-                                 uint32_t offset, uint32_t len, uint8_t *data)
+                                 uint32_t len, uint8_t *data,
+                                 uint32_t data_size)
 {
        /* validate the null arguments */
        if (!entry || !data) {
@@ -183,32 +204,18 @@ ulp_mapper_gen_tbl_entry_data_set(struct ulp_mapper_gen_tbl_entry *entry,
        }
 
        /* check the size of the buffer for validation */
-       if ((offset + len) > ULP_BYTE_2_BITS(entry->byte_data_size)) {
-               BNXT_TF_DBG(ERR, "invalid offset or length %x:%x:%x\n",
-                           offset, len, entry->byte_data_size);
+       if (len > ULP_BYTE_2_BITS(entry->byte_data_size) ||
+           data_size < ULP_BITS_2_BYTE(len)) {
+               BNXT_TF_DBG(ERR, "invalid offset or length %x:%x\n",
+                           len, entry->byte_data_size);
                return -EINVAL;
        }
-
-       if (entry->byte_order == BNXT_ULP_BYTE_ORDER_LE) {
-               if (ulp_bs_push_lsb(entry->byte_data, offset, len, data) !=
-                   len) {
-                       BNXT_TF_DBG(ERR, "write failed offset = %x, len =%x\n",
-                                   offset, len);
-                       return -EIO;
-               }
-       } else {
-               if (ulp_bs_push_msb(entry->byte_data, offset, len, data) !=
-                   len) {
-                       BNXT_TF_DBG(ERR, "write failed offset = %x, len =%x\n",
-                                   offset, len);
-                       return -EIO;
-               }
-       }
+       memcpy(entry->byte_data, data, ULP_BITS_2_BYTE(len));
        return 0;
 }
 
 /*
- * Get the data in the generic table entry
+ * Get the data in the generic table entry, Data is in Big endian format
  *
  * entry [in] - generic table entry
  * offset [in] - The offset in bits where the data has to get
@@ -244,8 +251,28 @@ ulp_mapper_gen_tbl_entry_data_get(struct ulp_mapper_gen_tbl_entry *entry,
        return 0;
 }
 
-/*
- * Free the generic table list entry
+/* Free the generic table list entry
+ *
+ * ulp_ctx [in] - Pointer to the ulp context
+ * tbl_idx [in] - Index of the generic table
+ * ckey [in] - Key for the entry in the table
+ *
+ * returns 0 on success
+ */
+int32_t
+ulp_mapper_gen_tbl_entry_free(struct bnxt_ulp_context *ulp_ctx,
+                             uint32_t tbl_idx, uint32_t ckey)
+{
+       struct ulp_flow_db_res_params res;
+
+       res.direction = tbl_idx & 0x1;
+       res.resource_sub_type = tbl_idx >> 1;
+       res.resource_hndl = ckey;
+
+       return ulp_mapper_gen_tbl_res_free(ulp_ctx, &res);
+}
+
+/* Free the generic table list resource
  *
  * ulp_ctx [in] - Pointer to the ulp context
  * res [in] - Pointer to flow db resource entry
@@ -256,9 +283,13 @@ int32_t
 ulp_mapper_gen_tbl_res_free(struct bnxt_ulp_context *ulp_ctx,
                            struct ulp_flow_db_res_params *res)
 {
+       struct bnxt_ulp_mapper_data *mapper_data;
+       struct ulp_mapper_gen_tbl_list *gen_tbl_list;
        struct ulp_mapper_gen_tbl_entry entry;
+       struct ulp_gen_hash_entry_params hash_entry;
        int32_t tbl_idx;
-       uint32_t fid;
+       uint32_t fid = 0;
+       uint32_t key_idx;
 
        /* Extract the resource sub type and direction */
        tbl_idx = ulp_mapper_gen_tbl_idx_calculate(res->resource_sub_type,
@@ -269,9 +300,30 @@ ulp_mapper_gen_tbl_res_free(struct bnxt_ulp_context *ulp_ctx,
                return -EINVAL;
        }
 
+       mapper_data = bnxt_ulp_cntxt_ptr2_mapper_data_get(ulp_ctx);
+       if (!mapper_data) {
+               BNXT_TF_DBG(ERR, "invalid ulp context %x\n", tbl_idx);
+               return -EINVAL;
+       }
+       /* get the generic table  */
+       gen_tbl_list = &mapper_data->gen_tbl_list[tbl_idx];
+
        /* Get the generic table entry*/
-       if (ulp_mapper_gen_tbl_entry_get(ulp_ctx, tbl_idx, res->resource_hndl,
-                                        &entry)) {
+       if (gen_tbl_list->hash_tbl) {
+               /* use the hash index to get the value */
+               hash_entry.hash_index = (uint32_t)res->resource_hndl;
+               if (ulp_gen_hash_tbl_list_index_search(gen_tbl_list->hash_tbl,
+                                                      &hash_entry)) {
+                       BNXT_TF_DBG(ERR, "Unable to find has entry %x:%x\n",
+                                   tbl_idx, hash_entry.hash_index);
+                       return -EINVAL;
+               }
+               key_idx = hash_entry.key_idx;
+
+       } else {
+               key_idx =  (uint32_t)res->resource_hndl;
+       }
+       if (ulp_mapper_gen_tbl_entry_get(gen_tbl_list, key_idx, &entry)) {
                BNXT_TF_DBG(ERR, "Gen tbl entry get failed %x:%" PRIX64 "\n",
                            tbl_idx, res->resource_hndl);
                return -EINVAL;
@@ -298,14 +350,73 @@ ulp_mapper_gen_tbl_res_free(struct bnxt_ulp_context *ulp_ctx,
                            tbl_idx, res->resource_hndl);
                return -EINVAL;
        }
+       fid = tfp_be_to_cpu_32(fid);
+       /* no need to del if fid is 0 since there is no associated resource */
+       if (fid) {
+               /* Destroy the flow associated with the shared flow id */
+               if (ulp_mapper_flow_destroy(ulp_ctx, BNXT_ULP_FDB_TYPE_RID,
+                                           fid))
+                       BNXT_TF_DBG(ERR,
+                                   "Error in deleting shared flow id %x\n",
+                                   fid);
+       }
 
-       /* Destroy the flow associated with the shared flow id */
-       if (ulp_mapper_flow_destroy(ulp_ctx, BNXT_ULP_FDB_TYPE_REGULAR,
-                                   fid))
-               BNXT_TF_DBG(ERR, "Error in deleting shared flow id %x\n", fid);
+       /* Delete the entry from the hash table */
+       if (gen_tbl_list->hash_tbl)
+               ulp_gen_hash_tbl_list_del(gen_tbl_list->hash_tbl, &hash_entry);
 
        /* clear the byte data of the generic table entry */
        memset(entry.byte_data, 0, entry.byte_data_size);
 
        return 0;
 }
+
+/*
+ * Write the generic table list hash entry
+ *
+ * tbl_list [in] - pointer to the generic table list
+ * hash_entry [in] -  Hash table entry
+ * gen_tbl_ent [out] - generic table entry
+ *
+ * returns 0 on success.
+ */
+int32_t
+ulp_mapper_gen_tbl_hash_entry_add(struct ulp_mapper_gen_tbl_list *tbl_list,
+                                 struct ulp_gen_hash_entry_params *hash_entry,
+                                 struct ulp_mapper_gen_tbl_entry *gen_tbl_ent)
+{
+       uint32_t key;
+       int32_t rc = 0;
+
+       switch (hash_entry->search_flag) {
+       case ULP_GEN_HASH_SEARCH_FOUND:
+               BNXT_TF_DBG(ERR, "%s: gen hash entry already present\n",
+                           tbl_list->gen_tbl_name);
+               return -EINVAL;
+       case ULP_GEN_HASH_SEARCH_FULL:
+               BNXT_TF_DBG(ERR, "%s: gen hash table is full\n",
+                           tbl_list->gen_tbl_name);
+               return -EINVAL;
+       case ULP_GEN_HASH_SEARCH_MISSED:
+               rc = ulp_gen_hash_tbl_list_add(tbl_list->hash_tbl, hash_entry);
+               if (rc) {
+                       BNXT_TF_DBG(ERR, "%s: gen hash table add failed\n",
+                                   tbl_list->gen_tbl_name);
+                       return -EINVAL;
+               }
+               key = hash_entry->key_idx;
+               gen_tbl_ent->ref_count = &tbl_list->container.ref_count[key];
+               gen_tbl_ent->byte_data_size =
+                       tbl_list->container.byte_data_size;
+               gen_tbl_ent->byte_data = &tbl_list->container.byte_data[key *
+                       gen_tbl_ent->byte_data_size];
+               gen_tbl_ent->byte_order = tbl_list->container.byte_order;
+               break;
+       default:
+               BNXT_TF_DBG(ERR, "%s: invalid search flag\n",
+                           tbl_list->gen_tbl_name);
+               return -EINVAL;
+       }
+
+       return rc;
+}