3610 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/*3 * Copyright (C) 2017 Chelsio Communications. All rights reserved.4 */5 6#include <linux/sort.h>7#include <linux/string.h>8 9#include "t4_regs.h"10#include "cxgb4.h"11#include "cxgb4_cudbg.h"12#include "cudbg_if.h"13#include "cudbg_lib_common.h"14#include "cudbg_entity.h"15#include "cudbg_lib.h"16#include "cudbg_zlib.h"17#include "cxgb4_tc_mqprio.h"18 19static const u32 t6_tp_pio_array[][IREG_NUM_ELEM] = {20 {0x7e40, 0x7e44, 0x020, 28}, /* t6_tp_pio_regs_20_to_3b */21 {0x7e40, 0x7e44, 0x040, 10}, /* t6_tp_pio_regs_40_to_49 */22 {0x7e40, 0x7e44, 0x050, 10}, /* t6_tp_pio_regs_50_to_59 */23 {0x7e40, 0x7e44, 0x060, 14}, /* t6_tp_pio_regs_60_to_6d */24 {0x7e40, 0x7e44, 0x06F, 1}, /* t6_tp_pio_regs_6f */25 {0x7e40, 0x7e44, 0x070, 6}, /* t6_tp_pio_regs_70_to_75 */26 {0x7e40, 0x7e44, 0x130, 18}, /* t6_tp_pio_regs_130_to_141 */27 {0x7e40, 0x7e44, 0x145, 19}, /* t6_tp_pio_regs_145_to_157 */28 {0x7e40, 0x7e44, 0x160, 1}, /* t6_tp_pio_regs_160 */29 {0x7e40, 0x7e44, 0x230, 25}, /* t6_tp_pio_regs_230_to_248 */30 {0x7e40, 0x7e44, 0x24a, 3}, /* t6_tp_pio_regs_24c */31 {0x7e40, 0x7e44, 0x8C0, 1} /* t6_tp_pio_regs_8c0 */32};33 34static const u32 t5_tp_pio_array[][IREG_NUM_ELEM] = {35 {0x7e40, 0x7e44, 0x020, 28}, /* t5_tp_pio_regs_20_to_3b */36 {0x7e40, 0x7e44, 0x040, 19}, /* t5_tp_pio_regs_40_to_52 */37 {0x7e40, 0x7e44, 0x054, 2}, /* t5_tp_pio_regs_54_to_55 */38 {0x7e40, 0x7e44, 0x060, 13}, /* t5_tp_pio_regs_60_to_6c */39 {0x7e40, 0x7e44, 0x06F, 1}, /* t5_tp_pio_regs_6f */40 {0x7e40, 0x7e44, 0x120, 4}, /* t5_tp_pio_regs_120_to_123 */41 {0x7e40, 0x7e44, 0x12b, 2}, /* t5_tp_pio_regs_12b_to_12c */42 {0x7e40, 0x7e44, 0x12f, 21}, /* t5_tp_pio_regs_12f_to_143 */43 {0x7e40, 0x7e44, 0x145, 19}, /* t5_tp_pio_regs_145_to_157 */44 {0x7e40, 0x7e44, 0x230, 25}, /* t5_tp_pio_regs_230_to_248 */45 {0x7e40, 0x7e44, 0x8C0, 1} /* t5_tp_pio_regs_8c0 */46};47 48static const u32 t6_tp_tm_pio_array[][IREG_NUM_ELEM] = {49 {0x7e18, 0x7e1c, 0x0, 12}50};51 52static const u32 t5_tp_tm_pio_array[][IREG_NUM_ELEM] = {53 {0x7e18, 0x7e1c, 0x0, 12}54};55 56static const u32 t6_tp_mib_index_array[6][IREG_NUM_ELEM] = {57 {0x7e50, 0x7e54, 0x0, 13},58 {0x7e50, 0x7e54, 0x10, 6},59 {0x7e50, 0x7e54, 0x18, 21},60 {0x7e50, 0x7e54, 0x30, 32},61 {0x7e50, 0x7e54, 0x50, 22},62 {0x7e50, 0x7e54, 0x68, 12}63};64 65static const u32 t5_tp_mib_index_array[9][IREG_NUM_ELEM] = {66 {0x7e50, 0x7e54, 0x0, 13},67 {0x7e50, 0x7e54, 0x10, 6},68 {0x7e50, 0x7e54, 0x18, 8},69 {0x7e50, 0x7e54, 0x20, 13},70 {0x7e50, 0x7e54, 0x30, 16},71 {0x7e50, 0x7e54, 0x40, 16},72 {0x7e50, 0x7e54, 0x50, 16},73 {0x7e50, 0x7e54, 0x60, 6},74 {0x7e50, 0x7e54, 0x68, 4}75};76 77static const u32 t5_sge_dbg_index_array[2][IREG_NUM_ELEM] = {78 {0x10cc, 0x10d0, 0x0, 16},79 {0x10cc, 0x10d4, 0x0, 16},80};81 82static const u32 t6_sge_qbase_index_array[] = {83 /* 1 addr reg SGE_QBASE_INDEX and 4 data reg SGE_QBASE_MAP[0-3] */84 0x1250, 0x1240, 0x1244, 0x1248, 0x124c,85};86 87static const u32 t5_pcie_pdbg_array[][IREG_NUM_ELEM] = {88 {0x5a04, 0x5a0c, 0x00, 0x20}, /* t5_pcie_pdbg_regs_00_to_20 */89 {0x5a04, 0x5a0c, 0x21, 0x20}, /* t5_pcie_pdbg_regs_21_to_40 */90 {0x5a04, 0x5a0c, 0x41, 0x10}, /* t5_pcie_pdbg_regs_41_to_50 */91};92 93static const u32 t5_pcie_cdbg_array[][IREG_NUM_ELEM] = {94 {0x5a10, 0x5a18, 0x00, 0x20}, /* t5_pcie_cdbg_regs_00_to_20 */95 {0x5a10, 0x5a18, 0x21, 0x18}, /* t5_pcie_cdbg_regs_21_to_37 */96};97 98static const u32 t5_pm_rx_array[][IREG_NUM_ELEM] = {99 {0x8FD0, 0x8FD4, 0x10000, 0x20}, /* t5_pm_rx_regs_10000_to_10020 */100 {0x8FD0, 0x8FD4, 0x10021, 0x0D}, /* t5_pm_rx_regs_10021_to_1002c */101};102 103static const u32 t5_pm_tx_array[][IREG_NUM_ELEM] = {104 {0x8FF0, 0x8FF4, 0x10000, 0x20}, /* t5_pm_tx_regs_10000_to_10020 */105 {0x8FF0, 0x8FF4, 0x10021, 0x1D}, /* t5_pm_tx_regs_10021_to_1003c */106};107 108static const u32 t5_pcie_config_array[][2] = {109 {0x0, 0x34},110 {0x3c, 0x40},111 {0x50, 0x64},112 {0x70, 0x80},113 {0x94, 0xa0},114 {0xb0, 0xb8},115 {0xd0, 0xd4},116 {0x100, 0x128},117 {0x140, 0x148},118 {0x150, 0x164},119 {0x170, 0x178},120 {0x180, 0x194},121 {0x1a0, 0x1b8},122 {0x1c0, 0x208},123};124 125static const u32 t6_ma_ireg_array[][IREG_NUM_ELEM] = {126 {0x78f8, 0x78fc, 0xa000, 23}, /* t6_ma_regs_a000_to_a016 */127 {0x78f8, 0x78fc, 0xa400, 30}, /* t6_ma_regs_a400_to_a41e */128 {0x78f8, 0x78fc, 0xa800, 20} /* t6_ma_regs_a800_to_a813 */129};130 131static const u32 t6_ma_ireg_array2[][IREG_NUM_ELEM] = {132 {0x78f8, 0x78fc, 0xe400, 17}, /* t6_ma_regs_e400_to_e600 */133 {0x78f8, 0x78fc, 0xe640, 13} /* t6_ma_regs_e640_to_e7c0 */134};135 136static const u32 t6_up_cim_reg_array[][IREG_NUM_ELEM + 1] = {137 {0x7b50, 0x7b54, 0x2000, 0x20, 0}, /* up_cim_2000_to_207c */138 {0x7b50, 0x7b54, 0x2080, 0x1d, 0}, /* up_cim_2080_to_20fc */139 {0x7b50, 0x7b54, 0x00, 0x20, 0}, /* up_cim_00_to_7c */140 {0x7b50, 0x7b54, 0x80, 0x20, 0}, /* up_cim_80_to_fc */141 {0x7b50, 0x7b54, 0x100, 0x11, 0}, /* up_cim_100_to_14c */142 {0x7b50, 0x7b54, 0x200, 0x10, 0}, /* up_cim_200_to_23c */143 {0x7b50, 0x7b54, 0x240, 0x2, 0}, /* up_cim_240_to_244 */144 {0x7b50, 0x7b54, 0x250, 0x2, 0}, /* up_cim_250_to_254 */145 {0x7b50, 0x7b54, 0x260, 0x2, 0}, /* up_cim_260_to_264 */146 {0x7b50, 0x7b54, 0x270, 0x2, 0}, /* up_cim_270_to_274 */147 {0x7b50, 0x7b54, 0x280, 0x20, 0}, /* up_cim_280_to_2fc */148 {0x7b50, 0x7b54, 0x300, 0x20, 0}, /* up_cim_300_to_37c */149 {0x7b50, 0x7b54, 0x380, 0x14, 0}, /* up_cim_380_to_3cc */150 {0x7b50, 0x7b54, 0x4900, 0x4, 0x4}, /* up_cim_4900_to_4c60 */151 {0x7b50, 0x7b54, 0x4904, 0x4, 0x4}, /* up_cim_4904_to_4c64 */152 {0x7b50, 0x7b54, 0x4908, 0x4, 0x4}, /* up_cim_4908_to_4c68 */153 {0x7b50, 0x7b54, 0x4910, 0x4, 0x4}, /* up_cim_4910_to_4c70 */154 {0x7b50, 0x7b54, 0x4914, 0x4, 0x4}, /* up_cim_4914_to_4c74 */155 {0x7b50, 0x7b54, 0x4920, 0x10, 0x10}, /* up_cim_4920_to_4a10 */156 {0x7b50, 0x7b54, 0x4924, 0x10, 0x10}, /* up_cim_4924_to_4a14 */157 {0x7b50, 0x7b54, 0x4928, 0x10, 0x10}, /* up_cim_4928_to_4a18 */158 {0x7b50, 0x7b54, 0x492c, 0x10, 0x10}, /* up_cim_492c_to_4a1c */159};160 161static const u32 t5_up_cim_reg_array[][IREG_NUM_ELEM + 1] = {162 {0x7b50, 0x7b54, 0x2000, 0x20, 0}, /* up_cim_2000_to_207c */163 {0x7b50, 0x7b54, 0x2080, 0x19, 0}, /* up_cim_2080_to_20ec */164 {0x7b50, 0x7b54, 0x00, 0x20, 0}, /* up_cim_00_to_7c */165 {0x7b50, 0x7b54, 0x80, 0x20, 0}, /* up_cim_80_to_fc */166 {0x7b50, 0x7b54, 0x100, 0x11, 0}, /* up_cim_100_to_14c */167 {0x7b50, 0x7b54, 0x200, 0x10, 0}, /* up_cim_200_to_23c */168 {0x7b50, 0x7b54, 0x240, 0x2, 0}, /* up_cim_240_to_244 */169 {0x7b50, 0x7b54, 0x250, 0x2, 0}, /* up_cim_250_to_254 */170 {0x7b50, 0x7b54, 0x260, 0x2, 0}, /* up_cim_260_to_264 */171 {0x7b50, 0x7b54, 0x270, 0x2, 0}, /* up_cim_270_to_274 */172 {0x7b50, 0x7b54, 0x280, 0x20, 0}, /* up_cim_280_to_2fc */173 {0x7b50, 0x7b54, 0x300, 0x20, 0}, /* up_cim_300_to_37c */174 {0x7b50, 0x7b54, 0x380, 0x14, 0}, /* up_cim_380_to_3cc */175};176 177static const u32 t6_hma_ireg_array[][IREG_NUM_ELEM] = {178 {0x51320, 0x51324, 0xa000, 32} /* t6_hma_regs_a000_to_a01f */179};180 181u32 cudbg_get_entity_length(struct adapter *adap, u32 entity)182{183 struct cudbg_tcam tcam_region = { 0 };184 u32 value, n = 0, len = 0;185 186 switch (entity) {187 case CUDBG_REG_DUMP:188 switch (CHELSIO_CHIP_VERSION(adap->params.chip)) {189 case CHELSIO_T4:190 len = T4_REGMAP_SIZE;191 break;192 case CHELSIO_T5:193 case CHELSIO_T6:194 len = T5_REGMAP_SIZE;195 break;196 default:197 break;198 }199 break;200 case CUDBG_DEV_LOG:201 len = adap->params.devlog.size;202 break;203 case CUDBG_CIM_LA:204 if (is_t6(adap->params.chip)) {205 len = adap->params.cim_la_size / 10 + 1;206 len *= 10 * sizeof(u32);207 } else {208 len = adap->params.cim_la_size / 8;209 len *= 8 * sizeof(u32);210 }211 len += sizeof(u32); /* for reading CIM LA configuration */212 break;213 case CUDBG_CIM_MA_LA:214 len = 2 * CIM_MALA_SIZE * 5 * sizeof(u32);215 break;216 case CUDBG_CIM_QCFG:217 len = sizeof(struct cudbg_cim_qcfg);218 break;219 case CUDBG_CIM_IBQ_TP0:220 case CUDBG_CIM_IBQ_TP1:221 case CUDBG_CIM_IBQ_ULP:222 case CUDBG_CIM_IBQ_SGE0:223 case CUDBG_CIM_IBQ_SGE1:224 case CUDBG_CIM_IBQ_NCSI:225 len = CIM_IBQ_SIZE * 4 * sizeof(u32);226 break;227 case CUDBG_CIM_OBQ_ULP0:228 len = cudbg_cim_obq_size(adap, 0);229 break;230 case CUDBG_CIM_OBQ_ULP1:231 len = cudbg_cim_obq_size(adap, 1);232 break;233 case CUDBG_CIM_OBQ_ULP2:234 len = cudbg_cim_obq_size(adap, 2);235 break;236 case CUDBG_CIM_OBQ_ULP3:237 len = cudbg_cim_obq_size(adap, 3);238 break;239 case CUDBG_CIM_OBQ_SGE:240 len = cudbg_cim_obq_size(adap, 4);241 break;242 case CUDBG_CIM_OBQ_NCSI:243 len = cudbg_cim_obq_size(adap, 5);244 break;245 case CUDBG_CIM_OBQ_RXQ0:246 len = cudbg_cim_obq_size(adap, 6);247 break;248 case CUDBG_CIM_OBQ_RXQ1:249 len = cudbg_cim_obq_size(adap, 7);250 break;251 case CUDBG_EDC0:252 value = t4_read_reg(adap, MA_TARGET_MEM_ENABLE_A);253 if (value & EDRAM0_ENABLE_F) {254 value = t4_read_reg(adap, MA_EDRAM0_BAR_A);255 len = EDRAM0_SIZE_G(value);256 }257 len = cudbg_mbytes_to_bytes(len);258 break;259 case CUDBG_EDC1:260 value = t4_read_reg(adap, MA_TARGET_MEM_ENABLE_A);261 if (value & EDRAM1_ENABLE_F) {262 value = t4_read_reg(adap, MA_EDRAM1_BAR_A);263 len = EDRAM1_SIZE_G(value);264 }265 len = cudbg_mbytes_to_bytes(len);266 break;267 case CUDBG_MC0:268 value = t4_read_reg(adap, MA_TARGET_MEM_ENABLE_A);269 if (value & EXT_MEM0_ENABLE_F) {270 value = t4_read_reg(adap, MA_EXT_MEMORY0_BAR_A);271 len = EXT_MEM0_SIZE_G(value);272 }273 len = cudbg_mbytes_to_bytes(len);274 break;275 case CUDBG_MC1:276 value = t4_read_reg(adap, MA_TARGET_MEM_ENABLE_A);277 if (value & EXT_MEM1_ENABLE_F) {278 value = t4_read_reg(adap, MA_EXT_MEMORY1_BAR_A);279 len = EXT_MEM1_SIZE_G(value);280 }281 len = cudbg_mbytes_to_bytes(len);282 break;283 case CUDBG_RSS:284 len = t4_chip_rss_size(adap) * sizeof(u16);285 break;286 case CUDBG_RSS_VF_CONF:287 len = adap->params.arch.vfcount *288 sizeof(struct cudbg_rss_vf_conf);289 break;290 case CUDBG_PATH_MTU:291 len = NMTUS * sizeof(u16);292 break;293 case CUDBG_PM_STATS:294 len = sizeof(struct cudbg_pm_stats);295 break;296 case CUDBG_HW_SCHED:297 len = sizeof(struct cudbg_hw_sched);298 break;299 case CUDBG_TP_INDIRECT:300 switch (CHELSIO_CHIP_VERSION(adap->params.chip)) {301 case CHELSIO_T5:302 n = sizeof(t5_tp_pio_array) +303 sizeof(t5_tp_tm_pio_array) +304 sizeof(t5_tp_mib_index_array);305 break;306 case CHELSIO_T6:307 n = sizeof(t6_tp_pio_array) +308 sizeof(t6_tp_tm_pio_array) +309 sizeof(t6_tp_mib_index_array);310 break;311 default:312 break;313 }314 n = n / (IREG_NUM_ELEM * sizeof(u32));315 len = sizeof(struct ireg_buf) * n;316 break;317 case CUDBG_SGE_INDIRECT:318 len = sizeof(struct ireg_buf) * 2 +319 sizeof(struct sge_qbase_reg_field);320 break;321 case CUDBG_ULPRX_LA:322 len = sizeof(struct cudbg_ulprx_la);323 break;324 case CUDBG_TP_LA:325 len = sizeof(struct cudbg_tp_la) + TPLA_SIZE * sizeof(u64);326 break;327 case CUDBG_MEMINFO:328 len = sizeof(struct cudbg_ver_hdr) +329 sizeof(struct cudbg_meminfo);330 break;331 case CUDBG_CIM_PIF_LA:332 len = sizeof(struct cudbg_cim_pif_la);333 len += 2 * CIM_PIFLA_SIZE * 6 * sizeof(u32);334 break;335 case CUDBG_CLK:336 len = sizeof(struct cudbg_clk_info);337 break;338 case CUDBG_PCIE_INDIRECT:339 n = sizeof(t5_pcie_pdbg_array) / (IREG_NUM_ELEM * sizeof(u32));340 len = sizeof(struct ireg_buf) * n * 2;341 break;342 case CUDBG_PM_INDIRECT:343 n = sizeof(t5_pm_rx_array) / (IREG_NUM_ELEM * sizeof(u32));344 len = sizeof(struct ireg_buf) * n * 2;345 break;346 case CUDBG_TID_INFO:347 len = sizeof(struct cudbg_tid_info_region_rev1);348 break;349 case CUDBG_PCIE_CONFIG:350 len = sizeof(u32) * CUDBG_NUM_PCIE_CONFIG_REGS;351 break;352 case CUDBG_DUMP_CONTEXT:353 len = cudbg_dump_context_size(adap);354 break;355 case CUDBG_MPS_TCAM:356 len = sizeof(struct cudbg_mps_tcam) *357 adap->params.arch.mps_tcam_size;358 break;359 case CUDBG_VPD_DATA:360 len = sizeof(struct cudbg_vpd_data);361 break;362 case CUDBG_LE_TCAM:363 cudbg_fill_le_tcam_info(adap, &tcam_region);364 len = sizeof(struct cudbg_tcam) +365 sizeof(struct cudbg_tid_data) * tcam_region.max_tid;366 break;367 case CUDBG_CCTRL:368 len = sizeof(u16) * NMTUS * NCCTRL_WIN;369 break;370 case CUDBG_MA_INDIRECT:371 if (CHELSIO_CHIP_VERSION(adap->params.chip) > CHELSIO_T5) {372 n = sizeof(t6_ma_ireg_array) /373 (IREG_NUM_ELEM * sizeof(u32));374 len = sizeof(struct ireg_buf) * n * 2;375 }376 break;377 case CUDBG_ULPTX_LA:378 len = sizeof(struct cudbg_ver_hdr) +379 sizeof(struct cudbg_ulptx_la);380 break;381 case CUDBG_UP_CIM_INDIRECT:382 n = 0;383 if (is_t5(adap->params.chip))384 n = sizeof(t5_up_cim_reg_array) /385 ((IREG_NUM_ELEM + 1) * sizeof(u32));386 else if (is_t6(adap->params.chip))387 n = sizeof(t6_up_cim_reg_array) /388 ((IREG_NUM_ELEM + 1) * sizeof(u32));389 len = sizeof(struct ireg_buf) * n;390 break;391 case CUDBG_PBT_TABLE:392 len = sizeof(struct cudbg_pbt_tables);393 break;394 case CUDBG_MBOX_LOG:395 len = sizeof(struct cudbg_mbox_log) * adap->mbox_log->size;396 break;397 case CUDBG_HMA_INDIRECT:398 if (CHELSIO_CHIP_VERSION(adap->params.chip) > CHELSIO_T5) {399 n = sizeof(t6_hma_ireg_array) /400 (IREG_NUM_ELEM * sizeof(u32));401 len = sizeof(struct ireg_buf) * n;402 }403 break;404 case CUDBG_HMA:405 value = t4_read_reg(adap, MA_TARGET_MEM_ENABLE_A);406 if (value & HMA_MUX_F) {407 /* In T6, there's no MC1. So, HMA shares MC1408 * address space.409 */410 value = t4_read_reg(adap, MA_EXT_MEMORY1_BAR_A);411 len = EXT_MEM1_SIZE_G(value);412 }413 len = cudbg_mbytes_to_bytes(len);414 break;415 case CUDBG_QDESC:416 cudbg_fill_qdesc_num_and_size(adap, NULL, &len);417 break;418 default:419 break;420 }421 422 return len;423}424 425static int cudbg_do_compression(struct cudbg_init *pdbg_init,426 struct cudbg_buffer *pin_buff,427 struct cudbg_buffer *dbg_buff)428{429 struct cudbg_buffer temp_in_buff = { 0 };430 int bytes_left, bytes_read, bytes;431 u32 offset = dbg_buff->offset;432 int rc;433 434 temp_in_buff.offset = pin_buff->offset;435 temp_in_buff.data = pin_buff->data;436 temp_in_buff.size = pin_buff->size;437 438 bytes_left = pin_buff->size;439 bytes_read = 0;440 while (bytes_left > 0) {441 /* Do compression in smaller chunks */442 bytes = min_t(unsigned long, bytes_left,443 (unsigned long)CUDBG_CHUNK_SIZE);444 temp_in_buff.data = (char *)pin_buff->data + bytes_read;445 temp_in_buff.size = bytes;446 rc = cudbg_compress_buff(pdbg_init, &temp_in_buff, dbg_buff);447 if (rc)448 return rc;449 bytes_left -= bytes;450 bytes_read += bytes;451 }452 453 pin_buff->size = dbg_buff->offset - offset;454 return 0;455}456 457static int cudbg_write_and_release_buff(struct cudbg_init *pdbg_init,458 struct cudbg_buffer *pin_buff,459 struct cudbg_buffer *dbg_buff)460{461 int rc = 0;462 463 if (pdbg_init->compress_type == CUDBG_COMPRESSION_NONE) {464 cudbg_update_buff(pin_buff, dbg_buff);465 } else {466 rc = cudbg_do_compression(pdbg_init, pin_buff, dbg_buff);467 if (rc)468 goto out;469 }470 471out:472 cudbg_put_buff(pdbg_init, pin_buff);473 return rc;474}475 476static int is_fw_attached(struct cudbg_init *pdbg_init)477{478 struct adapter *padap = pdbg_init->adap;479 480 if (!(padap->flags & CXGB4_FW_OK) || padap->use_bd)481 return 0;482 483 return 1;484}485 486/* This function will add additional padding bytes into debug_buffer to make it487 * 4 byte aligned.488 */489void cudbg_align_debug_buffer(struct cudbg_buffer *dbg_buff,490 struct cudbg_entity_hdr *entity_hdr)491{492 u8 zero_buf[4] = {0};493 u8 padding, remain;494 495 remain = (dbg_buff->offset - entity_hdr->start_offset) % 4;496 padding = 4 - remain;497 if (remain) {498 memcpy(((u8 *)dbg_buff->data) + dbg_buff->offset, &zero_buf,499 padding);500 dbg_buff->offset += padding;501 entity_hdr->num_pad = padding;502 }503 entity_hdr->size = dbg_buff->offset - entity_hdr->start_offset;504}505 506struct cudbg_entity_hdr *cudbg_get_entity_hdr(void *outbuf, int i)507{508 struct cudbg_hdr *cudbg_hdr = (struct cudbg_hdr *)outbuf;509 510 return (struct cudbg_entity_hdr *)511 ((char *)outbuf + cudbg_hdr->hdr_len +512 (sizeof(struct cudbg_entity_hdr) * (i - 1)));513}514 515static int cudbg_read_vpd_reg(struct adapter *padap, u32 addr, u32 len,516 void *dest)517{518 int vaddr, rc;519 520 vaddr = t4_eeprom_ptov(addr, padap->pf, EEPROMPFSIZE);521 if (vaddr < 0)522 return vaddr;523 524 rc = pci_read_vpd(padap->pdev, vaddr, len, dest);525 if (rc < 0)526 return rc;527 528 return 0;529}530 531static int cudbg_mem_desc_cmp(const void *a, const void *b)532{533 return ((const struct cudbg_mem_desc *)a)->base -534 ((const struct cudbg_mem_desc *)b)->base;535}536 537int cudbg_fill_meminfo(struct adapter *padap,538 struct cudbg_meminfo *meminfo_buff)539{540 struct cudbg_mem_desc *md;541 u32 lo, hi, used, alloc;542 int n, i;543 544 memset(meminfo_buff->avail, 0,545 ARRAY_SIZE(meminfo_buff->avail) *546 sizeof(struct cudbg_mem_desc));547 memset(meminfo_buff->mem, 0,548 (ARRAY_SIZE(cudbg_region) + 3) * sizeof(struct cudbg_mem_desc));549 md = meminfo_buff->mem;550 551 for (i = 0; i < ARRAY_SIZE(meminfo_buff->mem); i++) {552 meminfo_buff->mem[i].limit = 0;553 meminfo_buff->mem[i].idx = i;554 }555 556 /* Find and sort the populated memory ranges */557 i = 0;558 lo = t4_read_reg(padap, MA_TARGET_MEM_ENABLE_A);559 if (lo & EDRAM0_ENABLE_F) {560 hi = t4_read_reg(padap, MA_EDRAM0_BAR_A);561 meminfo_buff->avail[i].base =562 cudbg_mbytes_to_bytes(EDRAM0_BASE_G(hi));563 meminfo_buff->avail[i].limit =564 meminfo_buff->avail[i].base +565 cudbg_mbytes_to_bytes(EDRAM0_SIZE_G(hi));566 meminfo_buff->avail[i].idx = 0;567 i++;568 }569 570 if (lo & EDRAM1_ENABLE_F) {571 hi = t4_read_reg(padap, MA_EDRAM1_BAR_A);572 meminfo_buff->avail[i].base =573 cudbg_mbytes_to_bytes(EDRAM1_BASE_G(hi));574 meminfo_buff->avail[i].limit =575 meminfo_buff->avail[i].base +576 cudbg_mbytes_to_bytes(EDRAM1_SIZE_G(hi));577 meminfo_buff->avail[i].idx = 1;578 i++;579 }580 581 if (is_t5(padap->params.chip)) {582 if (lo & EXT_MEM0_ENABLE_F) {583 hi = t4_read_reg(padap, MA_EXT_MEMORY0_BAR_A);584 meminfo_buff->avail[i].base =585 cudbg_mbytes_to_bytes(EXT_MEM_BASE_G(hi));586 meminfo_buff->avail[i].limit =587 meminfo_buff->avail[i].base +588 cudbg_mbytes_to_bytes(EXT_MEM_SIZE_G(hi));589 meminfo_buff->avail[i].idx = 3;590 i++;591 }592 593 if (lo & EXT_MEM1_ENABLE_F) {594 hi = t4_read_reg(padap, MA_EXT_MEMORY1_BAR_A);595 meminfo_buff->avail[i].base =596 cudbg_mbytes_to_bytes(EXT_MEM1_BASE_G(hi));597 meminfo_buff->avail[i].limit =598 meminfo_buff->avail[i].base +599 cudbg_mbytes_to_bytes(EXT_MEM1_SIZE_G(hi));600 meminfo_buff->avail[i].idx = 4;601 i++;602 }603 } else {604 if (lo & EXT_MEM_ENABLE_F) {605 hi = t4_read_reg(padap, MA_EXT_MEMORY_BAR_A);606 meminfo_buff->avail[i].base =607 cudbg_mbytes_to_bytes(EXT_MEM_BASE_G(hi));608 meminfo_buff->avail[i].limit =609 meminfo_buff->avail[i].base +610 cudbg_mbytes_to_bytes(EXT_MEM_SIZE_G(hi));611 meminfo_buff->avail[i].idx = 2;612 i++;613 }614 615 if (lo & HMA_MUX_F) {616 hi = t4_read_reg(padap, MA_EXT_MEMORY1_BAR_A);617 meminfo_buff->avail[i].base =618 cudbg_mbytes_to_bytes(EXT_MEM1_BASE_G(hi));619 meminfo_buff->avail[i].limit =620 meminfo_buff->avail[i].base +621 cudbg_mbytes_to_bytes(EXT_MEM1_SIZE_G(hi));622 meminfo_buff->avail[i].idx = 5;623 i++;624 }625 }626 627 if (!i) /* no memory available */628 return CUDBG_STATUS_ENTITY_NOT_FOUND;629 630 meminfo_buff->avail_c = i;631 sort(meminfo_buff->avail, i, sizeof(struct cudbg_mem_desc),632 cudbg_mem_desc_cmp, NULL);633 (md++)->base = t4_read_reg(padap, SGE_DBQ_CTXT_BADDR_A);634 (md++)->base = t4_read_reg(padap, SGE_IMSG_CTXT_BADDR_A);635 (md++)->base = t4_read_reg(padap, SGE_FLM_CACHE_BADDR_A);636 (md++)->base = t4_read_reg(padap, TP_CMM_TCB_BASE_A);637 (md++)->base = t4_read_reg(padap, TP_CMM_MM_BASE_A);638 (md++)->base = t4_read_reg(padap, TP_CMM_TIMER_BASE_A);639 (md++)->base = t4_read_reg(padap, TP_CMM_MM_RX_FLST_BASE_A);640 (md++)->base = t4_read_reg(padap, TP_CMM_MM_TX_FLST_BASE_A);641 (md++)->base = t4_read_reg(padap, TP_CMM_MM_PS_FLST_BASE_A);642 643 /* the next few have explicit upper bounds */644 md->base = t4_read_reg(padap, TP_PMM_TX_BASE_A);645 md->limit = md->base - 1 +646 t4_read_reg(padap, TP_PMM_TX_PAGE_SIZE_A) *647 PMTXMAXPAGE_G(t4_read_reg(padap, TP_PMM_TX_MAX_PAGE_A));648 md++;649 650 md->base = t4_read_reg(padap, TP_PMM_RX_BASE_A);651 md->limit = md->base - 1 +652 t4_read_reg(padap, TP_PMM_RX_PAGE_SIZE_A) *653 PMRXMAXPAGE_G(t4_read_reg(padap, TP_PMM_RX_MAX_PAGE_A));654 md++;655 656 if (t4_read_reg(padap, LE_DB_CONFIG_A) & HASHEN_F) {657 if (CHELSIO_CHIP_VERSION(padap->params.chip) <= CHELSIO_T5) {658 hi = t4_read_reg(padap, LE_DB_TID_HASHBASE_A) / 4;659 md->base = t4_read_reg(padap, LE_DB_HASH_TID_BASE_A);660 } else {661 hi = t4_read_reg(padap, LE_DB_HASH_TID_BASE_A);662 md->base = t4_read_reg(padap,663 LE_DB_HASH_TBL_BASE_ADDR_A);664 }665 md->limit = 0;666 } else {667 md->base = 0;668 md->idx = ARRAY_SIZE(cudbg_region); /* hide it */669 }670 md++;671 672#define ulp_region(reg) do { \673 md->base = t4_read_reg(padap, ULP_ ## reg ## _LLIMIT_A);\674 (md++)->limit = t4_read_reg(padap, ULP_ ## reg ## _ULIMIT_A);\675} while (0)676 677 ulp_region(RX_ISCSI);678 ulp_region(RX_TDDP);679 ulp_region(TX_TPT);680 ulp_region(RX_STAG);681 ulp_region(RX_RQ);682 ulp_region(RX_RQUDP);683 ulp_region(RX_PBL);684 ulp_region(TX_PBL);685#undef ulp_region686 md->base = 0;687 md->idx = ARRAY_SIZE(cudbg_region);688 if (!is_t4(padap->params.chip)) {689 u32 fifo_size = t4_read_reg(padap, SGE_DBVFIFO_SIZE_A);690 u32 sge_ctrl = t4_read_reg(padap, SGE_CONTROL2_A);691 u32 size = 0;692 693 if (is_t5(padap->params.chip)) {694 if (sge_ctrl & VFIFO_ENABLE_F)695 size = DBVFIFO_SIZE_G(fifo_size);696 } else {697 size = T6_DBVFIFO_SIZE_G(fifo_size);698 }699 700 if (size) {701 md->base = BASEADDR_G(t4_read_reg(padap,702 SGE_DBVFIFO_BADDR_A));703 md->limit = md->base + (size << 2) - 1;704 }705 }706 707 md++;708 709 md->base = t4_read_reg(padap, ULP_RX_CTX_BASE_A);710 md->limit = 0;711 md++;712 md->base = t4_read_reg(padap, ULP_TX_ERR_TABLE_BASE_A);713 md->limit = 0;714 md++;715 716 md->base = padap->vres.ocq.start;717 if (padap->vres.ocq.size)718 md->limit = md->base + padap->vres.ocq.size - 1;719 else720 md->idx = ARRAY_SIZE(cudbg_region); /* hide it */721 md++;722 723 /* add any address-space holes, there can be up to 3 */724 for (n = 0; n < i - 1; n++)725 if (meminfo_buff->avail[n].limit <726 meminfo_buff->avail[n + 1].base)727 (md++)->base = meminfo_buff->avail[n].limit;728 729 if (meminfo_buff->avail[n].limit)730 (md++)->base = meminfo_buff->avail[n].limit;731 732 n = md - meminfo_buff->mem;733 meminfo_buff->mem_c = n;734 735 sort(meminfo_buff->mem, n, sizeof(struct cudbg_mem_desc),736 cudbg_mem_desc_cmp, NULL);737 738 lo = t4_read_reg(padap, CIM_SDRAM_BASE_ADDR_A);739 hi = t4_read_reg(padap, CIM_SDRAM_ADDR_SIZE_A) + lo - 1;740 meminfo_buff->up_ram_lo = lo;741 meminfo_buff->up_ram_hi = hi;742 743 lo = t4_read_reg(padap, CIM_EXTMEM2_BASE_ADDR_A);744 hi = t4_read_reg(padap, CIM_EXTMEM2_ADDR_SIZE_A) + lo - 1;745 meminfo_buff->up_extmem2_lo = lo;746 meminfo_buff->up_extmem2_hi = hi;747 748 lo = t4_read_reg(padap, TP_PMM_RX_MAX_PAGE_A);749 for (i = 0, meminfo_buff->free_rx_cnt = 0; i < 2; i++)750 meminfo_buff->free_rx_cnt +=751 FREERXPAGECOUNT_G(t4_read_reg(padap,752 TP_FLM_FREE_RX_CNT_A));753 754 meminfo_buff->rx_pages_data[0] = PMRXMAXPAGE_G(lo);755 meminfo_buff->rx_pages_data[1] =756 t4_read_reg(padap, TP_PMM_RX_PAGE_SIZE_A) >> 10;757 meminfo_buff->rx_pages_data[2] = (lo & PMRXNUMCHN_F) ? 2 : 1;758 759 lo = t4_read_reg(padap, TP_PMM_TX_MAX_PAGE_A);760 hi = t4_read_reg(padap, TP_PMM_TX_PAGE_SIZE_A);761 for (i = 0, meminfo_buff->free_tx_cnt = 0; i < 4; i++)762 meminfo_buff->free_tx_cnt +=763 FREETXPAGECOUNT_G(t4_read_reg(padap,764 TP_FLM_FREE_TX_CNT_A));765 766 meminfo_buff->tx_pages_data[0] = PMTXMAXPAGE_G(lo);767 meminfo_buff->tx_pages_data[1] =768 hi >= (1 << 20) ? (hi >> 20) : (hi >> 10);769 meminfo_buff->tx_pages_data[2] =770 hi >= (1 << 20) ? 'M' : 'K';771 meminfo_buff->tx_pages_data[3] = 1 << PMTXNUMCHN_G(lo);772 773 meminfo_buff->p_structs = t4_read_reg(padap, TP_CMM_MM_MAX_PSTRUCT_A);774 meminfo_buff->p_structs_free_cnt =775 FREEPSTRUCTCOUNT_G(t4_read_reg(padap, TP_FLM_FREE_PS_CNT_A));776 777 for (i = 0; i < 4; i++) {778 if (CHELSIO_CHIP_VERSION(padap->params.chip) > CHELSIO_T5)779 lo = t4_read_reg(padap,780 MPS_RX_MAC_BG_PG_CNT0_A + i * 4);781 else782 lo = t4_read_reg(padap, MPS_RX_PG_RSV0_A + i * 4);783 if (is_t5(padap->params.chip)) {784 used = T5_USED_G(lo);785 alloc = T5_ALLOC_G(lo);786 } else {787 used = USED_G(lo);788 alloc = ALLOC_G(lo);789 }790 meminfo_buff->port_used[i] = used;791 meminfo_buff->port_alloc[i] = alloc;792 }793 794 for (i = 0; i < padap->params.arch.nchan; i++) {795 if (CHELSIO_CHIP_VERSION(padap->params.chip) > CHELSIO_T5)796 lo = t4_read_reg(padap,797 MPS_RX_LPBK_BG_PG_CNT0_A + i * 4);798 else799 lo = t4_read_reg(padap, MPS_RX_PG_RSV4_A + i * 4);800 if (is_t5(padap->params.chip)) {801 used = T5_USED_G(lo);802 alloc = T5_ALLOC_G(lo);803 } else {804 used = USED_G(lo);805 alloc = ALLOC_G(lo);806 }807 meminfo_buff->loopback_used[i] = used;808 meminfo_buff->loopback_alloc[i] = alloc;809 }810 811 return 0;812}813 814int cudbg_collect_reg_dump(struct cudbg_init *pdbg_init,815 struct cudbg_buffer *dbg_buff,816 struct cudbg_error *cudbg_err)817{818 struct adapter *padap = pdbg_init->adap;819 struct cudbg_buffer temp_buff = { 0 };820 u32 buf_size = 0;821 int rc = 0;822 823 if (is_t4(padap->params.chip))824 buf_size = T4_REGMAP_SIZE;825 else if (is_t5(padap->params.chip) || is_t6(padap->params.chip))826 buf_size = T5_REGMAP_SIZE;827 828 rc = cudbg_get_buff(pdbg_init, dbg_buff, buf_size, &temp_buff);829 if (rc)830 return rc;831 t4_get_regs(padap, (void *)temp_buff.data, temp_buff.size);832 return cudbg_write_and_release_buff(pdbg_init, &temp_buff, dbg_buff);833}834 835int cudbg_collect_fw_devlog(struct cudbg_init *pdbg_init,836 struct cudbg_buffer *dbg_buff,837 struct cudbg_error *cudbg_err)838{839 struct adapter *padap = pdbg_init->adap;840 struct cudbg_buffer temp_buff = { 0 };841 struct devlog_params *dparams;842 int rc = 0;843 844 rc = t4_init_devlog_params(padap);845 if (rc < 0) {846 cudbg_err->sys_err = rc;847 return rc;848 }849 850 dparams = &padap->params.devlog;851 rc = cudbg_get_buff(pdbg_init, dbg_buff, dparams->size, &temp_buff);852 if (rc)853 return rc;854 855 /* Collect FW devlog */856 if (dparams->start != 0) {857 spin_lock(&padap->win0_lock);858 rc = t4_memory_rw(padap, padap->params.drv_memwin,859 dparams->memtype, dparams->start,860 dparams->size,861 (__be32 *)(char *)temp_buff.data,862 1);863 spin_unlock(&padap->win0_lock);864 if (rc) {865 cudbg_err->sys_err = rc;866 cudbg_put_buff(pdbg_init, &temp_buff);867 return rc;868 }869 }870 return cudbg_write_and_release_buff(pdbg_init, &temp_buff, dbg_buff);871}872 873int cudbg_collect_cim_la(struct cudbg_init *pdbg_init,874 struct cudbg_buffer *dbg_buff,875 struct cudbg_error *cudbg_err)876{877 struct adapter *padap = pdbg_init->adap;878 struct cudbg_buffer temp_buff = { 0 };879 int size, rc;880 u32 cfg = 0;881 882 if (is_t6(padap->params.chip)) {883 size = padap->params.cim_la_size / 10 + 1;884 size *= 10 * sizeof(u32);885 } else {886 size = padap->params.cim_la_size / 8;887 size *= 8 * sizeof(u32);888 }889 890 size += sizeof(cfg);891 rc = cudbg_get_buff(pdbg_init, dbg_buff, size, &temp_buff);892 if (rc)893 return rc;894 895 rc = t4_cim_read(padap, UP_UP_DBG_LA_CFG_A, 1, &cfg);896 if (rc) {897 cudbg_err->sys_err = rc;898 cudbg_put_buff(pdbg_init, &temp_buff);899 return rc;900 }901 902 memcpy((char *)temp_buff.data, &cfg, sizeof(cfg));903 rc = t4_cim_read_la(padap,904 (u32 *)((char *)temp_buff.data + sizeof(cfg)),905 NULL);906 if (rc < 0) {907 cudbg_err->sys_err = rc;908 cudbg_put_buff(pdbg_init, &temp_buff);909 return rc;910 }911 return cudbg_write_and_release_buff(pdbg_init, &temp_buff, dbg_buff);912}913 914int cudbg_collect_cim_ma_la(struct cudbg_init *pdbg_init,915 struct cudbg_buffer *dbg_buff,916 struct cudbg_error *cudbg_err)917{918 struct adapter *padap = pdbg_init->adap;919 struct cudbg_buffer temp_buff = { 0 };920 int size, rc;921 922 size = 2 * CIM_MALA_SIZE * 5 * sizeof(u32);923 rc = cudbg_get_buff(pdbg_init, dbg_buff, size, &temp_buff);924 if (rc)925 return rc;926 927 t4_cim_read_ma_la(padap,928 (u32 *)temp_buff.data,929 (u32 *)((char *)temp_buff.data +930 5 * CIM_MALA_SIZE));931 return cudbg_write_and_release_buff(pdbg_init, &temp_buff, dbg_buff);932}933 934int cudbg_collect_cim_qcfg(struct cudbg_init *pdbg_init,935 struct cudbg_buffer *dbg_buff,936 struct cudbg_error *cudbg_err)937{938 struct adapter *padap = pdbg_init->adap;939 struct cudbg_buffer temp_buff = { 0 };940 struct cudbg_cim_qcfg *cim_qcfg_data;941 int rc;942 943 rc = cudbg_get_buff(pdbg_init, dbg_buff, sizeof(struct cudbg_cim_qcfg),944 &temp_buff);945 if (rc)946 return rc;947 948 cim_qcfg_data = (struct cudbg_cim_qcfg *)temp_buff.data;949 cim_qcfg_data->chip = padap->params.chip;950 rc = t4_cim_read(padap, UP_IBQ_0_RDADDR_A,951 ARRAY_SIZE(cim_qcfg_data->stat), cim_qcfg_data->stat);952 if (rc) {953 cudbg_err->sys_err = rc;954 cudbg_put_buff(pdbg_init, &temp_buff);955 return rc;956 }957 958 rc = t4_cim_read(padap, UP_OBQ_0_REALADDR_A,959 ARRAY_SIZE(cim_qcfg_data->obq_wr),960 cim_qcfg_data->obq_wr);961 if (rc) {962 cudbg_err->sys_err = rc;963 cudbg_put_buff(pdbg_init, &temp_buff);964 return rc;965 }966 967 t4_read_cimq_cfg(padap, cim_qcfg_data->base, cim_qcfg_data->size,968 cim_qcfg_data->thres);969 return cudbg_write_and_release_buff(pdbg_init, &temp_buff, dbg_buff);970}971 972static int cudbg_read_cim_ibq(struct cudbg_init *pdbg_init,973 struct cudbg_buffer *dbg_buff,974 struct cudbg_error *cudbg_err, int qid)975{976 struct adapter *padap = pdbg_init->adap;977 struct cudbg_buffer temp_buff = { 0 };978 int no_of_read_words, rc = 0;979 u32 qsize;980 981 /* collect CIM IBQ */982 qsize = CIM_IBQ_SIZE * 4 * sizeof(u32);983 rc = cudbg_get_buff(pdbg_init, dbg_buff, qsize, &temp_buff);984 if (rc)985 return rc;986 987 /* t4_read_cim_ibq will return no. of read words or error */988 no_of_read_words = t4_read_cim_ibq(padap, qid,989 (u32 *)temp_buff.data, qsize);990 /* no_of_read_words is less than or equal to 0 means error */991 if (no_of_read_words <= 0) {992 if (!no_of_read_words)993 rc = CUDBG_SYSTEM_ERROR;994 else995 rc = no_of_read_words;996 cudbg_err->sys_err = rc;997 cudbg_put_buff(pdbg_init, &temp_buff);998 return rc;999 }1000 return cudbg_write_and_release_buff(pdbg_init, &temp_buff, dbg_buff);1001}1002 1003int cudbg_collect_cim_ibq_tp0(struct cudbg_init *pdbg_init,1004 struct cudbg_buffer *dbg_buff,1005 struct cudbg_error *cudbg_err)1006{1007 return cudbg_read_cim_ibq(pdbg_init, dbg_buff, cudbg_err, 0);1008}1009 1010int cudbg_collect_cim_ibq_tp1(struct cudbg_init *pdbg_init,1011 struct cudbg_buffer *dbg_buff,1012 struct cudbg_error *cudbg_err)1013{1014 return cudbg_read_cim_ibq(pdbg_init, dbg_buff, cudbg_err, 1);1015}1016 1017int cudbg_collect_cim_ibq_ulp(struct cudbg_init *pdbg_init,1018 struct cudbg_buffer *dbg_buff,1019 struct cudbg_error *cudbg_err)1020{1021 return cudbg_read_cim_ibq(pdbg_init, dbg_buff, cudbg_err, 2);1022}1023 1024int cudbg_collect_cim_ibq_sge0(struct cudbg_init *pdbg_init,1025 struct cudbg_buffer *dbg_buff,1026 struct cudbg_error *cudbg_err)1027{1028 return cudbg_read_cim_ibq(pdbg_init, dbg_buff, cudbg_err, 3);1029}1030 1031int cudbg_collect_cim_ibq_sge1(struct cudbg_init *pdbg_init,1032 struct cudbg_buffer *dbg_buff,1033 struct cudbg_error *cudbg_err)1034{1035 return cudbg_read_cim_ibq(pdbg_init, dbg_buff, cudbg_err, 4);1036}1037 1038int cudbg_collect_cim_ibq_ncsi(struct cudbg_init *pdbg_init,1039 struct cudbg_buffer *dbg_buff,1040 struct cudbg_error *cudbg_err)1041{1042 return cudbg_read_cim_ibq(pdbg_init, dbg_buff, cudbg_err, 5);1043}1044 1045u32 cudbg_cim_obq_size(struct adapter *padap, int qid)1046{1047 u32 value;1048 1049 t4_write_reg(padap, CIM_QUEUE_CONFIG_REF_A, OBQSELECT_F |1050 QUENUMSELECT_V(qid));1051 value = t4_read_reg(padap, CIM_QUEUE_CONFIG_CTRL_A);1052 value = CIMQSIZE_G(value) * 64; /* size in number of words */1053 return value * sizeof(u32);1054}1055 1056static int cudbg_read_cim_obq(struct cudbg_init *pdbg_init,1057 struct cudbg_buffer *dbg_buff,1058 struct cudbg_error *cudbg_err, int qid)1059{1060 struct adapter *padap = pdbg_init->adap;1061 struct cudbg_buffer temp_buff = { 0 };1062 int no_of_read_words, rc = 0;1063 u32 qsize;1064 1065 /* collect CIM OBQ */1066 qsize = cudbg_cim_obq_size(padap, qid);1067 rc = cudbg_get_buff(pdbg_init, dbg_buff, qsize, &temp_buff);1068 if (rc)1069 return rc;1070 1071 /* t4_read_cim_obq will return no. of read words or error */1072 no_of_read_words = t4_read_cim_obq(padap, qid,1073 (u32 *)temp_buff.data, qsize);1074 /* no_of_read_words is less than or equal to 0 means error */1075 if (no_of_read_words <= 0) {1076 if (!no_of_read_words)1077 rc = CUDBG_SYSTEM_ERROR;1078 else1079 rc = no_of_read_words;1080 cudbg_err->sys_err = rc;1081 cudbg_put_buff(pdbg_init, &temp_buff);1082 return rc;1083 }1084 return cudbg_write_and_release_buff(pdbg_init, &temp_buff, dbg_buff);1085}1086 1087int cudbg_collect_cim_obq_ulp0(struct cudbg_init *pdbg_init,1088 struct cudbg_buffer *dbg_buff,1089 struct cudbg_error *cudbg_err)1090{1091 return cudbg_read_cim_obq(pdbg_init, dbg_buff, cudbg_err, 0);1092}1093 1094int cudbg_collect_cim_obq_ulp1(struct cudbg_init *pdbg_init,1095 struct cudbg_buffer *dbg_buff,1096 struct cudbg_error *cudbg_err)1097{1098 return cudbg_read_cim_obq(pdbg_init, dbg_buff, cudbg_err, 1);1099}1100 1101int cudbg_collect_cim_obq_ulp2(struct cudbg_init *pdbg_init,1102 struct cudbg_buffer *dbg_buff,1103 struct cudbg_error *cudbg_err)1104{1105 return cudbg_read_cim_obq(pdbg_init, dbg_buff, cudbg_err, 2);1106}1107 1108int cudbg_collect_cim_obq_ulp3(struct cudbg_init *pdbg_init,1109 struct cudbg_buffer *dbg_buff,1110 struct cudbg_error *cudbg_err)1111{1112 return cudbg_read_cim_obq(pdbg_init, dbg_buff, cudbg_err, 3);1113}1114 1115int cudbg_collect_cim_obq_sge(struct cudbg_init *pdbg_init,1116 struct cudbg_buffer *dbg_buff,1117 struct cudbg_error *cudbg_err)1118{1119 return cudbg_read_cim_obq(pdbg_init, dbg_buff, cudbg_err, 4);1120}1121 1122int cudbg_collect_cim_obq_ncsi(struct cudbg_init *pdbg_init,1123 struct cudbg_buffer *dbg_buff,1124 struct cudbg_error *cudbg_err)1125{1126 return cudbg_read_cim_obq(pdbg_init, dbg_buff, cudbg_err, 5);1127}1128 1129int cudbg_collect_obq_sge_rx_q0(struct cudbg_init *pdbg_init,1130 struct cudbg_buffer *dbg_buff,1131 struct cudbg_error *cudbg_err)1132{1133 return cudbg_read_cim_obq(pdbg_init, dbg_buff, cudbg_err, 6);1134}1135 1136int cudbg_collect_obq_sge_rx_q1(struct cudbg_init *pdbg_init,1137 struct cudbg_buffer *dbg_buff,1138 struct cudbg_error *cudbg_err)1139{1140 return cudbg_read_cim_obq(pdbg_init, dbg_buff, cudbg_err, 7);1141}1142 1143static int cudbg_meminfo_get_mem_index(struct adapter *padap,1144 struct cudbg_meminfo *mem_info,1145 u8 mem_type, u8 *idx)1146{1147 u8 i, flag;1148 1149 switch (mem_type) {1150 case MEM_EDC0:1151 flag = EDC0_FLAG;1152 break;1153 case MEM_EDC1:1154 flag = EDC1_FLAG;1155 break;1156 case MEM_MC0:1157 /* Some T5 cards have both MC0 and MC1. */1158 flag = is_t5(padap->params.chip) ? MC0_FLAG : MC_FLAG;1159 break;1160 case MEM_MC1:1161 flag = MC1_FLAG;1162 break;1163 case MEM_HMA:1164 flag = HMA_FLAG;1165 break;1166 default:1167 return CUDBG_STATUS_ENTITY_NOT_FOUND;1168 }1169 1170 for (i = 0; i < mem_info->avail_c; i++) {1171 if (mem_info->avail[i].idx == flag) {1172 *idx = i;1173 return 0;1174 }1175 }1176 1177 return CUDBG_STATUS_ENTITY_NOT_FOUND;1178}1179 1180/* Fetch the @region_name's start and end from @meminfo. */1181static int cudbg_get_mem_region(struct adapter *padap,1182 struct cudbg_meminfo *meminfo,1183 u8 mem_type, const char *region_name,1184 struct cudbg_mem_desc *mem_desc)1185{1186 u8 mc, found = 0;1187 u32 idx = 0;1188 int rc, i;1189 1190 rc = cudbg_meminfo_get_mem_index(padap, meminfo, mem_type, &mc);1191 if (rc)1192 return rc;1193 1194 i = match_string(cudbg_region, ARRAY_SIZE(cudbg_region), region_name);1195 if (i < 0)1196 return -EINVAL;1197 1198 idx = i;1199 for (i = 0; i < meminfo->mem_c; i++) {1200 if (meminfo->mem[i].idx >= ARRAY_SIZE(cudbg_region))1201 continue; /* Skip holes */1202 1203 if (!(meminfo->mem[i].limit))1204 meminfo->mem[i].limit =1205 i < meminfo->mem_c - 1 ?1206 meminfo->mem[i + 1].base - 1 : ~0;1207 1208 if (meminfo->mem[i].idx == idx) {1209 /* Check if the region exists in @mem_type memory */1210 if (meminfo->mem[i].base < meminfo->avail[mc].base &&1211 meminfo->mem[i].limit < meminfo->avail[mc].base)1212 return -EINVAL;1213 1214 if (meminfo->mem[i].base > meminfo->avail[mc].limit)1215 return -EINVAL;1216 1217 memcpy(mem_desc, &meminfo->mem[i],1218 sizeof(struct cudbg_mem_desc));1219 found = 1;1220 break;1221 }1222 }1223 if (!found)1224 return -EINVAL;1225 1226 return 0;1227}1228 1229/* Fetch and update the start and end of the requested memory region w.r.t 01230 * in the corresponding EDC/MC/HMA.1231 */1232static int cudbg_get_mem_relative(struct adapter *padap,1233 struct cudbg_meminfo *meminfo,1234 u8 mem_type, u32 *out_base, u32 *out_end)1235{1236 u8 mc_idx;1237 int rc;1238 1239 rc = cudbg_meminfo_get_mem_index(padap, meminfo, mem_type, &mc_idx);1240 if (rc)1241 return rc;1242 1243 if (*out_base < meminfo->avail[mc_idx].base)1244 *out_base = 0;1245 else1246 *out_base -= meminfo->avail[mc_idx].base;1247 1248 if (*out_end > meminfo->avail[mc_idx].limit)1249 *out_end = meminfo->avail[mc_idx].limit;1250 else1251 *out_end -= meminfo->avail[mc_idx].base;1252 1253 return 0;1254}1255 1256/* Get TX and RX Payload region */1257static int cudbg_get_payload_range(struct adapter *padap, u8 mem_type,1258 const char *region_name,1259 struct cudbg_region_info *payload)1260{1261 struct cudbg_mem_desc mem_desc = { 0 };1262 struct cudbg_meminfo meminfo;1263 int rc;1264 1265 rc = cudbg_fill_meminfo(padap, &meminfo);1266 if (rc)1267 return rc;1268 1269 rc = cudbg_get_mem_region(padap, &meminfo, mem_type, region_name,1270 &mem_desc);1271 if (rc) {1272 payload->exist = false;1273 return 0;1274 }1275 1276 payload->exist = true;1277 payload->start = mem_desc.base;1278 payload->end = mem_desc.limit;1279 1280 return cudbg_get_mem_relative(padap, &meminfo, mem_type,1281 &payload->start, &payload->end);1282}1283 1284static int cudbg_memory_read(struct cudbg_init *pdbg_init, int win,1285 int mtype, u32 addr, u32 len, void *hbuf)1286{1287 u32 win_pf, memoffset, mem_aperture, mem_base;1288 struct adapter *adap = pdbg_init->adap;1289 u32 pos, offset, resid;1290 u32 *res_buf;1291 u64 *buf;1292 int ret;1293 1294 /* Argument sanity checks ...1295 */1296 if (addr & 0x3 || (uintptr_t)hbuf & 0x3)1297 return -EINVAL;1298 1299 buf = (u64 *)hbuf;1300 1301 /* Try to do 64-bit reads. Residual will be handled later. */1302 resid = len & 0x7;1303 len -= resid;1304 1305 ret = t4_memory_rw_init(adap, win, mtype, &memoffset, &mem_base,1306 &mem_aperture);1307 if (ret)1308 return ret;1309 1310 addr = addr + memoffset;1311 win_pf = is_t4(adap->params.chip) ? 0 : PFNUM_V(adap->pf);1312 1313 pos = addr & ~(mem_aperture - 1);1314 offset = addr - pos;1315 1316 /* Set up initial PCI-E Memory Window to cover the start of our1317 * transfer.1318 */1319 t4_memory_update_win(adap, win, pos | win_pf);1320 1321 /* Transfer data from the adapter */1322 while (len > 0) {1323 *buf++ = le64_to_cpu((__force __le64)1324 t4_read_reg64(adap, mem_base + offset));1325 offset += sizeof(u64);1326 len -= sizeof(u64);1327 1328 /* If we've reached the end of our current window aperture,1329 * move the PCI-E Memory Window on to the next.1330 */1331 if (offset == mem_aperture) {1332 pos += mem_aperture;1333 offset = 0;1334 t4_memory_update_win(adap, win, pos | win_pf);1335 }1336 }1337 1338 res_buf = (u32 *)buf;1339 /* Read residual in 32-bit multiples */1340 while (resid > sizeof(u32)) {1341 *res_buf++ = le32_to_cpu((__force __le32)1342 t4_read_reg(adap, mem_base + offset));1343 offset += sizeof(u32);1344 resid -= sizeof(u32);1345 1346 /* If we've reached the end of our current window aperture,1347 * move the PCI-E Memory Window on to the next.1348 */1349 if (offset == mem_aperture) {1350 pos += mem_aperture;1351 offset = 0;1352 t4_memory_update_win(adap, win, pos | win_pf);1353 }1354 }1355 1356 /* Transfer residual < 32-bits */1357 if (resid)1358 t4_memory_rw_residual(adap, resid, mem_base + offset,1359 (u8 *)res_buf, T4_MEMORY_READ);1360 1361 return 0;1362}1363 1364#define CUDBG_YIELD_ITERATION 2561365 1366static int cudbg_read_fw_mem(struct cudbg_init *pdbg_init,1367 struct cudbg_buffer *dbg_buff, u8 mem_type,1368 unsigned long tot_len,1369 struct cudbg_error *cudbg_err)1370{1371 static const char * const region_name[] = { "Tx payload:",1372 "Rx payload:" };1373 unsigned long bytes, bytes_left, bytes_read = 0;1374 struct adapter *padap = pdbg_init->adap;1375 struct cudbg_buffer temp_buff = { 0 };1376 struct cudbg_region_info payload[2];1377 u32 yield_count = 0;1378 int rc = 0;1379 u8 i;1380 1381 /* Get TX/RX Payload region range if they exist */1382 memset(payload, 0, sizeof(payload));1383 for (i = 0; i < ARRAY_SIZE(region_name); i++) {1384 rc = cudbg_get_payload_range(padap, mem_type, region_name[i],1385 &payload[i]);1386 if (rc)1387 return rc;1388 1389 if (payload[i].exist) {1390 /* Align start and end to avoid wrap around */1391 payload[i].start = roundup(payload[i].start,1392 CUDBG_CHUNK_SIZE);1393 payload[i].end = rounddown(payload[i].end,1394 CUDBG_CHUNK_SIZE);1395 }1396 }1397 1398 bytes_left = tot_len;1399 while (bytes_left > 0) {1400 /* As MC size is huge and read through PIO access, this1401 * loop will hold cpu for a longer time. OS may think that1402 * the process is hanged and will generate CPU stall traces.1403 * So yield the cpu regularly.1404 */1405 yield_count++;1406 if (!(yield_count % CUDBG_YIELD_ITERATION))1407 schedule();1408 1409 bytes = min_t(unsigned long, bytes_left,1410 (unsigned long)CUDBG_CHUNK_SIZE);1411 rc = cudbg_get_buff(pdbg_init, dbg_buff, bytes, &temp_buff);1412 if (rc)1413 return rc;1414 1415 for (i = 0; i < ARRAY_SIZE(payload); i++)1416 if (payload[i].exist &&1417 bytes_read >= payload[i].start &&1418 bytes_read + bytes <= payload[i].end)1419 /* TX and RX Payload regions can't overlap */1420 goto skip_read;1421 1422 spin_lock(&padap->win0_lock);1423 rc = cudbg_memory_read(pdbg_init, MEMWIN_NIC, mem_type,1424 bytes_read, bytes, temp_buff.data);1425 spin_unlock(&padap->win0_lock);1426 if (rc) {1427 cudbg_err->sys_err = rc;1428 cudbg_put_buff(pdbg_init, &temp_buff);1429 return rc;1430 }1431 1432skip_read:1433 bytes_left -= bytes;1434 bytes_read += bytes;1435 rc = cudbg_write_and_release_buff(pdbg_init, &temp_buff,1436 dbg_buff);1437 if (rc) {1438 cudbg_put_buff(pdbg_init, &temp_buff);1439 return rc;1440 }1441 }1442 return rc;1443}1444 1445static void cudbg_t4_fwcache(struct cudbg_init *pdbg_init,1446 struct cudbg_error *cudbg_err)1447{1448 struct adapter *padap = pdbg_init->adap;1449 int rc;1450 1451 if (is_fw_attached(pdbg_init)) {1452 /* Flush uP dcache before reading edcX/mcX */1453 rc = t4_fwcache(padap, FW_PARAM_DEV_FWCACHE_FLUSH);1454 if (rc)1455 cudbg_err->sys_warn = rc;1456 }1457}1458 1459static int cudbg_mem_region_size(struct cudbg_init *pdbg_init,1460 struct cudbg_error *cudbg_err,1461 u8 mem_type, unsigned long *region_size)1462{1463 struct adapter *padap = pdbg_init->adap;1464 struct cudbg_meminfo mem_info;1465 u8 mc_idx;1466 int rc;1467 1468 memset(&mem_info, 0, sizeof(struct cudbg_meminfo));1469 rc = cudbg_fill_meminfo(padap, &mem_info);1470 if (rc) {1471 cudbg_err->sys_err = rc;1472 return rc;1473 }1474 1475 cudbg_t4_fwcache(pdbg_init, cudbg_err);1476 rc = cudbg_meminfo_get_mem_index(padap, &mem_info, mem_type, &mc_idx);1477 if (rc) {1478 cudbg_err->sys_err = rc;1479 return rc;1480 }1481 1482 if (region_size)1483 *region_size = mem_info.avail[mc_idx].limit -1484 mem_info.avail[mc_idx].base;1485 1486 return 0;1487}1488 1489static int cudbg_collect_mem_region(struct cudbg_init *pdbg_init,1490 struct cudbg_buffer *dbg_buff,1491 struct cudbg_error *cudbg_err,1492 u8 mem_type)1493{1494 unsigned long size = 0;1495 int rc;1496 1497 rc = cudbg_mem_region_size(pdbg_init, cudbg_err, mem_type, &size);1498 if (rc)1499 return rc;1500 1501 return cudbg_read_fw_mem(pdbg_init, dbg_buff, mem_type, size,1502 cudbg_err);1503}1504 1505int cudbg_collect_edc0_meminfo(struct cudbg_init *pdbg_init,1506 struct cudbg_buffer *dbg_buff,1507 struct cudbg_error *cudbg_err)1508{1509 return cudbg_collect_mem_region(pdbg_init, dbg_buff, cudbg_err,1510 MEM_EDC0);1511}1512 1513int cudbg_collect_edc1_meminfo(struct cudbg_init *pdbg_init,1514 struct cudbg_buffer *dbg_buff,1515 struct cudbg_error *cudbg_err)1516{1517 return cudbg_collect_mem_region(pdbg_init, dbg_buff, cudbg_err,1518 MEM_EDC1);1519}1520 1521int cudbg_collect_mc0_meminfo(struct cudbg_init *pdbg_init,1522 struct cudbg_buffer *dbg_buff,1523 struct cudbg_error *cudbg_err)1524{1525 return cudbg_collect_mem_region(pdbg_init, dbg_buff, cudbg_err,1526 MEM_MC0);1527}1528 1529int cudbg_collect_mc1_meminfo(struct cudbg_init *pdbg_init,1530 struct cudbg_buffer *dbg_buff,1531 struct cudbg_error *cudbg_err)1532{1533 return cudbg_collect_mem_region(pdbg_init, dbg_buff, cudbg_err,1534 MEM_MC1);1535}1536 1537int cudbg_collect_hma_meminfo(struct cudbg_init *pdbg_init,1538 struct cudbg_buffer *dbg_buff,1539 struct cudbg_error *cudbg_err)1540{1541 return cudbg_collect_mem_region(pdbg_init, dbg_buff, cudbg_err,1542 MEM_HMA);1543}1544 1545int cudbg_collect_rss(struct cudbg_init *pdbg_init,1546 struct cudbg_buffer *dbg_buff,1547 struct cudbg_error *cudbg_err)1548{1549 struct adapter *padap = pdbg_init->adap;1550 struct cudbg_buffer temp_buff = { 0 };1551 int rc, nentries;1552 1553 nentries = t4_chip_rss_size(padap);1554 rc = cudbg_get_buff(pdbg_init, dbg_buff, nentries * sizeof(u16),1555 &temp_buff);1556 if (rc)1557 return rc;1558 1559 rc = t4_read_rss(padap, (u16 *)temp_buff.data);1560 if (rc) {1561 cudbg_err->sys_err = rc;1562 cudbg_put_buff(pdbg_init, &temp_buff);1563 return rc;1564 }1565 return cudbg_write_and_release_buff(pdbg_init, &temp_buff, dbg_buff);1566}1567 1568int cudbg_collect_rss_vf_config(struct cudbg_init *pdbg_init,1569 struct cudbg_buffer *dbg_buff,1570 struct cudbg_error *cudbg_err)1571{1572 struct adapter *padap = pdbg_init->adap;1573 struct cudbg_buffer temp_buff = { 0 };1574 struct cudbg_rss_vf_conf *vfconf;1575 int vf, rc, vf_count;1576 1577 vf_count = padap->params.arch.vfcount;1578 rc = cudbg_get_buff(pdbg_init, dbg_buff,1579 vf_count * sizeof(struct cudbg_rss_vf_conf),1580 &temp_buff);1581 if (rc)1582 return rc;1583 1584 vfconf = (struct cudbg_rss_vf_conf *)temp_buff.data;1585 for (vf = 0; vf < vf_count; vf++)1586 t4_read_rss_vf_config(padap, vf, &vfconf[vf].rss_vf_vfl,1587 &vfconf[vf].rss_vf_vfh, true);1588 return cudbg_write_and_release_buff(pdbg_init, &temp_buff, dbg_buff);1589}1590 1591int cudbg_collect_path_mtu(struct cudbg_init *pdbg_init,1592 struct cudbg_buffer *dbg_buff,1593 struct cudbg_error *cudbg_err)1594{1595 struct adapter *padap = pdbg_init->adap;1596 struct cudbg_buffer temp_buff = { 0 };1597 int rc;1598 1599 rc = cudbg_get_buff(pdbg_init, dbg_buff, NMTUS * sizeof(u16),1600 &temp_buff);1601 if (rc)1602 return rc;1603 1604 t4_read_mtu_tbl(padap, (u16 *)temp_buff.data, NULL);1605 return cudbg_write_and_release_buff(pdbg_init, &temp_buff, dbg_buff);1606}1607 1608int cudbg_collect_pm_stats(struct cudbg_init *pdbg_init,1609 struct cudbg_buffer *dbg_buff,1610 struct cudbg_error *cudbg_err)1611{1612 struct adapter *padap = pdbg_init->adap;1613 struct cudbg_buffer temp_buff = { 0 };1614 struct cudbg_pm_stats *pm_stats_buff;1615 int rc;1616 1617 rc = cudbg_get_buff(pdbg_init, dbg_buff, sizeof(struct cudbg_pm_stats),1618 &temp_buff);1619 if (rc)1620 return rc;1621 1622 pm_stats_buff = (struct cudbg_pm_stats *)temp_buff.data;1623 t4_pmtx_get_stats(padap, pm_stats_buff->tx_cnt, pm_stats_buff->tx_cyc);1624 t4_pmrx_get_stats(padap, pm_stats_buff->rx_cnt, pm_stats_buff->rx_cyc);1625 return cudbg_write_and_release_buff(pdbg_init, &temp_buff, dbg_buff);1626}1627 1628int cudbg_collect_hw_sched(struct cudbg_init *pdbg_init,1629 struct cudbg_buffer *dbg_buff,1630 struct cudbg_error *cudbg_err)1631{1632 struct adapter *padap = pdbg_init->adap;1633 struct cudbg_buffer temp_buff = { 0 };1634 struct cudbg_hw_sched *hw_sched_buff;1635 int i, rc = 0;1636 1637 if (!padap->params.vpd.cclk)1638 return CUDBG_STATUS_CCLK_NOT_DEFINED;1639 1640 rc = cudbg_get_buff(pdbg_init, dbg_buff, sizeof(struct cudbg_hw_sched),1641 &temp_buff);1642 1643 if (rc)1644 return rc;1645 1646 hw_sched_buff = (struct cudbg_hw_sched *)temp_buff.data;1647 hw_sched_buff->map = t4_read_reg(padap, TP_TX_MOD_QUEUE_REQ_MAP_A);1648 hw_sched_buff->mode = TIMERMODE_G(t4_read_reg(padap, TP_MOD_CONFIG_A));1649 t4_read_pace_tbl(padap, hw_sched_buff->pace_tab);1650 for (i = 0; i < NTX_SCHED; ++i)1651 t4_get_tx_sched(padap, i, &hw_sched_buff->kbps[i],1652 &hw_sched_buff->ipg[i], true);1653 return cudbg_write_and_release_buff(pdbg_init, &temp_buff, dbg_buff);1654}1655 1656int cudbg_collect_tp_indirect(struct cudbg_init *pdbg_init,1657 struct cudbg_buffer *dbg_buff,1658 struct cudbg_error *cudbg_err)1659{1660 struct adapter *padap = pdbg_init->adap;1661 struct cudbg_buffer temp_buff = { 0 };1662 struct ireg_buf *ch_tp_pio;1663 int i, rc, n = 0;1664 u32 size;1665 1666 if (is_t5(padap->params.chip))1667 n = sizeof(t5_tp_pio_array) +1668 sizeof(t5_tp_tm_pio_array) +1669 sizeof(t5_tp_mib_index_array);1670 else1671 n = sizeof(t6_tp_pio_array) +1672 sizeof(t6_tp_tm_pio_array) +1673 sizeof(t6_tp_mib_index_array);1674 1675 n = n / (IREG_NUM_ELEM * sizeof(u32));1676 size = sizeof(struct ireg_buf) * n;1677 rc = cudbg_get_buff(pdbg_init, dbg_buff, size, &temp_buff);1678 if (rc)1679 return rc;1680 1681 ch_tp_pio = (struct ireg_buf *)temp_buff.data;1682 1683 /* TP_PIO */1684 if (is_t5(padap->params.chip))1685 n = sizeof(t5_tp_pio_array) / (IREG_NUM_ELEM * sizeof(u32));1686 else if (is_t6(padap->params.chip))1687 n = sizeof(t6_tp_pio_array) / (IREG_NUM_ELEM * sizeof(u32));1688 1689 for (i = 0; i < n; i++) {1690 struct ireg_field *tp_pio = &ch_tp_pio->tp_pio;1691 u32 *buff = ch_tp_pio->outbuf;1692 1693 if (is_t5(padap->params.chip)) {1694 tp_pio->ireg_addr = t5_tp_pio_array[i][0];1695 tp_pio->ireg_data = t5_tp_pio_array[i][1];1696 tp_pio->ireg_local_offset = t5_tp_pio_array[i][2];1697 tp_pio->ireg_offset_range = t5_tp_pio_array[i][3];1698 } else if (is_t6(padap->params.chip)) {1699 tp_pio->ireg_addr = t6_tp_pio_array[i][0];1700 tp_pio->ireg_data = t6_tp_pio_array[i][1];1701 tp_pio->ireg_local_offset = t6_tp_pio_array[i][2];1702 tp_pio->ireg_offset_range = t6_tp_pio_array[i][3];1703 }1704 t4_tp_pio_read(padap, buff, tp_pio->ireg_offset_range,1705 tp_pio->ireg_local_offset, true);1706 ch_tp_pio++;1707 }1708 1709 /* TP_TM_PIO */1710 if (is_t5(padap->params.chip))1711 n = sizeof(t5_tp_tm_pio_array) / (IREG_NUM_ELEM * sizeof(u32));1712 else if (is_t6(padap->params.chip))1713 n = sizeof(t6_tp_tm_pio_array) / (IREG_NUM_ELEM * sizeof(u32));1714 1715 for (i = 0; i < n; i++) {1716 struct ireg_field *tp_pio = &ch_tp_pio->tp_pio;1717 u32 *buff = ch_tp_pio->outbuf;1718 1719 if (is_t5(padap->params.chip)) {1720 tp_pio->ireg_addr = t5_tp_tm_pio_array[i][0];1721 tp_pio->ireg_data = t5_tp_tm_pio_array[i][1];1722 tp_pio->ireg_local_offset = t5_tp_tm_pio_array[i][2];1723 tp_pio->ireg_offset_range = t5_tp_tm_pio_array[i][3];1724 } else if (is_t6(padap->params.chip)) {1725 tp_pio->ireg_addr = t6_tp_tm_pio_array[i][0];1726 tp_pio->ireg_data = t6_tp_tm_pio_array[i][1];1727 tp_pio->ireg_local_offset = t6_tp_tm_pio_array[i][2];1728 tp_pio->ireg_offset_range = t6_tp_tm_pio_array[i][3];1729 }1730 t4_tp_tm_pio_read(padap, buff, tp_pio->ireg_offset_range,1731 tp_pio->ireg_local_offset, true);1732 ch_tp_pio++;1733 }1734 1735 /* TP_MIB_INDEX */1736 if (is_t5(padap->params.chip))1737 n = sizeof(t5_tp_mib_index_array) /1738 (IREG_NUM_ELEM * sizeof(u32));1739 else if (is_t6(padap->params.chip))1740 n = sizeof(t6_tp_mib_index_array) /1741 (IREG_NUM_ELEM * sizeof(u32));1742 1743 for (i = 0; i < n ; i++) {1744 struct ireg_field *tp_pio = &ch_tp_pio->tp_pio;1745 u32 *buff = ch_tp_pio->outbuf;1746 1747 if (is_t5(padap->params.chip)) {1748 tp_pio->ireg_addr = t5_tp_mib_index_array[i][0];1749 tp_pio->ireg_data = t5_tp_mib_index_array[i][1];1750 tp_pio->ireg_local_offset =1751 t5_tp_mib_index_array[i][2];1752 tp_pio->ireg_offset_range =1753 t5_tp_mib_index_array[i][3];1754 } else if (is_t6(padap->params.chip)) {1755 tp_pio->ireg_addr = t6_tp_mib_index_array[i][0];1756 tp_pio->ireg_data = t6_tp_mib_index_array[i][1];1757 tp_pio->ireg_local_offset =1758 t6_tp_mib_index_array[i][2];1759 tp_pio->ireg_offset_range =1760 t6_tp_mib_index_array[i][3];1761 }1762 t4_tp_mib_read(padap, buff, tp_pio->ireg_offset_range,1763 tp_pio->ireg_local_offset, true);1764 ch_tp_pio++;1765 }1766 return cudbg_write_and_release_buff(pdbg_init, &temp_buff, dbg_buff);1767}1768 1769static void cudbg_read_sge_qbase_indirect_reg(struct adapter *padap,1770 struct sge_qbase_reg_field *qbase,1771 u32 func, bool is_pf)1772{1773 u32 *buff, i;1774 1775 if (is_pf) {1776 buff = qbase->pf_data_value[func];1777 } else {1778 buff = qbase->vf_data_value[func];1779 /* In SGE_QBASE_INDEX,1780 * Entries 0->7 are PF0->7, Entries 8->263 are VFID0->256.1781 */1782 func += 8;1783 }1784 1785 t4_write_reg(padap, qbase->reg_addr, func);1786 for (i = 0; i < SGE_QBASE_DATA_REG_NUM; i++, buff++)1787 *buff = t4_read_reg(padap, qbase->reg_data[i]);1788}1789 1790int cudbg_collect_sge_indirect(struct cudbg_init *pdbg_init,1791 struct cudbg_buffer *dbg_buff,1792 struct cudbg_error *cudbg_err)1793{1794 struct adapter *padap = pdbg_init->adap;1795 struct cudbg_buffer temp_buff = { 0 };1796 struct sge_qbase_reg_field *sge_qbase;1797 struct ireg_buf *ch_sge_dbg;1798 u8 padap_running = 0;1799 int i, rc;1800 u32 size;1801 1802 /* Accessing SGE_QBASE_MAP[0-3] and SGE_QBASE_INDEX regs can1803 * lead to SGE missing doorbells under heavy traffic. So, only1804 * collect them when adapter is idle.1805 */1806 for_each_port(padap, i) {1807 padap_running = netif_running(padap->port[i]);1808 if (padap_running)1809 break;1810 }1811 1812 size = sizeof(*ch_sge_dbg) * 2;1813 if (!padap_running)1814 size += sizeof(*sge_qbase);1815 1816 rc = cudbg_get_buff(pdbg_init, dbg_buff, size, &temp_buff);1817 if (rc)1818 return rc;1819 1820 ch_sge_dbg = (struct ireg_buf *)temp_buff.data;1821 for (i = 0; i < 2; i++) {1822 struct ireg_field *sge_pio = &ch_sge_dbg->tp_pio;1823 u32 *buff = ch_sge_dbg->outbuf;1824 1825 sge_pio->ireg_addr = t5_sge_dbg_index_array[i][0];1826 sge_pio->ireg_data = t5_sge_dbg_index_array[i][1];1827 sge_pio->ireg_local_offset = t5_sge_dbg_index_array[i][2];1828 sge_pio->ireg_offset_range = t5_sge_dbg_index_array[i][3];1829 t4_read_indirect(padap,1830 sge_pio->ireg_addr,1831 sge_pio->ireg_data,1832 buff,1833 sge_pio->ireg_offset_range,1834 sge_pio->ireg_local_offset);1835 ch_sge_dbg++;1836 }1837 1838 if (CHELSIO_CHIP_VERSION(padap->params.chip) > CHELSIO_T5 &&1839 !padap_running) {1840 sge_qbase = (struct sge_qbase_reg_field *)ch_sge_dbg;1841 /* 1 addr reg SGE_QBASE_INDEX and 4 data reg1842 * SGE_QBASE_MAP[0-3]1843 */1844 sge_qbase->reg_addr = t6_sge_qbase_index_array[0];1845 for (i = 0; i < SGE_QBASE_DATA_REG_NUM; i++)1846 sge_qbase->reg_data[i] =1847 t6_sge_qbase_index_array[i + 1];1848 1849 for (i = 0; i <= PCIE_FW_MASTER_M; i++)1850 cudbg_read_sge_qbase_indirect_reg(padap, sge_qbase,1851 i, true);1852 1853 for (i = 0; i < padap->params.arch.vfcount; i++)1854 cudbg_read_sge_qbase_indirect_reg(padap, sge_qbase,1855 i, false);1856 1857 sge_qbase->vfcount = padap->params.arch.vfcount;1858 }1859 1860 return cudbg_write_and_release_buff(pdbg_init, &temp_buff, dbg_buff);1861}1862 1863int cudbg_collect_ulprx_la(struct cudbg_init *pdbg_init,1864 struct cudbg_buffer *dbg_buff,1865 struct cudbg_error *cudbg_err)1866{1867 struct adapter *padap = pdbg_init->adap;1868 struct cudbg_buffer temp_buff = { 0 };1869 struct cudbg_ulprx_la *ulprx_la_buff;1870 int rc;1871 1872 rc = cudbg_get_buff(pdbg_init, dbg_buff, sizeof(struct cudbg_ulprx_la),1873 &temp_buff);1874 if (rc)1875 return rc;1876 1877 ulprx_la_buff = (struct cudbg_ulprx_la *)temp_buff.data;1878 t4_ulprx_read_la(padap, (u32 *)ulprx_la_buff->data);1879 ulprx_la_buff->size = ULPRX_LA_SIZE;1880 return cudbg_write_and_release_buff(pdbg_init, &temp_buff, dbg_buff);1881}1882 1883int cudbg_collect_tp_la(struct cudbg_init *pdbg_init,1884 struct cudbg_buffer *dbg_buff,1885 struct cudbg_error *cudbg_err)1886{1887 struct adapter *padap = pdbg_init->adap;1888 struct cudbg_buffer temp_buff = { 0 };1889 struct cudbg_tp_la *tp_la_buff;1890 int size, rc;1891 1892 size = sizeof(struct cudbg_tp_la) + TPLA_SIZE * sizeof(u64);1893 rc = cudbg_get_buff(pdbg_init, dbg_buff, size, &temp_buff);1894 if (rc)1895 return rc;1896 1897 tp_la_buff = (struct cudbg_tp_la *)temp_buff.data;1898 tp_la_buff->mode = DBGLAMODE_G(t4_read_reg(padap, TP_DBG_LA_CONFIG_A));1899 t4_tp_read_la(padap, (u64 *)tp_la_buff->data, NULL);1900 return cudbg_write_and_release_buff(pdbg_init, &temp_buff, dbg_buff);1901}1902 1903int cudbg_collect_meminfo(struct cudbg_init *pdbg_init,1904 struct cudbg_buffer *dbg_buff,1905 struct cudbg_error *cudbg_err)1906{1907 struct adapter *padap = pdbg_init->adap;1908 struct cudbg_buffer temp_buff = { 0 };1909 struct cudbg_meminfo *meminfo_buff;1910 struct cudbg_ver_hdr *ver_hdr;1911 int rc;1912 1913 rc = cudbg_get_buff(pdbg_init, dbg_buff,1914 sizeof(struct cudbg_ver_hdr) +1915 sizeof(struct cudbg_meminfo),1916 &temp_buff);1917 if (rc)1918 return rc;1919 1920 ver_hdr = (struct cudbg_ver_hdr *)temp_buff.data;1921 ver_hdr->signature = CUDBG_ENTITY_SIGNATURE;1922 ver_hdr->revision = CUDBG_MEMINFO_REV;1923 ver_hdr->size = sizeof(struct cudbg_meminfo);1924 1925 meminfo_buff = (struct cudbg_meminfo *)(temp_buff.data +1926 sizeof(*ver_hdr));1927 rc = cudbg_fill_meminfo(padap, meminfo_buff);1928 if (rc) {1929 cudbg_err->sys_err = rc;1930 cudbg_put_buff(pdbg_init, &temp_buff);1931 return rc;1932 }1933 1934 return cudbg_write_and_release_buff(pdbg_init, &temp_buff, dbg_buff);1935}1936 1937int cudbg_collect_cim_pif_la(struct cudbg_init *pdbg_init,1938 struct cudbg_buffer *dbg_buff,1939 struct cudbg_error *cudbg_err)1940{1941 struct cudbg_cim_pif_la *cim_pif_la_buff;1942 struct adapter *padap = pdbg_init->adap;1943 struct cudbg_buffer temp_buff = { 0 };1944 int size, rc;1945 1946 size = sizeof(struct cudbg_cim_pif_la) +1947 2 * CIM_PIFLA_SIZE * 6 * sizeof(u32);1948 rc = cudbg_get_buff(pdbg_init, dbg_buff, size, &temp_buff);1949 if (rc)1950 return rc;1951 1952 cim_pif_la_buff = (struct cudbg_cim_pif_la *)temp_buff.data;1953 cim_pif_la_buff->size = CIM_PIFLA_SIZE;1954 t4_cim_read_pif_la(padap, (u32 *)cim_pif_la_buff->data,1955 (u32 *)cim_pif_la_buff->data + 6 * CIM_PIFLA_SIZE,1956 NULL, NULL);1957 return cudbg_write_and_release_buff(pdbg_init, &temp_buff, dbg_buff);1958}1959 1960int cudbg_collect_clk_info(struct cudbg_init *pdbg_init,1961 struct cudbg_buffer *dbg_buff,1962 struct cudbg_error *cudbg_err)1963{1964 struct adapter *padap = pdbg_init->adap;1965 struct cudbg_buffer temp_buff = { 0 };1966 struct cudbg_clk_info *clk_info_buff;1967 u64 tp_tick_us;1968 int rc;1969 1970 if (!padap->params.vpd.cclk)1971 return CUDBG_STATUS_CCLK_NOT_DEFINED;1972 1973 rc = cudbg_get_buff(pdbg_init, dbg_buff, sizeof(struct cudbg_clk_info),1974 &temp_buff);1975 if (rc)1976 return rc;1977 1978 clk_info_buff = (struct cudbg_clk_info *)temp_buff.data;1979 clk_info_buff->cclk_ps = 1000000000 / padap->params.vpd.cclk; /* psec */1980 clk_info_buff->res = t4_read_reg(padap, TP_TIMER_RESOLUTION_A);1981 clk_info_buff->tre = TIMERRESOLUTION_G(clk_info_buff->res);1982 clk_info_buff->dack_re = DELAYEDACKRESOLUTION_G(clk_info_buff->res);1983 tp_tick_us = (clk_info_buff->cclk_ps << clk_info_buff->tre) / 1000000;1984 1985 clk_info_buff->dack_timer =1986 (clk_info_buff->cclk_ps << clk_info_buff->dack_re) / 1000000 *1987 t4_read_reg(padap, TP_DACK_TIMER_A);1988 clk_info_buff->retransmit_min =1989 tp_tick_us * t4_read_reg(padap, TP_RXT_MIN_A);1990 clk_info_buff->retransmit_max =1991 tp_tick_us * t4_read_reg(padap, TP_RXT_MAX_A);1992 clk_info_buff->persist_timer_min =1993 tp_tick_us * t4_read_reg(padap, TP_PERS_MIN_A);1994 clk_info_buff->persist_timer_max =1995 tp_tick_us * t4_read_reg(padap, TP_PERS_MAX_A);1996 clk_info_buff->keepalive_idle_timer =1997 tp_tick_us * t4_read_reg(padap, TP_KEEP_IDLE_A);1998 clk_info_buff->keepalive_interval =1999 tp_tick_us * t4_read_reg(padap, TP_KEEP_INTVL_A);2000 clk_info_buff->initial_srtt =2001 tp_tick_us * INITSRTT_G(t4_read_reg(padap, TP_INIT_SRTT_A));2002 clk_info_buff->finwait2_timer =2003 tp_tick_us * t4_read_reg(padap, TP_FINWAIT2_TIMER_A);2004 2005 return cudbg_write_and_release_buff(pdbg_init, &temp_buff, dbg_buff);2006}2007 2008int cudbg_collect_pcie_indirect(struct cudbg_init *pdbg_init,2009 struct cudbg_buffer *dbg_buff,2010 struct cudbg_error *cudbg_err)2011{2012 struct adapter *padap = pdbg_init->adap;2013 struct cudbg_buffer temp_buff = { 0 };2014 struct ireg_buf *ch_pcie;2015 int i, rc, n;2016 u32 size;2017 2018 n = sizeof(t5_pcie_pdbg_array) / (IREG_NUM_ELEM * sizeof(u32));2019 size = sizeof(struct ireg_buf) * n * 2;2020 rc = cudbg_get_buff(pdbg_init, dbg_buff, size, &temp_buff);2021 if (rc)2022 return rc;2023 2024 ch_pcie = (struct ireg_buf *)temp_buff.data;2025 /* PCIE_PDBG */2026 for (i = 0; i < n; i++) {2027 struct ireg_field *pcie_pio = &ch_pcie->tp_pio;2028 u32 *buff = ch_pcie->outbuf;2029 2030 pcie_pio->ireg_addr = t5_pcie_pdbg_array[i][0];2031 pcie_pio->ireg_data = t5_pcie_pdbg_array[i][1];2032 pcie_pio->ireg_local_offset = t5_pcie_pdbg_array[i][2];2033 pcie_pio->ireg_offset_range = t5_pcie_pdbg_array[i][3];2034 t4_read_indirect(padap,2035 pcie_pio->ireg_addr,2036 pcie_pio->ireg_data,2037 buff,2038 pcie_pio->ireg_offset_range,2039 pcie_pio->ireg_local_offset);2040 ch_pcie++;2041 }2042 2043 /* PCIE_CDBG */2044 n = sizeof(t5_pcie_cdbg_array) / (IREG_NUM_ELEM * sizeof(u32));2045 for (i = 0; i < n; i++) {2046 struct ireg_field *pcie_pio = &ch_pcie->tp_pio;2047 u32 *buff = ch_pcie->outbuf;2048 2049 pcie_pio->ireg_addr = t5_pcie_cdbg_array[i][0];2050 pcie_pio->ireg_data = t5_pcie_cdbg_array[i][1];2051 pcie_pio->ireg_local_offset = t5_pcie_cdbg_array[i][2];2052 pcie_pio->ireg_offset_range = t5_pcie_cdbg_array[i][3];2053 t4_read_indirect(padap,2054 pcie_pio->ireg_addr,2055 pcie_pio->ireg_data,2056 buff,2057 pcie_pio->ireg_offset_range,2058 pcie_pio->ireg_local_offset);2059 ch_pcie++;2060 }2061 return cudbg_write_and_release_buff(pdbg_init, &temp_buff, dbg_buff);2062}2063 2064int cudbg_collect_pm_indirect(struct cudbg_init *pdbg_init,2065 struct cudbg_buffer *dbg_buff,2066 struct cudbg_error *cudbg_err)2067{2068 struct adapter *padap = pdbg_init->adap;2069 struct cudbg_buffer temp_buff = { 0 };2070 struct ireg_buf *ch_pm;2071 int i, rc, n;2072 u32 size;2073 2074 n = sizeof(t5_pm_rx_array) / (IREG_NUM_ELEM * sizeof(u32));2075 size = sizeof(struct ireg_buf) * n * 2;2076 rc = cudbg_get_buff(pdbg_init, dbg_buff, size, &temp_buff);2077 if (rc)2078 return rc;2079 2080 ch_pm = (struct ireg_buf *)temp_buff.data;2081 /* PM_RX */2082 for (i = 0; i < n; i++) {2083 struct ireg_field *pm_pio = &ch_pm->tp_pio;2084 u32 *buff = ch_pm->outbuf;2085 2086 pm_pio->ireg_addr = t5_pm_rx_array[i][0];2087 pm_pio->ireg_data = t5_pm_rx_array[i][1];2088 pm_pio->ireg_local_offset = t5_pm_rx_array[i][2];2089 pm_pio->ireg_offset_range = t5_pm_rx_array[i][3];2090 t4_read_indirect(padap,2091 pm_pio->ireg_addr,2092 pm_pio->ireg_data,2093 buff,2094 pm_pio->ireg_offset_range,2095 pm_pio->ireg_local_offset);2096 ch_pm++;2097 }2098 2099 /* PM_TX */2100 n = sizeof(t5_pm_tx_array) / (IREG_NUM_ELEM * sizeof(u32));2101 for (i = 0; i < n; i++) {2102 struct ireg_field *pm_pio = &ch_pm->tp_pio;2103 u32 *buff = ch_pm->outbuf;2104 2105 pm_pio->ireg_addr = t5_pm_tx_array[i][0];2106 pm_pio->ireg_data = t5_pm_tx_array[i][1];2107 pm_pio->ireg_local_offset = t5_pm_tx_array[i][2];2108 pm_pio->ireg_offset_range = t5_pm_tx_array[i][3];2109 t4_read_indirect(padap,2110 pm_pio->ireg_addr,2111 pm_pio->ireg_data,2112 buff,2113 pm_pio->ireg_offset_range,2114 pm_pio->ireg_local_offset);2115 ch_pm++;2116 }2117 return cudbg_write_and_release_buff(pdbg_init, &temp_buff, dbg_buff);2118}2119 2120int cudbg_collect_tid(struct cudbg_init *pdbg_init,2121 struct cudbg_buffer *dbg_buff,2122 struct cudbg_error *cudbg_err)2123{2124 struct adapter *padap = pdbg_init->adap;2125 struct cudbg_tid_info_region_rev1 *tid1;2126 struct cudbg_buffer temp_buff = { 0 };2127 struct cudbg_tid_info_region *tid;2128 u32 para[2], val[2];2129 int rc;2130 2131 rc = cudbg_get_buff(pdbg_init, dbg_buff,2132 sizeof(struct cudbg_tid_info_region_rev1),2133 &temp_buff);2134 if (rc)2135 return rc;2136 2137 tid1 = (struct cudbg_tid_info_region_rev1 *)temp_buff.data;2138 tid = &tid1->tid;2139 tid1->ver_hdr.signature = CUDBG_ENTITY_SIGNATURE;2140 tid1->ver_hdr.revision = CUDBG_TID_INFO_REV;2141 tid1->ver_hdr.size = sizeof(struct cudbg_tid_info_region_rev1) -2142 sizeof(struct cudbg_ver_hdr);2143 2144 /* If firmware is not attached/alive, use backdoor register2145 * access to collect dump.2146 */2147 if (!is_fw_attached(pdbg_init))2148 goto fill_tid;2149 2150#define FW_PARAM_PFVF_A(param) \2151 (FW_PARAMS_MNEM_V(FW_PARAMS_MNEM_PFVF) | \2152 FW_PARAMS_PARAM_X_V(FW_PARAMS_PARAM_PFVF_##param) | \2153 FW_PARAMS_PARAM_Y_V(0) | \2154 FW_PARAMS_PARAM_Z_V(0))2155 2156 para[0] = FW_PARAM_PFVF_A(ETHOFLD_START);2157 para[1] = FW_PARAM_PFVF_A(ETHOFLD_END);2158 rc = t4_query_params(padap, padap->mbox, padap->pf, 0, 2, para, val);2159 if (rc < 0) {2160 cudbg_err->sys_err = rc;2161 cudbg_put_buff(pdbg_init, &temp_buff);2162 return rc;2163 }2164 tid->uotid_base = val[0];2165 tid->nuotids = val[1] - val[0] + 1;2166 2167 if (is_t5(padap->params.chip)) {2168 tid->sb = t4_read_reg(padap, LE_DB_SERVER_INDEX_A) / 4;2169 } else if (is_t6(padap->params.chip)) {2170 tid1->tid_start =2171 t4_read_reg(padap, LE_DB_ACTIVE_TABLE_START_INDEX_A);2172 tid->sb = t4_read_reg(padap, LE_DB_SRVR_START_INDEX_A);2173 2174 para[0] = FW_PARAM_PFVF_A(HPFILTER_START);2175 para[1] = FW_PARAM_PFVF_A(HPFILTER_END);2176 rc = t4_query_params(padap, padap->mbox, padap->pf, 0, 2,2177 para, val);2178 if (rc < 0) {2179 cudbg_err->sys_err = rc;2180 cudbg_put_buff(pdbg_init, &temp_buff);2181 return rc;2182 }2183 tid->hpftid_base = val[0];2184 tid->nhpftids = val[1] - val[0] + 1;2185 }2186 2187#undef FW_PARAM_PFVF_A2188 2189fill_tid:2190 tid->ntids = padap->tids.ntids;2191 tid->nstids = padap->tids.nstids;2192 tid->stid_base = padap->tids.stid_base;2193 tid->hash_base = padap->tids.hash_base;2194 2195 tid->natids = padap->tids.natids;2196 tid->nftids = padap->tids.nftids;2197 tid->ftid_base = padap->tids.ftid_base;2198 tid->aftid_base = padap->tids.aftid_base;2199 tid->aftid_end = padap->tids.aftid_end;2200 2201 tid->sftid_base = padap->tids.sftid_base;2202 tid->nsftids = padap->tids.nsftids;2203 2204 tid->flags = padap->flags;2205 tid->le_db_conf = t4_read_reg(padap, LE_DB_CONFIG_A);2206 tid->ip_users = t4_read_reg(padap, LE_DB_ACT_CNT_IPV4_A);2207 tid->ipv6_users = t4_read_reg(padap, LE_DB_ACT_CNT_IPV6_A);2208 2209 return cudbg_write_and_release_buff(pdbg_init, &temp_buff, dbg_buff);2210}2211 2212int cudbg_collect_pcie_config(struct cudbg_init *pdbg_init,2213 struct cudbg_buffer *dbg_buff,2214 struct cudbg_error *cudbg_err)2215{2216 struct adapter *padap = pdbg_init->adap;2217 struct cudbg_buffer temp_buff = { 0 };2218 u32 size, *value, j;2219 int i, rc, n;2220 2221 size = sizeof(u32) * CUDBG_NUM_PCIE_CONFIG_REGS;2222 n = sizeof(t5_pcie_config_array) / (2 * sizeof(u32));2223 rc = cudbg_get_buff(pdbg_init, dbg_buff, size, &temp_buff);2224 if (rc)2225 return rc;2226 2227 value = (u32 *)temp_buff.data;2228 for (i = 0; i < n; i++) {2229 for (j = t5_pcie_config_array[i][0];2230 j <= t5_pcie_config_array[i][1]; j += 4) {2231 t4_hw_pci_read_cfg4(padap, j, value);2232 value++;2233 }2234 }2235 return cudbg_write_and_release_buff(pdbg_init, &temp_buff, dbg_buff);2236}2237 2238static int cudbg_sge_ctxt_check_valid(u32 *buf, int type)2239{2240 int index, bit, bit_pos = 0;2241 2242 switch (type) {2243 case CTXT_EGRESS:2244 bit_pos = 176;2245 break;2246 case CTXT_INGRESS:2247 bit_pos = 141;2248 break;2249 case CTXT_FLM:2250 bit_pos = 89;2251 break;2252 }2253 index = bit_pos / 32;2254 bit = bit_pos % 32;2255 return buf[index] & (1U << bit);2256}2257 2258static int cudbg_get_ctxt_region_info(struct adapter *padap,2259 struct cudbg_region_info *ctx_info,2260 u8 *mem_type)2261{2262 struct cudbg_mem_desc mem_desc;2263 struct cudbg_meminfo meminfo;2264 u32 i, j, value, found;2265 u8 flq;2266 int rc;2267 2268 rc = cudbg_fill_meminfo(padap, &meminfo);2269 if (rc)2270 return rc;2271 2272 /* Get EGRESS and INGRESS context region size */2273 for (i = CTXT_EGRESS; i <= CTXT_INGRESS; i++) {2274 found = 0;2275 memset(&mem_desc, 0, sizeof(struct cudbg_mem_desc));2276 for (j = 0; j < ARRAY_SIZE(meminfo.avail); j++) {2277 rc = cudbg_get_mem_region(padap, &meminfo, j,2278 cudbg_region[i],2279 &mem_desc);2280 if (!rc) {2281 found = 1;2282 rc = cudbg_get_mem_relative(padap, &meminfo, j,2283 &mem_desc.base,2284 &mem_desc.limit);2285 if (rc) {2286 ctx_info[i].exist = false;2287 break;2288 }2289 ctx_info[i].exist = true;2290 ctx_info[i].start = mem_desc.base;2291 ctx_info[i].end = mem_desc.limit;2292 mem_type[i] = j;2293 break;2294 }2295 }2296 if (!found)2297 ctx_info[i].exist = false;2298 }2299 2300 /* Get FLM and CNM max qid. */2301 value = t4_read_reg(padap, SGE_FLM_CFG_A);2302 2303 /* Get number of data freelist queues */2304 flq = HDRSTARTFLQ_G(value);2305 ctx_info[CTXT_FLM].exist = true;2306 ctx_info[CTXT_FLM].end = (CUDBG_MAX_FL_QIDS >> flq) * SGE_CTXT_SIZE;2307 2308 /* The number of CONM contexts are same as number of freelist2309 * queues.2310 */2311 ctx_info[CTXT_CNM].exist = true;2312 ctx_info[CTXT_CNM].end = ctx_info[CTXT_FLM].end;2313 2314 return 0;2315}2316 2317int cudbg_dump_context_size(struct adapter *padap)2318{2319 struct cudbg_region_info region_info[CTXT_CNM + 1] = { {0} };2320 u8 mem_type[CTXT_INGRESS + 1] = { 0 };2321 u32 i, size = 0;2322 int rc;2323 2324 /* Get max valid qid for each type of queue */2325 rc = cudbg_get_ctxt_region_info(padap, region_info, mem_type);2326 if (rc)2327 return rc;2328 2329 for (i = 0; i < CTXT_CNM; i++) {2330 if (!region_info[i].exist) {2331 if (i == CTXT_EGRESS || i == CTXT_INGRESS)2332 size += CUDBG_LOWMEM_MAX_CTXT_QIDS *2333 SGE_CTXT_SIZE;2334 continue;2335 }2336 2337 size += (region_info[i].end - region_info[i].start + 1) /2338 SGE_CTXT_SIZE;2339 }2340 return size * sizeof(struct cudbg_ch_cntxt);2341}2342 2343static void cudbg_read_sge_ctxt(struct cudbg_init *pdbg_init, u32 cid,2344 enum ctxt_type ctype, u32 *data)2345{2346 struct adapter *padap = pdbg_init->adap;2347 int rc = -1;2348 2349 /* Under heavy traffic, the SGE Queue contexts registers will be2350 * frequently accessed by firmware.2351 *2352 * To avoid conflicts with firmware, always ask firmware to fetch2353 * the SGE Queue contexts via mailbox. On failure, fallback to2354 * accessing hardware registers directly.2355 */2356 if (is_fw_attached(pdbg_init))2357 rc = t4_sge_ctxt_rd(padap, padap->mbox, cid, ctype, data);2358 if (rc)2359 t4_sge_ctxt_rd_bd(padap, cid, ctype, data);2360}2361 2362static void cudbg_get_sge_ctxt_fw(struct cudbg_init *pdbg_init, u32 max_qid,2363 u8 ctxt_type,2364 struct cudbg_ch_cntxt **out_buff)2365{2366 struct cudbg_ch_cntxt *buff = *out_buff;2367 int rc;2368 u32 j;2369 2370 for (j = 0; j < max_qid; j++) {2371 cudbg_read_sge_ctxt(pdbg_init, j, ctxt_type, buff->data);2372 rc = cudbg_sge_ctxt_check_valid(buff->data, ctxt_type);2373 if (!rc)2374 continue;2375 2376 buff->cntxt_type = ctxt_type;2377 buff->cntxt_id = j;2378 buff++;2379 if (ctxt_type == CTXT_FLM) {2380 cudbg_read_sge_ctxt(pdbg_init, j, CTXT_CNM, buff->data);2381 buff->cntxt_type = CTXT_CNM;2382 buff->cntxt_id = j;2383 buff++;2384 }2385 }2386 2387 *out_buff = buff;2388}2389 2390int cudbg_collect_dump_context(struct cudbg_init *pdbg_init,2391 struct cudbg_buffer *dbg_buff,2392 struct cudbg_error *cudbg_err)2393{2394 struct cudbg_region_info region_info[CTXT_CNM + 1] = { {0} };2395 struct adapter *padap = pdbg_init->adap;2396 u32 j, size, max_ctx_size, max_ctx_qid;2397 u8 mem_type[CTXT_INGRESS + 1] = { 0 };2398 struct cudbg_buffer temp_buff = { 0 };2399 struct cudbg_ch_cntxt *buff;2400 u8 *ctx_buf;2401 u8 i, k;2402 int rc;2403 2404 /* Get max valid qid for each type of queue */2405 rc = cudbg_get_ctxt_region_info(padap, region_info, mem_type);2406 if (rc)2407 return rc;2408 2409 rc = cudbg_dump_context_size(padap);2410 if (rc <= 0)2411 return CUDBG_STATUS_ENTITY_NOT_FOUND;2412 2413 size = rc;2414 rc = cudbg_get_buff(pdbg_init, dbg_buff, size, &temp_buff);2415 if (rc)2416 return rc;2417 2418 /* Get buffer with enough space to read the biggest context2419 * region in memory.2420 */2421 max_ctx_size = max(region_info[CTXT_EGRESS].end -2422 region_info[CTXT_EGRESS].start + 1,2423 region_info[CTXT_INGRESS].end -2424 region_info[CTXT_INGRESS].start + 1);2425 2426 ctx_buf = kvzalloc(max_ctx_size, GFP_KERNEL);2427 if (!ctx_buf) {2428 cudbg_put_buff(pdbg_init, &temp_buff);2429 return -ENOMEM;2430 }2431 2432 buff = (struct cudbg_ch_cntxt *)temp_buff.data;2433 2434 /* Collect EGRESS and INGRESS context data.2435 * In case of failures, fallback to collecting via FW or2436 * backdoor access.2437 */2438 for (i = CTXT_EGRESS; i <= CTXT_INGRESS; i++) {2439 if (!region_info[i].exist) {2440 max_ctx_qid = CUDBG_LOWMEM_MAX_CTXT_QIDS;2441 cudbg_get_sge_ctxt_fw(pdbg_init, max_ctx_qid, i,2442 &buff);2443 continue;2444 }2445 2446 max_ctx_size = region_info[i].end - region_info[i].start + 1;2447 max_ctx_qid = max_ctx_size / SGE_CTXT_SIZE;2448 2449 /* If firmware is not attached/alive, use backdoor register2450 * access to collect dump.2451 */2452 if (is_fw_attached(pdbg_init)) {2453 t4_sge_ctxt_flush(padap, padap->mbox, i);2454 2455 rc = t4_memory_rw(padap, MEMWIN_NIC, mem_type[i],2456 region_info[i].start, max_ctx_size,2457 (__be32 *)ctx_buf, 1);2458 }2459 2460 if (rc || !is_fw_attached(pdbg_init)) {2461 max_ctx_qid = CUDBG_LOWMEM_MAX_CTXT_QIDS;2462 cudbg_get_sge_ctxt_fw(pdbg_init, max_ctx_qid, i,2463 &buff);2464 continue;2465 }2466 2467 for (j = 0; j < max_ctx_qid; j++) {2468 __be64 *dst_off;2469 u64 *src_off;2470 2471 src_off = (u64 *)(ctx_buf + j * SGE_CTXT_SIZE);2472 dst_off = (__be64 *)buff->data;2473 2474 /* The data is stored in 64-bit cpu order. Convert it2475 * to big endian before parsing.2476 */2477 for (k = 0; k < SGE_CTXT_SIZE / sizeof(u64); k++)2478 dst_off[k] = cpu_to_be64(src_off[k]);2479 2480 rc = cudbg_sge_ctxt_check_valid(buff->data, i);2481 if (!rc)2482 continue;2483 2484 buff->cntxt_type = i;2485 buff->cntxt_id = j;2486 buff++;2487 }2488 }2489 2490 kvfree(ctx_buf);2491 2492 /* Collect FREELIST and CONGESTION MANAGER contexts */2493 max_ctx_size = region_info[CTXT_FLM].end -2494 region_info[CTXT_FLM].start + 1;2495 max_ctx_qid = max_ctx_size / SGE_CTXT_SIZE;2496 /* Since FLM and CONM are 1-to-1 mapped, the below function2497 * will fetch both FLM and CONM contexts.2498 */2499 cudbg_get_sge_ctxt_fw(pdbg_init, max_ctx_qid, CTXT_FLM, &buff);2500 2501 return cudbg_write_and_release_buff(pdbg_init, &temp_buff, dbg_buff);2502}2503 2504static inline void cudbg_tcamxy2valmask(u64 x, u64 y, u8 *addr, u64 *mask)2505{2506 *mask = x | y;2507 y = (__force u64)cpu_to_be64(y);2508 memcpy(addr, (char *)&y + 2, ETH_ALEN);2509}2510 2511static void cudbg_mps_rpl_backdoor(struct adapter *padap,2512 struct fw_ldst_mps_rplc *mps_rplc)2513{2514 if (is_t5(padap->params.chip)) {2515 mps_rplc->rplc255_224 = htonl(t4_read_reg(padap,2516 MPS_VF_RPLCT_MAP3_A));2517 mps_rplc->rplc223_192 = htonl(t4_read_reg(padap,2518 MPS_VF_RPLCT_MAP2_A));2519 mps_rplc->rplc191_160 = htonl(t4_read_reg(padap,2520 MPS_VF_RPLCT_MAP1_A));2521 mps_rplc->rplc159_128 = htonl(t4_read_reg(padap,2522 MPS_VF_RPLCT_MAP0_A));2523 } else {2524 mps_rplc->rplc255_224 = htonl(t4_read_reg(padap,2525 MPS_VF_RPLCT_MAP7_A));2526 mps_rplc->rplc223_192 = htonl(t4_read_reg(padap,2527 MPS_VF_RPLCT_MAP6_A));2528 mps_rplc->rplc191_160 = htonl(t4_read_reg(padap,2529 MPS_VF_RPLCT_MAP5_A));2530 mps_rplc->rplc159_128 = htonl(t4_read_reg(padap,2531 MPS_VF_RPLCT_MAP4_A));2532 }2533 mps_rplc->rplc127_96 = htonl(t4_read_reg(padap, MPS_VF_RPLCT_MAP3_A));2534 mps_rplc->rplc95_64 = htonl(t4_read_reg(padap, MPS_VF_RPLCT_MAP2_A));2535 mps_rplc->rplc63_32 = htonl(t4_read_reg(padap, MPS_VF_RPLCT_MAP1_A));2536 mps_rplc->rplc31_0 = htonl(t4_read_reg(padap, MPS_VF_RPLCT_MAP0_A));2537}2538 2539static int cudbg_collect_tcam_index(struct cudbg_init *pdbg_init,2540 struct cudbg_mps_tcam *tcam, u32 idx)2541{2542 struct adapter *padap = pdbg_init->adap;2543 u64 tcamy, tcamx, val;2544 u32 ctl, data2;2545 int rc = 0;2546 2547 if (CHELSIO_CHIP_VERSION(padap->params.chip) >= CHELSIO_T6) {2548 /* CtlReqID - 1: use Host Driver Requester ID2549 * CtlCmdType - 0: Read, 1: Write2550 * CtlTcamSel - 0: TCAM0, 1: TCAM12551 * CtlXYBitSel- 0: Y bit, 1: X bit2552 */2553 2554 /* Read tcamy */2555 ctl = CTLREQID_V(1) | CTLCMDTYPE_V(0) | CTLXYBITSEL_V(0);2556 if (idx < 256)2557 ctl |= CTLTCAMINDEX_V(idx) | CTLTCAMSEL_V(0);2558 else2559 ctl |= CTLTCAMINDEX_V(idx - 256) | CTLTCAMSEL_V(1);2560 2561 t4_write_reg(padap, MPS_CLS_TCAM_DATA2_CTL_A, ctl);2562 val = t4_read_reg(padap, MPS_CLS_TCAM_RDATA1_REQ_ID1_A);2563 tcamy = DMACH_G(val) << 32;2564 tcamy |= t4_read_reg(padap, MPS_CLS_TCAM_RDATA0_REQ_ID1_A);2565 data2 = t4_read_reg(padap, MPS_CLS_TCAM_RDATA2_REQ_ID1_A);2566 tcam->lookup_type = DATALKPTYPE_G(data2);2567 2568 /* 0 - Outer header, 1 - Inner header2569 * [71:48] bit locations are overloaded for2570 * outer vs. inner lookup types.2571 */2572 if (tcam->lookup_type && tcam->lookup_type != DATALKPTYPE_M) {2573 /* Inner header VNI */2574 tcam->vniy = (data2 & DATAVIDH2_F) | DATAVIDH1_G(data2);2575 tcam->vniy = (tcam->vniy << 16) | VIDL_G(val);2576 tcam->dip_hit = data2 & DATADIPHIT_F;2577 } else {2578 tcam->vlan_vld = data2 & DATAVIDH2_F;2579 tcam->ivlan = VIDL_G(val);2580 }2581 2582 tcam->port_num = DATAPORTNUM_G(data2);2583 2584 /* Read tcamx. Change the control param */2585 ctl |= CTLXYBITSEL_V(1);2586 t4_write_reg(padap, MPS_CLS_TCAM_DATA2_CTL_A, ctl);2587 val = t4_read_reg(padap, MPS_CLS_TCAM_RDATA1_REQ_ID1_A);2588 tcamx = DMACH_G(val) << 32;2589 tcamx |= t4_read_reg(padap, MPS_CLS_TCAM_RDATA0_REQ_ID1_A);2590 data2 = t4_read_reg(padap, MPS_CLS_TCAM_RDATA2_REQ_ID1_A);2591 if (tcam->lookup_type && tcam->lookup_type != DATALKPTYPE_M) {2592 /* Inner header VNI mask */2593 tcam->vnix = (data2 & DATAVIDH2_F) | DATAVIDH1_G(data2);2594 tcam->vnix = (tcam->vnix << 16) | VIDL_G(val);2595 }2596 } else {2597 tcamy = t4_read_reg64(padap, MPS_CLS_TCAM_Y_L(idx));2598 tcamx = t4_read_reg64(padap, MPS_CLS_TCAM_X_L(idx));2599 }2600 2601 /* If no entry, return */2602 if (tcamx & tcamy)2603 return rc;2604 2605 tcam->cls_lo = t4_read_reg(padap, MPS_CLS_SRAM_L(idx));2606 tcam->cls_hi = t4_read_reg(padap, MPS_CLS_SRAM_H(idx));2607 2608 if (is_t5(padap->params.chip))2609 tcam->repli = (tcam->cls_lo & REPLICATE_F);2610 else if (is_t6(padap->params.chip))2611 tcam->repli = (tcam->cls_lo & T6_REPLICATE_F);2612 2613 if (tcam->repli) {2614 struct fw_ldst_cmd ldst_cmd;2615 struct fw_ldst_mps_rplc mps_rplc;2616 2617 memset(&ldst_cmd, 0, sizeof(ldst_cmd));2618 ldst_cmd.op_to_addrspace =2619 htonl(FW_CMD_OP_V(FW_LDST_CMD) |2620 FW_CMD_REQUEST_F | FW_CMD_READ_F |2621 FW_LDST_CMD_ADDRSPACE_V(FW_LDST_ADDRSPC_MPS));2622 ldst_cmd.cycles_to_len16 = htonl(FW_LEN16(ldst_cmd));2623 ldst_cmd.u.mps.rplc.fid_idx =2624 htons(FW_LDST_CMD_FID_V(FW_LDST_MPS_RPLC) |2625 FW_LDST_CMD_IDX_V(idx));2626 2627 /* If firmware is not attached/alive, use backdoor register2628 * access to collect dump.2629 */2630 if (is_fw_attached(pdbg_init))2631 rc = t4_wr_mbox(padap, padap->mbox, &ldst_cmd,2632 sizeof(ldst_cmd), &ldst_cmd);2633 2634 if (rc || !is_fw_attached(pdbg_init)) {2635 cudbg_mps_rpl_backdoor(padap, &mps_rplc);2636 /* Ignore error since we collected directly from2637 * reading registers.2638 */2639 rc = 0;2640 } else {2641 mps_rplc = ldst_cmd.u.mps.rplc;2642 }2643 2644 tcam->rplc[0] = ntohl(mps_rplc.rplc31_0);2645 tcam->rplc[1] = ntohl(mps_rplc.rplc63_32);2646 tcam->rplc[2] = ntohl(mps_rplc.rplc95_64);2647 tcam->rplc[3] = ntohl(mps_rplc.rplc127_96);2648 if (padap->params.arch.mps_rplc_size > CUDBG_MAX_RPLC_SIZE) {2649 tcam->rplc[4] = ntohl(mps_rplc.rplc159_128);2650 tcam->rplc[5] = ntohl(mps_rplc.rplc191_160);2651 tcam->rplc[6] = ntohl(mps_rplc.rplc223_192);2652 tcam->rplc[7] = ntohl(mps_rplc.rplc255_224);2653 }2654 }2655 cudbg_tcamxy2valmask(tcamx, tcamy, tcam->addr, &tcam->mask);2656 tcam->idx = idx;2657 tcam->rplc_size = padap->params.arch.mps_rplc_size;2658 return rc;2659}2660 2661int cudbg_collect_mps_tcam(struct cudbg_init *pdbg_init,2662 struct cudbg_buffer *dbg_buff,2663 struct cudbg_error *cudbg_err)2664{2665 struct adapter *padap = pdbg_init->adap;2666 struct cudbg_buffer temp_buff = { 0 };2667 u32 size = 0, i, n, total_size = 0;2668 struct cudbg_mps_tcam *tcam;2669 int rc;2670 2671 n = padap->params.arch.mps_tcam_size;2672 size = sizeof(struct cudbg_mps_tcam) * n;2673 rc = cudbg_get_buff(pdbg_init, dbg_buff, size, &temp_buff);2674 if (rc)2675 return rc;2676 2677 tcam = (struct cudbg_mps_tcam *)temp_buff.data;2678 for (i = 0; i < n; i++) {2679 rc = cudbg_collect_tcam_index(pdbg_init, tcam, i);2680 if (rc) {2681 cudbg_err->sys_err = rc;2682 cudbg_put_buff(pdbg_init, &temp_buff);2683 return rc;2684 }2685 total_size += sizeof(struct cudbg_mps_tcam);2686 tcam++;2687 }2688 2689 if (!total_size) {2690 rc = CUDBG_SYSTEM_ERROR;2691 cudbg_err->sys_err = rc;2692 cudbg_put_buff(pdbg_init, &temp_buff);2693 return rc;2694 }2695 return cudbg_write_and_release_buff(pdbg_init, &temp_buff, dbg_buff);2696}2697 2698int cudbg_collect_vpd_data(struct cudbg_init *pdbg_init,2699 struct cudbg_buffer *dbg_buff,2700 struct cudbg_error *cudbg_err)2701{2702 struct adapter *padap = pdbg_init->adap;2703 struct cudbg_buffer temp_buff = { 0 };2704 char vpd_str[CUDBG_VPD_VER_LEN + 1];2705 struct cudbg_vpd_data *vpd_data;2706 struct vpd_params vpd = { 0 };2707 u32 vpd_vers, fw_vers;2708 int rc;2709 2710 rc = t4_get_raw_vpd_params(padap, &vpd);2711 if (rc)2712 return rc;2713 2714 rc = t4_get_fw_version(padap, &fw_vers);2715 if (rc)2716 return rc;2717 2718 rc = cudbg_read_vpd_reg(padap, CUDBG_VPD_VER_ADDR, CUDBG_VPD_VER_LEN,2719 vpd_str);2720 if (rc)2721 return rc;2722 2723 vpd_str[CUDBG_VPD_VER_LEN] = '\0';2724 rc = kstrtouint(vpd_str, 0, &vpd_vers);2725 if (rc)2726 return rc;2727 2728 rc = cudbg_get_buff(pdbg_init, dbg_buff, sizeof(struct cudbg_vpd_data),2729 &temp_buff);2730 if (rc)2731 return rc;2732 2733 vpd_data = (struct cudbg_vpd_data *)temp_buff.data;2734 memcpy(vpd_data->sn, vpd.sn, SERNUM_LEN + 1);2735 memcpy(vpd_data->bn, vpd.pn, PN_LEN + 1);2736 memcpy(vpd_data->na, vpd.na, MACADDR_LEN + 1);2737 memcpy(vpd_data->mn, vpd.id, ID_LEN + 1);2738 vpd_data->scfg_vers = t4_read_reg(padap, PCIE_STATIC_SPARE2_A);2739 vpd_data->vpd_vers = vpd_vers;2740 vpd_data->fw_major = FW_HDR_FW_VER_MAJOR_G(fw_vers);2741 vpd_data->fw_minor = FW_HDR_FW_VER_MINOR_G(fw_vers);2742 vpd_data->fw_micro = FW_HDR_FW_VER_MICRO_G(fw_vers);2743 vpd_data->fw_build = FW_HDR_FW_VER_BUILD_G(fw_vers);2744 return cudbg_write_and_release_buff(pdbg_init, &temp_buff, dbg_buff);2745}2746 2747static int cudbg_read_tid(struct cudbg_init *pdbg_init, u32 tid,2748 struct cudbg_tid_data *tid_data)2749{2750 struct adapter *padap = pdbg_init->adap;2751 int i, cmd_retry = 8;2752 u32 val;2753 2754 /* Fill REQ_DATA regs with 0's */2755 for (i = 0; i < NUM_LE_DB_DBGI_REQ_DATA_INSTANCES; i++)2756 t4_write_reg(padap, LE_DB_DBGI_REQ_DATA_A + (i << 2), 0);2757 2758 /* Write DBIG command */2759 val = DBGICMD_V(4) | DBGITID_V(tid);2760 t4_write_reg(padap, LE_DB_DBGI_REQ_TCAM_CMD_A, val);2761 tid_data->dbig_cmd = val;2762 2763 val = DBGICMDSTRT_F | DBGICMDMODE_V(1); /* LE mode */2764 t4_write_reg(padap, LE_DB_DBGI_CONFIG_A, val);2765 tid_data->dbig_conf = val;2766 2767 /* Poll the DBGICMDBUSY bit */2768 val = 1;2769 while (val) {2770 val = t4_read_reg(padap, LE_DB_DBGI_CONFIG_A);2771 val = val & DBGICMDBUSY_F;2772 cmd_retry--;2773 if (!cmd_retry)2774 return CUDBG_SYSTEM_ERROR;2775 }2776 2777 /* Check RESP status */2778 val = t4_read_reg(padap, LE_DB_DBGI_RSP_STATUS_A);2779 tid_data->dbig_rsp_stat = val;2780 if (!(val & 1))2781 return CUDBG_SYSTEM_ERROR;2782 2783 /* Read RESP data */2784 for (i = 0; i < NUM_LE_DB_DBGI_RSP_DATA_INSTANCES; i++)2785 tid_data->data[i] = t4_read_reg(padap,2786 LE_DB_DBGI_RSP_DATA_A +2787 (i << 2));2788 tid_data->tid = tid;2789 return 0;2790}2791 2792static int cudbg_get_le_type(u32 tid, struct cudbg_tcam tcam_region)2793{2794 int type = LE_ET_UNKNOWN;2795 2796 if (tid < tcam_region.server_start)2797 type = LE_ET_TCAM_CON;2798 else if (tid < tcam_region.filter_start)2799 type = LE_ET_TCAM_SERVER;2800 else if (tid < tcam_region.clip_start)2801 type = LE_ET_TCAM_FILTER;2802 else if (tid < tcam_region.routing_start)2803 type = LE_ET_TCAM_CLIP;2804 else if (tid < tcam_region.tid_hash_base)2805 type = LE_ET_TCAM_ROUTING;2806 else if (tid < tcam_region.max_tid)2807 type = LE_ET_HASH_CON;2808 else2809 type = LE_ET_INVALID_TID;2810 2811 return type;2812}2813 2814static int cudbg_is_ipv6_entry(struct cudbg_tid_data *tid_data,2815 struct cudbg_tcam tcam_region)2816{2817 int ipv6 = 0;2818 int le_type;2819 2820 le_type = cudbg_get_le_type(tid_data->tid, tcam_region);2821 if (tid_data->tid & 1)2822 return 0;2823 2824 if (le_type == LE_ET_HASH_CON) {2825 ipv6 = tid_data->data[16] & 0x8000;2826 } else if (le_type == LE_ET_TCAM_CON) {2827 ipv6 = tid_data->data[16] & 0x8000;2828 if (ipv6)2829 ipv6 = tid_data->data[9] == 0x00C00000;2830 } else {2831 ipv6 = 0;2832 }2833 return ipv6;2834}2835 2836void cudbg_fill_le_tcam_info(struct adapter *padap,2837 struct cudbg_tcam *tcam_region)2838{2839 u32 value;2840 2841 /* Get the LE regions */2842 value = t4_read_reg(padap, LE_DB_TID_HASHBASE_A); /* hash base index */2843 tcam_region->tid_hash_base = value;2844 2845 /* Get routing table index */2846 value = t4_read_reg(padap, LE_DB_ROUTING_TABLE_INDEX_A);2847 tcam_region->routing_start = value;2848 2849 /* Get clip table index. For T6 there is separate CLIP TCAM */2850 if (is_t6(padap->params.chip))2851 value = t4_read_reg(padap, LE_DB_CLCAM_TID_BASE_A);2852 else2853 value = t4_read_reg(padap, LE_DB_CLIP_TABLE_INDEX_A);2854 tcam_region->clip_start = value;2855 2856 /* Get filter table index */2857 value = t4_read_reg(padap, LE_DB_FILTER_TABLE_INDEX_A);2858 tcam_region->filter_start = value;2859 2860 /* Get server table index */2861 value = t4_read_reg(padap, LE_DB_SERVER_INDEX_A);2862 tcam_region->server_start = value;2863 2864 /* Check whether hash is enabled and calculate the max tids */2865 value = t4_read_reg(padap, LE_DB_CONFIG_A);2866 if ((value >> HASHEN_S) & 1) {2867 value = t4_read_reg(padap, LE_DB_HASH_CONFIG_A);2868 if (CHELSIO_CHIP_VERSION(padap->params.chip) > CHELSIO_T5) {2869 tcam_region->max_tid = (value & 0xFFFFF) +2870 tcam_region->tid_hash_base;2871 } else {2872 value = HASHTIDSIZE_G(value);2873 value = 1 << value;2874 tcam_region->max_tid = value +2875 tcam_region->tid_hash_base;2876 }2877 } else { /* hash not enabled */2878 if (is_t6(padap->params.chip))2879 tcam_region->max_tid = (value & ASLIPCOMPEN_F) ?2880 CUDBG_MAX_TID_COMP_EN :2881 CUDBG_MAX_TID_COMP_DIS;2882 else2883 tcam_region->max_tid = CUDBG_MAX_TCAM_TID;2884 }2885 2886 if (is_t6(padap->params.chip))2887 tcam_region->max_tid += CUDBG_T6_CLIP;2888}2889 2890int cudbg_collect_le_tcam(struct cudbg_init *pdbg_init,2891 struct cudbg_buffer *dbg_buff,2892 struct cudbg_error *cudbg_err)2893{2894 struct adapter *padap = pdbg_init->adap;2895 struct cudbg_buffer temp_buff = { 0 };2896 struct cudbg_tcam tcam_region = { 0 };2897 struct cudbg_tid_data *tid_data;2898 u32 bytes = 0;2899 int rc, size;2900 u32 i;2901 2902 cudbg_fill_le_tcam_info(padap, &tcam_region);2903 2904 size = sizeof(struct cudbg_tid_data) * tcam_region.max_tid;2905 size += sizeof(struct cudbg_tcam);2906 rc = cudbg_get_buff(pdbg_init, dbg_buff, size, &temp_buff);2907 if (rc)2908 return rc;2909 2910 memcpy(temp_buff.data, &tcam_region, sizeof(struct cudbg_tcam));2911 bytes = sizeof(struct cudbg_tcam);2912 tid_data = (struct cudbg_tid_data *)(temp_buff.data + bytes);2913 /* read all tid */2914 for (i = 0; i < tcam_region.max_tid; ) {2915 rc = cudbg_read_tid(pdbg_init, i, tid_data);2916 if (rc) {2917 cudbg_err->sys_warn = CUDBG_STATUS_PARTIAL_DATA;2918 /* Update tcam header and exit */2919 tcam_region.max_tid = i;2920 memcpy(temp_buff.data, &tcam_region,2921 sizeof(struct cudbg_tcam));2922 goto out;2923 }2924 2925 if (cudbg_is_ipv6_entry(tid_data, tcam_region)) {2926 /* T6 CLIP TCAM: ipv6 takes 4 entries */2927 if (is_t6(padap->params.chip) &&2928 i >= tcam_region.clip_start &&2929 i < tcam_region.clip_start + CUDBG_T6_CLIP)2930 i += 4;2931 else /* Main TCAM: ipv6 takes two tids */2932 i += 2;2933 } else {2934 i++;2935 }2936 2937 tid_data++;2938 bytes += sizeof(struct cudbg_tid_data);2939 }2940 2941out:2942 return cudbg_write_and_release_buff(pdbg_init, &temp_buff, dbg_buff);2943}2944 2945int cudbg_collect_cctrl(struct cudbg_init *pdbg_init,2946 struct cudbg_buffer *dbg_buff,2947 struct cudbg_error *cudbg_err)2948{2949 struct adapter *padap = pdbg_init->adap;2950 struct cudbg_buffer temp_buff = { 0 };2951 u32 size;2952 int rc;2953 2954 size = sizeof(u16) * NMTUS * NCCTRL_WIN;2955 rc = cudbg_get_buff(pdbg_init, dbg_buff, size, &temp_buff);2956 if (rc)2957 return rc;2958 2959 t4_read_cong_tbl(padap, (void *)temp_buff.data);2960 return cudbg_write_and_release_buff(pdbg_init, &temp_buff, dbg_buff);2961}2962 2963int cudbg_collect_ma_indirect(struct cudbg_init *pdbg_init,2964 struct cudbg_buffer *dbg_buff,2965 struct cudbg_error *cudbg_err)2966{2967 struct adapter *padap = pdbg_init->adap;2968 struct cudbg_buffer temp_buff = { 0 };2969 struct ireg_buf *ma_indr;2970 int i, rc, n;2971 u32 size, j;2972 2973 if (CHELSIO_CHIP_VERSION(padap->params.chip) < CHELSIO_T6)2974 return CUDBG_STATUS_ENTITY_NOT_FOUND;2975 2976 n = sizeof(t6_ma_ireg_array) / (IREG_NUM_ELEM * sizeof(u32));2977 size = sizeof(struct ireg_buf) * n * 2;2978 rc = cudbg_get_buff(pdbg_init, dbg_buff, size, &temp_buff);2979 if (rc)2980 return rc;2981 2982 ma_indr = (struct ireg_buf *)temp_buff.data;2983 for (i = 0; i < n; i++) {2984 struct ireg_field *ma_fli = &ma_indr->tp_pio;2985 u32 *buff = ma_indr->outbuf;2986 2987 ma_fli->ireg_addr = t6_ma_ireg_array[i][0];2988 ma_fli->ireg_data = t6_ma_ireg_array[i][1];2989 ma_fli->ireg_local_offset = t6_ma_ireg_array[i][2];2990 ma_fli->ireg_offset_range = t6_ma_ireg_array[i][3];2991 t4_read_indirect(padap, ma_fli->ireg_addr, ma_fli->ireg_data,2992 buff, ma_fli->ireg_offset_range,2993 ma_fli->ireg_local_offset);2994 ma_indr++;2995 }2996 2997 n = sizeof(t6_ma_ireg_array2) / (IREG_NUM_ELEM * sizeof(u32));2998 for (i = 0; i < n; i++) {2999 struct ireg_field *ma_fli = &ma_indr->tp_pio;3000 u32 *buff = ma_indr->outbuf;3001 3002 ma_fli->ireg_addr = t6_ma_ireg_array2[i][0];3003 ma_fli->ireg_data = t6_ma_ireg_array2[i][1];3004 ma_fli->ireg_local_offset = t6_ma_ireg_array2[i][2];3005 for (j = 0; j < t6_ma_ireg_array2[i][3]; j++) {3006 t4_read_indirect(padap, ma_fli->ireg_addr,3007 ma_fli->ireg_data, buff, 1,3008 ma_fli->ireg_local_offset);3009 buff++;3010 ma_fli->ireg_local_offset += 0x20;3011 }3012 ma_indr++;3013 }3014 return cudbg_write_and_release_buff(pdbg_init, &temp_buff, dbg_buff);3015}3016 3017int cudbg_collect_ulptx_la(struct cudbg_init *pdbg_init,3018 struct cudbg_buffer *dbg_buff,3019 struct cudbg_error *cudbg_err)3020{3021 struct adapter *padap = pdbg_init->adap;3022 struct cudbg_buffer temp_buff = { 0 };3023 struct cudbg_ulptx_la *ulptx_la_buff;3024 struct cudbg_ver_hdr *ver_hdr;3025 u32 i, j;3026 int rc;3027 3028 rc = cudbg_get_buff(pdbg_init, dbg_buff,3029 sizeof(struct cudbg_ver_hdr) +3030 sizeof(struct cudbg_ulptx_la),3031 &temp_buff);3032 if (rc)3033 return rc;3034 3035 ver_hdr = (struct cudbg_ver_hdr *)temp_buff.data;3036 ver_hdr->signature = CUDBG_ENTITY_SIGNATURE;3037 ver_hdr->revision = CUDBG_ULPTX_LA_REV;3038 ver_hdr->size = sizeof(struct cudbg_ulptx_la);3039 3040 ulptx_la_buff = (struct cudbg_ulptx_la *)(temp_buff.data +3041 sizeof(*ver_hdr));3042 for (i = 0; i < CUDBG_NUM_ULPTX; i++) {3043 ulptx_la_buff->rdptr[i] = t4_read_reg(padap,3044 ULP_TX_LA_RDPTR_0_A +3045 0x10 * i);3046 ulptx_la_buff->wrptr[i] = t4_read_reg(padap,3047 ULP_TX_LA_WRPTR_0_A +3048 0x10 * i);3049 ulptx_la_buff->rddata[i] = t4_read_reg(padap,3050 ULP_TX_LA_RDDATA_0_A +3051 0x10 * i);3052 for (j = 0; j < CUDBG_NUM_ULPTX_READ; j++)3053 ulptx_la_buff->rd_data[i][j] =3054 t4_read_reg(padap,3055 ULP_TX_LA_RDDATA_0_A + 0x10 * i);3056 }3057 3058 for (i = 0; i < CUDBG_NUM_ULPTX_ASIC_READ; i++) {3059 t4_write_reg(padap, ULP_TX_ASIC_DEBUG_CTRL_A, 0x1);3060 ulptx_la_buff->rdptr_asic[i] =3061 t4_read_reg(padap, ULP_TX_ASIC_DEBUG_CTRL_A);3062 ulptx_la_buff->rddata_asic[i][0] =3063 t4_read_reg(padap, ULP_TX_ASIC_DEBUG_0_A);3064 ulptx_la_buff->rddata_asic[i][1] =3065 t4_read_reg(padap, ULP_TX_ASIC_DEBUG_1_A);3066 ulptx_la_buff->rddata_asic[i][2] =3067 t4_read_reg(padap, ULP_TX_ASIC_DEBUG_2_A);3068 ulptx_la_buff->rddata_asic[i][3] =3069 t4_read_reg(padap, ULP_TX_ASIC_DEBUG_3_A);3070 ulptx_la_buff->rddata_asic[i][4] =3071 t4_read_reg(padap, ULP_TX_ASIC_DEBUG_4_A);3072 ulptx_la_buff->rddata_asic[i][5] =3073 t4_read_reg(padap, PM_RX_BASE_ADDR);3074 }3075 3076 return cudbg_write_and_release_buff(pdbg_init, &temp_buff, dbg_buff);3077}3078 3079int cudbg_collect_up_cim_indirect(struct cudbg_init *pdbg_init,3080 struct cudbg_buffer *dbg_buff,3081 struct cudbg_error *cudbg_err)3082{3083 struct adapter *padap = pdbg_init->adap;3084 struct cudbg_buffer temp_buff = { 0 };3085 u32 local_offset, local_range;3086 struct ireg_buf *up_cim;3087 u32 size, j, iter;3088 u32 instance = 0;3089 int i, rc, n;3090 3091 if (is_t5(padap->params.chip))3092 n = sizeof(t5_up_cim_reg_array) /3093 ((IREG_NUM_ELEM + 1) * sizeof(u32));3094 else if (is_t6(padap->params.chip))3095 n = sizeof(t6_up_cim_reg_array) /3096 ((IREG_NUM_ELEM + 1) * sizeof(u32));3097 else3098 return CUDBG_STATUS_NOT_IMPLEMENTED;3099 3100 size = sizeof(struct ireg_buf) * n;3101 rc = cudbg_get_buff(pdbg_init, dbg_buff, size, &temp_buff);3102 if (rc)3103 return rc;3104 3105 up_cim = (struct ireg_buf *)temp_buff.data;3106 for (i = 0; i < n; i++) {3107 struct ireg_field *up_cim_reg = &up_cim->tp_pio;3108 u32 *buff = up_cim->outbuf;3109 3110 if (is_t5(padap->params.chip)) {3111 up_cim_reg->ireg_addr = t5_up_cim_reg_array[i][0];3112 up_cim_reg->ireg_data = t5_up_cim_reg_array[i][1];3113 up_cim_reg->ireg_local_offset =3114 t5_up_cim_reg_array[i][2];3115 up_cim_reg->ireg_offset_range =3116 t5_up_cim_reg_array[i][3];3117 instance = t5_up_cim_reg_array[i][4];3118 } else if (is_t6(padap->params.chip)) {3119 up_cim_reg->ireg_addr = t6_up_cim_reg_array[i][0];3120 up_cim_reg->ireg_data = t6_up_cim_reg_array[i][1];3121 up_cim_reg->ireg_local_offset =3122 t6_up_cim_reg_array[i][2];3123 up_cim_reg->ireg_offset_range =3124 t6_up_cim_reg_array[i][3];3125 instance = t6_up_cim_reg_array[i][4];3126 }3127 3128 switch (instance) {3129 case NUM_CIM_CTL_TSCH_CHANNEL_INSTANCES:3130 iter = up_cim_reg->ireg_offset_range;3131 local_offset = 0x120;3132 local_range = 1;3133 break;3134 case NUM_CIM_CTL_TSCH_CHANNEL_TSCH_CLASS_INSTANCES:3135 iter = up_cim_reg->ireg_offset_range;3136 local_offset = 0x10;3137 local_range = 1;3138 break;3139 default:3140 iter = 1;3141 local_offset = 0;3142 local_range = up_cim_reg->ireg_offset_range;3143 break;3144 }3145 3146 for (j = 0; j < iter; j++, buff++) {3147 rc = t4_cim_read(padap,3148 up_cim_reg->ireg_local_offset +3149 (j * local_offset), local_range, buff);3150 if (rc) {3151 cudbg_put_buff(pdbg_init, &temp_buff);3152 return rc;3153 }3154 }3155 up_cim++;3156 }3157 return cudbg_write_and_release_buff(pdbg_init, &temp_buff, dbg_buff);3158}3159 3160int cudbg_collect_pbt_tables(struct cudbg_init *pdbg_init,3161 struct cudbg_buffer *dbg_buff,3162 struct cudbg_error *cudbg_err)3163{3164 struct adapter *padap = pdbg_init->adap;3165 struct cudbg_buffer temp_buff = { 0 };3166 struct cudbg_pbt_tables *pbt;3167 int i, rc;3168 u32 addr;3169 3170 rc = cudbg_get_buff(pdbg_init, dbg_buff,3171 sizeof(struct cudbg_pbt_tables),3172 &temp_buff);3173 if (rc)3174 return rc;3175 3176 pbt = (struct cudbg_pbt_tables *)temp_buff.data;3177 /* PBT dynamic entries */3178 addr = CUDBG_CHAC_PBT_ADDR;3179 for (i = 0; i < CUDBG_PBT_DYNAMIC_ENTRIES; i++) {3180 rc = t4_cim_read(padap, addr + (i * 4), 1,3181 &pbt->pbt_dynamic[i]);3182 if (rc) {3183 cudbg_err->sys_err = rc;3184 cudbg_put_buff(pdbg_init, &temp_buff);3185 return rc;3186 }3187 }3188 3189 /* PBT static entries */3190 /* static entries start when bit 6 is set */3191 addr = CUDBG_CHAC_PBT_ADDR + (1 << 6);3192 for (i = 0; i < CUDBG_PBT_STATIC_ENTRIES; i++) {3193 rc = t4_cim_read(padap, addr + (i * 4), 1,3194 &pbt->pbt_static[i]);3195 if (rc) {3196 cudbg_err->sys_err = rc;3197 cudbg_put_buff(pdbg_init, &temp_buff);3198 return rc;3199 }3200 }3201 3202 /* LRF entries */3203 addr = CUDBG_CHAC_PBT_LRF;3204 for (i = 0; i < CUDBG_LRF_ENTRIES; i++) {3205 rc = t4_cim_read(padap, addr + (i * 4), 1,3206 &pbt->lrf_table[i]);3207 if (rc) {3208 cudbg_err->sys_err = rc;3209 cudbg_put_buff(pdbg_init, &temp_buff);3210 return rc;3211 }3212 }3213 3214 /* PBT data entries */3215 addr = CUDBG_CHAC_PBT_DATA;3216 for (i = 0; i < CUDBG_PBT_DATA_ENTRIES; i++) {3217 rc = t4_cim_read(padap, addr + (i * 4), 1,3218 &pbt->pbt_data[i]);3219 if (rc) {3220 cudbg_err->sys_err = rc;3221 cudbg_put_buff(pdbg_init, &temp_buff);3222 return rc;3223 }3224 }3225 return cudbg_write_and_release_buff(pdbg_init, &temp_buff, dbg_buff);3226}3227 3228int cudbg_collect_mbox_log(struct cudbg_init *pdbg_init,3229 struct cudbg_buffer *dbg_buff,3230 struct cudbg_error *cudbg_err)3231{3232 struct adapter *padap = pdbg_init->adap;3233 struct cudbg_mbox_log *mboxlog = NULL;3234 struct cudbg_buffer temp_buff = { 0 };3235 struct mbox_cmd_log *log = NULL;3236 struct mbox_cmd *entry;3237 unsigned int entry_idx;3238 u16 mbox_cmds;3239 int i, k, rc;3240 u64 flit;3241 u32 size;3242 3243 log = padap->mbox_log;3244 mbox_cmds = padap->mbox_log->size;3245 size = sizeof(struct cudbg_mbox_log) * mbox_cmds;3246 rc = cudbg_get_buff(pdbg_init, dbg_buff, size, &temp_buff);3247 if (rc)3248 return rc;3249 3250 mboxlog = (struct cudbg_mbox_log *)temp_buff.data;3251 for (k = 0; k < mbox_cmds; k++) {3252 entry_idx = log->cursor + k;3253 if (entry_idx >= log->size)3254 entry_idx -= log->size;3255 3256 entry = mbox_cmd_log_entry(log, entry_idx);3257 /* skip over unused entries */3258 if (entry->timestamp == 0)3259 continue;3260 3261 memcpy(&mboxlog->entry, entry, sizeof(struct mbox_cmd));3262 for (i = 0; i < MBOX_LEN / 8; i++) {3263 flit = entry->cmd[i];3264 mboxlog->hi[i] = (u32)(flit >> 32);3265 mboxlog->lo[i] = (u32)flit;3266 }3267 mboxlog++;3268 }3269 return cudbg_write_and_release_buff(pdbg_init, &temp_buff, dbg_buff);3270}3271 3272int cudbg_collect_hma_indirect(struct cudbg_init *pdbg_init,3273 struct cudbg_buffer *dbg_buff,3274 struct cudbg_error *cudbg_err)3275{3276 struct adapter *padap = pdbg_init->adap;3277 struct cudbg_buffer temp_buff = { 0 };3278 struct ireg_buf *hma_indr;3279 int i, rc, n;3280 u32 size;3281 3282 if (CHELSIO_CHIP_VERSION(padap->params.chip) < CHELSIO_T6)3283 return CUDBG_STATUS_ENTITY_NOT_FOUND;3284 3285 n = sizeof(t6_hma_ireg_array) / (IREG_NUM_ELEM * sizeof(u32));3286 size = sizeof(struct ireg_buf) * n;3287 rc = cudbg_get_buff(pdbg_init, dbg_buff, size, &temp_buff);3288 if (rc)3289 return rc;3290 3291 hma_indr = (struct ireg_buf *)temp_buff.data;3292 for (i = 0; i < n; i++) {3293 struct ireg_field *hma_fli = &hma_indr->tp_pio;3294 u32 *buff = hma_indr->outbuf;3295 3296 hma_fli->ireg_addr = t6_hma_ireg_array[i][0];3297 hma_fli->ireg_data = t6_hma_ireg_array[i][1];3298 hma_fli->ireg_local_offset = t6_hma_ireg_array[i][2];3299 hma_fli->ireg_offset_range = t6_hma_ireg_array[i][3];3300 t4_read_indirect(padap, hma_fli->ireg_addr, hma_fli->ireg_data,3301 buff, hma_fli->ireg_offset_range,3302 hma_fli->ireg_local_offset);3303 hma_indr++;3304 }3305 return cudbg_write_and_release_buff(pdbg_init, &temp_buff, dbg_buff);3306}3307 3308void cudbg_fill_qdesc_num_and_size(const struct adapter *padap,3309 u32 *num, u32 *size)3310{3311 u32 tot_entries = 0, tot_size = 0;3312 3313 /* NIC TXQ, RXQ, FLQ, and CTRLQ */3314 tot_entries += MAX_ETH_QSETS * 3;3315 tot_entries += MAX_CTRL_QUEUES;3316 3317 tot_size += MAX_ETH_QSETS * MAX_TXQ_ENTRIES * MAX_TXQ_DESC_SIZE;3318 tot_size += MAX_ETH_QSETS * MAX_RSPQ_ENTRIES * MAX_RXQ_DESC_SIZE;3319 tot_size += MAX_ETH_QSETS * MAX_RX_BUFFERS * MAX_FL_DESC_SIZE;3320 tot_size += MAX_CTRL_QUEUES * MAX_CTRL_TXQ_ENTRIES *3321 MAX_CTRL_TXQ_DESC_SIZE;3322 3323 /* FW_EVTQ and INTRQ */3324 tot_entries += INGQ_EXTRAS;3325 tot_size += INGQ_EXTRAS * MAX_RSPQ_ENTRIES * MAX_RXQ_DESC_SIZE;3326 3327 /* PTP_TXQ */3328 tot_entries += 1;3329 tot_size += MAX_TXQ_ENTRIES * MAX_TXQ_DESC_SIZE;3330 3331 /* ULD TXQ, RXQ, and FLQ */3332 tot_entries += CXGB4_TX_MAX * MAX_OFLD_QSETS;3333 tot_entries += CXGB4_ULD_MAX * MAX_ULD_QSETS * 2;3334 3335 tot_size += CXGB4_TX_MAX * MAX_OFLD_QSETS * MAX_TXQ_ENTRIES *3336 MAX_TXQ_DESC_SIZE;3337 tot_size += CXGB4_ULD_MAX * MAX_ULD_QSETS * MAX_RSPQ_ENTRIES *3338 MAX_RXQ_DESC_SIZE;3339 tot_size += CXGB4_ULD_MAX * MAX_ULD_QSETS * MAX_RX_BUFFERS *3340 MAX_FL_DESC_SIZE;3341 3342 /* ULD CIQ */3343 tot_entries += CXGB4_ULD_MAX * MAX_ULD_QSETS;3344 tot_size += CXGB4_ULD_MAX * MAX_ULD_QSETS * SGE_MAX_IQ_SIZE *3345 MAX_RXQ_DESC_SIZE;3346 3347 /* ETHOFLD TXQ, RXQ, and FLQ */3348 tot_entries += MAX_OFLD_QSETS * 3;3349 tot_size += MAX_OFLD_QSETS * MAX_TXQ_ENTRIES * MAX_TXQ_DESC_SIZE;3350 3351 tot_size += sizeof(struct cudbg_ver_hdr) +3352 sizeof(struct cudbg_qdesc_info) +3353 sizeof(struct cudbg_qdesc_entry) * tot_entries;3354 3355 if (num)3356 *num = tot_entries;3357 3358 if (size)3359 *size = tot_size;3360}3361 3362int cudbg_collect_qdesc(struct cudbg_init *pdbg_init,3363 struct cudbg_buffer *dbg_buff,3364 struct cudbg_error *cudbg_err)3365{3366 u32 num_queues = 0, tot_entries = 0, size = 0;3367 struct adapter *padap = pdbg_init->adap;3368 struct cudbg_buffer temp_buff = { 0 };3369 struct cudbg_qdesc_entry *qdesc_entry;3370 struct cudbg_qdesc_info *qdesc_info;3371 struct cudbg_ver_hdr *ver_hdr;3372 struct sge *s = &padap->sge;3373 u32 i, j, cur_off, tot_len;3374 u8 *data;3375 int rc;3376 3377 cudbg_fill_qdesc_num_and_size(padap, &tot_entries, &size);3378 size = min_t(u32, size, CUDBG_DUMP_BUFF_SIZE);3379 tot_len = size;3380 data = kvzalloc(size, GFP_KERNEL);3381 if (!data)3382 return -ENOMEM;3383 3384 ver_hdr = (struct cudbg_ver_hdr *)data;3385 ver_hdr->signature = CUDBG_ENTITY_SIGNATURE;3386 ver_hdr->revision = CUDBG_QDESC_REV;3387 ver_hdr->size = sizeof(struct cudbg_qdesc_info);3388 size -= sizeof(*ver_hdr);3389 3390 qdesc_info = (struct cudbg_qdesc_info *)(data +3391 sizeof(*ver_hdr));3392 size -= sizeof(*qdesc_info);3393 qdesc_entry = (struct cudbg_qdesc_entry *)qdesc_info->data;3394 3395#define QDESC_GET(q, desc, type, label) do { \3396 if (size <= 0) { \3397 goto label; \3398 } \3399 if (desc) { \3400 cudbg_fill_qdesc_##q(q, type, qdesc_entry); \3401 size -= sizeof(*qdesc_entry) + qdesc_entry->data_size; \3402 num_queues++; \3403 qdesc_entry = cudbg_next_qdesc(qdesc_entry); \3404 } \3405} while (0)3406 3407#define QDESC_GET_TXQ(q, type, label) do { \3408 struct sge_txq *txq = (struct sge_txq *)q; \3409 QDESC_GET(txq, txq->desc, type, label); \3410} while (0)3411 3412#define QDESC_GET_RXQ(q, type, label) do { \3413 struct sge_rspq *rxq = (struct sge_rspq *)q; \3414 QDESC_GET(rxq, rxq->desc, type, label); \3415} while (0)3416 3417#define QDESC_GET_FLQ(q, type, label) do { \3418 struct sge_fl *flq = (struct sge_fl *)q; \3419 QDESC_GET(flq, flq->desc, type, label); \3420} while (0)3421 3422 /* NIC TXQ */3423 for (i = 0; i < s->ethqsets; i++)3424 QDESC_GET_TXQ(&s->ethtxq[i].q, CUDBG_QTYPE_NIC_TXQ, out);3425 3426 /* NIC RXQ */3427 for (i = 0; i < s->ethqsets; i++)3428 QDESC_GET_RXQ(&s->ethrxq[i].rspq, CUDBG_QTYPE_NIC_RXQ, out);3429 3430 /* NIC FLQ */3431 for (i = 0; i < s->ethqsets; i++)3432 QDESC_GET_FLQ(&s->ethrxq[i].fl, CUDBG_QTYPE_NIC_FLQ, out);3433 3434 /* NIC CTRLQ */3435 for (i = 0; i < padap->params.nports; i++)3436 QDESC_GET_TXQ(&s->ctrlq[i].q, CUDBG_QTYPE_CTRLQ, out);3437 3438 /* FW_EVTQ */3439 QDESC_GET_RXQ(&s->fw_evtq, CUDBG_QTYPE_FWEVTQ, out);3440 3441 /* INTRQ */3442 QDESC_GET_RXQ(&s->intrq, CUDBG_QTYPE_INTRQ, out);3443 3444 /* PTP_TXQ */3445 QDESC_GET_TXQ(&s->ptptxq.q, CUDBG_QTYPE_PTP_TXQ, out);3446 3447 /* ULD Queues */3448 mutex_lock(&uld_mutex);3449 3450 if (s->uld_txq_info) {3451 struct sge_uld_txq_info *utxq;3452 3453 /* ULD TXQ */3454 for (j = 0; j < CXGB4_TX_MAX; j++) {3455 if (!s->uld_txq_info[j])3456 continue;3457 3458 utxq = s->uld_txq_info[j];3459 for (i = 0; i < utxq->ntxq; i++)3460 QDESC_GET_TXQ(&utxq->uldtxq[i].q,3461 cudbg_uld_txq_to_qtype(j),3462 out_unlock_uld);3463 }3464 }3465 3466 if (s->uld_rxq_info) {3467 struct sge_uld_rxq_info *urxq;3468 u32 base;3469 3470 /* ULD RXQ */3471 for (j = 0; j < CXGB4_ULD_MAX; j++) {3472 if (!s->uld_rxq_info[j])3473 continue;3474 3475 urxq = s->uld_rxq_info[j];3476 for (i = 0; i < urxq->nrxq; i++)3477 QDESC_GET_RXQ(&urxq->uldrxq[i].rspq,3478 cudbg_uld_rxq_to_qtype(j),3479 out_unlock_uld);3480 }3481 3482 /* ULD FLQ */3483 for (j = 0; j < CXGB4_ULD_MAX; j++) {3484 if (!s->uld_rxq_info[j])3485 continue;3486 3487 urxq = s->uld_rxq_info[j];3488 for (i = 0; i < urxq->nrxq; i++)3489 QDESC_GET_FLQ(&urxq->uldrxq[i].fl,3490 cudbg_uld_flq_to_qtype(j),3491 out_unlock_uld);3492 }3493 3494 /* ULD CIQ */3495 for (j = 0; j < CXGB4_ULD_MAX; j++) {3496 if (!s->uld_rxq_info[j])3497 continue;3498 3499 urxq = s->uld_rxq_info[j];3500 base = urxq->nrxq;3501 for (i = 0; i < urxq->nciq; i++)3502 QDESC_GET_RXQ(&urxq->uldrxq[base + i].rspq,3503 cudbg_uld_ciq_to_qtype(j),3504 out_unlock_uld);3505 }3506 }3507 mutex_unlock(&uld_mutex);3508 3509 if (!padap->tc_mqprio)3510 goto out;3511 3512 mutex_lock(&padap->tc_mqprio->mqprio_mutex);3513 /* ETHOFLD TXQ */3514 if (s->eohw_txq)3515 for (i = 0; i < s->eoqsets; i++)3516 QDESC_GET_TXQ(&s->eohw_txq[i].q,3517 CUDBG_QTYPE_ETHOFLD_TXQ, out_unlock_mqprio);3518 3519 /* ETHOFLD RXQ and FLQ */3520 if (s->eohw_rxq) {3521 for (i = 0; i < s->eoqsets; i++)3522 QDESC_GET_RXQ(&s->eohw_rxq[i].rspq,3523 CUDBG_QTYPE_ETHOFLD_RXQ, out_unlock_mqprio);3524 3525 for (i = 0; i < s->eoqsets; i++)3526 QDESC_GET_FLQ(&s->eohw_rxq[i].fl,3527 CUDBG_QTYPE_ETHOFLD_FLQ, out_unlock_mqprio);3528 }3529 3530out_unlock_mqprio:3531 mutex_unlock(&padap->tc_mqprio->mqprio_mutex);3532 3533out:3534 qdesc_info->qdesc_entry_size = sizeof(*qdesc_entry);3535 qdesc_info->num_queues = num_queues;3536 cur_off = 0;3537 while (tot_len) {3538 u32 chunk_size = min_t(u32, tot_len, CUDBG_CHUNK_SIZE);3539 3540 rc = cudbg_get_buff(pdbg_init, dbg_buff, chunk_size,3541 &temp_buff);3542 if (rc) {3543 cudbg_err->sys_warn = CUDBG_STATUS_PARTIAL_DATA;3544 goto out_free;3545 }3546 3547 memcpy(temp_buff.data, data + cur_off, chunk_size);3548 tot_len -= chunk_size;3549 cur_off += chunk_size;3550 rc = cudbg_write_and_release_buff(pdbg_init, &temp_buff,3551 dbg_buff);3552 if (rc) {3553 cudbg_put_buff(pdbg_init, &temp_buff);3554 cudbg_err->sys_warn = CUDBG_STATUS_PARTIAL_DATA;3555 goto out_free;3556 }3557 }3558 3559out_free:3560 kvfree(data);3561 3562#undef QDESC_GET_FLQ3563#undef QDESC_GET_RXQ3564#undef QDESC_GET_TXQ3565#undef QDESC_GET3566 3567 return rc;3568 3569out_unlock_uld:3570 mutex_unlock(&uld_mutex);3571 goto out;3572}3573 3574int cudbg_collect_flash(struct cudbg_init *pdbg_init,3575 struct cudbg_buffer *dbg_buff,3576 struct cudbg_error *cudbg_err)3577{3578 struct adapter *padap = pdbg_init->adap;3579 u32 count = padap->params.sf_size, n;3580 struct cudbg_buffer temp_buff = {0};3581 u32 addr, i;3582 int rc;3583 3584 addr = FLASH_EXP_ROM_START;3585 3586 for (i = 0; i < count; i += SF_PAGE_SIZE) {3587 n = min_t(u32, count - i, SF_PAGE_SIZE);3588 3589 rc = cudbg_get_buff(pdbg_init, dbg_buff, n, &temp_buff);3590 if (rc) {3591 cudbg_err->sys_warn = CUDBG_STATUS_PARTIAL_DATA;3592 goto out;3593 }3594 rc = t4_read_flash(padap, addr, n, (u32 *)temp_buff.data, 0);3595 if (rc)3596 goto out;3597 3598 addr += (n * 4);3599 rc = cudbg_write_and_release_buff(pdbg_init, &temp_buff,3600 dbg_buff);3601 if (rc) {3602 cudbg_err->sys_warn = CUDBG_STATUS_PARTIAL_DATA;3603 goto out;3604 }3605 }3606 3607out:3608 return rc;3609}3610