14fa9c49fSThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only 2a7975a2fSRahul Lakkireddy /* 3a7975a2fSRahul Lakkireddy * Copyright (C) 2017 Chelsio Communications. All rights reserved. 4a7975a2fSRahul Lakkireddy */ 5a7975a2fSRahul Lakkireddy 6123e25c4SRahul Lakkireddy #include <linux/sort.h> 7c8119fa8SYueHaibing #include <linux/string.h> 8123e25c4SRahul Lakkireddy 9b33af022SRahul Lakkireddy #include "t4_regs.h" 10a7975a2fSRahul Lakkireddy #include "cxgb4.h" 1168ddc82aSRahul Lakkireddy #include "cxgb4_cudbg.h" 12a7975a2fSRahul Lakkireddy #include "cudbg_if.h" 13a7975a2fSRahul Lakkireddy #include "cudbg_lib_common.h" 14b33af022SRahul Lakkireddy #include "cudbg_entity.h" 15123e25c4SRahul Lakkireddy #include "cudbg_lib.h" 1656cf2635SRahul Lakkireddy #include "cudbg_zlib.h" 17a7975a2fSRahul Lakkireddy 1856cf2635SRahul Lakkireddy static int cudbg_do_compression(struct cudbg_init *pdbg_init, 1956cf2635SRahul Lakkireddy struct cudbg_buffer *pin_buff, 20a7975a2fSRahul Lakkireddy struct cudbg_buffer *dbg_buff) 21a7975a2fSRahul Lakkireddy { 2256cf2635SRahul Lakkireddy struct cudbg_buffer temp_in_buff = { 0 }; 2356cf2635SRahul Lakkireddy int bytes_left, bytes_read, bytes; 2456cf2635SRahul Lakkireddy u32 offset = dbg_buff->offset; 2556cf2635SRahul Lakkireddy int rc; 2656cf2635SRahul Lakkireddy 2756cf2635SRahul Lakkireddy temp_in_buff.offset = pin_buff->offset; 2856cf2635SRahul Lakkireddy temp_in_buff.data = pin_buff->data; 2956cf2635SRahul Lakkireddy temp_in_buff.size = pin_buff->size; 3056cf2635SRahul Lakkireddy 3156cf2635SRahul Lakkireddy bytes_left = pin_buff->size; 3256cf2635SRahul Lakkireddy bytes_read = 0; 3356cf2635SRahul Lakkireddy while (bytes_left > 0) { 3456cf2635SRahul Lakkireddy /* Do compression in smaller chunks */ 3556cf2635SRahul Lakkireddy bytes = min_t(unsigned long, bytes_left, 3656cf2635SRahul Lakkireddy (unsigned long)CUDBG_CHUNK_SIZE); 3756cf2635SRahul Lakkireddy temp_in_buff.data = (char *)pin_buff->data + bytes_read; 3856cf2635SRahul Lakkireddy temp_in_buff.size = bytes; 3956cf2635SRahul Lakkireddy rc = cudbg_compress_buff(pdbg_init, &temp_in_buff, dbg_buff); 4056cf2635SRahul Lakkireddy if (rc) 4156cf2635SRahul Lakkireddy return rc; 4256cf2635SRahul Lakkireddy bytes_left -= bytes; 4356cf2635SRahul Lakkireddy bytes_read += bytes; 4456cf2635SRahul Lakkireddy } 4556cf2635SRahul Lakkireddy 4656cf2635SRahul Lakkireddy pin_buff->size = dbg_buff->offset - offset; 4756cf2635SRahul Lakkireddy return 0; 4856cf2635SRahul Lakkireddy } 4956cf2635SRahul Lakkireddy 5056cf2635SRahul Lakkireddy static int cudbg_write_and_release_buff(struct cudbg_init *pdbg_init, 5156cf2635SRahul Lakkireddy struct cudbg_buffer *pin_buff, 5256cf2635SRahul Lakkireddy struct cudbg_buffer *dbg_buff) 5356cf2635SRahul Lakkireddy { 5456cf2635SRahul Lakkireddy int rc = 0; 5556cf2635SRahul Lakkireddy 5656cf2635SRahul Lakkireddy if (pdbg_init->compress_type == CUDBG_COMPRESSION_NONE) { 57a7975a2fSRahul Lakkireddy cudbg_update_buff(pin_buff, dbg_buff); 5856cf2635SRahul Lakkireddy } else { 5956cf2635SRahul Lakkireddy rc = cudbg_do_compression(pdbg_init, pin_buff, dbg_buff); 6056cf2635SRahul Lakkireddy if (rc) 6156cf2635SRahul Lakkireddy goto out; 6256cf2635SRahul Lakkireddy } 6356cf2635SRahul Lakkireddy 6456cf2635SRahul Lakkireddy out: 6556cf2635SRahul Lakkireddy cudbg_put_buff(pdbg_init, pin_buff); 6656cf2635SRahul Lakkireddy return rc; 67a7975a2fSRahul Lakkireddy } 68a7975a2fSRahul Lakkireddy 69b33af022SRahul Lakkireddy static int is_fw_attached(struct cudbg_init *pdbg_init) 70b33af022SRahul Lakkireddy { 71b33af022SRahul Lakkireddy struct adapter *padap = pdbg_init->adap; 72b33af022SRahul Lakkireddy 7380f61f19SArjun Vynipadath if (!(padap->flags & CXGB4_FW_OK) || padap->use_bd) 74b33af022SRahul Lakkireddy return 0; 75b33af022SRahul Lakkireddy 76b33af022SRahul Lakkireddy return 1; 77b33af022SRahul Lakkireddy } 78b33af022SRahul Lakkireddy 79a7975a2fSRahul Lakkireddy /* This function will add additional padding bytes into debug_buffer to make it 80a7975a2fSRahul Lakkireddy * 4 byte aligned. 81a7975a2fSRahul Lakkireddy */ 82a7975a2fSRahul Lakkireddy void cudbg_align_debug_buffer(struct cudbg_buffer *dbg_buff, 83a7975a2fSRahul Lakkireddy struct cudbg_entity_hdr *entity_hdr) 84a7975a2fSRahul Lakkireddy { 85a7975a2fSRahul Lakkireddy u8 zero_buf[4] = {0}; 86a7975a2fSRahul Lakkireddy u8 padding, remain; 87a7975a2fSRahul Lakkireddy 88a7975a2fSRahul Lakkireddy remain = (dbg_buff->offset - entity_hdr->start_offset) % 4; 89a7975a2fSRahul Lakkireddy padding = 4 - remain; 90a7975a2fSRahul Lakkireddy if (remain) { 91a7975a2fSRahul Lakkireddy memcpy(((u8 *)dbg_buff->data) + dbg_buff->offset, &zero_buf, 92a7975a2fSRahul Lakkireddy padding); 93a7975a2fSRahul Lakkireddy dbg_buff->offset += padding; 94a7975a2fSRahul Lakkireddy entity_hdr->num_pad = padding; 95a7975a2fSRahul Lakkireddy } 96a7975a2fSRahul Lakkireddy entity_hdr->size = dbg_buff->offset - entity_hdr->start_offset; 97a7975a2fSRahul Lakkireddy } 98a7975a2fSRahul Lakkireddy 99a7975a2fSRahul Lakkireddy struct cudbg_entity_hdr *cudbg_get_entity_hdr(void *outbuf, int i) 100a7975a2fSRahul Lakkireddy { 101a7975a2fSRahul Lakkireddy struct cudbg_hdr *cudbg_hdr = (struct cudbg_hdr *)outbuf; 102a7975a2fSRahul Lakkireddy 103a7975a2fSRahul Lakkireddy return (struct cudbg_entity_hdr *) 104a7975a2fSRahul Lakkireddy ((char *)outbuf + cudbg_hdr->hdr_len + 105a7975a2fSRahul Lakkireddy (sizeof(struct cudbg_entity_hdr) * (i - 1))); 106a7975a2fSRahul Lakkireddy } 107a7975a2fSRahul Lakkireddy 108940c9c45SRahul Lakkireddy static int cudbg_read_vpd_reg(struct adapter *padap, u32 addr, u32 len, 109940c9c45SRahul Lakkireddy void *dest) 110940c9c45SRahul Lakkireddy { 111940c9c45SRahul Lakkireddy int vaddr, rc; 112940c9c45SRahul Lakkireddy 113940c9c45SRahul Lakkireddy vaddr = t4_eeprom_ptov(addr, padap->pf, EEPROMPFSIZE); 114940c9c45SRahul Lakkireddy if (vaddr < 0) 115940c9c45SRahul Lakkireddy return vaddr; 116940c9c45SRahul Lakkireddy 117940c9c45SRahul Lakkireddy rc = pci_read_vpd(padap->pdev, vaddr, len, dest); 118940c9c45SRahul Lakkireddy if (rc < 0) 119940c9c45SRahul Lakkireddy return rc; 120940c9c45SRahul Lakkireddy 121940c9c45SRahul Lakkireddy return 0; 122940c9c45SRahul Lakkireddy } 123940c9c45SRahul Lakkireddy 124123e25c4SRahul Lakkireddy static int cudbg_mem_desc_cmp(const void *a, const void *b) 125123e25c4SRahul Lakkireddy { 126123e25c4SRahul Lakkireddy return ((const struct cudbg_mem_desc *)a)->base - 127123e25c4SRahul Lakkireddy ((const struct cudbg_mem_desc *)b)->base; 128123e25c4SRahul Lakkireddy } 129123e25c4SRahul Lakkireddy 130123e25c4SRahul Lakkireddy int cudbg_fill_meminfo(struct adapter *padap, 131123e25c4SRahul Lakkireddy struct cudbg_meminfo *meminfo_buff) 132123e25c4SRahul Lakkireddy { 133123e25c4SRahul Lakkireddy struct cudbg_mem_desc *md; 134123e25c4SRahul Lakkireddy u32 lo, hi, used, alloc; 135123e25c4SRahul Lakkireddy int n, i; 136123e25c4SRahul Lakkireddy 137123e25c4SRahul Lakkireddy memset(meminfo_buff->avail, 0, 138123e25c4SRahul Lakkireddy ARRAY_SIZE(meminfo_buff->avail) * 139123e25c4SRahul Lakkireddy sizeof(struct cudbg_mem_desc)); 140123e25c4SRahul Lakkireddy memset(meminfo_buff->mem, 0, 141123e25c4SRahul Lakkireddy (ARRAY_SIZE(cudbg_region) + 3) * sizeof(struct cudbg_mem_desc)); 142123e25c4SRahul Lakkireddy md = meminfo_buff->mem; 143123e25c4SRahul Lakkireddy 144123e25c4SRahul Lakkireddy for (i = 0; i < ARRAY_SIZE(meminfo_buff->mem); i++) { 145123e25c4SRahul Lakkireddy meminfo_buff->mem[i].limit = 0; 146123e25c4SRahul Lakkireddy meminfo_buff->mem[i].idx = i; 147123e25c4SRahul Lakkireddy } 148123e25c4SRahul Lakkireddy 149123e25c4SRahul Lakkireddy /* Find and sort the populated memory ranges */ 150123e25c4SRahul Lakkireddy i = 0; 151123e25c4SRahul Lakkireddy lo = t4_read_reg(padap, MA_TARGET_MEM_ENABLE_A); 152123e25c4SRahul Lakkireddy if (lo & EDRAM0_ENABLE_F) { 153123e25c4SRahul Lakkireddy hi = t4_read_reg(padap, MA_EDRAM0_BAR_A); 154123e25c4SRahul Lakkireddy meminfo_buff->avail[i].base = 155123e25c4SRahul Lakkireddy cudbg_mbytes_to_bytes(EDRAM0_BASE_G(hi)); 156123e25c4SRahul Lakkireddy meminfo_buff->avail[i].limit = 157123e25c4SRahul Lakkireddy meminfo_buff->avail[i].base + 158123e25c4SRahul Lakkireddy cudbg_mbytes_to_bytes(EDRAM0_SIZE_G(hi)); 159123e25c4SRahul Lakkireddy meminfo_buff->avail[i].idx = 0; 160123e25c4SRahul Lakkireddy i++; 161123e25c4SRahul Lakkireddy } 162123e25c4SRahul Lakkireddy 163123e25c4SRahul Lakkireddy if (lo & EDRAM1_ENABLE_F) { 164123e25c4SRahul Lakkireddy hi = t4_read_reg(padap, MA_EDRAM1_BAR_A); 165123e25c4SRahul Lakkireddy meminfo_buff->avail[i].base = 166123e25c4SRahul Lakkireddy cudbg_mbytes_to_bytes(EDRAM1_BASE_G(hi)); 167123e25c4SRahul Lakkireddy meminfo_buff->avail[i].limit = 168123e25c4SRahul Lakkireddy meminfo_buff->avail[i].base + 169123e25c4SRahul Lakkireddy cudbg_mbytes_to_bytes(EDRAM1_SIZE_G(hi)); 170123e25c4SRahul Lakkireddy meminfo_buff->avail[i].idx = 1; 171123e25c4SRahul Lakkireddy i++; 172123e25c4SRahul Lakkireddy } 173123e25c4SRahul Lakkireddy 174123e25c4SRahul Lakkireddy if (is_t5(padap->params.chip)) { 175123e25c4SRahul Lakkireddy if (lo & EXT_MEM0_ENABLE_F) { 176123e25c4SRahul Lakkireddy hi = t4_read_reg(padap, MA_EXT_MEMORY0_BAR_A); 177123e25c4SRahul Lakkireddy meminfo_buff->avail[i].base = 178123e25c4SRahul Lakkireddy cudbg_mbytes_to_bytes(EXT_MEM_BASE_G(hi)); 179123e25c4SRahul Lakkireddy meminfo_buff->avail[i].limit = 180123e25c4SRahul Lakkireddy meminfo_buff->avail[i].base + 181123e25c4SRahul Lakkireddy cudbg_mbytes_to_bytes(EXT_MEM_SIZE_G(hi)); 182123e25c4SRahul Lakkireddy meminfo_buff->avail[i].idx = 3; 183123e25c4SRahul Lakkireddy i++; 184123e25c4SRahul Lakkireddy } 185123e25c4SRahul Lakkireddy 186123e25c4SRahul Lakkireddy if (lo & EXT_MEM1_ENABLE_F) { 187123e25c4SRahul Lakkireddy hi = t4_read_reg(padap, MA_EXT_MEMORY1_BAR_A); 188123e25c4SRahul Lakkireddy meminfo_buff->avail[i].base = 189123e25c4SRahul Lakkireddy cudbg_mbytes_to_bytes(EXT_MEM1_BASE_G(hi)); 190123e25c4SRahul Lakkireddy meminfo_buff->avail[i].limit = 191123e25c4SRahul Lakkireddy meminfo_buff->avail[i].base + 192123e25c4SRahul Lakkireddy cudbg_mbytes_to_bytes(EXT_MEM1_SIZE_G(hi)); 193123e25c4SRahul Lakkireddy meminfo_buff->avail[i].idx = 4; 194123e25c4SRahul Lakkireddy i++; 195123e25c4SRahul Lakkireddy } 196123e25c4SRahul Lakkireddy } else { 197123e25c4SRahul Lakkireddy if (lo & EXT_MEM_ENABLE_F) { 198123e25c4SRahul Lakkireddy hi = t4_read_reg(padap, MA_EXT_MEMORY_BAR_A); 199123e25c4SRahul Lakkireddy meminfo_buff->avail[i].base = 200123e25c4SRahul Lakkireddy cudbg_mbytes_to_bytes(EXT_MEM_BASE_G(hi)); 201123e25c4SRahul Lakkireddy meminfo_buff->avail[i].limit = 202123e25c4SRahul Lakkireddy meminfo_buff->avail[i].base + 203123e25c4SRahul Lakkireddy cudbg_mbytes_to_bytes(EXT_MEM_SIZE_G(hi)); 204123e25c4SRahul Lakkireddy meminfo_buff->avail[i].idx = 2; 205123e25c4SRahul Lakkireddy i++; 206123e25c4SRahul Lakkireddy } 2074db0401fSRahul Lakkireddy 2084db0401fSRahul Lakkireddy if (lo & HMA_MUX_F) { 2094db0401fSRahul Lakkireddy hi = t4_read_reg(padap, MA_EXT_MEMORY1_BAR_A); 2104db0401fSRahul Lakkireddy meminfo_buff->avail[i].base = 2114db0401fSRahul Lakkireddy cudbg_mbytes_to_bytes(EXT_MEM1_BASE_G(hi)); 2124db0401fSRahul Lakkireddy meminfo_buff->avail[i].limit = 2134db0401fSRahul Lakkireddy meminfo_buff->avail[i].base + 2144db0401fSRahul Lakkireddy cudbg_mbytes_to_bytes(EXT_MEM1_SIZE_G(hi)); 2154db0401fSRahul Lakkireddy meminfo_buff->avail[i].idx = 5; 2164db0401fSRahul Lakkireddy i++; 2174db0401fSRahul Lakkireddy } 218123e25c4SRahul Lakkireddy } 219123e25c4SRahul Lakkireddy 220123e25c4SRahul Lakkireddy if (!i) /* no memory available */ 221123e25c4SRahul Lakkireddy return CUDBG_STATUS_ENTITY_NOT_FOUND; 222123e25c4SRahul Lakkireddy 223123e25c4SRahul Lakkireddy meminfo_buff->avail_c = i; 224123e25c4SRahul Lakkireddy sort(meminfo_buff->avail, i, sizeof(struct cudbg_mem_desc), 225123e25c4SRahul Lakkireddy cudbg_mem_desc_cmp, NULL); 226123e25c4SRahul Lakkireddy (md++)->base = t4_read_reg(padap, SGE_DBQ_CTXT_BADDR_A); 227123e25c4SRahul Lakkireddy (md++)->base = t4_read_reg(padap, SGE_IMSG_CTXT_BADDR_A); 228123e25c4SRahul Lakkireddy (md++)->base = t4_read_reg(padap, SGE_FLM_CACHE_BADDR_A); 229123e25c4SRahul Lakkireddy (md++)->base = t4_read_reg(padap, TP_CMM_TCB_BASE_A); 230123e25c4SRahul Lakkireddy (md++)->base = t4_read_reg(padap, TP_CMM_MM_BASE_A); 231123e25c4SRahul Lakkireddy (md++)->base = t4_read_reg(padap, TP_CMM_TIMER_BASE_A); 232123e25c4SRahul Lakkireddy (md++)->base = t4_read_reg(padap, TP_CMM_MM_RX_FLST_BASE_A); 233123e25c4SRahul Lakkireddy (md++)->base = t4_read_reg(padap, TP_CMM_MM_TX_FLST_BASE_A); 234123e25c4SRahul Lakkireddy (md++)->base = t4_read_reg(padap, TP_CMM_MM_PS_FLST_BASE_A); 235123e25c4SRahul Lakkireddy 236123e25c4SRahul Lakkireddy /* the next few have explicit upper bounds */ 237123e25c4SRahul Lakkireddy md->base = t4_read_reg(padap, TP_PMM_TX_BASE_A); 238123e25c4SRahul Lakkireddy md->limit = md->base - 1 + 239123e25c4SRahul Lakkireddy t4_read_reg(padap, TP_PMM_TX_PAGE_SIZE_A) * 240123e25c4SRahul Lakkireddy PMTXMAXPAGE_G(t4_read_reg(padap, TP_PMM_TX_MAX_PAGE_A)); 241123e25c4SRahul Lakkireddy md++; 242123e25c4SRahul Lakkireddy 243123e25c4SRahul Lakkireddy md->base = t4_read_reg(padap, TP_PMM_RX_BASE_A); 244123e25c4SRahul Lakkireddy md->limit = md->base - 1 + 245123e25c4SRahul Lakkireddy t4_read_reg(padap, TP_PMM_RX_PAGE_SIZE_A) * 246123e25c4SRahul Lakkireddy PMRXMAXPAGE_G(t4_read_reg(padap, TP_PMM_RX_MAX_PAGE_A)); 247123e25c4SRahul Lakkireddy md++; 248123e25c4SRahul Lakkireddy 249123e25c4SRahul Lakkireddy if (t4_read_reg(padap, LE_DB_CONFIG_A) & HASHEN_F) { 250123e25c4SRahul Lakkireddy if (CHELSIO_CHIP_VERSION(padap->params.chip) <= CHELSIO_T5) { 251123e25c4SRahul Lakkireddy hi = t4_read_reg(padap, LE_DB_TID_HASHBASE_A) / 4; 252123e25c4SRahul Lakkireddy md->base = t4_read_reg(padap, LE_DB_HASH_TID_BASE_A); 253123e25c4SRahul Lakkireddy } else { 254123e25c4SRahul Lakkireddy hi = t4_read_reg(padap, LE_DB_HASH_TID_BASE_A); 255123e25c4SRahul Lakkireddy md->base = t4_read_reg(padap, 256123e25c4SRahul Lakkireddy LE_DB_HASH_TBL_BASE_ADDR_A); 257123e25c4SRahul Lakkireddy } 258123e25c4SRahul Lakkireddy md->limit = 0; 259123e25c4SRahul Lakkireddy } else { 260123e25c4SRahul Lakkireddy md->base = 0; 261123e25c4SRahul Lakkireddy md->idx = ARRAY_SIZE(cudbg_region); /* hide it */ 262123e25c4SRahul Lakkireddy } 263123e25c4SRahul Lakkireddy md++; 264123e25c4SRahul Lakkireddy 265123e25c4SRahul Lakkireddy #define ulp_region(reg) do { \ 266123e25c4SRahul Lakkireddy md->base = t4_read_reg(padap, ULP_ ## reg ## _LLIMIT_A);\ 267123e25c4SRahul Lakkireddy (md++)->limit = t4_read_reg(padap, ULP_ ## reg ## _ULIMIT_A);\ 268123e25c4SRahul Lakkireddy } while (0) 269123e25c4SRahul Lakkireddy 270123e25c4SRahul Lakkireddy ulp_region(RX_ISCSI); 271123e25c4SRahul Lakkireddy ulp_region(RX_TDDP); 272123e25c4SRahul Lakkireddy ulp_region(TX_TPT); 273123e25c4SRahul Lakkireddy ulp_region(RX_STAG); 274123e25c4SRahul Lakkireddy ulp_region(RX_RQ); 275123e25c4SRahul Lakkireddy ulp_region(RX_RQUDP); 276123e25c4SRahul Lakkireddy ulp_region(RX_PBL); 277123e25c4SRahul Lakkireddy ulp_region(TX_PBL); 278123e25c4SRahul Lakkireddy #undef ulp_region 279123e25c4SRahul Lakkireddy md->base = 0; 280123e25c4SRahul Lakkireddy md->idx = ARRAY_SIZE(cudbg_region); 281123e25c4SRahul Lakkireddy if (!is_t4(padap->params.chip)) { 282123e25c4SRahul Lakkireddy u32 fifo_size = t4_read_reg(padap, SGE_DBVFIFO_SIZE_A); 283123e25c4SRahul Lakkireddy u32 sge_ctrl = t4_read_reg(padap, SGE_CONTROL2_A); 284123e25c4SRahul Lakkireddy u32 size = 0; 285123e25c4SRahul Lakkireddy 286123e25c4SRahul Lakkireddy if (is_t5(padap->params.chip)) { 287123e25c4SRahul Lakkireddy if (sge_ctrl & VFIFO_ENABLE_F) 288123e25c4SRahul Lakkireddy size = DBVFIFO_SIZE_G(fifo_size); 289123e25c4SRahul Lakkireddy } else { 290123e25c4SRahul Lakkireddy size = T6_DBVFIFO_SIZE_G(fifo_size); 291123e25c4SRahul Lakkireddy } 292123e25c4SRahul Lakkireddy 293123e25c4SRahul Lakkireddy if (size) { 294123e25c4SRahul Lakkireddy md->base = BASEADDR_G(t4_read_reg(padap, 295123e25c4SRahul Lakkireddy SGE_DBVFIFO_BADDR_A)); 296123e25c4SRahul Lakkireddy md->limit = md->base + (size << 2) - 1; 297123e25c4SRahul Lakkireddy } 298123e25c4SRahul Lakkireddy } 299123e25c4SRahul Lakkireddy 300123e25c4SRahul Lakkireddy md++; 301123e25c4SRahul Lakkireddy 302123e25c4SRahul Lakkireddy md->base = t4_read_reg(padap, ULP_RX_CTX_BASE_A); 303123e25c4SRahul Lakkireddy md->limit = 0; 304123e25c4SRahul Lakkireddy md++; 305123e25c4SRahul Lakkireddy md->base = t4_read_reg(padap, ULP_TX_ERR_TABLE_BASE_A); 306123e25c4SRahul Lakkireddy md->limit = 0; 307123e25c4SRahul Lakkireddy md++; 308123e25c4SRahul Lakkireddy 309123e25c4SRahul Lakkireddy md->base = padap->vres.ocq.start; 310123e25c4SRahul Lakkireddy if (padap->vres.ocq.size) 311123e25c4SRahul Lakkireddy md->limit = md->base + padap->vres.ocq.size - 1; 312123e25c4SRahul Lakkireddy else 313123e25c4SRahul Lakkireddy md->idx = ARRAY_SIZE(cudbg_region); /* hide it */ 314123e25c4SRahul Lakkireddy md++; 315123e25c4SRahul Lakkireddy 316123e25c4SRahul Lakkireddy /* add any address-space holes, there can be up to 3 */ 317123e25c4SRahul Lakkireddy for (n = 0; n < i - 1; n++) 318123e25c4SRahul Lakkireddy if (meminfo_buff->avail[n].limit < 319123e25c4SRahul Lakkireddy meminfo_buff->avail[n + 1].base) 320123e25c4SRahul Lakkireddy (md++)->base = meminfo_buff->avail[n].limit; 321123e25c4SRahul Lakkireddy 322123e25c4SRahul Lakkireddy if (meminfo_buff->avail[n].limit) 323123e25c4SRahul Lakkireddy (md++)->base = meminfo_buff->avail[n].limit; 324123e25c4SRahul Lakkireddy 325123e25c4SRahul Lakkireddy n = md - meminfo_buff->mem; 326123e25c4SRahul Lakkireddy meminfo_buff->mem_c = n; 327123e25c4SRahul Lakkireddy 328123e25c4SRahul Lakkireddy sort(meminfo_buff->mem, n, sizeof(struct cudbg_mem_desc), 329123e25c4SRahul Lakkireddy cudbg_mem_desc_cmp, NULL); 330123e25c4SRahul Lakkireddy 331123e25c4SRahul Lakkireddy lo = t4_read_reg(padap, CIM_SDRAM_BASE_ADDR_A); 332123e25c4SRahul Lakkireddy hi = t4_read_reg(padap, CIM_SDRAM_ADDR_SIZE_A) + lo - 1; 333123e25c4SRahul Lakkireddy meminfo_buff->up_ram_lo = lo; 334123e25c4SRahul Lakkireddy meminfo_buff->up_ram_hi = hi; 335123e25c4SRahul Lakkireddy 336123e25c4SRahul Lakkireddy lo = t4_read_reg(padap, CIM_EXTMEM2_BASE_ADDR_A); 337123e25c4SRahul Lakkireddy hi = t4_read_reg(padap, CIM_EXTMEM2_ADDR_SIZE_A) + lo - 1; 338123e25c4SRahul Lakkireddy meminfo_buff->up_extmem2_lo = lo; 339123e25c4SRahul Lakkireddy meminfo_buff->up_extmem2_hi = hi; 340123e25c4SRahul Lakkireddy 341123e25c4SRahul Lakkireddy lo = t4_read_reg(padap, TP_PMM_RX_MAX_PAGE_A); 342ae2a922fSRahul Lakkireddy for (i = 0, meminfo_buff->free_rx_cnt = 0; i < 2; i++) 343ae2a922fSRahul Lakkireddy meminfo_buff->free_rx_cnt += 344ae2a922fSRahul Lakkireddy FREERXPAGECOUNT_G(t4_read_reg(padap, 345ae2a922fSRahul Lakkireddy TP_FLM_FREE_RX_CNT_A)); 346ae2a922fSRahul Lakkireddy 347123e25c4SRahul Lakkireddy meminfo_buff->rx_pages_data[0] = PMRXMAXPAGE_G(lo); 348123e25c4SRahul Lakkireddy meminfo_buff->rx_pages_data[1] = 349123e25c4SRahul Lakkireddy t4_read_reg(padap, TP_PMM_RX_PAGE_SIZE_A) >> 10; 350123e25c4SRahul Lakkireddy meminfo_buff->rx_pages_data[2] = (lo & PMRXNUMCHN_F) ? 2 : 1; 351123e25c4SRahul Lakkireddy 352123e25c4SRahul Lakkireddy lo = t4_read_reg(padap, TP_PMM_TX_MAX_PAGE_A); 353123e25c4SRahul Lakkireddy hi = t4_read_reg(padap, TP_PMM_TX_PAGE_SIZE_A); 354ae2a922fSRahul Lakkireddy for (i = 0, meminfo_buff->free_tx_cnt = 0; i < 4; i++) 355ae2a922fSRahul Lakkireddy meminfo_buff->free_tx_cnt += 356ae2a922fSRahul Lakkireddy FREETXPAGECOUNT_G(t4_read_reg(padap, 357ae2a922fSRahul Lakkireddy TP_FLM_FREE_TX_CNT_A)); 358ae2a922fSRahul Lakkireddy 359123e25c4SRahul Lakkireddy meminfo_buff->tx_pages_data[0] = PMTXMAXPAGE_G(lo); 360123e25c4SRahul Lakkireddy meminfo_buff->tx_pages_data[1] = 361123e25c4SRahul Lakkireddy hi >= (1 << 20) ? (hi >> 20) : (hi >> 10); 362123e25c4SRahul Lakkireddy meminfo_buff->tx_pages_data[2] = 363123e25c4SRahul Lakkireddy hi >= (1 << 20) ? 'M' : 'K'; 364123e25c4SRahul Lakkireddy meminfo_buff->tx_pages_data[3] = 1 << PMTXNUMCHN_G(lo); 365123e25c4SRahul Lakkireddy 366123e25c4SRahul Lakkireddy meminfo_buff->p_structs = t4_read_reg(padap, TP_CMM_MM_MAX_PSTRUCT_A); 3679d0f180cSRahul Lakkireddy meminfo_buff->p_structs_free_cnt = 3689d0f180cSRahul Lakkireddy FREEPSTRUCTCOUNT_G(t4_read_reg(padap, TP_FLM_FREE_PS_CNT_A)); 369123e25c4SRahul Lakkireddy 370123e25c4SRahul Lakkireddy for (i = 0; i < 4; i++) { 371123e25c4SRahul Lakkireddy if (CHELSIO_CHIP_VERSION(padap->params.chip) > CHELSIO_T5) 372123e25c4SRahul Lakkireddy lo = t4_read_reg(padap, 373123e25c4SRahul Lakkireddy MPS_RX_MAC_BG_PG_CNT0_A + i * 4); 374123e25c4SRahul Lakkireddy else 375123e25c4SRahul Lakkireddy lo = t4_read_reg(padap, MPS_RX_PG_RSV0_A + i * 4); 376123e25c4SRahul Lakkireddy if (is_t5(padap->params.chip)) { 377123e25c4SRahul Lakkireddy used = T5_USED_G(lo); 378123e25c4SRahul Lakkireddy alloc = T5_ALLOC_G(lo); 379123e25c4SRahul Lakkireddy } else { 380123e25c4SRahul Lakkireddy used = USED_G(lo); 381123e25c4SRahul Lakkireddy alloc = ALLOC_G(lo); 382123e25c4SRahul Lakkireddy } 383123e25c4SRahul Lakkireddy meminfo_buff->port_used[i] = used; 384123e25c4SRahul Lakkireddy meminfo_buff->port_alloc[i] = alloc; 385123e25c4SRahul Lakkireddy } 386123e25c4SRahul Lakkireddy 387123e25c4SRahul Lakkireddy for (i = 0; i < padap->params.arch.nchan; i++) { 388123e25c4SRahul Lakkireddy if (CHELSIO_CHIP_VERSION(padap->params.chip) > CHELSIO_T5) 389123e25c4SRahul Lakkireddy lo = t4_read_reg(padap, 390123e25c4SRahul Lakkireddy MPS_RX_LPBK_BG_PG_CNT0_A + i * 4); 391123e25c4SRahul Lakkireddy else 392123e25c4SRahul Lakkireddy lo = t4_read_reg(padap, MPS_RX_PG_RSV4_A + i * 4); 393123e25c4SRahul Lakkireddy if (is_t5(padap->params.chip)) { 394123e25c4SRahul Lakkireddy used = T5_USED_G(lo); 395123e25c4SRahul Lakkireddy alloc = T5_ALLOC_G(lo); 396123e25c4SRahul Lakkireddy } else { 397123e25c4SRahul Lakkireddy used = USED_G(lo); 398123e25c4SRahul Lakkireddy alloc = ALLOC_G(lo); 399123e25c4SRahul Lakkireddy } 400123e25c4SRahul Lakkireddy meminfo_buff->loopback_used[i] = used; 401123e25c4SRahul Lakkireddy meminfo_buff->loopback_alloc[i] = alloc; 402123e25c4SRahul Lakkireddy } 403123e25c4SRahul Lakkireddy 404123e25c4SRahul Lakkireddy return 0; 405123e25c4SRahul Lakkireddy } 406123e25c4SRahul Lakkireddy 407a7975a2fSRahul Lakkireddy int cudbg_collect_reg_dump(struct cudbg_init *pdbg_init, 408a7975a2fSRahul Lakkireddy struct cudbg_buffer *dbg_buff, 409a7975a2fSRahul Lakkireddy struct cudbg_error *cudbg_err) 410a7975a2fSRahul Lakkireddy { 411a7975a2fSRahul Lakkireddy struct adapter *padap = pdbg_init->adap; 412a7975a2fSRahul Lakkireddy struct cudbg_buffer temp_buff = { 0 }; 413a7975a2fSRahul Lakkireddy u32 buf_size = 0; 414a7975a2fSRahul Lakkireddy int rc = 0; 415a7975a2fSRahul Lakkireddy 416a7975a2fSRahul Lakkireddy if (is_t4(padap->params.chip)) 417a7975a2fSRahul Lakkireddy buf_size = T4_REGMAP_SIZE; 418a7975a2fSRahul Lakkireddy else if (is_t5(padap->params.chip) || is_t6(padap->params.chip)) 419a7975a2fSRahul Lakkireddy buf_size = T5_REGMAP_SIZE; 420a7975a2fSRahul Lakkireddy 42156cf2635SRahul Lakkireddy rc = cudbg_get_buff(pdbg_init, dbg_buff, buf_size, &temp_buff); 422a7975a2fSRahul Lakkireddy if (rc) 423a7975a2fSRahul Lakkireddy return rc; 424a7975a2fSRahul Lakkireddy t4_get_regs(padap, (void *)temp_buff.data, temp_buff.size); 42556cf2635SRahul Lakkireddy return cudbg_write_and_release_buff(pdbg_init, &temp_buff, dbg_buff); 426a7975a2fSRahul Lakkireddy } 427b33af022SRahul Lakkireddy 428844d1b6fSRahul Lakkireddy int cudbg_collect_fw_devlog(struct cudbg_init *pdbg_init, 429844d1b6fSRahul Lakkireddy struct cudbg_buffer *dbg_buff, 430844d1b6fSRahul Lakkireddy struct cudbg_error *cudbg_err) 431844d1b6fSRahul Lakkireddy { 432844d1b6fSRahul Lakkireddy struct adapter *padap = pdbg_init->adap; 433844d1b6fSRahul Lakkireddy struct cudbg_buffer temp_buff = { 0 }; 434844d1b6fSRahul Lakkireddy struct devlog_params *dparams; 435844d1b6fSRahul Lakkireddy int rc = 0; 436844d1b6fSRahul Lakkireddy 437844d1b6fSRahul Lakkireddy rc = t4_init_devlog_params(padap); 438844d1b6fSRahul Lakkireddy if (rc < 0) { 439844d1b6fSRahul Lakkireddy cudbg_err->sys_err = rc; 440844d1b6fSRahul Lakkireddy return rc; 441844d1b6fSRahul Lakkireddy } 442844d1b6fSRahul Lakkireddy 443844d1b6fSRahul Lakkireddy dparams = &padap->params.devlog; 44456cf2635SRahul Lakkireddy rc = cudbg_get_buff(pdbg_init, dbg_buff, dparams->size, &temp_buff); 445844d1b6fSRahul Lakkireddy if (rc) 446844d1b6fSRahul Lakkireddy return rc; 447844d1b6fSRahul Lakkireddy 448844d1b6fSRahul Lakkireddy /* Collect FW devlog */ 449844d1b6fSRahul Lakkireddy if (dparams->start != 0) { 450844d1b6fSRahul Lakkireddy spin_lock(&padap->win0_lock); 451844d1b6fSRahul Lakkireddy rc = t4_memory_rw(padap, padap->params.drv_memwin, 452844d1b6fSRahul Lakkireddy dparams->memtype, dparams->start, 453844d1b6fSRahul Lakkireddy dparams->size, 454844d1b6fSRahul Lakkireddy (__be32 *)(char *)temp_buff.data, 455844d1b6fSRahul Lakkireddy 1); 456844d1b6fSRahul Lakkireddy spin_unlock(&padap->win0_lock); 457844d1b6fSRahul Lakkireddy if (rc) { 458844d1b6fSRahul Lakkireddy cudbg_err->sys_err = rc; 45956cf2635SRahul Lakkireddy cudbg_put_buff(pdbg_init, &temp_buff); 460844d1b6fSRahul Lakkireddy return rc; 461844d1b6fSRahul Lakkireddy } 462844d1b6fSRahul Lakkireddy } 46356cf2635SRahul Lakkireddy return cudbg_write_and_release_buff(pdbg_init, &temp_buff, dbg_buff); 464844d1b6fSRahul Lakkireddy } 465844d1b6fSRahul Lakkireddy 46627887bc7SRahul Lakkireddy int cudbg_collect_cim_la(struct cudbg_init *pdbg_init, 46727887bc7SRahul Lakkireddy struct cudbg_buffer *dbg_buff, 46827887bc7SRahul Lakkireddy struct cudbg_error *cudbg_err) 46927887bc7SRahul Lakkireddy { 47027887bc7SRahul Lakkireddy struct adapter *padap = pdbg_init->adap; 47127887bc7SRahul Lakkireddy struct cudbg_buffer temp_buff = { 0 }; 47227887bc7SRahul Lakkireddy int size, rc; 47327887bc7SRahul Lakkireddy u32 cfg = 0; 47427887bc7SRahul Lakkireddy 47527887bc7SRahul Lakkireddy if (is_t6(padap->params.chip)) { 47627887bc7SRahul Lakkireddy size = padap->params.cim_la_size / 10 + 1; 477e6f02a4dSRahul Lakkireddy size *= 10 * sizeof(u32); 47827887bc7SRahul Lakkireddy } else { 47927887bc7SRahul Lakkireddy size = padap->params.cim_la_size / 8; 48027887bc7SRahul Lakkireddy size *= 8 * sizeof(u32); 48127887bc7SRahul Lakkireddy } 48227887bc7SRahul Lakkireddy 48327887bc7SRahul Lakkireddy size += sizeof(cfg); 48456cf2635SRahul Lakkireddy rc = cudbg_get_buff(pdbg_init, dbg_buff, size, &temp_buff); 48527887bc7SRahul Lakkireddy if (rc) 48627887bc7SRahul Lakkireddy return rc; 48727887bc7SRahul Lakkireddy 48827887bc7SRahul Lakkireddy rc = t4_cim_read(padap, UP_UP_DBG_LA_CFG_A, 1, &cfg); 48927887bc7SRahul Lakkireddy if (rc) { 49027887bc7SRahul Lakkireddy cudbg_err->sys_err = rc; 49156cf2635SRahul Lakkireddy cudbg_put_buff(pdbg_init, &temp_buff); 49227887bc7SRahul Lakkireddy return rc; 49327887bc7SRahul Lakkireddy } 49427887bc7SRahul Lakkireddy 49527887bc7SRahul Lakkireddy memcpy((char *)temp_buff.data, &cfg, sizeof(cfg)); 49627887bc7SRahul Lakkireddy rc = t4_cim_read_la(padap, 49727887bc7SRahul Lakkireddy (u32 *)((char *)temp_buff.data + sizeof(cfg)), 49827887bc7SRahul Lakkireddy NULL); 49927887bc7SRahul Lakkireddy if (rc < 0) { 50027887bc7SRahul Lakkireddy cudbg_err->sys_err = rc; 50156cf2635SRahul Lakkireddy cudbg_put_buff(pdbg_init, &temp_buff); 50227887bc7SRahul Lakkireddy return rc; 50327887bc7SRahul Lakkireddy } 50456cf2635SRahul Lakkireddy return cudbg_write_and_release_buff(pdbg_init, &temp_buff, dbg_buff); 50527887bc7SRahul Lakkireddy } 50627887bc7SRahul Lakkireddy 50727887bc7SRahul Lakkireddy int cudbg_collect_cim_ma_la(struct cudbg_init *pdbg_init, 50827887bc7SRahul Lakkireddy struct cudbg_buffer *dbg_buff, 50927887bc7SRahul Lakkireddy struct cudbg_error *cudbg_err) 51027887bc7SRahul Lakkireddy { 51127887bc7SRahul Lakkireddy struct adapter *padap = pdbg_init->adap; 51227887bc7SRahul Lakkireddy struct cudbg_buffer temp_buff = { 0 }; 51327887bc7SRahul Lakkireddy int size, rc; 51427887bc7SRahul Lakkireddy 51527887bc7SRahul Lakkireddy size = 2 * CIM_MALA_SIZE * 5 * sizeof(u32); 51656cf2635SRahul Lakkireddy rc = cudbg_get_buff(pdbg_init, dbg_buff, size, &temp_buff); 51727887bc7SRahul Lakkireddy if (rc) 51827887bc7SRahul Lakkireddy return rc; 51927887bc7SRahul Lakkireddy 52027887bc7SRahul Lakkireddy t4_cim_read_ma_la(padap, 52127887bc7SRahul Lakkireddy (u32 *)temp_buff.data, 52227887bc7SRahul Lakkireddy (u32 *)((char *)temp_buff.data + 52327887bc7SRahul Lakkireddy 5 * CIM_MALA_SIZE)); 52456cf2635SRahul Lakkireddy return cudbg_write_and_release_buff(pdbg_init, &temp_buff, dbg_buff); 52527887bc7SRahul Lakkireddy } 52627887bc7SRahul Lakkireddy 5273044d0fbSRahul Lakkireddy int cudbg_collect_cim_qcfg(struct cudbg_init *pdbg_init, 5283044d0fbSRahul Lakkireddy struct cudbg_buffer *dbg_buff, 5293044d0fbSRahul Lakkireddy struct cudbg_error *cudbg_err) 5303044d0fbSRahul Lakkireddy { 5313044d0fbSRahul Lakkireddy struct adapter *padap = pdbg_init->adap; 5323044d0fbSRahul Lakkireddy struct cudbg_buffer temp_buff = { 0 }; 5333044d0fbSRahul Lakkireddy struct cudbg_cim_qcfg *cim_qcfg_data; 5343044d0fbSRahul Lakkireddy int rc; 5353044d0fbSRahul Lakkireddy 53656cf2635SRahul Lakkireddy rc = cudbg_get_buff(pdbg_init, dbg_buff, sizeof(struct cudbg_cim_qcfg), 5373044d0fbSRahul Lakkireddy &temp_buff); 5383044d0fbSRahul Lakkireddy if (rc) 5393044d0fbSRahul Lakkireddy return rc; 5403044d0fbSRahul Lakkireddy 5413044d0fbSRahul Lakkireddy cim_qcfg_data = (struct cudbg_cim_qcfg *)temp_buff.data; 5423044d0fbSRahul Lakkireddy cim_qcfg_data->chip = padap->params.chip; 5433044d0fbSRahul Lakkireddy rc = t4_cim_read(padap, UP_IBQ_0_RDADDR_A, 5443044d0fbSRahul Lakkireddy ARRAY_SIZE(cim_qcfg_data->stat), cim_qcfg_data->stat); 5453044d0fbSRahul Lakkireddy if (rc) { 5463044d0fbSRahul Lakkireddy cudbg_err->sys_err = rc; 54756cf2635SRahul Lakkireddy cudbg_put_buff(pdbg_init, &temp_buff); 5483044d0fbSRahul Lakkireddy return rc; 5493044d0fbSRahul Lakkireddy } 5503044d0fbSRahul Lakkireddy 5513044d0fbSRahul Lakkireddy rc = t4_cim_read(padap, UP_OBQ_0_REALADDR_A, 5523044d0fbSRahul Lakkireddy ARRAY_SIZE(cim_qcfg_data->obq_wr), 5533044d0fbSRahul Lakkireddy cim_qcfg_data->obq_wr); 5543044d0fbSRahul Lakkireddy if (rc) { 5553044d0fbSRahul Lakkireddy cudbg_err->sys_err = rc; 55656cf2635SRahul Lakkireddy cudbg_put_buff(pdbg_init, &temp_buff); 5573044d0fbSRahul Lakkireddy return rc; 5583044d0fbSRahul Lakkireddy } 5593044d0fbSRahul Lakkireddy 5603044d0fbSRahul Lakkireddy t4_read_cimq_cfg(padap, cim_qcfg_data->base, cim_qcfg_data->size, 5613044d0fbSRahul Lakkireddy cim_qcfg_data->thres); 56256cf2635SRahul Lakkireddy return cudbg_write_and_release_buff(pdbg_init, &temp_buff, dbg_buff); 5633044d0fbSRahul Lakkireddy } 5643044d0fbSRahul Lakkireddy 5657c075ce2SRahul Lakkireddy static int cudbg_read_cim_ibq(struct cudbg_init *pdbg_init, 5667c075ce2SRahul Lakkireddy struct cudbg_buffer *dbg_buff, 5677c075ce2SRahul Lakkireddy struct cudbg_error *cudbg_err, int qid) 5687c075ce2SRahul Lakkireddy { 5697c075ce2SRahul Lakkireddy struct adapter *padap = pdbg_init->adap; 5707c075ce2SRahul Lakkireddy struct cudbg_buffer temp_buff = { 0 }; 5717c075ce2SRahul Lakkireddy int no_of_read_words, rc = 0; 5727c075ce2SRahul Lakkireddy u32 qsize; 5737c075ce2SRahul Lakkireddy 5747c075ce2SRahul Lakkireddy /* collect CIM IBQ */ 5757c075ce2SRahul Lakkireddy qsize = CIM_IBQ_SIZE * 4 * sizeof(u32); 57656cf2635SRahul Lakkireddy rc = cudbg_get_buff(pdbg_init, dbg_buff, qsize, &temp_buff); 5777c075ce2SRahul Lakkireddy if (rc) 5787c075ce2SRahul Lakkireddy return rc; 5797c075ce2SRahul Lakkireddy 5807c075ce2SRahul Lakkireddy /* t4_read_cim_ibq will return no. of read words or error */ 5817c075ce2SRahul Lakkireddy no_of_read_words = t4_read_cim_ibq(padap, qid, 582acfdf7eaSRahul Lakkireddy (u32 *)temp_buff.data, qsize); 5837c075ce2SRahul Lakkireddy /* no_of_read_words is less than or equal to 0 means error */ 5847c075ce2SRahul Lakkireddy if (no_of_read_words <= 0) { 5857c075ce2SRahul Lakkireddy if (!no_of_read_words) 5867c075ce2SRahul Lakkireddy rc = CUDBG_SYSTEM_ERROR; 5877c075ce2SRahul Lakkireddy else 5887c075ce2SRahul Lakkireddy rc = no_of_read_words; 5897c075ce2SRahul Lakkireddy cudbg_err->sys_err = rc; 59056cf2635SRahul Lakkireddy cudbg_put_buff(pdbg_init, &temp_buff); 5917c075ce2SRahul Lakkireddy return rc; 5927c075ce2SRahul Lakkireddy } 59356cf2635SRahul Lakkireddy return cudbg_write_and_release_buff(pdbg_init, &temp_buff, dbg_buff); 5947c075ce2SRahul Lakkireddy } 5957c075ce2SRahul Lakkireddy 5967c075ce2SRahul Lakkireddy int cudbg_collect_cim_ibq_tp0(struct cudbg_init *pdbg_init, 5977c075ce2SRahul Lakkireddy struct cudbg_buffer *dbg_buff, 5987c075ce2SRahul Lakkireddy struct cudbg_error *cudbg_err) 5997c075ce2SRahul Lakkireddy { 6007c075ce2SRahul Lakkireddy return cudbg_read_cim_ibq(pdbg_init, dbg_buff, cudbg_err, 0); 6017c075ce2SRahul Lakkireddy } 6027c075ce2SRahul Lakkireddy 6037c075ce2SRahul Lakkireddy int cudbg_collect_cim_ibq_tp1(struct cudbg_init *pdbg_init, 6047c075ce2SRahul Lakkireddy struct cudbg_buffer *dbg_buff, 6057c075ce2SRahul Lakkireddy struct cudbg_error *cudbg_err) 6067c075ce2SRahul Lakkireddy { 6077c075ce2SRahul Lakkireddy return cudbg_read_cim_ibq(pdbg_init, dbg_buff, cudbg_err, 1); 6087c075ce2SRahul Lakkireddy } 6097c075ce2SRahul Lakkireddy 6107c075ce2SRahul Lakkireddy int cudbg_collect_cim_ibq_ulp(struct cudbg_init *pdbg_init, 6117c075ce2SRahul Lakkireddy struct cudbg_buffer *dbg_buff, 6127c075ce2SRahul Lakkireddy struct cudbg_error *cudbg_err) 6137c075ce2SRahul Lakkireddy { 6147c075ce2SRahul Lakkireddy return cudbg_read_cim_ibq(pdbg_init, dbg_buff, cudbg_err, 2); 6157c075ce2SRahul Lakkireddy } 6167c075ce2SRahul Lakkireddy 6177c075ce2SRahul Lakkireddy int cudbg_collect_cim_ibq_sge0(struct cudbg_init *pdbg_init, 6187c075ce2SRahul Lakkireddy struct cudbg_buffer *dbg_buff, 6197c075ce2SRahul Lakkireddy struct cudbg_error *cudbg_err) 6207c075ce2SRahul Lakkireddy { 6217c075ce2SRahul Lakkireddy return cudbg_read_cim_ibq(pdbg_init, dbg_buff, cudbg_err, 3); 6227c075ce2SRahul Lakkireddy } 6237c075ce2SRahul Lakkireddy 6247c075ce2SRahul Lakkireddy int cudbg_collect_cim_ibq_sge1(struct cudbg_init *pdbg_init, 6257c075ce2SRahul Lakkireddy struct cudbg_buffer *dbg_buff, 6267c075ce2SRahul Lakkireddy struct cudbg_error *cudbg_err) 6277c075ce2SRahul Lakkireddy { 6287c075ce2SRahul Lakkireddy return cudbg_read_cim_ibq(pdbg_init, dbg_buff, cudbg_err, 4); 6297c075ce2SRahul Lakkireddy } 6307c075ce2SRahul Lakkireddy 6317c075ce2SRahul Lakkireddy int cudbg_collect_cim_ibq_ncsi(struct cudbg_init *pdbg_init, 6327c075ce2SRahul Lakkireddy struct cudbg_buffer *dbg_buff, 6337c075ce2SRahul Lakkireddy struct cudbg_error *cudbg_err) 6347c075ce2SRahul Lakkireddy { 6357c075ce2SRahul Lakkireddy return cudbg_read_cim_ibq(pdbg_init, dbg_buff, cudbg_err, 5); 6367c075ce2SRahul Lakkireddy } 6377c075ce2SRahul Lakkireddy 638acfdf7eaSRahul Lakkireddy u32 cudbg_cim_obq_size(struct adapter *padap, int qid) 639acfdf7eaSRahul Lakkireddy { 640acfdf7eaSRahul Lakkireddy u32 value; 641acfdf7eaSRahul Lakkireddy 642acfdf7eaSRahul Lakkireddy t4_write_reg(padap, CIM_QUEUE_CONFIG_REF_A, OBQSELECT_F | 643acfdf7eaSRahul Lakkireddy QUENUMSELECT_V(qid)); 644acfdf7eaSRahul Lakkireddy value = t4_read_reg(padap, CIM_QUEUE_CONFIG_CTRL_A); 645acfdf7eaSRahul Lakkireddy value = CIMQSIZE_G(value) * 64; /* size in number of words */ 646acfdf7eaSRahul Lakkireddy return value * sizeof(u32); 647acfdf7eaSRahul Lakkireddy } 648acfdf7eaSRahul Lakkireddy 6497c075ce2SRahul Lakkireddy static int cudbg_read_cim_obq(struct cudbg_init *pdbg_init, 6507c075ce2SRahul Lakkireddy struct cudbg_buffer *dbg_buff, 6517c075ce2SRahul Lakkireddy struct cudbg_error *cudbg_err, int qid) 6527c075ce2SRahul Lakkireddy { 6537c075ce2SRahul Lakkireddy struct adapter *padap = pdbg_init->adap; 6547c075ce2SRahul Lakkireddy struct cudbg_buffer temp_buff = { 0 }; 6557c075ce2SRahul Lakkireddy int no_of_read_words, rc = 0; 6567c075ce2SRahul Lakkireddy u32 qsize; 6577c075ce2SRahul Lakkireddy 6587c075ce2SRahul Lakkireddy /* collect CIM OBQ */ 659acfdf7eaSRahul Lakkireddy qsize = cudbg_cim_obq_size(padap, qid); 66056cf2635SRahul Lakkireddy rc = cudbg_get_buff(pdbg_init, dbg_buff, qsize, &temp_buff); 6617c075ce2SRahul Lakkireddy if (rc) 6627c075ce2SRahul Lakkireddy return rc; 6637c075ce2SRahul Lakkireddy 6647c075ce2SRahul Lakkireddy /* t4_read_cim_obq will return no. of read words or error */ 6657c075ce2SRahul Lakkireddy no_of_read_words = t4_read_cim_obq(padap, qid, 666acfdf7eaSRahul Lakkireddy (u32 *)temp_buff.data, qsize); 6677c075ce2SRahul Lakkireddy /* no_of_read_words is less than or equal to 0 means error */ 6687c075ce2SRahul Lakkireddy if (no_of_read_words <= 0) { 6697c075ce2SRahul Lakkireddy if (!no_of_read_words) 6707c075ce2SRahul Lakkireddy rc = CUDBG_SYSTEM_ERROR; 6717c075ce2SRahul Lakkireddy else 6727c075ce2SRahul Lakkireddy rc = no_of_read_words; 6737c075ce2SRahul Lakkireddy cudbg_err->sys_err = rc; 67456cf2635SRahul Lakkireddy cudbg_put_buff(pdbg_init, &temp_buff); 6757c075ce2SRahul Lakkireddy return rc; 6767c075ce2SRahul Lakkireddy } 67756cf2635SRahul Lakkireddy return cudbg_write_and_release_buff(pdbg_init, &temp_buff, dbg_buff); 6787c075ce2SRahul Lakkireddy } 6797c075ce2SRahul Lakkireddy 6807c075ce2SRahul Lakkireddy int cudbg_collect_cim_obq_ulp0(struct cudbg_init *pdbg_init, 6817c075ce2SRahul Lakkireddy struct cudbg_buffer *dbg_buff, 6827c075ce2SRahul Lakkireddy struct cudbg_error *cudbg_err) 6837c075ce2SRahul Lakkireddy { 6847c075ce2SRahul Lakkireddy return cudbg_read_cim_obq(pdbg_init, dbg_buff, cudbg_err, 0); 6857c075ce2SRahul Lakkireddy } 6867c075ce2SRahul Lakkireddy 6877c075ce2SRahul Lakkireddy int cudbg_collect_cim_obq_ulp1(struct cudbg_init *pdbg_init, 6887c075ce2SRahul Lakkireddy struct cudbg_buffer *dbg_buff, 6897c075ce2SRahul Lakkireddy struct cudbg_error *cudbg_err) 6907c075ce2SRahul Lakkireddy { 6917c075ce2SRahul Lakkireddy return cudbg_read_cim_obq(pdbg_init, dbg_buff, cudbg_err, 1); 6927c075ce2SRahul Lakkireddy } 6937c075ce2SRahul Lakkireddy 6947c075ce2SRahul Lakkireddy int cudbg_collect_cim_obq_ulp2(struct cudbg_init *pdbg_init, 6957c075ce2SRahul Lakkireddy struct cudbg_buffer *dbg_buff, 6967c075ce2SRahul Lakkireddy struct cudbg_error *cudbg_err) 6977c075ce2SRahul Lakkireddy { 6987c075ce2SRahul Lakkireddy return cudbg_read_cim_obq(pdbg_init, dbg_buff, cudbg_err, 2); 6997c075ce2SRahul Lakkireddy } 7007c075ce2SRahul Lakkireddy 7017c075ce2SRahul Lakkireddy int cudbg_collect_cim_obq_ulp3(struct cudbg_init *pdbg_init, 7027c075ce2SRahul Lakkireddy struct cudbg_buffer *dbg_buff, 7037c075ce2SRahul Lakkireddy struct cudbg_error *cudbg_err) 7047c075ce2SRahul Lakkireddy { 7057c075ce2SRahul Lakkireddy return cudbg_read_cim_obq(pdbg_init, dbg_buff, cudbg_err, 3); 7067c075ce2SRahul Lakkireddy } 7077c075ce2SRahul Lakkireddy 7087c075ce2SRahul Lakkireddy int cudbg_collect_cim_obq_sge(struct cudbg_init *pdbg_init, 7097c075ce2SRahul Lakkireddy struct cudbg_buffer *dbg_buff, 7107c075ce2SRahul Lakkireddy struct cudbg_error *cudbg_err) 7117c075ce2SRahul Lakkireddy { 7127c075ce2SRahul Lakkireddy return cudbg_read_cim_obq(pdbg_init, dbg_buff, cudbg_err, 4); 7137c075ce2SRahul Lakkireddy } 7147c075ce2SRahul Lakkireddy 7157c075ce2SRahul Lakkireddy int cudbg_collect_cim_obq_ncsi(struct cudbg_init *pdbg_init, 7167c075ce2SRahul Lakkireddy struct cudbg_buffer *dbg_buff, 7177c075ce2SRahul Lakkireddy struct cudbg_error *cudbg_err) 7187c075ce2SRahul Lakkireddy { 7197c075ce2SRahul Lakkireddy return cudbg_read_cim_obq(pdbg_init, dbg_buff, cudbg_err, 5); 7207c075ce2SRahul Lakkireddy } 7217c075ce2SRahul Lakkireddy 7227c075ce2SRahul Lakkireddy int cudbg_collect_obq_sge_rx_q0(struct cudbg_init *pdbg_init, 7237c075ce2SRahul Lakkireddy struct cudbg_buffer *dbg_buff, 7247c075ce2SRahul Lakkireddy struct cudbg_error *cudbg_err) 7257c075ce2SRahul Lakkireddy { 7267c075ce2SRahul Lakkireddy return cudbg_read_cim_obq(pdbg_init, dbg_buff, cudbg_err, 6); 7277c075ce2SRahul Lakkireddy } 7287c075ce2SRahul Lakkireddy 7297c075ce2SRahul Lakkireddy int cudbg_collect_obq_sge_rx_q1(struct cudbg_init *pdbg_init, 7307c075ce2SRahul Lakkireddy struct cudbg_buffer *dbg_buff, 7317c075ce2SRahul Lakkireddy struct cudbg_error *cudbg_err) 7327c075ce2SRahul Lakkireddy { 7337c075ce2SRahul Lakkireddy return cudbg_read_cim_obq(pdbg_init, dbg_buff, cudbg_err, 7); 7347c075ce2SRahul Lakkireddy } 7357c075ce2SRahul Lakkireddy 736a1c69520SRahul Lakkireddy static int cudbg_meminfo_get_mem_index(struct adapter *padap, 737a1c69520SRahul Lakkireddy struct cudbg_meminfo *mem_info, 738a1c69520SRahul Lakkireddy u8 mem_type, u8 *idx) 739a1c69520SRahul Lakkireddy { 740a1c69520SRahul Lakkireddy u8 i, flag; 741a1c69520SRahul Lakkireddy 742a1c69520SRahul Lakkireddy switch (mem_type) { 743a1c69520SRahul Lakkireddy case MEM_EDC0: 744a1c69520SRahul Lakkireddy flag = EDC0_FLAG; 745a1c69520SRahul Lakkireddy break; 746a1c69520SRahul Lakkireddy case MEM_EDC1: 747a1c69520SRahul Lakkireddy flag = EDC1_FLAG; 748a1c69520SRahul Lakkireddy break; 749a1c69520SRahul Lakkireddy case MEM_MC0: 750a1c69520SRahul Lakkireddy /* Some T5 cards have both MC0 and MC1. */ 751a1c69520SRahul Lakkireddy flag = is_t5(padap->params.chip) ? MC0_FLAG : MC_FLAG; 752a1c69520SRahul Lakkireddy break; 753a1c69520SRahul Lakkireddy case MEM_MC1: 754a1c69520SRahul Lakkireddy flag = MC1_FLAG; 755a1c69520SRahul Lakkireddy break; 7564db0401fSRahul Lakkireddy case MEM_HMA: 7574db0401fSRahul Lakkireddy flag = HMA_FLAG; 7584db0401fSRahul Lakkireddy break; 759a1c69520SRahul Lakkireddy default: 760a1c69520SRahul Lakkireddy return CUDBG_STATUS_ENTITY_NOT_FOUND; 761a1c69520SRahul Lakkireddy } 762a1c69520SRahul Lakkireddy 763a1c69520SRahul Lakkireddy for (i = 0; i < mem_info->avail_c; i++) { 764a1c69520SRahul Lakkireddy if (mem_info->avail[i].idx == flag) { 765a1c69520SRahul Lakkireddy *idx = i; 766a1c69520SRahul Lakkireddy return 0; 767a1c69520SRahul Lakkireddy } 768a1c69520SRahul Lakkireddy } 769a1c69520SRahul Lakkireddy 770a1c69520SRahul Lakkireddy return CUDBG_STATUS_ENTITY_NOT_FOUND; 771a1c69520SRahul Lakkireddy } 772a1c69520SRahul Lakkireddy 773c1219653SRahul Lakkireddy /* Fetch the @region_name's start and end from @meminfo. */ 774c1219653SRahul Lakkireddy static int cudbg_get_mem_region(struct adapter *padap, 775c1219653SRahul Lakkireddy struct cudbg_meminfo *meminfo, 776c1219653SRahul Lakkireddy u8 mem_type, const char *region_name, 777c1219653SRahul Lakkireddy struct cudbg_mem_desc *mem_desc) 778c1219653SRahul Lakkireddy { 779c1219653SRahul Lakkireddy u8 mc, found = 0; 780c8119fa8SYueHaibing u32 idx = 0; 781c8119fa8SYueHaibing int rc, i; 782c1219653SRahul Lakkireddy 783c1219653SRahul Lakkireddy rc = cudbg_meminfo_get_mem_index(padap, meminfo, mem_type, &mc); 784c1219653SRahul Lakkireddy if (rc) 785c1219653SRahul Lakkireddy return rc; 786c1219653SRahul Lakkireddy 787c8119fa8SYueHaibing i = match_string(cudbg_region, ARRAY_SIZE(cudbg_region), region_name); 788c8119fa8SYueHaibing if (i < 0) 789c1219653SRahul Lakkireddy return -EINVAL; 790c1219653SRahul Lakkireddy 791c8119fa8SYueHaibing idx = i; 792c1219653SRahul Lakkireddy for (i = 0; i < meminfo->mem_c; i++) { 793c1219653SRahul Lakkireddy if (meminfo->mem[i].idx >= ARRAY_SIZE(cudbg_region)) 794c1219653SRahul Lakkireddy continue; /* Skip holes */ 795c1219653SRahul Lakkireddy 796c1219653SRahul Lakkireddy if (!(meminfo->mem[i].limit)) 797c1219653SRahul Lakkireddy meminfo->mem[i].limit = 798c1219653SRahul Lakkireddy i < meminfo->mem_c - 1 ? 799c1219653SRahul Lakkireddy meminfo->mem[i + 1].base - 1 : ~0; 800c1219653SRahul Lakkireddy 801c1219653SRahul Lakkireddy if (meminfo->mem[i].idx == idx) { 802c1219653SRahul Lakkireddy /* Check if the region exists in @mem_type memory */ 803c1219653SRahul Lakkireddy if (meminfo->mem[i].base < meminfo->avail[mc].base && 804c1219653SRahul Lakkireddy meminfo->mem[i].limit < meminfo->avail[mc].base) 805c1219653SRahul Lakkireddy return -EINVAL; 806c1219653SRahul Lakkireddy 807c1219653SRahul Lakkireddy if (meminfo->mem[i].base > meminfo->avail[mc].limit) 808c1219653SRahul Lakkireddy return -EINVAL; 809c1219653SRahul Lakkireddy 810c1219653SRahul Lakkireddy memcpy(mem_desc, &meminfo->mem[i], 811c1219653SRahul Lakkireddy sizeof(struct cudbg_mem_desc)); 812c1219653SRahul Lakkireddy found = 1; 813c1219653SRahul Lakkireddy break; 814c1219653SRahul Lakkireddy } 815c1219653SRahul Lakkireddy } 816c1219653SRahul Lakkireddy if (!found) 817c1219653SRahul Lakkireddy return -EINVAL; 818c1219653SRahul Lakkireddy 819c1219653SRahul Lakkireddy return 0; 820c1219653SRahul Lakkireddy } 821c1219653SRahul Lakkireddy 822c1219653SRahul Lakkireddy /* Fetch and update the start and end of the requested memory region w.r.t 0 823c1219653SRahul Lakkireddy * in the corresponding EDC/MC/HMA. 824c1219653SRahul Lakkireddy */ 825c1219653SRahul Lakkireddy static int cudbg_get_mem_relative(struct adapter *padap, 826c1219653SRahul Lakkireddy struct cudbg_meminfo *meminfo, 827c1219653SRahul Lakkireddy u8 mem_type, u32 *out_base, u32 *out_end) 828c1219653SRahul Lakkireddy { 829c1219653SRahul Lakkireddy u8 mc_idx; 830c1219653SRahul Lakkireddy int rc; 831c1219653SRahul Lakkireddy 832c1219653SRahul Lakkireddy rc = cudbg_meminfo_get_mem_index(padap, meminfo, mem_type, &mc_idx); 833c1219653SRahul Lakkireddy if (rc) 834c1219653SRahul Lakkireddy return rc; 835c1219653SRahul Lakkireddy 836c1219653SRahul Lakkireddy if (*out_base < meminfo->avail[mc_idx].base) 837c1219653SRahul Lakkireddy *out_base = 0; 838c1219653SRahul Lakkireddy else 839c1219653SRahul Lakkireddy *out_base -= meminfo->avail[mc_idx].base; 840c1219653SRahul Lakkireddy 841c1219653SRahul Lakkireddy if (*out_end > meminfo->avail[mc_idx].limit) 842c1219653SRahul Lakkireddy *out_end = meminfo->avail[mc_idx].limit; 843c1219653SRahul Lakkireddy else 844c1219653SRahul Lakkireddy *out_end -= meminfo->avail[mc_idx].base; 845c1219653SRahul Lakkireddy 846c1219653SRahul Lakkireddy return 0; 847c1219653SRahul Lakkireddy } 848c1219653SRahul Lakkireddy 849c1219653SRahul Lakkireddy /* Get TX and RX Payload region */ 850c1219653SRahul Lakkireddy static int cudbg_get_payload_range(struct adapter *padap, u8 mem_type, 851c1219653SRahul Lakkireddy const char *region_name, 852c1219653SRahul Lakkireddy struct cudbg_region_info *payload) 853c1219653SRahul Lakkireddy { 854c1219653SRahul Lakkireddy struct cudbg_mem_desc mem_desc = { 0 }; 855c1219653SRahul Lakkireddy struct cudbg_meminfo meminfo; 856c1219653SRahul Lakkireddy int rc; 857c1219653SRahul Lakkireddy 858c1219653SRahul Lakkireddy rc = cudbg_fill_meminfo(padap, &meminfo); 859c1219653SRahul Lakkireddy if (rc) 860c1219653SRahul Lakkireddy return rc; 861c1219653SRahul Lakkireddy 862c1219653SRahul Lakkireddy rc = cudbg_get_mem_region(padap, &meminfo, mem_type, region_name, 863c1219653SRahul Lakkireddy &mem_desc); 864c1219653SRahul Lakkireddy if (rc) { 865c1219653SRahul Lakkireddy payload->exist = false; 866c1219653SRahul Lakkireddy return 0; 867c1219653SRahul Lakkireddy } 868c1219653SRahul Lakkireddy 869c1219653SRahul Lakkireddy payload->exist = true; 870c1219653SRahul Lakkireddy payload->start = mem_desc.base; 871c1219653SRahul Lakkireddy payload->end = mem_desc.limit; 872c1219653SRahul Lakkireddy 873c1219653SRahul Lakkireddy return cudbg_get_mem_relative(padap, &meminfo, mem_type, 874c1219653SRahul Lakkireddy &payload->start, &payload->end); 875c1219653SRahul Lakkireddy } 876c1219653SRahul Lakkireddy 8771a4330cdSRahul Lakkireddy static int cudbg_memory_read(struct cudbg_init *pdbg_init, int win, 8781a4330cdSRahul Lakkireddy int mtype, u32 addr, u32 len, void *hbuf) 8791a4330cdSRahul Lakkireddy { 8801a4330cdSRahul Lakkireddy u32 win_pf, memoffset, mem_aperture, mem_base; 8811a4330cdSRahul Lakkireddy struct adapter *adap = pdbg_init->adap; 8821a4330cdSRahul Lakkireddy u32 pos, offset, resid; 8837494f980SRahul Lakkireddy u32 *res_buf; 8847494f980SRahul Lakkireddy u64 *buf; 8851a4330cdSRahul Lakkireddy int ret; 8861a4330cdSRahul Lakkireddy 8871a4330cdSRahul Lakkireddy /* Argument sanity checks ... 8881a4330cdSRahul Lakkireddy */ 8891a4330cdSRahul Lakkireddy if (addr & 0x3 || (uintptr_t)hbuf & 0x3) 8901a4330cdSRahul Lakkireddy return -EINVAL; 8911a4330cdSRahul Lakkireddy 8927494f980SRahul Lakkireddy buf = (u64 *)hbuf; 8931a4330cdSRahul Lakkireddy 8947494f980SRahul Lakkireddy /* Try to do 64-bit reads. Residual will be handled later. */ 8957494f980SRahul Lakkireddy resid = len & 0x7; 8961a4330cdSRahul Lakkireddy len -= resid; 8971a4330cdSRahul Lakkireddy 8981a4330cdSRahul Lakkireddy ret = t4_memory_rw_init(adap, win, mtype, &memoffset, &mem_base, 8991a4330cdSRahul Lakkireddy &mem_aperture); 9001a4330cdSRahul Lakkireddy if (ret) 9011a4330cdSRahul Lakkireddy return ret; 9021a4330cdSRahul Lakkireddy 9031a4330cdSRahul Lakkireddy addr = addr + memoffset; 9041a4330cdSRahul Lakkireddy win_pf = is_t4(adap->params.chip) ? 0 : PFNUM_V(adap->pf); 9051a4330cdSRahul Lakkireddy 9061a4330cdSRahul Lakkireddy pos = addr & ~(mem_aperture - 1); 9071a4330cdSRahul Lakkireddy offset = addr - pos; 9081a4330cdSRahul Lakkireddy 9091a4330cdSRahul Lakkireddy /* Set up initial PCI-E Memory Window to cover the start of our 9101a4330cdSRahul Lakkireddy * transfer. 9111a4330cdSRahul Lakkireddy */ 9121a4330cdSRahul Lakkireddy t4_memory_update_win(adap, win, pos | win_pf); 9131a4330cdSRahul Lakkireddy 9141a4330cdSRahul Lakkireddy /* Transfer data from the adapter */ 9151a4330cdSRahul Lakkireddy while (len > 0) { 9167494f980SRahul Lakkireddy *buf++ = le64_to_cpu((__force __le64) 9177494f980SRahul Lakkireddy t4_read_reg64(adap, mem_base + offset)); 9187494f980SRahul Lakkireddy offset += sizeof(u64); 9197494f980SRahul Lakkireddy len -= sizeof(u64); 9201a4330cdSRahul Lakkireddy 9211a4330cdSRahul Lakkireddy /* If we've reached the end of our current window aperture, 9221a4330cdSRahul Lakkireddy * move the PCI-E Memory Window on to the next. 9231a4330cdSRahul Lakkireddy */ 9241a4330cdSRahul Lakkireddy if (offset == mem_aperture) { 9251a4330cdSRahul Lakkireddy pos += mem_aperture; 9261a4330cdSRahul Lakkireddy offset = 0; 9271a4330cdSRahul Lakkireddy t4_memory_update_win(adap, win, pos | win_pf); 9281a4330cdSRahul Lakkireddy } 9291a4330cdSRahul Lakkireddy } 9301a4330cdSRahul Lakkireddy 9317494f980SRahul Lakkireddy res_buf = (u32 *)buf; 9327494f980SRahul Lakkireddy /* Read residual in 32-bit multiples */ 9337494f980SRahul Lakkireddy while (resid > sizeof(u32)) { 9347494f980SRahul Lakkireddy *res_buf++ = le32_to_cpu((__force __le32) 9357494f980SRahul Lakkireddy t4_read_reg(adap, mem_base + offset)); 9367494f980SRahul Lakkireddy offset += sizeof(u32); 9377494f980SRahul Lakkireddy resid -= sizeof(u32); 9387494f980SRahul Lakkireddy 9397494f980SRahul Lakkireddy /* If we've reached the end of our current window aperture, 9407494f980SRahul Lakkireddy * move the PCI-E Memory Window on to the next. 9417494f980SRahul Lakkireddy */ 9427494f980SRahul Lakkireddy if (offset == mem_aperture) { 9437494f980SRahul Lakkireddy pos += mem_aperture; 9447494f980SRahul Lakkireddy offset = 0; 9457494f980SRahul Lakkireddy t4_memory_update_win(adap, win, pos | win_pf); 9467494f980SRahul Lakkireddy } 9477494f980SRahul Lakkireddy } 9487494f980SRahul Lakkireddy 9497494f980SRahul Lakkireddy /* Transfer residual < 32-bits */ 9501a4330cdSRahul Lakkireddy if (resid) 9511a4330cdSRahul Lakkireddy t4_memory_rw_residual(adap, resid, mem_base + offset, 9527494f980SRahul Lakkireddy (u8 *)res_buf, T4_MEMORY_READ); 9531a4330cdSRahul Lakkireddy 9541a4330cdSRahul Lakkireddy return 0; 9551a4330cdSRahul Lakkireddy } 9561a4330cdSRahul Lakkireddy 957a1c69520SRahul Lakkireddy #define CUDBG_YIELD_ITERATION 256 958a1c69520SRahul Lakkireddy 959b33af022SRahul Lakkireddy static int cudbg_read_fw_mem(struct cudbg_init *pdbg_init, 960b33af022SRahul Lakkireddy struct cudbg_buffer *dbg_buff, u8 mem_type, 961b33af022SRahul Lakkireddy unsigned long tot_len, 962b33af022SRahul Lakkireddy struct cudbg_error *cudbg_err) 963b33af022SRahul Lakkireddy { 964c1219653SRahul Lakkireddy static const char * const region_name[] = { "Tx payload:", 965c1219653SRahul Lakkireddy "Rx payload:" }; 966b33af022SRahul Lakkireddy unsigned long bytes, bytes_left, bytes_read = 0; 967b33af022SRahul Lakkireddy struct adapter *padap = pdbg_init->adap; 968b33af022SRahul Lakkireddy struct cudbg_buffer temp_buff = { 0 }; 969c1219653SRahul Lakkireddy struct cudbg_region_info payload[2]; 970a1c69520SRahul Lakkireddy u32 yield_count = 0; 971b33af022SRahul Lakkireddy int rc = 0; 972c1219653SRahul Lakkireddy u8 i; 973c1219653SRahul Lakkireddy 974c1219653SRahul Lakkireddy /* Get TX/RX Payload region range if they exist */ 975c1219653SRahul Lakkireddy memset(payload, 0, sizeof(payload)); 976c1219653SRahul Lakkireddy for (i = 0; i < ARRAY_SIZE(region_name); i++) { 977c1219653SRahul Lakkireddy rc = cudbg_get_payload_range(padap, mem_type, region_name[i], 978c1219653SRahul Lakkireddy &payload[i]); 979c1219653SRahul Lakkireddy if (rc) 980c1219653SRahul Lakkireddy return rc; 981c1219653SRahul Lakkireddy 982c1219653SRahul Lakkireddy if (payload[i].exist) { 983c1219653SRahul Lakkireddy /* Align start and end to avoid wrap around */ 984c1219653SRahul Lakkireddy payload[i].start = roundup(payload[i].start, 985c1219653SRahul Lakkireddy CUDBG_CHUNK_SIZE); 986c1219653SRahul Lakkireddy payload[i].end = rounddown(payload[i].end, 987c1219653SRahul Lakkireddy CUDBG_CHUNK_SIZE); 988c1219653SRahul Lakkireddy } 989c1219653SRahul Lakkireddy } 990b33af022SRahul Lakkireddy 991b33af022SRahul Lakkireddy bytes_left = tot_len; 992b33af022SRahul Lakkireddy while (bytes_left > 0) { 993a1c69520SRahul Lakkireddy /* As MC size is huge and read through PIO access, this 994a1c69520SRahul Lakkireddy * loop will hold cpu for a longer time. OS may think that 995a1c69520SRahul Lakkireddy * the process is hanged and will generate CPU stall traces. 996a1c69520SRahul Lakkireddy * So yield the cpu regularly. 997a1c69520SRahul Lakkireddy */ 998a1c69520SRahul Lakkireddy yield_count++; 999a1c69520SRahul Lakkireddy if (!(yield_count % CUDBG_YIELD_ITERATION)) 1000a1c69520SRahul Lakkireddy schedule(); 1001a1c69520SRahul Lakkireddy 1002b33af022SRahul Lakkireddy bytes = min_t(unsigned long, bytes_left, 1003b33af022SRahul Lakkireddy (unsigned long)CUDBG_CHUNK_SIZE); 100456cf2635SRahul Lakkireddy rc = cudbg_get_buff(pdbg_init, dbg_buff, bytes, &temp_buff); 1005b33af022SRahul Lakkireddy if (rc) 1006b33af022SRahul Lakkireddy return rc; 1007c1219653SRahul Lakkireddy 1008c1219653SRahul Lakkireddy for (i = 0; i < ARRAY_SIZE(payload); i++) 1009c1219653SRahul Lakkireddy if (payload[i].exist && 1010c1219653SRahul Lakkireddy bytes_read >= payload[i].start && 1011c1219653SRahul Lakkireddy bytes_read + bytes <= payload[i].end) 1012c1219653SRahul Lakkireddy /* TX and RX Payload regions can't overlap */ 1013c1219653SRahul Lakkireddy goto skip_read; 1014c1219653SRahul Lakkireddy 1015b33af022SRahul Lakkireddy spin_lock(&padap->win0_lock); 10161a4330cdSRahul Lakkireddy rc = cudbg_memory_read(pdbg_init, MEMWIN_NIC, mem_type, 10171a4330cdSRahul Lakkireddy bytes_read, bytes, temp_buff.data); 1018b33af022SRahul Lakkireddy spin_unlock(&padap->win0_lock); 1019b33af022SRahul Lakkireddy if (rc) { 1020b33af022SRahul Lakkireddy cudbg_err->sys_err = rc; 102156cf2635SRahul Lakkireddy cudbg_put_buff(pdbg_init, &temp_buff); 1022b33af022SRahul Lakkireddy return rc; 1023b33af022SRahul Lakkireddy } 1024c1219653SRahul Lakkireddy 1025c1219653SRahul Lakkireddy skip_read: 1026b33af022SRahul Lakkireddy bytes_left -= bytes; 1027b33af022SRahul Lakkireddy bytes_read += bytes; 102856cf2635SRahul Lakkireddy rc = cudbg_write_and_release_buff(pdbg_init, &temp_buff, 102956cf2635SRahul Lakkireddy dbg_buff); 103056cf2635SRahul Lakkireddy if (rc) { 103156cf2635SRahul Lakkireddy cudbg_put_buff(pdbg_init, &temp_buff); 103256cf2635SRahul Lakkireddy return rc; 103356cf2635SRahul Lakkireddy } 1034b33af022SRahul Lakkireddy } 1035b33af022SRahul Lakkireddy return rc; 1036b33af022SRahul Lakkireddy } 1037b33af022SRahul Lakkireddy 1038b33af022SRahul Lakkireddy static void cudbg_t4_fwcache(struct cudbg_init *pdbg_init, 1039b33af022SRahul Lakkireddy struct cudbg_error *cudbg_err) 1040b33af022SRahul Lakkireddy { 1041b33af022SRahul Lakkireddy struct adapter *padap = pdbg_init->adap; 1042b33af022SRahul Lakkireddy int rc; 1043b33af022SRahul Lakkireddy 1044b33af022SRahul Lakkireddy if (is_fw_attached(pdbg_init)) { 1045b33af022SRahul Lakkireddy /* Flush uP dcache before reading edcX/mcX */ 1046b33af022SRahul Lakkireddy rc = t4_fwcache(padap, FW_PARAM_DEV_FWCACHE_FLUSH); 1047b33af022SRahul Lakkireddy if (rc) 1048b33af022SRahul Lakkireddy cudbg_err->sys_warn = rc; 1049b33af022SRahul Lakkireddy } 1050b33af022SRahul Lakkireddy } 1051b33af022SRahul Lakkireddy 1052ce222748SVishal Kulkarni static int cudbg_mem_region_size(struct cudbg_init *pdbg_init, 1053b33af022SRahul Lakkireddy struct cudbg_error *cudbg_err, 1054ce222748SVishal Kulkarni u8 mem_type, unsigned long *region_size) 1055b33af022SRahul Lakkireddy { 1056a1c69520SRahul Lakkireddy struct adapter *padap = pdbg_init->adap; 1057a1c69520SRahul Lakkireddy struct cudbg_meminfo mem_info; 1058a1c69520SRahul Lakkireddy u8 mc_idx; 1059b33af022SRahul Lakkireddy int rc; 1060b33af022SRahul Lakkireddy 1061a1c69520SRahul Lakkireddy memset(&mem_info, 0, sizeof(struct cudbg_meminfo)); 1062a1c69520SRahul Lakkireddy rc = cudbg_fill_meminfo(padap, &mem_info); 1063ce222748SVishal Kulkarni if (rc) { 1064ce222748SVishal Kulkarni cudbg_err->sys_err = rc; 1065b33af022SRahul Lakkireddy return rc; 1066ce222748SVishal Kulkarni } 1067a1c69520SRahul Lakkireddy 1068a1c69520SRahul Lakkireddy cudbg_t4_fwcache(pdbg_init, cudbg_err); 1069a1c69520SRahul Lakkireddy rc = cudbg_meminfo_get_mem_index(padap, &mem_info, mem_type, &mc_idx); 1070ce222748SVishal Kulkarni if (rc) { 1071ce222748SVishal Kulkarni cudbg_err->sys_err = rc; 1072a1c69520SRahul Lakkireddy return rc; 1073ce222748SVishal Kulkarni } 1074a1c69520SRahul Lakkireddy 1075ce222748SVishal Kulkarni if (region_size) 1076ce222748SVishal Kulkarni *region_size = mem_info.avail[mc_idx].limit - 1077ce222748SVishal Kulkarni mem_info.avail[mc_idx].base; 1078ce222748SVishal Kulkarni 1079ce222748SVishal Kulkarni return 0; 1080752c2ea2SArnd Bergmann } 1081752c2ea2SArnd Bergmann 1082752c2ea2SArnd Bergmann static int cudbg_collect_mem_region(struct cudbg_init *pdbg_init, 1083752c2ea2SArnd Bergmann struct cudbg_buffer *dbg_buff, 1084752c2ea2SArnd Bergmann struct cudbg_error *cudbg_err, 1085752c2ea2SArnd Bergmann u8 mem_type) 1086752c2ea2SArnd Bergmann { 1087ce222748SVishal Kulkarni unsigned long size = 0; 1088ce222748SVishal Kulkarni int rc; 1089ce222748SVishal Kulkarni 1090ce222748SVishal Kulkarni rc = cudbg_mem_region_size(pdbg_init, cudbg_err, mem_type, &size); 1091ce222748SVishal Kulkarni if (rc) 1092ce222748SVishal Kulkarni return rc; 1093752c2ea2SArnd Bergmann 1094a1c69520SRahul Lakkireddy return cudbg_read_fw_mem(pdbg_init, dbg_buff, mem_type, size, 1095a1c69520SRahul Lakkireddy cudbg_err); 1096b33af022SRahul Lakkireddy } 1097b33af022SRahul Lakkireddy 1098b33af022SRahul Lakkireddy int cudbg_collect_edc0_meminfo(struct cudbg_init *pdbg_init, 1099b33af022SRahul Lakkireddy struct cudbg_buffer *dbg_buff, 1100b33af022SRahul Lakkireddy struct cudbg_error *cudbg_err) 1101b33af022SRahul Lakkireddy { 1102b33af022SRahul Lakkireddy return cudbg_collect_mem_region(pdbg_init, dbg_buff, cudbg_err, 1103b33af022SRahul Lakkireddy MEM_EDC0); 1104b33af022SRahul Lakkireddy } 1105b33af022SRahul Lakkireddy 1106b33af022SRahul Lakkireddy int cudbg_collect_edc1_meminfo(struct cudbg_init *pdbg_init, 1107b33af022SRahul Lakkireddy struct cudbg_buffer *dbg_buff, 1108b33af022SRahul Lakkireddy struct cudbg_error *cudbg_err) 1109b33af022SRahul Lakkireddy { 1110b33af022SRahul Lakkireddy return cudbg_collect_mem_region(pdbg_init, dbg_buff, cudbg_err, 1111b33af022SRahul Lakkireddy MEM_EDC1); 1112b33af022SRahul Lakkireddy } 1113844d1b6fSRahul Lakkireddy 1114a1c69520SRahul Lakkireddy int cudbg_collect_mc0_meminfo(struct cudbg_init *pdbg_init, 1115a1c69520SRahul Lakkireddy struct cudbg_buffer *dbg_buff, 1116a1c69520SRahul Lakkireddy struct cudbg_error *cudbg_err) 1117a1c69520SRahul Lakkireddy { 1118a1c69520SRahul Lakkireddy return cudbg_collect_mem_region(pdbg_init, dbg_buff, cudbg_err, 1119a1c69520SRahul Lakkireddy MEM_MC0); 1120a1c69520SRahul Lakkireddy } 1121a1c69520SRahul Lakkireddy 1122a1c69520SRahul Lakkireddy int cudbg_collect_mc1_meminfo(struct cudbg_init *pdbg_init, 1123a1c69520SRahul Lakkireddy struct cudbg_buffer *dbg_buff, 1124a1c69520SRahul Lakkireddy struct cudbg_error *cudbg_err) 1125a1c69520SRahul Lakkireddy { 1126a1c69520SRahul Lakkireddy return cudbg_collect_mem_region(pdbg_init, dbg_buff, cudbg_err, 1127a1c69520SRahul Lakkireddy MEM_MC1); 1128a1c69520SRahul Lakkireddy } 1129a1c69520SRahul Lakkireddy 11304db0401fSRahul Lakkireddy int cudbg_collect_hma_meminfo(struct cudbg_init *pdbg_init, 11314db0401fSRahul Lakkireddy struct cudbg_buffer *dbg_buff, 11324db0401fSRahul Lakkireddy struct cudbg_error *cudbg_err) 11334db0401fSRahul Lakkireddy { 11344db0401fSRahul Lakkireddy return cudbg_collect_mem_region(pdbg_init, dbg_buff, cudbg_err, 11354db0401fSRahul Lakkireddy MEM_HMA); 11364db0401fSRahul Lakkireddy } 11374db0401fSRahul Lakkireddy 113828b44556SRahul Lakkireddy int cudbg_collect_rss(struct cudbg_init *pdbg_init, 113928b44556SRahul Lakkireddy struct cudbg_buffer *dbg_buff, 114028b44556SRahul Lakkireddy struct cudbg_error *cudbg_err) 114128b44556SRahul Lakkireddy { 114228b44556SRahul Lakkireddy struct adapter *padap = pdbg_init->adap; 114328b44556SRahul Lakkireddy struct cudbg_buffer temp_buff = { 0 }; 1144f988008aSGanesh Goudar int rc, nentries; 114528b44556SRahul Lakkireddy 1146f988008aSGanesh Goudar nentries = t4_chip_rss_size(padap); 114756cf2635SRahul Lakkireddy rc = cudbg_get_buff(pdbg_init, dbg_buff, nentries * sizeof(u16), 114856cf2635SRahul Lakkireddy &temp_buff); 114928b44556SRahul Lakkireddy if (rc) 115028b44556SRahul Lakkireddy return rc; 115128b44556SRahul Lakkireddy 115228b44556SRahul Lakkireddy rc = t4_read_rss(padap, (u16 *)temp_buff.data); 115328b44556SRahul Lakkireddy if (rc) { 115428b44556SRahul Lakkireddy cudbg_err->sys_err = rc; 115556cf2635SRahul Lakkireddy cudbg_put_buff(pdbg_init, &temp_buff); 115628b44556SRahul Lakkireddy return rc; 115728b44556SRahul Lakkireddy } 115856cf2635SRahul Lakkireddy return cudbg_write_and_release_buff(pdbg_init, &temp_buff, dbg_buff); 115928b44556SRahul Lakkireddy } 116028b44556SRahul Lakkireddy 116128b44556SRahul Lakkireddy int cudbg_collect_rss_vf_config(struct cudbg_init *pdbg_init, 116228b44556SRahul Lakkireddy struct cudbg_buffer *dbg_buff, 116328b44556SRahul Lakkireddy struct cudbg_error *cudbg_err) 116428b44556SRahul Lakkireddy { 116528b44556SRahul Lakkireddy struct adapter *padap = pdbg_init->adap; 116628b44556SRahul Lakkireddy struct cudbg_buffer temp_buff = { 0 }; 116728b44556SRahul Lakkireddy struct cudbg_rss_vf_conf *vfconf; 116828b44556SRahul Lakkireddy int vf, rc, vf_count; 116928b44556SRahul Lakkireddy 117028b44556SRahul Lakkireddy vf_count = padap->params.arch.vfcount; 117156cf2635SRahul Lakkireddy rc = cudbg_get_buff(pdbg_init, dbg_buff, 117228b44556SRahul Lakkireddy vf_count * sizeof(struct cudbg_rss_vf_conf), 117328b44556SRahul Lakkireddy &temp_buff); 117428b44556SRahul Lakkireddy if (rc) 117528b44556SRahul Lakkireddy return rc; 117628b44556SRahul Lakkireddy 117728b44556SRahul Lakkireddy vfconf = (struct cudbg_rss_vf_conf *)temp_buff.data; 117828b44556SRahul Lakkireddy for (vf = 0; vf < vf_count; vf++) 117928b44556SRahul Lakkireddy t4_read_rss_vf_config(padap, vf, &vfconf[vf].rss_vf_vfl, 118028b44556SRahul Lakkireddy &vfconf[vf].rss_vf_vfh, true); 118156cf2635SRahul Lakkireddy return cudbg_write_and_release_buff(pdbg_init, &temp_buff, dbg_buff); 118228b44556SRahul Lakkireddy } 118328b44556SRahul Lakkireddy 11846f92a654SRahul Lakkireddy int cudbg_collect_path_mtu(struct cudbg_init *pdbg_init, 11856f92a654SRahul Lakkireddy struct cudbg_buffer *dbg_buff, 11866f92a654SRahul Lakkireddy struct cudbg_error *cudbg_err) 11876f92a654SRahul Lakkireddy { 11886f92a654SRahul Lakkireddy struct adapter *padap = pdbg_init->adap; 11896f92a654SRahul Lakkireddy struct cudbg_buffer temp_buff = { 0 }; 11906f92a654SRahul Lakkireddy int rc; 11916f92a654SRahul Lakkireddy 119256cf2635SRahul Lakkireddy rc = cudbg_get_buff(pdbg_init, dbg_buff, NMTUS * sizeof(u16), 119356cf2635SRahul Lakkireddy &temp_buff); 11946f92a654SRahul Lakkireddy if (rc) 11956f92a654SRahul Lakkireddy return rc; 11966f92a654SRahul Lakkireddy 11976f92a654SRahul Lakkireddy t4_read_mtu_tbl(padap, (u16 *)temp_buff.data, NULL); 119856cf2635SRahul Lakkireddy return cudbg_write_and_release_buff(pdbg_init, &temp_buff, dbg_buff); 11996f92a654SRahul Lakkireddy } 12006f92a654SRahul Lakkireddy 12016f92a654SRahul Lakkireddy int cudbg_collect_pm_stats(struct cudbg_init *pdbg_init, 12026f92a654SRahul Lakkireddy struct cudbg_buffer *dbg_buff, 12036f92a654SRahul Lakkireddy struct cudbg_error *cudbg_err) 12046f92a654SRahul Lakkireddy { 12056f92a654SRahul Lakkireddy struct adapter *padap = pdbg_init->adap; 12066f92a654SRahul Lakkireddy struct cudbg_buffer temp_buff = { 0 }; 12076f92a654SRahul Lakkireddy struct cudbg_pm_stats *pm_stats_buff; 12086f92a654SRahul Lakkireddy int rc; 12096f92a654SRahul Lakkireddy 121056cf2635SRahul Lakkireddy rc = cudbg_get_buff(pdbg_init, dbg_buff, sizeof(struct cudbg_pm_stats), 12116f92a654SRahul Lakkireddy &temp_buff); 12126f92a654SRahul Lakkireddy if (rc) 12136f92a654SRahul Lakkireddy return rc; 12146f92a654SRahul Lakkireddy 12156f92a654SRahul Lakkireddy pm_stats_buff = (struct cudbg_pm_stats *)temp_buff.data; 12166f92a654SRahul Lakkireddy t4_pmtx_get_stats(padap, pm_stats_buff->tx_cnt, pm_stats_buff->tx_cyc); 12176f92a654SRahul Lakkireddy t4_pmrx_get_stats(padap, pm_stats_buff->rx_cnt, pm_stats_buff->rx_cyc); 121856cf2635SRahul Lakkireddy return cudbg_write_and_release_buff(pdbg_init, &temp_buff, dbg_buff); 12196f92a654SRahul Lakkireddy } 12206f92a654SRahul Lakkireddy 122108c4901bSRahul Lakkireddy int cudbg_collect_hw_sched(struct cudbg_init *pdbg_init, 122208c4901bSRahul Lakkireddy struct cudbg_buffer *dbg_buff, 122308c4901bSRahul Lakkireddy struct cudbg_error *cudbg_err) 122408c4901bSRahul Lakkireddy { 122508c4901bSRahul Lakkireddy struct adapter *padap = pdbg_init->adap; 122608c4901bSRahul Lakkireddy struct cudbg_buffer temp_buff = { 0 }; 122708c4901bSRahul Lakkireddy struct cudbg_hw_sched *hw_sched_buff; 122808c4901bSRahul Lakkireddy int i, rc = 0; 122908c4901bSRahul Lakkireddy 123008c4901bSRahul Lakkireddy if (!padap->params.vpd.cclk) 123108c4901bSRahul Lakkireddy return CUDBG_STATUS_CCLK_NOT_DEFINED; 123208c4901bSRahul Lakkireddy 123356cf2635SRahul Lakkireddy rc = cudbg_get_buff(pdbg_init, dbg_buff, sizeof(struct cudbg_hw_sched), 123408c4901bSRahul Lakkireddy &temp_buff); 1235ca19fcb6SAditya Pakki 1236ca19fcb6SAditya Pakki if (rc) 1237ca19fcb6SAditya Pakki return rc; 1238ca19fcb6SAditya Pakki 123908c4901bSRahul Lakkireddy hw_sched_buff = (struct cudbg_hw_sched *)temp_buff.data; 124008c4901bSRahul Lakkireddy hw_sched_buff->map = t4_read_reg(padap, TP_TX_MOD_QUEUE_REQ_MAP_A); 124108c4901bSRahul Lakkireddy hw_sched_buff->mode = TIMERMODE_G(t4_read_reg(padap, TP_MOD_CONFIG_A)); 124208c4901bSRahul Lakkireddy t4_read_pace_tbl(padap, hw_sched_buff->pace_tab); 124308c4901bSRahul Lakkireddy for (i = 0; i < NTX_SCHED; ++i) 124408c4901bSRahul Lakkireddy t4_get_tx_sched(padap, i, &hw_sched_buff->kbps[i], 124508c4901bSRahul Lakkireddy &hw_sched_buff->ipg[i], true); 124656cf2635SRahul Lakkireddy return cudbg_write_and_release_buff(pdbg_init, &temp_buff, dbg_buff); 124708c4901bSRahul Lakkireddy } 124808c4901bSRahul Lakkireddy 12494359cf33SRahul Lakkireddy int cudbg_collect_tp_indirect(struct cudbg_init *pdbg_init, 12504359cf33SRahul Lakkireddy struct cudbg_buffer *dbg_buff, 12514359cf33SRahul Lakkireddy struct cudbg_error *cudbg_err) 12524359cf33SRahul Lakkireddy { 12534359cf33SRahul Lakkireddy struct adapter *padap = pdbg_init->adap; 12544359cf33SRahul Lakkireddy struct cudbg_buffer temp_buff = { 0 }; 12554359cf33SRahul Lakkireddy struct ireg_buf *ch_tp_pio; 12564359cf33SRahul Lakkireddy int i, rc, n = 0; 12574359cf33SRahul Lakkireddy u32 size; 12584359cf33SRahul Lakkireddy 12594359cf33SRahul Lakkireddy if (is_t5(padap->params.chip)) 12604359cf33SRahul Lakkireddy n = sizeof(t5_tp_pio_array) + 12614359cf33SRahul Lakkireddy sizeof(t5_tp_tm_pio_array) + 12624359cf33SRahul Lakkireddy sizeof(t5_tp_mib_index_array); 12634359cf33SRahul Lakkireddy else 12644359cf33SRahul Lakkireddy n = sizeof(t6_tp_pio_array) + 12654359cf33SRahul Lakkireddy sizeof(t6_tp_tm_pio_array) + 12664359cf33SRahul Lakkireddy sizeof(t6_tp_mib_index_array); 12674359cf33SRahul Lakkireddy 12684359cf33SRahul Lakkireddy n = n / (IREG_NUM_ELEM * sizeof(u32)); 12694359cf33SRahul Lakkireddy size = sizeof(struct ireg_buf) * n; 127056cf2635SRahul Lakkireddy rc = cudbg_get_buff(pdbg_init, dbg_buff, size, &temp_buff); 12714359cf33SRahul Lakkireddy if (rc) 12724359cf33SRahul Lakkireddy return rc; 12734359cf33SRahul Lakkireddy 12744359cf33SRahul Lakkireddy ch_tp_pio = (struct ireg_buf *)temp_buff.data; 12754359cf33SRahul Lakkireddy 12764359cf33SRahul Lakkireddy /* TP_PIO */ 12774359cf33SRahul Lakkireddy if (is_t5(padap->params.chip)) 12784359cf33SRahul Lakkireddy n = sizeof(t5_tp_pio_array) / (IREG_NUM_ELEM * sizeof(u32)); 12794359cf33SRahul Lakkireddy else if (is_t6(padap->params.chip)) 12804359cf33SRahul Lakkireddy n = sizeof(t6_tp_pio_array) / (IREG_NUM_ELEM * sizeof(u32)); 12814359cf33SRahul Lakkireddy 12824359cf33SRahul Lakkireddy for (i = 0; i < n; i++) { 12834359cf33SRahul Lakkireddy struct ireg_field *tp_pio = &ch_tp_pio->tp_pio; 12844359cf33SRahul Lakkireddy u32 *buff = ch_tp_pio->outbuf; 12854359cf33SRahul Lakkireddy 12864359cf33SRahul Lakkireddy if (is_t5(padap->params.chip)) { 12874359cf33SRahul Lakkireddy tp_pio->ireg_addr = t5_tp_pio_array[i][0]; 12884359cf33SRahul Lakkireddy tp_pio->ireg_data = t5_tp_pio_array[i][1]; 12894359cf33SRahul Lakkireddy tp_pio->ireg_local_offset = t5_tp_pio_array[i][2]; 12904359cf33SRahul Lakkireddy tp_pio->ireg_offset_range = t5_tp_pio_array[i][3]; 12914359cf33SRahul Lakkireddy } else if (is_t6(padap->params.chip)) { 12924359cf33SRahul Lakkireddy tp_pio->ireg_addr = t6_tp_pio_array[i][0]; 12934359cf33SRahul Lakkireddy tp_pio->ireg_data = t6_tp_pio_array[i][1]; 12944359cf33SRahul Lakkireddy tp_pio->ireg_local_offset = t6_tp_pio_array[i][2]; 12954359cf33SRahul Lakkireddy tp_pio->ireg_offset_range = t6_tp_pio_array[i][3]; 12964359cf33SRahul Lakkireddy } 12974359cf33SRahul Lakkireddy t4_tp_pio_read(padap, buff, tp_pio->ireg_offset_range, 12984359cf33SRahul Lakkireddy tp_pio->ireg_local_offset, true); 12994359cf33SRahul Lakkireddy ch_tp_pio++; 13004359cf33SRahul Lakkireddy } 13014359cf33SRahul Lakkireddy 13024359cf33SRahul Lakkireddy /* TP_TM_PIO */ 13034359cf33SRahul Lakkireddy if (is_t5(padap->params.chip)) 13044359cf33SRahul Lakkireddy n = sizeof(t5_tp_tm_pio_array) / (IREG_NUM_ELEM * sizeof(u32)); 13054359cf33SRahul Lakkireddy else if (is_t6(padap->params.chip)) 13064359cf33SRahul Lakkireddy n = sizeof(t6_tp_tm_pio_array) / (IREG_NUM_ELEM * sizeof(u32)); 13074359cf33SRahul Lakkireddy 13084359cf33SRahul Lakkireddy for (i = 0; i < n; i++) { 13094359cf33SRahul Lakkireddy struct ireg_field *tp_pio = &ch_tp_pio->tp_pio; 13104359cf33SRahul Lakkireddy u32 *buff = ch_tp_pio->outbuf; 13114359cf33SRahul Lakkireddy 13124359cf33SRahul Lakkireddy if (is_t5(padap->params.chip)) { 13134359cf33SRahul Lakkireddy tp_pio->ireg_addr = t5_tp_tm_pio_array[i][0]; 13144359cf33SRahul Lakkireddy tp_pio->ireg_data = t5_tp_tm_pio_array[i][1]; 13154359cf33SRahul Lakkireddy tp_pio->ireg_local_offset = t5_tp_tm_pio_array[i][2]; 13164359cf33SRahul Lakkireddy tp_pio->ireg_offset_range = t5_tp_tm_pio_array[i][3]; 13174359cf33SRahul Lakkireddy } else if (is_t6(padap->params.chip)) { 13184359cf33SRahul Lakkireddy tp_pio->ireg_addr = t6_tp_tm_pio_array[i][0]; 13194359cf33SRahul Lakkireddy tp_pio->ireg_data = t6_tp_tm_pio_array[i][1]; 13204359cf33SRahul Lakkireddy tp_pio->ireg_local_offset = t6_tp_tm_pio_array[i][2]; 13214359cf33SRahul Lakkireddy tp_pio->ireg_offset_range = t6_tp_tm_pio_array[i][3]; 13224359cf33SRahul Lakkireddy } 13234359cf33SRahul Lakkireddy t4_tp_tm_pio_read(padap, buff, tp_pio->ireg_offset_range, 13244359cf33SRahul Lakkireddy tp_pio->ireg_local_offset, true); 13254359cf33SRahul Lakkireddy ch_tp_pio++; 13264359cf33SRahul Lakkireddy } 13274359cf33SRahul Lakkireddy 13284359cf33SRahul Lakkireddy /* TP_MIB_INDEX */ 13294359cf33SRahul Lakkireddy if (is_t5(padap->params.chip)) 13304359cf33SRahul Lakkireddy n = sizeof(t5_tp_mib_index_array) / 13314359cf33SRahul Lakkireddy (IREG_NUM_ELEM * sizeof(u32)); 13324359cf33SRahul Lakkireddy else if (is_t6(padap->params.chip)) 13334359cf33SRahul Lakkireddy n = sizeof(t6_tp_mib_index_array) / 13344359cf33SRahul Lakkireddy (IREG_NUM_ELEM * sizeof(u32)); 13354359cf33SRahul Lakkireddy 13364359cf33SRahul Lakkireddy for (i = 0; i < n ; i++) { 13374359cf33SRahul Lakkireddy struct ireg_field *tp_pio = &ch_tp_pio->tp_pio; 13384359cf33SRahul Lakkireddy u32 *buff = ch_tp_pio->outbuf; 13394359cf33SRahul Lakkireddy 13404359cf33SRahul Lakkireddy if (is_t5(padap->params.chip)) { 13414359cf33SRahul Lakkireddy tp_pio->ireg_addr = t5_tp_mib_index_array[i][0]; 13424359cf33SRahul Lakkireddy tp_pio->ireg_data = t5_tp_mib_index_array[i][1]; 13434359cf33SRahul Lakkireddy tp_pio->ireg_local_offset = 13444359cf33SRahul Lakkireddy t5_tp_mib_index_array[i][2]; 13454359cf33SRahul Lakkireddy tp_pio->ireg_offset_range = 13464359cf33SRahul Lakkireddy t5_tp_mib_index_array[i][3]; 13474359cf33SRahul Lakkireddy } else if (is_t6(padap->params.chip)) { 13484359cf33SRahul Lakkireddy tp_pio->ireg_addr = t6_tp_mib_index_array[i][0]; 13494359cf33SRahul Lakkireddy tp_pio->ireg_data = t6_tp_mib_index_array[i][1]; 13504359cf33SRahul Lakkireddy tp_pio->ireg_local_offset = 13514359cf33SRahul Lakkireddy t6_tp_mib_index_array[i][2]; 13524359cf33SRahul Lakkireddy tp_pio->ireg_offset_range = 13534359cf33SRahul Lakkireddy t6_tp_mib_index_array[i][3]; 13544359cf33SRahul Lakkireddy } 13554359cf33SRahul Lakkireddy t4_tp_mib_read(padap, buff, tp_pio->ireg_offset_range, 13564359cf33SRahul Lakkireddy tp_pio->ireg_local_offset, true); 13574359cf33SRahul Lakkireddy ch_tp_pio++; 13584359cf33SRahul Lakkireddy } 135956cf2635SRahul Lakkireddy return cudbg_write_and_release_buff(pdbg_init, &temp_buff, dbg_buff); 13604359cf33SRahul Lakkireddy } 13614359cf33SRahul Lakkireddy 136280a95a80SRahul Lakkireddy static void cudbg_read_sge_qbase_indirect_reg(struct adapter *padap, 136380a95a80SRahul Lakkireddy struct sge_qbase_reg_field *qbase, 136480a95a80SRahul Lakkireddy u32 func, bool is_pf) 136580a95a80SRahul Lakkireddy { 136680a95a80SRahul Lakkireddy u32 *buff, i; 136780a95a80SRahul Lakkireddy 136880a95a80SRahul Lakkireddy if (is_pf) { 136980a95a80SRahul Lakkireddy buff = qbase->pf_data_value[func]; 137080a95a80SRahul Lakkireddy } else { 137180a95a80SRahul Lakkireddy buff = qbase->vf_data_value[func]; 137280a95a80SRahul Lakkireddy /* In SGE_QBASE_INDEX, 137380a95a80SRahul Lakkireddy * Entries 0->7 are PF0->7, Entries 8->263 are VFID0->256. 137480a95a80SRahul Lakkireddy */ 137580a95a80SRahul Lakkireddy func += 8; 137680a95a80SRahul Lakkireddy } 137780a95a80SRahul Lakkireddy 137880a95a80SRahul Lakkireddy t4_write_reg(padap, qbase->reg_addr, func); 137980a95a80SRahul Lakkireddy for (i = 0; i < SGE_QBASE_DATA_REG_NUM; i++, buff++) 138080a95a80SRahul Lakkireddy *buff = t4_read_reg(padap, qbase->reg_data[i]); 138180a95a80SRahul Lakkireddy } 138280a95a80SRahul Lakkireddy 1383270d39bfSRahul Lakkireddy int cudbg_collect_sge_indirect(struct cudbg_init *pdbg_init, 1384270d39bfSRahul Lakkireddy struct cudbg_buffer *dbg_buff, 1385270d39bfSRahul Lakkireddy struct cudbg_error *cudbg_err) 1386270d39bfSRahul Lakkireddy { 1387270d39bfSRahul Lakkireddy struct adapter *padap = pdbg_init->adap; 1388270d39bfSRahul Lakkireddy struct cudbg_buffer temp_buff = { 0 }; 138980a95a80SRahul Lakkireddy struct sge_qbase_reg_field *sge_qbase; 1390270d39bfSRahul Lakkireddy struct ireg_buf *ch_sge_dbg; 1391270d39bfSRahul Lakkireddy int i, rc; 1392270d39bfSRahul Lakkireddy 139380a95a80SRahul Lakkireddy rc = cudbg_get_buff(pdbg_init, dbg_buff, 139480a95a80SRahul Lakkireddy sizeof(*ch_sge_dbg) * 2 + sizeof(*sge_qbase), 139556cf2635SRahul Lakkireddy &temp_buff); 1396270d39bfSRahul Lakkireddy if (rc) 1397270d39bfSRahul Lakkireddy return rc; 1398270d39bfSRahul Lakkireddy 1399270d39bfSRahul Lakkireddy ch_sge_dbg = (struct ireg_buf *)temp_buff.data; 1400270d39bfSRahul Lakkireddy for (i = 0; i < 2; i++) { 1401270d39bfSRahul Lakkireddy struct ireg_field *sge_pio = &ch_sge_dbg->tp_pio; 1402270d39bfSRahul Lakkireddy u32 *buff = ch_sge_dbg->outbuf; 1403270d39bfSRahul Lakkireddy 1404270d39bfSRahul Lakkireddy sge_pio->ireg_addr = t5_sge_dbg_index_array[i][0]; 1405270d39bfSRahul Lakkireddy sge_pio->ireg_data = t5_sge_dbg_index_array[i][1]; 1406270d39bfSRahul Lakkireddy sge_pio->ireg_local_offset = t5_sge_dbg_index_array[i][2]; 1407270d39bfSRahul Lakkireddy sge_pio->ireg_offset_range = t5_sge_dbg_index_array[i][3]; 1408270d39bfSRahul Lakkireddy t4_read_indirect(padap, 1409270d39bfSRahul Lakkireddy sge_pio->ireg_addr, 1410270d39bfSRahul Lakkireddy sge_pio->ireg_data, 1411270d39bfSRahul Lakkireddy buff, 1412270d39bfSRahul Lakkireddy sge_pio->ireg_offset_range, 1413270d39bfSRahul Lakkireddy sge_pio->ireg_local_offset); 1414270d39bfSRahul Lakkireddy ch_sge_dbg++; 1415270d39bfSRahul Lakkireddy } 141680a95a80SRahul Lakkireddy 141780a95a80SRahul Lakkireddy if (CHELSIO_CHIP_VERSION(padap->params.chip) > CHELSIO_T5) { 141880a95a80SRahul Lakkireddy sge_qbase = (struct sge_qbase_reg_field *)ch_sge_dbg; 141980a95a80SRahul Lakkireddy /* 1 addr reg SGE_QBASE_INDEX and 4 data reg 142080a95a80SRahul Lakkireddy * SGE_QBASE_MAP[0-3] 142180a95a80SRahul Lakkireddy */ 142280a95a80SRahul Lakkireddy sge_qbase->reg_addr = t6_sge_qbase_index_array[0]; 142380a95a80SRahul Lakkireddy for (i = 0; i < SGE_QBASE_DATA_REG_NUM; i++) 142480a95a80SRahul Lakkireddy sge_qbase->reg_data[i] = 142580a95a80SRahul Lakkireddy t6_sge_qbase_index_array[i + 1]; 142680a95a80SRahul Lakkireddy 142780a95a80SRahul Lakkireddy for (i = 0; i <= PCIE_FW_MASTER_M; i++) 142880a95a80SRahul Lakkireddy cudbg_read_sge_qbase_indirect_reg(padap, sge_qbase, 142980a95a80SRahul Lakkireddy i, true); 143080a95a80SRahul Lakkireddy 143180a95a80SRahul Lakkireddy for (i = 0; i < padap->params.arch.vfcount; i++) 143280a95a80SRahul Lakkireddy cudbg_read_sge_qbase_indirect_reg(padap, sge_qbase, 143380a95a80SRahul Lakkireddy i, false); 143480a95a80SRahul Lakkireddy 143580a95a80SRahul Lakkireddy sge_qbase->vfcount = padap->params.arch.vfcount; 143680a95a80SRahul Lakkireddy } 143780a95a80SRahul Lakkireddy 143856cf2635SRahul Lakkireddy return cudbg_write_and_release_buff(pdbg_init, &temp_buff, dbg_buff); 1439270d39bfSRahul Lakkireddy } 1440270d39bfSRahul Lakkireddy 144127887bc7SRahul Lakkireddy int cudbg_collect_ulprx_la(struct cudbg_init *pdbg_init, 144227887bc7SRahul Lakkireddy struct cudbg_buffer *dbg_buff, 144327887bc7SRahul Lakkireddy struct cudbg_error *cudbg_err) 144427887bc7SRahul Lakkireddy { 144527887bc7SRahul Lakkireddy struct adapter *padap = pdbg_init->adap; 144627887bc7SRahul Lakkireddy struct cudbg_buffer temp_buff = { 0 }; 144727887bc7SRahul Lakkireddy struct cudbg_ulprx_la *ulprx_la_buff; 144827887bc7SRahul Lakkireddy int rc; 144927887bc7SRahul Lakkireddy 145056cf2635SRahul Lakkireddy rc = cudbg_get_buff(pdbg_init, dbg_buff, sizeof(struct cudbg_ulprx_la), 145127887bc7SRahul Lakkireddy &temp_buff); 145227887bc7SRahul Lakkireddy if (rc) 145327887bc7SRahul Lakkireddy return rc; 145427887bc7SRahul Lakkireddy 145527887bc7SRahul Lakkireddy ulprx_la_buff = (struct cudbg_ulprx_la *)temp_buff.data; 145627887bc7SRahul Lakkireddy t4_ulprx_read_la(padap, (u32 *)ulprx_la_buff->data); 145727887bc7SRahul Lakkireddy ulprx_la_buff->size = ULPRX_LA_SIZE; 145856cf2635SRahul Lakkireddy return cudbg_write_and_release_buff(pdbg_init, &temp_buff, dbg_buff); 145927887bc7SRahul Lakkireddy } 146027887bc7SRahul Lakkireddy 146127887bc7SRahul Lakkireddy int cudbg_collect_tp_la(struct cudbg_init *pdbg_init, 146227887bc7SRahul Lakkireddy struct cudbg_buffer *dbg_buff, 146327887bc7SRahul Lakkireddy struct cudbg_error *cudbg_err) 146427887bc7SRahul Lakkireddy { 146527887bc7SRahul Lakkireddy struct adapter *padap = pdbg_init->adap; 146627887bc7SRahul Lakkireddy struct cudbg_buffer temp_buff = { 0 }; 146727887bc7SRahul Lakkireddy struct cudbg_tp_la *tp_la_buff; 146827887bc7SRahul Lakkireddy int size, rc; 146927887bc7SRahul Lakkireddy 147027887bc7SRahul Lakkireddy size = sizeof(struct cudbg_tp_la) + TPLA_SIZE * sizeof(u64); 147156cf2635SRahul Lakkireddy rc = cudbg_get_buff(pdbg_init, dbg_buff, size, &temp_buff); 147227887bc7SRahul Lakkireddy if (rc) 147327887bc7SRahul Lakkireddy return rc; 147427887bc7SRahul Lakkireddy 147527887bc7SRahul Lakkireddy tp_la_buff = (struct cudbg_tp_la *)temp_buff.data; 147627887bc7SRahul Lakkireddy tp_la_buff->mode = DBGLAMODE_G(t4_read_reg(padap, TP_DBG_LA_CONFIG_A)); 147727887bc7SRahul Lakkireddy t4_tp_read_la(padap, (u64 *)tp_la_buff->data, NULL); 147856cf2635SRahul Lakkireddy return cudbg_write_and_release_buff(pdbg_init, &temp_buff, dbg_buff); 147927887bc7SRahul Lakkireddy } 148027887bc7SRahul Lakkireddy 1481123e25c4SRahul Lakkireddy int cudbg_collect_meminfo(struct cudbg_init *pdbg_init, 1482123e25c4SRahul Lakkireddy struct cudbg_buffer *dbg_buff, 1483123e25c4SRahul Lakkireddy struct cudbg_error *cudbg_err) 1484123e25c4SRahul Lakkireddy { 1485123e25c4SRahul Lakkireddy struct adapter *padap = pdbg_init->adap; 1486123e25c4SRahul Lakkireddy struct cudbg_buffer temp_buff = { 0 }; 1487123e25c4SRahul Lakkireddy struct cudbg_meminfo *meminfo_buff; 14889d0f180cSRahul Lakkireddy struct cudbg_ver_hdr *ver_hdr; 1489123e25c4SRahul Lakkireddy int rc; 1490123e25c4SRahul Lakkireddy 14919d0f180cSRahul Lakkireddy rc = cudbg_get_buff(pdbg_init, dbg_buff, 14929d0f180cSRahul Lakkireddy sizeof(struct cudbg_ver_hdr) + 14939d0f180cSRahul Lakkireddy sizeof(struct cudbg_meminfo), 149456cf2635SRahul Lakkireddy &temp_buff); 1495123e25c4SRahul Lakkireddy if (rc) 1496123e25c4SRahul Lakkireddy return rc; 1497123e25c4SRahul Lakkireddy 14989d0f180cSRahul Lakkireddy ver_hdr = (struct cudbg_ver_hdr *)temp_buff.data; 14999d0f180cSRahul Lakkireddy ver_hdr->signature = CUDBG_ENTITY_SIGNATURE; 15009d0f180cSRahul Lakkireddy ver_hdr->revision = CUDBG_MEMINFO_REV; 15019d0f180cSRahul Lakkireddy ver_hdr->size = sizeof(struct cudbg_meminfo); 15029d0f180cSRahul Lakkireddy 15039d0f180cSRahul Lakkireddy meminfo_buff = (struct cudbg_meminfo *)(temp_buff.data + 15049d0f180cSRahul Lakkireddy sizeof(*ver_hdr)); 1505123e25c4SRahul Lakkireddy rc = cudbg_fill_meminfo(padap, meminfo_buff); 1506123e25c4SRahul Lakkireddy if (rc) { 1507123e25c4SRahul Lakkireddy cudbg_err->sys_err = rc; 150856cf2635SRahul Lakkireddy cudbg_put_buff(pdbg_init, &temp_buff); 1509123e25c4SRahul Lakkireddy return rc; 1510123e25c4SRahul Lakkireddy } 1511123e25c4SRahul Lakkireddy 151256cf2635SRahul Lakkireddy return cudbg_write_and_release_buff(pdbg_init, &temp_buff, dbg_buff); 1513123e25c4SRahul Lakkireddy } 1514123e25c4SRahul Lakkireddy 151527887bc7SRahul Lakkireddy int cudbg_collect_cim_pif_la(struct cudbg_init *pdbg_init, 151627887bc7SRahul Lakkireddy struct cudbg_buffer *dbg_buff, 151727887bc7SRahul Lakkireddy struct cudbg_error *cudbg_err) 151827887bc7SRahul Lakkireddy { 151927887bc7SRahul Lakkireddy struct cudbg_cim_pif_la *cim_pif_la_buff; 152027887bc7SRahul Lakkireddy struct adapter *padap = pdbg_init->adap; 152127887bc7SRahul Lakkireddy struct cudbg_buffer temp_buff = { 0 }; 152227887bc7SRahul Lakkireddy int size, rc; 152327887bc7SRahul Lakkireddy 152427887bc7SRahul Lakkireddy size = sizeof(struct cudbg_cim_pif_la) + 152527887bc7SRahul Lakkireddy 2 * CIM_PIFLA_SIZE * 6 * sizeof(u32); 152656cf2635SRahul Lakkireddy rc = cudbg_get_buff(pdbg_init, dbg_buff, size, &temp_buff); 152727887bc7SRahul Lakkireddy if (rc) 152827887bc7SRahul Lakkireddy return rc; 152927887bc7SRahul Lakkireddy 153027887bc7SRahul Lakkireddy cim_pif_la_buff = (struct cudbg_cim_pif_la *)temp_buff.data; 153127887bc7SRahul Lakkireddy cim_pif_la_buff->size = CIM_PIFLA_SIZE; 153227887bc7SRahul Lakkireddy t4_cim_read_pif_la(padap, (u32 *)cim_pif_la_buff->data, 153327887bc7SRahul Lakkireddy (u32 *)cim_pif_la_buff->data + 6 * CIM_PIFLA_SIZE, 153427887bc7SRahul Lakkireddy NULL, NULL); 153556cf2635SRahul Lakkireddy return cudbg_write_and_release_buff(pdbg_init, &temp_buff, dbg_buff); 153627887bc7SRahul Lakkireddy } 153727887bc7SRahul Lakkireddy 15386f92a654SRahul Lakkireddy int cudbg_collect_clk_info(struct cudbg_init *pdbg_init, 15396f92a654SRahul Lakkireddy struct cudbg_buffer *dbg_buff, 15406f92a654SRahul Lakkireddy struct cudbg_error *cudbg_err) 15416f92a654SRahul Lakkireddy { 15426f92a654SRahul Lakkireddy struct adapter *padap = pdbg_init->adap; 15436f92a654SRahul Lakkireddy struct cudbg_buffer temp_buff = { 0 }; 15446f92a654SRahul Lakkireddy struct cudbg_clk_info *clk_info_buff; 15456f92a654SRahul Lakkireddy u64 tp_tick_us; 15466f92a654SRahul Lakkireddy int rc; 15476f92a654SRahul Lakkireddy 15486f92a654SRahul Lakkireddy if (!padap->params.vpd.cclk) 15496f92a654SRahul Lakkireddy return CUDBG_STATUS_CCLK_NOT_DEFINED; 15506f92a654SRahul Lakkireddy 155156cf2635SRahul Lakkireddy rc = cudbg_get_buff(pdbg_init, dbg_buff, sizeof(struct cudbg_clk_info), 15526f92a654SRahul Lakkireddy &temp_buff); 15536f92a654SRahul Lakkireddy if (rc) 15546f92a654SRahul Lakkireddy return rc; 15556f92a654SRahul Lakkireddy 15566f92a654SRahul Lakkireddy clk_info_buff = (struct cudbg_clk_info *)temp_buff.data; 15576f92a654SRahul Lakkireddy clk_info_buff->cclk_ps = 1000000000 / padap->params.vpd.cclk; /* psec */ 15586f92a654SRahul Lakkireddy clk_info_buff->res = t4_read_reg(padap, TP_TIMER_RESOLUTION_A); 15596f92a654SRahul Lakkireddy clk_info_buff->tre = TIMERRESOLUTION_G(clk_info_buff->res); 15606f92a654SRahul Lakkireddy clk_info_buff->dack_re = DELAYEDACKRESOLUTION_G(clk_info_buff->res); 15616f92a654SRahul Lakkireddy tp_tick_us = (clk_info_buff->cclk_ps << clk_info_buff->tre) / 1000000; 15626f92a654SRahul Lakkireddy 15636f92a654SRahul Lakkireddy clk_info_buff->dack_timer = 15646f92a654SRahul Lakkireddy (clk_info_buff->cclk_ps << clk_info_buff->dack_re) / 1000000 * 15656f92a654SRahul Lakkireddy t4_read_reg(padap, TP_DACK_TIMER_A); 15666f92a654SRahul Lakkireddy clk_info_buff->retransmit_min = 15676f92a654SRahul Lakkireddy tp_tick_us * t4_read_reg(padap, TP_RXT_MIN_A); 15686f92a654SRahul Lakkireddy clk_info_buff->retransmit_max = 15696f92a654SRahul Lakkireddy tp_tick_us * t4_read_reg(padap, TP_RXT_MAX_A); 15706f92a654SRahul Lakkireddy clk_info_buff->persist_timer_min = 15716f92a654SRahul Lakkireddy tp_tick_us * t4_read_reg(padap, TP_PERS_MIN_A); 15726f92a654SRahul Lakkireddy clk_info_buff->persist_timer_max = 15736f92a654SRahul Lakkireddy tp_tick_us * t4_read_reg(padap, TP_PERS_MAX_A); 15746f92a654SRahul Lakkireddy clk_info_buff->keepalive_idle_timer = 15756f92a654SRahul Lakkireddy tp_tick_us * t4_read_reg(padap, TP_KEEP_IDLE_A); 15766f92a654SRahul Lakkireddy clk_info_buff->keepalive_interval = 15776f92a654SRahul Lakkireddy tp_tick_us * t4_read_reg(padap, TP_KEEP_INTVL_A); 15786f92a654SRahul Lakkireddy clk_info_buff->initial_srtt = 15796f92a654SRahul Lakkireddy tp_tick_us * INITSRTT_G(t4_read_reg(padap, TP_INIT_SRTT_A)); 15806f92a654SRahul Lakkireddy clk_info_buff->finwait2_timer = 15816f92a654SRahul Lakkireddy tp_tick_us * t4_read_reg(padap, TP_FINWAIT2_TIMER_A); 15826f92a654SRahul Lakkireddy 158356cf2635SRahul Lakkireddy return cudbg_write_and_release_buff(pdbg_init, &temp_buff, dbg_buff); 15846f92a654SRahul Lakkireddy } 15856f92a654SRahul Lakkireddy 1586270d39bfSRahul Lakkireddy int cudbg_collect_pcie_indirect(struct cudbg_init *pdbg_init, 1587270d39bfSRahul Lakkireddy struct cudbg_buffer *dbg_buff, 1588270d39bfSRahul Lakkireddy struct cudbg_error *cudbg_err) 1589270d39bfSRahul Lakkireddy { 1590270d39bfSRahul Lakkireddy struct adapter *padap = pdbg_init->adap; 1591270d39bfSRahul Lakkireddy struct cudbg_buffer temp_buff = { 0 }; 1592270d39bfSRahul Lakkireddy struct ireg_buf *ch_pcie; 1593270d39bfSRahul Lakkireddy int i, rc, n; 1594270d39bfSRahul Lakkireddy u32 size; 1595270d39bfSRahul Lakkireddy 1596270d39bfSRahul Lakkireddy n = sizeof(t5_pcie_pdbg_array) / (IREG_NUM_ELEM * sizeof(u32)); 1597270d39bfSRahul Lakkireddy size = sizeof(struct ireg_buf) * n * 2; 159856cf2635SRahul Lakkireddy rc = cudbg_get_buff(pdbg_init, dbg_buff, size, &temp_buff); 1599270d39bfSRahul Lakkireddy if (rc) 1600270d39bfSRahul Lakkireddy return rc; 1601270d39bfSRahul Lakkireddy 1602270d39bfSRahul Lakkireddy ch_pcie = (struct ireg_buf *)temp_buff.data; 1603270d39bfSRahul Lakkireddy /* PCIE_PDBG */ 1604270d39bfSRahul Lakkireddy for (i = 0; i < n; i++) { 1605270d39bfSRahul Lakkireddy struct ireg_field *pcie_pio = &ch_pcie->tp_pio; 1606270d39bfSRahul Lakkireddy u32 *buff = ch_pcie->outbuf; 1607270d39bfSRahul Lakkireddy 1608270d39bfSRahul Lakkireddy pcie_pio->ireg_addr = t5_pcie_pdbg_array[i][0]; 1609270d39bfSRahul Lakkireddy pcie_pio->ireg_data = t5_pcie_pdbg_array[i][1]; 1610270d39bfSRahul Lakkireddy pcie_pio->ireg_local_offset = t5_pcie_pdbg_array[i][2]; 1611270d39bfSRahul Lakkireddy pcie_pio->ireg_offset_range = t5_pcie_pdbg_array[i][3]; 1612270d39bfSRahul Lakkireddy t4_read_indirect(padap, 1613270d39bfSRahul Lakkireddy pcie_pio->ireg_addr, 1614270d39bfSRahul Lakkireddy pcie_pio->ireg_data, 1615270d39bfSRahul Lakkireddy buff, 1616270d39bfSRahul Lakkireddy pcie_pio->ireg_offset_range, 1617270d39bfSRahul Lakkireddy pcie_pio->ireg_local_offset); 1618270d39bfSRahul Lakkireddy ch_pcie++; 1619270d39bfSRahul Lakkireddy } 1620270d39bfSRahul Lakkireddy 1621270d39bfSRahul Lakkireddy /* PCIE_CDBG */ 1622270d39bfSRahul Lakkireddy n = sizeof(t5_pcie_cdbg_array) / (IREG_NUM_ELEM * sizeof(u32)); 1623270d39bfSRahul Lakkireddy for (i = 0; i < n; i++) { 1624270d39bfSRahul Lakkireddy struct ireg_field *pcie_pio = &ch_pcie->tp_pio; 1625270d39bfSRahul Lakkireddy u32 *buff = ch_pcie->outbuf; 1626270d39bfSRahul Lakkireddy 1627270d39bfSRahul Lakkireddy pcie_pio->ireg_addr = t5_pcie_cdbg_array[i][0]; 1628270d39bfSRahul Lakkireddy pcie_pio->ireg_data = t5_pcie_cdbg_array[i][1]; 1629270d39bfSRahul Lakkireddy pcie_pio->ireg_local_offset = t5_pcie_cdbg_array[i][2]; 1630270d39bfSRahul Lakkireddy pcie_pio->ireg_offset_range = t5_pcie_cdbg_array[i][3]; 1631270d39bfSRahul Lakkireddy t4_read_indirect(padap, 1632270d39bfSRahul Lakkireddy pcie_pio->ireg_addr, 1633270d39bfSRahul Lakkireddy pcie_pio->ireg_data, 1634270d39bfSRahul Lakkireddy buff, 1635270d39bfSRahul Lakkireddy pcie_pio->ireg_offset_range, 1636270d39bfSRahul Lakkireddy pcie_pio->ireg_local_offset); 1637270d39bfSRahul Lakkireddy ch_pcie++; 1638270d39bfSRahul Lakkireddy } 163956cf2635SRahul Lakkireddy return cudbg_write_and_release_buff(pdbg_init, &temp_buff, dbg_buff); 1640270d39bfSRahul Lakkireddy } 1641270d39bfSRahul Lakkireddy 1642270d39bfSRahul Lakkireddy int cudbg_collect_pm_indirect(struct cudbg_init *pdbg_init, 1643270d39bfSRahul Lakkireddy struct cudbg_buffer *dbg_buff, 1644270d39bfSRahul Lakkireddy struct cudbg_error *cudbg_err) 1645270d39bfSRahul Lakkireddy { 1646270d39bfSRahul Lakkireddy struct adapter *padap = pdbg_init->adap; 1647270d39bfSRahul Lakkireddy struct cudbg_buffer temp_buff = { 0 }; 1648270d39bfSRahul Lakkireddy struct ireg_buf *ch_pm; 1649270d39bfSRahul Lakkireddy int i, rc, n; 1650270d39bfSRahul Lakkireddy u32 size; 1651270d39bfSRahul Lakkireddy 1652270d39bfSRahul Lakkireddy n = sizeof(t5_pm_rx_array) / (IREG_NUM_ELEM * sizeof(u32)); 1653270d39bfSRahul Lakkireddy size = sizeof(struct ireg_buf) * n * 2; 165456cf2635SRahul Lakkireddy rc = cudbg_get_buff(pdbg_init, dbg_buff, size, &temp_buff); 1655270d39bfSRahul Lakkireddy if (rc) 1656270d39bfSRahul Lakkireddy return rc; 1657270d39bfSRahul Lakkireddy 1658270d39bfSRahul Lakkireddy ch_pm = (struct ireg_buf *)temp_buff.data; 1659270d39bfSRahul Lakkireddy /* PM_RX */ 1660270d39bfSRahul Lakkireddy for (i = 0; i < n; i++) { 1661270d39bfSRahul Lakkireddy struct ireg_field *pm_pio = &ch_pm->tp_pio; 1662270d39bfSRahul Lakkireddy u32 *buff = ch_pm->outbuf; 1663270d39bfSRahul Lakkireddy 1664270d39bfSRahul Lakkireddy pm_pio->ireg_addr = t5_pm_rx_array[i][0]; 1665270d39bfSRahul Lakkireddy pm_pio->ireg_data = t5_pm_rx_array[i][1]; 1666270d39bfSRahul Lakkireddy pm_pio->ireg_local_offset = t5_pm_rx_array[i][2]; 1667270d39bfSRahul Lakkireddy pm_pio->ireg_offset_range = t5_pm_rx_array[i][3]; 1668270d39bfSRahul Lakkireddy t4_read_indirect(padap, 1669270d39bfSRahul Lakkireddy pm_pio->ireg_addr, 1670270d39bfSRahul Lakkireddy pm_pio->ireg_data, 1671270d39bfSRahul Lakkireddy buff, 1672270d39bfSRahul Lakkireddy pm_pio->ireg_offset_range, 1673270d39bfSRahul Lakkireddy pm_pio->ireg_local_offset); 1674270d39bfSRahul Lakkireddy ch_pm++; 1675270d39bfSRahul Lakkireddy } 1676270d39bfSRahul Lakkireddy 1677270d39bfSRahul Lakkireddy /* PM_TX */ 1678270d39bfSRahul Lakkireddy n = sizeof(t5_pm_tx_array) / (IREG_NUM_ELEM * sizeof(u32)); 1679270d39bfSRahul Lakkireddy for (i = 0; i < n; i++) { 1680270d39bfSRahul Lakkireddy struct ireg_field *pm_pio = &ch_pm->tp_pio; 1681270d39bfSRahul Lakkireddy u32 *buff = ch_pm->outbuf; 1682270d39bfSRahul Lakkireddy 1683270d39bfSRahul Lakkireddy pm_pio->ireg_addr = t5_pm_tx_array[i][0]; 1684270d39bfSRahul Lakkireddy pm_pio->ireg_data = t5_pm_tx_array[i][1]; 1685270d39bfSRahul Lakkireddy pm_pio->ireg_local_offset = t5_pm_tx_array[i][2]; 1686270d39bfSRahul Lakkireddy pm_pio->ireg_offset_range = t5_pm_tx_array[i][3]; 1687270d39bfSRahul Lakkireddy t4_read_indirect(padap, 1688270d39bfSRahul Lakkireddy pm_pio->ireg_addr, 1689270d39bfSRahul Lakkireddy pm_pio->ireg_data, 1690270d39bfSRahul Lakkireddy buff, 1691270d39bfSRahul Lakkireddy pm_pio->ireg_offset_range, 1692270d39bfSRahul Lakkireddy pm_pio->ireg_local_offset); 1693270d39bfSRahul Lakkireddy ch_pm++; 1694270d39bfSRahul Lakkireddy } 169556cf2635SRahul Lakkireddy return cudbg_write_and_release_buff(pdbg_init, &temp_buff, dbg_buff); 1696270d39bfSRahul Lakkireddy } 1697270d39bfSRahul Lakkireddy 16989030e498SRahul Lakkireddy int cudbg_collect_tid(struct cudbg_init *pdbg_init, 16999030e498SRahul Lakkireddy struct cudbg_buffer *dbg_buff, 17009030e498SRahul Lakkireddy struct cudbg_error *cudbg_err) 17019030e498SRahul Lakkireddy { 17029030e498SRahul Lakkireddy struct adapter *padap = pdbg_init->adap; 17039030e498SRahul Lakkireddy struct cudbg_tid_info_region_rev1 *tid1; 17049030e498SRahul Lakkireddy struct cudbg_buffer temp_buff = { 0 }; 17059030e498SRahul Lakkireddy struct cudbg_tid_info_region *tid; 17069030e498SRahul Lakkireddy u32 para[2], val[2]; 17079030e498SRahul Lakkireddy int rc; 17089030e498SRahul Lakkireddy 170956cf2635SRahul Lakkireddy rc = cudbg_get_buff(pdbg_init, dbg_buff, 171056cf2635SRahul Lakkireddy sizeof(struct cudbg_tid_info_region_rev1), 17119030e498SRahul Lakkireddy &temp_buff); 17129030e498SRahul Lakkireddy if (rc) 17139030e498SRahul Lakkireddy return rc; 17149030e498SRahul Lakkireddy 17159030e498SRahul Lakkireddy tid1 = (struct cudbg_tid_info_region_rev1 *)temp_buff.data; 17169030e498SRahul Lakkireddy tid = &tid1->tid; 17179030e498SRahul Lakkireddy tid1->ver_hdr.signature = CUDBG_ENTITY_SIGNATURE; 17189030e498SRahul Lakkireddy tid1->ver_hdr.revision = CUDBG_TID_INFO_REV; 17199030e498SRahul Lakkireddy tid1->ver_hdr.size = sizeof(struct cudbg_tid_info_region_rev1) - 17209030e498SRahul Lakkireddy sizeof(struct cudbg_ver_hdr); 17219030e498SRahul Lakkireddy 1722770ca347SRahul Lakkireddy /* If firmware is not attached/alive, use backdoor register 1723770ca347SRahul Lakkireddy * access to collect dump. 1724770ca347SRahul Lakkireddy */ 1725770ca347SRahul Lakkireddy if (!is_fw_attached(pdbg_init)) 1726770ca347SRahul Lakkireddy goto fill_tid; 1727770ca347SRahul Lakkireddy 17289030e498SRahul Lakkireddy #define FW_PARAM_PFVF_A(param) \ 17299030e498SRahul Lakkireddy (FW_PARAMS_MNEM_V(FW_PARAMS_MNEM_PFVF) | \ 17309030e498SRahul Lakkireddy FW_PARAMS_PARAM_X_V(FW_PARAMS_PARAM_PFVF_##param) | \ 17319030e498SRahul Lakkireddy FW_PARAMS_PARAM_Y_V(0) | \ 17329030e498SRahul Lakkireddy FW_PARAMS_PARAM_Z_V(0)) 17339030e498SRahul Lakkireddy 17349030e498SRahul Lakkireddy para[0] = FW_PARAM_PFVF_A(ETHOFLD_START); 17359030e498SRahul Lakkireddy para[1] = FW_PARAM_PFVF_A(ETHOFLD_END); 17369030e498SRahul Lakkireddy rc = t4_query_params(padap, padap->mbox, padap->pf, 0, 2, para, val); 17379030e498SRahul Lakkireddy if (rc < 0) { 17389030e498SRahul Lakkireddy cudbg_err->sys_err = rc; 173956cf2635SRahul Lakkireddy cudbg_put_buff(pdbg_init, &temp_buff); 17409030e498SRahul Lakkireddy return rc; 17419030e498SRahul Lakkireddy } 17429030e498SRahul Lakkireddy tid->uotid_base = val[0]; 17439030e498SRahul Lakkireddy tid->nuotids = val[1] - val[0] + 1; 17449030e498SRahul Lakkireddy 17459030e498SRahul Lakkireddy if (is_t5(padap->params.chip)) { 17469030e498SRahul Lakkireddy tid->sb = t4_read_reg(padap, LE_DB_SERVER_INDEX_A) / 4; 17479030e498SRahul Lakkireddy } else if (is_t6(padap->params.chip)) { 17489030e498SRahul Lakkireddy tid1->tid_start = 17499030e498SRahul Lakkireddy t4_read_reg(padap, LE_DB_ACTIVE_TABLE_START_INDEX_A); 17509030e498SRahul Lakkireddy tid->sb = t4_read_reg(padap, LE_DB_SRVR_START_INDEX_A); 17519030e498SRahul Lakkireddy 17529030e498SRahul Lakkireddy para[0] = FW_PARAM_PFVF_A(HPFILTER_START); 17539030e498SRahul Lakkireddy para[1] = FW_PARAM_PFVF_A(HPFILTER_END); 17549030e498SRahul Lakkireddy rc = t4_query_params(padap, padap->mbox, padap->pf, 0, 2, 17559030e498SRahul Lakkireddy para, val); 17569030e498SRahul Lakkireddy if (rc < 0) { 17579030e498SRahul Lakkireddy cudbg_err->sys_err = rc; 175856cf2635SRahul Lakkireddy cudbg_put_buff(pdbg_init, &temp_buff); 17599030e498SRahul Lakkireddy return rc; 17609030e498SRahul Lakkireddy } 17619030e498SRahul Lakkireddy tid->hpftid_base = val[0]; 17629030e498SRahul Lakkireddy tid->nhpftids = val[1] - val[0] + 1; 17639030e498SRahul Lakkireddy } 17649030e498SRahul Lakkireddy 1765770ca347SRahul Lakkireddy #undef FW_PARAM_PFVF_A 1766770ca347SRahul Lakkireddy 1767770ca347SRahul Lakkireddy fill_tid: 17689030e498SRahul Lakkireddy tid->ntids = padap->tids.ntids; 17699030e498SRahul Lakkireddy tid->nstids = padap->tids.nstids; 17709030e498SRahul Lakkireddy tid->stid_base = padap->tids.stid_base; 17719030e498SRahul Lakkireddy tid->hash_base = padap->tids.hash_base; 17729030e498SRahul Lakkireddy 17739030e498SRahul Lakkireddy tid->natids = padap->tids.natids; 17749030e498SRahul Lakkireddy tid->nftids = padap->tids.nftids; 17759030e498SRahul Lakkireddy tid->ftid_base = padap->tids.ftid_base; 17769030e498SRahul Lakkireddy tid->aftid_base = padap->tids.aftid_base; 17779030e498SRahul Lakkireddy tid->aftid_end = padap->tids.aftid_end; 17789030e498SRahul Lakkireddy 17799030e498SRahul Lakkireddy tid->sftid_base = padap->tids.sftid_base; 17809030e498SRahul Lakkireddy tid->nsftids = padap->tids.nsftids; 17819030e498SRahul Lakkireddy 17829030e498SRahul Lakkireddy tid->flags = padap->flags; 17839030e498SRahul Lakkireddy tid->le_db_conf = t4_read_reg(padap, LE_DB_CONFIG_A); 17849030e498SRahul Lakkireddy tid->ip_users = t4_read_reg(padap, LE_DB_ACT_CNT_IPV4_A); 17859030e498SRahul Lakkireddy tid->ipv6_users = t4_read_reg(padap, LE_DB_ACT_CNT_IPV6_A); 17869030e498SRahul Lakkireddy 178756cf2635SRahul Lakkireddy return cudbg_write_and_release_buff(pdbg_init, &temp_buff, dbg_buff); 17889030e498SRahul Lakkireddy } 17899030e498SRahul Lakkireddy 17906078ab19SRahul Lakkireddy int cudbg_collect_pcie_config(struct cudbg_init *pdbg_init, 17916078ab19SRahul Lakkireddy struct cudbg_buffer *dbg_buff, 17926078ab19SRahul Lakkireddy struct cudbg_error *cudbg_err) 17936078ab19SRahul Lakkireddy { 17946078ab19SRahul Lakkireddy struct adapter *padap = pdbg_init->adap; 17956078ab19SRahul Lakkireddy struct cudbg_buffer temp_buff = { 0 }; 17966078ab19SRahul Lakkireddy u32 size, *value, j; 17976078ab19SRahul Lakkireddy int i, rc, n; 17986078ab19SRahul Lakkireddy 17996078ab19SRahul Lakkireddy size = sizeof(u32) * CUDBG_NUM_PCIE_CONFIG_REGS; 18006078ab19SRahul Lakkireddy n = sizeof(t5_pcie_config_array) / (2 * sizeof(u32)); 180156cf2635SRahul Lakkireddy rc = cudbg_get_buff(pdbg_init, dbg_buff, size, &temp_buff); 18026078ab19SRahul Lakkireddy if (rc) 18036078ab19SRahul Lakkireddy return rc; 18046078ab19SRahul Lakkireddy 18056078ab19SRahul Lakkireddy value = (u32 *)temp_buff.data; 18066078ab19SRahul Lakkireddy for (i = 0; i < n; i++) { 18076078ab19SRahul Lakkireddy for (j = t5_pcie_config_array[i][0]; 18086078ab19SRahul Lakkireddy j <= t5_pcie_config_array[i][1]; j += 4) { 18096078ab19SRahul Lakkireddy t4_hw_pci_read_cfg4(padap, j, value); 18106078ab19SRahul Lakkireddy value++; 18116078ab19SRahul Lakkireddy } 18126078ab19SRahul Lakkireddy } 181356cf2635SRahul Lakkireddy return cudbg_write_and_release_buff(pdbg_init, &temp_buff, dbg_buff); 18146078ab19SRahul Lakkireddy } 18156078ab19SRahul Lakkireddy 1816736c3b94SRahul Lakkireddy static int cudbg_sge_ctxt_check_valid(u32 *buf, int type) 18179e5c598cSRahul Lakkireddy { 1818736c3b94SRahul Lakkireddy int index, bit, bit_pos = 0; 18199e5c598cSRahul Lakkireddy 1820736c3b94SRahul Lakkireddy switch (type) { 1821736c3b94SRahul Lakkireddy case CTXT_EGRESS: 1822736c3b94SRahul Lakkireddy bit_pos = 176; 1823736c3b94SRahul Lakkireddy break; 1824736c3b94SRahul Lakkireddy case CTXT_INGRESS: 1825736c3b94SRahul Lakkireddy bit_pos = 141; 1826736c3b94SRahul Lakkireddy break; 1827736c3b94SRahul Lakkireddy case CTXT_FLM: 1828736c3b94SRahul Lakkireddy bit_pos = 89; 1829736c3b94SRahul Lakkireddy break; 1830736c3b94SRahul Lakkireddy } 1831736c3b94SRahul Lakkireddy index = bit_pos / 32; 1832736c3b94SRahul Lakkireddy bit = bit_pos % 32; 1833736c3b94SRahul Lakkireddy return buf[index] & (1U << bit); 1834736c3b94SRahul Lakkireddy } 1835736c3b94SRahul Lakkireddy 1836736c3b94SRahul Lakkireddy static int cudbg_get_ctxt_region_info(struct adapter *padap, 1837736c3b94SRahul Lakkireddy struct cudbg_region_info *ctx_info, 1838736c3b94SRahul Lakkireddy u8 *mem_type) 1839736c3b94SRahul Lakkireddy { 1840736c3b94SRahul Lakkireddy struct cudbg_mem_desc mem_desc; 1841736c3b94SRahul Lakkireddy struct cudbg_meminfo meminfo; 1842736c3b94SRahul Lakkireddy u32 i, j, value, found; 1843736c3b94SRahul Lakkireddy u8 flq; 1844736c3b94SRahul Lakkireddy int rc; 1845736c3b94SRahul Lakkireddy 1846736c3b94SRahul Lakkireddy rc = cudbg_fill_meminfo(padap, &meminfo); 1847736c3b94SRahul Lakkireddy if (rc) 1848736c3b94SRahul Lakkireddy return rc; 1849736c3b94SRahul Lakkireddy 1850736c3b94SRahul Lakkireddy /* Get EGRESS and INGRESS context region size */ 1851736c3b94SRahul Lakkireddy for (i = CTXT_EGRESS; i <= CTXT_INGRESS; i++) { 1852736c3b94SRahul Lakkireddy found = 0; 1853736c3b94SRahul Lakkireddy memset(&mem_desc, 0, sizeof(struct cudbg_mem_desc)); 1854736c3b94SRahul Lakkireddy for (j = 0; j < ARRAY_SIZE(meminfo.avail); j++) { 1855736c3b94SRahul Lakkireddy rc = cudbg_get_mem_region(padap, &meminfo, j, 1856736c3b94SRahul Lakkireddy cudbg_region[i], 1857736c3b94SRahul Lakkireddy &mem_desc); 1858736c3b94SRahul Lakkireddy if (!rc) { 1859736c3b94SRahul Lakkireddy found = 1; 1860736c3b94SRahul Lakkireddy rc = cudbg_get_mem_relative(padap, &meminfo, j, 1861736c3b94SRahul Lakkireddy &mem_desc.base, 1862736c3b94SRahul Lakkireddy &mem_desc.limit); 1863736c3b94SRahul Lakkireddy if (rc) { 1864736c3b94SRahul Lakkireddy ctx_info[i].exist = false; 1865736c3b94SRahul Lakkireddy break; 1866736c3b94SRahul Lakkireddy } 1867736c3b94SRahul Lakkireddy ctx_info[i].exist = true; 1868736c3b94SRahul Lakkireddy ctx_info[i].start = mem_desc.base; 1869736c3b94SRahul Lakkireddy ctx_info[i].end = mem_desc.limit; 1870736c3b94SRahul Lakkireddy mem_type[i] = j; 1871736c3b94SRahul Lakkireddy break; 1872736c3b94SRahul Lakkireddy } 1873736c3b94SRahul Lakkireddy } 1874736c3b94SRahul Lakkireddy if (!found) 1875736c3b94SRahul Lakkireddy ctx_info[i].exist = false; 1876736c3b94SRahul Lakkireddy } 1877736c3b94SRahul Lakkireddy 1878736c3b94SRahul Lakkireddy /* Get FLM and CNM max qid. */ 18799e5c598cSRahul Lakkireddy value = t4_read_reg(padap, SGE_FLM_CFG_A); 18809e5c598cSRahul Lakkireddy 18819e5c598cSRahul Lakkireddy /* Get number of data freelist queues */ 18829e5c598cSRahul Lakkireddy flq = HDRSTARTFLQ_G(value); 1883736c3b94SRahul Lakkireddy ctx_info[CTXT_FLM].exist = true; 1884736c3b94SRahul Lakkireddy ctx_info[CTXT_FLM].end = (CUDBG_MAX_FL_QIDS >> flq) * SGE_CTXT_SIZE; 18859e5c598cSRahul Lakkireddy 1886736c3b94SRahul Lakkireddy /* The number of CONM contexts are same as number of freelist 18879e5c598cSRahul Lakkireddy * queues. 18889e5c598cSRahul Lakkireddy */ 1889736c3b94SRahul Lakkireddy ctx_info[CTXT_CNM].exist = true; 1890736c3b94SRahul Lakkireddy ctx_info[CTXT_CNM].end = ctx_info[CTXT_FLM].end; 1891736c3b94SRahul Lakkireddy 1892736c3b94SRahul Lakkireddy return 0; 1893736c3b94SRahul Lakkireddy } 1894736c3b94SRahul Lakkireddy 1895736c3b94SRahul Lakkireddy int cudbg_dump_context_size(struct adapter *padap) 1896736c3b94SRahul Lakkireddy { 1897736c3b94SRahul Lakkireddy struct cudbg_region_info region_info[CTXT_CNM + 1] = { {0} }; 1898736c3b94SRahul Lakkireddy u8 mem_type[CTXT_INGRESS + 1] = { 0 }; 1899736c3b94SRahul Lakkireddy u32 i, size = 0; 1900736c3b94SRahul Lakkireddy int rc; 1901736c3b94SRahul Lakkireddy 1902736c3b94SRahul Lakkireddy /* Get max valid qid for each type of queue */ 1903736c3b94SRahul Lakkireddy rc = cudbg_get_ctxt_region_info(padap, region_info, mem_type); 1904736c3b94SRahul Lakkireddy if (rc) 1905736c3b94SRahul Lakkireddy return rc; 1906736c3b94SRahul Lakkireddy 1907736c3b94SRahul Lakkireddy for (i = 0; i < CTXT_CNM; i++) { 1908736c3b94SRahul Lakkireddy if (!region_info[i].exist) { 1909736c3b94SRahul Lakkireddy if (i == CTXT_EGRESS || i == CTXT_INGRESS) 1910736c3b94SRahul Lakkireddy size += CUDBG_LOWMEM_MAX_CTXT_QIDS * 1911736c3b94SRahul Lakkireddy SGE_CTXT_SIZE; 1912736c3b94SRahul Lakkireddy continue; 1913736c3b94SRahul Lakkireddy } 1914736c3b94SRahul Lakkireddy 1915736c3b94SRahul Lakkireddy size += (region_info[i].end - region_info[i].start + 1) / 1916736c3b94SRahul Lakkireddy SGE_CTXT_SIZE; 1917736c3b94SRahul Lakkireddy } 19189e5c598cSRahul Lakkireddy return size * sizeof(struct cudbg_ch_cntxt); 19199e5c598cSRahul Lakkireddy } 19209e5c598cSRahul Lakkireddy 19219e5c598cSRahul Lakkireddy static void cudbg_read_sge_ctxt(struct cudbg_init *pdbg_init, u32 cid, 19229e5c598cSRahul Lakkireddy enum ctxt_type ctype, u32 *data) 19239e5c598cSRahul Lakkireddy { 19249e5c598cSRahul Lakkireddy struct adapter *padap = pdbg_init->adap; 19259e5c598cSRahul Lakkireddy int rc = -1; 19269e5c598cSRahul Lakkireddy 19279e5c598cSRahul Lakkireddy /* Under heavy traffic, the SGE Queue contexts registers will be 19289e5c598cSRahul Lakkireddy * frequently accessed by firmware. 19299e5c598cSRahul Lakkireddy * 19309e5c598cSRahul Lakkireddy * To avoid conflicts with firmware, always ask firmware to fetch 19319e5c598cSRahul Lakkireddy * the SGE Queue contexts via mailbox. On failure, fallback to 19329e5c598cSRahul Lakkireddy * accessing hardware registers directly. 19339e5c598cSRahul Lakkireddy */ 19349e5c598cSRahul Lakkireddy if (is_fw_attached(pdbg_init)) 19359e5c598cSRahul Lakkireddy rc = t4_sge_ctxt_rd(padap, padap->mbox, cid, ctype, data); 19369e5c598cSRahul Lakkireddy if (rc) 19379e5c598cSRahul Lakkireddy t4_sge_ctxt_rd_bd(padap, cid, ctype, data); 19389e5c598cSRahul Lakkireddy } 19399e5c598cSRahul Lakkireddy 1940736c3b94SRahul Lakkireddy static void cudbg_get_sge_ctxt_fw(struct cudbg_init *pdbg_init, u32 max_qid, 1941736c3b94SRahul Lakkireddy u8 ctxt_type, 1942736c3b94SRahul Lakkireddy struct cudbg_ch_cntxt **out_buff) 1943736c3b94SRahul Lakkireddy { 1944736c3b94SRahul Lakkireddy struct cudbg_ch_cntxt *buff = *out_buff; 1945736c3b94SRahul Lakkireddy int rc; 1946736c3b94SRahul Lakkireddy u32 j; 1947736c3b94SRahul Lakkireddy 1948736c3b94SRahul Lakkireddy for (j = 0; j < max_qid; j++) { 1949736c3b94SRahul Lakkireddy cudbg_read_sge_ctxt(pdbg_init, j, ctxt_type, buff->data); 1950736c3b94SRahul Lakkireddy rc = cudbg_sge_ctxt_check_valid(buff->data, ctxt_type); 1951736c3b94SRahul Lakkireddy if (!rc) 1952736c3b94SRahul Lakkireddy continue; 1953736c3b94SRahul Lakkireddy 1954736c3b94SRahul Lakkireddy buff->cntxt_type = ctxt_type; 1955736c3b94SRahul Lakkireddy buff->cntxt_id = j; 1956736c3b94SRahul Lakkireddy buff++; 1957736c3b94SRahul Lakkireddy if (ctxt_type == CTXT_FLM) { 1958736c3b94SRahul Lakkireddy cudbg_read_sge_ctxt(pdbg_init, j, CTXT_CNM, buff->data); 1959736c3b94SRahul Lakkireddy buff->cntxt_type = CTXT_CNM; 1960736c3b94SRahul Lakkireddy buff->cntxt_id = j; 1961736c3b94SRahul Lakkireddy buff++; 1962736c3b94SRahul Lakkireddy } 1963736c3b94SRahul Lakkireddy } 1964736c3b94SRahul Lakkireddy 1965736c3b94SRahul Lakkireddy *out_buff = buff; 1966736c3b94SRahul Lakkireddy } 1967736c3b94SRahul Lakkireddy 19689e5c598cSRahul Lakkireddy int cudbg_collect_dump_context(struct cudbg_init *pdbg_init, 19699e5c598cSRahul Lakkireddy struct cudbg_buffer *dbg_buff, 19709e5c598cSRahul Lakkireddy struct cudbg_error *cudbg_err) 19719e5c598cSRahul Lakkireddy { 1972736c3b94SRahul Lakkireddy struct cudbg_region_info region_info[CTXT_CNM + 1] = { {0} }; 19739e5c598cSRahul Lakkireddy struct adapter *padap = pdbg_init->adap; 1974736c3b94SRahul Lakkireddy u32 j, size, max_ctx_size, max_ctx_qid; 1975736c3b94SRahul Lakkireddy u8 mem_type[CTXT_INGRESS + 1] = { 0 }; 19769e5c598cSRahul Lakkireddy struct cudbg_buffer temp_buff = { 0 }; 19779e5c598cSRahul Lakkireddy struct cudbg_ch_cntxt *buff; 1978736c3b94SRahul Lakkireddy u64 *dst_off, *src_off; 1979736c3b94SRahul Lakkireddy u8 *ctx_buf; 1980736c3b94SRahul Lakkireddy u8 i, k; 19819e5c598cSRahul Lakkireddy int rc; 19829e5c598cSRahul Lakkireddy 1983736c3b94SRahul Lakkireddy /* Get max valid qid for each type of queue */ 1984736c3b94SRahul Lakkireddy rc = cudbg_get_ctxt_region_info(padap, region_info, mem_type); 1985736c3b94SRahul Lakkireddy if (rc) 1986736c3b94SRahul Lakkireddy return rc; 1987736c3b94SRahul Lakkireddy 19889e5c598cSRahul Lakkireddy rc = cudbg_dump_context_size(padap); 19899e5c598cSRahul Lakkireddy if (rc <= 0) 19909e5c598cSRahul Lakkireddy return CUDBG_STATUS_ENTITY_NOT_FOUND; 19919e5c598cSRahul Lakkireddy 19929e5c598cSRahul Lakkireddy size = rc; 199356cf2635SRahul Lakkireddy rc = cudbg_get_buff(pdbg_init, dbg_buff, size, &temp_buff); 19949e5c598cSRahul Lakkireddy if (rc) 19959e5c598cSRahul Lakkireddy return rc; 19969e5c598cSRahul Lakkireddy 1997736c3b94SRahul Lakkireddy /* Get buffer with enough space to read the biggest context 1998736c3b94SRahul Lakkireddy * region in memory. 1999736c3b94SRahul Lakkireddy */ 2000736c3b94SRahul Lakkireddy max_ctx_size = max(region_info[CTXT_EGRESS].end - 2001736c3b94SRahul Lakkireddy region_info[CTXT_EGRESS].start + 1, 2002736c3b94SRahul Lakkireddy region_info[CTXT_INGRESS].end - 2003736c3b94SRahul Lakkireddy region_info[CTXT_INGRESS].start + 1); 20049e5c598cSRahul Lakkireddy 2005736c3b94SRahul Lakkireddy ctx_buf = kvzalloc(max_ctx_size, GFP_KERNEL); 2006736c3b94SRahul Lakkireddy if (!ctx_buf) { 200756cf2635SRahul Lakkireddy cudbg_put_buff(pdbg_init, &temp_buff); 2008736c3b94SRahul Lakkireddy return -ENOMEM; 20099e5c598cSRahul Lakkireddy } 20109e5c598cSRahul Lakkireddy 2011736c3b94SRahul Lakkireddy buff = (struct cudbg_ch_cntxt *)temp_buff.data; 2012736c3b94SRahul Lakkireddy 2013736c3b94SRahul Lakkireddy /* Collect EGRESS and INGRESS context data. 2014736c3b94SRahul Lakkireddy * In case of failures, fallback to collecting via FW or 2015736c3b94SRahul Lakkireddy * backdoor access. 2016736c3b94SRahul Lakkireddy */ 2017736c3b94SRahul Lakkireddy for (i = CTXT_EGRESS; i <= CTXT_INGRESS; i++) { 2018736c3b94SRahul Lakkireddy if (!region_info[i].exist) { 2019736c3b94SRahul Lakkireddy max_ctx_qid = CUDBG_LOWMEM_MAX_CTXT_QIDS; 2020736c3b94SRahul Lakkireddy cudbg_get_sge_ctxt_fw(pdbg_init, max_ctx_qid, i, 2021736c3b94SRahul Lakkireddy &buff); 2022736c3b94SRahul Lakkireddy continue; 2023736c3b94SRahul Lakkireddy } 2024736c3b94SRahul Lakkireddy 2025736c3b94SRahul Lakkireddy max_ctx_size = region_info[i].end - region_info[i].start + 1; 2026736c3b94SRahul Lakkireddy max_ctx_qid = max_ctx_size / SGE_CTXT_SIZE; 2027736c3b94SRahul Lakkireddy 2028770ca347SRahul Lakkireddy /* If firmware is not attached/alive, use backdoor register 2029770ca347SRahul Lakkireddy * access to collect dump. 2030770ca347SRahul Lakkireddy */ 2031770ca347SRahul Lakkireddy if (is_fw_attached(pdbg_init)) { 2032736c3b94SRahul Lakkireddy t4_sge_ctxt_flush(padap, padap->mbox, i); 2033770ca347SRahul Lakkireddy 2034736c3b94SRahul Lakkireddy rc = t4_memory_rw(padap, MEMWIN_NIC, mem_type[i], 2035736c3b94SRahul Lakkireddy region_info[i].start, max_ctx_size, 2036736c3b94SRahul Lakkireddy (__be32 *)ctx_buf, 1); 2037770ca347SRahul Lakkireddy } 2038770ca347SRahul Lakkireddy 2039770ca347SRahul Lakkireddy if (rc || !is_fw_attached(pdbg_init)) { 2040736c3b94SRahul Lakkireddy max_ctx_qid = CUDBG_LOWMEM_MAX_CTXT_QIDS; 2041736c3b94SRahul Lakkireddy cudbg_get_sge_ctxt_fw(pdbg_init, max_ctx_qid, i, 2042736c3b94SRahul Lakkireddy &buff); 2043736c3b94SRahul Lakkireddy continue; 2044736c3b94SRahul Lakkireddy } 2045736c3b94SRahul Lakkireddy 2046736c3b94SRahul Lakkireddy for (j = 0; j < max_ctx_qid; j++) { 2047736c3b94SRahul Lakkireddy src_off = (u64 *)(ctx_buf + j * SGE_CTXT_SIZE); 2048736c3b94SRahul Lakkireddy dst_off = (u64 *)buff->data; 2049736c3b94SRahul Lakkireddy 2050736c3b94SRahul Lakkireddy /* The data is stored in 64-bit cpu order. Convert it 2051736c3b94SRahul Lakkireddy * to big endian before parsing. 2052736c3b94SRahul Lakkireddy */ 2053736c3b94SRahul Lakkireddy for (k = 0; k < SGE_CTXT_SIZE / sizeof(u64); k++) 2054736c3b94SRahul Lakkireddy dst_off[k] = cpu_to_be64(src_off[k]); 2055736c3b94SRahul Lakkireddy 2056736c3b94SRahul Lakkireddy rc = cudbg_sge_ctxt_check_valid(buff->data, i); 2057736c3b94SRahul Lakkireddy if (!rc) 2058736c3b94SRahul Lakkireddy continue; 2059736c3b94SRahul Lakkireddy 2060736c3b94SRahul Lakkireddy buff->cntxt_type = i; 2061736c3b94SRahul Lakkireddy buff->cntxt_id = j; 2062736c3b94SRahul Lakkireddy buff++; 2063736c3b94SRahul Lakkireddy } 2064736c3b94SRahul Lakkireddy } 2065736c3b94SRahul Lakkireddy 2066736c3b94SRahul Lakkireddy kvfree(ctx_buf); 2067736c3b94SRahul Lakkireddy 2068736c3b94SRahul Lakkireddy /* Collect FREELIST and CONGESTION MANAGER contexts */ 2069736c3b94SRahul Lakkireddy max_ctx_size = region_info[CTXT_FLM].end - 2070736c3b94SRahul Lakkireddy region_info[CTXT_FLM].start + 1; 2071736c3b94SRahul Lakkireddy max_ctx_qid = max_ctx_size / SGE_CTXT_SIZE; 2072736c3b94SRahul Lakkireddy /* Since FLM and CONM are 1-to-1 mapped, the below function 2073736c3b94SRahul Lakkireddy * will fetch both FLM and CONM contexts. 2074736c3b94SRahul Lakkireddy */ 2075736c3b94SRahul Lakkireddy cudbg_get_sge_ctxt_fw(pdbg_init, max_ctx_qid, CTXT_FLM, &buff); 2076736c3b94SRahul Lakkireddy 207756cf2635SRahul Lakkireddy return cudbg_write_and_release_buff(pdbg_init, &temp_buff, dbg_buff); 20789e5c598cSRahul Lakkireddy } 20799e5c598cSRahul Lakkireddy 2080b289593eSRahul Lakkireddy static inline void cudbg_tcamxy2valmask(u64 x, u64 y, u8 *addr, u64 *mask) 2081b289593eSRahul Lakkireddy { 2082b289593eSRahul Lakkireddy *mask = x | y; 2083b289593eSRahul Lakkireddy y = (__force u64)cpu_to_be64(y); 2084b289593eSRahul Lakkireddy memcpy(addr, (char *)&y + 2, ETH_ALEN); 2085b289593eSRahul Lakkireddy } 2086b289593eSRahul Lakkireddy 2087b289593eSRahul Lakkireddy static void cudbg_mps_rpl_backdoor(struct adapter *padap, 2088b289593eSRahul Lakkireddy struct fw_ldst_mps_rplc *mps_rplc) 2089b289593eSRahul Lakkireddy { 2090b289593eSRahul Lakkireddy if (is_t5(padap->params.chip)) { 2091b289593eSRahul Lakkireddy mps_rplc->rplc255_224 = htonl(t4_read_reg(padap, 2092b289593eSRahul Lakkireddy MPS_VF_RPLCT_MAP3_A)); 2093b289593eSRahul Lakkireddy mps_rplc->rplc223_192 = htonl(t4_read_reg(padap, 2094b289593eSRahul Lakkireddy MPS_VF_RPLCT_MAP2_A)); 2095b289593eSRahul Lakkireddy mps_rplc->rplc191_160 = htonl(t4_read_reg(padap, 2096b289593eSRahul Lakkireddy MPS_VF_RPLCT_MAP1_A)); 2097b289593eSRahul Lakkireddy mps_rplc->rplc159_128 = htonl(t4_read_reg(padap, 2098b289593eSRahul Lakkireddy MPS_VF_RPLCT_MAP0_A)); 2099b289593eSRahul Lakkireddy } else { 2100b289593eSRahul Lakkireddy mps_rplc->rplc255_224 = htonl(t4_read_reg(padap, 2101b289593eSRahul Lakkireddy MPS_VF_RPLCT_MAP7_A)); 2102b289593eSRahul Lakkireddy mps_rplc->rplc223_192 = htonl(t4_read_reg(padap, 2103b289593eSRahul Lakkireddy MPS_VF_RPLCT_MAP6_A)); 2104b289593eSRahul Lakkireddy mps_rplc->rplc191_160 = htonl(t4_read_reg(padap, 2105b289593eSRahul Lakkireddy MPS_VF_RPLCT_MAP5_A)); 2106b289593eSRahul Lakkireddy mps_rplc->rplc159_128 = htonl(t4_read_reg(padap, 2107b289593eSRahul Lakkireddy MPS_VF_RPLCT_MAP4_A)); 2108b289593eSRahul Lakkireddy } 2109b289593eSRahul Lakkireddy mps_rplc->rplc127_96 = htonl(t4_read_reg(padap, MPS_VF_RPLCT_MAP3_A)); 2110b289593eSRahul Lakkireddy mps_rplc->rplc95_64 = htonl(t4_read_reg(padap, MPS_VF_RPLCT_MAP2_A)); 2111b289593eSRahul Lakkireddy mps_rplc->rplc63_32 = htonl(t4_read_reg(padap, MPS_VF_RPLCT_MAP1_A)); 2112b289593eSRahul Lakkireddy mps_rplc->rplc31_0 = htonl(t4_read_reg(padap, MPS_VF_RPLCT_MAP0_A)); 2113b289593eSRahul Lakkireddy } 2114b289593eSRahul Lakkireddy 2115770ca347SRahul Lakkireddy static int cudbg_collect_tcam_index(struct cudbg_init *pdbg_init, 2116b289593eSRahul Lakkireddy struct cudbg_mps_tcam *tcam, u32 idx) 2117b289593eSRahul Lakkireddy { 2118770ca347SRahul Lakkireddy struct adapter *padap = pdbg_init->adap; 2119b289593eSRahul Lakkireddy u64 tcamy, tcamx, val; 2120b289593eSRahul Lakkireddy u32 ctl, data2; 2121b289593eSRahul Lakkireddy int rc = 0; 2122b289593eSRahul Lakkireddy 2123b289593eSRahul Lakkireddy if (CHELSIO_CHIP_VERSION(padap->params.chip) >= CHELSIO_T6) { 2124b289593eSRahul Lakkireddy /* CtlReqID - 1: use Host Driver Requester ID 2125b289593eSRahul Lakkireddy * CtlCmdType - 0: Read, 1: Write 2126b289593eSRahul Lakkireddy * CtlTcamSel - 0: TCAM0, 1: TCAM1 2127b289593eSRahul Lakkireddy * CtlXYBitSel- 0: Y bit, 1: X bit 2128b289593eSRahul Lakkireddy */ 2129b289593eSRahul Lakkireddy 2130b289593eSRahul Lakkireddy /* Read tcamy */ 2131b289593eSRahul Lakkireddy ctl = CTLREQID_V(1) | CTLCMDTYPE_V(0) | CTLXYBITSEL_V(0); 2132b289593eSRahul Lakkireddy if (idx < 256) 2133b289593eSRahul Lakkireddy ctl |= CTLTCAMINDEX_V(idx) | CTLTCAMSEL_V(0); 2134b289593eSRahul Lakkireddy else 2135b289593eSRahul Lakkireddy ctl |= CTLTCAMINDEX_V(idx - 256) | CTLTCAMSEL_V(1); 2136b289593eSRahul Lakkireddy 2137b289593eSRahul Lakkireddy t4_write_reg(padap, MPS_CLS_TCAM_DATA2_CTL_A, ctl); 2138b289593eSRahul Lakkireddy val = t4_read_reg(padap, MPS_CLS_TCAM_RDATA1_REQ_ID1_A); 2139b289593eSRahul Lakkireddy tcamy = DMACH_G(val) << 32; 2140b289593eSRahul Lakkireddy tcamy |= t4_read_reg(padap, MPS_CLS_TCAM_RDATA0_REQ_ID1_A); 2141b289593eSRahul Lakkireddy data2 = t4_read_reg(padap, MPS_CLS_TCAM_RDATA2_REQ_ID1_A); 2142b289593eSRahul Lakkireddy tcam->lookup_type = DATALKPTYPE_G(data2); 2143b289593eSRahul Lakkireddy 2144b289593eSRahul Lakkireddy /* 0 - Outer header, 1 - Inner header 2145b289593eSRahul Lakkireddy * [71:48] bit locations are overloaded for 2146b289593eSRahul Lakkireddy * outer vs. inner lookup types. 2147b289593eSRahul Lakkireddy */ 2148b289593eSRahul Lakkireddy if (tcam->lookup_type && tcam->lookup_type != DATALKPTYPE_M) { 2149b289593eSRahul Lakkireddy /* Inner header VNI */ 2150b289593eSRahul Lakkireddy tcam->vniy = (data2 & DATAVIDH2_F) | DATAVIDH1_G(data2); 2151b289593eSRahul Lakkireddy tcam->vniy = (tcam->vniy << 16) | VIDL_G(val); 2152b289593eSRahul Lakkireddy tcam->dip_hit = data2 & DATADIPHIT_F; 2153b289593eSRahul Lakkireddy } else { 2154b289593eSRahul Lakkireddy tcam->vlan_vld = data2 & DATAVIDH2_F; 2155b289593eSRahul Lakkireddy tcam->ivlan = VIDL_G(val); 2156b289593eSRahul Lakkireddy } 2157b289593eSRahul Lakkireddy 2158b289593eSRahul Lakkireddy tcam->port_num = DATAPORTNUM_G(data2); 2159b289593eSRahul Lakkireddy 2160b289593eSRahul Lakkireddy /* Read tcamx. Change the control param */ 2161b289593eSRahul Lakkireddy ctl |= CTLXYBITSEL_V(1); 2162b289593eSRahul Lakkireddy t4_write_reg(padap, MPS_CLS_TCAM_DATA2_CTL_A, ctl); 2163b289593eSRahul Lakkireddy val = t4_read_reg(padap, MPS_CLS_TCAM_RDATA1_REQ_ID1_A); 2164b289593eSRahul Lakkireddy tcamx = DMACH_G(val) << 32; 2165b289593eSRahul Lakkireddy tcamx |= t4_read_reg(padap, MPS_CLS_TCAM_RDATA0_REQ_ID1_A); 2166b289593eSRahul Lakkireddy data2 = t4_read_reg(padap, MPS_CLS_TCAM_RDATA2_REQ_ID1_A); 2167b289593eSRahul Lakkireddy if (tcam->lookup_type && tcam->lookup_type != DATALKPTYPE_M) { 2168b289593eSRahul Lakkireddy /* Inner header VNI mask */ 2169b289593eSRahul Lakkireddy tcam->vnix = (data2 & DATAVIDH2_F) | DATAVIDH1_G(data2); 2170b289593eSRahul Lakkireddy tcam->vnix = (tcam->vnix << 16) | VIDL_G(val); 2171b289593eSRahul Lakkireddy } 2172b289593eSRahul Lakkireddy } else { 2173b289593eSRahul Lakkireddy tcamy = t4_read_reg64(padap, MPS_CLS_TCAM_Y_L(idx)); 2174b289593eSRahul Lakkireddy tcamx = t4_read_reg64(padap, MPS_CLS_TCAM_X_L(idx)); 2175b289593eSRahul Lakkireddy } 2176b289593eSRahul Lakkireddy 2177b289593eSRahul Lakkireddy /* If no entry, return */ 2178b289593eSRahul Lakkireddy if (tcamx & tcamy) 2179b289593eSRahul Lakkireddy return rc; 2180b289593eSRahul Lakkireddy 2181b289593eSRahul Lakkireddy tcam->cls_lo = t4_read_reg(padap, MPS_CLS_SRAM_L(idx)); 2182b289593eSRahul Lakkireddy tcam->cls_hi = t4_read_reg(padap, MPS_CLS_SRAM_H(idx)); 2183b289593eSRahul Lakkireddy 2184b289593eSRahul Lakkireddy if (is_t5(padap->params.chip)) 2185b289593eSRahul Lakkireddy tcam->repli = (tcam->cls_lo & REPLICATE_F); 2186b289593eSRahul Lakkireddy else if (is_t6(padap->params.chip)) 2187b289593eSRahul Lakkireddy tcam->repli = (tcam->cls_lo & T6_REPLICATE_F); 2188b289593eSRahul Lakkireddy 2189b289593eSRahul Lakkireddy if (tcam->repli) { 2190b289593eSRahul Lakkireddy struct fw_ldst_cmd ldst_cmd; 2191b289593eSRahul Lakkireddy struct fw_ldst_mps_rplc mps_rplc; 2192b289593eSRahul Lakkireddy 2193b289593eSRahul Lakkireddy memset(&ldst_cmd, 0, sizeof(ldst_cmd)); 2194b289593eSRahul Lakkireddy ldst_cmd.op_to_addrspace = 2195b289593eSRahul Lakkireddy htonl(FW_CMD_OP_V(FW_LDST_CMD) | 2196b289593eSRahul Lakkireddy FW_CMD_REQUEST_F | FW_CMD_READ_F | 2197b289593eSRahul Lakkireddy FW_LDST_CMD_ADDRSPACE_V(FW_LDST_ADDRSPC_MPS)); 2198b289593eSRahul Lakkireddy ldst_cmd.cycles_to_len16 = htonl(FW_LEN16(ldst_cmd)); 2199b289593eSRahul Lakkireddy ldst_cmd.u.mps.rplc.fid_idx = 2200b289593eSRahul Lakkireddy htons(FW_LDST_CMD_FID_V(FW_LDST_MPS_RPLC) | 2201b289593eSRahul Lakkireddy FW_LDST_CMD_IDX_V(idx)); 2202b289593eSRahul Lakkireddy 2203770ca347SRahul Lakkireddy /* If firmware is not attached/alive, use backdoor register 2204770ca347SRahul Lakkireddy * access to collect dump. 2205770ca347SRahul Lakkireddy */ 2206770ca347SRahul Lakkireddy if (is_fw_attached(pdbg_init)) 2207770ca347SRahul Lakkireddy rc = t4_wr_mbox(padap, padap->mbox, &ldst_cmd, 2208770ca347SRahul Lakkireddy sizeof(ldst_cmd), &ldst_cmd); 2209770ca347SRahul Lakkireddy 2210770ca347SRahul Lakkireddy if (rc || !is_fw_attached(pdbg_init)) { 2211b289593eSRahul Lakkireddy cudbg_mps_rpl_backdoor(padap, &mps_rplc); 2212770ca347SRahul Lakkireddy /* Ignore error since we collected directly from 2213770ca347SRahul Lakkireddy * reading registers. 2214770ca347SRahul Lakkireddy */ 2215770ca347SRahul Lakkireddy rc = 0; 2216770ca347SRahul Lakkireddy } else { 2217b289593eSRahul Lakkireddy mps_rplc = ldst_cmd.u.mps.rplc; 2218770ca347SRahul Lakkireddy } 2219b289593eSRahul Lakkireddy 2220b289593eSRahul Lakkireddy tcam->rplc[0] = ntohl(mps_rplc.rplc31_0); 2221b289593eSRahul Lakkireddy tcam->rplc[1] = ntohl(mps_rplc.rplc63_32); 2222b289593eSRahul Lakkireddy tcam->rplc[2] = ntohl(mps_rplc.rplc95_64); 2223b289593eSRahul Lakkireddy tcam->rplc[3] = ntohl(mps_rplc.rplc127_96); 2224b289593eSRahul Lakkireddy if (padap->params.arch.mps_rplc_size > CUDBG_MAX_RPLC_SIZE) { 2225b289593eSRahul Lakkireddy tcam->rplc[4] = ntohl(mps_rplc.rplc159_128); 2226b289593eSRahul Lakkireddy tcam->rplc[5] = ntohl(mps_rplc.rplc191_160); 2227b289593eSRahul Lakkireddy tcam->rplc[6] = ntohl(mps_rplc.rplc223_192); 2228b289593eSRahul Lakkireddy tcam->rplc[7] = ntohl(mps_rplc.rplc255_224); 2229b289593eSRahul Lakkireddy } 2230b289593eSRahul Lakkireddy } 2231b289593eSRahul Lakkireddy cudbg_tcamxy2valmask(tcamx, tcamy, tcam->addr, &tcam->mask); 2232b289593eSRahul Lakkireddy tcam->idx = idx; 2233b289593eSRahul Lakkireddy tcam->rplc_size = padap->params.arch.mps_rplc_size; 2234b289593eSRahul Lakkireddy return rc; 2235b289593eSRahul Lakkireddy } 2236b289593eSRahul Lakkireddy 2237b289593eSRahul Lakkireddy int cudbg_collect_mps_tcam(struct cudbg_init *pdbg_init, 2238b289593eSRahul Lakkireddy struct cudbg_buffer *dbg_buff, 2239b289593eSRahul Lakkireddy struct cudbg_error *cudbg_err) 2240b289593eSRahul Lakkireddy { 2241b289593eSRahul Lakkireddy struct adapter *padap = pdbg_init->adap; 2242b289593eSRahul Lakkireddy struct cudbg_buffer temp_buff = { 0 }; 2243b289593eSRahul Lakkireddy u32 size = 0, i, n, total_size = 0; 2244b289593eSRahul Lakkireddy struct cudbg_mps_tcam *tcam; 2245b289593eSRahul Lakkireddy int rc; 2246b289593eSRahul Lakkireddy 2247b289593eSRahul Lakkireddy n = padap->params.arch.mps_tcam_size; 2248b289593eSRahul Lakkireddy size = sizeof(struct cudbg_mps_tcam) * n; 224956cf2635SRahul Lakkireddy rc = cudbg_get_buff(pdbg_init, dbg_buff, size, &temp_buff); 2250b289593eSRahul Lakkireddy if (rc) 2251b289593eSRahul Lakkireddy return rc; 2252b289593eSRahul Lakkireddy 2253b289593eSRahul Lakkireddy tcam = (struct cudbg_mps_tcam *)temp_buff.data; 2254b289593eSRahul Lakkireddy for (i = 0; i < n; i++) { 2255770ca347SRahul Lakkireddy rc = cudbg_collect_tcam_index(pdbg_init, tcam, i); 2256b289593eSRahul Lakkireddy if (rc) { 2257b289593eSRahul Lakkireddy cudbg_err->sys_err = rc; 225856cf2635SRahul Lakkireddy cudbg_put_buff(pdbg_init, &temp_buff); 2259b289593eSRahul Lakkireddy return rc; 2260b289593eSRahul Lakkireddy } 2261b289593eSRahul Lakkireddy total_size += sizeof(struct cudbg_mps_tcam); 2262b289593eSRahul Lakkireddy tcam++; 2263b289593eSRahul Lakkireddy } 2264b289593eSRahul Lakkireddy 2265b289593eSRahul Lakkireddy if (!total_size) { 2266b289593eSRahul Lakkireddy rc = CUDBG_SYSTEM_ERROR; 2267b289593eSRahul Lakkireddy cudbg_err->sys_err = rc; 226856cf2635SRahul Lakkireddy cudbg_put_buff(pdbg_init, &temp_buff); 2269b289593eSRahul Lakkireddy return rc; 2270b289593eSRahul Lakkireddy } 227156cf2635SRahul Lakkireddy return cudbg_write_and_release_buff(pdbg_init, &temp_buff, dbg_buff); 2272b289593eSRahul Lakkireddy } 2273b289593eSRahul Lakkireddy 22746f92a654SRahul Lakkireddy int cudbg_collect_vpd_data(struct cudbg_init *pdbg_init, 22756f92a654SRahul Lakkireddy struct cudbg_buffer *dbg_buff, 22766f92a654SRahul Lakkireddy struct cudbg_error *cudbg_err) 22776f92a654SRahul Lakkireddy { 22786f92a654SRahul Lakkireddy struct adapter *padap = pdbg_init->adap; 22796f92a654SRahul Lakkireddy struct cudbg_buffer temp_buff = { 0 }; 2280940c9c45SRahul Lakkireddy char vpd_str[CUDBG_VPD_VER_LEN + 1]; 2281940c9c45SRahul Lakkireddy u32 scfg_vers, vpd_vers, fw_vers; 22826f92a654SRahul Lakkireddy struct cudbg_vpd_data *vpd_data; 2283940c9c45SRahul Lakkireddy struct vpd_params vpd = { 0 }; 2284940c9c45SRahul Lakkireddy int rc, ret; 2285940c9c45SRahul Lakkireddy 2286940c9c45SRahul Lakkireddy rc = t4_get_raw_vpd_params(padap, &vpd); 2287940c9c45SRahul Lakkireddy if (rc) 2288940c9c45SRahul Lakkireddy return rc; 2289940c9c45SRahul Lakkireddy 2290940c9c45SRahul Lakkireddy rc = t4_get_fw_version(padap, &fw_vers); 2291940c9c45SRahul Lakkireddy if (rc) 2292940c9c45SRahul Lakkireddy return rc; 2293940c9c45SRahul Lakkireddy 2294940c9c45SRahul Lakkireddy /* Serial Configuration Version is located beyond the PF's vpd size. 2295940c9c45SRahul Lakkireddy * Temporarily give access to entire EEPROM to get it. 2296940c9c45SRahul Lakkireddy */ 2297940c9c45SRahul Lakkireddy rc = pci_set_vpd_size(padap->pdev, EEPROMVSIZE); 2298940c9c45SRahul Lakkireddy if (rc < 0) 2299940c9c45SRahul Lakkireddy return rc; 2300940c9c45SRahul Lakkireddy 2301940c9c45SRahul Lakkireddy ret = cudbg_read_vpd_reg(padap, CUDBG_SCFG_VER_ADDR, CUDBG_SCFG_VER_LEN, 2302940c9c45SRahul Lakkireddy &scfg_vers); 2303940c9c45SRahul Lakkireddy 2304940c9c45SRahul Lakkireddy /* Restore back to original PF's vpd size */ 2305940c9c45SRahul Lakkireddy rc = pci_set_vpd_size(padap->pdev, CUDBG_VPD_PF_SIZE); 2306940c9c45SRahul Lakkireddy if (rc < 0) 2307940c9c45SRahul Lakkireddy return rc; 2308940c9c45SRahul Lakkireddy 2309940c9c45SRahul Lakkireddy if (ret) 2310940c9c45SRahul Lakkireddy return ret; 2311940c9c45SRahul Lakkireddy 2312940c9c45SRahul Lakkireddy rc = cudbg_read_vpd_reg(padap, CUDBG_VPD_VER_ADDR, CUDBG_VPD_VER_LEN, 2313940c9c45SRahul Lakkireddy vpd_str); 2314940c9c45SRahul Lakkireddy if (rc) 2315940c9c45SRahul Lakkireddy return rc; 2316940c9c45SRahul Lakkireddy 2317940c9c45SRahul Lakkireddy vpd_str[CUDBG_VPD_VER_LEN] = '\0'; 2318940c9c45SRahul Lakkireddy rc = kstrtouint(vpd_str, 0, &vpd_vers); 2319940c9c45SRahul Lakkireddy if (rc) 2320940c9c45SRahul Lakkireddy return rc; 23216f92a654SRahul Lakkireddy 232256cf2635SRahul Lakkireddy rc = cudbg_get_buff(pdbg_init, dbg_buff, sizeof(struct cudbg_vpd_data), 23236f92a654SRahul Lakkireddy &temp_buff); 23246f92a654SRahul Lakkireddy if (rc) 23256f92a654SRahul Lakkireddy return rc; 23266f92a654SRahul Lakkireddy 23276f92a654SRahul Lakkireddy vpd_data = (struct cudbg_vpd_data *)temp_buff.data; 2328940c9c45SRahul Lakkireddy memcpy(vpd_data->sn, vpd.sn, SERNUM_LEN + 1); 2329940c9c45SRahul Lakkireddy memcpy(vpd_data->bn, vpd.pn, PN_LEN + 1); 2330940c9c45SRahul Lakkireddy memcpy(vpd_data->na, vpd.na, MACADDR_LEN + 1); 2331940c9c45SRahul Lakkireddy memcpy(vpd_data->mn, vpd.id, ID_LEN + 1); 2332940c9c45SRahul Lakkireddy vpd_data->scfg_vers = scfg_vers; 2333940c9c45SRahul Lakkireddy vpd_data->vpd_vers = vpd_vers; 2334940c9c45SRahul Lakkireddy vpd_data->fw_major = FW_HDR_FW_VER_MAJOR_G(fw_vers); 2335940c9c45SRahul Lakkireddy vpd_data->fw_minor = FW_HDR_FW_VER_MINOR_G(fw_vers); 2336940c9c45SRahul Lakkireddy vpd_data->fw_micro = FW_HDR_FW_VER_MICRO_G(fw_vers); 2337940c9c45SRahul Lakkireddy vpd_data->fw_build = FW_HDR_FW_VER_BUILD_G(fw_vers); 233856cf2635SRahul Lakkireddy return cudbg_write_and_release_buff(pdbg_init, &temp_buff, dbg_buff); 23396f92a654SRahul Lakkireddy } 23406f92a654SRahul Lakkireddy 234103e98b91SRahul Lakkireddy static int cudbg_read_tid(struct cudbg_init *pdbg_init, u32 tid, 234203e98b91SRahul Lakkireddy struct cudbg_tid_data *tid_data) 234303e98b91SRahul Lakkireddy { 234403e98b91SRahul Lakkireddy struct adapter *padap = pdbg_init->adap; 234503e98b91SRahul Lakkireddy int i, cmd_retry = 8; 234603e98b91SRahul Lakkireddy u32 val; 234703e98b91SRahul Lakkireddy 234803e98b91SRahul Lakkireddy /* Fill REQ_DATA regs with 0's */ 234903e98b91SRahul Lakkireddy for (i = 0; i < NUM_LE_DB_DBGI_REQ_DATA_INSTANCES; i++) 235003e98b91SRahul Lakkireddy t4_write_reg(padap, LE_DB_DBGI_REQ_DATA_A + (i << 2), 0); 235103e98b91SRahul Lakkireddy 235203e98b91SRahul Lakkireddy /* Write DBIG command */ 235303e98b91SRahul Lakkireddy val = DBGICMD_V(4) | DBGITID_V(tid); 235403e98b91SRahul Lakkireddy t4_write_reg(padap, LE_DB_DBGI_REQ_TCAM_CMD_A, val); 235503e98b91SRahul Lakkireddy tid_data->dbig_cmd = val; 235603e98b91SRahul Lakkireddy 235703e98b91SRahul Lakkireddy val = DBGICMDSTRT_F | DBGICMDMODE_V(1); /* LE mode */ 235803e98b91SRahul Lakkireddy t4_write_reg(padap, LE_DB_DBGI_CONFIG_A, val); 235903e98b91SRahul Lakkireddy tid_data->dbig_conf = val; 236003e98b91SRahul Lakkireddy 236103e98b91SRahul Lakkireddy /* Poll the DBGICMDBUSY bit */ 236203e98b91SRahul Lakkireddy val = 1; 236303e98b91SRahul Lakkireddy while (val) { 236403e98b91SRahul Lakkireddy val = t4_read_reg(padap, LE_DB_DBGI_CONFIG_A); 236503e98b91SRahul Lakkireddy val = val & DBGICMDBUSY_F; 236603e98b91SRahul Lakkireddy cmd_retry--; 236703e98b91SRahul Lakkireddy if (!cmd_retry) 236803e98b91SRahul Lakkireddy return CUDBG_SYSTEM_ERROR; 236903e98b91SRahul Lakkireddy } 237003e98b91SRahul Lakkireddy 237103e98b91SRahul Lakkireddy /* Check RESP status */ 237203e98b91SRahul Lakkireddy val = t4_read_reg(padap, LE_DB_DBGI_RSP_STATUS_A); 237303e98b91SRahul Lakkireddy tid_data->dbig_rsp_stat = val; 237403e98b91SRahul Lakkireddy if (!(val & 1)) 237503e98b91SRahul Lakkireddy return CUDBG_SYSTEM_ERROR; 237603e98b91SRahul Lakkireddy 237703e98b91SRahul Lakkireddy /* Read RESP data */ 237803e98b91SRahul Lakkireddy for (i = 0; i < NUM_LE_DB_DBGI_RSP_DATA_INSTANCES; i++) 237903e98b91SRahul Lakkireddy tid_data->data[i] = t4_read_reg(padap, 238003e98b91SRahul Lakkireddy LE_DB_DBGI_RSP_DATA_A + 238103e98b91SRahul Lakkireddy (i << 2)); 238203e98b91SRahul Lakkireddy tid_data->tid = tid; 238303e98b91SRahul Lakkireddy return 0; 238403e98b91SRahul Lakkireddy } 238503e98b91SRahul Lakkireddy 238603e98b91SRahul Lakkireddy static int cudbg_get_le_type(u32 tid, struct cudbg_tcam tcam_region) 238703e98b91SRahul Lakkireddy { 238803e98b91SRahul Lakkireddy int type = LE_ET_UNKNOWN; 238903e98b91SRahul Lakkireddy 239003e98b91SRahul Lakkireddy if (tid < tcam_region.server_start) 239103e98b91SRahul Lakkireddy type = LE_ET_TCAM_CON; 239203e98b91SRahul Lakkireddy else if (tid < tcam_region.filter_start) 239303e98b91SRahul Lakkireddy type = LE_ET_TCAM_SERVER; 239403e98b91SRahul Lakkireddy else if (tid < tcam_region.clip_start) 239503e98b91SRahul Lakkireddy type = LE_ET_TCAM_FILTER; 239603e98b91SRahul Lakkireddy else if (tid < tcam_region.routing_start) 239703e98b91SRahul Lakkireddy type = LE_ET_TCAM_CLIP; 239803e98b91SRahul Lakkireddy else if (tid < tcam_region.tid_hash_base) 239903e98b91SRahul Lakkireddy type = LE_ET_TCAM_ROUTING; 240003e98b91SRahul Lakkireddy else if (tid < tcam_region.max_tid) 240103e98b91SRahul Lakkireddy type = LE_ET_HASH_CON; 240203e98b91SRahul Lakkireddy else 240303e98b91SRahul Lakkireddy type = LE_ET_INVALID_TID; 240403e98b91SRahul Lakkireddy 240503e98b91SRahul Lakkireddy return type; 240603e98b91SRahul Lakkireddy } 240703e98b91SRahul Lakkireddy 240803e98b91SRahul Lakkireddy static int cudbg_is_ipv6_entry(struct cudbg_tid_data *tid_data, 240903e98b91SRahul Lakkireddy struct cudbg_tcam tcam_region) 241003e98b91SRahul Lakkireddy { 241103e98b91SRahul Lakkireddy int ipv6 = 0; 241203e98b91SRahul Lakkireddy int le_type; 241303e98b91SRahul Lakkireddy 241403e98b91SRahul Lakkireddy le_type = cudbg_get_le_type(tid_data->tid, tcam_region); 241503e98b91SRahul Lakkireddy if (tid_data->tid & 1) 241603e98b91SRahul Lakkireddy return 0; 241703e98b91SRahul Lakkireddy 241803e98b91SRahul Lakkireddy if (le_type == LE_ET_HASH_CON) { 241903e98b91SRahul Lakkireddy ipv6 = tid_data->data[16] & 0x8000; 242003e98b91SRahul Lakkireddy } else if (le_type == LE_ET_TCAM_CON) { 242103e98b91SRahul Lakkireddy ipv6 = tid_data->data[16] & 0x8000; 242203e98b91SRahul Lakkireddy if (ipv6) 242303e98b91SRahul Lakkireddy ipv6 = tid_data->data[9] == 0x00C00000; 242403e98b91SRahul Lakkireddy } else { 242503e98b91SRahul Lakkireddy ipv6 = 0; 242603e98b91SRahul Lakkireddy } 242703e98b91SRahul Lakkireddy return ipv6; 242803e98b91SRahul Lakkireddy } 242903e98b91SRahul Lakkireddy 243003e98b91SRahul Lakkireddy void cudbg_fill_le_tcam_info(struct adapter *padap, 243103e98b91SRahul Lakkireddy struct cudbg_tcam *tcam_region) 243203e98b91SRahul Lakkireddy { 243303e98b91SRahul Lakkireddy u32 value; 243403e98b91SRahul Lakkireddy 243503e98b91SRahul Lakkireddy /* Get the LE regions */ 243603e98b91SRahul Lakkireddy value = t4_read_reg(padap, LE_DB_TID_HASHBASE_A); /* hash base index */ 243703e98b91SRahul Lakkireddy tcam_region->tid_hash_base = value; 243803e98b91SRahul Lakkireddy 243903e98b91SRahul Lakkireddy /* Get routing table index */ 244003e98b91SRahul Lakkireddy value = t4_read_reg(padap, LE_DB_ROUTING_TABLE_INDEX_A); 244103e98b91SRahul Lakkireddy tcam_region->routing_start = value; 244203e98b91SRahul Lakkireddy 24438e725f7cSRahul Lakkireddy /* Get clip table index. For T6 there is separate CLIP TCAM */ 24448e725f7cSRahul Lakkireddy if (is_t6(padap->params.chip)) 24458e725f7cSRahul Lakkireddy value = t4_read_reg(padap, LE_DB_CLCAM_TID_BASE_A); 24468e725f7cSRahul Lakkireddy else 244703e98b91SRahul Lakkireddy value = t4_read_reg(padap, LE_DB_CLIP_TABLE_INDEX_A); 244803e98b91SRahul Lakkireddy tcam_region->clip_start = value; 244903e98b91SRahul Lakkireddy 245003e98b91SRahul Lakkireddy /* Get filter table index */ 245103e98b91SRahul Lakkireddy value = t4_read_reg(padap, LE_DB_FILTER_TABLE_INDEX_A); 245203e98b91SRahul Lakkireddy tcam_region->filter_start = value; 245303e98b91SRahul Lakkireddy 245403e98b91SRahul Lakkireddy /* Get server table index */ 245503e98b91SRahul Lakkireddy value = t4_read_reg(padap, LE_DB_SERVER_INDEX_A); 245603e98b91SRahul Lakkireddy tcam_region->server_start = value; 245703e98b91SRahul Lakkireddy 245803e98b91SRahul Lakkireddy /* Check whether hash is enabled and calculate the max tids */ 245903e98b91SRahul Lakkireddy value = t4_read_reg(padap, LE_DB_CONFIG_A); 246003e98b91SRahul Lakkireddy if ((value >> HASHEN_S) & 1) { 246103e98b91SRahul Lakkireddy value = t4_read_reg(padap, LE_DB_HASH_CONFIG_A); 246203e98b91SRahul Lakkireddy if (CHELSIO_CHIP_VERSION(padap->params.chip) > CHELSIO_T5) { 246303e98b91SRahul Lakkireddy tcam_region->max_tid = (value & 0xFFFFF) + 246403e98b91SRahul Lakkireddy tcam_region->tid_hash_base; 246503e98b91SRahul Lakkireddy } else { 246603e98b91SRahul Lakkireddy value = HASHTIDSIZE_G(value); 246703e98b91SRahul Lakkireddy value = 1 << value; 246803e98b91SRahul Lakkireddy tcam_region->max_tid = value + 246903e98b91SRahul Lakkireddy tcam_region->tid_hash_base; 247003e98b91SRahul Lakkireddy } 247103e98b91SRahul Lakkireddy } else { /* hash not enabled */ 24728e725f7cSRahul Lakkireddy if (is_t6(padap->params.chip)) 24738e725f7cSRahul Lakkireddy tcam_region->max_tid = (value & ASLIPCOMPEN_F) ? 24748e725f7cSRahul Lakkireddy CUDBG_MAX_TID_COMP_EN : 24758e725f7cSRahul Lakkireddy CUDBG_MAX_TID_COMP_DIS; 24768e725f7cSRahul Lakkireddy else 247703e98b91SRahul Lakkireddy tcam_region->max_tid = CUDBG_MAX_TCAM_TID; 247803e98b91SRahul Lakkireddy } 24798e725f7cSRahul Lakkireddy 24808e725f7cSRahul Lakkireddy if (is_t6(padap->params.chip)) 24818e725f7cSRahul Lakkireddy tcam_region->max_tid += CUDBG_T6_CLIP; 248203e98b91SRahul Lakkireddy } 248303e98b91SRahul Lakkireddy 248403e98b91SRahul Lakkireddy int cudbg_collect_le_tcam(struct cudbg_init *pdbg_init, 248503e98b91SRahul Lakkireddy struct cudbg_buffer *dbg_buff, 248603e98b91SRahul Lakkireddy struct cudbg_error *cudbg_err) 248703e98b91SRahul Lakkireddy { 248803e98b91SRahul Lakkireddy struct adapter *padap = pdbg_init->adap; 248903e98b91SRahul Lakkireddy struct cudbg_buffer temp_buff = { 0 }; 249003e98b91SRahul Lakkireddy struct cudbg_tcam tcam_region = { 0 }; 249103e98b91SRahul Lakkireddy struct cudbg_tid_data *tid_data; 249203e98b91SRahul Lakkireddy u32 bytes = 0; 249303e98b91SRahul Lakkireddy int rc, size; 249403e98b91SRahul Lakkireddy u32 i; 249503e98b91SRahul Lakkireddy 249603e98b91SRahul Lakkireddy cudbg_fill_le_tcam_info(padap, &tcam_region); 249703e98b91SRahul Lakkireddy 249803e98b91SRahul Lakkireddy size = sizeof(struct cudbg_tid_data) * tcam_region.max_tid; 249903e98b91SRahul Lakkireddy size += sizeof(struct cudbg_tcam); 250056cf2635SRahul Lakkireddy rc = cudbg_get_buff(pdbg_init, dbg_buff, size, &temp_buff); 250103e98b91SRahul Lakkireddy if (rc) 250203e98b91SRahul Lakkireddy return rc; 250303e98b91SRahul Lakkireddy 250403e98b91SRahul Lakkireddy memcpy(temp_buff.data, &tcam_region, sizeof(struct cudbg_tcam)); 250503e98b91SRahul Lakkireddy bytes = sizeof(struct cudbg_tcam); 250603e98b91SRahul Lakkireddy tid_data = (struct cudbg_tid_data *)(temp_buff.data + bytes); 250703e98b91SRahul Lakkireddy /* read all tid */ 250803e98b91SRahul Lakkireddy for (i = 0; i < tcam_region.max_tid; ) { 250903e98b91SRahul Lakkireddy rc = cudbg_read_tid(pdbg_init, i, tid_data); 251003e98b91SRahul Lakkireddy if (rc) { 25118e725f7cSRahul Lakkireddy cudbg_err->sys_warn = CUDBG_STATUS_PARTIAL_DATA; 25128e725f7cSRahul Lakkireddy /* Update tcam header and exit */ 25138e725f7cSRahul Lakkireddy tcam_region.max_tid = i; 25148e725f7cSRahul Lakkireddy memcpy(temp_buff.data, &tcam_region, 25158e725f7cSRahul Lakkireddy sizeof(struct cudbg_tcam)); 25168e725f7cSRahul Lakkireddy goto out; 251703e98b91SRahul Lakkireddy } 251803e98b91SRahul Lakkireddy 25198e725f7cSRahul Lakkireddy if (cudbg_is_ipv6_entry(tid_data, tcam_region)) { 25208e725f7cSRahul Lakkireddy /* T6 CLIP TCAM: ipv6 takes 4 entries */ 25218e725f7cSRahul Lakkireddy if (is_t6(padap->params.chip) && 25228e725f7cSRahul Lakkireddy i >= tcam_region.clip_start && 25238e725f7cSRahul Lakkireddy i < tcam_region.clip_start + CUDBG_T6_CLIP) 25248e725f7cSRahul Lakkireddy i += 4; 25258e725f7cSRahul Lakkireddy else /* Main TCAM: ipv6 takes two tids */ 25268e725f7cSRahul Lakkireddy i += 2; 25278e725f7cSRahul Lakkireddy } else { 25288e725f7cSRahul Lakkireddy i++; 25298e725f7cSRahul Lakkireddy } 253003e98b91SRahul Lakkireddy 253103e98b91SRahul Lakkireddy tid_data++; 253203e98b91SRahul Lakkireddy bytes += sizeof(struct cudbg_tid_data); 253303e98b91SRahul Lakkireddy } 253403e98b91SRahul Lakkireddy 25358e725f7cSRahul Lakkireddy out: 253656cf2635SRahul Lakkireddy return cudbg_write_and_release_buff(pdbg_init, &temp_buff, dbg_buff); 253703e98b91SRahul Lakkireddy } 253803e98b91SRahul Lakkireddy 25396f92a654SRahul Lakkireddy int cudbg_collect_cctrl(struct cudbg_init *pdbg_init, 25406f92a654SRahul Lakkireddy struct cudbg_buffer *dbg_buff, 25416f92a654SRahul Lakkireddy struct cudbg_error *cudbg_err) 25426f92a654SRahul Lakkireddy { 25436f92a654SRahul Lakkireddy struct adapter *padap = pdbg_init->adap; 25446f92a654SRahul Lakkireddy struct cudbg_buffer temp_buff = { 0 }; 25456f92a654SRahul Lakkireddy u32 size; 25466f92a654SRahul Lakkireddy int rc; 25476f92a654SRahul Lakkireddy 25486f92a654SRahul Lakkireddy size = sizeof(u16) * NMTUS * NCCTRL_WIN; 254956cf2635SRahul Lakkireddy rc = cudbg_get_buff(pdbg_init, dbg_buff, size, &temp_buff); 25506f92a654SRahul Lakkireddy if (rc) 25516f92a654SRahul Lakkireddy return rc; 25526f92a654SRahul Lakkireddy 25536f92a654SRahul Lakkireddy t4_read_cong_tbl(padap, (void *)temp_buff.data); 255456cf2635SRahul Lakkireddy return cudbg_write_and_release_buff(pdbg_init, &temp_buff, dbg_buff); 25556f92a654SRahul Lakkireddy } 25566f92a654SRahul Lakkireddy 2557270d39bfSRahul Lakkireddy int cudbg_collect_ma_indirect(struct cudbg_init *pdbg_init, 2558270d39bfSRahul Lakkireddy struct cudbg_buffer *dbg_buff, 2559270d39bfSRahul Lakkireddy struct cudbg_error *cudbg_err) 2560270d39bfSRahul Lakkireddy { 2561270d39bfSRahul Lakkireddy struct adapter *padap = pdbg_init->adap; 2562270d39bfSRahul Lakkireddy struct cudbg_buffer temp_buff = { 0 }; 2563270d39bfSRahul Lakkireddy struct ireg_buf *ma_indr; 2564270d39bfSRahul Lakkireddy int i, rc, n; 2565270d39bfSRahul Lakkireddy u32 size, j; 2566270d39bfSRahul Lakkireddy 2567270d39bfSRahul Lakkireddy if (CHELSIO_CHIP_VERSION(padap->params.chip) < CHELSIO_T6) 2568270d39bfSRahul Lakkireddy return CUDBG_STATUS_ENTITY_NOT_FOUND; 2569270d39bfSRahul Lakkireddy 2570270d39bfSRahul Lakkireddy n = sizeof(t6_ma_ireg_array) / (IREG_NUM_ELEM * sizeof(u32)); 2571270d39bfSRahul Lakkireddy size = sizeof(struct ireg_buf) * n * 2; 257256cf2635SRahul Lakkireddy rc = cudbg_get_buff(pdbg_init, dbg_buff, size, &temp_buff); 2573270d39bfSRahul Lakkireddy if (rc) 2574270d39bfSRahul Lakkireddy return rc; 2575270d39bfSRahul Lakkireddy 2576270d39bfSRahul Lakkireddy ma_indr = (struct ireg_buf *)temp_buff.data; 2577270d39bfSRahul Lakkireddy for (i = 0; i < n; i++) { 2578270d39bfSRahul Lakkireddy struct ireg_field *ma_fli = &ma_indr->tp_pio; 2579270d39bfSRahul Lakkireddy u32 *buff = ma_indr->outbuf; 2580270d39bfSRahul Lakkireddy 2581270d39bfSRahul Lakkireddy ma_fli->ireg_addr = t6_ma_ireg_array[i][0]; 2582270d39bfSRahul Lakkireddy ma_fli->ireg_data = t6_ma_ireg_array[i][1]; 2583270d39bfSRahul Lakkireddy ma_fli->ireg_local_offset = t6_ma_ireg_array[i][2]; 2584270d39bfSRahul Lakkireddy ma_fli->ireg_offset_range = t6_ma_ireg_array[i][3]; 2585270d39bfSRahul Lakkireddy t4_read_indirect(padap, ma_fli->ireg_addr, ma_fli->ireg_data, 2586270d39bfSRahul Lakkireddy buff, ma_fli->ireg_offset_range, 2587270d39bfSRahul Lakkireddy ma_fli->ireg_local_offset); 2588270d39bfSRahul Lakkireddy ma_indr++; 2589270d39bfSRahul Lakkireddy } 2590270d39bfSRahul Lakkireddy 2591270d39bfSRahul Lakkireddy n = sizeof(t6_ma_ireg_array2) / (IREG_NUM_ELEM * sizeof(u32)); 2592270d39bfSRahul Lakkireddy for (i = 0; i < n; i++) { 2593270d39bfSRahul Lakkireddy struct ireg_field *ma_fli = &ma_indr->tp_pio; 2594270d39bfSRahul Lakkireddy u32 *buff = ma_indr->outbuf; 2595270d39bfSRahul Lakkireddy 2596270d39bfSRahul Lakkireddy ma_fli->ireg_addr = t6_ma_ireg_array2[i][0]; 2597270d39bfSRahul Lakkireddy ma_fli->ireg_data = t6_ma_ireg_array2[i][1]; 2598270d39bfSRahul Lakkireddy ma_fli->ireg_local_offset = t6_ma_ireg_array2[i][2]; 2599270d39bfSRahul Lakkireddy for (j = 0; j < t6_ma_ireg_array2[i][3]; j++) { 2600270d39bfSRahul Lakkireddy t4_read_indirect(padap, ma_fli->ireg_addr, 2601270d39bfSRahul Lakkireddy ma_fli->ireg_data, buff, 1, 2602270d39bfSRahul Lakkireddy ma_fli->ireg_local_offset); 2603270d39bfSRahul Lakkireddy buff++; 2604270d39bfSRahul Lakkireddy ma_fli->ireg_local_offset += 0x20; 2605270d39bfSRahul Lakkireddy } 2606270d39bfSRahul Lakkireddy ma_indr++; 2607270d39bfSRahul Lakkireddy } 260856cf2635SRahul Lakkireddy return cudbg_write_and_release_buff(pdbg_init, &temp_buff, dbg_buff); 2609270d39bfSRahul Lakkireddy } 2610270d39bfSRahul Lakkireddy 261127887bc7SRahul Lakkireddy int cudbg_collect_ulptx_la(struct cudbg_init *pdbg_init, 261227887bc7SRahul Lakkireddy struct cudbg_buffer *dbg_buff, 261327887bc7SRahul Lakkireddy struct cudbg_error *cudbg_err) 261427887bc7SRahul Lakkireddy { 261527887bc7SRahul Lakkireddy struct adapter *padap = pdbg_init->adap; 261627887bc7SRahul Lakkireddy struct cudbg_buffer temp_buff = { 0 }; 261727887bc7SRahul Lakkireddy struct cudbg_ulptx_la *ulptx_la_buff; 26181eb94d44SSurendra Mobiya struct cudbg_ver_hdr *ver_hdr; 261927887bc7SRahul Lakkireddy u32 i, j; 262027887bc7SRahul Lakkireddy int rc; 262127887bc7SRahul Lakkireddy 26221eb94d44SSurendra Mobiya rc = cudbg_get_buff(pdbg_init, dbg_buff, 26231eb94d44SSurendra Mobiya sizeof(struct cudbg_ver_hdr) + 26241eb94d44SSurendra Mobiya sizeof(struct cudbg_ulptx_la), 262527887bc7SRahul Lakkireddy &temp_buff); 262627887bc7SRahul Lakkireddy if (rc) 262727887bc7SRahul Lakkireddy return rc; 262827887bc7SRahul Lakkireddy 26291eb94d44SSurendra Mobiya ver_hdr = (struct cudbg_ver_hdr *)temp_buff.data; 26301eb94d44SSurendra Mobiya ver_hdr->signature = CUDBG_ENTITY_SIGNATURE; 26311eb94d44SSurendra Mobiya ver_hdr->revision = CUDBG_ULPTX_LA_REV; 26321eb94d44SSurendra Mobiya ver_hdr->size = sizeof(struct cudbg_ulptx_la); 26331eb94d44SSurendra Mobiya 26341eb94d44SSurendra Mobiya ulptx_la_buff = (struct cudbg_ulptx_la *)(temp_buff.data + 26351eb94d44SSurendra Mobiya sizeof(*ver_hdr)); 263627887bc7SRahul Lakkireddy for (i = 0; i < CUDBG_NUM_ULPTX; i++) { 263727887bc7SRahul Lakkireddy ulptx_la_buff->rdptr[i] = t4_read_reg(padap, 263827887bc7SRahul Lakkireddy ULP_TX_LA_RDPTR_0_A + 263927887bc7SRahul Lakkireddy 0x10 * i); 264027887bc7SRahul Lakkireddy ulptx_la_buff->wrptr[i] = t4_read_reg(padap, 264127887bc7SRahul Lakkireddy ULP_TX_LA_WRPTR_0_A + 264227887bc7SRahul Lakkireddy 0x10 * i); 264327887bc7SRahul Lakkireddy ulptx_la_buff->rddata[i] = t4_read_reg(padap, 264427887bc7SRahul Lakkireddy ULP_TX_LA_RDDATA_0_A + 264527887bc7SRahul Lakkireddy 0x10 * i); 264627887bc7SRahul Lakkireddy for (j = 0; j < CUDBG_NUM_ULPTX_READ; j++) 264727887bc7SRahul Lakkireddy ulptx_la_buff->rd_data[i][j] = 264827887bc7SRahul Lakkireddy t4_read_reg(padap, 264927887bc7SRahul Lakkireddy ULP_TX_LA_RDDATA_0_A + 0x10 * i); 265027887bc7SRahul Lakkireddy } 26511eb94d44SSurendra Mobiya 26521eb94d44SSurendra Mobiya for (i = 0; i < CUDBG_NUM_ULPTX_ASIC_READ; i++) { 26531eb94d44SSurendra Mobiya t4_write_reg(padap, ULP_TX_ASIC_DEBUG_CTRL_A, 0x1); 26541eb94d44SSurendra Mobiya ulptx_la_buff->rdptr_asic[i] = 26551eb94d44SSurendra Mobiya t4_read_reg(padap, ULP_TX_ASIC_DEBUG_CTRL_A); 26561eb94d44SSurendra Mobiya ulptx_la_buff->rddata_asic[i][0] = 26571eb94d44SSurendra Mobiya t4_read_reg(padap, ULP_TX_ASIC_DEBUG_0_A); 26581eb94d44SSurendra Mobiya ulptx_la_buff->rddata_asic[i][1] = 26591eb94d44SSurendra Mobiya t4_read_reg(padap, ULP_TX_ASIC_DEBUG_1_A); 26601eb94d44SSurendra Mobiya ulptx_la_buff->rddata_asic[i][2] = 26611eb94d44SSurendra Mobiya t4_read_reg(padap, ULP_TX_ASIC_DEBUG_2_A); 26621eb94d44SSurendra Mobiya ulptx_la_buff->rddata_asic[i][3] = 26631eb94d44SSurendra Mobiya t4_read_reg(padap, ULP_TX_ASIC_DEBUG_3_A); 26641eb94d44SSurendra Mobiya ulptx_la_buff->rddata_asic[i][4] = 26651eb94d44SSurendra Mobiya t4_read_reg(padap, ULP_TX_ASIC_DEBUG_4_A); 26661eb94d44SSurendra Mobiya ulptx_la_buff->rddata_asic[i][5] = 26671eb94d44SSurendra Mobiya t4_read_reg(padap, PM_RX_BASE_ADDR); 26681eb94d44SSurendra Mobiya } 26691eb94d44SSurendra Mobiya 267056cf2635SRahul Lakkireddy return cudbg_write_and_release_buff(pdbg_init, &temp_buff, dbg_buff); 267127887bc7SRahul Lakkireddy } 267227887bc7SRahul Lakkireddy 2673270d39bfSRahul Lakkireddy int cudbg_collect_up_cim_indirect(struct cudbg_init *pdbg_init, 2674270d39bfSRahul Lakkireddy struct cudbg_buffer *dbg_buff, 2675270d39bfSRahul Lakkireddy struct cudbg_error *cudbg_err) 2676270d39bfSRahul Lakkireddy { 2677270d39bfSRahul Lakkireddy struct adapter *padap = pdbg_init->adap; 2678270d39bfSRahul Lakkireddy struct cudbg_buffer temp_buff = { 0 }; 2679be6e36d9SRahul Lakkireddy u32 local_offset, local_range; 2680270d39bfSRahul Lakkireddy struct ireg_buf *up_cim; 2681be6e36d9SRahul Lakkireddy u32 size, j, iter; 2682be6e36d9SRahul Lakkireddy u32 instance = 0; 2683270d39bfSRahul Lakkireddy int i, rc, n; 2684270d39bfSRahul Lakkireddy 2685be6e36d9SRahul Lakkireddy if (is_t5(padap->params.chip)) 2686be6e36d9SRahul Lakkireddy n = sizeof(t5_up_cim_reg_array) / 2687be6e36d9SRahul Lakkireddy ((IREG_NUM_ELEM + 1) * sizeof(u32)); 2688be6e36d9SRahul Lakkireddy else if (is_t6(padap->params.chip)) 2689be6e36d9SRahul Lakkireddy n = sizeof(t6_up_cim_reg_array) / 2690be6e36d9SRahul Lakkireddy ((IREG_NUM_ELEM + 1) * sizeof(u32)); 2691be6e36d9SRahul Lakkireddy else 2692be6e36d9SRahul Lakkireddy return CUDBG_STATUS_NOT_IMPLEMENTED; 2693be6e36d9SRahul Lakkireddy 2694270d39bfSRahul Lakkireddy size = sizeof(struct ireg_buf) * n; 269556cf2635SRahul Lakkireddy rc = cudbg_get_buff(pdbg_init, dbg_buff, size, &temp_buff); 2696270d39bfSRahul Lakkireddy if (rc) 2697270d39bfSRahul Lakkireddy return rc; 2698270d39bfSRahul Lakkireddy 2699270d39bfSRahul Lakkireddy up_cim = (struct ireg_buf *)temp_buff.data; 2700270d39bfSRahul Lakkireddy for (i = 0; i < n; i++) { 2701270d39bfSRahul Lakkireddy struct ireg_field *up_cim_reg = &up_cim->tp_pio; 2702270d39bfSRahul Lakkireddy u32 *buff = up_cim->outbuf; 2703270d39bfSRahul Lakkireddy 2704270d39bfSRahul Lakkireddy if (is_t5(padap->params.chip)) { 2705270d39bfSRahul Lakkireddy up_cim_reg->ireg_addr = t5_up_cim_reg_array[i][0]; 2706270d39bfSRahul Lakkireddy up_cim_reg->ireg_data = t5_up_cim_reg_array[i][1]; 2707270d39bfSRahul Lakkireddy up_cim_reg->ireg_local_offset = 2708270d39bfSRahul Lakkireddy t5_up_cim_reg_array[i][2]; 2709270d39bfSRahul Lakkireddy up_cim_reg->ireg_offset_range = 2710270d39bfSRahul Lakkireddy t5_up_cim_reg_array[i][3]; 2711be6e36d9SRahul Lakkireddy instance = t5_up_cim_reg_array[i][4]; 2712270d39bfSRahul Lakkireddy } else if (is_t6(padap->params.chip)) { 2713270d39bfSRahul Lakkireddy up_cim_reg->ireg_addr = t6_up_cim_reg_array[i][0]; 2714270d39bfSRahul Lakkireddy up_cim_reg->ireg_data = t6_up_cim_reg_array[i][1]; 2715270d39bfSRahul Lakkireddy up_cim_reg->ireg_local_offset = 2716270d39bfSRahul Lakkireddy t6_up_cim_reg_array[i][2]; 2717270d39bfSRahul Lakkireddy up_cim_reg->ireg_offset_range = 2718270d39bfSRahul Lakkireddy t6_up_cim_reg_array[i][3]; 2719be6e36d9SRahul Lakkireddy instance = t6_up_cim_reg_array[i][4]; 2720270d39bfSRahul Lakkireddy } 2721270d39bfSRahul Lakkireddy 2722be6e36d9SRahul Lakkireddy switch (instance) { 2723be6e36d9SRahul Lakkireddy case NUM_CIM_CTL_TSCH_CHANNEL_INSTANCES: 2724be6e36d9SRahul Lakkireddy iter = up_cim_reg->ireg_offset_range; 2725be6e36d9SRahul Lakkireddy local_offset = 0x120; 2726be6e36d9SRahul Lakkireddy local_range = 1; 2727be6e36d9SRahul Lakkireddy break; 2728be6e36d9SRahul Lakkireddy case NUM_CIM_CTL_TSCH_CHANNEL_TSCH_CLASS_INSTANCES: 2729be6e36d9SRahul Lakkireddy iter = up_cim_reg->ireg_offset_range; 2730be6e36d9SRahul Lakkireddy local_offset = 0x10; 2731be6e36d9SRahul Lakkireddy local_range = 1; 2732be6e36d9SRahul Lakkireddy break; 2733be6e36d9SRahul Lakkireddy default: 2734be6e36d9SRahul Lakkireddy iter = 1; 2735be6e36d9SRahul Lakkireddy local_offset = 0; 2736be6e36d9SRahul Lakkireddy local_range = up_cim_reg->ireg_offset_range; 2737be6e36d9SRahul Lakkireddy break; 2738be6e36d9SRahul Lakkireddy } 2739be6e36d9SRahul Lakkireddy 2740be6e36d9SRahul Lakkireddy for (j = 0; j < iter; j++, buff++) { 2741be6e36d9SRahul Lakkireddy rc = t4_cim_read(padap, 2742be6e36d9SRahul Lakkireddy up_cim_reg->ireg_local_offset + 2743be6e36d9SRahul Lakkireddy (j * local_offset), local_range, buff); 2744270d39bfSRahul Lakkireddy if (rc) { 274556cf2635SRahul Lakkireddy cudbg_put_buff(pdbg_init, &temp_buff); 2746270d39bfSRahul Lakkireddy return rc; 2747270d39bfSRahul Lakkireddy } 2748be6e36d9SRahul Lakkireddy } 2749270d39bfSRahul Lakkireddy up_cim++; 2750270d39bfSRahul Lakkireddy } 275156cf2635SRahul Lakkireddy return cudbg_write_and_release_buff(pdbg_init, &temp_buff, dbg_buff); 2752270d39bfSRahul Lakkireddy } 2753270d39bfSRahul Lakkireddy 2754db8cd7ceSRahul Lakkireddy int cudbg_collect_pbt_tables(struct cudbg_init *pdbg_init, 2755db8cd7ceSRahul Lakkireddy struct cudbg_buffer *dbg_buff, 2756db8cd7ceSRahul Lakkireddy struct cudbg_error *cudbg_err) 2757db8cd7ceSRahul Lakkireddy { 2758db8cd7ceSRahul Lakkireddy struct adapter *padap = pdbg_init->adap; 2759db8cd7ceSRahul Lakkireddy struct cudbg_buffer temp_buff = { 0 }; 2760db8cd7ceSRahul Lakkireddy struct cudbg_pbt_tables *pbt; 2761db8cd7ceSRahul Lakkireddy int i, rc; 2762db8cd7ceSRahul Lakkireddy u32 addr; 2763db8cd7ceSRahul Lakkireddy 276456cf2635SRahul Lakkireddy rc = cudbg_get_buff(pdbg_init, dbg_buff, 276556cf2635SRahul Lakkireddy sizeof(struct cudbg_pbt_tables), 2766db8cd7ceSRahul Lakkireddy &temp_buff); 2767db8cd7ceSRahul Lakkireddy if (rc) 2768db8cd7ceSRahul Lakkireddy return rc; 2769db8cd7ceSRahul Lakkireddy 2770db8cd7ceSRahul Lakkireddy pbt = (struct cudbg_pbt_tables *)temp_buff.data; 2771db8cd7ceSRahul Lakkireddy /* PBT dynamic entries */ 2772db8cd7ceSRahul Lakkireddy addr = CUDBG_CHAC_PBT_ADDR; 2773db8cd7ceSRahul Lakkireddy for (i = 0; i < CUDBG_PBT_DYNAMIC_ENTRIES; i++) { 2774db8cd7ceSRahul Lakkireddy rc = t4_cim_read(padap, addr + (i * 4), 1, 2775db8cd7ceSRahul Lakkireddy &pbt->pbt_dynamic[i]); 2776db8cd7ceSRahul Lakkireddy if (rc) { 2777db8cd7ceSRahul Lakkireddy cudbg_err->sys_err = rc; 277856cf2635SRahul Lakkireddy cudbg_put_buff(pdbg_init, &temp_buff); 2779db8cd7ceSRahul Lakkireddy return rc; 2780db8cd7ceSRahul Lakkireddy } 2781db8cd7ceSRahul Lakkireddy } 2782db8cd7ceSRahul Lakkireddy 2783db8cd7ceSRahul Lakkireddy /* PBT static entries */ 2784db8cd7ceSRahul Lakkireddy /* static entries start when bit 6 is set */ 2785db8cd7ceSRahul Lakkireddy addr = CUDBG_CHAC_PBT_ADDR + (1 << 6); 2786db8cd7ceSRahul Lakkireddy for (i = 0; i < CUDBG_PBT_STATIC_ENTRIES; i++) { 2787db8cd7ceSRahul Lakkireddy rc = t4_cim_read(padap, addr + (i * 4), 1, 2788db8cd7ceSRahul Lakkireddy &pbt->pbt_static[i]); 2789db8cd7ceSRahul Lakkireddy if (rc) { 2790db8cd7ceSRahul Lakkireddy cudbg_err->sys_err = rc; 279156cf2635SRahul Lakkireddy cudbg_put_buff(pdbg_init, &temp_buff); 2792db8cd7ceSRahul Lakkireddy return rc; 2793db8cd7ceSRahul Lakkireddy } 2794db8cd7ceSRahul Lakkireddy } 2795db8cd7ceSRahul Lakkireddy 2796db8cd7ceSRahul Lakkireddy /* LRF entries */ 2797db8cd7ceSRahul Lakkireddy addr = CUDBG_CHAC_PBT_LRF; 2798db8cd7ceSRahul Lakkireddy for (i = 0; i < CUDBG_LRF_ENTRIES; i++) { 2799db8cd7ceSRahul Lakkireddy rc = t4_cim_read(padap, addr + (i * 4), 1, 2800db8cd7ceSRahul Lakkireddy &pbt->lrf_table[i]); 2801db8cd7ceSRahul Lakkireddy if (rc) { 2802db8cd7ceSRahul Lakkireddy cudbg_err->sys_err = rc; 280356cf2635SRahul Lakkireddy cudbg_put_buff(pdbg_init, &temp_buff); 2804db8cd7ceSRahul Lakkireddy return rc; 2805db8cd7ceSRahul Lakkireddy } 2806db8cd7ceSRahul Lakkireddy } 2807db8cd7ceSRahul Lakkireddy 2808db8cd7ceSRahul Lakkireddy /* PBT data entries */ 2809db8cd7ceSRahul Lakkireddy addr = CUDBG_CHAC_PBT_DATA; 2810db8cd7ceSRahul Lakkireddy for (i = 0; i < CUDBG_PBT_DATA_ENTRIES; i++) { 2811db8cd7ceSRahul Lakkireddy rc = t4_cim_read(padap, addr + (i * 4), 1, 2812db8cd7ceSRahul Lakkireddy &pbt->pbt_data[i]); 2813db8cd7ceSRahul Lakkireddy if (rc) { 2814db8cd7ceSRahul Lakkireddy cudbg_err->sys_err = rc; 281556cf2635SRahul Lakkireddy cudbg_put_buff(pdbg_init, &temp_buff); 2816db8cd7ceSRahul Lakkireddy return rc; 2817db8cd7ceSRahul Lakkireddy } 2818db8cd7ceSRahul Lakkireddy } 281956cf2635SRahul Lakkireddy return cudbg_write_and_release_buff(pdbg_init, &temp_buff, dbg_buff); 2820db8cd7ceSRahul Lakkireddy } 2821db8cd7ceSRahul Lakkireddy 2822844d1b6fSRahul Lakkireddy int cudbg_collect_mbox_log(struct cudbg_init *pdbg_init, 2823844d1b6fSRahul Lakkireddy struct cudbg_buffer *dbg_buff, 2824844d1b6fSRahul Lakkireddy struct cudbg_error *cudbg_err) 2825844d1b6fSRahul Lakkireddy { 2826844d1b6fSRahul Lakkireddy struct adapter *padap = pdbg_init->adap; 2827844d1b6fSRahul Lakkireddy struct cudbg_mbox_log *mboxlog = NULL; 2828844d1b6fSRahul Lakkireddy struct cudbg_buffer temp_buff = { 0 }; 2829844d1b6fSRahul Lakkireddy struct mbox_cmd_log *log = NULL; 2830844d1b6fSRahul Lakkireddy struct mbox_cmd *entry; 2831844d1b6fSRahul Lakkireddy unsigned int entry_idx; 2832844d1b6fSRahul Lakkireddy u16 mbox_cmds; 2833844d1b6fSRahul Lakkireddy int i, k, rc; 2834844d1b6fSRahul Lakkireddy u64 flit; 2835844d1b6fSRahul Lakkireddy u32 size; 2836844d1b6fSRahul Lakkireddy 2837844d1b6fSRahul Lakkireddy log = padap->mbox_log; 2838844d1b6fSRahul Lakkireddy mbox_cmds = padap->mbox_log->size; 2839844d1b6fSRahul Lakkireddy size = sizeof(struct cudbg_mbox_log) * mbox_cmds; 284056cf2635SRahul Lakkireddy rc = cudbg_get_buff(pdbg_init, dbg_buff, size, &temp_buff); 2841844d1b6fSRahul Lakkireddy if (rc) 2842844d1b6fSRahul Lakkireddy return rc; 2843844d1b6fSRahul Lakkireddy 2844844d1b6fSRahul Lakkireddy mboxlog = (struct cudbg_mbox_log *)temp_buff.data; 2845844d1b6fSRahul Lakkireddy for (k = 0; k < mbox_cmds; k++) { 2846844d1b6fSRahul Lakkireddy entry_idx = log->cursor + k; 2847844d1b6fSRahul Lakkireddy if (entry_idx >= log->size) 2848844d1b6fSRahul Lakkireddy entry_idx -= log->size; 2849844d1b6fSRahul Lakkireddy 2850844d1b6fSRahul Lakkireddy entry = mbox_cmd_log_entry(log, entry_idx); 2851844d1b6fSRahul Lakkireddy /* skip over unused entries */ 2852844d1b6fSRahul Lakkireddy if (entry->timestamp == 0) 2853844d1b6fSRahul Lakkireddy continue; 2854844d1b6fSRahul Lakkireddy 2855844d1b6fSRahul Lakkireddy memcpy(&mboxlog->entry, entry, sizeof(struct mbox_cmd)); 2856844d1b6fSRahul Lakkireddy for (i = 0; i < MBOX_LEN / 8; i++) { 2857844d1b6fSRahul Lakkireddy flit = entry->cmd[i]; 2858844d1b6fSRahul Lakkireddy mboxlog->hi[i] = (u32)(flit >> 32); 2859844d1b6fSRahul Lakkireddy mboxlog->lo[i] = (u32)flit; 2860844d1b6fSRahul Lakkireddy } 2861844d1b6fSRahul Lakkireddy mboxlog++; 2862844d1b6fSRahul Lakkireddy } 286356cf2635SRahul Lakkireddy return cudbg_write_and_release_buff(pdbg_init, &temp_buff, dbg_buff); 2864844d1b6fSRahul Lakkireddy } 2865270d39bfSRahul Lakkireddy 2866270d39bfSRahul Lakkireddy int cudbg_collect_hma_indirect(struct cudbg_init *pdbg_init, 2867270d39bfSRahul Lakkireddy struct cudbg_buffer *dbg_buff, 2868270d39bfSRahul Lakkireddy struct cudbg_error *cudbg_err) 2869270d39bfSRahul Lakkireddy { 2870270d39bfSRahul Lakkireddy struct adapter *padap = pdbg_init->adap; 2871270d39bfSRahul Lakkireddy struct cudbg_buffer temp_buff = { 0 }; 2872270d39bfSRahul Lakkireddy struct ireg_buf *hma_indr; 2873270d39bfSRahul Lakkireddy int i, rc, n; 2874270d39bfSRahul Lakkireddy u32 size; 2875270d39bfSRahul Lakkireddy 2876270d39bfSRahul Lakkireddy if (CHELSIO_CHIP_VERSION(padap->params.chip) < CHELSIO_T6) 2877270d39bfSRahul Lakkireddy return CUDBG_STATUS_ENTITY_NOT_FOUND; 2878270d39bfSRahul Lakkireddy 2879270d39bfSRahul Lakkireddy n = sizeof(t6_hma_ireg_array) / (IREG_NUM_ELEM * sizeof(u32)); 2880270d39bfSRahul Lakkireddy size = sizeof(struct ireg_buf) * n; 288156cf2635SRahul Lakkireddy rc = cudbg_get_buff(pdbg_init, dbg_buff, size, &temp_buff); 2882270d39bfSRahul Lakkireddy if (rc) 2883270d39bfSRahul Lakkireddy return rc; 2884270d39bfSRahul Lakkireddy 2885270d39bfSRahul Lakkireddy hma_indr = (struct ireg_buf *)temp_buff.data; 2886270d39bfSRahul Lakkireddy for (i = 0; i < n; i++) { 2887270d39bfSRahul Lakkireddy struct ireg_field *hma_fli = &hma_indr->tp_pio; 2888270d39bfSRahul Lakkireddy u32 *buff = hma_indr->outbuf; 2889270d39bfSRahul Lakkireddy 2890270d39bfSRahul Lakkireddy hma_fli->ireg_addr = t6_hma_ireg_array[i][0]; 2891270d39bfSRahul Lakkireddy hma_fli->ireg_data = t6_hma_ireg_array[i][1]; 2892270d39bfSRahul Lakkireddy hma_fli->ireg_local_offset = t6_hma_ireg_array[i][2]; 2893270d39bfSRahul Lakkireddy hma_fli->ireg_offset_range = t6_hma_ireg_array[i][3]; 2894270d39bfSRahul Lakkireddy t4_read_indirect(padap, hma_fli->ireg_addr, hma_fli->ireg_data, 2895270d39bfSRahul Lakkireddy buff, hma_fli->ireg_offset_range, 2896270d39bfSRahul Lakkireddy hma_fli->ireg_local_offset); 2897270d39bfSRahul Lakkireddy hma_indr++; 2898270d39bfSRahul Lakkireddy } 289956cf2635SRahul Lakkireddy return cudbg_write_and_release_buff(pdbg_init, &temp_buff, dbg_buff); 2900270d39bfSRahul Lakkireddy } 290168ddc82aSRahul Lakkireddy 290268ddc82aSRahul Lakkireddy void cudbg_fill_qdesc_num_and_size(const struct adapter *padap, 290368ddc82aSRahul Lakkireddy u32 *num, u32 *size) 290468ddc82aSRahul Lakkireddy { 290568ddc82aSRahul Lakkireddy u32 tot_entries = 0, tot_size = 0; 290668ddc82aSRahul Lakkireddy 290768ddc82aSRahul Lakkireddy /* NIC TXQ, RXQ, FLQ, and CTRLQ */ 290868ddc82aSRahul Lakkireddy tot_entries += MAX_ETH_QSETS * 3; 290968ddc82aSRahul Lakkireddy tot_entries += MAX_CTRL_QUEUES; 291068ddc82aSRahul Lakkireddy 291168ddc82aSRahul Lakkireddy tot_size += MAX_ETH_QSETS * MAX_TXQ_ENTRIES * MAX_TXQ_DESC_SIZE; 291268ddc82aSRahul Lakkireddy tot_size += MAX_ETH_QSETS * MAX_RSPQ_ENTRIES * MAX_RXQ_DESC_SIZE; 291368ddc82aSRahul Lakkireddy tot_size += MAX_ETH_QSETS * MAX_RX_BUFFERS * MAX_FL_DESC_SIZE; 291468ddc82aSRahul Lakkireddy tot_size += MAX_CTRL_QUEUES * MAX_CTRL_TXQ_ENTRIES * 291568ddc82aSRahul Lakkireddy MAX_CTRL_TXQ_DESC_SIZE; 291668ddc82aSRahul Lakkireddy 291768ddc82aSRahul Lakkireddy /* FW_EVTQ and INTRQ */ 291868ddc82aSRahul Lakkireddy tot_entries += INGQ_EXTRAS; 291968ddc82aSRahul Lakkireddy tot_size += INGQ_EXTRAS * MAX_RSPQ_ENTRIES * MAX_RXQ_DESC_SIZE; 292068ddc82aSRahul Lakkireddy 292168ddc82aSRahul Lakkireddy /* PTP_TXQ */ 292268ddc82aSRahul Lakkireddy tot_entries += 1; 292368ddc82aSRahul Lakkireddy tot_size += MAX_TXQ_ENTRIES * MAX_TXQ_DESC_SIZE; 292468ddc82aSRahul Lakkireddy 292568ddc82aSRahul Lakkireddy /* ULD TXQ, RXQ, and FLQ */ 292668ddc82aSRahul Lakkireddy tot_entries += CXGB4_TX_MAX * MAX_OFLD_QSETS; 292768ddc82aSRahul Lakkireddy tot_entries += CXGB4_ULD_MAX * MAX_ULD_QSETS * 2; 292868ddc82aSRahul Lakkireddy 292968ddc82aSRahul Lakkireddy tot_size += CXGB4_TX_MAX * MAX_OFLD_QSETS * MAX_TXQ_ENTRIES * 293068ddc82aSRahul Lakkireddy MAX_TXQ_DESC_SIZE; 293168ddc82aSRahul Lakkireddy tot_size += CXGB4_ULD_MAX * MAX_ULD_QSETS * MAX_RSPQ_ENTRIES * 293268ddc82aSRahul Lakkireddy MAX_RXQ_DESC_SIZE; 293368ddc82aSRahul Lakkireddy tot_size += CXGB4_ULD_MAX * MAX_ULD_QSETS * MAX_RX_BUFFERS * 293468ddc82aSRahul Lakkireddy MAX_FL_DESC_SIZE; 293568ddc82aSRahul Lakkireddy 293668ddc82aSRahul Lakkireddy /* ULD CIQ */ 293768ddc82aSRahul Lakkireddy tot_entries += CXGB4_ULD_MAX * MAX_ULD_QSETS; 293868ddc82aSRahul Lakkireddy tot_size += CXGB4_ULD_MAX * MAX_ULD_QSETS * SGE_MAX_IQ_SIZE * 293968ddc82aSRahul Lakkireddy MAX_RXQ_DESC_SIZE; 294068ddc82aSRahul Lakkireddy 29412d0cb84dSRahul Lakkireddy /* ETHOFLD TXQ, RXQ, and FLQ */ 29422d0cb84dSRahul Lakkireddy tot_entries += MAX_OFLD_QSETS * 3; 29432d0cb84dSRahul Lakkireddy tot_size += MAX_OFLD_QSETS * MAX_TXQ_ENTRIES * MAX_TXQ_DESC_SIZE; 29442d0cb84dSRahul Lakkireddy 294568ddc82aSRahul Lakkireddy tot_size += sizeof(struct cudbg_ver_hdr) + 294668ddc82aSRahul Lakkireddy sizeof(struct cudbg_qdesc_info) + 294768ddc82aSRahul Lakkireddy sizeof(struct cudbg_qdesc_entry) * tot_entries; 294868ddc82aSRahul Lakkireddy 294968ddc82aSRahul Lakkireddy if (num) 295068ddc82aSRahul Lakkireddy *num = tot_entries; 295168ddc82aSRahul Lakkireddy 295268ddc82aSRahul Lakkireddy if (size) 295368ddc82aSRahul Lakkireddy *size = tot_size; 295468ddc82aSRahul Lakkireddy } 295568ddc82aSRahul Lakkireddy 295668ddc82aSRahul Lakkireddy int cudbg_collect_qdesc(struct cudbg_init *pdbg_init, 295768ddc82aSRahul Lakkireddy struct cudbg_buffer *dbg_buff, 295868ddc82aSRahul Lakkireddy struct cudbg_error *cudbg_err) 295968ddc82aSRahul Lakkireddy { 296068ddc82aSRahul Lakkireddy u32 num_queues = 0, tot_entries = 0, size = 0; 296168ddc82aSRahul Lakkireddy struct adapter *padap = pdbg_init->adap; 296268ddc82aSRahul Lakkireddy struct cudbg_buffer temp_buff = { 0 }; 296368ddc82aSRahul Lakkireddy struct cudbg_qdesc_entry *qdesc_entry; 296468ddc82aSRahul Lakkireddy struct cudbg_qdesc_info *qdesc_info; 296568ddc82aSRahul Lakkireddy struct cudbg_ver_hdr *ver_hdr; 296668ddc82aSRahul Lakkireddy struct sge *s = &padap->sge; 296768ddc82aSRahul Lakkireddy u32 i, j, cur_off, tot_len; 296868ddc82aSRahul Lakkireddy u8 *data; 296968ddc82aSRahul Lakkireddy int rc; 297068ddc82aSRahul Lakkireddy 297168ddc82aSRahul Lakkireddy cudbg_fill_qdesc_num_and_size(padap, &tot_entries, &size); 297268ddc82aSRahul Lakkireddy size = min_t(u32, size, CUDBG_DUMP_BUFF_SIZE); 297368ddc82aSRahul Lakkireddy tot_len = size; 297468ddc82aSRahul Lakkireddy data = kvzalloc(size, GFP_KERNEL); 297568ddc82aSRahul Lakkireddy if (!data) 297668ddc82aSRahul Lakkireddy return -ENOMEM; 297768ddc82aSRahul Lakkireddy 297868ddc82aSRahul Lakkireddy ver_hdr = (struct cudbg_ver_hdr *)data; 297968ddc82aSRahul Lakkireddy ver_hdr->signature = CUDBG_ENTITY_SIGNATURE; 298068ddc82aSRahul Lakkireddy ver_hdr->revision = CUDBG_QDESC_REV; 298168ddc82aSRahul Lakkireddy ver_hdr->size = sizeof(struct cudbg_qdesc_info); 298268ddc82aSRahul Lakkireddy size -= sizeof(*ver_hdr); 298368ddc82aSRahul Lakkireddy 298468ddc82aSRahul Lakkireddy qdesc_info = (struct cudbg_qdesc_info *)(data + 298568ddc82aSRahul Lakkireddy sizeof(*ver_hdr)); 298668ddc82aSRahul Lakkireddy size -= sizeof(*qdesc_info); 298768ddc82aSRahul Lakkireddy qdesc_entry = (struct cudbg_qdesc_entry *)qdesc_info->data; 298868ddc82aSRahul Lakkireddy 298968ddc82aSRahul Lakkireddy #define QDESC_GET(q, desc, type, label) do { \ 299068ddc82aSRahul Lakkireddy if (size <= 0) { \ 299168ddc82aSRahul Lakkireddy goto label; \ 299268ddc82aSRahul Lakkireddy } \ 299368ddc82aSRahul Lakkireddy if (desc) { \ 299468ddc82aSRahul Lakkireddy cudbg_fill_qdesc_##q(q, type, qdesc_entry); \ 299568ddc82aSRahul Lakkireddy size -= sizeof(*qdesc_entry) + qdesc_entry->data_size; \ 299668ddc82aSRahul Lakkireddy num_queues++; \ 299768ddc82aSRahul Lakkireddy qdesc_entry = cudbg_next_qdesc(qdesc_entry); \ 299868ddc82aSRahul Lakkireddy } \ 299968ddc82aSRahul Lakkireddy } while (0) 300068ddc82aSRahul Lakkireddy 300168ddc82aSRahul Lakkireddy #define QDESC_GET_TXQ(q, type, label) do { \ 300268ddc82aSRahul Lakkireddy struct sge_txq *txq = (struct sge_txq *)q; \ 300368ddc82aSRahul Lakkireddy QDESC_GET(txq, txq->desc, type, label); \ 300468ddc82aSRahul Lakkireddy } while (0) 300568ddc82aSRahul Lakkireddy 300668ddc82aSRahul Lakkireddy #define QDESC_GET_RXQ(q, type, label) do { \ 300768ddc82aSRahul Lakkireddy struct sge_rspq *rxq = (struct sge_rspq *)q; \ 300868ddc82aSRahul Lakkireddy QDESC_GET(rxq, rxq->desc, type, label); \ 300968ddc82aSRahul Lakkireddy } while (0) 301068ddc82aSRahul Lakkireddy 301168ddc82aSRahul Lakkireddy #define QDESC_GET_FLQ(q, type, label) do { \ 301268ddc82aSRahul Lakkireddy struct sge_fl *flq = (struct sge_fl *)q; \ 301368ddc82aSRahul Lakkireddy QDESC_GET(flq, flq->desc, type, label); \ 301468ddc82aSRahul Lakkireddy } while (0) 301568ddc82aSRahul Lakkireddy 301668ddc82aSRahul Lakkireddy /* NIC TXQ */ 301768ddc82aSRahul Lakkireddy for (i = 0; i < s->ethqsets; i++) 301868ddc82aSRahul Lakkireddy QDESC_GET_TXQ(&s->ethtxq[i].q, CUDBG_QTYPE_NIC_TXQ, out); 301968ddc82aSRahul Lakkireddy 302068ddc82aSRahul Lakkireddy /* NIC RXQ */ 302168ddc82aSRahul Lakkireddy for (i = 0; i < s->ethqsets; i++) 302268ddc82aSRahul Lakkireddy QDESC_GET_RXQ(&s->ethrxq[i].rspq, CUDBG_QTYPE_NIC_RXQ, out); 302368ddc82aSRahul Lakkireddy 302468ddc82aSRahul Lakkireddy /* NIC FLQ */ 302568ddc82aSRahul Lakkireddy for (i = 0; i < s->ethqsets; i++) 302668ddc82aSRahul Lakkireddy QDESC_GET_FLQ(&s->ethrxq[i].fl, CUDBG_QTYPE_NIC_FLQ, out); 302768ddc82aSRahul Lakkireddy 302868ddc82aSRahul Lakkireddy /* NIC CTRLQ */ 302968ddc82aSRahul Lakkireddy for (i = 0; i < padap->params.nports; i++) 303068ddc82aSRahul Lakkireddy QDESC_GET_TXQ(&s->ctrlq[i].q, CUDBG_QTYPE_CTRLQ, out); 303168ddc82aSRahul Lakkireddy 303268ddc82aSRahul Lakkireddy /* FW_EVTQ */ 303368ddc82aSRahul Lakkireddy QDESC_GET_RXQ(&s->fw_evtq, CUDBG_QTYPE_FWEVTQ, out); 303468ddc82aSRahul Lakkireddy 303568ddc82aSRahul Lakkireddy /* INTRQ */ 303668ddc82aSRahul Lakkireddy QDESC_GET_RXQ(&s->intrq, CUDBG_QTYPE_INTRQ, out); 303768ddc82aSRahul Lakkireddy 303868ddc82aSRahul Lakkireddy /* PTP_TXQ */ 303968ddc82aSRahul Lakkireddy QDESC_GET_TXQ(&s->ptptxq.q, CUDBG_QTYPE_PTP_TXQ, out); 304068ddc82aSRahul Lakkireddy 304168ddc82aSRahul Lakkireddy /* ULD Queues */ 304268ddc82aSRahul Lakkireddy mutex_lock(&uld_mutex); 304368ddc82aSRahul Lakkireddy 304468ddc82aSRahul Lakkireddy if (s->uld_txq_info) { 304568ddc82aSRahul Lakkireddy struct sge_uld_txq_info *utxq; 304668ddc82aSRahul Lakkireddy 304768ddc82aSRahul Lakkireddy /* ULD TXQ */ 304868ddc82aSRahul Lakkireddy for (j = 0; j < CXGB4_TX_MAX; j++) { 304968ddc82aSRahul Lakkireddy if (!s->uld_txq_info[j]) 305068ddc82aSRahul Lakkireddy continue; 305168ddc82aSRahul Lakkireddy 305268ddc82aSRahul Lakkireddy utxq = s->uld_txq_info[j]; 305368ddc82aSRahul Lakkireddy for (i = 0; i < utxq->ntxq; i++) 305468ddc82aSRahul Lakkireddy QDESC_GET_TXQ(&utxq->uldtxq[i].q, 305568ddc82aSRahul Lakkireddy cudbg_uld_txq_to_qtype(j), 305668ddc82aSRahul Lakkireddy out_unlock); 305768ddc82aSRahul Lakkireddy } 305868ddc82aSRahul Lakkireddy } 305968ddc82aSRahul Lakkireddy 306068ddc82aSRahul Lakkireddy if (s->uld_rxq_info) { 306168ddc82aSRahul Lakkireddy struct sge_uld_rxq_info *urxq; 306268ddc82aSRahul Lakkireddy u32 base; 306368ddc82aSRahul Lakkireddy 306468ddc82aSRahul Lakkireddy /* ULD RXQ */ 306568ddc82aSRahul Lakkireddy for (j = 0; j < CXGB4_ULD_MAX; j++) { 306668ddc82aSRahul Lakkireddy if (!s->uld_rxq_info[j]) 306768ddc82aSRahul Lakkireddy continue; 306868ddc82aSRahul Lakkireddy 306968ddc82aSRahul Lakkireddy urxq = s->uld_rxq_info[j]; 307068ddc82aSRahul Lakkireddy for (i = 0; i < urxq->nrxq; i++) 307168ddc82aSRahul Lakkireddy QDESC_GET_RXQ(&urxq->uldrxq[i].rspq, 307268ddc82aSRahul Lakkireddy cudbg_uld_rxq_to_qtype(j), 307368ddc82aSRahul Lakkireddy out_unlock); 307468ddc82aSRahul Lakkireddy } 307568ddc82aSRahul Lakkireddy 307668ddc82aSRahul Lakkireddy /* ULD FLQ */ 307768ddc82aSRahul Lakkireddy for (j = 0; j < CXGB4_ULD_MAX; j++) { 307868ddc82aSRahul Lakkireddy if (!s->uld_rxq_info[j]) 307968ddc82aSRahul Lakkireddy continue; 308068ddc82aSRahul Lakkireddy 308168ddc82aSRahul Lakkireddy urxq = s->uld_rxq_info[j]; 308268ddc82aSRahul Lakkireddy for (i = 0; i < urxq->nrxq; i++) 308368ddc82aSRahul Lakkireddy QDESC_GET_FLQ(&urxq->uldrxq[i].fl, 308468ddc82aSRahul Lakkireddy cudbg_uld_flq_to_qtype(j), 308568ddc82aSRahul Lakkireddy out_unlock); 308668ddc82aSRahul Lakkireddy } 308768ddc82aSRahul Lakkireddy 308868ddc82aSRahul Lakkireddy /* ULD CIQ */ 308968ddc82aSRahul Lakkireddy for (j = 0; j < CXGB4_ULD_MAX; j++) { 309068ddc82aSRahul Lakkireddy if (!s->uld_rxq_info[j]) 309168ddc82aSRahul Lakkireddy continue; 309268ddc82aSRahul Lakkireddy 309368ddc82aSRahul Lakkireddy urxq = s->uld_rxq_info[j]; 309468ddc82aSRahul Lakkireddy base = urxq->nrxq; 309568ddc82aSRahul Lakkireddy for (i = 0; i < urxq->nciq; i++) 309668ddc82aSRahul Lakkireddy QDESC_GET_RXQ(&urxq->uldrxq[base + i].rspq, 309768ddc82aSRahul Lakkireddy cudbg_uld_ciq_to_qtype(j), 309868ddc82aSRahul Lakkireddy out_unlock); 309968ddc82aSRahul Lakkireddy } 310068ddc82aSRahul Lakkireddy } 310168ddc82aSRahul Lakkireddy 31022d0cb84dSRahul Lakkireddy /* ETHOFLD TXQ */ 31032d0cb84dSRahul Lakkireddy if (s->eohw_txq) 31042d0cb84dSRahul Lakkireddy for (i = 0; i < s->eoqsets; i++) 31052d0cb84dSRahul Lakkireddy QDESC_GET_TXQ(&s->eohw_txq[i].q, 31062d0cb84dSRahul Lakkireddy CUDBG_QTYPE_ETHOFLD_TXQ, out); 31072d0cb84dSRahul Lakkireddy 31082d0cb84dSRahul Lakkireddy /* ETHOFLD RXQ and FLQ */ 31092d0cb84dSRahul Lakkireddy if (s->eohw_rxq) { 31102d0cb84dSRahul Lakkireddy for (i = 0; i < s->eoqsets; i++) 31112d0cb84dSRahul Lakkireddy QDESC_GET_RXQ(&s->eohw_rxq[i].rspq, 31122d0cb84dSRahul Lakkireddy CUDBG_QTYPE_ETHOFLD_RXQ, out); 31132d0cb84dSRahul Lakkireddy 31142d0cb84dSRahul Lakkireddy for (i = 0; i < s->eoqsets; i++) 31152d0cb84dSRahul Lakkireddy QDESC_GET_FLQ(&s->eohw_rxq[i].fl, 31162d0cb84dSRahul Lakkireddy CUDBG_QTYPE_ETHOFLD_FLQ, out); 31172d0cb84dSRahul Lakkireddy } 31182d0cb84dSRahul Lakkireddy 311968ddc82aSRahul Lakkireddy out_unlock: 312068ddc82aSRahul Lakkireddy mutex_unlock(&uld_mutex); 312168ddc82aSRahul Lakkireddy 312268ddc82aSRahul Lakkireddy out: 312368ddc82aSRahul Lakkireddy qdesc_info->qdesc_entry_size = sizeof(*qdesc_entry); 312468ddc82aSRahul Lakkireddy qdesc_info->num_queues = num_queues; 312568ddc82aSRahul Lakkireddy cur_off = 0; 312668ddc82aSRahul Lakkireddy while (tot_len) { 312768ddc82aSRahul Lakkireddy u32 chunk_size = min_t(u32, tot_len, CUDBG_CHUNK_SIZE); 312868ddc82aSRahul Lakkireddy 312968ddc82aSRahul Lakkireddy rc = cudbg_get_buff(pdbg_init, dbg_buff, chunk_size, 313068ddc82aSRahul Lakkireddy &temp_buff); 313168ddc82aSRahul Lakkireddy if (rc) { 313268ddc82aSRahul Lakkireddy cudbg_err->sys_warn = CUDBG_STATUS_PARTIAL_DATA; 313368ddc82aSRahul Lakkireddy goto out_free; 313468ddc82aSRahul Lakkireddy } 313568ddc82aSRahul Lakkireddy 313668ddc82aSRahul Lakkireddy memcpy(temp_buff.data, data + cur_off, chunk_size); 313768ddc82aSRahul Lakkireddy tot_len -= chunk_size; 313868ddc82aSRahul Lakkireddy cur_off += chunk_size; 313968ddc82aSRahul Lakkireddy rc = cudbg_write_and_release_buff(pdbg_init, &temp_buff, 314068ddc82aSRahul Lakkireddy dbg_buff); 314168ddc82aSRahul Lakkireddy if (rc) { 314268ddc82aSRahul Lakkireddy cudbg_put_buff(pdbg_init, &temp_buff); 314368ddc82aSRahul Lakkireddy cudbg_err->sys_warn = CUDBG_STATUS_PARTIAL_DATA; 314468ddc82aSRahul Lakkireddy goto out_free; 314568ddc82aSRahul Lakkireddy } 314668ddc82aSRahul Lakkireddy } 314768ddc82aSRahul Lakkireddy 314868ddc82aSRahul Lakkireddy out_free: 314968ddc82aSRahul Lakkireddy if (data) 315068ddc82aSRahul Lakkireddy kvfree(data); 315168ddc82aSRahul Lakkireddy 315268ddc82aSRahul Lakkireddy #undef QDESC_GET_FLQ 315368ddc82aSRahul Lakkireddy #undef QDESC_GET_RXQ 315468ddc82aSRahul Lakkireddy #undef QDESC_GET_TXQ 315568ddc82aSRahul Lakkireddy #undef QDESC_GET 315668ddc82aSRahul Lakkireddy 315768ddc82aSRahul Lakkireddy return rc; 315868ddc82aSRahul Lakkireddy } 315917b332f4SVishal Kulkarni 316017b332f4SVishal Kulkarni int cudbg_collect_flash(struct cudbg_init *pdbg_init, 316117b332f4SVishal Kulkarni struct cudbg_buffer *dbg_buff, 316217b332f4SVishal Kulkarni struct cudbg_error *cudbg_err) 316317b332f4SVishal Kulkarni { 316417b332f4SVishal Kulkarni struct adapter *padap = pdbg_init->adap; 316517b332f4SVishal Kulkarni u32 count = padap->params.sf_size, n; 316617b332f4SVishal Kulkarni struct cudbg_buffer temp_buff = {0}; 316717b332f4SVishal Kulkarni u32 addr, i; 316817b332f4SVishal Kulkarni int rc; 316917b332f4SVishal Kulkarni 317017b332f4SVishal Kulkarni addr = FLASH_EXP_ROM_START; 317117b332f4SVishal Kulkarni 317217b332f4SVishal Kulkarni for (i = 0; i < count; i += SF_PAGE_SIZE) { 317317b332f4SVishal Kulkarni n = min_t(u32, count - i, SF_PAGE_SIZE); 317417b332f4SVishal Kulkarni 317517b332f4SVishal Kulkarni rc = cudbg_get_buff(pdbg_init, dbg_buff, n, &temp_buff); 317617b332f4SVishal Kulkarni if (rc) { 317717b332f4SVishal Kulkarni cudbg_err->sys_warn = CUDBG_STATUS_PARTIAL_DATA; 317817b332f4SVishal Kulkarni goto out; 317917b332f4SVishal Kulkarni } 318017b332f4SVishal Kulkarni rc = t4_read_flash(padap, addr, n, (u32 *)temp_buff.data, 0); 318117b332f4SVishal Kulkarni if (rc) 318217b332f4SVishal Kulkarni goto out; 318317b332f4SVishal Kulkarni 318417b332f4SVishal Kulkarni addr += (n * 4); 318517b332f4SVishal Kulkarni rc = cudbg_write_and_release_buff(pdbg_init, &temp_buff, 318617b332f4SVishal Kulkarni dbg_buff); 318717b332f4SVishal Kulkarni if (rc) { 318817b332f4SVishal Kulkarni cudbg_err->sys_warn = CUDBG_STATUS_PARTIAL_DATA; 318917b332f4SVishal Kulkarni goto out; 319017b332f4SVishal Kulkarni } 319117b332f4SVishal Kulkarni } 319217b332f4SVishal Kulkarni 319317b332f4SVishal Kulkarni out: 319417b332f4SVishal Kulkarni return rc; 319517b332f4SVishal Kulkarni } 3196