+/*
+ * Process the flow database opcode alloc action.
+ * returns 0 on success
+ */
+static int32_t
+ulp_mapper_fdb_opc_alloc_rid(struct bnxt_ulp_mapper_parms *parms,
+ struct bnxt_ulp_mapper_tbl_info *tbl)
+{
+ uint32_t rid = 0;
+ uint64_t val64;
+ int32_t rc = 0;
+
+ /* allocate a new fid */
+ rc = ulp_flow_db_fid_alloc(parms->ulp_ctx,
+ BNXT_ULP_FDB_TYPE_RID,
+ 0, &rid);
+ if (rc) {
+ BNXT_TF_DBG(ERR,
+ "Unable to allocate flow table entry\n");
+ return -EINVAL;
+ }
+ /* Store the allocated fid in regfile*/
+ val64 = rid;
+ rc = ulp_regfile_write(parms->regfile, tbl->fdb_operand,
+ tfp_cpu_to_be_64(val64));
+ if (rc) {
+ BNXT_TF_DBG(ERR, "Write regfile[%d] failed\n",
+ tbl->fdb_operand);
+ ulp_flow_db_fid_free(parms->ulp_ctx,
+ BNXT_ULP_FDB_TYPE_RID, rid);
+ return -EINVAL;
+ }
+ return 0;
+}
+
+/*
+ * Process the flow database opcode action.
+ * returns 0 on success.
+ */
+static int32_t
+ulp_mapper_fdb_opc_process(struct bnxt_ulp_mapper_parms *parms,
+ struct bnxt_ulp_mapper_tbl_info *tbl,
+ struct ulp_flow_db_res_params *fid_parms)
+{
+ uint32_t push_fid;
+ uint64_t val64;
+ enum bnxt_ulp_fdb_type flow_type;
+ int32_t rc = 0;
+
+ switch (tbl->fdb_opcode) {
+ case BNXT_ULP_FDB_OPC_PUSH_FID:
+ push_fid = parms->fid;
+ flow_type = parms->flow_type;
+ break;
+ case BNXT_ULP_FDB_OPC_PUSH_RID_REGFILE:
+ /* get the fid from the regfile */
+ rc = ulp_regfile_read(parms->regfile, tbl->fdb_operand,
+ &val64);
+ if (!rc) {
+ BNXT_TF_DBG(ERR, "regfile[%d] read oob\n",
+ tbl->fdb_operand);
+ return -EINVAL;
+ }
+ /* Use the extracted fid to update the flow resource */
+ push_fid = (uint32_t)tfp_be_to_cpu_64(val64);
+ flow_type = BNXT_ULP_FDB_TYPE_RID;
+ break;
+ default:
+ return rc; /* Nothing to be done */
+ }
+
+ /* Add the resource to the flow database */
+ rc = ulp_flow_db_resource_add(parms->ulp_ctx, flow_type,
+ push_fid, fid_parms);
+ if (rc)
+ BNXT_TF_DBG(ERR, "Failed to add res to flow %x rc = %d\n",
+ push_fid, rc);
+ return rc;
+}
+
+/*
+ * Process the flow database opcode action.
+ * returns 0 on success.
+ */
+static int32_t
+ulp_mapper_priority_opc_process(struct bnxt_ulp_mapper_parms *parms,
+ struct bnxt_ulp_mapper_tbl_info *tbl,
+ uint32_t *priority)
+{
+ int32_t rc = 0;
+
+ switch (tbl->pri_opcode) {
+ case BNXT_ULP_PRI_OPC_NOT_USED:
+ *priority = 0;
+ break;
+ case BNXT_ULP_PRI_OPC_CONST:
+ *priority = tbl->pri_operand;
+ break;
+ case BNXT_ULP_PRI_OPC_APP_PRI:
+ *priority = parms->app_priority;
+ break;
+ default:
+ BNXT_TF_DBG(ERR, "Priority opcode not supported %d\n",
+ tbl->pri_opcode);
+ rc = -EINVAL;
+ break;
+ }
+ return rc;
+}
+
+/*
+ * Process the identifier list in the given table.
+ * Extract the ident from the table entry and
+ * write it to the reg file.
+ * returns 0 on success.
+ */
+static int32_t
+ulp_mapper_tbl_ident_scan_ext(struct bnxt_ulp_mapper_parms *parms,
+ struct bnxt_ulp_mapper_tbl_info *tbl,
+ uint8_t *byte_data,
+ uint32_t byte_data_size,
+ enum bnxt_ulp_byte_order byte_order)
+{
+ struct bnxt_ulp_mapper_ident_info *idents;
+ uint32_t i, num_idents = 0;
+ uint64_t val64;
+
+ /* validate the null arguments */
+ if (!byte_data) {
+ BNXT_TF_DBG(ERR, "invalid argument\n");
+ return -EINVAL;
+ }
+
+ /* Get the ident list and process each one */
+ idents = ulp_mapper_ident_fields_get(parms, tbl, &num_idents);
+
+ for (i = 0; i < num_idents; i++) {
+ /* check the size of the buffer for validation */
+ if ((idents[i].ident_bit_pos + idents[i].ident_bit_size) >
+ ULP_BYTE_2_BITS(byte_data_size) ||
+ idents[i].ident_bit_size > ULP_BYTE_2_BITS(sizeof(val64))) {
+ BNXT_TF_DBG(ERR, "invalid offset or length %x:%x:%x\n",
+ idents[i].ident_bit_pos,
+ idents[i].ident_bit_size,
+ byte_data_size);
+ return -EINVAL;
+ }
+ val64 = 0;
+ if (byte_order == BNXT_ULP_BYTE_ORDER_LE)
+ ulp_bs_pull_lsb(byte_data, (uint8_t *)&val64,
+ sizeof(val64),
+ idents[i].ident_bit_pos,
+ idents[i].ident_bit_size);
+ else
+ ulp_bs_pull_msb(byte_data, (uint8_t *)&val64,
+ idents[i].ident_bit_pos,
+ idents[i].ident_bit_size);
+
+ /* Write it to the regfile, val64 is already in big-endian*/
+ if (ulp_regfile_write(parms->regfile,
+ idents[i].regfile_idx, val64)) {
+ BNXT_TF_DBG(ERR, "Regfile[%d] write failed.\n",
+ idents[i].regfile_idx);
+ return -EINVAL;
+ }
+ }
+ return 0;
+}
+