1a7975a2fSRahul Lakkireddy /*
2a7975a2fSRahul Lakkireddy  *  Copyright (C) 2017 Chelsio Communications.  All rights reserved.
3a7975a2fSRahul Lakkireddy  *
4a7975a2fSRahul Lakkireddy  *  This program is free software; you can redistribute it and/or modify it
5a7975a2fSRahul Lakkireddy  *  under the terms and conditions of the GNU General Public License,
6a7975a2fSRahul Lakkireddy  *  version 2, as published by the Free Software Foundation.
7a7975a2fSRahul Lakkireddy  *
8a7975a2fSRahul Lakkireddy  *  This program is distributed in the hope it will be useful, but WITHOUT
9a7975a2fSRahul Lakkireddy  *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10a7975a2fSRahul Lakkireddy  *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
11a7975a2fSRahul Lakkireddy  *  more details.
12a7975a2fSRahul Lakkireddy  *
13a7975a2fSRahul Lakkireddy  *  The full GNU General Public License is included in this distribution in
14a7975a2fSRahul Lakkireddy  *  the file called "COPYING".
15a7975a2fSRahul Lakkireddy  *
16a7975a2fSRahul Lakkireddy  */
17a7975a2fSRahul Lakkireddy 
18123e25c4SRahul Lakkireddy #include <linux/sort.h>
19123e25c4SRahul Lakkireddy 
20b33af022SRahul Lakkireddy #include "t4_regs.h"
21a7975a2fSRahul Lakkireddy #include "cxgb4.h"
22a7975a2fSRahul Lakkireddy #include "cudbg_if.h"
23a7975a2fSRahul Lakkireddy #include "cudbg_lib_common.h"
24b33af022SRahul Lakkireddy #include "cudbg_entity.h"
25123e25c4SRahul Lakkireddy #include "cudbg_lib.h"
26a7975a2fSRahul Lakkireddy 
27a7975a2fSRahul Lakkireddy static void cudbg_write_and_release_buff(struct cudbg_buffer *pin_buff,
28a7975a2fSRahul Lakkireddy 					 struct cudbg_buffer *dbg_buff)
29a7975a2fSRahul Lakkireddy {
30a7975a2fSRahul Lakkireddy 	cudbg_update_buff(pin_buff, dbg_buff);
31a7975a2fSRahul Lakkireddy 	cudbg_put_buff(pin_buff, dbg_buff);
32a7975a2fSRahul Lakkireddy }
33a7975a2fSRahul Lakkireddy 
34b33af022SRahul Lakkireddy static int is_fw_attached(struct cudbg_init *pdbg_init)
35b33af022SRahul Lakkireddy {
36b33af022SRahul Lakkireddy 	struct adapter *padap = pdbg_init->adap;
37b33af022SRahul Lakkireddy 
38b33af022SRahul Lakkireddy 	if (!(padap->flags & FW_OK) || padap->use_bd)
39b33af022SRahul Lakkireddy 		return 0;
40b33af022SRahul Lakkireddy 
41b33af022SRahul Lakkireddy 	return 1;
42b33af022SRahul Lakkireddy }
43b33af022SRahul Lakkireddy 
44a7975a2fSRahul Lakkireddy /* This function will add additional padding bytes into debug_buffer to make it
45a7975a2fSRahul Lakkireddy  * 4 byte aligned.
46a7975a2fSRahul Lakkireddy  */
47a7975a2fSRahul Lakkireddy void cudbg_align_debug_buffer(struct cudbg_buffer *dbg_buff,
48a7975a2fSRahul Lakkireddy 			      struct cudbg_entity_hdr *entity_hdr)
49a7975a2fSRahul Lakkireddy {
50a7975a2fSRahul Lakkireddy 	u8 zero_buf[4] = {0};
51a7975a2fSRahul Lakkireddy 	u8 padding, remain;
52a7975a2fSRahul Lakkireddy 
53a7975a2fSRahul Lakkireddy 	remain = (dbg_buff->offset - entity_hdr->start_offset) % 4;
54a7975a2fSRahul Lakkireddy 	padding = 4 - remain;
55a7975a2fSRahul Lakkireddy 	if (remain) {
56a7975a2fSRahul Lakkireddy 		memcpy(((u8 *)dbg_buff->data) + dbg_buff->offset, &zero_buf,
57a7975a2fSRahul Lakkireddy 		       padding);
58a7975a2fSRahul Lakkireddy 		dbg_buff->offset += padding;
59a7975a2fSRahul Lakkireddy 		entity_hdr->num_pad = padding;
60a7975a2fSRahul Lakkireddy 	}
61a7975a2fSRahul Lakkireddy 	entity_hdr->size = dbg_buff->offset - entity_hdr->start_offset;
62a7975a2fSRahul Lakkireddy }
63a7975a2fSRahul Lakkireddy 
64a7975a2fSRahul Lakkireddy struct cudbg_entity_hdr *cudbg_get_entity_hdr(void *outbuf, int i)
65a7975a2fSRahul Lakkireddy {
66a7975a2fSRahul Lakkireddy 	struct cudbg_hdr *cudbg_hdr = (struct cudbg_hdr *)outbuf;
67a7975a2fSRahul Lakkireddy 
68a7975a2fSRahul Lakkireddy 	return (struct cudbg_entity_hdr *)
69a7975a2fSRahul Lakkireddy 	       ((char *)outbuf + cudbg_hdr->hdr_len +
70a7975a2fSRahul Lakkireddy 		(sizeof(struct cudbg_entity_hdr) * (i - 1)));
71a7975a2fSRahul Lakkireddy }
72a7975a2fSRahul Lakkireddy 
73940c9c45SRahul Lakkireddy static int cudbg_read_vpd_reg(struct adapter *padap, u32 addr, u32 len,
74940c9c45SRahul Lakkireddy 			      void *dest)
75940c9c45SRahul Lakkireddy {
76940c9c45SRahul Lakkireddy 	int vaddr, rc;
77940c9c45SRahul Lakkireddy 
78940c9c45SRahul Lakkireddy 	vaddr = t4_eeprom_ptov(addr, padap->pf, EEPROMPFSIZE);
79940c9c45SRahul Lakkireddy 	if (vaddr < 0)
80940c9c45SRahul Lakkireddy 		return vaddr;
81940c9c45SRahul Lakkireddy 
82940c9c45SRahul Lakkireddy 	rc = pci_read_vpd(padap->pdev, vaddr, len, dest);
83940c9c45SRahul Lakkireddy 	if (rc < 0)
84940c9c45SRahul Lakkireddy 		return rc;
85940c9c45SRahul Lakkireddy 
86940c9c45SRahul Lakkireddy 	return 0;
87940c9c45SRahul Lakkireddy }
88940c9c45SRahul Lakkireddy 
89123e25c4SRahul Lakkireddy static int cudbg_mem_desc_cmp(const void *a, const void *b)
90123e25c4SRahul Lakkireddy {
91123e25c4SRahul Lakkireddy 	return ((const struct cudbg_mem_desc *)a)->base -
92123e25c4SRahul Lakkireddy 	       ((const struct cudbg_mem_desc *)b)->base;
93123e25c4SRahul Lakkireddy }
94123e25c4SRahul Lakkireddy 
95123e25c4SRahul Lakkireddy int cudbg_fill_meminfo(struct adapter *padap,
96123e25c4SRahul Lakkireddy 		       struct cudbg_meminfo *meminfo_buff)
97123e25c4SRahul Lakkireddy {
98123e25c4SRahul Lakkireddy 	struct cudbg_mem_desc *md;
99123e25c4SRahul Lakkireddy 	u32 lo, hi, used, alloc;
100123e25c4SRahul Lakkireddy 	int n, i;
101123e25c4SRahul Lakkireddy 
102123e25c4SRahul Lakkireddy 	memset(meminfo_buff->avail, 0,
103123e25c4SRahul Lakkireddy 	       ARRAY_SIZE(meminfo_buff->avail) *
104123e25c4SRahul Lakkireddy 	       sizeof(struct cudbg_mem_desc));
105123e25c4SRahul Lakkireddy 	memset(meminfo_buff->mem, 0,
106123e25c4SRahul Lakkireddy 	       (ARRAY_SIZE(cudbg_region) + 3) * sizeof(struct cudbg_mem_desc));
107123e25c4SRahul Lakkireddy 	md  = meminfo_buff->mem;
108123e25c4SRahul Lakkireddy 
109123e25c4SRahul Lakkireddy 	for (i = 0; i < ARRAY_SIZE(meminfo_buff->mem); i++) {
110123e25c4SRahul Lakkireddy 		meminfo_buff->mem[i].limit = 0;
111123e25c4SRahul Lakkireddy 		meminfo_buff->mem[i].idx = i;
112123e25c4SRahul Lakkireddy 	}
113123e25c4SRahul Lakkireddy 
114123e25c4SRahul Lakkireddy 	/* Find and sort the populated memory ranges */
115123e25c4SRahul Lakkireddy 	i = 0;
116123e25c4SRahul Lakkireddy 	lo = t4_read_reg(padap, MA_TARGET_MEM_ENABLE_A);
117123e25c4SRahul Lakkireddy 	if (lo & EDRAM0_ENABLE_F) {
118123e25c4SRahul Lakkireddy 		hi = t4_read_reg(padap, MA_EDRAM0_BAR_A);
119123e25c4SRahul Lakkireddy 		meminfo_buff->avail[i].base =
120123e25c4SRahul Lakkireddy 			cudbg_mbytes_to_bytes(EDRAM0_BASE_G(hi));
121123e25c4SRahul Lakkireddy 		meminfo_buff->avail[i].limit =
122123e25c4SRahul Lakkireddy 			meminfo_buff->avail[i].base +
123123e25c4SRahul Lakkireddy 			cudbg_mbytes_to_bytes(EDRAM0_SIZE_G(hi));
124123e25c4SRahul Lakkireddy 		meminfo_buff->avail[i].idx = 0;
125123e25c4SRahul Lakkireddy 		i++;
126123e25c4SRahul Lakkireddy 	}
127123e25c4SRahul Lakkireddy 
128123e25c4SRahul Lakkireddy 	if (lo & EDRAM1_ENABLE_F) {
129123e25c4SRahul Lakkireddy 		hi =  t4_read_reg(padap, MA_EDRAM1_BAR_A);
130123e25c4SRahul Lakkireddy 		meminfo_buff->avail[i].base =
131123e25c4SRahul Lakkireddy 			cudbg_mbytes_to_bytes(EDRAM1_BASE_G(hi));
132123e25c4SRahul Lakkireddy 		meminfo_buff->avail[i].limit =
133123e25c4SRahul Lakkireddy 			meminfo_buff->avail[i].base +
134123e25c4SRahul Lakkireddy 			cudbg_mbytes_to_bytes(EDRAM1_SIZE_G(hi));
135123e25c4SRahul Lakkireddy 		meminfo_buff->avail[i].idx = 1;
136123e25c4SRahul Lakkireddy 		i++;
137123e25c4SRahul Lakkireddy 	}
138123e25c4SRahul Lakkireddy 
139123e25c4SRahul Lakkireddy 	if (is_t5(padap->params.chip)) {
140123e25c4SRahul Lakkireddy 		if (lo & EXT_MEM0_ENABLE_F) {
141123e25c4SRahul Lakkireddy 			hi = t4_read_reg(padap, MA_EXT_MEMORY0_BAR_A);
142123e25c4SRahul Lakkireddy 			meminfo_buff->avail[i].base =
143123e25c4SRahul Lakkireddy 				cudbg_mbytes_to_bytes(EXT_MEM_BASE_G(hi));
144123e25c4SRahul Lakkireddy 			meminfo_buff->avail[i].limit =
145123e25c4SRahul Lakkireddy 				meminfo_buff->avail[i].base +
146123e25c4SRahul Lakkireddy 				cudbg_mbytes_to_bytes(EXT_MEM_SIZE_G(hi));
147123e25c4SRahul Lakkireddy 			meminfo_buff->avail[i].idx = 3;
148123e25c4SRahul Lakkireddy 			i++;
149123e25c4SRahul Lakkireddy 		}
150123e25c4SRahul Lakkireddy 
151123e25c4SRahul Lakkireddy 		if (lo & EXT_MEM1_ENABLE_F) {
152123e25c4SRahul Lakkireddy 			hi = t4_read_reg(padap, MA_EXT_MEMORY1_BAR_A);
153123e25c4SRahul Lakkireddy 			meminfo_buff->avail[i].base =
154123e25c4SRahul Lakkireddy 				cudbg_mbytes_to_bytes(EXT_MEM1_BASE_G(hi));
155123e25c4SRahul Lakkireddy 			meminfo_buff->avail[i].limit =
156123e25c4SRahul Lakkireddy 				meminfo_buff->avail[i].base +
157123e25c4SRahul Lakkireddy 				cudbg_mbytes_to_bytes(EXT_MEM1_SIZE_G(hi));
158123e25c4SRahul Lakkireddy 			meminfo_buff->avail[i].idx = 4;
159123e25c4SRahul Lakkireddy 			i++;
160123e25c4SRahul Lakkireddy 		}
161123e25c4SRahul Lakkireddy 	} else {
162123e25c4SRahul Lakkireddy 		if (lo & EXT_MEM_ENABLE_F) {
163123e25c4SRahul Lakkireddy 			hi = t4_read_reg(padap, MA_EXT_MEMORY_BAR_A);
164123e25c4SRahul Lakkireddy 			meminfo_buff->avail[i].base =
165123e25c4SRahul Lakkireddy 				cudbg_mbytes_to_bytes(EXT_MEM_BASE_G(hi));
166123e25c4SRahul Lakkireddy 			meminfo_buff->avail[i].limit =
167123e25c4SRahul Lakkireddy 				meminfo_buff->avail[i].base +
168123e25c4SRahul Lakkireddy 				cudbg_mbytes_to_bytes(EXT_MEM_SIZE_G(hi));
169123e25c4SRahul Lakkireddy 			meminfo_buff->avail[i].idx = 2;
170123e25c4SRahul Lakkireddy 			i++;
171123e25c4SRahul Lakkireddy 		}
1724db0401fSRahul Lakkireddy 
1734db0401fSRahul Lakkireddy 		if (lo & HMA_MUX_F) {
1744db0401fSRahul Lakkireddy 			hi = t4_read_reg(padap, MA_EXT_MEMORY1_BAR_A);
1754db0401fSRahul Lakkireddy 			meminfo_buff->avail[i].base =
1764db0401fSRahul Lakkireddy 				cudbg_mbytes_to_bytes(EXT_MEM1_BASE_G(hi));
1774db0401fSRahul Lakkireddy 			meminfo_buff->avail[i].limit =
1784db0401fSRahul Lakkireddy 				meminfo_buff->avail[i].base +
1794db0401fSRahul Lakkireddy 				cudbg_mbytes_to_bytes(EXT_MEM1_SIZE_G(hi));
1804db0401fSRahul Lakkireddy 			meminfo_buff->avail[i].idx = 5;
1814db0401fSRahul Lakkireddy 			i++;
1824db0401fSRahul Lakkireddy 		}
183123e25c4SRahul Lakkireddy 	}
184123e25c4SRahul Lakkireddy 
185123e25c4SRahul Lakkireddy 	if (!i) /* no memory available */
186123e25c4SRahul Lakkireddy 		return CUDBG_STATUS_ENTITY_NOT_FOUND;
187123e25c4SRahul Lakkireddy 
188123e25c4SRahul Lakkireddy 	meminfo_buff->avail_c = i;
189123e25c4SRahul Lakkireddy 	sort(meminfo_buff->avail, i, sizeof(struct cudbg_mem_desc),
190123e25c4SRahul Lakkireddy 	     cudbg_mem_desc_cmp, NULL);
191123e25c4SRahul Lakkireddy 	(md++)->base = t4_read_reg(padap, SGE_DBQ_CTXT_BADDR_A);
192123e25c4SRahul Lakkireddy 	(md++)->base = t4_read_reg(padap, SGE_IMSG_CTXT_BADDR_A);
193123e25c4SRahul Lakkireddy 	(md++)->base = t4_read_reg(padap, SGE_FLM_CACHE_BADDR_A);
194123e25c4SRahul Lakkireddy 	(md++)->base = t4_read_reg(padap, TP_CMM_TCB_BASE_A);
195123e25c4SRahul Lakkireddy 	(md++)->base = t4_read_reg(padap, TP_CMM_MM_BASE_A);
196123e25c4SRahul Lakkireddy 	(md++)->base = t4_read_reg(padap, TP_CMM_TIMER_BASE_A);
197123e25c4SRahul Lakkireddy 	(md++)->base = t4_read_reg(padap, TP_CMM_MM_RX_FLST_BASE_A);
198123e25c4SRahul Lakkireddy 	(md++)->base = t4_read_reg(padap, TP_CMM_MM_TX_FLST_BASE_A);
199123e25c4SRahul Lakkireddy 	(md++)->base = t4_read_reg(padap, TP_CMM_MM_PS_FLST_BASE_A);
200123e25c4SRahul Lakkireddy 
201123e25c4SRahul Lakkireddy 	/* the next few have explicit upper bounds */
202123e25c4SRahul Lakkireddy 	md->base = t4_read_reg(padap, TP_PMM_TX_BASE_A);
203123e25c4SRahul Lakkireddy 	md->limit = md->base - 1 +
204123e25c4SRahul Lakkireddy 		    t4_read_reg(padap, TP_PMM_TX_PAGE_SIZE_A) *
205123e25c4SRahul Lakkireddy 		    PMTXMAXPAGE_G(t4_read_reg(padap, TP_PMM_TX_MAX_PAGE_A));
206123e25c4SRahul Lakkireddy 	md++;
207123e25c4SRahul Lakkireddy 
208123e25c4SRahul Lakkireddy 	md->base = t4_read_reg(padap, TP_PMM_RX_BASE_A);
209123e25c4SRahul Lakkireddy 	md->limit = md->base - 1 +
210123e25c4SRahul Lakkireddy 		    t4_read_reg(padap, TP_PMM_RX_PAGE_SIZE_A) *
211123e25c4SRahul Lakkireddy 		    PMRXMAXPAGE_G(t4_read_reg(padap, TP_PMM_RX_MAX_PAGE_A));
212123e25c4SRahul Lakkireddy 	md++;
213123e25c4SRahul Lakkireddy 
214123e25c4SRahul Lakkireddy 	if (t4_read_reg(padap, LE_DB_CONFIG_A) & HASHEN_F) {
215123e25c4SRahul Lakkireddy 		if (CHELSIO_CHIP_VERSION(padap->params.chip) <= CHELSIO_T5) {
216123e25c4SRahul Lakkireddy 			hi = t4_read_reg(padap, LE_DB_TID_HASHBASE_A) / 4;
217123e25c4SRahul Lakkireddy 			md->base = t4_read_reg(padap, LE_DB_HASH_TID_BASE_A);
218123e25c4SRahul Lakkireddy 		} else {
219123e25c4SRahul Lakkireddy 			hi = t4_read_reg(padap, LE_DB_HASH_TID_BASE_A);
220123e25c4SRahul Lakkireddy 			md->base = t4_read_reg(padap,
221123e25c4SRahul Lakkireddy 					       LE_DB_HASH_TBL_BASE_ADDR_A);
222123e25c4SRahul Lakkireddy 		}
223123e25c4SRahul Lakkireddy 		md->limit = 0;
224123e25c4SRahul Lakkireddy 	} else {
225123e25c4SRahul Lakkireddy 		md->base = 0;
226123e25c4SRahul Lakkireddy 		md->idx = ARRAY_SIZE(cudbg_region);  /* hide it */
227123e25c4SRahul Lakkireddy 	}
228123e25c4SRahul Lakkireddy 	md++;
229123e25c4SRahul Lakkireddy 
230123e25c4SRahul Lakkireddy #define ulp_region(reg) do { \
231123e25c4SRahul Lakkireddy 	md->base = t4_read_reg(padap, ULP_ ## reg ## _LLIMIT_A);\
232123e25c4SRahul Lakkireddy 	(md++)->limit = t4_read_reg(padap, ULP_ ## reg ## _ULIMIT_A);\
233123e25c4SRahul Lakkireddy } while (0)
234123e25c4SRahul Lakkireddy 
235123e25c4SRahul Lakkireddy 	ulp_region(RX_ISCSI);
236123e25c4SRahul Lakkireddy 	ulp_region(RX_TDDP);
237123e25c4SRahul Lakkireddy 	ulp_region(TX_TPT);
238123e25c4SRahul Lakkireddy 	ulp_region(RX_STAG);
239123e25c4SRahul Lakkireddy 	ulp_region(RX_RQ);
240123e25c4SRahul Lakkireddy 	ulp_region(RX_RQUDP);
241123e25c4SRahul Lakkireddy 	ulp_region(RX_PBL);
242123e25c4SRahul Lakkireddy 	ulp_region(TX_PBL);
243123e25c4SRahul Lakkireddy #undef ulp_region
244123e25c4SRahul Lakkireddy 	md->base = 0;
245123e25c4SRahul Lakkireddy 	md->idx = ARRAY_SIZE(cudbg_region);
246123e25c4SRahul Lakkireddy 	if (!is_t4(padap->params.chip)) {
247123e25c4SRahul Lakkireddy 		u32 fifo_size = t4_read_reg(padap, SGE_DBVFIFO_SIZE_A);
248123e25c4SRahul Lakkireddy 		u32 sge_ctrl = t4_read_reg(padap, SGE_CONTROL2_A);
249123e25c4SRahul Lakkireddy 		u32 size = 0;
250123e25c4SRahul Lakkireddy 
251123e25c4SRahul Lakkireddy 		if (is_t5(padap->params.chip)) {
252123e25c4SRahul Lakkireddy 			if (sge_ctrl & VFIFO_ENABLE_F)
253123e25c4SRahul Lakkireddy 				size = DBVFIFO_SIZE_G(fifo_size);
254123e25c4SRahul Lakkireddy 		} else {
255123e25c4SRahul Lakkireddy 			size = T6_DBVFIFO_SIZE_G(fifo_size);
256123e25c4SRahul Lakkireddy 		}
257123e25c4SRahul Lakkireddy 
258123e25c4SRahul Lakkireddy 		if (size) {
259123e25c4SRahul Lakkireddy 			md->base = BASEADDR_G(t4_read_reg(padap,
260123e25c4SRahul Lakkireddy 							  SGE_DBVFIFO_BADDR_A));
261123e25c4SRahul Lakkireddy 			md->limit = md->base + (size << 2) - 1;
262123e25c4SRahul Lakkireddy 		}
263123e25c4SRahul Lakkireddy 	}
264123e25c4SRahul Lakkireddy 
265123e25c4SRahul Lakkireddy 	md++;
266123e25c4SRahul Lakkireddy 
267123e25c4SRahul Lakkireddy 	md->base = t4_read_reg(padap, ULP_RX_CTX_BASE_A);
268123e25c4SRahul Lakkireddy 	md->limit = 0;
269123e25c4SRahul Lakkireddy 	md++;
270123e25c4SRahul Lakkireddy 	md->base = t4_read_reg(padap, ULP_TX_ERR_TABLE_BASE_A);
271123e25c4SRahul Lakkireddy 	md->limit = 0;
272123e25c4SRahul Lakkireddy 	md++;
273123e25c4SRahul Lakkireddy 
274123e25c4SRahul Lakkireddy 	md->base = padap->vres.ocq.start;
275123e25c4SRahul Lakkireddy 	if (padap->vres.ocq.size)
276123e25c4SRahul Lakkireddy 		md->limit = md->base + padap->vres.ocq.size - 1;
277123e25c4SRahul Lakkireddy 	else
278123e25c4SRahul Lakkireddy 		md->idx = ARRAY_SIZE(cudbg_region);  /* hide it */
279123e25c4SRahul Lakkireddy 	md++;
280123e25c4SRahul Lakkireddy 
281123e25c4SRahul Lakkireddy 	/* add any address-space holes, there can be up to 3 */
282123e25c4SRahul Lakkireddy 	for (n = 0; n < i - 1; n++)
283123e25c4SRahul Lakkireddy 		if (meminfo_buff->avail[n].limit <
284123e25c4SRahul Lakkireddy 		    meminfo_buff->avail[n + 1].base)
285123e25c4SRahul Lakkireddy 			(md++)->base = meminfo_buff->avail[n].limit;
286123e25c4SRahul Lakkireddy 
287123e25c4SRahul Lakkireddy 	if (meminfo_buff->avail[n].limit)
288123e25c4SRahul Lakkireddy 		(md++)->base = meminfo_buff->avail[n].limit;
289123e25c4SRahul Lakkireddy 
290123e25c4SRahul Lakkireddy 	n = md - meminfo_buff->mem;
291123e25c4SRahul Lakkireddy 	meminfo_buff->mem_c = n;
292123e25c4SRahul Lakkireddy 
293123e25c4SRahul Lakkireddy 	sort(meminfo_buff->mem, n, sizeof(struct cudbg_mem_desc),
294123e25c4SRahul Lakkireddy 	     cudbg_mem_desc_cmp, NULL);
295123e25c4SRahul Lakkireddy 
296123e25c4SRahul Lakkireddy 	lo = t4_read_reg(padap, CIM_SDRAM_BASE_ADDR_A);
297123e25c4SRahul Lakkireddy 	hi = t4_read_reg(padap, CIM_SDRAM_ADDR_SIZE_A) + lo - 1;
298123e25c4SRahul Lakkireddy 	meminfo_buff->up_ram_lo = lo;
299123e25c4SRahul Lakkireddy 	meminfo_buff->up_ram_hi = hi;
300123e25c4SRahul Lakkireddy 
301123e25c4SRahul Lakkireddy 	lo = t4_read_reg(padap, CIM_EXTMEM2_BASE_ADDR_A);
302123e25c4SRahul Lakkireddy 	hi = t4_read_reg(padap, CIM_EXTMEM2_ADDR_SIZE_A) + lo - 1;
303123e25c4SRahul Lakkireddy 	meminfo_buff->up_extmem2_lo = lo;
304123e25c4SRahul Lakkireddy 	meminfo_buff->up_extmem2_hi = hi;
305123e25c4SRahul Lakkireddy 
306123e25c4SRahul Lakkireddy 	lo = t4_read_reg(padap, TP_PMM_RX_MAX_PAGE_A);
307123e25c4SRahul Lakkireddy 	meminfo_buff->rx_pages_data[0] =  PMRXMAXPAGE_G(lo);
308123e25c4SRahul Lakkireddy 	meminfo_buff->rx_pages_data[1] =
309123e25c4SRahul Lakkireddy 		t4_read_reg(padap, TP_PMM_RX_PAGE_SIZE_A) >> 10;
310123e25c4SRahul Lakkireddy 	meminfo_buff->rx_pages_data[2] = (lo & PMRXNUMCHN_F) ? 2 : 1;
311123e25c4SRahul Lakkireddy 
312123e25c4SRahul Lakkireddy 	lo = t4_read_reg(padap, TP_PMM_TX_MAX_PAGE_A);
313123e25c4SRahul Lakkireddy 	hi = t4_read_reg(padap, TP_PMM_TX_PAGE_SIZE_A);
314123e25c4SRahul Lakkireddy 	meminfo_buff->tx_pages_data[0] = PMTXMAXPAGE_G(lo);
315123e25c4SRahul Lakkireddy 	meminfo_buff->tx_pages_data[1] =
316123e25c4SRahul Lakkireddy 		hi >= (1 << 20) ? (hi >> 20) : (hi >> 10);
317123e25c4SRahul Lakkireddy 	meminfo_buff->tx_pages_data[2] =
318123e25c4SRahul Lakkireddy 		hi >= (1 << 20) ? 'M' : 'K';
319123e25c4SRahul Lakkireddy 	meminfo_buff->tx_pages_data[3] = 1 << PMTXNUMCHN_G(lo);
320123e25c4SRahul Lakkireddy 
321123e25c4SRahul Lakkireddy 	meminfo_buff->p_structs = t4_read_reg(padap, TP_CMM_MM_MAX_PSTRUCT_A);
322123e25c4SRahul Lakkireddy 
323123e25c4SRahul Lakkireddy 	for (i = 0; i < 4; i++) {
324123e25c4SRahul Lakkireddy 		if (CHELSIO_CHIP_VERSION(padap->params.chip) > CHELSIO_T5)
325123e25c4SRahul Lakkireddy 			lo = t4_read_reg(padap,
326123e25c4SRahul Lakkireddy 					 MPS_RX_MAC_BG_PG_CNT0_A + i * 4);
327123e25c4SRahul Lakkireddy 		else
328123e25c4SRahul Lakkireddy 			lo = t4_read_reg(padap, MPS_RX_PG_RSV0_A + i * 4);
329123e25c4SRahul Lakkireddy 		if (is_t5(padap->params.chip)) {
330123e25c4SRahul Lakkireddy 			used = T5_USED_G(lo);
331123e25c4SRahul Lakkireddy 			alloc = T5_ALLOC_G(lo);
332123e25c4SRahul Lakkireddy 		} else {
333123e25c4SRahul Lakkireddy 			used = USED_G(lo);
334123e25c4SRahul Lakkireddy 			alloc = ALLOC_G(lo);
335123e25c4SRahul Lakkireddy 		}
336123e25c4SRahul Lakkireddy 		meminfo_buff->port_used[i] = used;
337123e25c4SRahul Lakkireddy 		meminfo_buff->port_alloc[i] = alloc;
338123e25c4SRahul Lakkireddy 	}
339123e25c4SRahul Lakkireddy 
340123e25c4SRahul Lakkireddy 	for (i = 0; i < padap->params.arch.nchan; i++) {
341123e25c4SRahul Lakkireddy 		if (CHELSIO_CHIP_VERSION(padap->params.chip) > CHELSIO_T5)
342123e25c4SRahul Lakkireddy 			lo = t4_read_reg(padap,
343123e25c4SRahul Lakkireddy 					 MPS_RX_LPBK_BG_PG_CNT0_A + i * 4);
344123e25c4SRahul Lakkireddy 		else
345123e25c4SRahul Lakkireddy 			lo = t4_read_reg(padap, MPS_RX_PG_RSV4_A + i * 4);
346123e25c4SRahul Lakkireddy 		if (is_t5(padap->params.chip)) {
347123e25c4SRahul Lakkireddy 			used = T5_USED_G(lo);
348123e25c4SRahul Lakkireddy 			alloc = T5_ALLOC_G(lo);
349123e25c4SRahul Lakkireddy 		} else {
350123e25c4SRahul Lakkireddy 			used = USED_G(lo);
351123e25c4SRahul Lakkireddy 			alloc = ALLOC_G(lo);
352123e25c4SRahul Lakkireddy 		}
353123e25c4SRahul Lakkireddy 		meminfo_buff->loopback_used[i] = used;
354123e25c4SRahul Lakkireddy 		meminfo_buff->loopback_alloc[i] = alloc;
355123e25c4SRahul Lakkireddy 	}
356123e25c4SRahul Lakkireddy 
357123e25c4SRahul Lakkireddy 	return 0;
358123e25c4SRahul Lakkireddy }
359123e25c4SRahul Lakkireddy 
360a7975a2fSRahul Lakkireddy int cudbg_collect_reg_dump(struct cudbg_init *pdbg_init,
361a7975a2fSRahul Lakkireddy 			   struct cudbg_buffer *dbg_buff,
362a7975a2fSRahul Lakkireddy 			   struct cudbg_error *cudbg_err)
363a7975a2fSRahul Lakkireddy {
364a7975a2fSRahul Lakkireddy 	struct adapter *padap = pdbg_init->adap;
365a7975a2fSRahul Lakkireddy 	struct cudbg_buffer temp_buff = { 0 };
366a7975a2fSRahul Lakkireddy 	u32 buf_size = 0;
367a7975a2fSRahul Lakkireddy 	int rc = 0;
368a7975a2fSRahul Lakkireddy 
369a7975a2fSRahul Lakkireddy 	if (is_t4(padap->params.chip))
370a7975a2fSRahul Lakkireddy 		buf_size = T4_REGMAP_SIZE;
371a7975a2fSRahul Lakkireddy 	else if (is_t5(padap->params.chip) || is_t6(padap->params.chip))
372a7975a2fSRahul Lakkireddy 		buf_size = T5_REGMAP_SIZE;
373a7975a2fSRahul Lakkireddy 
374a7975a2fSRahul Lakkireddy 	rc = cudbg_get_buff(dbg_buff, buf_size, &temp_buff);
375a7975a2fSRahul Lakkireddy 	if (rc)
376a7975a2fSRahul Lakkireddy 		return rc;
377a7975a2fSRahul Lakkireddy 	t4_get_regs(padap, (void *)temp_buff.data, temp_buff.size);
378a7975a2fSRahul Lakkireddy 	cudbg_write_and_release_buff(&temp_buff, dbg_buff);
379a7975a2fSRahul Lakkireddy 	return rc;
380a7975a2fSRahul Lakkireddy }
381b33af022SRahul Lakkireddy 
382844d1b6fSRahul Lakkireddy int cudbg_collect_fw_devlog(struct cudbg_init *pdbg_init,
383844d1b6fSRahul Lakkireddy 			    struct cudbg_buffer *dbg_buff,
384844d1b6fSRahul Lakkireddy 			    struct cudbg_error *cudbg_err)
385844d1b6fSRahul Lakkireddy {
386844d1b6fSRahul Lakkireddy 	struct adapter *padap = pdbg_init->adap;
387844d1b6fSRahul Lakkireddy 	struct cudbg_buffer temp_buff = { 0 };
388844d1b6fSRahul Lakkireddy 	struct devlog_params *dparams;
389844d1b6fSRahul Lakkireddy 	int rc = 0;
390844d1b6fSRahul Lakkireddy 
391844d1b6fSRahul Lakkireddy 	rc = t4_init_devlog_params(padap);
392844d1b6fSRahul Lakkireddy 	if (rc < 0) {
393844d1b6fSRahul Lakkireddy 		cudbg_err->sys_err = rc;
394844d1b6fSRahul Lakkireddy 		return rc;
395844d1b6fSRahul Lakkireddy 	}
396844d1b6fSRahul Lakkireddy 
397844d1b6fSRahul Lakkireddy 	dparams = &padap->params.devlog;
398844d1b6fSRahul Lakkireddy 	rc = cudbg_get_buff(dbg_buff, dparams->size, &temp_buff);
399844d1b6fSRahul Lakkireddy 	if (rc)
400844d1b6fSRahul Lakkireddy 		return rc;
401844d1b6fSRahul Lakkireddy 
402844d1b6fSRahul Lakkireddy 	/* Collect FW devlog */
403844d1b6fSRahul Lakkireddy 	if (dparams->start != 0) {
404844d1b6fSRahul Lakkireddy 		spin_lock(&padap->win0_lock);
405844d1b6fSRahul Lakkireddy 		rc = t4_memory_rw(padap, padap->params.drv_memwin,
406844d1b6fSRahul Lakkireddy 				  dparams->memtype, dparams->start,
407844d1b6fSRahul Lakkireddy 				  dparams->size,
408844d1b6fSRahul Lakkireddy 				  (__be32 *)(char *)temp_buff.data,
409844d1b6fSRahul Lakkireddy 				  1);
410844d1b6fSRahul Lakkireddy 		spin_unlock(&padap->win0_lock);
411844d1b6fSRahul Lakkireddy 		if (rc) {
412844d1b6fSRahul Lakkireddy 			cudbg_err->sys_err = rc;
413844d1b6fSRahul Lakkireddy 			cudbg_put_buff(&temp_buff, dbg_buff);
414844d1b6fSRahul Lakkireddy 			return rc;
415844d1b6fSRahul Lakkireddy 		}
416844d1b6fSRahul Lakkireddy 	}
417844d1b6fSRahul Lakkireddy 	cudbg_write_and_release_buff(&temp_buff, dbg_buff);
418844d1b6fSRahul Lakkireddy 	return rc;
419844d1b6fSRahul Lakkireddy }
420844d1b6fSRahul Lakkireddy 
42127887bc7SRahul Lakkireddy int cudbg_collect_cim_la(struct cudbg_init *pdbg_init,
42227887bc7SRahul Lakkireddy 			 struct cudbg_buffer *dbg_buff,
42327887bc7SRahul Lakkireddy 			 struct cudbg_error *cudbg_err)
42427887bc7SRahul Lakkireddy {
42527887bc7SRahul Lakkireddy 	struct adapter *padap = pdbg_init->adap;
42627887bc7SRahul Lakkireddy 	struct cudbg_buffer temp_buff = { 0 };
42727887bc7SRahul Lakkireddy 	int size, rc;
42827887bc7SRahul Lakkireddy 	u32 cfg = 0;
42927887bc7SRahul Lakkireddy 
43027887bc7SRahul Lakkireddy 	if (is_t6(padap->params.chip)) {
43127887bc7SRahul Lakkireddy 		size = padap->params.cim_la_size / 10 + 1;
43227887bc7SRahul Lakkireddy 		size *= 11 * sizeof(u32);
43327887bc7SRahul Lakkireddy 	} else {
43427887bc7SRahul Lakkireddy 		size = padap->params.cim_la_size / 8;
43527887bc7SRahul Lakkireddy 		size *= 8 * sizeof(u32);
43627887bc7SRahul Lakkireddy 	}
43727887bc7SRahul Lakkireddy 
43827887bc7SRahul Lakkireddy 	size += sizeof(cfg);
43927887bc7SRahul Lakkireddy 	rc = cudbg_get_buff(dbg_buff, size, &temp_buff);
44027887bc7SRahul Lakkireddy 	if (rc)
44127887bc7SRahul Lakkireddy 		return rc;
44227887bc7SRahul Lakkireddy 
44327887bc7SRahul Lakkireddy 	rc = t4_cim_read(padap, UP_UP_DBG_LA_CFG_A, 1, &cfg);
44427887bc7SRahul Lakkireddy 	if (rc) {
44527887bc7SRahul Lakkireddy 		cudbg_err->sys_err = rc;
44627887bc7SRahul Lakkireddy 		cudbg_put_buff(&temp_buff, dbg_buff);
44727887bc7SRahul Lakkireddy 		return rc;
44827887bc7SRahul Lakkireddy 	}
44927887bc7SRahul Lakkireddy 
45027887bc7SRahul Lakkireddy 	memcpy((char *)temp_buff.data, &cfg, sizeof(cfg));
45127887bc7SRahul Lakkireddy 	rc = t4_cim_read_la(padap,
45227887bc7SRahul Lakkireddy 			    (u32 *)((char *)temp_buff.data + sizeof(cfg)),
45327887bc7SRahul Lakkireddy 			    NULL);
45427887bc7SRahul Lakkireddy 	if (rc < 0) {
45527887bc7SRahul Lakkireddy 		cudbg_err->sys_err = rc;
45627887bc7SRahul Lakkireddy 		cudbg_put_buff(&temp_buff, dbg_buff);
45727887bc7SRahul Lakkireddy 		return rc;
45827887bc7SRahul Lakkireddy 	}
45927887bc7SRahul Lakkireddy 	cudbg_write_and_release_buff(&temp_buff, dbg_buff);
46027887bc7SRahul Lakkireddy 	return rc;
46127887bc7SRahul Lakkireddy }
46227887bc7SRahul Lakkireddy 
46327887bc7SRahul Lakkireddy int cudbg_collect_cim_ma_la(struct cudbg_init *pdbg_init,
46427887bc7SRahul Lakkireddy 			    struct cudbg_buffer *dbg_buff,
46527887bc7SRahul Lakkireddy 			    struct cudbg_error *cudbg_err)
46627887bc7SRahul Lakkireddy {
46727887bc7SRahul Lakkireddy 	struct adapter *padap = pdbg_init->adap;
46827887bc7SRahul Lakkireddy 	struct cudbg_buffer temp_buff = { 0 };
46927887bc7SRahul Lakkireddy 	int size, rc;
47027887bc7SRahul Lakkireddy 
47127887bc7SRahul Lakkireddy 	size = 2 * CIM_MALA_SIZE * 5 * sizeof(u32);
47227887bc7SRahul Lakkireddy 	rc = cudbg_get_buff(dbg_buff, size, &temp_buff);
47327887bc7SRahul Lakkireddy 	if (rc)
47427887bc7SRahul Lakkireddy 		return rc;
47527887bc7SRahul Lakkireddy 
47627887bc7SRahul Lakkireddy 	t4_cim_read_ma_la(padap,
47727887bc7SRahul Lakkireddy 			  (u32 *)temp_buff.data,
47827887bc7SRahul Lakkireddy 			  (u32 *)((char *)temp_buff.data +
47927887bc7SRahul Lakkireddy 				  5 * CIM_MALA_SIZE));
48027887bc7SRahul Lakkireddy 	cudbg_write_and_release_buff(&temp_buff, dbg_buff);
48127887bc7SRahul Lakkireddy 	return rc;
48227887bc7SRahul Lakkireddy }
48327887bc7SRahul Lakkireddy 
4843044d0fbSRahul Lakkireddy int cudbg_collect_cim_qcfg(struct cudbg_init *pdbg_init,
4853044d0fbSRahul Lakkireddy 			   struct cudbg_buffer *dbg_buff,
4863044d0fbSRahul Lakkireddy 			   struct cudbg_error *cudbg_err)
4873044d0fbSRahul Lakkireddy {
4883044d0fbSRahul Lakkireddy 	struct adapter *padap = pdbg_init->adap;
4893044d0fbSRahul Lakkireddy 	struct cudbg_buffer temp_buff = { 0 };
4903044d0fbSRahul Lakkireddy 	struct cudbg_cim_qcfg *cim_qcfg_data;
4913044d0fbSRahul Lakkireddy 	int rc;
4923044d0fbSRahul Lakkireddy 
4933044d0fbSRahul Lakkireddy 	rc = cudbg_get_buff(dbg_buff, sizeof(struct cudbg_cim_qcfg),
4943044d0fbSRahul Lakkireddy 			    &temp_buff);
4953044d0fbSRahul Lakkireddy 	if (rc)
4963044d0fbSRahul Lakkireddy 		return rc;
4973044d0fbSRahul Lakkireddy 
4983044d0fbSRahul Lakkireddy 	cim_qcfg_data = (struct cudbg_cim_qcfg *)temp_buff.data;
4993044d0fbSRahul Lakkireddy 	cim_qcfg_data->chip = padap->params.chip;
5003044d0fbSRahul Lakkireddy 	rc = t4_cim_read(padap, UP_IBQ_0_RDADDR_A,
5013044d0fbSRahul Lakkireddy 			 ARRAY_SIZE(cim_qcfg_data->stat), cim_qcfg_data->stat);
5023044d0fbSRahul Lakkireddy 	if (rc) {
5033044d0fbSRahul Lakkireddy 		cudbg_err->sys_err = rc;
5043044d0fbSRahul Lakkireddy 		cudbg_put_buff(&temp_buff, dbg_buff);
5053044d0fbSRahul Lakkireddy 		return rc;
5063044d0fbSRahul Lakkireddy 	}
5073044d0fbSRahul Lakkireddy 
5083044d0fbSRahul Lakkireddy 	rc = t4_cim_read(padap, UP_OBQ_0_REALADDR_A,
5093044d0fbSRahul Lakkireddy 			 ARRAY_SIZE(cim_qcfg_data->obq_wr),
5103044d0fbSRahul Lakkireddy 			 cim_qcfg_data->obq_wr);
5113044d0fbSRahul Lakkireddy 	if (rc) {
5123044d0fbSRahul Lakkireddy 		cudbg_err->sys_err = rc;
5133044d0fbSRahul Lakkireddy 		cudbg_put_buff(&temp_buff, dbg_buff);
5143044d0fbSRahul Lakkireddy 		return rc;
5153044d0fbSRahul Lakkireddy 	}
5163044d0fbSRahul Lakkireddy 
5173044d0fbSRahul Lakkireddy 	t4_read_cimq_cfg(padap, cim_qcfg_data->base, cim_qcfg_data->size,
5183044d0fbSRahul Lakkireddy 			 cim_qcfg_data->thres);
5193044d0fbSRahul Lakkireddy 	cudbg_write_and_release_buff(&temp_buff, dbg_buff);
5203044d0fbSRahul Lakkireddy 	return rc;
5213044d0fbSRahul Lakkireddy }
5223044d0fbSRahul Lakkireddy 
5237c075ce2SRahul Lakkireddy static int cudbg_read_cim_ibq(struct cudbg_init *pdbg_init,
5247c075ce2SRahul Lakkireddy 			      struct cudbg_buffer *dbg_buff,
5257c075ce2SRahul Lakkireddy 			      struct cudbg_error *cudbg_err, int qid)
5267c075ce2SRahul Lakkireddy {
5277c075ce2SRahul Lakkireddy 	struct adapter *padap = pdbg_init->adap;
5287c075ce2SRahul Lakkireddy 	struct cudbg_buffer temp_buff = { 0 };
5297c075ce2SRahul Lakkireddy 	int no_of_read_words, rc = 0;
5307c075ce2SRahul Lakkireddy 	u32 qsize;
5317c075ce2SRahul Lakkireddy 
5327c075ce2SRahul Lakkireddy 	/* collect CIM IBQ */
5337c075ce2SRahul Lakkireddy 	qsize = CIM_IBQ_SIZE * 4 * sizeof(u32);
5347c075ce2SRahul Lakkireddy 	rc = cudbg_get_buff(dbg_buff, qsize, &temp_buff);
5357c075ce2SRahul Lakkireddy 	if (rc)
5367c075ce2SRahul Lakkireddy 		return rc;
5377c075ce2SRahul Lakkireddy 
5387c075ce2SRahul Lakkireddy 	/* t4_read_cim_ibq will return no. of read words or error */
5397c075ce2SRahul Lakkireddy 	no_of_read_words = t4_read_cim_ibq(padap, qid,
540acfdf7eaSRahul Lakkireddy 					   (u32 *)temp_buff.data, qsize);
5417c075ce2SRahul Lakkireddy 	/* no_of_read_words is less than or equal to 0 means error */
5427c075ce2SRahul Lakkireddy 	if (no_of_read_words <= 0) {
5437c075ce2SRahul Lakkireddy 		if (!no_of_read_words)
5447c075ce2SRahul Lakkireddy 			rc = CUDBG_SYSTEM_ERROR;
5457c075ce2SRahul Lakkireddy 		else
5467c075ce2SRahul Lakkireddy 			rc = no_of_read_words;
5477c075ce2SRahul Lakkireddy 		cudbg_err->sys_err = rc;
5487c075ce2SRahul Lakkireddy 		cudbg_put_buff(&temp_buff, dbg_buff);
5497c075ce2SRahul Lakkireddy 		return rc;
5507c075ce2SRahul Lakkireddy 	}
5517c075ce2SRahul Lakkireddy 	cudbg_write_and_release_buff(&temp_buff, dbg_buff);
5527c075ce2SRahul Lakkireddy 	return rc;
5537c075ce2SRahul Lakkireddy }
5547c075ce2SRahul Lakkireddy 
5557c075ce2SRahul Lakkireddy int cudbg_collect_cim_ibq_tp0(struct cudbg_init *pdbg_init,
5567c075ce2SRahul Lakkireddy 			      struct cudbg_buffer *dbg_buff,
5577c075ce2SRahul Lakkireddy 			      struct cudbg_error *cudbg_err)
5587c075ce2SRahul Lakkireddy {
5597c075ce2SRahul Lakkireddy 	return cudbg_read_cim_ibq(pdbg_init, dbg_buff, cudbg_err, 0);
5607c075ce2SRahul Lakkireddy }
5617c075ce2SRahul Lakkireddy 
5627c075ce2SRahul Lakkireddy int cudbg_collect_cim_ibq_tp1(struct cudbg_init *pdbg_init,
5637c075ce2SRahul Lakkireddy 			      struct cudbg_buffer *dbg_buff,
5647c075ce2SRahul Lakkireddy 			      struct cudbg_error *cudbg_err)
5657c075ce2SRahul Lakkireddy {
5667c075ce2SRahul Lakkireddy 	return cudbg_read_cim_ibq(pdbg_init, dbg_buff, cudbg_err, 1);
5677c075ce2SRahul Lakkireddy }
5687c075ce2SRahul Lakkireddy 
5697c075ce2SRahul Lakkireddy int cudbg_collect_cim_ibq_ulp(struct cudbg_init *pdbg_init,
5707c075ce2SRahul Lakkireddy 			      struct cudbg_buffer *dbg_buff,
5717c075ce2SRahul Lakkireddy 			      struct cudbg_error *cudbg_err)
5727c075ce2SRahul Lakkireddy {
5737c075ce2SRahul Lakkireddy 	return cudbg_read_cim_ibq(pdbg_init, dbg_buff, cudbg_err, 2);
5747c075ce2SRahul Lakkireddy }
5757c075ce2SRahul Lakkireddy 
5767c075ce2SRahul Lakkireddy int cudbg_collect_cim_ibq_sge0(struct cudbg_init *pdbg_init,
5777c075ce2SRahul Lakkireddy 			       struct cudbg_buffer *dbg_buff,
5787c075ce2SRahul Lakkireddy 			       struct cudbg_error *cudbg_err)
5797c075ce2SRahul Lakkireddy {
5807c075ce2SRahul Lakkireddy 	return cudbg_read_cim_ibq(pdbg_init, dbg_buff, cudbg_err, 3);
5817c075ce2SRahul Lakkireddy }
5827c075ce2SRahul Lakkireddy 
5837c075ce2SRahul Lakkireddy int cudbg_collect_cim_ibq_sge1(struct cudbg_init *pdbg_init,
5847c075ce2SRahul Lakkireddy 			       struct cudbg_buffer *dbg_buff,
5857c075ce2SRahul Lakkireddy 			       struct cudbg_error *cudbg_err)
5867c075ce2SRahul Lakkireddy {
5877c075ce2SRahul Lakkireddy 	return cudbg_read_cim_ibq(pdbg_init, dbg_buff, cudbg_err, 4);
5887c075ce2SRahul Lakkireddy }
5897c075ce2SRahul Lakkireddy 
5907c075ce2SRahul Lakkireddy int cudbg_collect_cim_ibq_ncsi(struct cudbg_init *pdbg_init,
5917c075ce2SRahul Lakkireddy 			       struct cudbg_buffer *dbg_buff,
5927c075ce2SRahul Lakkireddy 			       struct cudbg_error *cudbg_err)
5937c075ce2SRahul Lakkireddy {
5947c075ce2SRahul Lakkireddy 	return cudbg_read_cim_ibq(pdbg_init, dbg_buff, cudbg_err, 5);
5957c075ce2SRahul Lakkireddy }
5967c075ce2SRahul Lakkireddy 
597acfdf7eaSRahul Lakkireddy u32 cudbg_cim_obq_size(struct adapter *padap, int qid)
598acfdf7eaSRahul Lakkireddy {
599acfdf7eaSRahul Lakkireddy 	u32 value;
600acfdf7eaSRahul Lakkireddy 
601acfdf7eaSRahul Lakkireddy 	t4_write_reg(padap, CIM_QUEUE_CONFIG_REF_A, OBQSELECT_F |
602acfdf7eaSRahul Lakkireddy 		     QUENUMSELECT_V(qid));
603acfdf7eaSRahul Lakkireddy 	value = t4_read_reg(padap, CIM_QUEUE_CONFIG_CTRL_A);
604acfdf7eaSRahul Lakkireddy 	value = CIMQSIZE_G(value) * 64; /* size in number of words */
605acfdf7eaSRahul Lakkireddy 	return value * sizeof(u32);
606acfdf7eaSRahul Lakkireddy }
607acfdf7eaSRahul Lakkireddy 
6087c075ce2SRahul Lakkireddy static int cudbg_read_cim_obq(struct cudbg_init *pdbg_init,
6097c075ce2SRahul Lakkireddy 			      struct cudbg_buffer *dbg_buff,
6107c075ce2SRahul Lakkireddy 			      struct cudbg_error *cudbg_err, int qid)
6117c075ce2SRahul Lakkireddy {
6127c075ce2SRahul Lakkireddy 	struct adapter *padap = pdbg_init->adap;
6137c075ce2SRahul Lakkireddy 	struct cudbg_buffer temp_buff = { 0 };
6147c075ce2SRahul Lakkireddy 	int no_of_read_words, rc = 0;
6157c075ce2SRahul Lakkireddy 	u32 qsize;
6167c075ce2SRahul Lakkireddy 
6177c075ce2SRahul Lakkireddy 	/* collect CIM OBQ */
618acfdf7eaSRahul Lakkireddy 	qsize =  cudbg_cim_obq_size(padap, qid);
6197c075ce2SRahul Lakkireddy 	rc = cudbg_get_buff(dbg_buff, qsize, &temp_buff);
6207c075ce2SRahul Lakkireddy 	if (rc)
6217c075ce2SRahul Lakkireddy 		return rc;
6227c075ce2SRahul Lakkireddy 
6237c075ce2SRahul Lakkireddy 	/* t4_read_cim_obq will return no. of read words or error */
6247c075ce2SRahul Lakkireddy 	no_of_read_words = t4_read_cim_obq(padap, qid,
625acfdf7eaSRahul Lakkireddy 					   (u32 *)temp_buff.data, qsize);
6267c075ce2SRahul Lakkireddy 	/* no_of_read_words is less than or equal to 0 means error */
6277c075ce2SRahul Lakkireddy 	if (no_of_read_words <= 0) {
6287c075ce2SRahul Lakkireddy 		if (!no_of_read_words)
6297c075ce2SRahul Lakkireddy 			rc = CUDBG_SYSTEM_ERROR;
6307c075ce2SRahul Lakkireddy 		else
6317c075ce2SRahul Lakkireddy 			rc = no_of_read_words;
6327c075ce2SRahul Lakkireddy 		cudbg_err->sys_err = rc;
6337c075ce2SRahul Lakkireddy 		cudbg_put_buff(&temp_buff, dbg_buff);
6347c075ce2SRahul Lakkireddy 		return rc;
6357c075ce2SRahul Lakkireddy 	}
6367c075ce2SRahul Lakkireddy 	cudbg_write_and_release_buff(&temp_buff, dbg_buff);
6377c075ce2SRahul Lakkireddy 	return rc;
6387c075ce2SRahul Lakkireddy }
6397c075ce2SRahul Lakkireddy 
6407c075ce2SRahul Lakkireddy int cudbg_collect_cim_obq_ulp0(struct cudbg_init *pdbg_init,
6417c075ce2SRahul Lakkireddy 			       struct cudbg_buffer *dbg_buff,
6427c075ce2SRahul Lakkireddy 			       struct cudbg_error *cudbg_err)
6437c075ce2SRahul Lakkireddy {
6447c075ce2SRahul Lakkireddy 	return cudbg_read_cim_obq(pdbg_init, dbg_buff, cudbg_err, 0);
6457c075ce2SRahul Lakkireddy }
6467c075ce2SRahul Lakkireddy 
6477c075ce2SRahul Lakkireddy int cudbg_collect_cim_obq_ulp1(struct cudbg_init *pdbg_init,
6487c075ce2SRahul Lakkireddy 			       struct cudbg_buffer *dbg_buff,
6497c075ce2SRahul Lakkireddy 			       struct cudbg_error *cudbg_err)
6507c075ce2SRahul Lakkireddy {
6517c075ce2SRahul Lakkireddy 	return cudbg_read_cim_obq(pdbg_init, dbg_buff, cudbg_err, 1);
6527c075ce2SRahul Lakkireddy }
6537c075ce2SRahul Lakkireddy 
6547c075ce2SRahul Lakkireddy int cudbg_collect_cim_obq_ulp2(struct cudbg_init *pdbg_init,
6557c075ce2SRahul Lakkireddy 			       struct cudbg_buffer *dbg_buff,
6567c075ce2SRahul Lakkireddy 			       struct cudbg_error *cudbg_err)
6577c075ce2SRahul Lakkireddy {
6587c075ce2SRahul Lakkireddy 	return cudbg_read_cim_obq(pdbg_init, dbg_buff, cudbg_err, 2);
6597c075ce2SRahul Lakkireddy }
6607c075ce2SRahul Lakkireddy 
6617c075ce2SRahul Lakkireddy int cudbg_collect_cim_obq_ulp3(struct cudbg_init *pdbg_init,
6627c075ce2SRahul Lakkireddy 			       struct cudbg_buffer *dbg_buff,
6637c075ce2SRahul Lakkireddy 			       struct cudbg_error *cudbg_err)
6647c075ce2SRahul Lakkireddy {
6657c075ce2SRahul Lakkireddy 	return cudbg_read_cim_obq(pdbg_init, dbg_buff, cudbg_err, 3);
6667c075ce2SRahul Lakkireddy }
6677c075ce2SRahul Lakkireddy 
6687c075ce2SRahul Lakkireddy int cudbg_collect_cim_obq_sge(struct cudbg_init *pdbg_init,
6697c075ce2SRahul Lakkireddy 			      struct cudbg_buffer *dbg_buff,
6707c075ce2SRahul Lakkireddy 			      struct cudbg_error *cudbg_err)
6717c075ce2SRahul Lakkireddy {
6727c075ce2SRahul Lakkireddy 	return cudbg_read_cim_obq(pdbg_init, dbg_buff, cudbg_err, 4);
6737c075ce2SRahul Lakkireddy }
6747c075ce2SRahul Lakkireddy 
6757c075ce2SRahul Lakkireddy int cudbg_collect_cim_obq_ncsi(struct cudbg_init *pdbg_init,
6767c075ce2SRahul Lakkireddy 			       struct cudbg_buffer *dbg_buff,
6777c075ce2SRahul Lakkireddy 			       struct cudbg_error *cudbg_err)
6787c075ce2SRahul Lakkireddy {
6797c075ce2SRahul Lakkireddy 	return cudbg_read_cim_obq(pdbg_init, dbg_buff, cudbg_err, 5);
6807c075ce2SRahul Lakkireddy }
6817c075ce2SRahul Lakkireddy 
6827c075ce2SRahul Lakkireddy int cudbg_collect_obq_sge_rx_q0(struct cudbg_init *pdbg_init,
6837c075ce2SRahul Lakkireddy 				struct cudbg_buffer *dbg_buff,
6847c075ce2SRahul Lakkireddy 				struct cudbg_error *cudbg_err)
6857c075ce2SRahul Lakkireddy {
6867c075ce2SRahul Lakkireddy 	return cudbg_read_cim_obq(pdbg_init, dbg_buff, cudbg_err, 6);
6877c075ce2SRahul Lakkireddy }
6887c075ce2SRahul Lakkireddy 
6897c075ce2SRahul Lakkireddy int cudbg_collect_obq_sge_rx_q1(struct cudbg_init *pdbg_init,
6907c075ce2SRahul Lakkireddy 				struct cudbg_buffer *dbg_buff,
6917c075ce2SRahul Lakkireddy 				struct cudbg_error *cudbg_err)
6927c075ce2SRahul Lakkireddy {
6937c075ce2SRahul Lakkireddy 	return cudbg_read_cim_obq(pdbg_init, dbg_buff, cudbg_err, 7);
6947c075ce2SRahul Lakkireddy }
6957c075ce2SRahul Lakkireddy 
696a1c69520SRahul Lakkireddy static int cudbg_meminfo_get_mem_index(struct adapter *padap,
697a1c69520SRahul Lakkireddy 				       struct cudbg_meminfo *mem_info,
698a1c69520SRahul Lakkireddy 				       u8 mem_type, u8 *idx)
699a1c69520SRahul Lakkireddy {
700a1c69520SRahul Lakkireddy 	u8 i, flag;
701a1c69520SRahul Lakkireddy 
702a1c69520SRahul Lakkireddy 	switch (mem_type) {
703a1c69520SRahul Lakkireddy 	case MEM_EDC0:
704a1c69520SRahul Lakkireddy 		flag = EDC0_FLAG;
705a1c69520SRahul Lakkireddy 		break;
706a1c69520SRahul Lakkireddy 	case MEM_EDC1:
707a1c69520SRahul Lakkireddy 		flag = EDC1_FLAG;
708a1c69520SRahul Lakkireddy 		break;
709a1c69520SRahul Lakkireddy 	case MEM_MC0:
710a1c69520SRahul Lakkireddy 		/* Some T5 cards have both MC0 and MC1. */
711a1c69520SRahul Lakkireddy 		flag = is_t5(padap->params.chip) ? MC0_FLAG : MC_FLAG;
712a1c69520SRahul Lakkireddy 		break;
713a1c69520SRahul Lakkireddy 	case MEM_MC1:
714a1c69520SRahul Lakkireddy 		flag = MC1_FLAG;
715a1c69520SRahul Lakkireddy 		break;
7164db0401fSRahul Lakkireddy 	case MEM_HMA:
7174db0401fSRahul Lakkireddy 		flag = HMA_FLAG;
7184db0401fSRahul Lakkireddy 		break;
719a1c69520SRahul Lakkireddy 	default:
720a1c69520SRahul Lakkireddy 		return CUDBG_STATUS_ENTITY_NOT_FOUND;
721a1c69520SRahul Lakkireddy 	}
722a1c69520SRahul Lakkireddy 
723a1c69520SRahul Lakkireddy 	for (i = 0; i < mem_info->avail_c; i++) {
724a1c69520SRahul Lakkireddy 		if (mem_info->avail[i].idx == flag) {
725a1c69520SRahul Lakkireddy 			*idx = i;
726a1c69520SRahul Lakkireddy 			return 0;
727a1c69520SRahul Lakkireddy 		}
728a1c69520SRahul Lakkireddy 	}
729a1c69520SRahul Lakkireddy 
730a1c69520SRahul Lakkireddy 	return CUDBG_STATUS_ENTITY_NOT_FOUND;
731a1c69520SRahul Lakkireddy }
732a1c69520SRahul Lakkireddy 
733c1219653SRahul Lakkireddy /* Fetch the @region_name's start and end from @meminfo. */
734c1219653SRahul Lakkireddy static int cudbg_get_mem_region(struct adapter *padap,
735c1219653SRahul Lakkireddy 				struct cudbg_meminfo *meminfo,
736c1219653SRahul Lakkireddy 				u8 mem_type, const char *region_name,
737c1219653SRahul Lakkireddy 				struct cudbg_mem_desc *mem_desc)
738c1219653SRahul Lakkireddy {
739c1219653SRahul Lakkireddy 	u8 mc, found = 0;
740c1219653SRahul Lakkireddy 	u32 i, idx = 0;
741c1219653SRahul Lakkireddy 	int rc;
742c1219653SRahul Lakkireddy 
743c1219653SRahul Lakkireddy 	rc = cudbg_meminfo_get_mem_index(padap, meminfo, mem_type, &mc);
744c1219653SRahul Lakkireddy 	if (rc)
745c1219653SRahul Lakkireddy 		return rc;
746c1219653SRahul Lakkireddy 
747c1219653SRahul Lakkireddy 	for (i = 0; i < ARRAY_SIZE(cudbg_region); i++) {
748c1219653SRahul Lakkireddy 		if (!strcmp(cudbg_region[i], region_name)) {
749c1219653SRahul Lakkireddy 			found = 1;
750c1219653SRahul Lakkireddy 			idx = i;
751c1219653SRahul Lakkireddy 			break;
752c1219653SRahul Lakkireddy 		}
753c1219653SRahul Lakkireddy 	}
754c1219653SRahul Lakkireddy 	if (!found)
755c1219653SRahul Lakkireddy 		return -EINVAL;
756c1219653SRahul Lakkireddy 
757c1219653SRahul Lakkireddy 	found = 0;
758c1219653SRahul Lakkireddy 	for (i = 0; i < meminfo->mem_c; i++) {
759c1219653SRahul Lakkireddy 		if (meminfo->mem[i].idx >= ARRAY_SIZE(cudbg_region))
760c1219653SRahul Lakkireddy 			continue; /* Skip holes */
761c1219653SRahul Lakkireddy 
762c1219653SRahul Lakkireddy 		if (!(meminfo->mem[i].limit))
763c1219653SRahul Lakkireddy 			meminfo->mem[i].limit =
764c1219653SRahul Lakkireddy 				i < meminfo->mem_c - 1 ?
765c1219653SRahul Lakkireddy 				meminfo->mem[i + 1].base - 1 : ~0;
766c1219653SRahul Lakkireddy 
767c1219653SRahul Lakkireddy 		if (meminfo->mem[i].idx == idx) {
768c1219653SRahul Lakkireddy 			/* Check if the region exists in @mem_type memory */
769c1219653SRahul Lakkireddy 			if (meminfo->mem[i].base < meminfo->avail[mc].base &&
770c1219653SRahul Lakkireddy 			    meminfo->mem[i].limit < meminfo->avail[mc].base)
771c1219653SRahul Lakkireddy 				return -EINVAL;
772c1219653SRahul Lakkireddy 
773c1219653SRahul Lakkireddy 			if (meminfo->mem[i].base > meminfo->avail[mc].limit)
774c1219653SRahul Lakkireddy 				return -EINVAL;
775c1219653SRahul Lakkireddy 
776c1219653SRahul Lakkireddy 			memcpy(mem_desc, &meminfo->mem[i],
777c1219653SRahul Lakkireddy 			       sizeof(struct cudbg_mem_desc));
778c1219653SRahul Lakkireddy 			found = 1;
779c1219653SRahul Lakkireddy 			break;
780c1219653SRahul Lakkireddy 		}
781c1219653SRahul Lakkireddy 	}
782c1219653SRahul Lakkireddy 	if (!found)
783c1219653SRahul Lakkireddy 		return -EINVAL;
784c1219653SRahul Lakkireddy 
785c1219653SRahul Lakkireddy 	return 0;
786c1219653SRahul Lakkireddy }
787c1219653SRahul Lakkireddy 
788c1219653SRahul Lakkireddy /* Fetch and update the start and end of the requested memory region w.r.t 0
789c1219653SRahul Lakkireddy  * in the corresponding EDC/MC/HMA.
790c1219653SRahul Lakkireddy  */
791c1219653SRahul Lakkireddy static int cudbg_get_mem_relative(struct adapter *padap,
792c1219653SRahul Lakkireddy 				  struct cudbg_meminfo *meminfo,
793c1219653SRahul Lakkireddy 				  u8 mem_type, u32 *out_base, u32 *out_end)
794c1219653SRahul Lakkireddy {
795c1219653SRahul Lakkireddy 	u8 mc_idx;
796c1219653SRahul Lakkireddy 	int rc;
797c1219653SRahul Lakkireddy 
798c1219653SRahul Lakkireddy 	rc = cudbg_meminfo_get_mem_index(padap, meminfo, mem_type, &mc_idx);
799c1219653SRahul Lakkireddy 	if (rc)
800c1219653SRahul Lakkireddy 		return rc;
801c1219653SRahul Lakkireddy 
802c1219653SRahul Lakkireddy 	if (*out_base < meminfo->avail[mc_idx].base)
803c1219653SRahul Lakkireddy 		*out_base = 0;
804c1219653SRahul Lakkireddy 	else
805c1219653SRahul Lakkireddy 		*out_base -= meminfo->avail[mc_idx].base;
806c1219653SRahul Lakkireddy 
807c1219653SRahul Lakkireddy 	if (*out_end > meminfo->avail[mc_idx].limit)
808c1219653SRahul Lakkireddy 		*out_end = meminfo->avail[mc_idx].limit;
809c1219653SRahul Lakkireddy 	else
810c1219653SRahul Lakkireddy 		*out_end -= meminfo->avail[mc_idx].base;
811c1219653SRahul Lakkireddy 
812c1219653SRahul Lakkireddy 	return 0;
813c1219653SRahul Lakkireddy }
814c1219653SRahul Lakkireddy 
815c1219653SRahul Lakkireddy /* Get TX and RX Payload region */
816c1219653SRahul Lakkireddy static int cudbg_get_payload_range(struct adapter *padap, u8 mem_type,
817c1219653SRahul Lakkireddy 				   const char *region_name,
818c1219653SRahul Lakkireddy 				   struct cudbg_region_info *payload)
819c1219653SRahul Lakkireddy {
820c1219653SRahul Lakkireddy 	struct cudbg_mem_desc mem_desc = { 0 };
821c1219653SRahul Lakkireddy 	struct cudbg_meminfo meminfo;
822c1219653SRahul Lakkireddy 	int rc;
823c1219653SRahul Lakkireddy 
824c1219653SRahul Lakkireddy 	rc = cudbg_fill_meminfo(padap, &meminfo);
825c1219653SRahul Lakkireddy 	if (rc)
826c1219653SRahul Lakkireddy 		return rc;
827c1219653SRahul Lakkireddy 
828c1219653SRahul Lakkireddy 	rc = cudbg_get_mem_region(padap, &meminfo, mem_type, region_name,
829c1219653SRahul Lakkireddy 				  &mem_desc);
830c1219653SRahul Lakkireddy 	if (rc) {
831c1219653SRahul Lakkireddy 		payload->exist = false;
832c1219653SRahul Lakkireddy 		return 0;
833c1219653SRahul Lakkireddy 	}
834c1219653SRahul Lakkireddy 
835c1219653SRahul Lakkireddy 	payload->exist = true;
836c1219653SRahul Lakkireddy 	payload->start = mem_desc.base;
837c1219653SRahul Lakkireddy 	payload->end = mem_desc.limit;
838c1219653SRahul Lakkireddy 
839c1219653SRahul Lakkireddy 	return cudbg_get_mem_relative(padap, &meminfo, mem_type,
840c1219653SRahul Lakkireddy 				      &payload->start, &payload->end);
841c1219653SRahul Lakkireddy }
842c1219653SRahul Lakkireddy 
843a1c69520SRahul Lakkireddy #define CUDBG_YIELD_ITERATION 256
844a1c69520SRahul Lakkireddy 
845b33af022SRahul Lakkireddy static int cudbg_read_fw_mem(struct cudbg_init *pdbg_init,
846b33af022SRahul Lakkireddy 			     struct cudbg_buffer *dbg_buff, u8 mem_type,
847b33af022SRahul Lakkireddy 			     unsigned long tot_len,
848b33af022SRahul Lakkireddy 			     struct cudbg_error *cudbg_err)
849b33af022SRahul Lakkireddy {
850c1219653SRahul Lakkireddy 	static const char * const region_name[] = { "Tx payload:",
851c1219653SRahul Lakkireddy 						    "Rx payload:" };
852b33af022SRahul Lakkireddy 	unsigned long bytes, bytes_left, bytes_read = 0;
853b33af022SRahul Lakkireddy 	struct adapter *padap = pdbg_init->adap;
854b33af022SRahul Lakkireddy 	struct cudbg_buffer temp_buff = { 0 };
855c1219653SRahul Lakkireddy 	struct cudbg_region_info payload[2];
856a1c69520SRahul Lakkireddy 	u32 yield_count = 0;
857b33af022SRahul Lakkireddy 	int rc = 0;
858c1219653SRahul Lakkireddy 	u8 i;
859c1219653SRahul Lakkireddy 
860c1219653SRahul Lakkireddy 	/* Get TX/RX Payload region range if they exist */
861c1219653SRahul Lakkireddy 	memset(payload, 0, sizeof(payload));
862c1219653SRahul Lakkireddy 	for (i = 0; i < ARRAY_SIZE(region_name); i++) {
863c1219653SRahul Lakkireddy 		rc = cudbg_get_payload_range(padap, mem_type, region_name[i],
864c1219653SRahul Lakkireddy 					     &payload[i]);
865c1219653SRahul Lakkireddy 		if (rc)
866c1219653SRahul Lakkireddy 			return rc;
867c1219653SRahul Lakkireddy 
868c1219653SRahul Lakkireddy 		if (payload[i].exist) {
869c1219653SRahul Lakkireddy 			/* Align start and end to avoid wrap around */
870c1219653SRahul Lakkireddy 			payload[i].start = roundup(payload[i].start,
871c1219653SRahul Lakkireddy 						   CUDBG_CHUNK_SIZE);
872c1219653SRahul Lakkireddy 			payload[i].end = rounddown(payload[i].end,
873c1219653SRahul Lakkireddy 						   CUDBG_CHUNK_SIZE);
874c1219653SRahul Lakkireddy 		}
875c1219653SRahul Lakkireddy 	}
876b33af022SRahul Lakkireddy 
877b33af022SRahul Lakkireddy 	bytes_left = tot_len;
878b33af022SRahul Lakkireddy 	while (bytes_left > 0) {
879a1c69520SRahul Lakkireddy 		/* As MC size is huge and read through PIO access, this
880a1c69520SRahul Lakkireddy 		 * loop will hold cpu for a longer time. OS may think that
881a1c69520SRahul Lakkireddy 		 * the process is hanged and will generate CPU stall traces.
882a1c69520SRahul Lakkireddy 		 * So yield the cpu regularly.
883a1c69520SRahul Lakkireddy 		 */
884a1c69520SRahul Lakkireddy 		yield_count++;
885a1c69520SRahul Lakkireddy 		if (!(yield_count % CUDBG_YIELD_ITERATION))
886a1c69520SRahul Lakkireddy 			schedule();
887a1c69520SRahul Lakkireddy 
888b33af022SRahul Lakkireddy 		bytes = min_t(unsigned long, bytes_left,
889b33af022SRahul Lakkireddy 			      (unsigned long)CUDBG_CHUNK_SIZE);
890b33af022SRahul Lakkireddy 		rc = cudbg_get_buff(dbg_buff, bytes, &temp_buff);
891b33af022SRahul Lakkireddy 		if (rc)
892b33af022SRahul Lakkireddy 			return rc;
893c1219653SRahul Lakkireddy 
894c1219653SRahul Lakkireddy 		for (i = 0; i < ARRAY_SIZE(payload); i++)
895c1219653SRahul Lakkireddy 			if (payload[i].exist &&
896c1219653SRahul Lakkireddy 			    bytes_read >= payload[i].start &&
897c1219653SRahul Lakkireddy 			    bytes_read + bytes <= payload[i].end)
898c1219653SRahul Lakkireddy 				/* TX and RX Payload regions can't overlap */
899c1219653SRahul Lakkireddy 				goto skip_read;
900c1219653SRahul Lakkireddy 
901b33af022SRahul Lakkireddy 		spin_lock(&padap->win0_lock);
902b33af022SRahul Lakkireddy 		rc = t4_memory_rw(padap, MEMWIN_NIC, mem_type,
903b33af022SRahul Lakkireddy 				  bytes_read, bytes,
904b33af022SRahul Lakkireddy 				  (__be32 *)temp_buff.data,
905b33af022SRahul Lakkireddy 				  1);
906b33af022SRahul Lakkireddy 		spin_unlock(&padap->win0_lock);
907b33af022SRahul Lakkireddy 		if (rc) {
908b33af022SRahul Lakkireddy 			cudbg_err->sys_err = rc;
909b33af022SRahul Lakkireddy 			cudbg_put_buff(&temp_buff, dbg_buff);
910b33af022SRahul Lakkireddy 			return rc;
911b33af022SRahul Lakkireddy 		}
912c1219653SRahul Lakkireddy 
913c1219653SRahul Lakkireddy skip_read:
914b33af022SRahul Lakkireddy 		bytes_left -= bytes;
915b33af022SRahul Lakkireddy 		bytes_read += bytes;
916b33af022SRahul Lakkireddy 		cudbg_write_and_release_buff(&temp_buff, dbg_buff);
917b33af022SRahul Lakkireddy 	}
918b33af022SRahul Lakkireddy 	return rc;
919b33af022SRahul Lakkireddy }
920b33af022SRahul Lakkireddy 
921b33af022SRahul Lakkireddy static void cudbg_t4_fwcache(struct cudbg_init *pdbg_init,
922b33af022SRahul Lakkireddy 			     struct cudbg_error *cudbg_err)
923b33af022SRahul Lakkireddy {
924b33af022SRahul Lakkireddy 	struct adapter *padap = pdbg_init->adap;
925b33af022SRahul Lakkireddy 	int rc;
926b33af022SRahul Lakkireddy 
927b33af022SRahul Lakkireddy 	if (is_fw_attached(pdbg_init)) {
928b33af022SRahul Lakkireddy 		/* Flush uP dcache before reading edcX/mcX  */
929b33af022SRahul Lakkireddy 		rc = t4_fwcache(padap, FW_PARAM_DEV_FWCACHE_FLUSH);
930b33af022SRahul Lakkireddy 		if (rc)
931b33af022SRahul Lakkireddy 			cudbg_err->sys_warn = rc;
932b33af022SRahul Lakkireddy 	}
933b33af022SRahul Lakkireddy }
934b33af022SRahul Lakkireddy 
935b33af022SRahul Lakkireddy static int cudbg_collect_mem_region(struct cudbg_init *pdbg_init,
936b33af022SRahul Lakkireddy 				    struct cudbg_buffer *dbg_buff,
937b33af022SRahul Lakkireddy 				    struct cudbg_error *cudbg_err,
938b33af022SRahul Lakkireddy 				    u8 mem_type)
939b33af022SRahul Lakkireddy {
940a1c69520SRahul Lakkireddy 	struct adapter *padap = pdbg_init->adap;
941a1c69520SRahul Lakkireddy 	struct cudbg_meminfo mem_info;
942a1c69520SRahul Lakkireddy 	unsigned long size;
943a1c69520SRahul Lakkireddy 	u8 mc_idx;
944b33af022SRahul Lakkireddy 	int rc;
945b33af022SRahul Lakkireddy 
946a1c69520SRahul Lakkireddy 	memset(&mem_info, 0, sizeof(struct cudbg_meminfo));
947a1c69520SRahul Lakkireddy 	rc = cudbg_fill_meminfo(padap, &mem_info);
948b33af022SRahul Lakkireddy 	if (rc)
949b33af022SRahul Lakkireddy 		return rc;
950a1c69520SRahul Lakkireddy 
951a1c69520SRahul Lakkireddy 	cudbg_t4_fwcache(pdbg_init, cudbg_err);
952a1c69520SRahul Lakkireddy 	rc = cudbg_meminfo_get_mem_index(padap, &mem_info, mem_type, &mc_idx);
953a1c69520SRahul Lakkireddy 	if (rc)
954a1c69520SRahul Lakkireddy 		return rc;
955a1c69520SRahul Lakkireddy 
956a1c69520SRahul Lakkireddy 	size = mem_info.avail[mc_idx].limit - mem_info.avail[mc_idx].base;
957a1c69520SRahul Lakkireddy 	return cudbg_read_fw_mem(pdbg_init, dbg_buff, mem_type, size,
958a1c69520SRahul Lakkireddy 				 cudbg_err);
959b33af022SRahul Lakkireddy }
960b33af022SRahul Lakkireddy 
961b33af022SRahul Lakkireddy int cudbg_collect_edc0_meminfo(struct cudbg_init *pdbg_init,
962b33af022SRahul Lakkireddy 			       struct cudbg_buffer *dbg_buff,
963b33af022SRahul Lakkireddy 			       struct cudbg_error *cudbg_err)
964b33af022SRahul Lakkireddy {
965b33af022SRahul Lakkireddy 	return cudbg_collect_mem_region(pdbg_init, dbg_buff, cudbg_err,
966b33af022SRahul Lakkireddy 					MEM_EDC0);
967b33af022SRahul Lakkireddy }
968b33af022SRahul Lakkireddy 
969b33af022SRahul Lakkireddy int cudbg_collect_edc1_meminfo(struct cudbg_init *pdbg_init,
970b33af022SRahul Lakkireddy 			       struct cudbg_buffer *dbg_buff,
971b33af022SRahul Lakkireddy 			       struct cudbg_error *cudbg_err)
972b33af022SRahul Lakkireddy {
973b33af022SRahul Lakkireddy 	return cudbg_collect_mem_region(pdbg_init, dbg_buff, cudbg_err,
974b33af022SRahul Lakkireddy 					MEM_EDC1);
975b33af022SRahul Lakkireddy }
976844d1b6fSRahul Lakkireddy 
977a1c69520SRahul Lakkireddy int cudbg_collect_mc0_meminfo(struct cudbg_init *pdbg_init,
978a1c69520SRahul Lakkireddy 			      struct cudbg_buffer *dbg_buff,
979a1c69520SRahul Lakkireddy 			      struct cudbg_error *cudbg_err)
980a1c69520SRahul Lakkireddy {
981a1c69520SRahul Lakkireddy 	return cudbg_collect_mem_region(pdbg_init, dbg_buff, cudbg_err,
982a1c69520SRahul Lakkireddy 					MEM_MC0);
983a1c69520SRahul Lakkireddy }
984a1c69520SRahul Lakkireddy 
985a1c69520SRahul Lakkireddy int cudbg_collect_mc1_meminfo(struct cudbg_init *pdbg_init,
986a1c69520SRahul Lakkireddy 			      struct cudbg_buffer *dbg_buff,
987a1c69520SRahul Lakkireddy 			      struct cudbg_error *cudbg_err)
988a1c69520SRahul Lakkireddy {
989a1c69520SRahul Lakkireddy 	return cudbg_collect_mem_region(pdbg_init, dbg_buff, cudbg_err,
990a1c69520SRahul Lakkireddy 					MEM_MC1);
991a1c69520SRahul Lakkireddy }
992a1c69520SRahul Lakkireddy 
9934db0401fSRahul Lakkireddy int cudbg_collect_hma_meminfo(struct cudbg_init *pdbg_init,
9944db0401fSRahul Lakkireddy 			      struct cudbg_buffer *dbg_buff,
9954db0401fSRahul Lakkireddy 			      struct cudbg_error *cudbg_err)
9964db0401fSRahul Lakkireddy {
9974db0401fSRahul Lakkireddy 	return cudbg_collect_mem_region(pdbg_init, dbg_buff, cudbg_err,
9984db0401fSRahul Lakkireddy 					MEM_HMA);
9994db0401fSRahul Lakkireddy }
10004db0401fSRahul Lakkireddy 
100128b44556SRahul Lakkireddy int cudbg_collect_rss(struct cudbg_init *pdbg_init,
100228b44556SRahul Lakkireddy 		      struct cudbg_buffer *dbg_buff,
100328b44556SRahul Lakkireddy 		      struct cudbg_error *cudbg_err)
100428b44556SRahul Lakkireddy {
100528b44556SRahul Lakkireddy 	struct adapter *padap = pdbg_init->adap;
100628b44556SRahul Lakkireddy 	struct cudbg_buffer temp_buff = { 0 };
100728b44556SRahul Lakkireddy 	int rc;
100828b44556SRahul Lakkireddy 
100928b44556SRahul Lakkireddy 	rc = cudbg_get_buff(dbg_buff, RSS_NENTRIES * sizeof(u16), &temp_buff);
101028b44556SRahul Lakkireddy 	if (rc)
101128b44556SRahul Lakkireddy 		return rc;
101228b44556SRahul Lakkireddy 
101328b44556SRahul Lakkireddy 	rc = t4_read_rss(padap, (u16 *)temp_buff.data);
101428b44556SRahul Lakkireddy 	if (rc) {
101528b44556SRahul Lakkireddy 		cudbg_err->sys_err = rc;
101628b44556SRahul Lakkireddy 		cudbg_put_buff(&temp_buff, dbg_buff);
101728b44556SRahul Lakkireddy 		return rc;
101828b44556SRahul Lakkireddy 	}
101928b44556SRahul Lakkireddy 	cudbg_write_and_release_buff(&temp_buff, dbg_buff);
102028b44556SRahul Lakkireddy 	return rc;
102128b44556SRahul Lakkireddy }
102228b44556SRahul Lakkireddy 
102328b44556SRahul Lakkireddy int cudbg_collect_rss_vf_config(struct cudbg_init *pdbg_init,
102428b44556SRahul Lakkireddy 				struct cudbg_buffer *dbg_buff,
102528b44556SRahul Lakkireddy 				struct cudbg_error *cudbg_err)
102628b44556SRahul Lakkireddy {
102728b44556SRahul Lakkireddy 	struct adapter *padap = pdbg_init->adap;
102828b44556SRahul Lakkireddy 	struct cudbg_buffer temp_buff = { 0 };
102928b44556SRahul Lakkireddy 	struct cudbg_rss_vf_conf *vfconf;
103028b44556SRahul Lakkireddy 	int vf, rc, vf_count;
103128b44556SRahul Lakkireddy 
103228b44556SRahul Lakkireddy 	vf_count = padap->params.arch.vfcount;
103328b44556SRahul Lakkireddy 	rc = cudbg_get_buff(dbg_buff,
103428b44556SRahul Lakkireddy 			    vf_count * sizeof(struct cudbg_rss_vf_conf),
103528b44556SRahul Lakkireddy 			    &temp_buff);
103628b44556SRahul Lakkireddy 	if (rc)
103728b44556SRahul Lakkireddy 		return rc;
103828b44556SRahul Lakkireddy 
103928b44556SRahul Lakkireddy 	vfconf = (struct cudbg_rss_vf_conf *)temp_buff.data;
104028b44556SRahul Lakkireddy 	for (vf = 0; vf < vf_count; vf++)
104128b44556SRahul Lakkireddy 		t4_read_rss_vf_config(padap, vf, &vfconf[vf].rss_vf_vfl,
104228b44556SRahul Lakkireddy 				      &vfconf[vf].rss_vf_vfh, true);
104328b44556SRahul Lakkireddy 	cudbg_write_and_release_buff(&temp_buff, dbg_buff);
104428b44556SRahul Lakkireddy 	return rc;
104528b44556SRahul Lakkireddy }
104628b44556SRahul Lakkireddy 
10476f92a654SRahul Lakkireddy int cudbg_collect_path_mtu(struct cudbg_init *pdbg_init,
10486f92a654SRahul Lakkireddy 			   struct cudbg_buffer *dbg_buff,
10496f92a654SRahul Lakkireddy 			   struct cudbg_error *cudbg_err)
10506f92a654SRahul Lakkireddy {
10516f92a654SRahul Lakkireddy 	struct adapter *padap = pdbg_init->adap;
10526f92a654SRahul Lakkireddy 	struct cudbg_buffer temp_buff = { 0 };
10536f92a654SRahul Lakkireddy 	int rc;
10546f92a654SRahul Lakkireddy 
10556f92a654SRahul Lakkireddy 	rc = cudbg_get_buff(dbg_buff, NMTUS * sizeof(u16), &temp_buff);
10566f92a654SRahul Lakkireddy 	if (rc)
10576f92a654SRahul Lakkireddy 		return rc;
10586f92a654SRahul Lakkireddy 
10596f92a654SRahul Lakkireddy 	t4_read_mtu_tbl(padap, (u16 *)temp_buff.data, NULL);
10606f92a654SRahul Lakkireddy 	cudbg_write_and_release_buff(&temp_buff, dbg_buff);
10616f92a654SRahul Lakkireddy 	return rc;
10626f92a654SRahul Lakkireddy }
10636f92a654SRahul Lakkireddy 
10646f92a654SRahul Lakkireddy int cudbg_collect_pm_stats(struct cudbg_init *pdbg_init,
10656f92a654SRahul Lakkireddy 			   struct cudbg_buffer *dbg_buff,
10666f92a654SRahul Lakkireddy 			   struct cudbg_error *cudbg_err)
10676f92a654SRahul Lakkireddy {
10686f92a654SRahul Lakkireddy 	struct adapter *padap = pdbg_init->adap;
10696f92a654SRahul Lakkireddy 	struct cudbg_buffer temp_buff = { 0 };
10706f92a654SRahul Lakkireddy 	struct cudbg_pm_stats *pm_stats_buff;
10716f92a654SRahul Lakkireddy 	int rc;
10726f92a654SRahul Lakkireddy 
10736f92a654SRahul Lakkireddy 	rc = cudbg_get_buff(dbg_buff, sizeof(struct cudbg_pm_stats),
10746f92a654SRahul Lakkireddy 			    &temp_buff);
10756f92a654SRahul Lakkireddy 	if (rc)
10766f92a654SRahul Lakkireddy 		return rc;
10776f92a654SRahul Lakkireddy 
10786f92a654SRahul Lakkireddy 	pm_stats_buff = (struct cudbg_pm_stats *)temp_buff.data;
10796f92a654SRahul Lakkireddy 	t4_pmtx_get_stats(padap, pm_stats_buff->tx_cnt, pm_stats_buff->tx_cyc);
10806f92a654SRahul Lakkireddy 	t4_pmrx_get_stats(padap, pm_stats_buff->rx_cnt, pm_stats_buff->rx_cyc);
10816f92a654SRahul Lakkireddy 	cudbg_write_and_release_buff(&temp_buff, dbg_buff);
10826f92a654SRahul Lakkireddy 	return rc;
10836f92a654SRahul Lakkireddy }
10846f92a654SRahul Lakkireddy 
108508c4901bSRahul Lakkireddy int cudbg_collect_hw_sched(struct cudbg_init *pdbg_init,
108608c4901bSRahul Lakkireddy 			   struct cudbg_buffer *dbg_buff,
108708c4901bSRahul Lakkireddy 			   struct cudbg_error *cudbg_err)
108808c4901bSRahul Lakkireddy {
108908c4901bSRahul Lakkireddy 	struct adapter *padap = pdbg_init->adap;
109008c4901bSRahul Lakkireddy 	struct cudbg_buffer temp_buff = { 0 };
109108c4901bSRahul Lakkireddy 	struct cudbg_hw_sched *hw_sched_buff;
109208c4901bSRahul Lakkireddy 	int i, rc = 0;
109308c4901bSRahul Lakkireddy 
109408c4901bSRahul Lakkireddy 	if (!padap->params.vpd.cclk)
109508c4901bSRahul Lakkireddy 		return CUDBG_STATUS_CCLK_NOT_DEFINED;
109608c4901bSRahul Lakkireddy 
109708c4901bSRahul Lakkireddy 	rc = cudbg_get_buff(dbg_buff, sizeof(struct cudbg_hw_sched),
109808c4901bSRahul Lakkireddy 			    &temp_buff);
109908c4901bSRahul Lakkireddy 	hw_sched_buff = (struct cudbg_hw_sched *)temp_buff.data;
110008c4901bSRahul Lakkireddy 	hw_sched_buff->map = t4_read_reg(padap, TP_TX_MOD_QUEUE_REQ_MAP_A);
110108c4901bSRahul Lakkireddy 	hw_sched_buff->mode = TIMERMODE_G(t4_read_reg(padap, TP_MOD_CONFIG_A));
110208c4901bSRahul Lakkireddy 	t4_read_pace_tbl(padap, hw_sched_buff->pace_tab);
110308c4901bSRahul Lakkireddy 	for (i = 0; i < NTX_SCHED; ++i)
110408c4901bSRahul Lakkireddy 		t4_get_tx_sched(padap, i, &hw_sched_buff->kbps[i],
110508c4901bSRahul Lakkireddy 				&hw_sched_buff->ipg[i], true);
110608c4901bSRahul Lakkireddy 	cudbg_write_and_release_buff(&temp_buff, dbg_buff);
110708c4901bSRahul Lakkireddy 	return rc;
110808c4901bSRahul Lakkireddy }
110908c4901bSRahul Lakkireddy 
11104359cf33SRahul Lakkireddy int cudbg_collect_tp_indirect(struct cudbg_init *pdbg_init,
11114359cf33SRahul Lakkireddy 			      struct cudbg_buffer *dbg_buff,
11124359cf33SRahul Lakkireddy 			      struct cudbg_error *cudbg_err)
11134359cf33SRahul Lakkireddy {
11144359cf33SRahul Lakkireddy 	struct adapter *padap = pdbg_init->adap;
11154359cf33SRahul Lakkireddy 	struct cudbg_buffer temp_buff = { 0 };
11164359cf33SRahul Lakkireddy 	struct ireg_buf *ch_tp_pio;
11174359cf33SRahul Lakkireddy 	int i, rc, n = 0;
11184359cf33SRahul Lakkireddy 	u32 size;
11194359cf33SRahul Lakkireddy 
11204359cf33SRahul Lakkireddy 	if (is_t5(padap->params.chip))
11214359cf33SRahul Lakkireddy 		n = sizeof(t5_tp_pio_array) +
11224359cf33SRahul Lakkireddy 		    sizeof(t5_tp_tm_pio_array) +
11234359cf33SRahul Lakkireddy 		    sizeof(t5_tp_mib_index_array);
11244359cf33SRahul Lakkireddy 	else
11254359cf33SRahul Lakkireddy 		n = sizeof(t6_tp_pio_array) +
11264359cf33SRahul Lakkireddy 		    sizeof(t6_tp_tm_pio_array) +
11274359cf33SRahul Lakkireddy 		    sizeof(t6_tp_mib_index_array);
11284359cf33SRahul Lakkireddy 
11294359cf33SRahul Lakkireddy 	n = n / (IREG_NUM_ELEM * sizeof(u32));
11304359cf33SRahul Lakkireddy 	size = sizeof(struct ireg_buf) * n;
11314359cf33SRahul Lakkireddy 	rc = cudbg_get_buff(dbg_buff, size, &temp_buff);
11324359cf33SRahul Lakkireddy 	if (rc)
11334359cf33SRahul Lakkireddy 		return rc;
11344359cf33SRahul Lakkireddy 
11354359cf33SRahul Lakkireddy 	ch_tp_pio = (struct ireg_buf *)temp_buff.data;
11364359cf33SRahul Lakkireddy 
11374359cf33SRahul Lakkireddy 	/* TP_PIO */
11384359cf33SRahul Lakkireddy 	if (is_t5(padap->params.chip))
11394359cf33SRahul Lakkireddy 		n = sizeof(t5_tp_pio_array) / (IREG_NUM_ELEM * sizeof(u32));
11404359cf33SRahul Lakkireddy 	else if (is_t6(padap->params.chip))
11414359cf33SRahul Lakkireddy 		n = sizeof(t6_tp_pio_array) / (IREG_NUM_ELEM * sizeof(u32));
11424359cf33SRahul Lakkireddy 
11434359cf33SRahul Lakkireddy 	for (i = 0; i < n; i++) {
11444359cf33SRahul Lakkireddy 		struct ireg_field *tp_pio = &ch_tp_pio->tp_pio;
11454359cf33SRahul Lakkireddy 		u32 *buff = ch_tp_pio->outbuf;
11464359cf33SRahul Lakkireddy 
11474359cf33SRahul Lakkireddy 		if (is_t5(padap->params.chip)) {
11484359cf33SRahul Lakkireddy 			tp_pio->ireg_addr = t5_tp_pio_array[i][0];
11494359cf33SRahul Lakkireddy 			tp_pio->ireg_data = t5_tp_pio_array[i][1];
11504359cf33SRahul Lakkireddy 			tp_pio->ireg_local_offset = t5_tp_pio_array[i][2];
11514359cf33SRahul Lakkireddy 			tp_pio->ireg_offset_range = t5_tp_pio_array[i][3];
11524359cf33SRahul Lakkireddy 		} else if (is_t6(padap->params.chip)) {
11534359cf33SRahul Lakkireddy 			tp_pio->ireg_addr = t6_tp_pio_array[i][0];
11544359cf33SRahul Lakkireddy 			tp_pio->ireg_data = t6_tp_pio_array[i][1];
11554359cf33SRahul Lakkireddy 			tp_pio->ireg_local_offset = t6_tp_pio_array[i][2];
11564359cf33SRahul Lakkireddy 			tp_pio->ireg_offset_range = t6_tp_pio_array[i][3];
11574359cf33SRahul Lakkireddy 		}
11584359cf33SRahul Lakkireddy 		t4_tp_pio_read(padap, buff, tp_pio->ireg_offset_range,
11594359cf33SRahul Lakkireddy 			       tp_pio->ireg_local_offset, true);
11604359cf33SRahul Lakkireddy 		ch_tp_pio++;
11614359cf33SRahul Lakkireddy 	}
11624359cf33SRahul Lakkireddy 
11634359cf33SRahul Lakkireddy 	/* TP_TM_PIO */
11644359cf33SRahul Lakkireddy 	if (is_t5(padap->params.chip))
11654359cf33SRahul Lakkireddy 		n = sizeof(t5_tp_tm_pio_array) / (IREG_NUM_ELEM * sizeof(u32));
11664359cf33SRahul Lakkireddy 	else if (is_t6(padap->params.chip))
11674359cf33SRahul Lakkireddy 		n = sizeof(t6_tp_tm_pio_array) / (IREG_NUM_ELEM * sizeof(u32));
11684359cf33SRahul Lakkireddy 
11694359cf33SRahul Lakkireddy 	for (i = 0; i < n; i++) {
11704359cf33SRahul Lakkireddy 		struct ireg_field *tp_pio = &ch_tp_pio->tp_pio;
11714359cf33SRahul Lakkireddy 		u32 *buff = ch_tp_pio->outbuf;
11724359cf33SRahul Lakkireddy 
11734359cf33SRahul Lakkireddy 		if (is_t5(padap->params.chip)) {
11744359cf33SRahul Lakkireddy 			tp_pio->ireg_addr = t5_tp_tm_pio_array[i][0];
11754359cf33SRahul Lakkireddy 			tp_pio->ireg_data = t5_tp_tm_pio_array[i][1];
11764359cf33SRahul Lakkireddy 			tp_pio->ireg_local_offset = t5_tp_tm_pio_array[i][2];
11774359cf33SRahul Lakkireddy 			tp_pio->ireg_offset_range = t5_tp_tm_pio_array[i][3];
11784359cf33SRahul Lakkireddy 		} else if (is_t6(padap->params.chip)) {
11794359cf33SRahul Lakkireddy 			tp_pio->ireg_addr = t6_tp_tm_pio_array[i][0];
11804359cf33SRahul Lakkireddy 			tp_pio->ireg_data = t6_tp_tm_pio_array[i][1];
11814359cf33SRahul Lakkireddy 			tp_pio->ireg_local_offset = t6_tp_tm_pio_array[i][2];
11824359cf33SRahul Lakkireddy 			tp_pio->ireg_offset_range = t6_tp_tm_pio_array[i][3];
11834359cf33SRahul Lakkireddy 		}
11844359cf33SRahul Lakkireddy 		t4_tp_tm_pio_read(padap, buff, tp_pio->ireg_offset_range,
11854359cf33SRahul Lakkireddy 				  tp_pio->ireg_local_offset, true);
11864359cf33SRahul Lakkireddy 		ch_tp_pio++;
11874359cf33SRahul Lakkireddy 	}
11884359cf33SRahul Lakkireddy 
11894359cf33SRahul Lakkireddy 	/* TP_MIB_INDEX */
11904359cf33SRahul Lakkireddy 	if (is_t5(padap->params.chip))
11914359cf33SRahul Lakkireddy 		n = sizeof(t5_tp_mib_index_array) /
11924359cf33SRahul Lakkireddy 		    (IREG_NUM_ELEM * sizeof(u32));
11934359cf33SRahul Lakkireddy 	else if (is_t6(padap->params.chip))
11944359cf33SRahul Lakkireddy 		n = sizeof(t6_tp_mib_index_array) /
11954359cf33SRahul Lakkireddy 		    (IREG_NUM_ELEM * sizeof(u32));
11964359cf33SRahul Lakkireddy 
11974359cf33SRahul Lakkireddy 	for (i = 0; i < n ; i++) {
11984359cf33SRahul Lakkireddy 		struct ireg_field *tp_pio = &ch_tp_pio->tp_pio;
11994359cf33SRahul Lakkireddy 		u32 *buff = ch_tp_pio->outbuf;
12004359cf33SRahul Lakkireddy 
12014359cf33SRahul Lakkireddy 		if (is_t5(padap->params.chip)) {
12024359cf33SRahul Lakkireddy 			tp_pio->ireg_addr = t5_tp_mib_index_array[i][0];
12034359cf33SRahul Lakkireddy 			tp_pio->ireg_data = t5_tp_mib_index_array[i][1];
12044359cf33SRahul Lakkireddy 			tp_pio->ireg_local_offset =
12054359cf33SRahul Lakkireddy 				t5_tp_mib_index_array[i][2];
12064359cf33SRahul Lakkireddy 			tp_pio->ireg_offset_range =
12074359cf33SRahul Lakkireddy 				t5_tp_mib_index_array[i][3];
12084359cf33SRahul Lakkireddy 		} else if (is_t6(padap->params.chip)) {
12094359cf33SRahul Lakkireddy 			tp_pio->ireg_addr = t6_tp_mib_index_array[i][0];
12104359cf33SRahul Lakkireddy 			tp_pio->ireg_data = t6_tp_mib_index_array[i][1];
12114359cf33SRahul Lakkireddy 			tp_pio->ireg_local_offset =
12124359cf33SRahul Lakkireddy 				t6_tp_mib_index_array[i][2];
12134359cf33SRahul Lakkireddy 			tp_pio->ireg_offset_range =
12144359cf33SRahul Lakkireddy 				t6_tp_mib_index_array[i][3];
12154359cf33SRahul Lakkireddy 		}
12164359cf33SRahul Lakkireddy 		t4_tp_mib_read(padap, buff, tp_pio->ireg_offset_range,
12174359cf33SRahul Lakkireddy 			       tp_pio->ireg_local_offset, true);
12184359cf33SRahul Lakkireddy 		ch_tp_pio++;
12194359cf33SRahul Lakkireddy 	}
12204359cf33SRahul Lakkireddy 	cudbg_write_and_release_buff(&temp_buff, dbg_buff);
12214359cf33SRahul Lakkireddy 	return rc;
12224359cf33SRahul Lakkireddy }
12234359cf33SRahul Lakkireddy 
1224270d39bfSRahul Lakkireddy int cudbg_collect_sge_indirect(struct cudbg_init *pdbg_init,
1225270d39bfSRahul Lakkireddy 			       struct cudbg_buffer *dbg_buff,
1226270d39bfSRahul Lakkireddy 			       struct cudbg_error *cudbg_err)
1227270d39bfSRahul Lakkireddy {
1228270d39bfSRahul Lakkireddy 	struct adapter *padap = pdbg_init->adap;
1229270d39bfSRahul Lakkireddy 	struct cudbg_buffer temp_buff = { 0 };
1230270d39bfSRahul Lakkireddy 	struct ireg_buf *ch_sge_dbg;
1231270d39bfSRahul Lakkireddy 	int i, rc;
1232270d39bfSRahul Lakkireddy 
1233270d39bfSRahul Lakkireddy 	rc = cudbg_get_buff(dbg_buff, sizeof(*ch_sge_dbg) * 2, &temp_buff);
1234270d39bfSRahul Lakkireddy 	if (rc)
1235270d39bfSRahul Lakkireddy 		return rc;
1236270d39bfSRahul Lakkireddy 
1237270d39bfSRahul Lakkireddy 	ch_sge_dbg = (struct ireg_buf *)temp_buff.data;
1238270d39bfSRahul Lakkireddy 	for (i = 0; i < 2; i++) {
1239270d39bfSRahul Lakkireddy 		struct ireg_field *sge_pio = &ch_sge_dbg->tp_pio;
1240270d39bfSRahul Lakkireddy 		u32 *buff = ch_sge_dbg->outbuf;
1241270d39bfSRahul Lakkireddy 
1242270d39bfSRahul Lakkireddy 		sge_pio->ireg_addr = t5_sge_dbg_index_array[i][0];
1243270d39bfSRahul Lakkireddy 		sge_pio->ireg_data = t5_sge_dbg_index_array[i][1];
1244270d39bfSRahul Lakkireddy 		sge_pio->ireg_local_offset = t5_sge_dbg_index_array[i][2];
1245270d39bfSRahul Lakkireddy 		sge_pio->ireg_offset_range = t5_sge_dbg_index_array[i][3];
1246270d39bfSRahul Lakkireddy 		t4_read_indirect(padap,
1247270d39bfSRahul Lakkireddy 				 sge_pio->ireg_addr,
1248270d39bfSRahul Lakkireddy 				 sge_pio->ireg_data,
1249270d39bfSRahul Lakkireddy 				 buff,
1250270d39bfSRahul Lakkireddy 				 sge_pio->ireg_offset_range,
1251270d39bfSRahul Lakkireddy 				 sge_pio->ireg_local_offset);
1252270d39bfSRahul Lakkireddy 		ch_sge_dbg++;
1253270d39bfSRahul Lakkireddy 	}
1254270d39bfSRahul Lakkireddy 	cudbg_write_and_release_buff(&temp_buff, dbg_buff);
1255270d39bfSRahul Lakkireddy 	return rc;
1256270d39bfSRahul Lakkireddy }
1257270d39bfSRahul Lakkireddy 
125827887bc7SRahul Lakkireddy int cudbg_collect_ulprx_la(struct cudbg_init *pdbg_init,
125927887bc7SRahul Lakkireddy 			   struct cudbg_buffer *dbg_buff,
126027887bc7SRahul Lakkireddy 			   struct cudbg_error *cudbg_err)
126127887bc7SRahul Lakkireddy {
126227887bc7SRahul Lakkireddy 	struct adapter *padap = pdbg_init->adap;
126327887bc7SRahul Lakkireddy 	struct cudbg_buffer temp_buff = { 0 };
126427887bc7SRahul Lakkireddy 	struct cudbg_ulprx_la *ulprx_la_buff;
126527887bc7SRahul Lakkireddy 	int rc;
126627887bc7SRahul Lakkireddy 
126727887bc7SRahul Lakkireddy 	rc = cudbg_get_buff(dbg_buff, sizeof(struct cudbg_ulprx_la),
126827887bc7SRahul Lakkireddy 			    &temp_buff);
126927887bc7SRahul Lakkireddy 	if (rc)
127027887bc7SRahul Lakkireddy 		return rc;
127127887bc7SRahul Lakkireddy 
127227887bc7SRahul Lakkireddy 	ulprx_la_buff = (struct cudbg_ulprx_la *)temp_buff.data;
127327887bc7SRahul Lakkireddy 	t4_ulprx_read_la(padap, (u32 *)ulprx_la_buff->data);
127427887bc7SRahul Lakkireddy 	ulprx_la_buff->size = ULPRX_LA_SIZE;
127527887bc7SRahul Lakkireddy 	cudbg_write_and_release_buff(&temp_buff, dbg_buff);
127627887bc7SRahul Lakkireddy 	return rc;
127727887bc7SRahul Lakkireddy }
127827887bc7SRahul Lakkireddy 
127927887bc7SRahul Lakkireddy int cudbg_collect_tp_la(struct cudbg_init *pdbg_init,
128027887bc7SRahul Lakkireddy 			struct cudbg_buffer *dbg_buff,
128127887bc7SRahul Lakkireddy 			struct cudbg_error *cudbg_err)
128227887bc7SRahul Lakkireddy {
128327887bc7SRahul Lakkireddy 	struct adapter *padap = pdbg_init->adap;
128427887bc7SRahul Lakkireddy 	struct cudbg_buffer temp_buff = { 0 };
128527887bc7SRahul Lakkireddy 	struct cudbg_tp_la *tp_la_buff;
128627887bc7SRahul Lakkireddy 	int size, rc;
128727887bc7SRahul Lakkireddy 
128827887bc7SRahul Lakkireddy 	size = sizeof(struct cudbg_tp_la) + TPLA_SIZE *  sizeof(u64);
128927887bc7SRahul Lakkireddy 	rc = cudbg_get_buff(dbg_buff, size, &temp_buff);
129027887bc7SRahul Lakkireddy 	if (rc)
129127887bc7SRahul Lakkireddy 		return rc;
129227887bc7SRahul Lakkireddy 
129327887bc7SRahul Lakkireddy 	tp_la_buff = (struct cudbg_tp_la *)temp_buff.data;
129427887bc7SRahul Lakkireddy 	tp_la_buff->mode = DBGLAMODE_G(t4_read_reg(padap, TP_DBG_LA_CONFIG_A));
129527887bc7SRahul Lakkireddy 	t4_tp_read_la(padap, (u64 *)tp_la_buff->data, NULL);
129627887bc7SRahul Lakkireddy 	cudbg_write_and_release_buff(&temp_buff, dbg_buff);
129727887bc7SRahul Lakkireddy 	return rc;
129827887bc7SRahul Lakkireddy }
129927887bc7SRahul Lakkireddy 
1300123e25c4SRahul Lakkireddy int cudbg_collect_meminfo(struct cudbg_init *pdbg_init,
1301123e25c4SRahul Lakkireddy 			  struct cudbg_buffer *dbg_buff,
1302123e25c4SRahul Lakkireddy 			  struct cudbg_error *cudbg_err)
1303123e25c4SRahul Lakkireddy {
1304123e25c4SRahul Lakkireddy 	struct adapter *padap = pdbg_init->adap;
1305123e25c4SRahul Lakkireddy 	struct cudbg_buffer temp_buff = { 0 };
1306123e25c4SRahul Lakkireddy 	struct cudbg_meminfo *meminfo_buff;
1307123e25c4SRahul Lakkireddy 	int rc;
1308123e25c4SRahul Lakkireddy 
1309123e25c4SRahul Lakkireddy 	rc = cudbg_get_buff(dbg_buff, sizeof(struct cudbg_meminfo), &temp_buff);
1310123e25c4SRahul Lakkireddy 	if (rc)
1311123e25c4SRahul Lakkireddy 		return rc;
1312123e25c4SRahul Lakkireddy 
1313123e25c4SRahul Lakkireddy 	meminfo_buff = (struct cudbg_meminfo *)temp_buff.data;
1314123e25c4SRahul Lakkireddy 	rc = cudbg_fill_meminfo(padap, meminfo_buff);
1315123e25c4SRahul Lakkireddy 	if (rc) {
1316123e25c4SRahul Lakkireddy 		cudbg_err->sys_err = rc;
1317123e25c4SRahul Lakkireddy 		cudbg_put_buff(&temp_buff, dbg_buff);
1318123e25c4SRahul Lakkireddy 		return rc;
1319123e25c4SRahul Lakkireddy 	}
1320123e25c4SRahul Lakkireddy 
1321123e25c4SRahul Lakkireddy 	cudbg_write_and_release_buff(&temp_buff, dbg_buff);
1322123e25c4SRahul Lakkireddy 	return rc;
1323123e25c4SRahul Lakkireddy }
1324123e25c4SRahul Lakkireddy 
132527887bc7SRahul Lakkireddy int cudbg_collect_cim_pif_la(struct cudbg_init *pdbg_init,
132627887bc7SRahul Lakkireddy 			     struct cudbg_buffer *dbg_buff,
132727887bc7SRahul Lakkireddy 			     struct cudbg_error *cudbg_err)
132827887bc7SRahul Lakkireddy {
132927887bc7SRahul Lakkireddy 	struct cudbg_cim_pif_la *cim_pif_la_buff;
133027887bc7SRahul Lakkireddy 	struct adapter *padap = pdbg_init->adap;
133127887bc7SRahul Lakkireddy 	struct cudbg_buffer temp_buff = { 0 };
133227887bc7SRahul Lakkireddy 	int size, rc;
133327887bc7SRahul Lakkireddy 
133427887bc7SRahul Lakkireddy 	size = sizeof(struct cudbg_cim_pif_la) +
133527887bc7SRahul Lakkireddy 	       2 * CIM_PIFLA_SIZE * 6 * sizeof(u32);
133627887bc7SRahul Lakkireddy 	rc = cudbg_get_buff(dbg_buff, size, &temp_buff);
133727887bc7SRahul Lakkireddy 	if (rc)
133827887bc7SRahul Lakkireddy 		return rc;
133927887bc7SRahul Lakkireddy 
134027887bc7SRahul Lakkireddy 	cim_pif_la_buff = (struct cudbg_cim_pif_la *)temp_buff.data;
134127887bc7SRahul Lakkireddy 	cim_pif_la_buff->size = CIM_PIFLA_SIZE;
134227887bc7SRahul Lakkireddy 	t4_cim_read_pif_la(padap, (u32 *)cim_pif_la_buff->data,
134327887bc7SRahul Lakkireddy 			   (u32 *)cim_pif_la_buff->data + 6 * CIM_PIFLA_SIZE,
134427887bc7SRahul Lakkireddy 			   NULL, NULL);
134527887bc7SRahul Lakkireddy 	cudbg_write_and_release_buff(&temp_buff, dbg_buff);
134627887bc7SRahul Lakkireddy 	return rc;
134727887bc7SRahul Lakkireddy }
134827887bc7SRahul Lakkireddy 
13496f92a654SRahul Lakkireddy int cudbg_collect_clk_info(struct cudbg_init *pdbg_init,
13506f92a654SRahul Lakkireddy 			   struct cudbg_buffer *dbg_buff,
13516f92a654SRahul Lakkireddy 			   struct cudbg_error *cudbg_err)
13526f92a654SRahul Lakkireddy {
13536f92a654SRahul Lakkireddy 	struct adapter *padap = pdbg_init->adap;
13546f92a654SRahul Lakkireddy 	struct cudbg_buffer temp_buff = { 0 };
13556f92a654SRahul Lakkireddy 	struct cudbg_clk_info *clk_info_buff;
13566f92a654SRahul Lakkireddy 	u64 tp_tick_us;
13576f92a654SRahul Lakkireddy 	int rc;
13586f92a654SRahul Lakkireddy 
13596f92a654SRahul Lakkireddy 	if (!padap->params.vpd.cclk)
13606f92a654SRahul Lakkireddy 		return CUDBG_STATUS_CCLK_NOT_DEFINED;
13616f92a654SRahul Lakkireddy 
13626f92a654SRahul Lakkireddy 	rc = cudbg_get_buff(dbg_buff, sizeof(struct cudbg_clk_info),
13636f92a654SRahul Lakkireddy 			    &temp_buff);
13646f92a654SRahul Lakkireddy 	if (rc)
13656f92a654SRahul Lakkireddy 		return rc;
13666f92a654SRahul Lakkireddy 
13676f92a654SRahul Lakkireddy 	clk_info_buff = (struct cudbg_clk_info *)temp_buff.data;
13686f92a654SRahul Lakkireddy 	clk_info_buff->cclk_ps = 1000000000 / padap->params.vpd.cclk; /* psec */
13696f92a654SRahul Lakkireddy 	clk_info_buff->res = t4_read_reg(padap, TP_TIMER_RESOLUTION_A);
13706f92a654SRahul Lakkireddy 	clk_info_buff->tre = TIMERRESOLUTION_G(clk_info_buff->res);
13716f92a654SRahul Lakkireddy 	clk_info_buff->dack_re = DELAYEDACKRESOLUTION_G(clk_info_buff->res);
13726f92a654SRahul Lakkireddy 	tp_tick_us = (clk_info_buff->cclk_ps << clk_info_buff->tre) / 1000000;
13736f92a654SRahul Lakkireddy 
13746f92a654SRahul Lakkireddy 	clk_info_buff->dack_timer =
13756f92a654SRahul Lakkireddy 		(clk_info_buff->cclk_ps << clk_info_buff->dack_re) / 1000000 *
13766f92a654SRahul Lakkireddy 		t4_read_reg(padap, TP_DACK_TIMER_A);
13776f92a654SRahul Lakkireddy 	clk_info_buff->retransmit_min =
13786f92a654SRahul Lakkireddy 		tp_tick_us * t4_read_reg(padap, TP_RXT_MIN_A);
13796f92a654SRahul Lakkireddy 	clk_info_buff->retransmit_max =
13806f92a654SRahul Lakkireddy 		tp_tick_us * t4_read_reg(padap, TP_RXT_MAX_A);
13816f92a654SRahul Lakkireddy 	clk_info_buff->persist_timer_min =
13826f92a654SRahul Lakkireddy 		tp_tick_us * t4_read_reg(padap, TP_PERS_MIN_A);
13836f92a654SRahul Lakkireddy 	clk_info_buff->persist_timer_max =
13846f92a654SRahul Lakkireddy 		tp_tick_us * t4_read_reg(padap, TP_PERS_MAX_A);
13856f92a654SRahul Lakkireddy 	clk_info_buff->keepalive_idle_timer =
13866f92a654SRahul Lakkireddy 		tp_tick_us * t4_read_reg(padap, TP_KEEP_IDLE_A);
13876f92a654SRahul Lakkireddy 	clk_info_buff->keepalive_interval =
13886f92a654SRahul Lakkireddy 		tp_tick_us * t4_read_reg(padap, TP_KEEP_INTVL_A);
13896f92a654SRahul Lakkireddy 	clk_info_buff->initial_srtt =
13906f92a654SRahul Lakkireddy 		tp_tick_us * INITSRTT_G(t4_read_reg(padap, TP_INIT_SRTT_A));
13916f92a654SRahul Lakkireddy 	clk_info_buff->finwait2_timer =
13926f92a654SRahul Lakkireddy 		tp_tick_us * t4_read_reg(padap, TP_FINWAIT2_TIMER_A);
13936f92a654SRahul Lakkireddy 
13946f92a654SRahul Lakkireddy 	cudbg_write_and_release_buff(&temp_buff, dbg_buff);
13956f92a654SRahul Lakkireddy 	return rc;
13966f92a654SRahul Lakkireddy }
13976f92a654SRahul Lakkireddy 
1398270d39bfSRahul Lakkireddy int cudbg_collect_pcie_indirect(struct cudbg_init *pdbg_init,
1399270d39bfSRahul Lakkireddy 				struct cudbg_buffer *dbg_buff,
1400270d39bfSRahul Lakkireddy 				struct cudbg_error *cudbg_err)
1401270d39bfSRahul Lakkireddy {
1402270d39bfSRahul Lakkireddy 	struct adapter *padap = pdbg_init->adap;
1403270d39bfSRahul Lakkireddy 	struct cudbg_buffer temp_buff = { 0 };
1404270d39bfSRahul Lakkireddy 	struct ireg_buf *ch_pcie;
1405270d39bfSRahul Lakkireddy 	int i, rc, n;
1406270d39bfSRahul Lakkireddy 	u32 size;
1407270d39bfSRahul Lakkireddy 
1408270d39bfSRahul Lakkireddy 	n = sizeof(t5_pcie_pdbg_array) / (IREG_NUM_ELEM * sizeof(u32));
1409270d39bfSRahul Lakkireddy 	size = sizeof(struct ireg_buf) * n * 2;
1410270d39bfSRahul Lakkireddy 	rc = cudbg_get_buff(dbg_buff, size, &temp_buff);
1411270d39bfSRahul Lakkireddy 	if (rc)
1412270d39bfSRahul Lakkireddy 		return rc;
1413270d39bfSRahul Lakkireddy 
1414270d39bfSRahul Lakkireddy 	ch_pcie = (struct ireg_buf *)temp_buff.data;
1415270d39bfSRahul Lakkireddy 	/* PCIE_PDBG */
1416270d39bfSRahul Lakkireddy 	for (i = 0; i < n; i++) {
1417270d39bfSRahul Lakkireddy 		struct ireg_field *pcie_pio = &ch_pcie->tp_pio;
1418270d39bfSRahul Lakkireddy 		u32 *buff = ch_pcie->outbuf;
1419270d39bfSRahul Lakkireddy 
1420270d39bfSRahul Lakkireddy 		pcie_pio->ireg_addr = t5_pcie_pdbg_array[i][0];
1421270d39bfSRahul Lakkireddy 		pcie_pio->ireg_data = t5_pcie_pdbg_array[i][1];
1422270d39bfSRahul Lakkireddy 		pcie_pio->ireg_local_offset = t5_pcie_pdbg_array[i][2];
1423270d39bfSRahul Lakkireddy 		pcie_pio->ireg_offset_range = t5_pcie_pdbg_array[i][3];
1424270d39bfSRahul Lakkireddy 		t4_read_indirect(padap,
1425270d39bfSRahul Lakkireddy 				 pcie_pio->ireg_addr,
1426270d39bfSRahul Lakkireddy 				 pcie_pio->ireg_data,
1427270d39bfSRahul Lakkireddy 				 buff,
1428270d39bfSRahul Lakkireddy 				 pcie_pio->ireg_offset_range,
1429270d39bfSRahul Lakkireddy 				 pcie_pio->ireg_local_offset);
1430270d39bfSRahul Lakkireddy 		ch_pcie++;
1431270d39bfSRahul Lakkireddy 	}
1432270d39bfSRahul Lakkireddy 
1433270d39bfSRahul Lakkireddy 	/* PCIE_CDBG */
1434270d39bfSRahul Lakkireddy 	n = sizeof(t5_pcie_cdbg_array) / (IREG_NUM_ELEM * sizeof(u32));
1435270d39bfSRahul Lakkireddy 	for (i = 0; i < n; i++) {
1436270d39bfSRahul Lakkireddy 		struct ireg_field *pcie_pio = &ch_pcie->tp_pio;
1437270d39bfSRahul Lakkireddy 		u32 *buff = ch_pcie->outbuf;
1438270d39bfSRahul Lakkireddy 
1439270d39bfSRahul Lakkireddy 		pcie_pio->ireg_addr = t5_pcie_cdbg_array[i][0];
1440270d39bfSRahul Lakkireddy 		pcie_pio->ireg_data = t5_pcie_cdbg_array[i][1];
1441270d39bfSRahul Lakkireddy 		pcie_pio->ireg_local_offset = t5_pcie_cdbg_array[i][2];
1442270d39bfSRahul Lakkireddy 		pcie_pio->ireg_offset_range = t5_pcie_cdbg_array[i][3];
1443270d39bfSRahul Lakkireddy 		t4_read_indirect(padap,
1444270d39bfSRahul Lakkireddy 				 pcie_pio->ireg_addr,
1445270d39bfSRahul Lakkireddy 				 pcie_pio->ireg_data,
1446270d39bfSRahul Lakkireddy 				 buff,
1447270d39bfSRahul Lakkireddy 				 pcie_pio->ireg_offset_range,
1448270d39bfSRahul Lakkireddy 				 pcie_pio->ireg_local_offset);
1449270d39bfSRahul Lakkireddy 		ch_pcie++;
1450270d39bfSRahul Lakkireddy 	}
1451270d39bfSRahul Lakkireddy 	cudbg_write_and_release_buff(&temp_buff, dbg_buff);
1452270d39bfSRahul Lakkireddy 	return rc;
1453270d39bfSRahul Lakkireddy }
1454270d39bfSRahul Lakkireddy 
1455270d39bfSRahul Lakkireddy int cudbg_collect_pm_indirect(struct cudbg_init *pdbg_init,
1456270d39bfSRahul Lakkireddy 			      struct cudbg_buffer *dbg_buff,
1457270d39bfSRahul Lakkireddy 			      struct cudbg_error *cudbg_err)
1458270d39bfSRahul Lakkireddy {
1459270d39bfSRahul Lakkireddy 	struct adapter *padap = pdbg_init->adap;
1460270d39bfSRahul Lakkireddy 	struct cudbg_buffer temp_buff = { 0 };
1461270d39bfSRahul Lakkireddy 	struct ireg_buf *ch_pm;
1462270d39bfSRahul Lakkireddy 	int i, rc, n;
1463270d39bfSRahul Lakkireddy 	u32 size;
1464270d39bfSRahul Lakkireddy 
1465270d39bfSRahul Lakkireddy 	n = sizeof(t5_pm_rx_array) / (IREG_NUM_ELEM * sizeof(u32));
1466270d39bfSRahul Lakkireddy 	size = sizeof(struct ireg_buf) * n * 2;
1467270d39bfSRahul Lakkireddy 	rc = cudbg_get_buff(dbg_buff, size, &temp_buff);
1468270d39bfSRahul Lakkireddy 	if (rc)
1469270d39bfSRahul Lakkireddy 		return rc;
1470270d39bfSRahul Lakkireddy 
1471270d39bfSRahul Lakkireddy 	ch_pm = (struct ireg_buf *)temp_buff.data;
1472270d39bfSRahul Lakkireddy 	/* PM_RX */
1473270d39bfSRahul Lakkireddy 	for (i = 0; i < n; i++) {
1474270d39bfSRahul Lakkireddy 		struct ireg_field *pm_pio = &ch_pm->tp_pio;
1475270d39bfSRahul Lakkireddy 		u32 *buff = ch_pm->outbuf;
1476270d39bfSRahul Lakkireddy 
1477270d39bfSRahul Lakkireddy 		pm_pio->ireg_addr = t5_pm_rx_array[i][0];
1478270d39bfSRahul Lakkireddy 		pm_pio->ireg_data = t5_pm_rx_array[i][1];
1479270d39bfSRahul Lakkireddy 		pm_pio->ireg_local_offset = t5_pm_rx_array[i][2];
1480270d39bfSRahul Lakkireddy 		pm_pio->ireg_offset_range = t5_pm_rx_array[i][3];
1481270d39bfSRahul Lakkireddy 		t4_read_indirect(padap,
1482270d39bfSRahul Lakkireddy 				 pm_pio->ireg_addr,
1483270d39bfSRahul Lakkireddy 				 pm_pio->ireg_data,
1484270d39bfSRahul Lakkireddy 				 buff,
1485270d39bfSRahul Lakkireddy 				 pm_pio->ireg_offset_range,
1486270d39bfSRahul Lakkireddy 				 pm_pio->ireg_local_offset);
1487270d39bfSRahul Lakkireddy 		ch_pm++;
1488270d39bfSRahul Lakkireddy 	}
1489270d39bfSRahul Lakkireddy 
1490270d39bfSRahul Lakkireddy 	/* PM_TX */
1491270d39bfSRahul Lakkireddy 	n = sizeof(t5_pm_tx_array) / (IREG_NUM_ELEM * sizeof(u32));
1492270d39bfSRahul Lakkireddy 	for (i = 0; i < n; i++) {
1493270d39bfSRahul Lakkireddy 		struct ireg_field *pm_pio = &ch_pm->tp_pio;
1494270d39bfSRahul Lakkireddy 		u32 *buff = ch_pm->outbuf;
1495270d39bfSRahul Lakkireddy 
1496270d39bfSRahul Lakkireddy 		pm_pio->ireg_addr = t5_pm_tx_array[i][0];
1497270d39bfSRahul Lakkireddy 		pm_pio->ireg_data = t5_pm_tx_array[i][1];
1498270d39bfSRahul Lakkireddy 		pm_pio->ireg_local_offset = t5_pm_tx_array[i][2];
1499270d39bfSRahul Lakkireddy 		pm_pio->ireg_offset_range = t5_pm_tx_array[i][3];
1500270d39bfSRahul Lakkireddy 		t4_read_indirect(padap,
1501270d39bfSRahul Lakkireddy 				 pm_pio->ireg_addr,
1502270d39bfSRahul Lakkireddy 				 pm_pio->ireg_data,
1503270d39bfSRahul Lakkireddy 				 buff,
1504270d39bfSRahul Lakkireddy 				 pm_pio->ireg_offset_range,
1505270d39bfSRahul Lakkireddy 				 pm_pio->ireg_local_offset);
1506270d39bfSRahul Lakkireddy 		ch_pm++;
1507270d39bfSRahul Lakkireddy 	}
1508270d39bfSRahul Lakkireddy 	cudbg_write_and_release_buff(&temp_buff, dbg_buff);
1509270d39bfSRahul Lakkireddy 	return rc;
1510270d39bfSRahul Lakkireddy }
1511270d39bfSRahul Lakkireddy 
15129030e498SRahul Lakkireddy int cudbg_collect_tid(struct cudbg_init *pdbg_init,
15139030e498SRahul Lakkireddy 		      struct cudbg_buffer *dbg_buff,
15149030e498SRahul Lakkireddy 		      struct cudbg_error *cudbg_err)
15159030e498SRahul Lakkireddy {
15169030e498SRahul Lakkireddy 	struct adapter *padap = pdbg_init->adap;
15179030e498SRahul Lakkireddy 	struct cudbg_tid_info_region_rev1 *tid1;
15189030e498SRahul Lakkireddy 	struct cudbg_buffer temp_buff = { 0 };
15199030e498SRahul Lakkireddy 	struct cudbg_tid_info_region *tid;
15209030e498SRahul Lakkireddy 	u32 para[2], val[2];
15219030e498SRahul Lakkireddy 	int rc;
15229030e498SRahul Lakkireddy 
15239030e498SRahul Lakkireddy 	rc = cudbg_get_buff(dbg_buff, sizeof(struct cudbg_tid_info_region_rev1),
15249030e498SRahul Lakkireddy 			    &temp_buff);
15259030e498SRahul Lakkireddy 	if (rc)
15269030e498SRahul Lakkireddy 		return rc;
15279030e498SRahul Lakkireddy 
15289030e498SRahul Lakkireddy 	tid1 = (struct cudbg_tid_info_region_rev1 *)temp_buff.data;
15299030e498SRahul Lakkireddy 	tid = &tid1->tid;
15309030e498SRahul Lakkireddy 	tid1->ver_hdr.signature = CUDBG_ENTITY_SIGNATURE;
15319030e498SRahul Lakkireddy 	tid1->ver_hdr.revision = CUDBG_TID_INFO_REV;
15329030e498SRahul Lakkireddy 	tid1->ver_hdr.size = sizeof(struct cudbg_tid_info_region_rev1) -
15339030e498SRahul Lakkireddy 			     sizeof(struct cudbg_ver_hdr);
15349030e498SRahul Lakkireddy 
15359030e498SRahul Lakkireddy #define FW_PARAM_PFVF_A(param) \
15369030e498SRahul Lakkireddy 	(FW_PARAMS_MNEM_V(FW_PARAMS_MNEM_PFVF) | \
15379030e498SRahul Lakkireddy 	 FW_PARAMS_PARAM_X_V(FW_PARAMS_PARAM_PFVF_##param) | \
15389030e498SRahul Lakkireddy 	 FW_PARAMS_PARAM_Y_V(0) | \
15399030e498SRahul Lakkireddy 	 FW_PARAMS_PARAM_Z_V(0))
15409030e498SRahul Lakkireddy 
15419030e498SRahul Lakkireddy 	para[0] = FW_PARAM_PFVF_A(ETHOFLD_START);
15429030e498SRahul Lakkireddy 	para[1] = FW_PARAM_PFVF_A(ETHOFLD_END);
15439030e498SRahul Lakkireddy 	rc = t4_query_params(padap, padap->mbox, padap->pf, 0, 2, para, val);
15449030e498SRahul Lakkireddy 	if (rc <  0) {
15459030e498SRahul Lakkireddy 		cudbg_err->sys_err = rc;
15469030e498SRahul Lakkireddy 		cudbg_put_buff(&temp_buff, dbg_buff);
15479030e498SRahul Lakkireddy 		return rc;
15489030e498SRahul Lakkireddy 	}
15499030e498SRahul Lakkireddy 	tid->uotid_base = val[0];
15509030e498SRahul Lakkireddy 	tid->nuotids = val[1] - val[0] + 1;
15519030e498SRahul Lakkireddy 
15529030e498SRahul Lakkireddy 	if (is_t5(padap->params.chip)) {
15539030e498SRahul Lakkireddy 		tid->sb = t4_read_reg(padap, LE_DB_SERVER_INDEX_A) / 4;
15549030e498SRahul Lakkireddy 	} else if (is_t6(padap->params.chip)) {
15559030e498SRahul Lakkireddy 		tid1->tid_start =
15569030e498SRahul Lakkireddy 			t4_read_reg(padap, LE_DB_ACTIVE_TABLE_START_INDEX_A);
15579030e498SRahul Lakkireddy 		tid->sb = t4_read_reg(padap, LE_DB_SRVR_START_INDEX_A);
15589030e498SRahul Lakkireddy 
15599030e498SRahul Lakkireddy 		para[0] = FW_PARAM_PFVF_A(HPFILTER_START);
15609030e498SRahul Lakkireddy 		para[1] = FW_PARAM_PFVF_A(HPFILTER_END);
15619030e498SRahul Lakkireddy 		rc = t4_query_params(padap, padap->mbox, padap->pf, 0, 2,
15629030e498SRahul Lakkireddy 				     para, val);
15639030e498SRahul Lakkireddy 		if (rc < 0) {
15649030e498SRahul Lakkireddy 			cudbg_err->sys_err = rc;
15659030e498SRahul Lakkireddy 			cudbg_put_buff(&temp_buff, dbg_buff);
15669030e498SRahul Lakkireddy 			return rc;
15679030e498SRahul Lakkireddy 		}
15689030e498SRahul Lakkireddy 		tid->hpftid_base = val[0];
15699030e498SRahul Lakkireddy 		tid->nhpftids = val[1] - val[0] + 1;
15709030e498SRahul Lakkireddy 	}
15719030e498SRahul Lakkireddy 
15729030e498SRahul Lakkireddy 	tid->ntids = padap->tids.ntids;
15739030e498SRahul Lakkireddy 	tid->nstids = padap->tids.nstids;
15749030e498SRahul Lakkireddy 	tid->stid_base = padap->tids.stid_base;
15759030e498SRahul Lakkireddy 	tid->hash_base = padap->tids.hash_base;
15769030e498SRahul Lakkireddy 
15779030e498SRahul Lakkireddy 	tid->natids = padap->tids.natids;
15789030e498SRahul Lakkireddy 	tid->nftids = padap->tids.nftids;
15799030e498SRahul Lakkireddy 	tid->ftid_base = padap->tids.ftid_base;
15809030e498SRahul Lakkireddy 	tid->aftid_base = padap->tids.aftid_base;
15819030e498SRahul Lakkireddy 	tid->aftid_end = padap->tids.aftid_end;
15829030e498SRahul Lakkireddy 
15839030e498SRahul Lakkireddy 	tid->sftid_base = padap->tids.sftid_base;
15849030e498SRahul Lakkireddy 	tid->nsftids = padap->tids.nsftids;
15859030e498SRahul Lakkireddy 
15869030e498SRahul Lakkireddy 	tid->flags = padap->flags;
15879030e498SRahul Lakkireddy 	tid->le_db_conf = t4_read_reg(padap, LE_DB_CONFIG_A);
15889030e498SRahul Lakkireddy 	tid->ip_users = t4_read_reg(padap, LE_DB_ACT_CNT_IPV4_A);
15899030e498SRahul Lakkireddy 	tid->ipv6_users = t4_read_reg(padap, LE_DB_ACT_CNT_IPV6_A);
15909030e498SRahul Lakkireddy 
15919030e498SRahul Lakkireddy #undef FW_PARAM_PFVF_A
15929030e498SRahul Lakkireddy 
15939030e498SRahul Lakkireddy 	cudbg_write_and_release_buff(&temp_buff, dbg_buff);
15949030e498SRahul Lakkireddy 	return rc;
15959030e498SRahul Lakkireddy }
15969030e498SRahul Lakkireddy 
1597736c3b94SRahul Lakkireddy static int cudbg_sge_ctxt_check_valid(u32 *buf, int type)
15989e5c598cSRahul Lakkireddy {
1599736c3b94SRahul Lakkireddy 	int index, bit, bit_pos = 0;
16009e5c598cSRahul Lakkireddy 
1601736c3b94SRahul Lakkireddy 	switch (type) {
1602736c3b94SRahul Lakkireddy 	case CTXT_EGRESS:
1603736c3b94SRahul Lakkireddy 		bit_pos = 176;
1604736c3b94SRahul Lakkireddy 		break;
1605736c3b94SRahul Lakkireddy 	case CTXT_INGRESS:
1606736c3b94SRahul Lakkireddy 		bit_pos = 141;
1607736c3b94SRahul Lakkireddy 		break;
1608736c3b94SRahul Lakkireddy 	case CTXT_FLM:
1609736c3b94SRahul Lakkireddy 		bit_pos = 89;
1610736c3b94SRahul Lakkireddy 		break;
1611736c3b94SRahul Lakkireddy 	}
1612736c3b94SRahul Lakkireddy 	index = bit_pos / 32;
1613736c3b94SRahul Lakkireddy 	bit =  bit_pos % 32;
1614736c3b94SRahul Lakkireddy 	return buf[index] & (1U << bit);
1615736c3b94SRahul Lakkireddy }
1616736c3b94SRahul Lakkireddy 
1617736c3b94SRahul Lakkireddy static int cudbg_get_ctxt_region_info(struct adapter *padap,
1618736c3b94SRahul Lakkireddy 				      struct cudbg_region_info *ctx_info,
1619736c3b94SRahul Lakkireddy 				      u8 *mem_type)
1620736c3b94SRahul Lakkireddy {
1621736c3b94SRahul Lakkireddy 	struct cudbg_mem_desc mem_desc;
1622736c3b94SRahul Lakkireddy 	struct cudbg_meminfo meminfo;
1623736c3b94SRahul Lakkireddy 	u32 i, j, value, found;
1624736c3b94SRahul Lakkireddy 	u8 flq;
1625736c3b94SRahul Lakkireddy 	int rc;
1626736c3b94SRahul Lakkireddy 
1627736c3b94SRahul Lakkireddy 	rc = cudbg_fill_meminfo(padap, &meminfo);
1628736c3b94SRahul Lakkireddy 	if (rc)
1629736c3b94SRahul Lakkireddy 		return rc;
1630736c3b94SRahul Lakkireddy 
1631736c3b94SRahul Lakkireddy 	/* Get EGRESS and INGRESS context region size */
1632736c3b94SRahul Lakkireddy 	for (i = CTXT_EGRESS; i <= CTXT_INGRESS; i++) {
1633736c3b94SRahul Lakkireddy 		found = 0;
1634736c3b94SRahul Lakkireddy 		memset(&mem_desc, 0, sizeof(struct cudbg_mem_desc));
1635736c3b94SRahul Lakkireddy 		for (j = 0; j < ARRAY_SIZE(meminfo.avail); j++) {
1636736c3b94SRahul Lakkireddy 			rc = cudbg_get_mem_region(padap, &meminfo, j,
1637736c3b94SRahul Lakkireddy 						  cudbg_region[i],
1638736c3b94SRahul Lakkireddy 						  &mem_desc);
1639736c3b94SRahul Lakkireddy 			if (!rc) {
1640736c3b94SRahul Lakkireddy 				found = 1;
1641736c3b94SRahul Lakkireddy 				rc = cudbg_get_mem_relative(padap, &meminfo, j,
1642736c3b94SRahul Lakkireddy 							    &mem_desc.base,
1643736c3b94SRahul Lakkireddy 							    &mem_desc.limit);
1644736c3b94SRahul Lakkireddy 				if (rc) {
1645736c3b94SRahul Lakkireddy 					ctx_info[i].exist = false;
1646736c3b94SRahul Lakkireddy 					break;
1647736c3b94SRahul Lakkireddy 				}
1648736c3b94SRahul Lakkireddy 				ctx_info[i].exist = true;
1649736c3b94SRahul Lakkireddy 				ctx_info[i].start = mem_desc.base;
1650736c3b94SRahul Lakkireddy 				ctx_info[i].end = mem_desc.limit;
1651736c3b94SRahul Lakkireddy 				mem_type[i] = j;
1652736c3b94SRahul Lakkireddy 				break;
1653736c3b94SRahul Lakkireddy 			}
1654736c3b94SRahul Lakkireddy 		}
1655736c3b94SRahul Lakkireddy 		if (!found)
1656736c3b94SRahul Lakkireddy 			ctx_info[i].exist = false;
1657736c3b94SRahul Lakkireddy 	}
1658736c3b94SRahul Lakkireddy 
1659736c3b94SRahul Lakkireddy 	/* Get FLM and CNM max qid. */
16609e5c598cSRahul Lakkireddy 	value = t4_read_reg(padap, SGE_FLM_CFG_A);
16619e5c598cSRahul Lakkireddy 
16629e5c598cSRahul Lakkireddy 	/* Get number of data freelist queues */
16639e5c598cSRahul Lakkireddy 	flq = HDRSTARTFLQ_G(value);
1664736c3b94SRahul Lakkireddy 	ctx_info[CTXT_FLM].exist = true;
1665736c3b94SRahul Lakkireddy 	ctx_info[CTXT_FLM].end = (CUDBG_MAX_FL_QIDS >> flq) * SGE_CTXT_SIZE;
16669e5c598cSRahul Lakkireddy 
1667736c3b94SRahul Lakkireddy 	/* The number of CONM contexts are same as number of freelist
16689e5c598cSRahul Lakkireddy 	 * queues.
16699e5c598cSRahul Lakkireddy 	 */
1670736c3b94SRahul Lakkireddy 	ctx_info[CTXT_CNM].exist = true;
1671736c3b94SRahul Lakkireddy 	ctx_info[CTXT_CNM].end = ctx_info[CTXT_FLM].end;
1672736c3b94SRahul Lakkireddy 
1673736c3b94SRahul Lakkireddy 	return 0;
1674736c3b94SRahul Lakkireddy }
1675736c3b94SRahul Lakkireddy 
1676736c3b94SRahul Lakkireddy int cudbg_dump_context_size(struct adapter *padap)
1677736c3b94SRahul Lakkireddy {
1678736c3b94SRahul Lakkireddy 	struct cudbg_region_info region_info[CTXT_CNM + 1] = { {0} };
1679736c3b94SRahul Lakkireddy 	u8 mem_type[CTXT_INGRESS + 1] = { 0 };
1680736c3b94SRahul Lakkireddy 	u32 i, size = 0;
1681736c3b94SRahul Lakkireddy 	int rc;
1682736c3b94SRahul Lakkireddy 
1683736c3b94SRahul Lakkireddy 	/* Get max valid qid for each type of queue */
1684736c3b94SRahul Lakkireddy 	rc = cudbg_get_ctxt_region_info(padap, region_info, mem_type);
1685736c3b94SRahul Lakkireddy 	if (rc)
1686736c3b94SRahul Lakkireddy 		return rc;
1687736c3b94SRahul Lakkireddy 
1688736c3b94SRahul Lakkireddy 	for (i = 0; i < CTXT_CNM; i++) {
1689736c3b94SRahul Lakkireddy 		if (!region_info[i].exist) {
1690736c3b94SRahul Lakkireddy 			if (i == CTXT_EGRESS || i == CTXT_INGRESS)
1691736c3b94SRahul Lakkireddy 				size += CUDBG_LOWMEM_MAX_CTXT_QIDS *
1692736c3b94SRahul Lakkireddy 					SGE_CTXT_SIZE;
1693736c3b94SRahul Lakkireddy 			continue;
1694736c3b94SRahul Lakkireddy 		}
1695736c3b94SRahul Lakkireddy 
1696736c3b94SRahul Lakkireddy 		size += (region_info[i].end - region_info[i].start + 1) /
1697736c3b94SRahul Lakkireddy 			SGE_CTXT_SIZE;
1698736c3b94SRahul Lakkireddy 	}
16999e5c598cSRahul Lakkireddy 	return size * sizeof(struct cudbg_ch_cntxt);
17009e5c598cSRahul Lakkireddy }
17019e5c598cSRahul Lakkireddy 
17029e5c598cSRahul Lakkireddy static void cudbg_read_sge_ctxt(struct cudbg_init *pdbg_init, u32 cid,
17039e5c598cSRahul Lakkireddy 				enum ctxt_type ctype, u32 *data)
17049e5c598cSRahul Lakkireddy {
17059e5c598cSRahul Lakkireddy 	struct adapter *padap = pdbg_init->adap;
17069e5c598cSRahul Lakkireddy 	int rc = -1;
17079e5c598cSRahul Lakkireddy 
17089e5c598cSRahul Lakkireddy 	/* Under heavy traffic, the SGE Queue contexts registers will be
17099e5c598cSRahul Lakkireddy 	 * frequently accessed by firmware.
17109e5c598cSRahul Lakkireddy 	 *
17119e5c598cSRahul Lakkireddy 	 * To avoid conflicts with firmware, always ask firmware to fetch
17129e5c598cSRahul Lakkireddy 	 * the SGE Queue contexts via mailbox. On failure, fallback to
17139e5c598cSRahul Lakkireddy 	 * accessing hardware registers directly.
17149e5c598cSRahul Lakkireddy 	 */
17159e5c598cSRahul Lakkireddy 	if (is_fw_attached(pdbg_init))
17169e5c598cSRahul Lakkireddy 		rc = t4_sge_ctxt_rd(padap, padap->mbox, cid, ctype, data);
17179e5c598cSRahul Lakkireddy 	if (rc)
17189e5c598cSRahul Lakkireddy 		t4_sge_ctxt_rd_bd(padap, cid, ctype, data);
17199e5c598cSRahul Lakkireddy }
17209e5c598cSRahul Lakkireddy 
1721736c3b94SRahul Lakkireddy static void cudbg_get_sge_ctxt_fw(struct cudbg_init *pdbg_init, u32 max_qid,
1722736c3b94SRahul Lakkireddy 				  u8 ctxt_type,
1723736c3b94SRahul Lakkireddy 				  struct cudbg_ch_cntxt **out_buff)
1724736c3b94SRahul Lakkireddy {
1725736c3b94SRahul Lakkireddy 	struct cudbg_ch_cntxt *buff = *out_buff;
1726736c3b94SRahul Lakkireddy 	int rc;
1727736c3b94SRahul Lakkireddy 	u32 j;
1728736c3b94SRahul Lakkireddy 
1729736c3b94SRahul Lakkireddy 	for (j = 0; j < max_qid; j++) {
1730736c3b94SRahul Lakkireddy 		cudbg_read_sge_ctxt(pdbg_init, j, ctxt_type, buff->data);
1731736c3b94SRahul Lakkireddy 		rc = cudbg_sge_ctxt_check_valid(buff->data, ctxt_type);
1732736c3b94SRahul Lakkireddy 		if (!rc)
1733736c3b94SRahul Lakkireddy 			continue;
1734736c3b94SRahul Lakkireddy 
1735736c3b94SRahul Lakkireddy 		buff->cntxt_type = ctxt_type;
1736736c3b94SRahul Lakkireddy 		buff->cntxt_id = j;
1737736c3b94SRahul Lakkireddy 		buff++;
1738736c3b94SRahul Lakkireddy 		if (ctxt_type == CTXT_FLM) {
1739736c3b94SRahul Lakkireddy 			cudbg_read_sge_ctxt(pdbg_init, j, CTXT_CNM, buff->data);
1740736c3b94SRahul Lakkireddy 			buff->cntxt_type = CTXT_CNM;
1741736c3b94SRahul Lakkireddy 			buff->cntxt_id = j;
1742736c3b94SRahul Lakkireddy 			buff++;
1743736c3b94SRahul Lakkireddy 		}
1744736c3b94SRahul Lakkireddy 	}
1745736c3b94SRahul Lakkireddy 
1746736c3b94SRahul Lakkireddy 	*out_buff = buff;
1747736c3b94SRahul Lakkireddy }
1748736c3b94SRahul Lakkireddy 
17499e5c598cSRahul Lakkireddy int cudbg_collect_dump_context(struct cudbg_init *pdbg_init,
17509e5c598cSRahul Lakkireddy 			       struct cudbg_buffer *dbg_buff,
17519e5c598cSRahul Lakkireddy 			       struct cudbg_error *cudbg_err)
17529e5c598cSRahul Lakkireddy {
1753736c3b94SRahul Lakkireddy 	struct cudbg_region_info region_info[CTXT_CNM + 1] = { {0} };
17549e5c598cSRahul Lakkireddy 	struct adapter *padap = pdbg_init->adap;
1755736c3b94SRahul Lakkireddy 	u32 j, size, max_ctx_size, max_ctx_qid;
1756736c3b94SRahul Lakkireddy 	u8 mem_type[CTXT_INGRESS + 1] = { 0 };
17579e5c598cSRahul Lakkireddy 	struct cudbg_buffer temp_buff = { 0 };
17589e5c598cSRahul Lakkireddy 	struct cudbg_ch_cntxt *buff;
1759736c3b94SRahul Lakkireddy 	u64 *dst_off, *src_off;
1760736c3b94SRahul Lakkireddy 	u8 *ctx_buf;
1761736c3b94SRahul Lakkireddy 	u8 i, k;
17629e5c598cSRahul Lakkireddy 	int rc;
17639e5c598cSRahul Lakkireddy 
1764736c3b94SRahul Lakkireddy 	/* Get max valid qid for each type of queue */
1765736c3b94SRahul Lakkireddy 	rc = cudbg_get_ctxt_region_info(padap, region_info, mem_type);
1766736c3b94SRahul Lakkireddy 	if (rc)
1767736c3b94SRahul Lakkireddy 		return rc;
1768736c3b94SRahul Lakkireddy 
17699e5c598cSRahul Lakkireddy 	rc = cudbg_dump_context_size(padap);
17709e5c598cSRahul Lakkireddy 	if (rc <= 0)
17719e5c598cSRahul Lakkireddy 		return CUDBG_STATUS_ENTITY_NOT_FOUND;
17729e5c598cSRahul Lakkireddy 
17739e5c598cSRahul Lakkireddy 	size = rc;
17749e5c598cSRahul Lakkireddy 	rc = cudbg_get_buff(dbg_buff, size, &temp_buff);
17759e5c598cSRahul Lakkireddy 	if (rc)
17769e5c598cSRahul Lakkireddy 		return rc;
17779e5c598cSRahul Lakkireddy 
1778736c3b94SRahul Lakkireddy 	/* Get buffer with enough space to read the biggest context
1779736c3b94SRahul Lakkireddy 	 * region in memory.
1780736c3b94SRahul Lakkireddy 	 */
1781736c3b94SRahul Lakkireddy 	max_ctx_size = max(region_info[CTXT_EGRESS].end -
1782736c3b94SRahul Lakkireddy 			   region_info[CTXT_EGRESS].start + 1,
1783736c3b94SRahul Lakkireddy 			   region_info[CTXT_INGRESS].end -
1784736c3b94SRahul Lakkireddy 			   region_info[CTXT_INGRESS].start + 1);
17859e5c598cSRahul Lakkireddy 
1786736c3b94SRahul Lakkireddy 	ctx_buf = kvzalloc(max_ctx_size, GFP_KERNEL);
1787736c3b94SRahul Lakkireddy 	if (!ctx_buf) {
1788736c3b94SRahul Lakkireddy 		cudbg_put_buff(&temp_buff, dbg_buff);
1789736c3b94SRahul Lakkireddy 		return -ENOMEM;
17909e5c598cSRahul Lakkireddy 	}
17919e5c598cSRahul Lakkireddy 
1792736c3b94SRahul Lakkireddy 	buff = (struct cudbg_ch_cntxt *)temp_buff.data;
1793736c3b94SRahul Lakkireddy 
1794736c3b94SRahul Lakkireddy 	/* Collect EGRESS and INGRESS context data.
1795736c3b94SRahul Lakkireddy 	 * In case of failures, fallback to collecting via FW or
1796736c3b94SRahul Lakkireddy 	 * backdoor access.
1797736c3b94SRahul Lakkireddy 	 */
1798736c3b94SRahul Lakkireddy 	for (i = CTXT_EGRESS; i <= CTXT_INGRESS; i++) {
1799736c3b94SRahul Lakkireddy 		if (!region_info[i].exist) {
1800736c3b94SRahul Lakkireddy 			max_ctx_qid = CUDBG_LOWMEM_MAX_CTXT_QIDS;
1801736c3b94SRahul Lakkireddy 			cudbg_get_sge_ctxt_fw(pdbg_init, max_ctx_qid, i,
1802736c3b94SRahul Lakkireddy 					      &buff);
1803736c3b94SRahul Lakkireddy 			continue;
1804736c3b94SRahul Lakkireddy 		}
1805736c3b94SRahul Lakkireddy 
1806736c3b94SRahul Lakkireddy 		max_ctx_size = region_info[i].end - region_info[i].start + 1;
1807736c3b94SRahul Lakkireddy 		max_ctx_qid = max_ctx_size / SGE_CTXT_SIZE;
1808736c3b94SRahul Lakkireddy 
1809736c3b94SRahul Lakkireddy 		t4_sge_ctxt_flush(padap, padap->mbox, i);
1810736c3b94SRahul Lakkireddy 		rc = t4_memory_rw(padap, MEMWIN_NIC, mem_type[i],
1811736c3b94SRahul Lakkireddy 				  region_info[i].start, max_ctx_size,
1812736c3b94SRahul Lakkireddy 				  (__be32 *)ctx_buf, 1);
1813736c3b94SRahul Lakkireddy 		if (rc) {
1814736c3b94SRahul Lakkireddy 			max_ctx_qid = CUDBG_LOWMEM_MAX_CTXT_QIDS;
1815736c3b94SRahul Lakkireddy 			cudbg_get_sge_ctxt_fw(pdbg_init, max_ctx_qid, i,
1816736c3b94SRahul Lakkireddy 					      &buff);
1817736c3b94SRahul Lakkireddy 			continue;
1818736c3b94SRahul Lakkireddy 		}
1819736c3b94SRahul Lakkireddy 
1820736c3b94SRahul Lakkireddy 		for (j = 0; j < max_ctx_qid; j++) {
1821736c3b94SRahul Lakkireddy 			src_off = (u64 *)(ctx_buf + j * SGE_CTXT_SIZE);
1822736c3b94SRahul Lakkireddy 			dst_off = (u64 *)buff->data;
1823736c3b94SRahul Lakkireddy 
1824736c3b94SRahul Lakkireddy 			/* The data is stored in 64-bit cpu order.  Convert it
1825736c3b94SRahul Lakkireddy 			 * to big endian before parsing.
1826736c3b94SRahul Lakkireddy 			 */
1827736c3b94SRahul Lakkireddy 			for (k = 0; k < SGE_CTXT_SIZE / sizeof(u64); k++)
1828736c3b94SRahul Lakkireddy 				dst_off[k] = cpu_to_be64(src_off[k]);
1829736c3b94SRahul Lakkireddy 
1830736c3b94SRahul Lakkireddy 			rc = cudbg_sge_ctxt_check_valid(buff->data, i);
1831736c3b94SRahul Lakkireddy 			if (!rc)
1832736c3b94SRahul Lakkireddy 				continue;
1833736c3b94SRahul Lakkireddy 
1834736c3b94SRahul Lakkireddy 			buff->cntxt_type = i;
1835736c3b94SRahul Lakkireddy 			buff->cntxt_id = j;
1836736c3b94SRahul Lakkireddy 			buff++;
1837736c3b94SRahul Lakkireddy 		}
1838736c3b94SRahul Lakkireddy 	}
1839736c3b94SRahul Lakkireddy 
1840736c3b94SRahul Lakkireddy 	kvfree(ctx_buf);
1841736c3b94SRahul Lakkireddy 
1842736c3b94SRahul Lakkireddy 	/* Collect FREELIST and CONGESTION MANAGER contexts */
1843736c3b94SRahul Lakkireddy 	max_ctx_size = region_info[CTXT_FLM].end -
1844736c3b94SRahul Lakkireddy 		       region_info[CTXT_FLM].start + 1;
1845736c3b94SRahul Lakkireddy 	max_ctx_qid = max_ctx_size / SGE_CTXT_SIZE;
1846736c3b94SRahul Lakkireddy 	/* Since FLM and CONM are 1-to-1 mapped, the below function
1847736c3b94SRahul Lakkireddy 	 * will fetch both FLM and CONM contexts.
1848736c3b94SRahul Lakkireddy 	 */
1849736c3b94SRahul Lakkireddy 	cudbg_get_sge_ctxt_fw(pdbg_init, max_ctx_qid, CTXT_FLM, &buff);
1850736c3b94SRahul Lakkireddy 
18519e5c598cSRahul Lakkireddy 	cudbg_write_and_release_buff(&temp_buff, dbg_buff);
18529e5c598cSRahul Lakkireddy 	return rc;
18539e5c598cSRahul Lakkireddy }
18549e5c598cSRahul Lakkireddy 
1855b289593eSRahul Lakkireddy static inline void cudbg_tcamxy2valmask(u64 x, u64 y, u8 *addr, u64 *mask)
1856b289593eSRahul Lakkireddy {
1857b289593eSRahul Lakkireddy 	*mask = x | y;
1858b289593eSRahul Lakkireddy 	y = (__force u64)cpu_to_be64(y);
1859b289593eSRahul Lakkireddy 	memcpy(addr, (char *)&y + 2, ETH_ALEN);
1860b289593eSRahul Lakkireddy }
1861b289593eSRahul Lakkireddy 
1862b289593eSRahul Lakkireddy static void cudbg_mps_rpl_backdoor(struct adapter *padap,
1863b289593eSRahul Lakkireddy 				   struct fw_ldst_mps_rplc *mps_rplc)
1864b289593eSRahul Lakkireddy {
1865b289593eSRahul Lakkireddy 	if (is_t5(padap->params.chip)) {
1866b289593eSRahul Lakkireddy 		mps_rplc->rplc255_224 = htonl(t4_read_reg(padap,
1867b289593eSRahul Lakkireddy 							  MPS_VF_RPLCT_MAP3_A));
1868b289593eSRahul Lakkireddy 		mps_rplc->rplc223_192 = htonl(t4_read_reg(padap,
1869b289593eSRahul Lakkireddy 							  MPS_VF_RPLCT_MAP2_A));
1870b289593eSRahul Lakkireddy 		mps_rplc->rplc191_160 = htonl(t4_read_reg(padap,
1871b289593eSRahul Lakkireddy 							  MPS_VF_RPLCT_MAP1_A));
1872b289593eSRahul Lakkireddy 		mps_rplc->rplc159_128 = htonl(t4_read_reg(padap,
1873b289593eSRahul Lakkireddy 							  MPS_VF_RPLCT_MAP0_A));
1874b289593eSRahul Lakkireddy 	} else {
1875b289593eSRahul Lakkireddy 		mps_rplc->rplc255_224 = htonl(t4_read_reg(padap,
1876b289593eSRahul Lakkireddy 							  MPS_VF_RPLCT_MAP7_A));
1877b289593eSRahul Lakkireddy 		mps_rplc->rplc223_192 = htonl(t4_read_reg(padap,
1878b289593eSRahul Lakkireddy 							  MPS_VF_RPLCT_MAP6_A));
1879b289593eSRahul Lakkireddy 		mps_rplc->rplc191_160 = htonl(t4_read_reg(padap,
1880b289593eSRahul Lakkireddy 							  MPS_VF_RPLCT_MAP5_A));
1881b289593eSRahul Lakkireddy 		mps_rplc->rplc159_128 = htonl(t4_read_reg(padap,
1882b289593eSRahul Lakkireddy 							  MPS_VF_RPLCT_MAP4_A));
1883b289593eSRahul Lakkireddy 	}
1884b289593eSRahul Lakkireddy 	mps_rplc->rplc127_96 = htonl(t4_read_reg(padap, MPS_VF_RPLCT_MAP3_A));
1885b289593eSRahul Lakkireddy 	mps_rplc->rplc95_64 = htonl(t4_read_reg(padap, MPS_VF_RPLCT_MAP2_A));
1886b289593eSRahul Lakkireddy 	mps_rplc->rplc63_32 = htonl(t4_read_reg(padap, MPS_VF_RPLCT_MAP1_A));
1887b289593eSRahul Lakkireddy 	mps_rplc->rplc31_0 = htonl(t4_read_reg(padap, MPS_VF_RPLCT_MAP0_A));
1888b289593eSRahul Lakkireddy }
1889b289593eSRahul Lakkireddy 
1890b289593eSRahul Lakkireddy static int cudbg_collect_tcam_index(struct adapter *padap,
1891b289593eSRahul Lakkireddy 				    struct cudbg_mps_tcam *tcam, u32 idx)
1892b289593eSRahul Lakkireddy {
1893b289593eSRahul Lakkireddy 	u64 tcamy, tcamx, val;
1894b289593eSRahul Lakkireddy 	u32 ctl, data2;
1895b289593eSRahul Lakkireddy 	int rc = 0;
1896b289593eSRahul Lakkireddy 
1897b289593eSRahul Lakkireddy 	if (CHELSIO_CHIP_VERSION(padap->params.chip) >= CHELSIO_T6) {
1898b289593eSRahul Lakkireddy 		/* CtlReqID   - 1: use Host Driver Requester ID
1899b289593eSRahul Lakkireddy 		 * CtlCmdType - 0: Read, 1: Write
1900b289593eSRahul Lakkireddy 		 * CtlTcamSel - 0: TCAM0, 1: TCAM1
1901b289593eSRahul Lakkireddy 		 * CtlXYBitSel- 0: Y bit, 1: X bit
1902b289593eSRahul Lakkireddy 		 */
1903b289593eSRahul Lakkireddy 
1904b289593eSRahul Lakkireddy 		/* Read tcamy */
1905b289593eSRahul Lakkireddy 		ctl = CTLREQID_V(1) | CTLCMDTYPE_V(0) | CTLXYBITSEL_V(0);
1906b289593eSRahul Lakkireddy 		if (idx < 256)
1907b289593eSRahul Lakkireddy 			ctl |= CTLTCAMINDEX_V(idx) | CTLTCAMSEL_V(0);
1908b289593eSRahul Lakkireddy 		else
1909b289593eSRahul Lakkireddy 			ctl |= CTLTCAMINDEX_V(idx - 256) | CTLTCAMSEL_V(1);
1910b289593eSRahul Lakkireddy 
1911b289593eSRahul Lakkireddy 		t4_write_reg(padap, MPS_CLS_TCAM_DATA2_CTL_A, ctl);
1912b289593eSRahul Lakkireddy 		val = t4_read_reg(padap, MPS_CLS_TCAM_RDATA1_REQ_ID1_A);
1913b289593eSRahul Lakkireddy 		tcamy = DMACH_G(val) << 32;
1914b289593eSRahul Lakkireddy 		tcamy |= t4_read_reg(padap, MPS_CLS_TCAM_RDATA0_REQ_ID1_A);
1915b289593eSRahul Lakkireddy 		data2 = t4_read_reg(padap, MPS_CLS_TCAM_RDATA2_REQ_ID1_A);
1916b289593eSRahul Lakkireddy 		tcam->lookup_type = DATALKPTYPE_G(data2);
1917b289593eSRahul Lakkireddy 
1918b289593eSRahul Lakkireddy 		/* 0 - Outer header, 1 - Inner header
1919b289593eSRahul Lakkireddy 		 * [71:48] bit locations are overloaded for
1920b289593eSRahul Lakkireddy 		 * outer vs. inner lookup types.
1921b289593eSRahul Lakkireddy 		 */
1922b289593eSRahul Lakkireddy 		if (tcam->lookup_type && tcam->lookup_type != DATALKPTYPE_M) {
1923b289593eSRahul Lakkireddy 			/* Inner header VNI */
1924b289593eSRahul Lakkireddy 			tcam->vniy = (data2 & DATAVIDH2_F) | DATAVIDH1_G(data2);
1925b289593eSRahul Lakkireddy 			tcam->vniy = (tcam->vniy << 16) | VIDL_G(val);
1926b289593eSRahul Lakkireddy 			tcam->dip_hit = data2 & DATADIPHIT_F;
1927b289593eSRahul Lakkireddy 		} else {
1928b289593eSRahul Lakkireddy 			tcam->vlan_vld = data2 & DATAVIDH2_F;
1929b289593eSRahul Lakkireddy 			tcam->ivlan = VIDL_G(val);
1930b289593eSRahul Lakkireddy 		}
1931b289593eSRahul Lakkireddy 
1932b289593eSRahul Lakkireddy 		tcam->port_num = DATAPORTNUM_G(data2);
1933b289593eSRahul Lakkireddy 
1934b289593eSRahul Lakkireddy 		/* Read tcamx. Change the control param */
1935b289593eSRahul Lakkireddy 		ctl |= CTLXYBITSEL_V(1);
1936b289593eSRahul Lakkireddy 		t4_write_reg(padap, MPS_CLS_TCAM_DATA2_CTL_A, ctl);
1937b289593eSRahul Lakkireddy 		val = t4_read_reg(padap, MPS_CLS_TCAM_RDATA1_REQ_ID1_A);
1938b289593eSRahul Lakkireddy 		tcamx = DMACH_G(val) << 32;
1939b289593eSRahul Lakkireddy 		tcamx |= t4_read_reg(padap, MPS_CLS_TCAM_RDATA0_REQ_ID1_A);
1940b289593eSRahul Lakkireddy 		data2 = t4_read_reg(padap, MPS_CLS_TCAM_RDATA2_REQ_ID1_A);
1941b289593eSRahul Lakkireddy 		if (tcam->lookup_type && tcam->lookup_type != DATALKPTYPE_M) {
1942b289593eSRahul Lakkireddy 			/* Inner header VNI mask */
1943b289593eSRahul Lakkireddy 			tcam->vnix = (data2 & DATAVIDH2_F) | DATAVIDH1_G(data2);
1944b289593eSRahul Lakkireddy 			tcam->vnix = (tcam->vnix << 16) | VIDL_G(val);
1945b289593eSRahul Lakkireddy 		}
1946b289593eSRahul Lakkireddy 	} else {
1947b289593eSRahul Lakkireddy 		tcamy = t4_read_reg64(padap, MPS_CLS_TCAM_Y_L(idx));
1948b289593eSRahul Lakkireddy 		tcamx = t4_read_reg64(padap, MPS_CLS_TCAM_X_L(idx));
1949b289593eSRahul Lakkireddy 	}
1950b289593eSRahul Lakkireddy 
1951b289593eSRahul Lakkireddy 	/* If no entry, return */
1952b289593eSRahul Lakkireddy 	if (tcamx & tcamy)
1953b289593eSRahul Lakkireddy 		return rc;
1954b289593eSRahul Lakkireddy 
1955b289593eSRahul Lakkireddy 	tcam->cls_lo = t4_read_reg(padap, MPS_CLS_SRAM_L(idx));
1956b289593eSRahul Lakkireddy 	tcam->cls_hi = t4_read_reg(padap, MPS_CLS_SRAM_H(idx));
1957b289593eSRahul Lakkireddy 
1958b289593eSRahul Lakkireddy 	if (is_t5(padap->params.chip))
1959b289593eSRahul Lakkireddy 		tcam->repli = (tcam->cls_lo & REPLICATE_F);
1960b289593eSRahul Lakkireddy 	else if (is_t6(padap->params.chip))
1961b289593eSRahul Lakkireddy 		tcam->repli = (tcam->cls_lo & T6_REPLICATE_F);
1962b289593eSRahul Lakkireddy 
1963b289593eSRahul Lakkireddy 	if (tcam->repli) {
1964b289593eSRahul Lakkireddy 		struct fw_ldst_cmd ldst_cmd;
1965b289593eSRahul Lakkireddy 		struct fw_ldst_mps_rplc mps_rplc;
1966b289593eSRahul Lakkireddy 
1967b289593eSRahul Lakkireddy 		memset(&ldst_cmd, 0, sizeof(ldst_cmd));
1968b289593eSRahul Lakkireddy 		ldst_cmd.op_to_addrspace =
1969b289593eSRahul Lakkireddy 			htonl(FW_CMD_OP_V(FW_LDST_CMD) |
1970b289593eSRahul Lakkireddy 			      FW_CMD_REQUEST_F | FW_CMD_READ_F |
1971b289593eSRahul Lakkireddy 			      FW_LDST_CMD_ADDRSPACE_V(FW_LDST_ADDRSPC_MPS));
1972b289593eSRahul Lakkireddy 		ldst_cmd.cycles_to_len16 = htonl(FW_LEN16(ldst_cmd));
1973b289593eSRahul Lakkireddy 		ldst_cmd.u.mps.rplc.fid_idx =
1974b289593eSRahul Lakkireddy 			htons(FW_LDST_CMD_FID_V(FW_LDST_MPS_RPLC) |
1975b289593eSRahul Lakkireddy 			      FW_LDST_CMD_IDX_V(idx));
1976b289593eSRahul Lakkireddy 
1977b289593eSRahul Lakkireddy 		rc = t4_wr_mbox(padap, padap->mbox, &ldst_cmd, sizeof(ldst_cmd),
1978b289593eSRahul Lakkireddy 				&ldst_cmd);
1979b289593eSRahul Lakkireddy 		if (rc)
1980b289593eSRahul Lakkireddy 			cudbg_mps_rpl_backdoor(padap, &mps_rplc);
1981b289593eSRahul Lakkireddy 		else
1982b289593eSRahul Lakkireddy 			mps_rplc = ldst_cmd.u.mps.rplc;
1983b289593eSRahul Lakkireddy 
1984b289593eSRahul Lakkireddy 		tcam->rplc[0] = ntohl(mps_rplc.rplc31_0);
1985b289593eSRahul Lakkireddy 		tcam->rplc[1] = ntohl(mps_rplc.rplc63_32);
1986b289593eSRahul Lakkireddy 		tcam->rplc[2] = ntohl(mps_rplc.rplc95_64);
1987b289593eSRahul Lakkireddy 		tcam->rplc[3] = ntohl(mps_rplc.rplc127_96);
1988b289593eSRahul Lakkireddy 		if (padap->params.arch.mps_rplc_size > CUDBG_MAX_RPLC_SIZE) {
1989b289593eSRahul Lakkireddy 			tcam->rplc[4] = ntohl(mps_rplc.rplc159_128);
1990b289593eSRahul Lakkireddy 			tcam->rplc[5] = ntohl(mps_rplc.rplc191_160);
1991b289593eSRahul Lakkireddy 			tcam->rplc[6] = ntohl(mps_rplc.rplc223_192);
1992b289593eSRahul Lakkireddy 			tcam->rplc[7] = ntohl(mps_rplc.rplc255_224);
1993b289593eSRahul Lakkireddy 		}
1994b289593eSRahul Lakkireddy 	}
1995b289593eSRahul Lakkireddy 	cudbg_tcamxy2valmask(tcamx, tcamy, tcam->addr, &tcam->mask);
1996b289593eSRahul Lakkireddy 	tcam->idx = idx;
1997b289593eSRahul Lakkireddy 	tcam->rplc_size = padap->params.arch.mps_rplc_size;
1998b289593eSRahul Lakkireddy 	return rc;
1999b289593eSRahul Lakkireddy }
2000b289593eSRahul Lakkireddy 
2001b289593eSRahul Lakkireddy int cudbg_collect_mps_tcam(struct cudbg_init *pdbg_init,
2002b289593eSRahul Lakkireddy 			   struct cudbg_buffer *dbg_buff,
2003b289593eSRahul Lakkireddy 			   struct cudbg_error *cudbg_err)
2004b289593eSRahul Lakkireddy {
2005b289593eSRahul Lakkireddy 	struct adapter *padap = pdbg_init->adap;
2006b289593eSRahul Lakkireddy 	struct cudbg_buffer temp_buff = { 0 };
2007b289593eSRahul Lakkireddy 	u32 size = 0, i, n, total_size = 0;
2008b289593eSRahul Lakkireddy 	struct cudbg_mps_tcam *tcam;
2009b289593eSRahul Lakkireddy 	int rc;
2010b289593eSRahul Lakkireddy 
2011b289593eSRahul Lakkireddy 	n = padap->params.arch.mps_tcam_size;
2012b289593eSRahul Lakkireddy 	size = sizeof(struct cudbg_mps_tcam) * n;
2013b289593eSRahul Lakkireddy 	rc = cudbg_get_buff(dbg_buff, size, &temp_buff);
2014b289593eSRahul Lakkireddy 	if (rc)
2015b289593eSRahul Lakkireddy 		return rc;
2016b289593eSRahul Lakkireddy 
2017b289593eSRahul Lakkireddy 	tcam = (struct cudbg_mps_tcam *)temp_buff.data;
2018b289593eSRahul Lakkireddy 	for (i = 0; i < n; i++) {
2019b289593eSRahul Lakkireddy 		rc = cudbg_collect_tcam_index(padap, tcam, i);
2020b289593eSRahul Lakkireddy 		if (rc) {
2021b289593eSRahul Lakkireddy 			cudbg_err->sys_err = rc;
2022b289593eSRahul Lakkireddy 			cudbg_put_buff(&temp_buff, dbg_buff);
2023b289593eSRahul Lakkireddy 			return rc;
2024b289593eSRahul Lakkireddy 		}
2025b289593eSRahul Lakkireddy 		total_size += sizeof(struct cudbg_mps_tcam);
2026b289593eSRahul Lakkireddy 		tcam++;
2027b289593eSRahul Lakkireddy 	}
2028b289593eSRahul Lakkireddy 
2029b289593eSRahul Lakkireddy 	if (!total_size) {
2030b289593eSRahul Lakkireddy 		rc = CUDBG_SYSTEM_ERROR;
2031b289593eSRahul Lakkireddy 		cudbg_err->sys_err = rc;
2032b289593eSRahul Lakkireddy 		cudbg_put_buff(&temp_buff, dbg_buff);
2033b289593eSRahul Lakkireddy 		return rc;
2034b289593eSRahul Lakkireddy 	}
2035b289593eSRahul Lakkireddy 	cudbg_write_and_release_buff(&temp_buff, dbg_buff);
2036b289593eSRahul Lakkireddy 	return rc;
2037b289593eSRahul Lakkireddy }
2038b289593eSRahul Lakkireddy 
20396f92a654SRahul Lakkireddy int cudbg_collect_vpd_data(struct cudbg_init *pdbg_init,
20406f92a654SRahul Lakkireddy 			   struct cudbg_buffer *dbg_buff,
20416f92a654SRahul Lakkireddy 			   struct cudbg_error *cudbg_err)
20426f92a654SRahul Lakkireddy {
20436f92a654SRahul Lakkireddy 	struct adapter *padap = pdbg_init->adap;
20446f92a654SRahul Lakkireddy 	struct cudbg_buffer temp_buff = { 0 };
2045940c9c45SRahul Lakkireddy 	char vpd_str[CUDBG_VPD_VER_LEN + 1];
2046940c9c45SRahul Lakkireddy 	u32 scfg_vers, vpd_vers, fw_vers;
20476f92a654SRahul Lakkireddy 	struct cudbg_vpd_data *vpd_data;
2048940c9c45SRahul Lakkireddy 	struct vpd_params vpd = { 0 };
2049940c9c45SRahul Lakkireddy 	int rc, ret;
2050940c9c45SRahul Lakkireddy 
2051940c9c45SRahul Lakkireddy 	rc = t4_get_raw_vpd_params(padap, &vpd);
2052940c9c45SRahul Lakkireddy 	if (rc)
2053940c9c45SRahul Lakkireddy 		return rc;
2054940c9c45SRahul Lakkireddy 
2055940c9c45SRahul Lakkireddy 	rc = t4_get_fw_version(padap, &fw_vers);
2056940c9c45SRahul Lakkireddy 	if (rc)
2057940c9c45SRahul Lakkireddy 		return rc;
2058940c9c45SRahul Lakkireddy 
2059940c9c45SRahul Lakkireddy 	/* Serial Configuration Version is located beyond the PF's vpd size.
2060940c9c45SRahul Lakkireddy 	 * Temporarily give access to entire EEPROM to get it.
2061940c9c45SRahul Lakkireddy 	 */
2062940c9c45SRahul Lakkireddy 	rc = pci_set_vpd_size(padap->pdev, EEPROMVSIZE);
2063940c9c45SRahul Lakkireddy 	if (rc < 0)
2064940c9c45SRahul Lakkireddy 		return rc;
2065940c9c45SRahul Lakkireddy 
2066940c9c45SRahul Lakkireddy 	ret = cudbg_read_vpd_reg(padap, CUDBG_SCFG_VER_ADDR, CUDBG_SCFG_VER_LEN,
2067940c9c45SRahul Lakkireddy 				 &scfg_vers);
2068940c9c45SRahul Lakkireddy 
2069940c9c45SRahul Lakkireddy 	/* Restore back to original PF's vpd size */
2070940c9c45SRahul Lakkireddy 	rc = pci_set_vpd_size(padap->pdev, CUDBG_VPD_PF_SIZE);
2071940c9c45SRahul Lakkireddy 	if (rc < 0)
2072940c9c45SRahul Lakkireddy 		return rc;
2073940c9c45SRahul Lakkireddy 
2074940c9c45SRahul Lakkireddy 	if (ret)
2075940c9c45SRahul Lakkireddy 		return ret;
2076940c9c45SRahul Lakkireddy 
2077940c9c45SRahul Lakkireddy 	rc = cudbg_read_vpd_reg(padap, CUDBG_VPD_VER_ADDR, CUDBG_VPD_VER_LEN,
2078940c9c45SRahul Lakkireddy 				vpd_str);
2079940c9c45SRahul Lakkireddy 	if (rc)
2080940c9c45SRahul Lakkireddy 		return rc;
2081940c9c45SRahul Lakkireddy 
2082940c9c45SRahul Lakkireddy 	vpd_str[CUDBG_VPD_VER_LEN] = '\0';
2083940c9c45SRahul Lakkireddy 	rc = kstrtouint(vpd_str, 0, &vpd_vers);
2084940c9c45SRahul Lakkireddy 	if (rc)
2085940c9c45SRahul Lakkireddy 		return rc;
20866f92a654SRahul Lakkireddy 
20876f92a654SRahul Lakkireddy 	rc = cudbg_get_buff(dbg_buff, sizeof(struct cudbg_vpd_data),
20886f92a654SRahul Lakkireddy 			    &temp_buff);
20896f92a654SRahul Lakkireddy 	if (rc)
20906f92a654SRahul Lakkireddy 		return rc;
20916f92a654SRahul Lakkireddy 
20926f92a654SRahul Lakkireddy 	vpd_data = (struct cudbg_vpd_data *)temp_buff.data;
2093940c9c45SRahul Lakkireddy 	memcpy(vpd_data->sn, vpd.sn, SERNUM_LEN + 1);
2094940c9c45SRahul Lakkireddy 	memcpy(vpd_data->bn, vpd.pn, PN_LEN + 1);
2095940c9c45SRahul Lakkireddy 	memcpy(vpd_data->na, vpd.na, MACADDR_LEN + 1);
2096940c9c45SRahul Lakkireddy 	memcpy(vpd_data->mn, vpd.id, ID_LEN + 1);
2097940c9c45SRahul Lakkireddy 	vpd_data->scfg_vers = scfg_vers;
2098940c9c45SRahul Lakkireddy 	vpd_data->vpd_vers = vpd_vers;
2099940c9c45SRahul Lakkireddy 	vpd_data->fw_major = FW_HDR_FW_VER_MAJOR_G(fw_vers);
2100940c9c45SRahul Lakkireddy 	vpd_data->fw_minor = FW_HDR_FW_VER_MINOR_G(fw_vers);
2101940c9c45SRahul Lakkireddy 	vpd_data->fw_micro = FW_HDR_FW_VER_MICRO_G(fw_vers);
2102940c9c45SRahul Lakkireddy 	vpd_data->fw_build = FW_HDR_FW_VER_BUILD_G(fw_vers);
21036f92a654SRahul Lakkireddy 	cudbg_write_and_release_buff(&temp_buff, dbg_buff);
21046f92a654SRahul Lakkireddy 	return rc;
21056f92a654SRahul Lakkireddy }
21066f92a654SRahul Lakkireddy 
210703e98b91SRahul Lakkireddy static int cudbg_read_tid(struct cudbg_init *pdbg_init, u32 tid,
210803e98b91SRahul Lakkireddy 			  struct cudbg_tid_data *tid_data)
210903e98b91SRahul Lakkireddy {
211003e98b91SRahul Lakkireddy 	struct adapter *padap = pdbg_init->adap;
211103e98b91SRahul Lakkireddy 	int i, cmd_retry = 8;
211203e98b91SRahul Lakkireddy 	u32 val;
211303e98b91SRahul Lakkireddy 
211403e98b91SRahul Lakkireddy 	/* Fill REQ_DATA regs with 0's */
211503e98b91SRahul Lakkireddy 	for (i = 0; i < NUM_LE_DB_DBGI_REQ_DATA_INSTANCES; i++)
211603e98b91SRahul Lakkireddy 		t4_write_reg(padap, LE_DB_DBGI_REQ_DATA_A + (i << 2), 0);
211703e98b91SRahul Lakkireddy 
211803e98b91SRahul Lakkireddy 	/* Write DBIG command */
211903e98b91SRahul Lakkireddy 	val = DBGICMD_V(4) | DBGITID_V(tid);
212003e98b91SRahul Lakkireddy 	t4_write_reg(padap, LE_DB_DBGI_REQ_TCAM_CMD_A, val);
212103e98b91SRahul Lakkireddy 	tid_data->dbig_cmd = val;
212203e98b91SRahul Lakkireddy 
212303e98b91SRahul Lakkireddy 	val = DBGICMDSTRT_F | DBGICMDMODE_V(1); /* LE mode */
212403e98b91SRahul Lakkireddy 	t4_write_reg(padap, LE_DB_DBGI_CONFIG_A, val);
212503e98b91SRahul Lakkireddy 	tid_data->dbig_conf = val;
212603e98b91SRahul Lakkireddy 
212703e98b91SRahul Lakkireddy 	/* Poll the DBGICMDBUSY bit */
212803e98b91SRahul Lakkireddy 	val = 1;
212903e98b91SRahul Lakkireddy 	while (val) {
213003e98b91SRahul Lakkireddy 		val = t4_read_reg(padap, LE_DB_DBGI_CONFIG_A);
213103e98b91SRahul Lakkireddy 		val = val & DBGICMDBUSY_F;
213203e98b91SRahul Lakkireddy 		cmd_retry--;
213303e98b91SRahul Lakkireddy 		if (!cmd_retry)
213403e98b91SRahul Lakkireddy 			return CUDBG_SYSTEM_ERROR;
213503e98b91SRahul Lakkireddy 	}
213603e98b91SRahul Lakkireddy 
213703e98b91SRahul Lakkireddy 	/* Check RESP status */
213803e98b91SRahul Lakkireddy 	val = t4_read_reg(padap, LE_DB_DBGI_RSP_STATUS_A);
213903e98b91SRahul Lakkireddy 	tid_data->dbig_rsp_stat = val;
214003e98b91SRahul Lakkireddy 	if (!(val & 1))
214103e98b91SRahul Lakkireddy 		return CUDBG_SYSTEM_ERROR;
214203e98b91SRahul Lakkireddy 
214303e98b91SRahul Lakkireddy 	/* Read RESP data */
214403e98b91SRahul Lakkireddy 	for (i = 0; i < NUM_LE_DB_DBGI_RSP_DATA_INSTANCES; i++)
214503e98b91SRahul Lakkireddy 		tid_data->data[i] = t4_read_reg(padap,
214603e98b91SRahul Lakkireddy 						LE_DB_DBGI_RSP_DATA_A +
214703e98b91SRahul Lakkireddy 						(i << 2));
214803e98b91SRahul Lakkireddy 	tid_data->tid = tid;
214903e98b91SRahul Lakkireddy 	return 0;
215003e98b91SRahul Lakkireddy }
215103e98b91SRahul Lakkireddy 
215203e98b91SRahul Lakkireddy static int cudbg_get_le_type(u32 tid, struct cudbg_tcam tcam_region)
215303e98b91SRahul Lakkireddy {
215403e98b91SRahul Lakkireddy 	int type = LE_ET_UNKNOWN;
215503e98b91SRahul Lakkireddy 
215603e98b91SRahul Lakkireddy 	if (tid < tcam_region.server_start)
215703e98b91SRahul Lakkireddy 		type = LE_ET_TCAM_CON;
215803e98b91SRahul Lakkireddy 	else if (tid < tcam_region.filter_start)
215903e98b91SRahul Lakkireddy 		type = LE_ET_TCAM_SERVER;
216003e98b91SRahul Lakkireddy 	else if (tid < tcam_region.clip_start)
216103e98b91SRahul Lakkireddy 		type = LE_ET_TCAM_FILTER;
216203e98b91SRahul Lakkireddy 	else if (tid < tcam_region.routing_start)
216303e98b91SRahul Lakkireddy 		type = LE_ET_TCAM_CLIP;
216403e98b91SRahul Lakkireddy 	else if (tid < tcam_region.tid_hash_base)
216503e98b91SRahul Lakkireddy 		type = LE_ET_TCAM_ROUTING;
216603e98b91SRahul Lakkireddy 	else if (tid < tcam_region.max_tid)
216703e98b91SRahul Lakkireddy 		type = LE_ET_HASH_CON;
216803e98b91SRahul Lakkireddy 	else
216903e98b91SRahul Lakkireddy 		type = LE_ET_INVALID_TID;
217003e98b91SRahul Lakkireddy 
217103e98b91SRahul Lakkireddy 	return type;
217203e98b91SRahul Lakkireddy }
217303e98b91SRahul Lakkireddy 
217403e98b91SRahul Lakkireddy static int cudbg_is_ipv6_entry(struct cudbg_tid_data *tid_data,
217503e98b91SRahul Lakkireddy 			       struct cudbg_tcam tcam_region)
217603e98b91SRahul Lakkireddy {
217703e98b91SRahul Lakkireddy 	int ipv6 = 0;
217803e98b91SRahul Lakkireddy 	int le_type;
217903e98b91SRahul Lakkireddy 
218003e98b91SRahul Lakkireddy 	le_type = cudbg_get_le_type(tid_data->tid, tcam_region);
218103e98b91SRahul Lakkireddy 	if (tid_data->tid & 1)
218203e98b91SRahul Lakkireddy 		return 0;
218303e98b91SRahul Lakkireddy 
218403e98b91SRahul Lakkireddy 	if (le_type == LE_ET_HASH_CON) {
218503e98b91SRahul Lakkireddy 		ipv6 = tid_data->data[16] & 0x8000;
218603e98b91SRahul Lakkireddy 	} else if (le_type == LE_ET_TCAM_CON) {
218703e98b91SRahul Lakkireddy 		ipv6 = tid_data->data[16] & 0x8000;
218803e98b91SRahul Lakkireddy 		if (ipv6)
218903e98b91SRahul Lakkireddy 			ipv6 = tid_data->data[9] == 0x00C00000;
219003e98b91SRahul Lakkireddy 	} else {
219103e98b91SRahul Lakkireddy 		ipv6 = 0;
219203e98b91SRahul Lakkireddy 	}
219303e98b91SRahul Lakkireddy 	return ipv6;
219403e98b91SRahul Lakkireddy }
219503e98b91SRahul Lakkireddy 
219603e98b91SRahul Lakkireddy void cudbg_fill_le_tcam_info(struct adapter *padap,
219703e98b91SRahul Lakkireddy 			     struct cudbg_tcam *tcam_region)
219803e98b91SRahul Lakkireddy {
219903e98b91SRahul Lakkireddy 	u32 value;
220003e98b91SRahul Lakkireddy 
220103e98b91SRahul Lakkireddy 	/* Get the LE regions */
220203e98b91SRahul Lakkireddy 	value = t4_read_reg(padap, LE_DB_TID_HASHBASE_A); /* hash base index */
220303e98b91SRahul Lakkireddy 	tcam_region->tid_hash_base = value;
220403e98b91SRahul Lakkireddy 
220503e98b91SRahul Lakkireddy 	/* Get routing table index */
220603e98b91SRahul Lakkireddy 	value = t4_read_reg(padap, LE_DB_ROUTING_TABLE_INDEX_A);
220703e98b91SRahul Lakkireddy 	tcam_region->routing_start = value;
220803e98b91SRahul Lakkireddy 
220903e98b91SRahul Lakkireddy 	/*Get clip table index */
221003e98b91SRahul Lakkireddy 	value = t4_read_reg(padap, LE_DB_CLIP_TABLE_INDEX_A);
221103e98b91SRahul Lakkireddy 	tcam_region->clip_start = value;
221203e98b91SRahul Lakkireddy 
221303e98b91SRahul Lakkireddy 	/* Get filter table index */
221403e98b91SRahul Lakkireddy 	value = t4_read_reg(padap, LE_DB_FILTER_TABLE_INDEX_A);
221503e98b91SRahul Lakkireddy 	tcam_region->filter_start = value;
221603e98b91SRahul Lakkireddy 
221703e98b91SRahul Lakkireddy 	/* Get server table index */
221803e98b91SRahul Lakkireddy 	value = t4_read_reg(padap, LE_DB_SERVER_INDEX_A);
221903e98b91SRahul Lakkireddy 	tcam_region->server_start = value;
222003e98b91SRahul Lakkireddy 
222103e98b91SRahul Lakkireddy 	/* Check whether hash is enabled and calculate the max tids */
222203e98b91SRahul Lakkireddy 	value = t4_read_reg(padap, LE_DB_CONFIG_A);
222303e98b91SRahul Lakkireddy 	if ((value >> HASHEN_S) & 1) {
222403e98b91SRahul Lakkireddy 		value = t4_read_reg(padap, LE_DB_HASH_CONFIG_A);
222503e98b91SRahul Lakkireddy 		if (CHELSIO_CHIP_VERSION(padap->params.chip) > CHELSIO_T5) {
222603e98b91SRahul Lakkireddy 			tcam_region->max_tid = (value & 0xFFFFF) +
222703e98b91SRahul Lakkireddy 					       tcam_region->tid_hash_base;
222803e98b91SRahul Lakkireddy 		} else {
222903e98b91SRahul Lakkireddy 			value = HASHTIDSIZE_G(value);
223003e98b91SRahul Lakkireddy 			value = 1 << value;
223103e98b91SRahul Lakkireddy 			tcam_region->max_tid = value +
223203e98b91SRahul Lakkireddy 					       tcam_region->tid_hash_base;
223303e98b91SRahul Lakkireddy 		}
223403e98b91SRahul Lakkireddy 	} else { /* hash not enabled */
223503e98b91SRahul Lakkireddy 		tcam_region->max_tid = CUDBG_MAX_TCAM_TID;
223603e98b91SRahul Lakkireddy 	}
223703e98b91SRahul Lakkireddy }
223803e98b91SRahul Lakkireddy 
223903e98b91SRahul Lakkireddy int cudbg_collect_le_tcam(struct cudbg_init *pdbg_init,
224003e98b91SRahul Lakkireddy 			  struct cudbg_buffer *dbg_buff,
224103e98b91SRahul Lakkireddy 			  struct cudbg_error *cudbg_err)
224203e98b91SRahul Lakkireddy {
224303e98b91SRahul Lakkireddy 	struct adapter *padap = pdbg_init->adap;
224403e98b91SRahul Lakkireddy 	struct cudbg_buffer temp_buff = { 0 };
224503e98b91SRahul Lakkireddy 	struct cudbg_tcam tcam_region = { 0 };
224603e98b91SRahul Lakkireddy 	struct cudbg_tid_data *tid_data;
224703e98b91SRahul Lakkireddy 	u32 bytes = 0;
224803e98b91SRahul Lakkireddy 	int rc, size;
224903e98b91SRahul Lakkireddy 	u32 i;
225003e98b91SRahul Lakkireddy 
225103e98b91SRahul Lakkireddy 	cudbg_fill_le_tcam_info(padap, &tcam_region);
225203e98b91SRahul Lakkireddy 
225303e98b91SRahul Lakkireddy 	size = sizeof(struct cudbg_tid_data) * tcam_region.max_tid;
225403e98b91SRahul Lakkireddy 	size += sizeof(struct cudbg_tcam);
225503e98b91SRahul Lakkireddy 	rc = cudbg_get_buff(dbg_buff, size, &temp_buff);
225603e98b91SRahul Lakkireddy 	if (rc)
225703e98b91SRahul Lakkireddy 		return rc;
225803e98b91SRahul Lakkireddy 
225903e98b91SRahul Lakkireddy 	memcpy(temp_buff.data, &tcam_region, sizeof(struct cudbg_tcam));
226003e98b91SRahul Lakkireddy 	bytes = sizeof(struct cudbg_tcam);
226103e98b91SRahul Lakkireddy 	tid_data = (struct cudbg_tid_data *)(temp_buff.data + bytes);
226203e98b91SRahul Lakkireddy 	/* read all tid */
226303e98b91SRahul Lakkireddy 	for (i = 0; i < tcam_region.max_tid; ) {
226403e98b91SRahul Lakkireddy 		rc = cudbg_read_tid(pdbg_init, i, tid_data);
226503e98b91SRahul Lakkireddy 		if (rc) {
226603e98b91SRahul Lakkireddy 			cudbg_err->sys_err = rc;
226703e98b91SRahul Lakkireddy 			cudbg_put_buff(&temp_buff, dbg_buff);
226803e98b91SRahul Lakkireddy 			return rc;
226903e98b91SRahul Lakkireddy 		}
227003e98b91SRahul Lakkireddy 
227103e98b91SRahul Lakkireddy 		/* ipv6 takes two tids */
227203e98b91SRahul Lakkireddy 		cudbg_is_ipv6_entry(tid_data, tcam_region) ? i += 2 : i++;
227303e98b91SRahul Lakkireddy 
227403e98b91SRahul Lakkireddy 		tid_data++;
227503e98b91SRahul Lakkireddy 		bytes += sizeof(struct cudbg_tid_data);
227603e98b91SRahul Lakkireddy 	}
227703e98b91SRahul Lakkireddy 
227803e98b91SRahul Lakkireddy 	cudbg_write_and_release_buff(&temp_buff, dbg_buff);
227903e98b91SRahul Lakkireddy 	return rc;
228003e98b91SRahul Lakkireddy }
228103e98b91SRahul Lakkireddy 
22826f92a654SRahul Lakkireddy int cudbg_collect_cctrl(struct cudbg_init *pdbg_init,
22836f92a654SRahul Lakkireddy 			struct cudbg_buffer *dbg_buff,
22846f92a654SRahul Lakkireddy 			struct cudbg_error *cudbg_err)
22856f92a654SRahul Lakkireddy {
22866f92a654SRahul Lakkireddy 	struct adapter *padap = pdbg_init->adap;
22876f92a654SRahul Lakkireddy 	struct cudbg_buffer temp_buff = { 0 };
22886f92a654SRahul Lakkireddy 	u32 size;
22896f92a654SRahul Lakkireddy 	int rc;
22906f92a654SRahul Lakkireddy 
22916f92a654SRahul Lakkireddy 	size = sizeof(u16) * NMTUS * NCCTRL_WIN;
22926f92a654SRahul Lakkireddy 	rc = cudbg_get_buff(dbg_buff, size, &temp_buff);
22936f92a654SRahul Lakkireddy 	if (rc)
22946f92a654SRahul Lakkireddy 		return rc;
22956f92a654SRahul Lakkireddy 
22966f92a654SRahul Lakkireddy 	t4_read_cong_tbl(padap, (void *)temp_buff.data);
22976f92a654SRahul Lakkireddy 	cudbg_write_and_release_buff(&temp_buff, dbg_buff);
22986f92a654SRahul Lakkireddy 	return rc;
22996f92a654SRahul Lakkireddy }
23006f92a654SRahul Lakkireddy 
2301270d39bfSRahul Lakkireddy int cudbg_collect_ma_indirect(struct cudbg_init *pdbg_init,
2302270d39bfSRahul Lakkireddy 			      struct cudbg_buffer *dbg_buff,
2303270d39bfSRahul Lakkireddy 			      struct cudbg_error *cudbg_err)
2304270d39bfSRahul Lakkireddy {
2305270d39bfSRahul Lakkireddy 	struct adapter *padap = pdbg_init->adap;
2306270d39bfSRahul Lakkireddy 	struct cudbg_buffer temp_buff = { 0 };
2307270d39bfSRahul Lakkireddy 	struct ireg_buf *ma_indr;
2308270d39bfSRahul Lakkireddy 	int i, rc, n;
2309270d39bfSRahul Lakkireddy 	u32 size, j;
2310270d39bfSRahul Lakkireddy 
2311270d39bfSRahul Lakkireddy 	if (CHELSIO_CHIP_VERSION(padap->params.chip) < CHELSIO_T6)
2312270d39bfSRahul Lakkireddy 		return CUDBG_STATUS_ENTITY_NOT_FOUND;
2313270d39bfSRahul Lakkireddy 
2314270d39bfSRahul Lakkireddy 	n = sizeof(t6_ma_ireg_array) / (IREG_NUM_ELEM * sizeof(u32));
2315270d39bfSRahul Lakkireddy 	size = sizeof(struct ireg_buf) * n * 2;
2316270d39bfSRahul Lakkireddy 	rc = cudbg_get_buff(dbg_buff, size, &temp_buff);
2317270d39bfSRahul Lakkireddy 	if (rc)
2318270d39bfSRahul Lakkireddy 		return rc;
2319270d39bfSRahul Lakkireddy 
2320270d39bfSRahul Lakkireddy 	ma_indr = (struct ireg_buf *)temp_buff.data;
2321270d39bfSRahul Lakkireddy 	for (i = 0; i < n; i++) {
2322270d39bfSRahul Lakkireddy 		struct ireg_field *ma_fli = &ma_indr->tp_pio;
2323270d39bfSRahul Lakkireddy 		u32 *buff = ma_indr->outbuf;
2324270d39bfSRahul Lakkireddy 
2325270d39bfSRahul Lakkireddy 		ma_fli->ireg_addr = t6_ma_ireg_array[i][0];
2326270d39bfSRahul Lakkireddy 		ma_fli->ireg_data = t6_ma_ireg_array[i][1];
2327270d39bfSRahul Lakkireddy 		ma_fli->ireg_local_offset = t6_ma_ireg_array[i][2];
2328270d39bfSRahul Lakkireddy 		ma_fli->ireg_offset_range = t6_ma_ireg_array[i][3];
2329270d39bfSRahul Lakkireddy 		t4_read_indirect(padap, ma_fli->ireg_addr, ma_fli->ireg_data,
2330270d39bfSRahul Lakkireddy 				 buff, ma_fli->ireg_offset_range,
2331270d39bfSRahul Lakkireddy 				 ma_fli->ireg_local_offset);
2332270d39bfSRahul Lakkireddy 		ma_indr++;
2333270d39bfSRahul Lakkireddy 	}
2334270d39bfSRahul Lakkireddy 
2335270d39bfSRahul Lakkireddy 	n = sizeof(t6_ma_ireg_array2) / (IREG_NUM_ELEM * sizeof(u32));
2336270d39bfSRahul Lakkireddy 	for (i = 0; i < n; i++) {
2337270d39bfSRahul Lakkireddy 		struct ireg_field *ma_fli = &ma_indr->tp_pio;
2338270d39bfSRahul Lakkireddy 		u32 *buff = ma_indr->outbuf;
2339270d39bfSRahul Lakkireddy 
2340270d39bfSRahul Lakkireddy 		ma_fli->ireg_addr = t6_ma_ireg_array2[i][0];
2341270d39bfSRahul Lakkireddy 		ma_fli->ireg_data = t6_ma_ireg_array2[i][1];
2342270d39bfSRahul Lakkireddy 		ma_fli->ireg_local_offset = t6_ma_ireg_array2[i][2];
2343270d39bfSRahul Lakkireddy 		for (j = 0; j < t6_ma_ireg_array2[i][3]; j++) {
2344270d39bfSRahul Lakkireddy 			t4_read_indirect(padap, ma_fli->ireg_addr,
2345270d39bfSRahul Lakkireddy 					 ma_fli->ireg_data, buff, 1,
2346270d39bfSRahul Lakkireddy 					 ma_fli->ireg_local_offset);
2347270d39bfSRahul Lakkireddy 			buff++;
2348270d39bfSRahul Lakkireddy 			ma_fli->ireg_local_offset += 0x20;
2349270d39bfSRahul Lakkireddy 		}
2350270d39bfSRahul Lakkireddy 		ma_indr++;
2351270d39bfSRahul Lakkireddy 	}
2352270d39bfSRahul Lakkireddy 	cudbg_write_and_release_buff(&temp_buff, dbg_buff);
2353270d39bfSRahul Lakkireddy 	return rc;
2354270d39bfSRahul Lakkireddy }
2355270d39bfSRahul Lakkireddy 
235627887bc7SRahul Lakkireddy int cudbg_collect_ulptx_la(struct cudbg_init *pdbg_init,
235727887bc7SRahul Lakkireddy 			   struct cudbg_buffer *dbg_buff,
235827887bc7SRahul Lakkireddy 			   struct cudbg_error *cudbg_err)
235927887bc7SRahul Lakkireddy {
236027887bc7SRahul Lakkireddy 	struct adapter *padap = pdbg_init->adap;
236127887bc7SRahul Lakkireddy 	struct cudbg_buffer temp_buff = { 0 };
236227887bc7SRahul Lakkireddy 	struct cudbg_ulptx_la *ulptx_la_buff;
236327887bc7SRahul Lakkireddy 	u32 i, j;
236427887bc7SRahul Lakkireddy 	int rc;
236527887bc7SRahul Lakkireddy 
236627887bc7SRahul Lakkireddy 	rc = cudbg_get_buff(dbg_buff, sizeof(struct cudbg_ulptx_la),
236727887bc7SRahul Lakkireddy 			    &temp_buff);
236827887bc7SRahul Lakkireddy 	if (rc)
236927887bc7SRahul Lakkireddy 		return rc;
237027887bc7SRahul Lakkireddy 
237127887bc7SRahul Lakkireddy 	ulptx_la_buff = (struct cudbg_ulptx_la *)temp_buff.data;
237227887bc7SRahul Lakkireddy 	for (i = 0; i < CUDBG_NUM_ULPTX; i++) {
237327887bc7SRahul Lakkireddy 		ulptx_la_buff->rdptr[i] = t4_read_reg(padap,
237427887bc7SRahul Lakkireddy 						      ULP_TX_LA_RDPTR_0_A +
237527887bc7SRahul Lakkireddy 						      0x10 * i);
237627887bc7SRahul Lakkireddy 		ulptx_la_buff->wrptr[i] = t4_read_reg(padap,
237727887bc7SRahul Lakkireddy 						      ULP_TX_LA_WRPTR_0_A +
237827887bc7SRahul Lakkireddy 						      0x10 * i);
237927887bc7SRahul Lakkireddy 		ulptx_la_buff->rddata[i] = t4_read_reg(padap,
238027887bc7SRahul Lakkireddy 						       ULP_TX_LA_RDDATA_0_A +
238127887bc7SRahul Lakkireddy 						       0x10 * i);
238227887bc7SRahul Lakkireddy 		for (j = 0; j < CUDBG_NUM_ULPTX_READ; j++)
238327887bc7SRahul Lakkireddy 			ulptx_la_buff->rd_data[i][j] =
238427887bc7SRahul Lakkireddy 				t4_read_reg(padap,
238527887bc7SRahul Lakkireddy 					    ULP_TX_LA_RDDATA_0_A + 0x10 * i);
238627887bc7SRahul Lakkireddy 	}
238727887bc7SRahul Lakkireddy 	cudbg_write_and_release_buff(&temp_buff, dbg_buff);
238827887bc7SRahul Lakkireddy 	return rc;
238927887bc7SRahul Lakkireddy }
239027887bc7SRahul Lakkireddy 
2391270d39bfSRahul Lakkireddy int cudbg_collect_up_cim_indirect(struct cudbg_init *pdbg_init,
2392270d39bfSRahul Lakkireddy 				  struct cudbg_buffer *dbg_buff,
2393270d39bfSRahul Lakkireddy 				  struct cudbg_error *cudbg_err)
2394270d39bfSRahul Lakkireddy {
2395270d39bfSRahul Lakkireddy 	struct adapter *padap = pdbg_init->adap;
2396270d39bfSRahul Lakkireddy 	struct cudbg_buffer temp_buff = { 0 };
2397270d39bfSRahul Lakkireddy 	struct ireg_buf *up_cim;
2398270d39bfSRahul Lakkireddy 	int i, rc, n;
2399270d39bfSRahul Lakkireddy 	u32 size;
2400270d39bfSRahul Lakkireddy 
2401270d39bfSRahul Lakkireddy 	n = sizeof(t5_up_cim_reg_array) / (IREG_NUM_ELEM * sizeof(u32));
2402270d39bfSRahul Lakkireddy 	size = sizeof(struct ireg_buf) * n;
2403270d39bfSRahul Lakkireddy 	rc = cudbg_get_buff(dbg_buff, size, &temp_buff);
2404270d39bfSRahul Lakkireddy 	if (rc)
2405270d39bfSRahul Lakkireddy 		return rc;
2406270d39bfSRahul Lakkireddy 
2407270d39bfSRahul Lakkireddy 	up_cim = (struct ireg_buf *)temp_buff.data;
2408270d39bfSRahul Lakkireddy 	for (i = 0; i < n; i++) {
2409270d39bfSRahul Lakkireddy 		struct ireg_field *up_cim_reg = &up_cim->tp_pio;
2410270d39bfSRahul Lakkireddy 		u32 *buff = up_cim->outbuf;
2411270d39bfSRahul Lakkireddy 
2412270d39bfSRahul Lakkireddy 		if (is_t5(padap->params.chip)) {
2413270d39bfSRahul Lakkireddy 			up_cim_reg->ireg_addr = t5_up_cim_reg_array[i][0];
2414270d39bfSRahul Lakkireddy 			up_cim_reg->ireg_data = t5_up_cim_reg_array[i][1];
2415270d39bfSRahul Lakkireddy 			up_cim_reg->ireg_local_offset =
2416270d39bfSRahul Lakkireddy 						t5_up_cim_reg_array[i][2];
2417270d39bfSRahul Lakkireddy 			up_cim_reg->ireg_offset_range =
2418270d39bfSRahul Lakkireddy 						t5_up_cim_reg_array[i][3];
2419270d39bfSRahul Lakkireddy 		} else if (is_t6(padap->params.chip)) {
2420270d39bfSRahul Lakkireddy 			up_cim_reg->ireg_addr = t6_up_cim_reg_array[i][0];
2421270d39bfSRahul Lakkireddy 			up_cim_reg->ireg_data = t6_up_cim_reg_array[i][1];
2422270d39bfSRahul Lakkireddy 			up_cim_reg->ireg_local_offset =
2423270d39bfSRahul Lakkireddy 						t6_up_cim_reg_array[i][2];
2424270d39bfSRahul Lakkireddy 			up_cim_reg->ireg_offset_range =
2425270d39bfSRahul Lakkireddy 						t6_up_cim_reg_array[i][3];
2426270d39bfSRahul Lakkireddy 		}
2427270d39bfSRahul Lakkireddy 
2428270d39bfSRahul Lakkireddy 		rc = t4_cim_read(padap, up_cim_reg->ireg_local_offset,
2429270d39bfSRahul Lakkireddy 				 up_cim_reg->ireg_offset_range, buff);
2430270d39bfSRahul Lakkireddy 		if (rc) {
2431270d39bfSRahul Lakkireddy 			cudbg_put_buff(&temp_buff, dbg_buff);
2432270d39bfSRahul Lakkireddy 			return rc;
2433270d39bfSRahul Lakkireddy 		}
2434270d39bfSRahul Lakkireddy 		up_cim++;
2435270d39bfSRahul Lakkireddy 	}
2436270d39bfSRahul Lakkireddy 	cudbg_write_and_release_buff(&temp_buff, dbg_buff);
2437270d39bfSRahul Lakkireddy 	return rc;
2438270d39bfSRahul Lakkireddy }
2439270d39bfSRahul Lakkireddy 
2440db8cd7ceSRahul Lakkireddy int cudbg_collect_pbt_tables(struct cudbg_init *pdbg_init,
2441db8cd7ceSRahul Lakkireddy 			     struct cudbg_buffer *dbg_buff,
2442db8cd7ceSRahul Lakkireddy 			     struct cudbg_error *cudbg_err)
2443db8cd7ceSRahul Lakkireddy {
2444db8cd7ceSRahul Lakkireddy 	struct adapter *padap = pdbg_init->adap;
2445db8cd7ceSRahul Lakkireddy 	struct cudbg_buffer temp_buff = { 0 };
2446db8cd7ceSRahul Lakkireddy 	struct cudbg_pbt_tables *pbt;
2447db8cd7ceSRahul Lakkireddy 	int i, rc;
2448db8cd7ceSRahul Lakkireddy 	u32 addr;
2449db8cd7ceSRahul Lakkireddy 
2450db8cd7ceSRahul Lakkireddy 	rc = cudbg_get_buff(dbg_buff, sizeof(struct cudbg_pbt_tables),
2451db8cd7ceSRahul Lakkireddy 			    &temp_buff);
2452db8cd7ceSRahul Lakkireddy 	if (rc)
2453db8cd7ceSRahul Lakkireddy 		return rc;
2454db8cd7ceSRahul Lakkireddy 
2455db8cd7ceSRahul Lakkireddy 	pbt = (struct cudbg_pbt_tables *)temp_buff.data;
2456db8cd7ceSRahul Lakkireddy 	/* PBT dynamic entries */
2457db8cd7ceSRahul Lakkireddy 	addr = CUDBG_CHAC_PBT_ADDR;
2458db8cd7ceSRahul Lakkireddy 	for (i = 0; i < CUDBG_PBT_DYNAMIC_ENTRIES; i++) {
2459db8cd7ceSRahul Lakkireddy 		rc = t4_cim_read(padap, addr + (i * 4), 1,
2460db8cd7ceSRahul Lakkireddy 				 &pbt->pbt_dynamic[i]);
2461db8cd7ceSRahul Lakkireddy 		if (rc) {
2462db8cd7ceSRahul Lakkireddy 			cudbg_err->sys_err = rc;
2463db8cd7ceSRahul Lakkireddy 			cudbg_put_buff(&temp_buff, dbg_buff);
2464db8cd7ceSRahul Lakkireddy 			return rc;
2465db8cd7ceSRahul Lakkireddy 		}
2466db8cd7ceSRahul Lakkireddy 	}
2467db8cd7ceSRahul Lakkireddy 
2468db8cd7ceSRahul Lakkireddy 	/* PBT static entries */
2469db8cd7ceSRahul Lakkireddy 	/* static entries start when bit 6 is set */
2470db8cd7ceSRahul Lakkireddy 	addr = CUDBG_CHAC_PBT_ADDR + (1 << 6);
2471db8cd7ceSRahul Lakkireddy 	for (i = 0; i < CUDBG_PBT_STATIC_ENTRIES; i++) {
2472db8cd7ceSRahul Lakkireddy 		rc = t4_cim_read(padap, addr + (i * 4), 1,
2473db8cd7ceSRahul Lakkireddy 				 &pbt->pbt_static[i]);
2474db8cd7ceSRahul Lakkireddy 		if (rc) {
2475db8cd7ceSRahul Lakkireddy 			cudbg_err->sys_err = rc;
2476db8cd7ceSRahul Lakkireddy 			cudbg_put_buff(&temp_buff, dbg_buff);
2477db8cd7ceSRahul Lakkireddy 			return rc;
2478db8cd7ceSRahul Lakkireddy 		}
2479db8cd7ceSRahul Lakkireddy 	}
2480db8cd7ceSRahul Lakkireddy 
2481db8cd7ceSRahul Lakkireddy 	/* LRF entries */
2482db8cd7ceSRahul Lakkireddy 	addr = CUDBG_CHAC_PBT_LRF;
2483db8cd7ceSRahul Lakkireddy 	for (i = 0; i < CUDBG_LRF_ENTRIES; i++) {
2484db8cd7ceSRahul Lakkireddy 		rc = t4_cim_read(padap, addr + (i * 4), 1,
2485db8cd7ceSRahul Lakkireddy 				 &pbt->lrf_table[i]);
2486db8cd7ceSRahul Lakkireddy 		if (rc) {
2487db8cd7ceSRahul Lakkireddy 			cudbg_err->sys_err = rc;
2488db8cd7ceSRahul Lakkireddy 			cudbg_put_buff(&temp_buff, dbg_buff);
2489db8cd7ceSRahul Lakkireddy 			return rc;
2490db8cd7ceSRahul Lakkireddy 		}
2491db8cd7ceSRahul Lakkireddy 	}
2492db8cd7ceSRahul Lakkireddy 
2493db8cd7ceSRahul Lakkireddy 	/* PBT data entries */
2494db8cd7ceSRahul Lakkireddy 	addr = CUDBG_CHAC_PBT_DATA;
2495db8cd7ceSRahul Lakkireddy 	for (i = 0; i < CUDBG_PBT_DATA_ENTRIES; i++) {
2496db8cd7ceSRahul Lakkireddy 		rc = t4_cim_read(padap, addr + (i * 4), 1,
2497db8cd7ceSRahul Lakkireddy 				 &pbt->pbt_data[i]);
2498db8cd7ceSRahul Lakkireddy 		if (rc) {
2499db8cd7ceSRahul Lakkireddy 			cudbg_err->sys_err = rc;
2500db8cd7ceSRahul Lakkireddy 			cudbg_put_buff(&temp_buff, dbg_buff);
2501db8cd7ceSRahul Lakkireddy 			return rc;
2502db8cd7ceSRahul Lakkireddy 		}
2503db8cd7ceSRahul Lakkireddy 	}
2504db8cd7ceSRahul Lakkireddy 	cudbg_write_and_release_buff(&temp_buff, dbg_buff);
2505db8cd7ceSRahul Lakkireddy 	return rc;
2506db8cd7ceSRahul Lakkireddy }
2507db8cd7ceSRahul Lakkireddy 
2508844d1b6fSRahul Lakkireddy int cudbg_collect_mbox_log(struct cudbg_init *pdbg_init,
2509844d1b6fSRahul Lakkireddy 			   struct cudbg_buffer *dbg_buff,
2510844d1b6fSRahul Lakkireddy 			   struct cudbg_error *cudbg_err)
2511844d1b6fSRahul Lakkireddy {
2512844d1b6fSRahul Lakkireddy 	struct adapter *padap = pdbg_init->adap;
2513844d1b6fSRahul Lakkireddy 	struct cudbg_mbox_log *mboxlog = NULL;
2514844d1b6fSRahul Lakkireddy 	struct cudbg_buffer temp_buff = { 0 };
2515844d1b6fSRahul Lakkireddy 	struct mbox_cmd_log *log = NULL;
2516844d1b6fSRahul Lakkireddy 	struct mbox_cmd *entry;
2517844d1b6fSRahul Lakkireddy 	unsigned int entry_idx;
2518844d1b6fSRahul Lakkireddy 	u16 mbox_cmds;
2519844d1b6fSRahul Lakkireddy 	int i, k, rc;
2520844d1b6fSRahul Lakkireddy 	u64 flit;
2521844d1b6fSRahul Lakkireddy 	u32 size;
2522844d1b6fSRahul Lakkireddy 
2523844d1b6fSRahul Lakkireddy 	log = padap->mbox_log;
2524844d1b6fSRahul Lakkireddy 	mbox_cmds = padap->mbox_log->size;
2525844d1b6fSRahul Lakkireddy 	size = sizeof(struct cudbg_mbox_log) * mbox_cmds;
2526844d1b6fSRahul Lakkireddy 	rc = cudbg_get_buff(dbg_buff, size, &temp_buff);
2527844d1b6fSRahul Lakkireddy 	if (rc)
2528844d1b6fSRahul Lakkireddy 		return rc;
2529844d1b6fSRahul Lakkireddy 
2530844d1b6fSRahul Lakkireddy 	mboxlog = (struct cudbg_mbox_log *)temp_buff.data;
2531844d1b6fSRahul Lakkireddy 	for (k = 0; k < mbox_cmds; k++) {
2532844d1b6fSRahul Lakkireddy 		entry_idx = log->cursor + k;
2533844d1b6fSRahul Lakkireddy 		if (entry_idx >= log->size)
2534844d1b6fSRahul Lakkireddy 			entry_idx -= log->size;
2535844d1b6fSRahul Lakkireddy 
2536844d1b6fSRahul Lakkireddy 		entry = mbox_cmd_log_entry(log, entry_idx);
2537844d1b6fSRahul Lakkireddy 		/* skip over unused entries */
2538844d1b6fSRahul Lakkireddy 		if (entry->timestamp == 0)
2539844d1b6fSRahul Lakkireddy 			continue;
2540844d1b6fSRahul Lakkireddy 
2541844d1b6fSRahul Lakkireddy 		memcpy(&mboxlog->entry, entry, sizeof(struct mbox_cmd));
2542844d1b6fSRahul Lakkireddy 		for (i = 0; i < MBOX_LEN / 8; i++) {
2543844d1b6fSRahul Lakkireddy 			flit = entry->cmd[i];
2544844d1b6fSRahul Lakkireddy 			mboxlog->hi[i] = (u32)(flit >> 32);
2545844d1b6fSRahul Lakkireddy 			mboxlog->lo[i] = (u32)flit;
2546844d1b6fSRahul Lakkireddy 		}
2547844d1b6fSRahul Lakkireddy 		mboxlog++;
2548844d1b6fSRahul Lakkireddy 	}
2549844d1b6fSRahul Lakkireddy 	cudbg_write_and_release_buff(&temp_buff, dbg_buff);
2550844d1b6fSRahul Lakkireddy 	return rc;
2551844d1b6fSRahul Lakkireddy }
2552270d39bfSRahul Lakkireddy 
2553270d39bfSRahul Lakkireddy int cudbg_collect_hma_indirect(struct cudbg_init *pdbg_init,
2554270d39bfSRahul Lakkireddy 			       struct cudbg_buffer *dbg_buff,
2555270d39bfSRahul Lakkireddy 			       struct cudbg_error *cudbg_err)
2556270d39bfSRahul Lakkireddy {
2557270d39bfSRahul Lakkireddy 	struct adapter *padap = pdbg_init->adap;
2558270d39bfSRahul Lakkireddy 	struct cudbg_buffer temp_buff = { 0 };
2559270d39bfSRahul Lakkireddy 	struct ireg_buf *hma_indr;
2560270d39bfSRahul Lakkireddy 	int i, rc, n;
2561270d39bfSRahul Lakkireddy 	u32 size;
2562270d39bfSRahul Lakkireddy 
2563270d39bfSRahul Lakkireddy 	if (CHELSIO_CHIP_VERSION(padap->params.chip) < CHELSIO_T6)
2564270d39bfSRahul Lakkireddy 		return CUDBG_STATUS_ENTITY_NOT_FOUND;
2565270d39bfSRahul Lakkireddy 
2566270d39bfSRahul Lakkireddy 	n = sizeof(t6_hma_ireg_array) / (IREG_NUM_ELEM * sizeof(u32));
2567270d39bfSRahul Lakkireddy 	size = sizeof(struct ireg_buf) * n;
2568270d39bfSRahul Lakkireddy 	rc = cudbg_get_buff(dbg_buff, size, &temp_buff);
2569270d39bfSRahul Lakkireddy 	if (rc)
2570270d39bfSRahul Lakkireddy 		return rc;
2571270d39bfSRahul Lakkireddy 
2572270d39bfSRahul Lakkireddy 	hma_indr = (struct ireg_buf *)temp_buff.data;
2573270d39bfSRahul Lakkireddy 	for (i = 0; i < n; i++) {
2574270d39bfSRahul Lakkireddy 		struct ireg_field *hma_fli = &hma_indr->tp_pio;
2575270d39bfSRahul Lakkireddy 		u32 *buff = hma_indr->outbuf;
2576270d39bfSRahul Lakkireddy 
2577270d39bfSRahul Lakkireddy 		hma_fli->ireg_addr = t6_hma_ireg_array[i][0];
2578270d39bfSRahul Lakkireddy 		hma_fli->ireg_data = t6_hma_ireg_array[i][1];
2579270d39bfSRahul Lakkireddy 		hma_fli->ireg_local_offset = t6_hma_ireg_array[i][2];
2580270d39bfSRahul Lakkireddy 		hma_fli->ireg_offset_range = t6_hma_ireg_array[i][3];
2581270d39bfSRahul Lakkireddy 		t4_read_indirect(padap, hma_fli->ireg_addr, hma_fli->ireg_data,
2582270d39bfSRahul Lakkireddy 				 buff, hma_fli->ireg_offset_range,
2583270d39bfSRahul Lakkireddy 				 hma_fli->ireg_local_offset);
2584270d39bfSRahul Lakkireddy 		hma_indr++;
2585270d39bfSRahul Lakkireddy 	}
2586270d39bfSRahul Lakkireddy 	cudbg_write_and_release_buff(&temp_buff, dbg_buff);
2587270d39bfSRahul Lakkireddy 	return rc;
2588270d39bfSRahul Lakkireddy }
2589