File Index
Files and directories
Sign in
FILE

dr_dbg.c

File preview with syntax highlighting.

linux-6.19.14/drivers/net/ethernet/mellanox/mlx5/core/steering/sws/dr_dbg.c C
   1// SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB
   2// Copyright (c) 2021, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
   3
   4#include <linux/debugfs.h>
   5#include <linux/kernel.h>
   6#include <linux/seq_file.h>
   7#include <linux/version.h>
   8#include "dr_types.h"
   9
  10#define DR_DBG_PTR_TO_ID(p) ((u64)(uintptr_t)(p) & 0xFFFFFFFFULL)
  11
  12enum dr_dump_rec_type {
  13	DR_DUMP_REC_TYPE_DOMAIN = 3000,
  14	DR_DUMP_REC_TYPE_DOMAIN_INFO_FLEX_PARSER = 3001,
  15	DR_DUMP_REC_TYPE_DOMAIN_INFO_DEV_ATTR = 3002,
  16	DR_DUMP_REC_TYPE_DOMAIN_INFO_VPORT = 3003,
  17	DR_DUMP_REC_TYPE_DOMAIN_INFO_CAPS = 3004,
  18	DR_DUMP_REC_TYPE_DOMAIN_SEND_RING = 3005,
  19
  20	DR_DUMP_REC_TYPE_TABLE = 3100,
  21	DR_DUMP_REC_TYPE_TABLE_RX = 3101,
  22	DR_DUMP_REC_TYPE_TABLE_TX = 3102,
  23
  24	DR_DUMP_REC_TYPE_MATCHER = 3200,
  25	DR_DUMP_REC_TYPE_MATCHER_MASK_DEPRECATED = 3201,
  26	DR_DUMP_REC_TYPE_MATCHER_RX = 3202,
  27	DR_DUMP_REC_TYPE_MATCHER_TX = 3203,
  28	DR_DUMP_REC_TYPE_MATCHER_BUILDER = 3204,
  29	DR_DUMP_REC_TYPE_MATCHER_MASK = 3205,
  30
  31	DR_DUMP_REC_TYPE_RULE = 3300,
  32	DR_DUMP_REC_TYPE_RULE_RX_ENTRY_V0 = 3301,
  33	DR_DUMP_REC_TYPE_RULE_TX_ENTRY_V0 = 3302,
  34	DR_DUMP_REC_TYPE_RULE_RX_ENTRY_V1 = 3303,
  35	DR_DUMP_REC_TYPE_RULE_TX_ENTRY_V1 = 3304,
  36
  37	DR_DUMP_REC_TYPE_ACTION_ENCAP_L2 = 3400,
  38	DR_DUMP_REC_TYPE_ACTION_ENCAP_L3 = 3401,
  39	DR_DUMP_REC_TYPE_ACTION_MODIFY_HDR = 3402,
  40	DR_DUMP_REC_TYPE_ACTION_DROP = 3403,
  41	DR_DUMP_REC_TYPE_ACTION_QP = 3404,
  42	DR_DUMP_REC_TYPE_ACTION_FT = 3405,
  43	DR_DUMP_REC_TYPE_ACTION_CTR = 3406,
  44	DR_DUMP_REC_TYPE_ACTION_TAG = 3407,
  45	DR_DUMP_REC_TYPE_ACTION_VPORT = 3408,
  46	DR_DUMP_REC_TYPE_ACTION_DECAP_L2 = 3409,
  47	DR_DUMP_REC_TYPE_ACTION_DECAP_L3 = 3410,
  48	DR_DUMP_REC_TYPE_ACTION_DEVX_TIR = 3411,
  49	DR_DUMP_REC_TYPE_ACTION_PUSH_VLAN = 3412,
  50	DR_DUMP_REC_TYPE_ACTION_POP_VLAN = 3413,
  51	DR_DUMP_REC_TYPE_ACTION_SAMPLER = 3415,
  52	DR_DUMP_REC_TYPE_ACTION_INSERT_HDR = 3420,
  53	DR_DUMP_REC_TYPE_ACTION_REMOVE_HDR = 3421,
  54	DR_DUMP_REC_TYPE_ACTION_MATCH_RANGE = 3425,
  55};
  56
  57static struct mlx5dr_dbg_dump_buff *
  58mlx5dr_dbg_dump_data_init_new_buff(struct mlx5dr_dbg_dump_data *dump_data)
  59{
  60	struct mlx5dr_dbg_dump_buff *new_buff;
  61
  62	new_buff = kzalloc(sizeof(*new_buff), GFP_KERNEL);
  63	if (!new_buff)
  64		return NULL;
  65
  66	new_buff->buff = kvzalloc(MLX5DR_DEBUG_DUMP_BUFF_SIZE, GFP_KERNEL);
  67	if (!new_buff->buff) {
  68		kfree(new_buff);
  69		return NULL;
  70	}
  71
  72	INIT_LIST_HEAD(&new_buff->node);
  73	list_add_tail(&new_buff->node, &dump_data->buff_list);
  74
  75	return new_buff;
  76}
  77
  78static struct mlx5dr_dbg_dump_data *
  79mlx5dr_dbg_create_dump_data(void)
  80{
  81	struct mlx5dr_dbg_dump_data *dump_data;
  82
  83	dump_data = kzalloc(sizeof(*dump_data), GFP_KERNEL);
  84	if (!dump_data)
  85		return NULL;
  86
  87	INIT_LIST_HEAD(&dump_data->buff_list);
  88
  89	if (!mlx5dr_dbg_dump_data_init_new_buff(dump_data)) {
  90		kfree(dump_data);
  91		return NULL;
  92	}
  93
  94	return dump_data;
  95}
  96
  97static void
  98mlx5dr_dbg_destroy_dump_data(struct mlx5dr_dbg_dump_data *dump_data)
  99{
 100	struct mlx5dr_dbg_dump_buff *dump_buff, *tmp_buff;
 101
 102	if (!dump_data)
 103		return;
 104
 105	list_for_each_entry_safe(dump_buff, tmp_buff, &dump_data->buff_list, node) {
 106		kvfree(dump_buff->buff);
 107		list_del(&dump_buff->node);
 108		kfree(dump_buff);
 109	}
 110
 111	kfree(dump_data);
 112}
 113
 114static int
 115mlx5dr_dbg_dump_data_print(struct seq_file *file, char *str, u32 size)
 116{
 117	struct mlx5dr_domain *dmn = file->private;
 118	struct mlx5dr_dbg_dump_data *dump_data;
 119	struct mlx5dr_dbg_dump_buff *buff;
 120	u32 buff_capacity, write_size;
 121	int remain_size, ret;
 122
 123	if (size >= MLX5DR_DEBUG_DUMP_BUFF_SIZE)
 124		return -EINVAL;
 125
 126	dump_data = dmn->dump_info.dump_data;
 127	buff = list_last_entry(&dump_data->buff_list,
 128			       struct mlx5dr_dbg_dump_buff, node);
 129
 130	buff_capacity = (MLX5DR_DEBUG_DUMP_BUFF_SIZE - 1) - buff->index;
 131	remain_size = buff_capacity - size;
 132	write_size = (remain_size > 0) ? size : buff_capacity;
 133
 134	if (likely(write_size)) {
 135		ret = snprintf(buff->buff + buff->index, write_size + 1, "%s", str);
 136		if (ret < 0)
 137			return ret;
 138
 139		buff->index += write_size;
 140	}
 141
 142	if (remain_size < 0) {
 143		remain_size *= -1;
 144		buff = mlx5dr_dbg_dump_data_init_new_buff(dump_data);
 145		if (!buff)
 146			return -ENOMEM;
 147
 148		ret = snprintf(buff->buff, remain_size + 1, "%s", str + write_size);
 149		if (ret < 0)
 150			return ret;
 151
 152		buff->index += remain_size;
 153	}
 154
 155	return 0;
 156}
 157
 158void mlx5dr_dbg_tbl_add(struct mlx5dr_table *tbl)
 159{
 160	mutex_lock(&tbl->dmn->dump_info.dbg_mutex);
 161	list_add_tail(&tbl->dbg_node, &tbl->dmn->dbg_tbl_list);
 162	mutex_unlock(&tbl->dmn->dump_info.dbg_mutex);
 163}
 164
 165void mlx5dr_dbg_tbl_del(struct mlx5dr_table *tbl)
 166{
 167	mutex_lock(&tbl->dmn->dump_info.dbg_mutex);
 168	list_del(&tbl->dbg_node);
 169	mutex_unlock(&tbl->dmn->dump_info.dbg_mutex);
 170}
 171
 172void mlx5dr_dbg_rule_add(struct mlx5dr_rule *rule)
 173{
 174	struct mlx5dr_domain *dmn = rule->matcher->tbl->dmn;
 175
 176	mutex_lock(&dmn->dump_info.dbg_mutex);
 177	list_add_tail(&rule->dbg_node, &rule->matcher->dbg_rule_list);
 178	mutex_unlock(&dmn->dump_info.dbg_mutex);
 179}
 180
 181void mlx5dr_dbg_rule_del(struct mlx5dr_rule *rule)
 182{
 183	struct mlx5dr_domain *dmn = rule->matcher->tbl->dmn;
 184
 185	mutex_lock(&dmn->dump_info.dbg_mutex);
 186	list_del(&rule->dbg_node);
 187	mutex_unlock(&dmn->dump_info.dbg_mutex);
 188}
 189
 190static u64 dr_dump_icm_to_idx(u64 icm_addr)
 191{
 192	return (icm_addr >> 6) & 0xffffffff;
 193}
 194
 195#define DR_HEX_SIZE 256
 196
 197static void
 198dr_dump_hex_print(char hex[DR_HEX_SIZE], char *src, u32 size)
 199{
 200	if (WARN_ON_ONCE(DR_HEX_SIZE < 2 * size + 1))
 201		size = DR_HEX_SIZE / 2 - 1; /* truncate */
 202
 203	bin2hex(hex, src, size);
 204	hex[2 * size] = 0; /* NULL-terminate */
 205}
 206
 207static int
 208dr_dump_rule_action_mem(struct seq_file *file, char *buff, const u64 rule_id,
 209			struct mlx5dr_rule_action_member *action_mem)
 210{
 211	struct mlx5dr_action *action = action_mem->action;
 212	const u64 action_id = DR_DBG_PTR_TO_ID(action);
 213	u64 hit_tbl_ptr, miss_tbl_ptr;
 214	u32 hit_tbl_id, miss_tbl_id;
 215	int ret;
 216
 217	switch (action->action_type) {
 218	case DR_ACTION_TYP_DROP:
 219		ret = snprintf(buff, MLX5DR_DEBUG_DUMP_BUFF_LENGTH,
 220			       "%d,0x%llx,0x%llx\n",
 221			       DR_DUMP_REC_TYPE_ACTION_DROP, action_id,
 222			       rule_id);
 223		if (ret < 0)
 224			return ret;
 225
 226		ret = mlx5dr_dbg_dump_data_print(file, buff, ret);
 227		if (ret)
 228			return ret;
 229		break;
 230	case DR_ACTION_TYP_FT:
 231		if (action->dest_tbl->is_fw_tbl)
 232			ret = snprintf(buff, MLX5DR_DEBUG_DUMP_BUFF_LENGTH,
 233				       "%d,0x%llx,0x%llx,0x%x,0x%x\n",
 234				       DR_DUMP_REC_TYPE_ACTION_FT, action_id,
 235				       rule_id, action->dest_tbl->fw_tbl.id,
 236				       -1);
 237		else
 238			ret = snprintf(buff, MLX5DR_DEBUG_DUMP_BUFF_LENGTH,
 239				       "%d,0x%llx,0x%llx,0x%x,0x%llx\n",
 240				       DR_DUMP_REC_TYPE_ACTION_FT, action_id,
 241				       rule_id, action->dest_tbl->tbl->table_id,
 242				       DR_DBG_PTR_TO_ID(action->dest_tbl->tbl));
 243
 244		if (ret < 0)
 245			return ret;
 246
 247		ret = mlx5dr_dbg_dump_data_print(file, buff, ret);
 248		if (ret)
 249			return ret;
 250		break;
 251	case DR_ACTION_TYP_CTR:
 252		ret = snprintf(buff, MLX5DR_DEBUG_DUMP_BUFF_LENGTH,
 253			       "%d,0x%llx,0x%llx,0x%x\n",
 254			       DR_DUMP_REC_TYPE_ACTION_CTR, action_id, rule_id,
 255			       action->ctr->ctr_id + action->ctr->offset);
 256		if (ret < 0)
 257			return ret;
 258
 259		ret = mlx5dr_dbg_dump_data_print(file, buff, ret);
 260		if (ret)
 261			return ret;
 262		break;
 263	case DR_ACTION_TYP_TAG:
 264		ret = snprintf(buff, MLX5DR_DEBUG_DUMP_BUFF_LENGTH,
 265			       "%d,0x%llx,0x%llx,0x%x\n",
 266			       DR_DUMP_REC_TYPE_ACTION_TAG, action_id, rule_id,
 267			       action->flow_tag->flow_tag);
 268		if (ret < 0)
 269			return ret;
 270
 271		ret = mlx5dr_dbg_dump_data_print(file, buff, ret);
 272		if (ret)
 273			return ret;
 274		break;
 275	case DR_ACTION_TYP_MODIFY_HDR:
 276	{
 277		struct mlx5dr_ptrn_obj *ptrn = action->rewrite->ptrn;
 278		struct mlx5dr_arg_obj *arg = action->rewrite->arg;
 279		u8 *rewrite_data = action->rewrite->data;
 280		bool ptrn_arg;
 281		int i;
 282
 283		ptrn_arg = !action->rewrite->single_action_opt && ptrn && arg;
 284
 285		ret = snprintf(buff, MLX5DR_DEBUG_DUMP_BUFF_LENGTH,
 286			       "%d,0x%llx,0x%llx,0x%x,%d,0x%x,0x%x,0x%x",
 287			       DR_DUMP_REC_TYPE_ACTION_MODIFY_HDR, action_id,
 288			       rule_id, action->rewrite->index,
 289			       action->rewrite->single_action_opt,
 290			       ptrn_arg ? action->rewrite->num_of_actions : 0,
 291			       ptrn_arg ? ptrn->index : 0,
 292			       ptrn_arg ? mlx5dr_arg_get_obj_id(arg) : 0);
 293		if (ret < 0)
 294			return ret;
 295
 296		ret = mlx5dr_dbg_dump_data_print(file, buff, ret);
 297		if (ret)
 298			return ret;
 299
 300		if (ptrn_arg) {
 301			for (i = 0; i < action->rewrite->num_of_actions; i++) {
 302				ret = snprintf(buff, MLX5DR_DEBUG_DUMP_BUFF_LENGTH,
 303					       ",0x%016llx",
 304					       be64_to_cpu(((__be64 *)rewrite_data)[i]));
 305				if (ret < 0)
 306					return ret;
 307
 308				ret = mlx5dr_dbg_dump_data_print(file, buff, ret);
 309				if (ret)
 310					return ret;
 311			}
 312		}
 313
 314		ret = snprintf(buff, MLX5DR_DEBUG_DUMP_BUFF_LENGTH, "\n");
 315		if (ret < 0)
 316			return ret;
 317		ret = mlx5dr_dbg_dump_data_print(file, buff, ret);
 318		if (ret)
 319			return ret;
 320		break;
 321	}
 322	case DR_ACTION_TYP_VPORT:
 323		ret = snprintf(buff, MLX5DR_DEBUG_DUMP_BUFF_LENGTH,
 324			       "%d,0x%llx,0x%llx,0x%x\n",
 325			       DR_DUMP_REC_TYPE_ACTION_VPORT, action_id, rule_id,
 326			       action->vport->caps->num);
 327		if (ret < 0)
 328			return ret;
 329
 330		ret = mlx5dr_dbg_dump_data_print(file, buff, ret);
 331		if (ret)
 332			return ret;
 333		break;
 334	case DR_ACTION_TYP_TNL_L2_TO_L2:
 335		ret = snprintf(buff, MLX5DR_DEBUG_DUMP_BUFF_LENGTH,
 336			       "%d,0x%llx,0x%llx\n",
 337			       DR_DUMP_REC_TYPE_ACTION_DECAP_L2, action_id,
 338			       rule_id);
 339		if (ret < 0)
 340			return ret;
 341
 342		ret = mlx5dr_dbg_dump_data_print(file, buff, ret);
 343		if (ret)
 344			return ret;
 345		break;
 346	case DR_ACTION_TYP_TNL_L3_TO_L2:
 347		ret = snprintf(buff, MLX5DR_DEBUG_DUMP_BUFF_LENGTH,
 348			       "%d,0x%llx,0x%llx,0x%x\n",
 349			       DR_DUMP_REC_TYPE_ACTION_DECAP_L3, action_id,
 350			       rule_id,
 351			       (action->rewrite->ptrn && action->rewrite->arg) ?
 352			       mlx5dr_arg_get_obj_id(action->rewrite->arg) :
 353			       action->rewrite->index);
 354		if (ret < 0)
 355			return ret;
 356
 357		ret = mlx5dr_dbg_dump_data_print(file, buff, ret);
 358		if (ret)
 359			return ret;
 360		break;
 361	case DR_ACTION_TYP_L2_TO_TNL_L2:
 362		ret = snprintf(buff, MLX5DR_DEBUG_DUMP_BUFF_LENGTH,
 363			       "%d,0x%llx,0x%llx,0x%x\n",
 364			       DR_DUMP_REC_TYPE_ACTION_ENCAP_L2, action_id,
 365			       rule_id, action->reformat->id);
 366		if (ret < 0)
 367			return ret;
 368
 369		ret = mlx5dr_dbg_dump_data_print(file, buff, ret);
 370		if (ret)
 371			return ret;
 372		break;
 373	case DR_ACTION_TYP_L2_TO_TNL_L3:
 374		ret = snprintf(buff, MLX5DR_DEBUG_DUMP_BUFF_LENGTH,
 375			       "%d,0x%llx,0x%llx,0x%x\n",
 376			       DR_DUMP_REC_TYPE_ACTION_ENCAP_L3, action_id,
 377			       rule_id, action->reformat->id);
 378		if (ret < 0)
 379			return ret;
 380
 381		ret = mlx5dr_dbg_dump_data_print(file, buff, ret);
 382		if (ret)
 383			return ret;
 384		break;
 385	case DR_ACTION_TYP_POP_VLAN:
 386		ret = snprintf(buff, MLX5DR_DEBUG_DUMP_BUFF_LENGTH,
 387			       "%d,0x%llx,0x%llx\n",
 388			       DR_DUMP_REC_TYPE_ACTION_POP_VLAN, action_id,
 389			       rule_id);
 390		if (ret < 0)
 391			return ret;
 392
 393		ret = mlx5dr_dbg_dump_data_print(file, buff, ret);
 394		if (ret)
 395			return ret;
 396		break;
 397	case DR_ACTION_TYP_PUSH_VLAN:
 398		ret = snprintf(buff, MLX5DR_DEBUG_DUMP_BUFF_LENGTH,
 399			       "%d,0x%llx,0x%llx,0x%x\n",
 400			       DR_DUMP_REC_TYPE_ACTION_PUSH_VLAN, action_id,
 401			       rule_id, action->push_vlan->vlan_hdr);
 402		if (ret < 0)
 403			return ret;
 404
 405		ret = mlx5dr_dbg_dump_data_print(file, buff, ret);
 406		if (ret)
 407			return ret;
 408		break;
 409	case DR_ACTION_TYP_INSERT_HDR:
 410		ret = snprintf(buff, MLX5DR_DEBUG_DUMP_BUFF_LENGTH,
 411			       "%d,0x%llx,0x%llx,0x%x,0x%x,0x%x\n",
 412			       DR_DUMP_REC_TYPE_ACTION_INSERT_HDR, action_id,
 413			       rule_id, action->reformat->id,
 414			       action->reformat->param_0,
 415			       action->reformat->param_1);
 416		if (ret < 0)
 417			return ret;
 418
 419		ret = mlx5dr_dbg_dump_data_print(file, buff, ret);
 420		if (ret)
 421			return ret;
 422		break;
 423	case DR_ACTION_TYP_REMOVE_HDR:
 424		ret = snprintf(buff, MLX5DR_DEBUG_DUMP_BUFF_LENGTH,
 425			       "%d,0x%llx,0x%llx,0x%x,0x%x,0x%x\n",
 426			       DR_DUMP_REC_TYPE_ACTION_REMOVE_HDR, action_id,
 427			       rule_id, action->reformat->id,
 428			       action->reformat->param_0,
 429			       action->reformat->param_1);
 430		if (ret < 0)
 431			return ret;
 432
 433		ret = mlx5dr_dbg_dump_data_print(file, buff, ret);
 434		if (ret)
 435			return ret;
 436		break;
 437	case DR_ACTION_TYP_SAMPLER:
 438		ret = snprintf(buff, MLX5DR_DEBUG_DUMP_BUFF_LENGTH,
 439			       "%d,0x%llx,0x%llx,0x%x,0x%x,0x%x,0x%llx,0x%llx\n",
 440			       DR_DUMP_REC_TYPE_ACTION_SAMPLER, action_id,
 441			       rule_id, 0, 0, action->sampler->sampler_id,
 442			       action->sampler->rx_icm_addr,
 443			       action->sampler->tx_icm_addr);
 444		if (ret < 0)
 445			return ret;
 446
 447		ret = mlx5dr_dbg_dump_data_print(file, buff, ret);
 448		if (ret)
 449			return ret;
 450		break;
 451	case DR_ACTION_TYP_RANGE:
 452		if (action->range->hit_tbl_action->dest_tbl->is_fw_tbl) {
 453			hit_tbl_id = action->range->hit_tbl_action->dest_tbl->fw_tbl.id;
 454			hit_tbl_ptr = 0;
 455		} else {
 456			hit_tbl_id = action->range->hit_tbl_action->dest_tbl->tbl->table_id;
 457			hit_tbl_ptr =
 458				DR_DBG_PTR_TO_ID(action->range->hit_tbl_action->dest_tbl->tbl);
 459		}
 460
 461		if (action->range->miss_tbl_action->dest_tbl->is_fw_tbl) {
 462			miss_tbl_id = action->range->miss_tbl_action->dest_tbl->fw_tbl.id;
 463			miss_tbl_ptr = 0;
 464		} else {
 465			miss_tbl_id = action->range->miss_tbl_action->dest_tbl->tbl->table_id;
 466			miss_tbl_ptr =
 467				DR_DBG_PTR_TO_ID(action->range->miss_tbl_action->dest_tbl->tbl);
 468		}
 469
 470		ret = snprintf(buff, MLX5DR_DEBUG_DUMP_BUFF_LENGTH,
 471			       "%d,0x%llx,0x%llx,0x%x,0x%llx,0x%x,0x%llx,0x%x\n",
 472			       DR_DUMP_REC_TYPE_ACTION_MATCH_RANGE, action_id,
 473			       rule_id, hit_tbl_id, hit_tbl_ptr, miss_tbl_id,
 474			       miss_tbl_ptr, action->range->definer_id);
 475		if (ret < 0)
 476			return ret;
 477
 478		ret = mlx5dr_dbg_dump_data_print(file, buff, ret);
 479		if (ret)
 480			return ret;
 481		break;
 482	default:
 483		return 0;
 484	}
 485
 486	return 0;
 487}
 488
 489static int
 490dr_dump_rule_mem(struct seq_file *file, char *buff, struct mlx5dr_ste *ste,
 491		 bool is_rx, const u64 rule_id, u8 format_ver)
 492{
 493	char hw_ste_dump[DR_HEX_SIZE];
 494	u32 mem_rec_type;
 495	int ret;
 496
 497	if (format_ver == MLX5_STEERING_FORMAT_CONNECTX_5) {
 498		mem_rec_type = is_rx ? DR_DUMP_REC_TYPE_RULE_RX_ENTRY_V0 :
 499				       DR_DUMP_REC_TYPE_RULE_TX_ENTRY_V0;
 500	} else {
 501		mem_rec_type = is_rx ? DR_DUMP_REC_TYPE_RULE_RX_ENTRY_V1 :
 502				       DR_DUMP_REC_TYPE_RULE_TX_ENTRY_V1;
 503	}
 504
 505	dr_dump_hex_print(hw_ste_dump, (char *)mlx5dr_ste_get_hw_ste(ste),
 506			  DR_STE_SIZE_REDUCED);
 507
 508	ret = snprintf(buff, MLX5DR_DEBUG_DUMP_BUFF_LENGTH,
 509		       "%d,0x%llx,0x%llx,%s\n", mem_rec_type,
 510		       dr_dump_icm_to_idx(mlx5dr_ste_get_icm_addr(ste)),
 511		       rule_id, hw_ste_dump);
 512	if (ret < 0)
 513		return ret;
 514
 515	ret = mlx5dr_dbg_dump_data_print(file, buff, ret);
 516	if (ret)
 517		return ret;
 518
 519	return 0;
 520}
 521
 522static int
 523dr_dump_rule_rx_tx(struct seq_file *file, char *buff,
 524		   struct mlx5dr_rule_rx_tx *rule_rx_tx,
 525		   bool is_rx, const u64 rule_id, u8 format_ver)
 526{
 527	struct mlx5dr_ste *ste_arr[DR_RULE_MAX_STES + DR_ACTION_MAX_STES];
 528	struct mlx5dr_ste *curr_ste = rule_rx_tx->last_rule_ste;
 529	int ret, i;
 530
 531	if (mlx5dr_rule_get_reverse_rule_members(ste_arr, curr_ste, &i))
 532		return 0;
 533
 534	while (i--) {
 535		ret = dr_dump_rule_mem(file, buff, ste_arr[i], is_rx, rule_id,
 536				       format_ver);
 537		if (ret < 0)
 538			return ret;
 539	}
 540
 541	return 0;
 542}
 543
 544static noinline_for_stack int
 545dr_dump_rule(struct seq_file *file, struct mlx5dr_rule *rule)
 546{
 547	struct mlx5dr_rule_action_member *action_mem;
 548	const u64 rule_id = DR_DBG_PTR_TO_ID(rule);
 549	char buff[MLX5DR_DEBUG_DUMP_BUFF_LENGTH];
 550	struct mlx5dr_rule_rx_tx *rx = &rule->rx;
 551	struct mlx5dr_rule_rx_tx *tx = &rule->tx;
 552	u8 format_ver;
 553	int ret;
 554
 555	format_ver = rule->matcher->tbl->dmn->info.caps.sw_format_ver;
 556
 557	ret = snprintf(buff, MLX5DR_DEBUG_DUMP_BUFF_LENGTH,
 558		       "%d,0x%llx,0x%llx\n", DR_DUMP_REC_TYPE_RULE,
 559		       rule_id, DR_DBG_PTR_TO_ID(rule->matcher));
 560	if (ret < 0)
 561		return ret;
 562
 563	ret = mlx5dr_dbg_dump_data_print(file, buff, ret);
 564	if (ret)
 565		return ret;
 566
 567	if (rx->nic_matcher) {
 568		ret = dr_dump_rule_rx_tx(file, buff, rx, true, rule_id, format_ver);
 569		if (ret < 0)
 570			return ret;
 571	}
 572
 573	if (tx->nic_matcher) {
 574		ret = dr_dump_rule_rx_tx(file, buff, tx, false, rule_id, format_ver);
 575		if (ret < 0)
 576			return ret;
 577	}
 578
 579	list_for_each_entry(action_mem, &rule->rule_actions_list, list) {
 580		ret = dr_dump_rule_action_mem(file, buff, rule_id, action_mem);
 581		if (ret < 0)
 582			return ret;
 583	}
 584
 585	return 0;
 586}
 587
 588static int
 589dr_dump_matcher_mask(struct seq_file *file, char *buff,
 590		     struct mlx5dr_match_param *mask,
 591		     u8 criteria, const u64 matcher_id)
 592{
 593	char dump[DR_HEX_SIZE];
 594	int ret;
 595
 596	ret = snprintf(buff, MLX5DR_DEBUG_DUMP_BUFF_LENGTH, "%d,0x%llx,",
 597		       DR_DUMP_REC_TYPE_MATCHER_MASK, matcher_id);
 598	if (ret < 0)
 599		return ret;
 600
 601	ret = mlx5dr_dbg_dump_data_print(file, buff, ret);
 602	if (ret)
 603		return ret;
 604
 605	if (criteria & DR_MATCHER_CRITERIA_OUTER) {
 606		dr_dump_hex_print(dump, (char *)&mask->outer, sizeof(mask->outer));
 607		ret = snprintf(buff, MLX5DR_DEBUG_DUMP_BUFF_LENGTH,
 608			       "%s,", dump);
 609	} else {
 610		ret = snprintf(buff, MLX5DR_DEBUG_DUMP_BUFF_LENGTH, ",");
 611	}
 612
 613	if (ret < 0)
 614		return ret;
 615
 616	ret = mlx5dr_dbg_dump_data_print(file, buff, ret);
 617	if (ret)
 618		return ret;
 619
 620	if (criteria & DR_MATCHER_CRITERIA_INNER) {
 621		dr_dump_hex_print(dump, (char *)&mask->inner, sizeof(mask->inner));
 622		ret = snprintf(buff, MLX5DR_DEBUG_DUMP_BUFF_LENGTH,
 623			       "%s,", dump);
 624	} else {
 625		ret = snprintf(buff, MLX5DR_DEBUG_DUMP_BUFF_LENGTH, ",");
 626	}
 627
 628	if (ret < 0)
 629		return ret;
 630
 631	ret = mlx5dr_dbg_dump_data_print(file, buff, ret);
 632	if (ret)
 633		return ret;
 634
 635	if (criteria & DR_MATCHER_CRITERIA_MISC) {
 636		dr_dump_hex_print(dump, (char *)&mask->misc, sizeof(mask->misc));
 637		ret = snprintf(buff, MLX5DR_DEBUG_DUMP_BUFF_LENGTH,
 638			       "%s,", dump);
 639	} else {
 640		ret = snprintf(buff, MLX5DR_DEBUG_DUMP_BUFF_LENGTH, ",");
 641	}
 642
 643	if (ret < 0)
 644		return ret;
 645
 646	ret = mlx5dr_dbg_dump_data_print(file, buff, ret);
 647	if (ret)
 648		return ret;
 649
 650	if (criteria & DR_MATCHER_CRITERIA_MISC2) {
 651		dr_dump_hex_print(dump, (char *)&mask->misc2, sizeof(mask->misc2));
 652		ret = snprintf(buff, MLX5DR_DEBUG_DUMP_BUFF_LENGTH,
 653			       "%s,", dump);
 654	} else {
 655		ret = snprintf(buff, MLX5DR_DEBUG_DUMP_BUFF_LENGTH, ",");
 656	}
 657
 658	if (ret < 0)
 659		return ret;
 660
 661	ret = mlx5dr_dbg_dump_data_print(file, buff, ret);
 662	if (ret)
 663		return ret;
 664
 665	if (criteria & DR_MATCHER_CRITERIA_MISC3) {
 666		dr_dump_hex_print(dump, (char *)&mask->misc3, sizeof(mask->misc3));
 667		ret = snprintf(buff, MLX5DR_DEBUG_DUMP_BUFF_LENGTH,
 668			       "%s\n", dump);
 669	} else {
 670		ret = snprintf(buff, MLX5DR_DEBUG_DUMP_BUFF_LENGTH, ",\n");
 671	}
 672
 673	if (ret < 0)
 674		return ret;
 675
 676	ret = mlx5dr_dbg_dump_data_print(file, buff, ret);
 677	if (ret)
 678		return ret;
 679
 680	return 0;
 681}
 682
 683static int
 684dr_dump_matcher_builder(struct seq_file *file, char *buff,
 685			struct mlx5dr_ste_build *builder,
 686			u32 index, bool is_rx, const u64 matcher_id)
 687{
 688	int ret;
 689
 690	ret = snprintf(buff, MLX5DR_DEBUG_DUMP_BUFF_LENGTH,
 691		       "%d,0x%llx,%d,%d,0x%x\n",
 692		       DR_DUMP_REC_TYPE_MATCHER_BUILDER, matcher_id, index,
 693		       is_rx, builder->lu_type);
 694	if (ret < 0)
 695		return ret;
 696
 697	ret = mlx5dr_dbg_dump_data_print(file, buff, ret);
 698	if (ret)
 699		return ret;
 700
 701	return 0;
 702}
 703
 704static int
 705dr_dump_matcher_rx_tx(struct seq_file *file, char *buff, bool is_rx,
 706		      struct mlx5dr_matcher_rx_tx *matcher_rx_tx,
 707		      const u64 matcher_id)
 708{
 709	enum dr_dump_rec_type rec_type;
 710	u64 s_icm_addr, e_icm_addr;
 711	int i, ret;
 712
 713	rec_type = is_rx ? DR_DUMP_REC_TYPE_MATCHER_RX :
 714			   DR_DUMP_REC_TYPE_MATCHER_TX;
 715
 716	s_icm_addr = mlx5dr_icm_pool_get_chunk_icm_addr(matcher_rx_tx->s_htbl->chunk);
 717	e_icm_addr = mlx5dr_icm_pool_get_chunk_icm_addr(matcher_rx_tx->e_anchor->chunk);
 718	ret = snprintf(buff, MLX5DR_DEBUG_DUMP_BUFF_LENGTH,
 719		       "%d,0x%llx,0x%llx,%d,0x%llx,0x%llx\n",
 720		       rec_type, DR_DBG_PTR_TO_ID(matcher_rx_tx),
 721		       matcher_id, matcher_rx_tx->num_of_builders,
 722		       dr_dump_icm_to_idx(s_icm_addr),
 723		       dr_dump_icm_to_idx(e_icm_addr));
 724
 725	if (ret < 0)
 726		return ret;
 727
 728	ret = mlx5dr_dbg_dump_data_print(file, buff, ret);
 729	if (ret)
 730		return ret;
 731
 732	for (i = 0; i < matcher_rx_tx->num_of_builders; i++) {
 733		ret = dr_dump_matcher_builder(file, buff,
 734					      &matcher_rx_tx->ste_builder[i],
 735					      i, is_rx, matcher_id);
 736		if (ret < 0)
 737			return ret;
 738	}
 739
 740	return 0;
 741}
 742
 743static noinline_for_stack int
 744dr_dump_matcher(struct seq_file *file, struct mlx5dr_matcher *matcher)
 745{
 746	struct mlx5dr_matcher_rx_tx *rx = &matcher->rx;
 747	struct mlx5dr_matcher_rx_tx *tx = &matcher->tx;
 748	char buff[MLX5DR_DEBUG_DUMP_BUFF_LENGTH];
 749	u64 matcher_id;
 750	int ret;
 751
 752	matcher_id = DR_DBG_PTR_TO_ID(matcher);
 753
 754	ret = snprintf(buff, MLX5DR_DEBUG_DUMP_BUFF_LENGTH,
 755		       "%d,0x%llx,0x%llx,%d\n", DR_DUMP_REC_TYPE_MATCHER,
 756		       matcher_id, DR_DBG_PTR_TO_ID(matcher->tbl),
 757		       matcher->prio);
 758	if (ret < 0)
 759		return ret;
 760
 761	ret = mlx5dr_dbg_dump_data_print(file, buff, ret);
 762	if (ret)
 763		return ret;
 764
 765	ret = dr_dump_matcher_mask(file, buff, &matcher->mask,
 766				   matcher->match_criteria, matcher_id);
 767	if (ret < 0)
 768		return ret;
 769
 770	if (rx->nic_tbl) {
 771		ret = dr_dump_matcher_rx_tx(file, buff, true, rx, matcher_id);
 772		if (ret < 0)
 773			return ret;
 774	}
 775
 776	if (tx->nic_tbl) {
 777		ret = dr_dump_matcher_rx_tx(file, buff, false, tx, matcher_id);
 778		if (ret < 0)
 779			return ret;
 780	}
 781
 782	return 0;
 783}
 784
 785static int
 786dr_dump_matcher_all(struct seq_file *file, struct mlx5dr_matcher *matcher)
 787{
 788	struct mlx5dr_rule *rule;
 789	int ret;
 790
 791	ret = dr_dump_matcher(file, matcher);
 792	if (ret < 0)
 793		return ret;
 794
 795	list_for_each_entry(rule, &matcher->dbg_rule_list, dbg_node) {
 796		ret = dr_dump_rule(file, rule);
 797		if (ret < 0)
 798			return ret;
 799	}
 800
 801	return 0;
 802}
 803
 804static int
 805dr_dump_table_rx_tx(struct seq_file *file, char *buff, bool is_rx,
 806		    struct mlx5dr_table_rx_tx *table_rx_tx,
 807		    const u64 table_id)
 808{
 809	enum dr_dump_rec_type rec_type;
 810	u64 s_icm_addr;
 811	int ret;
 812
 813	rec_type = is_rx ? DR_DUMP_REC_TYPE_TABLE_RX :
 814			   DR_DUMP_REC_TYPE_TABLE_TX;
 815
 816	s_icm_addr = mlx5dr_icm_pool_get_chunk_icm_addr(table_rx_tx->s_anchor->chunk);
 817	ret = snprintf(buff, MLX5DR_DEBUG_DUMP_BUFF_LENGTH,
 818		       "%d,0x%llx,0x%llx\n", rec_type, table_id,
 819		       dr_dump_icm_to_idx(s_icm_addr));
 820	if (ret < 0)
 821		return ret;
 822
 823	ret = mlx5dr_dbg_dump_data_print(file, buff, ret);
 824	if (ret)
 825		return ret;
 826
 827	return 0;
 828}
 829
 830static noinline_for_stack int
 831dr_dump_table(struct seq_file *file, struct mlx5dr_table *table)
 832{
 833	struct mlx5dr_table_rx_tx *rx = &table->rx;
 834	struct mlx5dr_table_rx_tx *tx = &table->tx;
 835	char buff[MLX5DR_DEBUG_DUMP_BUFF_LENGTH];
 836	int ret;
 837
 838	ret = snprintf(buff, MLX5DR_DEBUG_DUMP_BUFF_LENGTH,
 839		       "%d,0x%llx,0x%llx,%d,%d\n", DR_DUMP_REC_TYPE_TABLE,
 840		       DR_DBG_PTR_TO_ID(table), DR_DBG_PTR_TO_ID(table->dmn),
 841		       table->table_type, table->level);
 842	if (ret < 0)
 843		return ret;
 844
 845	ret = mlx5dr_dbg_dump_data_print(file, buff, ret);
 846	if (ret)
 847		return ret;
 848
 849	if (rx->nic_dmn) {
 850		ret = dr_dump_table_rx_tx(file, buff, true, rx,
 851					  DR_DBG_PTR_TO_ID(table));
 852		if (ret < 0)
 853			return ret;
 854	}
 855
 856	if (tx->nic_dmn) {
 857		ret = dr_dump_table_rx_tx(file, buff, false, tx,
 858					  DR_DBG_PTR_TO_ID(table));
 859		if (ret < 0)
 860			return ret;
 861	}
 862	return 0;
 863}
 864
 865static int dr_dump_table_all(struct seq_file *file, struct mlx5dr_table *tbl)
 866{
 867	struct mlx5dr_matcher *matcher;
 868	int ret;
 869
 870	ret = dr_dump_table(file, tbl);
 871	if (ret < 0)
 872		return ret;
 873
 874	list_for_each_entry(matcher, &tbl->matcher_list, list_node) {
 875		ret = dr_dump_matcher_all(file, matcher);
 876		if (ret < 0)
 877			return ret;
 878	}
 879	return 0;
 880}
 881
 882static int
 883dr_dump_send_ring(struct seq_file *file, char *buff,
 884		  struct mlx5dr_send_ring *ring,
 885		  const u64 domain_id)
 886{
 887	int ret;
 888
 889	ret = snprintf(buff, MLX5DR_DEBUG_DUMP_BUFF_LENGTH,
 890		       "%d,0x%llx,0x%llx,0x%x,0x%x\n",
 891		       DR_DUMP_REC_TYPE_DOMAIN_SEND_RING,
 892		       DR_DBG_PTR_TO_ID(ring), domain_id,
 893		       ring->cq->mcq.cqn, ring->qp->qpn);
 894	if (ret < 0)
 895		return ret;
 896
 897	ret = mlx5dr_dbg_dump_data_print(file, buff, ret);
 898	if (ret)
 899		return ret;
 900
 901	return 0;
 902}
 903
 904static int
 905dr_dump_domain_info_flex_parser(struct seq_file *file,
 906				char *buff,
 907				const char *flex_parser_name,
 908				const u8 flex_parser_value,
 909				const u64 domain_id)
 910{
 911	int ret;
 912
 913	ret = snprintf(buff, MLX5DR_DEBUG_DUMP_BUFF_LENGTH,
 914		       "%d,0x%llx,%s,0x%x\n",
 915		       DR_DUMP_REC_TYPE_DOMAIN_INFO_FLEX_PARSER, domain_id,
 916		       flex_parser_name, flex_parser_value);
 917	if (ret < 0)
 918		return ret;
 919
 920	ret = mlx5dr_dbg_dump_data_print(file, buff, ret);
 921	if (ret)
 922		return ret;
 923
 924	return 0;
 925}
 926
 927static int
 928dr_dump_domain_info_caps(struct seq_file *file, char *buff,
 929			 struct mlx5dr_cmd_caps *caps,
 930			 const u64 domain_id)
 931{
 932	struct mlx5dr_cmd_vport_cap *vport_caps;
 933	unsigned long i, vports_num;
 934	int ret;
 935
 936	xa_for_each(&caps->vports.vports_caps_xa, vports_num, vport_caps)
 937		; /* count the number of vports in xarray */
 938
 939	ret = snprintf(buff, MLX5DR_DEBUG_DUMP_BUFF_LENGTH,
 940		       "%d,0x%llx,0x%x,0x%llx,0x%llx,0x%x,%lu,%d\n",
 941		       DR_DUMP_REC_TYPE_DOMAIN_INFO_CAPS, domain_id, caps->gvmi,
 942		       caps->nic_rx_drop_address, caps->nic_tx_drop_address,
 943		       caps->flex_protocols, vports_num, caps->eswitch_manager);
 944	if (ret < 0)
 945		return ret;
 946
 947	ret = mlx5dr_dbg_dump_data_print(file, buff, ret);
 948	if (ret)
 949		return ret;
 950
 951	xa_for_each(&caps->vports.vports_caps_xa, i, vport_caps) {
 952		vport_caps = xa_load(&caps->vports.vports_caps_xa, i);
 953
 954		ret = snprintf(buff, MLX5DR_DEBUG_DUMP_BUFF_LENGTH,
 955			       "%d,0x%llx,%lu,0x%x,0x%llx,0x%llx\n",
 956			       DR_DUMP_REC_TYPE_DOMAIN_INFO_VPORT,
 957			       domain_id, i, vport_caps->vport_gvmi,
 958			       vport_caps->icm_address_rx,
 959			       vport_caps->icm_address_tx);
 960		if (ret < 0)
 961			return ret;
 962
 963		ret = mlx5dr_dbg_dump_data_print(file, buff, ret);
 964		if (ret)
 965			return ret;
 966	}
 967	return 0;
 968}
 969
 970static int
 971dr_dump_domain_info(struct seq_file *file, char *buff,
 972		    struct mlx5dr_domain_info *info,
 973		    const u64 domain_id)
 974{
 975	int ret;
 976
 977	ret = dr_dump_domain_info_caps(file, buff, &info->caps, domain_id);
 978	if (ret < 0)
 979		return ret;
 980
 981	ret = dr_dump_domain_info_flex_parser(file, buff, "icmp_dw0",
 982					      info->caps.flex_parser_id_icmp_dw0,
 983					      domain_id);
 984	if (ret < 0)
 985		return ret;
 986
 987	ret = dr_dump_domain_info_flex_parser(file, buff, "icmp_dw1",
 988					      info->caps.flex_parser_id_icmp_dw1,
 989					      domain_id);
 990	if (ret < 0)
 991		return ret;
 992
 993	ret = dr_dump_domain_info_flex_parser(file, buff, "icmpv6_dw0",
 994					      info->caps.flex_parser_id_icmpv6_dw0,
 995					      domain_id);
 996	if (ret < 0)
 997		return ret;
 998
 999	ret = dr_dump_domain_info_flex_parser(file, buff, "icmpv6_dw1",
1000					      info->caps.flex_parser_id_icmpv6_dw1,
1001					      domain_id);
1002	if (ret < 0)
1003		return ret;
1004
1005	return 0;
1006}
1007
1008static noinline_for_stack int
1009dr_dump_domain(struct seq_file *file, struct mlx5dr_domain *dmn)
1010{
1011	char buff[MLX5DR_DEBUG_DUMP_BUFF_LENGTH];
1012	u64 domain_id = DR_DBG_PTR_TO_ID(dmn);
1013	int ret;
1014
1015	ret = snprintf(buff, MLX5DR_DEBUG_DUMP_BUFF_LENGTH,
1016		       "%d,0x%llx,%d,0%x,%d,%u.%u.%u,%s,%d,%u,%u,%u\n",
1017		       DR_DUMP_REC_TYPE_DOMAIN,
1018		       domain_id, dmn->type, dmn->info.caps.gvmi,
1019		       dmn->info.supp_sw_steering,
1020		       /* package version */
1021		       LINUX_VERSION_MAJOR, LINUX_VERSION_PATCHLEVEL,
1022		       LINUX_VERSION_SUBLEVEL,
1023		       pci_name(dmn->mdev->pdev),
1024		       0, /* domain flags */
1025		       dmn->num_buddies[DR_ICM_TYPE_STE],
1026		       dmn->num_buddies[DR_ICM_TYPE_MODIFY_ACTION],
1027		       dmn->num_buddies[DR_ICM_TYPE_MODIFY_HDR_PTRN]);
1028	if (ret < 0)
1029		return ret;
1030
1031	ret = mlx5dr_dbg_dump_data_print(file, buff, ret);
1032	if (ret)
1033		return ret;
1034
1035	ret = dr_dump_domain_info(file, buff, &dmn->info, domain_id);
1036	if (ret < 0)
1037		return ret;
1038
1039	if (dmn->info.supp_sw_steering) {
1040		ret = dr_dump_send_ring(file, buff, dmn->send_ring, domain_id);
1041		if (ret < 0)
1042			return ret;
1043	}
1044
1045	return 0;
1046}
1047
1048static int dr_dump_domain_all(struct seq_file *file, struct mlx5dr_domain *dmn)
1049{
1050	struct mlx5dr_table *tbl;
1051	int ret;
1052
1053	mlx5dr_domain_lock(dmn);
1054	mutex_lock(&dmn->dump_info.dbg_mutex);
1055
1056	ret = dr_dump_domain(file, dmn);
1057	if (ret < 0)
1058		goto unlock_mutex;
1059
1060	list_for_each_entry(tbl, &dmn->dbg_tbl_list, dbg_node) {
1061		ret = dr_dump_table_all(file, tbl);
1062		if (ret < 0)
1063			break;
1064	}
1065
1066unlock_mutex:
1067	mutex_unlock(&dmn->dump_info.dbg_mutex);
1068	mlx5dr_domain_unlock(dmn);
1069	return ret;
1070}
1071
1072static void *
1073dr_dump_start(struct seq_file *file, loff_t *pos)
1074{
1075	struct mlx5dr_domain *dmn = file->private;
1076	struct mlx5dr_dbg_dump_data *dump_data;
1077
1078	if (atomic_read(&dmn->dump_info.state) != MLX5DR_DEBUG_DUMP_STATE_FREE) {
1079		mlx5_core_warn(dmn->mdev, "Dump already in progress\n");
1080		return ERR_PTR(-EBUSY);
1081	}
1082
1083	atomic_set(&dmn->dump_info.state, MLX5DR_DEBUG_DUMP_STATE_IN_PROGRESS);
1084	dump_data = dmn->dump_info.dump_data;
1085
1086	if (dump_data) {
1087		return seq_list_start(&dump_data->buff_list, *pos);
1088	} else if (*pos == 0) {
1089		dump_data = mlx5dr_dbg_create_dump_data();
1090		if (!dump_data)
1091			goto exit;
1092
1093		dmn->dump_info.dump_data = dump_data;
1094		if (dr_dump_domain_all(file, dmn)) {
1095			mlx5dr_dbg_destroy_dump_data(dump_data);
1096			dmn->dump_info.dump_data = NULL;
1097			goto exit;
1098		}
1099
1100		return seq_list_start(&dump_data->buff_list, *pos);
1101	}
1102
1103exit:
1104	atomic_set(&dmn->dump_info.state, MLX5DR_DEBUG_DUMP_STATE_FREE);
1105	return NULL;
1106}
1107
1108static void *
1109dr_dump_next(struct seq_file *file, void *v, loff_t *pos)
1110{
1111	struct mlx5dr_domain *dmn = file->private;
1112	struct mlx5dr_dbg_dump_data *dump_data;
1113
1114	dump_data = dmn->dump_info.dump_data;
1115
1116	return seq_list_next(v, &dump_data->buff_list, pos);
1117}
1118
1119static void
1120dr_dump_stop(struct seq_file *file, void *v)
1121{
1122	struct mlx5dr_domain *dmn = file->private;
1123	struct mlx5dr_dbg_dump_data *dump_data;
1124
1125	if (v && IS_ERR(v))
1126		return;
1127
1128	if (!v) {
1129		dump_data = dmn->dump_info.dump_data;
1130		if (dump_data) {
1131			mlx5dr_dbg_destroy_dump_data(dump_data);
1132			dmn->dump_info.dump_data = NULL;
1133		}
1134	}
1135
1136	atomic_set(&dmn->dump_info.state, MLX5DR_DEBUG_DUMP_STATE_FREE);
1137}
1138
1139static int
1140dr_dump_show(struct seq_file *file, void *v)
1141{
1142	struct mlx5dr_dbg_dump_buff *entry;
1143
1144	entry = list_entry(v, struct mlx5dr_dbg_dump_buff, node);
1145	seq_printf(file, "%s", entry->buff);
1146
1147	return 0;
1148}
1149
1150static const struct seq_operations dr_dump_sops = {
1151	.start	= dr_dump_start,
1152	.next	= dr_dump_next,
1153	.stop	= dr_dump_stop,
1154	.show	= dr_dump_show,
1155};
1156DEFINE_SEQ_ATTRIBUTE(dr_dump);
1157
1158void mlx5dr_dbg_init_dump(struct mlx5dr_domain *dmn)
1159{
1160	struct mlx5_core_dev *dev = dmn->mdev;
1161	char file_name[128];
1162
1163	if (dmn->type != MLX5DR_DOMAIN_TYPE_FDB) {
1164		mlx5_core_warn(dev,
1165			       "Steering dump is not supported for NIC RX/TX domains\n");
1166		return;
1167	}
1168
1169	dmn->dump_info.steering_debugfs =
1170		debugfs_create_dir("steering", mlx5_debugfs_get_dev_root(dev));
1171	dmn->dump_info.fdb_debugfs =
1172		debugfs_create_dir("fdb", dmn->dump_info.steering_debugfs);
1173
1174	sprintf(file_name, "dmn_%p", dmn);
1175	debugfs_create_file(file_name, 0444, dmn->dump_info.fdb_debugfs,
1176			    dmn, &dr_dump_fops);
1177
1178	INIT_LIST_HEAD(&dmn->dbg_tbl_list);
1179	mutex_init(&dmn->dump_info.dbg_mutex);
1180}
1181
1182void mlx5dr_dbg_uninit_dump(struct mlx5dr_domain *dmn)
1183{
1184	debugfs_remove_recursive(dmn->dump_info.steering_debugfs);
1185	mutex_destroy(&dmn->dump_info.dbg_mutex);
1186}
~/ Read-only file preview.