+
+int32_t
+ulp_mapper_init(struct bnxt_ulp_context *ulp_ctx)
+{
+ struct tf_alloc_identifier_parms iparms;
+ struct bnxt_ulp_mapper_data *data;
+ struct bnxt_ulp_def_ident_info *dflt_ids;
+ uint32_t i, num_dflt_ids, reg_idx;
+ uint64_t regval;
+ struct tf *tfp;
+ int32_t rc;
+
+ if (!ulp_ctx)
+ return -EINVAL;
+
+ tfp = bnxt_ulp_cntxt_tfp_get(ulp_ctx);
+ if (!tfp)
+ return -EINVAL;
+
+ data = rte_zmalloc("ulp_mapper_data",
+ sizeof(struct bnxt_ulp_mapper_data), 0);
+ if (!data) {
+ BNXT_TF_DBG(ERR, "Failed to allocate the mapper data\n");
+ return -ENOMEM;
+ }
+
+ if (bnxt_ulp_cntxt_ptr2_mapper_data_set(ulp_ctx, data)) {
+ BNXT_TF_DBG(ERR, "Failed to set mapper data in context\n");
+ /* Don't call deinit since the prof_func wasn't allocated. */
+ rte_free(data);
+ return -ENOMEM;
+ }
+
+ /* Allocate the default ids. */
+ dflt_ids = ulp_mapper_def_ident_info_list_get(&num_dflt_ids);
+ for (i = 0; i < num_dflt_ids; i++) {
+ iparms.ident_type = dflt_ids[i].ident_type;
+ iparms.dir = dflt_ids[i].direction;
+
+ rc = tf_alloc_identifier(tfp, &iparms);
+ if (rc) {
+ BNXT_TF_DBG(ERR, "Failed to alloc dflt "
+ "identifier [%s][%d]\n",
+ (iparms.dir == TF_DIR_RX) ? "RX" : "TX",
+ iparms.ident_type);
+ goto error;
+ }
+ reg_idx = dflt_ids[i].def_regfile_index;
+ /* All regfile entries are stored as 64bit big-endian values. */
+ regval = tfp_cpu_to_be_64((uint64_t)iparms.id);
+ if (ulp_mapper_def_regfile_write(data,
+ iparms.dir,
+ reg_idx,
+ regval)) {
+ BNXT_TF_DBG(ERR, "Failed to write to default "
+ "regfile.\n");
+ goto error;
+ }
+ }
+
+ return 0;
+error:
+ /* Ignore the return code in favor of returning the original error. */
+ ulp_mapper_deinit(ulp_ctx);
+ return rc;
+}
+
+void
+ulp_mapper_deinit(struct bnxt_ulp_context *ulp_ctx)
+{
+ struct tf_free_identifier_parms free_parms;
+ struct bnxt_ulp_def_ident_info *dflt_ids;
+ struct bnxt_ulp_mapper_data *data;
+ uint32_t i, num_dflt_ids, reg_idx;
+ enum tf_dir dir;
+ uint64_t regval;
+ struct tf *tfp;
+
+ if (!ulp_ctx) {
+ BNXT_TF_DBG(ERR,
+ "Failed to acquire ulp context, so data may "
+ "not be released.\n");
+ return;
+ }
+
+ data = (struct bnxt_ulp_mapper_data *)
+ bnxt_ulp_cntxt_ptr2_mapper_data_get(ulp_ctx);
+ if (!data) {
+ /* Go ahead and return since there is no allocated data. */
+ BNXT_TF_DBG(ERR, "No data appears to have been allocated.\n");
+ return;
+ }
+
+ tfp = bnxt_ulp_cntxt_tfp_get(ulp_ctx);
+ if (!tfp) {
+ BNXT_TF_DBG(ERR, "Failed to acquire tfp.\n");
+ /* Free the mapper data regardless of errors. */
+ goto free_mapper_data;
+ }
+
+ /* Free the default prof func ids per direction. */
+ dflt_ids = ulp_mapper_def_ident_info_list_get(&num_dflt_ids);
+ for (i = 0; i < num_dflt_ids; i++) {
+ reg_idx = dflt_ids[i].def_regfile_index;
+ dir = dflt_ids[i].direction;
+ free_parms.ident_type = dflt_ids[i].ident_type;
+ free_parms.dir = dir;
+ if (ulp_mapper_def_regfile_read(data, dir, reg_idx, ®val)) {
+ BNXT_TF_DBG(ERR, "Failed to read def regfile to free "
+ "identifier.\n");
+ continue;
+ }
+ /*
+ * All regfile entries are stored as 64bit big-endian. Need
+ * to convert the value to cpu before calling tf.
+ */
+ regval = tfp_be_to_cpu_64(regval);
+ free_parms.id = (uint16_t)regval;
+ /* Ignore errors and free the remaining identifiers. */
+ tf_free_identifier(tfp, &free_parms);
+ }
+
+free_mapper_data:
+ rte_free(data);
+ /* Reset the data pointer within the ulp_ctx. */
+ bnxt_ulp_cntxt_ptr2_mapper_data_set(ulp_ctx, NULL);
+}