root/drivers/net/ethernet/qlogic/qed/qed_debug.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. cond5
  2. cond7
  3. cond6
  4. cond9
  5. cond10
  6. cond4
  7. cond0
  8. cond1
  9. cond11
  10. cond12
  11. cond3
  12. cond13
  13. cond8
  14. cond2
  15. qed_read_unaligned_dword
  16. qed_grc_set_param
  17. qed_grc_get_param
  18. qed_dbg_grc_init_params
  19. qed_dbg_dev_init
  20. get_dbg_bus_block_desc
  21. qed_read_storm_fw_info
  22. qed_dump_str
  23. qed_dump_align
  24. qed_dump_str_param
  25. qed_dump_num_param
  26. qed_dump_fw_ver_param
  27. qed_dump_mfw_ver_param
  28. qed_dump_section_hdr
  29. qed_dump_common_global_params
  30. qed_dump_last_section
  31. qed_update_blocks_reset_state
  32. qed_bus_enable_dbg_block
  33. qed_bus_reset_dbg_block
  34. qed_bus_set_framing_mode
  35. qed_bus_enable_clients
  36. qed_is_mode_match
  37. qed_grc_is_included
  38. qed_grc_is_storm_included
  39. qed_grc_is_mem_included
  40. qed_grc_stall_storms
  41. qed_grc_unreset_blocks
  42. qed_get_block_attn_data
  43. qed_get_block_attn_regs
  44. qed_grc_clear_all_prty
  45. qed_grc_dump_regs_hdr
  46. qed_read_regs
  47. qed_grc_dump_addr_range
  48. qed_grc_dump_reg_entry_hdr
  49. qed_grc_dump_reg_entry
  50. qed_grc_dump_reg_entry_skip
  51. qed_grc_dump_regs_entries
  52. qed_grc_dump_split_data
  53. qed_grc_dump_registers
  54. qed_grc_dump_reset_regs
  55. qed_grc_dump_modified_regs
  56. qed_grc_dump_special_regs
  57. qed_grc_dump_mem_hdr
  58. qed_grc_dump_mem
  59. qed_grc_dump_mem_entries
  60. qed_grc_dump_memories
  61. qed_grc_dump_ctx_data
  62. qed_grc_dump_ctx
  63. qed_grc_dump_iors
  64. qed_grc_dump_vfc_cam
  65. qed_grc_dump_vfc_ram
  66. qed_grc_dump_vfc
  67. qed_grc_dump_rss
  68. qed_grc_dump_big_ram
  69. qed_grc_dump_mcp
  70. qed_grc_dump_phy
  71. qed_config_dbg_line
  72. qed_grc_dump_static_debug
  73. qed_grc_dump
  74. qed_idle_chk_dump_failure
  75. qed_idle_chk_dump_rule_entries
  76. qed_idle_chk_dump
  77. qed_find_nvram_image
  78. qed_nvram_read
  79. qed_mcp_trace_get_data_info
  80. qed_mcp_trace_get_meta_info
  81. qed_mcp_trace_read_meta
  82. qed_mcp_trace_dump
  83. qed_reg_fifo_dump
  84. qed_igu_fifo_dump
  85. qed_protection_override_dump
  86. qed_fw_asserts_dump
  87. qed_dbg_set_bin_ptr
  88. qed_read_fw_info
  89. qed_dbg_grc_config
  90. qed_dbg_grc_set_params_default
  91. qed_dbg_grc_get_dump_buf_size
  92. qed_dbg_grc_dump
  93. qed_dbg_idle_chk_get_dump_buf_size
  94. qed_dbg_idle_chk_dump
  95. qed_dbg_mcp_trace_get_dump_buf_size
  96. qed_dbg_mcp_trace_dump
  97. qed_dbg_reg_fifo_get_dump_buf_size
  98. qed_dbg_reg_fifo_dump
  99. qed_dbg_igu_fifo_get_dump_buf_size
  100. qed_dbg_igu_fifo_dump
  101. qed_dbg_protection_override_get_dump_buf_size
  102. qed_dbg_protection_override_dump
  103. qed_dbg_fw_asserts_get_dump_buf_size
  104. qed_dbg_fw_asserts_dump
  105. qed_dbg_read_attn
  106. qed_cyclic_add
  107. qed_cyclic_sub
  108. qed_read_from_cyclic_buf
  109. qed_read_byte_from_buf
  110. qed_read_dword_from_buf
  111. qed_read_str_from_buf
  112. qed_get_buf_ptr
  113. qed_read_param
  114. qed_read_section_hdr
  115. qed_print_section_params
  116. qed_dbg_get_user_data
  117. qed_parse_idle_chk_dump_rules
  118. qed_parse_idle_chk_dump
  119. qed_mcp_trace_alloc_meta_data
  120. qed_parse_mcp_trace_buf
  121. qed_parse_mcp_trace_dump
  122. qed_parse_reg_fifo_dump
  123. qed_parse_igu_fifo_element
  124. qed_parse_igu_fifo_dump
  125. qed_parse_protection_override_dump
  126. qed_parse_fw_asserts_dump
  127. qed_dbg_user_set_bin_ptr
  128. qed_dbg_alloc_user_data
  129. qed_dbg_get_status_str
  130. qed_get_idle_chk_results_buf_size
  131. qed_print_idle_chk_results
  132. qed_dbg_mcp_trace_set_meta_data
  133. qed_get_mcp_trace_results_buf_size
  134. qed_print_mcp_trace_results
  135. qed_print_mcp_trace_results_cont
  136. qed_print_mcp_trace_line
  137. qed_mcp_trace_free_meta_data
  138. qed_get_reg_fifo_results_buf_size
  139. qed_print_reg_fifo_results
  140. qed_get_igu_fifo_results_buf_size
  141. qed_print_igu_fifo_results
  142. qed_get_protection_override_results_buf_size
  143. qed_print_protection_override_results
  144. qed_get_fw_asserts_results_buf_size
  145. qed_print_fw_asserts_results
  146. qed_dbg_parse_attn
  147. qed_print_idle_chk_results_wrapper
  148. qed_dbg_print_feature
  149. format_feature
  150. qed_dbg_dump
  151. qed_dbg_grc
  152. qed_dbg_grc_size
  153. qed_dbg_idle_chk
  154. qed_dbg_idle_chk_size
  155. qed_dbg_reg_fifo
  156. qed_dbg_reg_fifo_size
  157. qed_dbg_igu_fifo
  158. qed_dbg_igu_fifo_size
  159. qed_dbg_nvm_image_length
  160. qed_dbg_nvm_image
  161. qed_dbg_protection_override
  162. qed_dbg_protection_override_size
  163. qed_dbg_fw_asserts
  164. qed_dbg_fw_asserts_size
  165. qed_dbg_mcp_trace
  166. qed_dbg_mcp_trace_size
  167. qed_calc_regdump_header
  168. qed_dbg_all_data
  169. qed_dbg_all_data_size
  170. qed_dbg_feature
  171. qed_dbg_feature_size
  172. qed_get_debug_engine
  173. qed_set_debug_engine
  174. qed_dbg_pf_init
  175. qed_dbg_pf_exit

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /* QLogic qed NIC Driver
   3  * Copyright (c) 2015 QLogic Corporation
   4  */
   5 
   6 #include <linux/module.h>
   7 #include <linux/vmalloc.h>
   8 #include <linux/crc32.h>
   9 #include "qed.h"
  10 #include "qed_hsi.h"
  11 #include "qed_hw.h"
  12 #include "qed_mcp.h"
  13 #include "qed_reg_addr.h"
  14 
  15 /* Memory groups enum */
  16 enum mem_groups {
  17         MEM_GROUP_PXP_MEM,
  18         MEM_GROUP_DMAE_MEM,
  19         MEM_GROUP_CM_MEM,
  20         MEM_GROUP_QM_MEM,
  21         MEM_GROUP_DORQ_MEM,
  22         MEM_GROUP_BRB_RAM,
  23         MEM_GROUP_BRB_MEM,
  24         MEM_GROUP_PRS_MEM,
  25         MEM_GROUP_IOR,
  26         MEM_GROUP_BTB_RAM,
  27         MEM_GROUP_CONN_CFC_MEM,
  28         MEM_GROUP_TASK_CFC_MEM,
  29         MEM_GROUP_CAU_PI,
  30         MEM_GROUP_CAU_MEM,
  31         MEM_GROUP_PXP_ILT,
  32         MEM_GROUP_TM_MEM,
  33         MEM_GROUP_SDM_MEM,
  34         MEM_GROUP_PBUF,
  35         MEM_GROUP_RAM,
  36         MEM_GROUP_MULD_MEM,
  37         MEM_GROUP_BTB_MEM,
  38         MEM_GROUP_RDIF_CTX,
  39         MEM_GROUP_TDIF_CTX,
  40         MEM_GROUP_CFC_MEM,
  41         MEM_GROUP_IGU_MEM,
  42         MEM_GROUP_IGU_MSIX,
  43         MEM_GROUP_CAU_SB,
  44         MEM_GROUP_BMB_RAM,
  45         MEM_GROUP_BMB_MEM,
  46         MEM_GROUPS_NUM
  47 };
  48 
  49 /* Memory groups names */
  50 static const char * const s_mem_group_names[] = {
  51         "PXP_MEM",
  52         "DMAE_MEM",
  53         "CM_MEM",
  54         "QM_MEM",
  55         "DORQ_MEM",
  56         "BRB_RAM",
  57         "BRB_MEM",
  58         "PRS_MEM",
  59         "IOR",
  60         "BTB_RAM",
  61         "CONN_CFC_MEM",
  62         "TASK_CFC_MEM",
  63         "CAU_PI",
  64         "CAU_MEM",
  65         "PXP_ILT",
  66         "TM_MEM",
  67         "SDM_MEM",
  68         "PBUF",
  69         "RAM",
  70         "MULD_MEM",
  71         "BTB_MEM",
  72         "RDIF_CTX",
  73         "TDIF_CTX",
  74         "CFC_MEM",
  75         "IGU_MEM",
  76         "IGU_MSIX",
  77         "CAU_SB",
  78         "BMB_RAM",
  79         "BMB_MEM",
  80 };
  81 
  82 /* Idle check conditions */
  83 
  84 static u32 cond5(const u32 *r, const u32 *imm)
  85 {
  86         return ((r[0] & imm[0]) != imm[1]) && ((r[1] & imm[2]) != imm[3]);
  87 }
  88 
  89 static u32 cond7(const u32 *r, const u32 *imm)
  90 {
  91         return ((r[0] >> imm[0]) & imm[1]) != imm[2];
  92 }
  93 
  94 static u32 cond6(const u32 *r, const u32 *imm)
  95 {
  96         return (r[0] & imm[0]) != imm[1];
  97 }
  98 
  99 static u32 cond9(const u32 *r, const u32 *imm)
 100 {
 101         return ((r[0] & imm[0]) >> imm[1]) !=
 102             (((r[0] & imm[2]) >> imm[3]) | ((r[1] & imm[4]) << imm[5]));
 103 }
 104 
 105 static u32 cond10(const u32 *r, const u32 *imm)
 106 {
 107         return ((r[0] & imm[0]) >> imm[1]) != (r[0] & imm[2]);
 108 }
 109 
 110 static u32 cond4(const u32 *r, const u32 *imm)
 111 {
 112         return (r[0] & ~imm[0]) != imm[1];
 113 }
 114 
 115 static u32 cond0(const u32 *r, const u32 *imm)
 116 {
 117         return (r[0] & ~r[1]) != imm[0];
 118 }
 119 
 120 static u32 cond1(const u32 *r, const u32 *imm)
 121 {
 122         return r[0] != imm[0];
 123 }
 124 
 125 static u32 cond11(const u32 *r, const u32 *imm)
 126 {
 127         return r[0] != r[1] && r[2] == imm[0];
 128 }
 129 
 130 static u32 cond12(const u32 *r, const u32 *imm)
 131 {
 132         return r[0] != r[1] && r[2] > imm[0];
 133 }
 134 
 135 static u32 cond3(const u32 *r, const u32 *imm)
 136 {
 137         return r[0] != r[1];
 138 }
 139 
 140 static u32 cond13(const u32 *r, const u32 *imm)
 141 {
 142         return r[0] & imm[0];
 143 }
 144 
 145 static u32 cond8(const u32 *r, const u32 *imm)
 146 {
 147         return r[0] < (r[1] - imm[0]);
 148 }
 149 
 150 static u32 cond2(const u32 *r, const u32 *imm)
 151 {
 152         return r[0] > imm[0];
 153 }
 154 
 155 /* Array of Idle Check conditions */
 156 static u32(*cond_arr[]) (const u32 *r, const u32 *imm) = {
 157         cond0,
 158         cond1,
 159         cond2,
 160         cond3,
 161         cond4,
 162         cond5,
 163         cond6,
 164         cond7,
 165         cond8,
 166         cond9,
 167         cond10,
 168         cond11,
 169         cond12,
 170         cond13,
 171 };
 172 
 173 /******************************* Data Types **********************************/
 174 
 175 enum platform_ids {
 176         PLATFORM_ASIC,
 177         PLATFORM_RESERVED,
 178         PLATFORM_RESERVED2,
 179         PLATFORM_RESERVED3,
 180         MAX_PLATFORM_IDS
 181 };
 182 
 183 /* Chip constant definitions */
 184 struct chip_defs {
 185         const char *name;
 186 };
 187 
 188 /* Platform constant definitions */
 189 struct platform_defs {
 190         const char *name;
 191         u32 delay_factor;
 192         u32 dmae_thresh;
 193         u32 log_thresh;
 194 };
 195 
 196 /* Storm constant definitions.
 197  * Addresses are in bytes, sizes are in quad-regs.
 198  */
 199 struct storm_defs {
 200         char letter;
 201         enum block_id block_id;
 202         enum dbg_bus_clients dbg_client_id[MAX_CHIP_IDS];
 203         bool has_vfc;
 204         u32 sem_fast_mem_addr;
 205         u32 sem_frame_mode_addr;
 206         u32 sem_slow_enable_addr;
 207         u32 sem_slow_mode_addr;
 208         u32 sem_slow_mode1_conf_addr;
 209         u32 sem_sync_dbg_empty_addr;
 210         u32 sem_slow_dbg_empty_addr;
 211         u32 cm_ctx_wr_addr;
 212         u32 cm_conn_ag_ctx_lid_size;
 213         u32 cm_conn_ag_ctx_rd_addr;
 214         u32 cm_conn_st_ctx_lid_size;
 215         u32 cm_conn_st_ctx_rd_addr;
 216         u32 cm_task_ag_ctx_lid_size;
 217         u32 cm_task_ag_ctx_rd_addr;
 218         u32 cm_task_st_ctx_lid_size;
 219         u32 cm_task_st_ctx_rd_addr;
 220 };
 221 
 222 /* Block constant definitions */
 223 struct block_defs {
 224         const char *name;
 225         bool exists[MAX_CHIP_IDS];
 226         bool associated_to_storm;
 227 
 228         /* Valid only if associated_to_storm is true */
 229         u32 storm_id;
 230         enum dbg_bus_clients dbg_client_id[MAX_CHIP_IDS];
 231         u32 dbg_select_addr;
 232         u32 dbg_enable_addr;
 233         u32 dbg_shift_addr;
 234         u32 dbg_force_valid_addr;
 235         u32 dbg_force_frame_addr;
 236         bool has_reset_bit;
 237 
 238         /* If true, block is taken out of reset before dump */
 239         bool unreset;
 240         enum dbg_reset_regs reset_reg;
 241 
 242         /* Bit offset in reset register */
 243         u8 reset_bit_offset;
 244 };
 245 
 246 /* Reset register definitions */
 247 struct reset_reg_defs {
 248         u32 addr;
 249         bool exists[MAX_CHIP_IDS];
 250         u32 unreset_val[MAX_CHIP_IDS];
 251 };
 252 
 253 struct grc_param_defs {
 254         u32 default_val[MAX_CHIP_IDS];
 255         u32 min;
 256         u32 max;
 257         bool is_preset;
 258         bool is_persistent;
 259         u32 exclude_all_preset_val;
 260         u32 crash_preset_val;
 261 };
 262 
 263 /* Address is in 128b units. Width is in bits. */
 264 struct rss_mem_defs {
 265         const char *mem_name;
 266         const char *type_name;
 267         u32 addr;
 268         u32 entry_width;
 269         u32 num_entries[MAX_CHIP_IDS];
 270 };
 271 
 272 struct vfc_ram_defs {
 273         const char *mem_name;
 274         const char *type_name;
 275         u32 base_row;
 276         u32 num_rows;
 277 };
 278 
 279 struct big_ram_defs {
 280         const char *instance_name;
 281         enum mem_groups mem_group_id;
 282         enum mem_groups ram_mem_group_id;
 283         enum dbg_grc_params grc_param;
 284         u32 addr_reg_addr;
 285         u32 data_reg_addr;
 286         u32 is_256b_reg_addr;
 287         u32 is_256b_bit_offset[MAX_CHIP_IDS];
 288         u32 ram_size[MAX_CHIP_IDS]; /* In dwords */
 289 };
 290 
 291 struct phy_defs {
 292         const char *phy_name;
 293 
 294         /* PHY base GRC address */
 295         u32 base_addr;
 296 
 297         /* Relative address of indirect TBUS address register (bits 0..7) */
 298         u32 tbus_addr_lo_addr;
 299 
 300         /* Relative address of indirect TBUS address register (bits 8..10) */
 301         u32 tbus_addr_hi_addr;
 302 
 303         /* Relative address of indirect TBUS data register (bits 0..7) */
 304         u32 tbus_data_lo_addr;
 305 
 306         /* Relative address of indirect TBUS data register (bits 8..11) */
 307         u32 tbus_data_hi_addr;
 308 };
 309 
 310 /* Split type definitions */
 311 struct split_type_defs {
 312         const char *name;
 313 };
 314 
 315 /******************************** Constants **********************************/
 316 
 317 #define MAX_LCIDS                       320
 318 #define MAX_LTIDS                       320
 319 
 320 #define NUM_IOR_SETS                    2
 321 #define IORS_PER_SET                    176
 322 #define IOR_SET_OFFSET(set_id)          ((set_id) * 256)
 323 
 324 #define BYTES_IN_DWORD                  sizeof(u32)
 325 
 326 /* In the macros below, size and offset are specified in bits */
 327 #define CEIL_DWORDS(size)               DIV_ROUND_UP(size, 32)
 328 #define FIELD_BIT_OFFSET(type, field)   type ## _ ## field ## _ ## OFFSET
 329 #define FIELD_BIT_SIZE(type, field)     type ## _ ## field ## _ ## SIZE
 330 #define FIELD_DWORD_OFFSET(type, field) \
 331          (int)(FIELD_BIT_OFFSET(type, field) / 32)
 332 #define FIELD_DWORD_SHIFT(type, field)  (FIELD_BIT_OFFSET(type, field) % 32)
 333 #define FIELD_BIT_MASK(type, field) \
 334         (((1 << FIELD_BIT_SIZE(type, field)) - 1) << \
 335          FIELD_DWORD_SHIFT(type, field))
 336 
 337 #define SET_VAR_FIELD(var, type, field, val) \
 338         do { \
 339                 var[FIELD_DWORD_OFFSET(type, field)] &= \
 340                 (~FIELD_BIT_MASK(type, field)); \
 341                 var[FIELD_DWORD_OFFSET(type, field)] |= \
 342                 (val) << FIELD_DWORD_SHIFT(type, field); \
 343         } while (0)
 344 
 345 #define ARR_REG_WR(dev, ptt, addr, arr, arr_size) \
 346         do { \
 347                 for (i = 0; i < (arr_size); i++) \
 348                         qed_wr(dev, ptt, addr,  (arr)[i]); \
 349         } while (0)
 350 
 351 #define ARR_REG_RD(dev, ptt, addr, arr, arr_size) \
 352         do { \
 353                 for (i = 0; i < (arr_size); i++) \
 354                         (arr)[i] = qed_rd(dev, ptt, addr); \
 355         } while (0)
 356 
 357 #define DWORDS_TO_BYTES(dwords)         ((dwords) * BYTES_IN_DWORD)
 358 #define BYTES_TO_DWORDS(bytes)          ((bytes) / BYTES_IN_DWORD)
 359 
 360 /* Extra lines include a signature line + optional latency events line */
 361 #define NUM_EXTRA_DBG_LINES(block_desc) \
 362         (1 + ((block_desc)->has_latency_events ? 1 : 0))
 363 #define NUM_DBG_LINES(block_desc) \
 364         ((block_desc)->num_of_lines + NUM_EXTRA_DBG_LINES(block_desc))
 365 
 366 #define RAM_LINES_TO_DWORDS(lines)      ((lines) * 2)
 367 #define RAM_LINES_TO_BYTES(lines) \
 368         DWORDS_TO_BYTES(RAM_LINES_TO_DWORDS(lines))
 369 
 370 #define REG_DUMP_LEN_SHIFT              24
 371 #define MEM_DUMP_ENTRY_SIZE_DWORDS \
 372         BYTES_TO_DWORDS(sizeof(struct dbg_dump_mem))
 373 
 374 #define IDLE_CHK_RULE_SIZE_DWORDS \
 375         BYTES_TO_DWORDS(sizeof(struct dbg_idle_chk_rule))
 376 
 377 #define IDLE_CHK_RESULT_HDR_DWORDS \
 378         BYTES_TO_DWORDS(sizeof(struct dbg_idle_chk_result_hdr))
 379 
 380 #define IDLE_CHK_RESULT_REG_HDR_DWORDS \
 381         BYTES_TO_DWORDS(sizeof(struct dbg_idle_chk_result_reg_hdr))
 382 
 383 #define IDLE_CHK_MAX_ENTRIES_SIZE       32
 384 
 385 /* The sizes and offsets below are specified in bits */
 386 #define VFC_CAM_CMD_STRUCT_SIZE         64
 387 #define VFC_CAM_CMD_ROW_OFFSET          48
 388 #define VFC_CAM_CMD_ROW_SIZE            9
 389 #define VFC_CAM_ADDR_STRUCT_SIZE        16
 390 #define VFC_CAM_ADDR_OP_OFFSET          0
 391 #define VFC_CAM_ADDR_OP_SIZE            4
 392 #define VFC_CAM_RESP_STRUCT_SIZE        256
 393 #define VFC_RAM_ADDR_STRUCT_SIZE        16
 394 #define VFC_RAM_ADDR_OP_OFFSET          0
 395 #define VFC_RAM_ADDR_OP_SIZE            2
 396 #define VFC_RAM_ADDR_ROW_OFFSET         2
 397 #define VFC_RAM_ADDR_ROW_SIZE           10
 398 #define VFC_RAM_RESP_STRUCT_SIZE        256
 399 
 400 #define VFC_CAM_CMD_DWORDS              CEIL_DWORDS(VFC_CAM_CMD_STRUCT_SIZE)
 401 #define VFC_CAM_ADDR_DWORDS             CEIL_DWORDS(VFC_CAM_ADDR_STRUCT_SIZE)
 402 #define VFC_CAM_RESP_DWORDS             CEIL_DWORDS(VFC_CAM_RESP_STRUCT_SIZE)
 403 #define VFC_RAM_CMD_DWORDS              VFC_CAM_CMD_DWORDS
 404 #define VFC_RAM_ADDR_DWORDS             CEIL_DWORDS(VFC_RAM_ADDR_STRUCT_SIZE)
 405 #define VFC_RAM_RESP_DWORDS             CEIL_DWORDS(VFC_RAM_RESP_STRUCT_SIZE)
 406 
 407 #define NUM_VFC_RAM_TYPES               4
 408 
 409 #define VFC_CAM_NUM_ROWS                512
 410 
 411 #define VFC_OPCODE_CAM_RD               14
 412 #define VFC_OPCODE_RAM_RD               0
 413 
 414 #define NUM_RSS_MEM_TYPES               5
 415 
 416 #define NUM_BIG_RAM_TYPES               3
 417 #define BIG_RAM_NAME_LEN                3
 418 
 419 #define NUM_PHY_TBUS_ADDRESSES          2048
 420 #define PHY_DUMP_SIZE_DWORDS            (NUM_PHY_TBUS_ADDRESSES / 2)
 421 
 422 #define RESET_REG_UNRESET_OFFSET        4
 423 
 424 #define STALL_DELAY_MS                  500
 425 
 426 #define STATIC_DEBUG_LINE_DWORDS        9
 427 
 428 #define NUM_COMMON_GLOBAL_PARAMS        8
 429 
 430 #define FW_IMG_MAIN                     1
 431 
 432 #define REG_FIFO_ELEMENT_DWORDS         2
 433 #define REG_FIFO_DEPTH_ELEMENTS         32
 434 #define REG_FIFO_DEPTH_DWORDS \
 435         (REG_FIFO_ELEMENT_DWORDS * REG_FIFO_DEPTH_ELEMENTS)
 436 
 437 #define IGU_FIFO_ELEMENT_DWORDS         4
 438 #define IGU_FIFO_DEPTH_ELEMENTS         64
 439 #define IGU_FIFO_DEPTH_DWORDS \
 440         (IGU_FIFO_ELEMENT_DWORDS * IGU_FIFO_DEPTH_ELEMENTS)
 441 
 442 #define PROTECTION_OVERRIDE_ELEMENT_DWORDS      2
 443 #define PROTECTION_OVERRIDE_DEPTH_ELEMENTS      20
 444 #define PROTECTION_OVERRIDE_DEPTH_DWORDS \
 445         (PROTECTION_OVERRIDE_DEPTH_ELEMENTS * \
 446          PROTECTION_OVERRIDE_ELEMENT_DWORDS)
 447 
 448 #define MCP_SPAD_TRACE_OFFSIZE_ADDR \
 449         (MCP_REG_SCRATCH + \
 450          offsetof(struct static_init, sections[SPAD_SECTION_TRACE]))
 451 
 452 #define EMPTY_FW_VERSION_STR            "???_???_???_???"
 453 #define EMPTY_FW_IMAGE_STR              "???????????????"
 454 
 455 /***************************** Constant Arrays *******************************/
 456 
 457 struct dbg_array {
 458         const u32 *ptr;
 459         u32 size_in_dwords;
 460 };
 461 
 462 /* Debug arrays */
 463 static struct dbg_array s_dbg_arrays[MAX_BIN_DBG_BUFFER_TYPE] = { {NULL} };
 464 
 465 /* Chip constant definitions array */
 466 static struct chip_defs s_chip_defs[MAX_CHIP_IDS] = {
 467         {"bb"},
 468         {"ah"},
 469         {"reserved"},
 470 };
 471 
 472 /* Storm constant definitions array */
 473 static struct storm_defs s_storm_defs[] = {
 474         /* Tstorm */
 475         {'T', BLOCK_TSEM,
 476          {DBG_BUS_CLIENT_RBCT, DBG_BUS_CLIENT_RBCT,
 477           DBG_BUS_CLIENT_RBCT}, true,
 478          TSEM_REG_FAST_MEMORY,
 479          TSEM_REG_DBG_FRAME_MODE_BB_K2, TSEM_REG_SLOW_DBG_ACTIVE_BB_K2,
 480          TSEM_REG_SLOW_DBG_MODE_BB_K2, TSEM_REG_DBG_MODE1_CFG_BB_K2,
 481          TSEM_REG_SYNC_DBG_EMPTY, TSEM_REG_SLOW_DBG_EMPTY_BB_K2,
 482          TCM_REG_CTX_RBC_ACCS,
 483          4, TCM_REG_AGG_CON_CTX,
 484          16, TCM_REG_SM_CON_CTX,
 485          2, TCM_REG_AGG_TASK_CTX,
 486          4, TCM_REG_SM_TASK_CTX},
 487 
 488         /* Mstorm */
 489         {'M', BLOCK_MSEM,
 490          {DBG_BUS_CLIENT_RBCT, DBG_BUS_CLIENT_RBCM,
 491           DBG_BUS_CLIENT_RBCM}, false,
 492          MSEM_REG_FAST_MEMORY,
 493          MSEM_REG_DBG_FRAME_MODE_BB_K2, MSEM_REG_SLOW_DBG_ACTIVE_BB_K2,
 494          MSEM_REG_SLOW_DBG_MODE_BB_K2, MSEM_REG_DBG_MODE1_CFG_BB_K2,
 495          MSEM_REG_SYNC_DBG_EMPTY, MSEM_REG_SLOW_DBG_EMPTY_BB_K2,
 496          MCM_REG_CTX_RBC_ACCS,
 497          1, MCM_REG_AGG_CON_CTX,
 498          10, MCM_REG_SM_CON_CTX,
 499          2, MCM_REG_AGG_TASK_CTX,
 500          7, MCM_REG_SM_TASK_CTX},
 501 
 502         /* Ustorm */
 503         {'U', BLOCK_USEM,
 504          {DBG_BUS_CLIENT_RBCU, DBG_BUS_CLIENT_RBCU,
 505           DBG_BUS_CLIENT_RBCU}, false,
 506          USEM_REG_FAST_MEMORY,
 507          USEM_REG_DBG_FRAME_MODE_BB_K2, USEM_REG_SLOW_DBG_ACTIVE_BB_K2,
 508          USEM_REG_SLOW_DBG_MODE_BB_K2, USEM_REG_DBG_MODE1_CFG_BB_K2,
 509          USEM_REG_SYNC_DBG_EMPTY, USEM_REG_SLOW_DBG_EMPTY_BB_K2,
 510          UCM_REG_CTX_RBC_ACCS,
 511          2, UCM_REG_AGG_CON_CTX,
 512          13, UCM_REG_SM_CON_CTX,
 513          3, UCM_REG_AGG_TASK_CTX,
 514          3, UCM_REG_SM_TASK_CTX},
 515 
 516         /* Xstorm */
 517         {'X', BLOCK_XSEM,
 518          {DBG_BUS_CLIENT_RBCX, DBG_BUS_CLIENT_RBCX,
 519           DBG_BUS_CLIENT_RBCX}, false,
 520          XSEM_REG_FAST_MEMORY,
 521          XSEM_REG_DBG_FRAME_MODE_BB_K2, XSEM_REG_SLOW_DBG_ACTIVE_BB_K2,
 522          XSEM_REG_SLOW_DBG_MODE_BB_K2, XSEM_REG_DBG_MODE1_CFG_BB_K2,
 523          XSEM_REG_SYNC_DBG_EMPTY, XSEM_REG_SLOW_DBG_EMPTY_BB_K2,
 524          XCM_REG_CTX_RBC_ACCS,
 525          9, XCM_REG_AGG_CON_CTX,
 526          15, XCM_REG_SM_CON_CTX,
 527          0, 0,
 528          0, 0},
 529 
 530         /* Ystorm */
 531         {'Y', BLOCK_YSEM,
 532          {DBG_BUS_CLIENT_RBCX, DBG_BUS_CLIENT_RBCY,
 533           DBG_BUS_CLIENT_RBCY}, false,
 534          YSEM_REG_FAST_MEMORY,
 535          YSEM_REG_DBG_FRAME_MODE_BB_K2, YSEM_REG_SLOW_DBG_ACTIVE_BB_K2,
 536          YSEM_REG_SLOW_DBG_MODE_BB_K2, YSEM_REG_DBG_MODE1_CFG_BB_K2,
 537          YSEM_REG_SYNC_DBG_EMPTY, TSEM_REG_SLOW_DBG_EMPTY_BB_K2,
 538          YCM_REG_CTX_RBC_ACCS,
 539          2, YCM_REG_AGG_CON_CTX,
 540          3, YCM_REG_SM_CON_CTX,
 541          2, YCM_REG_AGG_TASK_CTX,
 542          12, YCM_REG_SM_TASK_CTX},
 543 
 544         /* Pstorm */
 545         {'P', BLOCK_PSEM,
 546          {DBG_BUS_CLIENT_RBCS, DBG_BUS_CLIENT_RBCS,
 547           DBG_BUS_CLIENT_RBCS}, true,
 548          PSEM_REG_FAST_MEMORY,
 549          PSEM_REG_DBG_FRAME_MODE_BB_K2, PSEM_REG_SLOW_DBG_ACTIVE_BB_K2,
 550          PSEM_REG_SLOW_DBG_MODE_BB_K2, PSEM_REG_DBG_MODE1_CFG_BB_K2,
 551          PSEM_REG_SYNC_DBG_EMPTY, PSEM_REG_SLOW_DBG_EMPTY_BB_K2,
 552          PCM_REG_CTX_RBC_ACCS,
 553          0, 0,
 554          10, PCM_REG_SM_CON_CTX,
 555          0, 0,
 556          0, 0}
 557 };
 558 
 559 /* Block definitions array */
 560 
 561 static struct block_defs block_grc_defs = {
 562         "grc",
 563         {true, true, true}, false, 0,
 564         {DBG_BUS_CLIENT_RBCN, DBG_BUS_CLIENT_RBCN, DBG_BUS_CLIENT_RBCN},
 565         GRC_REG_DBG_SELECT, GRC_REG_DBG_DWORD_ENABLE,
 566         GRC_REG_DBG_SHIFT, GRC_REG_DBG_FORCE_VALID,
 567         GRC_REG_DBG_FORCE_FRAME,
 568         true, false, DBG_RESET_REG_MISC_PL_UA, 1
 569 };
 570 
 571 static struct block_defs block_miscs_defs = {
 572         "miscs", {true, true, true}, false, 0,
 573         {MAX_DBG_BUS_CLIENTS, MAX_DBG_BUS_CLIENTS, MAX_DBG_BUS_CLIENTS},
 574         0, 0, 0, 0, 0,
 575         false, false, MAX_DBG_RESET_REGS, 0
 576 };
 577 
 578 static struct block_defs block_misc_defs = {
 579         "misc", {true, true, true}, false, 0,
 580         {MAX_DBG_BUS_CLIENTS, MAX_DBG_BUS_CLIENTS, MAX_DBG_BUS_CLIENTS},
 581         0, 0, 0, 0, 0,
 582         false, false, MAX_DBG_RESET_REGS, 0
 583 };
 584 
 585 static struct block_defs block_dbu_defs = {
 586         "dbu", {true, true, true}, false, 0,
 587         {MAX_DBG_BUS_CLIENTS, MAX_DBG_BUS_CLIENTS, MAX_DBG_BUS_CLIENTS},
 588         0, 0, 0, 0, 0,
 589         false, false, MAX_DBG_RESET_REGS, 0
 590 };
 591 
 592 static struct block_defs block_pglue_b_defs = {
 593         "pglue_b",
 594         {true, true, true}, false, 0,
 595         {DBG_BUS_CLIENT_RBCH, DBG_BUS_CLIENT_RBCH, DBG_BUS_CLIENT_RBCH},
 596         PGLUE_B_REG_DBG_SELECT, PGLUE_B_REG_DBG_DWORD_ENABLE,
 597         PGLUE_B_REG_DBG_SHIFT, PGLUE_B_REG_DBG_FORCE_VALID,
 598         PGLUE_B_REG_DBG_FORCE_FRAME,
 599         true, false, DBG_RESET_REG_MISCS_PL_HV, 1
 600 };
 601 
 602 static struct block_defs block_cnig_defs = {
 603         "cnig",
 604         {true, true, true}, false, 0,
 605         {MAX_DBG_BUS_CLIENTS, DBG_BUS_CLIENT_RBCW,
 606          DBG_BUS_CLIENT_RBCW},
 607         CNIG_REG_DBG_SELECT_K2_E5, CNIG_REG_DBG_DWORD_ENABLE_K2_E5,
 608         CNIG_REG_DBG_SHIFT_K2_E5, CNIG_REG_DBG_FORCE_VALID_K2_E5,
 609         CNIG_REG_DBG_FORCE_FRAME_K2_E5,
 610         true, false, DBG_RESET_REG_MISCS_PL_HV, 0
 611 };
 612 
 613 static struct block_defs block_cpmu_defs = {
 614         "cpmu", {true, true, true}, false, 0,
 615         {MAX_DBG_BUS_CLIENTS, MAX_DBG_BUS_CLIENTS, MAX_DBG_BUS_CLIENTS},
 616         0, 0, 0, 0, 0,
 617         true, false, DBG_RESET_REG_MISCS_PL_HV, 8
 618 };
 619 
 620 static struct block_defs block_ncsi_defs = {
 621         "ncsi",
 622         {true, true, true}, false, 0,
 623         {DBG_BUS_CLIENT_RBCZ, DBG_BUS_CLIENT_RBCZ, DBG_BUS_CLIENT_RBCZ},
 624         NCSI_REG_DBG_SELECT, NCSI_REG_DBG_DWORD_ENABLE,
 625         NCSI_REG_DBG_SHIFT, NCSI_REG_DBG_FORCE_VALID,
 626         NCSI_REG_DBG_FORCE_FRAME,
 627         true, false, DBG_RESET_REG_MISCS_PL_HV, 5
 628 };
 629 
 630 static struct block_defs block_opte_defs = {
 631         "opte", {true, true, false}, false, 0,
 632         {MAX_DBG_BUS_CLIENTS, MAX_DBG_BUS_CLIENTS, MAX_DBG_BUS_CLIENTS},
 633         0, 0, 0, 0, 0,
 634         true, false, DBG_RESET_REG_MISCS_PL_HV, 4
 635 };
 636 
 637 static struct block_defs block_bmb_defs = {
 638         "bmb",
 639         {true, true, true}, false, 0,
 640         {DBG_BUS_CLIENT_RBCZ, DBG_BUS_CLIENT_RBCB, DBG_BUS_CLIENT_RBCB},
 641         BMB_REG_DBG_SELECT, BMB_REG_DBG_DWORD_ENABLE,
 642         BMB_REG_DBG_SHIFT, BMB_REG_DBG_FORCE_VALID,
 643         BMB_REG_DBG_FORCE_FRAME,
 644         true, false, DBG_RESET_REG_MISCS_PL_UA, 7
 645 };
 646 
 647 static struct block_defs block_pcie_defs = {
 648         "pcie",
 649         {true, true, true}, false, 0,
 650         {MAX_DBG_BUS_CLIENTS, DBG_BUS_CLIENT_RBCH,
 651          DBG_BUS_CLIENT_RBCH},
 652         PCIE_REG_DBG_COMMON_SELECT_K2_E5,
 653         PCIE_REG_DBG_COMMON_DWORD_ENABLE_K2_E5,
 654         PCIE_REG_DBG_COMMON_SHIFT_K2_E5,
 655         PCIE_REG_DBG_COMMON_FORCE_VALID_K2_E5,
 656         PCIE_REG_DBG_COMMON_FORCE_FRAME_K2_E5,
 657         false, false, MAX_DBG_RESET_REGS, 0
 658 };
 659 
 660 static struct block_defs block_mcp_defs = {
 661         "mcp", {true, true, true}, false, 0,
 662         {MAX_DBG_BUS_CLIENTS, MAX_DBG_BUS_CLIENTS, MAX_DBG_BUS_CLIENTS},
 663         0, 0, 0, 0, 0,
 664         false, false, MAX_DBG_RESET_REGS, 0
 665 };
 666 
 667 static struct block_defs block_mcp2_defs = {
 668         "mcp2",
 669         {true, true, true}, false, 0,
 670         {DBG_BUS_CLIENT_RBCZ, DBG_BUS_CLIENT_RBCZ, DBG_BUS_CLIENT_RBCZ},
 671         MCP2_REG_DBG_SELECT, MCP2_REG_DBG_DWORD_ENABLE,
 672         MCP2_REG_DBG_SHIFT, MCP2_REG_DBG_FORCE_VALID,
 673         MCP2_REG_DBG_FORCE_FRAME,
 674         false, false, MAX_DBG_RESET_REGS, 0
 675 };
 676 
 677 static struct block_defs block_pswhst_defs = {
 678         "pswhst",
 679         {true, true, true}, false, 0,
 680         {DBG_BUS_CLIENT_RBCP, DBG_BUS_CLIENT_RBCP, DBG_BUS_CLIENT_RBCP},
 681         PSWHST_REG_DBG_SELECT, PSWHST_REG_DBG_DWORD_ENABLE,
 682         PSWHST_REG_DBG_SHIFT, PSWHST_REG_DBG_FORCE_VALID,
 683         PSWHST_REG_DBG_FORCE_FRAME,
 684         true, false, DBG_RESET_REG_MISC_PL_HV, 0
 685 };
 686 
 687 static struct block_defs block_pswhst2_defs = {
 688         "pswhst2",
 689         {true, true, true}, false, 0,
 690         {DBG_BUS_CLIENT_RBCP, DBG_BUS_CLIENT_RBCP, DBG_BUS_CLIENT_RBCP},
 691         PSWHST2_REG_DBG_SELECT, PSWHST2_REG_DBG_DWORD_ENABLE,
 692         PSWHST2_REG_DBG_SHIFT, PSWHST2_REG_DBG_FORCE_VALID,
 693         PSWHST2_REG_DBG_FORCE_FRAME,
 694         true, false, DBG_RESET_REG_MISC_PL_HV, 0
 695 };
 696 
 697 static struct block_defs block_pswrd_defs = {
 698         "pswrd",
 699         {true, true, true}, false, 0,
 700         {DBG_BUS_CLIENT_RBCP, DBG_BUS_CLIENT_RBCP, DBG_BUS_CLIENT_RBCP},
 701         PSWRD_REG_DBG_SELECT, PSWRD_REG_DBG_DWORD_ENABLE,
 702         PSWRD_REG_DBG_SHIFT, PSWRD_REG_DBG_FORCE_VALID,
 703         PSWRD_REG_DBG_FORCE_FRAME,
 704         true, false, DBG_RESET_REG_MISC_PL_HV, 2
 705 };
 706 
 707 static struct block_defs block_pswrd2_defs = {
 708         "pswrd2",
 709         {true, true, true}, false, 0,
 710         {DBG_BUS_CLIENT_RBCP, DBG_BUS_CLIENT_RBCP, DBG_BUS_CLIENT_RBCP},
 711         PSWRD2_REG_DBG_SELECT, PSWRD2_REG_DBG_DWORD_ENABLE,
 712         PSWRD2_REG_DBG_SHIFT, PSWRD2_REG_DBG_FORCE_VALID,
 713         PSWRD2_REG_DBG_FORCE_FRAME,
 714         true, false, DBG_RESET_REG_MISC_PL_HV, 2
 715 };
 716 
 717 static struct block_defs block_pswwr_defs = {
 718         "pswwr",
 719         {true, true, true}, false, 0,
 720         {DBG_BUS_CLIENT_RBCP, DBG_BUS_CLIENT_RBCP, DBG_BUS_CLIENT_RBCP},
 721         PSWWR_REG_DBG_SELECT, PSWWR_REG_DBG_DWORD_ENABLE,
 722         PSWWR_REG_DBG_SHIFT, PSWWR_REG_DBG_FORCE_VALID,
 723         PSWWR_REG_DBG_FORCE_FRAME,
 724         true, false, DBG_RESET_REG_MISC_PL_HV, 3
 725 };
 726 
 727 static struct block_defs block_pswwr2_defs = {
 728         "pswwr2", {true, true, true}, false, 0,
 729         {MAX_DBG_BUS_CLIENTS, MAX_DBG_BUS_CLIENTS, MAX_DBG_BUS_CLIENTS},
 730         0, 0, 0, 0, 0,
 731         true, false, DBG_RESET_REG_MISC_PL_HV, 3
 732 };
 733 
 734 static struct block_defs block_pswrq_defs = {
 735         "pswrq",
 736         {true, true, true}, false, 0,
 737         {DBG_BUS_CLIENT_RBCP, DBG_BUS_CLIENT_RBCP, DBG_BUS_CLIENT_RBCP},
 738         PSWRQ_REG_DBG_SELECT, PSWRQ_REG_DBG_DWORD_ENABLE,
 739         PSWRQ_REG_DBG_SHIFT, PSWRQ_REG_DBG_FORCE_VALID,
 740         PSWRQ_REG_DBG_FORCE_FRAME,
 741         true, false, DBG_RESET_REG_MISC_PL_HV, 1
 742 };
 743 
 744 static struct block_defs block_pswrq2_defs = {
 745         "pswrq2",
 746         {true, true, true}, false, 0,
 747         {DBG_BUS_CLIENT_RBCP, DBG_BUS_CLIENT_RBCP, DBG_BUS_CLIENT_RBCP},
 748         PSWRQ2_REG_DBG_SELECT, PSWRQ2_REG_DBG_DWORD_ENABLE,
 749         PSWRQ2_REG_DBG_SHIFT, PSWRQ2_REG_DBG_FORCE_VALID,
 750         PSWRQ2_REG_DBG_FORCE_FRAME,
 751         true, false, DBG_RESET_REG_MISC_PL_HV, 1
 752 };
 753 
 754 static struct block_defs block_pglcs_defs = {
 755         "pglcs",
 756         {true, true, true}, false, 0,
 757         {MAX_DBG_BUS_CLIENTS, DBG_BUS_CLIENT_RBCH,
 758          DBG_BUS_CLIENT_RBCH},
 759         PGLCS_REG_DBG_SELECT_K2_E5, PGLCS_REG_DBG_DWORD_ENABLE_K2_E5,
 760         PGLCS_REG_DBG_SHIFT_K2_E5, PGLCS_REG_DBG_FORCE_VALID_K2_E5,
 761         PGLCS_REG_DBG_FORCE_FRAME_K2_E5,
 762         true, false, DBG_RESET_REG_MISCS_PL_HV, 2
 763 };
 764 
 765 static struct block_defs block_ptu_defs = {
 766         "ptu",
 767         {true, true, true}, false, 0,
 768         {DBG_BUS_CLIENT_RBCP, DBG_BUS_CLIENT_RBCP, DBG_BUS_CLIENT_RBCP},
 769         PTU_REG_DBG_SELECT, PTU_REG_DBG_DWORD_ENABLE,
 770         PTU_REG_DBG_SHIFT, PTU_REG_DBG_FORCE_VALID,
 771         PTU_REG_DBG_FORCE_FRAME,
 772         true, true, DBG_RESET_REG_MISC_PL_PDA_VMAIN_2, 20
 773 };
 774 
 775 static struct block_defs block_dmae_defs = {
 776         "dmae",
 777         {true, true, true}, false, 0,
 778         {DBG_BUS_CLIENT_RBCP, DBG_BUS_CLIENT_RBCP, DBG_BUS_CLIENT_RBCP},
 779         DMAE_REG_DBG_SELECT, DMAE_REG_DBG_DWORD_ENABLE,
 780         DMAE_REG_DBG_SHIFT, DMAE_REG_DBG_FORCE_VALID,
 781         DMAE_REG_DBG_FORCE_FRAME,
 782         true, true, DBG_RESET_REG_MISC_PL_PDA_VMAIN_1, 28
 783 };
 784 
 785 static struct block_defs block_tcm_defs = {
 786         "tcm",
 787         {true, true, true}, true, DBG_TSTORM_ID,
 788         {DBG_BUS_CLIENT_RBCT, DBG_BUS_CLIENT_RBCT, DBG_BUS_CLIENT_RBCT},
 789         TCM_REG_DBG_SELECT, TCM_REG_DBG_DWORD_ENABLE,
 790         TCM_REG_DBG_SHIFT, TCM_REG_DBG_FORCE_VALID,
 791         TCM_REG_DBG_FORCE_FRAME,
 792         true, true, DBG_RESET_REG_MISC_PL_PDA_VMAIN_1, 5
 793 };
 794 
 795 static struct block_defs block_mcm_defs = {
 796         "mcm",
 797         {true, true, true}, true, DBG_MSTORM_ID,
 798         {DBG_BUS_CLIENT_RBCT, DBG_BUS_CLIENT_RBCM, DBG_BUS_CLIENT_RBCM},
 799         MCM_REG_DBG_SELECT, MCM_REG_DBG_DWORD_ENABLE,
 800         MCM_REG_DBG_SHIFT, MCM_REG_DBG_FORCE_VALID,
 801         MCM_REG_DBG_FORCE_FRAME,
 802         true, true, DBG_RESET_REG_MISC_PL_PDA_VMAIN_2, 3
 803 };
 804 
 805 static struct block_defs block_ucm_defs = {
 806         "ucm",
 807         {true, true, true}, true, DBG_USTORM_ID,
 808         {DBG_BUS_CLIENT_RBCU, DBG_BUS_CLIENT_RBCU, DBG_BUS_CLIENT_RBCU},
 809         UCM_REG_DBG_SELECT, UCM_REG_DBG_DWORD_ENABLE,
 810         UCM_REG_DBG_SHIFT, UCM_REG_DBG_FORCE_VALID,
 811         UCM_REG_DBG_FORCE_FRAME,
 812         true, true, DBG_RESET_REG_MISC_PL_PDA_VMAIN_1, 8
 813 };
 814 
 815 static struct block_defs block_xcm_defs = {
 816         "xcm",
 817         {true, true, true}, true, DBG_XSTORM_ID,
 818         {DBG_BUS_CLIENT_RBCX, DBG_BUS_CLIENT_RBCX, DBG_BUS_CLIENT_RBCX},
 819         XCM_REG_DBG_SELECT, XCM_REG_DBG_DWORD_ENABLE,
 820         XCM_REG_DBG_SHIFT, XCM_REG_DBG_FORCE_VALID,
 821         XCM_REG_DBG_FORCE_FRAME,
 822         true, true, DBG_RESET_REG_MISC_PL_PDA_VMAIN_1, 19
 823 };
 824 
 825 static struct block_defs block_ycm_defs = {
 826         "ycm",
 827         {true, true, true}, true, DBG_YSTORM_ID,
 828         {DBG_BUS_CLIENT_RBCX, DBG_BUS_CLIENT_RBCY, DBG_BUS_CLIENT_RBCY},
 829         YCM_REG_DBG_SELECT, YCM_REG_DBG_DWORD_ENABLE,
 830         YCM_REG_DBG_SHIFT, YCM_REG_DBG_FORCE_VALID,
 831         YCM_REG_DBG_FORCE_FRAME,
 832         true, true, DBG_RESET_REG_MISC_PL_PDA_VMAIN_2, 5
 833 };
 834 
 835 static struct block_defs block_pcm_defs = {
 836         "pcm",
 837         {true, true, true}, true, DBG_PSTORM_ID,
 838         {DBG_BUS_CLIENT_RBCS, DBG_BUS_CLIENT_RBCS, DBG_BUS_CLIENT_RBCS},
 839         PCM_REG_DBG_SELECT, PCM_REG_DBG_DWORD_ENABLE,
 840         PCM_REG_DBG_SHIFT, PCM_REG_DBG_FORCE_VALID,
 841         PCM_REG_DBG_FORCE_FRAME,
 842         true, true, DBG_RESET_REG_MISC_PL_PDA_VMAIN_2, 4
 843 };
 844 
 845 static struct block_defs block_qm_defs = {
 846         "qm",
 847         {true, true, true}, false, 0,
 848         {DBG_BUS_CLIENT_RBCP, DBG_BUS_CLIENT_RBCQ, DBG_BUS_CLIENT_RBCQ},
 849         QM_REG_DBG_SELECT, QM_REG_DBG_DWORD_ENABLE,
 850         QM_REG_DBG_SHIFT, QM_REG_DBG_FORCE_VALID,
 851         QM_REG_DBG_FORCE_FRAME,
 852         true, true, DBG_RESET_REG_MISC_PL_PDA_VMAIN_1, 16
 853 };
 854 
 855 static struct block_defs block_tm_defs = {
 856         "tm",
 857         {true, true, true}, false, 0,
 858         {DBG_BUS_CLIENT_RBCS, DBG_BUS_CLIENT_RBCS, DBG_BUS_CLIENT_RBCS},
 859         TM_REG_DBG_SELECT, TM_REG_DBG_DWORD_ENABLE,
 860         TM_REG_DBG_SHIFT, TM_REG_DBG_FORCE_VALID,
 861         TM_REG_DBG_FORCE_FRAME,
 862         true, true, DBG_RESET_REG_MISC_PL_PDA_VMAIN_1, 17
 863 };
 864 
 865 static struct block_defs block_dorq_defs = {
 866         "dorq",
 867         {true, true, true}, false, 0,
 868         {DBG_BUS_CLIENT_RBCX, DBG_BUS_CLIENT_RBCY, DBG_BUS_CLIENT_RBCY},
 869         DORQ_REG_DBG_SELECT, DORQ_REG_DBG_DWORD_ENABLE,
 870         DORQ_REG_DBG_SHIFT, DORQ_REG_DBG_FORCE_VALID,
 871         DORQ_REG_DBG_FORCE_FRAME,
 872         true, true, DBG_RESET_REG_MISC_PL_PDA_VMAIN_1, 18
 873 };
 874 
 875 static struct block_defs block_brb_defs = {
 876         "brb",
 877         {true, true, true}, false, 0,
 878         {DBG_BUS_CLIENT_RBCR, DBG_BUS_CLIENT_RBCR, DBG_BUS_CLIENT_RBCR},
 879         BRB_REG_DBG_SELECT, BRB_REG_DBG_DWORD_ENABLE,
 880         BRB_REG_DBG_SHIFT, BRB_REG_DBG_FORCE_VALID,
 881         BRB_REG_DBG_FORCE_FRAME,
 882         true, true, DBG_RESET_REG_MISC_PL_PDA_VMAIN_1, 0
 883 };
 884 
 885 static struct block_defs block_src_defs = {
 886         "src",
 887         {true, true, true}, false, 0,
 888         {DBG_BUS_CLIENT_RBCF, DBG_BUS_CLIENT_RBCF, DBG_BUS_CLIENT_RBCF},
 889         SRC_REG_DBG_SELECT, SRC_REG_DBG_DWORD_ENABLE,
 890         SRC_REG_DBG_SHIFT, SRC_REG_DBG_FORCE_VALID,
 891         SRC_REG_DBG_FORCE_FRAME,
 892         true, true, DBG_RESET_REG_MISC_PL_PDA_VMAIN_1, 2
 893 };
 894 
 895 static struct block_defs block_prs_defs = {
 896         "prs",
 897         {true, true, true}, false, 0,
 898         {DBG_BUS_CLIENT_RBCR, DBG_BUS_CLIENT_RBCR, DBG_BUS_CLIENT_RBCR},
 899         PRS_REG_DBG_SELECT, PRS_REG_DBG_DWORD_ENABLE,
 900         PRS_REG_DBG_SHIFT, PRS_REG_DBG_FORCE_VALID,
 901         PRS_REG_DBG_FORCE_FRAME,
 902         true, true, DBG_RESET_REG_MISC_PL_PDA_VMAIN_1, 1
 903 };
 904 
 905 static struct block_defs block_tsdm_defs = {
 906         "tsdm",
 907         {true, true, true}, true, DBG_TSTORM_ID,
 908         {DBG_BUS_CLIENT_RBCT, DBG_BUS_CLIENT_RBCT, DBG_BUS_CLIENT_RBCT},
 909         TSDM_REG_DBG_SELECT, TSDM_REG_DBG_DWORD_ENABLE,
 910         TSDM_REG_DBG_SHIFT, TSDM_REG_DBG_FORCE_VALID,
 911         TSDM_REG_DBG_FORCE_FRAME,
 912         true, true, DBG_RESET_REG_MISC_PL_PDA_VMAIN_1, 3
 913 };
 914 
 915 static struct block_defs block_msdm_defs = {
 916         "msdm",
 917         {true, true, true}, true, DBG_MSTORM_ID,
 918         {DBG_BUS_CLIENT_RBCT, DBG_BUS_CLIENT_RBCM, DBG_BUS_CLIENT_RBCM},
 919         MSDM_REG_DBG_SELECT, MSDM_REG_DBG_DWORD_ENABLE,
 920         MSDM_REG_DBG_SHIFT, MSDM_REG_DBG_FORCE_VALID,
 921         MSDM_REG_DBG_FORCE_FRAME,
 922         true, true, DBG_RESET_REG_MISC_PL_PDA_VMAIN_2, 6
 923 };
 924 
 925 static struct block_defs block_usdm_defs = {
 926         "usdm",
 927         {true, true, true}, true, DBG_USTORM_ID,
 928         {DBG_BUS_CLIENT_RBCU, DBG_BUS_CLIENT_RBCU, DBG_BUS_CLIENT_RBCU},
 929         USDM_REG_DBG_SELECT, USDM_REG_DBG_DWORD_ENABLE,
 930         USDM_REG_DBG_SHIFT, USDM_REG_DBG_FORCE_VALID,
 931         USDM_REG_DBG_FORCE_FRAME,
 932         true, true, DBG_RESET_REG_MISC_PL_PDA_VMAIN_1, 7
 933 };
 934 
 935 static struct block_defs block_xsdm_defs = {
 936         "xsdm",
 937         {true, true, true}, true, DBG_XSTORM_ID,
 938         {DBG_BUS_CLIENT_RBCX, DBG_BUS_CLIENT_RBCX, DBG_BUS_CLIENT_RBCX},
 939         XSDM_REG_DBG_SELECT, XSDM_REG_DBG_DWORD_ENABLE,
 940         XSDM_REG_DBG_SHIFT, XSDM_REG_DBG_FORCE_VALID,
 941         XSDM_REG_DBG_FORCE_FRAME,
 942         true, true, DBG_RESET_REG_MISC_PL_PDA_VMAIN_1, 20
 943 };
 944 
 945 static struct block_defs block_ysdm_defs = {
 946         "ysdm",
 947         {true, true, true}, true, DBG_YSTORM_ID,
 948         {DBG_BUS_CLIENT_RBCX, DBG_BUS_CLIENT_RBCY, DBG_BUS_CLIENT_RBCY},
 949         YSDM_REG_DBG_SELECT, YSDM_REG_DBG_DWORD_ENABLE,
 950         YSDM_REG_DBG_SHIFT, YSDM_REG_DBG_FORCE_VALID,
 951         YSDM_REG_DBG_FORCE_FRAME,
 952         true, true, DBG_RESET_REG_MISC_PL_PDA_VMAIN_2, 8
 953 };
 954 
 955 static struct block_defs block_psdm_defs = {
 956         "psdm",
 957         {true, true, true}, true, DBG_PSTORM_ID,
 958         {DBG_BUS_CLIENT_RBCS, DBG_BUS_CLIENT_RBCS, DBG_BUS_CLIENT_RBCS},
 959         PSDM_REG_DBG_SELECT, PSDM_REG_DBG_DWORD_ENABLE,
 960         PSDM_REG_DBG_SHIFT, PSDM_REG_DBG_FORCE_VALID,
 961         PSDM_REG_DBG_FORCE_FRAME,
 962         true, true, DBG_RESET_REG_MISC_PL_PDA_VMAIN_2, 7
 963 };
 964 
 965 static struct block_defs block_tsem_defs = {
 966         "tsem",
 967         {true, true, true}, true, DBG_TSTORM_ID,
 968         {DBG_BUS_CLIENT_RBCT, DBG_BUS_CLIENT_RBCT, DBG_BUS_CLIENT_RBCT},
 969         TSEM_REG_DBG_SELECT, TSEM_REG_DBG_DWORD_ENABLE,
 970         TSEM_REG_DBG_SHIFT, TSEM_REG_DBG_FORCE_VALID,
 971         TSEM_REG_DBG_FORCE_FRAME,
 972         true, true, DBG_RESET_REG_MISC_PL_PDA_VMAIN_1, 4
 973 };
 974 
 975 static struct block_defs block_msem_defs = {
 976         "msem",
 977         {true, true, true}, true, DBG_MSTORM_ID,
 978         {DBG_BUS_CLIENT_RBCT, DBG_BUS_CLIENT_RBCM, DBG_BUS_CLIENT_RBCM},
 979         MSEM_REG_DBG_SELECT, MSEM_REG_DBG_DWORD_ENABLE,
 980         MSEM_REG_DBG_SHIFT, MSEM_REG_DBG_FORCE_VALID,
 981         MSEM_REG_DBG_FORCE_FRAME,
 982         true, true, DBG_RESET_REG_MISC_PL_PDA_VMAIN_2, 9
 983 };
 984 
 985 static struct block_defs block_usem_defs = {
 986         "usem",
 987         {true, true, true}, true, DBG_USTORM_ID,
 988         {DBG_BUS_CLIENT_RBCU, DBG_BUS_CLIENT_RBCU, DBG_BUS_CLIENT_RBCU},
 989         USEM_REG_DBG_SELECT, USEM_REG_DBG_DWORD_ENABLE,
 990         USEM_REG_DBG_SHIFT, USEM_REG_DBG_FORCE_VALID,
 991         USEM_REG_DBG_FORCE_FRAME,
 992         true, true, DBG_RESET_REG_MISC_PL_PDA_VMAIN_1, 9
 993 };
 994 
 995 static struct block_defs block_xsem_defs = {
 996         "xsem",
 997         {true, true, true}, true, DBG_XSTORM_ID,
 998         {DBG_BUS_CLIENT_RBCX, DBG_BUS_CLIENT_RBCX, DBG_BUS_CLIENT_RBCX},
 999         XSEM_REG_DBG_SELECT, XSEM_REG_DBG_DWORD_ENABLE,
1000         XSEM_REG_DBG_SHIFT, XSEM_REG_DBG_FORCE_VALID,
1001         XSEM_REG_DBG_FORCE_FRAME,
1002         true, true, DBG_RESET_REG_MISC_PL_PDA_VMAIN_1, 21
1003 };
1004 
1005 static struct block_defs block_ysem_defs = {
1006         "ysem",
1007         {true, true, true}, true, DBG_YSTORM_ID,
1008         {DBG_BUS_CLIENT_RBCX, DBG_BUS_CLIENT_RBCY, DBG_BUS_CLIENT_RBCY},
1009         YSEM_REG_DBG_SELECT, YSEM_REG_DBG_DWORD_ENABLE,
1010         YSEM_REG_DBG_SHIFT, YSEM_REG_DBG_FORCE_VALID,
1011         YSEM_REG_DBG_FORCE_FRAME,
1012         true, true, DBG_RESET_REG_MISC_PL_PDA_VMAIN_2, 11
1013 };
1014 
1015 static struct block_defs block_psem_defs = {
1016         "psem",
1017         {true, true, true}, true, DBG_PSTORM_ID,
1018         {DBG_BUS_CLIENT_RBCS, DBG_BUS_CLIENT_RBCS, DBG_BUS_CLIENT_RBCS},
1019         PSEM_REG_DBG_SELECT, PSEM_REG_DBG_DWORD_ENABLE,
1020         PSEM_REG_DBG_SHIFT, PSEM_REG_DBG_FORCE_VALID,
1021         PSEM_REG_DBG_FORCE_FRAME,
1022         true, true, DBG_RESET_REG_MISC_PL_PDA_VMAIN_2, 10
1023 };
1024 
1025 static struct block_defs block_rss_defs = {
1026         "rss",
1027         {true, true, true}, false, 0,
1028         {DBG_BUS_CLIENT_RBCT, DBG_BUS_CLIENT_RBCT, DBG_BUS_CLIENT_RBCT},
1029         RSS_REG_DBG_SELECT, RSS_REG_DBG_DWORD_ENABLE,
1030         RSS_REG_DBG_SHIFT, RSS_REG_DBG_FORCE_VALID,
1031         RSS_REG_DBG_FORCE_FRAME,
1032         true, true, DBG_RESET_REG_MISC_PL_PDA_VMAIN_2, 18
1033 };
1034 
1035 static struct block_defs block_tmld_defs = {
1036         "tmld",
1037         {true, true, true}, false, 0,
1038         {DBG_BUS_CLIENT_RBCT, DBG_BUS_CLIENT_RBCM, DBG_BUS_CLIENT_RBCM},
1039         TMLD_REG_DBG_SELECT, TMLD_REG_DBG_DWORD_ENABLE,
1040         TMLD_REG_DBG_SHIFT, TMLD_REG_DBG_FORCE_VALID,
1041         TMLD_REG_DBG_FORCE_FRAME,
1042         true, true, DBG_RESET_REG_MISC_PL_PDA_VMAIN_2, 13
1043 };
1044 
1045 static struct block_defs block_muld_defs = {
1046         "muld",
1047         {true, true, true}, false, 0,
1048         {DBG_BUS_CLIENT_RBCU, DBG_BUS_CLIENT_RBCU, DBG_BUS_CLIENT_RBCU},
1049         MULD_REG_DBG_SELECT, MULD_REG_DBG_DWORD_ENABLE,
1050         MULD_REG_DBG_SHIFT, MULD_REG_DBG_FORCE_VALID,
1051         MULD_REG_DBG_FORCE_FRAME,
1052         true, true, DBG_RESET_REG_MISC_PL_PDA_VMAIN_2, 14
1053 };
1054 
1055 static struct block_defs block_yuld_defs = {
1056         "yuld",
1057         {true, true, false}, false, 0,
1058         {DBG_BUS_CLIENT_RBCU, DBG_BUS_CLIENT_RBCU,
1059          MAX_DBG_BUS_CLIENTS},
1060         YULD_REG_DBG_SELECT_BB_K2, YULD_REG_DBG_DWORD_ENABLE_BB_K2,
1061         YULD_REG_DBG_SHIFT_BB_K2, YULD_REG_DBG_FORCE_VALID_BB_K2,
1062         YULD_REG_DBG_FORCE_FRAME_BB_K2,
1063         true, true, DBG_RESET_REG_MISC_PL_PDA_VMAIN_2,
1064         15
1065 };
1066 
1067 static struct block_defs block_xyld_defs = {
1068         "xyld",
1069         {true, true, true}, false, 0,
1070         {DBG_BUS_CLIENT_RBCX, DBG_BUS_CLIENT_RBCX, DBG_BUS_CLIENT_RBCX},
1071         XYLD_REG_DBG_SELECT, XYLD_REG_DBG_DWORD_ENABLE,
1072         XYLD_REG_DBG_SHIFT, XYLD_REG_DBG_FORCE_VALID,
1073         XYLD_REG_DBG_FORCE_FRAME,
1074         true, true, DBG_RESET_REG_MISC_PL_PDA_VMAIN_2, 12
1075 };
1076 
1077 static struct block_defs block_ptld_defs = {
1078         "ptld",
1079         {false, false, true}, false, 0,
1080         {MAX_DBG_BUS_CLIENTS, MAX_DBG_BUS_CLIENTS, DBG_BUS_CLIENT_RBCT},
1081         PTLD_REG_DBG_SELECT_E5, PTLD_REG_DBG_DWORD_ENABLE_E5,
1082         PTLD_REG_DBG_SHIFT_E5, PTLD_REG_DBG_FORCE_VALID_E5,
1083         PTLD_REG_DBG_FORCE_FRAME_E5,
1084         true, true, DBG_RESET_REG_MISC_PL_PDA_VMAIN_2,
1085         28
1086 };
1087 
1088 static struct block_defs block_ypld_defs = {
1089         "ypld",
1090         {false, false, true}, false, 0,
1091         {MAX_DBG_BUS_CLIENTS, MAX_DBG_BUS_CLIENTS, DBG_BUS_CLIENT_RBCS},
1092         YPLD_REG_DBG_SELECT_E5, YPLD_REG_DBG_DWORD_ENABLE_E5,
1093         YPLD_REG_DBG_SHIFT_E5, YPLD_REG_DBG_FORCE_VALID_E5,
1094         YPLD_REG_DBG_FORCE_FRAME_E5,
1095         true, true, DBG_RESET_REG_MISC_PL_PDA_VMAIN_2,
1096         27
1097 };
1098 
1099 static struct block_defs block_prm_defs = {
1100         "prm",
1101         {true, true, true}, false, 0,
1102         {DBG_BUS_CLIENT_RBCT, DBG_BUS_CLIENT_RBCM, DBG_BUS_CLIENT_RBCM},
1103         PRM_REG_DBG_SELECT, PRM_REG_DBG_DWORD_ENABLE,
1104         PRM_REG_DBG_SHIFT, PRM_REG_DBG_FORCE_VALID,
1105         PRM_REG_DBG_FORCE_FRAME,
1106         true, true, DBG_RESET_REG_MISC_PL_PDA_VMAIN_2, 21
1107 };
1108 
1109 static struct block_defs block_pbf_pb1_defs = {
1110         "pbf_pb1",
1111         {true, true, true}, false, 0,
1112         {DBG_BUS_CLIENT_RBCS, DBG_BUS_CLIENT_RBCV, DBG_BUS_CLIENT_RBCV},
1113         PBF_PB1_REG_DBG_SELECT, PBF_PB1_REG_DBG_DWORD_ENABLE,
1114         PBF_PB1_REG_DBG_SHIFT, PBF_PB1_REG_DBG_FORCE_VALID,
1115         PBF_PB1_REG_DBG_FORCE_FRAME,
1116         true, true, DBG_RESET_REG_MISC_PL_PDA_VMAIN_1,
1117         11
1118 };
1119 
1120 static struct block_defs block_pbf_pb2_defs = {
1121         "pbf_pb2",
1122         {true, true, true}, false, 0,
1123         {DBG_BUS_CLIENT_RBCS, DBG_BUS_CLIENT_RBCV, DBG_BUS_CLIENT_RBCV},
1124         PBF_PB2_REG_DBG_SELECT, PBF_PB2_REG_DBG_DWORD_ENABLE,
1125         PBF_PB2_REG_DBG_SHIFT, PBF_PB2_REG_DBG_FORCE_VALID,
1126         PBF_PB2_REG_DBG_FORCE_FRAME,
1127         true, true, DBG_RESET_REG_MISC_PL_PDA_VMAIN_1,
1128         12
1129 };
1130 
1131 static struct block_defs block_rpb_defs = {
1132         "rpb",
1133         {true, true, true}, false, 0,
1134         {DBG_BUS_CLIENT_RBCT, DBG_BUS_CLIENT_RBCM, DBG_BUS_CLIENT_RBCM},
1135         RPB_REG_DBG_SELECT, RPB_REG_DBG_DWORD_ENABLE,
1136         RPB_REG_DBG_SHIFT, RPB_REG_DBG_FORCE_VALID,
1137         RPB_REG_DBG_FORCE_FRAME,
1138         true, true, DBG_RESET_REG_MISC_PL_PDA_VMAIN_1, 13
1139 };
1140 
1141 static struct block_defs block_btb_defs = {
1142         "btb",
1143         {true, true, true}, false, 0,
1144         {DBG_BUS_CLIENT_RBCR, DBG_BUS_CLIENT_RBCV, DBG_BUS_CLIENT_RBCV},
1145         BTB_REG_DBG_SELECT, BTB_REG_DBG_DWORD_ENABLE,
1146         BTB_REG_DBG_SHIFT, BTB_REG_DBG_FORCE_VALID,
1147         BTB_REG_DBG_FORCE_FRAME,
1148         true, true, DBG_RESET_REG_MISC_PL_PDA_VMAIN_1, 10
1149 };
1150 
1151 static struct block_defs block_pbf_defs = {
1152         "pbf",
1153         {true, true, true}, false, 0,
1154         {DBG_BUS_CLIENT_RBCS, DBG_BUS_CLIENT_RBCV, DBG_BUS_CLIENT_RBCV},
1155         PBF_REG_DBG_SELECT, PBF_REG_DBG_DWORD_ENABLE,
1156         PBF_REG_DBG_SHIFT, PBF_REG_DBG_FORCE_VALID,
1157         PBF_REG_DBG_FORCE_FRAME,
1158         true, true, DBG_RESET_REG_MISC_PL_PDA_VMAIN_1, 15
1159 };
1160 
1161 static struct block_defs block_rdif_defs = {
1162         "rdif",
1163         {true, true, true}, false, 0,
1164         {DBG_BUS_CLIENT_RBCT, DBG_BUS_CLIENT_RBCM, DBG_BUS_CLIENT_RBCM},
1165         RDIF_REG_DBG_SELECT, RDIF_REG_DBG_DWORD_ENABLE,
1166         RDIF_REG_DBG_SHIFT, RDIF_REG_DBG_FORCE_VALID,
1167         RDIF_REG_DBG_FORCE_FRAME,
1168         true, true, DBG_RESET_REG_MISC_PL_PDA_VMAIN_2, 16
1169 };
1170 
1171 static struct block_defs block_tdif_defs = {
1172         "tdif",
1173         {true, true, true}, false, 0,
1174         {DBG_BUS_CLIENT_RBCS, DBG_BUS_CLIENT_RBCS, DBG_BUS_CLIENT_RBCS},
1175         TDIF_REG_DBG_SELECT, TDIF_REG_DBG_DWORD_ENABLE,
1176         TDIF_REG_DBG_SHIFT, TDIF_REG_DBG_FORCE_VALID,
1177         TDIF_REG_DBG_FORCE_FRAME,
1178         true, true, DBG_RESET_REG_MISC_PL_PDA_VMAIN_2, 17
1179 };
1180 
1181 static struct block_defs block_cdu_defs = {
1182         "cdu",
1183         {true, true, true}, false, 0,
1184         {DBG_BUS_CLIENT_RBCF, DBG_BUS_CLIENT_RBCF, DBG_BUS_CLIENT_RBCF},
1185         CDU_REG_DBG_SELECT, CDU_REG_DBG_DWORD_ENABLE,
1186         CDU_REG_DBG_SHIFT, CDU_REG_DBG_FORCE_VALID,
1187         CDU_REG_DBG_FORCE_FRAME,
1188         true, true, DBG_RESET_REG_MISC_PL_PDA_VMAIN_1, 23
1189 };
1190 
1191 static struct block_defs block_ccfc_defs = {
1192         "ccfc",
1193         {true, true, true}, false, 0,
1194         {DBG_BUS_CLIENT_RBCF, DBG_BUS_CLIENT_RBCF, DBG_BUS_CLIENT_RBCF},
1195         CCFC_REG_DBG_SELECT, CCFC_REG_DBG_DWORD_ENABLE,
1196         CCFC_REG_DBG_SHIFT, CCFC_REG_DBG_FORCE_VALID,
1197         CCFC_REG_DBG_FORCE_FRAME,
1198         true, true, DBG_RESET_REG_MISC_PL_PDA_VMAIN_1, 24
1199 };
1200 
1201 static struct block_defs block_tcfc_defs = {
1202         "tcfc",
1203         {true, true, true}, false, 0,
1204         {DBG_BUS_CLIENT_RBCF, DBG_BUS_CLIENT_RBCF, DBG_BUS_CLIENT_RBCF},
1205         TCFC_REG_DBG_SELECT, TCFC_REG_DBG_DWORD_ENABLE,
1206         TCFC_REG_DBG_SHIFT, TCFC_REG_DBG_FORCE_VALID,
1207         TCFC_REG_DBG_FORCE_FRAME,
1208         true, true, DBG_RESET_REG_MISC_PL_PDA_VMAIN_1, 25
1209 };
1210 
1211 static struct block_defs block_igu_defs = {
1212         "igu",
1213         {true, true, true}, false, 0,
1214         {DBG_BUS_CLIENT_RBCP, DBG_BUS_CLIENT_RBCP, DBG_BUS_CLIENT_RBCP},
1215         IGU_REG_DBG_SELECT, IGU_REG_DBG_DWORD_ENABLE,
1216         IGU_REG_DBG_SHIFT, IGU_REG_DBG_FORCE_VALID,
1217         IGU_REG_DBG_FORCE_FRAME,
1218         true, true, DBG_RESET_REG_MISC_PL_PDA_VMAIN_1, 27
1219 };
1220 
1221 static struct block_defs block_cau_defs = {
1222         "cau",
1223         {true, true, true}, false, 0,
1224         {DBG_BUS_CLIENT_RBCP, DBG_BUS_CLIENT_RBCP, DBG_BUS_CLIENT_RBCP},
1225         CAU_REG_DBG_SELECT, CAU_REG_DBG_DWORD_ENABLE,
1226         CAU_REG_DBG_SHIFT, CAU_REG_DBG_FORCE_VALID,
1227         CAU_REG_DBG_FORCE_FRAME,
1228         true, true, DBG_RESET_REG_MISC_PL_PDA_VMAIN_2, 19
1229 };
1230 
1231 static struct block_defs block_rgfs_defs = {
1232         "rgfs", {false, false, true}, false, 0,
1233         {MAX_DBG_BUS_CLIENTS, MAX_DBG_BUS_CLIENTS, MAX_DBG_BUS_CLIENTS},
1234         0, 0, 0, 0, 0,
1235         true, true, DBG_RESET_REG_MISC_PL_PDA_VMAIN_2, 29
1236 };
1237 
1238 static struct block_defs block_rgsrc_defs = {
1239         "rgsrc",
1240         {false, false, true}, false, 0,
1241         {MAX_DBG_BUS_CLIENTS, MAX_DBG_BUS_CLIENTS, DBG_BUS_CLIENT_RBCH},
1242         RGSRC_REG_DBG_SELECT_E5, RGSRC_REG_DBG_DWORD_ENABLE_E5,
1243         RGSRC_REG_DBG_SHIFT_E5, RGSRC_REG_DBG_FORCE_VALID_E5,
1244         RGSRC_REG_DBG_FORCE_FRAME_E5,
1245         true, true, DBG_RESET_REG_MISC_PL_PDA_VMAIN_1,
1246         30
1247 };
1248 
1249 static struct block_defs block_tgfs_defs = {
1250         "tgfs", {false, false, true}, false, 0,
1251         {MAX_DBG_BUS_CLIENTS, MAX_DBG_BUS_CLIENTS, MAX_DBG_BUS_CLIENTS},
1252         0, 0, 0, 0, 0,
1253         true, true, DBG_RESET_REG_MISC_PL_PDA_VMAIN_2, 30
1254 };
1255 
1256 static struct block_defs block_tgsrc_defs = {
1257         "tgsrc",
1258         {false, false, true}, false, 0,
1259         {MAX_DBG_BUS_CLIENTS, MAX_DBG_BUS_CLIENTS, DBG_BUS_CLIENT_RBCV},
1260         TGSRC_REG_DBG_SELECT_E5, TGSRC_REG_DBG_DWORD_ENABLE_E5,
1261         TGSRC_REG_DBG_SHIFT_E5, TGSRC_REG_DBG_FORCE_VALID_E5,
1262         TGSRC_REG_DBG_FORCE_FRAME_E5,
1263         true, true, DBG_RESET_REG_MISC_PL_PDA_VMAIN_1,
1264         31
1265 };
1266 
1267 static struct block_defs block_umac_defs = {
1268         "umac",
1269         {true, true, true}, false, 0,
1270         {MAX_DBG_BUS_CLIENTS, DBG_BUS_CLIENT_RBCZ,
1271          DBG_BUS_CLIENT_RBCZ},
1272         UMAC_REG_DBG_SELECT_K2_E5, UMAC_REG_DBG_DWORD_ENABLE_K2_E5,
1273         UMAC_REG_DBG_SHIFT_K2_E5, UMAC_REG_DBG_FORCE_VALID_K2_E5,
1274         UMAC_REG_DBG_FORCE_FRAME_K2_E5,
1275         true, false, DBG_RESET_REG_MISCS_PL_HV, 6
1276 };
1277 
1278 static struct block_defs block_xmac_defs = {
1279         "xmac", {true, false, false}, false, 0,
1280         {MAX_DBG_BUS_CLIENTS, MAX_DBG_BUS_CLIENTS, MAX_DBG_BUS_CLIENTS},
1281         0, 0, 0, 0, 0,
1282         false, false, MAX_DBG_RESET_REGS, 0
1283 };
1284 
1285 static struct block_defs block_dbg_defs = {
1286         "dbg", {true, true, true}, false, 0,
1287         {MAX_DBG_BUS_CLIENTS, MAX_DBG_BUS_CLIENTS, MAX_DBG_BUS_CLIENTS},
1288         0, 0, 0, 0, 0,
1289         true, true, DBG_RESET_REG_MISC_PL_PDA_VAUX, 3
1290 };
1291 
1292 static struct block_defs block_nig_defs = {
1293         "nig",
1294         {true, true, true}, false, 0,
1295         {DBG_BUS_CLIENT_RBCN, DBG_BUS_CLIENT_RBCN, DBG_BUS_CLIENT_RBCN},
1296         NIG_REG_DBG_SELECT, NIG_REG_DBG_DWORD_ENABLE,
1297         NIG_REG_DBG_SHIFT, NIG_REG_DBG_FORCE_VALID,
1298         NIG_REG_DBG_FORCE_FRAME,
1299         true, true, DBG_RESET_REG_MISC_PL_PDA_VAUX, 0
1300 };
1301 
1302 static struct block_defs block_wol_defs = {
1303         "wol",
1304         {false, true, true}, false, 0,
1305         {MAX_DBG_BUS_CLIENTS, DBG_BUS_CLIENT_RBCZ, DBG_BUS_CLIENT_RBCZ},
1306         WOL_REG_DBG_SELECT_K2_E5, WOL_REG_DBG_DWORD_ENABLE_K2_E5,
1307         WOL_REG_DBG_SHIFT_K2_E5, WOL_REG_DBG_FORCE_VALID_K2_E5,
1308         WOL_REG_DBG_FORCE_FRAME_K2_E5,
1309         true, true, DBG_RESET_REG_MISC_PL_PDA_VAUX, 7
1310 };
1311 
1312 static struct block_defs block_bmbn_defs = {
1313         "bmbn",
1314         {false, true, true}, false, 0,
1315         {MAX_DBG_BUS_CLIENTS, DBG_BUS_CLIENT_RBCB,
1316          DBG_BUS_CLIENT_RBCB},
1317         BMBN_REG_DBG_SELECT_K2_E5, BMBN_REG_DBG_DWORD_ENABLE_K2_E5,
1318         BMBN_REG_DBG_SHIFT_K2_E5, BMBN_REG_DBG_FORCE_VALID_K2_E5,
1319         BMBN_REG_DBG_FORCE_FRAME_K2_E5,
1320         false, false, MAX_DBG_RESET_REGS, 0
1321 };
1322 
1323 static struct block_defs block_ipc_defs = {
1324         "ipc", {true, true, true}, false, 0,
1325         {MAX_DBG_BUS_CLIENTS, MAX_DBG_BUS_CLIENTS, MAX_DBG_BUS_CLIENTS},
1326         0, 0, 0, 0, 0,
1327         true, false, DBG_RESET_REG_MISCS_PL_UA, 8
1328 };
1329 
1330 static struct block_defs block_nwm_defs = {
1331         "nwm",
1332         {false, true, true}, false, 0,
1333         {MAX_DBG_BUS_CLIENTS, DBG_BUS_CLIENT_RBCW, DBG_BUS_CLIENT_RBCW},
1334         NWM_REG_DBG_SELECT_K2_E5, NWM_REG_DBG_DWORD_ENABLE_K2_E5,
1335         NWM_REG_DBG_SHIFT_K2_E5, NWM_REG_DBG_FORCE_VALID_K2_E5,
1336         NWM_REG_DBG_FORCE_FRAME_K2_E5,
1337         true, false, DBG_RESET_REG_MISCS_PL_HV_2, 0
1338 };
1339 
1340 static struct block_defs block_nws_defs = {
1341         "nws",
1342         {false, true, true}, false, 0,
1343         {MAX_DBG_BUS_CLIENTS, DBG_BUS_CLIENT_RBCW, DBG_BUS_CLIENT_RBCW},
1344         NWS_REG_DBG_SELECT_K2_E5, NWS_REG_DBG_DWORD_ENABLE_K2_E5,
1345         NWS_REG_DBG_SHIFT_K2_E5, NWS_REG_DBG_FORCE_VALID_K2_E5,
1346         NWS_REG_DBG_FORCE_FRAME_K2_E5,
1347         true, false, DBG_RESET_REG_MISCS_PL_HV, 12
1348 };
1349 
1350 static struct block_defs block_ms_defs = {
1351         "ms",
1352         {false, true, true}, false, 0,
1353         {MAX_DBG_BUS_CLIENTS, DBG_BUS_CLIENT_RBCZ, DBG_BUS_CLIENT_RBCZ},
1354         MS_REG_DBG_SELECT_K2_E5, MS_REG_DBG_DWORD_ENABLE_K2_E5,
1355         MS_REG_DBG_SHIFT_K2_E5, MS_REG_DBG_FORCE_VALID_K2_E5,
1356         MS_REG_DBG_FORCE_FRAME_K2_E5,
1357         true, false, DBG_RESET_REG_MISCS_PL_HV, 13
1358 };
1359 
1360 static struct block_defs block_phy_pcie_defs = {
1361         "phy_pcie",
1362         {false, true, true}, false, 0,
1363         {MAX_DBG_BUS_CLIENTS, DBG_BUS_CLIENT_RBCH,
1364          DBG_BUS_CLIENT_RBCH},
1365         PCIE_REG_DBG_COMMON_SELECT_K2_E5,
1366         PCIE_REG_DBG_COMMON_DWORD_ENABLE_K2_E5,
1367         PCIE_REG_DBG_COMMON_SHIFT_K2_E5,
1368         PCIE_REG_DBG_COMMON_FORCE_VALID_K2_E5,
1369         PCIE_REG_DBG_COMMON_FORCE_FRAME_K2_E5,
1370         false, false, MAX_DBG_RESET_REGS, 0
1371 };
1372 
1373 static struct block_defs block_led_defs = {
1374         "led", {false, true, true}, false, 0,
1375         {MAX_DBG_BUS_CLIENTS, MAX_DBG_BUS_CLIENTS, MAX_DBG_BUS_CLIENTS},
1376         0, 0, 0, 0, 0,
1377         true, false, DBG_RESET_REG_MISCS_PL_HV, 14
1378 };
1379 
1380 static struct block_defs block_avs_wrap_defs = {
1381         "avs_wrap", {false, true, false}, false, 0,
1382         {MAX_DBG_BUS_CLIENTS, MAX_DBG_BUS_CLIENTS, MAX_DBG_BUS_CLIENTS},
1383         0, 0, 0, 0, 0,
1384         true, false, DBG_RESET_REG_MISCS_PL_UA, 11
1385 };
1386 
1387 static struct block_defs block_pxpreqbus_defs = {
1388         "pxpreqbus", {false, false, false}, false, 0,
1389         {MAX_DBG_BUS_CLIENTS, MAX_DBG_BUS_CLIENTS, MAX_DBG_BUS_CLIENTS},
1390         0, 0, 0, 0, 0,
1391         false, false, MAX_DBG_RESET_REGS, 0
1392 };
1393 
1394 static struct block_defs block_misc_aeu_defs = {
1395         "misc_aeu", {true, true, true}, false, 0,
1396         {MAX_DBG_BUS_CLIENTS, MAX_DBG_BUS_CLIENTS, MAX_DBG_BUS_CLIENTS},
1397         0, 0, 0, 0, 0,
1398         false, false, MAX_DBG_RESET_REGS, 0
1399 };
1400 
1401 static struct block_defs block_bar0_map_defs = {
1402         "bar0_map", {true, true, true}, false, 0,
1403         {MAX_DBG_BUS_CLIENTS, MAX_DBG_BUS_CLIENTS, MAX_DBG_BUS_CLIENTS},
1404         0, 0, 0, 0, 0,
1405         false, false, MAX_DBG_RESET_REGS, 0
1406 };
1407 
1408 static struct block_defs *s_block_defs[MAX_BLOCK_ID] = {
1409         &block_grc_defs,
1410         &block_miscs_defs,
1411         &block_misc_defs,
1412         &block_dbu_defs,
1413         &block_pglue_b_defs,
1414         &block_cnig_defs,
1415         &block_cpmu_defs,
1416         &block_ncsi_defs,
1417         &block_opte_defs,
1418         &block_bmb_defs,
1419         &block_pcie_defs,
1420         &block_mcp_defs,
1421         &block_mcp2_defs,
1422         &block_pswhst_defs,
1423         &block_pswhst2_defs,
1424         &block_pswrd_defs,
1425         &block_pswrd2_defs,
1426         &block_pswwr_defs,
1427         &block_pswwr2_defs,
1428         &block_pswrq_defs,
1429         &block_pswrq2_defs,
1430         &block_pglcs_defs,
1431         &block_dmae_defs,
1432         &block_ptu_defs,
1433         &block_tcm_defs,
1434         &block_mcm_defs,
1435         &block_ucm_defs,
1436         &block_xcm_defs,
1437         &block_ycm_defs,
1438         &block_pcm_defs,
1439         &block_qm_defs,
1440         &block_tm_defs,
1441         &block_dorq_defs,
1442         &block_brb_defs,
1443         &block_src_defs,
1444         &block_prs_defs,
1445         &block_tsdm_defs,
1446         &block_msdm_defs,
1447         &block_usdm_defs,
1448         &block_xsdm_defs,
1449         &block_ysdm_defs,
1450         &block_psdm_defs,
1451         &block_tsem_defs,
1452         &block_msem_defs,
1453         &block_usem_defs,
1454         &block_xsem_defs,
1455         &block_ysem_defs,
1456         &block_psem_defs,
1457         &block_rss_defs,
1458         &block_tmld_defs,
1459         &block_muld_defs,
1460         &block_yuld_defs,
1461         &block_xyld_defs,
1462         &block_ptld_defs,
1463         &block_ypld_defs,
1464         &block_prm_defs,
1465         &block_pbf_pb1_defs,
1466         &block_pbf_pb2_defs,
1467         &block_rpb_defs,
1468         &block_btb_defs,
1469         &block_pbf_defs,
1470         &block_rdif_defs,
1471         &block_tdif_defs,
1472         &block_cdu_defs,
1473         &block_ccfc_defs,
1474         &block_tcfc_defs,
1475         &block_igu_defs,
1476         &block_cau_defs,
1477         &block_rgfs_defs,
1478         &block_rgsrc_defs,
1479         &block_tgfs_defs,
1480         &block_tgsrc_defs,
1481         &block_umac_defs,
1482         &block_xmac_defs,
1483         &block_dbg_defs,
1484         &block_nig_defs,
1485         &block_wol_defs,
1486         &block_bmbn_defs,
1487         &block_ipc_defs,
1488         &block_nwm_defs,
1489         &block_nws_defs,
1490         &block_ms_defs,
1491         &block_phy_pcie_defs,
1492         &block_led_defs,
1493         &block_avs_wrap_defs,
1494         &block_pxpreqbus_defs,
1495         &block_misc_aeu_defs,
1496         &block_bar0_map_defs,
1497 };
1498 
1499 static struct platform_defs s_platform_defs[] = {
1500         {"asic", 1, 256, 32768},
1501         {"reserved", 0, 0, 0},
1502         {"reserved2", 0, 0, 0},
1503         {"reserved3", 0, 0, 0}
1504 };
1505 
1506 static struct grc_param_defs s_grc_param_defs[] = {
1507         /* DBG_GRC_PARAM_DUMP_TSTORM */
1508         {{1, 1, 1}, 0, 1, false, false, 1, 1},
1509 
1510         /* DBG_GRC_PARAM_DUMP_MSTORM */
1511         {{1, 1, 1}, 0, 1, false, false, 1, 1},
1512 
1513         /* DBG_GRC_PARAM_DUMP_USTORM */
1514         {{1, 1, 1}, 0, 1, false, false, 1, 1},
1515 
1516         /* DBG_GRC_PARAM_DUMP_XSTORM */
1517         {{1, 1, 1}, 0, 1, false, false, 1, 1},
1518 
1519         /* DBG_GRC_PARAM_DUMP_YSTORM */
1520         {{1, 1, 1}, 0, 1, false, false, 1, 1},
1521 
1522         /* DBG_GRC_PARAM_DUMP_PSTORM */
1523         {{1, 1, 1}, 0, 1, false, false, 1, 1},
1524 
1525         /* DBG_GRC_PARAM_DUMP_REGS */
1526         {{1, 1, 1}, 0, 1, false, false, 0, 1},
1527 
1528         /* DBG_GRC_PARAM_DUMP_RAM */
1529         {{1, 1, 1}, 0, 1, false, false, 0, 1},
1530 
1531         /* DBG_GRC_PARAM_DUMP_PBUF */
1532         {{1, 1, 1}, 0, 1, false, false, 0, 1},
1533 
1534         /* DBG_GRC_PARAM_DUMP_IOR */
1535         {{0, 0, 0}, 0, 1, false, false, 0, 1},
1536 
1537         /* DBG_GRC_PARAM_DUMP_VFC */
1538         {{0, 0, 0}, 0, 1, false, false, 0, 1},
1539 
1540         /* DBG_GRC_PARAM_DUMP_CM_CTX */
1541         {{1, 1, 1}, 0, 1, false, false, 0, 1},
1542 
1543         /* DBG_GRC_PARAM_DUMP_ILT */
1544         {{1, 1, 1}, 0, 1, false, false, 0, 1},
1545 
1546         /* DBG_GRC_PARAM_DUMP_RSS */
1547         {{1, 1, 1}, 0, 1, false, false, 0, 1},
1548 
1549         /* DBG_GRC_PARAM_DUMP_CAU */
1550         {{1, 1, 1}, 0, 1, false, false, 0, 1},
1551 
1552         /* DBG_GRC_PARAM_DUMP_QM */
1553         {{1, 1, 1}, 0, 1, false, false, 0, 1},
1554 
1555         /* DBG_GRC_PARAM_DUMP_MCP */
1556         {{1, 1, 1}, 0, 1, false, false, 0, 1},
1557 
1558         /* DBG_GRC_PARAM_MCP_TRACE_META_SIZE */
1559         {{1, 1, 1}, 1, 0xffffffff, false, true, 0, 1},
1560 
1561         /* DBG_GRC_PARAM_DUMP_CFC */
1562         {{1, 1, 1}, 0, 1, false, false, 0, 1},
1563 
1564         /* DBG_GRC_PARAM_DUMP_IGU */
1565         {{1, 1, 1}, 0, 1, false, false, 0, 1},
1566 
1567         /* DBG_GRC_PARAM_DUMP_BRB */
1568         {{0, 0, 0}, 0, 1, false, false, 0, 1},
1569 
1570         /* DBG_GRC_PARAM_DUMP_BTB */
1571         {{0, 0, 0}, 0, 1, false, false, 0, 1},
1572 
1573         /* DBG_GRC_PARAM_DUMP_BMB */
1574         {{0, 0, 0}, 0, 1, false, false, 0, 0},
1575 
1576         /* DBG_GRC_PARAM_DUMP_NIG */
1577         {{1, 1, 1}, 0, 1, false, false, 0, 1},
1578 
1579         /* DBG_GRC_PARAM_DUMP_MULD */
1580         {{1, 1, 1}, 0, 1, false, false, 0, 1},
1581 
1582         /* DBG_GRC_PARAM_DUMP_PRS */
1583         {{1, 1, 1}, 0, 1, false, false, 0, 1},
1584 
1585         /* DBG_GRC_PARAM_DUMP_DMAE */
1586         {{1, 1, 1}, 0, 1, false, false, 0, 1},
1587 
1588         /* DBG_GRC_PARAM_DUMP_TM */
1589         {{1, 1, 1}, 0, 1, false, false, 0, 1},
1590 
1591         /* DBG_GRC_PARAM_DUMP_SDM */
1592         {{1, 1, 1}, 0, 1, false, false, 0, 1},
1593 
1594         /* DBG_GRC_PARAM_DUMP_DIF */
1595         {{1, 1, 1}, 0, 1, false, false, 0, 1},
1596 
1597         /* DBG_GRC_PARAM_DUMP_STATIC */
1598         {{1, 1, 1}, 0, 1, false, false, 0, 1},
1599 
1600         /* DBG_GRC_PARAM_UNSTALL */
1601         {{0, 0, 0}, 0, 1, false, false, 0, 0},
1602 
1603         /* DBG_GRC_PARAM_NUM_LCIDS */
1604         {{MAX_LCIDS, MAX_LCIDS, MAX_LCIDS}, 1, MAX_LCIDS, false, false,
1605          MAX_LCIDS, MAX_LCIDS},
1606 
1607         /* DBG_GRC_PARAM_NUM_LTIDS */
1608         {{MAX_LTIDS, MAX_LTIDS, MAX_LTIDS}, 1, MAX_LTIDS, false, false,
1609          MAX_LTIDS, MAX_LTIDS},
1610 
1611         /* DBG_GRC_PARAM_EXCLUDE_ALL */
1612         {{0, 0, 0}, 0, 1, true, false, 0, 0},
1613 
1614         /* DBG_GRC_PARAM_CRASH */
1615         {{0, 0, 0}, 0, 1, true, false, 0, 0},
1616 
1617         /* DBG_GRC_PARAM_PARITY_SAFE */
1618         {{0, 0, 0}, 0, 1, false, false, 1, 0},
1619 
1620         /* DBG_GRC_PARAM_DUMP_CM */
1621         {{1, 1, 1}, 0, 1, false, false, 0, 1},
1622 
1623         /* DBG_GRC_PARAM_DUMP_PHY */
1624         {{1, 1, 1}, 0, 1, false, false, 0, 1},
1625 
1626         /* DBG_GRC_PARAM_NO_MCP */
1627         {{0, 0, 0}, 0, 1, false, false, 0, 0},
1628 
1629         /* DBG_GRC_PARAM_NO_FW_VER */
1630         {{0, 0, 0}, 0, 1, false, false, 0, 0}
1631 };
1632 
1633 static struct rss_mem_defs s_rss_mem_defs[] = {
1634         { "rss_mem_cid", "rss_cid", 0, 32,
1635           {256, 320, 512} },
1636 
1637         { "rss_mem_key_msb", "rss_key", 1024, 256,
1638           {128, 208, 257} },
1639 
1640         { "rss_mem_key_lsb", "rss_key", 2048, 64,
1641           {128, 208, 257} },
1642 
1643         { "rss_mem_info", "rss_info", 3072, 16,
1644           {128, 208, 256} },
1645 
1646         { "rss_mem_ind", "rss_ind", 4096, 16,
1647           {16384, 26624, 32768} }
1648 };
1649 
1650 static struct vfc_ram_defs s_vfc_ram_defs[] = {
1651         {"vfc_ram_tt1", "vfc_ram", 0, 512},
1652         {"vfc_ram_mtt2", "vfc_ram", 512, 128},
1653         {"vfc_ram_stt2", "vfc_ram", 640, 32},
1654         {"vfc_ram_ro_vect", "vfc_ram", 672, 32}
1655 };
1656 
1657 static struct big_ram_defs s_big_ram_defs[] = {
1658         { "BRB", MEM_GROUP_BRB_MEM, MEM_GROUP_BRB_RAM, DBG_GRC_PARAM_DUMP_BRB,
1659           BRB_REG_BIG_RAM_ADDRESS, BRB_REG_BIG_RAM_DATA,
1660           MISC_REG_BLOCK_256B_EN, {0, 0, 0},
1661           {153600, 180224, 282624} },
1662 
1663         { "BTB", MEM_GROUP_BTB_MEM, MEM_GROUP_BTB_RAM, DBG_GRC_PARAM_DUMP_BTB,
1664           BTB_REG_BIG_RAM_ADDRESS, BTB_REG_BIG_RAM_DATA,
1665           MISC_REG_BLOCK_256B_EN, {0, 1, 1},
1666           {92160, 117760, 168960} },
1667 
1668         { "BMB", MEM_GROUP_BMB_MEM, MEM_GROUP_BMB_RAM, DBG_GRC_PARAM_DUMP_BMB,
1669           BMB_REG_BIG_RAM_ADDRESS, BMB_REG_BIG_RAM_DATA,
1670           MISCS_REG_BLOCK_256B_EN, {0, 0, 0},
1671           {36864, 36864, 36864} }
1672 };
1673 
1674 static struct reset_reg_defs s_reset_regs_defs[] = {
1675         /* DBG_RESET_REG_MISCS_PL_UA */
1676         { MISCS_REG_RESET_PL_UA,
1677           {true, true, true}, {0x0, 0x0, 0x0} },
1678 
1679         /* DBG_RESET_REG_MISCS_PL_HV */
1680         { MISCS_REG_RESET_PL_HV,
1681           {true, true, true}, {0x0, 0x400, 0x600} },
1682 
1683         /* DBG_RESET_REG_MISCS_PL_HV_2 */
1684         { MISCS_REG_RESET_PL_HV_2_K2_E5,
1685           {false, true, true}, {0x0, 0x0, 0x0} },
1686 
1687         /* DBG_RESET_REG_MISC_PL_UA */
1688         { MISC_REG_RESET_PL_UA,
1689           {true, true, true}, {0x0, 0x0, 0x0} },
1690 
1691         /* DBG_RESET_REG_MISC_PL_HV */
1692         { MISC_REG_RESET_PL_HV,
1693           {true, true, true}, {0x0, 0x0, 0x0} },
1694 
1695         /* DBG_RESET_REG_MISC_PL_PDA_VMAIN_1 */
1696         { MISC_REG_RESET_PL_PDA_VMAIN_1,
1697           {true, true, true}, {0x4404040, 0x4404040, 0x404040} },
1698 
1699         /* DBG_RESET_REG_MISC_PL_PDA_VMAIN_2 */
1700         { MISC_REG_RESET_PL_PDA_VMAIN_2,
1701           {true, true, true}, {0x7, 0x7c00007, 0x5c08007} },
1702 
1703         /* DBG_RESET_REG_MISC_PL_PDA_VAUX */
1704         { MISC_REG_RESET_PL_PDA_VAUX,
1705           {true, true, true}, {0x2, 0x2, 0x2} },
1706 };
1707 
1708 static struct phy_defs s_phy_defs[] = {
1709         {"nw_phy", NWS_REG_NWS_CMU_K2,
1710          PHY_NW_IP_REG_PHY0_TOP_TBUS_ADDR_7_0_K2_E5,
1711          PHY_NW_IP_REG_PHY0_TOP_TBUS_ADDR_15_8_K2_E5,
1712          PHY_NW_IP_REG_PHY0_TOP_TBUS_DATA_7_0_K2_E5,
1713          PHY_NW_IP_REG_PHY0_TOP_TBUS_DATA_11_8_K2_E5},
1714         {"sgmii_phy", MS_REG_MS_CMU_K2_E5,
1715          PHY_SGMII_IP_REG_AHB_CMU_CSR_0_X132_K2_E5,
1716          PHY_SGMII_IP_REG_AHB_CMU_CSR_0_X133_K2_E5,
1717          PHY_SGMII_IP_REG_AHB_CMU_CSR_0_X130_K2_E5,
1718          PHY_SGMII_IP_REG_AHB_CMU_CSR_0_X131_K2_E5},
1719         {"pcie_phy0", PHY_PCIE_REG_PHY0_K2_E5,
1720          PHY_PCIE_IP_REG_AHB_CMU_CSR_0_X132_K2_E5,
1721          PHY_PCIE_IP_REG_AHB_CMU_CSR_0_X133_K2_E5,
1722          PHY_PCIE_IP_REG_AHB_CMU_CSR_0_X130_K2_E5,
1723          PHY_PCIE_IP_REG_AHB_CMU_CSR_0_X131_K2_E5},
1724         {"pcie_phy1", PHY_PCIE_REG_PHY1_K2_E5,
1725          PHY_PCIE_IP_REG_AHB_CMU_CSR_0_X132_K2_E5,
1726          PHY_PCIE_IP_REG_AHB_CMU_CSR_0_X133_K2_E5,
1727          PHY_PCIE_IP_REG_AHB_CMU_CSR_0_X130_K2_E5,
1728          PHY_PCIE_IP_REG_AHB_CMU_CSR_0_X131_K2_E5},
1729 };
1730 
1731 static struct split_type_defs s_split_type_defs[] = {
1732         /* SPLIT_TYPE_NONE */
1733         {"eng"},
1734 
1735         /* SPLIT_TYPE_PORT */
1736         {"port"},
1737 
1738         /* SPLIT_TYPE_PF */
1739         {"pf"},
1740 
1741         /* SPLIT_TYPE_PORT_PF */
1742         {"port"},
1743 
1744         /* SPLIT_TYPE_VF */
1745         {"vf"}
1746 };
1747 
1748 /**************************** Private Functions ******************************/
1749 
1750 /* Reads and returns a single dword from the specified unaligned buffer */
1751 static u32 qed_read_unaligned_dword(u8 *buf)
1752 {
1753         u32 dword;
1754 
1755         memcpy((u8 *)&dword, buf, sizeof(dword));
1756         return dword;
1757 }
1758 
1759 /* Sets the value of the specified GRC param */
1760 static void qed_grc_set_param(struct qed_hwfn *p_hwfn,
1761                               enum dbg_grc_params grc_param, u32 val)
1762 {
1763         struct dbg_tools_data *dev_data = &p_hwfn->dbg_info;
1764 
1765         dev_data->grc.param_val[grc_param] = val;
1766 }
1767 
1768 /* Returns the value of the specified GRC param */
1769 static u32 qed_grc_get_param(struct qed_hwfn *p_hwfn,
1770                              enum dbg_grc_params grc_param)
1771 {
1772         struct dbg_tools_data *dev_data = &p_hwfn->dbg_info;
1773 
1774         return dev_data->grc.param_val[grc_param];
1775 }
1776 
1777 /* Initializes the GRC parameters */
1778 static void qed_dbg_grc_init_params(struct qed_hwfn *p_hwfn)
1779 {
1780         struct dbg_tools_data *dev_data = &p_hwfn->dbg_info;
1781 
1782         if (!dev_data->grc.params_initialized) {
1783                 qed_dbg_grc_set_params_default(p_hwfn);
1784                 dev_data->grc.params_initialized = 1;
1785         }
1786 }
1787 
1788 /* Initializes debug data for the specified device */
1789 static enum dbg_status qed_dbg_dev_init(struct qed_hwfn *p_hwfn,
1790                                         struct qed_ptt *p_ptt)
1791 {
1792         struct dbg_tools_data *dev_data = &p_hwfn->dbg_info;
1793         u8 num_pfs = 0, max_pfs_per_port = 0;
1794 
1795         if (dev_data->initialized)
1796                 return DBG_STATUS_OK;
1797 
1798         /* Set chip */
1799         if (QED_IS_K2(p_hwfn->cdev)) {
1800                 dev_data->chip_id = CHIP_K2;
1801                 dev_data->mode_enable[MODE_K2] = 1;
1802                 dev_data->num_vfs = MAX_NUM_VFS_K2;
1803                 num_pfs = MAX_NUM_PFS_K2;
1804                 max_pfs_per_port = MAX_NUM_PFS_K2 / 2;
1805         } else if (QED_IS_BB_B0(p_hwfn->cdev)) {
1806                 dev_data->chip_id = CHIP_BB;
1807                 dev_data->mode_enable[MODE_BB] = 1;
1808                 dev_data->num_vfs = MAX_NUM_VFS_BB;
1809                 num_pfs = MAX_NUM_PFS_BB;
1810                 max_pfs_per_port = MAX_NUM_PFS_BB;
1811         } else {
1812                 return DBG_STATUS_UNKNOWN_CHIP;
1813         }
1814 
1815         /* Set platofrm */
1816         dev_data->platform_id = PLATFORM_ASIC;
1817         dev_data->mode_enable[MODE_ASIC] = 1;
1818 
1819         /* Set port mode */
1820         switch (qed_rd(p_hwfn, p_ptt, MISC_REG_PORT_MODE)) {
1821         case 0:
1822                 dev_data->mode_enable[MODE_PORTS_PER_ENG_1] = 1;
1823                 break;
1824         case 1:
1825                 dev_data->mode_enable[MODE_PORTS_PER_ENG_2] = 1;
1826                 break;
1827         case 2:
1828                 dev_data->mode_enable[MODE_PORTS_PER_ENG_4] = 1;
1829                 break;
1830         }
1831 
1832         /* Set 100G mode */
1833         if (dev_data->chip_id == CHIP_BB &&
1834             qed_rd(p_hwfn, p_ptt, CNIG_REG_NW_PORT_MODE_BB) == 2)
1835                 dev_data->mode_enable[MODE_100G] = 1;
1836 
1837         /* Set number of ports */
1838         if (dev_data->mode_enable[MODE_PORTS_PER_ENG_1] ||
1839             dev_data->mode_enable[MODE_100G])
1840                 dev_data->num_ports = 1;
1841         else if (dev_data->mode_enable[MODE_PORTS_PER_ENG_2])
1842                 dev_data->num_ports = 2;
1843         else if (dev_data->mode_enable[MODE_PORTS_PER_ENG_4])
1844                 dev_data->num_ports = 4;
1845 
1846         /* Set number of PFs per port */
1847         dev_data->num_pfs_per_port = min_t(u32,
1848                                            num_pfs / dev_data->num_ports,
1849                                            max_pfs_per_port);
1850 
1851         /* Initializes the GRC parameters */
1852         qed_dbg_grc_init_params(p_hwfn);
1853 
1854         dev_data->use_dmae = true;
1855         dev_data->initialized = 1;
1856 
1857         return DBG_STATUS_OK;
1858 }
1859 
1860 static struct dbg_bus_block *get_dbg_bus_block_desc(struct qed_hwfn *p_hwfn,
1861                                                     enum block_id block_id)
1862 {
1863         struct dbg_tools_data *dev_data = &p_hwfn->dbg_info;
1864 
1865         return (struct dbg_bus_block *)&dbg_bus_blocks[block_id *
1866                                                        MAX_CHIP_IDS +
1867                                                        dev_data->chip_id];
1868 }
1869 
1870 /* Reads the FW info structure for the specified Storm from the chip,
1871  * and writes it to the specified fw_info pointer.
1872  */
1873 static void qed_read_storm_fw_info(struct qed_hwfn *p_hwfn,
1874                                    struct qed_ptt *p_ptt,
1875                                    u8 storm_id, struct fw_info *fw_info)
1876 {
1877         struct storm_defs *storm = &s_storm_defs[storm_id];
1878         struct fw_info_location fw_info_location;
1879         u32 addr, i, *dest;
1880 
1881         memset(&fw_info_location, 0, sizeof(fw_info_location));
1882         memset(fw_info, 0, sizeof(*fw_info));
1883 
1884         /* Read first the address that points to fw_info location.
1885          * The address is located in the last line of the Storm RAM.
1886          */
1887         addr = storm->sem_fast_mem_addr + SEM_FAST_REG_INT_RAM +
1888                DWORDS_TO_BYTES(SEM_FAST_REG_INT_RAM_SIZE_BB_K2) -
1889                sizeof(fw_info_location);
1890         dest = (u32 *)&fw_info_location;
1891 
1892         for (i = 0; i < BYTES_TO_DWORDS(sizeof(fw_info_location));
1893              i++, addr += BYTES_IN_DWORD)
1894                 dest[i] = qed_rd(p_hwfn, p_ptt, addr);
1895 
1896         /* Read FW version info from Storm RAM */
1897         if (fw_info_location.size > 0 && fw_info_location.size <=
1898             sizeof(*fw_info)) {
1899                 addr = fw_info_location.grc_addr;
1900                 dest = (u32 *)fw_info;
1901                 for (i = 0; i < BYTES_TO_DWORDS(fw_info_location.size);
1902                      i++, addr += BYTES_IN_DWORD)
1903                         dest[i] = qed_rd(p_hwfn, p_ptt, addr);
1904         }
1905 }
1906 
1907 /* Dumps the specified string to the specified buffer.
1908  * Returns the dumped size in bytes.
1909  */
1910 static u32 qed_dump_str(char *dump_buf, bool dump, const char *str)
1911 {
1912         if (dump)
1913                 strcpy(dump_buf, str);
1914 
1915         return (u32)strlen(str) + 1;
1916 }
1917 
1918 /* Dumps zeros to align the specified buffer to dwords.
1919  * Returns the dumped size in bytes.
1920  */
1921 static u32 qed_dump_align(char *dump_buf, bool dump, u32 byte_offset)
1922 {
1923         u8 offset_in_dword, align_size;
1924 
1925         offset_in_dword = (u8)(byte_offset & 0x3);
1926         align_size = offset_in_dword ? BYTES_IN_DWORD - offset_in_dword : 0;
1927 
1928         if (dump && align_size)
1929                 memset(dump_buf, 0, align_size);
1930 
1931         return align_size;
1932 }
1933 
1934 /* Writes the specified string param to the specified buffer.
1935  * Returns the dumped size in dwords.
1936  */
1937 static u32 qed_dump_str_param(u32 *dump_buf,
1938                               bool dump,
1939                               const char *param_name, const char *param_val)
1940 {
1941         char *char_buf = (char *)dump_buf;
1942         u32 offset = 0;
1943 
1944         /* Dump param name */
1945         offset += qed_dump_str(char_buf + offset, dump, param_name);
1946 
1947         /* Indicate a string param value */
1948         if (dump)
1949                 *(char_buf + offset) = 1;
1950         offset++;
1951 
1952         /* Dump param value */
1953         offset += qed_dump_str(char_buf + offset, dump, param_val);
1954 
1955         /* Align buffer to next dword */
1956         offset += qed_dump_align(char_buf + offset, dump, offset);
1957 
1958         return BYTES_TO_DWORDS(offset);
1959 }
1960 
1961 /* Writes the specified numeric param to the specified buffer.
1962  * Returns the dumped size in dwords.
1963  */
1964 static u32 qed_dump_num_param(u32 *dump_buf,
1965                               bool dump, const char *param_name, u32 param_val)
1966 {
1967         char *char_buf = (char *)dump_buf;
1968         u32 offset = 0;
1969 
1970         /* Dump param name */
1971         offset += qed_dump_str(char_buf + offset, dump, param_name);
1972 
1973         /* Indicate a numeric param value */
1974         if (dump)
1975                 *(char_buf + offset) = 0;
1976         offset++;
1977 
1978         /* Align buffer to next dword */
1979         offset += qed_dump_align(char_buf + offset, dump, offset);
1980 
1981         /* Dump param value (and change offset from bytes to dwords) */
1982         offset = BYTES_TO_DWORDS(offset);
1983         if (dump)
1984                 *(dump_buf + offset) = param_val;
1985         offset++;
1986 
1987         return offset;
1988 }
1989 
1990 /* Reads the FW version and writes it as a param to the specified buffer.
1991  * Returns the dumped size in dwords.
1992  */
1993 static u32 qed_dump_fw_ver_param(struct qed_hwfn *p_hwfn,
1994                                  struct qed_ptt *p_ptt,
1995                                  u32 *dump_buf, bool dump)
1996 {
1997         char fw_ver_str[16] = EMPTY_FW_VERSION_STR;
1998         char fw_img_str[16] = EMPTY_FW_IMAGE_STR;
1999         struct fw_info fw_info = { {0}, {0} };
2000         u32 offset = 0;
2001 
2002         if (dump && !qed_grc_get_param(p_hwfn, DBG_GRC_PARAM_NO_FW_VER)) {
2003                 /* Read FW info from chip */
2004                 qed_read_fw_info(p_hwfn, p_ptt, &fw_info);
2005 
2006                 /* Create FW version/image strings */
2007                 if (snprintf(fw_ver_str, sizeof(fw_ver_str),
2008                              "%d_%d_%d_%d", fw_info.ver.num.major,
2009                              fw_info.ver.num.minor, fw_info.ver.num.rev,
2010                              fw_info.ver.num.eng) < 0)
2011                         DP_NOTICE(p_hwfn,
2012                                   "Unexpected debug error: invalid FW version string\n");
2013                 switch (fw_info.ver.image_id) {
2014                 case FW_IMG_MAIN:
2015                         strcpy(fw_img_str, "main");
2016                         break;
2017                 default:
2018                         strcpy(fw_img_str, "unknown");
2019                         break;
2020                 }
2021         }
2022 
2023         /* Dump FW version, image and timestamp */
2024         offset += qed_dump_str_param(dump_buf + offset,
2025                                      dump, "fw-version", fw_ver_str);
2026         offset += qed_dump_str_param(dump_buf + offset,
2027                                      dump, "fw-image", fw_img_str);
2028         offset += qed_dump_num_param(dump_buf + offset,
2029                                      dump,
2030                                      "fw-timestamp", fw_info.ver.timestamp);
2031 
2032         return offset;
2033 }
2034 
2035 /* Reads the MFW version and writes it as a param to the specified buffer.
2036  * Returns the dumped size in dwords.
2037  */
2038 static u32 qed_dump_mfw_ver_param(struct qed_hwfn *p_hwfn,
2039                                   struct qed_ptt *p_ptt,
2040                                   u32 *dump_buf, bool dump)
2041 {
2042         char mfw_ver_str[16] = EMPTY_FW_VERSION_STR;
2043 
2044         if (dump &&
2045             !qed_grc_get_param(p_hwfn, DBG_GRC_PARAM_NO_FW_VER)) {
2046                 u32 global_section_offsize, global_section_addr, mfw_ver;
2047                 u32 public_data_addr, global_section_offsize_addr;
2048 
2049                 /* Find MCP public data GRC address. Needs to be ORed with
2050                  * MCP_REG_SCRATCH due to a HW bug.
2051                  */
2052                 public_data_addr = qed_rd(p_hwfn,
2053                                           p_ptt,
2054                                           MISC_REG_SHARED_MEM_ADDR) |
2055                                    MCP_REG_SCRATCH;
2056 
2057                 /* Find MCP public global section offset */
2058                 global_section_offsize_addr = public_data_addr +
2059                                               offsetof(struct mcp_public_data,
2060                                                        sections) +
2061                                               sizeof(offsize_t) * PUBLIC_GLOBAL;
2062                 global_section_offsize = qed_rd(p_hwfn, p_ptt,
2063                                                 global_section_offsize_addr);
2064                 global_section_addr =
2065                         MCP_REG_SCRATCH +
2066                         (global_section_offsize & OFFSIZE_OFFSET_MASK) * 4;
2067 
2068                 /* Read MFW version from MCP public global section */
2069                 mfw_ver = qed_rd(p_hwfn, p_ptt,
2070                                  global_section_addr +
2071                                  offsetof(struct public_global, mfw_ver));
2072 
2073                 /* Dump MFW version param */
2074                 if (snprintf(mfw_ver_str, sizeof(mfw_ver_str), "%d_%d_%d_%d",
2075                              (u8)(mfw_ver >> 24), (u8)(mfw_ver >> 16),
2076                              (u8)(mfw_ver >> 8), (u8)mfw_ver) < 0)
2077                         DP_NOTICE(p_hwfn,
2078                                   "Unexpected debug error: invalid MFW version string\n");
2079         }
2080 
2081         return qed_dump_str_param(dump_buf, dump, "mfw-version", mfw_ver_str);
2082 }
2083 
2084 /* Writes a section header to the specified buffer.
2085  * Returns the dumped size in dwords.
2086  */
2087 static u32 qed_dump_section_hdr(u32 *dump_buf,
2088                                 bool dump, const char *name, u32 num_params)
2089 {
2090         return qed_dump_num_param(dump_buf, dump, name, num_params);
2091 }
2092 
2093 /* Writes the common global params to the specified buffer.
2094  * Returns the dumped size in dwords.
2095  */
2096 static u32 qed_dump_common_global_params(struct qed_hwfn *p_hwfn,
2097                                          struct qed_ptt *p_ptt,
2098                                          u32 *dump_buf,
2099                                          bool dump,
2100                                          u8 num_specific_global_params)
2101 {
2102         struct dbg_tools_data *dev_data = &p_hwfn->dbg_info;
2103         u32 offset = 0;
2104         u8 num_params;
2105 
2106         /* Dump global params section header */
2107         num_params = NUM_COMMON_GLOBAL_PARAMS + num_specific_global_params;
2108         offset += qed_dump_section_hdr(dump_buf + offset,
2109                                        dump, "global_params", num_params);
2110 
2111         /* Store params */
2112         offset += qed_dump_fw_ver_param(p_hwfn, p_ptt, dump_buf + offset, dump);
2113         offset += qed_dump_mfw_ver_param(p_hwfn,
2114                                          p_ptt, dump_buf + offset, dump);
2115         offset += qed_dump_num_param(dump_buf + offset,
2116                                      dump, "tools-version", TOOLS_VERSION);
2117         offset += qed_dump_str_param(dump_buf + offset,
2118                                      dump,
2119                                      "chip",
2120                                      s_chip_defs[dev_data->chip_id].name);
2121         offset += qed_dump_str_param(dump_buf + offset,
2122                                      dump,
2123                                      "platform",
2124                                      s_platform_defs[dev_data->platform_id].
2125                                      name);
2126         offset +=
2127             qed_dump_num_param(dump_buf + offset, dump, "pci-func",
2128                                p_hwfn->abs_pf_id);
2129 
2130         return offset;
2131 }
2132 
2133 /* Writes the "last" section (including CRC) to the specified buffer at the
2134  * given offset. Returns the dumped size in dwords.
2135  */
2136 static u32 qed_dump_last_section(u32 *dump_buf, u32 offset, bool dump)
2137 {
2138         u32 start_offset = offset;
2139 
2140         /* Dump CRC section header */
2141         offset += qed_dump_section_hdr(dump_buf + offset, dump, "last", 0);
2142 
2143         /* Calculate CRC32 and add it to the dword after the "last" section */
2144         if (dump)
2145                 *(dump_buf + offset) = ~crc32(0xffffffff,
2146                                               (u8 *)dump_buf,
2147                                               DWORDS_TO_BYTES(offset));
2148 
2149         offset++;
2150 
2151         return offset - start_offset;
2152 }
2153 
2154 /* Update blocks reset state  */
2155 static void qed_update_blocks_reset_state(struct qed_hwfn *p_hwfn,
2156                                           struct qed_ptt *p_ptt)
2157 {
2158         struct dbg_tools_data *dev_data = &p_hwfn->dbg_info;
2159         u32 reg_val[MAX_DBG_RESET_REGS] = { 0 };
2160         u32 i;
2161 
2162         /* Read reset registers */
2163         for (i = 0; i < MAX_DBG_RESET_REGS; i++)
2164                 if (s_reset_regs_defs[i].exists[dev_data->chip_id])
2165                         reg_val[i] = qed_rd(p_hwfn,
2166                                             p_ptt, s_reset_regs_defs[i].addr);
2167 
2168         /* Check if blocks are in reset */
2169         for (i = 0; i < MAX_BLOCK_ID; i++) {
2170                 struct block_defs *block = s_block_defs[i];
2171 
2172                 dev_data->block_in_reset[i] = block->has_reset_bit &&
2173                     !(reg_val[block->reset_reg] & BIT(block->reset_bit_offset));
2174         }
2175 }
2176 
2177 /* Enable / disable the Debug block */
2178 static void qed_bus_enable_dbg_block(struct qed_hwfn *p_hwfn,
2179                                      struct qed_ptt *p_ptt, bool enable)
2180 {
2181         qed_wr(p_hwfn, p_ptt, DBG_REG_DBG_BLOCK_ON, enable ? 1 : 0);
2182 }
2183 
2184 /* Resets the Debug block */
2185 static void qed_bus_reset_dbg_block(struct qed_hwfn *p_hwfn,
2186                                     struct qed_ptt *p_ptt)
2187 {
2188         u32 dbg_reset_reg_addr, old_reset_reg_val, new_reset_reg_val;
2189         struct block_defs *dbg_block = s_block_defs[BLOCK_DBG];
2190 
2191         dbg_reset_reg_addr = s_reset_regs_defs[dbg_block->reset_reg].addr;
2192         old_reset_reg_val = qed_rd(p_hwfn, p_ptt, dbg_reset_reg_addr);
2193         new_reset_reg_val =
2194             old_reset_reg_val & ~BIT(dbg_block->reset_bit_offset);
2195 
2196         qed_wr(p_hwfn, p_ptt, dbg_reset_reg_addr, new_reset_reg_val);
2197         qed_wr(p_hwfn, p_ptt, dbg_reset_reg_addr, old_reset_reg_val);
2198 }
2199 
2200 static void qed_bus_set_framing_mode(struct qed_hwfn *p_hwfn,
2201                                      struct qed_ptt *p_ptt,
2202                                      enum dbg_bus_frame_modes mode)
2203 {
2204         qed_wr(p_hwfn, p_ptt, DBG_REG_FRAMING_MODE, (u8)mode);
2205 }
2206 
2207 /* Enable / disable Debug Bus clients according to the specified mask
2208  * (1 = enable, 0 = disable).
2209  */
2210 static void qed_bus_enable_clients(struct qed_hwfn *p_hwfn,
2211                                    struct qed_ptt *p_ptt, u32 client_mask)
2212 {
2213         qed_wr(p_hwfn, p_ptt, DBG_REG_CLIENT_ENABLE, client_mask);
2214 }
2215 
2216 static bool qed_is_mode_match(struct qed_hwfn *p_hwfn, u16 *modes_buf_offset)
2217 {
2218         struct dbg_tools_data *dev_data = &p_hwfn->dbg_info;
2219         bool arg1, arg2;
2220         const u32 *ptr;
2221         u8 tree_val;
2222 
2223         /* Get next element from modes tree buffer */
2224         ptr = s_dbg_arrays[BIN_BUF_DBG_MODE_TREE].ptr;
2225         tree_val = ((u8 *)ptr)[(*modes_buf_offset)++];
2226 
2227         switch (tree_val) {
2228         case INIT_MODE_OP_NOT:
2229                 return !qed_is_mode_match(p_hwfn, modes_buf_offset);
2230         case INIT_MODE_OP_OR:
2231         case INIT_MODE_OP_AND:
2232                 arg1 = qed_is_mode_match(p_hwfn, modes_buf_offset);
2233                 arg2 = qed_is_mode_match(p_hwfn, modes_buf_offset);
2234                 return (tree_val == INIT_MODE_OP_OR) ? (arg1 ||
2235                                                         arg2) : (arg1 && arg2);
2236         default:
2237                 return dev_data->mode_enable[tree_val - MAX_INIT_MODE_OPS] > 0;
2238         }
2239 }
2240 
2241 /* Returns true if the specified entity (indicated by GRC param) should be
2242  * included in the dump, false otherwise.
2243  */
2244 static bool qed_grc_is_included(struct qed_hwfn *p_hwfn,
2245                                 enum dbg_grc_params grc_param)
2246 {
2247         return qed_grc_get_param(p_hwfn, grc_param) > 0;
2248 }
2249 
2250 /* Returns true of the specified Storm should be included in the dump, false
2251  * otherwise.
2252  */
2253 static bool qed_grc_is_storm_included(struct qed_hwfn *p_hwfn,
2254                                       enum dbg_storms storm)
2255 {
2256         return qed_grc_get_param(p_hwfn, (enum dbg_grc_params)storm) > 0;
2257 }
2258 
2259 /* Returns true if the specified memory should be included in the dump, false
2260  * otherwise.
2261  */
2262 static bool qed_grc_is_mem_included(struct qed_hwfn *p_hwfn,
2263                                     enum block_id block_id, u8 mem_group_id)
2264 {
2265         struct block_defs *block = s_block_defs[block_id];
2266         u8 i;
2267 
2268         /* Check Storm match */
2269         if (block->associated_to_storm &&
2270             !qed_grc_is_storm_included(p_hwfn,
2271                                        (enum dbg_storms)block->storm_id))
2272                 return false;
2273 
2274         for (i = 0; i < NUM_BIG_RAM_TYPES; i++) {
2275                 struct big_ram_defs *big_ram = &s_big_ram_defs[i];
2276 
2277                 if (mem_group_id == big_ram->mem_group_id ||
2278                     mem_group_id == big_ram->ram_mem_group_id)
2279                         return qed_grc_is_included(p_hwfn, big_ram->grc_param);
2280         }
2281 
2282         switch (mem_group_id) {
2283         case MEM_GROUP_PXP_ILT:
2284         case MEM_GROUP_PXP_MEM:
2285                 return qed_grc_is_included(p_hwfn, DBG_GRC_PARAM_DUMP_PXP);
2286         case MEM_GROUP_RAM:
2287                 return qed_grc_is_included(p_hwfn, DBG_GRC_PARAM_DUMP_RAM);
2288         case MEM_GROUP_PBUF:
2289                 return qed_grc_is_included(p_hwfn, DBG_GRC_PARAM_DUMP_PBUF);
2290         case MEM_GROUP_CAU_MEM:
2291         case MEM_GROUP_CAU_SB:
2292         case MEM_GROUP_CAU_PI:
2293                 return qed_grc_is_included(p_hwfn, DBG_GRC_PARAM_DUMP_CAU);
2294         case MEM_GROUP_QM_MEM:
2295                 return qed_grc_is_included(p_hwfn, DBG_GRC_PARAM_DUMP_QM);
2296         case MEM_GROUP_CFC_MEM:
2297         case MEM_GROUP_CONN_CFC_MEM:
2298         case MEM_GROUP_TASK_CFC_MEM:
2299                 return qed_grc_is_included(p_hwfn, DBG_GRC_PARAM_DUMP_CFC) ||
2300                        qed_grc_is_included(p_hwfn, DBG_GRC_PARAM_DUMP_CM_CTX);
2301         case MEM_GROUP_IGU_MEM:
2302         case MEM_GROUP_IGU_MSIX:
2303                 return qed_grc_is_included(p_hwfn, DBG_GRC_PARAM_DUMP_IGU);
2304         case MEM_GROUP_MULD_MEM:
2305                 return qed_grc_is_included(p_hwfn, DBG_GRC_PARAM_DUMP_MULD);
2306         case MEM_GROUP_PRS_MEM:
2307                 return qed_grc_is_included(p_hwfn, DBG_GRC_PARAM_DUMP_PRS);
2308         case MEM_GROUP_DMAE_MEM:
2309                 return qed_grc_is_included(p_hwfn, DBG_GRC_PARAM_DUMP_DMAE);
2310         case MEM_GROUP_TM_MEM:
2311                 return qed_grc_is_included(p_hwfn, DBG_GRC_PARAM_DUMP_TM);
2312         case MEM_GROUP_SDM_MEM:
2313                 return qed_grc_is_included(p_hwfn, DBG_GRC_PARAM_DUMP_SDM);
2314         case MEM_GROUP_TDIF_CTX:
2315         case MEM_GROUP_RDIF_CTX:
2316                 return qed_grc_is_included(p_hwfn, DBG_GRC_PARAM_DUMP_DIF);
2317         case MEM_GROUP_CM_MEM:
2318                 return qed_grc_is_included(p_hwfn, DBG_GRC_PARAM_DUMP_CM);
2319         case MEM_GROUP_IOR:
2320                 return qed_grc_is_included(p_hwfn, DBG_GRC_PARAM_DUMP_IOR);
2321         default:
2322                 return true;
2323         }
2324 }
2325 
2326 /* Stalls all Storms */
2327 static void qed_grc_stall_storms(struct qed_hwfn *p_hwfn,
2328                                  struct qed_ptt *p_ptt, bool stall)
2329 {
2330         u32 reg_addr;
2331         u8 storm_id;
2332 
2333         for (storm_id = 0; storm_id < MAX_DBG_STORMS; storm_id++) {
2334                 if (!qed_grc_is_storm_included(p_hwfn,
2335                                                (enum dbg_storms)storm_id))
2336                         continue;
2337 
2338                 reg_addr = s_storm_defs[storm_id].sem_fast_mem_addr +
2339                     SEM_FAST_REG_STALL_0_BB_K2;
2340                 qed_wr(p_hwfn, p_ptt, reg_addr, stall ? 1 : 0);
2341         }
2342 
2343         msleep(STALL_DELAY_MS);
2344 }
2345 
2346 /* Takes all blocks out of reset */
2347 static void qed_grc_unreset_blocks(struct qed_hwfn *p_hwfn,
2348                                    struct qed_ptt *p_ptt)
2349 {
2350         struct dbg_tools_data *dev_data = &p_hwfn->dbg_info;
2351         u32 reg_val[MAX_DBG_RESET_REGS] = { 0 };
2352         u32 block_id, i;
2353 
2354         /* Fill reset regs values */
2355         for (block_id = 0; block_id < MAX_BLOCK_ID; block_id++) {
2356                 struct block_defs *block = s_block_defs[block_id];
2357 
2358                 if (block->exists[dev_data->chip_id] && block->has_reset_bit &&
2359                     block->unreset)
2360                         reg_val[block->reset_reg] |=
2361                             BIT(block->reset_bit_offset);
2362         }
2363 
2364         /* Write reset registers */
2365         for (i = 0; i < MAX_DBG_RESET_REGS; i++) {
2366                 if (!s_reset_regs_defs[i].exists[dev_data->chip_id])
2367                         continue;
2368 
2369                 reg_val[i] |=
2370                         s_reset_regs_defs[i].unreset_val[dev_data->chip_id];
2371 
2372                 if (reg_val[i])
2373                         qed_wr(p_hwfn,
2374                                p_ptt,
2375                                s_reset_regs_defs[i].addr +
2376                                RESET_REG_UNRESET_OFFSET, reg_val[i]);
2377         }
2378 }
2379 
2380 /* Returns the attention block data of the specified block */
2381 static const struct dbg_attn_block_type_data *
2382 qed_get_block_attn_data(enum block_id block_id, enum dbg_attn_type attn_type)
2383 {
2384         const struct dbg_attn_block *base_attn_block_arr =
2385                 (const struct dbg_attn_block *)
2386                 s_dbg_arrays[BIN_BUF_DBG_ATTN_BLOCKS].ptr;
2387 
2388         return &base_attn_block_arr[block_id].per_type_data[attn_type];
2389 }
2390 
2391 /* Returns the attention registers of the specified block */
2392 static const struct dbg_attn_reg *
2393 qed_get_block_attn_regs(enum block_id block_id, enum dbg_attn_type attn_type,
2394                         u8 *num_attn_regs)
2395 {
2396         const struct dbg_attn_block_type_data *block_type_data =
2397                 qed_get_block_attn_data(block_id, attn_type);
2398 
2399         *num_attn_regs = block_type_data->num_regs;
2400 
2401         return &((const struct dbg_attn_reg *)
2402                  s_dbg_arrays[BIN_BUF_DBG_ATTN_REGS].ptr)[block_type_data->
2403                                                           regs_offset];
2404 }
2405 
2406 /* For each block, clear the status of all parities */
2407 static void qed_grc_clear_all_prty(struct qed_hwfn *p_hwfn,
2408                                    struct qed_ptt *p_ptt)
2409 {
2410         struct dbg_tools_data *dev_data = &p_hwfn->dbg_info;
2411         const struct dbg_attn_reg *attn_reg_arr;
2412         u8 reg_idx, num_attn_regs;
2413         u32 block_id;
2414 
2415         for (block_id = 0; block_id < MAX_BLOCK_ID; block_id++) {
2416                 if (dev_data->block_in_reset[block_id])
2417                         continue;
2418 
2419                 attn_reg_arr = qed_get_block_attn_regs((enum block_id)block_id,
2420                                                        ATTN_TYPE_PARITY,
2421                                                        &num_attn_regs);
2422 
2423                 for (reg_idx = 0; reg_idx < num_attn_regs; reg_idx++) {
2424                         const struct dbg_attn_reg *reg_data =
2425                                 &attn_reg_arr[reg_idx];
2426                         u16 modes_buf_offset;
2427                         bool eval_mode;
2428 
2429                         /* Check mode */
2430                         eval_mode = GET_FIELD(reg_data->mode.data,
2431                                               DBG_MODE_HDR_EVAL_MODE) > 0;
2432                         modes_buf_offset =
2433                                 GET_FIELD(reg_data->mode.data,
2434                                           DBG_MODE_HDR_MODES_BUF_OFFSET);
2435 
2436                         /* If Mode match: clear parity status */
2437                         if (!eval_mode ||
2438                             qed_is_mode_match(p_hwfn, &modes_buf_offset))
2439                                 qed_rd(p_hwfn, p_ptt,
2440                                        DWORDS_TO_BYTES(reg_data->
2441                                                        sts_clr_address));
2442                 }
2443         }
2444 }
2445 
2446 /* Dumps GRC registers section header. Returns the dumped size in dwords.
2447  * The following parameters are dumped:
2448  * - count: no. of dumped entries
2449  * - split_type: split type
2450  * - split_id: split ID (dumped only if split_id != SPLIT_TYPE_NONE)
2451  * - param_name: user parameter value (dumped only if param_name != NULL
2452  *               and param_val != NULL).
2453  */
2454 static u32 qed_grc_dump_regs_hdr(u32 *dump_buf,
2455                                  bool dump,
2456                                  u32 num_reg_entries,
2457                                  enum init_split_types split_type,
2458                                  u8 split_id,
2459                                  const char *param_name, const char *param_val)
2460 {
2461         u8 num_params = 2 +
2462             (split_type != SPLIT_TYPE_NONE ? 1 : 0) + (param_name ? 1 : 0);
2463         u32 offset = 0;
2464 
2465         offset += qed_dump_section_hdr(dump_buf + offset,
2466                                        dump, "grc_regs", num_params);
2467         offset += qed_dump_num_param(dump_buf + offset,
2468                                      dump, "count", num_reg_entries);
2469         offset += qed_dump_str_param(dump_buf + offset,
2470                                      dump, "split",
2471                                      s_split_type_defs[split_type].name);
2472         if (split_type != SPLIT_TYPE_NONE)
2473                 offset += qed_dump_num_param(dump_buf + offset,
2474                                              dump, "id", split_id);
2475         if (param_name && param_val)
2476                 offset += qed_dump_str_param(dump_buf + offset,
2477                                              dump, param_name, param_val);
2478 
2479         return offset;
2480 }
2481 
2482 /* Reads the specified registers into the specified buffer.
2483  * The addr and len arguments are specified in dwords.
2484  */
2485 void qed_read_regs(struct qed_hwfn *p_hwfn,
2486                    struct qed_ptt *p_ptt, u32 *buf, u32 addr, u32 len)
2487 {
2488         u32 i;
2489 
2490         for (i = 0; i < len; i++)
2491                 buf[i] = qed_rd(p_hwfn, p_ptt, DWORDS_TO_BYTES(addr + i));
2492 }
2493 
2494 /* Dumps the GRC registers in the specified address range.
2495  * Returns the dumped size in dwords.
2496  * The addr and len arguments are specified in dwords.
2497  */
2498 static u32 qed_grc_dump_addr_range(struct qed_hwfn *p_hwfn,
2499                                    struct qed_ptt *p_ptt,
2500                                    u32 *dump_buf,
2501                                    bool dump, u32 addr, u32 len, bool wide_bus,
2502                                    enum init_split_types split_type,
2503                                    u8 split_id)
2504 {
2505         struct dbg_tools_data *dev_data = &p_hwfn->dbg_info;
2506         u8 port_id = 0, pf_id = 0, vf_id = 0, fid = 0;
2507 
2508         if (!dump)
2509                 return len;
2510 
2511         /* Print log if needed */
2512         dev_data->num_regs_read += len;
2513         if (dev_data->num_regs_read >=
2514             s_platform_defs[dev_data->platform_id].log_thresh) {
2515                 DP_VERBOSE(p_hwfn,
2516                            QED_MSG_DEBUG,
2517                            "Dumping %d registers...\n",
2518                            dev_data->num_regs_read);
2519                 dev_data->num_regs_read = 0;
2520         }
2521 
2522         switch (split_type) {
2523         case SPLIT_TYPE_PORT:
2524                 port_id = split_id;
2525                 break;
2526         case SPLIT_TYPE_PF:
2527                 pf_id = split_id;
2528                 break;
2529         case SPLIT_TYPE_PORT_PF:
2530                 port_id = split_id / dev_data->num_pfs_per_port;
2531                 pf_id = port_id + dev_data->num_ports *
2532                     (split_id % dev_data->num_pfs_per_port);
2533                 break;
2534         case SPLIT_TYPE_VF:
2535                 vf_id = split_id;
2536                 break;
2537         default:
2538                 break;
2539         }
2540 
2541         /* Try reading using DMAE */
2542         if (dev_data->use_dmae && split_type == SPLIT_TYPE_NONE &&
2543             (len >= s_platform_defs[dev_data->platform_id].dmae_thresh ||
2544              wide_bus)) {
2545                 if (!qed_dmae_grc2host(p_hwfn, p_ptt, DWORDS_TO_BYTES(addr),
2546                                        (u64)(uintptr_t)(dump_buf), len, NULL))
2547                         return len;
2548                 dev_data->use_dmae = 0;
2549                 DP_VERBOSE(p_hwfn,
2550                            QED_MSG_DEBUG,
2551                            "Failed reading from chip using DMAE, using GRC instead\n");
2552         }
2553 
2554         /* If not read using DMAE, read using GRC */
2555 
2556         /* Set pretend */
2557         if (split_type != dev_data->pretend.split_type || split_id !=
2558             dev_data->pretend.split_id) {
2559                 switch (split_type) {
2560                 case SPLIT_TYPE_PORT:
2561                         qed_port_pretend(p_hwfn, p_ptt, port_id);
2562                         break;
2563                 case SPLIT_TYPE_PF:
2564                         fid = pf_id << PXP_PRETEND_CONCRETE_FID_PFID_SHIFT;
2565                         qed_fid_pretend(p_hwfn, p_ptt, fid);
2566                         break;
2567                 case SPLIT_TYPE_PORT_PF:
2568                         fid = pf_id << PXP_PRETEND_CONCRETE_FID_PFID_SHIFT;
2569                         qed_port_fid_pretend(p_hwfn, p_ptt, port_id, fid);
2570                         break;
2571                 case SPLIT_TYPE_VF:
2572                         fid = BIT(PXP_PRETEND_CONCRETE_FID_VFVALID_SHIFT) |
2573                               (vf_id << PXP_PRETEND_CONCRETE_FID_VFID_SHIFT);
2574                         qed_fid_pretend(p_hwfn, p_ptt, fid);
2575                         break;
2576                 default:
2577                         break;
2578                 }
2579 
2580                 dev_data->pretend.split_type = (u8)split_type;
2581                 dev_data->pretend.split_id = split_id;
2582         }
2583 
2584         /* Read registers using GRC */
2585         qed_read_regs(p_hwfn, p_ptt, dump_buf, addr, len);
2586 
2587         return len;
2588 }
2589 
2590 /* Dumps GRC registers sequence header. Returns the dumped size in dwords.
2591  * The addr and len arguments are specified in dwords.
2592  */
2593 static u32 qed_grc_dump_reg_entry_hdr(u32 *dump_buf,
2594                                       bool dump, u32 addr, u32 len)
2595 {
2596         if (dump)
2597                 *dump_buf = addr | (len << REG_DUMP_LEN_SHIFT);
2598 
2599         return 1;
2600 }
2601 
2602 /* Dumps GRC registers sequence. Returns the dumped size in dwords.
2603  * The addr and len arguments are specified in dwords.
2604  */
2605 static u32 qed_grc_dump_reg_entry(struct qed_hwfn *p_hwfn,
2606                                   struct qed_ptt *p_ptt,
2607                                   u32 *dump_buf,
2608                                   bool dump, u32 addr, u32 len, bool wide_bus,
2609                                   enum init_split_types split_type, u8 split_id)
2610 {
2611         u32 offset = 0;
2612 
2613         offset += qed_grc_dump_reg_entry_hdr(dump_buf, dump, addr, len);
2614         offset += qed_grc_dump_addr_range(p_hwfn,
2615                                           p_ptt,
2616                                           dump_buf + offset,
2617                                           dump, addr, len, wide_bus,
2618                                           split_type, split_id);
2619 
2620         return offset;
2621 }
2622 
2623 /* Dumps GRC registers sequence with skip cycle.
2624  * Returns the dumped size in dwords.
2625  * - addr:      start GRC address in dwords
2626  * - total_len: total no. of dwords to dump
2627  * - read_len:  no. consecutive dwords to read
2628  * - skip_len:  no. of dwords to skip (and fill with zeros)
2629  */
2630 static u32 qed_grc_dump_reg_entry_skip(struct qed_hwfn *p_hwfn,
2631                                        struct qed_ptt *p_ptt,
2632                                        u32 *dump_buf,
2633                                        bool dump,
2634                                        u32 addr,
2635                                        u32 total_len,
2636                                        u32 read_len, u32 skip_len)
2637 {
2638         u32 offset = 0, reg_offset = 0;
2639 
2640         offset += qed_grc_dump_reg_entry_hdr(dump_buf, dump, addr, total_len);
2641 
2642         if (!dump)
2643                 return offset + total_len;
2644 
2645         while (reg_offset < total_len) {
2646                 u32 curr_len = min_t(u32, read_len, total_len - reg_offset);
2647 
2648                 offset += qed_grc_dump_addr_range(p_hwfn,
2649                                                   p_ptt,
2650                                                   dump_buf + offset,
2651                                                   dump,  addr, curr_len, false,
2652                                                   SPLIT_TYPE_NONE, 0);
2653                 reg_offset += curr_len;
2654                 addr += curr_len;
2655 
2656                 if (reg_offset < total_len) {
2657                         curr_len = min_t(u32, skip_len, total_len - skip_len);
2658                         memset(dump_buf + offset, 0, DWORDS_TO_BYTES(curr_len));
2659                         offset += curr_len;
2660                         reg_offset += curr_len;
2661                         addr += curr_len;
2662                 }
2663         }
2664 
2665         return offset;
2666 }
2667 
2668 /* Dumps GRC registers entries. Returns the dumped size in dwords. */
2669 static u32 qed_grc_dump_regs_entries(struct qed_hwfn *p_hwfn,
2670                                      struct qed_ptt *p_ptt,
2671                                      struct dbg_array input_regs_arr,
2672                                      u32 *dump_buf,
2673                                      bool dump,
2674                                      enum init_split_types split_type,
2675                                      u8 split_id,
2676                                      bool block_enable[MAX_BLOCK_ID],
2677                                      u32 *num_dumped_reg_entries)
2678 {
2679         u32 i, offset = 0, input_offset = 0;
2680         bool mode_match = true;
2681 
2682         *num_dumped_reg_entries = 0;
2683 
2684         while (input_offset < input_regs_arr.size_in_dwords) {
2685                 const struct dbg_dump_cond_hdr *cond_hdr =
2686                     (const struct dbg_dump_cond_hdr *)
2687                     &input_regs_arr.ptr[input_offset++];
2688                 u16 modes_buf_offset;
2689                 bool eval_mode;
2690 
2691                 /* Check mode/block */
2692                 eval_mode = GET_FIELD(cond_hdr->mode.data,
2693                                       DBG_MODE_HDR_EVAL_MODE) > 0;
2694                 if (eval_mode) {
2695                         modes_buf_offset =
2696                                 GET_FIELD(cond_hdr->mode.data,
2697                                           DBG_MODE_HDR_MODES_BUF_OFFSET);
2698                         mode_match = qed_is_mode_match(p_hwfn,
2699                                                        &modes_buf_offset);
2700                 }
2701 
2702                 if (!mode_match || !block_enable[cond_hdr->block_id]) {
2703                         input_offset += cond_hdr->data_size;
2704                         continue;
2705                 }
2706 
2707                 for (i = 0; i < cond_hdr->data_size; i++, input_offset++) {
2708                         const struct dbg_dump_reg *reg =
2709                             (const struct dbg_dump_reg *)
2710                             &input_regs_arr.ptr[input_offset];
2711                         u32 addr, len;
2712                         bool wide_bus;
2713 
2714                         addr = GET_FIELD(reg->data, DBG_DUMP_REG_ADDRESS);
2715                         len = GET_FIELD(reg->data, DBG_DUMP_REG_LENGTH);
2716                         wide_bus = GET_FIELD(reg->data, DBG_DUMP_REG_WIDE_BUS);
2717                         offset += qed_grc_dump_reg_entry(p_hwfn,
2718                                                          p_ptt,
2719                                                          dump_buf + offset,
2720                                                          dump,
2721                                                          addr,
2722                                                          len,
2723                                                          wide_bus,
2724                                                          split_type, split_id);
2725                         (*num_dumped_reg_entries)++;
2726                 }
2727         }
2728 
2729         return offset;
2730 }
2731 
2732 /* Dumps GRC registers entries. Returns the dumped size in dwords. */
2733 static u32 qed_grc_dump_split_data(struct qed_hwfn *p_hwfn,
2734                                    struct qed_ptt *p_ptt,
2735                                    struct dbg_array input_regs_arr,
2736                                    u32 *dump_buf,
2737                                    bool dump,
2738                                    bool block_enable[MAX_BLOCK_ID],
2739                                    enum init_split_types split_type,
2740                                    u8 split_id,
2741                                    const char *param_name,
2742                                    const char *param_val)
2743 {
2744         struct dbg_tools_data *dev_data = &p_hwfn->dbg_info;
2745         enum init_split_types hdr_split_type = split_type;
2746         u32 num_dumped_reg_entries, offset;
2747         u8 hdr_split_id = split_id;
2748 
2749         /* In PORT_PF split type, print a port split header */
2750         if (split_type == SPLIT_TYPE_PORT_PF) {
2751                 hdr_split_type = SPLIT_TYPE_PORT;
2752                 hdr_split_id = split_id / dev_data->num_pfs_per_port;
2753         }
2754 
2755         /* Calculate register dump header size (and skip it for now) */
2756         offset = qed_grc_dump_regs_hdr(dump_buf,
2757                                        false,
2758                                        0,
2759                                        hdr_split_type,
2760                                        hdr_split_id, param_name, param_val);
2761 
2762         /* Dump registers */
2763         offset += qed_grc_dump_regs_entries(p_hwfn,
2764                                             p_ptt,
2765                                             input_regs_arr,
2766                                             dump_buf + offset,
2767                                             dump,
2768                                             split_type,
2769                                             split_id,
2770                                             block_enable,
2771                                             &num_dumped_reg_entries);
2772 
2773         /* Write register dump header */
2774         if (dump && num_dumped_reg_entries > 0)
2775                 qed_grc_dump_regs_hdr(dump_buf,
2776                                       dump,
2777                                       num_dumped_reg_entries,
2778                                       hdr_split_type,
2779                                       hdr_split_id, param_name, param_val);
2780 
2781         return num_dumped_reg_entries > 0 ? offset : 0;
2782 }
2783 
2784 /* Dumps registers according to the input registers array. Returns the dumped
2785  * size in dwords.
2786  */
2787 static u32 qed_grc_dump_registers(struct qed_hwfn *p_hwfn,
2788                                   struct qed_ptt *p_ptt,
2789                                   u32 *dump_buf,
2790                                   bool dump,
2791                                   bool block_enable[MAX_BLOCK_ID],
2792                                   const char *param_name, const char *param_val)
2793 {
2794         struct dbg_tools_data *dev_data = &p_hwfn->dbg_info;
2795         u32 offset = 0, input_offset = 0;
2796         u16 fid;
2797         while (input_offset <
2798                s_dbg_arrays[BIN_BUF_DBG_DUMP_REG].size_in_dwords) {
2799                 const struct dbg_dump_split_hdr *split_hdr;
2800                 struct dbg_array curr_input_regs_arr;
2801                 enum init_split_types split_type;
2802                 u16 split_count = 0;
2803                 u32 split_data_size;
2804                 u8 split_id;
2805 
2806                 split_hdr =
2807                         (const struct dbg_dump_split_hdr *)
2808                         &s_dbg_arrays[BIN_BUF_DBG_DUMP_REG].ptr[input_offset++];
2809                 split_type =
2810                         GET_FIELD(split_hdr->hdr,
2811                                   DBG_DUMP_SPLIT_HDR_SPLIT_TYPE_ID);
2812                 split_data_size =
2813                         GET_FIELD(split_hdr->hdr,
2814                                   DBG_DUMP_SPLIT_HDR_DATA_SIZE);
2815                 curr_input_regs_arr.ptr =
2816                         &s_dbg_arrays[BIN_BUF_DBG_DUMP_REG].ptr[input_offset];
2817                 curr_input_regs_arr.size_in_dwords = split_data_size;
2818 
2819                 switch (split_type) {
2820                 case SPLIT_TYPE_NONE:
2821                         split_count = 1;
2822                         break;
2823                 case SPLIT_TYPE_PORT:
2824                         split_count = dev_data->num_ports;
2825                         break;
2826                 case SPLIT_TYPE_PF:
2827                 case SPLIT_TYPE_PORT_PF:
2828                         split_count = dev_data->num_ports *
2829                             dev_data->num_pfs_per_port;
2830                         break;
2831                 case SPLIT_TYPE_VF:
2832                         split_count = dev_data->num_vfs;
2833                         break;
2834                 default:
2835                         return 0;
2836                 }
2837 
2838                 for (split_id = 0; split_id < split_count; split_id++)
2839                         offset += qed_grc_dump_split_data(p_hwfn, p_ptt,
2840                                                           curr_input_regs_arr,
2841                                                           dump_buf + offset,
2842                                                           dump, block_enable,
2843                                                           split_type,
2844                                                           split_id,
2845                                                           param_name,
2846                                                           param_val);
2847 
2848                 input_offset += split_data_size;
2849         }
2850 
2851         /* Cancel pretends (pretend to original PF) */
2852         if (dump) {
2853                 fid = p_hwfn->rel_pf_id << PXP_PRETEND_CONCRETE_FID_PFID_SHIFT;
2854                 qed_fid_pretend(p_hwfn, p_ptt, fid);
2855                 dev_data->pretend.split_type = SPLIT_TYPE_NONE;
2856                 dev_data->pretend.split_id = 0;
2857         }
2858 
2859         return offset;
2860 }
2861 
2862 /* Dump reset registers. Returns the dumped size in dwords. */
2863 static u32 qed_grc_dump_reset_regs(struct qed_hwfn *p_hwfn,
2864                                    struct qed_ptt *p_ptt,
2865                                    u32 *dump_buf, bool dump)
2866 {
2867         struct dbg_tools_data *dev_data = &p_hwfn->dbg_info;
2868         u32 i, offset = 0, num_regs = 0;
2869 
2870         /* Calculate header size */
2871         offset += qed_grc_dump_regs_hdr(dump_buf,
2872                                         false, 0,
2873                                         SPLIT_TYPE_NONE, 0, NULL, NULL);
2874 
2875         /* Write reset registers */
2876         for (i = 0; i < MAX_DBG_RESET_REGS; i++) {
2877                 if (!s_reset_regs_defs[i].exists[dev_data->chip_id])
2878                         continue;
2879 
2880                 offset += qed_grc_dump_reg_entry(p_hwfn,
2881                                                  p_ptt,
2882                                                  dump_buf + offset,
2883                                                  dump,
2884                                                  BYTES_TO_DWORDS
2885                                                  (s_reset_regs_defs[i].addr), 1,
2886                                                  false, SPLIT_TYPE_NONE, 0);
2887                 num_regs++;
2888         }
2889 
2890         /* Write header */
2891         if (dump)
2892                 qed_grc_dump_regs_hdr(dump_buf,
2893                                       true, num_regs, SPLIT_TYPE_NONE,
2894                                       0, NULL, NULL);
2895 
2896         return offset;
2897 }
2898 
2899 /* Dump registers that are modified during GRC Dump and therefore must be
2900  * dumped first. Returns the dumped size in dwords.
2901  */
2902 static u32 qed_grc_dump_modified_regs(struct qed_hwfn *p_hwfn,
2903                                       struct qed_ptt *p_ptt,
2904                                       u32 *dump_buf, bool dump)
2905 {
2906         struct dbg_tools_data *dev_data = &p_hwfn->dbg_info;
2907         u32 block_id, offset = 0, num_reg_entries = 0;
2908         const struct dbg_attn_reg *attn_reg_arr;
2909         u8 storm_id, reg_idx, num_attn_regs;
2910 
2911         /* Calculate header size */
2912         offset += qed_grc_dump_regs_hdr(dump_buf,
2913                                         false, 0, SPLIT_TYPE_NONE,
2914                                         0, NULL, NULL);
2915 
2916         /* Write parity registers */
2917         for (block_id = 0; block_id < MAX_BLOCK_ID; block_id++) {
2918                 if (dev_data->block_in_reset[block_id] && dump)
2919                         continue;
2920 
2921                 attn_reg_arr = qed_get_block_attn_regs((enum block_id)block_id,
2922                                                        ATTN_TYPE_PARITY,
2923                                                        &num_attn_regs);
2924 
2925                 for (reg_idx = 0; reg_idx < num_attn_regs; reg_idx++) {
2926                         const struct dbg_attn_reg *reg_data =
2927                                 &attn_reg_arr[reg_idx];
2928                         u16 modes_buf_offset;
2929                         bool eval_mode;
2930                         u32 addr;
2931 
2932                         /* Check mode */
2933                         eval_mode = GET_FIELD(reg_data->mode.data,
2934                                               DBG_MODE_HDR_EVAL_MODE) > 0;
2935                         modes_buf_offset =
2936                                 GET_FIELD(reg_data->mode.data,
2937                                           DBG_MODE_HDR_MODES_BUF_OFFSET);
2938                         if (eval_mode &&
2939                             !qed_is_mode_match(p_hwfn, &modes_buf_offset))
2940                                 continue;
2941 
2942                         /* Mode match: read & dump registers */
2943                         addr = reg_data->mask_address;
2944                         offset += qed_grc_dump_reg_entry(p_hwfn,
2945                                                          p_ptt,
2946                                                          dump_buf + offset,
2947                                                          dump,
2948                                                          addr,
2949                                                          1, false,
2950                                                          SPLIT_TYPE_NONE, 0);
2951                         addr = GET_FIELD(reg_data->data,
2952                                          DBG_ATTN_REG_STS_ADDRESS);
2953                         offset += qed_grc_dump_reg_entry(p_hwfn,
2954                                                          p_ptt,
2955                                                          dump_buf + offset,
2956                                                          dump,
2957                                                          addr,
2958                                                          1, false,
2959                                                          SPLIT_TYPE_NONE, 0);
2960                         num_reg_entries += 2;
2961                 }
2962         }
2963 
2964         /* Write Storm stall status registers */
2965         for (storm_id = 0; storm_id < MAX_DBG_STORMS; storm_id++) {
2966                 struct storm_defs *storm = &s_storm_defs[storm_id];
2967                 u32 addr;
2968 
2969                 if (dev_data->block_in_reset[storm->block_id] && dump)
2970                         continue;
2971 
2972                 addr =
2973                     BYTES_TO_DWORDS(s_storm_defs[storm_id].sem_fast_mem_addr +
2974                                     SEM_FAST_REG_STALLED);
2975                 offset += qed_grc_dump_reg_entry(p_hwfn,
2976                                                  p_ptt,
2977                                                  dump_buf + offset,
2978                                                  dump,
2979                                                  addr,
2980                                                  1,
2981                                                  false, SPLIT_TYPE_NONE, 0);
2982                 num_reg_entries++;
2983         }
2984 
2985         /* Write header */
2986         if (dump)
2987                 qed_grc_dump_regs_hdr(dump_buf,
2988                                       true,
2989                                       num_reg_entries, SPLIT_TYPE_NONE,
2990                                       0, NULL, NULL);
2991 
2992         return offset;
2993 }
2994 
2995 /* Dumps registers that can't be represented in the debug arrays */
2996 static u32 qed_grc_dump_special_regs(struct qed_hwfn *p_hwfn,
2997                                      struct qed_ptt *p_ptt,
2998                                      u32 *dump_buf, bool dump)
2999 {
3000         u32 offset = 0, addr;
3001 
3002         offset += qed_grc_dump_regs_hdr(dump_buf,
3003                                         dump, 2, SPLIT_TYPE_NONE, 0,
3004                                         NULL, NULL);
3005 
3006         /* Dump R/TDIF_REG_DEBUG_ERROR_INFO_SIZE (every 8'th register should be
3007          * skipped).
3008          */
3009         addr = BYTES_TO_DWORDS(RDIF_REG_DEBUG_ERROR_INFO);
3010         offset += qed_grc_dump_reg_entry_skip(p_hwfn,
3011                                               p_ptt,
3012                                               dump_buf + offset,
3013                                               dump,
3014                                               addr,
3015                                               RDIF_REG_DEBUG_ERROR_INFO_SIZE,
3016                                               7,
3017                                               1);
3018         addr = BYTES_TO_DWORDS(TDIF_REG_DEBUG_ERROR_INFO);
3019         offset +=
3020             qed_grc_dump_reg_entry_skip(p_hwfn,
3021                                         p_ptt,
3022                                         dump_buf + offset,
3023                                         dump,
3024                                         addr,
3025                                         TDIF_REG_DEBUG_ERROR_INFO_SIZE,
3026                                         7,
3027                                         1);
3028 
3029         return offset;
3030 }
3031 
3032 /* Dumps a GRC memory header (section and params). Returns the dumped size in
3033  * dwords. The following parameters are dumped:
3034  * - name:         dumped only if it's not NULL.
3035  * - addr:         in dwords, dumped only if name is NULL.
3036  * - len:          in dwords, always dumped.
3037  * - width:        dumped if it's not zero.
3038  * - packed:       dumped only if it's not false.
3039  * - mem_group:    always dumped.
3040  * - is_storm:     true only if the memory is related to a Storm.
3041  * - storm_letter: valid only if is_storm is true.
3042  *
3043  */
3044 static u32 qed_grc_dump_mem_hdr(struct qed_hwfn *p_hwfn,
3045                                 u32 *dump_buf,
3046                                 bool dump,
3047                                 const char *name,
3048                                 u32 addr,
3049                                 u32 len,
3050                                 u32 bit_width,
3051                                 bool packed,
3052                                 const char *mem_group,
3053                                 bool is_storm, char storm_letter)
3054 {
3055         u8 num_params = 3;
3056         u32 offset = 0;
3057         char buf[64];
3058 
3059         if (!len)
3060                 DP_NOTICE(p_hwfn,
3061                           "Unexpected GRC Dump error: dumped memory size must be non-zero\n");
3062 
3063         if (bit_width)
3064                 num_params++;
3065         if (packed)
3066                 num_params++;
3067 
3068         /* Dump section header */
3069         offset += qed_dump_section_hdr(dump_buf + offset,
3070                                        dump, "grc_mem", num_params);
3071 
3072         if (name) {
3073                 /* Dump name */
3074                 if (is_storm) {
3075                         strcpy(buf, "?STORM_");
3076                         buf[0] = storm_letter;
3077                         strcpy(buf + strlen(buf), name);
3078                 } else {
3079                         strcpy(buf, name);
3080                 }
3081 
3082                 offset += qed_dump_str_param(dump_buf + offset,
3083                                              dump, "name", buf);
3084         } else {
3085                 /* Dump address */
3086                 u32 addr_in_bytes = DWORDS_TO_BYTES(addr);
3087 
3088                 offset += qed_dump_num_param(dump_buf + offset,
3089                                              dump, "addr", addr_in_bytes);
3090         }
3091 
3092         /* Dump len */
3093         offset += qed_dump_num_param(dump_buf + offset, dump, "len", len);
3094 
3095         /* Dump bit width */
3096         if (bit_width)
3097                 offset += qed_dump_num_param(dump_buf + offset,
3098                                              dump, "width", bit_width);
3099 
3100         /* Dump packed */
3101         if (packed)
3102                 offset += qed_dump_num_param(dump_buf + offset,
3103                                              dump, "packed", 1);
3104 
3105         /* Dump reg type */
3106         if (is_storm) {
3107                 strcpy(buf, "?STORM_");
3108                 buf[0] = storm_letter;
3109                 strcpy(buf + strlen(buf), mem_group);
3110         } else {
3111                 strcpy(buf, mem_group);
3112         }
3113 
3114         offset += qed_dump_str_param(dump_buf + offset, dump, "type", buf);
3115 
3116         return offset;
3117 }
3118 
3119 /* Dumps a single GRC memory. If name is NULL, the memory is stored by address.
3120  * Returns the dumped size in dwords.
3121  * The addr and len arguments are specified in dwords.
3122  */
3123 static u32 qed_grc_dump_mem(struct qed_hwfn *p_hwfn,
3124                             struct qed_ptt *p_ptt,
3125                             u32 *dump_buf,
3126                             bool dump,
3127                             const char *name,
3128                             u32 addr,
3129                             u32 len,
3130                             bool wide_bus,
3131                             u32 bit_width,
3132                             bool packed,
3133                             const char *mem_group,
3134                             bool is_storm, char storm_letter)
3135 {
3136         u32 offset = 0;
3137 
3138         offset += qed_grc_dump_mem_hdr(p_hwfn,
3139                                        dump_buf + offset,
3140                                        dump,
3141                                        name,
3142                                        addr,
3143                                        len,
3144                                        bit_width,
3145                                        packed,
3146                                        mem_group, is_storm, storm_letter);
3147         offset += qed_grc_dump_addr_range(p_hwfn,
3148                                           p_ptt,
3149                                           dump_buf + offset,
3150                                           dump, addr, len, wide_bus,
3151                                           SPLIT_TYPE_NONE, 0);
3152 
3153         return offset;
3154 }
3155 
3156 /* Dumps GRC memories entries. Returns the dumped size in dwords. */
3157 static u32 qed_grc_dump_mem_entries(struct qed_hwfn *p_hwfn,
3158                                     struct qed_ptt *p_ptt,
3159                                     struct dbg_array input_mems_arr,
3160                                     u32 *dump_buf, bool dump)
3161 {
3162         u32 i, offset = 0, input_offset = 0;
3163         bool mode_match = true;
3164 
3165         while (input_offset < input_mems_arr.size_in_dwords) {
3166                 const struct dbg_dump_cond_hdr *cond_hdr;
3167                 u16 modes_buf_offset;
3168                 u32 num_entries;
3169                 bool eval_mode;
3170 
3171                 cond_hdr = (const struct dbg_dump_cond_hdr *)
3172                            &input_mems_arr.ptr[input_offset++];
3173                 num_entries = cond_hdr->data_size / MEM_DUMP_ENTRY_SIZE_DWORDS;
3174 
3175                 /* Check required mode */
3176                 eval_mode = GET_FIELD(cond_hdr->mode.data,
3177                                       DBG_MODE_HDR_EVAL_MODE) > 0;
3178                 if (eval_mode) {
3179                         modes_buf_offset =
3180                                 GET_FIELD(cond_hdr->mode.data,
3181                                           DBG_MODE_HDR_MODES_BUF_OFFSET);
3182                         mode_match = qed_is_mode_match(p_hwfn,
3183                                                        &modes_buf_offset);
3184                 }
3185 
3186                 if (!mode_match) {
3187                         input_offset += cond_hdr->data_size;
3188                         continue;
3189                 }
3190 
3191                 for (i = 0; i < num_entries;
3192                      i++, input_offset += MEM_DUMP_ENTRY_SIZE_DWORDS) {
3193                         const struct dbg_dump_mem *mem =
3194                                 (const struct dbg_dump_mem *)
3195                                 &input_mems_arr.ptr[input_offset];
3196                         u8 mem_group_id = GET_FIELD(mem->dword0,
3197                                                     DBG_DUMP_MEM_MEM_GROUP_ID);
3198                         bool is_storm = false, mem_wide_bus;
3199                         enum dbg_grc_params grc_param;
3200                         char storm_letter = 'a';
3201                         enum block_id block_id;
3202                         u32 mem_addr, mem_len;
3203 
3204                         if (mem_group_id >= MEM_GROUPS_NUM) {
3205                                 DP_NOTICE(p_hwfn, "Invalid mem_group_id\n");
3206                                 return 0;
3207                         }
3208 
3209                         block_id = (enum block_id)cond_hdr->block_id;
3210                         if (!qed_grc_is_mem_included(p_hwfn,
3211                                                      block_id,
3212                                                      mem_group_id))
3213                                 continue;
3214 
3215                         mem_addr = GET_FIELD(mem->dword0, DBG_DUMP_MEM_ADDRESS);
3216                         mem_len = GET_FIELD(mem->dword1, DBG_DUMP_MEM_LENGTH);
3217                         mem_wide_bus = GET_FIELD(mem->dword1,
3218                                                  DBG_DUMP_MEM_WIDE_BUS);
3219 
3220                         /* Update memory length for CCFC/TCFC memories
3221                          * according to number of LCIDs/LTIDs.
3222                          */
3223                         if (mem_group_id == MEM_GROUP_CONN_CFC_MEM) {
3224                                 if (mem_len % MAX_LCIDS) {
3225                                         DP_NOTICE(p_hwfn,
3226                                                   "Invalid CCFC connection memory size\n");
3227                                         return 0;
3228                                 }
3229 
3230                                 grc_param = DBG_GRC_PARAM_NUM_LCIDS;
3231                                 mem_len = qed_grc_get_param(p_hwfn, grc_param) *
3232                                           (mem_len / MAX_LCIDS);
3233                         } else if (mem_group_id == MEM_GROUP_TASK_CFC_MEM) {
3234                                 if (mem_len % MAX_LTIDS) {
3235                                         DP_NOTICE(p_hwfn,
3236                                                   "Invalid TCFC task memory size\n");
3237                                         return 0;
3238                                 }
3239 
3240                                 grc_param = DBG_GRC_PARAM_NUM_LTIDS;
3241                                 mem_len = qed_grc_get_param(p_hwfn, grc_param) *
3242                                           (mem_len / MAX_LTIDS);
3243                         }
3244 
3245                         /* If memory is associated with Storm, update Storm
3246                          * details.
3247                          */
3248                         if (s_block_defs
3249                             [cond_hdr->block_id]->associated_to_storm) {
3250                                 is_storm = true;
3251                                 storm_letter =
3252                                     s_storm_defs[s_block_defs
3253                                                  [cond_hdr->block_id]->
3254                                                  storm_id].letter;
3255                         }
3256 
3257                         /* Dump memory */
3258                         offset += qed_grc_dump_mem(p_hwfn,
3259                                                 p_ptt,
3260                                                 dump_buf + offset,
3261                                                 dump,
3262                                                 NULL,
3263                                                 mem_addr,
3264                                                 mem_len,
3265                                                 mem_wide_bus,
3266                                                 0,
3267                                                 false,
3268                                                 s_mem_group_names[mem_group_id],
3269                                                 is_storm,
3270                                                 storm_letter);
3271                 }
3272         }
3273 
3274         return offset;
3275 }
3276 
3277 /* Dumps GRC memories according to the input array dump_mem.
3278  * Returns the dumped size in dwords.
3279  */
3280 static u32 qed_grc_dump_memories(struct qed_hwfn *p_hwfn,
3281                                  struct qed_ptt *p_ptt,
3282                                  u32 *dump_buf, bool dump)
3283 {
3284         u32 offset = 0, input_offset = 0;
3285 
3286         while (input_offset <
3287                s_dbg_arrays[BIN_BUF_DBG_DUMP_MEM].size_in_dwords) {
3288                 const struct dbg_dump_split_hdr *split_hdr;
3289                 struct dbg_array curr_input_mems_arr;
3290                 enum init_split_types split_type;
3291                 u32 split_data_size;
3292 
3293                 split_hdr = (const struct dbg_dump_split_hdr *)
3294                         &s_dbg_arrays[BIN_BUF_DBG_DUMP_MEM].ptr[input_offset++];
3295                 split_type =
3296                         GET_FIELD(split_hdr->hdr,
3297                                   DBG_DUMP_SPLIT_HDR_SPLIT_TYPE_ID);
3298                 split_data_size =
3299                         GET_FIELD(split_hdr->hdr,
3300                                   DBG_DUMP_SPLIT_HDR_DATA_SIZE);
3301                 curr_input_mems_arr.ptr =
3302                         &s_dbg_arrays[BIN_BUF_DBG_DUMP_MEM].ptr[input_offset];
3303                 curr_input_mems_arr.size_in_dwords = split_data_size;
3304 
3305                 if (split_type == SPLIT_TYPE_NONE)
3306                         offset += qed_grc_dump_mem_entries(p_hwfn,
3307                                                            p_ptt,
3308                                                            curr_input_mems_arr,
3309                                                            dump_buf + offset,
3310                                                            dump);
3311                 else
3312                         DP_NOTICE(p_hwfn,
3313                                   "Dumping split memories is currently not supported\n");
3314 
3315                 input_offset += split_data_size;
3316         }
3317 
3318         return offset;
3319 }
3320 
3321 /* Dumps GRC context data for the specified Storm.
3322  * Returns the dumped size in dwords.
3323  * The lid_size argument is specified in quad-regs.
3324  */
3325 static u32 qed_grc_dump_ctx_data(struct qed_hwfn *p_hwfn,
3326                                  struct qed_ptt *p_ptt,
3327                                  u32 *dump_buf,
3328                                  bool dump,
3329                                  const char *name,
3330                                  u32 num_lids,
3331                                  u32 lid_size,
3332                                  u32 rd_reg_addr,
3333                                  u8 storm_id)
3334 {
3335         struct storm_defs *storm = &s_storm_defs[storm_id];
3336         u32 i, lid, total_size, offset = 0;
3337 
3338         if (!lid_size)
3339                 return 0;
3340 
3341         lid_size *= BYTES_IN_DWORD;
3342         total_size = num_lids * lid_size;
3343 
3344         offset += qed_grc_dump_mem_hdr(p_hwfn,
3345                                        dump_buf + offset,
3346                                        dump,
3347                                        name,
3348                                        0,
3349                                        total_size,
3350                                        lid_size * 32,
3351                                        false, name, true, storm->letter);
3352 
3353         if (!dump)
3354                 return offset + total_size;
3355 
3356         /* Dump context data */
3357         for (lid = 0; lid < num_lids; lid++) {
3358                 for (i = 0; i < lid_size; i++, offset++) {
3359                         qed_wr(p_hwfn,
3360                                p_ptt, storm->cm_ctx_wr_addr, (i << 9) | lid);
3361                         *(dump_buf + offset) = qed_rd(p_hwfn,
3362                                                       p_ptt, rd_reg_addr);
3363                 }
3364         }
3365 
3366         return offset;
3367 }
3368 
3369 /* Dumps GRC contexts. Returns the dumped size in dwords. */
3370 static u32 qed_grc_dump_ctx(struct qed_hwfn *p_hwfn,
3371                             struct qed_ptt *p_ptt, u32 *dump_buf, bool dump)
3372 {
3373         enum dbg_grc_params grc_param;
3374         u32 offset = 0;
3375         u8 storm_id;
3376 
3377         for (storm_id = 0; storm_id < MAX_DBG_STORMS; storm_id++) {
3378                 struct storm_defs *storm = &s_storm_defs[storm_id];
3379 
3380                 if (!qed_grc_is_storm_included(p_hwfn,
3381                                                (enum dbg_storms)storm_id))
3382                         continue;
3383 
3384                 /* Dump Conn AG context size */
3385                 grc_param = DBG_GRC_PARAM_NUM_LCIDS;
3386                 offset +=
3387                         qed_grc_dump_ctx_data(p_hwfn,
3388                                               p_ptt,
3389                                               dump_buf + offset,
3390                                               dump,
3391                                               "CONN_AG_CTX",
3392                                               qed_grc_get_param(p_hwfn,
3393                                                                 grc_param),
3394                                               storm->cm_conn_ag_ctx_lid_size,
3395                                               storm->cm_conn_ag_ctx_rd_addr,
3396                                               storm_id);
3397 
3398                 /* Dump Conn ST context size */
3399                 grc_param = DBG_GRC_PARAM_NUM_LCIDS;
3400                 offset +=
3401                         qed_grc_dump_ctx_data(p_hwfn,
3402                                               p_ptt,
3403                                               dump_buf + offset,
3404                                               dump,
3405                                               "CONN_ST_CTX",
3406                                               qed_grc_get_param(p_hwfn,
3407                                                                 grc_param),
3408                                               storm->cm_conn_st_ctx_lid_size,
3409                                               storm->cm_conn_st_ctx_rd_addr,
3410                                               storm_id);
3411 
3412                 /* Dump Task AG context size */
3413                 grc_param = DBG_GRC_PARAM_NUM_LTIDS;
3414                 offset +=
3415                         qed_grc_dump_ctx_data(p_hwfn,
3416                                               p_ptt,
3417                                               dump_buf + offset,
3418                                               dump,
3419                                               "TASK_AG_CTX",
3420                                               qed_grc_get_param(p_hwfn,
3421                                                                 grc_param),
3422                                               storm->cm_task_ag_ctx_lid_size,
3423                                               storm->cm_task_ag_ctx_rd_addr,
3424                                               storm_id);
3425 
3426                 /* Dump Task ST context size */
3427                 grc_param = DBG_GRC_PARAM_NUM_LTIDS;
3428                 offset +=
3429                         qed_grc_dump_ctx_data(p_hwfn,
3430                                               p_ptt,
3431                                               dump_buf + offset,
3432                                               dump,
3433                                               "TASK_ST_CTX",
3434                                               qed_grc_get_param(p_hwfn,
3435                                                                 grc_param),
3436                                               storm->cm_task_st_ctx_lid_size,
3437                                               storm->cm_task_st_ctx_rd_addr,
3438                                               storm_id);
3439         }
3440 
3441         return offset;
3442 }
3443 
3444 /* Dumps GRC IORs data. Returns the dumped size in dwords. */
3445 static u32 qed_grc_dump_iors(struct qed_hwfn *p_hwfn,
3446                              struct qed_ptt *p_ptt, u32 *dump_buf, bool dump)
3447 {
3448         char buf[10] = "IOR_SET_?";
3449         u32 addr, offset = 0;
3450         u8 storm_id, set_id;
3451 
3452         for (storm_id = 0; storm_id < MAX_DBG_STORMS; storm_id++) {
3453                 struct storm_defs *storm = &s_storm_defs[storm_id];
3454 
3455                 if (!qed_grc_is_storm_included(p_hwfn,
3456                                                (enum dbg_storms)storm_id))
3457                         continue;
3458 
3459                 for (set_id = 0; set_id < NUM_IOR_SETS; set_id++) {
3460                         addr = BYTES_TO_DWORDS(storm->sem_fast_mem_addr +
3461                                                SEM_FAST_REG_STORM_REG_FILE) +
3462                                IOR_SET_OFFSET(set_id);
3463                         if (strlen(buf) > 0)
3464                                 buf[strlen(buf) - 1] = '0' + set_id;
3465                         offset += qed_grc_dump_mem(p_hwfn,
3466                                                    p_ptt,
3467                                                    dump_buf + offset,
3468                                                    dump,
3469                                                    buf,
3470                                                    addr,
3471                                                    IORS_PER_SET,
3472                                                    false,
3473                                                    32,
3474                                                    false,
3475                                                    "ior",
3476                                                    true,
3477                                                    storm->letter);
3478                 }
3479         }
3480 
3481         return offset;
3482 }
3483 
3484 /* Dump VFC CAM. Returns the dumped size in dwords. */
3485 static u32 qed_grc_dump_vfc_cam(struct qed_hwfn *p_hwfn,
3486                                 struct qed_ptt *p_ptt,
3487                                 u32 *dump_buf, bool dump, u8 storm_id)
3488 {
3489         u32 total_size = VFC_CAM_NUM_ROWS * VFC_CAM_RESP_DWORDS;
3490         struct storm_defs *storm = &s_storm_defs[storm_id];
3491         u32 cam_addr[VFC_CAM_ADDR_DWORDS] = { 0 };
3492         u32 cam_cmd[VFC_CAM_CMD_DWORDS] = { 0 };
3493         u32 row, i, offset = 0;
3494 
3495         offset += qed_grc_dump_mem_hdr(p_hwfn,
3496                                        dump_buf + offset,
3497                                        dump,
3498                                        "vfc_cam",
3499                                        0,
3500                                        total_size,
3501                                        256,
3502                                        false, "vfc_cam", true, storm->letter);
3503 
3504         if (!dump)
3505                 return offset + total_size;
3506 
3507         /* Prepare CAM address */
3508         SET_VAR_FIELD(cam_addr, VFC_CAM_ADDR, OP, VFC_OPCODE_CAM_RD);
3509 
3510         for (row = 0; row < VFC_CAM_NUM_ROWS;
3511              row++, offset += VFC_CAM_RESP_DWORDS) {
3512                 /* Write VFC CAM command */
3513                 SET_VAR_FIELD(cam_cmd, VFC_CAM_CMD, ROW, row);
3514                 ARR_REG_WR(p_hwfn,
3515                            p_ptt,
3516                            storm->sem_fast_mem_addr + SEM_FAST_REG_VFC_DATA_WR,
3517                            cam_cmd, VFC_CAM_CMD_DWORDS);
3518 
3519                 /* Write VFC CAM address */
3520                 ARR_REG_WR(p_hwfn,
3521                            p_ptt,
3522                            storm->sem_fast_mem_addr + SEM_FAST_REG_VFC_ADDR,
3523                            cam_addr, VFC_CAM_ADDR_DWORDS);
3524 
3525                 /* Read VFC CAM read response */
3526                 ARR_REG_RD(p_hwfn,
3527                            p_ptt,
3528                            storm->sem_fast_mem_addr + SEM_FAST_REG_VFC_DATA_RD,
3529                            dump_buf + offset, VFC_CAM_RESP_DWORDS);
3530         }
3531 
3532         return offset;
3533 }
3534 
3535 /* Dump VFC RAM. Returns the dumped size in dwords. */
3536 static u32 qed_grc_dump_vfc_ram(struct qed_hwfn *p_hwfn,
3537                                 struct qed_ptt *p_ptt,
3538                                 u32 *dump_buf,
3539                                 bool dump,
3540                                 u8 storm_id, struct vfc_ram_defs *ram_defs)
3541 {
3542         u32 total_size = ram_defs->num_rows * VFC_RAM_RESP_DWORDS;
3543         struct storm_defs *storm = &s_storm_defs[storm_id];
3544         u32 ram_addr[VFC_RAM_ADDR_DWORDS] = { 0 };
3545         u32 ram_cmd[VFC_RAM_CMD_DWORDS] = { 0 };
3546         u32 row, i, offset = 0;
3547 
3548         offset += qed_grc_dump_mem_hdr(p_hwfn,
3549                                        dump_buf + offset,
3550                                        dump,
3551                                        ram_defs->mem_name,
3552                                        0,
3553                                        total_size,
3554                                        256,
3555                                        false,
3556                                        ram_defs->type_name,
3557                                        true, storm->letter);
3558 
3559         /* Prepare RAM address */
3560         SET_VAR_FIELD(ram_addr, VFC_RAM_ADDR, OP, VFC_OPCODE_RAM_RD);
3561 
3562         if (!dump)
3563                 return offset + total_size;
3564 
3565         for (row = ram_defs->base_row;
3566              row < ram_defs->base_row + ram_defs->num_rows;
3567              row++, offset += VFC_RAM_RESP_DWORDS) {
3568                 /* Write VFC RAM command */
3569                 ARR_REG_WR(p_hwfn,
3570                            p_ptt,
3571                            storm->sem_fast_mem_addr + SEM_FAST_REG_VFC_DATA_WR,
3572                            ram_cmd, VFC_RAM_CMD_DWORDS);
3573 
3574                 /* Write VFC RAM address */
3575                 SET_VAR_FIELD(ram_addr, VFC_RAM_ADDR, ROW, row);
3576                 ARR_REG_WR(p_hwfn,
3577                            p_ptt,
3578                            storm->sem_fast_mem_addr + SEM_FAST_REG_VFC_ADDR,
3579                            ram_addr, VFC_RAM_ADDR_DWORDS);
3580 
3581                 /* Read VFC RAM read response */
3582                 ARR_REG_RD(p_hwfn,
3583                            p_ptt,
3584                            storm->sem_fast_mem_addr + SEM_FAST_REG_VFC_DATA_RD,
3585                            dump_buf + offset, VFC_RAM_RESP_DWORDS);
3586         }
3587 
3588         return offset;
3589 }
3590 
3591 /* Dumps GRC VFC data. Returns the dumped size in dwords. */
3592 static u32 qed_grc_dump_vfc(struct qed_hwfn *p_hwfn,
3593                             struct qed_ptt *p_ptt, u32 *dump_buf, bool dump)
3594 {
3595         struct dbg_tools_data *dev_data = &p_hwfn->dbg_info;
3596         u8 storm_id, i;
3597         u32 offset = 0;
3598 
3599         for (storm_id = 0; storm_id < MAX_DBG_STORMS; storm_id++) {
3600                 if (!qed_grc_is_storm_included(p_hwfn,
3601                                                (enum dbg_storms)storm_id) ||
3602                     !s_storm_defs[storm_id].has_vfc ||
3603                     (storm_id == DBG_PSTORM_ID && dev_data->platform_id !=
3604                      PLATFORM_ASIC))
3605                         continue;
3606 
3607                 /* Read CAM */
3608                 offset += qed_grc_dump_vfc_cam(p_hwfn,
3609                                                p_ptt,
3610                                                dump_buf + offset,
3611                                                dump, storm_id);
3612 
3613                 /* Read RAM */
3614                 for (i = 0; i < NUM_VFC_RAM_TYPES; i++)
3615                         offset += qed_grc_dump_vfc_ram(p_hwfn,
3616                                                        p_ptt,
3617                                                        dump_buf + offset,
3618                                                        dump,
3619                                                        storm_id,
3620                                                        &s_vfc_ram_defs[i]);
3621         }
3622 
3623         return offset;
3624 }
3625 
3626 /* Dumps GRC RSS data. Returns the dumped size in dwords. */
3627 static u32 qed_grc_dump_rss(struct qed_hwfn *p_hwfn,
3628                             struct qed_ptt *p_ptt, u32 *dump_buf, bool dump)
3629 {
3630         struct dbg_tools_data *dev_data = &p_hwfn->dbg_info;
3631         u32 offset = 0;
3632         u8 rss_mem_id;
3633 
3634         for (rss_mem_id = 0; rss_mem_id < NUM_RSS_MEM_TYPES; rss_mem_id++) {
3635                 u32 rss_addr, num_entries, total_dwords;
3636                 struct rss_mem_defs *rss_defs;
3637                 u32 addr, num_dwords_to_read;
3638                 bool packed;
3639 
3640                 rss_defs = &s_rss_mem_defs[rss_mem_id];
3641                 rss_addr = rss_defs->addr;
3642                 num_entries = rss_defs->num_entries[dev_data->chip_id];
3643                 total_dwords = (num_entries * rss_defs->entry_width) / 32;
3644                 packed = (rss_defs->entry_width == 16);
3645 
3646                 offset += qed_grc_dump_mem_hdr(p_hwfn,
3647                                                dump_buf + offset,
3648                                                dump,
3649                                                rss_defs->mem_name,
3650                                                0,
3651                                                total_dwords,
3652                                                rss_defs->entry_width,
3653                                                packed,
3654                                                rss_defs->type_name, false, 0);
3655 
3656                 /* Dump RSS data */
3657                 if (!dump) {
3658                         offset += total_dwords;
3659                         continue;
3660                 }
3661 
3662                 addr = BYTES_TO_DWORDS(RSS_REG_RSS_RAM_DATA);
3663                 while (total_dwords) {
3664                         num_dwords_to_read = min_t(u32,
3665                                                    RSS_REG_RSS_RAM_DATA_SIZE,
3666                                                    total_dwords);
3667                         qed_wr(p_hwfn, p_ptt, RSS_REG_RSS_RAM_ADDR, rss_addr);
3668                         offset += qed_grc_dump_addr_range(p_hwfn,
3669                                                           p_ptt,
3670                                                           dump_buf + offset,
3671                                                           dump,
3672                                                           addr,
3673                                                           num_dwords_to_read,
3674                                                           false,
3675                                                           SPLIT_TYPE_NONE, 0);
3676                         total_dwords -= num_dwords_to_read;
3677                         rss_addr++;
3678                 }
3679         }
3680 
3681         return offset;
3682 }
3683 
3684 /* Dumps GRC Big RAM. Returns the dumped size in dwords. */
3685 static u32 qed_grc_dump_big_ram(struct qed_hwfn *p_hwfn,
3686                                 struct qed_ptt *p_ptt,
3687                                 u32 *dump_buf, bool dump, u8 big_ram_id)
3688 {
3689         struct dbg_tools_data *dev_data = &p_hwfn->dbg_info;
3690         u32 block_size, ram_size, offset = 0, reg_val, i;
3691         char mem_name[12] = "???_BIG_RAM";
3692         char type_name[8] = "???_RAM";
3693         struct big_ram_defs *big_ram;
3694 
3695         big_ram = &s_big_ram_defs[big_ram_id];
3696         ram_size = big_ram->ram_size[dev_data->chip_id];
3697 
3698         reg_val = qed_rd(p_hwfn, p_ptt, big_ram->is_256b_reg_addr);
3699         block_size = reg_val &
3700                      BIT(big_ram->is_256b_bit_offset[dev_data->chip_id]) ? 256
3701                                                                          : 128;
3702 
3703         strncpy(type_name, big_ram->instance_name, BIG_RAM_NAME_LEN);
3704         strncpy(mem_name, big_ram->instance_name, BIG_RAM_NAME_LEN);
3705 
3706         /* Dump memory header */
3707         offset += qed_grc_dump_mem_hdr(p_hwfn,
3708                                        dump_buf + offset,
3709                                        dump,
3710                                        mem_name,
3711                                        0,
3712                                        ram_size,
3713                                        block_size * 8,
3714                                        false, type_name, false, 0);
3715 
3716         /* Read and dump Big RAM data */
3717         if (!dump)
3718                 return offset + ram_size;
3719 
3720         /* Dump Big RAM */
3721         for (i = 0; i < DIV_ROUND_UP(ram_size, BRB_REG_BIG_RAM_DATA_SIZE);
3722              i++) {
3723                 u32 addr, len;
3724 
3725                 qed_wr(p_hwfn, p_ptt, big_ram->addr_reg_addr, i);
3726                 addr = BYTES_TO_DWORDS(big_ram->data_reg_addr);
3727                 len = BRB_REG_BIG_RAM_DATA_SIZE;
3728                 offset += qed_grc_dump_addr_range(p_hwfn,
3729                                                   p_ptt,
3730                                                   dump_buf + offset,
3731                                                   dump,
3732                                                   addr,
3733                                                   len,
3734                                                   false, SPLIT_TYPE_NONE, 0);
3735         }
3736 
3737         return offset;
3738 }
3739 
3740 static u32 qed_grc_dump_mcp(struct qed_hwfn *p_hwfn,
3741                             struct qed_ptt *p_ptt, u32 *dump_buf, bool dump)
3742 {
3743         bool block_enable[MAX_BLOCK_ID] = { 0 };
3744         u32 offset = 0, addr;
3745         bool halted = false;
3746 
3747         /* Halt MCP */
3748         if (dump && !qed_grc_get_param(p_hwfn, DBG_GRC_PARAM_NO_MCP)) {
3749                 halted = !qed_mcp_halt(p_hwfn, p_ptt);
3750                 if (!halted)
3751                         DP_NOTICE(p_hwfn, "MCP halt failed!\n");
3752         }
3753 
3754         /* Dump MCP scratchpad */
3755         offset += qed_grc_dump_mem(p_hwfn,
3756                                    p_ptt,
3757                                    dump_buf + offset,
3758                                    dump,
3759                                    NULL,
3760                                    BYTES_TO_DWORDS(MCP_REG_SCRATCH),
3761                                    MCP_REG_SCRATCH_SIZE_BB_K2,
3762                                    false, 0, false, "MCP", false, 0);
3763 
3764         /* Dump MCP cpu_reg_file */
3765         offset += qed_grc_dump_mem(p_hwfn,
3766                                    p_ptt,
3767                                    dump_buf + offset,
3768                                    dump,
3769                                    NULL,
3770                                    BYTES_TO_DWORDS(MCP_REG_CPU_REG_FILE),
3771                                    MCP_REG_CPU_REG_FILE_SIZE,
3772                                    false, 0, false, "MCP", false, 0);
3773 
3774         /* Dump MCP registers */
3775         block_enable[BLOCK_MCP] = true;
3776         offset += qed_grc_dump_registers(p_hwfn,
3777                                          p_ptt,
3778                                          dump_buf + offset,
3779                                          dump, block_enable, "block", "MCP");
3780 
3781         /* Dump required non-MCP registers */
3782         offset += qed_grc_dump_regs_hdr(dump_buf + offset,
3783                                         dump, 1, SPLIT_TYPE_NONE, 0,
3784                                         "block", "MCP");
3785         addr = BYTES_TO_DWORDS(MISC_REG_SHARED_MEM_ADDR);
3786         offset += qed_grc_dump_reg_entry(p_hwfn,
3787                                          p_ptt,
3788                                          dump_buf + offset,
3789                                          dump,
3790                                          addr,
3791                                          1,
3792                                          false, SPLIT_TYPE_NONE, 0);
3793 
3794         /* Release MCP */
3795         if (halted && qed_mcp_resume(p_hwfn, p_ptt))
3796                 DP_NOTICE(p_hwfn, "Failed to resume MCP after halt!\n");
3797 
3798         return offset;
3799 }
3800 
3801 /* Dumps the tbus indirect memory for all PHYs. */
3802 static u32 qed_grc_dump_phy(struct qed_hwfn *p_hwfn,
3803                             struct qed_ptt *p_ptt, u32 *dump_buf, bool dump)
3804 {
3805         u32 offset = 0, tbus_lo_offset, tbus_hi_offset;
3806         char mem_name[32];
3807         u8 phy_id;
3808 
3809         for (phy_id = 0; phy_id < ARRAY_SIZE(s_phy_defs); phy_id++) {
3810                 u32 addr_lo_addr, addr_hi_addr, data_lo_addr, data_hi_addr;
3811                 struct phy_defs *phy_defs;
3812                 u8 *bytes_buf;
3813 
3814                 phy_defs = &s_phy_defs[phy_id];
3815                 addr_lo_addr = phy_defs->base_addr +
3816                                phy_defs->tbus_addr_lo_addr;
3817                 addr_hi_addr = phy_defs->base_addr +
3818                                phy_defs->tbus_addr_hi_addr;
3819                 data_lo_addr = phy_defs->base_addr +
3820                                phy_defs->tbus_data_lo_addr;
3821                 data_hi_addr = phy_defs->base_addr +
3822                                phy_defs->tbus_data_hi_addr;
3823 
3824                 if (snprintf(mem_name, sizeof(mem_name), "tbus_%s",
3825                              phy_defs->phy_name) < 0)
3826                         DP_NOTICE(p_hwfn,
3827                                   "Unexpected debug error: invalid PHY memory name\n");
3828 
3829                 offset += qed_grc_dump_mem_hdr(p_hwfn,
3830                                                dump_buf + offset,
3831                                                dump,
3832                                                mem_name,
3833                                                0,
3834                                                PHY_DUMP_SIZE_DWORDS,
3835                                                16, true, mem_name, false, 0);
3836 
3837                 if (!dump) {
3838                         offset += PHY_DUMP_SIZE_DWORDS;
3839                         continue;
3840                 }
3841 
3842                 bytes_buf = (u8 *)(dump_buf + offset);
3843                 for (tbus_hi_offset = 0;
3844                      tbus_hi_offset < (NUM_PHY_TBUS_ADDRESSES >> 8);
3845                      tbus_hi_offset++) {
3846                         qed_wr(p_hwfn, p_ptt, addr_hi_addr, tbus_hi_offset);
3847                         for (tbus_lo_offset = 0; tbus_lo_offset < 256;
3848                              tbus_lo_offset++) {
3849                                 qed_wr(p_hwfn,
3850                                        p_ptt, addr_lo_addr, tbus_lo_offset);
3851                                 *(bytes_buf++) = (u8)qed_rd(p_hwfn,
3852                                                             p_ptt,
3853                                                             data_lo_addr);
3854                                 *(bytes_buf++) = (u8)qed_rd(p_hwfn,
3855                                                             p_ptt,
3856                                                             data_hi_addr);
3857                         }
3858                 }
3859 
3860                 offset += PHY_DUMP_SIZE_DWORDS;
3861         }
3862 
3863         return offset;
3864 }
3865 
3866 static void qed_config_dbg_line(struct qed_hwfn *p_hwfn,
3867                                 struct qed_ptt *p_ptt,
3868                                 enum block_id block_id,
3869                                 u8 line_id,
3870                                 u8 enable_mask,
3871                                 u8 right_shift,
3872                                 u8 force_valid_mask, u8 force_frame_mask)
3873 {
3874         struct block_defs *block = s_block_defs[block_id];
3875 
3876         qed_wr(p_hwfn, p_ptt, block->dbg_select_addr, line_id);
3877         qed_wr(p_hwfn, p_ptt, block->dbg_enable_addr, enable_mask);
3878         qed_wr(p_hwfn, p_ptt, block->dbg_shift_addr, right_shift);
3879         qed_wr(p_hwfn, p_ptt, block->dbg_force_valid_addr, force_valid_mask);
3880         qed_wr(p_hwfn, p_ptt, block->dbg_force_frame_addr, force_frame_mask);
3881 }
3882 
3883 /* Dumps Static Debug data. Returns the dumped size in dwords. */
3884 static u32 qed_grc_dump_static_debug(struct qed_hwfn *p_hwfn,
3885                                      struct qed_ptt *p_ptt,
3886                                      u32 *dump_buf, bool dump)
3887 {
3888         struct dbg_tools_data *dev_data = &p_hwfn->dbg_info;
3889         u32 block_id, line_id, offset = 0;
3890 
3891         /* Don't dump static debug if a debug bus recording is in progress */
3892         if (dump && qed_rd(p_hwfn, p_ptt, DBG_REG_DBG_BLOCK_ON))
3893                 return 0;
3894 
3895         if (dump) {
3896                 /* Disable all blocks debug output */
3897                 for (block_id = 0; block_id < MAX_BLOCK_ID; block_id++) {
3898                         struct block_defs *block = s_block_defs[block_id];
3899 
3900                         if (block->dbg_client_id[dev_data->chip_id] !=
3901                             MAX_DBG_BUS_CLIENTS)
3902                                 qed_wr(p_hwfn, p_ptt, block->dbg_enable_addr,
3903                                        0);
3904                 }
3905 
3906                 qed_bus_reset_dbg_block(p_hwfn, p_ptt);
3907                 qed_bus_set_framing_mode(p_hwfn,
3908                                          p_ptt, DBG_BUS_FRAME_MODE_8HW_0ST);
3909                 qed_wr(p_hwfn,
3910                        p_ptt, DBG_REG_DEBUG_TARGET, DBG_BUS_TARGET_ID_INT_BUF);
3911                 qed_wr(p_hwfn, p_ptt, DBG_REG_FULL_MODE, 1);
3912                 qed_bus_enable_dbg_block(p_hwfn, p_ptt, true);
3913         }
3914 
3915         /* Dump all static debug lines for each relevant block */
3916         for (block_id = 0; block_id < MAX_BLOCK_ID; block_id++) {
3917                 struct block_defs *block = s_block_defs[block_id];
3918                 struct dbg_bus_block *block_desc;
3919                 u32 block_dwords, addr, len;
3920                 u8 dbg_client_id;
3921 
3922                 if (block->dbg_client_id[dev_data->chip_id] ==
3923                     MAX_DBG_BUS_CLIENTS)
3924                         continue;
3925 
3926                 block_desc = get_dbg_bus_block_desc(p_hwfn,
3927                                                     (enum block_id)block_id);
3928                 block_dwords = NUM_DBG_LINES(block_desc) *
3929                                STATIC_DEBUG_LINE_DWORDS;
3930 
3931                 /* Dump static section params */
3932                 offset += qed_grc_dump_mem_hdr(p_hwfn,
3933                                                dump_buf + offset,
3934                                                dump,
3935                                                block->name,
3936                                                0,
3937                                                block_dwords,
3938                                                32, false, "STATIC", false, 0);
3939 
3940                 if (!dump) {
3941                         offset += block_dwords;
3942                         continue;
3943                 }
3944 
3945                 /* If all lines are invalid - dump zeros */
3946                 if (dev_data->block_in_reset[block_id]) {
3947                         memset(dump_buf + offset, 0,
3948                                DWORDS_TO_BYTES(block_dwords));
3949                         offset += block_dwords;
3950                         continue;
3951                 }
3952 
3953                 /* Enable block's client */
3954                 dbg_client_id = block->dbg_client_id[dev_data->chip_id];
3955                 qed_bus_enable_clients(p_hwfn,
3956                                        p_ptt,
3957                                        BIT(dbg_client_id));
3958 
3959                 addr = BYTES_TO_DWORDS(DBG_REG_CALENDAR_OUT_DATA);
3960                 len = STATIC_DEBUG_LINE_DWORDS;
3961                 for (line_id = 0; line_id < (u32)NUM_DBG_LINES(block_desc);
3962                      line_id++) {
3963                         /* Configure debug line ID */
3964                         qed_config_dbg_line(p_hwfn,
3965                                             p_ptt,
3966                                             (enum block_id)block_id,
3967                                             (u8)line_id, 0xf, 0, 0, 0);
3968 
3969                         /* Read debug line info */
3970                         offset += qed_grc_dump_addr_range(p_hwfn,
3971                                                           p_ptt,
3972                                                           dump_buf + offset,
3973                                                           dump,
3974                                                           addr,
3975                                                           len,
3976                                                           true, SPLIT_TYPE_NONE,
3977                                                           0);
3978                 }
3979 
3980                 /* Disable block's client and debug output */
3981                 qed_bus_enable_clients(p_hwfn, p_ptt, 0);
3982                 qed_wr(p_hwfn, p_ptt, block->dbg_enable_addr, 0);
3983         }
3984 
3985         if (dump) {
3986                 qed_bus_enable_dbg_block(p_hwfn, p_ptt, false);
3987                 qed_bus_enable_clients(p_hwfn, p_ptt, 0);
3988         }
3989 
3990         return offset;
3991 }
3992 
3993 /* Performs GRC Dump to the specified buffer.
3994  * Returns the dumped size in dwords.
3995  */
3996 static enum dbg_status qed_grc_dump(struct qed_hwfn *p_hwfn,
3997                                     struct qed_ptt *p_ptt,
3998                                     u32 *dump_buf,
3999                                     bool dump, u32 *num_dumped_dwords)
4000 {
4001         struct dbg_tools_data *dev_data = &p_hwfn->dbg_info;
4002         bool parities_masked = false;
4003         u32 offset = 0;
4004         u8 i;
4005 
4006         *num_dumped_dwords = 0;
4007         dev_data->num_regs_read = 0;
4008 
4009         /* Update reset state */
4010         if (dump)
4011                 qed_update_blocks_reset_state(p_hwfn, p_ptt);
4012 
4013         /* Dump global params */
4014         offset += qed_dump_common_global_params(p_hwfn,
4015                                                 p_ptt,
4016                                                 dump_buf + offset, dump, 4);
4017         offset += qed_dump_str_param(dump_buf + offset,
4018                                      dump, "dump-type", "grc-dump");
4019         offset += qed_dump_num_param(dump_buf + offset,
4020                                      dump,
4021                                      "num-lcids",
4022                                      qed_grc_get_param(p_hwfn,
4023                                                 DBG_GRC_PARAM_NUM_LCIDS));
4024         offset += qed_dump_num_param(dump_buf + offset,
4025                                      dump,
4026                                      "num-ltids",
4027                                      qed_grc_get_param(p_hwfn,
4028                                                 DBG_GRC_PARAM_NUM_LTIDS));
4029         offset += qed_dump_num_param(dump_buf + offset,
4030                                      dump, "num-ports", dev_data->num_ports);
4031 
4032         /* Dump reset registers (dumped before taking blocks out of reset ) */
4033         if (qed_grc_is_included(p_hwfn, DBG_GRC_PARAM_DUMP_REGS))
4034                 offset += qed_grc_dump_reset_regs(p_hwfn,
4035                                                   p_ptt,
4036                                                   dump_buf + offset, dump);
4037 
4038         /* Take all blocks out of reset (using reset registers) */
4039         if (dump) {
4040                 qed_grc_unreset_blocks(p_hwfn, p_ptt);
4041                 qed_update_blocks_reset_state(p_hwfn, p_ptt);
4042         }
4043 
4044         /* Disable all parities using MFW command */
4045         if (dump &&
4046             !qed_grc_get_param(p_hwfn, DBG_GRC_PARAM_NO_MCP)) {
4047                 parities_masked = !qed_mcp_mask_parities(p_hwfn, p_ptt, 1);
4048                 if (!parities_masked) {
4049                         DP_NOTICE(p_hwfn,
4050                                   "Failed to mask parities using MFW\n");
4051                         if (qed_grc_get_param
4052                             (p_hwfn, DBG_GRC_PARAM_PARITY_SAFE))
4053                                 return DBG_STATUS_MCP_COULD_NOT_MASK_PRTY;
4054                 }
4055         }
4056 
4057         /* Dump modified registers (dumped before modifying them) */
4058         if (qed_grc_is_included(p_hwfn, DBG_GRC_PARAM_DUMP_REGS))
4059                 offset += qed_grc_dump_modified_regs(p_hwfn,
4060                                                      p_ptt,
4061                                                      dump_buf + offset, dump);
4062 
4063         /* Stall storms */
4064         if (dump &&
4065             (qed_grc_is_included(p_hwfn,
4066                                  DBG_GRC_PARAM_DUMP_IOR) ||
4067              qed_grc_is_included(p_hwfn, DBG_GRC_PARAM_DUMP_VFC)))
4068                 qed_grc_stall_storms(p_hwfn, p_ptt, true);
4069 
4070         /* Dump all regs  */
4071         if (qed_grc_is_included(p_hwfn, DBG_GRC_PARAM_DUMP_REGS)) {
4072                 bool block_enable[MAX_BLOCK_ID];
4073 
4074                 /* Dump all blocks except MCP */
4075                 for (i = 0; i < MAX_BLOCK_ID; i++)
4076                         block_enable[i] = true;
4077                 block_enable[BLOCK_MCP] = false;
4078                 offset += qed_grc_dump_registers(p_hwfn,
4079                                                  p_ptt,
4080                                                  dump_buf +
4081                                                  offset,
4082                                                  dump,
4083                                                  block_enable, NULL, NULL);
4084 
4085                 /* Dump special registers */
4086                 offset += qed_grc_dump_special_regs(p_hwfn,
4087                                                     p_ptt,
4088                                                     dump_buf + offset, dump);
4089         }
4090 
4091         /* Dump memories */
4092         offset += qed_grc_dump_memories(p_hwfn, p_ptt, dump_buf + offset, dump);
4093 
4094         /* Dump MCP */
4095         if (qed_grc_is_included(p_hwfn, DBG_GRC_PARAM_DUMP_MCP))
4096                 offset += qed_grc_dump_mcp(p_hwfn,
4097                                            p_ptt, dump_buf + offset, dump);
4098 
4099         /* Dump context */
4100         if (qed_grc_is_included(p_hwfn, DBG_GRC_PARAM_DUMP_CM_CTX))
4101                 offset += qed_grc_dump_ctx(p_hwfn,
4102                                            p_ptt, dump_buf + offset, dump);
4103 
4104         /* Dump RSS memories */
4105         if (qed_grc_is_included(p_hwfn, DBG_GRC_PARAM_DUMP_RSS))
4106                 offset += qed_grc_dump_rss(p_hwfn,
4107                                            p_ptt, dump_buf + offset, dump);
4108 
4109         /* Dump Big RAM */
4110         for (i = 0; i < NUM_BIG_RAM_TYPES; i++)
4111                 if (qed_grc_is_included(p_hwfn, s_big_ram_defs[i].grc_param))
4112                         offset += qed_grc_dump_big_ram(p_hwfn,
4113                                                        p_ptt,
4114                                                        dump_buf + offset,
4115                                                        dump, i);
4116 
4117         /* Dump IORs */
4118         if (qed_grc_is_included(p_hwfn, DBG_GRC_PARAM_DUMP_IOR))
4119                 offset += qed_grc_dump_iors(p_hwfn,
4120                                             p_ptt, dump_buf + offset, dump);
4121 
4122         /* Dump VFC */
4123         if (qed_grc_is_included(p_hwfn, DBG_GRC_PARAM_DUMP_VFC))
4124                 offset += qed_grc_dump_vfc(p_hwfn,
4125                                            p_ptt, dump_buf + offset, dump);
4126 
4127         /* Dump PHY tbus */
4128         if (qed_grc_is_included(p_hwfn,
4129                                 DBG_GRC_PARAM_DUMP_PHY) && dev_data->chip_id ==
4130             CHIP_K2 && dev_data->platform_id == PLATFORM_ASIC)
4131                 offset += qed_grc_dump_phy(p_hwfn,
4132                                            p_ptt, dump_buf + offset, dump);
4133 
4134         /* Dump static debug data (only if not during debug bus recording) */
4135         if (qed_grc_is_included(p_hwfn,
4136                                 DBG_GRC_PARAM_DUMP_STATIC) &&
4137             (!dump || dev_data->bus.state == DBG_BUS_STATE_IDLE))
4138                 offset += qed_grc_dump_static_debug(p_hwfn,
4139                                                     p_ptt,
4140                                                     dump_buf + offset, dump);
4141 
4142         /* Dump last section */
4143         offset += qed_dump_last_section(dump_buf, offset, dump);
4144 
4145         if (dump) {
4146                 /* Unstall storms */
4147                 if (qed_grc_get_param(p_hwfn, DBG_GRC_PARAM_UNSTALL))
4148                         qed_grc_stall_storms(p_hwfn, p_ptt, false);
4149 
4150                 /* Clear parity status */
4151                 qed_grc_clear_all_prty(p_hwfn, p_ptt);
4152 
4153                 /* Enable all parities using MFW command */
4154                 if (parities_masked)
4155                         qed_mcp_mask_parities(p_hwfn, p_ptt, 0);
4156         }
4157 
4158         *num_dumped_dwords = offset;
4159 
4160         return DBG_STATUS_OK;
4161 }
4162 
4163 /* Writes the specified failing Idle Check rule to the specified buffer.
4164  * Returns the dumped size in dwords.
4165  */
4166 static u32 qed_idle_chk_dump_failure(struct qed_hwfn *p_hwfn,
4167                                      struct qed_ptt *p_ptt,
4168                                      u32 *
4169                                      dump_buf,
4170                                      bool dump,
4171                                      u16 rule_id,
4172                                      const struct dbg_idle_chk_rule *rule,
4173                                      u16 fail_entry_id, u32 *cond_reg_values)
4174 {
4175         struct dbg_tools_data *dev_data = &p_hwfn->dbg_info;
4176         const struct dbg_idle_chk_cond_reg *cond_regs;
4177         const struct dbg_idle_chk_info_reg *info_regs;
4178         u32 i, next_reg_offset = 0, offset = 0;
4179         struct dbg_idle_chk_result_hdr *hdr;
4180         const union dbg_idle_chk_reg *regs;
4181         u8 reg_id;
4182 
4183         hdr = (struct dbg_idle_chk_result_hdr *)dump_buf;
4184         regs = &((const union dbg_idle_chk_reg *)
4185                  s_dbg_arrays[BIN_BUF_DBG_IDLE_CHK_REGS].ptr)[rule->reg_offset];
4186         cond_regs = &regs[0].cond_reg;
4187         info_regs = &regs[rule->num_cond_regs].info_reg;
4188 
4189         /* Dump rule data */
4190         if (dump) {
4191                 memset(hdr, 0, sizeof(*hdr));
4192                 hdr->rule_id = rule_id;
4193                 hdr->mem_entry_id = fail_entry_id;
4194                 hdr->severity = rule->severity;
4195                 hdr->num_dumped_cond_regs = rule->num_cond_regs;
4196         }
4197 
4198         offset += IDLE_CHK_RESULT_HDR_DWORDS;
4199 
4200         /* Dump condition register values */
4201         for (reg_id = 0; reg_id < rule->num_cond_regs; reg_id++) {
4202                 const struct dbg_idle_chk_cond_reg *reg = &cond_regs[reg_id];
4203                 struct dbg_idle_chk_result_reg_hdr *reg_hdr;
4204 
4205                 reg_hdr = (struct dbg_idle_chk_result_reg_hdr *)
4206                           (dump_buf + offset);
4207 
4208                 /* Write register header */
4209                 if (!dump) {
4210                         offset += IDLE_CHK_RESULT_REG_HDR_DWORDS +
4211                             reg->entry_size;
4212                         continue;
4213                 }
4214 
4215                 offset += IDLE_CHK_RESULT_REG_HDR_DWORDS;
4216                 memset(reg_hdr, 0, sizeof(*reg_hdr));
4217                 reg_hdr->start_entry = reg->start_entry;
4218                 reg_hdr->size = reg->entry_size;
4219                 SET_FIELD(reg_hdr->data,
4220                           DBG_IDLE_CHK_RESULT_REG_HDR_IS_MEM,
4221                           reg->num_entries > 1 || reg->start_entry > 0 ? 1 : 0);
4222                 SET_FIELD(reg_hdr->data,
4223                           DBG_IDLE_CHK_RESULT_REG_HDR_REG_ID, reg_id);
4224 
4225                 /* Write register values */
4226                 for (i = 0; i < reg_hdr->size; i++, next_reg_offset++, offset++)
4227                         dump_buf[offset] = cond_reg_values[next_reg_offset];
4228         }
4229 
4230         /* Dump info register values */
4231         for (reg_id = 0; reg_id < rule->num_info_regs; reg_id++) {
4232                 const struct dbg_idle_chk_info_reg *reg = &info_regs[reg_id];
4233                 u32 block_id;
4234 
4235                 /* Check if register's block is in reset */
4236                 if (!dump) {
4237                         offset += IDLE_CHK_RESULT_REG_HDR_DWORDS + reg->size;
4238                         continue;
4239                 }
4240 
4241                 block_id = GET_FIELD(reg->data, DBG_IDLE_CHK_INFO_REG_BLOCK_ID);
4242                 if (block_id >= MAX_BLOCK_ID) {
4243                         DP_NOTICE(p_hwfn, "Invalid block_id\n");
4244                         return 0;
4245                 }
4246 
4247                 if (!dev_data->block_in_reset[block_id]) {
4248                         struct dbg_idle_chk_result_reg_hdr *reg_hdr;
4249                         bool wide_bus, eval_mode, mode_match = true;
4250                         u16 modes_buf_offset;
4251                         u32 addr;
4252 
4253                         reg_hdr = (struct dbg_idle_chk_result_reg_hdr *)
4254                                   (dump_buf + offset);
4255 
4256                         /* Check mode */
4257                         eval_mode = GET_FIELD(reg->mode.data,
4258                                               DBG_MODE_HDR_EVAL_MODE) > 0;
4259                         if (eval_mode) {
4260                                 modes_buf_offset =
4261                                     GET_FIELD(reg->mode.data,
4262                                               DBG_MODE_HDR_MODES_BUF_OFFSET);
4263                                 mode_match =
4264                                         qed_is_mode_match(p_hwfn,
4265                                                           &modes_buf_offset);
4266                         }
4267 
4268                         if (!mode_match)
4269                                 continue;
4270 
4271                         addr = GET_FIELD(reg->data,
4272                                          DBG_IDLE_CHK_INFO_REG_ADDRESS);
4273                         wide_bus = GET_FIELD(reg->data,
4274                                              DBG_IDLE_CHK_INFO_REG_WIDE_BUS);
4275 
4276                         /* Write register header */
4277                         offset += IDLE_CHK_RESULT_REG_HDR_DWORDS;
4278                         hdr->num_dumped_info_regs++;
4279                         memset(reg_hdr, 0, sizeof(*reg_hdr));
4280                         reg_hdr->size = reg->size;
4281                         SET_FIELD(reg_hdr->data,
4282                                   DBG_IDLE_CHK_RESULT_REG_HDR_REG_ID,
4283                                   rule->num_cond_regs + reg_id);
4284 
4285                         /* Write register values */
4286                         offset += qed_grc_dump_addr_range(p_hwfn,
4287                                                           p_ptt,
4288                                                           dump_buf + offset,
4289                                                           dump,
4290                                                           addr,
4291                                                           reg->size, wide_bus,
4292                                                           SPLIT_TYPE_NONE, 0);
4293                 }
4294         }
4295 
4296         return offset;
4297 }
4298 
4299 /* Dumps idle check rule entries. Returns the dumped size in dwords. */
4300 static u32
4301 qed_idle_chk_dump_rule_entries(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt,
4302                                u32 *dump_buf, bool dump,
4303                                const struct dbg_idle_chk_rule *input_rules,
4304                                u32 num_input_rules, u32 *num_failing_rules)
4305 {
4306         struct dbg_tools_data *dev_data = &p_hwfn->dbg_info;
4307         u32 cond_reg_values[IDLE_CHK_MAX_ENTRIES_SIZE];
4308         u32 i, offset = 0;
4309         u16 entry_id;
4310         u8 reg_id;
4311 
4312         *num_failing_rules = 0;
4313 
4314         for (i = 0; i < num_input_rules; i++) {
4315                 const struct dbg_idle_chk_cond_reg *cond_regs;
4316                 const struct dbg_idle_chk_rule *rule;
4317                 const union dbg_idle_chk_reg *regs;
4318                 u16 num_reg_entries = 1;
4319                 bool check_rule = true;
4320                 const u32 *imm_values;
4321 
4322                 rule = &input_rules[i];
4323                 regs = &((const union dbg_idle_chk_reg *)
4324                          s_dbg_arrays[BIN_BUF_DBG_IDLE_CHK_REGS].ptr)
4325                         [rule->reg_offset];
4326                 cond_regs = &regs[0].cond_reg;
4327                 imm_values = &s_dbg_arrays[BIN_BUF_DBG_IDLE_CHK_IMMS].ptr
4328                              [rule->imm_offset];
4329 
4330                 /* Check if all condition register blocks are out of reset, and
4331                  * find maximal number of entries (all condition registers that
4332                  * are memories must have the same size, which is > 1).
4333                  */
4334                 for (reg_id = 0; reg_id < rule->num_cond_regs && check_rule;
4335                      reg_id++) {
4336                         u32 block_id =
4337                                 GET_FIELD(cond_regs[reg_id].data,
4338                                           DBG_IDLE_CHK_COND_REG_BLOCK_ID);
4339 
4340                         if (block_id >= MAX_BLOCK_ID) {
4341                                 DP_NOTICE(p_hwfn, "Invalid block_id\n");
4342                                 return 0;
4343                         }
4344 
4345                         check_rule = !dev_data->block_in_reset[block_id];
4346                         if (cond_regs[reg_id].num_entries > num_reg_entries)
4347                                 num_reg_entries = cond_regs[reg_id].num_entries;
4348                 }
4349 
4350                 if (!check_rule && dump)
4351                         continue;
4352 
4353                 if (!dump) {
4354                         u32 entry_dump_size =
4355                                 qed_idle_chk_dump_failure(p_hwfn,
4356                                                           p_ptt,
4357                                                           dump_buf + offset,
4358                                                           false,
4359                                                           rule->rule_id,
4360                                                           rule,
4361                                                           0,
4362                                                           NULL);
4363 
4364                         offset += num_reg_entries * entry_dump_size;
4365                         (*num_failing_rules) += num_reg_entries;
4366                         continue;
4367                 }
4368 
4369                 /* Go over all register entries (number of entries is the same
4370                  * for all condition registers).
4371                  */
4372                 for (entry_id = 0; entry_id < num_reg_entries; entry_id++) {
4373                         u32 next_reg_offset = 0;
4374 
4375                         /* Read current entry of all condition registers */
4376                         for (reg_id = 0; reg_id < rule->num_cond_regs;
4377                              reg_id++) {
4378                                 const struct dbg_idle_chk_cond_reg *reg =
4379                                         &cond_regs[reg_id];
4380                                 u32 padded_entry_size, addr;
4381                                 bool wide_bus;
4382 
4383                                 /* Find GRC address (if it's a memory, the
4384                                  * address of the specific entry is calculated).
4385                                  */
4386                                 addr = GET_FIELD(reg->data,
4387                                                  DBG_IDLE_CHK_COND_REG_ADDRESS);
4388                                 wide_bus =
4389                                     GET_FIELD(reg->data,
4390                                               DBG_IDLE_CHK_COND_REG_WIDE_BUS);
4391                                 if (reg->num_entries > 1 ||
4392                                     reg->start_entry > 0) {
4393                                         padded_entry_size =
4394                                            reg->entry_size > 1 ?
4395                                            roundup_pow_of_two(reg->entry_size) :
4396                                            1;
4397                                         addr += (reg->start_entry + entry_id) *
4398                                                 padded_entry_size;
4399                                 }
4400 
4401                                 /* Read registers */
4402                                 if (next_reg_offset + reg->entry_size >=
4403                                     IDLE_CHK_MAX_ENTRIES_SIZE) {
4404                                         DP_NOTICE(p_hwfn,
4405                                                   "idle check registers entry is too large\n");
4406                                         return 0;
4407                                 }
4408 
4409                                 next_reg_offset +=
4410                                     qed_grc_dump_addr_range(p_hwfn, p_ptt,
4411                                                             cond_reg_values +
4412                                                             next_reg_offset,
4413                                                             dump, addr,
4414                                                             reg->entry_size,
4415                                                             wide_bus,
4416                                                             SPLIT_TYPE_NONE, 0);
4417                         }
4418 
4419                         /* Call rule condition function.
4420                          * If returns true, it's a failure.
4421                          */
4422                         if ((*cond_arr[rule->cond_id]) (cond_reg_values,
4423                                                         imm_values)) {
4424                                 offset += qed_idle_chk_dump_failure(p_hwfn,
4425                                                         p_ptt,
4426                                                         dump_buf + offset,
4427                                                         dump,
4428                                                         rule->rule_id,
4429                                                         rule,
4430                                                         entry_id,
4431                                                         cond_reg_values);
4432                                 (*num_failing_rules)++;
4433                         }
4434                 }
4435         }
4436 
4437         return offset;
4438 }
4439 
4440 /* Performs Idle Check Dump to the specified buffer.
4441  * Returns the dumped size in dwords.
4442  */
4443 static u32 qed_idle_chk_dump(struct qed_hwfn *p_hwfn,
4444                              struct qed_ptt *p_ptt, u32 *dump_buf, bool dump)
4445 {
4446         u32 num_failing_rules_offset, offset = 0, input_offset = 0;
4447         u32 num_failing_rules = 0;
4448 
4449         /* Dump global params */
4450         offset += qed_dump_common_global_params(p_hwfn,
4451                                                 p_ptt,
4452                                                 dump_buf + offset, dump, 1);
4453         offset += qed_dump_str_param(dump_buf + offset,
4454                                      dump, "dump-type", "idle-chk");
4455 
4456         /* Dump idle check section header with a single parameter */
4457         offset += qed_dump_section_hdr(dump_buf + offset, dump, "idle_chk", 1);
4458         num_failing_rules_offset = offset;
4459         offset += qed_dump_num_param(dump_buf + offset, dump, "num_rules", 0);
4460 
4461         while (input_offset <
4462                s_dbg_arrays[BIN_BUF_DBG_IDLE_CHK_RULES].size_in_dwords) {
4463                 const struct dbg_idle_chk_cond_hdr *cond_hdr =
4464                         (const struct dbg_idle_chk_cond_hdr *)
4465                         &s_dbg_arrays[BIN_BUF_DBG_IDLE_CHK_RULES].ptr
4466                         [input_offset++];
4467                 bool eval_mode, mode_match = true;
4468                 u32 curr_failing_rules;
4469                 u16 modes_buf_offset;
4470 
4471                 /* Check mode */
4472                 eval_mode = GET_FIELD(cond_hdr->mode.data,
4473                                       DBG_MODE_HDR_EVAL_MODE) > 0;
4474                 if (eval_mode) {
4475                         modes_buf_offset =
4476                                 GET_FIELD(cond_hdr->mode.data,
4477                                           DBG_MODE_HDR_MODES_BUF_OFFSET);
4478                         mode_match = qed_is_mode_match(p_hwfn,
4479                                                        &modes_buf_offset);
4480                 }
4481 
4482                 if (mode_match) {
4483                         offset +=
4484                             qed_idle_chk_dump_rule_entries(p_hwfn,
4485                                 p_ptt,
4486                                 dump_buf + offset,
4487                                 dump,
4488                                 (const struct dbg_idle_chk_rule *)
4489                                 &s_dbg_arrays[BIN_BUF_DBG_IDLE_CHK_RULES].
4490                                 ptr[input_offset],
4491                                 cond_hdr->data_size / IDLE_CHK_RULE_SIZE_DWORDS,
4492                                 &curr_failing_rules);
4493                         num_failing_rules += curr_failing_rules;
4494                 }
4495 
4496                 input_offset += cond_hdr->data_size;
4497         }
4498 
4499         /* Overwrite num_rules parameter */
4500         if (dump)
4501                 qed_dump_num_param(dump_buf + num_failing_rules_offset,
4502                                    dump, "num_rules", num_failing_rules);
4503 
4504         /* Dump last section */
4505         offset += qed_dump_last_section(dump_buf, offset, dump);
4506 
4507         return offset;
4508 }
4509 
4510 /* Finds the meta data image in NVRAM */
4511 static enum dbg_status qed_find_nvram_image(struct qed_hwfn *p_hwfn,
4512                                             struct qed_ptt *p_ptt,
4513                                             u32 image_type,
4514                                             u32 *nvram_offset_bytes,
4515                                             u32 *nvram_size_bytes)
4516 {
4517         u32 ret_mcp_resp, ret_mcp_param, ret_txn_size;
4518         struct mcp_file_att file_att;
4519         int nvm_result;
4520 
4521         /* Call NVRAM get file command */
4522         nvm_result = qed_mcp_nvm_rd_cmd(p_hwfn,
4523                                         p_ptt,
4524                                         DRV_MSG_CODE_NVM_GET_FILE_ATT,
4525                                         image_type,
4526                                         &ret_mcp_resp,
4527                                         &ret_mcp_param,
4528                                         &ret_txn_size, (u32 *)&file_att);
4529 
4530         /* Check response */
4531         if (nvm_result ||
4532             (ret_mcp_resp & FW_MSG_CODE_MASK) != FW_MSG_CODE_NVM_OK)
4533                 return DBG_STATUS_NVRAM_GET_IMAGE_FAILED;
4534 
4535         /* Update return values */
4536         *nvram_offset_bytes = file_att.nvm_start_addr;
4537         *nvram_size_bytes = file_att.len;
4538 
4539         DP_VERBOSE(p_hwfn,
4540                    QED_MSG_DEBUG,
4541                    "find_nvram_image: found NVRAM image of type %d in NVRAM offset %d bytes with size %d bytes\n",
4542                    image_type, *nvram_offset_bytes, *nvram_size_bytes);
4543 
4544         /* Check alignment */
4545         if (*nvram_size_bytes & 0x3)
4546                 return DBG_STATUS_NON_ALIGNED_NVRAM_IMAGE;
4547 
4548         return DBG_STATUS_OK;
4549 }
4550 
4551 /* Reads data from NVRAM */
4552 static enum dbg_status qed_nvram_read(struct qed_hwfn *p_hwfn,
4553                                       struct qed_ptt *p_ptt,
4554                                       u32 nvram_offset_bytes,
4555                                       u32 nvram_size_bytes, u32 *ret_buf)
4556 {
4557         u32 ret_mcp_resp, ret_mcp_param, ret_read_size, bytes_to_copy;
4558         s32 bytes_left = nvram_size_bytes;
4559         u32 read_offset = 0;
4560 
4561         DP_VERBOSE(p_hwfn,
4562                    QED_MSG_DEBUG,
4563                    "nvram_read: reading image of size %d bytes from NVRAM\n",
4564                    nvram_size_bytes);
4565 
4566         do {
4567                 bytes_to_copy =
4568                     (bytes_left >
4569                      MCP_DRV_NVM_BUF_LEN) ? MCP_DRV_NVM_BUF_LEN : bytes_left;
4570 
4571                 /* Call NVRAM read command */
4572                 if (qed_mcp_nvm_rd_cmd(p_hwfn, p_ptt,
4573                                        DRV_MSG_CODE_NVM_READ_NVRAM,
4574                                        (nvram_offset_bytes +
4575                                         read_offset) |
4576                                        (bytes_to_copy <<
4577                                         DRV_MB_PARAM_NVM_LEN_OFFSET),
4578                                        &ret_mcp_resp, &ret_mcp_param,
4579                                        &ret_read_size,
4580                                        (u32 *)((u8 *)ret_buf + read_offset)))
4581                         return DBG_STATUS_NVRAM_READ_FAILED;
4582 
4583                 /* Check response */
4584                 if ((ret_mcp_resp & FW_MSG_CODE_MASK) != FW_MSG_CODE_NVM_OK)
4585                         return DBG_STATUS_NVRAM_READ_FAILED;
4586 
4587                 /* Update read offset */
4588                 read_offset += ret_read_size;
4589                 bytes_left -= ret_read_size;
4590         } while (bytes_left > 0);
4591 
4592         return DBG_STATUS_OK;
4593 }
4594 
4595 /* Get info on the MCP Trace data in the scratchpad:
4596  * - trace_data_grc_addr (OUT): trace data GRC address in bytes
4597  * - trace_data_size (OUT): trace data size in bytes (without the header)
4598  */
4599 static enum dbg_status qed_mcp_trace_get_data_info(struct qed_hwfn *p_hwfn,
4600                                                    struct qed_ptt *p_ptt,
4601                                                    u32 *trace_data_grc_addr,
4602                                                    u32 *trace_data_size)
4603 {
4604         u32 spad_trace_offsize, signature;
4605 
4606         /* Read trace section offsize structure from MCP scratchpad */
4607         spad_trace_offsize = qed_rd(p_hwfn, p_ptt, MCP_SPAD_TRACE_OFFSIZE_ADDR);
4608 
4609         /* Extract trace section address from offsize (in scratchpad) */
4610         *trace_data_grc_addr =
4611                 MCP_REG_SCRATCH + SECTION_OFFSET(spad_trace_offsize);
4612 
4613         /* Read signature from MCP trace section */
4614         signature = qed_rd(p_hwfn, p_ptt,
4615                            *trace_data_grc_addr +
4616                            offsetof(struct mcp_trace, signature));
4617 
4618         if (signature != MFW_TRACE_SIGNATURE)
4619                 return DBG_STATUS_INVALID_TRACE_SIGNATURE;
4620 
4621         /* Read trace size from MCP trace section */
4622         *trace_data_size = qed_rd(p_hwfn,
4623                                   p_ptt,
4624                                   *trace_data_grc_addr +
4625                                   offsetof(struct mcp_trace, size));
4626 
4627         return DBG_STATUS_OK;
4628 }
4629 
4630 /* Reads MCP trace meta data image from NVRAM
4631  * - running_bundle_id (OUT): running bundle ID (invalid when loaded from file)
4632  * - trace_meta_offset (OUT): trace meta offset in NVRAM in bytes (invalid when
4633  *                            loaded from file).
4634  * - trace_meta_size (OUT):   size in bytes of the trace meta data.
4635  */
4636 static enum dbg_status qed_mcp_trace_get_meta_info(struct qed_hwfn *p_hwfn,
4637                                                    struct qed_ptt *p_ptt,
4638                                                    u32 trace_data_size_bytes,
4639                                                    u32 *running_bundle_id,
4640                                                    u32 *trace_meta_offset,
4641                                                    u32 *trace_meta_size)
4642 {
4643         u32 spad_trace_offsize, nvram_image_type, running_mfw_addr;
4644 
4645         /* Read MCP trace section offsize structure from MCP scratchpad */
4646         spad_trace_offsize = qed_rd(p_hwfn, p_ptt, MCP_SPAD_TRACE_OFFSIZE_ADDR);
4647 
4648         /* Find running bundle ID */
4649         running_mfw_addr =
4650                 MCP_REG_SCRATCH + SECTION_OFFSET(spad_trace_offsize) +
4651                 QED_SECTION_SIZE(spad_trace_offsize) + trace_data_size_bytes;
4652         *running_bundle_id = qed_rd(p_hwfn, p_ptt, running_mfw_addr);
4653         if (*running_bundle_id > 1)
4654                 return DBG_STATUS_INVALID_NVRAM_BUNDLE;
4655 
4656         /* Find image in NVRAM */
4657         nvram_image_type =
4658             (*running_bundle_id ==
4659              DIR_ID_1) ? NVM_TYPE_MFW_TRACE1 : NVM_TYPE_MFW_TRACE2;
4660         return qed_find_nvram_image(p_hwfn,
4661                                     p_ptt,
4662                                     nvram_image_type,
4663                                     trace_meta_offset, trace_meta_size);
4664 }
4665 
4666 /* Reads the MCP Trace meta data from NVRAM into the specified buffer */
4667 static enum dbg_status qed_mcp_trace_read_meta(struct qed_hwfn *p_hwfn,
4668                                                struct qed_ptt *p_ptt,
4669                                                u32 nvram_offset_in_bytes,
4670                                                u32 size_in_bytes, u32 *buf)
4671 {
4672         u8 modules_num, module_len, i, *byte_buf = (u8 *)buf;
4673         enum dbg_status status;
4674         u32 signature;
4675 
4676         /* Read meta data from NVRAM */
4677         status = qed_nvram_read(p_hwfn,
4678                                 p_ptt,
4679                                 nvram_offset_in_bytes, size_in_bytes, buf);
4680         if (status != DBG_STATUS_OK)
4681                 return status;
4682 
4683         /* Extract and check first signature */
4684         signature = qed_read_unaligned_dword(byte_buf);
4685         byte_buf += sizeof(signature);
4686         if (signature != NVM_MAGIC_VALUE)
4687                 return DBG_STATUS_INVALID_TRACE_SIGNATURE;
4688 
4689         /* Extract number of modules */
4690         modules_num = *(byte_buf++);
4691 
4692         /* Skip all modules */
4693         for (i = 0; i < modules_num; i++) {
4694                 module_len = *(byte_buf++);
4695                 byte_buf += module_len;
4696         }
4697 
4698         /* Extract and check second signature */
4699         signature = qed_read_unaligned_dword(byte_buf);
4700         byte_buf += sizeof(signature);
4701         if (signature != NVM_MAGIC_VALUE)
4702                 return DBG_STATUS_INVALID_TRACE_SIGNATURE;
4703 
4704         return DBG_STATUS_OK;
4705 }
4706 
4707 /* Dump MCP Trace */
4708 static enum dbg_status qed_mcp_trace_dump(struct qed_hwfn *p_hwfn,
4709                                           struct qed_ptt *p_ptt,
4710                                           u32 *dump_buf,
4711                                           bool dump, u32 *num_dumped_dwords)
4712 {
4713         u32 trace_data_grc_addr, trace_data_size_bytes, trace_data_size_dwords;
4714         u32 trace_meta_size_dwords = 0, running_bundle_id, offset = 0;
4715         u32 trace_meta_offset_bytes = 0, trace_meta_size_bytes = 0;
4716         enum dbg_status status;
4717         bool mcp_access;
4718         int halted = 0;
4719 
4720         *num_dumped_dwords = 0;
4721 
4722         mcp_access = !qed_grc_get_param(p_hwfn, DBG_GRC_PARAM_NO_MCP);
4723 
4724         /* Get trace data info */
4725         status = qed_mcp_trace_get_data_info(p_hwfn,
4726                                              p_ptt,
4727                                              &trace_data_grc_addr,
4728                                              &trace_data_size_bytes);
4729         if (status != DBG_STATUS_OK)
4730                 return status;
4731 
4732         /* Dump global params */
4733         offset += qed_dump_common_global_params(p_hwfn,
4734                                                 p_ptt,
4735                                                 dump_buf + offset, dump, 1);
4736         offset += qed_dump_str_param(dump_buf + offset,
4737                                      dump, "dump-type", "mcp-trace");
4738 
4739         /* Halt MCP while reading from scratchpad so the read data will be
4740          * consistent. if halt fails, MCP trace is taken anyway, with a small
4741          * risk that it may be corrupt.
4742          */
4743         if (dump && mcp_access) {
4744                 halted = !qed_mcp_halt(p_hwfn, p_ptt);
4745                 if (!halted)
4746                         DP_NOTICE(p_hwfn, "MCP halt failed!\n");
4747         }
4748 
4749         /* Find trace data size */
4750         trace_data_size_dwords =
4751             DIV_ROUND_UP(trace_data_size_bytes + sizeof(struct mcp_trace),
4752                          BYTES_IN_DWORD);
4753 
4754         /* Dump trace data section header and param */
4755         offset += qed_dump_section_hdr(dump_buf + offset,
4756                                        dump, "mcp_trace_data", 1);
4757         offset += qed_dump_num_param(dump_buf + offset,
4758                                      dump, "size", trace_data_size_dwords);
4759 
4760         /* Read trace data from scratchpad into dump buffer */
4761         offset += qed_grc_dump_addr_range(p_hwfn,
4762                                           p_ptt,
4763                                           dump_buf + offset,
4764                                           dump,
4765                                           BYTES_TO_DWORDS(trace_data_grc_addr),
4766                                           trace_data_size_dwords, false,
4767                                           SPLIT_TYPE_NONE, 0);
4768 
4769         /* Resume MCP (only if halt succeeded) */
4770         if (halted && qed_mcp_resume(p_hwfn, p_ptt))
4771                 DP_NOTICE(p_hwfn, "Failed to resume MCP after halt!\n");
4772 
4773         /* Dump trace meta section header */
4774         offset += qed_dump_section_hdr(dump_buf + offset,
4775                                        dump, "mcp_trace_meta", 1);
4776 
4777         /* If MCP Trace meta size parameter was set, use it.
4778          * Otherwise, read trace meta.
4779          * trace_meta_size_bytes is dword-aligned.
4780          */
4781         trace_meta_size_bytes =
4782                 qed_grc_get_param(p_hwfn, DBG_GRC_PARAM_MCP_TRACE_META_SIZE);
4783         if ((!trace_meta_size_bytes || dump) && mcp_access) {
4784                 status = qed_mcp_trace_get_meta_info(p_hwfn,
4785                                                      p_ptt,
4786                                                      trace_data_size_bytes,
4787                                                      &running_bundle_id,
4788                                                      &trace_meta_offset_bytes,
4789                                                      &trace_meta_size_bytes);
4790                 if (status == DBG_STATUS_OK)
4791                         trace_meta_size_dwords =
4792                                 BYTES_TO_DWORDS(trace_meta_size_bytes);
4793         }
4794 
4795         /* Dump trace meta size param */
4796         offset += qed_dump_num_param(dump_buf + offset,
4797                                      dump, "size", trace_meta_size_dwords);
4798 
4799         /* Read trace meta image into dump buffer */
4800         if (dump && trace_meta_size_dwords)
4801                 status = qed_mcp_trace_read_meta(p_hwfn,
4802                                                  p_ptt,
4803                                                  trace_meta_offset_bytes,
4804                                                  trace_meta_size_bytes,
4805                                                  dump_buf + offset);
4806         if (status == DBG_STATUS_OK)
4807                 offset += trace_meta_size_dwords;
4808 
4809         /* Dump last section */
4810         offset += qed_dump_last_section(dump_buf, offset, dump);
4811 
4812         *num_dumped_dwords = offset;
4813 
4814         /* If no mcp access, indicate that the dump doesn't contain the meta
4815          * data from NVRAM.
4816          */
4817         return mcp_access ? status : DBG_STATUS_NVRAM_GET_IMAGE_FAILED;
4818 }
4819 
4820 /* Dump GRC FIFO */
4821 static enum dbg_status qed_reg_fifo_dump(struct qed_hwfn *p_hwfn,
4822                                          struct qed_ptt *p_ptt,
4823                                          u32 *dump_buf,
4824                                          bool dump, u32 *num_dumped_dwords)
4825 {
4826         u32 dwords_read, size_param_offset, offset = 0, addr, len;
4827         bool fifo_has_data;
4828 
4829         *num_dumped_dwords = 0;
4830 
4831         /* Dump global params */
4832         offset += qed_dump_common_global_params(p_hwfn,
4833                                                 p_ptt,
4834                                                 dump_buf + offset, dump, 1);
4835         offset += qed_dump_str_param(dump_buf + offset,
4836                                      dump, "dump-type", "reg-fifo");
4837 
4838         /* Dump fifo data section header and param. The size param is 0 for
4839          * now, and is overwritten after reading the FIFO.
4840          */
4841         offset += qed_dump_section_hdr(dump_buf + offset,
4842                                        dump, "reg_fifo_data", 1);
4843         size_param_offset = offset;
4844         offset += qed_dump_num_param(dump_buf + offset, dump, "size", 0);
4845 
4846         if (!dump) {
4847                 /* FIFO max size is REG_FIFO_DEPTH_DWORDS. There is no way to
4848                  * test how much data is available, except for reading it.
4849                  */
4850                 offset += REG_FIFO_DEPTH_DWORDS;
4851                 goto out;
4852         }
4853 
4854         fifo_has_data = qed_rd(p_hwfn, p_ptt,
4855                                GRC_REG_TRACE_FIFO_VALID_DATA) > 0;
4856 
4857         /* Pull available data from fifo. Use DMAE since this is widebus memory
4858          * and must be accessed atomically. Test for dwords_read not passing
4859          * buffer size since more entries could be added to the buffer as we are
4860          * emptying it.
4861          */
4862         addr = BYTES_TO_DWORDS(GRC_REG_TRACE_FIFO);
4863         len = REG_FIFO_ELEMENT_DWORDS;
4864         for (dwords_read = 0;
4865              fifo_has_data && dwords_read < REG_FIFO_DEPTH_DWORDS;
4866              dwords_read += REG_FIFO_ELEMENT_DWORDS) {
4867                 offset += qed_grc_dump_addr_range(p_hwfn,
4868                                                   p_ptt,
4869                                                   dump_buf + offset,
4870                                                   true,
4871                                                   addr,
4872                                                   len,
4873                                                   true, SPLIT_TYPE_NONE,
4874                                                   0);
4875                 fifo_has_data = qed_rd(p_hwfn, p_ptt,
4876                                        GRC_REG_TRACE_FIFO_VALID_DATA) > 0;
4877         }
4878 
4879         qed_dump_num_param(dump_buf + size_param_offset, dump, "size",
4880                            dwords_read);
4881 out:
4882         /* Dump last section */
4883         offset += qed_dump_last_section(dump_buf, offset, dump);
4884 
4885         *num_dumped_dwords = offset;
4886 
4887         return DBG_STATUS_OK;
4888 }
4889 
4890 /* Dump IGU FIFO */
4891 static enum dbg_status qed_igu_fifo_dump(struct qed_hwfn *p_hwfn,
4892                                          struct qed_ptt *p_ptt,
4893                                          u32 *dump_buf,
4894                                          bool dump, u32 *num_dumped_dwords)
4895 {
4896         u32 dwords_read, size_param_offset, offset = 0, addr, len;
4897         bool fifo_has_data;
4898 
4899         *num_dumped_dwords = 0;
4900 
4901         /* Dump global params */
4902         offset += qed_dump_common_global_params(p_hwfn,
4903                                                 p_ptt,
4904                                                 dump_buf + offset, dump, 1);
4905         offset += qed_dump_str_param(dump_buf + offset,
4906                                      dump, "dump-type", "igu-fifo");
4907 
4908         /* Dump fifo data section header and param. The size param is 0 for
4909          * now, and is overwritten after reading the FIFO.
4910          */
4911         offset += qed_dump_section_hdr(dump_buf + offset,
4912                                        dump, "igu_fifo_data", 1);
4913         size_param_offset = offset;
4914         offset += qed_dump_num_param(dump_buf + offset, dump, "size", 0);
4915 
4916         if (!dump) {
4917                 /* FIFO max size is IGU_FIFO_DEPTH_DWORDS. There is no way to
4918                  * test how much data is available, except for reading it.
4919                  */
4920                 offset += IGU_FIFO_DEPTH_DWORDS;
4921                 goto out;
4922         }
4923 
4924         fifo_has_data = qed_rd(p_hwfn, p_ptt,
4925                                IGU_REG_ERROR_HANDLING_DATA_VALID) > 0;
4926 
4927         /* Pull available data from fifo. Use DMAE since this is widebus memory
4928          * and must be accessed atomically. Test for dwords_read not passing
4929          * buffer size since more entries could be added to the buffer as we are
4930          * emptying it.
4931          */
4932         addr = BYTES_TO_DWORDS(IGU_REG_ERROR_HANDLING_MEMORY);
4933         len = IGU_FIFO_ELEMENT_DWORDS;
4934         for (dwords_read = 0;
4935              fifo_has_data && dwords_read < IGU_FIFO_DEPTH_DWORDS;
4936              dwords_read += IGU_FIFO_ELEMENT_DWORDS) {
4937                 offset += qed_grc_dump_addr_range(p_hwfn,
4938                                                   p_ptt,
4939                                                   dump_buf + offset,
4940                                                   true,
4941                                                   addr,
4942                                                   len,
4943                                                   true, SPLIT_TYPE_NONE,
4944                                                   0);
4945                 fifo_has_data = qed_rd(p_hwfn, p_ptt,
4946                                        IGU_REG_ERROR_HANDLING_DATA_VALID) > 0;
4947         }
4948 
4949         qed_dump_num_param(dump_buf + size_param_offset, dump, "size",
4950                            dwords_read);
4951 out:
4952         /* Dump last section */
4953         offset += qed_dump_last_section(dump_buf, offset, dump);
4954 
4955         *num_dumped_dwords = offset;
4956 
4957         return DBG_STATUS_OK;
4958 }
4959 
4960 /* Protection Override dump */
4961 static enum dbg_status qed_protection_override_dump(struct qed_hwfn *p_hwfn,
4962                                                     struct qed_ptt *p_ptt,
4963                                                     u32 *dump_buf,
4964                                                     bool dump,
4965                                                     u32 *num_dumped_dwords)
4966 {
4967         u32 size_param_offset, override_window_dwords, offset = 0, addr;
4968 
4969         *num_dumped_dwords = 0;
4970 
4971         /* Dump global params */
4972         offset += qed_dump_common_global_params(p_hwfn,
4973                                                 p_ptt,
4974                                                 dump_buf + offset, dump, 1);
4975         offset += qed_dump_str_param(dump_buf + offset,
4976                                      dump, "dump-type", "protection-override");
4977 
4978         /* Dump data section header and param. The size param is 0 for now,
4979          * and is overwritten after reading the data.
4980          */
4981         offset += qed_dump_section_hdr(dump_buf + offset,
4982                                        dump, "protection_override_data", 1);
4983         size_param_offset = offset;
4984         offset += qed_dump_num_param(dump_buf + offset, dump, "size", 0);
4985 
4986         if (!dump) {
4987                 offset += PROTECTION_OVERRIDE_DEPTH_DWORDS;
4988                 goto out;
4989         }
4990 
4991         /* Add override window info to buffer */
4992         override_window_dwords =
4993                 qed_rd(p_hwfn, p_ptt, GRC_REG_NUMBER_VALID_OVERRIDE_WINDOW) *
4994                 PROTECTION_OVERRIDE_ELEMENT_DWORDS;
4995         addr = BYTES_TO_DWORDS(GRC_REG_PROTECTION_OVERRIDE_WINDOW);
4996         offset += qed_grc_dump_addr_range(p_hwfn,
4997                                           p_ptt,
4998                                           dump_buf + offset,
4999                                           true,
5000                                           addr,
5001                                           override_window_dwords,
5002                                           true, SPLIT_TYPE_NONE, 0);
5003         qed_dump_num_param(dump_buf + size_param_offset, dump, "size",
5004                            override_window_dwords);
5005 out:
5006         /* Dump last section */
5007         offset += qed_dump_last_section(dump_buf, offset, dump);
5008 
5009         *num_dumped_dwords = offset;
5010 
5011         return DBG_STATUS_OK;
5012 }
5013 
5014 /* Performs FW Asserts Dump to the specified buffer.
5015  * Returns the dumped size in dwords.
5016  */
5017 static u32 qed_fw_asserts_dump(struct qed_hwfn *p_hwfn,
5018                                struct qed_ptt *p_ptt, u32 *dump_buf, bool dump)
5019 {
5020         struct dbg_tools_data *dev_data = &p_hwfn->dbg_info;
5021         struct fw_asserts_ram_section *asserts;
5022         char storm_letter_str[2] = "?";
5023         struct fw_info fw_info;
5024         u32 offset = 0;
5025         u8 storm_id;
5026 
5027         /* Dump global params */
5028         offset += qed_dump_common_global_params(p_hwfn,
5029                                                 p_ptt,
5030                                                 dump_buf + offset, dump, 1);
5031         offset += qed_dump_str_param(dump_buf + offset,
5032                                      dump, "dump-type", "fw-asserts");
5033 
5034         /* Find Storm dump size */
5035         for (storm_id = 0; storm_id < MAX_DBG_STORMS; storm_id++) {
5036                 u32 fw_asserts_section_addr, next_list_idx_addr, next_list_idx;
5037                 struct storm_defs *storm = &s_storm_defs[storm_id];
5038                 u32 last_list_idx, addr;
5039 
5040                 if (dev_data->block_in_reset[storm->block_id])
5041                         continue;
5042 
5043                 /* Read FW info for the current Storm */
5044                 qed_read_storm_fw_info(p_hwfn, p_ptt, storm_id, &fw_info);
5045 
5046                 asserts = &fw_info.fw_asserts_section;
5047 
5048                 /* Dump FW Asserts section header and params */
5049                 storm_letter_str[0] = storm->letter;
5050                 offset += qed_dump_section_hdr(dump_buf + offset,
5051                                                dump, "fw_asserts", 2);
5052                 offset += qed_dump_str_param(dump_buf + offset,
5053                                              dump, "storm", storm_letter_str);
5054                 offset += qed_dump_num_param(dump_buf + offset,
5055                                              dump,
5056                                              "size",
5057                                              asserts->list_element_dword_size);
5058 
5059                 /* Read and dump FW Asserts data */
5060                 if (!dump) {
5061                         offset += asserts->list_element_dword_size;
5062                         continue;
5063                 }
5064 
5065                 fw_asserts_section_addr = storm->sem_fast_mem_addr +
5066                         SEM_FAST_REG_INT_RAM +
5067                         RAM_LINES_TO_BYTES(asserts->section_ram_line_offset);
5068                 next_list_idx_addr = fw_asserts_section_addr +
5069                         DWORDS_TO_BYTES(asserts->list_next_index_dword_offset);
5070                 next_list_idx = qed_rd(p_hwfn, p_ptt, next_list_idx_addr);
5071                 last_list_idx = (next_list_idx > 0 ?
5072                                  next_list_idx :
5073                                  asserts->list_num_elements) - 1;
5074                 addr = BYTES_TO_DWORDS(fw_asserts_section_addr) +
5075                        asserts->list_dword_offset +
5076                        last_list_idx * asserts->list_element_dword_size;
5077                 offset +=
5078                     qed_grc_dump_addr_range(p_hwfn, p_ptt,
5079                                             dump_buf + offset,
5080                                             dump, addr,
5081                                             asserts->list_element_dword_size,
5082                                                   false, SPLIT_TYPE_NONE, 0);
5083         }
5084 
5085         /* Dump last section */
5086         offset += qed_dump_last_section(dump_buf, offset, dump);
5087 
5088         return offset;
5089 }
5090 
5091 /***************************** Public Functions *******************************/
5092 
5093 enum dbg_status qed_dbg_set_bin_ptr(const u8 * const bin_ptr)
5094 {
5095         struct bin_buffer_hdr *buf_array = (struct bin_buffer_hdr *)bin_ptr;
5096         u8 buf_id;
5097 
5098         /* convert binary data to debug arrays */
5099         for (buf_id = 0; buf_id < MAX_BIN_DBG_BUFFER_TYPE; buf_id++) {
5100                 s_dbg_arrays[buf_id].ptr =
5101                     (u32 *)(bin_ptr + buf_array[buf_id].offset);
5102                 s_dbg_arrays[buf_id].size_in_dwords =
5103                     BYTES_TO_DWORDS(buf_array[buf_id].length);
5104         }
5105 
5106         return DBG_STATUS_OK;
5107 }
5108 
5109 bool qed_read_fw_info(struct qed_hwfn *p_hwfn,
5110                       struct qed_ptt *p_ptt, struct fw_info *fw_info)
5111 {
5112         struct dbg_tools_data *dev_data = &p_hwfn->dbg_info;
5113         u8 storm_id;
5114 
5115         for (storm_id = 0; storm_id < MAX_DBG_STORMS; storm_id++) {
5116                 struct storm_defs *storm = &s_storm_defs[storm_id];
5117 
5118                 /* Skip Storm if it's in reset */
5119                 if (dev_data->block_in_reset[storm->block_id])
5120                         continue;
5121 
5122                 /* Read FW info for the current Storm */
5123                 qed_read_storm_fw_info(p_hwfn, p_ptt, storm_id, fw_info);
5124 
5125                 return true;
5126         }
5127 
5128         return false;
5129 }
5130 
5131 enum dbg_status qed_dbg_grc_config(struct qed_hwfn *p_hwfn,
5132                                    struct qed_ptt *p_ptt,
5133                                    enum dbg_grc_params grc_param, u32 val)
5134 {
5135         enum dbg_status status;
5136         int i;
5137 
5138         DP_VERBOSE(p_hwfn, QED_MSG_DEBUG,
5139                    "dbg_grc_config: paramId = %d, val = %d\n", grc_param, val);
5140 
5141         status = qed_dbg_dev_init(p_hwfn, p_ptt);
5142         if (status != DBG_STATUS_OK)
5143                 return status;
5144 
5145         /* Initializes the GRC parameters (if not initialized). Needed in order
5146          * to set the default parameter values for the first time.
5147          */
5148         qed_dbg_grc_init_params(p_hwfn);
5149 
5150         if (grc_param >= MAX_DBG_GRC_PARAMS)
5151                 return DBG_STATUS_INVALID_ARGS;
5152         if (val < s_grc_param_defs[grc_param].min ||
5153             val > s_grc_param_defs[grc_param].max)
5154                 return DBG_STATUS_INVALID_ARGS;
5155 
5156         if (s_grc_param_defs[grc_param].is_preset) {
5157                 /* Preset param */
5158 
5159                 /* Disabling a preset is not allowed. Call
5160                  * dbg_grc_set_params_default instead.
5161                  */
5162                 if (!val)
5163                         return DBG_STATUS_INVALID_ARGS;
5164 
5165                 /* Update all params with the preset values */
5166                 for (i = 0; i < MAX_DBG_GRC_PARAMS; i++) {
5167                         u32 preset_val;
5168 
5169                         /* Skip persistent params */
5170                         if (s_grc_param_defs[i].is_persistent)
5171                                 continue;
5172 
5173                         /* Find preset value */
5174                         if (grc_param == DBG_GRC_PARAM_EXCLUDE_ALL)
5175                                 preset_val =
5176                                     s_grc_param_defs[i].exclude_all_preset_val;
5177                         else if (grc_param == DBG_GRC_PARAM_CRASH)
5178                                 preset_val =
5179                                     s_grc_param_defs[i].crash_preset_val;
5180                         else
5181                                 return DBG_STATUS_INVALID_ARGS;
5182 
5183                         qed_grc_set_param(p_hwfn,
5184                                           (enum dbg_grc_params)i, preset_val);
5185                 }
5186         } else {
5187                 /* Regular param - set its value */
5188                 qed_grc_set_param(p_hwfn, grc_param, val);
5189         }
5190 
5191         return DBG_STATUS_OK;
5192 }
5193 
5194 /* Assign default GRC param values */
5195 void qed_dbg_grc_set_params_default(struct qed_hwfn *p_hwfn)
5196 {
5197         struct dbg_tools_data *dev_data = &p_hwfn->dbg_info;
5198         u32 i;
5199 
5200         for (i = 0; i < MAX_DBG_GRC_PARAMS; i++)
5201                 if (!s_grc_param_defs[i].is_persistent)
5202                         dev_data->grc.param_val[i] =
5203                             s_grc_param_defs[i].default_val[dev_data->chip_id];
5204 }
5205 
5206 enum dbg_status qed_dbg_grc_get_dump_buf_size(struct qed_hwfn *p_hwfn,
5207                                               struct qed_ptt *p_ptt,
5208                                               u32 *buf_size)
5209 {
5210         enum dbg_status status = qed_dbg_dev_init(p_hwfn, p_ptt);
5211 
5212         *buf_size = 0;
5213 
5214         if (status != DBG_STATUS_OK)
5215                 return status;
5216 
5217         if (!s_dbg_arrays[BIN_BUF_DBG_MODE_TREE].ptr ||
5218             !s_dbg_arrays[BIN_BUF_DBG_DUMP_REG].ptr ||
5219             !s_dbg_arrays[BIN_BUF_DBG_DUMP_MEM].ptr ||
5220             !s_dbg_arrays[BIN_BUF_DBG_ATTN_BLOCKS].ptr ||
5221             !s_dbg_arrays[BIN_BUF_DBG_ATTN_REGS].ptr)
5222                 return DBG_STATUS_DBG_ARRAY_NOT_SET;
5223 
5224         return qed_grc_dump(p_hwfn, p_ptt, NULL, false, buf_size);
5225 }
5226 
5227 enum dbg_status qed_dbg_grc_dump(struct qed_hwfn *p_hwfn,
5228                                  struct qed_ptt *p_ptt,
5229                                  u32 *dump_buf,
5230                                  u32 buf_size_in_dwords,
5231                                  u32 *num_dumped_dwords)
5232 {
5233         u32 needed_buf_size_in_dwords;
5234         enum dbg_status status;
5235 
5236         *num_dumped_dwords = 0;
5237 
5238         status = qed_dbg_grc_get_dump_buf_size(p_hwfn,
5239                                                p_ptt,
5240                                                &needed_buf_size_in_dwords);
5241         if (status != DBG_STATUS_OK)
5242                 return status;
5243 
5244         if (buf_size_in_dwords < needed_buf_size_in_dwords)
5245                 return DBG_STATUS_DUMP_BUF_TOO_SMALL;
5246 
5247         /* GRC Dump */
5248         status = qed_grc_dump(p_hwfn, p_ptt, dump_buf, true, num_dumped_dwords);
5249 
5250         /* Revert GRC params to their default */
5251         qed_dbg_grc_set_params_default(p_hwfn);
5252 
5253         return status;
5254 }
5255 
5256 enum dbg_status qed_dbg_idle_chk_get_dump_buf_size(struct qed_hwfn *p_hwfn,
5257                                                    struct qed_ptt *p_ptt,
5258                                                    u32 *buf_size)
5259 {
5260         struct dbg_tools_data *dev_data = &p_hwfn->dbg_info;
5261         struct idle_chk_data *idle_chk;
5262         enum dbg_status status;
5263 
5264         idle_chk = &dev_data->idle_chk;
5265         *buf_size = 0;
5266 
5267         status = qed_dbg_dev_init(p_hwfn, p_ptt);
5268         if (status != DBG_STATUS_OK)
5269                 return status;
5270 
5271         if (!s_dbg_arrays[BIN_BUF_DBG_MODE_TREE].ptr ||
5272             !s_dbg_arrays[BIN_BUF_DBG_IDLE_CHK_REGS].ptr ||
5273             !s_dbg_arrays[BIN_BUF_DBG_IDLE_CHK_IMMS].ptr ||
5274             !s_dbg_arrays[BIN_BUF_DBG_IDLE_CHK_RULES].ptr)
5275                 return DBG_STATUS_DBG_ARRAY_NOT_SET;
5276 
5277         if (!idle_chk->buf_size_set) {
5278                 idle_chk->buf_size = qed_idle_chk_dump(p_hwfn,
5279                                                        p_ptt, NULL, false);
5280                 idle_chk->buf_size_set = true;
5281         }
5282 
5283         *buf_size = idle_chk->buf_size;
5284 
5285         return DBG_STATUS_OK;
5286 }
5287 
5288 enum dbg_status qed_dbg_idle_chk_dump(struct qed_hwfn *p_hwfn,
5289                                       struct qed_ptt *p_ptt,
5290                                       u32 *dump_buf,
5291                                       u32 buf_size_in_dwords,
5292                                       u32 *num_dumped_dwords)
5293 {
5294         u32 needed_buf_size_in_dwords;
5295         enum dbg_status status;
5296 
5297         *num_dumped_dwords = 0;
5298 
5299         status = qed_dbg_idle_chk_get_dump_buf_size(p_hwfn,
5300                                                     p_ptt,
5301                                                     &needed_buf_size_in_dwords);
5302         if (status != DBG_STATUS_OK)
5303                 return status;
5304 
5305         if (buf_size_in_dwords < needed_buf_size_in_dwords)
5306                 return DBG_STATUS_DUMP_BUF_TOO_SMALL;
5307 
5308         /* Update reset state */
5309         qed_update_blocks_reset_state(p_hwfn, p_ptt);
5310 
5311         /* Idle Check Dump */
5312         *num_dumped_dwords = qed_idle_chk_dump(p_hwfn, p_ptt, dump_buf, true);
5313 
5314         /* Revert GRC params to their default */
5315         qed_dbg_grc_set_params_default(p_hwfn);
5316 
5317         return DBG_STATUS_OK;
5318 }
5319 
5320 enum dbg_status qed_dbg_mcp_trace_get_dump_buf_size(struct qed_hwfn *p_hwfn,
5321                                                     struct qed_ptt *p_ptt,
5322                                                     u32 *buf_size)
5323 {
5324         enum dbg_status status = qed_dbg_dev_init(p_hwfn, p_ptt);
5325 
5326         *buf_size = 0;
5327 
5328         if (status != DBG_STATUS_OK)
5329                 return status;
5330 
5331         return qed_mcp_trace_dump(p_hwfn, p_ptt, NULL, false, buf_size);
5332 }
5333 
5334 enum dbg_status qed_dbg_mcp_trace_dump(struct qed_hwfn *p_hwfn,
5335                                        struct qed_ptt *p_ptt,
5336                                        u32 *dump_buf,
5337                                        u32 buf_size_in_dwords,
5338                                        u32 *num_dumped_dwords)
5339 {
5340         u32 needed_buf_size_in_dwords;
5341         enum dbg_status status;
5342 
5343         status =
5344                 qed_dbg_mcp_trace_get_dump_buf_size(p_hwfn,
5345                                                     p_ptt,
5346                                                     &needed_buf_size_in_dwords);
5347         if (status != DBG_STATUS_OK && status !=
5348             DBG_STATUS_NVRAM_GET_IMAGE_FAILED)
5349                 return status;
5350 
5351         if (buf_size_in_dwords < needed_buf_size_in_dwords)
5352                 return DBG_STATUS_DUMP_BUF_TOO_SMALL;
5353 
5354         /* Update reset state */
5355         qed_update_blocks_reset_state(p_hwfn, p_ptt);
5356 
5357         /* Perform dump */
5358         status = qed_mcp_trace_dump(p_hwfn,
5359                                     p_ptt, dump_buf, true, num_dumped_dwords);
5360 
5361         /* Revert GRC params to their default */
5362         qed_dbg_grc_set_params_default(p_hwfn);
5363 
5364         return status;
5365 }
5366 
5367 enum dbg_status qed_dbg_reg_fifo_get_dump_buf_size(struct qed_hwfn *p_hwfn,
5368                                                    struct qed_ptt *p_ptt,
5369                                                    u32 *buf_size)
5370 {
5371         enum dbg_status status = qed_dbg_dev_init(p_hwfn, p_ptt);
5372 
5373         *buf_size = 0;
5374 
5375         if (status != DBG_STATUS_OK)
5376                 return status;
5377 
5378         return qed_reg_fifo_dump(p_hwfn, p_ptt, NULL, false, buf_size);
5379 }
5380 
5381 enum dbg_status qed_dbg_reg_fifo_dump(struct qed_hwfn *p_hwfn,
5382                                       struct qed_ptt *p_ptt,
5383                                       u32 *dump_buf,
5384                                       u32 buf_size_in_dwords,
5385                                       u32 *num_dumped_dwords)
5386 {
5387         u32 needed_buf_size_in_dwords;
5388         enum dbg_status status;
5389 
5390         *num_dumped_dwords = 0;
5391 
5392         status = qed_dbg_reg_fifo_get_dump_buf_size(p_hwfn,
5393                                                     p_ptt,
5394                                                     &needed_buf_size_in_dwords);
5395         if (status != DBG_STATUS_OK)
5396                 return status;
5397 
5398         if (buf_size_in_dwords < needed_buf_size_in_dwords)
5399                 return DBG_STATUS_DUMP_BUF_TOO_SMALL;
5400 
5401         /* Update reset state */
5402         qed_update_blocks_reset_state(p_hwfn, p_ptt);
5403 
5404         status = qed_reg_fifo_dump(p_hwfn,
5405                                    p_ptt, dump_buf, true, num_dumped_dwords);
5406 
5407         /* Revert GRC params to their default */
5408         qed_dbg_grc_set_params_default(p_hwfn);
5409 
5410         return status;
5411 }
5412 
5413 enum dbg_status qed_dbg_igu_fifo_get_dump_buf_size(struct qed_hwfn *p_hwfn,
5414                                                    struct qed_ptt *p_ptt,
5415                                                    u32 *buf_size)
5416 {
5417         enum dbg_status status = qed_dbg_dev_init(p_hwfn, p_ptt);
5418 
5419         *buf_size = 0;
5420 
5421         if (status != DBG_STATUS_OK)
5422                 return status;
5423 
5424         return qed_igu_fifo_dump(p_hwfn, p_ptt, NULL, false, buf_size);
5425 }
5426 
5427 enum dbg_status qed_dbg_igu_fifo_dump(struct qed_hwfn *p_hwfn,
5428                                       struct qed_ptt *p_ptt,
5429                                       u32 *dump_buf,
5430                                       u32 buf_size_in_dwords,
5431                                       u32 *num_dumped_dwords)
5432 {
5433         u32 needed_buf_size_in_dwords;
5434         enum dbg_status status;
5435 
5436         *num_dumped_dwords = 0;
5437 
5438         status = qed_dbg_igu_fifo_get_dump_buf_size(p_hwfn,
5439                                                     p_ptt,
5440                                                     &needed_buf_size_in_dwords);
5441         if (status != DBG_STATUS_OK)
5442                 return status;
5443 
5444         if (buf_size_in_dwords < needed_buf_size_in_dwords)
5445                 return DBG_STATUS_DUMP_BUF_TOO_SMALL;
5446 
5447         /* Update reset state */
5448         qed_update_blocks_reset_state(p_hwfn, p_ptt);
5449 
5450         status = qed_igu_fifo_dump(p_hwfn,
5451                                    p_ptt, dump_buf, true, num_dumped_dwords);
5452         /* Revert GRC params to their default */
5453         qed_dbg_grc_set_params_default(p_hwfn);
5454 
5455         return status;
5456 }
5457 
5458 enum dbg_status
5459 qed_dbg_protection_override_get_dump_buf_size(struct qed_hwfn *p_hwfn,
5460                                               struct qed_ptt *p_ptt,
5461                                               u32 *buf_size)
5462 {
5463         enum dbg_status status = qed_dbg_dev_init(p_hwfn, p_ptt);
5464 
5465         *buf_size = 0;
5466 
5467         if (status != DBG_STATUS_OK)
5468                 return status;
5469 
5470         return qed_protection_override_dump(p_hwfn,
5471                                             p_ptt, NULL, false, buf_size);
5472 }
5473 
5474 enum dbg_status qed_dbg_protection_override_dump(struct qed_hwfn *p_hwfn,
5475                                                  struct qed_ptt *p_ptt,
5476                                                  u32 *dump_buf,
5477                                                  u32 buf_size_in_dwords,
5478                                                  u32 *num_dumped_dwords)
5479 {
5480         u32 needed_buf_size_in_dwords, *p_size = &needed_buf_size_in_dwords;
5481         enum dbg_status status;
5482 
5483         *num_dumped_dwords = 0;
5484 
5485         status =
5486                 qed_dbg_protection_override_get_dump_buf_size(p_hwfn,
5487                                                               p_ptt,
5488                                                               p_size);
5489         if (status != DBG_STATUS_OK)
5490                 return status;
5491 
5492         if (buf_size_in_dwords < needed_buf_size_in_dwords)
5493                 return DBG_STATUS_DUMP_BUF_TOO_SMALL;
5494 
5495         /* Update reset state */
5496         qed_update_blocks_reset_state(p_hwfn, p_ptt);
5497 
5498         status = qed_protection_override_dump(p_hwfn,
5499                                               p_ptt,
5500                                               dump_buf,
5501                                               true, num_dumped_dwords);
5502 
5503         /* Revert GRC params to their default */
5504         qed_dbg_grc_set_params_default(p_hwfn);
5505 
5506         return status;
5507 }
5508 
5509 enum dbg_status qed_dbg_fw_asserts_get_dump_buf_size(struct qed_hwfn *p_hwfn,
5510                                                      struct qed_ptt *p_ptt,
5511                                                      u32 *buf_size)
5512 {
5513         enum dbg_status status = qed_dbg_dev_init(p_hwfn, p_ptt);
5514 
5515         *buf_size = 0;
5516 
5517         if (status != DBG_STATUS_OK)
5518                 return status;
5519 
5520         /* Update reset state */
5521         qed_update_blocks_reset_state(p_hwfn, p_ptt);
5522 
5523         *buf_size = qed_fw_asserts_dump(p_hwfn, p_ptt, NULL, false);
5524 
5525         return DBG_STATUS_OK;
5526 }
5527 
5528 enum dbg_status qed_dbg_fw_asserts_dump(struct qed_hwfn *p_hwfn,
5529                                         struct qed_ptt *p_ptt,
5530                                         u32 *dump_buf,
5531                                         u32 buf_size_in_dwords,
5532                                         u32 *num_dumped_dwords)
5533 {
5534         u32 needed_buf_size_in_dwords, *p_size = &needed_buf_size_in_dwords;
5535         enum dbg_status status;
5536 
5537         *num_dumped_dwords = 0;
5538 
5539         status =
5540                 qed_dbg_fw_asserts_get_dump_buf_size(p_hwfn,
5541                                                      p_ptt,
5542                                                      p_size);
5543         if (status != DBG_STATUS_OK)
5544                 return status;
5545 
5546         if (buf_size_in_dwords < needed_buf_size_in_dwords)
5547                 return DBG_STATUS_DUMP_BUF_TOO_SMALL;
5548 
5549         *num_dumped_dwords = qed_fw_asserts_dump(p_hwfn, p_ptt, dump_buf, true);
5550 
5551         /* Revert GRC params to their default */
5552         qed_dbg_grc_set_params_default(p_hwfn);
5553 
5554         return DBG_STATUS_OK;
5555 }
5556 
5557 enum dbg_status qed_dbg_read_attn(struct qed_hwfn *p_hwfn,
5558                                   struct qed_ptt *p_ptt,
5559                                   enum block_id block_id,
5560                                   enum dbg_attn_type attn_type,
5561                                   bool clear_status,
5562                                   struct dbg_attn_block_result *results)
5563 {
5564         enum dbg_status status = qed_dbg_dev_init(p_hwfn, p_ptt);
5565         u8 reg_idx, num_attn_regs, num_result_regs = 0;
5566         const struct dbg_attn_reg *attn_reg_arr;
5567 
5568         if (status != DBG_STATUS_OK)
5569                 return status;
5570 
5571         if (!s_dbg_arrays[BIN_BUF_DBG_MODE_TREE].ptr ||
5572             !s_dbg_arrays[BIN_BUF_DBG_ATTN_BLOCKS].ptr ||
5573             !s_dbg_arrays[BIN_BUF_DBG_ATTN_REGS].ptr)
5574                 return DBG_STATUS_DBG_ARRAY_NOT_SET;
5575 
5576         attn_reg_arr = qed_get_block_attn_regs(block_id,
5577                                                attn_type, &num_attn_regs);
5578 
5579         for (reg_idx = 0; reg_idx < num_attn_regs; reg_idx++) {
5580                 const struct dbg_attn_reg *reg_data = &attn_reg_arr[reg_idx];
5581                 struct dbg_attn_reg_result *reg_result;
5582                 u32 sts_addr, sts_val;
5583                 u16 modes_buf_offset;
5584                 bool eval_mode;
5585 
5586                 /* Check mode */
5587                 eval_mode = GET_FIELD(reg_data->mode.data,
5588                                       DBG_MODE_HDR_EVAL_MODE) > 0;
5589                 modes_buf_offset = GET_FIELD(reg_data->mode.data,
5590                                              DBG_MODE_HDR_MODES_BUF_OFFSET);
5591                 if (eval_mode && !qed_is_mode_match(p_hwfn, &modes_buf_offset))
5592                         continue;
5593 
5594                 /* Mode match - read attention status register */
5595                 sts_addr = DWORDS_TO_BYTES(clear_status ?
5596                                            reg_data->sts_clr_address :
5597                                            GET_FIELD(reg_data->data,
5598                                                      DBG_ATTN_REG_STS_ADDRESS));
5599                 sts_val = qed_rd(p_hwfn, p_ptt, sts_addr);
5600                 if (!sts_val)
5601                         continue;
5602 
5603                 /* Non-zero attention status - add to results */
5604                 reg_result = &results->reg_results[num_result_regs];
5605                 SET_FIELD(reg_result->data,
5606                           DBG_ATTN_REG_RESULT_STS_ADDRESS, sts_addr);
5607                 SET_FIELD(reg_result->data,
5608                           DBG_ATTN_REG_RESULT_NUM_REG_ATTN,
5609                           GET_FIELD(reg_data->data, DBG_ATTN_REG_NUM_REG_ATTN));
5610                 reg_result->block_attn_offset = reg_data->block_attn_offset;
5611                 reg_result->sts_val = sts_val;
5612                 reg_result->mask_val = qed_rd(p_hwfn,
5613                                               p_ptt,
5614                                               DWORDS_TO_BYTES
5615                                               (reg_data->mask_address));
5616                 num_result_regs++;
5617         }
5618 
5619         results->block_id = (u8)block_id;
5620         results->names_offset =
5621             qed_get_block_attn_data(block_id, attn_type)->names_offset;
5622         SET_FIELD(results->data, DBG_ATTN_BLOCK_RESULT_ATTN_TYPE, attn_type);
5623         SET_FIELD(results->data,
5624                   DBG_ATTN_BLOCK_RESULT_NUM_REGS, num_result_regs);
5625 
5626         return DBG_STATUS_OK;
5627 }
5628 
5629 /******************************* Data Types **********************************/
5630 
5631 struct block_info {
5632         const char *name;
5633         enum block_id id;
5634 };
5635 
5636 /* REG fifo element */
5637 struct reg_fifo_element {
5638         u64 data;
5639 #define REG_FIFO_ELEMENT_ADDRESS_SHIFT          0
5640 #define REG_FIFO_ELEMENT_ADDRESS_MASK           0x7fffff
5641 #define REG_FIFO_ELEMENT_ACCESS_SHIFT           23
5642 #define REG_FIFO_ELEMENT_ACCESS_MASK            0x1
5643 #define REG_FIFO_ELEMENT_PF_SHIFT               24
5644 #define REG_FIFO_ELEMENT_PF_MASK                0xf
5645 #define REG_FIFO_ELEMENT_VF_SHIFT               28
5646 #define REG_FIFO_ELEMENT_VF_MASK                0xff
5647 #define REG_FIFO_ELEMENT_PORT_SHIFT             36
5648 #define REG_FIFO_ELEMENT_PORT_MASK              0x3
5649 #define REG_FIFO_ELEMENT_PRIVILEGE_SHIFT        38
5650 #define REG_FIFO_ELEMENT_PRIVILEGE_MASK         0x3
5651 #define REG_FIFO_ELEMENT_PROTECTION_SHIFT       40
5652 #define REG_FIFO_ELEMENT_PROTECTION_MASK        0x7
5653 #define REG_FIFO_ELEMENT_MASTER_SHIFT           43
5654 #define REG_FIFO_ELEMENT_MASTER_MASK            0xf
5655 #define REG_FIFO_ELEMENT_ERROR_SHIFT            47
5656 #define REG_FIFO_ELEMENT_ERROR_MASK             0x1f
5657 };
5658 
5659 /* IGU fifo element */
5660 struct igu_fifo_element {
5661         u32 dword0;
5662 #define IGU_FIFO_ELEMENT_DWORD0_FID_SHIFT               0
5663 #define IGU_FIFO_ELEMENT_DWORD0_FID_MASK                0xff
5664 #define IGU_FIFO_ELEMENT_DWORD0_IS_PF_SHIFT             8
5665 #define IGU_FIFO_ELEMENT_DWORD0_IS_PF_MASK              0x1
5666 #define IGU_FIFO_ELEMENT_DWORD0_SOURCE_SHIFT            9
5667 #define IGU_FIFO_ELEMENT_DWORD0_SOURCE_MASK             0xf
5668 #define IGU_FIFO_ELEMENT_DWORD0_ERR_TYPE_SHIFT          13
5669 #define IGU_FIFO_ELEMENT_DWORD0_ERR_TYPE_MASK           0xf
5670 #define IGU_FIFO_ELEMENT_DWORD0_CMD_ADDR_SHIFT          17
5671 #define IGU_FIFO_ELEMENT_DWORD0_CMD_ADDR_MASK           0x7fff
5672         u32 dword1;
5673         u32 dword2;
5674 #define IGU_FIFO_ELEMENT_DWORD12_IS_WR_CMD_SHIFT        0
5675 #define IGU_FIFO_ELEMENT_DWORD12_IS_WR_CMD_MASK         0x1
5676 #define IGU_FIFO_ELEMENT_DWORD12_WR_DATA_SHIFT          1
5677 #define IGU_FIFO_ELEMENT_DWORD12_WR_DATA_MASK           0xffffffff
5678         u32 reserved;
5679 };
5680 
5681 struct igu_fifo_wr_data {
5682         u32 data;
5683 #define IGU_FIFO_WR_DATA_PROD_CONS_SHIFT                0
5684 #define IGU_FIFO_WR_DATA_PROD_CONS_MASK                 0xffffff
5685 #define IGU_FIFO_WR_DATA_UPDATE_FLAG_SHIFT              24
5686 #define IGU_FIFO_WR_DATA_UPDATE_FLAG_MASK               0x1
5687 #define IGU_FIFO_WR_DATA_EN_DIS_INT_FOR_SB_SHIFT        25
5688 #define IGU_FIFO_WR_DATA_EN_DIS_INT_FOR_SB_MASK         0x3
5689 #define IGU_FIFO_WR_DATA_SEGMENT_SHIFT                  27
5690 #define IGU_FIFO_WR_DATA_SEGMENT_MASK                   0x1
5691 #define IGU_FIFO_WR_DATA_TIMER_MASK_SHIFT               28
5692 #define IGU_FIFO_WR_DATA_TIMER_MASK_MASK                0x1
5693 #define IGU_FIFO_WR_DATA_CMD_TYPE_SHIFT                 31
5694 #define IGU_FIFO_WR_DATA_CMD_TYPE_MASK                  0x1
5695 };
5696 
5697 struct igu_fifo_cleanup_wr_data {
5698         u32 data;
5699 #define IGU_FIFO_CLEANUP_WR_DATA_RESERVED_SHIFT         0
5700 #define IGU_FIFO_CLEANUP_WR_DATA_RESERVED_MASK          0x7ffffff
5701 #define IGU_FIFO_CLEANUP_WR_DATA_CLEANUP_VAL_SHIFT      27
5702 #define IGU_FIFO_CLEANUP_WR_DATA_CLEANUP_VAL_MASK       0x1
5703 #define IGU_FIFO_CLEANUP_WR_DATA_CLEANUP_TYPE_SHIFT     28
5704 #define IGU_FIFO_CLEANUP_WR_DATA_CLEANUP_TYPE_MASK      0x7
5705 #define IGU_FIFO_CLEANUP_WR_DATA_CMD_TYPE_SHIFT         31
5706 #define IGU_FIFO_CLEANUP_WR_DATA_CMD_TYPE_MASK          0x1
5707 };
5708 
5709 /* Protection override element */
5710 struct protection_override_element {
5711         u64 data;
5712 #define PROTECTION_OVERRIDE_ELEMENT_ADDRESS_SHIFT               0
5713 #define PROTECTION_OVERRIDE_ELEMENT_ADDRESS_MASK                0x7fffff
5714 #define PROTECTION_OVERRIDE_ELEMENT_WINDOW_SIZE_SHIFT           23
5715 #define PROTECTION_OVERRIDE_ELEMENT_WINDOW_SIZE_MASK            0xffffff
5716 #define PROTECTION_OVERRIDE_ELEMENT_READ_SHIFT                  47
5717 #define PROTECTION_OVERRIDE_ELEMENT_READ_MASK                   0x1
5718 #define PROTECTION_OVERRIDE_ELEMENT_WRITE_SHIFT                 48
5719 #define PROTECTION_OVERRIDE_ELEMENT_WRITE_MASK                  0x1
5720 #define PROTECTION_OVERRIDE_ELEMENT_READ_PROTECTION_SHIFT       49
5721 #define PROTECTION_OVERRIDE_ELEMENT_READ_PROTECTION_MASK        0x7
5722 #define PROTECTION_OVERRIDE_ELEMENT_WRITE_PROTECTION_SHIFT      52
5723 #define PROTECTION_OVERRIDE_ELEMENT_WRITE_PROTECTION_MASK       0x7
5724 };
5725 
5726 enum igu_fifo_sources {
5727         IGU_SRC_PXP0,
5728         IGU_SRC_PXP1,
5729         IGU_SRC_PXP2,
5730         IGU_SRC_PXP3,
5731         IGU_SRC_PXP4,
5732         IGU_SRC_PXP5,
5733         IGU_SRC_PXP6,
5734         IGU_SRC_PXP7,
5735         IGU_SRC_CAU,
5736         IGU_SRC_ATTN,
5737         IGU_SRC_GRC
5738 };
5739 
5740 enum igu_fifo_addr_types {
5741         IGU_ADDR_TYPE_MSIX_MEM,
5742         IGU_ADDR_TYPE_WRITE_PBA,
5743         IGU_ADDR_TYPE_WRITE_INT_ACK,
5744         IGU_ADDR_TYPE_WRITE_ATTN_BITS,
5745         IGU_ADDR_TYPE_READ_INT,
5746         IGU_ADDR_TYPE_WRITE_PROD_UPDATE,
5747         IGU_ADDR_TYPE_RESERVED
5748 };
5749 
5750 struct igu_fifo_addr_data {
5751         u16 start_addr;
5752         u16 end_addr;
5753         char *desc;
5754         char *vf_desc;
5755         enum igu_fifo_addr_types type;
5756 };
5757 
5758 struct mcp_trace_meta {
5759         u32 modules_num;
5760         char **modules;
5761         u32 formats_num;
5762         struct mcp_trace_format *formats;
5763         bool is_allocated;
5764 };
5765 
5766 /* Debug Tools user data */
5767 struct dbg_tools_user_data {
5768         struct mcp_trace_meta mcp_trace_meta;
5769         const u32 *mcp_trace_user_meta_buf;
5770 };
5771 
5772 /******************************** Constants **********************************/
5773 
5774 #define MAX_MSG_LEN                             1024
5775 
5776 #define MCP_TRACE_MAX_MODULE_LEN                8
5777 #define MCP_TRACE_FORMAT_MAX_PARAMS             3
5778 #define MCP_TRACE_FORMAT_PARAM_WIDTH \
5779         (MCP_TRACE_FORMAT_P2_SIZE_SHIFT - MCP_TRACE_FORMAT_P1_SIZE_SHIFT)
5780 
5781 #define REG_FIFO_ELEMENT_ADDR_FACTOR            4
5782 #define REG_FIFO_ELEMENT_IS_PF_VF_VAL           127
5783 
5784 #define PROTECTION_OVERRIDE_ELEMENT_ADDR_FACTOR 4
5785 
5786 /***************************** Constant Arrays *******************************/
5787 
5788 struct user_dbg_array {
5789         const u32 *ptr;
5790         u32 size_in_dwords;
5791 };
5792 
5793 /* Debug arrays */
5794 static struct user_dbg_array
5795 s_user_dbg_arrays[MAX_BIN_DBG_BUFFER_TYPE] = { {NULL} };
5796 
5797 /* Block names array */
5798 static struct block_info s_block_info_arr[] = {
5799         {"grc", BLOCK_GRC},
5800         {"miscs", BLOCK_MISCS},
5801         {"misc", BLOCK_MISC},
5802         {"dbu", BLOCK_DBU},
5803         {"pglue_b", BLOCK_PGLUE_B},
5804         {"cnig", BLOCK_CNIG},
5805         {"cpmu", BLOCK_CPMU},
5806         {"ncsi", BLOCK_NCSI},
5807         {"opte", BLOCK_OPTE},
5808         {"bmb", BLOCK_BMB},
5809         {"pcie", BLOCK_PCIE},
5810         {"mcp", BLOCK_MCP},
5811         {"mcp2", BLOCK_MCP2},
5812         {"pswhst", BLOCK_PSWHST},
5813         {"pswhst2", BLOCK_PSWHST2},
5814         {"pswrd", BLOCK_PSWRD},
5815         {"pswrd2", BLOCK_PSWRD2},
5816         {"pswwr", BLOCK_PSWWR},
5817         {"pswwr2", BLOCK_PSWWR2},
5818         {"pswrq", BLOCK_PSWRQ},
5819         {"pswrq2", BLOCK_PSWRQ2},
5820         {"pglcs", BLOCK_PGLCS},
5821         {"ptu", BLOCK_PTU},
5822         {"dmae", BLOCK_DMAE},
5823         {"tcm", BLOCK_TCM},
5824         {"mcm", BLOCK_MCM},
5825         {"ucm", BLOCK_UCM},
5826         {"xcm", BLOCK_XCM},
5827         {"ycm", BLOCK_YCM},
5828         {"pcm", BLOCK_PCM},
5829         {"qm", BLOCK_QM},
5830         {"tm", BLOCK_TM},
5831         {"dorq", BLOCK_DORQ},
5832         {"brb", BLOCK_BRB},
5833         {"src", BLOCK_SRC},
5834         {"prs", BLOCK_PRS},
5835         {"tsdm", BLOCK_TSDM},
5836         {"msdm", BLOCK_MSDM},
5837         {"usdm", BLOCK_USDM},
5838         {"xsdm", BLOCK_XSDM},
5839         {"ysdm", BLOCK_YSDM},
5840         {"psdm", BLOCK_PSDM},
5841         {"tsem", BLOCK_TSEM},
5842         {"msem", BLOCK_MSEM},
5843         {"usem", BLOCK_USEM},
5844         {"xsem", BLOCK_XSEM},
5845         {"ysem", BLOCK_YSEM},
5846         {"psem", BLOCK_PSEM},
5847         {"rss", BLOCK_RSS},
5848         {"tmld", BLOCK_TMLD},
5849         {"muld", BLOCK_MULD},
5850         {"yuld", BLOCK_YULD},
5851         {"xyld", BLOCK_XYLD},
5852         {"ptld", BLOCK_PTLD},
5853         {"ypld", BLOCK_YPLD},
5854         {"prm", BLOCK_PRM},
5855         {"pbf_pb1", BLOCK_PBF_PB1},
5856         {"pbf_pb2", BLOCK_PBF_PB2},
5857         {"rpb", BLOCK_RPB},
5858         {"btb", BLOCK_BTB},
5859         {"pbf", BLOCK_PBF},
5860         {"rdif", BLOCK_RDIF},
5861         {"tdif", BLOCK_TDIF},
5862         {"cdu", BLOCK_CDU},
5863         {"ccfc", BLOCK_CCFC},
5864         {"tcfc", BLOCK_TCFC},
5865         {"igu", BLOCK_IGU},
5866         {"cau", BLOCK_CAU},
5867         {"rgfs", BLOCK_RGFS},
5868         {"rgsrc", BLOCK_RGSRC},
5869         {"tgfs", BLOCK_TGFS},
5870         {"tgsrc", BLOCK_TGSRC},
5871         {"umac", BLOCK_UMAC},
5872         {"xmac", BLOCK_XMAC},
5873         {"dbg", BLOCK_DBG},
5874         {"nig", BLOCK_NIG},
5875         {"wol", BLOCK_WOL},
5876         {"bmbn", BLOCK_BMBN},
5877         {"ipc", BLOCK_IPC},
5878         {"nwm", BLOCK_NWM},
5879         {"nws", BLOCK_NWS},
5880         {"ms", BLOCK_MS},
5881         {"phy_pcie", BLOCK_PHY_PCIE},
5882         {"led", BLOCK_LED},
5883         {"avs_wrap", BLOCK_AVS_WRAP},
5884         {"pxpreqbus", BLOCK_PXPREQBUS},
5885         {"misc_aeu", BLOCK_MISC_AEU},
5886         {"bar0_map", BLOCK_BAR0_MAP}
5887 };
5888 
5889 /* Status string array */
5890 static const char * const s_status_str[] = {
5891         /* DBG_STATUS_OK */
5892         "Operation completed successfully",
5893 
5894         /* DBG_STATUS_APP_VERSION_NOT_SET */
5895         "Debug application version wasn't set",
5896 
5897         /* DBG_STATUS_UNSUPPORTED_APP_VERSION */
5898         "Unsupported debug application version",
5899 
5900         /* DBG_STATUS_DBG_BLOCK_NOT_RESET */
5901         "The debug block wasn't reset since the last recording",
5902 
5903         /* DBG_STATUS_INVALID_ARGS */
5904         "Invalid arguments",
5905 
5906         /* DBG_STATUS_OUTPUT_ALREADY_SET */
5907         "The debug output was already set",
5908 
5909         /* DBG_STATUS_INVALID_PCI_BUF_SIZE */
5910         "Invalid PCI buffer size",
5911 
5912         /* DBG_STATUS_PCI_BUF_ALLOC_FAILED */
5913         "PCI buffer allocation failed",
5914 
5915         /* DBG_STATUS_PCI_BUF_NOT_ALLOCATED */
5916         "A PCI buffer wasn't allocated",
5917 
5918         /* DBG_STATUS_TOO_MANY_INPUTS */
5919         "Too many inputs were enabled. Enabled less inputs, or set 'unifyInputs' to true",
5920 
5921         /* DBG_STATUS_INPUT_OVERLAP */
5922         "Overlapping debug bus inputs",
5923 
5924         /* DBG_STATUS_HW_ONLY_RECORDING */
5925         "Cannot record Storm data since the entire recording cycle is used by HW",
5926 
5927         /* DBG_STATUS_STORM_ALREADY_ENABLED */
5928         "The Storm was already enabled",
5929 
5930         /* DBG_STATUS_STORM_NOT_ENABLED */
5931         "The specified Storm wasn't enabled",
5932 
5933         /* DBG_STATUS_BLOCK_ALREADY_ENABLED */
5934         "The block was already enabled",
5935 
5936         /* DBG_STATUS_BLOCK_NOT_ENABLED */
5937         "The specified block wasn't enabled",
5938 
5939         /* DBG_STATUS_NO_INPUT_ENABLED */
5940         "No input was enabled for recording",
5941 
5942         /* DBG_STATUS_NO_FILTER_TRIGGER_64B */
5943         "Filters and triggers are not allowed when recording in 64b units",
5944 
5945         /* DBG_STATUS_FILTER_ALREADY_ENABLED */
5946         "The filter was already enabled",
5947 
5948         /* DBG_STATUS_TRIGGER_ALREADY_ENABLED */
5949         "The trigger was already enabled",
5950 
5951         /* DBG_STATUS_TRIGGER_NOT_ENABLED */
5952         "The trigger wasn't enabled",
5953 
5954         /* DBG_STATUS_CANT_ADD_CONSTRAINT */
5955         "A constraint can be added only after a filter was enabled or a trigger state was added",
5956 
5957         /* DBG_STATUS_TOO_MANY_TRIGGER_STATES */
5958         "Cannot add more than 3 trigger states",
5959 
5960         /* DBG_STATUS_TOO_MANY_CONSTRAINTS */
5961         "Cannot add more than 4 constraints per filter or trigger state",
5962 
5963         /* DBG_STATUS_RECORDING_NOT_STARTED */
5964         "The recording wasn't started",
5965 
5966         /* DBG_STATUS_DATA_DIDNT_TRIGGER */
5967         "A trigger was configured, but it didn't trigger",
5968 
5969         /* DBG_STATUS_NO_DATA_RECORDED */
5970         "No data was recorded",
5971 
5972         /* DBG_STATUS_DUMP_BUF_TOO_SMALL */
5973         "Dump buffer is too small",
5974 
5975         /* DBG_STATUS_DUMP_NOT_CHUNK_ALIGNED */
5976         "Dumped data is not aligned to chunks",
5977 
5978         /* DBG_STATUS_UNKNOWN_CHIP */
5979         "Unknown chip",
5980 
5981         /* DBG_STATUS_VIRT_MEM_ALLOC_FAILED */
5982         "Failed allocating virtual memory",
5983 
5984         /* DBG_STATUS_BLOCK_IN_RESET */
5985         "The input block is in reset",
5986 
5987         /* DBG_STATUS_INVALID_TRACE_SIGNATURE */
5988         "Invalid MCP trace signature found in NVRAM",
5989 
5990         /* DBG_STATUS_INVALID_NVRAM_BUNDLE */
5991         "Invalid bundle ID found in NVRAM",
5992 
5993         /* DBG_STATUS_NVRAM_GET_IMAGE_FAILED */
5994         "Failed getting NVRAM image",
5995 
5996         /* DBG_STATUS_NON_ALIGNED_NVRAM_IMAGE */
5997         "NVRAM image is not dword-aligned",
5998 
5999         /* DBG_STATUS_NVRAM_READ_FAILED */
6000         "Failed reading from NVRAM",
6001 
6002         /* DBG_STATUS_IDLE_CHK_PARSE_FAILED */
6003         "Idle check parsing failed",
6004 
6005         /* DBG_STATUS_MCP_TRACE_BAD_DATA */
6006         "MCP Trace data is corrupt",
6007 
6008         /* DBG_STATUS_MCP_TRACE_NO_META */
6009         "Dump doesn't contain meta data - it must be provided in image file",
6010 
6011         /* DBG_STATUS_MCP_COULD_NOT_HALT */
6012         "Failed to halt MCP",
6013 
6014         /* DBG_STATUS_MCP_COULD_NOT_RESUME */
6015         "Failed to resume MCP after halt",
6016 
6017         /* DBG_STATUS_RESERVED2 */
6018         "Reserved debug status - shouldn't be returned",
6019 
6020         /* DBG_STATUS_SEMI_FIFO_NOT_EMPTY */
6021         "Failed to empty SEMI sync FIFO",
6022 
6023         /* DBG_STATUS_IGU_FIFO_BAD_DATA */
6024         "IGU FIFO data is corrupt",
6025 
6026         /* DBG_STATUS_MCP_COULD_NOT_MASK_PRTY */
6027         "MCP failed to mask parities",
6028 
6029         /* DBG_STATUS_FW_ASSERTS_PARSE_FAILED */
6030         "FW Asserts parsing failed",
6031 
6032         /* DBG_STATUS_REG_FIFO_BAD_DATA */
6033         "GRC FIFO data is corrupt",
6034 
6035         /* DBG_STATUS_PROTECTION_OVERRIDE_BAD_DATA */
6036         "Protection Override data is corrupt",
6037 
6038         /* DBG_STATUS_DBG_ARRAY_NOT_SET */
6039         "Debug arrays were not set (when using binary files, dbg_set_bin_ptr must be called)",
6040 
6041         /* DBG_STATUS_FILTER_BUG */
6042         "Debug Bus filtering requires the -unifyInputs option (due to a HW bug)",
6043 
6044         /* DBG_STATUS_NON_MATCHING_LINES */
6045         "Non-matching debug lines - all lines must be of the same type (either 128b or 256b)",
6046 
6047         /* DBG_STATUS_INVALID_TRIGGER_DWORD_OFFSET */
6048         "The selected trigger dword offset wasn't enabled in the recorded HW block",
6049 
6050         /* DBG_STATUS_DBG_BUS_IN_USE */
6051         "The debug bus is in use"
6052 };
6053 
6054 /* Idle check severity names array */
6055 static const char * const s_idle_chk_severity_str[] = {
6056         "Error",
6057         "Error if no traffic",
6058         "Warning"
6059 };
6060 
6061 /* MCP Trace level names array */
6062 static const char * const s_mcp_trace_level_str[] = {
6063         "ERROR",
6064         "TRACE",
6065         "DEBUG"
6066 };
6067 
6068 /* Access type names array */
6069 static const char * const s_access_strs[] = {
6070         "read",
6071         "write"
6072 };
6073 
6074 /* Privilege type names array */
6075 static const char * const s_privilege_strs[] = {
6076         "VF",
6077         "PDA",
6078         "HV",
6079         "UA"
6080 };
6081 
6082 /* Protection type names array */
6083 static const char * const s_protection_strs[] = {
6084         "(default)",
6085         "(default)",
6086         "(default)",
6087         "(default)",
6088         "override VF",
6089         "override PDA",
6090         "override HV",
6091         "override UA"
6092 };
6093 
6094 /* Master type names array */
6095 static const char * const s_master_strs[] = {
6096         "???",
6097         "pxp",
6098         "mcp",
6099         "msdm",
6100         "psdm",
6101         "ysdm",
6102         "usdm",
6103         "tsdm",
6104         "xsdm",
6105         "dbu",
6106         "dmae",
6107         "???",
6108         "???",
6109         "???",
6110         "???",
6111         "???"
6112 };
6113 
6114 /* REG FIFO error messages array */
6115 static const char * const s_reg_fifo_error_strs[] = {
6116         "grc timeout",
6117         "address doesn't belong to any block",
6118         "reserved address in block or write to read-only address",
6119         "privilege/protection mismatch",
6120         "path isolation error"
6121 };
6122 
6123 /* IGU FIFO sources array */
6124 static const char * const s_igu_fifo_source_strs[] = {
6125         "TSTORM",
6126         "MSTORM",
6127         "USTORM",
6128         "XSTORM",
6129         "YSTORM",
6130         "PSTORM",
6131         "PCIE",
6132         "NIG_QM_PBF",
6133         "CAU",
6134         "ATTN",
6135         "GRC",
6136 };
6137 
6138 /* IGU FIFO error messages */
6139 static const char * const s_igu_fifo_error_strs[] = {
6140         "no error",
6141         "length error",
6142         "function disabled",
6143         "VF sent command to attention address",
6144         "host sent prod update command",
6145         "read of during interrupt register while in MIMD mode",
6146         "access to PXP BAR reserved address",
6147         "producer update command to attention index",
6148         "unknown error",
6149         "SB index not valid",
6150         "SB relative index and FID not found",
6151         "FID not match",
6152         "command with error flag asserted (PCI error or CAU discard)",
6153         "VF sent cleanup and RF cleanup is disabled",
6154         "cleanup command on type bigger than 4"
6155 };
6156 
6157 /* IGU FIFO address data */
6158 static const struct igu_fifo_addr_data s_igu_fifo_addr_data[] = {
6159         {0x0, 0x101, "MSI-X Memory", NULL,
6160          IGU_ADDR_TYPE_MSIX_MEM},
6161         {0x102, 0x1ff, "reserved", NULL,
6162          IGU_ADDR_TYPE_RESERVED},
6163         {0x200, 0x200, "Write PBA[0:63]", NULL,
6164          IGU_ADDR_TYPE_WRITE_PBA},
6165         {0x201, 0x201, "Write PBA[64:127]", "reserved",
6166          IGU_ADDR_TYPE_WRITE_PBA},
6167         {0x202, 0x202, "Write PBA[128]", "reserved",
6168          IGU_ADDR_TYPE_WRITE_PBA},
6169         {0x203, 0x3ff, "reserved", NULL,
6170          IGU_ADDR_TYPE_RESERVED},
6171         {0x400, 0x5ef, "Write interrupt acknowledgment", NULL,
6172          IGU_ADDR_TYPE_WRITE_INT_ACK},
6173         {0x5f0, 0x5f0, "Attention bits update", NULL,
6174          IGU_ADDR_TYPE_WRITE_ATTN_BITS},
6175         {0x5f1, 0x5f1, "Attention bits set", NULL,
6176          IGU_ADDR_TYPE_WRITE_ATTN_BITS},
6177         {0x5f2, 0x5f2, "Attention bits clear", NULL,
6178          IGU_ADDR_TYPE_WRITE_ATTN_BITS},
6179         {0x5f3, 0x5f3, "Read interrupt 0:63 with mask", NULL,
6180          IGU_ADDR_TYPE_READ_INT},
6181         {0x5f4, 0x5f4, "Read interrupt 0:31 with mask", NULL,
6182          IGU_ADDR_TYPE_READ_INT},
6183         {0x5f5, 0x5f5, "Read interrupt 32:63 with mask", NULL,
6184          IGU_ADDR_TYPE_READ_INT},
6185         {0x5f6, 0x5f6, "Read interrupt 0:63 without mask", NULL,
6186          IGU_ADDR_TYPE_READ_INT},
6187         {0x5f7, 0x5ff, "reserved", NULL,
6188          IGU_ADDR_TYPE_RESERVED},
6189         {0x600, 0x7ff, "Producer update", NULL,
6190          IGU_ADDR_TYPE_WRITE_PROD_UPDATE}
6191 };
6192 
6193 /******************************** Variables **********************************/
6194 
6195 /* Temporary buffer, used for print size calculations */
6196 static char s_temp_buf[MAX_MSG_LEN];
6197 
6198 /**************************** Private Functions ******************************/
6199 
6200 static u32 qed_cyclic_add(u32 a, u32 b, u32 size)
6201 {
6202         return (a + b) % size;
6203 }
6204 
6205 static u32 qed_cyclic_sub(u32 a, u32 b, u32 size)
6206 {
6207         return (size + a - b) % size;
6208 }
6209 
6210 /* Reads the specified number of bytes from the specified cyclic buffer (up to 4
6211  * bytes) and returns them as a dword value. the specified buffer offset is
6212  * updated.
6213  */
6214 static u32 qed_read_from_cyclic_buf(void *buf,
6215                                     u32 *offset,
6216                                     u32 buf_size, u8 num_bytes_to_read)
6217 {
6218         u8 i, *val_ptr, *bytes_buf = (u8 *)buf;
6219         u32 val = 0;
6220 
6221         val_ptr = (u8 *)&val;
6222 
6223         /* Assume running on a LITTLE ENDIAN and the buffer is network order
6224          * (BIG ENDIAN), as high order bytes are placed in lower memory address.
6225          */
6226         for (i = 0; i < num_bytes_to_read; i++) {
6227                 val_ptr[i] = bytes_buf[*offset];
6228                 *offset = qed_cyclic_add(*offset, 1, buf_size);
6229         }
6230 
6231         return val;
6232 }
6233 
6234 /* Reads and returns the next byte from the specified buffer.
6235  * The specified buffer offset is updated.
6236  */
6237 static u8 qed_read_byte_from_buf(void *buf, u32 *offset)
6238 {
6239         return ((u8 *)buf)[(*offset)++];
6240 }
6241 
6242 /* Reads and returns the next dword from the specified buffer.
6243  * The specified buffer offset is updated.
6244  */
6245 static u32 qed_read_dword_from_buf(void *buf, u32 *offset)
6246 {
6247         u32 dword_val = *(u32 *)&((u8 *)buf)[*offset];
6248 
6249         *offset += 4;
6250 
6251         return dword_val;
6252 }
6253 
6254 /* Reads the next string from the specified buffer, and copies it to the
6255  * specified pointer. The specified buffer offset is updated.
6256  */
6257 static void qed_read_str_from_buf(void *buf, u32 *offset, u32 size, char *dest)
6258 {
6259         const char *source_str = &((const char *)buf)[*offset];
6260 
6261         strncpy(dest, source_str, size);
6262         dest[size - 1] = '\0';
6263         *offset += size;
6264 }
6265 
6266 /* Returns a pointer to the specified offset (in bytes) of the specified buffer.
6267  * If the specified buffer in NULL, a temporary buffer pointer is returned.
6268  */
6269 static char *qed_get_buf_ptr(void *buf, u32 offset)
6270 {
6271         return buf ? (char *)buf + offset : s_temp_buf;
6272 }
6273 
6274 /* Reads a param from the specified buffer. Returns the number of dwords read.
6275  * If the returned str_param is NULL, the param is numeric and its value is
6276  * returned in num_param.
6277  * Otheriwise, the param is a string and its pointer is returned in str_param.
6278  */
6279 static u32 qed_read_param(u32 *dump_buf,
6280                           const char **param_name,
6281                           const char **param_str_val, u32 *param_num_val)
6282 {
6283         char *char_buf = (char *)dump_buf;
6284         size_t offset = 0;
6285 
6286         /* Extract param name */
6287         *param_name = char_buf;
6288         offset += strlen(*param_name) + 1;
6289 
6290         /* Check param type */
6291         if (*(char_buf + offset++)) {
6292                 /* String param */
6293                 *param_str_val = char_buf + offset;
6294                 *param_num_val = 0;
6295                 offset += strlen(*param_str_val) + 1;
6296                 if (offset & 0x3)
6297                         offset += (4 - (offset & 0x3));
6298         } else {
6299                 /* Numeric param */
6300                 *param_str_val = NULL;
6301                 if (offset & 0x3)
6302                         offset += (4 - (offset & 0x3));
6303                 *param_num_val = *(u32 *)(char_buf + offset);
6304                 offset += 4;
6305         }
6306 
6307         return (u32)offset / 4;
6308 }
6309 
6310 /* Reads a section header from the specified buffer.
6311  * Returns the number of dwords read.
6312  */
6313 static u32 qed_read_section_hdr(u32 *dump_buf,
6314                                 const char **section_name,
6315                                 u32 *num_section_params)
6316 {
6317         const char *param_str_val;
6318 
6319         return qed_read_param(dump_buf,
6320                               section_name, &param_str_val, num_section_params);
6321 }
6322 
6323 /* Reads section params from the specified buffer and prints them to the results
6324  * buffer. Returns the number of dwords read.
6325  */
6326 static u32 qed_print_section_params(u32 *dump_buf,
6327                                     u32 num_section_params,
6328                                     char *results_buf, u32 *num_chars_printed)
6329 {
6330         u32 i, dump_offset = 0, results_offset = 0;
6331 
6332         for (i = 0; i < num_section_params; i++) {
6333                 const char *param_name, *param_str_val;
6334                 u32 param_num_val = 0;
6335 
6336                 dump_offset += qed_read_param(dump_buf + dump_offset,
6337                                               &param_name,
6338                                               &param_str_val, &param_num_val);
6339 
6340                 if (param_str_val)
6341                         results_offset +=
6342                                 sprintf(qed_get_buf_ptr(results_buf,
6343                                                         results_offset),
6344                                         "%s: %s\n", param_name, param_str_val);
6345                 else if (strcmp(param_name, "fw-timestamp"))
6346                         results_offset +=
6347                                 sprintf(qed_get_buf_ptr(results_buf,
6348                                                         results_offset),
6349                                         "%s: %d\n", param_name, param_num_val);
6350         }
6351 
6352         results_offset += sprintf(qed_get_buf_ptr(results_buf, results_offset),
6353                                   "\n");
6354 
6355         *num_chars_printed = results_offset;
6356 
6357         return dump_offset;
6358 }
6359 
6360 static struct dbg_tools_user_data *
6361 qed_dbg_get_user_data(struct qed_hwfn *p_hwfn)
6362 {
6363         return (struct dbg_tools_user_data *)p_hwfn->dbg_user_info;
6364 }
6365 
6366 /* Parses the idle check rules and returns the number of characters printed.
6367  * In case of parsing error, returns 0.
6368  */
6369 static u32 qed_parse_idle_chk_dump_rules(u32 *dump_buf,
6370                                          u32 *dump_buf_end,
6371                                          u32 num_rules,
6372                                          bool print_fw_idle_chk,
6373                                          char *results_buf,
6374                                          u32 *num_errors, u32 *num_warnings)
6375 {
6376         /* Offset in results_buf in bytes */
6377         u32 results_offset = 0;
6378 
6379         u32 rule_idx;
6380         u16 i, j;
6381 
6382         *num_errors = 0;
6383         *num_warnings = 0;
6384 
6385         /* Go over dumped results */
6386         for (rule_idx = 0; rule_idx < num_rules && dump_buf < dump_buf_end;
6387              rule_idx++) {
6388                 const struct dbg_idle_chk_rule_parsing_data *rule_parsing_data;
6389                 struct dbg_idle_chk_result_hdr *hdr;
6390                 const char *parsing_str, *lsi_msg;
6391                 u32 parsing_str_offset;
6392                 bool has_fw_msg;
6393                 u8 curr_reg_id;
6394 
6395                 hdr = (struct dbg_idle_chk_result_hdr *)dump_buf;
6396                 rule_parsing_data =
6397                         (const struct dbg_idle_chk_rule_parsing_data *)
6398                         &s_user_dbg_arrays[BIN_BUF_DBG_IDLE_CHK_PARSING_DATA].
6399                         ptr[hdr->rule_id];
6400                 parsing_str_offset =
6401                         GET_FIELD(rule_parsing_data->data,
6402                                   DBG_IDLE_CHK_RULE_PARSING_DATA_STR_OFFSET);
6403                 has_fw_msg =
6404                         GET_FIELD(rule_parsing_data->data,
6405                                 DBG_IDLE_CHK_RULE_PARSING_DATA_HAS_FW_MSG) > 0;
6406                 parsing_str =
6407                         &((const char *)
6408                         s_user_dbg_arrays[BIN_BUF_DBG_PARSING_STRINGS].ptr)
6409                         [parsing_str_offset];
6410                 lsi_msg = parsing_str;
6411                 curr_reg_id = 0;
6412 
6413                 if (hdr->severity >= MAX_DBG_IDLE_CHK_SEVERITY_TYPES)
6414                         return 0;
6415 
6416                 /* Skip rule header */
6417                 dump_buf += BYTES_TO_DWORDS(sizeof(*hdr));
6418 
6419                 /* Update errors/warnings count */
6420                 if (hdr->severity == IDLE_CHK_SEVERITY_ERROR ||
6421                     hdr->severity == IDLE_CHK_SEVERITY_ERROR_NO_TRAFFIC)
6422                         (*num_errors)++;
6423                 else
6424                         (*num_warnings)++;
6425 
6426                 /* Print rule severity */
6427                 results_offset +=
6428                     sprintf(qed_get_buf_ptr(results_buf,
6429                                             results_offset), "%s: ",
6430                             s_idle_chk_severity_str[hdr->severity]);
6431 
6432                 /* Print rule message */
6433                 if (has_fw_msg)
6434                         parsing_str += strlen(parsing_str) + 1;
6435                 results_offset +=
6436                     sprintf(qed_get_buf_ptr(results_buf,
6437                                             results_offset), "%s.",
6438                             has_fw_msg &&
6439                             print_fw_idle_chk ? parsing_str : lsi_msg);
6440                 parsing_str += strlen(parsing_str) + 1;
6441 
6442                 /* Print register values */
6443                 results_offset +=
6444                     sprintf(qed_get_buf_ptr(results_buf,
6445                                             results_offset), " Registers:");
6446                 for (i = 0;
6447                      i < hdr->num_dumped_cond_regs + hdr->num_dumped_info_regs;
6448                      i++) {
6449                         struct dbg_idle_chk_result_reg_hdr *reg_hdr;
6450                         bool is_mem;
6451                         u8 reg_id;
6452 
6453                         reg_hdr =
6454                                 (struct dbg_idle_chk_result_reg_hdr *)dump_buf;
6455                         is_mem = GET_FIELD(reg_hdr->data,
6456                                            DBG_IDLE_CHK_RESULT_REG_HDR_IS_MEM);
6457                         reg_id = GET_FIELD(reg_hdr->data,
6458                                            DBG_IDLE_CHK_RESULT_REG_HDR_REG_ID);
6459 
6460                         /* Skip reg header */
6461                         dump_buf += BYTES_TO_DWORDS(sizeof(*reg_hdr));
6462 
6463                         /* Skip register names until the required reg_id is
6464                          * reached.
6465                          */
6466                         for (; reg_id > curr_reg_id;
6467                              curr_reg_id++,
6468                              parsing_str += strlen(parsing_str) + 1);
6469 
6470                         results_offset +=
6471                             sprintf(qed_get_buf_ptr(results_buf,
6472                                                     results_offset), " %s",
6473                                     parsing_str);
6474                         if (i < hdr->num_dumped_cond_regs && is_mem)
6475                                 results_offset +=
6476                                     sprintf(qed_get_buf_ptr(results_buf,
6477                                                             results_offset),
6478                                             "[%d]", hdr->mem_entry_id +
6479                                             reg_hdr->start_entry);
6480                         results_offset +=
6481                             sprintf(qed_get_buf_ptr(results_buf,
6482                                                     results_offset), "=");
6483                         for (j = 0; j < reg_hdr->size; j++, dump_buf++) {
6484                                 results_offset +=
6485                                     sprintf(qed_get_buf_ptr(results_buf,
6486                                                             results_offset),
6487                                             "0x%x", *dump_buf);
6488                                 if (j < reg_hdr->size - 1)
6489                                         results_offset +=
6490                                             sprintf(qed_get_buf_ptr
6491                                                     (results_buf,
6492                                                      results_offset), ",");
6493                         }
6494                 }
6495 
6496                 results_offset +=
6497                     sprintf(qed_get_buf_ptr(results_buf, results_offset), "\n");
6498         }
6499 
6500         /* Check if end of dump buffer was exceeded */
6501         if (dump_buf > dump_buf_end)
6502                 return 0;
6503 
6504         return results_offset;
6505 }
6506 
6507 /* Parses an idle check dump buffer.
6508  * If result_buf is not NULL, the idle check results are printed to it.
6509  * In any case, the required results buffer size is assigned to
6510  * parsed_results_bytes.
6511  * The parsing status is returned.
6512  */
6513 static enum dbg_status qed_parse_idle_chk_dump(u32 *dump_buf,
6514                                                u32 num_dumped_dwords,
6515                                                char *results_buf,
6516                                                u32 *parsed_results_bytes,
6517                                                u32 *num_errors,
6518                                                u32 *num_warnings)
6519 {
6520         const char *section_name, *param_name, *param_str_val;
6521         u32 *dump_buf_end = dump_buf + num_dumped_dwords;
6522         u32 num_section_params = 0, num_rules;
6523 
6524         /* Offset in results_buf in bytes */
6525         u32 results_offset = 0;
6526 
6527         *parsed_results_bytes = 0;
6528         *num_errors = 0;
6529         *num_warnings = 0;
6530 
6531         if (!s_user_dbg_arrays[BIN_BUF_DBG_PARSING_STRINGS].ptr ||
6532             !s_user_dbg_arrays[BIN_BUF_DBG_IDLE_CHK_PARSING_DATA].ptr)
6533                 return DBG_STATUS_DBG_ARRAY_NOT_SET;
6534 
6535         /* Read global_params section */
6536         dump_buf += qed_read_section_hdr(dump_buf,
6537                                          &section_name, &num_section_params);
6538         if (strcmp(section_name, "global_params"))
6539                 return DBG_STATUS_IDLE_CHK_PARSE_FAILED;
6540 
6541         /* Print global params */
6542         dump_buf += qed_print_section_params(dump_buf,
6543                                              num_section_params,
6544                                              results_buf, &results_offset);
6545 
6546         /* Read idle_chk section */
6547         dump_buf += qed_read_section_hdr(dump_buf,
6548                                          &section_name, &num_section_params);
6549         if (strcmp(section_name, "idle_chk") || num_section_params != 1)
6550                 return DBG_STATUS_IDLE_CHK_PARSE_FAILED;
6551         dump_buf += qed_read_param(dump_buf,
6552                                    &param_name, &param_str_val, &num_rules);
6553         if (strcmp(param_name, "num_rules"))
6554                 return DBG_STATUS_IDLE_CHK_PARSE_FAILED;
6555 
6556         if (num_rules) {
6557                 u32 rules_print_size;
6558 
6559                 /* Print FW output */
6560                 results_offset +=
6561                     sprintf(qed_get_buf_ptr(results_buf,
6562                                             results_offset),
6563                             "FW_IDLE_CHECK:\n");
6564                 rules_print_size =
6565                         qed_parse_idle_chk_dump_rules(dump_buf,
6566                                                       dump_buf_end,
6567                                                       num_rules,
6568                                                       true,
6569                                                       results_buf ?
6570                                                       results_buf +
6571                                                       results_offset :
6572                                                       NULL,
6573                                                       num_errors,
6574                                                       num_warnings);
6575                 results_offset += rules_print_size;
6576                 if (!rules_print_size)
6577                         return DBG_STATUS_IDLE_CHK_PARSE_FAILED;
6578 
6579                 /* Print LSI output */
6580                 results_offset +=
6581                     sprintf(qed_get_buf_ptr(results_buf,
6582                                             results_offset),
6583                             "\nLSI_IDLE_CHECK:\n");
6584                 rules_print_size =
6585                         qed_parse_idle_chk_dump_rules(dump_buf,
6586                                                       dump_buf_end,
6587                                                       num_rules,
6588                                                       false,
6589                                                       results_buf ?
6590                                                       results_buf +
6591                                                       results_offset :
6592                                                       NULL,
6593                                                       num_errors,
6594                                                       num_warnings);
6595                 results_offset += rules_print_size;
6596                 if (!rules_print_size)
6597                         return DBG_STATUS_IDLE_CHK_PARSE_FAILED;
6598         }
6599 
6600         /* Print errors/warnings count */
6601         if (*num_errors)
6602                 results_offset +=
6603                     sprintf(qed_get_buf_ptr(results_buf,
6604                                             results_offset),
6605                             "\nIdle Check failed!!! (with %d errors and %d warnings)\n",
6606                             *num_errors, *num_warnings);
6607         else if (*num_warnings)
6608                 results_offset +=
6609                     sprintf(qed_get_buf_ptr(results_buf,
6610                                             results_offset),
6611                             "\nIdle Check completed successfully (with %d warnings)\n",
6612                             *num_warnings);
6613         else
6614                 results_offset +=
6615                     sprintf(qed_get_buf_ptr(results_buf,
6616                                             results_offset),
6617                             "\nIdle Check completed successfully\n");
6618 
6619         /* Add 1 for string NULL termination */
6620         *parsed_results_bytes = results_offset + 1;
6621 
6622         return DBG_STATUS_OK;
6623 }
6624 
6625 /* Allocates and fills MCP Trace meta data based on the specified meta data
6626  * dump buffer.
6627  * Returns debug status code.
6628  */
6629 static enum dbg_status
6630 qed_mcp_trace_alloc_meta_data(struct qed_hwfn *p_hwfn,
6631                               const u32 *meta_buf)
6632 {
6633         struct dbg_tools_user_data *dev_user_data;
6634         u32 offset = 0, signature, i;
6635         struct mcp_trace_meta *meta;
6636         u8 *meta_buf_bytes;
6637 
6638         dev_user_data = qed_dbg_get_user_data(p_hwfn);
6639         meta = &dev_user_data->mcp_trace_meta;
6640         meta_buf_bytes = (u8 *)meta_buf;
6641 
6642         /* Free the previous meta before loading a new one. */
6643         if (meta->is_allocated)
6644                 qed_mcp_trace_free_meta_data(p_hwfn);
6645 
6646         memset(meta, 0, sizeof(*meta));
6647 
6648         /* Read first signature */
6649         signature = qed_read_dword_from_buf(meta_buf_bytes, &offset);
6650         if (signature != NVM_MAGIC_VALUE)
6651                 return DBG_STATUS_INVALID_TRACE_SIGNATURE;
6652 
6653         /* Read no. of modules and allocate memory for their pointers */
6654         meta->modules_num = qed_read_byte_from_buf(meta_buf_bytes, &offset);
6655         meta->modules = kcalloc(meta->modules_num, sizeof(char *),
6656                                 GFP_KERNEL);
6657         if (!meta->modules)
6658                 return DBG_STATUS_VIRT_MEM_ALLOC_FAILED;
6659 
6660         /* Allocate and read all module strings */
6661         for (i = 0; i < meta->modules_num; i++) {
6662                 u8 module_len = qed_read_byte_from_buf(meta_buf_bytes, &offset);
6663 
6664                 *(meta->modules + i) = kzalloc(module_len, GFP_KERNEL);
6665                 if (!(*(meta->modules + i))) {
6666                         /* Update number of modules to be released */
6667                         meta->modules_num = i ? i - 1 : 0;
6668                         return DBG_STATUS_VIRT_MEM_ALLOC_FAILED;
6669                 }
6670 
6671                 qed_read_str_from_buf(meta_buf_bytes, &offset, module_len,
6672                                       *(meta->modules + i));
6673                 if (module_len > MCP_TRACE_MAX_MODULE_LEN)
6674                         (*(meta->modules + i))[MCP_TRACE_MAX_MODULE_LEN] = '\0';
6675         }
6676 
6677         /* Read second signature */
6678         signature = qed_read_dword_from_buf(meta_buf_bytes, &offset);
6679         if (signature != NVM_MAGIC_VALUE)
6680                 return DBG_STATUS_INVALID_TRACE_SIGNATURE;
6681 
6682         /* Read number of formats and allocate memory for all formats */
6683         meta->formats_num = qed_read_dword_from_buf(meta_buf_bytes, &offset);
6684         meta->formats = kcalloc(meta->formats_num,
6685                                 sizeof(struct mcp_trace_format),
6686                                 GFP_KERNEL);
6687         if (!meta->formats)
6688                 return DBG_STATUS_VIRT_MEM_ALLOC_FAILED;
6689 
6690         /* Allocate and read all strings */
6691         for (i = 0; i < meta->formats_num; i++) {
6692                 struct mcp_trace_format *format_ptr = &meta->formats[i];
6693                 u8 format_len;
6694 
6695                 format_ptr->data = qed_read_dword_from_buf(meta_buf_bytes,
6696                                                            &offset);
6697                 format_len =
6698                     (format_ptr->data &
6699                      MCP_TRACE_FORMAT_LEN_MASK) >> MCP_TRACE_FORMAT_LEN_SHIFT;
6700                 format_ptr->format_str = kzalloc(format_len, GFP_KERNEL);
6701                 if (!format_ptr->format_str) {
6702                         /* Update number of modules to be released */
6703                         meta->formats_num = i ? i - 1 : 0;
6704                         return DBG_STATUS_VIRT_MEM_ALLOC_FAILED;
6705                 }
6706 
6707                 qed_read_str_from_buf(meta_buf_bytes,
6708                                       &offset,
6709                                       format_len, format_ptr->format_str);
6710         }
6711 
6712         meta->is_allocated = true;
6713         return DBG_STATUS_OK;
6714 }
6715 
6716 /* Parses an MCP trace buffer. If result_buf is not NULL, the MCP Trace results
6717  * are printed to it. The parsing status is returned.
6718  * Arguments:
6719  * trace_buf - MCP trace cyclic buffer
6720  * trace_buf_size - MCP trace cyclic buffer size in bytes
6721  * data_offset - offset in bytes of the data to parse in the MCP trace cyclic
6722  *               buffer.
6723  * data_size - size in bytes of data to parse.
6724  * parsed_buf - destination buffer for parsed data.
6725  * parsed_results_bytes - size of parsed data in bytes.
6726  */
6727 static enum dbg_status qed_parse_mcp_trace_buf(struct qed_hwfn *p_hwfn,
6728                                                u8 *trace_buf,
6729                                                u32 trace_buf_size,
6730                                                u32 data_offset,
6731                                                u32 data_size,
6732                                                char *parsed_buf,
6733                                                u32 *parsed_results_bytes)
6734 {
6735         struct dbg_tools_user_data *dev_user_data;
6736         struct mcp_trace_meta *meta;
6737         u32 param_mask, param_shift;
6738         enum dbg_status status;
6739 
6740         dev_user_data = qed_dbg_get_user_data(p_hwfn);
6741         meta = &dev_user_data->mcp_trace_meta;
6742         *parsed_results_bytes = 0;
6743 
6744         if (!meta->is_allocated)
6745                 return DBG_STATUS_MCP_TRACE_BAD_DATA;
6746 
6747         status = DBG_STATUS_OK;
6748 
6749         while (data_size) {
6750                 struct mcp_trace_format *format_ptr;
6751                 u8 format_level, format_module;
6752                 u32 params[3] = { 0, 0, 0 };
6753                 u32 header, format_idx, i;
6754 
6755                 if (data_size < MFW_TRACE_ENTRY_SIZE)
6756                         return DBG_STATUS_MCP_TRACE_BAD_DATA;
6757 
6758                 header = qed_read_from_cyclic_buf(trace_buf,
6759                                                   &data_offset,
6760                                                   trace_buf_size,
6761                                                   MFW_TRACE_ENTRY_SIZE);
6762                 data_size -= MFW_TRACE_ENTRY_SIZE;
6763                 format_idx = header & MFW_TRACE_EVENTID_MASK;
6764 
6765                 /* Skip message if its index doesn't exist in the meta data */
6766                 if (format_idx >= meta->formats_num) {
6767                         u8 format_size =
6768                                 (u8)((header & MFW_TRACE_PRM_SIZE_MASK) >>
6769                                      MFW_TRACE_PRM_SIZE_SHIFT);
6770 
6771                         if (data_size < format_size)
6772                                 return DBG_STATUS_MCP_TRACE_BAD_DATA;
6773 
6774                         data_offset = qed_cyclic_add(data_offset,
6775                                                      format_size,
6776                                                      trace_buf_size);
6777                         data_size -= format_size;
6778                         continue;
6779                 }
6780 
6781                 format_ptr = &meta->formats[format_idx];
6782 
6783                 for (i = 0,
6784                      param_mask = MCP_TRACE_FORMAT_P1_SIZE_MASK,
6785                      param_shift = MCP_TRACE_FORMAT_P1_SIZE_SHIFT;
6786                      i < MCP_TRACE_FORMAT_MAX_PARAMS;
6787                      i++,
6788                      param_mask <<= MCP_TRACE_FORMAT_PARAM_WIDTH,
6789                      param_shift += MCP_TRACE_FORMAT_PARAM_WIDTH) {
6790                         /* Extract param size (0..3) */
6791                         u8 param_size = (u8)((format_ptr->data & param_mask) >>
6792                                              param_shift);
6793 
6794                         /* If the param size is zero, there are no other
6795                          * parameters.
6796                          */
6797                         if (!param_size)
6798                                 break;
6799 
6800                         /* Size is encoded using 2 bits, where 3 is used to
6801                          * encode 4.
6802                          */
6803                         if (param_size == 3)
6804                                 param_size = 4;
6805 
6806                         if (data_size < param_size)
6807                                 return DBG_STATUS_MCP_TRACE_BAD_DATA;
6808 
6809                         params[i] = qed_read_from_cyclic_buf(trace_buf,
6810                                                              &data_offset,
6811                                                              trace_buf_size,
6812                                                              param_size);
6813                         data_size -= param_size;
6814                 }
6815 
6816                 format_level = (u8)((format_ptr->data &
6817                                      MCP_TRACE_FORMAT_LEVEL_MASK) >>
6818                                     MCP_TRACE_FORMAT_LEVEL_SHIFT);
6819                 format_module = (u8)((format_ptr->data &
6820                                       MCP_TRACE_FORMAT_MODULE_MASK) >>
6821                                      MCP_TRACE_FORMAT_MODULE_SHIFT);
6822                 if (format_level >= ARRAY_SIZE(s_mcp_trace_level_str))
6823                         return DBG_STATUS_MCP_TRACE_BAD_DATA;
6824 
6825                 /* Print current message to results buffer */
6826                 *parsed_results_bytes +=
6827                         sprintf(qed_get_buf_ptr(parsed_buf,
6828                                                 *parsed_results_bytes),
6829                                 "%s %-8s: ",
6830                                 s_mcp_trace_level_str[format_level],
6831                                 meta->modules[format_module]);
6832                 *parsed_results_bytes +=
6833                     sprintf(qed_get_buf_ptr(parsed_buf, *parsed_results_bytes),
6834                             format_ptr->format_str,
6835                             params[0], params[1], params[2]);
6836         }
6837 
6838         /* Add string NULL terminator */
6839         (*parsed_results_bytes)++;
6840 
6841         return status;
6842 }
6843 
6844 /* Parses an MCP Trace dump buffer.
6845  * If result_buf is not NULL, the MCP Trace results are printed to it.
6846  * In any case, the required results buffer size is assigned to
6847  * parsed_results_bytes.
6848  * The parsing status is returned.
6849  */
6850 static enum dbg_status qed_parse_mcp_trace_dump(struct qed_hwfn *p_hwfn,
6851                                                 u32 *dump_buf,
6852                                                 char *results_buf,
6853                                                 u32 *parsed_results_bytes,
6854                                                 bool free_meta_data)
6855 {
6856         const char *section_name, *param_name, *param_str_val;
6857         u32 data_size, trace_data_dwords, trace_meta_dwords;
6858         u32 offset, results_offset, results_buf_bytes;
6859         u32 param_num_val, num_section_params;
6860         struct mcp_trace *trace;
6861         enum dbg_status status;
6862         const u32 *meta_buf;
6863         u8 *trace_buf;
6864 
6865         *parsed_results_bytes = 0;
6866 
6867         /* Read global_params section */
6868         dump_buf += qed_read_section_hdr(dump_buf,
6869                                          &section_name, &num_section_params);
6870         if (strcmp(section_name, "global_params"))
6871                 return DBG_STATUS_MCP_TRACE_BAD_DATA;
6872 
6873         /* Print global params */
6874         dump_buf += qed_print_section_params(dump_buf,
6875                                              num_section_params,
6876                                              results_buf, &results_offset);
6877 
6878         /* Read trace_data section */
6879         dump_buf += qed_read_section_hdr(dump_buf,
6880                                          &section_name, &num_section_params);
6881         if (strcmp(section_name, "mcp_trace_data") || num_section_params != 1)
6882                 return DBG_STATUS_MCP_TRACE_BAD_DATA;
6883         dump_buf += qed_read_param(dump_buf,
6884                                    &param_name, &param_str_val, &param_num_val);
6885         if (strcmp(param_name, "size"))
6886                 return DBG_STATUS_MCP_TRACE_BAD_DATA;
6887         trace_data_dwords = param_num_val;
6888 
6889         /* Prepare trace info */
6890         trace = (struct mcp_trace *)dump_buf;
6891         if (trace->signature != MFW_TRACE_SIGNATURE || !trace->size)
6892                 return DBG_STATUS_MCP_TRACE_BAD_DATA;
6893 
6894         trace_buf = (u8 *)dump_buf + sizeof(*trace);
6895         offset = trace->trace_oldest;
6896         data_size = qed_cyclic_sub(trace->trace_prod, offset, trace->size);
6897         dump_buf += trace_data_dwords;
6898 
6899         /* Read meta_data section */
6900         dump_buf += qed_read_section_hdr(dump_buf,
6901                                          &section_name, &num_section_params);
6902         if (strcmp(section_name, "mcp_trace_meta"))
6903                 return DBG_STATUS_MCP_TRACE_BAD_DATA;
6904         dump_buf += qed_read_param(dump_buf,
6905                                    &param_name, &param_str_val, &param_num_val);
6906         if (strcmp(param_name, "size"))
6907                 return DBG_STATUS_MCP_TRACE_BAD_DATA;
6908         trace_meta_dwords = param_num_val;
6909 
6910         /* Choose meta data buffer */
6911         if (!trace_meta_dwords) {
6912                 /* Dump doesn't include meta data */
6913                 struct dbg_tools_user_data *dev_user_data =
6914                         qed_dbg_get_user_data(p_hwfn);
6915 
6916                 if (!dev_user_data->mcp_trace_user_meta_buf)
6917                         return DBG_STATUS_MCP_TRACE_NO_META;
6918 
6919                 meta_buf = dev_user_data->mcp_trace_user_meta_buf;
6920         } else {
6921                 /* Dump includes meta data */
6922                 meta_buf = dump_buf;
6923         }
6924 
6925         /* Allocate meta data memory */
6926         status = qed_mcp_trace_alloc_meta_data(p_hwfn, meta_buf);
6927         if (status != DBG_STATUS_OK)
6928                 return status;
6929 
6930         status = qed_parse_mcp_trace_buf(p_hwfn,
6931                                          trace_buf,
6932                                          trace->size,
6933                                          offset,
6934                                          data_size,
6935                                          results_buf ?
6936                                          results_buf + results_offset :
6937                                          NULL,
6938                                          &results_buf_bytes);
6939         if (status != DBG_STATUS_OK)
6940                 return status;
6941 
6942         if (free_meta_data)
6943                 qed_mcp_trace_free_meta_data(p_hwfn);
6944 
6945         *parsed_results_bytes = results_offset + results_buf_bytes;
6946 
6947         return DBG_STATUS_OK;
6948 }
6949 
6950 /* Parses a Reg FIFO dump buffer.
6951  * If result_buf is not NULL, the Reg FIFO results are printed to it.
6952  * In any case, the required results buffer size is assigned to
6953  * parsed_results_bytes.
6954  * The parsing status is returned.
6955  */
6956 static enum dbg_status qed_parse_reg_fifo_dump(u32 *dump_buf,
6957                                                char *results_buf,
6958                                                u32 *parsed_results_bytes)
6959 {
6960         const char *section_name, *param_name, *param_str_val;
6961         u32 param_num_val, num_section_params, num_elements;
6962         struct reg_fifo_element *elements;
6963         u8 i, j, err_val, vf_val;
6964         u32 results_offset = 0;
6965         char vf_str[4];
6966 
6967         /* Read global_params section */
6968         dump_buf += qed_read_section_hdr(dump_buf,
6969                                          &section_name, &num_section_params);
6970         if (strcmp(section_name, "global_params"))
6971                 return DBG_STATUS_REG_FIFO_BAD_DATA;
6972 
6973         /* Print global params */
6974         dump_buf += qed_print_section_params(dump_buf,
6975                                              num_section_params,
6976                                              results_buf, &results_offset);
6977 
6978         /* Read reg_fifo_data section */
6979         dump_buf += qed_read_section_hdr(dump_buf,
6980                                          &section_name, &num_section_params);
6981         if (strcmp(section_name, "reg_fifo_data"))
6982                 return DBG_STATUS_REG_FIFO_BAD_DATA;
6983         dump_buf += qed_read_param(dump_buf,
6984                                    &param_name, &param_str_val, &param_num_val);
6985         if (strcmp(param_name, "size"))
6986                 return DBG_STATUS_REG_FIFO_BAD_DATA;
6987         if (param_num_val % REG_FIFO_ELEMENT_DWORDS)
6988                 return DBG_STATUS_REG_FIFO_BAD_DATA;
6989         num_elements = param_num_val / REG_FIFO_ELEMENT_DWORDS;
6990         elements = (struct reg_fifo_element *)dump_buf;
6991 
6992         /* Decode elements */
6993         for (i = 0; i < num_elements; i++) {
6994                 bool err_printed = false;
6995 
6996                 /* Discover if element belongs to a VF or a PF */
6997                 vf_val = GET_FIELD(elements[i].data, REG_FIFO_ELEMENT_VF);
6998                 if (vf_val == REG_FIFO_ELEMENT_IS_PF_VF_VAL)
6999                         sprintf(vf_str, "%s", "N/A");
7000                 else
7001                         sprintf(vf_str, "%d", vf_val);
7002 
7003                 /* Add parsed element to parsed buffer */
7004                 results_offset +=
7005                     sprintf(qed_get_buf_ptr(results_buf,
7006                                             results_offset),
7007                             "raw: 0x%016llx, address: 0x%07x, access: %-5s, pf: %2d, vf: %s, port: %d, privilege: %-3s, protection: %-12s, master: %-4s, errors: ",
7008                             elements[i].data,
7009                             (u32)GET_FIELD(elements[i].data,
7010                                            REG_FIFO_ELEMENT_ADDRESS) *
7011                             REG_FIFO_ELEMENT_ADDR_FACTOR,
7012                             s_access_strs[GET_FIELD(elements[i].data,
7013                                                     REG_FIFO_ELEMENT_ACCESS)],
7014                             (u32)GET_FIELD(elements[i].data,
7015                                            REG_FIFO_ELEMENT_PF),
7016                             vf_str,
7017                             (u32)GET_FIELD(elements[i].data,
7018                                            REG_FIFO_ELEMENT_PORT),
7019                             s_privilege_strs[GET_FIELD(elements[i].data,
7020                                                 REG_FIFO_ELEMENT_PRIVILEGE)],
7021                             s_protection_strs[GET_FIELD(elements[i].data,
7022                                                 REG_FIFO_ELEMENT_PROTECTION)],
7023                             s_master_strs[GET_FIELD(elements[i].data,
7024                                                 REG_FIFO_ELEMENT_MASTER)]);
7025 
7026                 /* Print errors */
7027                 for (j = 0,
7028                      err_val = GET_FIELD(elements[i].data,
7029                                          REG_FIFO_ELEMENT_ERROR);
7030                      j < ARRAY_SIZE(s_reg_fifo_error_strs);
7031                      j++, err_val >>= 1) {
7032                         if (err_val & 0x1) {
7033                                 if (err_printed)
7034                                         results_offset +=
7035                                             sprintf(qed_get_buf_ptr
7036                                                     (results_buf,
7037                                                      results_offset), ", ");
7038                                 results_offset +=
7039                                     sprintf(qed_get_buf_ptr
7040                                             (results_buf, results_offset), "%s",
7041                                             s_reg_fifo_error_strs[j]);
7042                                 err_printed = true;
7043                         }
7044                 }
7045 
7046                 results_offset +=
7047                     sprintf(qed_get_buf_ptr(results_buf, results_offset), "\n");
7048         }
7049 
7050         results_offset += sprintf(qed_get_buf_ptr(results_buf,
7051                                                   results_offset),
7052                                   "fifo contained %d elements", num_elements);
7053 
7054         /* Add 1 for string NULL termination */
7055         *parsed_results_bytes = results_offset + 1;
7056 
7057         return DBG_STATUS_OK;
7058 }
7059 
7060 static enum dbg_status qed_parse_igu_fifo_element(struct igu_fifo_element
7061                                                   *element, char
7062                                                   *results_buf,
7063                                                   u32 *results_offset)
7064 {
7065         const struct igu_fifo_addr_data *found_addr = NULL;
7066         u8 source, err_type, i, is_cleanup;
7067         char parsed_addr_data[32];
7068         char parsed_wr_data[256];
7069         u32 wr_data, prod_cons;
7070         bool is_wr_cmd, is_pf;
7071         u16 cmd_addr;
7072         u64 dword12;
7073 
7074         /* Dword12 (dword index 1 and 2) contains bits 32..95 of the
7075          * FIFO element.
7076          */
7077         dword12 = ((u64)element->dword2 << 32) | element->dword1;
7078         is_wr_cmd = GET_FIELD(dword12, IGU_FIFO_ELEMENT_DWORD12_IS_WR_CMD);
7079         is_pf = GET_FIELD(element->dword0, IGU_FIFO_ELEMENT_DWORD0_IS_PF);
7080         cmd_addr = GET_FIELD(element->dword0, IGU_FIFO_ELEMENT_DWORD0_CMD_ADDR);
7081         source = GET_FIELD(element->dword0, IGU_FIFO_ELEMENT_DWORD0_SOURCE);
7082         err_type = GET_FIELD(element->dword0, IGU_FIFO_ELEMENT_DWORD0_ERR_TYPE);
7083 
7084         if (source >= ARRAY_SIZE(s_igu_fifo_source_strs))
7085                 return DBG_STATUS_IGU_FIFO_BAD_DATA;
7086         if (err_type >= ARRAY_SIZE(s_igu_fifo_error_strs))
7087                 return DBG_STATUS_IGU_FIFO_BAD_DATA;
7088 
7089         /* Find address data */
7090         for (i = 0; i < ARRAY_SIZE(s_igu_fifo_addr_data) && !found_addr; i++) {
7091                 const struct igu_fifo_addr_data *curr_addr =
7092                         &s_igu_fifo_addr_data[i];
7093 
7094                 if (cmd_addr >= curr_addr->start_addr && cmd_addr <=
7095                     curr_addr->end_addr)
7096                         found_addr = curr_addr;
7097         }
7098 
7099         if (!found_addr)
7100                 return DBG_STATUS_IGU_FIFO_BAD_DATA;
7101 
7102         /* Prepare parsed address data */
7103         switch (found_addr->type) {
7104         case IGU_ADDR_TYPE_MSIX_MEM:
7105                 sprintf(parsed_addr_data, " vector_num = 0x%x", cmd_addr / 2);
7106                 break;
7107         case IGU_ADDR_TYPE_WRITE_INT_ACK:
7108         case IGU_ADDR_TYPE_WRITE_PROD_UPDATE:
7109                 sprintf(parsed_addr_data,
7110                         " SB = 0x%x", cmd_addr - found_addr->start_addr);
7111                 break;
7112         default:
7113                 parsed_addr_data[0] = '\0';
7114         }
7115 
7116         if (!is_wr_cmd) {
7117                 parsed_wr_data[0] = '\0';
7118                 goto out;
7119         }
7120 
7121         /* Prepare parsed write data */
7122         wr_data = GET_FIELD(dword12, IGU_FIFO_ELEMENT_DWORD12_WR_DATA);
7123         prod_cons = GET_FIELD(wr_data, IGU_FIFO_WR_DATA_PROD_CONS);
7124         is_cleanup = GET_FIELD(wr_data, IGU_FIFO_WR_DATA_CMD_TYPE);
7125 
7126         if (source == IGU_SRC_ATTN) {
7127                 sprintf(parsed_wr_data, "prod: 0x%x, ", prod_cons);
7128         } else {
7129                 if (is_cleanup) {
7130                         u8 cleanup_val, cleanup_type;
7131 
7132                         cleanup_val =
7133                                 GET_FIELD(wr_data,
7134                                           IGU_FIFO_CLEANUP_WR_DATA_CLEANUP_VAL);
7135                         cleanup_type =
7136                             GET_FIELD(wr_data,
7137                                       IGU_FIFO_CLEANUP_WR_DATA_CLEANUP_TYPE);
7138 
7139                         sprintf(parsed_wr_data,
7140                                 "cmd_type: cleanup, cleanup_val: %s, cleanup_type : %d, ",
7141                                 cleanup_val ? "set" : "clear",
7142                                 cleanup_type);
7143                 } else {
7144                         u8 update_flag, en_dis_int_for_sb, segment;
7145                         u8 timer_mask;
7146 
7147                         update_flag = GET_FIELD(wr_data,
7148                                                 IGU_FIFO_WR_DATA_UPDATE_FLAG);
7149                         en_dis_int_for_sb =
7150                                 GET_FIELD(wr_data,
7151                                           IGU_FIFO_WR_DATA_EN_DIS_INT_FOR_SB);
7152                         segment = GET_FIELD(wr_data,
7153                                             IGU_FIFO_WR_DATA_SEGMENT);
7154                         timer_mask = GET_FIELD(wr_data,
7155                                                IGU_FIFO_WR_DATA_TIMER_MASK);
7156 
7157                         sprintf(parsed_wr_data,
7158                                 "cmd_type: prod/cons update, prod/cons: 0x%x, update_flag: %s, en_dis_int_for_sb : %s, segment : %s, timer_mask = %d, ",
7159                                 prod_cons,
7160                                 update_flag ? "update" : "nop",
7161                                 en_dis_int_for_sb ?
7162                                 (en_dis_int_for_sb == 1 ? "disable" : "nop") :
7163                                 "enable",
7164                                 segment ? "attn" : "regular",
7165                                 timer_mask);
7166                 }
7167         }
7168 out:
7169         /* Add parsed element to parsed buffer */
7170         *results_offset += sprintf(qed_get_buf_ptr(results_buf,
7171                                                    *results_offset),
7172                                    "raw: 0x%01x%08x%08x, %s: %d, source : %s, type : %s, cmd_addr : 0x%x(%s%s), %serror: %s\n",
7173                                    element->dword2, element->dword1,
7174                                    element->dword0,
7175                                    is_pf ? "pf" : "vf",
7176                                    GET_FIELD(element->dword0,
7177                                              IGU_FIFO_ELEMENT_DWORD0_FID),
7178                                    s_igu_fifo_source_strs[source],
7179                                    is_wr_cmd ? "wr" : "rd",
7180                                    cmd_addr,
7181                                    (!is_pf && found_addr->vf_desc)
7182                                    ? found_addr->vf_desc
7183                                    : found_addr->desc,
7184                                    parsed_addr_data,
7185                                    parsed_wr_data,
7186                                    s_igu_fifo_error_strs[err_type]);
7187 
7188         return DBG_STATUS_OK;
7189 }
7190 
7191 /* Parses an IGU FIFO dump buffer.
7192  * If result_buf is not NULL, the IGU FIFO results are printed to it.
7193  * In any case, the required results buffer size is assigned to
7194  * parsed_results_bytes.
7195  * The parsing status is returned.
7196  */
7197 static enum dbg_status qed_parse_igu_fifo_dump(u32 *dump_buf,
7198                                                char *results_buf,
7199                                                u32 *parsed_results_bytes)
7200 {
7201         const char *section_name, *param_name, *param_str_val;
7202         u32 param_num_val, num_section_params, num_elements;
7203         struct igu_fifo_element *elements;
7204         enum dbg_status status;
7205         u32 results_offset = 0;
7206         u8 i;
7207 
7208         /* Read global_params section */
7209         dump_buf += qed_read_section_hdr(dump_buf,
7210                                          &section_name, &num_section_params);
7211         if (strcmp(section_name, "global_params"))
7212                 return DBG_STATUS_IGU_FIFO_BAD_DATA;
7213 
7214         /* Print global params */
7215         dump_buf += qed_print_section_params(dump_buf,
7216                                              num_section_params,
7217                                              results_buf, &results_offset);
7218 
7219         /* Read igu_fifo_data section */
7220         dump_buf += qed_read_section_hdr(dump_buf,
7221                                          &section_name, &num_section_params);
7222         if (strcmp(section_name, "igu_fifo_data"))
7223                 return DBG_STATUS_IGU_FIFO_BAD_DATA;
7224         dump_buf += qed_read_param(dump_buf,
7225                                    &param_name, &param_str_val, &param_num_val);
7226         if (strcmp(param_name, "size"))
7227                 return DBG_STATUS_IGU_FIFO_BAD_DATA;
7228         if (param_num_val % IGU_FIFO_ELEMENT_DWORDS)
7229                 return DBG_STATUS_IGU_FIFO_BAD_DATA;
7230         num_elements = param_num_val / IGU_FIFO_ELEMENT_DWORDS;
7231         elements = (struct igu_fifo_element *)dump_buf;
7232 
7233         /* Decode elements */
7234         for (i = 0; i < num_elements; i++) {
7235                 status = qed_parse_igu_fifo_element(&elements[i],
7236                                                     results_buf,
7237                                                     &results_offset);
7238                 if (status != DBG_STATUS_OK)
7239                         return status;
7240         }
7241 
7242         results_offset += sprintf(qed_get_buf_ptr(results_buf,
7243                                                   results_offset),
7244                                   "fifo contained %d elements", num_elements);
7245 
7246         /* Add 1 for string NULL termination */
7247         *parsed_results_bytes = results_offset + 1;
7248 
7249         return DBG_STATUS_OK;
7250 }
7251 
7252 static enum dbg_status
7253 qed_parse_protection_override_dump(u32 *dump_buf,
7254                                    char *results_buf,
7255                                    u32 *parsed_results_bytes)
7256 {
7257         const char *section_name, *param_name, *param_str_val;
7258         u32 param_num_val, num_section_params, num_elements;
7259         struct protection_override_element *elements;
7260         u32 results_offset = 0;
7261         u8 i;
7262 
7263         /* Read global_params section */
7264         dump_buf += qed_read_section_hdr(dump_buf,
7265                                          &section_name, &num_section_params);
7266         if (strcmp(section_name, "global_params"))
7267                 return DBG_STATUS_PROTECTION_OVERRIDE_BAD_DATA;
7268 
7269         /* Print global params */
7270         dump_buf += qed_print_section_params(dump_buf,
7271                                              num_section_params,
7272                                              results_buf, &results_offset);
7273 
7274         /* Read protection_override_data section */
7275         dump_buf += qed_read_section_hdr(dump_buf,
7276                                          &section_name, &num_section_params);
7277         if (strcmp(section_name, "protection_override_data"))
7278                 return DBG_STATUS_PROTECTION_OVERRIDE_BAD_DATA;
7279         dump_buf += qed_read_param(dump_buf,
7280                                    &param_name, &param_str_val, &param_num_val);
7281         if (strcmp(param_name, "size"))
7282                 return DBG_STATUS_PROTECTION_OVERRIDE_BAD_DATA;
7283         if (param_num_val % PROTECTION_OVERRIDE_ELEMENT_DWORDS)
7284                 return DBG_STATUS_PROTECTION_OVERRIDE_BAD_DATA;
7285         num_elements = param_num_val / PROTECTION_OVERRIDE_ELEMENT_DWORDS;
7286         elements = (struct protection_override_element *)dump_buf;
7287 
7288         /* Decode elements */
7289         for (i = 0; i < num_elements; i++) {
7290                 u32 address = GET_FIELD(elements[i].data,
7291                                         PROTECTION_OVERRIDE_ELEMENT_ADDRESS) *
7292                               PROTECTION_OVERRIDE_ELEMENT_ADDR_FACTOR;
7293 
7294                 results_offset +=
7295                     sprintf(qed_get_buf_ptr(results_buf,
7296                                             results_offset),
7297                             "window %2d, address: 0x%07x, size: %7d regs, read: %d, write: %d, read protection: %-12s, write protection: %-12s\n",
7298                             i, address,
7299                             (u32)GET_FIELD(elements[i].data,
7300                                       PROTECTION_OVERRIDE_ELEMENT_WINDOW_SIZE),
7301                             (u32)GET_FIELD(elements[i].data,
7302                                       PROTECTION_OVERRIDE_ELEMENT_READ),
7303                             (u32)GET_FIELD(elements[i].data,
7304                                       PROTECTION_OVERRIDE_ELEMENT_WRITE),
7305                             s_protection_strs[GET_FIELD(elements[i].data,
7306                                 PROTECTION_OVERRIDE_ELEMENT_READ_PROTECTION)],
7307                             s_protection_strs[GET_FIELD(elements[i].data,
7308                                 PROTECTION_OVERRIDE_ELEMENT_WRITE_PROTECTION)]);
7309         }
7310 
7311         results_offset += sprintf(qed_get_buf_ptr(results_buf,
7312                                                   results_offset),
7313                                   "protection override contained %d elements",
7314                                   num_elements);
7315 
7316         /* Add 1 for string NULL termination */
7317         *parsed_results_bytes = results_offset + 1;
7318 
7319         return DBG_STATUS_OK;
7320 }
7321 
7322 /* Parses a FW Asserts dump buffer.
7323  * If result_buf is not NULL, the FW Asserts results are printed to it.
7324  * In any case, the required results buffer size is assigned to
7325  * parsed_results_bytes.
7326  * The parsing status is returned.
7327  */
7328 static enum dbg_status qed_parse_fw_asserts_dump(u32 *dump_buf,
7329                                                  char *results_buf,
7330                                                  u32 *parsed_results_bytes)
7331 {
7332         u32 num_section_params, param_num_val, i, results_offset = 0;
7333         const char *param_name, *param_str_val, *section_name;
7334         bool last_section_found = false;
7335 
7336         *parsed_results_bytes = 0;
7337 
7338         /* Read global_params section */
7339         dump_buf += qed_read_section_hdr(dump_buf,
7340                                          &section_name, &num_section_params);
7341         if (strcmp(section_name, "global_params"))
7342                 return DBG_STATUS_FW_ASSERTS_PARSE_FAILED;
7343 
7344         /* Print global params */
7345         dump_buf += qed_print_section_params(dump_buf,
7346                                              num_section_params,
7347                                              results_buf, &results_offset);
7348 
7349         while (!last_section_found) {
7350                 dump_buf += qed_read_section_hdr(dump_buf,
7351                                                  &section_name,
7352                                                  &num_section_params);
7353                 if (!strcmp(section_name, "fw_asserts")) {
7354                         /* Extract params */
7355                         const char *storm_letter = NULL;
7356                         u32 storm_dump_size = 0;
7357 
7358                         for (i = 0; i < num_section_params; i++) {
7359                                 dump_buf += qed_read_param(dump_buf,
7360                                                            &param_name,
7361                                                            &param_str_val,
7362                                                            &param_num_val);
7363                                 if (!strcmp(param_name, "storm"))
7364                                         storm_letter = param_str_val;
7365                                 else if (!strcmp(param_name, "size"))
7366                                         storm_dump_size = param_num_val;
7367                                 else
7368                                         return
7369                                             DBG_STATUS_FW_ASSERTS_PARSE_FAILED;
7370                         }
7371 
7372                         if (!storm_letter || !storm_dump_size)
7373                                 return DBG_STATUS_FW_ASSERTS_PARSE_FAILED;
7374 
7375                         /* Print data */
7376                         results_offset +=
7377                             sprintf(qed_get_buf_ptr(results_buf,
7378                                                     results_offset),
7379                                     "\n%sSTORM_ASSERT: size=%d\n",
7380                                     storm_letter, storm_dump_size);
7381                         for (i = 0; i < storm_dump_size; i++, dump_buf++)
7382                                 results_offset +=
7383                                     sprintf(qed_get_buf_ptr(results_buf,
7384                                                             results_offset),
7385                                             "%08x\n", *dump_buf);
7386                 } else if (!strcmp(section_name, "last")) {
7387                         last_section_found = true;
7388                 } else {
7389                         return DBG_STATUS_FW_ASSERTS_PARSE_FAILED;
7390                 }
7391         }
7392 
7393         /* Add 1 for string NULL termination */
7394         *parsed_results_bytes = results_offset + 1;
7395 
7396         return DBG_STATUS_OK;
7397 }
7398 
7399 /***************************** Public Functions *******************************/
7400 
7401 enum dbg_status qed_dbg_user_set_bin_ptr(const u8 * const bin_ptr)
7402 {
7403         struct bin_buffer_hdr *buf_array = (struct bin_buffer_hdr *)bin_ptr;
7404         u8 buf_id;
7405 
7406         /* Convert binary data to debug arrays */
7407         for (buf_id = 0; buf_id < MAX_BIN_DBG_BUFFER_TYPE; buf_id++) {
7408                 s_user_dbg_arrays[buf_id].ptr =
7409                         (u32 *)(bin_ptr + buf_array[buf_id].offset);
7410                 s_user_dbg_arrays[buf_id].size_in_dwords =
7411                         BYTES_TO_DWORDS(buf_array[buf_id].length);
7412         }
7413 
7414         return DBG_STATUS_OK;
7415 }
7416 
7417 enum dbg_status qed_dbg_alloc_user_data(struct qed_hwfn *p_hwfn)
7418 {
7419         p_hwfn->dbg_user_info = kzalloc(sizeof(struct dbg_tools_user_data),
7420                                         GFP_KERNEL);
7421         if (!p_hwfn->dbg_user_info)
7422                 return DBG_STATUS_VIRT_MEM_ALLOC_FAILED;
7423 
7424         return DBG_STATUS_OK;
7425 }
7426 
7427 const char *qed_dbg_get_status_str(enum dbg_status status)
7428 {
7429         return (status <
7430                 MAX_DBG_STATUS) ? s_status_str[status] : "Invalid debug status";
7431 }
7432 
7433 enum dbg_status qed_get_idle_chk_results_buf_size(struct qed_hwfn *p_hwfn,
7434                                                   u32 *dump_buf,
7435                                                   u32 num_dumped_dwords,
7436                                                   u32 *results_buf_size)
7437 {
7438         u32 num_errors, num_warnings;
7439 
7440         return qed_parse_idle_chk_dump(dump_buf,
7441                                        num_dumped_dwords,
7442                                        NULL,
7443                                        results_buf_size,
7444                                        &num_errors, &num_warnings);
7445 }
7446 
7447 enum dbg_status qed_print_idle_chk_results(struct qed_hwfn *p_hwfn,
7448                                            u32 *dump_buf,
7449                                            u32 num_dumped_dwords,
7450                                            char *results_buf,
7451                                            u32 *num_errors,
7452                                            u32 *num_warnings)
7453 {
7454         u32 parsed_buf_size;
7455 
7456         return qed_parse_idle_chk_dump(dump_buf,
7457                                        num_dumped_dwords,
7458                                        results_buf,
7459                                        &parsed_buf_size,
7460                                        num_errors, num_warnings);
7461 }
7462 
7463 void qed_dbg_mcp_trace_set_meta_data(struct qed_hwfn *p_hwfn,
7464                                      const u32 *meta_buf)
7465 {
7466         struct dbg_tools_user_data *dev_user_data =
7467                 qed_dbg_get_user_data(p_hwfn);
7468 
7469         dev_user_data->mcp_trace_user_meta_buf = meta_buf;
7470 }
7471 
7472 enum dbg_status qed_get_mcp_trace_results_buf_size(struct qed_hwfn *p_hwfn,
7473                                                    u32 *dump_buf,
7474                                                    u32 num_dumped_dwords,
7475                                                    u32 *results_buf_size)
7476 {
7477         return qed_parse_mcp_trace_dump(p_hwfn,
7478                                         dump_buf, NULL, results_buf_size, true);
7479 }
7480 
7481 enum dbg_status qed_print_mcp_trace_results(struct qed_hwfn *p_hwfn,
7482                                             u32 *dump_buf,
7483                                             u32 num_dumped_dwords,
7484                                             char *results_buf)
7485 {
7486         u32 parsed_buf_size;
7487 
7488         return qed_parse_mcp_trace_dump(p_hwfn,
7489                                         dump_buf,
7490                                         results_buf, &parsed_buf_size, true);
7491 }
7492 
7493 enum dbg_status qed_print_mcp_trace_results_cont(struct qed_hwfn *p_hwfn,
7494                                                  u32 *dump_buf,
7495                                                  char *results_buf)
7496 {
7497         u32 parsed_buf_size;
7498 
7499         return qed_parse_mcp_trace_dump(p_hwfn, dump_buf, results_buf,
7500                                         &parsed_buf_size, false);
7501 }
7502 
7503 enum dbg_status qed_print_mcp_trace_line(struct qed_hwfn *p_hwfn,
7504                                          u8 *dump_buf,
7505                                          u32 num_dumped_bytes,
7506                                          char *results_buf)
7507 {
7508         u32 parsed_results_bytes;
7509 
7510         return qed_parse_mcp_trace_buf(p_hwfn,
7511                                        dump_buf,
7512                                        num_dumped_bytes,
7513                                        0,
7514                                        num_dumped_bytes,
7515                                        results_buf, &parsed_results_bytes);
7516 }
7517 
7518 /* Frees the specified MCP Trace meta data */
7519 void qed_mcp_trace_free_meta_data(struct qed_hwfn *p_hwfn)
7520 {
7521         struct dbg_tools_user_data *dev_user_data;
7522         struct mcp_trace_meta *meta;
7523         u32 i;
7524 
7525         dev_user_data = qed_dbg_get_user_data(p_hwfn);
7526         meta = &dev_user_data->mcp_trace_meta;
7527         if (!meta->is_allocated)
7528                 return;
7529 
7530         /* Release modules */
7531         if (meta->modules) {
7532                 for (i = 0; i < meta->modules_num; i++)
7533                         kfree(meta->modules[i]);
7534                 kfree(meta->modules);
7535         }
7536 
7537         /* Release formats */
7538         if (meta->formats) {
7539                 for (i = 0; i < meta->formats_num; i++)
7540                         kfree(meta->formats[i].format_str);
7541                 kfree(meta->formats);
7542         }
7543 
7544         meta->is_allocated = false;
7545 }
7546 
7547 enum dbg_status qed_get_reg_fifo_results_buf_size(struct qed_hwfn *p_hwfn,
7548                                                   u32 *dump_buf,
7549                                                   u32 num_dumped_dwords,
7550                                                   u32 *results_buf_size)
7551 {
7552         return qed_parse_reg_fifo_dump(dump_buf, NULL, results_buf_size);
7553 }
7554 
7555 enum dbg_status qed_print_reg_fifo_results(struct qed_hwfn *p_hwfn,
7556                                            u32 *dump_buf,
7557                                            u32 num_dumped_dwords,
7558                                            char *results_buf)
7559 {
7560         u32 parsed_buf_size;
7561 
7562         return qed_parse_reg_fifo_dump(dump_buf, results_buf, &parsed_buf_size);
7563 }
7564 
7565 enum dbg_status qed_get_igu_fifo_results_buf_size(struct qed_hwfn *p_hwfn,
7566                                                   u32 *dump_buf,
7567                                                   u32 num_dumped_dwords,
7568                                                   u32 *results_buf_size)
7569 {
7570         return qed_parse_igu_fifo_dump(dump_buf, NULL, results_buf_size);
7571 }
7572 
7573 enum dbg_status qed_print_igu_fifo_results(struct qed_hwfn *p_hwfn,
7574                                            u32 *dump_buf,
7575                                            u32 num_dumped_dwords,
7576                                            char *results_buf)
7577 {
7578         u32 parsed_buf_size;
7579 
7580         return qed_parse_igu_fifo_dump(dump_buf, results_buf, &parsed_buf_size);
7581 }
7582 
7583 enum dbg_status
7584 qed_get_protection_override_results_buf_size(struct qed_hwfn *p_hwfn,
7585                                              u32 *dump_buf,
7586                                              u32 num_dumped_dwords,
7587                                              u32 *results_buf_size)
7588 {
7589         return qed_parse_protection_override_dump(dump_buf,
7590                                                   NULL, results_buf_size);
7591 }
7592 
7593 enum dbg_status qed_print_protection_override_results(struct qed_hwfn *p_hwfn,
7594                                                       u32 *dump_buf,
7595                                                       u32 num_dumped_dwords,
7596                                                       char *results_buf)
7597 {
7598         u32 parsed_buf_size;
7599 
7600         return qed_parse_protection_override_dump(dump_buf,
7601                                                   results_buf,
7602                                                   &parsed_buf_size);
7603 }
7604 
7605 enum dbg_status qed_get_fw_asserts_results_buf_size(struct qed_hwfn *p_hwfn,
7606                                                     u32 *dump_buf,
7607                                                     u32 num_dumped_dwords,
7608                                                     u32 *results_buf_size)
7609 {
7610         return qed_parse_fw_asserts_dump(dump_buf, NULL, results_buf_size);
7611 }
7612 
7613 enum dbg_status qed_print_fw_asserts_results(struct qed_hwfn *p_hwfn,
7614                                              u32 *dump_buf,
7615                                              u32 num_dumped_dwords,
7616                                              char *results_buf)
7617 {
7618         u32 parsed_buf_size;
7619 
7620         return qed_parse_fw_asserts_dump(dump_buf,
7621                                          results_buf, &parsed_buf_size);
7622 }
7623 
7624 enum dbg_status qed_dbg_parse_attn(struct qed_hwfn *p_hwfn,
7625                                    struct dbg_attn_block_result *results)
7626 {
7627         struct user_dbg_array *block_attn, *pstrings;
7628         const u32 *block_attn_name_offsets;
7629         enum dbg_attn_type attn_type;
7630         const char *block_name;
7631         u8 num_regs, i, j;
7632 
7633         num_regs = GET_FIELD(results->data, DBG_ATTN_BLOCK_RESULT_NUM_REGS);
7634         attn_type = (enum dbg_attn_type)
7635                     GET_FIELD(results->data,
7636                               DBG_ATTN_BLOCK_RESULT_ATTN_TYPE);
7637         block_name = s_block_info_arr[results->block_id].name;
7638 
7639         if (!s_user_dbg_arrays[BIN_BUF_DBG_ATTN_INDEXES].ptr ||
7640             !s_user_dbg_arrays[BIN_BUF_DBG_ATTN_NAME_OFFSETS].ptr ||
7641             !s_user_dbg_arrays[BIN_BUF_DBG_PARSING_STRINGS].ptr)
7642                 return DBG_STATUS_DBG_ARRAY_NOT_SET;
7643 
7644         block_attn = &s_user_dbg_arrays[BIN_BUF_DBG_ATTN_NAME_OFFSETS];
7645         block_attn_name_offsets = &block_attn->ptr[results->names_offset];
7646 
7647         /* Go over registers with a non-zero attention status */
7648         for (i = 0; i < num_regs; i++) {
7649                 struct dbg_attn_bit_mapping *bit_mapping;
7650                 struct dbg_attn_reg_result *reg_result;
7651                 u8 num_reg_attn, bit_idx = 0;
7652 
7653                 reg_result = &results->reg_results[i];
7654                 num_reg_attn = GET_FIELD(reg_result->data,
7655                                          DBG_ATTN_REG_RESULT_NUM_REG_ATTN);
7656                 block_attn = &s_user_dbg_arrays[BIN_BUF_DBG_ATTN_INDEXES];
7657                 bit_mapping = &((struct dbg_attn_bit_mapping *)
7658                                 block_attn->ptr)[reg_result->block_attn_offset];
7659 
7660                 pstrings = &s_user_dbg_arrays[BIN_BUF_DBG_PARSING_STRINGS];
7661 
7662                 /* Go over attention status bits */
7663                 for (j = 0; j < num_reg_attn; j++) {
7664                         u16 attn_idx_val = GET_FIELD(bit_mapping[j].data,
7665                                                      DBG_ATTN_BIT_MAPPING_VAL);
7666                         const char *attn_name, *attn_type_str, *masked_str;
7667                         u32 attn_name_offset, sts_addr;
7668 
7669                         /* Check if bit mask should be advanced (due to unused
7670                          * bits).
7671                          */
7672                         if (GET_FIELD(bit_mapping[j].data,
7673                                       DBG_ATTN_BIT_MAPPING_IS_UNUSED_BIT_CNT)) {
7674                                 bit_idx += (u8)attn_idx_val;
7675                                 continue;
7676                         }
7677 
7678                         /* Check current bit index */
7679                         if (!(reg_result->sts_val & BIT(bit_idx))) {
7680                                 bit_idx++;
7681                                 continue;
7682                         }
7683 
7684                         /* Find attention name */
7685                         attn_name_offset =
7686                                 block_attn_name_offsets[attn_idx_val];
7687                         attn_name = &((const char *)
7688                                       pstrings->ptr)[attn_name_offset];
7689                         attn_type_str = attn_type == ATTN_TYPE_INTERRUPT ?
7690                                         "Interrupt" : "Parity";
7691                         masked_str = reg_result->mask_val & BIT(bit_idx) ?
7692                                      " [masked]" : "";
7693                         sts_addr = GET_FIELD(reg_result->data,
7694                                              DBG_ATTN_REG_RESULT_STS_ADDRESS);
7695                         DP_NOTICE(p_hwfn,
7696                                   "%s (%s) : %s [address 0x%08x, bit %d]%s\n",
7697                                   block_name, attn_type_str, attn_name,
7698                                   sts_addr, bit_idx, masked_str);
7699 
7700                         bit_idx++;
7701                 }
7702         }
7703 
7704         return DBG_STATUS_OK;
7705 }
7706 
7707 /* Wrapper for unifying the idle_chk and mcp_trace api */
7708 static enum dbg_status
7709 qed_print_idle_chk_results_wrapper(struct qed_hwfn *p_hwfn,
7710                                    u32 *dump_buf,
7711                                    u32 num_dumped_dwords,
7712                                    char *results_buf)
7713 {
7714         u32 num_errors, num_warnnings;
7715 
7716         return qed_print_idle_chk_results(p_hwfn, dump_buf, num_dumped_dwords,
7717                                           results_buf, &num_errors,
7718                                           &num_warnnings);
7719 }
7720 
7721 /* Feature meta data lookup table */
7722 static struct {
7723         char *name;
7724         enum dbg_status (*get_size)(struct qed_hwfn *p_hwfn,
7725                                     struct qed_ptt *p_ptt, u32 *size);
7726         enum dbg_status (*perform_dump)(struct qed_hwfn *p_hwfn,
7727                                         struct qed_ptt *p_ptt, u32 *dump_buf,
7728                                         u32 buf_size, u32 *dumped_dwords);
7729         enum dbg_status (*print_results)(struct qed_hwfn *p_hwfn,
7730                                          u32 *dump_buf, u32 num_dumped_dwords,
7731                                          char *results_buf);
7732         enum dbg_status (*results_buf_size)(struct qed_hwfn *p_hwfn,
7733                                             u32 *dump_buf,
7734                                             u32 num_dumped_dwords,
7735                                             u32 *results_buf_size);
7736 } qed_features_lookup[] = {
7737         {
7738         "grc", qed_dbg_grc_get_dump_buf_size,
7739                     qed_dbg_grc_dump, NULL, NULL}, {
7740         "idle_chk",
7741                     qed_dbg_idle_chk_get_dump_buf_size,
7742                     qed_dbg_idle_chk_dump,
7743                     qed_print_idle_chk_results_wrapper,
7744                     qed_get_idle_chk_results_buf_size}, {
7745         "mcp_trace",
7746                     qed_dbg_mcp_trace_get_dump_buf_size,
7747                     qed_dbg_mcp_trace_dump, qed_print_mcp_trace_results,
7748                     qed_get_mcp_trace_results_buf_size}, {
7749         "reg_fifo",
7750                     qed_dbg_reg_fifo_get_dump_buf_size,
7751                     qed_dbg_reg_fifo_dump, qed_print_reg_fifo_results,
7752                     qed_get_reg_fifo_results_buf_size}, {
7753         "igu_fifo",
7754                     qed_dbg_igu_fifo_get_dump_buf_size,
7755                     qed_dbg_igu_fifo_dump, qed_print_igu_fifo_results,
7756                     qed_get_igu_fifo_results_buf_size}, {
7757         "protection_override",
7758                     qed_dbg_protection_override_get_dump_buf_size,
7759                     qed_dbg_protection_override_dump,
7760                     qed_print_protection_override_results,
7761                     qed_get_protection_override_results_buf_size}, {
7762         "fw_asserts",
7763                     qed_dbg_fw_asserts_get_dump_buf_size,
7764                     qed_dbg_fw_asserts_dump,
7765                     qed_print_fw_asserts_results,
7766                     qed_get_fw_asserts_results_buf_size},};
7767 
7768 static void qed_dbg_print_feature(u8 *p_text_buf, u32 text_size)
7769 {
7770         u32 i, precision = 80;
7771 
7772         if (!p_text_buf)
7773                 return;
7774 
7775         pr_notice("\n%.*s", precision, p_text_buf);
7776         for (i = precision; i < text_size; i += precision)
7777                 pr_cont("%.*s", precision, p_text_buf + i);
7778         pr_cont("\n");
7779 }
7780 
7781 #define QED_RESULTS_BUF_MIN_SIZE 16
7782 /* Generic function for decoding debug feature info */
7783 static enum dbg_status format_feature(struct qed_hwfn *p_hwfn,
7784                                       enum qed_dbg_features feature_idx)
7785 {
7786         struct qed_dbg_feature *feature =
7787             &p_hwfn->cdev->dbg_params.features[feature_idx];
7788         u32 text_size_bytes, null_char_pos, i;
7789         enum dbg_status rc;
7790         char *text_buf;
7791 
7792         /* Check if feature supports formatting capability */
7793         if (!qed_features_lookup[feature_idx].results_buf_size)
7794                 return DBG_STATUS_OK;
7795 
7796         /* Obtain size of formatted output */
7797         rc = qed_features_lookup[feature_idx].
7798                 results_buf_size(p_hwfn, (u32 *)feature->dump_buf,
7799                                  feature->dumped_dwords, &text_size_bytes);
7800         if (rc != DBG_STATUS_OK)
7801                 return rc;
7802 
7803         /* Make sure that the allocated size is a multiple of dword (4 bytes) */
7804         null_char_pos = text_size_bytes - 1;
7805         text_size_bytes = (text_size_bytes + 3) & ~0x3;
7806 
7807         if (text_size_bytes < QED_RESULTS_BUF_MIN_SIZE) {
7808                 DP_NOTICE(p_hwfn->cdev,
7809                           "formatted size of feature was too small %d. Aborting\n",
7810                           text_size_bytes);
7811                 return DBG_STATUS_INVALID_ARGS;
7812         }
7813 
7814         /* Allocate temp text buf */
7815         text_buf = vzalloc(text_size_bytes);
7816         if (!text_buf)
7817                 return DBG_STATUS_VIRT_MEM_ALLOC_FAILED;
7818 
7819         /* Decode feature opcodes to string on temp buf */
7820         rc = qed_features_lookup[feature_idx].
7821                 print_results(p_hwfn, (u32 *)feature->dump_buf,
7822                               feature->dumped_dwords, text_buf);
7823         if (rc != DBG_STATUS_OK) {
7824                 vfree(text_buf);
7825                 return rc;
7826         }
7827 
7828         /* Replace the original null character with a '\n' character.
7829          * The bytes that were added as a result of the dword alignment are also
7830          * padded with '\n' characters.
7831          */
7832         for (i = null_char_pos; i < text_size_bytes; i++)
7833                 text_buf[i] = '\n';
7834 
7835         /* Dump printable feature to log */
7836         if (p_hwfn->cdev->dbg_params.print_data)
7837                 qed_dbg_print_feature(text_buf, text_size_bytes);
7838 
7839         /* Free the old dump_buf and point the dump_buf to the newly allocagted
7840          * and formatted text buffer.
7841          */
7842         vfree(feature->dump_buf);
7843         feature->dump_buf = text_buf;
7844         feature->buf_size = text_size_bytes;
7845         feature->dumped_dwords = text_size_bytes / 4;
7846         return rc;
7847 }
7848 
7849 /* Generic function for performing the dump of a debug feature. */
7850 static enum dbg_status qed_dbg_dump(struct qed_hwfn *p_hwfn,
7851                                     struct qed_ptt *p_ptt,
7852                                     enum qed_dbg_features feature_idx)
7853 {
7854         struct qed_dbg_feature *feature =
7855             &p_hwfn->cdev->dbg_params.features[feature_idx];
7856         u32 buf_size_dwords;
7857         enum dbg_status rc;
7858 
7859         DP_NOTICE(p_hwfn->cdev, "Collecting a debug feature [\"%s\"]\n",
7860                   qed_features_lookup[feature_idx].name);
7861 
7862         /* Dump_buf was already allocated need to free (this can happen if dump
7863          * was called but file was never read).
7864          * We can't use the buffer as is since size may have changed.
7865          */
7866         if (feature->dump_buf) {
7867                 vfree(feature->dump_buf);
7868                 feature->dump_buf = NULL;
7869         }
7870 
7871         /* Get buffer size from hsi, allocate accordingly, and perform the
7872          * dump.
7873          */
7874         rc = qed_features_lookup[feature_idx].get_size(p_hwfn, p_ptt,
7875                                                        &buf_size_dwords);
7876         if (rc != DBG_STATUS_OK && rc != DBG_STATUS_NVRAM_GET_IMAGE_FAILED)
7877                 return rc;
7878         feature->buf_size = buf_size_dwords * sizeof(u32);
7879         feature->dump_buf = vmalloc(feature->buf_size);
7880         if (!feature->dump_buf)
7881                 return DBG_STATUS_VIRT_MEM_ALLOC_FAILED;
7882 
7883         rc = qed_features_lookup[feature_idx].
7884                 perform_dump(p_hwfn, p_ptt, (u32 *)feature->dump_buf,
7885                              feature->buf_size / sizeof(u32),
7886                              &feature->dumped_dwords);
7887 
7888         /* If mcp is stuck we get DBG_STATUS_NVRAM_GET_IMAGE_FAILED error.
7889          * In this case the buffer holds valid binary data, but we wont able
7890          * to parse it (since parsing relies on data in NVRAM which is only
7891          * accessible when MFW is responsive). skip the formatting but return
7892          * success so that binary data is provided.
7893          */
7894         if (rc == DBG_STATUS_NVRAM_GET_IMAGE_FAILED)
7895                 return DBG_STATUS_OK;
7896 
7897         if (rc != DBG_STATUS_OK)
7898                 return rc;
7899 
7900         /* Format output */
7901         rc = format_feature(p_hwfn, feature_idx);
7902         return rc;
7903 }
7904 
7905 int qed_dbg_grc(struct qed_dev *cdev, void *buffer, u32 *num_dumped_bytes)
7906 {
7907         return qed_dbg_feature(cdev, buffer, DBG_FEATURE_GRC, num_dumped_bytes);
7908 }
7909 
7910 int qed_dbg_grc_size(struct qed_dev *cdev)
7911 {
7912         return qed_dbg_feature_size(cdev, DBG_FEATURE_GRC);
7913 }
7914 
7915 int qed_dbg_idle_chk(struct qed_dev *cdev, void *buffer, u32 *num_dumped_bytes)
7916 {
7917         return qed_dbg_feature(cdev, buffer, DBG_FEATURE_IDLE_CHK,
7918                                num_dumped_bytes);
7919 }
7920 
7921 int qed_dbg_idle_chk_size(struct qed_dev *cdev)
7922 {
7923         return qed_dbg_feature_size(cdev, DBG_FEATURE_IDLE_CHK);
7924 }
7925 
7926 int qed_dbg_reg_fifo(struct qed_dev *cdev, void *buffer, u32 *num_dumped_bytes)
7927 {
7928         return qed_dbg_feature(cdev, buffer, DBG_FEATURE_REG_FIFO,
7929                                num_dumped_bytes);
7930 }
7931 
7932 int qed_dbg_reg_fifo_size(struct qed_dev *cdev)
7933 {
7934         return qed_dbg_feature_size(cdev, DBG_FEATURE_REG_FIFO);
7935 }
7936 
7937 int qed_dbg_igu_fifo(struct qed_dev *cdev, void *buffer, u32 *num_dumped_bytes)
7938 {
7939         return qed_dbg_feature(cdev, buffer, DBG_FEATURE_IGU_FIFO,
7940                                num_dumped_bytes);
7941 }
7942 
7943 int qed_dbg_igu_fifo_size(struct qed_dev *cdev)
7944 {
7945         return qed_dbg_feature_size(cdev, DBG_FEATURE_IGU_FIFO);
7946 }
7947 
7948 static int qed_dbg_nvm_image_length(struct qed_hwfn *p_hwfn,
7949                                     enum qed_nvm_images image_id, u32 *length)
7950 {
7951         struct qed_nvm_image_att image_att;
7952         int rc;
7953 
7954         *length = 0;
7955         rc = qed_mcp_get_nvm_image_att(p_hwfn, image_id, &image_att);
7956         if (rc)
7957                 return rc;
7958 
7959         *length = image_att.length;
7960 
7961         return rc;
7962 }
7963 
7964 static int qed_dbg_nvm_image(struct qed_dev *cdev, void *buffer,
7965                              u32 *num_dumped_bytes,
7966                              enum qed_nvm_images image_id)
7967 {
7968         struct qed_hwfn *p_hwfn =
7969                 &cdev->hwfns[cdev->dbg_params.engine_for_debug];
7970         u32 len_rounded, i;
7971         __be32 val;
7972         int rc;
7973 
7974         *num_dumped_bytes = 0;
7975         rc = qed_dbg_nvm_image_length(p_hwfn, image_id, &len_rounded);
7976         if (rc)
7977                 return rc;
7978 
7979         DP_NOTICE(p_hwfn->cdev,
7980                   "Collecting a debug feature [\"nvram image %d\"]\n",
7981                   image_id);
7982 
7983         len_rounded = roundup(len_rounded, sizeof(u32));
7984         rc = qed_mcp_get_nvm_image(p_hwfn, image_id, buffer, len_rounded);
7985         if (rc)
7986                 return rc;
7987 
7988         /* QED_NVM_IMAGE_NVM_META image is not swapped like other images */
7989         if (image_id != QED_NVM_IMAGE_NVM_META)
7990                 for (i = 0; i < len_rounded; i += 4) {
7991                         val = cpu_to_be32(*(u32 *)(buffer + i));
7992                         *(u32 *)(buffer + i) = val;
7993                 }
7994 
7995         *num_dumped_bytes = len_rounded;
7996 
7997         return rc;
7998 }
7999 
8000 int qed_dbg_protection_override(struct qed_dev *cdev, void *buffer,
8001                                 u32 *num_dumped_bytes)
8002 {
8003         return qed_dbg_feature(cdev, buffer, DBG_FEATURE_PROTECTION_OVERRIDE,
8004                                num_dumped_bytes);
8005 }
8006 
8007 int qed_dbg_protection_override_size(struct qed_dev *cdev)
8008 {
8009         return qed_dbg_feature_size(cdev, DBG_FEATURE_PROTECTION_OVERRIDE);
8010 }
8011 
8012 int qed_dbg_fw_asserts(struct qed_dev *cdev, void *buffer,
8013                        u32 *num_dumped_bytes)
8014 {
8015         return qed_dbg_feature(cdev, buffer, DBG_FEATURE_FW_ASSERTS,
8016                                num_dumped_bytes);
8017 }
8018 
8019 int qed_dbg_fw_asserts_size(struct qed_dev *cdev)
8020 {
8021         return qed_dbg_feature_size(cdev, DBG_FEATURE_FW_ASSERTS);
8022 }
8023 
8024 int qed_dbg_mcp_trace(struct qed_dev *cdev, void *buffer,
8025                       u32 *num_dumped_bytes)
8026 {
8027         return qed_dbg_feature(cdev, buffer, DBG_FEATURE_MCP_TRACE,
8028                                num_dumped_bytes);
8029 }
8030 
8031 int qed_dbg_mcp_trace_size(struct qed_dev *cdev)
8032 {
8033         return qed_dbg_feature_size(cdev, DBG_FEATURE_MCP_TRACE);
8034 }
8035 
8036 /* Defines the amount of bytes allocated for recording the length of debugfs
8037  * feature buffer.
8038  */
8039 #define REGDUMP_HEADER_SIZE                     sizeof(u32)
8040 #define REGDUMP_HEADER_FEATURE_SHIFT            24
8041 #define REGDUMP_HEADER_ENGINE_SHIFT             31
8042 #define REGDUMP_HEADER_OMIT_ENGINE_SHIFT        30
8043 enum debug_print_features {
8044         OLD_MODE = 0,
8045         IDLE_CHK = 1,
8046         GRC_DUMP = 2,
8047         MCP_TRACE = 3,
8048         REG_FIFO = 4,
8049         PROTECTION_OVERRIDE = 5,
8050         IGU_FIFO = 6,
8051         PHY = 7,
8052         FW_ASSERTS = 8,
8053         NVM_CFG1 = 9,
8054         DEFAULT_CFG = 10,
8055         NVM_META = 11,
8056 };
8057 
8058 static u32 qed_calc_regdump_header(enum debug_print_features feature,
8059                                    int engine, u32 feature_size, u8 omit_engine)
8060 {
8061         /* Insert the engine, feature and mode inside the header and combine it
8062          * with feature size.
8063          */
8064         return feature_size | (feature << REGDUMP_HEADER_FEATURE_SHIFT) |
8065                (omit_engine << REGDUMP_HEADER_OMIT_ENGINE_SHIFT) |
8066                (engine << REGDUMP_HEADER_ENGINE_SHIFT);
8067 }
8068 
8069 int qed_dbg_all_data(struct qed_dev *cdev, void *buffer)
8070 {
8071         u8 cur_engine, omit_engine = 0, org_engine;
8072         struct qed_hwfn *p_hwfn =
8073                 &cdev->hwfns[cdev->dbg_params.engine_for_debug];
8074         struct dbg_tools_data *dev_data = &p_hwfn->dbg_info;
8075         int grc_params[MAX_DBG_GRC_PARAMS], i;
8076         u32 offset = 0, feature_size;
8077         int rc;
8078 
8079         for (i = 0; i < MAX_DBG_GRC_PARAMS; i++)
8080                 grc_params[i] = dev_data->grc.param_val[i];
8081 
8082         if (cdev->num_hwfns == 1)
8083                 omit_engine = 1;
8084 
8085         org_engine = qed_get_debug_engine(cdev);
8086         for (cur_engine = 0; cur_engine < cdev->num_hwfns; cur_engine++) {
8087                 /* Collect idle_chks and grcDump for each hw function */
8088                 DP_VERBOSE(cdev, QED_MSG_DEBUG,
8089                            "obtaining idle_chk and grcdump for current engine\n");
8090                 qed_set_debug_engine(cdev, cur_engine);
8091 
8092                 /* First idle_chk */
8093                 rc = qed_dbg_idle_chk(cdev, (u8 *)buffer + offset +
8094                                       REGDUMP_HEADER_SIZE, &feature_size);
8095                 if (!rc) {
8096                         *(u32 *)((u8 *)buffer + offset) =
8097                             qed_calc_regdump_header(IDLE_CHK, cur_engine,
8098                                                     feature_size, omit_engine);
8099                         offset += (feature_size + REGDUMP_HEADER_SIZE);
8100                 } else {
8101                         DP_ERR(cdev, "qed_dbg_idle_chk failed. rc = %d\n", rc);
8102                 }
8103 
8104                 /* Second idle_chk */
8105                 rc = qed_dbg_idle_chk(cdev, (u8 *)buffer + offset +
8106                                       REGDUMP_HEADER_SIZE, &feature_size);
8107                 if (!rc) {
8108                         *(u32 *)((u8 *)buffer + offset) =
8109                             qed_calc_regdump_header(IDLE_CHK, cur_engine,
8110                                                     feature_size, omit_engine);
8111                         offset += (feature_size + REGDUMP_HEADER_SIZE);
8112                 } else {
8113                         DP_ERR(cdev, "qed_dbg_idle_chk failed. rc = %d\n", rc);
8114                 }
8115 
8116                 /* reg_fifo dump */
8117                 rc = qed_dbg_reg_fifo(cdev, (u8 *)buffer + offset +
8118                                       REGDUMP_HEADER_SIZE, &feature_size);
8119                 if (!rc) {
8120                         *(u32 *)((u8 *)buffer + offset) =
8121                             qed_calc_regdump_header(REG_FIFO, cur_engine,
8122                                                     feature_size, omit_engine);
8123                         offset += (feature_size + REGDUMP_HEADER_SIZE);
8124                 } else {
8125                         DP_ERR(cdev, "qed_dbg_reg_fifo failed. rc = %d\n", rc);
8126                 }
8127 
8128                 /* igu_fifo dump */
8129                 rc = qed_dbg_igu_fifo(cdev, (u8 *)buffer + offset +
8130                                       REGDUMP_HEADER_SIZE, &feature_size);
8131                 if (!rc) {
8132                         *(u32 *)((u8 *)buffer + offset) =
8133                             qed_calc_regdump_header(IGU_FIFO, cur_engine,
8134                                                     feature_size, omit_engine);
8135                         offset += (feature_size + REGDUMP_HEADER_SIZE);
8136                 } else {
8137                         DP_ERR(cdev, "qed_dbg_igu_fifo failed. rc = %d", rc);
8138                 }
8139 
8140                 /* protection_override dump */
8141                 rc = qed_dbg_protection_override(cdev, (u8 *)buffer + offset +
8142                                                  REGDUMP_HEADER_SIZE,
8143                                                  &feature_size);
8144                 if (!rc) {
8145                         *(u32 *)((u8 *)buffer + offset) =
8146                             qed_calc_regdump_header(PROTECTION_OVERRIDE,
8147                                                     cur_engine,
8148                                                     feature_size, omit_engine);
8149                         offset += (feature_size + REGDUMP_HEADER_SIZE);
8150                 } else {
8151                         DP_ERR(cdev,
8152                                "qed_dbg_protection_override failed. rc = %d\n",
8153                                rc);
8154                 }
8155 
8156                 /* fw_asserts dump */
8157                 rc = qed_dbg_fw_asserts(cdev, (u8 *)buffer + offset +
8158                                         REGDUMP_HEADER_SIZE, &feature_size);
8159                 if (!rc) {
8160                         *(u32 *)((u8 *)buffer + offset) =
8161                             qed_calc_regdump_header(FW_ASSERTS, cur_engine,
8162                                                     feature_size, omit_engine);
8163                         offset += (feature_size + REGDUMP_HEADER_SIZE);
8164                 } else {
8165                         DP_ERR(cdev, "qed_dbg_fw_asserts failed. rc = %d\n",
8166                                rc);
8167                 }
8168 
8169                 for (i = 0; i < MAX_DBG_GRC_PARAMS; i++)
8170                         dev_data->grc.param_val[i] = grc_params[i];
8171 
8172                 /* GRC dump - must be last because when mcp stuck it will
8173                  * clutter idle_chk, reg_fifo, ...
8174                  */
8175                 rc = qed_dbg_grc(cdev, (u8 *)buffer + offset +
8176                                  REGDUMP_HEADER_SIZE, &feature_size);
8177                 if (!rc) {
8178                         *(u32 *)((u8 *)buffer + offset) =
8179                             qed_calc_regdump_header(GRC_DUMP, cur_engine,
8180                                                     feature_size, omit_engine);
8181                         offset += (feature_size + REGDUMP_HEADER_SIZE);
8182                 } else {
8183                         DP_ERR(cdev, "qed_dbg_grc failed. rc = %d", rc);
8184                 }
8185         }
8186 
8187         qed_set_debug_engine(cdev, org_engine);
8188         /* mcp_trace */
8189         rc = qed_dbg_mcp_trace(cdev, (u8 *)buffer + offset +
8190                                REGDUMP_HEADER_SIZE, &feature_size);
8191         if (!rc) {
8192                 *(u32 *)((u8 *)buffer + offset) =
8193                     qed_calc_regdump_header(MCP_TRACE, cur_engine,
8194                                             feature_size, omit_engine);
8195                 offset += (feature_size + REGDUMP_HEADER_SIZE);
8196         } else {
8197                 DP_ERR(cdev, "qed_dbg_mcp_trace failed. rc = %d\n", rc);
8198         }
8199 
8200         /* nvm cfg1 */
8201         rc = qed_dbg_nvm_image(cdev,
8202                                (u8 *)buffer + offset + REGDUMP_HEADER_SIZE,
8203                                &feature_size, QED_NVM_IMAGE_NVM_CFG1);
8204         if (!rc) {
8205                 *(u32 *)((u8 *)buffer + offset) =
8206                     qed_calc_regdump_header(NVM_CFG1, cur_engine,
8207                                             feature_size, omit_engine);
8208                 offset += (feature_size + REGDUMP_HEADER_SIZE);
8209         } else if (rc != -ENOENT) {
8210                 DP_ERR(cdev,
8211                        "qed_dbg_nvm_image failed for image  %d (%s), rc = %d\n",
8212                        QED_NVM_IMAGE_NVM_CFG1, "QED_NVM_IMAGE_NVM_CFG1", rc);
8213         }
8214 
8215         /* nvm default */
8216         rc = qed_dbg_nvm_image(cdev,
8217                                (u8 *)buffer + offset + REGDUMP_HEADER_SIZE,
8218                                &feature_size, QED_NVM_IMAGE_DEFAULT_CFG);
8219         if (!rc) {
8220                 *(u32 *)((u8 *)buffer + offset) =
8221                     qed_calc_regdump_header(DEFAULT_CFG, cur_engine,
8222                                             feature_size, omit_engine);
8223                 offset += (feature_size + REGDUMP_HEADER_SIZE);
8224         } else if (rc != -ENOENT) {
8225                 DP_ERR(cdev,
8226                        "qed_dbg_nvm_image failed for image %d (%s), rc = %d\n",
8227                        QED_NVM_IMAGE_DEFAULT_CFG, "QED_NVM_IMAGE_DEFAULT_CFG",
8228                        rc);
8229         }
8230 
8231         /* nvm meta */
8232         rc = qed_dbg_nvm_image(cdev,
8233                                (u8 *)buffer + offset + REGDUMP_HEADER_SIZE,
8234                                &feature_size, QED_NVM_IMAGE_NVM_META);
8235         if (!rc) {
8236                 *(u32 *)((u8 *)buffer + offset) =
8237                     qed_calc_regdump_header(NVM_META, cur_engine,
8238                                             feature_size, omit_engine);
8239                 offset += (feature_size + REGDUMP_HEADER_SIZE);
8240         } else if (rc != -ENOENT) {
8241                 DP_ERR(cdev,
8242                        "qed_dbg_nvm_image failed for image %d (%s), rc = %d\n",
8243                        QED_NVM_IMAGE_NVM_META, "QED_NVM_IMAGE_NVM_META", rc);
8244         }
8245 
8246         return 0;
8247 }
8248 
8249 int qed_dbg_all_data_size(struct qed_dev *cdev)
8250 {
8251         struct qed_hwfn *p_hwfn =
8252                 &cdev->hwfns[cdev->dbg_params.engine_for_debug];
8253         u32 regs_len = 0, image_len = 0;
8254         u8 cur_engine, org_engine;
8255 
8256         org_engine = qed_get_debug_engine(cdev);
8257         for (cur_engine = 0; cur_engine < cdev->num_hwfns; cur_engine++) {
8258                 /* Engine specific */
8259                 DP_VERBOSE(cdev, QED_MSG_DEBUG,
8260                            "calculating idle_chk and grcdump register length for current engine\n");
8261                 qed_set_debug_engine(cdev, cur_engine);
8262                 regs_len += REGDUMP_HEADER_SIZE + qed_dbg_idle_chk_size(cdev) +
8263                             REGDUMP_HEADER_SIZE + qed_dbg_idle_chk_size(cdev) +
8264                             REGDUMP_HEADER_SIZE + qed_dbg_grc_size(cdev) +
8265                             REGDUMP_HEADER_SIZE + qed_dbg_reg_fifo_size(cdev) +
8266                             REGDUMP_HEADER_SIZE + qed_dbg_igu_fifo_size(cdev) +
8267                             REGDUMP_HEADER_SIZE +
8268                             qed_dbg_protection_override_size(cdev) +
8269                             REGDUMP_HEADER_SIZE + qed_dbg_fw_asserts_size(cdev);
8270         }
8271 
8272         qed_set_debug_engine(cdev, org_engine);
8273 
8274         /* Engine common */
8275         regs_len += REGDUMP_HEADER_SIZE + qed_dbg_mcp_trace_size(cdev);
8276         qed_dbg_nvm_image_length(p_hwfn, QED_NVM_IMAGE_NVM_CFG1, &image_len);
8277         if (image_len)
8278                 regs_len += REGDUMP_HEADER_SIZE + image_len;
8279         qed_dbg_nvm_image_length(p_hwfn, QED_NVM_IMAGE_DEFAULT_CFG, &image_len);
8280         if (image_len)
8281                 regs_len += REGDUMP_HEADER_SIZE + image_len;
8282         qed_dbg_nvm_image_length(p_hwfn, QED_NVM_IMAGE_NVM_META, &image_len);
8283         if (image_len)
8284                 regs_len += REGDUMP_HEADER_SIZE + image_len;
8285 
8286         return regs_len;
8287 }
8288 
8289 int qed_dbg_feature(struct qed_dev *cdev, void *buffer,
8290                     enum qed_dbg_features feature, u32 *num_dumped_bytes)
8291 {
8292         struct qed_hwfn *p_hwfn =
8293                 &cdev->hwfns[cdev->dbg_params.engine_for_debug];
8294         struct qed_dbg_feature *qed_feature =
8295                 &cdev->dbg_params.features[feature];
8296         enum dbg_status dbg_rc;
8297         struct qed_ptt *p_ptt;
8298         int rc = 0;
8299 
8300         /* Acquire ptt */
8301         p_ptt = qed_ptt_acquire(p_hwfn);
8302         if (!p_ptt)
8303                 return -EINVAL;
8304 
8305         /* Get dump */
8306         dbg_rc = qed_dbg_dump(p_hwfn, p_ptt, feature);
8307         if (dbg_rc != DBG_STATUS_OK) {
8308                 DP_VERBOSE(cdev, QED_MSG_DEBUG, "%s\n",
8309                            qed_dbg_get_status_str(dbg_rc));
8310                 *num_dumped_bytes = 0;
8311                 rc = -EINVAL;
8312                 goto out;
8313         }
8314 
8315         DP_VERBOSE(cdev, QED_MSG_DEBUG,
8316                    "copying debugfs feature to external buffer\n");
8317         memcpy(buffer, qed_feature->dump_buf, qed_feature->buf_size);
8318         *num_dumped_bytes = cdev->dbg_params.features[feature].dumped_dwords *
8319                             4;
8320 
8321 out:
8322         qed_ptt_release(p_hwfn, p_ptt);
8323         return rc;
8324 }
8325 
8326 int qed_dbg_feature_size(struct qed_dev *cdev, enum qed_dbg_features feature)
8327 {
8328         struct qed_hwfn *p_hwfn =
8329                 &cdev->hwfns[cdev->dbg_params.engine_for_debug];
8330         struct qed_ptt *p_ptt = qed_ptt_acquire(p_hwfn);
8331         struct qed_dbg_feature *qed_feature =
8332                 &cdev->dbg_params.features[feature];
8333         u32 buf_size_dwords;
8334         enum dbg_status rc;
8335 
8336         if (!p_ptt)
8337                 return -EINVAL;
8338 
8339         rc = qed_features_lookup[feature].get_size(p_hwfn, p_ptt,
8340                                                    &buf_size_dwords);
8341         if (rc != DBG_STATUS_OK)
8342                 buf_size_dwords = 0;
8343 
8344         qed_ptt_release(p_hwfn, p_ptt);
8345         qed_feature->buf_size = buf_size_dwords * sizeof(u32);
8346         return qed_feature->buf_size;
8347 }
8348 
8349 u8 qed_get_debug_engine(struct qed_dev *cdev)
8350 {
8351         return cdev->dbg_params.engine_for_debug;
8352 }
8353 
8354 void qed_set_debug_engine(struct qed_dev *cdev, int engine_number)
8355 {
8356         DP_VERBOSE(cdev, QED_MSG_DEBUG, "set debug engine to %d\n",
8357                    engine_number);
8358         cdev->dbg_params.engine_for_debug = engine_number;
8359 }
8360 
8361 void qed_dbg_pf_init(struct qed_dev *cdev)
8362 {
8363         const u8 *dbg_values;
8364 
8365         /* Debug values are after init values.
8366          * The offset is the first dword of the file.
8367          */
8368         dbg_values = cdev->firmware->data + *(u32 *)cdev->firmware->data;
8369         qed_dbg_set_bin_ptr((u8 *)dbg_values);
8370         qed_dbg_user_set_bin_ptr((u8 *)dbg_values);
8371 }
8372 
8373 void qed_dbg_pf_exit(struct qed_dev *cdev)
8374 {
8375         struct qed_dbg_feature *feature = NULL;
8376         enum qed_dbg_features feature_idx;
8377 
8378         /* Debug features' buffers may be allocated if debug feature was used
8379          * but dump wasn't called.
8380          */
8381         for (feature_idx = 0; feature_idx < DBG_FEATURE_NUM; feature_idx++) {
8382                 feature = &cdev->dbg_params.features[feature_idx];
8383                 if (feature->dump_buf) {
8384                         vfree(feature->dump_buf);
8385                         feature->dump_buf = NULL;
8386                 }
8387         }
8388 }

/* [<][>][^][v][top][bottom][index][help] */