+ 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;