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