return 0;
 }
 
+/*
+ * Allocate the flow database entry
+ *
+ * ulp_ctxt [in] Ptr to ulp_context
+ * tbl_idx [in] Specify it is regular or default flow
+ * fid [out] The index to the flow entry
+ *
+ * returns 0 on success and negative on failure.
+ */
+int32_t ulp_flow_db_fid_alloc(struct bnxt_ulp_context          *ulp_ctxt,
+                             enum bnxt_ulp_flow_db_tables      tbl_idx,
+                             uint32_t                          *fid)
+{
+       struct bnxt_ulp_flow_db         *flow_db;
+       struct bnxt_ulp_flow_tbl        *flow_tbl;
+
+       *fid = 0; /* Initialize fid to invalid value */
+       flow_db = bnxt_ulp_cntxt_ptr2_flow_db_get(ulp_ctxt);
+       if (!flow_db) {
+               BNXT_TF_DBG(ERR, "Invalid Arguments\n");
+               return -EINVAL;
+       }
+
+       flow_tbl = &flow_db->flow_tbl[tbl_idx];
+       /* check for max flows */
+       if (flow_tbl->num_flows <= flow_tbl->head_index) {
+               BNXT_TF_DBG(ERR, "Flow database has reached max flows\n");
+               return -ENOMEM;
+       }
+       *fid = flow_tbl->flow_tbl_stack[flow_tbl->head_index];
+       flow_tbl->head_index++;
+       ulp_flow_db_active_flow_set(flow_tbl, *fid, 1);
+
+       /* all good, return success */
+       return 0;
+}
+
 /*
  * Allocate the flow database entry.
  * The params->critical_resource has to be set to 0 to allocate a new resource.
 
  */
 int32_t        ulp_flow_db_deinit(struct bnxt_ulp_context *ulp_ctxt);
 
+/*
+ * Allocate the flow database entry
+ *
+ * ulp_ctxt [in] Ptr to ulp_context
+ * tbl_idx [in] Specify it is regular or default flow
+ * fid [out] The index to the flow entry
+ *
+ * returns 0 on success and negative on failure.
+ */
+int32_t ulp_flow_db_fid_alloc(struct bnxt_ulp_context          *ulp_ctxt,
+                             enum bnxt_ulp_flow_db_tables      tbl_idx,
+                             uint32_t                          *fid);
+
 /*
  * Allocate the flow database entry.
  * The params->critical_resource has to be set to 0 to allocate a new resource.
 
 #include "ulp_flow_db.h"
 #include "ulp_mapper.h"
 
-int32_t
-ulp_mapper_action_tbls_process(struct bnxt_ulp_mapper_parms *parms);
-
-int32_t
-ulp_mapper_class_tbls_process(struct bnxt_ulp_mapper_parms *parms);
-
 /*
  * Get the size of the action property for a given index.
  *
 }
 
 /*
- * Get the list of result fields that implement the flow action
+ * Get the list of result fields that implement the flow action.
+ * Gets a device dependent list of tables that implement the action template id.
+ *
+ * dev_id [in] The device id of the forwarding element
+ *
+ * tid [in] The action template id that matches the flow
+ *
+ * num_tbls [out] The number of action tables in the returned array
+ *
+ * Returns An array of action tables to implement the flow, or NULL on error.
+ */
+static struct bnxt_ulp_mapper_act_tbl_info *
+ulp_mapper_action_tbl_list_get(uint32_t dev_id,
+                              uint32_t tid,
+                              uint32_t *num_tbls)
+{
+       uint32_t        idx;
+       uint32_t        tidx;
+
+       if (!num_tbls) {
+               BNXT_TF_DBG(ERR, "Invalid arguments\n");
+               return NULL;
+       }
+
+       /* template shift and device mask */
+       tidx = ULP_DEVICE_PARAMS_INDEX(tid, dev_id);
+
+       /* NOTE: Need to have something from template compiler to help validate
+        * range of dev_id and act_tid
+        */
+       idx             = ulp_act_tmpl_list[tidx].start_tbl_idx;
+       *num_tbls       = ulp_act_tmpl_list[tidx].num_tbls;
+
+       return &ulp_act_tbl_list[idx];
+}
+
+/** Get a list of classifier tables that implement the flow
+ * Gets a device dependent list of tables that implement the class template id
+ *
+ * dev_id [in] The device id of the forwarding element
+ *
+ * tid [in] The template id that matches the flow
+ *
+ * num_tbls [out] The number of classifier tables in the returned array
+ *
+ * returns An array of classifier tables to implement the flow, or NULL on
+ * error
+ */
+static struct bnxt_ulp_mapper_class_tbl_info *
+ulp_mapper_class_tbl_list_get(uint32_t dev_id,
+                             uint32_t tid,
+                             uint32_t *num_tbls)
+{
+       uint32_t idx;
+       uint32_t tidx = ULP_DEVICE_PARAMS_INDEX(tid, dev_id);
+
+       if (!num_tbls)
+               return NULL;
+
+       /* NOTE: Need to have something from template compiler to help validate
+        * range of dev_id and tid
+        */
+       idx             = ulp_class_tmpl_list[tidx].start_tbl_idx;
+       *num_tbls       = ulp_class_tmpl_list[tidx].num_tbls;
+
+       return &ulp_class_tbl_list[idx];
+}
+
+/*
+ * Get the list of key fields that implement the flow.
  *
  * ctxt [in] The ulp context
  *
  *
  * num_flds [out] The number of key fields in the returned array
  *
- * returns array of Key fields, or NULL on error
+ * Returns array of Key fields, or NULL on error.
  */
 static struct bnxt_ulp_mapper_class_key_field_info *
 ulp_mapper_key_fields_get(struct bnxt_ulp_mapper_class_tbl_info *tbl,
  * Function to process the action template. Iterate through the list
  * action info templates and process it.
  */
-int32_t
+static int32_t
 ulp_mapper_action_tbls_process(struct bnxt_ulp_mapper_parms *parms)
 {
        uint32_t        i;
 }
 
 /* Create the classifier table entries for a flow. */
-int32_t
+static int32_t
 ulp_mapper_class_tbls_process(struct bnxt_ulp_mapper_parms *parms)
 {
        uint32_t        i;
                                         fid,
                                         BNXT_ULP_REGULAR_FLOW_TABLE);
 }
+
+/* Function to handle the mapping of the Flow to be compatible
+ * with the underlying hardware.
+ */
+int32_t
+ulp_mapper_flow_create(struct bnxt_ulp_context *ulp_ctx,
+                      uint32_t app_priority __rte_unused,
+                      struct ulp_rte_hdr_bitmap *hdr_bitmap __rte_unused,
+                      struct ulp_rte_hdr_field *hdr_field,
+                      struct ulp_rte_act_bitmap *act_bitmap,
+                      struct ulp_rte_act_prop *act_prop,
+                      uint32_t class_tid,
+                      uint32_t act_tid,
+                      uint32_t *flow_id)
+{
+       struct ulp_regfile              regfile;
+       struct bnxt_ulp_mapper_parms    parms;
+       struct bnxt_ulp_device_params   *device_params;
+       int32_t                         rc, trc;
+
+       /* Initialize the parms structure */
+       memset(&parms, 0, sizeof(parms));
+       parms.act_prop = act_prop;
+       parms.act_bitmap = act_bitmap;
+       parms.regfile = ®file;
+       parms.hdr_field = hdr_field;
+       parms.tfp = bnxt_ulp_cntxt_tfp_get(ulp_ctx);
+       parms.ulp_ctx = ulp_ctx;
+
+       /* Get the device id from the ulp context */
+       if (bnxt_ulp_cntxt_dev_id_get(ulp_ctx, &parms.dev_id)) {
+               BNXT_TF_DBG(ERR, "Invalid ulp context\n");
+               return -EINVAL;
+       }
+
+       /* Get the action table entry from device id and act context id */
+       parms.act_tid = act_tid;
+       parms.atbls = ulp_mapper_action_tbl_list_get(parms.dev_id,
+                                                    parms.act_tid,
+                                                    &parms.num_atbls);
+       if (!parms.atbls || !parms.num_atbls) {
+               BNXT_TF_DBG(ERR, "No action tables for %d:%d\n",
+                           parms.dev_id, parms.act_tid);
+               return -EINVAL;
+       }
+
+       /* Get the class table entry from device id and act context id */
+       parms.class_tid = class_tid;
+       parms.ctbls = ulp_mapper_class_tbl_list_get(parms.dev_id,
+                                                   parms.class_tid,
+                                                   &parms.num_ctbls);
+       if (!parms.ctbls || !parms.num_ctbls) {
+               BNXT_TF_DBG(ERR, "No class tables for %d:%d\n",
+                           parms.dev_id, parms.class_tid);
+               return -EINVAL;
+       }
+
+       /* Get the byte order for the further processing from device params */
+       device_params = bnxt_ulp_device_params_get(parms.dev_id);
+       if (!device_params) {
+               BNXT_TF_DBG(ERR, "No class tables for %d:%d\n",
+                           parms.dev_id, parms.class_tid);
+               return -EINVAL;
+       }
+       parms.order = device_params->byte_order;
+       parms.encap_byte_swap = device_params->encap_byte_swap;
+
+       /* initialize the registry file for further processing */
+       if (!ulp_regfile_init(parms.regfile)) {
+               BNXT_TF_DBG(ERR, "regfile initialization 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,
+                                  BNXT_ULP_REGULAR_FLOW_TABLE,
+                                  &parms.fid);
+       if (rc) {
+               BNXT_TF_DBG(ERR, "Unable to allocate flow table entry\n");
+               return rc;
+       }
+
+       /* Process the action template list from the selected action table*/
+       rc = ulp_mapper_action_tbls_process(&parms);
+       if (rc) {
+               BNXT_TF_DBG(ERR, "action tables failed creation for %d:%d\n",
+                           parms.dev_id, parms.act_tid);
+               goto flow_error;
+       }
+
+       /* All good. Now process the class template */
+       rc = ulp_mapper_class_tbls_process(&parms);
+       if (rc) {
+               BNXT_TF_DBG(ERR, "class tables failed creation for %d:%d\n",
+                           parms.dev_id, parms.class_tid);
+               goto flow_error;
+       }
+
+       *flow_id = parms.fid;
+
+       return rc;
+
+flow_error:
+       /* Free all resources that were allocated during flow creation */
+       trc = ulp_mapper_flow_destroy(ulp_ctx, parms.fid);
+       if (trc)
+               BNXT_TF_DBG(ERR, "Failed to free all resources rc=%d\n", trc);
+
+       return rc;
+}
 
        enum bnxt_ulp_flow_db_tables            tbl_idx;
 };
 
+/*
+ * Function to handle the mapping of the Flow to be compatible
+ * with the underlying hardware.
+ */
+int32_t
+ulp_mapper_flow_create(struct bnxt_ulp_context *ulp_ctx,
+                      uint32_t         app_priority,
+                      struct ulp_rte_hdr_bitmap  *hdr_bitmap,
+                      struct ulp_rte_hdr_field *hdr_field,
+                      struct ulp_rte_act_bitmap *act,
+                      struct ulp_rte_act_prop *act_prop,
+                      uint32_t         class_tid,
+                      uint32_t         act_tid,
+                      uint32_t         *flow_id);
+
 /* Function that frees all resources associated with the flow. */
 int32_t
 ulp_mapper_flow_destroy(struct bnxt_ulp_context        *ulp_ctx, uint32_t fid);
 
        }
 };
 
+struct bnxt_ulp_mapper_tbl_list_info ulp_class_tmpl_list[] = {
+       [((0 << BNXT_ULP_LOG2_MAX_NUM_DEV) | BNXT_ULP_DEVICE_ID_WH_PLUS)] = {
+       .device_name = BNXT_ULP_DEVICE_ID_WH_PLUS,
+       .num_tbls = 3,
+       .start_tbl_idx = 0
+       }
+};
+
+struct bnxt_ulp_mapper_class_tbl_info ulp_class_tbl_list[] = {
+       {
+       .resource_func = BNXT_ULP_RESOURCE_FUNC_TCAM_TABLE,
+       .table_type = TF_TCAM_TBL_TYPE_L2_CTXT_TCAM,
+       .direction = TF_DIR_RX,
+       .priority = BNXT_ULP_PRIORITY_LEVEL_0,
+       .srch_b4_alloc = BNXT_ULP_SEARCH_BEFORE_ALLOC_NO,
+       .key_start_idx = 0,
+       .blob_key_bit_size = 167,
+       .key_bit_size = 167,
+       .key_num_fields = 13,
+       .result_start_idx = 0,
+       .result_bit_size = 64,
+       .result_num_fields = 13,
+       .ident_start_idx = 0,
+       .ident_nums = 1,
+       .mark_enable = BNXT_ULP_MARK_ENABLE_NO,
+       .critical_resource = 0,
+       .regfile_wr_idx = BNXT_ULP_REGFILE_INDEX_NOT_USED
+       },
+       {
+       .resource_func = BNXT_ULP_RESOURCE_FUNC_TCAM_TABLE,
+       .table_type = TF_TCAM_TBL_TYPE_PROF_TCAM,
+       .direction = TF_DIR_RX,
+       .priority = BNXT_ULP_PRIORITY_LEVEL_0,
+       .srch_b4_alloc = BNXT_ULP_SEARCH_BEFORE_ALLOC_NO,
+       .key_start_idx = 13,
+       .blob_key_bit_size = 81,
+       .key_bit_size = 81,
+       .key_num_fields = 42,
+       .result_start_idx = 13,
+       .result_bit_size = 38,
+       .result_num_fields = 8,
+       .ident_start_idx = 1,
+       .ident_nums = 1,
+       .mark_enable = BNXT_ULP_MARK_ENABLE_NO,
+       .critical_resource = 0,
+       .regfile_wr_idx = BNXT_ULP_REGFILE_INDEX_NOT_USED
+       },
+       {
+       .resource_func = BNXT_ULP_RESOURCE_FUNC_EM_TABLE,
+       .table_type = TF_MEM_EXTERNAL,
+       .direction = TF_DIR_RX,
+       .priority = BNXT_ULP_PRIORITY_NOT_USED,
+       .srch_b4_alloc = BNXT_ULP_SEARCH_BEFORE_ALLOC_NO,
+       .key_start_idx = 55,
+       .blob_key_bit_size = 448,
+       .key_bit_size = 197,
+       .key_num_fields = 11,
+       .result_start_idx = 21,
+       .result_bit_size = 64,
+       .result_num_fields = 9,
+       .ident_start_idx = 2,
+       .ident_nums = 0,
+       .mark_enable = BNXT_ULP_MARK_ENABLE_YES,
+       .critical_resource = 1,
+       .regfile_wr_idx = BNXT_ULP_REGFILE_INDEX_NOT_USED
+       }
+};
+
 struct bnxt_ulp_mapper_class_key_field_info ulp_class_key_field_list[] = {
        {
        .field_bit_size = 12,
        }
 };
 
+struct bnxt_ulp_mapper_tbl_list_info ulp_act_tmpl_list[] = {
+       [((0 << BNXT_ULP_LOG2_MAX_NUM_DEV) | BNXT_ULP_DEVICE_ID_WH_PLUS)] = {
+       .device_name = BNXT_ULP_DEVICE_ID_WH_PLUS,
+       .num_tbls = 1,
+       .start_tbl_idx = 0
+       }
+};
+
+struct bnxt_ulp_mapper_act_tbl_info ulp_act_tbl_list[] = {
+       {
+       .resource_func = BNXT_ULP_RESOURCE_FUNC_INDEX_TABLE,
+       .table_type = TF_TBL_TYPE_EXT,
+       .direction = TF_DIR_RX,
+       .srch_b4_alloc = BNXT_ULP_SEARCH_BEFORE_ALLOC_NO,
+       .result_start_idx = 0,
+       .result_bit_size = 128,
+       .result_num_fields = 26,
+       .encap_num_fields = 0,
+       .regfile_wr_idx = BNXT_ULP_REGFILE_INDEX_ACTION_PTR_MAIN
+       }
+};
+
 struct bnxt_ulp_mapper_result_field_info ulp_act_result_field_list[] = {
        {
        .field_bit_size = 14,
 
 #define ULP_TEMPLATE_DB_H_
 
 #define BNXT_ULP_MAX_NUM_DEVICES 4
+#define BNXT_ULP_LOG2_MAX_NUM_DEV 2
 
 enum bnxt_ulp_action_bit {
        BNXT_ULP_ACTION_BIT_MARK             = 0x0000000000000001,
        BNXT_ULP_RESULT_OPC_LAST = 4
 };
 
+enum bnxt_ulp_search_before_alloc {
+       BNXT_ULP_SEARCH_BEFORE_ALLOC_NO = 0,
+       BNXT_ULP_SEARCH_BEFORE_ALLOC_YES = 1,
+       BNXT_ULP_SEARCH_BEFORE_ALLOC_LAST = 2
+};
+
 enum bnxt_ulp_spec_opc {
        BNXT_ULP_SPEC_OPC_SET_TO_CONSTANT = 0,
        BNXT_ULP_SPEC_OPC_SET_TO_HDR_FIELD = 1,
 
 #include "rte_flow.h"
 #include "tf_core.h"
 
+struct ulp_rte_hdr_bitmap {
+       uint64_t        bits;
+};
+
 /* Structure to store the protocol fields */
 #define RTE_PARSER_FLOW_HDR_FIELD_SIZE         16
 struct ulp_rte_hdr_field {
        uint32_t                        num_resources_per_flow;
 };
 
+/* Flow Mapper */
+struct bnxt_ulp_mapper_tbl_list_info {
+       uint32_t        device_name;
+       uint32_t        start_tbl_idx;
+       uint32_t        num_tbls;
+};
+
 struct bnxt_ulp_mapper_class_tbl_info {
        enum bnxt_ulp_resource_func     resource_func;
        uint32_t        table_type;
 extern struct bnxt_ulp_device_params ulp_device_params[];
 
 /*
- * The ulp_data_field_list provides the instructions for creating an action
+ * The ulp_class_tmpl_list and ulp_act_tmpl_list are indexed by the dev_id
+ * and template id (either class or action) returned by the matcher.
+ * The result provides the start index and number of entries in the connected
+ * ulp_class_tbl_list/ulp_act_tbl_list.
+ */
+extern struct bnxt_ulp_mapper_tbl_list_info    ulp_class_tmpl_list[];
+extern struct bnxt_ulp_mapper_tbl_list_info    ulp_act_tmpl_list[];
+
+/*
+ * The ulp_class_tbl_list and ulp_act_tbl_list are indexed based on the results
+ * of the template lists.  Each entry describes the high level details of the
+ * table entry to include the start index and number of instructions in the
+ * field lists.
+ */
+extern struct bnxt_ulp_mapper_class_tbl_info   ulp_class_tbl_list[];
+extern struct bnxt_ulp_mapper_act_tbl_info     ulp_act_tbl_list[];
+
+/*
+ * The ulp_class_result_field_list provides the instructions for creating result
  * records such as tcam/em results.
  */
 extern struct bnxt_ulp_mapper_result_field_info        ulp_class_result_field_list[];