net/bnxt: refactor flow id allocation
[dpdk.git] / drivers / net / bnxt / tf_ulp / ulp_mapper.c
index cd289cc..d5c129b 100644 (file)
@@ -14,8 +14,8 @@
 #include "tfp.h"
 #include "tf_ext_flow_handle.h"
 #include "ulp_mark_mgr.h"
-#include "ulp_flow_db.h"
 #include "ulp_mapper.h"
+#include "ulp_flow_db.h"
 #include "tf_util.h"
 
 static struct bnxt_ulp_glb_resource_info *
@@ -537,6 +537,65 @@ ulp_mapper_mark_free(struct bnxt_ulp_context *ulp,
                                    res->resource_hndl);
 }
 
+
+static inline int32_t
+ulp_mapper_parent_flow_free(struct bnxt_ulp_context *ulp,
+                           uint32_t parent_fid,
+                           struct ulp_flow_db_res_params *res)
+{
+       uint32_t idx, child_fid = 0, parent_idx;
+       struct bnxt_ulp_flow_db *flow_db;
+
+       parent_idx = (uint32_t)res->resource_hndl;
+
+       /* check the validity of the parent fid */
+       if (ulp_flow_db_parent_flow_idx_get(ulp, parent_fid, &idx) ||
+           idx != parent_idx) {
+               BNXT_TF_DBG(ERR, "invalid parent flow id %x\n", parent_fid);
+               return -EINVAL;
+       }
+
+       /* Clear all the child flows parent index */
+       flow_db = bnxt_ulp_cntxt_ptr2_flow_db_get(ulp);
+       while (!ulp_flow_db_parent_child_flow_next_entry_get(flow_db, idx,
+                                                            &child_fid)) {
+               /* update the child flows resource handle */
+               if (ulp_flow_db_child_flow_reset(ulp, BNXT_ULP_FDB_TYPE_REGULAR,
+                                                child_fid)) {
+                       BNXT_TF_DBG(ERR, "failed to reset child flow %x\n",
+                                   child_fid);
+                       return -EINVAL;
+               }
+       }
+
+       /* free the parent entry in the parent table flow */
+       if (ulp_flow_db_parent_flow_free(ulp, parent_fid)) {
+               BNXT_TF_DBG(ERR, "failed to free parent flow %x\n", parent_fid);
+               return -EINVAL;
+       }
+       return 0;
+}
+
+static inline int32_t
+ulp_mapper_child_flow_free(struct bnxt_ulp_context *ulp,
+                          uint32_t child_fid,
+                          struct ulp_flow_db_res_params *res)
+{
+       uint32_t parent_fid;
+
+       parent_fid = (uint32_t)res->resource_hndl;
+       if (!parent_fid)
+               return 0; /* Already freed - orphan child*/
+
+       /* reset the child flow bitset*/
+       if (ulp_flow_db_parent_child_flow_set(ulp, parent_fid, child_fid, 0)) {
+               BNXT_TF_DBG(ERR, "error in resetting child flow bitset %x:%x\n",
+                           parent_fid, child_fid);
+               return -EINVAL;
+       }
+       return 0;
+}
+
 /*
  * Process the identifier instruction and either store it in the flow database
  * or return it in the val (if not NULL) on success.  If val is NULL, the
@@ -1438,6 +1497,29 @@ ulp_mapper_tcam_tbl_entry_write(struct bnxt_ulp_mapper_parms *parms,
        return rc;
 }
 
+#define BNXT_ULP_WC_TCAM_SLICE_SIZE 80
+/* internal function to post process the key/mask blobs for wildcard tcam tbl */
+static void ulp_mapper_wc_tcam_tbl_post_process(struct ulp_blob *blob,
+                                               uint32_t len)
+{
+       uint8_t mode[2] = {0x0, 0x0};
+       uint32_t mode_len = len / BNXT_ULP_WC_TCAM_SLICE_SIZE;
+       uint32_t size, idx;
+
+       /* Add the mode bits to the key and mask*/
+       if (mode_len == 2)
+               mode[1] = 2;
+       else if (mode_len > 2)
+               mode[1] = 3;
+
+       size = BNXT_ULP_WC_TCAM_SLICE_SIZE + ULP_BYTE_2_BITS(sizeof(mode));
+       for (idx = 0; idx < mode_len; idx++)
+               ulp_blob_insert(blob, (size * idx), mode,
+                               ULP_BYTE_2_BITS(sizeof(mode)));
+       ulp_blob_perform_64B_word_swap(blob);
+       ulp_blob_perform_64B_byte_swap(blob);
+}
+
 static int32_t
 ulp_mapper_tcam_tbl_process(struct bnxt_ulp_mapper_parms *parms,
                            struct bnxt_ulp_mapper_tbl_info *tbl)
@@ -1474,9 +1556,9 @@ ulp_mapper_tcam_tbl_process(struct bnxt_ulp_mapper_parms *parms,
                return -EINVAL;
        }
 
-       if (!ulp_blob_init(&key, tbl->key_bit_size,
+       if (!ulp_blob_init(&key, tbl->blob_key_bit_size,
                           parms->device_params->byte_order) ||
-           !ulp_blob_init(&mask, tbl->key_bit_size,
+           !ulp_blob_init(&mask, tbl->blob_key_bit_size,
                           parms->device_params->byte_order) ||
            !ulp_blob_init(&data, tbl->result_bit_size,
                           parms->device_params->byte_order) ||
@@ -1486,6 +1568,11 @@ ulp_mapper_tcam_tbl_process(struct bnxt_ulp_mapper_parms *parms,
                return -EINVAL;
        }
 
+       if (tbl->resource_type == TF_TCAM_TBL_TYPE_WC_TCAM) {
+               key.byte_order = BNXT_ULP_BYTE_ORDER_BE;
+               mask.byte_order = BNXT_ULP_BYTE_ORDER_BE;
+       }
+
        /* create the key/mask */
        /*
         * NOTE: The WC table will require some kind of flag to handle the
@@ -1511,6 +1598,11 @@ ulp_mapper_tcam_tbl_process(struct bnxt_ulp_mapper_parms *parms,
                }
        }
 
+       if (tbl->resource_type == TF_TCAM_TBL_TYPE_WC_TCAM) {
+               ulp_mapper_wc_tcam_tbl_post_process(&key, tbl->key_bit_size);
+               ulp_mapper_wc_tcam_tbl_post_process(&mask, tbl->key_bit_size);
+       }
+
        if (tbl->srch_b4_alloc == BNXT_ULP_SEARCH_BEFORE_ALLOC_NO) {
                /*
                 * No search for re-use is requested, so simply allocate the
@@ -1519,18 +1611,18 @@ ulp_mapper_tcam_tbl_process(struct bnxt_ulp_mapper_parms *parms,
                aparms.dir              = tbl->direction;
                aparms.tcam_tbl_type    = tbl->resource_type;
                aparms.search_enable    = tbl->srch_b4_alloc;
-               aparms.key_sz_in_bits   = tbl->key_bit_size;
                aparms.key              = ulp_blob_data_get(&key, &tmplen);
-               if (tbl->key_bit_size != tmplen) {
+               aparms.key_sz_in_bits   = tmplen;
+               if (tbl->blob_key_bit_size != tmplen) {
                        BNXT_TF_DBG(ERR, "Key len (%d) != Expected (%d)\n",
-                                   tmplen, tbl->key_bit_size);
+                                   tmplen, tbl->blob_key_bit_size);
                        return -EINVAL;
                }
 
                aparms.mask             = ulp_blob_data_get(&mask, &tmplen);
-               if (tbl->key_bit_size != tmplen) {
+               if (tbl->blob_key_bit_size != tmplen) {
                        BNXT_TF_DBG(ERR, "Mask len (%d) != Expected (%d)\n",
-                                   tmplen, tbl->key_bit_size);
+                                   tmplen, tbl->blob_key_bit_size);
                        return -EINVAL;
                }
 
@@ -2484,6 +2576,7 @@ error:
 
 static int32_t
 ulp_mapper_resource_free(struct bnxt_ulp_context *ulp,
+                        uint32_t fid,
                         struct ulp_flow_db_res_params *res)
 {
        struct tf *tfp;
@@ -2520,6 +2613,12 @@ ulp_mapper_resource_free(struct bnxt_ulp_context *ulp,
        case BNXT_ULP_RESOURCE_FUNC_HW_FID:
                rc = ulp_mapper_mark_free(ulp, res);
                break;
+       case BNXT_ULP_RESOURCE_FUNC_PARENT_FLOW:
+               rc = ulp_mapper_parent_flow_free(ulp, fid, res);
+               break;
+       case BNXT_ULP_RESOURCE_FUNC_CHILD_FLOW:
+               rc = ulp_mapper_child_flow_free(ulp, fid, res);
+               break;
        default:
                break;
        }
@@ -2558,7 +2657,7 @@ ulp_mapper_resources_free(struct bnxt_ulp_context *ulp_ctx,
        }
 
        while (!rc) {
-               trc = ulp_mapper_resource_free(ulp_ctx, &res_parms);
+               trc = ulp_mapper_resource_free(ulp_ctx, fid, &res_parms);
                if (trc)
                        /*
                         * On fail, we still need to attempt to free the
@@ -2608,7 +2707,7 @@ ulp_mapper_glb_resource_info_deinit(struct bnxt_ulp_context *ulp_ctx,
                        /*convert it from BE to cpu */
                        res.resource_hndl =
                                tfp_be_to_cpu_64(ent->resource_hndl);
-                       ulp_mapper_resource_free(ulp_ctx, &res);
+                       ulp_mapper_resource_free(ulp_ctx, 0, &res);
                }
        }
 }
@@ -2624,15 +2723,9 @@ ulp_mapper_flow_destroy(struct bnxt_ulp_context *ulp_ctx,
                BNXT_TF_DBG(ERR, "Invalid parms, unable to free flow\n");
                return -EINVAL;
        }
-       if (bnxt_ulp_cntxt_acquire_fdb_lock(ulp_ctx)) {
-               BNXT_TF_DBG(ERR, "Flow db lock acquire failed\n");
-               return -EINVAL;
-       }
 
        rc = ulp_mapper_resources_free(ulp_ctx, flow_type, fid);
-       bnxt_ulp_cntxt_release_fdb_lock(ulp_ctx);
        return rc;
-
 }
 
 /* Function to handle the default global templates that are allocated during
@@ -2696,8 +2789,7 @@ ulp_mapper_glb_template_table_init(struct bnxt_ulp_context *ulp_ctx)
  */
 int32_t
 ulp_mapper_flow_create(struct bnxt_ulp_context *ulp_ctx,
-                      struct bnxt_ulp_mapper_create_parms *cparms,
-                      uint32_t *flowid)
+                      struct bnxt_ulp_mapper_create_parms *cparms)
 {
        struct bnxt_ulp_mapper_parms parms;
        struct ulp_regfile regfile;
@@ -2720,6 +2812,9 @@ ulp_mapper_flow_create(struct bnxt_ulp_context *ulp_ctx,
        parms.act_tid = cparms->act_tid;
        parms.class_tid = cparms->class_tid;
        parms.flow_type = cparms->flow_type;
+       parms.parent_flow = cparms->parent_flow;
+       parms.parent_fid = cparms->parent_fid;
+       parms.fid = cparms->flow_id;
 
        /* Get the device id from the ulp context */
        if (bnxt_ulp_cntxt_dev_id_get(ulp_ctx, &parms.dev_id)) {
@@ -2760,26 +2855,7 @@ ulp_mapper_flow_create(struct bnxt_ulp_context *ulp_ctx,
                return -EINVAL;
        }
 
-       /* Protect flow creation */
-       if (bnxt_ulp_cntxt_acquire_fdb_lock(ulp_ctx)) {
-               BNXT_TF_DBG(ERR, "Flow db lock acquire failed\n");
-               return -EINVAL;
-       }
-
-       /* Allocate a Flow ID for attaching all resources for the flow to.
-        * Once allocated, all errors have to walk the list of resources and
-        * free each of them.
-        */
-       rc = ulp_flow_db_fid_alloc(ulp_ctx,
-                                  parms.flow_type,
-                                  cparms->func_id,
-                                  &parms.fid);
-       if (rc) {
-               BNXT_TF_DBG(ERR, "Unable to allocate flow table entry\n");
-               bnxt_ulp_cntxt_release_fdb_lock(ulp_ctx);
-               return rc;
-       }
-
+       /* Process the action template list from the selected action table*/
        if (parms.act_tid) {
                parms.tmpl_type = BNXT_ULP_TEMPLATE_TYPE_ACTION;
                /* Process the action template tables */
@@ -2797,13 +2873,22 @@ ulp_mapper_flow_create(struct bnxt_ulp_context *ulp_ctx,
                        goto flow_error;
        }
 
-       *flowid = parms.fid;
-       bnxt_ulp_cntxt_release_fdb_lock(ulp_ctx);
+       /* setup the parent-child details */
+       if (parms.parent_flow) {
+               /* create a parent flow details */
+               rc = ulp_flow_db_parent_flow_create(&parms);
+               if (rc)
+                       goto flow_error;
+       } else if (parms.parent_fid) {
+               /* create a child flow details */
+               rc = ulp_flow_db_child_flow_create(&parms);
+               if (rc)
+                       goto flow_error;
+       }
 
        return rc;
 
 flow_error:
-       bnxt_ulp_cntxt_release_fdb_lock(ulp_ctx);
        /* Free all resources that were allocated during flow creation */
        trc = ulp_mapper_flow_destroy(ulp_ctx, BNXT_ULP_FDB_TYPE_REGULAR,
                                      parms.fid);