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