Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 123e25c4 authored by Rahul Lakkireddy's avatar Rahul Lakkireddy Committed by David S. Miller
Browse files

cxgb4: collect on-chip memory information



Collect memory layout of various on-chip memory regions.  Move code
for collecting on-chip memory information to cudbg_lib.c and update
cxgb4_debugfs.c to use the common function.  Also include
cudbg_entity.h before cudbg_lib.h to avoid adding cudbg entity
structure forward declarations in cudbg_lib.h.

Signed-off-by: default avatarRahul Lakkireddy <rahul.lakkireddy@chelsio.com>
Signed-off-by: default avatarGanesh Goudar <ganeshgr@chelsio.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 62fd8b18
Loading
Loading
Loading
Loading
+35 −0
Original line number Diff line number Diff line
@@ -87,6 +87,41 @@ struct cudbg_tp_la {
	u8 data[0];
};

static const char * const cudbg_region[] = {
	"DBQ contexts:", "IMSG contexts:", "FLM cache:", "TCBs:",
	"Pstructs:", "Timers:", "Rx FL:", "Tx FL:", "Pstruct FL:",
	"Tx payload:", "Rx payload:", "LE hash:", "iSCSI region:",
	"TDDP region:", "TPT region:", "STAG region:", "RQ region:",
	"RQUDP region:", "PBL region:", "TXPBL region:",
	"DBVFIFO region:", "ULPRX state:", "ULPTX state:",
	"On-chip queues:"
};

struct cudbg_mem_desc {
	u32 base;
	u32 limit;
	u32 idx;
};

struct cudbg_meminfo {
	struct cudbg_mem_desc avail[4];
	struct cudbg_mem_desc mem[ARRAY_SIZE(cudbg_region) + 3];
	u32 avail_c;
	u32 mem_c;
	u32 up_ram_lo;
	u32 up_ram_hi;
	u32 up_extmem2_lo;
	u32 up_extmem2_hi;
	u32 rx_pages_data[3];
	u32 tx_pages_data[4];
	u32 p_structs;
	u32 reserved[12];
	u32 port_used[4];
	u32 port_alloc[4];
	u32 loopback_used[NCHAN];
	u32 loopback_alloc[NCHAN];
};

struct cudbg_cim_pif_la {
	int size;
	u8 data[0];
+1 −0
Original line number Diff line number Diff line
@@ -56,6 +56,7 @@ enum cudbg_dbg_entity_type {
	CUDBG_SGE_INDIRECT = 37,
	CUDBG_ULPRX_LA = 41,
	CUDBG_TP_LA = 43,
	CUDBG_MEMINFO = 44,
	CUDBG_CIM_PIF_LA = 45,
	CUDBG_CLK = 46,
	CUDBG_CIM_OBQ_RXQ0 = 47,
+288 −1
Original line number Diff line number Diff line
@@ -15,12 +15,14 @@
 *
 */

#include <linux/sort.h>

#include "t4_regs.h"
#include "cxgb4.h"
#include "cudbg_if.h"
#include "cudbg_lib_common.h"
#include "cudbg_lib.h"
#include "cudbg_entity.h"
#include "cudbg_lib.h"

static void cudbg_write_and_release_buff(struct cudbg_buffer *pin_buff,
					 struct cudbg_buffer *dbg_buff)
@@ -84,6 +86,266 @@ static int cudbg_read_vpd_reg(struct adapter *padap, u32 addr, u32 len,
	return 0;
}

static int cudbg_mem_desc_cmp(const void *a, const void *b)
{
	return ((const struct cudbg_mem_desc *)a)->base -
	       ((const struct cudbg_mem_desc *)b)->base;
}

int cudbg_fill_meminfo(struct adapter *padap,
		       struct cudbg_meminfo *meminfo_buff)
{
	struct cudbg_mem_desc *md;
	u32 lo, hi, used, alloc;
	int n, i;

	memset(meminfo_buff->avail, 0,
	       ARRAY_SIZE(meminfo_buff->avail) *
	       sizeof(struct cudbg_mem_desc));
	memset(meminfo_buff->mem, 0,
	       (ARRAY_SIZE(cudbg_region) + 3) * sizeof(struct cudbg_mem_desc));
	md  = meminfo_buff->mem;

	for (i = 0; i < ARRAY_SIZE(meminfo_buff->mem); i++) {
		meminfo_buff->mem[i].limit = 0;
		meminfo_buff->mem[i].idx = i;
	}

	/* Find and sort the populated memory ranges */
	i = 0;
	lo = t4_read_reg(padap, MA_TARGET_MEM_ENABLE_A);
	if (lo & EDRAM0_ENABLE_F) {
		hi = t4_read_reg(padap, MA_EDRAM0_BAR_A);
		meminfo_buff->avail[i].base =
			cudbg_mbytes_to_bytes(EDRAM0_BASE_G(hi));
		meminfo_buff->avail[i].limit =
			meminfo_buff->avail[i].base +
			cudbg_mbytes_to_bytes(EDRAM0_SIZE_G(hi));
		meminfo_buff->avail[i].idx = 0;
		i++;
	}

	if (lo & EDRAM1_ENABLE_F) {
		hi =  t4_read_reg(padap, MA_EDRAM1_BAR_A);
		meminfo_buff->avail[i].base =
			cudbg_mbytes_to_bytes(EDRAM1_BASE_G(hi));
		meminfo_buff->avail[i].limit =
			meminfo_buff->avail[i].base +
			cudbg_mbytes_to_bytes(EDRAM1_SIZE_G(hi));
		meminfo_buff->avail[i].idx = 1;
		i++;
	}

	if (is_t5(padap->params.chip)) {
		if (lo & EXT_MEM0_ENABLE_F) {
			hi = t4_read_reg(padap, MA_EXT_MEMORY0_BAR_A);
			meminfo_buff->avail[i].base =
				cudbg_mbytes_to_bytes(EXT_MEM_BASE_G(hi));
			meminfo_buff->avail[i].limit =
				meminfo_buff->avail[i].base +
				cudbg_mbytes_to_bytes(EXT_MEM_SIZE_G(hi));
			meminfo_buff->avail[i].idx = 3;
			i++;
		}

		if (lo & EXT_MEM1_ENABLE_F) {
			hi = t4_read_reg(padap, MA_EXT_MEMORY1_BAR_A);
			meminfo_buff->avail[i].base =
				cudbg_mbytes_to_bytes(EXT_MEM1_BASE_G(hi));
			meminfo_buff->avail[i].limit =
				meminfo_buff->avail[i].base +
				cudbg_mbytes_to_bytes(EXT_MEM1_SIZE_G(hi));
			meminfo_buff->avail[i].idx = 4;
			i++;
		}
	} else {
		if (lo & EXT_MEM_ENABLE_F) {
			hi = t4_read_reg(padap, MA_EXT_MEMORY_BAR_A);
			meminfo_buff->avail[i].base =
				cudbg_mbytes_to_bytes(EXT_MEM_BASE_G(hi));
			meminfo_buff->avail[i].limit =
				meminfo_buff->avail[i].base +
				cudbg_mbytes_to_bytes(EXT_MEM_SIZE_G(hi));
			meminfo_buff->avail[i].idx = 2;
			i++;
		}
	}

	if (!i) /* no memory available */
		return CUDBG_STATUS_ENTITY_NOT_FOUND;

	meminfo_buff->avail_c = i;
	sort(meminfo_buff->avail, i, sizeof(struct cudbg_mem_desc),
	     cudbg_mem_desc_cmp, NULL);
	(md++)->base = t4_read_reg(padap, SGE_DBQ_CTXT_BADDR_A);
	(md++)->base = t4_read_reg(padap, SGE_IMSG_CTXT_BADDR_A);
	(md++)->base = t4_read_reg(padap, SGE_FLM_CACHE_BADDR_A);
	(md++)->base = t4_read_reg(padap, TP_CMM_TCB_BASE_A);
	(md++)->base = t4_read_reg(padap, TP_CMM_MM_BASE_A);
	(md++)->base = t4_read_reg(padap, TP_CMM_TIMER_BASE_A);
	(md++)->base = t4_read_reg(padap, TP_CMM_MM_RX_FLST_BASE_A);
	(md++)->base = t4_read_reg(padap, TP_CMM_MM_TX_FLST_BASE_A);
	(md++)->base = t4_read_reg(padap, TP_CMM_MM_PS_FLST_BASE_A);

	/* the next few have explicit upper bounds */
	md->base = t4_read_reg(padap, TP_PMM_TX_BASE_A);
	md->limit = md->base - 1 +
		    t4_read_reg(padap, TP_PMM_TX_PAGE_SIZE_A) *
		    PMTXMAXPAGE_G(t4_read_reg(padap, TP_PMM_TX_MAX_PAGE_A));
	md++;

	md->base = t4_read_reg(padap, TP_PMM_RX_BASE_A);
	md->limit = md->base - 1 +
		    t4_read_reg(padap, TP_PMM_RX_PAGE_SIZE_A) *
		    PMRXMAXPAGE_G(t4_read_reg(padap, TP_PMM_RX_MAX_PAGE_A));
	md++;

	if (t4_read_reg(padap, LE_DB_CONFIG_A) & HASHEN_F) {
		if (CHELSIO_CHIP_VERSION(padap->params.chip) <= CHELSIO_T5) {
			hi = t4_read_reg(padap, LE_DB_TID_HASHBASE_A) / 4;
			md->base = t4_read_reg(padap, LE_DB_HASH_TID_BASE_A);
		} else {
			hi = t4_read_reg(padap, LE_DB_HASH_TID_BASE_A);
			md->base = t4_read_reg(padap,
					       LE_DB_HASH_TBL_BASE_ADDR_A);
		}
		md->limit = 0;
	} else {
		md->base = 0;
		md->idx = ARRAY_SIZE(cudbg_region);  /* hide it */
	}
	md++;

#define ulp_region(reg) do { \
	md->base = t4_read_reg(padap, ULP_ ## reg ## _LLIMIT_A);\
	(md++)->limit = t4_read_reg(padap, ULP_ ## reg ## _ULIMIT_A);\
} while (0)

	ulp_region(RX_ISCSI);
	ulp_region(RX_TDDP);
	ulp_region(TX_TPT);
	ulp_region(RX_STAG);
	ulp_region(RX_RQ);
	ulp_region(RX_RQUDP);
	ulp_region(RX_PBL);
	ulp_region(TX_PBL);
#undef ulp_region
	md->base = 0;
	md->idx = ARRAY_SIZE(cudbg_region);
	if (!is_t4(padap->params.chip)) {
		u32 fifo_size = t4_read_reg(padap, SGE_DBVFIFO_SIZE_A);
		u32 sge_ctrl = t4_read_reg(padap, SGE_CONTROL2_A);
		u32 size = 0;

		if (is_t5(padap->params.chip)) {
			if (sge_ctrl & VFIFO_ENABLE_F)
				size = DBVFIFO_SIZE_G(fifo_size);
		} else {
			size = T6_DBVFIFO_SIZE_G(fifo_size);
		}

		if (size) {
			md->base = BASEADDR_G(t4_read_reg(padap,
							  SGE_DBVFIFO_BADDR_A));
			md->limit = md->base + (size << 2) - 1;
		}
	}

	md++;

	md->base = t4_read_reg(padap, ULP_RX_CTX_BASE_A);
	md->limit = 0;
	md++;
	md->base = t4_read_reg(padap, ULP_TX_ERR_TABLE_BASE_A);
	md->limit = 0;
	md++;

	md->base = padap->vres.ocq.start;
	if (padap->vres.ocq.size)
		md->limit = md->base + padap->vres.ocq.size - 1;
	else
		md->idx = ARRAY_SIZE(cudbg_region);  /* hide it */
	md++;

	/* add any address-space holes, there can be up to 3 */
	for (n = 0; n < i - 1; n++)
		if (meminfo_buff->avail[n].limit <
		    meminfo_buff->avail[n + 1].base)
			(md++)->base = meminfo_buff->avail[n].limit;

	if (meminfo_buff->avail[n].limit)
		(md++)->base = meminfo_buff->avail[n].limit;

	n = md - meminfo_buff->mem;
	meminfo_buff->mem_c = n;

	sort(meminfo_buff->mem, n, sizeof(struct cudbg_mem_desc),
	     cudbg_mem_desc_cmp, NULL);

	lo = t4_read_reg(padap, CIM_SDRAM_BASE_ADDR_A);
	hi = t4_read_reg(padap, CIM_SDRAM_ADDR_SIZE_A) + lo - 1;
	meminfo_buff->up_ram_lo = lo;
	meminfo_buff->up_ram_hi = hi;

	lo = t4_read_reg(padap, CIM_EXTMEM2_BASE_ADDR_A);
	hi = t4_read_reg(padap, CIM_EXTMEM2_ADDR_SIZE_A) + lo - 1;
	meminfo_buff->up_extmem2_lo = lo;
	meminfo_buff->up_extmem2_hi = hi;

	lo = t4_read_reg(padap, TP_PMM_RX_MAX_PAGE_A);
	meminfo_buff->rx_pages_data[0] =  PMRXMAXPAGE_G(lo);
	meminfo_buff->rx_pages_data[1] =
		t4_read_reg(padap, TP_PMM_RX_PAGE_SIZE_A) >> 10;
	meminfo_buff->rx_pages_data[2] = (lo & PMRXNUMCHN_F) ? 2 : 1;

	lo = t4_read_reg(padap, TP_PMM_TX_MAX_PAGE_A);
	hi = t4_read_reg(padap, TP_PMM_TX_PAGE_SIZE_A);
	meminfo_buff->tx_pages_data[0] = PMTXMAXPAGE_G(lo);
	meminfo_buff->tx_pages_data[1] =
		hi >= (1 << 20) ? (hi >> 20) : (hi >> 10);
	meminfo_buff->tx_pages_data[2] =
		hi >= (1 << 20) ? 'M' : 'K';
	meminfo_buff->tx_pages_data[3] = 1 << PMTXNUMCHN_G(lo);

	meminfo_buff->p_structs = t4_read_reg(padap, TP_CMM_MM_MAX_PSTRUCT_A);

	for (i = 0; i < 4; i++) {
		if (CHELSIO_CHIP_VERSION(padap->params.chip) > CHELSIO_T5)
			lo = t4_read_reg(padap,
					 MPS_RX_MAC_BG_PG_CNT0_A + i * 4);
		else
			lo = t4_read_reg(padap, MPS_RX_PG_RSV0_A + i * 4);
		if (is_t5(padap->params.chip)) {
			used = T5_USED_G(lo);
			alloc = T5_ALLOC_G(lo);
		} else {
			used = USED_G(lo);
			alloc = ALLOC_G(lo);
		}
		meminfo_buff->port_used[i] = used;
		meminfo_buff->port_alloc[i] = alloc;
	}

	for (i = 0; i < padap->params.arch.nchan; i++) {
		if (CHELSIO_CHIP_VERSION(padap->params.chip) > CHELSIO_T5)
			lo = t4_read_reg(padap,
					 MPS_RX_LPBK_BG_PG_CNT0_A + i * 4);
		else
			lo = t4_read_reg(padap, MPS_RX_PG_RSV4_A + i * 4);
		if (is_t5(padap->params.chip)) {
			used = T5_USED_G(lo);
			alloc = T5_ALLOC_G(lo);
		} else {
			used = USED_G(lo);
			alloc = ALLOC_G(lo);
		}
		meminfo_buff->loopback_used[i] = used;
		meminfo_buff->loopback_alloc[i] = alloc;
	}

	return 0;
}

int cudbg_collect_reg_dump(struct cudbg_init *pdbg_init,
			   struct cudbg_buffer *dbg_buff,
			   struct cudbg_error *cudbg_err)
@@ -843,6 +1105,31 @@ int cudbg_collect_tp_la(struct cudbg_init *pdbg_init,
	return rc;
}

int cudbg_collect_meminfo(struct cudbg_init *pdbg_init,
			  struct cudbg_buffer *dbg_buff,
			  struct cudbg_error *cudbg_err)
{
	struct adapter *padap = pdbg_init->adap;
	struct cudbg_buffer temp_buff = { 0 };
	struct cudbg_meminfo *meminfo_buff;
	int rc;

	rc = cudbg_get_buff(dbg_buff, sizeof(struct cudbg_meminfo), &temp_buff);
	if (rc)
		return rc;

	meminfo_buff = (struct cudbg_meminfo *)temp_buff.data;
	rc = cudbg_fill_meminfo(padap, meminfo_buff);
	if (rc) {
		cudbg_err->sys_err = rc;
		cudbg_put_buff(&temp_buff, dbg_buff);
		return rc;
	}

	cudbg_write_and_release_buff(&temp_buff, dbg_buff);
	return rc;
}

int cudbg_collect_cim_pif_la(struct cudbg_init *pdbg_init,
			     struct cudbg_buffer *dbg_buff,
			     struct cudbg_error *cudbg_err)
+5 −1
Original line number Diff line number Diff line
@@ -102,6 +102,9 @@ int cudbg_collect_ulprx_la(struct cudbg_init *pdbg_init,
int cudbg_collect_tp_la(struct cudbg_init *pdbg_init,
			struct cudbg_buffer *dbg_buff,
			struct cudbg_error *cudbg_err);
int cudbg_collect_meminfo(struct cudbg_init *pdbg_init,
			  struct cudbg_buffer *dbg_buff,
			  struct cudbg_error *cudbg_err);
int cudbg_collect_cim_pif_la(struct cudbg_init *pdbg_init,
			     struct cudbg_buffer *dbg_buff,
			     struct cudbg_error *cudbg_err);
@@ -163,7 +166,8 @@ void cudbg_align_debug_buffer(struct cudbg_buffer *dbg_buff,
u32 cudbg_cim_obq_size(struct adapter *padap, int qid);
int cudbg_dump_context_size(struct adapter *padap);

struct cudbg_tcam;
int cudbg_fill_meminfo(struct adapter *padap,
		       struct cudbg_meminfo *meminfo_buff);
void cudbg_fill_le_tcam_info(struct adapter *padap,
			     struct cudbg_tcam *tcam_region);
#endif /* __CUDBG_LIB_H__ */
+4 −1
Original line number Diff line number Diff line
@@ -18,7 +18,6 @@
#include "t4_regs.h"
#include "cxgb4.h"
#include "cxgb4_cudbg.h"
#include "cudbg_entity.h"

static const struct cxgb4_collect_entity cxgb4_collect_mem_dump[] = {
	{ CUDBG_EDC0, cudbg_collect_edc0_meminfo },
@@ -53,6 +52,7 @@ static const struct cxgb4_collect_entity cxgb4_collect_hw_dump[] = {
	{ CUDBG_SGE_INDIRECT, cudbg_collect_sge_indirect },
	{ CUDBG_ULPRX_LA, cudbg_collect_ulprx_la },
	{ CUDBG_TP_LA, cudbg_collect_tp_la },
	{ CUDBG_MEMINFO, cudbg_collect_meminfo },
	{ CUDBG_CIM_PIF_LA, cudbg_collect_cim_pif_la },
	{ CUDBG_CLK, cudbg_collect_clk_info },
	{ CUDBG_CIM_OBQ_RXQ0, cudbg_collect_obq_sge_rx_q0 },
@@ -201,6 +201,9 @@ static u32 cxgb4_get_entity_length(struct adapter *adap, u32 entity)
	case CUDBG_TP_LA:
		len = sizeof(struct cudbg_tp_la) + TPLA_SIZE * sizeof(u64);
		break;
	case CUDBG_MEMINFO:
		len = sizeof(struct cudbg_meminfo);
		break;
	case CUDBG_CIM_PIF_LA:
		len = sizeof(struct cudbg_cim_pif_la);
		len += 2 * CIM_PIFLA_SIZE * 6 * sizeof(u32);
Loading