/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2014-2020 Broadcom
+ * Copyright(c) 2014-2021 Broadcom
* All rights reserved.
*/
#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 *
return ulp_act_prop_map_table[idx];
}
-/*
- * Get the list of result fields that implement the flow action.
- * Gets a device dependent list of tables that implement the action template id.
- *
- * mparms [in] The mappers parms with data related to the flow.
- *
- * 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_tbl_info *
-ulp_mapper_action_tbl_list_get(struct bnxt_ulp_mapper_parms *mparms,
- uint32_t tid,
- uint32_t *num_tbls)
-{
- uint32_t idx;
- const struct ulp_template_device_tbls *dev_tbls;
-
- dev_tbls = mparms->device_params->dev_tbls;
-
- /* NOTE: Need to have something from template compiler to help validate
- * range of dev_id and act_tid
- */
- idx = dev_tbls->act_tmpl_list[tid].start_tbl_idx;
- *num_tbls = dev_tbls->act_tmpl_list[tid].num_tbls;
-
- return &dev_tbls->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
*
* num_tbls [out] The number of classifier tables in the returned array
*
- * fdb_tbl_idx [out] The flow database index Regular or default
- *
* returns An array of classifier tables to implement the flow, or NULL on
* error
*/
static struct bnxt_ulp_mapper_tbl_info *
-ulp_mapper_class_tbl_list_get(struct bnxt_ulp_mapper_parms *mparms,
- uint32_t tid,
- uint32_t *num_tbls,
- uint32_t *fdb_tbl_idx)
+ulp_mapper_tbl_list_get(struct bnxt_ulp_mapper_parms *mparms,
+ uint32_t tid,
+ uint32_t *num_tbls)
{
uint32_t idx;
const struct ulp_template_device_tbls *dev_tbls;
- dev_tbls = mparms->device_params->dev_tbls;
+ dev_tbls = &mparms->device_params->dev_tbls[mparms->tmpl_type];
- /* NOTE: Need to have something from template compiler to help validate
- * range of dev_id and tid
- */
- idx = dev_tbls->class_tmpl_list[tid].start_tbl_idx;
- *num_tbls = dev_tbls->class_tmpl_list[tid].num_tbls;
- *fdb_tbl_idx = dev_tbls->class_tmpl_list[tid].flow_db_table_type;
+ idx = dev_tbls->tmpl_list[tid].start_tbl_idx;
+ *num_tbls = dev_tbls->tmpl_list[tid].num_tbls;
- return &dev_tbls->class_tbl_list[idx];
+ return &dev_tbls->tbl_list[idx];
}
/*
*
* Returns array of Key fields, or NULL on error.
*/
-static struct bnxt_ulp_mapper_class_key_field_info *
+static struct bnxt_ulp_mapper_key_field_info *
ulp_mapper_key_fields_get(struct bnxt_ulp_mapper_parms *mparms,
struct bnxt_ulp_mapper_tbl_info *tbl,
uint32_t *num_flds)
uint32_t idx;
const struct ulp_template_device_tbls *dev_tbls;
- dev_tbls = mparms->device_params->dev_tbls;
+ dev_tbls = &mparms->device_params->dev_tbls[mparms->tmpl_type];
+ if (!dev_tbls->key_field_list) {
+ *num_flds = 0;
+ return NULL;
+ }
idx = tbl->key_start_idx;
*num_flds = tbl->key_num_fields;
- /* NOTE: Need template to provide range checking define */
- return &dev_tbls->class_key_field_list[idx];
+ return &dev_tbls->key_field_list[idx];
}
/*
uint32_t idx;
const struct ulp_template_device_tbls *dev_tbls;
- dev_tbls = mparms->device_params->dev_tbls;
+ dev_tbls = &mparms->device_params->dev_tbls[mparms->tmpl_type];
+ if (!dev_tbls->result_field_list) {
+ *num_flds = 0;
+ *num_encap_flds = 0;
+ return NULL;
+ }
idx = tbl->result_start_idx;
*num_flds = tbl->result_num_fields;
*num_encap_flds = tbl->encap_num_fields;
- /* NOTE: Need template to provide range checking define */
- return &dev_tbls->class_result_field_list[idx];
-}
-
-/*
- * Get the list of result fields that implement the flow action.
- *
- * mparms [in] The mapper parms with information about the flow
- *
- * tbl [in] A single table instance to get the results fields
- * from num_flds
- *
- * num_rslt_flds [out] The number of data fields in the returned
- * array.
- *
- * num_encap_flds [out] The number of encap fields if any.
- *
- * Returns array of data fields, or NULL on error.
- */
-static struct bnxt_ulp_mapper_result_field_info *
-ulp_mapper_act_result_fields_get(struct bnxt_ulp_mapper_parms *mparms,
- struct bnxt_ulp_mapper_tbl_info *tbl,
- uint32_t *num_rslt_flds,
- uint32_t *num_encap_flds)
-{
- uint32_t idx;
- const struct ulp_template_device_tbls *dev_tbls;
-
- dev_tbls = mparms->device_params->dev_tbls;
-
- idx = tbl->result_start_idx;
- *num_rslt_flds = tbl->result_num_fields;
- *num_encap_flds = tbl->encap_num_fields;
-
- /* NOTE: Need template to provide range checking define */
- return &dev_tbls->act_result_field_list[idx];
+ return &dev_tbls->result_field_list[idx];
}
/*
uint32_t *num_flds)
{
uint32_t idx;
+ const struct ulp_template_device_tbls *dev_tbls;
+
+ dev_tbls = &mparms->device_params->dev_tbls[mparms->tmpl_type];
+ if (!dev_tbls->ident_list) {
+ *num_flds = 0;
+ return NULL;
+ }
idx = tbl->ident_start_idx;
*num_flds = tbl->ident_nums;
- /* NOTE: Need template to provide range checking define */
- return &mparms->device_params->dev_tbls->ident_list[idx];
+ return &dev_tbls->ident_list[idx];
}
static struct bnxt_ulp_mapper_cache_entry *
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
fid_parms.critical_resource = BNXT_ULP_CRITICAL_RESOURCE_NO;
rc = ulp_flow_db_resource_add(parms->ulp_ctx,
- parms->tbl_idx,
+ parms->flow_type,
parms->fid,
&fid_parms);
if (rc) {
fid_parms.resource_hndl = sparms.search_id;
fid_parms.critical_resource = BNXT_ULP_CRITICAL_RESOURCE_NO;
rc = ulp_flow_db_resource_add(parms->ulp_ctx,
- parms->tbl_idx,
+ parms->flow_type,
parms->fid,
&fid_parms);
if (rc) {
static int32_t
ulp_mapper_keymask_field_process(struct bnxt_ulp_mapper_parms *parms,
enum tf_dir dir,
- struct bnxt_ulp_mapper_class_key_field_info *f,
+ struct bnxt_ulp_mapper_key_field_info *f,
struct ulp_blob *blob,
uint8_t is_key,
const char *name)
uint8_t *operand;
struct ulp_regfile *regfile = parms->regfile;
uint8_t *val = NULL;
- struct bnxt_ulp_mapper_class_key_field_info *fld = f;
+ struct bnxt_ulp_mapper_key_field_info *fld = f;
uint32_t field_size;
if (is_key) {
fid_parms.resource_type = mark_flag;
fid_parms.resource_hndl = gfid;
rc = ulp_flow_db_resource_add(parms->ulp_ctx,
- parms->tbl_idx,
+ parms->flow_type,
parms->fid,
&fid_parms);
if (rc)
fid_parms.resource_type = mark_flag;
fid_parms.resource_hndl = act_idx;
rc = ulp_flow_db_resource_add(parms->ulp_ctx,
- parms->tbl_idx,
+ parms->flow_type,
parms->fid,
&fid_parms);
if (rc)
fid_parms.resource_type = mark_flag;
fid_parms.resource_hndl = act_idx;
rc = ulp_flow_db_resource_add(parms->ulp_ctx,
- parms->tbl_idx,
+ parms->flow_type,
parms->fid,
&fid_parms);
if (rc)
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)
{
- struct bnxt_ulp_mapper_class_key_field_info *kflds;
+ struct bnxt_ulp_mapper_key_field_info *kflds;
struct ulp_blob key, mask, data, update_data;
uint32_t i, num_kflds;
struct tf *tfp;
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) ||
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
}
}
+ 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
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;
}
fid_parms.critical_resource = tbl->critical_resource;
fid_parms.resource_hndl = idx;
rc = ulp_flow_db_resource_add(parms->ulp_ctx,
- parms->tbl_idx,
+ parms->flow_type,
parms->fid,
&fid_parms);
if (rc) {
ulp_mapper_em_tbl_process(struct bnxt_ulp_mapper_parms *parms,
struct bnxt_ulp_mapper_tbl_info *tbl)
{
- struct bnxt_ulp_mapper_class_key_field_info *kflds;
+ struct bnxt_ulp_mapper_key_field_info *kflds;
struct bnxt_ulp_mapper_result_field_info *dflds;
struct ulp_blob key, data;
uint32_t i, num_kflds, num_dflds;
struct ulp_flow_db_res_params fid_parms = { 0 };
struct tf_insert_em_entry_parms iparms = { 0 };
struct tf_delete_em_entry_parms free_parms = { 0 };
+ enum bnxt_ulp_flow_mem_type mtype;
int32_t trc;
- enum bnxt_ulp_flow_mem_type mtype = parms->device_params->flow_mem_type;
int32_t rc = 0;
uint32_t encap_flds = 0;
+ rc = bnxt_ulp_cntxt_mem_type_get(parms->ulp_ctx, &mtype);
+ if (rc) {
+ BNXT_TF_DBG(ERR, "Failed to get the mem type for EM\n");
+ return -EINVAL;
+ }
+
kflds = ulp_mapper_key_fields_get(parms, tbl, &num_kflds);
if (!kflds || !num_kflds) {
BNXT_TF_DBG(ERR, "Failed to get key fields\n");
fid_parms.resource_hndl = iparms.flow_handle;
rc = ulp_flow_db_resource_add(parms->ulp_ctx,
- parms->tbl_idx,
+ parms->flow_type,
parms->fid,
&fid_parms);
if (rc) {
static int32_t
ulp_mapper_index_tbl_process(struct bnxt_ulp_mapper_parms *parms,
- struct bnxt_ulp_mapper_tbl_info *tbl,
- bool is_class_tbl)
+ struct bnxt_ulp_mapper_tbl_info *tbl)
{
struct bnxt_ulp_mapper_result_field_info *flds;
struct ulp_flow_db_res_params fid_parms;
}
/* Get the result fields list */
- if (is_class_tbl)
- flds = ulp_mapper_result_fields_get(parms, tbl, &num_flds,
- &encap_flds);
- else
- flds = ulp_mapper_act_result_fields_get(parms, tbl, &num_flds,
- &encap_flds);
+ flds = ulp_mapper_result_fields_get(parms, tbl, &num_flds, &encap_flds);
if (!flds || (!num_flds && !encap_flds)) {
BNXT_TF_DBG(ERR, "template undefined for the index table\n");
fid_parms.critical_resource = BNXT_ULP_CRITICAL_RESOURCE_NO;
rc = ulp_flow_db_resource_add(parms->ulp_ctx,
- parms->tbl_idx,
+ parms->flow_type,
parms->fid,
&fid_parms);
if (rc) {
ulp_mapper_cache_tbl_process(struct bnxt_ulp_mapper_parms *parms,
struct bnxt_ulp_mapper_tbl_info *tbl)
{
- struct bnxt_ulp_mapper_class_key_field_info *kflds;
+ struct bnxt_ulp_mapper_key_field_info *kflds;
struct bnxt_ulp_mapper_cache_entry *cache_entry;
struct bnxt_ulp_mapper_ident_info *idents;
uint32_t i, num_kflds = 0, num_idents = 0;
fid_parms.resource_hndl = (uint64_t)*ckey;
fid_parms.critical_resource = tbl->critical_resource;
rc = ulp_flow_db_resource_add(parms->ulp_ctx,
- parms->tbl_idx,
+ parms->flow_type,
parms->fid,
&fid_parms);
if (rc)
* Function to process the conditional opcode of the mapper table.
* returns 1 to skip the table.
* return 0 to continue processing the table.
+ *
+ * defaults to skip
*/
static int32_t
ulp_mapper_tbl_cond_opcode_process(struct bnxt_ulp_mapper_parms *parms,
}
/*
- * Function to process the action template. Iterate through the list
- * action info templates and process it.
+ * Function to process the memtype opcode of the mapper table.
+ * returns 1 to skip the table.
+ * return 0 to continue processing the table.
+ *
+ * defaults to skip
*/
static int32_t
-ulp_mapper_action_tbls_process(struct bnxt_ulp_mapper_parms *parms)
+ulp_mapper_tbl_memtype_opcode_process(struct bnxt_ulp_mapper_parms *parms,
+ struct bnxt_ulp_mapper_tbl_info *tbl)
{
- uint32_t i;
- int32_t rc = 0;
- struct bnxt_ulp_mapper_tbl_info *tbl;
-
- if (!parms->atbls || !parms->num_atbls) {
- BNXT_TF_DBG(ERR, "No action tables for template[%d][%d].\n",
- parms->dev_id, parms->act_tid);
- return -EINVAL;
- }
+ enum bnxt_ulp_flow_mem_type mtype = BNXT_ULP_FLOW_MEM_TYPE_INT;
+ int32_t rc = 1;
- for (i = 0; i < parms->num_atbls; i++) {
- tbl = &parms->atbls[i];
- if (ulp_mapper_tbl_cond_opcode_process(parms, tbl))
- continue;
+ bnxt_ulp_cntxt_mem_type_get(parms->ulp_ctx, &mtype);
- switch (tbl->resource_func) {
- case BNXT_ULP_RESOURCE_FUNC_INDEX_TABLE:
- rc = ulp_mapper_index_tbl_process(parms, tbl, false);
- if (rc) {
- BNXT_TF_DBG(ERR, "Resource type %d failed\n",
- tbl->resource_func);
- return rc;
- }
- break;
- default:
- BNXT_TF_DBG(ERR, "Unexpected action resource %d\n",
- tbl->resource_func);
- return -EINVAL;
- }
+ switch (tbl->mem_type_opcode) {
+ case BNXT_ULP_MEM_TYPE_OPCODE_EXECUTE_IF_INT:
+ if (mtype == BNXT_ULP_FLOW_MEM_TYPE_INT)
+ rc = 0;
+ break;
+ case BNXT_ULP_MEM_TYPE_OPCODE_EXECUTE_IF_EXT:
+ if (mtype == BNXT_ULP_FLOW_MEM_TYPE_EXT)
+ rc = 0;
+ break;
+ case BNXT_ULP_MEM_TYPE_OPCODE_NOP:
+ rc = 0;
+ break;
+ default:
+ BNXT_TF_DBG(ERR,
+ "Invalid arg in mapper in memtype opcode\n");
+ break;
}
-
return rc;
}
-/* Create the classifier table entries for a flow. */
static int32_t
-ulp_mapper_class_tbls_process(struct bnxt_ulp_mapper_parms *parms)
+ulp_mapper_tbls_process(struct bnxt_ulp_mapper_parms *parms, uint32_t tid)
{
- uint32_t i;
- int32_t rc = 0;
-
- if (!parms)
- return -EINVAL;
-
- if (!parms->ctbls || !parms->num_ctbls) {
- BNXT_TF_DBG(ERR, "No class tables for template[%d][%d].\n",
- parms->dev_id, parms->class_tid);
+ struct bnxt_ulp_mapper_tbl_info *tbls;
+ uint32_t num_tbls, i;
+ int32_t rc = -EINVAL;
+
+ tbls = ulp_mapper_tbl_list_get(parms, tid, &num_tbls);
+ if (!tbls || !num_tbls) {
+ BNXT_TF_DBG(ERR, "No %s tables for %d:%d\n",
+ (parms->tmpl_type == BNXT_ULP_TEMPLATE_TYPE_CLASS) ?
+ "class" : "action", parms->dev_id, tid);
return -EINVAL;
}
- for (i = 0; i < parms->num_ctbls; i++) {
- struct bnxt_ulp_mapper_tbl_info *tbl = &parms->ctbls[i];
+ for (i = 0; i < num_tbls; i++) {
+ struct bnxt_ulp_mapper_tbl_info *tbl = &tbls[i];
+ if (ulp_mapper_tbl_memtype_opcode_process(parms, tbl))
+ continue;
if (ulp_mapper_tbl_cond_opcode_process(parms, tbl))
continue;
rc = ulp_mapper_em_tbl_process(parms, tbl);
break;
case BNXT_ULP_RESOURCE_FUNC_INDEX_TABLE:
- rc = ulp_mapper_index_tbl_process(parms, tbl, true);
+ rc = ulp_mapper_index_tbl_process(parms, tbl);
break;
case BNXT_ULP_RESOURCE_FUNC_CACHE_TABLE:
rc = ulp_mapper_cache_tbl_process(parms, tbl);
rc = ulp_mapper_if_tbl_process(parms, tbl);
break;
default:
- BNXT_TF_DBG(ERR, "Unexpected class resource %d\n",
+ BNXT_TF_DBG(ERR, "Unexpected mapper resource %d\n",
tbl->resource_func);
- return -EINVAL;
+ rc = -EINVAL;
+ goto error;
}
if (rc) {
BNXT_TF_DBG(ERR, "Resource type %d failed\n",
tbl->resource_func);
- return rc;
+ goto error;
}
}
return rc;
+error:
+ BNXT_TF_DBG(ERR, "%s tables failed creation for %d:%d\n",
+ (parms->tmpl_type == BNXT_ULP_TEMPLATE_TYPE_CLASS) ?
+ "class" : "action", parms->dev_id, tid);
+ return rc;
}
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;
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;
}
}
int32_t
-ulp_mapper_resources_free(struct bnxt_ulp_context *ulp_ctx,
- uint32_t fid,
- enum bnxt_ulp_flow_db_tables tbl_type)
+ulp_mapper_resources_free(struct bnxt_ulp_context *ulp_ctx,
+ enum bnxt_ulp_fdb_type flow_type,
+ uint32_t fid)
{
- struct ulp_flow_db_res_params res_parms = { 0 };
- int32_t rc, trc;
+ struct ulp_flow_db_res_params res_parms = { 0 };
+ int32_t rc, trc;
if (!ulp_ctx) {
BNXT_TF_DBG(ERR, "Invalid parms, unable to free flow\n");
* while status is good
*/
res_parms.critical_resource = BNXT_ULP_CRITICAL_RESOURCE_YES;
- rc = ulp_flow_db_resource_del(ulp_ctx, tbl_type, fid, &res_parms);
+ rc = ulp_flow_db_resource_del(ulp_ctx, flow_type, fid, &res_parms);
if (rc) {
/*
* It likely means that the flow did not exist in the flow db.
*/
BNXT_TF_DBG(ERR, "Flow[%d][0x%08x] failed to free (rc=%d)\n",
- tbl_type, fid, rc);
+ flow_type, fid, rc);
return rc;
}
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
BNXT_TF_DBG(ERR,
"Flow[%d][0x%x] Res[%d][0x%016" PRIx64
"] failed rc=%d.\n",
- tbl_type, fid, res_parms.resource_func,
+ flow_type, fid, res_parms.resource_func,
res_parms.resource_hndl, trc);
/* All subsequent call require the non-critical_resource */
res_parms.critical_resource = BNXT_ULP_CRITICAL_RESOURCE_NO;
rc = ulp_flow_db_resource_del(ulp_ctx,
- tbl_type,
+ flow_type,
fid,
&res_parms);
}
/* Free the Flow ID since we've removed all resources */
- rc = ulp_flow_db_fid_free(ulp_ctx, tbl_type, fid);
+ rc = ulp_flow_db_fid_free(ulp_ctx, flow_type, fid);
return rc;
}
/*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);
}
}
}
int32_t
-ulp_mapper_flow_destroy(struct bnxt_ulp_context *ulp_ctx, uint32_t fid,
- enum bnxt_ulp_flow_db_tables flow_tbl_type)
+ulp_mapper_flow_destroy(struct bnxt_ulp_context *ulp_ctx,
+ enum bnxt_ulp_fdb_type flow_type,
+ uint32_t fid)
{
int32_t rc;
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, fid, flow_tbl_type);
- bnxt_ulp_cntxt_release_fdb_lock(ulp_ctx);
+ rc = ulp_mapper_resources_free(ulp_ctx, flow_type, fid);
return rc;
-
}
/* Function to handle the default global templates that are allocated during
parms.ulp_ctx = ulp_ctx;
parms.dev_id = dev_id;
parms.mapper_data = mapper_data;
+ parms.flow_type = BNXT_ULP_FDB_TYPE_DEFAULT;
+ parms.tmpl_type = BNXT_ULP_TEMPLATE_TYPE_CLASS;
/* Get the class table entry from dev id and class id */
parms.class_tid = glbl_tmpl_list[idx];
parms.dev_id);
return -EINVAL;
}
- parms.ctbls = ulp_mapper_class_tbl_list_get(&parms,
- parms.class_tid,
- &parms.num_ctbls,
- &parms.tbl_idx);
- 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;
- }
- 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);
+
+ rc = ulp_mapper_tbls_process(&parms, parms.class_tid);
+ if (rc)
return rc;
- }
}
return rc;
}
*/
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;
parms.tcam_tbl_opc = BNXT_ULP_MAPPER_TCAM_TBL_OPC_NORMAL;
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;
+ parms.tun_idx = cparms->tun_idx;
/* Get the device id from the ulp context */
if (bnxt_ulp_cntxt_dev_id_get(ulp_ctx, &parms.dev_id)) {
return -EINVAL;
}
- /* Get the action table entry from device id and act context id */
- /*
- * Perform the action table get only if act template is not zero
- * for act template zero like for default rules ignore the action
- * table processing.
- */
- if (parms.act_tid) {
- parms.atbls = ulp_mapper_action_tbl_list_get(&parms,
- 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.ctbls = ulp_mapper_class_tbl_list_get(&parms,
- parms.class_tid,
- &parms.num_ctbls,
- &parms.tbl_idx);
- 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;
- }
-
/* initialize the registry file for further processing */
if (!ulp_regfile_init(parms.regfile)) {
BNXT_TF_DBG(ERR, "regfile initialization failed.\n");
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.tbl_idx,
- 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) {
- 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);
+ parms.tmpl_type = BNXT_ULP_TEMPLATE_TYPE_ACTION;
+ /* Process the action template tables */
+ rc = ulp_mapper_tbls_process(&parms, parms.act_tid);
+ if (rc)
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;
+ if (parms.class_tid) {
+ parms.tmpl_type = BNXT_ULP_TEMPLATE_TYPE_CLASS;
+
+ /* Process the class template tables.*/
+ rc = ulp_mapper_tbls_process(&parms, parms.class_tid);
+ if (rc)
+ 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, parms.fid,
- BNXT_ULP_REGULAR_FLOW_TABLE);
+ trc = ulp_mapper_flow_destroy(ulp_ctx, BNXT_ULP_FDB_TYPE_REGULAR,
+ parms.fid);
if (trc)
BNXT_TF_DBG(ERR, "Failed to free all resources rc=%d\n", trc);