xref: /dpdk/drivers/net/mlx5/hws/mlx5dr_debug.c (revision da7e701151ea8b742d4c38ace3e4fefd1b4507fc)
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright (c) 2022 NVIDIA Corporation & Affiliates
3  */
4 
5 #include "mlx5dr_internal.h"
6 
7 const char *mlx5dr_debug_action_type_str[] = {
8 	[MLX5DR_ACTION_TYP_LAST] = "LAST",
9 	[MLX5DR_ACTION_TYP_REFORMAT_TNL_L2_TO_L2] = "TNL_L2_TO_L2",
10 	[MLX5DR_ACTION_TYP_REFORMAT_L2_TO_TNL_L2] = "L2_TO_TNL_L2",
11 	[MLX5DR_ACTION_TYP_REFORMAT_TNL_L3_TO_L2] = "TNL_L3_TO_L2",
12 	[MLX5DR_ACTION_TYP_REFORMAT_L2_TO_TNL_L3] = "L2_TO_TNL_L3",
13 	[MLX5DR_ACTION_TYP_DROP] = "DROP",
14 	[MLX5DR_ACTION_TYP_TIR] = "TIR",
15 	[MLX5DR_ACTION_TYP_TBL] = "TBL",
16 	[MLX5DR_ACTION_TYP_CTR] = "CTR",
17 	[MLX5DR_ACTION_TYP_TAG] = "TAG",
18 	[MLX5DR_ACTION_TYP_MODIFY_HDR] = "MODIFY_HDR",
19 	[MLX5DR_ACTION_TYP_VPORT] = "VPORT",
20 	[MLX5DR_ACTION_TYP_MISS] = "DEFAULT_MISS",
21 	[MLX5DR_ACTION_TYP_POP_VLAN] = "POP_VLAN",
22 	[MLX5DR_ACTION_TYP_PUSH_VLAN] = "PUSH_VLAN",
23 	[MLX5DR_ACTION_TYP_ASO_METER] = "ASO_METER",
24 	[MLX5DR_ACTION_TYP_ASO_CT] = "ASO_CT",
25 	[MLX5DR_ACTION_TYP_DEST_ROOT] = "DEST_ROOT",
26 	[MLX5DR_ACTION_TYP_DEST_ARRAY] = "DEST_ARRAY",
27 	[MLX5DR_ACTION_TYP_INSERT_HEADER] = "INSERT_HEADER",
28 	[MLX5DR_ACTION_TYP_REMOVE_HEADER] = "REMOVE_HEADER",
29 	[MLX5DR_ACTION_TYP_POP_IPV6_ROUTE_EXT] = "POP_IPV6_ROUTE_EXT",
30 	[MLX5DR_ACTION_TYP_PUSH_IPV6_ROUTE_EXT] = "PUSH_IPV6_ROUTE_EXT",
31 };
32 
33 static_assert(ARRAY_SIZE(mlx5dr_debug_action_type_str) == MLX5DR_ACTION_TYP_MAX,
34 	      "Missing mlx5dr_debug_action_type_str");
35 
36 const char *mlx5dr_debug_action_type_to_str(enum mlx5dr_action_type action_type)
37 {
38 	return mlx5dr_debug_action_type_str[action_type];
39 }
40 
41 static int
42 mlx5dr_debug_dump_matcher_template_definer(FILE *f,
43 					   void *parent_obj,
44 					   struct mlx5dr_definer *definer,
45 					   enum mlx5dr_debug_res_type type)
46 {
47 	int i, ret;
48 
49 	if (!definer)
50 		return 0;
51 
52 	ret = fprintf(f, "%d,0x%" PRIx64 ",0x%" PRIx64 ",%d,%d,",
53 		      type,
54 		      (uint64_t)(uintptr_t)definer,
55 		      (uint64_t)(uintptr_t)parent_obj,
56 		      definer->obj->id,
57 		      definer->type);
58 	if (ret < 0) {
59 		rte_errno = EINVAL;
60 		return rte_errno;
61 	}
62 
63 	for (i = 0; i < DW_SELECTORS; i++) {
64 		ret = fprintf(f, "0x%x%s", definer->dw_selector[i],
65 			      (i == DW_SELECTORS - 1) ? "," : "-");
66 		if (ret < 0) {
67 			rte_errno = EINVAL;
68 			return rte_errno;
69 		}
70 	}
71 
72 	for (i = 0; i < BYTE_SELECTORS; i++) {
73 		ret = fprintf(f, "0x%x%s", definer->byte_selector[i],
74 			      (i == BYTE_SELECTORS - 1) ? "," : "-");
75 		if (ret < 0) {
76 			rte_errno = EINVAL;
77 			return rte_errno;
78 		}
79 	}
80 
81 	for (i = 0; i < MLX5DR_JUMBO_TAG_SZ; i++) {
82 		ret = fprintf(f, "%02x", definer->mask.jumbo[i]);
83 		if (ret < 0) {
84 			rte_errno = EINVAL;
85 			return rte_errno;
86 		}
87 	}
88 
89 	ret = fprintf(f, "\n");
90 	if (ret < 0) {
91 		rte_errno = EINVAL;
92 		return rte_errno;
93 	}
94 
95 	return 0;
96 }
97 
98 static int
99 mlx5dr_debug_dump_matcher_match_template(FILE *f, struct mlx5dr_matcher *matcher)
100 {
101 	bool is_root = matcher->tbl->level == MLX5DR_ROOT_LEVEL;
102 	enum mlx5dr_debug_res_type type;
103 	int i, ret;
104 
105 	for (i = 0; i < matcher->num_of_mt; i++) {
106 		struct mlx5dr_match_template *mt = &matcher->mt[i];
107 
108 		ret = fprintf(f, "%d,0x%" PRIx64 ",0x%" PRIx64 ",%d,%d,%d\n",
109 			      MLX5DR_DEBUG_RES_TYPE_MATCHER_MATCH_TEMPLATE,
110 			      (uint64_t)(uintptr_t)mt,
111 			      (uint64_t)(uintptr_t)matcher,
112 			      is_root ? 0 : mt->fc_sz,
113 			      mt->flags,
114 			      is_root ? 0 : mt->fcr_sz);
115 		if (ret < 0) {
116 			rte_errno = EINVAL;
117 			return rte_errno;
118 		}
119 
120 		type = MLX5DR_DEBUG_RES_TYPE_MATCHER_TEMPLATE_MATCH_DEFINER;
121 		ret = mlx5dr_debug_dump_matcher_template_definer(f, mt, mt->definer, type);
122 		if (ret)
123 			return ret;
124 
125 		type = MLX5DR_DEBUG_RES_TYPE_MATCHER_TEMPLATE_RANGE_DEFINER;
126 		ret = mlx5dr_debug_dump_matcher_template_definer(f, mt, mt->range_definer, type);
127 		if (ret)
128 			return ret;
129 	}
130 
131 	type = MLX5DR_DEBUG_RES_TYPE_MATCHER_TEMPLATE_HASH_DEFINER;
132 	ret = mlx5dr_debug_dump_matcher_template_definer(f, matcher, matcher->hash_definer, type);
133 	if (ret)
134 		return ret;
135 
136 	return 0;
137 }
138 
139 static int
140 mlx5dr_debug_dump_matcher_action_template(FILE *f, struct mlx5dr_matcher *matcher)
141 {
142 	bool is_root = matcher->tbl->level == MLX5DR_ROOT_LEVEL;
143 	enum mlx5dr_action_type action_type;
144 	int i, j, ret;
145 
146 	for (i = 0; i < matcher->num_of_at; i++) {
147 		struct mlx5dr_action_template *at = &matcher->at[i];
148 
149 		ret = fprintf(f, "%d,0x%" PRIx64 ",0x%" PRIx64 ",%d,%d,%d",
150 			      MLX5DR_DEBUG_RES_TYPE_MATCHER_ACTION_TEMPLATE,
151 			      (uint64_t)(uintptr_t)at,
152 			      (uint64_t)(uintptr_t)matcher,
153 			      at->only_term ? 0 : 1,
154 			      is_root ? 0 : at->num_of_action_stes,
155 			      at->num_actions);
156 		if (ret < 0) {
157 			rte_errno = EINVAL;
158 			return rte_errno;
159 		}
160 
161 		for (j = 0; j < at->num_actions; j++) {
162 			action_type = at->action_type_arr[j];
163 			ret = fprintf(f, ",%s", mlx5dr_debug_action_type_to_str(action_type));
164 			if (ret < 0) {
165 				rte_errno = EINVAL;
166 				return rte_errno;
167 			}
168 		}
169 
170 		fprintf(f, "\n");
171 	}
172 
173 	return 0;
174 }
175 
176 static int
177 mlx5dr_debug_dump_matcher_attr(FILE *f, struct mlx5dr_matcher *matcher)
178 {
179 	struct mlx5dr_matcher_attr *attr = &matcher->attr;
180 	int ret;
181 
182 	ret = fprintf(f, "%d,0x%" PRIx64 ",%d,%d,%d,%d,%d,%d,%d,%d\n",
183 		      MLX5DR_DEBUG_RES_TYPE_MATCHER_ATTR,
184 		      (uint64_t)(uintptr_t)matcher,
185 		      attr->priority,
186 		      attr->mode,
187 		      attr->table.sz_row_log,
188 		      attr->table.sz_col_log,
189 		      attr->optimize_using_rule_idx,
190 		      attr->optimize_flow_src,
191 		      attr->insert_mode,
192 		      attr->distribute_mode);
193 	if (ret < 0) {
194 		rte_errno = EINVAL;
195 		return rte_errno;
196 	}
197 
198 	return 0;
199 }
200 
201 static int mlx5dr_debug_dump_matcher(FILE *f, struct mlx5dr_matcher *matcher)
202 {
203 	bool is_shared = mlx5dr_context_shared_gvmi_used(matcher->tbl->ctx);
204 	bool is_root = matcher->tbl->level == MLX5DR_ROOT_LEVEL;
205 	enum mlx5dr_table_type tbl_type = matcher->tbl->type;
206 	struct mlx5dr_cmd_ft_query_attr ft_attr = {0};
207 	struct mlx5dr_devx_obj *ste_0, *ste_1 = NULL;
208 	struct mlx5dr_pool_chunk *ste;
209 	struct mlx5dr_pool *ste_pool;
210 	uint64_t icm_addr_0 = 0;
211 	uint64_t icm_addr_1 = 0;
212 	int ret;
213 
214 	ret = fprintf(f, "%d,0x%" PRIx64 ",0x%" PRIx64 ",%d,%d,0x%" PRIx64,
215 		      MLX5DR_DEBUG_RES_TYPE_MATCHER,
216 		      (uint64_t)(uintptr_t)matcher,
217 		      (uint64_t)(uintptr_t)matcher->tbl,
218 		      matcher->num_of_mt,
219 		      is_root ? 0 : matcher->end_ft->id,
220 		      matcher->col_matcher ? (uint64_t)(uintptr_t)matcher->col_matcher : 0);
221 	if (ret < 0)
222 		goto out_err;
223 
224 	ste = &matcher->match_ste.ste;
225 	ste_pool = matcher->match_ste.pool;
226 	if (ste_pool) {
227 		ste_0 = mlx5dr_pool_chunk_get_base_devx_obj(ste_pool, ste);
228 		if (tbl_type == MLX5DR_TABLE_TYPE_FDB)
229 			ste_1 = mlx5dr_pool_chunk_get_base_devx_obj_mirror(ste_pool, ste);
230 	} else {
231 		ste_0 = NULL;
232 		ste_1 = NULL;
233 	}
234 
235 	ret = fprintf(f, ",%d,%d,%d,%d",
236 		      matcher->match_ste.rtc_0 ? matcher->match_ste.rtc_0->id : 0,
237 		      ste_0 ? (int)ste_0->id : -1,
238 		      matcher->match_ste.rtc_1 ? matcher->match_ste.rtc_1->id : 0,
239 		      ste_1 ? (int)ste_1->id : -1);
240 	if (ret < 0)
241 		goto out_err;
242 
243 	ste = &matcher->action_ste.ste;
244 	ste_pool = matcher->action_ste.pool;
245 	if (ste_pool) {
246 		ste_0 = mlx5dr_pool_chunk_get_base_devx_obj(ste_pool, ste);
247 		if (tbl_type == MLX5DR_TABLE_TYPE_FDB)
248 			ste_1 = mlx5dr_pool_chunk_get_base_devx_obj_mirror(ste_pool, ste);
249 	} else {
250 		ste_0 = NULL;
251 		ste_1 = NULL;
252 	}
253 
254 	if (!is_root) {
255 		ft_attr.type = matcher->tbl->fw_ft_type;
256 		ret = mlx5dr_cmd_flow_table_query(matcher->end_ft,
257 						  &ft_attr,
258 						  &icm_addr_0,
259 						  &icm_addr_1);
260 		if (ret)
261 			return ret;
262 	}
263 
264 	ret = fprintf(f, ",%d,%d,%d,%d,%d,0x%" PRIx64 ",0x%" PRIx64 "\n",
265 		      matcher->action_ste.rtc_0 ? matcher->action_ste.rtc_0->id : 0,
266 		      ste_0 ? (int)ste_0->id : -1,
267 		      matcher->action_ste.rtc_1 ? matcher->action_ste.rtc_1->id : 0,
268 		      ste_1 ? (int)ste_1->id : -1,
269 		      is_shared && !is_root ?
270 		      matcher->match_ste.aliased_rtc_0->id : 0,
271 		      mlx5dr_debug_icm_to_idx(icm_addr_0),
272 		      mlx5dr_debug_icm_to_idx(icm_addr_1));
273 	if (ret < 0)
274 		goto out_err;
275 
276 	ret = mlx5dr_debug_dump_matcher_attr(f, matcher);
277 	if (ret)
278 		return ret;
279 
280 	ret = mlx5dr_debug_dump_matcher_match_template(f, matcher);
281 	if (ret)
282 		return ret;
283 
284 	ret = mlx5dr_debug_dump_matcher_action_template(f, matcher);
285 	if (ret)
286 		return ret;
287 
288 	return 0;
289 
290 out_err:
291 	rte_errno = EINVAL;
292 	return rte_errno;
293 }
294 
295 static int mlx5dr_debug_dump_table(FILE *f, struct mlx5dr_table *tbl)
296 {
297 	bool is_shared = mlx5dr_context_shared_gvmi_used(tbl->ctx);
298 	bool is_root = tbl->level == MLX5DR_ROOT_LEVEL;
299 	struct mlx5dr_cmd_ft_query_attr ft_attr = {0};
300 	struct mlx5dr_matcher *matcher;
301 	uint64_t local_icm_addr_0 = 0;
302 	uint64_t local_icm_addr_1 = 0;
303 	uint64_t icm_addr_0 = 0;
304 	uint64_t icm_addr_1 = 0;
305 	int ret;
306 
307 	ret = fprintf(f, "%d,0x%" PRIx64 ",0x%" PRIx64 ",%d,%d,%d,%d,%d",
308 		      MLX5DR_DEBUG_RES_TYPE_TABLE,
309 		      (uint64_t)(uintptr_t)tbl,
310 		      (uint64_t)(uintptr_t)tbl->ctx,
311 		      is_root ? 0 : tbl->ft->id,
312 		      tbl->type,
313 		      is_root ? 0 : tbl->fw_ft_type,
314 		      tbl->level,
315 		      is_shared && !is_root ? tbl->local_ft->id : 0);
316 	if (ret < 0)
317 		goto out_err;
318 
319 	if (!is_root) {
320 		ft_attr.type = tbl->fw_ft_type;
321 		ret = mlx5dr_cmd_flow_table_query(tbl->ft,
322 						  &ft_attr,
323 						  &icm_addr_0,
324 						  &icm_addr_1);
325 		if (ret)
326 			return ret;
327 
328 		if (is_shared) {
329 			ft_attr.type = tbl->fw_ft_type;
330 			ret = mlx5dr_cmd_flow_table_query(tbl->local_ft,
331 							  &ft_attr,
332 							  &local_icm_addr_0,
333 							  &local_icm_addr_1);
334 			if (ret)
335 				return ret;
336 		}
337 	}
338 
339 	ret = fprintf(f, ",0x%" PRIx64 ",0x%" PRIx64 ",0x%" PRIx64 ",0x%" PRIx64 ",0x%" PRIx64 "\n",
340 		      mlx5dr_debug_icm_to_idx(icm_addr_0),
341 		      mlx5dr_debug_icm_to_idx(icm_addr_1),
342 		      mlx5dr_debug_icm_to_idx(local_icm_addr_0),
343 		      mlx5dr_debug_icm_to_idx(local_icm_addr_1),
344 		      (uint64_t)(uintptr_t)tbl->default_miss.miss_tbl);
345 	if (ret < 0)
346 		goto out_err;
347 
348 	LIST_FOREACH(matcher, &tbl->head, next) {
349 		ret = mlx5dr_debug_dump_matcher(f, matcher);
350 		if (ret)
351 			return ret;
352 	}
353 
354 	return 0;
355 
356 out_err:
357 	rte_errno = EINVAL;
358 	return rte_errno;
359 }
360 
361 static int
362 mlx5dr_debug_dump_context_send_engine(FILE *f, struct mlx5dr_context *ctx)
363 {
364 	struct mlx5dr_send_engine *send_queue;
365 	int ret, i, j;
366 
367 	for (i = 0; i < (int)ctx->queues; i++) {
368 		send_queue = &ctx->send_queue[i];
369 		ret = fprintf(f, "%d,0x%" PRIx64 ",%d,%d,%d,%d,%d,%d,%d,%d,%d\n",
370 			      MLX5DR_DEBUG_RES_TYPE_CONTEXT_SEND_ENGINE,
371 			      (uint64_t)(uintptr_t)ctx,
372 			      i,
373 			      send_queue->used_entries,
374 			      send_queue->th_entries,
375 			      send_queue->rings,
376 			      send_queue->num_entries,
377 			      send_queue->err,
378 			      send_queue->completed.ci,
379 			      send_queue->completed.pi,
380 			      send_queue->completed.mask);
381 		if (ret < 0) {
382 			rte_errno = EINVAL;
383 			return rte_errno;
384 		}
385 
386 		for (j = 0; j < MLX5DR_NUM_SEND_RINGS; j++) {
387 			struct mlx5dr_send_ring *send_ring = &send_queue->send_ring[j];
388 			struct mlx5dr_send_ring_cq *cq = &send_ring->send_cq;
389 			struct mlx5dr_send_ring_sq *sq = &send_ring->send_sq;
390 
391 			ret = fprintf(f, "%d,0x%" PRIx64 ",%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d\n",
392 				      MLX5DR_DEBUG_RES_TYPE_CONTEXT_SEND_RING,
393 				      (uint64_t)(uintptr_t)ctx,
394 				      j,
395 				      i,
396 				      cq->cqn,
397 				      cq->cons_index,
398 				      cq->ncqe_mask,
399 				      cq->buf_sz,
400 				      cq->ncqe,
401 				      cq->cqe_log_sz,
402 				      cq->poll_wqe,
403 				      cq->cqe_sz,
404 				      sq->sqn,
405 				      sq->obj->id,
406 				      sq->cur_post,
407 				      sq->buf_mask);
408 			if (ret < 0) {
409 				rte_errno = EINVAL;
410 				return rte_errno;
411 			}
412 		}
413 	}
414 
415 	return 0;
416 }
417 
418 static int mlx5dr_debug_dump_context_caps(FILE *f, struct mlx5dr_context *ctx)
419 {
420 	struct mlx5dr_cmd_query_caps *caps = ctx->caps;
421 	int ret;
422 
423 	ret = fprintf(f, "%d,0x%" PRIx64 ",%s,%d,%d,%d,%d,",
424 		      MLX5DR_DEBUG_RES_TYPE_CONTEXT_CAPS,
425 		      (uint64_t)(uintptr_t)ctx,
426 		      caps->fw_ver,
427 		      caps->wqe_based_update,
428 		      caps->ste_format,
429 		      caps->ste_alloc_log_max,
430 		      caps->log_header_modify_argument_max_alloc);
431 	if (ret < 0) {
432 		rte_errno = EINVAL;
433 		return rte_errno;
434 	}
435 
436 	ret = fprintf(f, "%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d\n",
437 		      caps->flex_protocols,
438 		      caps->rtc_reparse_mode,
439 		      caps->rtc_index_mode,
440 		      caps->ste_alloc_log_gran,
441 		      caps->stc_alloc_log_max,
442 		      caps->stc_alloc_log_gran,
443 		      caps->rtc_log_depth_max,
444 		      caps->format_select_gtpu_dw_0,
445 		      caps->format_select_gtpu_dw_1,
446 		      caps->format_select_gtpu_dw_2,
447 		      caps->format_select_gtpu_ext_dw_0,
448 		      caps->nic_ft.max_level,
449 		      caps->nic_ft.reparse,
450 		      caps->fdb_ft.max_level,
451 		      caps->fdb_ft.reparse,
452 		      caps->log_header_modify_argument_granularity);
453 	if (ret < 0) {
454 		rte_errno = EINVAL;
455 		return rte_errno;
456 	}
457 
458 	return 0;
459 }
460 
461 static int mlx5dr_debug_dump_context_attr(FILE *f, struct mlx5dr_context *ctx)
462 {
463 	int ret;
464 
465 	ret = fprintf(f, "%u,0x%" PRIx64 ",%d,%zu,%d,%s,%d,%d\n",
466 		      MLX5DR_DEBUG_RES_TYPE_CONTEXT_ATTR,
467 		      (uint64_t)(uintptr_t)ctx,
468 		      ctx->pd_num,
469 		      ctx->queues,
470 		      ctx->send_queue->num_entries,
471 		      mlx5dr_context_shared_gvmi_used(ctx) ?
472 		      mlx5_glue->get_device_name(ctx->ibv_ctx->device) : "None",
473 		      ctx->caps->vhca_id,
474 		      mlx5dr_context_shared_gvmi_used(ctx) ?
475 		      ctx->caps->shared_vhca_id : 0xffff);
476 	if (ret < 0) {
477 		rte_errno = EINVAL;
478 		return rte_errno;
479 	}
480 
481 	return 0;
482 }
483 
484 static int mlx5dr_debug_dump_context_info(FILE *f, struct mlx5dr_context *ctx)
485 {
486 	int ret;
487 
488 	ret = fprintf(f, "%d,0x%" PRIx64 ",%d,%s,%s\n",
489 		      MLX5DR_DEBUG_RES_TYPE_CONTEXT,
490 		      (uint64_t)(uintptr_t)ctx,
491 		      ctx->flags & MLX5DR_CONTEXT_FLAG_HWS_SUPPORT,
492 		      mlx5_glue->get_device_name(mlx5dr_context_get_local_ibv(ctx)->device),
493 		      DEBUG_VERSION);
494 	if (ret < 0) {
495 		rte_errno = EINVAL;
496 		return rte_errno;
497 	}
498 
499 	ret = mlx5dr_debug_dump_context_attr(f, ctx);
500 	if (ret)
501 		return ret;
502 
503 	ret = mlx5dr_debug_dump_context_caps(f, ctx);
504 	if (ret)
505 		return ret;
506 
507 	return 0;
508 }
509 
510 static int
511 mlx5dr_debug_dump_context_stc_resource(FILE *f,
512 				       struct mlx5dr_context *ctx,
513 				       uint32_t tbl_type,
514 				       struct mlx5dr_pool_resource *resource)
515 {
516 	int ret;
517 
518 	ret = fprintf(f, "%d,0x%" PRIx64 ",%u,%u\n",
519 		      MLX5DR_DEBUG_RES_TYPE_CONTEXT_STC,
520 		      (uint64_t)(uintptr_t)ctx,
521 		      tbl_type,
522 		      resource->base_id);
523 	if (ret < 0) {
524 		rte_errno = EINVAL;
525 		return rte_errno;
526 	}
527 
528 	return 0;
529 }
530 
531 static int mlx5dr_debug_dump_context_stc(FILE *f, struct mlx5dr_context *ctx)
532 {
533 	struct mlx5dr_pool *stc_pool;
534 	int ret;
535 	int i;
536 
537 	for (i = 0; i < MLX5DR_TABLE_TYPE_MAX; i++) {
538 		stc_pool = ctx->stc_pool[i];
539 
540 		if (!stc_pool)
541 			continue;
542 
543 		if (stc_pool->resource[0] != NULL) {
544 			ret = mlx5dr_debug_dump_context_stc_resource(f, ctx, i,
545 								     stc_pool->resource[0]);
546 			if (ret)
547 				return ret;
548 		}
549 
550 		if (i == MLX5DR_TABLE_TYPE_FDB && stc_pool->mirror_resource[0] != NULL) {
551 			ret = mlx5dr_debug_dump_context_stc_resource(f, ctx, i,
552 								     stc_pool->mirror_resource[0]);
553 			if (ret)
554 				return ret;
555 		}
556 	}
557 
558 	return 0;
559 }
560 
561 static int mlx5dr_debug_dump_context(FILE *f, struct mlx5dr_context *ctx)
562 {
563 	struct mlx5dr_table *tbl;
564 	int ret;
565 
566 	ret = mlx5dr_debug_dump_context_info(f, ctx);
567 	if (ret)
568 		return ret;
569 
570 	ret = mlx5dr_debug_dump_context_send_engine(f, ctx);
571 	if (ret)
572 		return ret;
573 
574 	ret = mlx5dr_debug_dump_context_stc(f, ctx);
575 	if (ret)
576 		return ret;
577 
578 	LIST_FOREACH(tbl, &ctx->head, next) {
579 		ret = mlx5dr_debug_dump_table(f, tbl);
580 		if (ret)
581 			return ret;
582 	}
583 
584 	return 0;
585 }
586 
587 int mlx5dr_debug_dump(struct mlx5dr_context *ctx, FILE *f)
588 {
589 	int ret;
590 
591 	if (!f || !ctx) {
592 		rte_errno = EINVAL;
593 		return -rte_errno;
594 	}
595 
596 	pthread_spin_lock(&ctx->ctrl_lock);
597 	ret = mlx5dr_debug_dump_context(f, ctx);
598 	pthread_spin_unlock(&ctx->ctrl_lock);
599 
600 	return -ret;
601 }
602