net/bnxt: add parent child flow create and free
authorKishore Padmanabha <kishore.padmanabha@broadcom.com>
Fri, 9 Oct 2020 11:11:29 +0000 (16:41 +0530)
committerFerruh Yigit <ferruh.yigit@intel.com>
Fri, 16 Oct 2020 17:47:58 +0000 (19:47 +0200)
Added support in the ULP mapper to enable parent child flow
creation and destroy. This feature enables support for the vxlan
decap functionality.

Signed-off-by: Kishore Padmanabha <kishore.padmanabha@broadcom.com>
Reviewed-by: Mike Baucom <michael.baucom@broadcom.com>
Reviewed-by: Ajit Khaparde <ajit.khaparde@broadcom.com>
drivers/net/bnxt/tf_ulp/ulp_flow_db.c
drivers/net/bnxt/tf_ulp/ulp_flow_db.h
drivers/net/bnxt/tf_ulp/ulp_mapper.c
drivers/net/bnxt/tf_ulp/ulp_mapper.h
drivers/net/bnxt/tf_ulp/ulp_template_db_enum.h

index a1c3932..3be7489 100644 (file)
@@ -6,10 +6,10 @@
 #include <rte_malloc.h>
 #include "bnxt.h"
 #include "bnxt_tf_common.h"
-#include "ulp_flow_db.h"
 #include "ulp_utils.h"
 #include "ulp_template_struct.h"
 #include "ulp_mapper.h"
+#include "ulp_flow_db.h"
 #include "ulp_fc_mgr.h"
 
 #define ULP_FLOW_DB_RES_DIR_BIT                31
@@ -56,10 +56,10 @@ ulp_flow_db_active_flows_bit_set(struct bnxt_ulp_flow_db *flow_db,
        } else {
                if (flow_type == BNXT_ULP_FDB_TYPE_REGULAR)
                        ULP_INDEX_BITMAP_RESET(f_tbl->active_reg_flows[a_idx],
-                                            idx);
+                                              idx);
                else
                        ULP_INDEX_BITMAP_RESET(f_tbl->active_dflt_flows[a_idx],
-                                            idx);
+                                              idx);
        }
 }
 
@@ -89,6 +89,13 @@ ulp_flow_db_active_flows_bit_is_set(struct bnxt_ulp_flow_db *flow_db,
                                            idx);
 }
 
+static inline enum tf_dir
+ulp_flow_db_resource_dir_get(struct ulp_fdb_resource_info *res_info)
+{
+       return ((res_info->nxt_resource_idx & ULP_FLOW_DB_RES_DIR_MASK) >>
+               ULP_FLOW_DB_RES_DIR_BIT);
+}
+
 static uint8_t
 ulp_flow_db_resource_func_get(struct ulp_fdb_resource_info *res_info)
 {
@@ -157,11 +164,9 @@ ulp_flow_db_res_info_to_params(struct ulp_fdb_resource_info *resource_info,
                               struct ulp_flow_db_res_params *params)
 {
        memset(params, 0, sizeof(struct ulp_flow_db_res_params));
-       params->direction = ((resource_info->nxt_resource_idx &
-                                ULP_FLOW_DB_RES_DIR_MASK) >>
-                                ULP_FLOW_DB_RES_DIR_BIT);
 
        /* use the helper function to get the resource func */
+       params->direction = ulp_flow_db_resource_dir_get(resource_info);
        params->resource_func = ulp_flow_db_resource_func_get(resource_info);
 
        if (params->resource_func == BNXT_ULP_RESOURCE_FUNC_EXT_EM_TABLE ||
@@ -303,6 +308,9 @@ ulp_flow_db_parent_tbl_init(struct bnxt_ulp_flow_db *flow_db,
        struct ulp_fdb_parent_child_db *p_db;
        uint32_t size, idx;
 
+       if (!num_entries)
+               return 0;
+
        /* update the sizes for the allocation */
        p_db = &flow_db->parent_child_db;
        p_db->child_bitset_size = (flow_db->flow_tbl.num_flows /
@@ -1171,6 +1179,12 @@ ulp_flow_db_parent_flow_alloc(struct bnxt_ulp_context *ulp_ctxt,
                return -EINVAL;
        }
 
+       /* No support for parent child db then just exit */
+       if (!flow_db->parent_child_db.entries_count) {
+               BNXT_TF_DBG(ERR, "parent child db not supported\n");
+               return -EINVAL;
+       }
+
        p_pdb = &flow_db->parent_child_db;
        for (idx = 0; idx <= p_pdb->entries_count; idx++) {
                if (p_pdb->parent_flow_tbl[idx].parent_fid == fid) {
@@ -1220,6 +1234,12 @@ ulp_flow_db_parent_flow_free(struct bnxt_ulp_context *ulp_ctxt,
                return -EINVAL;
        }
 
+       /* No support for parent child db then just exit */
+       if (!flow_db->parent_child_db.entries_count) {
+               BNXT_TF_DBG(ERR, "parent child db not supported\n");
+               return -EINVAL;
+       }
+
        p_pdb = &flow_db->parent_child_db;
        for (idx = 0; idx <= p_pdb->entries_count; idx++) {
                if (p_pdb->parent_flow_tbl[idx].parent_fid == fid) {
@@ -1273,6 +1293,12 @@ ulp_flow_db_parent_child_flow_set(struct bnxt_ulp_context *ulp_ctxt,
                return -EINVAL;
        }
 
+       /* No support for parent child db then just exit */
+       if (!flow_db->parent_child_db.entries_count) {
+               BNXT_TF_DBG(ERR, "parent child db not supported\n");
+               return -EINVAL;
+       }
+
        p_pdb = &flow_db->parent_child_db;
        a_idx = child_fid / ULP_INDEX_BITMAP_SIZE;
        for (idx = 0; idx <= p_pdb->entries_count; idx++) {
@@ -1320,6 +1346,12 @@ ulp_flow_db_parent_flow_idx_get(struct bnxt_ulp_context *ulp_ctxt,
                return -EINVAL;
        }
 
+       /* No support for parent child db then just exit */
+       if (!flow_db->parent_child_db.entries_count) {
+               BNXT_TF_DBG(ERR, "parent child db not supported\n");
+               return -EINVAL;
+       }
+
        p_pdb = &flow_db->parent_child_db;
        for (idx = 0; idx <= p_pdb->entries_count; idx++) {
                if (p_pdb->parent_flow_tbl[idx].parent_fid == parent_fid) {
@@ -1392,3 +1424,136 @@ ulp_flow_db_parent_child_flow_next_entry_get(struct bnxt_ulp_flow_db *flow_db,
        *child_fid = next_fid;
        return 0;
 }
+
+/*
+ * Orphan the child flow entry
+ * This is called only for child flows that have
+ * BNXT_ULP_RESOURCE_FUNC_CHILD_FLOW resource
+ *
+ * ulp_ctxt [in] Ptr to ulp_context
+ * flow_type [in] Specify it is regular or default flow
+ * fid [in] The index to the flow entry
+ *
+ * Returns 0 on success and negative on failure.
+ */
+int32_t
+ulp_flow_db_child_flow_reset(struct bnxt_ulp_context *ulp_ctxt,
+                            enum bnxt_ulp_fdb_type flow_type,
+                            uint32_t fid)
+{
+       struct bnxt_ulp_flow_db *flow_db;
+       struct bnxt_ulp_flow_tbl *flow_tbl;
+       struct ulp_fdb_resource_info *fid_res;
+       uint32_t res_id = 0;
+
+       flow_db = bnxt_ulp_cntxt_ptr2_flow_db_get(ulp_ctxt);
+       if (!flow_db) {
+               BNXT_TF_DBG(ERR, "Invalid Arguments\n");
+               return -EINVAL;
+       }
+
+       if (flow_type > BNXT_ULP_FDB_TYPE_DEFAULT) {
+               BNXT_TF_DBG(ERR, "Invalid flow type\n");
+               return -EINVAL;
+       }
+
+       flow_tbl = &flow_db->flow_tbl;
+       /* check for max flows */
+       if (fid >= flow_tbl->num_flows || !fid) {
+               BNXT_TF_DBG(ERR, "Invalid flow index %x\n", fid);
+               return -EINVAL;
+       }
+
+       /* check if the flow is active or not */
+       if (!ulp_flow_db_active_flows_bit_is_set(flow_db, flow_type, fid)) {
+               BNXT_TF_DBG(ERR, "flow does not exist\n");
+               return -EINVAL;
+       }
+
+       /* Iterate the resource to get the resource handle */
+       res_id =  fid;
+       while (res_id) {
+               fid_res = &flow_tbl->flow_resources[res_id];
+               if (ulp_flow_db_resource_func_get(fid_res) ==
+                   BNXT_ULP_RESOURCE_FUNC_CHILD_FLOW) {
+                       /* invalidate the resource details */
+                       fid_res->resource_hndl = 0;
+                       return 0;
+               }
+               res_id = 0;
+               ULP_FLOW_DB_RES_NXT_SET(res_id, fid_res->nxt_resource_idx);
+       }
+       /* failed */
+       return -1;
+}
+
+/*
+ * Create parent flow in the parent flow tbl
+ *
+ * parms [in] Ptr to mapper params
+ *
+ * Returns 0 on success and negative on failure.
+ */
+int32_t
+ulp_flow_db_parent_flow_create(struct bnxt_ulp_mapper_parms *parms)
+{
+       struct ulp_flow_db_res_params fid_parms;
+       int32_t fid_idx;
+
+       /* create the child flow entry in parent flow table */
+       fid_idx = ulp_flow_db_parent_flow_alloc(parms->ulp_ctx, parms->fid);
+       if (fid_idx < 0) {
+               BNXT_TF_DBG(ERR, "Error in creating parent flow fid %x\n",
+                           parms->fid);
+               return -1;
+       }
+
+       /* Add the parent details in the resource list of the flow */
+       memset(&fid_parms, 0, sizeof(fid_parms));
+       fid_parms.resource_func = BNXT_ULP_RESOURCE_FUNC_PARENT_FLOW;
+       fid_parms.resource_hndl = fid_idx;
+       fid_parms.critical_resource = BNXT_ULP_CRITICAL_RESOURCE_NO;
+       if (ulp_flow_db_resource_add(parms->ulp_ctx, BNXT_ULP_FDB_TYPE_REGULAR,
+                                    parms->fid, &fid_parms)) {
+               BNXT_TF_DBG(ERR, "Error in adding flow res for fid %x\n",
+                           parms->fid);
+               return -1;
+       }
+       return 0;
+}
+
+/*
+ * Create child flow in the parent flow tbl
+ *
+ * parms [in] Ptr to mapper params
+ *
+ * Returns 0 on success and negative on failure.
+ */
+int32_t
+ulp_flow_db_child_flow_create(struct bnxt_ulp_mapper_parms *parms)
+{
+       struct ulp_flow_db_res_params fid_parms;
+       int32_t rc;
+
+       /* create the parent flow entry in parent flow table */
+       rc = ulp_flow_db_parent_child_flow_set(parms->ulp_ctx,
+                                              parms->parent_fid,
+                                              parms->fid, 1);
+       if (rc) {
+               BNXT_TF_DBG(ERR, "Error in setting child fid %x\n", parms->fid);
+               return -1;
+       }
+
+       /* Add the parent details in the resource list of the flow */
+       memset(&fid_parms, 0, sizeof(fid_parms));
+       fid_parms.resource_func = BNXT_ULP_RESOURCE_FUNC_CHILD_FLOW;
+       fid_parms.resource_hndl = parms->parent_fid;
+       fid_parms.critical_resource = BNXT_ULP_CRITICAL_RESOURCE_NO;
+       if (ulp_flow_db_resource_add(parms->ulp_ctx, BNXT_ULP_FDB_TYPE_REGULAR,
+                                    parms->fid, &fid_parms)) {
+               BNXT_TF_DBG(ERR, "Error in adding flow res for fid %x\n",
+                           parms->fid);
+               return -1;
+       }
+       return 0;
+}
index 87bcd69..95fd199 100644 (file)
@@ -8,6 +8,7 @@
 
 #include "bnxt_ulp.h"
 #include "ulp_template_db_enum.h"
+#include "ulp_mapper.h"
 
 #define BNXT_FLOW_DB_DEFAULT_NUM_FLOWS         512
 #define BNXT_FLOW_DB_DEFAULT_NUM_RESOURCES     8
@@ -319,5 +320,40 @@ ulp_flow_db_parent_child_flow_next_entry_get(struct bnxt_ulp_flow_db *flow_db,
                                             uint32_t parent_idx,
                                             uint32_t *child_fid);
 
+/*
+ * Orphan the child flow entry
+ * This is called only for child flows that have
+ * BNXT_ULP_RESOURCE_FUNC_CHILD_FLOW resource
+ *
+ * ulp_ctxt [in] Ptr to ulp_context
+ * flow_type [in] Specify it is regular or default flow
+ * fid [in] The index to the flow entry
+ *
+ * Returns 0 on success and negative on failure.
+ */
+int32_t
+ulp_flow_db_child_flow_reset(struct bnxt_ulp_context *ulp_ctxt,
+                            enum bnxt_ulp_fdb_type flow_type,
+                            uint32_t fid);
+
+/*
+ * Create parent flow in the parent flow tbl
+ *
+ * parms [in] Ptr to mapper params
+ *
+ * Returns 0 on success and negative on failure.
+ */
+int32_t
+ulp_flow_db_parent_flow_create(struct bnxt_ulp_mapper_parms *parms);
+
+/*
+ * Create child flow in the parent flow tbl
+ *
+ * parms [in] Ptr to mapper params
+ *
+ * Returns 0 on success and negative on failure.
+ */
+int32_t
+ulp_flow_db_child_flow_create(struct bnxt_ulp_mapper_parms *parms);
 
 #endif /* _ULP_FLOW_DB_H_ */
index cd289cc..b74cb92 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
@@ -2484,6 +2543,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 +2580,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 +2624,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 +2674,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);
                }
        }
 }
@@ -2720,6 +2786,8 @@ 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;
 
        /* Get the device id from the ulp context */
        if (bnxt_ulp_cntxt_dev_id_get(ulp_ctx, &parms.dev_id)) {
@@ -2797,6 +2865,19 @@ ulp_mapper_flow_create(struct bnxt_ulp_context *ulp_ctx,
                        goto flow_error;
        }
 
+       /* 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;
+       }
+
        *flowid = parms.fid;
        bnxt_ulp_cntxt_release_fdb_lock(ulp_ctx);
 
index 6f93bcd..542e41e 100644 (file)
@@ -76,6 +76,8 @@ struct bnxt_ulp_mapper_parms {
        enum bnxt_ulp_cache_table_opc           tcam_tbl_opc;
        struct bnxt_ulp_mapper_cache_entry      *cache_ptr;
        struct bnxt_ulp_device_params           *device_params;
+       uint32_t                                parent_fid;
+       uint32_t                                parent_flow;
 };
 
 struct bnxt_ulp_mapper_create_parms {
@@ -90,6 +92,11 @@ struct bnxt_ulp_mapper_create_parms {
        uint16_t                        func_id;
        uint32_t                        dir_attr;
        enum bnxt_ulp_fdb_type          flow_type;
+
+       /* if set then create it as a child flow with parent as parent_fid */
+       uint32_t                        parent_fid;
+       /* if set then create a parent flow */
+       uint32_t                        parent_flow;
 };
 
 /* Function to initialize any dynamic mapper data. */
index 81da34e..168e308 100644 (file)
@@ -321,7 +321,10 @@ enum bnxt_ulp_resource_func {
        BNXT_ULP_RESOURCE_FUNC_CACHE_TABLE = 0x82,
        BNXT_ULP_RESOURCE_FUNC_IDENTIFIER = 0x83,
        BNXT_ULP_RESOURCE_FUNC_IF_TABLE = 0x84,
-       BNXT_ULP_RESOURCE_FUNC_HW_FID = 0x85
+       BNXT_ULP_RESOURCE_FUNC_HW_FID = 0x85,
+       BNXT_ULP_RESOURCE_FUNC_SHARED_TABLE = 0x86,
+       BNXT_ULP_RESOURCE_FUNC_PARENT_FLOW = 0x87,
+       BNXT_ULP_RESOURCE_FUNC_CHILD_FLOW = 0x88
 };
 
 enum bnxt_ulp_resource_sub_type {