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