xref: /dpdk/drivers/net/mlx5/hws/mlx5dr_debug.c (revision 89b5642d0d45c22c0ceab57efe3fab3b49ff4324)
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,
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_matcher_resize_data *resize_data;
210 	struct mlx5dr_cmd_ft_query_attr ft_attr = {0};
211 	struct mlx5dr_devx_obj *ste_0, *ste_1 = NULL;
212 	struct mlx5dr_pool_chunk *ste;
213 	struct mlx5dr_pool *ste_pool;
214 	uint64_t icm_addr_0 = 0;
215 	uint64_t icm_addr_1 = 0;
216 	int ret;
217 
218 	ret = fprintf(f, "%d,0x%" PRIx64 ",0x%" PRIx64 ",%d,%d,0x%" PRIx64,
219 		      MLX5DR_DEBUG_RES_TYPE_MATCHER,
220 		      (uint64_t)(uintptr_t)matcher,
221 		      (uint64_t)(uintptr_t)matcher->tbl,
222 		      matcher->num_of_mt,
223 		      is_root ? 0 : matcher->end_ft->id,
224 		      matcher->col_matcher ? (uint64_t)(uintptr_t)matcher->col_matcher : 0);
225 	if (ret < 0)
226 		goto out_err;
227 
228 	ste = &matcher->match_ste.ste;
229 	ste_pool = matcher->match_ste.pool;
230 	if (ste_pool) {
231 		ste_0 = mlx5dr_pool_chunk_get_base_devx_obj(ste_pool, ste);
232 		if (tbl_type == MLX5DR_TABLE_TYPE_FDB)
233 			ste_1 = mlx5dr_pool_chunk_get_base_devx_obj_mirror(ste_pool, ste);
234 	} else {
235 		ste_0 = NULL;
236 		ste_1 = NULL;
237 	}
238 
239 	ret = fprintf(f, ",%d,%d,%d,%d",
240 		      matcher->match_ste.rtc_0 ? matcher->match_ste.rtc_0->id : 0,
241 		      ste_0 ? (int)ste_0->id : -1,
242 		      matcher->match_ste.rtc_1 ? matcher->match_ste.rtc_1->id : 0,
243 		      ste_1 ? (int)ste_1->id : -1);
244 	if (ret < 0)
245 		goto out_err;
246 
247 	ste = &matcher->action_ste.ste;
248 	ste_pool = matcher->action_ste.pool;
249 	if (ste_pool) {
250 		ste_0 = mlx5dr_pool_chunk_get_base_devx_obj(ste_pool, ste);
251 		if (tbl_type == MLX5DR_TABLE_TYPE_FDB)
252 			ste_1 = mlx5dr_pool_chunk_get_base_devx_obj_mirror(ste_pool, ste);
253 	} else {
254 		ste_0 = NULL;
255 		ste_1 = NULL;
256 	}
257 
258 	if (!is_root) {
259 		ft_attr.type = matcher->tbl->fw_ft_type;
260 		ret = mlx5dr_cmd_flow_table_query(matcher->end_ft,
261 						  &ft_attr,
262 						  &icm_addr_0,
263 						  &icm_addr_1);
264 		if (ret)
265 			return ret;
266 	}
267 
268 	ret = fprintf(f, ",%d,%d,%d,%d,%d,0x%" PRIx64 ",0x%" PRIx64 "\n",
269 		      matcher->action_ste.rtc_0 ? matcher->action_ste.rtc_0->id : 0,
270 		      ste_0 ? (int)ste_0->id : -1,
271 		      matcher->action_ste.rtc_1 ? matcher->action_ste.rtc_1->id : 0,
272 		      ste_1 ? (int)ste_1->id : -1,
273 		      is_shared && !is_root ?
274 		      matcher->match_ste.aliased_rtc_0->id : 0,
275 		      mlx5dr_debug_icm_to_idx(icm_addr_0),
276 		      mlx5dr_debug_icm_to_idx(icm_addr_1));
277 	if (ret < 0)
278 		goto out_err;
279 
280 	ret = mlx5dr_debug_dump_matcher_attr(f, matcher);
281 	if (ret)
282 		return ret;
283 
284 	ret = mlx5dr_debug_dump_matcher_match_template(f, matcher);
285 	if (ret)
286 		return ret;
287 
288 	ret = mlx5dr_debug_dump_matcher_action_template(f, matcher);
289 	if (ret)
290 		return ret;
291 
292 	LIST_FOREACH(resize_data, &matcher->resize_data, next) {
293 		ste = &resize_data->ste;
294 		ste_pool = resize_data->action_ste_pool;
295 		if (ste_pool) {
296 			ste_0 = mlx5dr_pool_chunk_get_base_devx_obj(ste_pool, ste);
297 			if (tbl_type == MLX5DR_TABLE_TYPE_FDB)
298 				ste_1 = mlx5dr_pool_chunk_get_base_devx_obj_mirror(ste_pool, ste);
299 		} else {
300 			ste_0 = NULL;
301 			ste_1 = NULL;
302 		}
303 		ret = fprintf(f, "%d,0x%" PRIx64 ",%d,%d,%d,%d\n",
304 			      MLX5DR_DEBUG_RES_TYPE_MATCHER_RESIZABLE_ACTION_ARRAY,
305 			      (uint64_t)(uintptr_t)matcher,
306 			      resize_data->action_ste_rtc_0 ? resize_data->action_ste_rtc_0->id : 0,
307 			      ste_0 ? (int)ste_0->id : -1,
308 			      resize_data->action_ste_rtc_1 ? resize_data->action_ste_rtc_1->id : 0,
309 			      ste_1 ? (int)ste_1->id : -1);
310 		if (ret < 0)
311 			return ret;
312 	}
313 
314 	return 0;
315 
316 out_err:
317 	rte_errno = EINVAL;
318 	return rte_errno;
319 }
320 
321 static int mlx5dr_debug_dump_table(FILE *f, struct mlx5dr_table *tbl)
322 {
323 	bool is_shared = mlx5dr_context_shared_gvmi_used(tbl->ctx);
324 	bool is_root = tbl->level == MLX5DR_ROOT_LEVEL;
325 	struct mlx5dr_cmd_ft_query_attr ft_attr = {0};
326 	struct mlx5dr_matcher *matcher;
327 	uint64_t local_icm_addr_0 = 0;
328 	uint64_t local_icm_addr_1 = 0;
329 	uint64_t icm_addr_0 = 0;
330 	uint64_t icm_addr_1 = 0;
331 	int ret;
332 
333 	ret = fprintf(f, "%d,0x%" PRIx64 ",0x%" PRIx64 ",%d,%d,%d,%d,%d",
334 		      MLX5DR_DEBUG_RES_TYPE_TABLE,
335 		      (uint64_t)(uintptr_t)tbl,
336 		      (uint64_t)(uintptr_t)tbl->ctx,
337 		      is_root ? 0 : tbl->ft->id,
338 		      tbl->type,
339 		      is_root ? 0 : tbl->fw_ft_type,
340 		      tbl->level,
341 		      is_shared && !is_root ? tbl->local_ft->id : 0);
342 	if (ret < 0)
343 		goto out_err;
344 
345 	if (!is_root) {
346 		ft_attr.type = tbl->fw_ft_type;
347 		ret = mlx5dr_cmd_flow_table_query(tbl->ft,
348 						  &ft_attr,
349 						  &icm_addr_0,
350 						  &icm_addr_1);
351 		if (ret)
352 			return ret;
353 
354 		if (is_shared) {
355 			ft_attr.type = tbl->fw_ft_type;
356 			ret = mlx5dr_cmd_flow_table_query(tbl->local_ft,
357 							  &ft_attr,
358 							  &local_icm_addr_0,
359 							  &local_icm_addr_1);
360 			if (ret)
361 				return ret;
362 		}
363 	}
364 
365 	ret = fprintf(f, ",0x%" PRIx64 ",0x%" PRIx64 ",0x%" PRIx64 ",0x%" PRIx64 ",0x%" PRIx64 "\n",
366 		      mlx5dr_debug_icm_to_idx(icm_addr_0),
367 		      mlx5dr_debug_icm_to_idx(icm_addr_1),
368 		      mlx5dr_debug_icm_to_idx(local_icm_addr_0),
369 		      mlx5dr_debug_icm_to_idx(local_icm_addr_1),
370 		      (uint64_t)(uintptr_t)tbl->default_miss.miss_tbl);
371 	if (ret < 0)
372 		goto out_err;
373 
374 	LIST_FOREACH(matcher, &tbl->head, next) {
375 		ret = mlx5dr_debug_dump_matcher(f, matcher);
376 		if (ret)
377 			return ret;
378 	}
379 
380 	return 0;
381 
382 out_err:
383 	rte_errno = EINVAL;
384 	return rte_errno;
385 }
386 
387 static int
388 mlx5dr_debug_dump_context_send_engine(FILE *f, struct mlx5dr_context *ctx)
389 {
390 	struct mlx5dr_send_engine *send_queue;
391 	int ret, i, j;
392 
393 	for (i = 0; i < (int)ctx->queues; i++) {
394 		send_queue = &ctx->send_queue[i];
395 		ret = fprintf(f, "%d,0x%" PRIx64 ",%d,%d,%d,%d,%d,%d,%d,%d,%d\n",
396 			      MLX5DR_DEBUG_RES_TYPE_CONTEXT_SEND_ENGINE,
397 			      (uint64_t)(uintptr_t)ctx,
398 			      i,
399 			      send_queue->used_entries,
400 			      send_queue->th_entries,
401 			      send_queue->rings,
402 			      send_queue->num_entries,
403 			      send_queue->err,
404 			      send_queue->completed.ci,
405 			      send_queue->completed.pi,
406 			      send_queue->completed.mask);
407 		if (ret < 0) {
408 			rte_errno = EINVAL;
409 			return rte_errno;
410 		}
411 
412 		for (j = 0; j < MLX5DR_NUM_SEND_RINGS; j++) {
413 			struct mlx5dr_send_ring *send_ring = &send_queue->send_ring[j];
414 			struct mlx5dr_send_ring_cq *cq = &send_ring->send_cq;
415 			struct mlx5dr_send_ring_sq *sq = &send_ring->send_sq;
416 
417 			ret = fprintf(f, "%d,0x%" PRIx64 ",%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d\n",
418 				      MLX5DR_DEBUG_RES_TYPE_CONTEXT_SEND_RING,
419 				      (uint64_t)(uintptr_t)ctx,
420 				      j,
421 				      i,
422 				      cq->cqn,
423 				      cq->cons_index,
424 				      cq->ncqe_mask,
425 				      cq->buf_sz,
426 				      cq->ncqe,
427 				      cq->cqe_log_sz,
428 				      cq->poll_wqe,
429 				      cq->cqe_sz,
430 				      sq->sqn,
431 				      sq->obj->id,
432 				      sq->cur_post,
433 				      sq->buf_mask);
434 			if (ret < 0) {
435 				rte_errno = EINVAL;
436 				return rte_errno;
437 			}
438 		}
439 	}
440 
441 	return 0;
442 }
443 
444 static int mlx5dr_debug_dump_context_caps(FILE *f, struct mlx5dr_context *ctx)
445 {
446 	struct mlx5dr_cmd_query_caps *caps = ctx->caps;
447 	int ret;
448 
449 	ret = fprintf(f, "%d,0x%" PRIx64 ",%s,%d,%d,%d,%d,",
450 		      MLX5DR_DEBUG_RES_TYPE_CONTEXT_CAPS,
451 		      (uint64_t)(uintptr_t)ctx,
452 		      caps->fw_ver,
453 		      caps->wqe_based_update,
454 		      caps->ste_format,
455 		      caps->ste_alloc_log_max,
456 		      caps->log_header_modify_argument_max_alloc);
457 	if (ret < 0) {
458 		rte_errno = EINVAL;
459 		return rte_errno;
460 	}
461 
462 	ret = fprintf(f, "%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d\n",
463 		      caps->flex_protocols,
464 		      caps->rtc_reparse_mode,
465 		      caps->rtc_index_mode,
466 		      caps->ste_alloc_log_gran,
467 		      caps->stc_alloc_log_max,
468 		      caps->stc_alloc_log_gran,
469 		      caps->rtc_log_depth_max,
470 		      caps->format_select_gtpu_dw_0,
471 		      caps->format_select_gtpu_dw_1,
472 		      caps->format_select_gtpu_dw_2,
473 		      caps->format_select_gtpu_ext_dw_0,
474 		      caps->nic_ft.max_level,
475 		      caps->nic_ft.reparse,
476 		      caps->fdb_ft.max_level,
477 		      caps->fdb_ft.reparse,
478 		      caps->log_header_modify_argument_granularity);
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_attr(FILE *f, struct mlx5dr_context *ctx)
488 {
489 	int ret;
490 
491 	ret = fprintf(f, "%u,0x%" PRIx64 ",%d,%zu,%d,%s,%d,%d\n",
492 		      MLX5DR_DEBUG_RES_TYPE_CONTEXT_ATTR,
493 		      (uint64_t)(uintptr_t)ctx,
494 		      ctx->pd_num,
495 		      ctx->queues,
496 		      ctx->send_queue->num_entries,
497 		      mlx5dr_context_shared_gvmi_used(ctx) ?
498 		      mlx5_glue->get_device_name(ctx->ibv_ctx->device) : "None",
499 		      ctx->caps->vhca_id,
500 		      mlx5dr_context_shared_gvmi_used(ctx) ?
501 		      ctx->caps->shared_vhca_id : 0xffff);
502 	if (ret < 0) {
503 		rte_errno = EINVAL;
504 		return rte_errno;
505 	}
506 
507 	return 0;
508 }
509 
510 static int mlx5dr_debug_dump_context_info(FILE *f, struct mlx5dr_context *ctx)
511 {
512 	int ret;
513 
514 	ret = fprintf(f, "%d,0x%" PRIx64 ",%d,%s,%s\n",
515 		      MLX5DR_DEBUG_RES_TYPE_CONTEXT,
516 		      (uint64_t)(uintptr_t)ctx,
517 		      ctx->flags & MLX5DR_CONTEXT_FLAG_HWS_SUPPORT,
518 		      mlx5_glue->get_device_name(mlx5dr_context_get_local_ibv(ctx)->device),
519 		      DEBUG_VERSION);
520 	if (ret < 0) {
521 		rte_errno = EINVAL;
522 		return rte_errno;
523 	}
524 
525 	ret = mlx5dr_debug_dump_context_attr(f, ctx);
526 	if (ret)
527 		return ret;
528 
529 	ret = mlx5dr_debug_dump_context_caps(f, ctx);
530 	if (ret)
531 		return ret;
532 
533 	return 0;
534 }
535 
536 static int
537 mlx5dr_debug_dump_context_stc_resource(FILE *f,
538 				       struct mlx5dr_context *ctx,
539 				       uint32_t tbl_type,
540 				       struct mlx5dr_pool_resource *resource)
541 {
542 	int ret;
543 
544 	ret = fprintf(f, "%d,0x%" PRIx64 ",%u,%u\n",
545 		      MLX5DR_DEBUG_RES_TYPE_CONTEXT_STC,
546 		      (uint64_t)(uintptr_t)ctx,
547 		      tbl_type,
548 		      resource->base_id);
549 	if (ret < 0) {
550 		rte_errno = EINVAL;
551 		return rte_errno;
552 	}
553 
554 	return 0;
555 }
556 
557 static int mlx5dr_debug_dump_context_stc(FILE *f, struct mlx5dr_context *ctx)
558 {
559 	struct mlx5dr_pool *stc_pool;
560 	int ret;
561 	int i;
562 
563 	for (i = 0; i < MLX5DR_TABLE_TYPE_MAX; i++) {
564 		stc_pool = ctx->stc_pool[i];
565 
566 		if (!stc_pool)
567 			continue;
568 
569 		if (stc_pool->resource[0] != NULL) {
570 			ret = mlx5dr_debug_dump_context_stc_resource(f, ctx, i,
571 								     stc_pool->resource[0]);
572 			if (ret)
573 				return ret;
574 		}
575 
576 		if (i == MLX5DR_TABLE_TYPE_FDB && stc_pool->mirror_resource[0] != NULL) {
577 			ret = mlx5dr_debug_dump_context_stc_resource(f, ctx, i,
578 								     stc_pool->mirror_resource[0]);
579 			if (ret)
580 				return ret;
581 		}
582 	}
583 
584 	return 0;
585 }
586 
587 static int mlx5dr_debug_dump_context(FILE *f, struct mlx5dr_context *ctx)
588 {
589 	struct mlx5dr_table *tbl;
590 	int ret;
591 
592 	ret = mlx5dr_debug_dump_context_info(f, ctx);
593 	if (ret)
594 		return ret;
595 
596 	ret = mlx5dr_debug_dump_context_send_engine(f, ctx);
597 	if (ret)
598 		return ret;
599 
600 	ret = mlx5dr_debug_dump_context_stc(f, ctx);
601 	if (ret)
602 		return ret;
603 
604 	LIST_FOREACH(tbl, &ctx->head, next) {
605 		ret = mlx5dr_debug_dump_table(f, tbl);
606 		if (ret)
607 			return ret;
608 	}
609 
610 	return 0;
611 }
612 
613 int mlx5dr_debug_dump(struct mlx5dr_context *ctx, FILE *f)
614 {
615 	int ret;
616 
617 	if (!f || !ctx) {
618 		rte_errno = EINVAL;
619 		return -rte_errno;
620 	}
621 
622 	pthread_spin_lock(&ctx->ctrl_lock);
623 	ret = mlx5dr_debug_dump_context(f, ctx);
624 	pthread_spin_unlock(&ctx->ctrl_lock);
625 
626 	return -ret;
627 }
628