14fa9c49fSThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only
2a7975a2fSRahul Lakkireddy /*
3a7975a2fSRahul Lakkireddy  *  Copyright (C) 2017 Chelsio Communications.  All rights reserved.
4a7975a2fSRahul Lakkireddy  */
5a7975a2fSRahul Lakkireddy 
6123e25c4SRahul Lakkireddy #include <linux/sort.h>
7c8119fa8SYueHaibing #include <linux/string.h>
8123e25c4SRahul Lakkireddy 
9b33af022SRahul Lakkireddy #include "t4_regs.h"
10a7975a2fSRahul Lakkireddy #include "cxgb4.h"
1168ddc82aSRahul Lakkireddy #include "cxgb4_cudbg.h"
12a7975a2fSRahul Lakkireddy #include "cudbg_if.h"
13a7975a2fSRahul Lakkireddy #include "cudbg_lib_common.h"
14b33af022SRahul Lakkireddy #include "cudbg_entity.h"
15123e25c4SRahul Lakkireddy #include "cudbg_lib.h"
1656cf2635SRahul Lakkireddy #include "cudbg_zlib.h"
17a7975a2fSRahul Lakkireddy 
18f35d2117SRahul Lakkireddy static const u32 t6_tp_pio_array[][IREG_NUM_ELEM] = {
19f35d2117SRahul Lakkireddy 	{0x7e40, 0x7e44, 0x020, 28}, /* t6_tp_pio_regs_20_to_3b */
20f35d2117SRahul Lakkireddy 	{0x7e40, 0x7e44, 0x040, 10}, /* t6_tp_pio_regs_40_to_49 */
21f35d2117SRahul Lakkireddy 	{0x7e40, 0x7e44, 0x050, 10}, /* t6_tp_pio_regs_50_to_59 */
22f35d2117SRahul Lakkireddy 	{0x7e40, 0x7e44, 0x060, 14}, /* t6_tp_pio_regs_60_to_6d */
23f35d2117SRahul Lakkireddy 	{0x7e40, 0x7e44, 0x06F, 1}, /* t6_tp_pio_regs_6f */
24f35d2117SRahul Lakkireddy 	{0x7e40, 0x7e44, 0x070, 6}, /* t6_tp_pio_regs_70_to_75 */
25f35d2117SRahul Lakkireddy 	{0x7e40, 0x7e44, 0x130, 18}, /* t6_tp_pio_regs_130_to_141 */
26f35d2117SRahul Lakkireddy 	{0x7e40, 0x7e44, 0x145, 19}, /* t6_tp_pio_regs_145_to_157 */
27f35d2117SRahul Lakkireddy 	{0x7e40, 0x7e44, 0x160, 1}, /* t6_tp_pio_regs_160 */
28f35d2117SRahul Lakkireddy 	{0x7e40, 0x7e44, 0x230, 25}, /* t6_tp_pio_regs_230_to_248 */
29f35d2117SRahul Lakkireddy 	{0x7e40, 0x7e44, 0x24a, 3}, /* t6_tp_pio_regs_24c */
30f35d2117SRahul Lakkireddy 	{0x7e40, 0x7e44, 0x8C0, 1} /* t6_tp_pio_regs_8c0 */
31f35d2117SRahul Lakkireddy };
32f35d2117SRahul Lakkireddy 
33f35d2117SRahul Lakkireddy static const u32 t5_tp_pio_array[][IREG_NUM_ELEM] = {
34f35d2117SRahul Lakkireddy 	{0x7e40, 0x7e44, 0x020, 28}, /* t5_tp_pio_regs_20_to_3b */
35f35d2117SRahul Lakkireddy 	{0x7e40, 0x7e44, 0x040, 19}, /* t5_tp_pio_regs_40_to_52 */
36f35d2117SRahul Lakkireddy 	{0x7e40, 0x7e44, 0x054, 2}, /* t5_tp_pio_regs_54_to_55 */
37f35d2117SRahul Lakkireddy 	{0x7e40, 0x7e44, 0x060, 13}, /* t5_tp_pio_regs_60_to_6c */
38f35d2117SRahul Lakkireddy 	{0x7e40, 0x7e44, 0x06F, 1}, /* t5_tp_pio_regs_6f */
39f35d2117SRahul Lakkireddy 	{0x7e40, 0x7e44, 0x120, 4}, /* t5_tp_pio_regs_120_to_123 */
40f35d2117SRahul Lakkireddy 	{0x7e40, 0x7e44, 0x12b, 2}, /* t5_tp_pio_regs_12b_to_12c */
41f35d2117SRahul Lakkireddy 	{0x7e40, 0x7e44, 0x12f, 21}, /* t5_tp_pio_regs_12f_to_143 */
42f35d2117SRahul Lakkireddy 	{0x7e40, 0x7e44, 0x145, 19}, /* t5_tp_pio_regs_145_to_157 */
43f35d2117SRahul Lakkireddy 	{0x7e40, 0x7e44, 0x230, 25}, /* t5_tp_pio_regs_230_to_248 */
44f35d2117SRahul Lakkireddy 	{0x7e40, 0x7e44, 0x8C0, 1} /* t5_tp_pio_regs_8c0 */
45f35d2117SRahul Lakkireddy };
46f35d2117SRahul Lakkireddy 
47f35d2117SRahul Lakkireddy static const u32 t6_tp_tm_pio_array[][IREG_NUM_ELEM] = {
48f35d2117SRahul Lakkireddy 	{0x7e18, 0x7e1c, 0x0, 12}
49f35d2117SRahul Lakkireddy };
50f35d2117SRahul Lakkireddy 
51f35d2117SRahul Lakkireddy static const u32 t5_tp_tm_pio_array[][IREG_NUM_ELEM] = {
52f35d2117SRahul Lakkireddy 	{0x7e18, 0x7e1c, 0x0, 12}
53f35d2117SRahul Lakkireddy };
54f35d2117SRahul Lakkireddy 
55f35d2117SRahul Lakkireddy static const u32 t6_tp_mib_index_array[6][IREG_NUM_ELEM] = {
56f35d2117SRahul Lakkireddy 	{0x7e50, 0x7e54, 0x0, 13},
57f35d2117SRahul Lakkireddy 	{0x7e50, 0x7e54, 0x10, 6},
58f35d2117SRahul Lakkireddy 	{0x7e50, 0x7e54, 0x18, 21},
59f35d2117SRahul Lakkireddy 	{0x7e50, 0x7e54, 0x30, 32},
60f35d2117SRahul Lakkireddy 	{0x7e50, 0x7e54, 0x50, 22},
61f35d2117SRahul Lakkireddy 	{0x7e50, 0x7e54, 0x68, 12}
62f35d2117SRahul Lakkireddy };
63f35d2117SRahul Lakkireddy 
64f35d2117SRahul Lakkireddy static const u32 t5_tp_mib_index_array[9][IREG_NUM_ELEM] = {
65f35d2117SRahul Lakkireddy 	{0x7e50, 0x7e54, 0x0, 13},
66f35d2117SRahul Lakkireddy 	{0x7e50, 0x7e54, 0x10, 6},
67f35d2117SRahul Lakkireddy 	{0x7e50, 0x7e54, 0x18, 8},
68f35d2117SRahul Lakkireddy 	{0x7e50, 0x7e54, 0x20, 13},
69f35d2117SRahul Lakkireddy 	{0x7e50, 0x7e54, 0x30, 16},
70f35d2117SRahul Lakkireddy 	{0x7e50, 0x7e54, 0x40, 16},
71f35d2117SRahul Lakkireddy 	{0x7e50, 0x7e54, 0x50, 16},
72f35d2117SRahul Lakkireddy 	{0x7e50, 0x7e54, 0x60, 6},
73f35d2117SRahul Lakkireddy 	{0x7e50, 0x7e54, 0x68, 4}
74f35d2117SRahul Lakkireddy };
75f35d2117SRahul Lakkireddy 
76f35d2117SRahul Lakkireddy static const u32 t5_sge_dbg_index_array[2][IREG_NUM_ELEM] = {
77f35d2117SRahul Lakkireddy 	{0x10cc, 0x10d0, 0x0, 16},
78f35d2117SRahul Lakkireddy 	{0x10cc, 0x10d4, 0x0, 16},
79f35d2117SRahul Lakkireddy };
80f35d2117SRahul Lakkireddy 
81f35d2117SRahul Lakkireddy static const u32 t6_sge_qbase_index_array[] = {
82f35d2117SRahul Lakkireddy 	/* 1 addr reg SGE_QBASE_INDEX and 4 data reg SGE_QBASE_MAP[0-3] */
83f35d2117SRahul Lakkireddy 	0x1250, 0x1240, 0x1244, 0x1248, 0x124c,
84f35d2117SRahul Lakkireddy };
85f35d2117SRahul Lakkireddy 
86f35d2117SRahul Lakkireddy static const u32 t5_pcie_pdbg_array[][IREG_NUM_ELEM] = {
87f35d2117SRahul Lakkireddy 	{0x5a04, 0x5a0c, 0x00, 0x20}, /* t5_pcie_pdbg_regs_00_to_20 */
88f35d2117SRahul Lakkireddy 	{0x5a04, 0x5a0c, 0x21, 0x20}, /* t5_pcie_pdbg_regs_21_to_40 */
89f35d2117SRahul Lakkireddy 	{0x5a04, 0x5a0c, 0x41, 0x10}, /* t5_pcie_pdbg_regs_41_to_50 */
90f35d2117SRahul Lakkireddy };
91f35d2117SRahul Lakkireddy 
92f35d2117SRahul Lakkireddy static const u32 t5_pcie_cdbg_array[][IREG_NUM_ELEM] = {
93f35d2117SRahul Lakkireddy 	{0x5a10, 0x5a18, 0x00, 0x20}, /* t5_pcie_cdbg_regs_00_to_20 */
94f35d2117SRahul Lakkireddy 	{0x5a10, 0x5a18, 0x21, 0x18}, /* t5_pcie_cdbg_regs_21_to_37 */
95f35d2117SRahul Lakkireddy };
96f35d2117SRahul Lakkireddy 
97f35d2117SRahul Lakkireddy static const u32 t5_pm_rx_array[][IREG_NUM_ELEM] = {
98f35d2117SRahul Lakkireddy 	{0x8FD0, 0x8FD4, 0x10000, 0x20}, /* t5_pm_rx_regs_10000_to_10020 */
99f35d2117SRahul Lakkireddy 	{0x8FD0, 0x8FD4, 0x10021, 0x0D}, /* t5_pm_rx_regs_10021_to_1002c */
100f35d2117SRahul Lakkireddy };
101f35d2117SRahul Lakkireddy 
102f35d2117SRahul Lakkireddy static const u32 t5_pm_tx_array[][IREG_NUM_ELEM] = {
103f35d2117SRahul Lakkireddy 	{0x8FF0, 0x8FF4, 0x10000, 0x20}, /* t5_pm_tx_regs_10000_to_10020 */
104f35d2117SRahul Lakkireddy 	{0x8FF0, 0x8FF4, 0x10021, 0x1D}, /* t5_pm_tx_regs_10021_to_1003c */
105f35d2117SRahul Lakkireddy };
106f35d2117SRahul Lakkireddy 
107f35d2117SRahul Lakkireddy static const u32 t5_pcie_config_array[][2] = {
108f35d2117SRahul Lakkireddy 	{0x0, 0x34},
109f35d2117SRahul Lakkireddy 	{0x3c, 0x40},
110f35d2117SRahul Lakkireddy 	{0x50, 0x64},
111f35d2117SRahul Lakkireddy 	{0x70, 0x80},
112f35d2117SRahul Lakkireddy 	{0x94, 0xa0},
113f35d2117SRahul Lakkireddy 	{0xb0, 0xb8},
114f35d2117SRahul Lakkireddy 	{0xd0, 0xd4},
115f35d2117SRahul Lakkireddy 	{0x100, 0x128},
116f35d2117SRahul Lakkireddy 	{0x140, 0x148},
117f35d2117SRahul Lakkireddy 	{0x150, 0x164},
118f35d2117SRahul Lakkireddy 	{0x170, 0x178},
119f35d2117SRahul Lakkireddy 	{0x180, 0x194},
120f35d2117SRahul Lakkireddy 	{0x1a0, 0x1b8},
121f35d2117SRahul Lakkireddy 	{0x1c0, 0x208},
122f35d2117SRahul Lakkireddy };
123f35d2117SRahul Lakkireddy 
124f35d2117SRahul Lakkireddy static const u32 t6_ma_ireg_array[][IREG_NUM_ELEM] = {
125f35d2117SRahul Lakkireddy 	{0x78f8, 0x78fc, 0xa000, 23}, /* t6_ma_regs_a000_to_a016 */
126f35d2117SRahul Lakkireddy 	{0x78f8, 0x78fc, 0xa400, 30}, /* t6_ma_regs_a400_to_a41e */
127f35d2117SRahul Lakkireddy 	{0x78f8, 0x78fc, 0xa800, 20} /* t6_ma_regs_a800_to_a813 */
128f35d2117SRahul Lakkireddy };
129f35d2117SRahul Lakkireddy 
130f35d2117SRahul Lakkireddy static const u32 t6_ma_ireg_array2[][IREG_NUM_ELEM] = {
131f35d2117SRahul Lakkireddy 	{0x78f8, 0x78fc, 0xe400, 17}, /* t6_ma_regs_e400_to_e600 */
132f35d2117SRahul Lakkireddy 	{0x78f8, 0x78fc, 0xe640, 13} /* t6_ma_regs_e640_to_e7c0 */
133f35d2117SRahul Lakkireddy };
134f35d2117SRahul Lakkireddy 
135f35d2117SRahul Lakkireddy static const u32 t6_up_cim_reg_array[][IREG_NUM_ELEM + 1] = {
136f35d2117SRahul Lakkireddy 	{0x7b50, 0x7b54, 0x2000, 0x20, 0}, /* up_cim_2000_to_207c */
137f35d2117SRahul Lakkireddy 	{0x7b50, 0x7b54, 0x2080, 0x1d, 0}, /* up_cim_2080_to_20fc */
138f35d2117SRahul Lakkireddy 	{0x7b50, 0x7b54, 0x00, 0x20, 0}, /* up_cim_00_to_7c */
139f35d2117SRahul Lakkireddy 	{0x7b50, 0x7b54, 0x80, 0x20, 0}, /* up_cim_80_to_fc */
140f35d2117SRahul Lakkireddy 	{0x7b50, 0x7b54, 0x100, 0x11, 0}, /* up_cim_100_to_14c */
141f35d2117SRahul Lakkireddy 	{0x7b50, 0x7b54, 0x200, 0x10, 0}, /* up_cim_200_to_23c */
142f35d2117SRahul Lakkireddy 	{0x7b50, 0x7b54, 0x240, 0x2, 0}, /* up_cim_240_to_244 */
143f35d2117SRahul Lakkireddy 	{0x7b50, 0x7b54, 0x250, 0x2, 0}, /* up_cim_250_to_254 */
144f35d2117SRahul Lakkireddy 	{0x7b50, 0x7b54, 0x260, 0x2, 0}, /* up_cim_260_to_264 */
145f35d2117SRahul Lakkireddy 	{0x7b50, 0x7b54, 0x270, 0x2, 0}, /* up_cim_270_to_274 */
146f35d2117SRahul Lakkireddy 	{0x7b50, 0x7b54, 0x280, 0x20, 0}, /* up_cim_280_to_2fc */
147f35d2117SRahul Lakkireddy 	{0x7b50, 0x7b54, 0x300, 0x20, 0}, /* up_cim_300_to_37c */
148f35d2117SRahul Lakkireddy 	{0x7b50, 0x7b54, 0x380, 0x14, 0}, /* up_cim_380_to_3cc */
149f35d2117SRahul Lakkireddy 	{0x7b50, 0x7b54, 0x4900, 0x4, 0x4}, /* up_cim_4900_to_4c60 */
150f35d2117SRahul Lakkireddy 	{0x7b50, 0x7b54, 0x4904, 0x4, 0x4}, /* up_cim_4904_to_4c64 */
151f35d2117SRahul Lakkireddy 	{0x7b50, 0x7b54, 0x4908, 0x4, 0x4}, /* up_cim_4908_to_4c68 */
152f35d2117SRahul Lakkireddy 	{0x7b50, 0x7b54, 0x4910, 0x4, 0x4}, /* up_cim_4910_to_4c70 */
153f35d2117SRahul Lakkireddy 	{0x7b50, 0x7b54, 0x4914, 0x4, 0x4}, /* up_cim_4914_to_4c74 */
154f35d2117SRahul Lakkireddy 	{0x7b50, 0x7b54, 0x4920, 0x10, 0x10}, /* up_cim_4920_to_4a10 */
155f35d2117SRahul Lakkireddy 	{0x7b50, 0x7b54, 0x4924, 0x10, 0x10}, /* up_cim_4924_to_4a14 */
156f35d2117SRahul Lakkireddy 	{0x7b50, 0x7b54, 0x4928, 0x10, 0x10}, /* up_cim_4928_to_4a18 */
157f35d2117SRahul Lakkireddy 	{0x7b50, 0x7b54, 0x492c, 0x10, 0x10}, /* up_cim_492c_to_4a1c */
158f35d2117SRahul Lakkireddy };
159f35d2117SRahul Lakkireddy 
160f35d2117SRahul Lakkireddy static const u32 t5_up_cim_reg_array[][IREG_NUM_ELEM + 1] = {
161f35d2117SRahul Lakkireddy 	{0x7b50, 0x7b54, 0x2000, 0x20, 0}, /* up_cim_2000_to_207c */
162f35d2117SRahul Lakkireddy 	{0x7b50, 0x7b54, 0x2080, 0x19, 0}, /* up_cim_2080_to_20ec */
163f35d2117SRahul Lakkireddy 	{0x7b50, 0x7b54, 0x00, 0x20, 0}, /* up_cim_00_to_7c */
164f35d2117SRahul Lakkireddy 	{0x7b50, 0x7b54, 0x80, 0x20, 0}, /* up_cim_80_to_fc */
165f35d2117SRahul Lakkireddy 	{0x7b50, 0x7b54, 0x100, 0x11, 0}, /* up_cim_100_to_14c */
166f35d2117SRahul Lakkireddy 	{0x7b50, 0x7b54, 0x200, 0x10, 0}, /* up_cim_200_to_23c */
167f35d2117SRahul Lakkireddy 	{0x7b50, 0x7b54, 0x240, 0x2, 0}, /* up_cim_240_to_244 */
168f35d2117SRahul Lakkireddy 	{0x7b50, 0x7b54, 0x250, 0x2, 0}, /* up_cim_250_to_254 */
169f35d2117SRahul Lakkireddy 	{0x7b50, 0x7b54, 0x260, 0x2, 0}, /* up_cim_260_to_264 */
170f35d2117SRahul Lakkireddy 	{0x7b50, 0x7b54, 0x270, 0x2, 0}, /* up_cim_270_to_274 */
171f35d2117SRahul Lakkireddy 	{0x7b50, 0x7b54, 0x280, 0x20, 0}, /* up_cim_280_to_2fc */
172f35d2117SRahul Lakkireddy 	{0x7b50, 0x7b54, 0x300, 0x20, 0}, /* up_cim_300_to_37c */
173f35d2117SRahul Lakkireddy 	{0x7b50, 0x7b54, 0x380, 0x14, 0}, /* up_cim_380_to_3cc */
174f35d2117SRahul Lakkireddy };
175f35d2117SRahul Lakkireddy 
176f35d2117SRahul Lakkireddy static const u32 t6_hma_ireg_array[][IREG_NUM_ELEM] = {
177f35d2117SRahul Lakkireddy 	{0x51320, 0x51324, 0xa000, 32} /* t6_hma_regs_a000_to_a01f */
178f35d2117SRahul Lakkireddy };
179f35d2117SRahul Lakkireddy 
180f35d2117SRahul Lakkireddy u32 cudbg_get_entity_length(struct adapter *adap, u32 entity)
181f35d2117SRahul Lakkireddy {
182f35d2117SRahul Lakkireddy 	struct cudbg_tcam tcam_region = { 0 };
183f35d2117SRahul Lakkireddy 	u32 value, n = 0, len = 0;
184f35d2117SRahul Lakkireddy 
185f35d2117SRahul Lakkireddy 	switch (entity) {
186f35d2117SRahul Lakkireddy 	case CUDBG_REG_DUMP:
187f35d2117SRahul Lakkireddy 		switch (CHELSIO_CHIP_VERSION(adap->params.chip)) {
188f35d2117SRahul Lakkireddy 		case CHELSIO_T4:
189f35d2117SRahul Lakkireddy 			len = T4_REGMAP_SIZE;
190f35d2117SRahul Lakkireddy 			break;
191f35d2117SRahul Lakkireddy 		case CHELSIO_T5:
192f35d2117SRahul Lakkireddy 		case CHELSIO_T6:
193f35d2117SRahul Lakkireddy 			len = T5_REGMAP_SIZE;
194f35d2117SRahul Lakkireddy 			break;
195f35d2117SRahul Lakkireddy 		default:
196f35d2117SRahul Lakkireddy 			break;
197f35d2117SRahul Lakkireddy 		}
198f35d2117SRahul Lakkireddy 		break;
199f35d2117SRahul Lakkireddy 	case CUDBG_DEV_LOG:
200f35d2117SRahul Lakkireddy 		len = adap->params.devlog.size;
201f35d2117SRahul Lakkireddy 		break;
202f35d2117SRahul Lakkireddy 	case CUDBG_CIM_LA:
203f35d2117SRahul Lakkireddy 		if (is_t6(adap->params.chip)) {
204f35d2117SRahul Lakkireddy 			len = adap->params.cim_la_size / 10 + 1;
205f35d2117SRahul Lakkireddy 			len *= 10 * sizeof(u32);
206f35d2117SRahul Lakkireddy 		} else {
207f35d2117SRahul Lakkireddy 			len = adap->params.cim_la_size / 8;
208f35d2117SRahul Lakkireddy 			len *= 8 * sizeof(u32);
209f35d2117SRahul Lakkireddy 		}
210f35d2117SRahul Lakkireddy 		len += sizeof(u32); /* for reading CIM LA configuration */
211f35d2117SRahul Lakkireddy 		break;
212f35d2117SRahul Lakkireddy 	case CUDBG_CIM_MA_LA:
213f35d2117SRahul Lakkireddy 		len = 2 * CIM_MALA_SIZE * 5 * sizeof(u32);
214f35d2117SRahul Lakkireddy 		break;
215f35d2117SRahul Lakkireddy 	case CUDBG_CIM_QCFG:
216f35d2117SRahul Lakkireddy 		len = sizeof(struct cudbg_cim_qcfg);
217f35d2117SRahul Lakkireddy 		break;
218f35d2117SRahul Lakkireddy 	case CUDBG_CIM_IBQ_TP0:
219f35d2117SRahul Lakkireddy 	case CUDBG_CIM_IBQ_TP1:
220f35d2117SRahul Lakkireddy 	case CUDBG_CIM_IBQ_ULP:
221f35d2117SRahul Lakkireddy 	case CUDBG_CIM_IBQ_SGE0:
222f35d2117SRahul Lakkireddy 	case CUDBG_CIM_IBQ_SGE1:
223f35d2117SRahul Lakkireddy 	case CUDBG_CIM_IBQ_NCSI:
224f35d2117SRahul Lakkireddy 		len = CIM_IBQ_SIZE * 4 * sizeof(u32);
225f35d2117SRahul Lakkireddy 		break;
226f35d2117SRahul Lakkireddy 	case CUDBG_CIM_OBQ_ULP0:
227f35d2117SRahul Lakkireddy 		len = cudbg_cim_obq_size(adap, 0);
228f35d2117SRahul Lakkireddy 		break;
229f35d2117SRahul Lakkireddy 	case CUDBG_CIM_OBQ_ULP1:
230f35d2117SRahul Lakkireddy 		len = cudbg_cim_obq_size(adap, 1);
231f35d2117SRahul Lakkireddy 		break;
232f35d2117SRahul Lakkireddy 	case CUDBG_CIM_OBQ_ULP2:
233f35d2117SRahul Lakkireddy 		len = cudbg_cim_obq_size(adap, 2);
234f35d2117SRahul Lakkireddy 		break;
235f35d2117SRahul Lakkireddy 	case CUDBG_CIM_OBQ_ULP3:
236f35d2117SRahul Lakkireddy 		len = cudbg_cim_obq_size(adap, 3);
237f35d2117SRahul Lakkireddy 		break;
238f35d2117SRahul Lakkireddy 	case CUDBG_CIM_OBQ_SGE:
239f35d2117SRahul Lakkireddy 		len = cudbg_cim_obq_size(adap, 4);
240f35d2117SRahul Lakkireddy 		break;
241f35d2117SRahul Lakkireddy 	case CUDBG_CIM_OBQ_NCSI:
242f35d2117SRahul Lakkireddy 		len = cudbg_cim_obq_size(adap, 5);
243f35d2117SRahul Lakkireddy 		break;
244f35d2117SRahul Lakkireddy 	case CUDBG_CIM_OBQ_RXQ0:
245f35d2117SRahul Lakkireddy 		len = cudbg_cim_obq_size(adap, 6);
246f35d2117SRahul Lakkireddy 		break;
247f35d2117SRahul Lakkireddy 	case CUDBG_CIM_OBQ_RXQ1:
248f35d2117SRahul Lakkireddy 		len = cudbg_cim_obq_size(adap, 7);
249f35d2117SRahul Lakkireddy 		break;
250f35d2117SRahul Lakkireddy 	case CUDBG_EDC0:
251f35d2117SRahul Lakkireddy 		value = t4_read_reg(adap, MA_TARGET_MEM_ENABLE_A);
252f35d2117SRahul Lakkireddy 		if (value & EDRAM0_ENABLE_F) {
253f35d2117SRahul Lakkireddy 			value = t4_read_reg(adap, MA_EDRAM0_BAR_A);
254f35d2117SRahul Lakkireddy 			len = EDRAM0_SIZE_G(value);
255f35d2117SRahul Lakkireddy 		}
256f35d2117SRahul Lakkireddy 		len = cudbg_mbytes_to_bytes(len);
257f35d2117SRahul Lakkireddy 		break;
258f35d2117SRahul Lakkireddy 	case CUDBG_EDC1:
259f35d2117SRahul Lakkireddy 		value = t4_read_reg(adap, MA_TARGET_MEM_ENABLE_A);
260f35d2117SRahul Lakkireddy 		if (value & EDRAM1_ENABLE_F) {
261f35d2117SRahul Lakkireddy 			value = t4_read_reg(adap, MA_EDRAM1_BAR_A);
262f35d2117SRahul Lakkireddy 			len = EDRAM1_SIZE_G(value);
263f35d2117SRahul Lakkireddy 		}
264f35d2117SRahul Lakkireddy 		len = cudbg_mbytes_to_bytes(len);
265f35d2117SRahul Lakkireddy 		break;
266f35d2117SRahul Lakkireddy 	case CUDBG_MC0:
267f35d2117SRahul Lakkireddy 		value = t4_read_reg(adap, MA_TARGET_MEM_ENABLE_A);
268f35d2117SRahul Lakkireddy 		if (value & EXT_MEM0_ENABLE_F) {
269f35d2117SRahul Lakkireddy 			value = t4_read_reg(adap, MA_EXT_MEMORY0_BAR_A);
270f35d2117SRahul Lakkireddy 			len = EXT_MEM0_SIZE_G(value);
271f35d2117SRahul Lakkireddy 		}
272f35d2117SRahul Lakkireddy 		len = cudbg_mbytes_to_bytes(len);
273f35d2117SRahul Lakkireddy 		break;
274f35d2117SRahul Lakkireddy 	case CUDBG_MC1:
275f35d2117SRahul Lakkireddy 		value = t4_read_reg(adap, MA_TARGET_MEM_ENABLE_A);
276f35d2117SRahul Lakkireddy 		if (value & EXT_MEM1_ENABLE_F) {
277f35d2117SRahul Lakkireddy 			value = t4_read_reg(adap, MA_EXT_MEMORY1_BAR_A);
278f35d2117SRahul Lakkireddy 			len = EXT_MEM1_SIZE_G(value);
279f35d2117SRahul Lakkireddy 		}
280f35d2117SRahul Lakkireddy 		len = cudbg_mbytes_to_bytes(len);
281f35d2117SRahul Lakkireddy 		break;
282f35d2117SRahul Lakkireddy 	case CUDBG_RSS:
283f35d2117SRahul Lakkireddy 		len = t4_chip_rss_size(adap) * sizeof(u16);
284f35d2117SRahul Lakkireddy 		break;
285f35d2117SRahul Lakkireddy 	case CUDBG_RSS_VF_CONF:
286f35d2117SRahul Lakkireddy 		len = adap->params.arch.vfcount *
287f35d2117SRahul Lakkireddy 		      sizeof(struct cudbg_rss_vf_conf);
288f35d2117SRahul Lakkireddy 		break;
289f35d2117SRahul Lakkireddy 	case CUDBG_PATH_MTU:
290f35d2117SRahul Lakkireddy 		len = NMTUS * sizeof(u16);
291f35d2117SRahul Lakkireddy 		break;
292f35d2117SRahul Lakkireddy 	case CUDBG_PM_STATS:
293f35d2117SRahul Lakkireddy 		len = sizeof(struct cudbg_pm_stats);
294f35d2117SRahul Lakkireddy 		break;
295f35d2117SRahul Lakkireddy 	case CUDBG_HW_SCHED:
296f35d2117SRahul Lakkireddy 		len = sizeof(struct cudbg_hw_sched);
297f35d2117SRahul Lakkireddy 		break;
298f35d2117SRahul Lakkireddy 	case CUDBG_TP_INDIRECT:
299f35d2117SRahul Lakkireddy 		switch (CHELSIO_CHIP_VERSION(adap->params.chip)) {
300f35d2117SRahul Lakkireddy 		case CHELSIO_T5:
301f35d2117SRahul Lakkireddy 			n = sizeof(t5_tp_pio_array) +
302f35d2117SRahul Lakkireddy 			    sizeof(t5_tp_tm_pio_array) +
303f35d2117SRahul Lakkireddy 			    sizeof(t5_tp_mib_index_array);
304f35d2117SRahul Lakkireddy 			break;
305f35d2117SRahul Lakkireddy 		case CHELSIO_T6:
306f35d2117SRahul Lakkireddy 			n = sizeof(t6_tp_pio_array) +
307f35d2117SRahul Lakkireddy 			    sizeof(t6_tp_tm_pio_array) +
308f35d2117SRahul Lakkireddy 			    sizeof(t6_tp_mib_index_array);
309f35d2117SRahul Lakkireddy 			break;
310f35d2117SRahul Lakkireddy 		default:
311f35d2117SRahul Lakkireddy 			break;
312f35d2117SRahul Lakkireddy 		}
313f35d2117SRahul Lakkireddy 		n = n / (IREG_NUM_ELEM * sizeof(u32));
314f35d2117SRahul Lakkireddy 		len = sizeof(struct ireg_buf) * n;
315f35d2117SRahul Lakkireddy 		break;
316f35d2117SRahul Lakkireddy 	case CUDBG_SGE_INDIRECT:
317f35d2117SRahul Lakkireddy 		len = sizeof(struct ireg_buf) * 2 +
318f35d2117SRahul Lakkireddy 		      sizeof(struct sge_qbase_reg_field);
319f35d2117SRahul Lakkireddy 		break;
320f35d2117SRahul Lakkireddy 	case CUDBG_ULPRX_LA:
321f35d2117SRahul Lakkireddy 		len = sizeof(struct cudbg_ulprx_la);
322f35d2117SRahul Lakkireddy 		break;
323f35d2117SRahul Lakkireddy 	case CUDBG_TP_LA:
324f35d2117SRahul Lakkireddy 		len = sizeof(struct cudbg_tp_la) + TPLA_SIZE * sizeof(u64);
325f35d2117SRahul Lakkireddy 		break;
326f35d2117SRahul Lakkireddy 	case CUDBG_MEMINFO:
327f35d2117SRahul Lakkireddy 		len = sizeof(struct cudbg_ver_hdr) +
328f35d2117SRahul Lakkireddy 		      sizeof(struct cudbg_meminfo);
329f35d2117SRahul Lakkireddy 		break;
330f35d2117SRahul Lakkireddy 	case CUDBG_CIM_PIF_LA:
331f35d2117SRahul Lakkireddy 		len = sizeof(struct cudbg_cim_pif_la);
332f35d2117SRahul Lakkireddy 		len += 2 * CIM_PIFLA_SIZE * 6 * sizeof(u32);
333f35d2117SRahul Lakkireddy 		break;
334f35d2117SRahul Lakkireddy 	case CUDBG_CLK:
335f35d2117SRahul Lakkireddy 		len = sizeof(struct cudbg_clk_info);
336f35d2117SRahul Lakkireddy 		break;
337f35d2117SRahul Lakkireddy 	case CUDBG_PCIE_INDIRECT:
338f35d2117SRahul Lakkireddy 		n = sizeof(t5_pcie_pdbg_array) / (IREG_NUM_ELEM * sizeof(u32));
339f35d2117SRahul Lakkireddy 		len = sizeof(struct ireg_buf) * n * 2;
340f35d2117SRahul Lakkireddy 		break;
341f35d2117SRahul Lakkireddy 	case CUDBG_PM_INDIRECT:
342f35d2117SRahul Lakkireddy 		n = sizeof(t5_pm_rx_array) / (IREG_NUM_ELEM * sizeof(u32));
343f35d2117SRahul Lakkireddy 		len = sizeof(struct ireg_buf) * n * 2;
344f35d2117SRahul Lakkireddy 		break;
345f35d2117SRahul Lakkireddy 	case CUDBG_TID_INFO:
346f35d2117SRahul Lakkireddy 		len = sizeof(struct cudbg_tid_info_region_rev1);
347f35d2117SRahul Lakkireddy 		break;
348f35d2117SRahul Lakkireddy 	case CUDBG_PCIE_CONFIG:
349f35d2117SRahul Lakkireddy 		len = sizeof(u32) * CUDBG_NUM_PCIE_CONFIG_REGS;
350f35d2117SRahul Lakkireddy 		break;
351f35d2117SRahul Lakkireddy 	case CUDBG_DUMP_CONTEXT:
352f35d2117SRahul Lakkireddy 		len = cudbg_dump_context_size(adap);
353f35d2117SRahul Lakkireddy 		break;
354f35d2117SRahul Lakkireddy 	case CUDBG_MPS_TCAM:
355f35d2117SRahul Lakkireddy 		len = sizeof(struct cudbg_mps_tcam) *
356f35d2117SRahul Lakkireddy 		      adap->params.arch.mps_tcam_size;
357f35d2117SRahul Lakkireddy 		break;
358f35d2117SRahul Lakkireddy 	case CUDBG_VPD_DATA:
359f35d2117SRahul Lakkireddy 		len = sizeof(struct cudbg_vpd_data);
360f35d2117SRahul Lakkireddy 		break;
361f35d2117SRahul Lakkireddy 	case CUDBG_LE_TCAM:
362f35d2117SRahul Lakkireddy 		cudbg_fill_le_tcam_info(adap, &tcam_region);
363f35d2117SRahul Lakkireddy 		len = sizeof(struct cudbg_tcam) +
364f35d2117SRahul Lakkireddy 		      sizeof(struct cudbg_tid_data) * tcam_region.max_tid;
365f35d2117SRahul Lakkireddy 		break;
366f35d2117SRahul Lakkireddy 	case CUDBG_CCTRL:
367f35d2117SRahul Lakkireddy 		len = sizeof(u16) * NMTUS * NCCTRL_WIN;
368f35d2117SRahul Lakkireddy 		break;
369f35d2117SRahul Lakkireddy 	case CUDBG_MA_INDIRECT:
370f35d2117SRahul Lakkireddy 		if (CHELSIO_CHIP_VERSION(adap->params.chip) > CHELSIO_T5) {
371f35d2117SRahul Lakkireddy 			n = sizeof(t6_ma_ireg_array) /
372f35d2117SRahul Lakkireddy 			    (IREG_NUM_ELEM * sizeof(u32));
373f35d2117SRahul Lakkireddy 			len = sizeof(struct ireg_buf) * n * 2;
374f35d2117SRahul Lakkireddy 		}
375f35d2117SRahul Lakkireddy 		break;
376f35d2117SRahul Lakkireddy 	case CUDBG_ULPTX_LA:
377f35d2117SRahul Lakkireddy 		len = sizeof(struct cudbg_ver_hdr) +
378f35d2117SRahul Lakkireddy 		      sizeof(struct cudbg_ulptx_la);
379f35d2117SRahul Lakkireddy 		break;
380f35d2117SRahul Lakkireddy 	case CUDBG_UP_CIM_INDIRECT:
381f35d2117SRahul Lakkireddy 		n = 0;
382f35d2117SRahul Lakkireddy 		if (is_t5(adap->params.chip))
383f35d2117SRahul Lakkireddy 			n = sizeof(t5_up_cim_reg_array) /
384f35d2117SRahul Lakkireddy 			    ((IREG_NUM_ELEM + 1) * sizeof(u32));
385f35d2117SRahul Lakkireddy 		else if (is_t6(adap->params.chip))
386f35d2117SRahul Lakkireddy 			n = sizeof(t6_up_cim_reg_array) /
387f35d2117SRahul Lakkireddy 			    ((IREG_NUM_ELEM + 1) * sizeof(u32));
388f35d2117SRahul Lakkireddy 		len = sizeof(struct ireg_buf) * n;
389f35d2117SRahul Lakkireddy 		break;
390f35d2117SRahul Lakkireddy 	case CUDBG_PBT_TABLE:
391f35d2117SRahul Lakkireddy 		len = sizeof(struct cudbg_pbt_tables);
392f35d2117SRahul Lakkireddy 		break;
393f35d2117SRahul Lakkireddy 	case CUDBG_MBOX_LOG:
394f35d2117SRahul Lakkireddy 		len = sizeof(struct cudbg_mbox_log) * adap->mbox_log->size;
395f35d2117SRahul Lakkireddy 		break;
396f35d2117SRahul Lakkireddy 	case CUDBG_HMA_INDIRECT:
397f35d2117SRahul Lakkireddy 		if (CHELSIO_CHIP_VERSION(adap->params.chip) > CHELSIO_T5) {
398f35d2117SRahul Lakkireddy 			n = sizeof(t6_hma_ireg_array) /
399f35d2117SRahul Lakkireddy 			    (IREG_NUM_ELEM * sizeof(u32));
400f35d2117SRahul Lakkireddy 			len = sizeof(struct ireg_buf) * n;
401f35d2117SRahul Lakkireddy 		}
402f35d2117SRahul Lakkireddy 		break;
403f35d2117SRahul Lakkireddy 	case CUDBG_HMA:
404f35d2117SRahul Lakkireddy 		value = t4_read_reg(adap, MA_TARGET_MEM_ENABLE_A);
405f35d2117SRahul Lakkireddy 		if (value & HMA_MUX_F) {
406f35d2117SRahul Lakkireddy 			/* In T6, there's no MC1.  So, HMA shares MC1
407f35d2117SRahul Lakkireddy 			 * address space.
408f35d2117SRahul Lakkireddy 			 */
409f35d2117SRahul Lakkireddy 			value = t4_read_reg(adap, MA_EXT_MEMORY1_BAR_A);
410f35d2117SRahul Lakkireddy 			len = EXT_MEM1_SIZE_G(value);
411f35d2117SRahul Lakkireddy 		}
412f35d2117SRahul Lakkireddy 		len = cudbg_mbytes_to_bytes(len);
413f35d2117SRahul Lakkireddy 		break;
414f35d2117SRahul Lakkireddy 	case CUDBG_QDESC:
415f35d2117SRahul Lakkireddy 		cudbg_fill_qdesc_num_and_size(adap, NULL, &len);
416f35d2117SRahul Lakkireddy 		break;
417f35d2117SRahul Lakkireddy 	default:
418f35d2117SRahul Lakkireddy 		break;
419f35d2117SRahul Lakkireddy 	}
420f35d2117SRahul Lakkireddy 
421f35d2117SRahul Lakkireddy 	return len;
422f35d2117SRahul Lakkireddy }
423f35d2117SRahul Lakkireddy 
42456cf2635SRahul Lakkireddy static int cudbg_do_compression(struct cudbg_init *pdbg_init,
42556cf2635SRahul Lakkireddy 				struct cudbg_buffer *pin_buff,
426a7975a2fSRahul Lakkireddy 				struct cudbg_buffer *dbg_buff)
427a7975a2fSRahul Lakkireddy {
42856cf2635SRahul Lakkireddy 	struct cudbg_buffer temp_in_buff = { 0 };
42956cf2635SRahul Lakkireddy 	int bytes_left, bytes_read, bytes;
43056cf2635SRahul Lakkireddy 	u32 offset = dbg_buff->offset;
43156cf2635SRahul Lakkireddy 	int rc;
43256cf2635SRahul Lakkireddy 
43356cf2635SRahul Lakkireddy 	temp_in_buff.offset = pin_buff->offset;
43456cf2635SRahul Lakkireddy 	temp_in_buff.data = pin_buff->data;
43556cf2635SRahul Lakkireddy 	temp_in_buff.size = pin_buff->size;
43656cf2635SRahul Lakkireddy 
43756cf2635SRahul Lakkireddy 	bytes_left = pin_buff->size;
43856cf2635SRahul Lakkireddy 	bytes_read = 0;
43956cf2635SRahul Lakkireddy 	while (bytes_left > 0) {
44056cf2635SRahul Lakkireddy 		/* Do compression in smaller chunks */
44156cf2635SRahul Lakkireddy 		bytes = min_t(unsigned long, bytes_left,
44256cf2635SRahul Lakkireddy 			      (unsigned long)CUDBG_CHUNK_SIZE);
44356cf2635SRahul Lakkireddy 		temp_in_buff.data = (char *)pin_buff->data + bytes_read;
44456cf2635SRahul Lakkireddy 		temp_in_buff.size = bytes;
44556cf2635SRahul Lakkireddy 		rc = cudbg_compress_buff(pdbg_init, &temp_in_buff, dbg_buff);
44656cf2635SRahul Lakkireddy 		if (rc)
44756cf2635SRahul Lakkireddy 			return rc;
44856cf2635SRahul Lakkireddy 		bytes_left -= bytes;
44956cf2635SRahul Lakkireddy 		bytes_read += bytes;
45056cf2635SRahul Lakkireddy 	}
45156cf2635SRahul Lakkireddy 
45256cf2635SRahul Lakkireddy 	pin_buff->size = dbg_buff->offset - offset;
45356cf2635SRahul Lakkireddy 	return 0;
45456cf2635SRahul Lakkireddy }
45556cf2635SRahul Lakkireddy 
45656cf2635SRahul Lakkireddy static int cudbg_write_and_release_buff(struct cudbg_init *pdbg_init,
45756cf2635SRahul Lakkireddy 					struct cudbg_buffer *pin_buff,
45856cf2635SRahul Lakkireddy 					struct cudbg_buffer *dbg_buff)
45956cf2635SRahul Lakkireddy {
46056cf2635SRahul Lakkireddy 	int rc = 0;
46156cf2635SRahul Lakkireddy 
46256cf2635SRahul Lakkireddy 	if (pdbg_init->compress_type == CUDBG_COMPRESSION_NONE) {
463a7975a2fSRahul Lakkireddy 		cudbg_update_buff(pin_buff, dbg_buff);
46456cf2635SRahul Lakkireddy 	} else {
46556cf2635SRahul Lakkireddy 		rc = cudbg_do_compression(pdbg_init, pin_buff, dbg_buff);
46656cf2635SRahul Lakkireddy 		if (rc)
46756cf2635SRahul Lakkireddy 			goto out;
46856cf2635SRahul Lakkireddy 	}
46956cf2635SRahul Lakkireddy 
47056cf2635SRahul Lakkireddy out:
47156cf2635SRahul Lakkireddy 	cudbg_put_buff(pdbg_init, pin_buff);
47256cf2635SRahul Lakkireddy 	return rc;
473a7975a2fSRahul Lakkireddy }
474a7975a2fSRahul Lakkireddy 
475b33af022SRahul Lakkireddy static int is_fw_attached(struct cudbg_init *pdbg_init)
476b33af022SRahul Lakkireddy {
477b33af022SRahul Lakkireddy 	struct adapter *padap = pdbg_init->adap;
478b33af022SRahul Lakkireddy 
47980f61f19SArjun Vynipadath 	if (!(padap->flags & CXGB4_FW_OK) || padap->use_bd)
480b33af022SRahul Lakkireddy 		return 0;
481b33af022SRahul Lakkireddy 
482b33af022SRahul Lakkireddy 	return 1;
483b33af022SRahul Lakkireddy }
484b33af022SRahul Lakkireddy 
485a7975a2fSRahul Lakkireddy /* This function will add additional padding bytes into debug_buffer to make it
486a7975a2fSRahul Lakkireddy  * 4 byte aligned.
487a7975a2fSRahul Lakkireddy  */
488a7975a2fSRahul Lakkireddy void cudbg_align_debug_buffer(struct cudbg_buffer *dbg_buff,
489a7975a2fSRahul Lakkireddy 			      struct cudbg_entity_hdr *entity_hdr)
490a7975a2fSRahul Lakkireddy {
491a7975a2fSRahul Lakkireddy 	u8 zero_buf[4] = {0};
492a7975a2fSRahul Lakkireddy 	u8 padding, remain;
493a7975a2fSRahul Lakkireddy 
494a7975a2fSRahul Lakkireddy 	remain = (dbg_buff->offset - entity_hdr->start_offset) % 4;
495a7975a2fSRahul Lakkireddy 	padding = 4 - remain;
496a7975a2fSRahul Lakkireddy 	if (remain) {
497a7975a2fSRahul Lakkireddy 		memcpy(((u8 *)dbg_buff->data) + dbg_buff->offset, &zero_buf,
498a7975a2fSRahul Lakkireddy 		       padding);
499a7975a2fSRahul Lakkireddy 		dbg_buff->offset += padding;
500a7975a2fSRahul Lakkireddy 		entity_hdr->num_pad = padding;
501a7975a2fSRahul Lakkireddy 	}
502a7975a2fSRahul Lakkireddy 	entity_hdr->size = dbg_buff->offset - entity_hdr->start_offset;
503a7975a2fSRahul Lakkireddy }
504a7975a2fSRahul Lakkireddy 
505a7975a2fSRahul Lakkireddy struct cudbg_entity_hdr *cudbg_get_entity_hdr(void *outbuf, int i)
506a7975a2fSRahul Lakkireddy {
507a7975a2fSRahul Lakkireddy 	struct cudbg_hdr *cudbg_hdr = (struct cudbg_hdr *)outbuf;
508a7975a2fSRahul Lakkireddy 
509a7975a2fSRahul Lakkireddy 	return (struct cudbg_entity_hdr *)
510a7975a2fSRahul Lakkireddy 	       ((char *)outbuf + cudbg_hdr->hdr_len +
511a7975a2fSRahul Lakkireddy 		(sizeof(struct cudbg_entity_hdr) * (i - 1)));
512a7975a2fSRahul Lakkireddy }
513a7975a2fSRahul Lakkireddy 
514940c9c45SRahul Lakkireddy static int cudbg_read_vpd_reg(struct adapter *padap, u32 addr, u32 len,
515940c9c45SRahul Lakkireddy 			      void *dest)
516940c9c45SRahul Lakkireddy {
517940c9c45SRahul Lakkireddy 	int vaddr, rc;
518940c9c45SRahul Lakkireddy 
519940c9c45SRahul Lakkireddy 	vaddr = t4_eeprom_ptov(addr, padap->pf, EEPROMPFSIZE);
520940c9c45SRahul Lakkireddy 	if (vaddr < 0)
521940c9c45SRahul Lakkireddy 		return vaddr;
522940c9c45SRahul Lakkireddy 
523940c9c45SRahul Lakkireddy 	rc = pci_read_vpd(padap->pdev, vaddr, len, dest);
524940c9c45SRahul Lakkireddy 	if (rc < 0)
525940c9c45SRahul Lakkireddy 		return rc;
526940c9c45SRahul Lakkireddy 
527940c9c45SRahul Lakkireddy 	return 0;
528940c9c45SRahul Lakkireddy }
529940c9c45SRahul Lakkireddy 
530123e25c4SRahul Lakkireddy static int cudbg_mem_desc_cmp(const void *a, const void *b)
531123e25c4SRahul Lakkireddy {
532123e25c4SRahul Lakkireddy 	return ((const struct cudbg_mem_desc *)a)->base -
533123e25c4SRahul Lakkireddy 	       ((const struct cudbg_mem_desc *)b)->base;
534123e25c4SRahul Lakkireddy }
535123e25c4SRahul Lakkireddy 
536123e25c4SRahul Lakkireddy int cudbg_fill_meminfo(struct adapter *padap,
537123e25c4SRahul Lakkireddy 		       struct cudbg_meminfo *meminfo_buff)
538123e25c4SRahul Lakkireddy {
539123e25c4SRahul Lakkireddy 	struct cudbg_mem_desc *md;
540123e25c4SRahul Lakkireddy 	u32 lo, hi, used, alloc;
541123e25c4SRahul Lakkireddy 	int n, i;
542123e25c4SRahul Lakkireddy 
543123e25c4SRahul Lakkireddy 	memset(meminfo_buff->avail, 0,
544123e25c4SRahul Lakkireddy 	       ARRAY_SIZE(meminfo_buff->avail) *
545123e25c4SRahul Lakkireddy 	       sizeof(struct cudbg_mem_desc));
546123e25c4SRahul Lakkireddy 	memset(meminfo_buff->mem, 0,
547123e25c4SRahul Lakkireddy 	       (ARRAY_SIZE(cudbg_region) + 3) * sizeof(struct cudbg_mem_desc));
548123e25c4SRahul Lakkireddy 	md  = meminfo_buff->mem;
549123e25c4SRahul Lakkireddy 
550123e25c4SRahul Lakkireddy 	for (i = 0; i < ARRAY_SIZE(meminfo_buff->mem); i++) {
551123e25c4SRahul Lakkireddy 		meminfo_buff->mem[i].limit = 0;
552123e25c4SRahul Lakkireddy 		meminfo_buff->mem[i].idx = i;
553123e25c4SRahul Lakkireddy 	}
554123e25c4SRahul Lakkireddy 
555123e25c4SRahul Lakkireddy 	/* Find and sort the populated memory ranges */
556123e25c4SRahul Lakkireddy 	i = 0;
557123e25c4SRahul Lakkireddy 	lo = t4_read_reg(padap, MA_TARGET_MEM_ENABLE_A);
558123e25c4SRahul Lakkireddy 	if (lo & EDRAM0_ENABLE_F) {
559123e25c4SRahul Lakkireddy 		hi = t4_read_reg(padap, MA_EDRAM0_BAR_A);
560123e25c4SRahul Lakkireddy 		meminfo_buff->avail[i].base =
561123e25c4SRahul Lakkireddy 			cudbg_mbytes_to_bytes(EDRAM0_BASE_G(hi));
562123e25c4SRahul Lakkireddy 		meminfo_buff->avail[i].limit =
563123e25c4SRahul Lakkireddy 			meminfo_buff->avail[i].base +
564123e25c4SRahul Lakkireddy 			cudbg_mbytes_to_bytes(EDRAM0_SIZE_G(hi));
565123e25c4SRahul Lakkireddy 		meminfo_buff->avail[i].idx = 0;
566123e25c4SRahul Lakkireddy 		i++;
567123e25c4SRahul Lakkireddy 	}
568123e25c4SRahul Lakkireddy 
569123e25c4SRahul Lakkireddy 	if (lo & EDRAM1_ENABLE_F) {
570123e25c4SRahul Lakkireddy 		hi =  t4_read_reg(padap, MA_EDRAM1_BAR_A);
571123e25c4SRahul Lakkireddy 		meminfo_buff->avail[i].base =
572123e25c4SRahul Lakkireddy 			cudbg_mbytes_to_bytes(EDRAM1_BASE_G(hi));
573123e25c4SRahul Lakkireddy 		meminfo_buff->avail[i].limit =
574123e25c4SRahul Lakkireddy 			meminfo_buff->avail[i].base +
575123e25c4SRahul Lakkireddy 			cudbg_mbytes_to_bytes(EDRAM1_SIZE_G(hi));
576123e25c4SRahul Lakkireddy 		meminfo_buff->avail[i].idx = 1;
577123e25c4SRahul Lakkireddy 		i++;
578123e25c4SRahul Lakkireddy 	}
579123e25c4SRahul Lakkireddy 
580123e25c4SRahul Lakkireddy 	if (is_t5(padap->params.chip)) {
581123e25c4SRahul Lakkireddy 		if (lo & EXT_MEM0_ENABLE_F) {
582123e25c4SRahul Lakkireddy 			hi = t4_read_reg(padap, MA_EXT_MEMORY0_BAR_A);
583123e25c4SRahul Lakkireddy 			meminfo_buff->avail[i].base =
584123e25c4SRahul Lakkireddy 				cudbg_mbytes_to_bytes(EXT_MEM_BASE_G(hi));
585123e25c4SRahul Lakkireddy 			meminfo_buff->avail[i].limit =
586123e25c4SRahul Lakkireddy 				meminfo_buff->avail[i].base +
587123e25c4SRahul Lakkireddy 				cudbg_mbytes_to_bytes(EXT_MEM_SIZE_G(hi));
588123e25c4SRahul Lakkireddy 			meminfo_buff->avail[i].idx = 3;
589123e25c4SRahul Lakkireddy 			i++;
590123e25c4SRahul Lakkireddy 		}
591123e25c4SRahul Lakkireddy 
592123e25c4SRahul Lakkireddy 		if (lo & EXT_MEM1_ENABLE_F) {
593123e25c4SRahul Lakkireddy 			hi = t4_read_reg(padap, MA_EXT_MEMORY1_BAR_A);
594123e25c4SRahul Lakkireddy 			meminfo_buff->avail[i].base =
595123e25c4SRahul Lakkireddy 				cudbg_mbytes_to_bytes(EXT_MEM1_BASE_G(hi));
596123e25c4SRahul Lakkireddy 			meminfo_buff->avail[i].limit =
597123e25c4SRahul Lakkireddy 				meminfo_buff->avail[i].base +
598123e25c4SRahul Lakkireddy 				cudbg_mbytes_to_bytes(EXT_MEM1_SIZE_G(hi));
599123e25c4SRahul Lakkireddy 			meminfo_buff->avail[i].idx = 4;
600123e25c4SRahul Lakkireddy 			i++;
601123e25c4SRahul Lakkireddy 		}
602123e25c4SRahul Lakkireddy 	} else {
603123e25c4SRahul Lakkireddy 		if (lo & EXT_MEM_ENABLE_F) {
604123e25c4SRahul Lakkireddy 			hi = t4_read_reg(padap, MA_EXT_MEMORY_BAR_A);
605123e25c4SRahul Lakkireddy 			meminfo_buff->avail[i].base =
606123e25c4SRahul Lakkireddy 				cudbg_mbytes_to_bytes(EXT_MEM_BASE_G(hi));
607123e25c4SRahul Lakkireddy 			meminfo_buff->avail[i].limit =
608123e25c4SRahul Lakkireddy 				meminfo_buff->avail[i].base +
609123e25c4SRahul Lakkireddy 				cudbg_mbytes_to_bytes(EXT_MEM_SIZE_G(hi));
610123e25c4SRahul Lakkireddy 			meminfo_buff->avail[i].idx = 2;
611123e25c4SRahul Lakkireddy 			i++;
612123e25c4SRahul Lakkireddy 		}
6134db0401fSRahul Lakkireddy 
6144db0401fSRahul Lakkireddy 		if (lo & HMA_MUX_F) {
6154db0401fSRahul Lakkireddy 			hi = t4_read_reg(padap, MA_EXT_MEMORY1_BAR_A);
6164db0401fSRahul Lakkireddy 			meminfo_buff->avail[i].base =
6174db0401fSRahul Lakkireddy 				cudbg_mbytes_to_bytes(EXT_MEM1_BASE_G(hi));
6184db0401fSRahul Lakkireddy 			meminfo_buff->avail[i].limit =
6194db0401fSRahul Lakkireddy 				meminfo_buff->avail[i].base +
6204db0401fSRahul Lakkireddy 				cudbg_mbytes_to_bytes(EXT_MEM1_SIZE_G(hi));
6214db0401fSRahul Lakkireddy 			meminfo_buff->avail[i].idx = 5;
6224db0401fSRahul Lakkireddy 			i++;
6234db0401fSRahul Lakkireddy 		}
624123e25c4SRahul Lakkireddy 	}
625123e25c4SRahul Lakkireddy 
626123e25c4SRahul Lakkireddy 	if (!i) /* no memory available */
627123e25c4SRahul Lakkireddy 		return CUDBG_STATUS_ENTITY_NOT_FOUND;
628123e25c4SRahul Lakkireddy 
629123e25c4SRahul Lakkireddy 	meminfo_buff->avail_c = i;
630123e25c4SRahul Lakkireddy 	sort(meminfo_buff->avail, i, sizeof(struct cudbg_mem_desc),
631123e25c4SRahul Lakkireddy 	     cudbg_mem_desc_cmp, NULL);
632123e25c4SRahul Lakkireddy 	(md++)->base = t4_read_reg(padap, SGE_DBQ_CTXT_BADDR_A);
633123e25c4SRahul Lakkireddy 	(md++)->base = t4_read_reg(padap, SGE_IMSG_CTXT_BADDR_A);
634123e25c4SRahul Lakkireddy 	(md++)->base = t4_read_reg(padap, SGE_FLM_CACHE_BADDR_A);
635123e25c4SRahul Lakkireddy 	(md++)->base = t4_read_reg(padap, TP_CMM_TCB_BASE_A);
636123e25c4SRahul Lakkireddy 	(md++)->base = t4_read_reg(padap, TP_CMM_MM_BASE_A);
637123e25c4SRahul Lakkireddy 	(md++)->base = t4_read_reg(padap, TP_CMM_TIMER_BASE_A);
638123e25c4SRahul Lakkireddy 	(md++)->base = t4_read_reg(padap, TP_CMM_MM_RX_FLST_BASE_A);
639123e25c4SRahul Lakkireddy 	(md++)->base = t4_read_reg(padap, TP_CMM_MM_TX_FLST_BASE_A);
640123e25c4SRahul Lakkireddy 	(md++)->base = t4_read_reg(padap, TP_CMM_MM_PS_FLST_BASE_A);
641123e25c4SRahul Lakkireddy 
642123e25c4SRahul Lakkireddy 	/* the next few have explicit upper bounds */
643123e25c4SRahul Lakkireddy 	md->base = t4_read_reg(padap, TP_PMM_TX_BASE_A);
644123e25c4SRahul Lakkireddy 	md->limit = md->base - 1 +
645123e25c4SRahul Lakkireddy 		    t4_read_reg(padap, TP_PMM_TX_PAGE_SIZE_A) *
646123e25c4SRahul Lakkireddy 		    PMTXMAXPAGE_G(t4_read_reg(padap, TP_PMM_TX_MAX_PAGE_A));
647123e25c4SRahul Lakkireddy 	md++;
648123e25c4SRahul Lakkireddy 
649123e25c4SRahul Lakkireddy 	md->base = t4_read_reg(padap, TP_PMM_RX_BASE_A);
650123e25c4SRahul Lakkireddy 	md->limit = md->base - 1 +
651123e25c4SRahul Lakkireddy 		    t4_read_reg(padap, TP_PMM_RX_PAGE_SIZE_A) *
652123e25c4SRahul Lakkireddy 		    PMRXMAXPAGE_G(t4_read_reg(padap, TP_PMM_RX_MAX_PAGE_A));
653123e25c4SRahul Lakkireddy 	md++;
654123e25c4SRahul Lakkireddy 
655123e25c4SRahul Lakkireddy 	if (t4_read_reg(padap, LE_DB_CONFIG_A) & HASHEN_F) {
656123e25c4SRahul Lakkireddy 		if (CHELSIO_CHIP_VERSION(padap->params.chip) <= CHELSIO_T5) {
657123e25c4SRahul Lakkireddy 			hi = t4_read_reg(padap, LE_DB_TID_HASHBASE_A) / 4;
658123e25c4SRahul Lakkireddy 			md->base = t4_read_reg(padap, LE_DB_HASH_TID_BASE_A);
659123e25c4SRahul Lakkireddy 		} else {
660123e25c4SRahul Lakkireddy 			hi = t4_read_reg(padap, LE_DB_HASH_TID_BASE_A);
661123e25c4SRahul Lakkireddy 			md->base = t4_read_reg(padap,
662123e25c4SRahul Lakkireddy 					       LE_DB_HASH_TBL_BASE_ADDR_A);
663123e25c4SRahul Lakkireddy 		}
664123e25c4SRahul Lakkireddy 		md->limit = 0;
665123e25c4SRahul Lakkireddy 	} else {
666123e25c4SRahul Lakkireddy 		md->base = 0;
667123e25c4SRahul Lakkireddy 		md->idx = ARRAY_SIZE(cudbg_region);  /* hide it */
668123e25c4SRahul Lakkireddy 	}
669123e25c4SRahul Lakkireddy 	md++;
670123e25c4SRahul Lakkireddy 
671123e25c4SRahul Lakkireddy #define ulp_region(reg) do { \
672123e25c4SRahul Lakkireddy 	md->base = t4_read_reg(padap, ULP_ ## reg ## _LLIMIT_A);\
673123e25c4SRahul Lakkireddy 	(md++)->limit = t4_read_reg(padap, ULP_ ## reg ## _ULIMIT_A);\
674123e25c4SRahul Lakkireddy } while (0)
675123e25c4SRahul Lakkireddy 
676123e25c4SRahul Lakkireddy 	ulp_region(RX_ISCSI);
677123e25c4SRahul Lakkireddy 	ulp_region(RX_TDDP);
678123e25c4SRahul Lakkireddy 	ulp_region(TX_TPT);
679123e25c4SRahul Lakkireddy 	ulp_region(RX_STAG);
680123e25c4SRahul Lakkireddy 	ulp_region(RX_RQ);
681123e25c4SRahul Lakkireddy 	ulp_region(RX_RQUDP);
682123e25c4SRahul Lakkireddy 	ulp_region(RX_PBL);
683123e25c4SRahul Lakkireddy 	ulp_region(TX_PBL);
684123e25c4SRahul Lakkireddy #undef ulp_region
685123e25c4SRahul Lakkireddy 	md->base = 0;
686123e25c4SRahul Lakkireddy 	md->idx = ARRAY_SIZE(cudbg_region);
687123e25c4SRahul Lakkireddy 	if (!is_t4(padap->params.chip)) {
688123e25c4SRahul Lakkireddy 		u32 fifo_size = t4_read_reg(padap, SGE_DBVFIFO_SIZE_A);
689123e25c4SRahul Lakkireddy 		u32 sge_ctrl = t4_read_reg(padap, SGE_CONTROL2_A);
690123e25c4SRahul Lakkireddy 		u32 size = 0;
691123e25c4SRahul Lakkireddy 
692123e25c4SRahul Lakkireddy 		if (is_t5(padap->params.chip)) {
693123e25c4SRahul Lakkireddy 			if (sge_ctrl & VFIFO_ENABLE_F)
694123e25c4SRahul Lakkireddy 				size = DBVFIFO_SIZE_G(fifo_size);
695123e25c4SRahul Lakkireddy 		} else {
696123e25c4SRahul Lakkireddy 			size = T6_DBVFIFO_SIZE_G(fifo_size);
697123e25c4SRahul Lakkireddy 		}
698123e25c4SRahul Lakkireddy 
699123e25c4SRahul Lakkireddy 		if (size) {
700123e25c4SRahul Lakkireddy 			md->base = BASEADDR_G(t4_read_reg(padap,
701123e25c4SRahul Lakkireddy 							  SGE_DBVFIFO_BADDR_A));
702123e25c4SRahul Lakkireddy 			md->limit = md->base + (size << 2) - 1;
703123e25c4SRahul Lakkireddy 		}
704123e25c4SRahul Lakkireddy 	}
705123e25c4SRahul Lakkireddy 
706123e25c4SRahul Lakkireddy 	md++;
707123e25c4SRahul Lakkireddy 
708123e25c4SRahul Lakkireddy 	md->base = t4_read_reg(padap, ULP_RX_CTX_BASE_A);
709123e25c4SRahul Lakkireddy 	md->limit = 0;
710123e25c4SRahul Lakkireddy 	md++;
711123e25c4SRahul Lakkireddy 	md->base = t4_read_reg(padap, ULP_TX_ERR_TABLE_BASE_A);
712123e25c4SRahul Lakkireddy 	md->limit = 0;
713123e25c4SRahul Lakkireddy 	md++;
714123e25c4SRahul Lakkireddy 
715123e25c4SRahul Lakkireddy 	md->base = padap->vres.ocq.start;
716123e25c4SRahul Lakkireddy 	if (padap->vres.ocq.size)
717123e25c4SRahul Lakkireddy 		md->limit = md->base + padap->vres.ocq.size - 1;
718123e25c4SRahul Lakkireddy 	else
719123e25c4SRahul Lakkireddy 		md->idx = ARRAY_SIZE(cudbg_region);  /* hide it */
720123e25c4SRahul Lakkireddy 	md++;
721123e25c4SRahul Lakkireddy 
722123e25c4SRahul Lakkireddy 	/* add any address-space holes, there can be up to 3 */
723123e25c4SRahul Lakkireddy 	for (n = 0; n < i - 1; n++)
724123e25c4SRahul Lakkireddy 		if (meminfo_buff->avail[n].limit <
725123e25c4SRahul Lakkireddy 		    meminfo_buff->avail[n + 1].base)
726123e25c4SRahul Lakkireddy 			(md++)->base = meminfo_buff->avail[n].limit;
727123e25c4SRahul Lakkireddy 
728123e25c4SRahul Lakkireddy 	if (meminfo_buff->avail[n].limit)
729123e25c4SRahul Lakkireddy 		(md++)->base = meminfo_buff->avail[n].limit;
730123e25c4SRahul Lakkireddy 
731123e25c4SRahul Lakkireddy 	n = md - meminfo_buff->mem;
732123e25c4SRahul Lakkireddy 	meminfo_buff->mem_c = n;
733123e25c4SRahul Lakkireddy 
734123e25c4SRahul Lakkireddy 	sort(meminfo_buff->mem, n, sizeof(struct cudbg_mem_desc),
735123e25c4SRahul Lakkireddy 	     cudbg_mem_desc_cmp, NULL);
736123e25c4SRahul Lakkireddy 
737123e25c4SRahul Lakkireddy 	lo = t4_read_reg(padap, CIM_SDRAM_BASE_ADDR_A);
738123e25c4SRahul Lakkireddy 	hi = t4_read_reg(padap, CIM_SDRAM_ADDR_SIZE_A) + lo - 1;
739123e25c4SRahul Lakkireddy 	meminfo_buff->up_ram_lo = lo;
740123e25c4SRahul Lakkireddy 	meminfo_buff->up_ram_hi = hi;
741123e25c4SRahul Lakkireddy 
742123e25c4SRahul Lakkireddy 	lo = t4_read_reg(padap, CIM_EXTMEM2_BASE_ADDR_A);
743123e25c4SRahul Lakkireddy 	hi = t4_read_reg(padap, CIM_EXTMEM2_ADDR_SIZE_A) + lo - 1;
744123e25c4SRahul Lakkireddy 	meminfo_buff->up_extmem2_lo = lo;
745123e25c4SRahul Lakkireddy 	meminfo_buff->up_extmem2_hi = hi;
746123e25c4SRahul Lakkireddy 
747123e25c4SRahul Lakkireddy 	lo = t4_read_reg(padap, TP_PMM_RX_MAX_PAGE_A);
748ae2a922fSRahul Lakkireddy 	for (i = 0, meminfo_buff->free_rx_cnt = 0; i < 2; i++)
749ae2a922fSRahul Lakkireddy 		meminfo_buff->free_rx_cnt +=
750ae2a922fSRahul Lakkireddy 			FREERXPAGECOUNT_G(t4_read_reg(padap,
751ae2a922fSRahul Lakkireddy 						      TP_FLM_FREE_RX_CNT_A));
752ae2a922fSRahul Lakkireddy 
753123e25c4SRahul Lakkireddy 	meminfo_buff->rx_pages_data[0] =  PMRXMAXPAGE_G(lo);
754123e25c4SRahul Lakkireddy 	meminfo_buff->rx_pages_data[1] =
755123e25c4SRahul Lakkireddy 		t4_read_reg(padap, TP_PMM_RX_PAGE_SIZE_A) >> 10;
756123e25c4SRahul Lakkireddy 	meminfo_buff->rx_pages_data[2] = (lo & PMRXNUMCHN_F) ? 2 : 1;
757123e25c4SRahul Lakkireddy 
758123e25c4SRahul Lakkireddy 	lo = t4_read_reg(padap, TP_PMM_TX_MAX_PAGE_A);
759123e25c4SRahul Lakkireddy 	hi = t4_read_reg(padap, TP_PMM_TX_PAGE_SIZE_A);
760ae2a922fSRahul Lakkireddy 	for (i = 0, meminfo_buff->free_tx_cnt = 0; i < 4; i++)
761ae2a922fSRahul Lakkireddy 		meminfo_buff->free_tx_cnt +=
762ae2a922fSRahul Lakkireddy 			FREETXPAGECOUNT_G(t4_read_reg(padap,
763ae2a922fSRahul Lakkireddy 						      TP_FLM_FREE_TX_CNT_A));
764ae2a922fSRahul Lakkireddy 
765123e25c4SRahul Lakkireddy 	meminfo_buff->tx_pages_data[0] = PMTXMAXPAGE_G(lo);
766123e25c4SRahul Lakkireddy 	meminfo_buff->tx_pages_data[1] =
767123e25c4SRahul Lakkireddy 		hi >= (1 << 20) ? (hi >> 20) : (hi >> 10);
768123e25c4SRahul Lakkireddy 	meminfo_buff->tx_pages_data[2] =
769123e25c4SRahul Lakkireddy 		hi >= (1 << 20) ? 'M' : 'K';
770123e25c4SRahul Lakkireddy 	meminfo_buff->tx_pages_data[3] = 1 << PMTXNUMCHN_G(lo);
771123e25c4SRahul Lakkireddy 
772123e25c4SRahul Lakkireddy 	meminfo_buff->p_structs = t4_read_reg(padap, TP_CMM_MM_MAX_PSTRUCT_A);
7739d0f180cSRahul Lakkireddy 	meminfo_buff->p_structs_free_cnt =
7749d0f180cSRahul Lakkireddy 		FREEPSTRUCTCOUNT_G(t4_read_reg(padap, TP_FLM_FREE_PS_CNT_A));
775123e25c4SRahul Lakkireddy 
776123e25c4SRahul Lakkireddy 	for (i = 0; i < 4; i++) {
777123e25c4SRahul Lakkireddy 		if (CHELSIO_CHIP_VERSION(padap->params.chip) > CHELSIO_T5)
778123e25c4SRahul Lakkireddy 			lo = t4_read_reg(padap,
779123e25c4SRahul Lakkireddy 					 MPS_RX_MAC_BG_PG_CNT0_A + i * 4);
780123e25c4SRahul Lakkireddy 		else
781123e25c4SRahul Lakkireddy 			lo = t4_read_reg(padap, MPS_RX_PG_RSV0_A + i * 4);
782123e25c4SRahul Lakkireddy 		if (is_t5(padap->params.chip)) {
783123e25c4SRahul Lakkireddy 			used = T5_USED_G(lo);
784123e25c4SRahul Lakkireddy 			alloc = T5_ALLOC_G(lo);
785123e25c4SRahul Lakkireddy 		} else {
786123e25c4SRahul Lakkireddy 			used = USED_G(lo);
787123e25c4SRahul Lakkireddy 			alloc = ALLOC_G(lo);
788123e25c4SRahul Lakkireddy 		}
789123e25c4SRahul Lakkireddy 		meminfo_buff->port_used[i] = used;
790123e25c4SRahul Lakkireddy 		meminfo_buff->port_alloc[i] = alloc;
791123e25c4SRahul Lakkireddy 	}
792123e25c4SRahul Lakkireddy 
793123e25c4SRahul Lakkireddy 	for (i = 0; i < padap->params.arch.nchan; i++) {
794123e25c4SRahul Lakkireddy 		if (CHELSIO_CHIP_VERSION(padap->params.chip) > CHELSIO_T5)
795123e25c4SRahul Lakkireddy 			lo = t4_read_reg(padap,
796123e25c4SRahul Lakkireddy 					 MPS_RX_LPBK_BG_PG_CNT0_A + i * 4);
797123e25c4SRahul Lakkireddy 		else
798123e25c4SRahul Lakkireddy 			lo = t4_read_reg(padap, MPS_RX_PG_RSV4_A + i * 4);
799123e25c4SRahul Lakkireddy 		if (is_t5(padap->params.chip)) {
800123e25c4SRahul Lakkireddy 			used = T5_USED_G(lo);
801123e25c4SRahul Lakkireddy 			alloc = T5_ALLOC_G(lo);
802123e25c4SRahul Lakkireddy 		} else {
803123e25c4SRahul Lakkireddy 			used = USED_G(lo);
804123e25c4SRahul Lakkireddy 			alloc = ALLOC_G(lo);
805123e25c4SRahul Lakkireddy 		}
806123e25c4SRahul Lakkireddy 		meminfo_buff->loopback_used[i] = used;
807123e25c4SRahul Lakkireddy 		meminfo_buff->loopback_alloc[i] = alloc;
808123e25c4SRahul Lakkireddy 	}
809123e25c4SRahul Lakkireddy 
810123e25c4SRahul Lakkireddy 	return 0;
811123e25c4SRahul Lakkireddy }
812123e25c4SRahul Lakkireddy 
813a7975a2fSRahul Lakkireddy int cudbg_collect_reg_dump(struct cudbg_init *pdbg_init,
814a7975a2fSRahul Lakkireddy 			   struct cudbg_buffer *dbg_buff,
815a7975a2fSRahul Lakkireddy 			   struct cudbg_error *cudbg_err)
816a7975a2fSRahul Lakkireddy {
817a7975a2fSRahul Lakkireddy 	struct adapter *padap = pdbg_init->adap;
818a7975a2fSRahul Lakkireddy 	struct cudbg_buffer temp_buff = { 0 };
819a7975a2fSRahul Lakkireddy 	u32 buf_size = 0;
820a7975a2fSRahul Lakkireddy 	int rc = 0;
821a7975a2fSRahul Lakkireddy 
822a7975a2fSRahul Lakkireddy 	if (is_t4(padap->params.chip))
823a7975a2fSRahul Lakkireddy 		buf_size = T4_REGMAP_SIZE;
824a7975a2fSRahul Lakkireddy 	else if (is_t5(padap->params.chip) || is_t6(padap->params.chip))
825a7975a2fSRahul Lakkireddy 		buf_size = T5_REGMAP_SIZE;
826a7975a2fSRahul Lakkireddy 
82756cf2635SRahul Lakkireddy 	rc = cudbg_get_buff(pdbg_init, dbg_buff, buf_size, &temp_buff);
828a7975a2fSRahul Lakkireddy 	if (rc)
829a7975a2fSRahul Lakkireddy 		return rc;
830a7975a2fSRahul Lakkireddy 	t4_get_regs(padap, (void *)temp_buff.data, temp_buff.size);
83156cf2635SRahul Lakkireddy 	return cudbg_write_and_release_buff(pdbg_init, &temp_buff, dbg_buff);
832a7975a2fSRahul Lakkireddy }
833b33af022SRahul Lakkireddy 
834844d1b6fSRahul Lakkireddy int cudbg_collect_fw_devlog(struct cudbg_init *pdbg_init,
835844d1b6fSRahul Lakkireddy 			    struct cudbg_buffer *dbg_buff,
836844d1b6fSRahul Lakkireddy 			    struct cudbg_error *cudbg_err)
837844d1b6fSRahul Lakkireddy {
838844d1b6fSRahul Lakkireddy 	struct adapter *padap = pdbg_init->adap;
839844d1b6fSRahul Lakkireddy 	struct cudbg_buffer temp_buff = { 0 };
840844d1b6fSRahul Lakkireddy 	struct devlog_params *dparams;
841844d1b6fSRahul Lakkireddy 	int rc = 0;
842844d1b6fSRahul Lakkireddy 
843844d1b6fSRahul Lakkireddy 	rc = t4_init_devlog_params(padap);
844844d1b6fSRahul Lakkireddy 	if (rc < 0) {
845844d1b6fSRahul Lakkireddy 		cudbg_err->sys_err = rc;
846844d1b6fSRahul Lakkireddy 		return rc;
847844d1b6fSRahul Lakkireddy 	}
848844d1b6fSRahul Lakkireddy 
849844d1b6fSRahul Lakkireddy 	dparams = &padap->params.devlog;
85056cf2635SRahul Lakkireddy 	rc = cudbg_get_buff(pdbg_init, dbg_buff, dparams->size, &temp_buff);
851844d1b6fSRahul Lakkireddy 	if (rc)
852844d1b6fSRahul Lakkireddy 		return rc;
853844d1b6fSRahul Lakkireddy 
854844d1b6fSRahul Lakkireddy 	/* Collect FW devlog */
855844d1b6fSRahul Lakkireddy 	if (dparams->start != 0) {
856844d1b6fSRahul Lakkireddy 		spin_lock(&padap->win0_lock);
857844d1b6fSRahul Lakkireddy 		rc = t4_memory_rw(padap, padap->params.drv_memwin,
858844d1b6fSRahul Lakkireddy 				  dparams->memtype, dparams->start,
859844d1b6fSRahul Lakkireddy 				  dparams->size,
860844d1b6fSRahul Lakkireddy 				  (__be32 *)(char *)temp_buff.data,
861844d1b6fSRahul Lakkireddy 				  1);
862844d1b6fSRahul Lakkireddy 		spin_unlock(&padap->win0_lock);
863844d1b6fSRahul Lakkireddy 		if (rc) {
864844d1b6fSRahul Lakkireddy 			cudbg_err->sys_err = rc;
86556cf2635SRahul Lakkireddy 			cudbg_put_buff(pdbg_init, &temp_buff);
866844d1b6fSRahul Lakkireddy 			return rc;
867844d1b6fSRahul Lakkireddy 		}
868844d1b6fSRahul Lakkireddy 	}
86956cf2635SRahul Lakkireddy 	return cudbg_write_and_release_buff(pdbg_init, &temp_buff, dbg_buff);
870844d1b6fSRahul Lakkireddy }
871844d1b6fSRahul Lakkireddy 
87227887bc7SRahul Lakkireddy int cudbg_collect_cim_la(struct cudbg_init *pdbg_init,
87327887bc7SRahul Lakkireddy 			 struct cudbg_buffer *dbg_buff,
87427887bc7SRahul Lakkireddy 			 struct cudbg_error *cudbg_err)
87527887bc7SRahul Lakkireddy {
87627887bc7SRahul Lakkireddy 	struct adapter *padap = pdbg_init->adap;
87727887bc7SRahul Lakkireddy 	struct cudbg_buffer temp_buff = { 0 };
87827887bc7SRahul Lakkireddy 	int size, rc;
87927887bc7SRahul Lakkireddy 	u32 cfg = 0;
88027887bc7SRahul Lakkireddy 
88127887bc7SRahul Lakkireddy 	if (is_t6(padap->params.chip)) {
88227887bc7SRahul Lakkireddy 		size = padap->params.cim_la_size / 10 + 1;
883e6f02a4dSRahul Lakkireddy 		size *= 10 * sizeof(u32);
88427887bc7SRahul Lakkireddy 	} else {
88527887bc7SRahul Lakkireddy 		size = padap->params.cim_la_size / 8;
88627887bc7SRahul Lakkireddy 		size *= 8 * sizeof(u32);
88727887bc7SRahul Lakkireddy 	}
88827887bc7SRahul Lakkireddy 
88927887bc7SRahul Lakkireddy 	size += sizeof(cfg);
89056cf2635SRahul Lakkireddy 	rc = cudbg_get_buff(pdbg_init, dbg_buff, size, &temp_buff);
89127887bc7SRahul Lakkireddy 	if (rc)
89227887bc7SRahul Lakkireddy 		return rc;
89327887bc7SRahul Lakkireddy 
89427887bc7SRahul Lakkireddy 	rc = t4_cim_read(padap, UP_UP_DBG_LA_CFG_A, 1, &cfg);
89527887bc7SRahul Lakkireddy 	if (rc) {
89627887bc7SRahul Lakkireddy 		cudbg_err->sys_err = rc;
89756cf2635SRahul Lakkireddy 		cudbg_put_buff(pdbg_init, &temp_buff);
89827887bc7SRahul Lakkireddy 		return rc;
89927887bc7SRahul Lakkireddy 	}
90027887bc7SRahul Lakkireddy 
90127887bc7SRahul Lakkireddy 	memcpy((char *)temp_buff.data, &cfg, sizeof(cfg));
90227887bc7SRahul Lakkireddy 	rc = t4_cim_read_la(padap,
90327887bc7SRahul Lakkireddy 			    (u32 *)((char *)temp_buff.data + sizeof(cfg)),
90427887bc7SRahul Lakkireddy 			    NULL);
90527887bc7SRahul Lakkireddy 	if (rc < 0) {
90627887bc7SRahul Lakkireddy 		cudbg_err->sys_err = rc;
90756cf2635SRahul Lakkireddy 		cudbg_put_buff(pdbg_init, &temp_buff);
90827887bc7SRahul Lakkireddy 		return rc;
90927887bc7SRahul Lakkireddy 	}
91056cf2635SRahul Lakkireddy 	return cudbg_write_and_release_buff(pdbg_init, &temp_buff, dbg_buff);
91127887bc7SRahul Lakkireddy }
91227887bc7SRahul Lakkireddy 
91327887bc7SRahul Lakkireddy int cudbg_collect_cim_ma_la(struct cudbg_init *pdbg_init,
91427887bc7SRahul Lakkireddy 			    struct cudbg_buffer *dbg_buff,
91527887bc7SRahul Lakkireddy 			    struct cudbg_error *cudbg_err)
91627887bc7SRahul Lakkireddy {
91727887bc7SRahul Lakkireddy 	struct adapter *padap = pdbg_init->adap;
91827887bc7SRahul Lakkireddy 	struct cudbg_buffer temp_buff = { 0 };
91927887bc7SRahul Lakkireddy 	int size, rc;
92027887bc7SRahul Lakkireddy 
92127887bc7SRahul Lakkireddy 	size = 2 * CIM_MALA_SIZE * 5 * sizeof(u32);
92256cf2635SRahul Lakkireddy 	rc = cudbg_get_buff(pdbg_init, dbg_buff, size, &temp_buff);
92327887bc7SRahul Lakkireddy 	if (rc)
92427887bc7SRahul Lakkireddy 		return rc;
92527887bc7SRahul Lakkireddy 
92627887bc7SRahul Lakkireddy 	t4_cim_read_ma_la(padap,
92727887bc7SRahul Lakkireddy 			  (u32 *)temp_buff.data,
92827887bc7SRahul Lakkireddy 			  (u32 *)((char *)temp_buff.data +
92927887bc7SRahul Lakkireddy 				  5 * CIM_MALA_SIZE));
93056cf2635SRahul Lakkireddy 	return cudbg_write_and_release_buff(pdbg_init, &temp_buff, dbg_buff);
93127887bc7SRahul Lakkireddy }
93227887bc7SRahul Lakkireddy 
9333044d0fbSRahul Lakkireddy int cudbg_collect_cim_qcfg(struct cudbg_init *pdbg_init,
9343044d0fbSRahul Lakkireddy 			   struct cudbg_buffer *dbg_buff,
9353044d0fbSRahul Lakkireddy 			   struct cudbg_error *cudbg_err)
9363044d0fbSRahul Lakkireddy {
9373044d0fbSRahul Lakkireddy 	struct adapter *padap = pdbg_init->adap;
9383044d0fbSRahul Lakkireddy 	struct cudbg_buffer temp_buff = { 0 };
9393044d0fbSRahul Lakkireddy 	struct cudbg_cim_qcfg *cim_qcfg_data;
9403044d0fbSRahul Lakkireddy 	int rc;
9413044d0fbSRahul Lakkireddy 
94256cf2635SRahul Lakkireddy 	rc = cudbg_get_buff(pdbg_init, dbg_buff, sizeof(struct cudbg_cim_qcfg),
9433044d0fbSRahul Lakkireddy 			    &temp_buff);
9443044d0fbSRahul Lakkireddy 	if (rc)
9453044d0fbSRahul Lakkireddy 		return rc;
9463044d0fbSRahul Lakkireddy 
9473044d0fbSRahul Lakkireddy 	cim_qcfg_data = (struct cudbg_cim_qcfg *)temp_buff.data;
9483044d0fbSRahul Lakkireddy 	cim_qcfg_data->chip = padap->params.chip;
9493044d0fbSRahul Lakkireddy 	rc = t4_cim_read(padap, UP_IBQ_0_RDADDR_A,
9503044d0fbSRahul Lakkireddy 			 ARRAY_SIZE(cim_qcfg_data->stat), cim_qcfg_data->stat);
9513044d0fbSRahul Lakkireddy 	if (rc) {
9523044d0fbSRahul Lakkireddy 		cudbg_err->sys_err = rc;
95356cf2635SRahul Lakkireddy 		cudbg_put_buff(pdbg_init, &temp_buff);
9543044d0fbSRahul Lakkireddy 		return rc;
9553044d0fbSRahul Lakkireddy 	}
9563044d0fbSRahul Lakkireddy 
9573044d0fbSRahul Lakkireddy 	rc = t4_cim_read(padap, UP_OBQ_0_REALADDR_A,
9583044d0fbSRahul Lakkireddy 			 ARRAY_SIZE(cim_qcfg_data->obq_wr),
9593044d0fbSRahul Lakkireddy 			 cim_qcfg_data->obq_wr);
9603044d0fbSRahul Lakkireddy 	if (rc) {
9613044d0fbSRahul Lakkireddy 		cudbg_err->sys_err = rc;
96256cf2635SRahul Lakkireddy 		cudbg_put_buff(pdbg_init, &temp_buff);
9633044d0fbSRahul Lakkireddy 		return rc;
9643044d0fbSRahul Lakkireddy 	}
9653044d0fbSRahul Lakkireddy 
9663044d0fbSRahul Lakkireddy 	t4_read_cimq_cfg(padap, cim_qcfg_data->base, cim_qcfg_data->size,
9673044d0fbSRahul Lakkireddy 			 cim_qcfg_data->thres);
96856cf2635SRahul Lakkireddy 	return cudbg_write_and_release_buff(pdbg_init, &temp_buff, dbg_buff);
9693044d0fbSRahul Lakkireddy }
9703044d0fbSRahul Lakkireddy 
9717c075ce2SRahul Lakkireddy static int cudbg_read_cim_ibq(struct cudbg_init *pdbg_init,
9727c075ce2SRahul Lakkireddy 			      struct cudbg_buffer *dbg_buff,
9737c075ce2SRahul Lakkireddy 			      struct cudbg_error *cudbg_err, int qid)
9747c075ce2SRahul Lakkireddy {
9757c075ce2SRahul Lakkireddy 	struct adapter *padap = pdbg_init->adap;
9767c075ce2SRahul Lakkireddy 	struct cudbg_buffer temp_buff = { 0 };
9777c075ce2SRahul Lakkireddy 	int no_of_read_words, rc = 0;
9787c075ce2SRahul Lakkireddy 	u32 qsize;
9797c075ce2SRahul Lakkireddy 
9807c075ce2SRahul Lakkireddy 	/* collect CIM IBQ */
9817c075ce2SRahul Lakkireddy 	qsize = CIM_IBQ_SIZE * 4 * sizeof(u32);
98256cf2635SRahul Lakkireddy 	rc = cudbg_get_buff(pdbg_init, dbg_buff, qsize, &temp_buff);
9837c075ce2SRahul Lakkireddy 	if (rc)
9847c075ce2SRahul Lakkireddy 		return rc;
9857c075ce2SRahul Lakkireddy 
9867c075ce2SRahul Lakkireddy 	/* t4_read_cim_ibq will return no. of read words or error */
9877c075ce2SRahul Lakkireddy 	no_of_read_words = t4_read_cim_ibq(padap, qid,
988acfdf7eaSRahul Lakkireddy 					   (u32 *)temp_buff.data, qsize);
9897c075ce2SRahul Lakkireddy 	/* no_of_read_words is less than or equal to 0 means error */
9907c075ce2SRahul Lakkireddy 	if (no_of_read_words <= 0) {
9917c075ce2SRahul Lakkireddy 		if (!no_of_read_words)
9927c075ce2SRahul Lakkireddy 			rc = CUDBG_SYSTEM_ERROR;
9937c075ce2SRahul Lakkireddy 		else
9947c075ce2SRahul Lakkireddy 			rc = no_of_read_words;
9957c075ce2SRahul Lakkireddy 		cudbg_err->sys_err = rc;
99656cf2635SRahul Lakkireddy 		cudbg_put_buff(pdbg_init, &temp_buff);
9977c075ce2SRahul Lakkireddy 		return rc;
9987c075ce2SRahul Lakkireddy 	}
99956cf2635SRahul Lakkireddy 	return cudbg_write_and_release_buff(pdbg_init, &temp_buff, dbg_buff);
10007c075ce2SRahul Lakkireddy }
10017c075ce2SRahul Lakkireddy 
10027c075ce2SRahul Lakkireddy int cudbg_collect_cim_ibq_tp0(struct cudbg_init *pdbg_init,
10037c075ce2SRahul Lakkireddy 			      struct cudbg_buffer *dbg_buff,
10047c075ce2SRahul Lakkireddy 			      struct cudbg_error *cudbg_err)
10057c075ce2SRahul Lakkireddy {
10067c075ce2SRahul Lakkireddy 	return cudbg_read_cim_ibq(pdbg_init, dbg_buff, cudbg_err, 0);
10077c075ce2SRahul Lakkireddy }
10087c075ce2SRahul Lakkireddy 
10097c075ce2SRahul Lakkireddy int cudbg_collect_cim_ibq_tp1(struct cudbg_init *pdbg_init,
10107c075ce2SRahul Lakkireddy 			      struct cudbg_buffer *dbg_buff,
10117c075ce2SRahul Lakkireddy 			      struct cudbg_error *cudbg_err)
10127c075ce2SRahul Lakkireddy {
10137c075ce2SRahul Lakkireddy 	return cudbg_read_cim_ibq(pdbg_init, dbg_buff, cudbg_err, 1);
10147c075ce2SRahul Lakkireddy }
10157c075ce2SRahul Lakkireddy 
10167c075ce2SRahul Lakkireddy int cudbg_collect_cim_ibq_ulp(struct cudbg_init *pdbg_init,
10177c075ce2SRahul Lakkireddy 			      struct cudbg_buffer *dbg_buff,
10187c075ce2SRahul Lakkireddy 			      struct cudbg_error *cudbg_err)
10197c075ce2SRahul Lakkireddy {
10207c075ce2SRahul Lakkireddy 	return cudbg_read_cim_ibq(pdbg_init, dbg_buff, cudbg_err, 2);
10217c075ce2SRahul Lakkireddy }
10227c075ce2SRahul Lakkireddy 
10237c075ce2SRahul Lakkireddy int cudbg_collect_cim_ibq_sge0(struct cudbg_init *pdbg_init,
10247c075ce2SRahul Lakkireddy 			       struct cudbg_buffer *dbg_buff,
10257c075ce2SRahul Lakkireddy 			       struct cudbg_error *cudbg_err)
10267c075ce2SRahul Lakkireddy {
10277c075ce2SRahul Lakkireddy 	return cudbg_read_cim_ibq(pdbg_init, dbg_buff, cudbg_err, 3);
10287c075ce2SRahul Lakkireddy }
10297c075ce2SRahul Lakkireddy 
10307c075ce2SRahul Lakkireddy int cudbg_collect_cim_ibq_sge1(struct cudbg_init *pdbg_init,
10317c075ce2SRahul Lakkireddy 			       struct cudbg_buffer *dbg_buff,
10327c075ce2SRahul Lakkireddy 			       struct cudbg_error *cudbg_err)
10337c075ce2SRahul Lakkireddy {
10347c075ce2SRahul Lakkireddy 	return cudbg_read_cim_ibq(pdbg_init, dbg_buff, cudbg_err, 4);
10357c075ce2SRahul Lakkireddy }
10367c075ce2SRahul Lakkireddy 
10377c075ce2SRahul Lakkireddy int cudbg_collect_cim_ibq_ncsi(struct cudbg_init *pdbg_init,
10387c075ce2SRahul Lakkireddy 			       struct cudbg_buffer *dbg_buff,
10397c075ce2SRahul Lakkireddy 			       struct cudbg_error *cudbg_err)
10407c075ce2SRahul Lakkireddy {
10417c075ce2SRahul Lakkireddy 	return cudbg_read_cim_ibq(pdbg_init, dbg_buff, cudbg_err, 5);
10427c075ce2SRahul Lakkireddy }
10437c075ce2SRahul Lakkireddy 
1044acfdf7eaSRahul Lakkireddy u32 cudbg_cim_obq_size(struct adapter *padap, int qid)
1045acfdf7eaSRahul Lakkireddy {
1046acfdf7eaSRahul Lakkireddy 	u32 value;
1047acfdf7eaSRahul Lakkireddy 
1048acfdf7eaSRahul Lakkireddy 	t4_write_reg(padap, CIM_QUEUE_CONFIG_REF_A, OBQSELECT_F |
1049acfdf7eaSRahul Lakkireddy 		     QUENUMSELECT_V(qid));
1050acfdf7eaSRahul Lakkireddy 	value = t4_read_reg(padap, CIM_QUEUE_CONFIG_CTRL_A);
1051acfdf7eaSRahul Lakkireddy 	value = CIMQSIZE_G(value) * 64; /* size in number of words */
1052acfdf7eaSRahul Lakkireddy 	return value * sizeof(u32);
1053acfdf7eaSRahul Lakkireddy }
1054acfdf7eaSRahul Lakkireddy 
10557c075ce2SRahul Lakkireddy static int cudbg_read_cim_obq(struct cudbg_init *pdbg_init,
10567c075ce2SRahul Lakkireddy 			      struct cudbg_buffer *dbg_buff,
10577c075ce2SRahul Lakkireddy 			      struct cudbg_error *cudbg_err, int qid)
10587c075ce2SRahul Lakkireddy {
10597c075ce2SRahul Lakkireddy 	struct adapter *padap = pdbg_init->adap;
10607c075ce2SRahul Lakkireddy 	struct cudbg_buffer temp_buff = { 0 };
10617c075ce2SRahul Lakkireddy 	int no_of_read_words, rc = 0;
10627c075ce2SRahul Lakkireddy 	u32 qsize;
10637c075ce2SRahul Lakkireddy 
10647c075ce2SRahul Lakkireddy 	/* collect CIM OBQ */
1065acfdf7eaSRahul Lakkireddy 	qsize =  cudbg_cim_obq_size(padap, qid);
106656cf2635SRahul Lakkireddy 	rc = cudbg_get_buff(pdbg_init, dbg_buff, qsize, &temp_buff);
10677c075ce2SRahul Lakkireddy 	if (rc)
10687c075ce2SRahul Lakkireddy 		return rc;
10697c075ce2SRahul Lakkireddy 
10707c075ce2SRahul Lakkireddy 	/* t4_read_cim_obq will return no. of read words or error */
10717c075ce2SRahul Lakkireddy 	no_of_read_words = t4_read_cim_obq(padap, qid,
1072acfdf7eaSRahul Lakkireddy 					   (u32 *)temp_buff.data, qsize);
10737c075ce2SRahul Lakkireddy 	/* no_of_read_words is less than or equal to 0 means error */
10747c075ce2SRahul Lakkireddy 	if (no_of_read_words <= 0) {
10757c075ce2SRahul Lakkireddy 		if (!no_of_read_words)
10767c075ce2SRahul Lakkireddy 			rc = CUDBG_SYSTEM_ERROR;
10777c075ce2SRahul Lakkireddy 		else
10787c075ce2SRahul Lakkireddy 			rc = no_of_read_words;
10797c075ce2SRahul Lakkireddy 		cudbg_err->sys_err = rc;
108056cf2635SRahul Lakkireddy 		cudbg_put_buff(pdbg_init, &temp_buff);
10817c075ce2SRahul Lakkireddy 		return rc;
10827c075ce2SRahul Lakkireddy 	}
108356cf2635SRahul Lakkireddy 	return cudbg_write_and_release_buff(pdbg_init, &temp_buff, dbg_buff);
10847c075ce2SRahul Lakkireddy }
10857c075ce2SRahul Lakkireddy 
10867c075ce2SRahul Lakkireddy int cudbg_collect_cim_obq_ulp0(struct cudbg_init *pdbg_init,
10877c075ce2SRahul Lakkireddy 			       struct cudbg_buffer *dbg_buff,
10887c075ce2SRahul Lakkireddy 			       struct cudbg_error *cudbg_err)
10897c075ce2SRahul Lakkireddy {
10907c075ce2SRahul Lakkireddy 	return cudbg_read_cim_obq(pdbg_init, dbg_buff, cudbg_err, 0);
10917c075ce2SRahul Lakkireddy }
10927c075ce2SRahul Lakkireddy 
10937c075ce2SRahul Lakkireddy int cudbg_collect_cim_obq_ulp1(struct cudbg_init *pdbg_init,
10947c075ce2SRahul Lakkireddy 			       struct cudbg_buffer *dbg_buff,
10957c075ce2SRahul Lakkireddy 			       struct cudbg_error *cudbg_err)
10967c075ce2SRahul Lakkireddy {
10977c075ce2SRahul Lakkireddy 	return cudbg_read_cim_obq(pdbg_init, dbg_buff, cudbg_err, 1);
10987c075ce2SRahul Lakkireddy }
10997c075ce2SRahul Lakkireddy 
11007c075ce2SRahul Lakkireddy int cudbg_collect_cim_obq_ulp2(struct cudbg_init *pdbg_init,
11017c075ce2SRahul Lakkireddy 			       struct cudbg_buffer *dbg_buff,
11027c075ce2SRahul Lakkireddy 			       struct cudbg_error *cudbg_err)
11037c075ce2SRahul Lakkireddy {
11047c075ce2SRahul Lakkireddy 	return cudbg_read_cim_obq(pdbg_init, dbg_buff, cudbg_err, 2);
11057c075ce2SRahul Lakkireddy }
11067c075ce2SRahul Lakkireddy 
11077c075ce2SRahul Lakkireddy int cudbg_collect_cim_obq_ulp3(struct cudbg_init *pdbg_init,
11087c075ce2SRahul Lakkireddy 			       struct cudbg_buffer *dbg_buff,
11097c075ce2SRahul Lakkireddy 			       struct cudbg_error *cudbg_err)
11107c075ce2SRahul Lakkireddy {
11117c075ce2SRahul Lakkireddy 	return cudbg_read_cim_obq(pdbg_init, dbg_buff, cudbg_err, 3);
11127c075ce2SRahul Lakkireddy }
11137c075ce2SRahul Lakkireddy 
11147c075ce2SRahul Lakkireddy int cudbg_collect_cim_obq_sge(struct cudbg_init *pdbg_init,
11157c075ce2SRahul Lakkireddy 			      struct cudbg_buffer *dbg_buff,
11167c075ce2SRahul Lakkireddy 			      struct cudbg_error *cudbg_err)
11177c075ce2SRahul Lakkireddy {
11187c075ce2SRahul Lakkireddy 	return cudbg_read_cim_obq(pdbg_init, dbg_buff, cudbg_err, 4);
11197c075ce2SRahul Lakkireddy }
11207c075ce2SRahul Lakkireddy 
11217c075ce2SRahul Lakkireddy int cudbg_collect_cim_obq_ncsi(struct cudbg_init *pdbg_init,
11227c075ce2SRahul Lakkireddy 			       struct cudbg_buffer *dbg_buff,
11237c075ce2SRahul Lakkireddy 			       struct cudbg_error *cudbg_err)
11247c075ce2SRahul Lakkireddy {
11257c075ce2SRahul Lakkireddy 	return cudbg_read_cim_obq(pdbg_init, dbg_buff, cudbg_err, 5);
11267c075ce2SRahul Lakkireddy }
11277c075ce2SRahul Lakkireddy 
11287c075ce2SRahul Lakkireddy int cudbg_collect_obq_sge_rx_q0(struct cudbg_init *pdbg_init,
11297c075ce2SRahul Lakkireddy 				struct cudbg_buffer *dbg_buff,
11307c075ce2SRahul Lakkireddy 				struct cudbg_error *cudbg_err)
11317c075ce2SRahul Lakkireddy {
11327c075ce2SRahul Lakkireddy 	return cudbg_read_cim_obq(pdbg_init, dbg_buff, cudbg_err, 6);
11337c075ce2SRahul Lakkireddy }
11347c075ce2SRahul Lakkireddy 
11357c075ce2SRahul Lakkireddy int cudbg_collect_obq_sge_rx_q1(struct cudbg_init *pdbg_init,
11367c075ce2SRahul Lakkireddy 				struct cudbg_buffer *dbg_buff,
11377c075ce2SRahul Lakkireddy 				struct cudbg_error *cudbg_err)
11387c075ce2SRahul Lakkireddy {
11397c075ce2SRahul Lakkireddy 	return cudbg_read_cim_obq(pdbg_init, dbg_buff, cudbg_err, 7);
11407c075ce2SRahul Lakkireddy }
11417c075ce2SRahul Lakkireddy 
1142a1c69520SRahul Lakkireddy static int cudbg_meminfo_get_mem_index(struct adapter *padap,
1143a1c69520SRahul Lakkireddy 				       struct cudbg_meminfo *mem_info,
1144a1c69520SRahul Lakkireddy 				       u8 mem_type, u8 *idx)
1145a1c69520SRahul Lakkireddy {
1146a1c69520SRahul Lakkireddy 	u8 i, flag;
1147a1c69520SRahul Lakkireddy 
1148a1c69520SRahul Lakkireddy 	switch (mem_type) {
1149a1c69520SRahul Lakkireddy 	case MEM_EDC0:
1150a1c69520SRahul Lakkireddy 		flag = EDC0_FLAG;
1151a1c69520SRahul Lakkireddy 		break;
1152a1c69520SRahul Lakkireddy 	case MEM_EDC1:
1153a1c69520SRahul Lakkireddy 		flag = EDC1_FLAG;
1154a1c69520SRahul Lakkireddy 		break;
1155a1c69520SRahul Lakkireddy 	case MEM_MC0:
1156a1c69520SRahul Lakkireddy 		/* Some T5 cards have both MC0 and MC1. */
1157a1c69520SRahul Lakkireddy 		flag = is_t5(padap->params.chip) ? MC0_FLAG : MC_FLAG;
1158a1c69520SRahul Lakkireddy 		break;
1159a1c69520SRahul Lakkireddy 	case MEM_MC1:
1160a1c69520SRahul Lakkireddy 		flag = MC1_FLAG;
1161a1c69520SRahul Lakkireddy 		break;
11624db0401fSRahul Lakkireddy 	case MEM_HMA:
11634db0401fSRahul Lakkireddy 		flag = HMA_FLAG;
11644db0401fSRahul Lakkireddy 		break;
1165a1c69520SRahul Lakkireddy 	default:
1166a1c69520SRahul Lakkireddy 		return CUDBG_STATUS_ENTITY_NOT_FOUND;
1167a1c69520SRahul Lakkireddy 	}
1168a1c69520SRahul Lakkireddy 
1169a1c69520SRahul Lakkireddy 	for (i = 0; i < mem_info->avail_c; i++) {
1170a1c69520SRahul Lakkireddy 		if (mem_info->avail[i].idx == flag) {
1171a1c69520SRahul Lakkireddy 			*idx = i;
1172a1c69520SRahul Lakkireddy 			return 0;
1173a1c69520SRahul Lakkireddy 		}
1174a1c69520SRahul Lakkireddy 	}
1175a1c69520SRahul Lakkireddy 
1176a1c69520SRahul Lakkireddy 	return CUDBG_STATUS_ENTITY_NOT_FOUND;
1177a1c69520SRahul Lakkireddy }
1178a1c69520SRahul Lakkireddy 
1179c1219653SRahul Lakkireddy /* Fetch the @region_name's start and end from @meminfo. */
1180c1219653SRahul Lakkireddy static int cudbg_get_mem_region(struct adapter *padap,
1181c1219653SRahul Lakkireddy 				struct cudbg_meminfo *meminfo,
1182c1219653SRahul Lakkireddy 				u8 mem_type, const char *region_name,
1183c1219653SRahul Lakkireddy 				struct cudbg_mem_desc *mem_desc)
1184c1219653SRahul Lakkireddy {
1185c1219653SRahul Lakkireddy 	u8 mc, found = 0;
1186c8119fa8SYueHaibing 	u32 idx = 0;
1187c8119fa8SYueHaibing 	int rc, i;
1188c1219653SRahul Lakkireddy 
1189c1219653SRahul Lakkireddy 	rc = cudbg_meminfo_get_mem_index(padap, meminfo, mem_type, &mc);
1190c1219653SRahul Lakkireddy 	if (rc)
1191c1219653SRahul Lakkireddy 		return rc;
1192c1219653SRahul Lakkireddy 
1193c8119fa8SYueHaibing 	i = match_string(cudbg_region, ARRAY_SIZE(cudbg_region), region_name);
1194c8119fa8SYueHaibing 	if (i < 0)
1195c1219653SRahul Lakkireddy 		return -EINVAL;
1196c1219653SRahul Lakkireddy 
1197c8119fa8SYueHaibing 	idx = i;
1198c1219653SRahul Lakkireddy 	for (i = 0; i < meminfo->mem_c; i++) {
1199c1219653SRahul Lakkireddy 		if (meminfo->mem[i].idx >= ARRAY_SIZE(cudbg_region))
1200c1219653SRahul Lakkireddy 			continue; /* Skip holes */
1201c1219653SRahul Lakkireddy 
1202c1219653SRahul Lakkireddy 		if (!(meminfo->mem[i].limit))
1203c1219653SRahul Lakkireddy 			meminfo->mem[i].limit =
1204c1219653SRahul Lakkireddy 				i < meminfo->mem_c - 1 ?
1205c1219653SRahul Lakkireddy 				meminfo->mem[i + 1].base - 1 : ~0;
1206c1219653SRahul Lakkireddy 
1207c1219653SRahul Lakkireddy 		if (meminfo->mem[i].idx == idx) {
1208c1219653SRahul Lakkireddy 			/* Check if the region exists in @mem_type memory */
1209c1219653SRahul Lakkireddy 			if (meminfo->mem[i].base < meminfo->avail[mc].base &&
1210c1219653SRahul Lakkireddy 			    meminfo->mem[i].limit < meminfo->avail[mc].base)
1211c1219653SRahul Lakkireddy 				return -EINVAL;
1212c1219653SRahul Lakkireddy 
1213c1219653SRahul Lakkireddy 			if (meminfo->mem[i].base > meminfo->avail[mc].limit)
1214c1219653SRahul Lakkireddy 				return -EINVAL;
1215c1219653SRahul Lakkireddy 
1216c1219653SRahul Lakkireddy 			memcpy(mem_desc, &meminfo->mem[i],
1217c1219653SRahul Lakkireddy 			       sizeof(struct cudbg_mem_desc));
1218c1219653SRahul Lakkireddy 			found = 1;
1219c1219653SRahul Lakkireddy 			break;
1220c1219653SRahul Lakkireddy 		}
1221c1219653SRahul Lakkireddy 	}
1222c1219653SRahul Lakkireddy 	if (!found)
1223c1219653SRahul Lakkireddy 		return -EINVAL;
1224c1219653SRahul Lakkireddy 
1225c1219653SRahul Lakkireddy 	return 0;
1226c1219653SRahul Lakkireddy }
1227c1219653SRahul Lakkireddy 
1228c1219653SRahul Lakkireddy /* Fetch and update the start and end of the requested memory region w.r.t 0
1229c1219653SRahul Lakkireddy  * in the corresponding EDC/MC/HMA.
1230c1219653SRahul Lakkireddy  */
1231c1219653SRahul Lakkireddy static int cudbg_get_mem_relative(struct adapter *padap,
1232c1219653SRahul Lakkireddy 				  struct cudbg_meminfo *meminfo,
1233c1219653SRahul Lakkireddy 				  u8 mem_type, u32 *out_base, u32 *out_end)
1234c1219653SRahul Lakkireddy {
1235c1219653SRahul Lakkireddy 	u8 mc_idx;
1236c1219653SRahul Lakkireddy 	int rc;
1237c1219653SRahul Lakkireddy 
1238c1219653SRahul Lakkireddy 	rc = cudbg_meminfo_get_mem_index(padap, meminfo, mem_type, &mc_idx);
1239c1219653SRahul Lakkireddy 	if (rc)
1240c1219653SRahul Lakkireddy 		return rc;
1241c1219653SRahul Lakkireddy 
1242c1219653SRahul Lakkireddy 	if (*out_base < meminfo->avail[mc_idx].base)
1243c1219653SRahul Lakkireddy 		*out_base = 0;
1244c1219653SRahul Lakkireddy 	else
1245c1219653SRahul Lakkireddy 		*out_base -= meminfo->avail[mc_idx].base;
1246c1219653SRahul Lakkireddy 
1247c1219653SRahul Lakkireddy 	if (*out_end > meminfo->avail[mc_idx].limit)
1248c1219653SRahul Lakkireddy 		*out_end = meminfo->avail[mc_idx].limit;
1249c1219653SRahul Lakkireddy 	else
1250c1219653SRahul Lakkireddy 		*out_end -= meminfo->avail[mc_idx].base;
1251c1219653SRahul Lakkireddy 
1252c1219653SRahul Lakkireddy 	return 0;
1253c1219653SRahul Lakkireddy }
1254c1219653SRahul Lakkireddy 
1255c1219653SRahul Lakkireddy /* Get TX and RX Payload region */
1256c1219653SRahul Lakkireddy static int cudbg_get_payload_range(struct adapter *padap, u8 mem_type,
1257c1219653SRahul Lakkireddy 				   const char *region_name,
1258c1219653SRahul Lakkireddy 				   struct cudbg_region_info *payload)
1259c1219653SRahul Lakkireddy {
1260c1219653SRahul Lakkireddy 	struct cudbg_mem_desc mem_desc = { 0 };
1261c1219653SRahul Lakkireddy 	struct cudbg_meminfo meminfo;
1262c1219653SRahul Lakkireddy 	int rc;
1263c1219653SRahul Lakkireddy 
1264c1219653SRahul Lakkireddy 	rc = cudbg_fill_meminfo(padap, &meminfo);
1265c1219653SRahul Lakkireddy 	if (rc)
1266c1219653SRahul Lakkireddy 		return rc;
1267c1219653SRahul Lakkireddy 
1268c1219653SRahul Lakkireddy 	rc = cudbg_get_mem_region(padap, &meminfo, mem_type, region_name,
1269c1219653SRahul Lakkireddy 				  &mem_desc);
1270c1219653SRahul Lakkireddy 	if (rc) {
1271c1219653SRahul Lakkireddy 		payload->exist = false;
1272c1219653SRahul Lakkireddy 		return 0;
1273c1219653SRahul Lakkireddy 	}
1274c1219653SRahul Lakkireddy 
1275c1219653SRahul Lakkireddy 	payload->exist = true;
1276c1219653SRahul Lakkireddy 	payload->start = mem_desc.base;
1277c1219653SRahul Lakkireddy 	payload->end = mem_desc.limit;
1278c1219653SRahul Lakkireddy 
1279c1219653SRahul Lakkireddy 	return cudbg_get_mem_relative(padap, &meminfo, mem_type,
1280c1219653SRahul Lakkireddy 				      &payload->start, &payload->end);
1281c1219653SRahul Lakkireddy }
1282c1219653SRahul Lakkireddy 
12831a4330cdSRahul Lakkireddy static int cudbg_memory_read(struct cudbg_init *pdbg_init, int win,
12841a4330cdSRahul Lakkireddy 			     int mtype, u32 addr, u32 len, void *hbuf)
12851a4330cdSRahul Lakkireddy {
12861a4330cdSRahul Lakkireddy 	u32 win_pf, memoffset, mem_aperture, mem_base;
12871a4330cdSRahul Lakkireddy 	struct adapter *adap = pdbg_init->adap;
12881a4330cdSRahul Lakkireddy 	u32 pos, offset, resid;
12897494f980SRahul Lakkireddy 	u32 *res_buf;
12907494f980SRahul Lakkireddy 	u64 *buf;
12911a4330cdSRahul Lakkireddy 	int ret;
12921a4330cdSRahul Lakkireddy 
12931a4330cdSRahul Lakkireddy 	/* Argument sanity checks ...
12941a4330cdSRahul Lakkireddy 	 */
12951a4330cdSRahul Lakkireddy 	if (addr & 0x3 || (uintptr_t)hbuf & 0x3)
12961a4330cdSRahul Lakkireddy 		return -EINVAL;
12971a4330cdSRahul Lakkireddy 
12987494f980SRahul Lakkireddy 	buf = (u64 *)hbuf;
12991a4330cdSRahul Lakkireddy 
13007494f980SRahul Lakkireddy 	/* Try to do 64-bit reads.  Residual will be handled later. */
13017494f980SRahul Lakkireddy 	resid = len & 0x7;
13021a4330cdSRahul Lakkireddy 	len -= resid;
13031a4330cdSRahul Lakkireddy 
13041a4330cdSRahul Lakkireddy 	ret = t4_memory_rw_init(adap, win, mtype, &memoffset, &mem_base,
13051a4330cdSRahul Lakkireddy 				&mem_aperture);
13061a4330cdSRahul Lakkireddy 	if (ret)
13071a4330cdSRahul Lakkireddy 		return ret;
13081a4330cdSRahul Lakkireddy 
13091a4330cdSRahul Lakkireddy 	addr = addr + memoffset;
13101a4330cdSRahul Lakkireddy 	win_pf = is_t4(adap->params.chip) ? 0 : PFNUM_V(adap->pf);
13111a4330cdSRahul Lakkireddy 
13121a4330cdSRahul Lakkireddy 	pos = addr & ~(mem_aperture - 1);
13131a4330cdSRahul Lakkireddy 	offset = addr - pos;
13141a4330cdSRahul Lakkireddy 
13151a4330cdSRahul Lakkireddy 	/* Set up initial PCI-E Memory Window to cover the start of our
13161a4330cdSRahul Lakkireddy 	 * transfer.
13171a4330cdSRahul Lakkireddy 	 */
13181a4330cdSRahul Lakkireddy 	t4_memory_update_win(adap, win, pos | win_pf);
13191a4330cdSRahul Lakkireddy 
13201a4330cdSRahul Lakkireddy 	/* Transfer data from the adapter */
13211a4330cdSRahul Lakkireddy 	while (len > 0) {
13227494f980SRahul Lakkireddy 		*buf++ = le64_to_cpu((__force __le64)
13237494f980SRahul Lakkireddy 				     t4_read_reg64(adap, mem_base + offset));
13247494f980SRahul Lakkireddy 		offset += sizeof(u64);
13257494f980SRahul Lakkireddy 		len -= sizeof(u64);
13261a4330cdSRahul Lakkireddy 
13271a4330cdSRahul Lakkireddy 		/* If we've reached the end of our current window aperture,
13281a4330cdSRahul Lakkireddy 		 * move the PCI-E Memory Window on to the next.
13291a4330cdSRahul Lakkireddy 		 */
13301a4330cdSRahul Lakkireddy 		if (offset == mem_aperture) {
13311a4330cdSRahul Lakkireddy 			pos += mem_aperture;
13321a4330cdSRahul Lakkireddy 			offset = 0;
13331a4330cdSRahul Lakkireddy 			t4_memory_update_win(adap, win, pos | win_pf);
13341a4330cdSRahul Lakkireddy 		}
13351a4330cdSRahul Lakkireddy 	}
13361a4330cdSRahul Lakkireddy 
13377494f980SRahul Lakkireddy 	res_buf = (u32 *)buf;
13387494f980SRahul Lakkireddy 	/* Read residual in 32-bit multiples */
13397494f980SRahul Lakkireddy 	while (resid > sizeof(u32)) {
13407494f980SRahul Lakkireddy 		*res_buf++ = le32_to_cpu((__force __le32)
13417494f980SRahul Lakkireddy 					 t4_read_reg(adap, mem_base + offset));
13427494f980SRahul Lakkireddy 		offset += sizeof(u32);
13437494f980SRahul Lakkireddy 		resid -= sizeof(u32);
13447494f980SRahul Lakkireddy 
13457494f980SRahul Lakkireddy 		/* If we've reached the end of our current window aperture,
13467494f980SRahul Lakkireddy 		 * move the PCI-E Memory Window on to the next.
13477494f980SRahul Lakkireddy 		 */
13487494f980SRahul Lakkireddy 		if (offset == mem_aperture) {
13497494f980SRahul Lakkireddy 			pos += mem_aperture;
13507494f980SRahul Lakkireddy 			offset = 0;
13517494f980SRahul Lakkireddy 			t4_memory_update_win(adap, win, pos | win_pf);
13527494f980SRahul Lakkireddy 		}
13537494f980SRahul Lakkireddy 	}
13547494f980SRahul Lakkireddy 
13557494f980SRahul Lakkireddy 	/* Transfer residual < 32-bits */
13561a4330cdSRahul Lakkireddy 	if (resid)
13571a4330cdSRahul Lakkireddy 		t4_memory_rw_residual(adap, resid, mem_base + offset,
13587494f980SRahul Lakkireddy 				      (u8 *)res_buf, T4_MEMORY_READ);
13591a4330cdSRahul Lakkireddy 
13601a4330cdSRahul Lakkireddy 	return 0;
13611a4330cdSRahul Lakkireddy }
13621a4330cdSRahul Lakkireddy 
1363a1c69520SRahul Lakkireddy #define CUDBG_YIELD_ITERATION 256
1364a1c69520SRahul Lakkireddy 
1365b33af022SRahul Lakkireddy static int cudbg_read_fw_mem(struct cudbg_init *pdbg_init,
1366b33af022SRahul Lakkireddy 			     struct cudbg_buffer *dbg_buff, u8 mem_type,
1367b33af022SRahul Lakkireddy 			     unsigned long tot_len,
1368b33af022SRahul Lakkireddy 			     struct cudbg_error *cudbg_err)
1369b33af022SRahul Lakkireddy {
1370c1219653SRahul Lakkireddy 	static const char * const region_name[] = { "Tx payload:",
1371c1219653SRahul Lakkireddy 						    "Rx payload:" };
1372b33af022SRahul Lakkireddy 	unsigned long bytes, bytes_left, bytes_read = 0;
1373b33af022SRahul Lakkireddy 	struct adapter *padap = pdbg_init->adap;
1374b33af022SRahul Lakkireddy 	struct cudbg_buffer temp_buff = { 0 };
1375c1219653SRahul Lakkireddy 	struct cudbg_region_info payload[2];
1376a1c69520SRahul Lakkireddy 	u32 yield_count = 0;
1377b33af022SRahul Lakkireddy 	int rc = 0;
1378c1219653SRahul Lakkireddy 	u8 i;
1379c1219653SRahul Lakkireddy 
1380c1219653SRahul Lakkireddy 	/* Get TX/RX Payload region range if they exist */
1381c1219653SRahul Lakkireddy 	memset(payload, 0, sizeof(payload));
1382c1219653SRahul Lakkireddy 	for (i = 0; i < ARRAY_SIZE(region_name); i++) {
1383c1219653SRahul Lakkireddy 		rc = cudbg_get_payload_range(padap, mem_type, region_name[i],
1384c1219653SRahul Lakkireddy 					     &payload[i]);
1385c1219653SRahul Lakkireddy 		if (rc)
1386c1219653SRahul Lakkireddy 			return rc;
1387c1219653SRahul Lakkireddy 
1388c1219653SRahul Lakkireddy 		if (payload[i].exist) {
1389c1219653SRahul Lakkireddy 			/* Align start and end to avoid wrap around */
1390c1219653SRahul Lakkireddy 			payload[i].start = roundup(payload[i].start,
1391c1219653SRahul Lakkireddy 						   CUDBG_CHUNK_SIZE);
1392c1219653SRahul Lakkireddy 			payload[i].end = rounddown(payload[i].end,
1393c1219653SRahul Lakkireddy 						   CUDBG_CHUNK_SIZE);
1394c1219653SRahul Lakkireddy 		}
1395c1219653SRahul Lakkireddy 	}
1396b33af022SRahul Lakkireddy 
1397b33af022SRahul Lakkireddy 	bytes_left = tot_len;
1398b33af022SRahul Lakkireddy 	while (bytes_left > 0) {
1399a1c69520SRahul Lakkireddy 		/* As MC size is huge and read through PIO access, this
1400a1c69520SRahul Lakkireddy 		 * loop will hold cpu for a longer time. OS may think that
1401a1c69520SRahul Lakkireddy 		 * the process is hanged and will generate CPU stall traces.
1402a1c69520SRahul Lakkireddy 		 * So yield the cpu regularly.
1403a1c69520SRahul Lakkireddy 		 */
1404a1c69520SRahul Lakkireddy 		yield_count++;
1405a1c69520SRahul Lakkireddy 		if (!(yield_count % CUDBG_YIELD_ITERATION))
1406a1c69520SRahul Lakkireddy 			schedule();
1407a1c69520SRahul Lakkireddy 
1408b33af022SRahul Lakkireddy 		bytes = min_t(unsigned long, bytes_left,
1409b33af022SRahul Lakkireddy 			      (unsigned long)CUDBG_CHUNK_SIZE);
141056cf2635SRahul Lakkireddy 		rc = cudbg_get_buff(pdbg_init, dbg_buff, bytes, &temp_buff);
1411b33af022SRahul Lakkireddy 		if (rc)
1412b33af022SRahul Lakkireddy 			return rc;
1413c1219653SRahul Lakkireddy 
1414c1219653SRahul Lakkireddy 		for (i = 0; i < ARRAY_SIZE(payload); i++)
1415c1219653SRahul Lakkireddy 			if (payload[i].exist &&
1416c1219653SRahul Lakkireddy 			    bytes_read >= payload[i].start &&
1417c1219653SRahul Lakkireddy 			    bytes_read + bytes <= payload[i].end)
1418c1219653SRahul Lakkireddy 				/* TX and RX Payload regions can't overlap */
1419c1219653SRahul Lakkireddy 				goto skip_read;
1420c1219653SRahul Lakkireddy 
1421b33af022SRahul Lakkireddy 		spin_lock(&padap->win0_lock);
14221a4330cdSRahul Lakkireddy 		rc = cudbg_memory_read(pdbg_init, MEMWIN_NIC, mem_type,
14231a4330cdSRahul Lakkireddy 				       bytes_read, bytes, temp_buff.data);
1424b33af022SRahul Lakkireddy 		spin_unlock(&padap->win0_lock);
1425b33af022SRahul Lakkireddy 		if (rc) {
1426b33af022SRahul Lakkireddy 			cudbg_err->sys_err = rc;
142756cf2635SRahul Lakkireddy 			cudbg_put_buff(pdbg_init, &temp_buff);
1428b33af022SRahul Lakkireddy 			return rc;
1429b33af022SRahul Lakkireddy 		}
1430c1219653SRahul Lakkireddy 
1431c1219653SRahul Lakkireddy skip_read:
1432b33af022SRahul Lakkireddy 		bytes_left -= bytes;
1433b33af022SRahul Lakkireddy 		bytes_read += bytes;
143456cf2635SRahul Lakkireddy 		rc = cudbg_write_and_release_buff(pdbg_init, &temp_buff,
143556cf2635SRahul Lakkireddy 						  dbg_buff);
143656cf2635SRahul Lakkireddy 		if (rc) {
143756cf2635SRahul Lakkireddy 			cudbg_put_buff(pdbg_init, &temp_buff);
143856cf2635SRahul Lakkireddy 			return rc;
143956cf2635SRahul Lakkireddy 		}
1440b33af022SRahul Lakkireddy 	}
1441b33af022SRahul Lakkireddy 	return rc;
1442b33af022SRahul Lakkireddy }
1443b33af022SRahul Lakkireddy 
1444b33af022SRahul Lakkireddy static void cudbg_t4_fwcache(struct cudbg_init *pdbg_init,
1445b33af022SRahul Lakkireddy 			     struct cudbg_error *cudbg_err)
1446b33af022SRahul Lakkireddy {
1447b33af022SRahul Lakkireddy 	struct adapter *padap = pdbg_init->adap;
1448b33af022SRahul Lakkireddy 	int rc;
1449b33af022SRahul Lakkireddy 
1450b33af022SRahul Lakkireddy 	if (is_fw_attached(pdbg_init)) {
1451b33af022SRahul Lakkireddy 		/* Flush uP dcache before reading edcX/mcX  */
1452b33af022SRahul Lakkireddy 		rc = t4_fwcache(padap, FW_PARAM_DEV_FWCACHE_FLUSH);
1453b33af022SRahul Lakkireddy 		if (rc)
1454b33af022SRahul Lakkireddy 			cudbg_err->sys_warn = rc;
1455b33af022SRahul Lakkireddy 	}
1456b33af022SRahul Lakkireddy }
1457b33af022SRahul Lakkireddy 
1458ce222748SVishal Kulkarni static int cudbg_mem_region_size(struct cudbg_init *pdbg_init,
1459b33af022SRahul Lakkireddy 				 struct cudbg_error *cudbg_err,
1460ce222748SVishal Kulkarni 				 u8 mem_type, unsigned long *region_size)
1461b33af022SRahul Lakkireddy {
1462a1c69520SRahul Lakkireddy 	struct adapter *padap = pdbg_init->adap;
1463a1c69520SRahul Lakkireddy 	struct cudbg_meminfo mem_info;
1464a1c69520SRahul Lakkireddy 	u8 mc_idx;
1465b33af022SRahul Lakkireddy 	int rc;
1466b33af022SRahul Lakkireddy 
1467a1c69520SRahul Lakkireddy 	memset(&mem_info, 0, sizeof(struct cudbg_meminfo));
1468a1c69520SRahul Lakkireddy 	rc = cudbg_fill_meminfo(padap, &mem_info);
1469ce222748SVishal Kulkarni 	if (rc) {
1470ce222748SVishal Kulkarni 		cudbg_err->sys_err = rc;
1471b33af022SRahul Lakkireddy 		return rc;
1472ce222748SVishal Kulkarni 	}
1473a1c69520SRahul Lakkireddy 
1474a1c69520SRahul Lakkireddy 	cudbg_t4_fwcache(pdbg_init, cudbg_err);
1475a1c69520SRahul Lakkireddy 	rc = cudbg_meminfo_get_mem_index(padap, &mem_info, mem_type, &mc_idx);
1476ce222748SVishal Kulkarni 	if (rc) {
1477ce222748SVishal Kulkarni 		cudbg_err->sys_err = rc;
1478a1c69520SRahul Lakkireddy 		return rc;
1479ce222748SVishal Kulkarni 	}
1480a1c69520SRahul Lakkireddy 
1481ce222748SVishal Kulkarni 	if (region_size)
1482ce222748SVishal Kulkarni 		*region_size = mem_info.avail[mc_idx].limit -
1483ce222748SVishal Kulkarni 			       mem_info.avail[mc_idx].base;
1484ce222748SVishal Kulkarni 
1485ce222748SVishal Kulkarni 	return 0;
1486752c2ea2SArnd Bergmann }
1487752c2ea2SArnd Bergmann 
1488752c2ea2SArnd Bergmann static int cudbg_collect_mem_region(struct cudbg_init *pdbg_init,
1489752c2ea2SArnd Bergmann 				    struct cudbg_buffer *dbg_buff,
1490752c2ea2SArnd Bergmann 				    struct cudbg_error *cudbg_err,
1491752c2ea2SArnd Bergmann 				    u8 mem_type)
1492752c2ea2SArnd Bergmann {
1493ce222748SVishal Kulkarni 	unsigned long size = 0;
1494ce222748SVishal Kulkarni 	int rc;
1495ce222748SVishal Kulkarni 
1496ce222748SVishal Kulkarni 	rc = cudbg_mem_region_size(pdbg_init, cudbg_err, mem_type, &size);
1497ce222748SVishal Kulkarni 	if (rc)
1498ce222748SVishal Kulkarni 		return rc;
1499752c2ea2SArnd Bergmann 
1500a1c69520SRahul Lakkireddy 	return cudbg_read_fw_mem(pdbg_init, dbg_buff, mem_type, size,
1501a1c69520SRahul Lakkireddy 				 cudbg_err);
1502b33af022SRahul Lakkireddy }
1503b33af022SRahul Lakkireddy 
1504b33af022SRahul Lakkireddy int cudbg_collect_edc0_meminfo(struct cudbg_init *pdbg_init,
1505b33af022SRahul Lakkireddy 			       struct cudbg_buffer *dbg_buff,
1506b33af022SRahul Lakkireddy 			       struct cudbg_error *cudbg_err)
1507b33af022SRahul Lakkireddy {
1508b33af022SRahul Lakkireddy 	return cudbg_collect_mem_region(pdbg_init, dbg_buff, cudbg_err,
1509b33af022SRahul Lakkireddy 					MEM_EDC0);
1510b33af022SRahul Lakkireddy }
1511b33af022SRahul Lakkireddy 
1512b33af022SRahul Lakkireddy int cudbg_collect_edc1_meminfo(struct cudbg_init *pdbg_init,
1513b33af022SRahul Lakkireddy 			       struct cudbg_buffer *dbg_buff,
1514b33af022SRahul Lakkireddy 			       struct cudbg_error *cudbg_err)
1515b33af022SRahul Lakkireddy {
1516b33af022SRahul Lakkireddy 	return cudbg_collect_mem_region(pdbg_init, dbg_buff, cudbg_err,
1517b33af022SRahul Lakkireddy 					MEM_EDC1);
1518b33af022SRahul Lakkireddy }
1519844d1b6fSRahul Lakkireddy 
1520a1c69520SRahul Lakkireddy int cudbg_collect_mc0_meminfo(struct cudbg_init *pdbg_init,
1521a1c69520SRahul Lakkireddy 			      struct cudbg_buffer *dbg_buff,
1522a1c69520SRahul Lakkireddy 			      struct cudbg_error *cudbg_err)
1523a1c69520SRahul Lakkireddy {
1524a1c69520SRahul Lakkireddy 	return cudbg_collect_mem_region(pdbg_init, dbg_buff, cudbg_err,
1525a1c69520SRahul Lakkireddy 					MEM_MC0);
1526a1c69520SRahul Lakkireddy }
1527a1c69520SRahul Lakkireddy 
1528a1c69520SRahul Lakkireddy int cudbg_collect_mc1_meminfo(struct cudbg_init *pdbg_init,
1529a1c69520SRahul Lakkireddy 			      struct cudbg_buffer *dbg_buff,
1530a1c69520SRahul Lakkireddy 			      struct cudbg_error *cudbg_err)
1531a1c69520SRahul Lakkireddy {
1532a1c69520SRahul Lakkireddy 	return cudbg_collect_mem_region(pdbg_init, dbg_buff, cudbg_err,
1533a1c69520SRahul Lakkireddy 					MEM_MC1);
1534a1c69520SRahul Lakkireddy }
1535a1c69520SRahul Lakkireddy 
15364db0401fSRahul Lakkireddy int cudbg_collect_hma_meminfo(struct cudbg_init *pdbg_init,
15374db0401fSRahul Lakkireddy 			      struct cudbg_buffer *dbg_buff,
15384db0401fSRahul Lakkireddy 			      struct cudbg_error *cudbg_err)
15394db0401fSRahul Lakkireddy {
15404db0401fSRahul Lakkireddy 	return cudbg_collect_mem_region(pdbg_init, dbg_buff, cudbg_err,
15414db0401fSRahul Lakkireddy 					MEM_HMA);
15424db0401fSRahul Lakkireddy }
15434db0401fSRahul Lakkireddy 
154428b44556SRahul Lakkireddy int cudbg_collect_rss(struct cudbg_init *pdbg_init,
154528b44556SRahul Lakkireddy 		      struct cudbg_buffer *dbg_buff,
154628b44556SRahul Lakkireddy 		      struct cudbg_error *cudbg_err)
154728b44556SRahul Lakkireddy {
154828b44556SRahul Lakkireddy 	struct adapter *padap = pdbg_init->adap;
154928b44556SRahul Lakkireddy 	struct cudbg_buffer temp_buff = { 0 };
1550f988008aSGanesh Goudar 	int rc, nentries;
155128b44556SRahul Lakkireddy 
1552f988008aSGanesh Goudar 	nentries = t4_chip_rss_size(padap);
155356cf2635SRahul Lakkireddy 	rc = cudbg_get_buff(pdbg_init, dbg_buff, nentries * sizeof(u16),
155456cf2635SRahul Lakkireddy 			    &temp_buff);
155528b44556SRahul Lakkireddy 	if (rc)
155628b44556SRahul Lakkireddy 		return rc;
155728b44556SRahul Lakkireddy 
155828b44556SRahul Lakkireddy 	rc = t4_read_rss(padap, (u16 *)temp_buff.data);
155928b44556SRahul Lakkireddy 	if (rc) {
156028b44556SRahul Lakkireddy 		cudbg_err->sys_err = rc;
156156cf2635SRahul Lakkireddy 		cudbg_put_buff(pdbg_init, &temp_buff);
156228b44556SRahul Lakkireddy 		return rc;
156328b44556SRahul Lakkireddy 	}
156456cf2635SRahul Lakkireddy 	return cudbg_write_and_release_buff(pdbg_init, &temp_buff, dbg_buff);
156528b44556SRahul Lakkireddy }
156628b44556SRahul Lakkireddy 
156728b44556SRahul Lakkireddy int cudbg_collect_rss_vf_config(struct cudbg_init *pdbg_init,
156828b44556SRahul Lakkireddy 				struct cudbg_buffer *dbg_buff,
156928b44556SRahul Lakkireddy 				struct cudbg_error *cudbg_err)
157028b44556SRahul Lakkireddy {
157128b44556SRahul Lakkireddy 	struct adapter *padap = pdbg_init->adap;
157228b44556SRahul Lakkireddy 	struct cudbg_buffer temp_buff = { 0 };
157328b44556SRahul Lakkireddy 	struct cudbg_rss_vf_conf *vfconf;
157428b44556SRahul Lakkireddy 	int vf, rc, vf_count;
157528b44556SRahul Lakkireddy 
157628b44556SRahul Lakkireddy 	vf_count = padap->params.arch.vfcount;
157756cf2635SRahul Lakkireddy 	rc = cudbg_get_buff(pdbg_init, dbg_buff,
157828b44556SRahul Lakkireddy 			    vf_count * sizeof(struct cudbg_rss_vf_conf),
157928b44556SRahul Lakkireddy 			    &temp_buff);
158028b44556SRahul Lakkireddy 	if (rc)
158128b44556SRahul Lakkireddy 		return rc;
158228b44556SRahul Lakkireddy 
158328b44556SRahul Lakkireddy 	vfconf = (struct cudbg_rss_vf_conf *)temp_buff.data;
158428b44556SRahul Lakkireddy 	for (vf = 0; vf < vf_count; vf++)
158528b44556SRahul Lakkireddy 		t4_read_rss_vf_config(padap, vf, &vfconf[vf].rss_vf_vfl,
158628b44556SRahul Lakkireddy 				      &vfconf[vf].rss_vf_vfh, true);
158756cf2635SRahul Lakkireddy 	return cudbg_write_and_release_buff(pdbg_init, &temp_buff, dbg_buff);
158828b44556SRahul Lakkireddy }
158928b44556SRahul Lakkireddy 
15906f92a654SRahul Lakkireddy int cudbg_collect_path_mtu(struct cudbg_init *pdbg_init,
15916f92a654SRahul Lakkireddy 			   struct cudbg_buffer *dbg_buff,
15926f92a654SRahul Lakkireddy 			   struct cudbg_error *cudbg_err)
15936f92a654SRahul Lakkireddy {
15946f92a654SRahul Lakkireddy 	struct adapter *padap = pdbg_init->adap;
15956f92a654SRahul Lakkireddy 	struct cudbg_buffer temp_buff = { 0 };
15966f92a654SRahul Lakkireddy 	int rc;
15976f92a654SRahul Lakkireddy 
159856cf2635SRahul Lakkireddy 	rc = cudbg_get_buff(pdbg_init, dbg_buff, NMTUS * sizeof(u16),
159956cf2635SRahul Lakkireddy 			    &temp_buff);
16006f92a654SRahul Lakkireddy 	if (rc)
16016f92a654SRahul Lakkireddy 		return rc;
16026f92a654SRahul Lakkireddy 
16036f92a654SRahul Lakkireddy 	t4_read_mtu_tbl(padap, (u16 *)temp_buff.data, NULL);
160456cf2635SRahul Lakkireddy 	return cudbg_write_and_release_buff(pdbg_init, &temp_buff, dbg_buff);
16056f92a654SRahul Lakkireddy }
16066f92a654SRahul Lakkireddy 
16076f92a654SRahul Lakkireddy int cudbg_collect_pm_stats(struct cudbg_init *pdbg_init,
16086f92a654SRahul Lakkireddy 			   struct cudbg_buffer *dbg_buff,
16096f92a654SRahul Lakkireddy 			   struct cudbg_error *cudbg_err)
16106f92a654SRahul Lakkireddy {
16116f92a654SRahul Lakkireddy 	struct adapter *padap = pdbg_init->adap;
16126f92a654SRahul Lakkireddy 	struct cudbg_buffer temp_buff = { 0 };
16136f92a654SRahul Lakkireddy 	struct cudbg_pm_stats *pm_stats_buff;
16146f92a654SRahul Lakkireddy 	int rc;
16156f92a654SRahul Lakkireddy 
161656cf2635SRahul Lakkireddy 	rc = cudbg_get_buff(pdbg_init, dbg_buff, sizeof(struct cudbg_pm_stats),
16176f92a654SRahul Lakkireddy 			    &temp_buff);
16186f92a654SRahul Lakkireddy 	if (rc)
16196f92a654SRahul Lakkireddy 		return rc;
16206f92a654SRahul Lakkireddy 
16216f92a654SRahul Lakkireddy 	pm_stats_buff = (struct cudbg_pm_stats *)temp_buff.data;
16226f92a654SRahul Lakkireddy 	t4_pmtx_get_stats(padap, pm_stats_buff->tx_cnt, pm_stats_buff->tx_cyc);
16236f92a654SRahul Lakkireddy 	t4_pmrx_get_stats(padap, pm_stats_buff->rx_cnt, pm_stats_buff->rx_cyc);
162456cf2635SRahul Lakkireddy 	return cudbg_write_and_release_buff(pdbg_init, &temp_buff, dbg_buff);
16256f92a654SRahul Lakkireddy }
16266f92a654SRahul Lakkireddy 
162708c4901bSRahul Lakkireddy int cudbg_collect_hw_sched(struct cudbg_init *pdbg_init,
162808c4901bSRahul Lakkireddy 			   struct cudbg_buffer *dbg_buff,
162908c4901bSRahul Lakkireddy 			   struct cudbg_error *cudbg_err)
163008c4901bSRahul Lakkireddy {
163108c4901bSRahul Lakkireddy 	struct adapter *padap = pdbg_init->adap;
163208c4901bSRahul Lakkireddy 	struct cudbg_buffer temp_buff = { 0 };
163308c4901bSRahul Lakkireddy 	struct cudbg_hw_sched *hw_sched_buff;
163408c4901bSRahul Lakkireddy 	int i, rc = 0;
163508c4901bSRahul Lakkireddy 
163608c4901bSRahul Lakkireddy 	if (!padap->params.vpd.cclk)
163708c4901bSRahul Lakkireddy 		return CUDBG_STATUS_CCLK_NOT_DEFINED;
163808c4901bSRahul Lakkireddy 
163956cf2635SRahul Lakkireddy 	rc = cudbg_get_buff(pdbg_init, dbg_buff, sizeof(struct cudbg_hw_sched),
164008c4901bSRahul Lakkireddy 			    &temp_buff);
1641ca19fcb6SAditya Pakki 
1642ca19fcb6SAditya Pakki 	if (rc)
1643ca19fcb6SAditya Pakki 		return rc;
1644ca19fcb6SAditya Pakki 
164508c4901bSRahul Lakkireddy 	hw_sched_buff = (struct cudbg_hw_sched *)temp_buff.data;
164608c4901bSRahul Lakkireddy 	hw_sched_buff->map = t4_read_reg(padap, TP_TX_MOD_QUEUE_REQ_MAP_A);
164708c4901bSRahul Lakkireddy 	hw_sched_buff->mode = TIMERMODE_G(t4_read_reg(padap, TP_MOD_CONFIG_A));
164808c4901bSRahul Lakkireddy 	t4_read_pace_tbl(padap, hw_sched_buff->pace_tab);
164908c4901bSRahul Lakkireddy 	for (i = 0; i < NTX_SCHED; ++i)
165008c4901bSRahul Lakkireddy 		t4_get_tx_sched(padap, i, &hw_sched_buff->kbps[i],
165108c4901bSRahul Lakkireddy 				&hw_sched_buff->ipg[i], true);
165256cf2635SRahul Lakkireddy 	return cudbg_write_and_release_buff(pdbg_init, &temp_buff, dbg_buff);
165308c4901bSRahul Lakkireddy }
165408c4901bSRahul Lakkireddy 
16554359cf33SRahul Lakkireddy int cudbg_collect_tp_indirect(struct cudbg_init *pdbg_init,
16564359cf33SRahul Lakkireddy 			      struct cudbg_buffer *dbg_buff,
16574359cf33SRahul Lakkireddy 			      struct cudbg_error *cudbg_err)
16584359cf33SRahul Lakkireddy {
16594359cf33SRahul Lakkireddy 	struct adapter *padap = pdbg_init->adap;
16604359cf33SRahul Lakkireddy 	struct cudbg_buffer temp_buff = { 0 };
16614359cf33SRahul Lakkireddy 	struct ireg_buf *ch_tp_pio;
16624359cf33SRahul Lakkireddy 	int i, rc, n = 0;
16634359cf33SRahul Lakkireddy 	u32 size;
16644359cf33SRahul Lakkireddy 
16654359cf33SRahul Lakkireddy 	if (is_t5(padap->params.chip))
16664359cf33SRahul Lakkireddy 		n = sizeof(t5_tp_pio_array) +
16674359cf33SRahul Lakkireddy 		    sizeof(t5_tp_tm_pio_array) +
16684359cf33SRahul Lakkireddy 		    sizeof(t5_tp_mib_index_array);
16694359cf33SRahul Lakkireddy 	else
16704359cf33SRahul Lakkireddy 		n = sizeof(t6_tp_pio_array) +
16714359cf33SRahul Lakkireddy 		    sizeof(t6_tp_tm_pio_array) +
16724359cf33SRahul Lakkireddy 		    sizeof(t6_tp_mib_index_array);
16734359cf33SRahul Lakkireddy 
16744359cf33SRahul Lakkireddy 	n = n / (IREG_NUM_ELEM * sizeof(u32));
16754359cf33SRahul Lakkireddy 	size = sizeof(struct ireg_buf) * n;
167656cf2635SRahul Lakkireddy 	rc = cudbg_get_buff(pdbg_init, dbg_buff, size, &temp_buff);
16774359cf33SRahul Lakkireddy 	if (rc)
16784359cf33SRahul Lakkireddy 		return rc;
16794359cf33SRahul Lakkireddy 
16804359cf33SRahul Lakkireddy 	ch_tp_pio = (struct ireg_buf *)temp_buff.data;
16814359cf33SRahul Lakkireddy 
16824359cf33SRahul Lakkireddy 	/* TP_PIO */
16834359cf33SRahul Lakkireddy 	if (is_t5(padap->params.chip))
16844359cf33SRahul Lakkireddy 		n = sizeof(t5_tp_pio_array) / (IREG_NUM_ELEM * sizeof(u32));
16854359cf33SRahul Lakkireddy 	else if (is_t6(padap->params.chip))
16864359cf33SRahul Lakkireddy 		n = sizeof(t6_tp_pio_array) / (IREG_NUM_ELEM * sizeof(u32));
16874359cf33SRahul Lakkireddy 
16884359cf33SRahul Lakkireddy 	for (i = 0; i < n; i++) {
16894359cf33SRahul Lakkireddy 		struct ireg_field *tp_pio = &ch_tp_pio->tp_pio;
16904359cf33SRahul Lakkireddy 		u32 *buff = ch_tp_pio->outbuf;
16914359cf33SRahul Lakkireddy 
16924359cf33SRahul Lakkireddy 		if (is_t5(padap->params.chip)) {
16934359cf33SRahul Lakkireddy 			tp_pio->ireg_addr = t5_tp_pio_array[i][0];
16944359cf33SRahul Lakkireddy 			tp_pio->ireg_data = t5_tp_pio_array[i][1];
16954359cf33SRahul Lakkireddy 			tp_pio->ireg_local_offset = t5_tp_pio_array[i][2];
16964359cf33SRahul Lakkireddy 			tp_pio->ireg_offset_range = t5_tp_pio_array[i][3];
16974359cf33SRahul Lakkireddy 		} else if (is_t6(padap->params.chip)) {
16984359cf33SRahul Lakkireddy 			tp_pio->ireg_addr = t6_tp_pio_array[i][0];
16994359cf33SRahul Lakkireddy 			tp_pio->ireg_data = t6_tp_pio_array[i][1];
17004359cf33SRahul Lakkireddy 			tp_pio->ireg_local_offset = t6_tp_pio_array[i][2];
17014359cf33SRahul Lakkireddy 			tp_pio->ireg_offset_range = t6_tp_pio_array[i][3];
17024359cf33SRahul Lakkireddy 		}
17034359cf33SRahul Lakkireddy 		t4_tp_pio_read(padap, buff, tp_pio->ireg_offset_range,
17044359cf33SRahul Lakkireddy 			       tp_pio->ireg_local_offset, true);
17054359cf33SRahul Lakkireddy 		ch_tp_pio++;
17064359cf33SRahul Lakkireddy 	}
17074359cf33SRahul Lakkireddy 
17084359cf33SRahul Lakkireddy 	/* TP_TM_PIO */
17094359cf33SRahul Lakkireddy 	if (is_t5(padap->params.chip))
17104359cf33SRahul Lakkireddy 		n = sizeof(t5_tp_tm_pio_array) / (IREG_NUM_ELEM * sizeof(u32));
17114359cf33SRahul Lakkireddy 	else if (is_t6(padap->params.chip))
17124359cf33SRahul Lakkireddy 		n = sizeof(t6_tp_tm_pio_array) / (IREG_NUM_ELEM * sizeof(u32));
17134359cf33SRahul Lakkireddy 
17144359cf33SRahul Lakkireddy 	for (i = 0; i < n; i++) {
17154359cf33SRahul Lakkireddy 		struct ireg_field *tp_pio = &ch_tp_pio->tp_pio;
17164359cf33SRahul Lakkireddy 		u32 *buff = ch_tp_pio->outbuf;
17174359cf33SRahul Lakkireddy 
17184359cf33SRahul Lakkireddy 		if (is_t5(padap->params.chip)) {
17194359cf33SRahul Lakkireddy 			tp_pio->ireg_addr = t5_tp_tm_pio_array[i][0];
17204359cf33SRahul Lakkireddy 			tp_pio->ireg_data = t5_tp_tm_pio_array[i][1];
17214359cf33SRahul Lakkireddy 			tp_pio->ireg_local_offset = t5_tp_tm_pio_array[i][2];
17224359cf33SRahul Lakkireddy 			tp_pio->ireg_offset_range = t5_tp_tm_pio_array[i][3];
17234359cf33SRahul Lakkireddy 		} else if (is_t6(padap->params.chip)) {
17244359cf33SRahul Lakkireddy 			tp_pio->ireg_addr = t6_tp_tm_pio_array[i][0];
17254359cf33SRahul Lakkireddy 			tp_pio->ireg_data = t6_tp_tm_pio_array[i][1];
17264359cf33SRahul Lakkireddy 			tp_pio->ireg_local_offset = t6_tp_tm_pio_array[i][2];
17274359cf33SRahul Lakkireddy 			tp_pio->ireg_offset_range = t6_tp_tm_pio_array[i][3];
17284359cf33SRahul Lakkireddy 		}
17294359cf33SRahul Lakkireddy 		t4_tp_tm_pio_read(padap, buff, tp_pio->ireg_offset_range,
17304359cf33SRahul Lakkireddy 				  tp_pio->ireg_local_offset, true);
17314359cf33SRahul Lakkireddy 		ch_tp_pio++;
17324359cf33SRahul Lakkireddy 	}
17334359cf33SRahul Lakkireddy 
17344359cf33SRahul Lakkireddy 	/* TP_MIB_INDEX */
17354359cf33SRahul Lakkireddy 	if (is_t5(padap->params.chip))
17364359cf33SRahul Lakkireddy 		n = sizeof(t5_tp_mib_index_array) /
17374359cf33SRahul Lakkireddy 		    (IREG_NUM_ELEM * sizeof(u32));
17384359cf33SRahul Lakkireddy 	else if (is_t6(padap->params.chip))
17394359cf33SRahul Lakkireddy 		n = sizeof(t6_tp_mib_index_array) /
17404359cf33SRahul Lakkireddy 		    (IREG_NUM_ELEM * sizeof(u32));
17414359cf33SRahul Lakkireddy 
17424359cf33SRahul Lakkireddy 	for (i = 0; i < n ; i++) {
17434359cf33SRahul Lakkireddy 		struct ireg_field *tp_pio = &ch_tp_pio->tp_pio;
17444359cf33SRahul Lakkireddy 		u32 *buff = ch_tp_pio->outbuf;
17454359cf33SRahul Lakkireddy 
17464359cf33SRahul Lakkireddy 		if (is_t5(padap->params.chip)) {
17474359cf33SRahul Lakkireddy 			tp_pio->ireg_addr = t5_tp_mib_index_array[i][0];
17484359cf33SRahul Lakkireddy 			tp_pio->ireg_data = t5_tp_mib_index_array[i][1];
17494359cf33SRahul Lakkireddy 			tp_pio->ireg_local_offset =
17504359cf33SRahul Lakkireddy 				t5_tp_mib_index_array[i][2];
17514359cf33SRahul Lakkireddy 			tp_pio->ireg_offset_range =
17524359cf33SRahul Lakkireddy 				t5_tp_mib_index_array[i][3];
17534359cf33SRahul Lakkireddy 		} else if (is_t6(padap->params.chip)) {
17544359cf33SRahul Lakkireddy 			tp_pio->ireg_addr = t6_tp_mib_index_array[i][0];
17554359cf33SRahul Lakkireddy 			tp_pio->ireg_data = t6_tp_mib_index_array[i][1];
17564359cf33SRahul Lakkireddy 			tp_pio->ireg_local_offset =
17574359cf33SRahul Lakkireddy 				t6_tp_mib_index_array[i][2];
17584359cf33SRahul Lakkireddy 			tp_pio->ireg_offset_range =
17594359cf33SRahul Lakkireddy 				t6_tp_mib_index_array[i][3];
17604359cf33SRahul Lakkireddy 		}
17614359cf33SRahul Lakkireddy 		t4_tp_mib_read(padap, buff, tp_pio->ireg_offset_range,
17624359cf33SRahul Lakkireddy 			       tp_pio->ireg_local_offset, true);
17634359cf33SRahul Lakkireddy 		ch_tp_pio++;
17644359cf33SRahul Lakkireddy 	}
176556cf2635SRahul Lakkireddy 	return cudbg_write_and_release_buff(pdbg_init, &temp_buff, dbg_buff);
17664359cf33SRahul Lakkireddy }
17674359cf33SRahul Lakkireddy 
176880a95a80SRahul Lakkireddy static void cudbg_read_sge_qbase_indirect_reg(struct adapter *padap,
176980a95a80SRahul Lakkireddy 					      struct sge_qbase_reg_field *qbase,
177080a95a80SRahul Lakkireddy 					      u32 func, bool is_pf)
177180a95a80SRahul Lakkireddy {
177280a95a80SRahul Lakkireddy 	u32 *buff, i;
177380a95a80SRahul Lakkireddy 
177480a95a80SRahul Lakkireddy 	if (is_pf) {
177580a95a80SRahul Lakkireddy 		buff = qbase->pf_data_value[func];
177680a95a80SRahul Lakkireddy 	} else {
177780a95a80SRahul Lakkireddy 		buff = qbase->vf_data_value[func];
177880a95a80SRahul Lakkireddy 		/* In SGE_QBASE_INDEX,
177980a95a80SRahul Lakkireddy 		 * Entries 0->7 are PF0->7, Entries 8->263 are VFID0->256.
178080a95a80SRahul Lakkireddy 		 */
178180a95a80SRahul Lakkireddy 		func += 8;
178280a95a80SRahul Lakkireddy 	}
178380a95a80SRahul Lakkireddy 
178480a95a80SRahul Lakkireddy 	t4_write_reg(padap, qbase->reg_addr, func);
178580a95a80SRahul Lakkireddy 	for (i = 0; i < SGE_QBASE_DATA_REG_NUM; i++, buff++)
178680a95a80SRahul Lakkireddy 		*buff = t4_read_reg(padap, qbase->reg_data[i]);
178780a95a80SRahul Lakkireddy }
178880a95a80SRahul Lakkireddy 
1789270d39bfSRahul Lakkireddy int cudbg_collect_sge_indirect(struct cudbg_init *pdbg_init,
1790270d39bfSRahul Lakkireddy 			       struct cudbg_buffer *dbg_buff,
1791270d39bfSRahul Lakkireddy 			       struct cudbg_error *cudbg_err)
1792270d39bfSRahul Lakkireddy {
1793270d39bfSRahul Lakkireddy 	struct adapter *padap = pdbg_init->adap;
1794270d39bfSRahul Lakkireddy 	struct cudbg_buffer temp_buff = { 0 };
179580a95a80SRahul Lakkireddy 	struct sge_qbase_reg_field *sge_qbase;
1796270d39bfSRahul Lakkireddy 	struct ireg_buf *ch_sge_dbg;
1797*1bfb3deaSRahul Lakkireddy 	u8 padap_running = 0;
1798270d39bfSRahul Lakkireddy 	int i, rc;
1799*1bfb3deaSRahul Lakkireddy 	u32 size;
1800270d39bfSRahul Lakkireddy 
1801*1bfb3deaSRahul Lakkireddy 	/* Accessing SGE_QBASE_MAP[0-3] and SGE_QBASE_INDEX regs can
1802*1bfb3deaSRahul Lakkireddy 	 * lead to SGE missing doorbells under heavy traffic. So, only
1803*1bfb3deaSRahul Lakkireddy 	 * collect them when adapter is idle.
1804*1bfb3deaSRahul Lakkireddy 	 */
1805*1bfb3deaSRahul Lakkireddy 	for_each_port(padap, i) {
1806*1bfb3deaSRahul Lakkireddy 		padap_running = netif_running(padap->port[i]);
1807*1bfb3deaSRahul Lakkireddy 		if (padap_running)
1808*1bfb3deaSRahul Lakkireddy 			break;
1809*1bfb3deaSRahul Lakkireddy 	}
1810*1bfb3deaSRahul Lakkireddy 
1811*1bfb3deaSRahul Lakkireddy 	size = sizeof(*ch_sge_dbg) * 2;
1812*1bfb3deaSRahul Lakkireddy 	if (!padap_running)
1813*1bfb3deaSRahul Lakkireddy 		size += sizeof(*sge_qbase);
1814*1bfb3deaSRahul Lakkireddy 
1815*1bfb3deaSRahul Lakkireddy 	rc = cudbg_get_buff(pdbg_init, dbg_buff, size, &temp_buff);
1816270d39bfSRahul Lakkireddy 	if (rc)
1817270d39bfSRahul Lakkireddy 		return rc;
1818270d39bfSRahul Lakkireddy 
1819270d39bfSRahul Lakkireddy 	ch_sge_dbg = (struct ireg_buf *)temp_buff.data;
1820270d39bfSRahul Lakkireddy 	for (i = 0; i < 2; i++) {
1821270d39bfSRahul Lakkireddy 		struct ireg_field *sge_pio = &ch_sge_dbg->tp_pio;
1822270d39bfSRahul Lakkireddy 		u32 *buff = ch_sge_dbg->outbuf;
1823270d39bfSRahul Lakkireddy 
1824270d39bfSRahul Lakkireddy 		sge_pio->ireg_addr = t5_sge_dbg_index_array[i][0];
1825270d39bfSRahul Lakkireddy 		sge_pio->ireg_data = t5_sge_dbg_index_array[i][1];
1826270d39bfSRahul Lakkireddy 		sge_pio->ireg_local_offset = t5_sge_dbg_index_array[i][2];
1827270d39bfSRahul Lakkireddy 		sge_pio->ireg_offset_range = t5_sge_dbg_index_array[i][3];
1828270d39bfSRahul Lakkireddy 		t4_read_indirect(padap,
1829270d39bfSRahul Lakkireddy 				 sge_pio->ireg_addr,
1830270d39bfSRahul Lakkireddy 				 sge_pio->ireg_data,
1831270d39bfSRahul Lakkireddy 				 buff,
1832270d39bfSRahul Lakkireddy 				 sge_pio->ireg_offset_range,
1833270d39bfSRahul Lakkireddy 				 sge_pio->ireg_local_offset);
1834270d39bfSRahul Lakkireddy 		ch_sge_dbg++;
1835270d39bfSRahul Lakkireddy 	}
183680a95a80SRahul Lakkireddy 
1837*1bfb3deaSRahul Lakkireddy 	if (CHELSIO_CHIP_VERSION(padap->params.chip) > CHELSIO_T5 &&
1838*1bfb3deaSRahul Lakkireddy 	    !padap_running) {
183980a95a80SRahul Lakkireddy 		sge_qbase = (struct sge_qbase_reg_field *)ch_sge_dbg;
184080a95a80SRahul Lakkireddy 		/* 1 addr reg SGE_QBASE_INDEX and 4 data reg
184180a95a80SRahul Lakkireddy 		 * SGE_QBASE_MAP[0-3]
184280a95a80SRahul Lakkireddy 		 */
184380a95a80SRahul Lakkireddy 		sge_qbase->reg_addr = t6_sge_qbase_index_array[0];
184480a95a80SRahul Lakkireddy 		for (i = 0; i < SGE_QBASE_DATA_REG_NUM; i++)
184580a95a80SRahul Lakkireddy 			sge_qbase->reg_data[i] =
184680a95a80SRahul Lakkireddy 				t6_sge_qbase_index_array[i + 1];
184780a95a80SRahul Lakkireddy 
184880a95a80SRahul Lakkireddy 		for (i = 0; i <= PCIE_FW_MASTER_M; i++)
184980a95a80SRahul Lakkireddy 			cudbg_read_sge_qbase_indirect_reg(padap, sge_qbase,
185080a95a80SRahul Lakkireddy 							  i, true);
185180a95a80SRahul Lakkireddy 
185280a95a80SRahul Lakkireddy 		for (i = 0; i < padap->params.arch.vfcount; i++)
185380a95a80SRahul Lakkireddy 			cudbg_read_sge_qbase_indirect_reg(padap, sge_qbase,
185480a95a80SRahul Lakkireddy 							  i, false);
185580a95a80SRahul Lakkireddy 
185680a95a80SRahul Lakkireddy 		sge_qbase->vfcount = padap->params.arch.vfcount;
185780a95a80SRahul Lakkireddy 	}
185880a95a80SRahul Lakkireddy 
185956cf2635SRahul Lakkireddy 	return cudbg_write_and_release_buff(pdbg_init, &temp_buff, dbg_buff);
1860270d39bfSRahul Lakkireddy }
1861270d39bfSRahul Lakkireddy 
186227887bc7SRahul Lakkireddy int cudbg_collect_ulprx_la(struct cudbg_init *pdbg_init,
186327887bc7SRahul Lakkireddy 			   struct cudbg_buffer *dbg_buff,
186427887bc7SRahul Lakkireddy 			   struct cudbg_error *cudbg_err)
186527887bc7SRahul Lakkireddy {
186627887bc7SRahul Lakkireddy 	struct adapter *padap = pdbg_init->adap;
186727887bc7SRahul Lakkireddy 	struct cudbg_buffer temp_buff = { 0 };
186827887bc7SRahul Lakkireddy 	struct cudbg_ulprx_la *ulprx_la_buff;
186927887bc7SRahul Lakkireddy 	int rc;
187027887bc7SRahul Lakkireddy 
187156cf2635SRahul Lakkireddy 	rc = cudbg_get_buff(pdbg_init, dbg_buff, sizeof(struct cudbg_ulprx_la),
187227887bc7SRahul Lakkireddy 			    &temp_buff);
187327887bc7SRahul Lakkireddy 	if (rc)
187427887bc7SRahul Lakkireddy 		return rc;
187527887bc7SRahul Lakkireddy 
187627887bc7SRahul Lakkireddy 	ulprx_la_buff = (struct cudbg_ulprx_la *)temp_buff.data;
187727887bc7SRahul Lakkireddy 	t4_ulprx_read_la(padap, (u32 *)ulprx_la_buff->data);
187827887bc7SRahul Lakkireddy 	ulprx_la_buff->size = ULPRX_LA_SIZE;
187956cf2635SRahul Lakkireddy 	return cudbg_write_and_release_buff(pdbg_init, &temp_buff, dbg_buff);
188027887bc7SRahul Lakkireddy }
188127887bc7SRahul Lakkireddy 
188227887bc7SRahul Lakkireddy int cudbg_collect_tp_la(struct cudbg_init *pdbg_init,
188327887bc7SRahul Lakkireddy 			struct cudbg_buffer *dbg_buff,
188427887bc7SRahul Lakkireddy 			struct cudbg_error *cudbg_err)
188527887bc7SRahul Lakkireddy {
188627887bc7SRahul Lakkireddy 	struct adapter *padap = pdbg_init->adap;
188727887bc7SRahul Lakkireddy 	struct cudbg_buffer temp_buff = { 0 };
188827887bc7SRahul Lakkireddy 	struct cudbg_tp_la *tp_la_buff;
188927887bc7SRahul Lakkireddy 	int size, rc;
189027887bc7SRahul Lakkireddy 
189127887bc7SRahul Lakkireddy 	size = sizeof(struct cudbg_tp_la) + TPLA_SIZE *  sizeof(u64);
189256cf2635SRahul Lakkireddy 	rc = cudbg_get_buff(pdbg_init, dbg_buff, size, &temp_buff);
189327887bc7SRahul Lakkireddy 	if (rc)
189427887bc7SRahul Lakkireddy 		return rc;
189527887bc7SRahul Lakkireddy 
189627887bc7SRahul Lakkireddy 	tp_la_buff = (struct cudbg_tp_la *)temp_buff.data;
189727887bc7SRahul Lakkireddy 	tp_la_buff->mode = DBGLAMODE_G(t4_read_reg(padap, TP_DBG_LA_CONFIG_A));
189827887bc7SRahul Lakkireddy 	t4_tp_read_la(padap, (u64 *)tp_la_buff->data, NULL);
189956cf2635SRahul Lakkireddy 	return cudbg_write_and_release_buff(pdbg_init, &temp_buff, dbg_buff);
190027887bc7SRahul Lakkireddy }
190127887bc7SRahul Lakkireddy 
1902123e25c4SRahul Lakkireddy int cudbg_collect_meminfo(struct cudbg_init *pdbg_init,
1903123e25c4SRahul Lakkireddy 			  struct cudbg_buffer *dbg_buff,
1904123e25c4SRahul Lakkireddy 			  struct cudbg_error *cudbg_err)
1905123e25c4SRahul Lakkireddy {
1906123e25c4SRahul Lakkireddy 	struct adapter *padap = pdbg_init->adap;
1907123e25c4SRahul Lakkireddy 	struct cudbg_buffer temp_buff = { 0 };
1908123e25c4SRahul Lakkireddy 	struct cudbg_meminfo *meminfo_buff;
19099d0f180cSRahul Lakkireddy 	struct cudbg_ver_hdr *ver_hdr;
1910123e25c4SRahul Lakkireddy 	int rc;
1911123e25c4SRahul Lakkireddy 
19129d0f180cSRahul Lakkireddy 	rc = cudbg_get_buff(pdbg_init, dbg_buff,
19139d0f180cSRahul Lakkireddy 			    sizeof(struct cudbg_ver_hdr) +
19149d0f180cSRahul Lakkireddy 			    sizeof(struct cudbg_meminfo),
191556cf2635SRahul Lakkireddy 			    &temp_buff);
1916123e25c4SRahul Lakkireddy 	if (rc)
1917123e25c4SRahul Lakkireddy 		return rc;
1918123e25c4SRahul Lakkireddy 
19199d0f180cSRahul Lakkireddy 	ver_hdr = (struct cudbg_ver_hdr *)temp_buff.data;
19209d0f180cSRahul Lakkireddy 	ver_hdr->signature = CUDBG_ENTITY_SIGNATURE;
19219d0f180cSRahul Lakkireddy 	ver_hdr->revision = CUDBG_MEMINFO_REV;
19229d0f180cSRahul Lakkireddy 	ver_hdr->size = sizeof(struct cudbg_meminfo);
19239d0f180cSRahul Lakkireddy 
19249d0f180cSRahul Lakkireddy 	meminfo_buff = (struct cudbg_meminfo *)(temp_buff.data +
19259d0f180cSRahul Lakkireddy 						sizeof(*ver_hdr));
1926123e25c4SRahul Lakkireddy 	rc = cudbg_fill_meminfo(padap, meminfo_buff);
1927123e25c4SRahul Lakkireddy 	if (rc) {
1928123e25c4SRahul Lakkireddy 		cudbg_err->sys_err = rc;
192956cf2635SRahul Lakkireddy 		cudbg_put_buff(pdbg_init, &temp_buff);
1930123e25c4SRahul Lakkireddy 		return rc;
1931123e25c4SRahul Lakkireddy 	}
1932123e25c4SRahul Lakkireddy 
193356cf2635SRahul Lakkireddy 	return cudbg_write_and_release_buff(pdbg_init, &temp_buff, dbg_buff);
1934123e25c4SRahul Lakkireddy }
1935123e25c4SRahul Lakkireddy 
193627887bc7SRahul Lakkireddy int cudbg_collect_cim_pif_la(struct cudbg_init *pdbg_init,
193727887bc7SRahul Lakkireddy 			     struct cudbg_buffer *dbg_buff,
193827887bc7SRahul Lakkireddy 			     struct cudbg_error *cudbg_err)
193927887bc7SRahul Lakkireddy {
194027887bc7SRahul Lakkireddy 	struct cudbg_cim_pif_la *cim_pif_la_buff;
194127887bc7SRahul Lakkireddy 	struct adapter *padap = pdbg_init->adap;
194227887bc7SRahul Lakkireddy 	struct cudbg_buffer temp_buff = { 0 };
194327887bc7SRahul Lakkireddy 	int size, rc;
194427887bc7SRahul Lakkireddy 
194527887bc7SRahul Lakkireddy 	size = sizeof(struct cudbg_cim_pif_la) +
194627887bc7SRahul Lakkireddy 	       2 * CIM_PIFLA_SIZE * 6 * sizeof(u32);
194756cf2635SRahul Lakkireddy 	rc = cudbg_get_buff(pdbg_init, dbg_buff, size, &temp_buff);
194827887bc7SRahul Lakkireddy 	if (rc)
194927887bc7SRahul Lakkireddy 		return rc;
195027887bc7SRahul Lakkireddy 
195127887bc7SRahul Lakkireddy 	cim_pif_la_buff = (struct cudbg_cim_pif_la *)temp_buff.data;
195227887bc7SRahul Lakkireddy 	cim_pif_la_buff->size = CIM_PIFLA_SIZE;
195327887bc7SRahul Lakkireddy 	t4_cim_read_pif_la(padap, (u32 *)cim_pif_la_buff->data,
195427887bc7SRahul Lakkireddy 			   (u32 *)cim_pif_la_buff->data + 6 * CIM_PIFLA_SIZE,
195527887bc7SRahul Lakkireddy 			   NULL, NULL);
195656cf2635SRahul Lakkireddy 	return cudbg_write_and_release_buff(pdbg_init, &temp_buff, dbg_buff);
195727887bc7SRahul Lakkireddy }
195827887bc7SRahul Lakkireddy 
19596f92a654SRahul Lakkireddy int cudbg_collect_clk_info(struct cudbg_init *pdbg_init,
19606f92a654SRahul Lakkireddy 			   struct cudbg_buffer *dbg_buff,
19616f92a654SRahul Lakkireddy 			   struct cudbg_error *cudbg_err)
19626f92a654SRahul Lakkireddy {
19636f92a654SRahul Lakkireddy 	struct adapter *padap = pdbg_init->adap;
19646f92a654SRahul Lakkireddy 	struct cudbg_buffer temp_buff = { 0 };
19656f92a654SRahul Lakkireddy 	struct cudbg_clk_info *clk_info_buff;
19666f92a654SRahul Lakkireddy 	u64 tp_tick_us;
19676f92a654SRahul Lakkireddy 	int rc;
19686f92a654SRahul Lakkireddy 
19696f92a654SRahul Lakkireddy 	if (!padap->params.vpd.cclk)
19706f92a654SRahul Lakkireddy 		return CUDBG_STATUS_CCLK_NOT_DEFINED;
19716f92a654SRahul Lakkireddy 
197256cf2635SRahul Lakkireddy 	rc = cudbg_get_buff(pdbg_init, dbg_buff, sizeof(struct cudbg_clk_info),
19736f92a654SRahul Lakkireddy 			    &temp_buff);
19746f92a654SRahul Lakkireddy 	if (rc)
19756f92a654SRahul Lakkireddy 		return rc;
19766f92a654SRahul Lakkireddy 
19776f92a654SRahul Lakkireddy 	clk_info_buff = (struct cudbg_clk_info *)temp_buff.data;
19786f92a654SRahul Lakkireddy 	clk_info_buff->cclk_ps = 1000000000 / padap->params.vpd.cclk; /* psec */
19796f92a654SRahul Lakkireddy 	clk_info_buff->res = t4_read_reg(padap, TP_TIMER_RESOLUTION_A);
19806f92a654SRahul Lakkireddy 	clk_info_buff->tre = TIMERRESOLUTION_G(clk_info_buff->res);
19816f92a654SRahul Lakkireddy 	clk_info_buff->dack_re = DELAYEDACKRESOLUTION_G(clk_info_buff->res);
19826f92a654SRahul Lakkireddy 	tp_tick_us = (clk_info_buff->cclk_ps << clk_info_buff->tre) / 1000000;
19836f92a654SRahul Lakkireddy 
19846f92a654SRahul Lakkireddy 	clk_info_buff->dack_timer =
19856f92a654SRahul Lakkireddy 		(clk_info_buff->cclk_ps << clk_info_buff->dack_re) / 1000000 *
19866f92a654SRahul Lakkireddy 		t4_read_reg(padap, TP_DACK_TIMER_A);
19876f92a654SRahul Lakkireddy 	clk_info_buff->retransmit_min =
19886f92a654SRahul Lakkireddy 		tp_tick_us * t4_read_reg(padap, TP_RXT_MIN_A);
19896f92a654SRahul Lakkireddy 	clk_info_buff->retransmit_max =
19906f92a654SRahul Lakkireddy 		tp_tick_us * t4_read_reg(padap, TP_RXT_MAX_A);
19916f92a654SRahul Lakkireddy 	clk_info_buff->persist_timer_min =
19926f92a654SRahul Lakkireddy 		tp_tick_us * t4_read_reg(padap, TP_PERS_MIN_A);
19936f92a654SRahul Lakkireddy 	clk_info_buff->persist_timer_max =
19946f92a654SRahul Lakkireddy 		tp_tick_us * t4_read_reg(padap, TP_PERS_MAX_A);
19956f92a654SRahul Lakkireddy 	clk_info_buff->keepalive_idle_timer =
19966f92a654SRahul Lakkireddy 		tp_tick_us * t4_read_reg(padap, TP_KEEP_IDLE_A);
19976f92a654SRahul Lakkireddy 	clk_info_buff->keepalive_interval =
19986f92a654SRahul Lakkireddy 		tp_tick_us * t4_read_reg(padap, TP_KEEP_INTVL_A);
19996f92a654SRahul Lakkireddy 	clk_info_buff->initial_srtt =
20006f92a654SRahul Lakkireddy 		tp_tick_us * INITSRTT_G(t4_read_reg(padap, TP_INIT_SRTT_A));
20016f92a654SRahul Lakkireddy 	clk_info_buff->finwait2_timer =
20026f92a654SRahul Lakkireddy 		tp_tick_us * t4_read_reg(padap, TP_FINWAIT2_TIMER_A);
20036f92a654SRahul Lakkireddy 
200456cf2635SRahul Lakkireddy 	return cudbg_write_and_release_buff(pdbg_init, &temp_buff, dbg_buff);
20056f92a654SRahul Lakkireddy }
20066f92a654SRahul Lakkireddy 
2007270d39bfSRahul Lakkireddy int cudbg_collect_pcie_indirect(struct cudbg_init *pdbg_init,
2008270d39bfSRahul Lakkireddy 				struct cudbg_buffer *dbg_buff,
2009270d39bfSRahul Lakkireddy 				struct cudbg_error *cudbg_err)
2010270d39bfSRahul Lakkireddy {
2011270d39bfSRahul Lakkireddy 	struct adapter *padap = pdbg_init->adap;
2012270d39bfSRahul Lakkireddy 	struct cudbg_buffer temp_buff = { 0 };
2013270d39bfSRahul Lakkireddy 	struct ireg_buf *ch_pcie;
2014270d39bfSRahul Lakkireddy 	int i, rc, n;
2015270d39bfSRahul Lakkireddy 	u32 size;
2016270d39bfSRahul Lakkireddy 
2017270d39bfSRahul Lakkireddy 	n = sizeof(t5_pcie_pdbg_array) / (IREG_NUM_ELEM * sizeof(u32));
2018270d39bfSRahul Lakkireddy 	size = sizeof(struct ireg_buf) * n * 2;
201956cf2635SRahul Lakkireddy 	rc = cudbg_get_buff(pdbg_init, dbg_buff, size, &temp_buff);
2020270d39bfSRahul Lakkireddy 	if (rc)
2021270d39bfSRahul Lakkireddy 		return rc;
2022270d39bfSRahul Lakkireddy 
2023270d39bfSRahul Lakkireddy 	ch_pcie = (struct ireg_buf *)temp_buff.data;
2024270d39bfSRahul Lakkireddy 	/* PCIE_PDBG */
2025270d39bfSRahul Lakkireddy 	for (i = 0; i < n; i++) {
2026270d39bfSRahul Lakkireddy 		struct ireg_field *pcie_pio = &ch_pcie->tp_pio;
2027270d39bfSRahul Lakkireddy 		u32 *buff = ch_pcie->outbuf;
2028270d39bfSRahul Lakkireddy 
2029270d39bfSRahul Lakkireddy 		pcie_pio->ireg_addr = t5_pcie_pdbg_array[i][0];
2030270d39bfSRahul Lakkireddy 		pcie_pio->ireg_data = t5_pcie_pdbg_array[i][1];
2031270d39bfSRahul Lakkireddy 		pcie_pio->ireg_local_offset = t5_pcie_pdbg_array[i][2];
2032270d39bfSRahul Lakkireddy 		pcie_pio->ireg_offset_range = t5_pcie_pdbg_array[i][3];
2033270d39bfSRahul Lakkireddy 		t4_read_indirect(padap,
2034270d39bfSRahul Lakkireddy 				 pcie_pio->ireg_addr,
2035270d39bfSRahul Lakkireddy 				 pcie_pio->ireg_data,
2036270d39bfSRahul Lakkireddy 				 buff,
2037270d39bfSRahul Lakkireddy 				 pcie_pio->ireg_offset_range,
2038270d39bfSRahul Lakkireddy 				 pcie_pio->ireg_local_offset);
2039270d39bfSRahul Lakkireddy 		ch_pcie++;
2040270d39bfSRahul Lakkireddy 	}
2041270d39bfSRahul Lakkireddy 
2042270d39bfSRahul Lakkireddy 	/* PCIE_CDBG */
2043270d39bfSRahul Lakkireddy 	n = sizeof(t5_pcie_cdbg_array) / (IREG_NUM_ELEM * sizeof(u32));
2044270d39bfSRahul Lakkireddy 	for (i = 0; i < n; i++) {
2045270d39bfSRahul Lakkireddy 		struct ireg_field *pcie_pio = &ch_pcie->tp_pio;
2046270d39bfSRahul Lakkireddy 		u32 *buff = ch_pcie->outbuf;
2047270d39bfSRahul Lakkireddy 
2048270d39bfSRahul Lakkireddy 		pcie_pio->ireg_addr = t5_pcie_cdbg_array[i][0];
2049270d39bfSRahul Lakkireddy 		pcie_pio->ireg_data = t5_pcie_cdbg_array[i][1];
2050270d39bfSRahul Lakkireddy 		pcie_pio->ireg_local_offset = t5_pcie_cdbg_array[i][2];
2051270d39bfSRahul Lakkireddy 		pcie_pio->ireg_offset_range = t5_pcie_cdbg_array[i][3];
2052270d39bfSRahul Lakkireddy 		t4_read_indirect(padap,
2053270d39bfSRahul Lakkireddy 				 pcie_pio->ireg_addr,
2054270d39bfSRahul Lakkireddy 				 pcie_pio->ireg_data,
2055270d39bfSRahul Lakkireddy 				 buff,
2056270d39bfSRahul Lakkireddy 				 pcie_pio->ireg_offset_range,
2057270d39bfSRahul Lakkireddy 				 pcie_pio->ireg_local_offset);
2058270d39bfSRahul Lakkireddy 		ch_pcie++;
2059270d39bfSRahul Lakkireddy 	}
206056cf2635SRahul Lakkireddy 	return cudbg_write_and_release_buff(pdbg_init, &temp_buff, dbg_buff);
2061270d39bfSRahul Lakkireddy }
2062270d39bfSRahul Lakkireddy 
2063270d39bfSRahul Lakkireddy int cudbg_collect_pm_indirect(struct cudbg_init *pdbg_init,
2064270d39bfSRahul Lakkireddy 			      struct cudbg_buffer *dbg_buff,
2065270d39bfSRahul Lakkireddy 			      struct cudbg_error *cudbg_err)
2066270d39bfSRahul Lakkireddy {
2067270d39bfSRahul Lakkireddy 	struct adapter *padap = pdbg_init->adap;
2068270d39bfSRahul Lakkireddy 	struct cudbg_buffer temp_buff = { 0 };
2069270d39bfSRahul Lakkireddy 	struct ireg_buf *ch_pm;
2070270d39bfSRahul Lakkireddy 	int i, rc, n;
2071270d39bfSRahul Lakkireddy 	u32 size;
2072270d39bfSRahul Lakkireddy 
2073270d39bfSRahul Lakkireddy 	n = sizeof(t5_pm_rx_array) / (IREG_NUM_ELEM * sizeof(u32));
2074270d39bfSRahul Lakkireddy 	size = sizeof(struct ireg_buf) * n * 2;
207556cf2635SRahul Lakkireddy 	rc = cudbg_get_buff(pdbg_init, dbg_buff, size, &temp_buff);
2076270d39bfSRahul Lakkireddy 	if (rc)
2077270d39bfSRahul Lakkireddy 		return rc;
2078270d39bfSRahul Lakkireddy 
2079270d39bfSRahul Lakkireddy 	ch_pm = (struct ireg_buf *)temp_buff.data;
2080270d39bfSRahul Lakkireddy 	/* PM_RX */
2081270d39bfSRahul Lakkireddy 	for (i = 0; i < n; i++) {
2082270d39bfSRahul Lakkireddy 		struct ireg_field *pm_pio = &ch_pm->tp_pio;
2083270d39bfSRahul Lakkireddy 		u32 *buff = ch_pm->outbuf;
2084270d39bfSRahul Lakkireddy 
2085270d39bfSRahul Lakkireddy 		pm_pio->ireg_addr = t5_pm_rx_array[i][0];
2086270d39bfSRahul Lakkireddy 		pm_pio->ireg_data = t5_pm_rx_array[i][1];
2087270d39bfSRahul Lakkireddy 		pm_pio->ireg_local_offset = t5_pm_rx_array[i][2];
2088270d39bfSRahul Lakkireddy 		pm_pio->ireg_offset_range = t5_pm_rx_array[i][3];
2089270d39bfSRahul Lakkireddy 		t4_read_indirect(padap,
2090270d39bfSRahul Lakkireddy 				 pm_pio->ireg_addr,
2091270d39bfSRahul Lakkireddy 				 pm_pio->ireg_data,
2092270d39bfSRahul Lakkireddy 				 buff,
2093270d39bfSRahul Lakkireddy 				 pm_pio->ireg_offset_range,
2094270d39bfSRahul Lakkireddy 				 pm_pio->ireg_local_offset);
2095270d39bfSRahul Lakkireddy 		ch_pm++;
2096270d39bfSRahul Lakkireddy 	}
2097270d39bfSRahul Lakkireddy 
2098270d39bfSRahul Lakkireddy 	/* PM_TX */
2099270d39bfSRahul Lakkireddy 	n = sizeof(t5_pm_tx_array) / (IREG_NUM_ELEM * sizeof(u32));
2100270d39bfSRahul Lakkireddy 	for (i = 0; i < n; i++) {
2101270d39bfSRahul Lakkireddy 		struct ireg_field *pm_pio = &ch_pm->tp_pio;
2102270d39bfSRahul Lakkireddy 		u32 *buff = ch_pm->outbuf;
2103270d39bfSRahul Lakkireddy 
2104270d39bfSRahul Lakkireddy 		pm_pio->ireg_addr = t5_pm_tx_array[i][0];
2105270d39bfSRahul Lakkireddy 		pm_pio->ireg_data = t5_pm_tx_array[i][1];
2106270d39bfSRahul Lakkireddy 		pm_pio->ireg_local_offset = t5_pm_tx_array[i][2];
2107270d39bfSRahul Lakkireddy 		pm_pio->ireg_offset_range = t5_pm_tx_array[i][3];
2108270d39bfSRahul Lakkireddy 		t4_read_indirect(padap,
2109270d39bfSRahul Lakkireddy 				 pm_pio->ireg_addr,
2110270d39bfSRahul Lakkireddy 				 pm_pio->ireg_data,
2111270d39bfSRahul Lakkireddy 				 buff,
2112270d39bfSRahul Lakkireddy 				 pm_pio->ireg_offset_range,
2113270d39bfSRahul Lakkireddy 				 pm_pio->ireg_local_offset);
2114270d39bfSRahul Lakkireddy 		ch_pm++;
2115270d39bfSRahul Lakkireddy 	}
211656cf2635SRahul Lakkireddy 	return cudbg_write_and_release_buff(pdbg_init, &temp_buff, dbg_buff);
2117270d39bfSRahul Lakkireddy }
2118270d39bfSRahul Lakkireddy 
21199030e498SRahul Lakkireddy int cudbg_collect_tid(struct cudbg_init *pdbg_init,
21209030e498SRahul Lakkireddy 		      struct cudbg_buffer *dbg_buff,
21219030e498SRahul Lakkireddy 		      struct cudbg_error *cudbg_err)
21229030e498SRahul Lakkireddy {
21239030e498SRahul Lakkireddy 	struct adapter *padap = pdbg_init->adap;
21249030e498SRahul Lakkireddy 	struct cudbg_tid_info_region_rev1 *tid1;
21259030e498SRahul Lakkireddy 	struct cudbg_buffer temp_buff = { 0 };
21269030e498SRahul Lakkireddy 	struct cudbg_tid_info_region *tid;
21279030e498SRahul Lakkireddy 	u32 para[2], val[2];
21289030e498SRahul Lakkireddy 	int rc;
21299030e498SRahul Lakkireddy 
213056cf2635SRahul Lakkireddy 	rc = cudbg_get_buff(pdbg_init, dbg_buff,
213156cf2635SRahul Lakkireddy 			    sizeof(struct cudbg_tid_info_region_rev1),
21329030e498SRahul Lakkireddy 			    &temp_buff);
21339030e498SRahul Lakkireddy 	if (rc)
21349030e498SRahul Lakkireddy 		return rc;
21359030e498SRahul Lakkireddy 
21369030e498SRahul Lakkireddy 	tid1 = (struct cudbg_tid_info_region_rev1 *)temp_buff.data;
21379030e498SRahul Lakkireddy 	tid = &tid1->tid;
21389030e498SRahul Lakkireddy 	tid1->ver_hdr.signature = CUDBG_ENTITY_SIGNATURE;
21399030e498SRahul Lakkireddy 	tid1->ver_hdr.revision = CUDBG_TID_INFO_REV;
21409030e498SRahul Lakkireddy 	tid1->ver_hdr.size = sizeof(struct cudbg_tid_info_region_rev1) -
21419030e498SRahul Lakkireddy 			     sizeof(struct cudbg_ver_hdr);
21429030e498SRahul Lakkireddy 
2143770ca347SRahul Lakkireddy 	/* If firmware is not attached/alive, use backdoor register
2144770ca347SRahul Lakkireddy 	 * access to collect dump.
2145770ca347SRahul Lakkireddy 	 */
2146770ca347SRahul Lakkireddy 	if (!is_fw_attached(pdbg_init))
2147770ca347SRahul Lakkireddy 		goto fill_tid;
2148770ca347SRahul Lakkireddy 
21499030e498SRahul Lakkireddy #define FW_PARAM_PFVF_A(param) \
21509030e498SRahul Lakkireddy 	(FW_PARAMS_MNEM_V(FW_PARAMS_MNEM_PFVF) | \
21519030e498SRahul Lakkireddy 	 FW_PARAMS_PARAM_X_V(FW_PARAMS_PARAM_PFVF_##param) | \
21529030e498SRahul Lakkireddy 	 FW_PARAMS_PARAM_Y_V(0) | \
21539030e498SRahul Lakkireddy 	 FW_PARAMS_PARAM_Z_V(0))
21549030e498SRahul Lakkireddy 
21559030e498SRahul Lakkireddy 	para[0] = FW_PARAM_PFVF_A(ETHOFLD_START);
21569030e498SRahul Lakkireddy 	para[1] = FW_PARAM_PFVF_A(ETHOFLD_END);
21579030e498SRahul Lakkireddy 	rc = t4_query_params(padap, padap->mbox, padap->pf, 0, 2, para, val);
21589030e498SRahul Lakkireddy 	if (rc <  0) {
21599030e498SRahul Lakkireddy 		cudbg_err->sys_err = rc;
216056cf2635SRahul Lakkireddy 		cudbg_put_buff(pdbg_init, &temp_buff);
21619030e498SRahul Lakkireddy 		return rc;
21629030e498SRahul Lakkireddy 	}
21639030e498SRahul Lakkireddy 	tid->uotid_base = val[0];
21649030e498SRahul Lakkireddy 	tid->nuotids = val[1] - val[0] + 1;
21659030e498SRahul Lakkireddy 
21669030e498SRahul Lakkireddy 	if (is_t5(padap->params.chip)) {
21679030e498SRahul Lakkireddy 		tid->sb = t4_read_reg(padap, LE_DB_SERVER_INDEX_A) / 4;
21689030e498SRahul Lakkireddy 	} else if (is_t6(padap->params.chip)) {
21699030e498SRahul Lakkireddy 		tid1->tid_start =
21709030e498SRahul Lakkireddy 			t4_read_reg(padap, LE_DB_ACTIVE_TABLE_START_INDEX_A);
21719030e498SRahul Lakkireddy 		tid->sb = t4_read_reg(padap, LE_DB_SRVR_START_INDEX_A);
21729030e498SRahul Lakkireddy 
21739030e498SRahul Lakkireddy 		para[0] = FW_PARAM_PFVF_A(HPFILTER_START);
21749030e498SRahul Lakkireddy 		para[1] = FW_PARAM_PFVF_A(HPFILTER_END);
21759030e498SRahul Lakkireddy 		rc = t4_query_params(padap, padap->mbox, padap->pf, 0, 2,
21769030e498SRahul Lakkireddy 				     para, val);
21779030e498SRahul Lakkireddy 		if (rc < 0) {
21789030e498SRahul Lakkireddy 			cudbg_err->sys_err = rc;
217956cf2635SRahul Lakkireddy 			cudbg_put_buff(pdbg_init, &temp_buff);
21809030e498SRahul Lakkireddy 			return rc;
21819030e498SRahul Lakkireddy 		}
21829030e498SRahul Lakkireddy 		tid->hpftid_base = val[0];
21839030e498SRahul Lakkireddy 		tid->nhpftids = val[1] - val[0] + 1;
21849030e498SRahul Lakkireddy 	}
21859030e498SRahul Lakkireddy 
2186770ca347SRahul Lakkireddy #undef FW_PARAM_PFVF_A
2187770ca347SRahul Lakkireddy 
2188770ca347SRahul Lakkireddy fill_tid:
21899030e498SRahul Lakkireddy 	tid->ntids = padap->tids.ntids;
21909030e498SRahul Lakkireddy 	tid->nstids = padap->tids.nstids;
21919030e498SRahul Lakkireddy 	tid->stid_base = padap->tids.stid_base;
21929030e498SRahul Lakkireddy 	tid->hash_base = padap->tids.hash_base;
21939030e498SRahul Lakkireddy 
21949030e498SRahul Lakkireddy 	tid->natids = padap->tids.natids;
21959030e498SRahul Lakkireddy 	tid->nftids = padap->tids.nftids;
21969030e498SRahul Lakkireddy 	tid->ftid_base = padap->tids.ftid_base;
21979030e498SRahul Lakkireddy 	tid->aftid_base = padap->tids.aftid_base;
21989030e498SRahul Lakkireddy 	tid->aftid_end = padap->tids.aftid_end;
21999030e498SRahul Lakkireddy 
22009030e498SRahul Lakkireddy 	tid->sftid_base = padap->tids.sftid_base;
22019030e498SRahul Lakkireddy 	tid->nsftids = padap->tids.nsftids;
22029030e498SRahul Lakkireddy 
22039030e498SRahul Lakkireddy 	tid->flags = padap->flags;
22049030e498SRahul Lakkireddy 	tid->le_db_conf = t4_read_reg(padap, LE_DB_CONFIG_A);
22059030e498SRahul Lakkireddy 	tid->ip_users = t4_read_reg(padap, LE_DB_ACT_CNT_IPV4_A);
22069030e498SRahul Lakkireddy 	tid->ipv6_users = t4_read_reg(padap, LE_DB_ACT_CNT_IPV6_A);
22079030e498SRahul Lakkireddy 
220856cf2635SRahul Lakkireddy 	return cudbg_write_and_release_buff(pdbg_init, &temp_buff, dbg_buff);
22099030e498SRahul Lakkireddy }
22109030e498SRahul Lakkireddy 
22116078ab19SRahul Lakkireddy int cudbg_collect_pcie_config(struct cudbg_init *pdbg_init,
22126078ab19SRahul Lakkireddy 			      struct cudbg_buffer *dbg_buff,
22136078ab19SRahul Lakkireddy 			      struct cudbg_error *cudbg_err)
22146078ab19SRahul Lakkireddy {
22156078ab19SRahul Lakkireddy 	struct adapter *padap = pdbg_init->adap;
22166078ab19SRahul Lakkireddy 	struct cudbg_buffer temp_buff = { 0 };
22176078ab19SRahul Lakkireddy 	u32 size, *value, j;
22186078ab19SRahul Lakkireddy 	int i, rc, n;
22196078ab19SRahul Lakkireddy 
22206078ab19SRahul Lakkireddy 	size = sizeof(u32) * CUDBG_NUM_PCIE_CONFIG_REGS;
22216078ab19SRahul Lakkireddy 	n = sizeof(t5_pcie_config_array) / (2 * sizeof(u32));
222256cf2635SRahul Lakkireddy 	rc = cudbg_get_buff(pdbg_init, dbg_buff, size, &temp_buff);
22236078ab19SRahul Lakkireddy 	if (rc)
22246078ab19SRahul Lakkireddy 		return rc;
22256078ab19SRahul Lakkireddy 
22266078ab19SRahul Lakkireddy 	value = (u32 *)temp_buff.data;
22276078ab19SRahul Lakkireddy 	for (i = 0; i < n; i++) {
22286078ab19SRahul Lakkireddy 		for (j = t5_pcie_config_array[i][0];
22296078ab19SRahul Lakkireddy 		     j <= t5_pcie_config_array[i][1]; j += 4) {
22306078ab19SRahul Lakkireddy 			t4_hw_pci_read_cfg4(padap, j, value);
22316078ab19SRahul Lakkireddy 			value++;
22326078ab19SRahul Lakkireddy 		}
22336078ab19SRahul Lakkireddy 	}
223456cf2635SRahul Lakkireddy 	return cudbg_write_and_release_buff(pdbg_init, &temp_buff, dbg_buff);
22356078ab19SRahul Lakkireddy }
22366078ab19SRahul Lakkireddy 
2237736c3b94SRahul Lakkireddy static int cudbg_sge_ctxt_check_valid(u32 *buf, int type)
22389e5c598cSRahul Lakkireddy {
2239736c3b94SRahul Lakkireddy 	int index, bit, bit_pos = 0;
22409e5c598cSRahul Lakkireddy 
2241736c3b94SRahul Lakkireddy 	switch (type) {
2242736c3b94SRahul Lakkireddy 	case CTXT_EGRESS:
2243736c3b94SRahul Lakkireddy 		bit_pos = 176;
2244736c3b94SRahul Lakkireddy 		break;
2245736c3b94SRahul Lakkireddy 	case CTXT_INGRESS:
2246736c3b94SRahul Lakkireddy 		bit_pos = 141;
2247736c3b94SRahul Lakkireddy 		break;
2248736c3b94SRahul Lakkireddy 	case CTXT_FLM:
2249736c3b94SRahul Lakkireddy 		bit_pos = 89;
2250736c3b94SRahul Lakkireddy 		break;
2251736c3b94SRahul Lakkireddy 	}
2252736c3b94SRahul Lakkireddy 	index = bit_pos / 32;
2253736c3b94SRahul Lakkireddy 	bit =  bit_pos % 32;
2254736c3b94SRahul Lakkireddy 	return buf[index] & (1U << bit);
2255736c3b94SRahul Lakkireddy }
2256736c3b94SRahul Lakkireddy 
2257736c3b94SRahul Lakkireddy static int cudbg_get_ctxt_region_info(struct adapter *padap,
2258736c3b94SRahul Lakkireddy 				      struct cudbg_region_info *ctx_info,
2259736c3b94SRahul Lakkireddy 				      u8 *mem_type)
2260736c3b94SRahul Lakkireddy {
2261736c3b94SRahul Lakkireddy 	struct cudbg_mem_desc mem_desc;
2262736c3b94SRahul Lakkireddy 	struct cudbg_meminfo meminfo;
2263736c3b94SRahul Lakkireddy 	u32 i, j, value, found;
2264736c3b94SRahul Lakkireddy 	u8 flq;
2265736c3b94SRahul Lakkireddy 	int rc;
2266736c3b94SRahul Lakkireddy 
2267736c3b94SRahul Lakkireddy 	rc = cudbg_fill_meminfo(padap, &meminfo);
2268736c3b94SRahul Lakkireddy 	if (rc)
2269736c3b94SRahul Lakkireddy 		return rc;
2270736c3b94SRahul Lakkireddy 
2271736c3b94SRahul Lakkireddy 	/* Get EGRESS and INGRESS context region size */
2272736c3b94SRahul Lakkireddy 	for (i = CTXT_EGRESS; i <= CTXT_INGRESS; i++) {
2273736c3b94SRahul Lakkireddy 		found = 0;
2274736c3b94SRahul Lakkireddy 		memset(&mem_desc, 0, sizeof(struct cudbg_mem_desc));
2275736c3b94SRahul Lakkireddy 		for (j = 0; j < ARRAY_SIZE(meminfo.avail); j++) {
2276736c3b94SRahul Lakkireddy 			rc = cudbg_get_mem_region(padap, &meminfo, j,
2277736c3b94SRahul Lakkireddy 						  cudbg_region[i],
2278736c3b94SRahul Lakkireddy 						  &mem_desc);
2279736c3b94SRahul Lakkireddy 			if (!rc) {
2280736c3b94SRahul Lakkireddy 				found = 1;
2281736c3b94SRahul Lakkireddy 				rc = cudbg_get_mem_relative(padap, &meminfo, j,
2282736c3b94SRahul Lakkireddy 							    &mem_desc.base,
2283736c3b94SRahul Lakkireddy 							    &mem_desc.limit);
2284736c3b94SRahul Lakkireddy 				if (rc) {
2285736c3b94SRahul Lakkireddy 					ctx_info[i].exist = false;
2286736c3b94SRahul Lakkireddy 					break;
2287736c3b94SRahul Lakkireddy 				}
2288736c3b94SRahul Lakkireddy 				ctx_info[i].exist = true;
2289736c3b94SRahul Lakkireddy 				ctx_info[i].start = mem_desc.base;
2290736c3b94SRahul Lakkireddy 				ctx_info[i].end = mem_desc.limit;
2291736c3b94SRahul Lakkireddy 				mem_type[i] = j;
2292736c3b94SRahul Lakkireddy 				break;
2293736c3b94SRahul Lakkireddy 			}
2294736c3b94SRahul Lakkireddy 		}
2295736c3b94SRahul Lakkireddy 		if (!found)
2296736c3b94SRahul Lakkireddy 			ctx_info[i].exist = false;
2297736c3b94SRahul Lakkireddy 	}
2298736c3b94SRahul Lakkireddy 
2299736c3b94SRahul Lakkireddy 	/* Get FLM and CNM max qid. */
23009e5c598cSRahul Lakkireddy 	value = t4_read_reg(padap, SGE_FLM_CFG_A);
23019e5c598cSRahul Lakkireddy 
23029e5c598cSRahul Lakkireddy 	/* Get number of data freelist queues */
23039e5c598cSRahul Lakkireddy 	flq = HDRSTARTFLQ_G(value);
2304736c3b94SRahul Lakkireddy 	ctx_info[CTXT_FLM].exist = true;
2305736c3b94SRahul Lakkireddy 	ctx_info[CTXT_FLM].end = (CUDBG_MAX_FL_QIDS >> flq) * SGE_CTXT_SIZE;
23069e5c598cSRahul Lakkireddy 
2307736c3b94SRahul Lakkireddy 	/* The number of CONM contexts are same as number of freelist
23089e5c598cSRahul Lakkireddy 	 * queues.
23099e5c598cSRahul Lakkireddy 	 */
2310736c3b94SRahul Lakkireddy 	ctx_info[CTXT_CNM].exist = true;
2311736c3b94SRahul Lakkireddy 	ctx_info[CTXT_CNM].end = ctx_info[CTXT_FLM].end;
2312736c3b94SRahul Lakkireddy 
2313736c3b94SRahul Lakkireddy 	return 0;
2314736c3b94SRahul Lakkireddy }
2315736c3b94SRahul Lakkireddy 
2316736c3b94SRahul Lakkireddy int cudbg_dump_context_size(struct adapter *padap)
2317736c3b94SRahul Lakkireddy {
2318736c3b94SRahul Lakkireddy 	struct cudbg_region_info region_info[CTXT_CNM + 1] = { {0} };
2319736c3b94SRahul Lakkireddy 	u8 mem_type[CTXT_INGRESS + 1] = { 0 };
2320736c3b94SRahul Lakkireddy 	u32 i, size = 0;
2321736c3b94SRahul Lakkireddy 	int rc;
2322736c3b94SRahul Lakkireddy 
2323736c3b94SRahul Lakkireddy 	/* Get max valid qid for each type of queue */
2324736c3b94SRahul Lakkireddy 	rc = cudbg_get_ctxt_region_info(padap, region_info, mem_type);
2325736c3b94SRahul Lakkireddy 	if (rc)
2326736c3b94SRahul Lakkireddy 		return rc;
2327736c3b94SRahul Lakkireddy 
2328736c3b94SRahul Lakkireddy 	for (i = 0; i < CTXT_CNM; i++) {
2329736c3b94SRahul Lakkireddy 		if (!region_info[i].exist) {
2330736c3b94SRahul Lakkireddy 			if (i == CTXT_EGRESS || i == CTXT_INGRESS)
2331736c3b94SRahul Lakkireddy 				size += CUDBG_LOWMEM_MAX_CTXT_QIDS *
2332736c3b94SRahul Lakkireddy 					SGE_CTXT_SIZE;
2333736c3b94SRahul Lakkireddy 			continue;
2334736c3b94SRahul Lakkireddy 		}
2335736c3b94SRahul Lakkireddy 
2336736c3b94SRahul Lakkireddy 		size += (region_info[i].end - region_info[i].start + 1) /
2337736c3b94SRahul Lakkireddy 			SGE_CTXT_SIZE;
2338736c3b94SRahul Lakkireddy 	}
23399e5c598cSRahul Lakkireddy 	return size * sizeof(struct cudbg_ch_cntxt);
23409e5c598cSRahul Lakkireddy }
23419e5c598cSRahul Lakkireddy 
23429e5c598cSRahul Lakkireddy static void cudbg_read_sge_ctxt(struct cudbg_init *pdbg_init, u32 cid,
23439e5c598cSRahul Lakkireddy 				enum ctxt_type ctype, u32 *data)
23449e5c598cSRahul Lakkireddy {
23459e5c598cSRahul Lakkireddy 	struct adapter *padap = pdbg_init->adap;
23469e5c598cSRahul Lakkireddy 	int rc = -1;
23479e5c598cSRahul Lakkireddy 
23489e5c598cSRahul Lakkireddy 	/* Under heavy traffic, the SGE Queue contexts registers will be
23499e5c598cSRahul Lakkireddy 	 * frequently accessed by firmware.
23509e5c598cSRahul Lakkireddy 	 *
23519e5c598cSRahul Lakkireddy 	 * To avoid conflicts with firmware, always ask firmware to fetch
23529e5c598cSRahul Lakkireddy 	 * the SGE Queue contexts via mailbox. On failure, fallback to
23539e5c598cSRahul Lakkireddy 	 * accessing hardware registers directly.
23549e5c598cSRahul Lakkireddy 	 */
23559e5c598cSRahul Lakkireddy 	if (is_fw_attached(pdbg_init))
23569e5c598cSRahul Lakkireddy 		rc = t4_sge_ctxt_rd(padap, padap->mbox, cid, ctype, data);
23579e5c598cSRahul Lakkireddy 	if (rc)
23589e5c598cSRahul Lakkireddy 		t4_sge_ctxt_rd_bd(padap, cid, ctype, data);
23599e5c598cSRahul Lakkireddy }
23609e5c598cSRahul Lakkireddy 
2361736c3b94SRahul Lakkireddy static void cudbg_get_sge_ctxt_fw(struct cudbg_init *pdbg_init, u32 max_qid,
2362736c3b94SRahul Lakkireddy 				  u8 ctxt_type,
2363736c3b94SRahul Lakkireddy 				  struct cudbg_ch_cntxt **out_buff)
2364736c3b94SRahul Lakkireddy {
2365736c3b94SRahul Lakkireddy 	struct cudbg_ch_cntxt *buff = *out_buff;
2366736c3b94SRahul Lakkireddy 	int rc;
2367736c3b94SRahul Lakkireddy 	u32 j;
2368736c3b94SRahul Lakkireddy 
2369736c3b94SRahul Lakkireddy 	for (j = 0; j < max_qid; j++) {
2370736c3b94SRahul Lakkireddy 		cudbg_read_sge_ctxt(pdbg_init, j, ctxt_type, buff->data);
2371736c3b94SRahul Lakkireddy 		rc = cudbg_sge_ctxt_check_valid(buff->data, ctxt_type);
2372736c3b94SRahul Lakkireddy 		if (!rc)
2373736c3b94SRahul Lakkireddy 			continue;
2374736c3b94SRahul Lakkireddy 
2375736c3b94SRahul Lakkireddy 		buff->cntxt_type = ctxt_type;
2376736c3b94SRahul Lakkireddy 		buff->cntxt_id = j;
2377736c3b94SRahul Lakkireddy 		buff++;
2378736c3b94SRahul Lakkireddy 		if (ctxt_type == CTXT_FLM) {
2379736c3b94SRahul Lakkireddy 			cudbg_read_sge_ctxt(pdbg_init, j, CTXT_CNM, buff->data);
2380736c3b94SRahul Lakkireddy 			buff->cntxt_type = CTXT_CNM;
2381736c3b94SRahul Lakkireddy 			buff->cntxt_id = j;
2382736c3b94SRahul Lakkireddy 			buff++;
2383736c3b94SRahul Lakkireddy 		}
2384736c3b94SRahul Lakkireddy 	}
2385736c3b94SRahul Lakkireddy 
2386736c3b94SRahul Lakkireddy 	*out_buff = buff;
2387736c3b94SRahul Lakkireddy }
2388736c3b94SRahul Lakkireddy 
23899e5c598cSRahul Lakkireddy int cudbg_collect_dump_context(struct cudbg_init *pdbg_init,
23909e5c598cSRahul Lakkireddy 			       struct cudbg_buffer *dbg_buff,
23919e5c598cSRahul Lakkireddy 			       struct cudbg_error *cudbg_err)
23929e5c598cSRahul Lakkireddy {
2393736c3b94SRahul Lakkireddy 	struct cudbg_region_info region_info[CTXT_CNM + 1] = { {0} };
23949e5c598cSRahul Lakkireddy 	struct adapter *padap = pdbg_init->adap;
2395736c3b94SRahul Lakkireddy 	u32 j, size, max_ctx_size, max_ctx_qid;
2396736c3b94SRahul Lakkireddy 	u8 mem_type[CTXT_INGRESS + 1] = { 0 };
23979e5c598cSRahul Lakkireddy 	struct cudbg_buffer temp_buff = { 0 };
23989e5c598cSRahul Lakkireddy 	struct cudbg_ch_cntxt *buff;
2399736c3b94SRahul Lakkireddy 	u8 *ctx_buf;
2400736c3b94SRahul Lakkireddy 	u8 i, k;
24019e5c598cSRahul Lakkireddy 	int rc;
24029e5c598cSRahul Lakkireddy 
2403736c3b94SRahul Lakkireddy 	/* Get max valid qid for each type of queue */
2404736c3b94SRahul Lakkireddy 	rc = cudbg_get_ctxt_region_info(padap, region_info, mem_type);
2405736c3b94SRahul Lakkireddy 	if (rc)
2406736c3b94SRahul Lakkireddy 		return rc;
2407736c3b94SRahul Lakkireddy 
24089e5c598cSRahul Lakkireddy 	rc = cudbg_dump_context_size(padap);
24099e5c598cSRahul Lakkireddy 	if (rc <= 0)
24109e5c598cSRahul Lakkireddy 		return CUDBG_STATUS_ENTITY_NOT_FOUND;
24119e5c598cSRahul Lakkireddy 
24129e5c598cSRahul Lakkireddy 	size = rc;
241356cf2635SRahul Lakkireddy 	rc = cudbg_get_buff(pdbg_init, dbg_buff, size, &temp_buff);
24149e5c598cSRahul Lakkireddy 	if (rc)
24159e5c598cSRahul Lakkireddy 		return rc;
24169e5c598cSRahul Lakkireddy 
2417736c3b94SRahul Lakkireddy 	/* Get buffer with enough space to read the biggest context
2418736c3b94SRahul Lakkireddy 	 * region in memory.
2419736c3b94SRahul Lakkireddy 	 */
2420736c3b94SRahul Lakkireddy 	max_ctx_size = max(region_info[CTXT_EGRESS].end -
2421736c3b94SRahul Lakkireddy 			   region_info[CTXT_EGRESS].start + 1,
2422736c3b94SRahul Lakkireddy 			   region_info[CTXT_INGRESS].end -
2423736c3b94SRahul Lakkireddy 			   region_info[CTXT_INGRESS].start + 1);
24249e5c598cSRahul Lakkireddy 
2425736c3b94SRahul Lakkireddy 	ctx_buf = kvzalloc(max_ctx_size, GFP_KERNEL);
2426736c3b94SRahul Lakkireddy 	if (!ctx_buf) {
242756cf2635SRahul Lakkireddy 		cudbg_put_buff(pdbg_init, &temp_buff);
2428736c3b94SRahul Lakkireddy 		return -ENOMEM;
24299e5c598cSRahul Lakkireddy 	}
24309e5c598cSRahul Lakkireddy 
2431736c3b94SRahul Lakkireddy 	buff = (struct cudbg_ch_cntxt *)temp_buff.data;
2432736c3b94SRahul Lakkireddy 
2433736c3b94SRahul Lakkireddy 	/* Collect EGRESS and INGRESS context data.
2434736c3b94SRahul Lakkireddy 	 * In case of failures, fallback to collecting via FW or
2435736c3b94SRahul Lakkireddy 	 * backdoor access.
2436736c3b94SRahul Lakkireddy 	 */
2437736c3b94SRahul Lakkireddy 	for (i = CTXT_EGRESS; i <= CTXT_INGRESS; i++) {
2438736c3b94SRahul Lakkireddy 		if (!region_info[i].exist) {
2439736c3b94SRahul Lakkireddy 			max_ctx_qid = CUDBG_LOWMEM_MAX_CTXT_QIDS;
2440736c3b94SRahul Lakkireddy 			cudbg_get_sge_ctxt_fw(pdbg_init, max_ctx_qid, i,
2441736c3b94SRahul Lakkireddy 					      &buff);
2442736c3b94SRahul Lakkireddy 			continue;
2443736c3b94SRahul Lakkireddy 		}
2444736c3b94SRahul Lakkireddy 
2445736c3b94SRahul Lakkireddy 		max_ctx_size = region_info[i].end - region_info[i].start + 1;
2446736c3b94SRahul Lakkireddy 		max_ctx_qid = max_ctx_size / SGE_CTXT_SIZE;
2447736c3b94SRahul Lakkireddy 
2448770ca347SRahul Lakkireddy 		/* If firmware is not attached/alive, use backdoor register
2449770ca347SRahul Lakkireddy 		 * access to collect dump.
2450770ca347SRahul Lakkireddy 		 */
2451770ca347SRahul Lakkireddy 		if (is_fw_attached(pdbg_init)) {
2452736c3b94SRahul Lakkireddy 			t4_sge_ctxt_flush(padap, padap->mbox, i);
2453770ca347SRahul Lakkireddy 
2454736c3b94SRahul Lakkireddy 			rc = t4_memory_rw(padap, MEMWIN_NIC, mem_type[i],
2455736c3b94SRahul Lakkireddy 					  region_info[i].start, max_ctx_size,
2456736c3b94SRahul Lakkireddy 					  (__be32 *)ctx_buf, 1);
2457770ca347SRahul Lakkireddy 		}
2458770ca347SRahul Lakkireddy 
2459770ca347SRahul Lakkireddy 		if (rc || !is_fw_attached(pdbg_init)) {
2460736c3b94SRahul Lakkireddy 			max_ctx_qid = CUDBG_LOWMEM_MAX_CTXT_QIDS;
2461736c3b94SRahul Lakkireddy 			cudbg_get_sge_ctxt_fw(pdbg_init, max_ctx_qid, i,
2462736c3b94SRahul Lakkireddy 					      &buff);
2463736c3b94SRahul Lakkireddy 			continue;
2464736c3b94SRahul Lakkireddy 		}
2465736c3b94SRahul Lakkireddy 
2466736c3b94SRahul Lakkireddy 		for (j = 0; j < max_ctx_qid; j++) {
24671992ded5SRahul Lakkireddy 			__be64 *dst_off;
24681992ded5SRahul Lakkireddy 			u64 *src_off;
24691992ded5SRahul Lakkireddy 
2470736c3b94SRahul Lakkireddy 			src_off = (u64 *)(ctx_buf + j * SGE_CTXT_SIZE);
24711992ded5SRahul Lakkireddy 			dst_off = (__be64 *)buff->data;
2472736c3b94SRahul Lakkireddy 
2473736c3b94SRahul Lakkireddy 			/* The data is stored in 64-bit cpu order.  Convert it
2474736c3b94SRahul Lakkireddy 			 * to big endian before parsing.
2475736c3b94SRahul Lakkireddy 			 */
2476736c3b94SRahul Lakkireddy 			for (k = 0; k < SGE_CTXT_SIZE / sizeof(u64); k++)
2477736c3b94SRahul Lakkireddy 				dst_off[k] = cpu_to_be64(src_off[k]);
2478736c3b94SRahul Lakkireddy 
2479736c3b94SRahul Lakkireddy 			rc = cudbg_sge_ctxt_check_valid(buff->data, i);
2480736c3b94SRahul Lakkireddy 			if (!rc)
2481736c3b94SRahul Lakkireddy 				continue;
2482736c3b94SRahul Lakkireddy 
2483736c3b94SRahul Lakkireddy 			buff->cntxt_type = i;
2484736c3b94SRahul Lakkireddy 			buff->cntxt_id = j;
2485736c3b94SRahul Lakkireddy 			buff++;
2486736c3b94SRahul Lakkireddy 		}
2487736c3b94SRahul Lakkireddy 	}
2488736c3b94SRahul Lakkireddy 
2489736c3b94SRahul Lakkireddy 	kvfree(ctx_buf);
2490736c3b94SRahul Lakkireddy 
2491736c3b94SRahul Lakkireddy 	/* Collect FREELIST and CONGESTION MANAGER contexts */
2492736c3b94SRahul Lakkireddy 	max_ctx_size = region_info[CTXT_FLM].end -
2493736c3b94SRahul Lakkireddy 		       region_info[CTXT_FLM].start + 1;
2494736c3b94SRahul Lakkireddy 	max_ctx_qid = max_ctx_size / SGE_CTXT_SIZE;
2495736c3b94SRahul Lakkireddy 	/* Since FLM and CONM are 1-to-1 mapped, the below function
2496736c3b94SRahul Lakkireddy 	 * will fetch both FLM and CONM contexts.
2497736c3b94SRahul Lakkireddy 	 */
2498736c3b94SRahul Lakkireddy 	cudbg_get_sge_ctxt_fw(pdbg_init, max_ctx_qid, CTXT_FLM, &buff);
2499736c3b94SRahul Lakkireddy 
250056cf2635SRahul Lakkireddy 	return cudbg_write_and_release_buff(pdbg_init, &temp_buff, dbg_buff);
25019e5c598cSRahul Lakkireddy }
25029e5c598cSRahul Lakkireddy 
2503b289593eSRahul Lakkireddy static inline void cudbg_tcamxy2valmask(u64 x, u64 y, u8 *addr, u64 *mask)
2504b289593eSRahul Lakkireddy {
2505b289593eSRahul Lakkireddy 	*mask = x | y;
2506b289593eSRahul Lakkireddy 	y = (__force u64)cpu_to_be64(y);
2507b289593eSRahul Lakkireddy 	memcpy(addr, (char *)&y + 2, ETH_ALEN);
2508b289593eSRahul Lakkireddy }
2509b289593eSRahul Lakkireddy 
2510b289593eSRahul Lakkireddy static void cudbg_mps_rpl_backdoor(struct adapter *padap,
2511b289593eSRahul Lakkireddy 				   struct fw_ldst_mps_rplc *mps_rplc)
2512b289593eSRahul Lakkireddy {
2513b289593eSRahul Lakkireddy 	if (is_t5(padap->params.chip)) {
2514b289593eSRahul Lakkireddy 		mps_rplc->rplc255_224 = htonl(t4_read_reg(padap,
2515b289593eSRahul Lakkireddy 							  MPS_VF_RPLCT_MAP3_A));
2516b289593eSRahul Lakkireddy 		mps_rplc->rplc223_192 = htonl(t4_read_reg(padap,
2517b289593eSRahul Lakkireddy 							  MPS_VF_RPLCT_MAP2_A));
2518b289593eSRahul Lakkireddy 		mps_rplc->rplc191_160 = htonl(t4_read_reg(padap,
2519b289593eSRahul Lakkireddy 							  MPS_VF_RPLCT_MAP1_A));
2520b289593eSRahul Lakkireddy 		mps_rplc->rplc159_128 = htonl(t4_read_reg(padap,
2521b289593eSRahul Lakkireddy 							  MPS_VF_RPLCT_MAP0_A));
2522b289593eSRahul Lakkireddy 	} else {
2523b289593eSRahul Lakkireddy 		mps_rplc->rplc255_224 = htonl(t4_read_reg(padap,
2524b289593eSRahul Lakkireddy 							  MPS_VF_RPLCT_MAP7_A));
2525b289593eSRahul Lakkireddy 		mps_rplc->rplc223_192 = htonl(t4_read_reg(padap,
2526b289593eSRahul Lakkireddy 							  MPS_VF_RPLCT_MAP6_A));
2527b289593eSRahul Lakkireddy 		mps_rplc->rplc191_160 = htonl(t4_read_reg(padap,
2528b289593eSRahul Lakkireddy 							  MPS_VF_RPLCT_MAP5_A));
2529b289593eSRahul Lakkireddy 		mps_rplc->rplc159_128 = htonl(t4_read_reg(padap,
2530b289593eSRahul Lakkireddy 							  MPS_VF_RPLCT_MAP4_A));
2531b289593eSRahul Lakkireddy 	}
2532b289593eSRahul Lakkireddy 	mps_rplc->rplc127_96 = htonl(t4_read_reg(padap, MPS_VF_RPLCT_MAP3_A));
2533b289593eSRahul Lakkireddy 	mps_rplc->rplc95_64 = htonl(t4_read_reg(padap, MPS_VF_RPLCT_MAP2_A));
2534b289593eSRahul Lakkireddy 	mps_rplc->rplc63_32 = htonl(t4_read_reg(padap, MPS_VF_RPLCT_MAP1_A));
2535b289593eSRahul Lakkireddy 	mps_rplc->rplc31_0 = htonl(t4_read_reg(padap, MPS_VF_RPLCT_MAP0_A));
2536b289593eSRahul Lakkireddy }
2537b289593eSRahul Lakkireddy 
2538770ca347SRahul Lakkireddy static int cudbg_collect_tcam_index(struct cudbg_init *pdbg_init,
2539b289593eSRahul Lakkireddy 				    struct cudbg_mps_tcam *tcam, u32 idx)
2540b289593eSRahul Lakkireddy {
2541770ca347SRahul Lakkireddy 	struct adapter *padap = pdbg_init->adap;
2542b289593eSRahul Lakkireddy 	u64 tcamy, tcamx, val;
2543b289593eSRahul Lakkireddy 	u32 ctl, data2;
2544b289593eSRahul Lakkireddy 	int rc = 0;
2545b289593eSRahul Lakkireddy 
2546b289593eSRahul Lakkireddy 	if (CHELSIO_CHIP_VERSION(padap->params.chip) >= CHELSIO_T6) {
2547b289593eSRahul Lakkireddy 		/* CtlReqID   - 1: use Host Driver Requester ID
2548b289593eSRahul Lakkireddy 		 * CtlCmdType - 0: Read, 1: Write
2549b289593eSRahul Lakkireddy 		 * CtlTcamSel - 0: TCAM0, 1: TCAM1
2550b289593eSRahul Lakkireddy 		 * CtlXYBitSel- 0: Y bit, 1: X bit
2551b289593eSRahul Lakkireddy 		 */
2552b289593eSRahul Lakkireddy 
2553b289593eSRahul Lakkireddy 		/* Read tcamy */
2554b289593eSRahul Lakkireddy 		ctl = CTLREQID_V(1) | CTLCMDTYPE_V(0) | CTLXYBITSEL_V(0);
2555b289593eSRahul Lakkireddy 		if (idx < 256)
2556b289593eSRahul Lakkireddy 			ctl |= CTLTCAMINDEX_V(idx) | CTLTCAMSEL_V(0);
2557b289593eSRahul Lakkireddy 		else
2558b289593eSRahul Lakkireddy 			ctl |= CTLTCAMINDEX_V(idx - 256) | CTLTCAMSEL_V(1);
2559b289593eSRahul Lakkireddy 
2560b289593eSRahul Lakkireddy 		t4_write_reg(padap, MPS_CLS_TCAM_DATA2_CTL_A, ctl);
2561b289593eSRahul Lakkireddy 		val = t4_read_reg(padap, MPS_CLS_TCAM_RDATA1_REQ_ID1_A);
2562b289593eSRahul Lakkireddy 		tcamy = DMACH_G(val) << 32;
2563b289593eSRahul Lakkireddy 		tcamy |= t4_read_reg(padap, MPS_CLS_TCAM_RDATA0_REQ_ID1_A);
2564b289593eSRahul Lakkireddy 		data2 = t4_read_reg(padap, MPS_CLS_TCAM_RDATA2_REQ_ID1_A);
2565b289593eSRahul Lakkireddy 		tcam->lookup_type = DATALKPTYPE_G(data2);
2566b289593eSRahul Lakkireddy 
2567b289593eSRahul Lakkireddy 		/* 0 - Outer header, 1 - Inner header
2568b289593eSRahul Lakkireddy 		 * [71:48] bit locations are overloaded for
2569b289593eSRahul Lakkireddy 		 * outer vs. inner lookup types.
2570b289593eSRahul Lakkireddy 		 */
2571b289593eSRahul Lakkireddy 		if (tcam->lookup_type && tcam->lookup_type != DATALKPTYPE_M) {
2572b289593eSRahul Lakkireddy 			/* Inner header VNI */
2573b289593eSRahul Lakkireddy 			tcam->vniy = (data2 & DATAVIDH2_F) | DATAVIDH1_G(data2);
2574b289593eSRahul Lakkireddy 			tcam->vniy = (tcam->vniy << 16) | VIDL_G(val);
2575b289593eSRahul Lakkireddy 			tcam->dip_hit = data2 & DATADIPHIT_F;
2576b289593eSRahul Lakkireddy 		} else {
2577b289593eSRahul Lakkireddy 			tcam->vlan_vld = data2 & DATAVIDH2_F;
2578b289593eSRahul Lakkireddy 			tcam->ivlan = VIDL_G(val);
2579b289593eSRahul Lakkireddy 		}
2580b289593eSRahul Lakkireddy 
2581b289593eSRahul Lakkireddy 		tcam->port_num = DATAPORTNUM_G(data2);
2582b289593eSRahul Lakkireddy 
2583b289593eSRahul Lakkireddy 		/* Read tcamx. Change the control param */
2584b289593eSRahul Lakkireddy 		ctl |= CTLXYBITSEL_V(1);
2585b289593eSRahul Lakkireddy 		t4_write_reg(padap, MPS_CLS_TCAM_DATA2_CTL_A, ctl);
2586b289593eSRahul Lakkireddy 		val = t4_read_reg(padap, MPS_CLS_TCAM_RDATA1_REQ_ID1_A);
2587b289593eSRahul Lakkireddy 		tcamx = DMACH_G(val) << 32;
2588b289593eSRahul Lakkireddy 		tcamx |= t4_read_reg(padap, MPS_CLS_TCAM_RDATA0_REQ_ID1_A);
2589b289593eSRahul Lakkireddy 		data2 = t4_read_reg(padap, MPS_CLS_TCAM_RDATA2_REQ_ID1_A);
2590b289593eSRahul Lakkireddy 		if (tcam->lookup_type && tcam->lookup_type != DATALKPTYPE_M) {
2591b289593eSRahul Lakkireddy 			/* Inner header VNI mask */
2592b289593eSRahul Lakkireddy 			tcam->vnix = (data2 & DATAVIDH2_F) | DATAVIDH1_G(data2);
2593b289593eSRahul Lakkireddy 			tcam->vnix = (tcam->vnix << 16) | VIDL_G(val);
2594b289593eSRahul Lakkireddy 		}
2595b289593eSRahul Lakkireddy 	} else {
2596b289593eSRahul Lakkireddy 		tcamy = t4_read_reg64(padap, MPS_CLS_TCAM_Y_L(idx));
2597b289593eSRahul Lakkireddy 		tcamx = t4_read_reg64(padap, MPS_CLS_TCAM_X_L(idx));
2598b289593eSRahul Lakkireddy 	}
2599b289593eSRahul Lakkireddy 
2600b289593eSRahul Lakkireddy 	/* If no entry, return */
2601b289593eSRahul Lakkireddy 	if (tcamx & tcamy)
2602b289593eSRahul Lakkireddy 		return rc;
2603b289593eSRahul Lakkireddy 
2604b289593eSRahul Lakkireddy 	tcam->cls_lo = t4_read_reg(padap, MPS_CLS_SRAM_L(idx));
2605b289593eSRahul Lakkireddy 	tcam->cls_hi = t4_read_reg(padap, MPS_CLS_SRAM_H(idx));
2606b289593eSRahul Lakkireddy 
2607b289593eSRahul Lakkireddy 	if (is_t5(padap->params.chip))
2608b289593eSRahul Lakkireddy 		tcam->repli = (tcam->cls_lo & REPLICATE_F);
2609b289593eSRahul Lakkireddy 	else if (is_t6(padap->params.chip))
2610b289593eSRahul Lakkireddy 		tcam->repli = (tcam->cls_lo & T6_REPLICATE_F);
2611b289593eSRahul Lakkireddy 
2612b289593eSRahul Lakkireddy 	if (tcam->repli) {
2613b289593eSRahul Lakkireddy 		struct fw_ldst_cmd ldst_cmd;
2614b289593eSRahul Lakkireddy 		struct fw_ldst_mps_rplc mps_rplc;
2615b289593eSRahul Lakkireddy 
2616b289593eSRahul Lakkireddy 		memset(&ldst_cmd, 0, sizeof(ldst_cmd));
2617b289593eSRahul Lakkireddy 		ldst_cmd.op_to_addrspace =
2618b289593eSRahul Lakkireddy 			htonl(FW_CMD_OP_V(FW_LDST_CMD) |
2619b289593eSRahul Lakkireddy 			      FW_CMD_REQUEST_F | FW_CMD_READ_F |
2620b289593eSRahul Lakkireddy 			      FW_LDST_CMD_ADDRSPACE_V(FW_LDST_ADDRSPC_MPS));
2621b289593eSRahul Lakkireddy 		ldst_cmd.cycles_to_len16 = htonl(FW_LEN16(ldst_cmd));
2622b289593eSRahul Lakkireddy 		ldst_cmd.u.mps.rplc.fid_idx =
2623b289593eSRahul Lakkireddy 			htons(FW_LDST_CMD_FID_V(FW_LDST_MPS_RPLC) |
2624b289593eSRahul Lakkireddy 			      FW_LDST_CMD_IDX_V(idx));
2625b289593eSRahul Lakkireddy 
2626770ca347SRahul Lakkireddy 		/* If firmware is not attached/alive, use backdoor register
2627770ca347SRahul Lakkireddy 		 * access to collect dump.
2628770ca347SRahul Lakkireddy 		 */
2629770ca347SRahul Lakkireddy 		if (is_fw_attached(pdbg_init))
2630770ca347SRahul Lakkireddy 			rc = t4_wr_mbox(padap, padap->mbox, &ldst_cmd,
2631770ca347SRahul Lakkireddy 					sizeof(ldst_cmd), &ldst_cmd);
2632770ca347SRahul Lakkireddy 
2633770ca347SRahul Lakkireddy 		if (rc || !is_fw_attached(pdbg_init)) {
2634b289593eSRahul Lakkireddy 			cudbg_mps_rpl_backdoor(padap, &mps_rplc);
2635770ca347SRahul Lakkireddy 			/* Ignore error since we collected directly from
2636770ca347SRahul Lakkireddy 			 * reading registers.
2637770ca347SRahul Lakkireddy 			 */
2638770ca347SRahul Lakkireddy 			rc = 0;
2639770ca347SRahul Lakkireddy 		} else {
2640b289593eSRahul Lakkireddy 			mps_rplc = ldst_cmd.u.mps.rplc;
2641770ca347SRahul Lakkireddy 		}
2642b289593eSRahul Lakkireddy 
2643b289593eSRahul Lakkireddy 		tcam->rplc[0] = ntohl(mps_rplc.rplc31_0);
2644b289593eSRahul Lakkireddy 		tcam->rplc[1] = ntohl(mps_rplc.rplc63_32);
2645b289593eSRahul Lakkireddy 		tcam->rplc[2] = ntohl(mps_rplc.rplc95_64);
2646b289593eSRahul Lakkireddy 		tcam->rplc[3] = ntohl(mps_rplc.rplc127_96);
2647b289593eSRahul Lakkireddy 		if (padap->params.arch.mps_rplc_size > CUDBG_MAX_RPLC_SIZE) {
2648b289593eSRahul Lakkireddy 			tcam->rplc[4] = ntohl(mps_rplc.rplc159_128);
2649b289593eSRahul Lakkireddy 			tcam->rplc[5] = ntohl(mps_rplc.rplc191_160);
2650b289593eSRahul Lakkireddy 			tcam->rplc[6] = ntohl(mps_rplc.rplc223_192);
2651b289593eSRahul Lakkireddy 			tcam->rplc[7] = ntohl(mps_rplc.rplc255_224);
2652b289593eSRahul Lakkireddy 		}
2653b289593eSRahul Lakkireddy 	}
2654b289593eSRahul Lakkireddy 	cudbg_tcamxy2valmask(tcamx, tcamy, tcam->addr, &tcam->mask);
2655b289593eSRahul Lakkireddy 	tcam->idx = idx;
2656b289593eSRahul Lakkireddy 	tcam->rplc_size = padap->params.arch.mps_rplc_size;
2657b289593eSRahul Lakkireddy 	return rc;
2658b289593eSRahul Lakkireddy }
2659b289593eSRahul Lakkireddy 
2660b289593eSRahul Lakkireddy int cudbg_collect_mps_tcam(struct cudbg_init *pdbg_init,
2661b289593eSRahul Lakkireddy 			   struct cudbg_buffer *dbg_buff,
2662b289593eSRahul Lakkireddy 			   struct cudbg_error *cudbg_err)
2663b289593eSRahul Lakkireddy {
2664b289593eSRahul Lakkireddy 	struct adapter *padap = pdbg_init->adap;
2665b289593eSRahul Lakkireddy 	struct cudbg_buffer temp_buff = { 0 };
2666b289593eSRahul Lakkireddy 	u32 size = 0, i, n, total_size = 0;
2667b289593eSRahul Lakkireddy 	struct cudbg_mps_tcam *tcam;
2668b289593eSRahul Lakkireddy 	int rc;
2669b289593eSRahul Lakkireddy 
2670b289593eSRahul Lakkireddy 	n = padap->params.arch.mps_tcam_size;
2671b289593eSRahul Lakkireddy 	size = sizeof(struct cudbg_mps_tcam) * n;
267256cf2635SRahul Lakkireddy 	rc = cudbg_get_buff(pdbg_init, dbg_buff, size, &temp_buff);
2673b289593eSRahul Lakkireddy 	if (rc)
2674b289593eSRahul Lakkireddy 		return rc;
2675b289593eSRahul Lakkireddy 
2676b289593eSRahul Lakkireddy 	tcam = (struct cudbg_mps_tcam *)temp_buff.data;
2677b289593eSRahul Lakkireddy 	for (i = 0; i < n; i++) {
2678770ca347SRahul Lakkireddy 		rc = cudbg_collect_tcam_index(pdbg_init, tcam, i);
2679b289593eSRahul Lakkireddy 		if (rc) {
2680b289593eSRahul Lakkireddy 			cudbg_err->sys_err = rc;
268156cf2635SRahul Lakkireddy 			cudbg_put_buff(pdbg_init, &temp_buff);
2682b289593eSRahul Lakkireddy 			return rc;
2683b289593eSRahul Lakkireddy 		}
2684b289593eSRahul Lakkireddy 		total_size += sizeof(struct cudbg_mps_tcam);
2685b289593eSRahul Lakkireddy 		tcam++;
2686b289593eSRahul Lakkireddy 	}
2687b289593eSRahul Lakkireddy 
2688b289593eSRahul Lakkireddy 	if (!total_size) {
2689b289593eSRahul Lakkireddy 		rc = CUDBG_SYSTEM_ERROR;
2690b289593eSRahul Lakkireddy 		cudbg_err->sys_err = rc;
269156cf2635SRahul Lakkireddy 		cudbg_put_buff(pdbg_init, &temp_buff);
2692b289593eSRahul Lakkireddy 		return rc;
2693b289593eSRahul Lakkireddy 	}
269456cf2635SRahul Lakkireddy 	return cudbg_write_and_release_buff(pdbg_init, &temp_buff, dbg_buff);
2695b289593eSRahul Lakkireddy }
2696b289593eSRahul Lakkireddy 
26976f92a654SRahul Lakkireddy int cudbg_collect_vpd_data(struct cudbg_init *pdbg_init,
26986f92a654SRahul Lakkireddy 			   struct cudbg_buffer *dbg_buff,
26996f92a654SRahul Lakkireddy 			   struct cudbg_error *cudbg_err)
27006f92a654SRahul Lakkireddy {
27016f92a654SRahul Lakkireddy 	struct adapter *padap = pdbg_init->adap;
27026f92a654SRahul Lakkireddy 	struct cudbg_buffer temp_buff = { 0 };
2703940c9c45SRahul Lakkireddy 	char vpd_str[CUDBG_VPD_VER_LEN + 1];
27046f92a654SRahul Lakkireddy 	struct cudbg_vpd_data *vpd_data;
2705940c9c45SRahul Lakkireddy 	struct vpd_params vpd = { 0 };
270624a1720aSRahul Lakkireddy 	u32 vpd_vers, fw_vers;
270724a1720aSRahul Lakkireddy 	int rc;
2708940c9c45SRahul Lakkireddy 
2709940c9c45SRahul Lakkireddy 	rc = t4_get_raw_vpd_params(padap, &vpd);
2710940c9c45SRahul Lakkireddy 	if (rc)
2711940c9c45SRahul Lakkireddy 		return rc;
2712940c9c45SRahul Lakkireddy 
2713940c9c45SRahul Lakkireddy 	rc = t4_get_fw_version(padap, &fw_vers);
2714940c9c45SRahul Lakkireddy 	if (rc)
2715940c9c45SRahul Lakkireddy 		return rc;
2716940c9c45SRahul Lakkireddy 
2717940c9c45SRahul Lakkireddy 	rc = cudbg_read_vpd_reg(padap, CUDBG_VPD_VER_ADDR, CUDBG_VPD_VER_LEN,
2718940c9c45SRahul Lakkireddy 				vpd_str);
2719940c9c45SRahul Lakkireddy 	if (rc)
2720940c9c45SRahul Lakkireddy 		return rc;
2721940c9c45SRahul Lakkireddy 
2722940c9c45SRahul Lakkireddy 	vpd_str[CUDBG_VPD_VER_LEN] = '\0';
2723940c9c45SRahul Lakkireddy 	rc = kstrtouint(vpd_str, 0, &vpd_vers);
2724940c9c45SRahul Lakkireddy 	if (rc)
2725940c9c45SRahul Lakkireddy 		return rc;
27266f92a654SRahul Lakkireddy 
272756cf2635SRahul Lakkireddy 	rc = cudbg_get_buff(pdbg_init, dbg_buff, sizeof(struct cudbg_vpd_data),
27286f92a654SRahul Lakkireddy 			    &temp_buff);
27296f92a654SRahul Lakkireddy 	if (rc)
27306f92a654SRahul Lakkireddy 		return rc;
27316f92a654SRahul Lakkireddy 
27326f92a654SRahul Lakkireddy 	vpd_data = (struct cudbg_vpd_data *)temp_buff.data;
2733940c9c45SRahul Lakkireddy 	memcpy(vpd_data->sn, vpd.sn, SERNUM_LEN + 1);
2734940c9c45SRahul Lakkireddy 	memcpy(vpd_data->bn, vpd.pn, PN_LEN + 1);
2735940c9c45SRahul Lakkireddy 	memcpy(vpd_data->na, vpd.na, MACADDR_LEN + 1);
2736940c9c45SRahul Lakkireddy 	memcpy(vpd_data->mn, vpd.id, ID_LEN + 1);
273724a1720aSRahul Lakkireddy 	vpd_data->scfg_vers = t4_read_reg(padap, PCIE_STATIC_SPARE2_A);
2738940c9c45SRahul Lakkireddy 	vpd_data->vpd_vers = vpd_vers;
2739940c9c45SRahul Lakkireddy 	vpd_data->fw_major = FW_HDR_FW_VER_MAJOR_G(fw_vers);
2740940c9c45SRahul Lakkireddy 	vpd_data->fw_minor = FW_HDR_FW_VER_MINOR_G(fw_vers);
2741940c9c45SRahul Lakkireddy 	vpd_data->fw_micro = FW_HDR_FW_VER_MICRO_G(fw_vers);
2742940c9c45SRahul Lakkireddy 	vpd_data->fw_build = FW_HDR_FW_VER_BUILD_G(fw_vers);
274356cf2635SRahul Lakkireddy 	return cudbg_write_and_release_buff(pdbg_init, &temp_buff, dbg_buff);
27446f92a654SRahul Lakkireddy }
27456f92a654SRahul Lakkireddy 
274603e98b91SRahul Lakkireddy static int cudbg_read_tid(struct cudbg_init *pdbg_init, u32 tid,
274703e98b91SRahul Lakkireddy 			  struct cudbg_tid_data *tid_data)
274803e98b91SRahul Lakkireddy {
274903e98b91SRahul Lakkireddy 	struct adapter *padap = pdbg_init->adap;
275003e98b91SRahul Lakkireddy 	int i, cmd_retry = 8;
275103e98b91SRahul Lakkireddy 	u32 val;
275203e98b91SRahul Lakkireddy 
275303e98b91SRahul Lakkireddy 	/* Fill REQ_DATA regs with 0's */
275403e98b91SRahul Lakkireddy 	for (i = 0; i < NUM_LE_DB_DBGI_REQ_DATA_INSTANCES; i++)
275503e98b91SRahul Lakkireddy 		t4_write_reg(padap, LE_DB_DBGI_REQ_DATA_A + (i << 2), 0);
275603e98b91SRahul Lakkireddy 
275703e98b91SRahul Lakkireddy 	/* Write DBIG command */
275803e98b91SRahul Lakkireddy 	val = DBGICMD_V(4) | DBGITID_V(tid);
275903e98b91SRahul Lakkireddy 	t4_write_reg(padap, LE_DB_DBGI_REQ_TCAM_CMD_A, val);
276003e98b91SRahul Lakkireddy 	tid_data->dbig_cmd = val;
276103e98b91SRahul Lakkireddy 
276203e98b91SRahul Lakkireddy 	val = DBGICMDSTRT_F | DBGICMDMODE_V(1); /* LE mode */
276303e98b91SRahul Lakkireddy 	t4_write_reg(padap, LE_DB_DBGI_CONFIG_A, val);
276403e98b91SRahul Lakkireddy 	tid_data->dbig_conf = val;
276503e98b91SRahul Lakkireddy 
276603e98b91SRahul Lakkireddy 	/* Poll the DBGICMDBUSY bit */
276703e98b91SRahul Lakkireddy 	val = 1;
276803e98b91SRahul Lakkireddy 	while (val) {
276903e98b91SRahul Lakkireddy 		val = t4_read_reg(padap, LE_DB_DBGI_CONFIG_A);
277003e98b91SRahul Lakkireddy 		val = val & DBGICMDBUSY_F;
277103e98b91SRahul Lakkireddy 		cmd_retry--;
277203e98b91SRahul Lakkireddy 		if (!cmd_retry)
277303e98b91SRahul Lakkireddy 			return CUDBG_SYSTEM_ERROR;
277403e98b91SRahul Lakkireddy 	}
277503e98b91SRahul Lakkireddy 
277603e98b91SRahul Lakkireddy 	/* Check RESP status */
277703e98b91SRahul Lakkireddy 	val = t4_read_reg(padap, LE_DB_DBGI_RSP_STATUS_A);
277803e98b91SRahul Lakkireddy 	tid_data->dbig_rsp_stat = val;
277903e98b91SRahul Lakkireddy 	if (!(val & 1))
278003e98b91SRahul Lakkireddy 		return CUDBG_SYSTEM_ERROR;
278103e98b91SRahul Lakkireddy 
278203e98b91SRahul Lakkireddy 	/* Read RESP data */
278303e98b91SRahul Lakkireddy 	for (i = 0; i < NUM_LE_DB_DBGI_RSP_DATA_INSTANCES; i++)
278403e98b91SRahul Lakkireddy 		tid_data->data[i] = t4_read_reg(padap,
278503e98b91SRahul Lakkireddy 						LE_DB_DBGI_RSP_DATA_A +
278603e98b91SRahul Lakkireddy 						(i << 2));
278703e98b91SRahul Lakkireddy 	tid_data->tid = tid;
278803e98b91SRahul Lakkireddy 	return 0;
278903e98b91SRahul Lakkireddy }
279003e98b91SRahul Lakkireddy 
279103e98b91SRahul Lakkireddy static int cudbg_get_le_type(u32 tid, struct cudbg_tcam tcam_region)
279203e98b91SRahul Lakkireddy {
279303e98b91SRahul Lakkireddy 	int type = LE_ET_UNKNOWN;
279403e98b91SRahul Lakkireddy 
279503e98b91SRahul Lakkireddy 	if (tid < tcam_region.server_start)
279603e98b91SRahul Lakkireddy 		type = LE_ET_TCAM_CON;
279703e98b91SRahul Lakkireddy 	else if (tid < tcam_region.filter_start)
279803e98b91SRahul Lakkireddy 		type = LE_ET_TCAM_SERVER;
279903e98b91SRahul Lakkireddy 	else if (tid < tcam_region.clip_start)
280003e98b91SRahul Lakkireddy 		type = LE_ET_TCAM_FILTER;
280103e98b91SRahul Lakkireddy 	else if (tid < tcam_region.routing_start)
280203e98b91SRahul Lakkireddy 		type = LE_ET_TCAM_CLIP;
280303e98b91SRahul Lakkireddy 	else if (tid < tcam_region.tid_hash_base)
280403e98b91SRahul Lakkireddy 		type = LE_ET_TCAM_ROUTING;
280503e98b91SRahul Lakkireddy 	else if (tid < tcam_region.max_tid)
280603e98b91SRahul Lakkireddy 		type = LE_ET_HASH_CON;
280703e98b91SRahul Lakkireddy 	else
280803e98b91SRahul Lakkireddy 		type = LE_ET_INVALID_TID;
280903e98b91SRahul Lakkireddy 
281003e98b91SRahul Lakkireddy 	return type;
281103e98b91SRahul Lakkireddy }
281203e98b91SRahul Lakkireddy 
281303e98b91SRahul Lakkireddy static int cudbg_is_ipv6_entry(struct cudbg_tid_data *tid_data,
281403e98b91SRahul Lakkireddy 			       struct cudbg_tcam tcam_region)
281503e98b91SRahul Lakkireddy {
281603e98b91SRahul Lakkireddy 	int ipv6 = 0;
281703e98b91SRahul Lakkireddy 	int le_type;
281803e98b91SRahul Lakkireddy 
281903e98b91SRahul Lakkireddy 	le_type = cudbg_get_le_type(tid_data->tid, tcam_region);
282003e98b91SRahul Lakkireddy 	if (tid_data->tid & 1)
282103e98b91SRahul Lakkireddy 		return 0;
282203e98b91SRahul Lakkireddy 
282303e98b91SRahul Lakkireddy 	if (le_type == LE_ET_HASH_CON) {
282403e98b91SRahul Lakkireddy 		ipv6 = tid_data->data[16] & 0x8000;
282503e98b91SRahul Lakkireddy 	} else if (le_type == LE_ET_TCAM_CON) {
282603e98b91SRahul Lakkireddy 		ipv6 = tid_data->data[16] & 0x8000;
282703e98b91SRahul Lakkireddy 		if (ipv6)
282803e98b91SRahul Lakkireddy 			ipv6 = tid_data->data[9] == 0x00C00000;
282903e98b91SRahul Lakkireddy 	} else {
283003e98b91SRahul Lakkireddy 		ipv6 = 0;
283103e98b91SRahul Lakkireddy 	}
283203e98b91SRahul Lakkireddy 	return ipv6;
283303e98b91SRahul Lakkireddy }
283403e98b91SRahul Lakkireddy 
283503e98b91SRahul Lakkireddy void cudbg_fill_le_tcam_info(struct adapter *padap,
283603e98b91SRahul Lakkireddy 			     struct cudbg_tcam *tcam_region)
283703e98b91SRahul Lakkireddy {
283803e98b91SRahul Lakkireddy 	u32 value;
283903e98b91SRahul Lakkireddy 
284003e98b91SRahul Lakkireddy 	/* Get the LE regions */
284103e98b91SRahul Lakkireddy 	value = t4_read_reg(padap, LE_DB_TID_HASHBASE_A); /* hash base index */
284203e98b91SRahul Lakkireddy 	tcam_region->tid_hash_base = value;
284303e98b91SRahul Lakkireddy 
284403e98b91SRahul Lakkireddy 	/* Get routing table index */
284503e98b91SRahul Lakkireddy 	value = t4_read_reg(padap, LE_DB_ROUTING_TABLE_INDEX_A);
284603e98b91SRahul Lakkireddy 	tcam_region->routing_start = value;
284703e98b91SRahul Lakkireddy 
28488e725f7cSRahul Lakkireddy 	/* Get clip table index. For T6 there is separate CLIP TCAM */
28498e725f7cSRahul Lakkireddy 	if (is_t6(padap->params.chip))
28508e725f7cSRahul Lakkireddy 		value = t4_read_reg(padap, LE_DB_CLCAM_TID_BASE_A);
28518e725f7cSRahul Lakkireddy 	else
285203e98b91SRahul Lakkireddy 		value = t4_read_reg(padap, LE_DB_CLIP_TABLE_INDEX_A);
285303e98b91SRahul Lakkireddy 	tcam_region->clip_start = value;
285403e98b91SRahul Lakkireddy 
285503e98b91SRahul Lakkireddy 	/* Get filter table index */
285603e98b91SRahul Lakkireddy 	value = t4_read_reg(padap, LE_DB_FILTER_TABLE_INDEX_A);
285703e98b91SRahul Lakkireddy 	tcam_region->filter_start = value;
285803e98b91SRahul Lakkireddy 
285903e98b91SRahul Lakkireddy 	/* Get server table index */
286003e98b91SRahul Lakkireddy 	value = t4_read_reg(padap, LE_DB_SERVER_INDEX_A);
286103e98b91SRahul Lakkireddy 	tcam_region->server_start = value;
286203e98b91SRahul Lakkireddy 
286303e98b91SRahul Lakkireddy 	/* Check whether hash is enabled and calculate the max tids */
286403e98b91SRahul Lakkireddy 	value = t4_read_reg(padap, LE_DB_CONFIG_A);
286503e98b91SRahul Lakkireddy 	if ((value >> HASHEN_S) & 1) {
286603e98b91SRahul Lakkireddy 		value = t4_read_reg(padap, LE_DB_HASH_CONFIG_A);
286703e98b91SRahul Lakkireddy 		if (CHELSIO_CHIP_VERSION(padap->params.chip) > CHELSIO_T5) {
286803e98b91SRahul Lakkireddy 			tcam_region->max_tid = (value & 0xFFFFF) +
286903e98b91SRahul Lakkireddy 					       tcam_region->tid_hash_base;
287003e98b91SRahul Lakkireddy 		} else {
287103e98b91SRahul Lakkireddy 			value = HASHTIDSIZE_G(value);
287203e98b91SRahul Lakkireddy 			value = 1 << value;
287303e98b91SRahul Lakkireddy 			tcam_region->max_tid = value +
287403e98b91SRahul Lakkireddy 					       tcam_region->tid_hash_base;
287503e98b91SRahul Lakkireddy 		}
287603e98b91SRahul Lakkireddy 	} else { /* hash not enabled */
28778e725f7cSRahul Lakkireddy 		if (is_t6(padap->params.chip))
28788e725f7cSRahul Lakkireddy 			tcam_region->max_tid = (value & ASLIPCOMPEN_F) ?
28798e725f7cSRahul Lakkireddy 					       CUDBG_MAX_TID_COMP_EN :
28808e725f7cSRahul Lakkireddy 					       CUDBG_MAX_TID_COMP_DIS;
28818e725f7cSRahul Lakkireddy 		else
288203e98b91SRahul Lakkireddy 			tcam_region->max_tid = CUDBG_MAX_TCAM_TID;
288303e98b91SRahul Lakkireddy 	}
28848e725f7cSRahul Lakkireddy 
28858e725f7cSRahul Lakkireddy 	if (is_t6(padap->params.chip))
28868e725f7cSRahul Lakkireddy 		tcam_region->max_tid += CUDBG_T6_CLIP;
288703e98b91SRahul Lakkireddy }
288803e98b91SRahul Lakkireddy 
288903e98b91SRahul Lakkireddy int cudbg_collect_le_tcam(struct cudbg_init *pdbg_init,
289003e98b91SRahul Lakkireddy 			  struct cudbg_buffer *dbg_buff,
289103e98b91SRahul Lakkireddy 			  struct cudbg_error *cudbg_err)
289203e98b91SRahul Lakkireddy {
289303e98b91SRahul Lakkireddy 	struct adapter *padap = pdbg_init->adap;
289403e98b91SRahul Lakkireddy 	struct cudbg_buffer temp_buff = { 0 };
289503e98b91SRahul Lakkireddy 	struct cudbg_tcam tcam_region = { 0 };
289603e98b91SRahul Lakkireddy 	struct cudbg_tid_data *tid_data;
289703e98b91SRahul Lakkireddy 	u32 bytes = 0;
289803e98b91SRahul Lakkireddy 	int rc, size;
289903e98b91SRahul Lakkireddy 	u32 i;
290003e98b91SRahul Lakkireddy 
290103e98b91SRahul Lakkireddy 	cudbg_fill_le_tcam_info(padap, &tcam_region);
290203e98b91SRahul Lakkireddy 
290303e98b91SRahul Lakkireddy 	size = sizeof(struct cudbg_tid_data) * tcam_region.max_tid;
290403e98b91SRahul Lakkireddy 	size += sizeof(struct cudbg_tcam);
290556cf2635SRahul Lakkireddy 	rc = cudbg_get_buff(pdbg_init, dbg_buff, size, &temp_buff);
290603e98b91SRahul Lakkireddy 	if (rc)
290703e98b91SRahul Lakkireddy 		return rc;
290803e98b91SRahul Lakkireddy 
290903e98b91SRahul Lakkireddy 	memcpy(temp_buff.data, &tcam_region, sizeof(struct cudbg_tcam));
291003e98b91SRahul Lakkireddy 	bytes = sizeof(struct cudbg_tcam);
291103e98b91SRahul Lakkireddy 	tid_data = (struct cudbg_tid_data *)(temp_buff.data + bytes);
291203e98b91SRahul Lakkireddy 	/* read all tid */
291303e98b91SRahul Lakkireddy 	for (i = 0; i < tcam_region.max_tid; ) {
291403e98b91SRahul Lakkireddy 		rc = cudbg_read_tid(pdbg_init, i, tid_data);
291503e98b91SRahul Lakkireddy 		if (rc) {
29168e725f7cSRahul Lakkireddy 			cudbg_err->sys_warn = CUDBG_STATUS_PARTIAL_DATA;
29178e725f7cSRahul Lakkireddy 			/* Update tcam header and exit */
29188e725f7cSRahul Lakkireddy 			tcam_region.max_tid = i;
29198e725f7cSRahul Lakkireddy 			memcpy(temp_buff.data, &tcam_region,
29208e725f7cSRahul Lakkireddy 			       sizeof(struct cudbg_tcam));
29218e725f7cSRahul Lakkireddy 			goto out;
292203e98b91SRahul Lakkireddy 		}
292303e98b91SRahul Lakkireddy 
29248e725f7cSRahul Lakkireddy 		if (cudbg_is_ipv6_entry(tid_data, tcam_region)) {
29258e725f7cSRahul Lakkireddy 			/* T6 CLIP TCAM: ipv6 takes 4 entries */
29268e725f7cSRahul Lakkireddy 			if (is_t6(padap->params.chip) &&
29278e725f7cSRahul Lakkireddy 			    i >= tcam_region.clip_start &&
29288e725f7cSRahul Lakkireddy 			    i < tcam_region.clip_start + CUDBG_T6_CLIP)
29298e725f7cSRahul Lakkireddy 				i += 4;
29308e725f7cSRahul Lakkireddy 			else /* Main TCAM: ipv6 takes two tids */
29318e725f7cSRahul Lakkireddy 				i += 2;
29328e725f7cSRahul Lakkireddy 		} else {
29338e725f7cSRahul Lakkireddy 			i++;
29348e725f7cSRahul Lakkireddy 		}
293503e98b91SRahul Lakkireddy 
293603e98b91SRahul Lakkireddy 		tid_data++;
293703e98b91SRahul Lakkireddy 		bytes += sizeof(struct cudbg_tid_data);
293803e98b91SRahul Lakkireddy 	}
293903e98b91SRahul Lakkireddy 
29408e725f7cSRahul Lakkireddy out:
294156cf2635SRahul Lakkireddy 	return cudbg_write_and_release_buff(pdbg_init, &temp_buff, dbg_buff);
294203e98b91SRahul Lakkireddy }
294303e98b91SRahul Lakkireddy 
29446f92a654SRahul Lakkireddy int cudbg_collect_cctrl(struct cudbg_init *pdbg_init,
29456f92a654SRahul Lakkireddy 			struct cudbg_buffer *dbg_buff,
29466f92a654SRahul Lakkireddy 			struct cudbg_error *cudbg_err)
29476f92a654SRahul Lakkireddy {
29486f92a654SRahul Lakkireddy 	struct adapter *padap = pdbg_init->adap;
29496f92a654SRahul Lakkireddy 	struct cudbg_buffer temp_buff = { 0 };
29506f92a654SRahul Lakkireddy 	u32 size;
29516f92a654SRahul Lakkireddy 	int rc;
29526f92a654SRahul Lakkireddy 
29536f92a654SRahul Lakkireddy 	size = sizeof(u16) * NMTUS * NCCTRL_WIN;
295456cf2635SRahul Lakkireddy 	rc = cudbg_get_buff(pdbg_init, dbg_buff, size, &temp_buff);
29556f92a654SRahul Lakkireddy 	if (rc)
29566f92a654SRahul Lakkireddy 		return rc;
29576f92a654SRahul Lakkireddy 
29586f92a654SRahul Lakkireddy 	t4_read_cong_tbl(padap, (void *)temp_buff.data);
295956cf2635SRahul Lakkireddy 	return cudbg_write_and_release_buff(pdbg_init, &temp_buff, dbg_buff);
29606f92a654SRahul Lakkireddy }
29616f92a654SRahul Lakkireddy 
2962270d39bfSRahul Lakkireddy int cudbg_collect_ma_indirect(struct cudbg_init *pdbg_init,
2963270d39bfSRahul Lakkireddy 			      struct cudbg_buffer *dbg_buff,
2964270d39bfSRahul Lakkireddy 			      struct cudbg_error *cudbg_err)
2965270d39bfSRahul Lakkireddy {
2966270d39bfSRahul Lakkireddy 	struct adapter *padap = pdbg_init->adap;
2967270d39bfSRahul Lakkireddy 	struct cudbg_buffer temp_buff = { 0 };
2968270d39bfSRahul Lakkireddy 	struct ireg_buf *ma_indr;
2969270d39bfSRahul Lakkireddy 	int i, rc, n;
2970270d39bfSRahul Lakkireddy 	u32 size, j;
2971270d39bfSRahul Lakkireddy 
2972270d39bfSRahul Lakkireddy 	if (CHELSIO_CHIP_VERSION(padap->params.chip) < CHELSIO_T6)
2973270d39bfSRahul Lakkireddy 		return CUDBG_STATUS_ENTITY_NOT_FOUND;
2974270d39bfSRahul Lakkireddy 
2975270d39bfSRahul Lakkireddy 	n = sizeof(t6_ma_ireg_array) / (IREG_NUM_ELEM * sizeof(u32));
2976270d39bfSRahul Lakkireddy 	size = sizeof(struct ireg_buf) * n * 2;
297756cf2635SRahul Lakkireddy 	rc = cudbg_get_buff(pdbg_init, dbg_buff, size, &temp_buff);
2978270d39bfSRahul Lakkireddy 	if (rc)
2979270d39bfSRahul Lakkireddy 		return rc;
2980270d39bfSRahul Lakkireddy 
2981270d39bfSRahul Lakkireddy 	ma_indr = (struct ireg_buf *)temp_buff.data;
2982270d39bfSRahul Lakkireddy 	for (i = 0; i < n; i++) {
2983270d39bfSRahul Lakkireddy 		struct ireg_field *ma_fli = &ma_indr->tp_pio;
2984270d39bfSRahul Lakkireddy 		u32 *buff = ma_indr->outbuf;
2985270d39bfSRahul Lakkireddy 
2986270d39bfSRahul Lakkireddy 		ma_fli->ireg_addr = t6_ma_ireg_array[i][0];
2987270d39bfSRahul Lakkireddy 		ma_fli->ireg_data = t6_ma_ireg_array[i][1];
2988270d39bfSRahul Lakkireddy 		ma_fli->ireg_local_offset = t6_ma_ireg_array[i][2];
2989270d39bfSRahul Lakkireddy 		ma_fli->ireg_offset_range = t6_ma_ireg_array[i][3];
2990270d39bfSRahul Lakkireddy 		t4_read_indirect(padap, ma_fli->ireg_addr, ma_fli->ireg_data,
2991270d39bfSRahul Lakkireddy 				 buff, ma_fli->ireg_offset_range,
2992270d39bfSRahul Lakkireddy 				 ma_fli->ireg_local_offset);
2993270d39bfSRahul Lakkireddy 		ma_indr++;
2994270d39bfSRahul Lakkireddy 	}
2995270d39bfSRahul Lakkireddy 
2996270d39bfSRahul Lakkireddy 	n = sizeof(t6_ma_ireg_array2) / (IREG_NUM_ELEM * sizeof(u32));
2997270d39bfSRahul Lakkireddy 	for (i = 0; i < n; i++) {
2998270d39bfSRahul Lakkireddy 		struct ireg_field *ma_fli = &ma_indr->tp_pio;
2999270d39bfSRahul Lakkireddy 		u32 *buff = ma_indr->outbuf;
3000270d39bfSRahul Lakkireddy 
3001270d39bfSRahul Lakkireddy 		ma_fli->ireg_addr = t6_ma_ireg_array2[i][0];
3002270d39bfSRahul Lakkireddy 		ma_fli->ireg_data = t6_ma_ireg_array2[i][1];
3003270d39bfSRahul Lakkireddy 		ma_fli->ireg_local_offset = t6_ma_ireg_array2[i][2];
3004270d39bfSRahul Lakkireddy 		for (j = 0; j < t6_ma_ireg_array2[i][3]; j++) {
3005270d39bfSRahul Lakkireddy 			t4_read_indirect(padap, ma_fli->ireg_addr,
3006270d39bfSRahul Lakkireddy 					 ma_fli->ireg_data, buff, 1,
3007270d39bfSRahul Lakkireddy 					 ma_fli->ireg_local_offset);
3008270d39bfSRahul Lakkireddy 			buff++;
3009270d39bfSRahul Lakkireddy 			ma_fli->ireg_local_offset += 0x20;
3010270d39bfSRahul Lakkireddy 		}
3011270d39bfSRahul Lakkireddy 		ma_indr++;
3012270d39bfSRahul Lakkireddy 	}
301356cf2635SRahul Lakkireddy 	return cudbg_write_and_release_buff(pdbg_init, &temp_buff, dbg_buff);
3014270d39bfSRahul Lakkireddy }
3015270d39bfSRahul Lakkireddy 
301627887bc7SRahul Lakkireddy int cudbg_collect_ulptx_la(struct cudbg_init *pdbg_init,
301727887bc7SRahul Lakkireddy 			   struct cudbg_buffer *dbg_buff,
301827887bc7SRahul Lakkireddy 			   struct cudbg_error *cudbg_err)
301927887bc7SRahul Lakkireddy {
302027887bc7SRahul Lakkireddy 	struct adapter *padap = pdbg_init->adap;
302127887bc7SRahul Lakkireddy 	struct cudbg_buffer temp_buff = { 0 };
302227887bc7SRahul Lakkireddy 	struct cudbg_ulptx_la *ulptx_la_buff;
30231eb94d44SSurendra Mobiya 	struct cudbg_ver_hdr *ver_hdr;
302427887bc7SRahul Lakkireddy 	u32 i, j;
302527887bc7SRahul Lakkireddy 	int rc;
302627887bc7SRahul Lakkireddy 
30271eb94d44SSurendra Mobiya 	rc = cudbg_get_buff(pdbg_init, dbg_buff,
30281eb94d44SSurendra Mobiya 			    sizeof(struct cudbg_ver_hdr) +
30291eb94d44SSurendra Mobiya 			    sizeof(struct cudbg_ulptx_la),
303027887bc7SRahul Lakkireddy 			    &temp_buff);
303127887bc7SRahul Lakkireddy 	if (rc)
303227887bc7SRahul Lakkireddy 		return rc;
303327887bc7SRahul Lakkireddy 
30341eb94d44SSurendra Mobiya 	ver_hdr = (struct cudbg_ver_hdr *)temp_buff.data;
30351eb94d44SSurendra Mobiya 	ver_hdr->signature = CUDBG_ENTITY_SIGNATURE;
30361eb94d44SSurendra Mobiya 	ver_hdr->revision = CUDBG_ULPTX_LA_REV;
30371eb94d44SSurendra Mobiya 	ver_hdr->size = sizeof(struct cudbg_ulptx_la);
30381eb94d44SSurendra Mobiya 
30391eb94d44SSurendra Mobiya 	ulptx_la_buff = (struct cudbg_ulptx_la *)(temp_buff.data +
30401eb94d44SSurendra Mobiya 						  sizeof(*ver_hdr));
304127887bc7SRahul Lakkireddy 	for (i = 0; i < CUDBG_NUM_ULPTX; i++) {
304227887bc7SRahul Lakkireddy 		ulptx_la_buff->rdptr[i] = t4_read_reg(padap,
304327887bc7SRahul Lakkireddy 						      ULP_TX_LA_RDPTR_0_A +
304427887bc7SRahul Lakkireddy 						      0x10 * i);
304527887bc7SRahul Lakkireddy 		ulptx_la_buff->wrptr[i] = t4_read_reg(padap,
304627887bc7SRahul Lakkireddy 						      ULP_TX_LA_WRPTR_0_A +
304727887bc7SRahul Lakkireddy 						      0x10 * i);
304827887bc7SRahul Lakkireddy 		ulptx_la_buff->rddata[i] = t4_read_reg(padap,
304927887bc7SRahul Lakkireddy 						       ULP_TX_LA_RDDATA_0_A +
305027887bc7SRahul Lakkireddy 						       0x10 * i);
305127887bc7SRahul Lakkireddy 		for (j = 0; j < CUDBG_NUM_ULPTX_READ; j++)
305227887bc7SRahul Lakkireddy 			ulptx_la_buff->rd_data[i][j] =
305327887bc7SRahul Lakkireddy 				t4_read_reg(padap,
305427887bc7SRahul Lakkireddy 					    ULP_TX_LA_RDDATA_0_A + 0x10 * i);
305527887bc7SRahul Lakkireddy 	}
30561eb94d44SSurendra Mobiya 
30571eb94d44SSurendra Mobiya 	for (i = 0; i < CUDBG_NUM_ULPTX_ASIC_READ; i++) {
30581eb94d44SSurendra Mobiya 		t4_write_reg(padap, ULP_TX_ASIC_DEBUG_CTRL_A, 0x1);
30591eb94d44SSurendra Mobiya 		ulptx_la_buff->rdptr_asic[i] =
30601eb94d44SSurendra Mobiya 				t4_read_reg(padap, ULP_TX_ASIC_DEBUG_CTRL_A);
30611eb94d44SSurendra Mobiya 		ulptx_la_buff->rddata_asic[i][0] =
30621eb94d44SSurendra Mobiya 				t4_read_reg(padap, ULP_TX_ASIC_DEBUG_0_A);
30631eb94d44SSurendra Mobiya 		ulptx_la_buff->rddata_asic[i][1] =
30641eb94d44SSurendra Mobiya 				t4_read_reg(padap, ULP_TX_ASIC_DEBUG_1_A);
30651eb94d44SSurendra Mobiya 		ulptx_la_buff->rddata_asic[i][2] =
30661eb94d44SSurendra Mobiya 				t4_read_reg(padap, ULP_TX_ASIC_DEBUG_2_A);
30671eb94d44SSurendra Mobiya 		ulptx_la_buff->rddata_asic[i][3] =
30681eb94d44SSurendra Mobiya 				t4_read_reg(padap, ULP_TX_ASIC_DEBUG_3_A);
30691eb94d44SSurendra Mobiya 		ulptx_la_buff->rddata_asic[i][4] =
30701eb94d44SSurendra Mobiya 				t4_read_reg(padap, ULP_TX_ASIC_DEBUG_4_A);
30711eb94d44SSurendra Mobiya 		ulptx_la_buff->rddata_asic[i][5] =
30721eb94d44SSurendra Mobiya 				t4_read_reg(padap, PM_RX_BASE_ADDR);
30731eb94d44SSurendra Mobiya 	}
30741eb94d44SSurendra Mobiya 
307556cf2635SRahul Lakkireddy 	return cudbg_write_and_release_buff(pdbg_init, &temp_buff, dbg_buff);
307627887bc7SRahul Lakkireddy }
307727887bc7SRahul Lakkireddy 
3078270d39bfSRahul Lakkireddy int cudbg_collect_up_cim_indirect(struct cudbg_init *pdbg_init,
3079270d39bfSRahul Lakkireddy 				  struct cudbg_buffer *dbg_buff,
3080270d39bfSRahul Lakkireddy 				  struct cudbg_error *cudbg_err)
3081270d39bfSRahul Lakkireddy {
3082270d39bfSRahul Lakkireddy 	struct adapter *padap = pdbg_init->adap;
3083270d39bfSRahul Lakkireddy 	struct cudbg_buffer temp_buff = { 0 };
3084be6e36d9SRahul Lakkireddy 	u32 local_offset, local_range;
3085270d39bfSRahul Lakkireddy 	struct ireg_buf *up_cim;
3086be6e36d9SRahul Lakkireddy 	u32 size, j, iter;
3087be6e36d9SRahul Lakkireddy 	u32 instance = 0;
3088270d39bfSRahul Lakkireddy 	int i, rc, n;
3089270d39bfSRahul Lakkireddy 
3090be6e36d9SRahul Lakkireddy 	if (is_t5(padap->params.chip))
3091be6e36d9SRahul Lakkireddy 		n = sizeof(t5_up_cim_reg_array) /
3092be6e36d9SRahul Lakkireddy 		    ((IREG_NUM_ELEM + 1) * sizeof(u32));
3093be6e36d9SRahul Lakkireddy 	else if (is_t6(padap->params.chip))
3094be6e36d9SRahul Lakkireddy 		n = sizeof(t6_up_cim_reg_array) /
3095be6e36d9SRahul Lakkireddy 		    ((IREG_NUM_ELEM + 1) * sizeof(u32));
3096be6e36d9SRahul Lakkireddy 	else
3097be6e36d9SRahul Lakkireddy 		return CUDBG_STATUS_NOT_IMPLEMENTED;
3098be6e36d9SRahul Lakkireddy 
3099270d39bfSRahul Lakkireddy 	size = sizeof(struct ireg_buf) * n;
310056cf2635SRahul Lakkireddy 	rc = cudbg_get_buff(pdbg_init, dbg_buff, size, &temp_buff);
3101270d39bfSRahul Lakkireddy 	if (rc)
3102270d39bfSRahul Lakkireddy 		return rc;
3103270d39bfSRahul Lakkireddy 
3104270d39bfSRahul Lakkireddy 	up_cim = (struct ireg_buf *)temp_buff.data;
3105270d39bfSRahul Lakkireddy 	for (i = 0; i < n; i++) {
3106270d39bfSRahul Lakkireddy 		struct ireg_field *up_cim_reg = &up_cim->tp_pio;
3107270d39bfSRahul Lakkireddy 		u32 *buff = up_cim->outbuf;
3108270d39bfSRahul Lakkireddy 
3109270d39bfSRahul Lakkireddy 		if (is_t5(padap->params.chip)) {
3110270d39bfSRahul Lakkireddy 			up_cim_reg->ireg_addr = t5_up_cim_reg_array[i][0];
3111270d39bfSRahul Lakkireddy 			up_cim_reg->ireg_data = t5_up_cim_reg_array[i][1];
3112270d39bfSRahul Lakkireddy 			up_cim_reg->ireg_local_offset =
3113270d39bfSRahul Lakkireddy 						t5_up_cim_reg_array[i][2];
3114270d39bfSRahul Lakkireddy 			up_cim_reg->ireg_offset_range =
3115270d39bfSRahul Lakkireddy 						t5_up_cim_reg_array[i][3];
3116be6e36d9SRahul Lakkireddy 			instance = t5_up_cim_reg_array[i][4];
3117270d39bfSRahul Lakkireddy 		} else if (is_t6(padap->params.chip)) {
3118270d39bfSRahul Lakkireddy 			up_cim_reg->ireg_addr = t6_up_cim_reg_array[i][0];
3119270d39bfSRahul Lakkireddy 			up_cim_reg->ireg_data = t6_up_cim_reg_array[i][1];
3120270d39bfSRahul Lakkireddy 			up_cim_reg->ireg_local_offset =
3121270d39bfSRahul Lakkireddy 						t6_up_cim_reg_array[i][2];
3122270d39bfSRahul Lakkireddy 			up_cim_reg->ireg_offset_range =
3123270d39bfSRahul Lakkireddy 						t6_up_cim_reg_array[i][3];
3124be6e36d9SRahul Lakkireddy 			instance = t6_up_cim_reg_array[i][4];
3125270d39bfSRahul Lakkireddy 		}
3126270d39bfSRahul Lakkireddy 
3127be6e36d9SRahul Lakkireddy 		switch (instance) {
3128be6e36d9SRahul Lakkireddy 		case NUM_CIM_CTL_TSCH_CHANNEL_INSTANCES:
3129be6e36d9SRahul Lakkireddy 			iter = up_cim_reg->ireg_offset_range;
3130be6e36d9SRahul Lakkireddy 			local_offset = 0x120;
3131be6e36d9SRahul Lakkireddy 			local_range = 1;
3132be6e36d9SRahul Lakkireddy 			break;
3133be6e36d9SRahul Lakkireddy 		case NUM_CIM_CTL_TSCH_CHANNEL_TSCH_CLASS_INSTANCES:
3134be6e36d9SRahul Lakkireddy 			iter = up_cim_reg->ireg_offset_range;
3135be6e36d9SRahul Lakkireddy 			local_offset = 0x10;
3136be6e36d9SRahul Lakkireddy 			local_range = 1;
3137be6e36d9SRahul Lakkireddy 			break;
3138be6e36d9SRahul Lakkireddy 		default:
3139be6e36d9SRahul Lakkireddy 			iter = 1;
3140be6e36d9SRahul Lakkireddy 			local_offset = 0;
3141be6e36d9SRahul Lakkireddy 			local_range = up_cim_reg->ireg_offset_range;
3142be6e36d9SRahul Lakkireddy 			break;
3143be6e36d9SRahul Lakkireddy 		}
3144be6e36d9SRahul Lakkireddy 
3145be6e36d9SRahul Lakkireddy 		for (j = 0; j < iter; j++, buff++) {
3146be6e36d9SRahul Lakkireddy 			rc = t4_cim_read(padap,
3147be6e36d9SRahul Lakkireddy 					 up_cim_reg->ireg_local_offset +
3148be6e36d9SRahul Lakkireddy 					 (j * local_offset), local_range, buff);
3149270d39bfSRahul Lakkireddy 			if (rc) {
315056cf2635SRahul Lakkireddy 				cudbg_put_buff(pdbg_init, &temp_buff);
3151270d39bfSRahul Lakkireddy 				return rc;
3152270d39bfSRahul Lakkireddy 			}
3153be6e36d9SRahul Lakkireddy 		}
3154270d39bfSRahul Lakkireddy 		up_cim++;
3155270d39bfSRahul Lakkireddy 	}
315656cf2635SRahul Lakkireddy 	return cudbg_write_and_release_buff(pdbg_init, &temp_buff, dbg_buff);
3157270d39bfSRahul Lakkireddy }
3158270d39bfSRahul Lakkireddy 
3159db8cd7ceSRahul Lakkireddy int cudbg_collect_pbt_tables(struct cudbg_init *pdbg_init,
3160db8cd7ceSRahul Lakkireddy 			     struct cudbg_buffer *dbg_buff,
3161db8cd7ceSRahul Lakkireddy 			     struct cudbg_error *cudbg_err)
3162db8cd7ceSRahul Lakkireddy {
3163db8cd7ceSRahul Lakkireddy 	struct adapter *padap = pdbg_init->adap;
3164db8cd7ceSRahul Lakkireddy 	struct cudbg_buffer temp_buff = { 0 };
3165db8cd7ceSRahul Lakkireddy 	struct cudbg_pbt_tables *pbt;
3166db8cd7ceSRahul Lakkireddy 	int i, rc;
3167db8cd7ceSRahul Lakkireddy 	u32 addr;
3168db8cd7ceSRahul Lakkireddy 
316956cf2635SRahul Lakkireddy 	rc = cudbg_get_buff(pdbg_init, dbg_buff,
317056cf2635SRahul Lakkireddy 			    sizeof(struct cudbg_pbt_tables),
3171db8cd7ceSRahul Lakkireddy 			    &temp_buff);
3172db8cd7ceSRahul Lakkireddy 	if (rc)
3173db8cd7ceSRahul Lakkireddy 		return rc;
3174db8cd7ceSRahul Lakkireddy 
3175db8cd7ceSRahul Lakkireddy 	pbt = (struct cudbg_pbt_tables *)temp_buff.data;
3176db8cd7ceSRahul Lakkireddy 	/* PBT dynamic entries */
3177db8cd7ceSRahul Lakkireddy 	addr = CUDBG_CHAC_PBT_ADDR;
3178db8cd7ceSRahul Lakkireddy 	for (i = 0; i < CUDBG_PBT_DYNAMIC_ENTRIES; i++) {
3179db8cd7ceSRahul Lakkireddy 		rc = t4_cim_read(padap, addr + (i * 4), 1,
3180db8cd7ceSRahul Lakkireddy 				 &pbt->pbt_dynamic[i]);
3181db8cd7ceSRahul Lakkireddy 		if (rc) {
3182db8cd7ceSRahul Lakkireddy 			cudbg_err->sys_err = rc;
318356cf2635SRahul Lakkireddy 			cudbg_put_buff(pdbg_init, &temp_buff);
3184db8cd7ceSRahul Lakkireddy 			return rc;
3185db8cd7ceSRahul Lakkireddy 		}
3186db8cd7ceSRahul Lakkireddy 	}
3187db8cd7ceSRahul Lakkireddy 
3188db8cd7ceSRahul Lakkireddy 	/* PBT static entries */
3189db8cd7ceSRahul Lakkireddy 	/* static entries start when bit 6 is set */
3190db8cd7ceSRahul Lakkireddy 	addr = CUDBG_CHAC_PBT_ADDR + (1 << 6);
3191db8cd7ceSRahul Lakkireddy 	for (i = 0; i < CUDBG_PBT_STATIC_ENTRIES; i++) {
3192db8cd7ceSRahul Lakkireddy 		rc = t4_cim_read(padap, addr + (i * 4), 1,
3193db8cd7ceSRahul Lakkireddy 				 &pbt->pbt_static[i]);
3194db8cd7ceSRahul Lakkireddy 		if (rc) {
3195db8cd7ceSRahul Lakkireddy 			cudbg_err->sys_err = rc;
319656cf2635SRahul Lakkireddy 			cudbg_put_buff(pdbg_init, &temp_buff);
3197db8cd7ceSRahul Lakkireddy 			return rc;
3198db8cd7ceSRahul Lakkireddy 		}
3199db8cd7ceSRahul Lakkireddy 	}
3200db8cd7ceSRahul Lakkireddy 
3201db8cd7ceSRahul Lakkireddy 	/* LRF entries */
3202db8cd7ceSRahul Lakkireddy 	addr = CUDBG_CHAC_PBT_LRF;
3203db8cd7ceSRahul Lakkireddy 	for (i = 0; i < CUDBG_LRF_ENTRIES; i++) {
3204db8cd7ceSRahul Lakkireddy 		rc = t4_cim_read(padap, addr + (i * 4), 1,
3205db8cd7ceSRahul Lakkireddy 				 &pbt->lrf_table[i]);
3206db8cd7ceSRahul Lakkireddy 		if (rc) {
3207db8cd7ceSRahul Lakkireddy 			cudbg_err->sys_err = rc;
320856cf2635SRahul Lakkireddy 			cudbg_put_buff(pdbg_init, &temp_buff);
3209db8cd7ceSRahul Lakkireddy 			return rc;
3210db8cd7ceSRahul Lakkireddy 		}
3211db8cd7ceSRahul Lakkireddy 	}
3212db8cd7ceSRahul Lakkireddy 
3213db8cd7ceSRahul Lakkireddy 	/* PBT data entries */
3214db8cd7ceSRahul Lakkireddy 	addr = CUDBG_CHAC_PBT_DATA;
3215db8cd7ceSRahul Lakkireddy 	for (i = 0; i < CUDBG_PBT_DATA_ENTRIES; i++) {
3216db8cd7ceSRahul Lakkireddy 		rc = t4_cim_read(padap, addr + (i * 4), 1,
3217db8cd7ceSRahul Lakkireddy 				 &pbt->pbt_data[i]);
3218db8cd7ceSRahul Lakkireddy 		if (rc) {
3219db8cd7ceSRahul Lakkireddy 			cudbg_err->sys_err = rc;
322056cf2635SRahul Lakkireddy 			cudbg_put_buff(pdbg_init, &temp_buff);
3221db8cd7ceSRahul Lakkireddy 			return rc;
3222db8cd7ceSRahul Lakkireddy 		}
3223db8cd7ceSRahul Lakkireddy 	}
322456cf2635SRahul Lakkireddy 	return cudbg_write_and_release_buff(pdbg_init, &temp_buff, dbg_buff);
3225db8cd7ceSRahul Lakkireddy }
3226db8cd7ceSRahul Lakkireddy 
3227844d1b6fSRahul Lakkireddy int cudbg_collect_mbox_log(struct cudbg_init *pdbg_init,
3228844d1b6fSRahul Lakkireddy 			   struct cudbg_buffer *dbg_buff,
3229844d1b6fSRahul Lakkireddy 			   struct cudbg_error *cudbg_err)
3230844d1b6fSRahul Lakkireddy {
3231844d1b6fSRahul Lakkireddy 	struct adapter *padap = pdbg_init->adap;
3232844d1b6fSRahul Lakkireddy 	struct cudbg_mbox_log *mboxlog = NULL;
3233844d1b6fSRahul Lakkireddy 	struct cudbg_buffer temp_buff = { 0 };
3234844d1b6fSRahul Lakkireddy 	struct mbox_cmd_log *log = NULL;
3235844d1b6fSRahul Lakkireddy 	struct mbox_cmd *entry;
3236844d1b6fSRahul Lakkireddy 	unsigned int entry_idx;
3237844d1b6fSRahul Lakkireddy 	u16 mbox_cmds;
3238844d1b6fSRahul Lakkireddy 	int i, k, rc;
3239844d1b6fSRahul Lakkireddy 	u64 flit;
3240844d1b6fSRahul Lakkireddy 	u32 size;
3241844d1b6fSRahul Lakkireddy 
3242844d1b6fSRahul Lakkireddy 	log = padap->mbox_log;
3243844d1b6fSRahul Lakkireddy 	mbox_cmds = padap->mbox_log->size;
3244844d1b6fSRahul Lakkireddy 	size = sizeof(struct cudbg_mbox_log) * mbox_cmds;
324556cf2635SRahul Lakkireddy 	rc = cudbg_get_buff(pdbg_init, dbg_buff, size, &temp_buff);
3246844d1b6fSRahul Lakkireddy 	if (rc)
3247844d1b6fSRahul Lakkireddy 		return rc;
3248844d1b6fSRahul Lakkireddy 
3249844d1b6fSRahul Lakkireddy 	mboxlog = (struct cudbg_mbox_log *)temp_buff.data;
3250844d1b6fSRahul Lakkireddy 	for (k = 0; k < mbox_cmds; k++) {
3251844d1b6fSRahul Lakkireddy 		entry_idx = log->cursor + k;
3252844d1b6fSRahul Lakkireddy 		if (entry_idx >= log->size)
3253844d1b6fSRahul Lakkireddy 			entry_idx -= log->size;
3254844d1b6fSRahul Lakkireddy 
3255844d1b6fSRahul Lakkireddy 		entry = mbox_cmd_log_entry(log, entry_idx);
3256844d1b6fSRahul Lakkireddy 		/* skip over unused entries */
3257844d1b6fSRahul Lakkireddy 		if (entry->timestamp == 0)
3258844d1b6fSRahul Lakkireddy 			continue;
3259844d1b6fSRahul Lakkireddy 
3260844d1b6fSRahul Lakkireddy 		memcpy(&mboxlog->entry, entry, sizeof(struct mbox_cmd));
3261844d1b6fSRahul Lakkireddy 		for (i = 0; i < MBOX_LEN / 8; i++) {
3262844d1b6fSRahul Lakkireddy 			flit = entry->cmd[i];
3263844d1b6fSRahul Lakkireddy 			mboxlog->hi[i] = (u32)(flit >> 32);
3264844d1b6fSRahul Lakkireddy 			mboxlog->lo[i] = (u32)flit;
3265844d1b6fSRahul Lakkireddy 		}
3266844d1b6fSRahul Lakkireddy 		mboxlog++;
3267844d1b6fSRahul Lakkireddy 	}
326856cf2635SRahul Lakkireddy 	return cudbg_write_and_release_buff(pdbg_init, &temp_buff, dbg_buff);
3269844d1b6fSRahul Lakkireddy }
3270270d39bfSRahul Lakkireddy 
3271270d39bfSRahul Lakkireddy int cudbg_collect_hma_indirect(struct cudbg_init *pdbg_init,
3272270d39bfSRahul Lakkireddy 			       struct cudbg_buffer *dbg_buff,
3273270d39bfSRahul Lakkireddy 			       struct cudbg_error *cudbg_err)
3274270d39bfSRahul Lakkireddy {
3275270d39bfSRahul Lakkireddy 	struct adapter *padap = pdbg_init->adap;
3276270d39bfSRahul Lakkireddy 	struct cudbg_buffer temp_buff = { 0 };
3277270d39bfSRahul Lakkireddy 	struct ireg_buf *hma_indr;
3278270d39bfSRahul Lakkireddy 	int i, rc, n;
3279270d39bfSRahul Lakkireddy 	u32 size;
3280270d39bfSRahul Lakkireddy 
3281270d39bfSRahul Lakkireddy 	if (CHELSIO_CHIP_VERSION(padap->params.chip) < CHELSIO_T6)
3282270d39bfSRahul Lakkireddy 		return CUDBG_STATUS_ENTITY_NOT_FOUND;
3283270d39bfSRahul Lakkireddy 
3284270d39bfSRahul Lakkireddy 	n = sizeof(t6_hma_ireg_array) / (IREG_NUM_ELEM * sizeof(u32));
3285270d39bfSRahul Lakkireddy 	size = sizeof(struct ireg_buf) * n;
328656cf2635SRahul Lakkireddy 	rc = cudbg_get_buff(pdbg_init, dbg_buff, size, &temp_buff);
3287270d39bfSRahul Lakkireddy 	if (rc)
3288270d39bfSRahul Lakkireddy 		return rc;
3289270d39bfSRahul Lakkireddy 
3290270d39bfSRahul Lakkireddy 	hma_indr = (struct ireg_buf *)temp_buff.data;
3291270d39bfSRahul Lakkireddy 	for (i = 0; i < n; i++) {
3292270d39bfSRahul Lakkireddy 		struct ireg_field *hma_fli = &hma_indr->tp_pio;
3293270d39bfSRahul Lakkireddy 		u32 *buff = hma_indr->outbuf;
3294270d39bfSRahul Lakkireddy 
3295270d39bfSRahul Lakkireddy 		hma_fli->ireg_addr = t6_hma_ireg_array[i][0];
3296270d39bfSRahul Lakkireddy 		hma_fli->ireg_data = t6_hma_ireg_array[i][1];
3297270d39bfSRahul Lakkireddy 		hma_fli->ireg_local_offset = t6_hma_ireg_array[i][2];
3298270d39bfSRahul Lakkireddy 		hma_fli->ireg_offset_range = t6_hma_ireg_array[i][3];
3299270d39bfSRahul Lakkireddy 		t4_read_indirect(padap, hma_fli->ireg_addr, hma_fli->ireg_data,
3300270d39bfSRahul Lakkireddy 				 buff, hma_fli->ireg_offset_range,
3301270d39bfSRahul Lakkireddy 				 hma_fli->ireg_local_offset);
3302270d39bfSRahul Lakkireddy 		hma_indr++;
3303270d39bfSRahul Lakkireddy 	}
330456cf2635SRahul Lakkireddy 	return cudbg_write_and_release_buff(pdbg_init, &temp_buff, dbg_buff);
3305270d39bfSRahul Lakkireddy }
330668ddc82aSRahul Lakkireddy 
330768ddc82aSRahul Lakkireddy void cudbg_fill_qdesc_num_and_size(const struct adapter *padap,
330868ddc82aSRahul Lakkireddy 				   u32 *num, u32 *size)
330968ddc82aSRahul Lakkireddy {
331068ddc82aSRahul Lakkireddy 	u32 tot_entries = 0, tot_size = 0;
331168ddc82aSRahul Lakkireddy 
331268ddc82aSRahul Lakkireddy 	/* NIC TXQ, RXQ, FLQ, and CTRLQ */
331368ddc82aSRahul Lakkireddy 	tot_entries += MAX_ETH_QSETS * 3;
331468ddc82aSRahul Lakkireddy 	tot_entries += MAX_CTRL_QUEUES;
331568ddc82aSRahul Lakkireddy 
331668ddc82aSRahul Lakkireddy 	tot_size += MAX_ETH_QSETS * MAX_TXQ_ENTRIES * MAX_TXQ_DESC_SIZE;
331768ddc82aSRahul Lakkireddy 	tot_size += MAX_ETH_QSETS * MAX_RSPQ_ENTRIES * MAX_RXQ_DESC_SIZE;
331868ddc82aSRahul Lakkireddy 	tot_size += MAX_ETH_QSETS * MAX_RX_BUFFERS * MAX_FL_DESC_SIZE;
331968ddc82aSRahul Lakkireddy 	tot_size += MAX_CTRL_QUEUES * MAX_CTRL_TXQ_ENTRIES *
332068ddc82aSRahul Lakkireddy 		    MAX_CTRL_TXQ_DESC_SIZE;
332168ddc82aSRahul Lakkireddy 
332268ddc82aSRahul Lakkireddy 	/* FW_EVTQ and INTRQ */
332368ddc82aSRahul Lakkireddy 	tot_entries += INGQ_EXTRAS;
332468ddc82aSRahul Lakkireddy 	tot_size += INGQ_EXTRAS * MAX_RSPQ_ENTRIES * MAX_RXQ_DESC_SIZE;
332568ddc82aSRahul Lakkireddy 
332668ddc82aSRahul Lakkireddy 	/* PTP_TXQ */
332768ddc82aSRahul Lakkireddy 	tot_entries += 1;
332868ddc82aSRahul Lakkireddy 	tot_size += MAX_TXQ_ENTRIES * MAX_TXQ_DESC_SIZE;
332968ddc82aSRahul Lakkireddy 
333068ddc82aSRahul Lakkireddy 	/* ULD TXQ, RXQ, and FLQ */
333168ddc82aSRahul Lakkireddy 	tot_entries += CXGB4_TX_MAX * MAX_OFLD_QSETS;
333268ddc82aSRahul Lakkireddy 	tot_entries += CXGB4_ULD_MAX * MAX_ULD_QSETS * 2;
333368ddc82aSRahul Lakkireddy 
333468ddc82aSRahul Lakkireddy 	tot_size += CXGB4_TX_MAX * MAX_OFLD_QSETS * MAX_TXQ_ENTRIES *
333568ddc82aSRahul Lakkireddy 		    MAX_TXQ_DESC_SIZE;
333668ddc82aSRahul Lakkireddy 	tot_size += CXGB4_ULD_MAX * MAX_ULD_QSETS * MAX_RSPQ_ENTRIES *
333768ddc82aSRahul Lakkireddy 		    MAX_RXQ_DESC_SIZE;
333868ddc82aSRahul Lakkireddy 	tot_size += CXGB4_ULD_MAX * MAX_ULD_QSETS * MAX_RX_BUFFERS *
333968ddc82aSRahul Lakkireddy 		    MAX_FL_DESC_SIZE;
334068ddc82aSRahul Lakkireddy 
334168ddc82aSRahul Lakkireddy 	/* ULD CIQ */
334268ddc82aSRahul Lakkireddy 	tot_entries += CXGB4_ULD_MAX * MAX_ULD_QSETS;
334368ddc82aSRahul Lakkireddy 	tot_size += CXGB4_ULD_MAX * MAX_ULD_QSETS * SGE_MAX_IQ_SIZE *
334468ddc82aSRahul Lakkireddy 		    MAX_RXQ_DESC_SIZE;
334568ddc82aSRahul Lakkireddy 
33462d0cb84dSRahul Lakkireddy 	/* ETHOFLD TXQ, RXQ, and FLQ */
33472d0cb84dSRahul Lakkireddy 	tot_entries += MAX_OFLD_QSETS * 3;
33482d0cb84dSRahul Lakkireddy 	tot_size += MAX_OFLD_QSETS * MAX_TXQ_ENTRIES * MAX_TXQ_DESC_SIZE;
33492d0cb84dSRahul Lakkireddy 
335068ddc82aSRahul Lakkireddy 	tot_size += sizeof(struct cudbg_ver_hdr) +
335168ddc82aSRahul Lakkireddy 		    sizeof(struct cudbg_qdesc_info) +
335268ddc82aSRahul Lakkireddy 		    sizeof(struct cudbg_qdesc_entry) * tot_entries;
335368ddc82aSRahul Lakkireddy 
335468ddc82aSRahul Lakkireddy 	if (num)
335568ddc82aSRahul Lakkireddy 		*num = tot_entries;
335668ddc82aSRahul Lakkireddy 
335768ddc82aSRahul Lakkireddy 	if (size)
335868ddc82aSRahul Lakkireddy 		*size = tot_size;
335968ddc82aSRahul Lakkireddy }
336068ddc82aSRahul Lakkireddy 
336168ddc82aSRahul Lakkireddy int cudbg_collect_qdesc(struct cudbg_init *pdbg_init,
336268ddc82aSRahul Lakkireddy 			struct cudbg_buffer *dbg_buff,
336368ddc82aSRahul Lakkireddy 			struct cudbg_error *cudbg_err)
336468ddc82aSRahul Lakkireddy {
336568ddc82aSRahul Lakkireddy 	u32 num_queues = 0, tot_entries = 0, size = 0;
336668ddc82aSRahul Lakkireddy 	struct adapter *padap = pdbg_init->adap;
336768ddc82aSRahul Lakkireddy 	struct cudbg_buffer temp_buff = { 0 };
336868ddc82aSRahul Lakkireddy 	struct cudbg_qdesc_entry *qdesc_entry;
336968ddc82aSRahul Lakkireddy 	struct cudbg_qdesc_info *qdesc_info;
337068ddc82aSRahul Lakkireddy 	struct cudbg_ver_hdr *ver_hdr;
337168ddc82aSRahul Lakkireddy 	struct sge *s = &padap->sge;
337268ddc82aSRahul Lakkireddy 	u32 i, j, cur_off, tot_len;
337368ddc82aSRahul Lakkireddy 	u8 *data;
337468ddc82aSRahul Lakkireddy 	int rc;
337568ddc82aSRahul Lakkireddy 
337668ddc82aSRahul Lakkireddy 	cudbg_fill_qdesc_num_and_size(padap, &tot_entries, &size);
337768ddc82aSRahul Lakkireddy 	size = min_t(u32, size, CUDBG_DUMP_BUFF_SIZE);
337868ddc82aSRahul Lakkireddy 	tot_len = size;
337968ddc82aSRahul Lakkireddy 	data = kvzalloc(size, GFP_KERNEL);
338068ddc82aSRahul Lakkireddy 	if (!data)
338168ddc82aSRahul Lakkireddy 		return -ENOMEM;
338268ddc82aSRahul Lakkireddy 
338368ddc82aSRahul Lakkireddy 	ver_hdr = (struct cudbg_ver_hdr *)data;
338468ddc82aSRahul Lakkireddy 	ver_hdr->signature = CUDBG_ENTITY_SIGNATURE;
338568ddc82aSRahul Lakkireddy 	ver_hdr->revision = CUDBG_QDESC_REV;
338668ddc82aSRahul Lakkireddy 	ver_hdr->size = sizeof(struct cudbg_qdesc_info);
338768ddc82aSRahul Lakkireddy 	size -= sizeof(*ver_hdr);
338868ddc82aSRahul Lakkireddy 
338968ddc82aSRahul Lakkireddy 	qdesc_info = (struct cudbg_qdesc_info *)(data +
339068ddc82aSRahul Lakkireddy 						 sizeof(*ver_hdr));
339168ddc82aSRahul Lakkireddy 	size -= sizeof(*qdesc_info);
339268ddc82aSRahul Lakkireddy 	qdesc_entry = (struct cudbg_qdesc_entry *)qdesc_info->data;
339368ddc82aSRahul Lakkireddy 
339468ddc82aSRahul Lakkireddy #define QDESC_GET(q, desc, type, label) do { \
339568ddc82aSRahul Lakkireddy 	if (size <= 0) { \
339668ddc82aSRahul Lakkireddy 		goto label; \
339768ddc82aSRahul Lakkireddy 	} \
339868ddc82aSRahul Lakkireddy 	if (desc) { \
339968ddc82aSRahul Lakkireddy 		cudbg_fill_qdesc_##q(q, type, qdesc_entry); \
340068ddc82aSRahul Lakkireddy 		size -= sizeof(*qdesc_entry) + qdesc_entry->data_size; \
340168ddc82aSRahul Lakkireddy 		num_queues++; \
340268ddc82aSRahul Lakkireddy 		qdesc_entry = cudbg_next_qdesc(qdesc_entry); \
340368ddc82aSRahul Lakkireddy 	} \
340468ddc82aSRahul Lakkireddy } while (0)
340568ddc82aSRahul Lakkireddy 
340668ddc82aSRahul Lakkireddy #define QDESC_GET_TXQ(q, type, label) do { \
340768ddc82aSRahul Lakkireddy 	struct sge_txq *txq = (struct sge_txq *)q; \
340868ddc82aSRahul Lakkireddy 	QDESC_GET(txq, txq->desc, type, label); \
340968ddc82aSRahul Lakkireddy } while (0)
341068ddc82aSRahul Lakkireddy 
341168ddc82aSRahul Lakkireddy #define QDESC_GET_RXQ(q, type, label) do { \
341268ddc82aSRahul Lakkireddy 	struct sge_rspq *rxq = (struct sge_rspq *)q; \
341368ddc82aSRahul Lakkireddy 	QDESC_GET(rxq, rxq->desc, type, label); \
341468ddc82aSRahul Lakkireddy } while (0)
341568ddc82aSRahul Lakkireddy 
341668ddc82aSRahul Lakkireddy #define QDESC_GET_FLQ(q, type, label) do { \
341768ddc82aSRahul Lakkireddy 	struct sge_fl *flq = (struct sge_fl *)q; \
341868ddc82aSRahul Lakkireddy 	QDESC_GET(flq, flq->desc, type, label); \
341968ddc82aSRahul Lakkireddy } while (0)
342068ddc82aSRahul Lakkireddy 
342168ddc82aSRahul Lakkireddy 	/* NIC TXQ */
342268ddc82aSRahul Lakkireddy 	for (i = 0; i < s->ethqsets; i++)
342368ddc82aSRahul Lakkireddy 		QDESC_GET_TXQ(&s->ethtxq[i].q, CUDBG_QTYPE_NIC_TXQ, out);
342468ddc82aSRahul Lakkireddy 
342568ddc82aSRahul Lakkireddy 	/* NIC RXQ */
342668ddc82aSRahul Lakkireddy 	for (i = 0; i < s->ethqsets; i++)
342768ddc82aSRahul Lakkireddy 		QDESC_GET_RXQ(&s->ethrxq[i].rspq, CUDBG_QTYPE_NIC_RXQ, out);
342868ddc82aSRahul Lakkireddy 
342968ddc82aSRahul Lakkireddy 	/* NIC FLQ */
343068ddc82aSRahul Lakkireddy 	for (i = 0; i < s->ethqsets; i++)
343168ddc82aSRahul Lakkireddy 		QDESC_GET_FLQ(&s->ethrxq[i].fl, CUDBG_QTYPE_NIC_FLQ, out);
343268ddc82aSRahul Lakkireddy 
343368ddc82aSRahul Lakkireddy 	/* NIC CTRLQ */
343468ddc82aSRahul Lakkireddy 	for (i = 0; i < padap->params.nports; i++)
343568ddc82aSRahul Lakkireddy 		QDESC_GET_TXQ(&s->ctrlq[i].q, CUDBG_QTYPE_CTRLQ, out);
343668ddc82aSRahul Lakkireddy 
343768ddc82aSRahul Lakkireddy 	/* FW_EVTQ */
343868ddc82aSRahul Lakkireddy 	QDESC_GET_RXQ(&s->fw_evtq, CUDBG_QTYPE_FWEVTQ, out);
343968ddc82aSRahul Lakkireddy 
344068ddc82aSRahul Lakkireddy 	/* INTRQ */
344168ddc82aSRahul Lakkireddy 	QDESC_GET_RXQ(&s->intrq, CUDBG_QTYPE_INTRQ, out);
344268ddc82aSRahul Lakkireddy 
344368ddc82aSRahul Lakkireddy 	/* PTP_TXQ */
344468ddc82aSRahul Lakkireddy 	QDESC_GET_TXQ(&s->ptptxq.q, CUDBG_QTYPE_PTP_TXQ, out);
344568ddc82aSRahul Lakkireddy 
344668ddc82aSRahul Lakkireddy 	/* ULD Queues */
344768ddc82aSRahul Lakkireddy 	mutex_lock(&uld_mutex);
344868ddc82aSRahul Lakkireddy 
344968ddc82aSRahul Lakkireddy 	if (s->uld_txq_info) {
345068ddc82aSRahul Lakkireddy 		struct sge_uld_txq_info *utxq;
345168ddc82aSRahul Lakkireddy 
345268ddc82aSRahul Lakkireddy 		/* ULD TXQ */
345368ddc82aSRahul Lakkireddy 		for (j = 0; j < CXGB4_TX_MAX; j++) {
345468ddc82aSRahul Lakkireddy 			if (!s->uld_txq_info[j])
345568ddc82aSRahul Lakkireddy 				continue;
345668ddc82aSRahul Lakkireddy 
345768ddc82aSRahul Lakkireddy 			utxq = s->uld_txq_info[j];
345868ddc82aSRahul Lakkireddy 			for (i = 0; i < utxq->ntxq; i++)
345968ddc82aSRahul Lakkireddy 				QDESC_GET_TXQ(&utxq->uldtxq[i].q,
346068ddc82aSRahul Lakkireddy 					      cudbg_uld_txq_to_qtype(j),
346168ddc82aSRahul Lakkireddy 					      out_unlock);
346268ddc82aSRahul Lakkireddy 		}
346368ddc82aSRahul Lakkireddy 	}
346468ddc82aSRahul Lakkireddy 
346568ddc82aSRahul Lakkireddy 	if (s->uld_rxq_info) {
346668ddc82aSRahul Lakkireddy 		struct sge_uld_rxq_info *urxq;
346768ddc82aSRahul Lakkireddy 		u32 base;
346868ddc82aSRahul Lakkireddy 
346968ddc82aSRahul Lakkireddy 		/* ULD RXQ */
347068ddc82aSRahul Lakkireddy 		for (j = 0; j < CXGB4_ULD_MAX; j++) {
347168ddc82aSRahul Lakkireddy 			if (!s->uld_rxq_info[j])
347268ddc82aSRahul Lakkireddy 				continue;
347368ddc82aSRahul Lakkireddy 
347468ddc82aSRahul Lakkireddy 			urxq = s->uld_rxq_info[j];
347568ddc82aSRahul Lakkireddy 			for (i = 0; i < urxq->nrxq; i++)
347668ddc82aSRahul Lakkireddy 				QDESC_GET_RXQ(&urxq->uldrxq[i].rspq,
347768ddc82aSRahul Lakkireddy 					      cudbg_uld_rxq_to_qtype(j),
347868ddc82aSRahul Lakkireddy 					      out_unlock);
347968ddc82aSRahul Lakkireddy 		}
348068ddc82aSRahul Lakkireddy 
348168ddc82aSRahul Lakkireddy 		/* ULD FLQ */
348268ddc82aSRahul Lakkireddy 		for (j = 0; j < CXGB4_ULD_MAX; j++) {
348368ddc82aSRahul Lakkireddy 			if (!s->uld_rxq_info[j])
348468ddc82aSRahul Lakkireddy 				continue;
348568ddc82aSRahul Lakkireddy 
348668ddc82aSRahul Lakkireddy 			urxq = s->uld_rxq_info[j];
348768ddc82aSRahul Lakkireddy 			for (i = 0; i < urxq->nrxq; i++)
348868ddc82aSRahul Lakkireddy 				QDESC_GET_FLQ(&urxq->uldrxq[i].fl,
348968ddc82aSRahul Lakkireddy 					      cudbg_uld_flq_to_qtype(j),
349068ddc82aSRahul Lakkireddy 					      out_unlock);
349168ddc82aSRahul Lakkireddy 		}
349268ddc82aSRahul Lakkireddy 
349368ddc82aSRahul Lakkireddy 		/* ULD CIQ */
349468ddc82aSRahul Lakkireddy 		for (j = 0; j < CXGB4_ULD_MAX; j++) {
349568ddc82aSRahul Lakkireddy 			if (!s->uld_rxq_info[j])
349668ddc82aSRahul Lakkireddy 				continue;
349768ddc82aSRahul Lakkireddy 
349868ddc82aSRahul Lakkireddy 			urxq = s->uld_rxq_info[j];
349968ddc82aSRahul Lakkireddy 			base = urxq->nrxq;
350068ddc82aSRahul Lakkireddy 			for (i = 0; i < urxq->nciq; i++)
350168ddc82aSRahul Lakkireddy 				QDESC_GET_RXQ(&urxq->uldrxq[base + i].rspq,
350268ddc82aSRahul Lakkireddy 					      cudbg_uld_ciq_to_qtype(j),
350368ddc82aSRahul Lakkireddy 					      out_unlock);
350468ddc82aSRahul Lakkireddy 		}
350568ddc82aSRahul Lakkireddy 	}
350668ddc82aSRahul Lakkireddy 
35072d0cb84dSRahul Lakkireddy 	/* ETHOFLD TXQ */
35082d0cb84dSRahul Lakkireddy 	if (s->eohw_txq)
35092d0cb84dSRahul Lakkireddy 		for (i = 0; i < s->eoqsets; i++)
35102d0cb84dSRahul Lakkireddy 			QDESC_GET_TXQ(&s->eohw_txq[i].q,
35112d0cb84dSRahul Lakkireddy 				      CUDBG_QTYPE_ETHOFLD_TXQ, out);
35122d0cb84dSRahul Lakkireddy 
35132d0cb84dSRahul Lakkireddy 	/* ETHOFLD RXQ and FLQ */
35142d0cb84dSRahul Lakkireddy 	if (s->eohw_rxq) {
35152d0cb84dSRahul Lakkireddy 		for (i = 0; i < s->eoqsets; i++)
35162d0cb84dSRahul Lakkireddy 			QDESC_GET_RXQ(&s->eohw_rxq[i].rspq,
35172d0cb84dSRahul Lakkireddy 				      CUDBG_QTYPE_ETHOFLD_RXQ, out);
35182d0cb84dSRahul Lakkireddy 
35192d0cb84dSRahul Lakkireddy 		for (i = 0; i < s->eoqsets; i++)
35202d0cb84dSRahul Lakkireddy 			QDESC_GET_FLQ(&s->eohw_rxq[i].fl,
35212d0cb84dSRahul Lakkireddy 				      CUDBG_QTYPE_ETHOFLD_FLQ, out);
35222d0cb84dSRahul Lakkireddy 	}
35232d0cb84dSRahul Lakkireddy 
352468ddc82aSRahul Lakkireddy out_unlock:
352568ddc82aSRahul Lakkireddy 	mutex_unlock(&uld_mutex);
352668ddc82aSRahul Lakkireddy 
352768ddc82aSRahul Lakkireddy out:
352868ddc82aSRahul Lakkireddy 	qdesc_info->qdesc_entry_size = sizeof(*qdesc_entry);
352968ddc82aSRahul Lakkireddy 	qdesc_info->num_queues = num_queues;
353068ddc82aSRahul Lakkireddy 	cur_off = 0;
353168ddc82aSRahul Lakkireddy 	while (tot_len) {
353268ddc82aSRahul Lakkireddy 		u32 chunk_size = min_t(u32, tot_len, CUDBG_CHUNK_SIZE);
353368ddc82aSRahul Lakkireddy 
353468ddc82aSRahul Lakkireddy 		rc = cudbg_get_buff(pdbg_init, dbg_buff, chunk_size,
353568ddc82aSRahul Lakkireddy 				    &temp_buff);
353668ddc82aSRahul Lakkireddy 		if (rc) {
353768ddc82aSRahul Lakkireddy 			cudbg_err->sys_warn = CUDBG_STATUS_PARTIAL_DATA;
353868ddc82aSRahul Lakkireddy 			goto out_free;
353968ddc82aSRahul Lakkireddy 		}
354068ddc82aSRahul Lakkireddy 
354168ddc82aSRahul Lakkireddy 		memcpy(temp_buff.data, data + cur_off, chunk_size);
354268ddc82aSRahul Lakkireddy 		tot_len -= chunk_size;
354368ddc82aSRahul Lakkireddy 		cur_off += chunk_size;
354468ddc82aSRahul Lakkireddy 		rc = cudbg_write_and_release_buff(pdbg_init, &temp_buff,
354568ddc82aSRahul Lakkireddy 						  dbg_buff);
354668ddc82aSRahul Lakkireddy 		if (rc) {
354768ddc82aSRahul Lakkireddy 			cudbg_put_buff(pdbg_init, &temp_buff);
354868ddc82aSRahul Lakkireddy 			cudbg_err->sys_warn = CUDBG_STATUS_PARTIAL_DATA;
354968ddc82aSRahul Lakkireddy 			goto out_free;
355068ddc82aSRahul Lakkireddy 		}
355168ddc82aSRahul Lakkireddy 	}
355268ddc82aSRahul Lakkireddy 
355368ddc82aSRahul Lakkireddy out_free:
355468ddc82aSRahul Lakkireddy 	if (data)
355568ddc82aSRahul Lakkireddy 		kvfree(data);
355668ddc82aSRahul Lakkireddy 
355768ddc82aSRahul Lakkireddy #undef QDESC_GET_FLQ
355868ddc82aSRahul Lakkireddy #undef QDESC_GET_RXQ
355968ddc82aSRahul Lakkireddy #undef QDESC_GET_TXQ
356068ddc82aSRahul Lakkireddy #undef QDESC_GET
356168ddc82aSRahul Lakkireddy 
356268ddc82aSRahul Lakkireddy 	return rc;
356368ddc82aSRahul Lakkireddy }
356417b332f4SVishal Kulkarni 
356517b332f4SVishal Kulkarni int cudbg_collect_flash(struct cudbg_init *pdbg_init,
356617b332f4SVishal Kulkarni 			struct cudbg_buffer *dbg_buff,
356717b332f4SVishal Kulkarni 			struct cudbg_error *cudbg_err)
356817b332f4SVishal Kulkarni {
356917b332f4SVishal Kulkarni 	struct adapter *padap = pdbg_init->adap;
357017b332f4SVishal Kulkarni 	u32 count = padap->params.sf_size, n;
357117b332f4SVishal Kulkarni 	struct cudbg_buffer temp_buff = {0};
357217b332f4SVishal Kulkarni 	u32 addr, i;
357317b332f4SVishal Kulkarni 	int rc;
357417b332f4SVishal Kulkarni 
357517b332f4SVishal Kulkarni 	addr = FLASH_EXP_ROM_START;
357617b332f4SVishal Kulkarni 
357717b332f4SVishal Kulkarni 	for (i = 0; i < count; i += SF_PAGE_SIZE) {
357817b332f4SVishal Kulkarni 		n = min_t(u32, count - i, SF_PAGE_SIZE);
357917b332f4SVishal Kulkarni 
358017b332f4SVishal Kulkarni 		rc = cudbg_get_buff(pdbg_init, dbg_buff, n, &temp_buff);
358117b332f4SVishal Kulkarni 		if (rc) {
358217b332f4SVishal Kulkarni 			cudbg_err->sys_warn = CUDBG_STATUS_PARTIAL_DATA;
358317b332f4SVishal Kulkarni 			goto out;
358417b332f4SVishal Kulkarni 		}
358517b332f4SVishal Kulkarni 		rc = t4_read_flash(padap, addr, n, (u32 *)temp_buff.data, 0);
358617b332f4SVishal Kulkarni 		if (rc)
358717b332f4SVishal Kulkarni 			goto out;
358817b332f4SVishal Kulkarni 
358917b332f4SVishal Kulkarni 		addr += (n * 4);
359017b332f4SVishal Kulkarni 		rc = cudbg_write_and_release_buff(pdbg_init, &temp_buff,
359117b332f4SVishal Kulkarni 						  dbg_buff);
359217b332f4SVishal Kulkarni 		if (rc) {
359317b332f4SVishal Kulkarni 			cudbg_err->sys_warn = CUDBG_STATUS_PARTIAL_DATA;
359417b332f4SVishal Kulkarni 			goto out;
359517b332f4SVishal Kulkarni 		}
359617b332f4SVishal Kulkarni 	}
359717b332f4SVishal Kulkarni 
359817b332f4SVishal Kulkarni out:
359917b332f4SVishal Kulkarni 	return rc;
360017b332f4SVishal Kulkarni }
3601