+ulp_mapper_if_tbl_process(struct bnxt_ulp_mapper_parms *parms,
+ struct bnxt_ulp_mapper_tbl_info *tbl)
+{
+ struct ulp_blob data, res_blob;
+ uint64_t idx;
+ uint16_t tmplen;
+ int32_t rc = 0;
+ struct tf_set_if_tbl_entry_parms iftbl_params = { 0 };
+ struct tf_get_if_tbl_entry_parms get_parms = { 0 };
+ struct tf *tfp;
+ enum bnxt_ulp_if_tbl_opc if_opc = tbl->tbl_opcode;
+ uint32_t res_size;
+
+ tfp = bnxt_ulp_cntxt_tfp_get(parms->ulp_ctx, tbl->shared_session);
+ /* Initialize the blob data */
+ if (!ulp_blob_init(&data, tbl->result_bit_size,
+ parms->device_params->result_byte_order)) {
+ BNXT_TF_DBG(ERR, "Failed initial index table blob\n");
+ return -EINVAL;
+ }
+
+ /* create the result blob */
+ rc = ulp_mapper_tbl_result_build(parms, tbl, &data, "IFtable Result");
+ if (rc) {
+ BNXT_TF_DBG(ERR, "Failed to build the result blob\n");
+ return rc;
+ }
+
+ /* Get the index details */
+ switch (if_opc) {
+ case BNXT_ULP_IF_TBL_OPC_WR_COMP_FIELD:
+ idx = ULP_COMP_FLD_IDX_RD(parms, tbl->tbl_operand);
+ break;
+ case BNXT_ULP_IF_TBL_OPC_WR_REGFILE:
+ if (!ulp_regfile_read(parms->regfile, tbl->tbl_operand, &idx)) {
+ BNXT_TF_DBG(ERR, "regfile[%d] read oob\n",
+ tbl->tbl_operand);
+ return -EINVAL;
+ }
+ idx = tfp_be_to_cpu_64(idx);
+ break;
+ case BNXT_ULP_IF_TBL_OPC_WR_CONST:
+ idx = tbl->tbl_operand;
+ break;
+ case BNXT_ULP_IF_TBL_OPC_RD_COMP_FIELD:
+ /* Initialize the result blob */
+ if (!ulp_blob_init(&res_blob, tbl->result_bit_size,
+ parms->device_params->result_byte_order)) {
+ BNXT_TF_DBG(ERR, "Failed initial result blob\n");
+ return -EINVAL;
+ }
+
+ /* read the interface table */
+ idx = ULP_COMP_FLD_IDX_RD(parms, tbl->tbl_operand);
+ res_size = ULP_BITS_2_BYTE(tbl->result_bit_size);
+ get_parms.dir = tbl->direction;
+ get_parms.type = tbl->resource_type;
+ get_parms.idx = idx;
+ get_parms.data = ulp_blob_data_get(&res_blob, &tmplen);
+ get_parms.data_sz_in_bytes = res_size;
+
+ rc = tf_get_if_tbl_entry(tfp, &get_parms);
+ if (rc) {
+ BNXT_TF_DBG(ERR, "Get table[%d][%s][%x] failed rc=%d\n",
+ get_parms.type,
+ tf_dir_2_str(get_parms.dir),
+ get_parms.idx, rc);
+ return rc;
+ }
+ rc = ulp_mapper_tbl_ident_scan_ext(parms, tbl,
+ res_blob.data,
+ res_size,
+ res_blob.byte_order);
+ if (rc)
+ BNXT_TF_DBG(ERR, "Scan and extract failed rc=%d\n", rc);
+ return rc;
+ case BNXT_ULP_IF_TBL_OPC_NOT_USED:
+ return rc; /* skip it */
+ default:
+ BNXT_TF_DBG(ERR, "Invalid tbl index opcode\n");
+ return -EINVAL;
+ }
+
+ /* Perform the tf table set by filling the set params */
+ iftbl_params.dir = tbl->direction;
+ iftbl_params.type = tbl->resource_type;
+ iftbl_params.data = ulp_blob_data_get(&data, &tmplen);
+ iftbl_params.data_sz_in_bytes = ULP_BITS_2_BYTE(tmplen);
+ iftbl_params.idx = idx;
+
+ rc = tf_set_if_tbl_entry(tfp, &iftbl_params);
+ if (rc) {
+ BNXT_TF_DBG(ERR, "Set table[%d][%s][%x] failed rc=%d\n",
+ iftbl_params.type,/* TBD: add tf_if_tbl_2_str */
+ tf_dir_2_str(iftbl_params.dir),
+ iftbl_params.idx, rc);
+ return rc;
+ }
+ BNXT_TF_INF("Set table[%s][%s][%x] success.\n",
+ tf_if_tbl_2_str(iftbl_params.type),
+ tf_dir_2_str(iftbl_params.dir),
+ iftbl_params.idx);
+
+ /*
+ * TBD: Need to look at the need to store idx in flow db for restore
+ * the table to its original state on deletion of this entry.
+ */
+ return rc;
+}
+
+static int32_t
+ulp_mapper_gen_tbl_process(struct bnxt_ulp_mapper_parms *parms,
+ struct bnxt_ulp_mapper_tbl_info *tbl)
+{
+ struct ulp_mapper_gen_tbl_list *gen_tbl_list;
+ struct bnxt_ulp_mapper_key_info *kflds;
+ struct ulp_flow_db_res_params fid_parms;
+ struct ulp_mapper_gen_tbl_entry gen_tbl_ent, *g;
+ struct ulp_gen_hash_entry_params hash_entry;
+ uint16_t tmplen = 0;
+ struct ulp_blob key, data;
+ uint8_t *cache_key;
+ int32_t tbl_idx;
+ uint32_t i, num_kflds = 0, key_index = 0;
+ uint32_t gen_tbl_miss = 1, fdb_write = 0;
+ uint8_t *byte_data;
+ int32_t rc = 0;
+
+ /* Get the key fields list and build the key. */
+ kflds = ulp_mapper_key_fields_get(parms, tbl, &num_kflds);
+ if (!kflds || !num_kflds) {
+ BNXT_TF_DBG(ERR, "Failed to get key fields\n");
+ return -EINVAL;
+ }
+
+ if (!ulp_blob_init(&key, tbl->key_bit_size,
+ parms->device_params->key_byte_order)) {
+ BNXT_TF_DBG(ERR, "Failed to alloc blob\n");
+ return -EINVAL;
+ }
+ for (i = 0; i < num_kflds; i++) {
+ /* Setup the key */
+ rc = ulp_mapper_field_opc_process(parms, tbl->direction,
+ &kflds[i].field_info_spec,
+ &key, 1, "Gen Tbl Key");
+ if (rc) {
+ BNXT_TF_DBG(ERR,
+ "Failed to create key for Gen tbl rc=%d\n",
+ rc);
+ return -EINVAL;
+ }
+ }
+
+ /* Calculate the table index for the generic table*/
+ tbl_idx = ulp_mapper_gen_tbl_idx_calculate(tbl->resource_sub_type,
+ tbl->direction);
+ if (tbl_idx < 0) {
+ BNXT_TF_DBG(ERR, "Invalid table index %x:%x\n",
+ tbl->resource_sub_type, tbl->direction);
+ return -EINVAL;
+ }
+
+ /* The_key is a byte array convert it to a search index */
+ cache_key = ulp_blob_data_get(&key, &tmplen);
+#ifdef RTE_LIBRTE_BNXT_TRUFLOW_DEBUG
+#ifdef RTE_LIBRTE_BNXT_TRUFLOW_DEBUG_MAPPER
+ ulp_mapper_gen_tbl_dump(tbl->resource_sub_type, tbl->direction, &key);
+#endif
+#endif
+ /* get the generic table */
+ gen_tbl_list = &parms->mapper_data->gen_tbl_list[tbl_idx];
+
+ /* Check if generic hash table */
+ if (gen_tbl_list->hash_tbl) {
+ if (tbl->gen_tbl_lkup_type !=
+ BNXT_ULP_GENERIC_TBL_LKUP_TYPE_HASH) {
+ BNXT_TF_DBG(ERR, "%s: Invalid template lkup type\n",
+ gen_tbl_list->gen_tbl_name);
+ return -EINVAL;
+ }
+ hash_entry.key_data = cache_key;
+ hash_entry.key_length = ULP_BITS_2_BYTE(tmplen);
+ rc = ulp_gen_hash_tbl_list_key_search(gen_tbl_list->hash_tbl,
+ &hash_entry);
+ if (rc) {
+ BNXT_TF_DBG(ERR, "%s: hash tbl search failed\n",
+ gen_tbl_list->gen_tbl_name);
+ return rc;
+ }
+ if (hash_entry.search_flag == ULP_GEN_HASH_SEARCH_FOUND) {
+ key_index = hash_entry.key_idx;
+ /* Get the generic table entry */
+ if (ulp_mapper_gen_tbl_entry_get(gen_tbl_list,
+ key_index,
+ &gen_tbl_ent))
+ return -EINVAL;
+ /* store the hash index in the fdb */
+ key_index = hash_entry.hash_index;
+ }
+ } else {
+ /* convert key to index directly */
+ if (ULP_BITS_2_BYTE(tmplen) > (int32_t)sizeof(key_index)) {
+ BNXT_TF_DBG(ERR, "%s: keysize is bigger then 4 bytes\n",
+ gen_tbl_list->gen_tbl_name);
+ return -EINVAL;
+ }
+ memcpy(&key_index, cache_key, ULP_BITS_2_BYTE(tmplen));
+ /* Get the generic table entry */
+ if (ulp_mapper_gen_tbl_entry_get(gen_tbl_list, key_index,
+ &gen_tbl_ent))
+ return -EINVAL;
+ }
+ switch (tbl->tbl_opcode) {
+ case BNXT_ULP_GENERIC_TBL_OPC_READ:
+ if (gen_tbl_list->hash_tbl) {
+ if (hash_entry.search_flag != ULP_GEN_HASH_SEARCH_FOUND)
+ break; /* nothing to be done , no entry */
+ }
+
+ /* check the reference count */
+ if (ULP_GEN_TBL_REF_CNT(&gen_tbl_ent)) {
+ g = &gen_tbl_ent;
+ /* Scan ident list and create the result blob*/
+ rc = ulp_mapper_tbl_ident_scan_ext(parms, tbl,
+ g->byte_data,
+ g->byte_data_size,
+ g->byte_order);
+ if (rc) {
+ BNXT_TF_DBG(ERR,
+ "Failed to scan ident list\n");
+ return -EINVAL;
+ }
+ if (tbl->fdb_opcode != BNXT_ULP_FDB_OPC_NOP) {
+ /* increment the reference count */
+ ULP_GEN_TBL_REF_CNT_INC(&gen_tbl_ent);
+ }
+
+ /* it is a hit */
+ gen_tbl_miss = 0;
+ fdb_write = 1;
+ }
+ break;
+ case BNXT_ULP_GENERIC_TBL_OPC_WRITE:
+ if (gen_tbl_list->hash_tbl) {
+ rc = ulp_mapper_gen_tbl_hash_entry_add(gen_tbl_list,
+ &hash_entry,
+ &gen_tbl_ent);
+ if (rc)
+ return rc;
+ /* store the hash index in the fdb */
+ key_index = hash_entry.hash_index;
+ }
+ /* check the reference count */
+ if (ULP_GEN_TBL_REF_CNT(&gen_tbl_ent)) {
+ /* a hit then error */
+ BNXT_TF_DBG(ERR, "generic entry already present\n");
+ return -EINVAL; /* success */
+ }
+
+ /* Initialize the blob data */
+ if (!ulp_blob_init(&data, tbl->result_bit_size,
+ gen_tbl_ent.byte_order)) {
+ BNXT_TF_DBG(ERR, "Failed initial index table blob\n");
+ return -EINVAL;
+ }
+
+ /* Get the result fields list */
+ rc = ulp_mapper_tbl_result_build(parms, tbl, &data,
+ "Gen tbl Result");
+ if (rc) {
+ BNXT_TF_DBG(ERR, "Failed to build the result blob\n");
+ return rc;
+ }
+ byte_data = ulp_blob_data_get(&data, &tmplen);
+ rc = ulp_mapper_gen_tbl_entry_data_set(&gen_tbl_ent,
+ tmplen, byte_data,
+ ULP_BITS_2_BYTE(tmplen));
+ if (rc) {
+ BNXT_TF_DBG(ERR, "Failed to write generic table\n");
+ return -EINVAL;
+ }
+
+ /* increment the reference count */
+ ULP_GEN_TBL_REF_CNT_INC(&gen_tbl_ent);
+ fdb_write = 1;
+ parms->shared_hndl = (uint64_t)tbl_idx << 32 | key_index;
+ break;
+ default:
+ BNXT_TF_DBG(ERR, "Invalid table opcode %x\n", tbl->tbl_opcode);
+ return -EINVAL;
+ }
+
+ /* Set the generic entry hit */
+ rc = ulp_regfile_write(parms->regfile,
+ BNXT_ULP_RF_IDX_GENERIC_TBL_MISS,
+ tfp_cpu_to_be_64(gen_tbl_miss));
+ if (rc) {
+ BNXT_TF_DBG(ERR, "Write regfile[%d] failed\n",
+ BNXT_ULP_RF_IDX_GENERIC_TBL_MISS);
+ return -EIO;
+ }
+
+ /* add the entry to the flow database */
+ if (fdb_write) {
+ memset(&fid_parms, 0, sizeof(fid_parms));
+ fid_parms.direction = tbl->direction;
+ fid_parms.resource_func = tbl->resource_func;
+ fid_parms.resource_sub_type = tbl->resource_sub_type;
+ fid_parms.resource_hndl = key_index;
+ fid_parms.critical_resource = tbl->critical_resource;
+ ulp_flow_db_shared_session_set(&fid_parms, tbl->shared_session);
+
+ rc = ulp_mapper_fdb_opc_process(parms, tbl, &fid_parms);
+ if (rc)
+ BNXT_TF_DBG(ERR, "Fail to add gen ent flowdb %d\n", rc);
+ }
+ return rc;
+}
+
+static int32_t
+ulp_mapper_ctrl_tbl_process(struct bnxt_ulp_mapper_parms *parms,
+ struct bnxt_ulp_mapper_tbl_info *tbl)
+{
+ int32_t rc = 0;
+
+ /* process the fdb opcode for alloc push */
+ if (tbl->fdb_opcode == BNXT_ULP_FDB_OPC_ALLOC_RID_REGFILE) {
+ rc = ulp_mapper_fdb_opc_alloc_rid(parms, tbl);
+ if (rc) {
+ BNXT_TF_DBG(ERR, "Failed to do fdb alloc\n");
+ return rc;
+ }
+ }
+ return rc;
+}
+
+static int32_t
+ulp_mapper_glb_resource_info_init(struct bnxt_ulp_context *ulp_ctx,
+ struct bnxt_ulp_mapper_data *mapper_data)
+{
+ struct bnxt_ulp_glb_resource_info *glb_res;
+ uint32_t num_glb_res_ids, idx, dev_id;
+ uint8_t app_id;
+ int32_t rc = 0;
+
+ glb_res = ulp_mapper_glb_resource_info_list_get(&num_glb_res_ids);
+ if (!glb_res || !num_glb_res_ids) {
+ BNXT_TF_DBG(ERR, "Invalid Arguments\n");
+ return -EINVAL;
+ }
+
+ rc = bnxt_ulp_cntxt_dev_id_get(ulp_ctx, &dev_id);
+ if (rc) {
+ BNXT_TF_DBG(ERR, "Failed to get device id for glb init (%d)\n",
+ rc);
+ return rc;
+ }
+
+ rc = bnxt_ulp_cntxt_app_id_get(ulp_ctx, &app_id);
+ if (rc) {
+ BNXT_TF_DBG(ERR, "Failed to get app id for glb init (%d)\n",
+ rc);
+ return rc;
+ }
+
+ /* Iterate the global resources and process each one */
+ for (idx = 0; idx < num_glb_res_ids; idx++) {
+ if (dev_id != glb_res[idx].device_id ||
+ glb_res[idx].app_id != app_id)
+ continue;
+ switch (glb_res[idx].resource_func) {
+ case BNXT_ULP_RESOURCE_FUNC_IDENTIFIER:
+ rc = ulp_mapper_resource_ident_allocate(ulp_ctx,
+ mapper_data,
+ &glb_res[idx]);
+ break;
+ case BNXT_ULP_RESOURCE_FUNC_INDEX_TABLE:
+ rc = ulp_mapper_resource_index_tbl_alloc(ulp_ctx,
+ mapper_data,
+ &glb_res[idx]);
+ break;
+ default:
+ BNXT_TF_DBG(ERR, "Global resource %x not supported\n",
+ glb_res[idx].resource_func);
+ rc = -EINVAL;
+ break;
+ }
+ if (rc)
+ return rc;
+ }
+ return rc;
+}
+
+/*
+ * Iterate over the shared resources assigned during tf_open_session and store
+ * them in the global regfile with the shared flag.
+ */
+static int32_t
+ulp_mapper_app_glb_resource_info_init(struct bnxt_ulp_context *ulp_ctx,
+ struct bnxt_ulp_mapper_data *mapper_data)
+{
+ struct tf_get_shared_tbl_increment_parms iparms;
+ struct bnxt_ulp_glb_resource_info *glb_res;
+ struct tf_get_session_info_parms sparms;
+ uint32_t num_entries, i, dev_id, res;
+ struct tf_resource_info *res_info;
+ uint32_t addend;
+ uint64_t regval;
+ enum tf_dir dir;
+ int32_t rc = 0;
+ struct tf *tfp;
+ uint8_t app_id;
+
+ memset(&sparms, 0, sizeof(sparms));
+ glb_res = bnxt_ulp_app_glb_resource_info_list_get(&num_entries);
+ if (!glb_res || !num_entries) {
+ BNXT_TF_DBG(ERR, "Invalid Arguments\n");
+ return -EINVAL;
+ }
+ tfp = bnxt_ulp_cntxt_shared_tfp_get(ulp_ctx);
+ if (!tfp) {
+ BNXT_TF_DBG(ERR, "Failed to get tfp for app global init");
+ return -EINVAL;
+ }
+ /*
+ * Retrieve the resources that were assigned during the shared session
+ * creation.
+ */
+ rc = tf_get_session_info(tfp, &sparms);
+ if (rc) {
+ BNXT_TF_DBG(ERR, "Failed to get session info (%d)\n", rc);
+ return rc;
+ }
+
+ rc = bnxt_ulp_cntxt_app_id_get(ulp_ctx, &app_id);
+ if (rc) {
+ BNXT_TF_DBG(ERR, "Failed to get the app id in glb init (%d).\n",
+ rc);
+ return rc;
+ }
+
+ rc = bnxt_ulp_cntxt_dev_id_get(ulp_ctx, &dev_id);
+ if (rc) {
+ BNXT_TF_DBG(ERR, "Failed to get dev id for app glb init (%d)\n",
+ rc);
+ return rc;
+ }
+
+ /* Store all the app global resources */
+ for (i = 0; i < num_entries; i++) {
+ if (dev_id != glb_res[i].device_id ||
+ app_id != glb_res[i].app_id)
+ continue;
+ dir = glb_res[i].direction;
+ res = glb_res[i].resource_type;
+ addend = 1;
+
+ switch (glb_res[i].resource_func) {
+ case BNXT_ULP_RESOURCE_FUNC_IDENTIFIER:
+ res_info = &sparms.session_info.ident[dir].info[res];
+ break;
+ case BNXT_ULP_RESOURCE_FUNC_INDEX_TABLE:
+ /*
+ * Tables may have various strides for the allocations.
+ * Need to account.
+ */
+ memset(&iparms, 0, sizeof(iparms));
+ iparms.dir = dir;
+ iparms.type = res;
+ rc = tf_get_shared_tbl_increment(tfp, &iparms);
+ if (rc) {
+ BNXT_TF_DBG(ERR,
+ "Failed to get addend for %s[%s] rc=(%d)\n",
+ tf_tbl_type_2_str(res),
+ tf_dir_2_str(dir), rc);
+ return rc;
+ }
+ addend = iparms.increment_cnt;
+ res_info = &sparms.session_info.tbl[dir].info[res];
+ break;
+ case BNXT_ULP_RESOURCE_FUNC_TCAM_TABLE:
+ res_info = &sparms.session_info.tcam[dir].info[res];
+ break;
+ case BNXT_ULP_RESOURCE_FUNC_EM_TABLE:
+ res_info = &sparms.session_info.em[dir].info[res];
+ break;
+ default:
+ BNXT_TF_DBG(ERR, "Unknown resource func (0x%x)\n",
+ glb_res[i].resource_func);
+ continue;
+ }
+ regval = tfp_cpu_to_be_64((uint64_t)res_info->start);
+ res_info->start += addend;
+ /*
+ * All resources written to the global regfile are shared for
+ * this function.
+ */
+ rc = ulp_mapper_glb_resource_write(mapper_data, &glb_res[i],
+ regval, true);
+ if (rc)
+ return rc;
+ }
+
+ return rc;
+}
+
+/*
+ * Common conditional opcode process routine that is used for both the template
+ * rejection and table conditional execution.
+ */
+static int32_t
+ulp_mapper_cond_opc_process(struct bnxt_ulp_mapper_parms *parms,
+ enum bnxt_ulp_cond_opc opc,
+ uint32_t operand,
+ int32_t *res)
+{
+ enum bnxt_ulp_flow_mem_type mtype = BNXT_ULP_FLOW_MEM_TYPE_INT;
+ int32_t rc = 0;
+ uint8_t bit;
+ uint64_t regval;
+
+ switch (opc) {
+ case BNXT_ULP_COND_OPC_CF_IS_SET:
+ if (operand < BNXT_ULP_CF_IDX_LAST) {
+ *res = ULP_COMP_FLD_IDX_RD(parms, operand);
+ } else {
+ BNXT_TF_DBG(ERR, "comp field out of bounds %d\n",
+ operand);
+ rc = -EINVAL;
+ }
+ break;
+ case BNXT_ULP_COND_OPC_CF_NOT_SET:
+ if (operand < BNXT_ULP_CF_IDX_LAST) {
+ *res = !ULP_COMP_FLD_IDX_RD(parms, operand);
+ } else {
+ BNXT_TF_DBG(ERR, "comp field out of bounds %d\n",
+ operand);
+ rc = -EINVAL;
+ }
+ break;
+ case BNXT_ULP_COND_OPC_ACT_BIT_IS_SET:
+ if (operand < BNXT_ULP_ACT_BIT_LAST) {
+ *res = ULP_BITMAP_ISSET(parms->act_bitmap->bits,
+ operand);
+ } else {
+ BNXT_TF_DBG(ERR, "action bit out of bounds %d\n",
+ operand);
+ rc = -EINVAL;
+ }
+ break;
+ case BNXT_ULP_COND_OPC_ACT_BIT_NOT_SET:
+ if (operand < BNXT_ULP_ACT_BIT_LAST) {
+ *res = !ULP_BITMAP_ISSET(parms->act_bitmap->bits,
+ operand);
+ } else {
+ BNXT_TF_DBG(ERR, "action bit out of bounds %d\n",
+ operand);
+ rc = -EINVAL;
+ }
+ break;
+ case BNXT_ULP_COND_OPC_HDR_BIT_IS_SET:
+ if (operand < BNXT_ULP_HDR_BIT_LAST) {
+ *res = ULP_BITMAP_ISSET(parms->hdr_bitmap->bits,
+ operand);
+ } else {
+ BNXT_TF_DBG(ERR, "header bit out of bounds %d\n",
+ operand);
+ rc = -EINVAL;
+ }
+ break;
+ case BNXT_ULP_COND_OPC_HDR_BIT_NOT_SET:
+ if (operand < BNXT_ULP_HDR_BIT_LAST) {
+ *res = !ULP_BITMAP_ISSET(parms->hdr_bitmap->bits,
+ operand);
+ } else {
+ BNXT_TF_DBG(ERR, "header bit out of bounds %d\n",
+ operand);
+ rc = -EINVAL;
+ }
+ break;
+ case BNXT_ULP_COND_OPC_FIELD_BIT_IS_SET:
+ rc = ulp_mapper_glb_field_tbl_get(parms, operand, &bit);
+ if (rc) {
+ BNXT_TF_DBG(ERR, "invalid ulp_glb_field_tbl idx %d\n",
+ operand);
+ return -EINVAL;
+ }
+ *res = ULP_INDEX_BITMAP_GET(parms->fld_bitmap->bits, bit);
+ break;
+ case BNXT_ULP_COND_OPC_FIELD_BIT_NOT_SET:
+ rc = ulp_mapper_glb_field_tbl_get(parms, operand, &bit);
+ if (rc) {
+ BNXT_TF_DBG(ERR, "invalid ulp_glb_field_tbl idx %d\n",
+ operand);
+ return -EINVAL;
+ }
+ *res = !ULP_INDEX_BITMAP_GET(parms->fld_bitmap->bits, bit);
+ break;
+ case BNXT_ULP_COND_OPC_RF_IS_SET:
+ if (!ulp_regfile_read(parms->regfile, operand, ®val)) {
+ BNXT_TF_DBG(ERR, "regfile[%d] read oob\n", operand);
+ return -EINVAL;
+ }
+ *res = regval != 0;
+ break;
+ case BNXT_ULP_COND_OPC_RF_NOT_SET:
+ if (!ulp_regfile_read(parms->regfile, operand, ®val)) {
+ BNXT_TF_DBG(ERR, "regfile[%d] read oob\n", operand);
+ return -EINVAL;
+ }
+ *res = regval == 0;
+ break;
+ case BNXT_ULP_COND_OPC_FLOW_PAT_MATCH:
+ *res = parms->flow_pattern_id == operand;
+ break;
+ case BNXT_ULP_COND_OPC_ACT_PAT_MATCH:
+ *res = parms->act_pattern_id == operand;
+ break;
+ case BNXT_ULP_COND_OPC_EXT_MEM_IS_SET:
+ if (bnxt_ulp_cntxt_mem_type_get(parms->ulp_ctx, &mtype)) {
+ BNXT_TF_DBG(ERR, "Failed to get the mem type\n");
+ return -EINVAL;
+ }
+ *res = (mtype == BNXT_ULP_FLOW_MEM_TYPE_INT) ? 0 : 1;
+ break;
+ case BNXT_ULP_COND_OPC_EXT_MEM_NOT_SET:
+ if (bnxt_ulp_cntxt_mem_type_get(parms->ulp_ctx, &mtype)) {
+ BNXT_TF_DBG(ERR, "Failed to get the mem type\n");
+ return -EINVAL;
+ }
+ *res = (mtype == BNXT_ULP_FLOW_MEM_TYPE_INT) ? 1 : 0;
+ break;
+ case BNXT_ULP_COND_OPC_ENC_HDR_BIT_IS_SET:
+ if (operand < BNXT_ULP_HDR_BIT_LAST) {
+ *res = ULP_BITMAP_ISSET(parms->enc_hdr_bitmap->bits,
+ operand);
+ } else {
+ BNXT_TF_DBG(ERR, "header bit out of bounds %d\n",
+ operand);
+ rc = -EINVAL;
+ }
+ break;
+ case BNXT_ULP_COND_OPC_ENC_HDR_BIT_NOT_SET:
+ if (operand < BNXT_ULP_HDR_BIT_LAST) {
+ *res = !ULP_BITMAP_ISSET(parms->enc_hdr_bitmap->bits,
+ operand);
+ } else {
+ BNXT_TF_DBG(ERR, "header bit out of bounds %d\n",
+ operand);
+ rc = -EINVAL;
+ }
+ break;
+ default:
+ BNXT_TF_DBG(ERR, "Invalid conditional opcode %d\n", opc);
+ rc = -EINVAL;
+ break;
+ }
+ return (rc);
+}
+
+static int32_t
+ulp_mapper_func_opr_compute(struct bnxt_ulp_mapper_parms *parms,
+ enum tf_dir dir,
+ enum bnxt_ulp_func_src func_src,
+ uint16_t func_opr,
+ uint64_t *result)