From 5888111cb8f7368304db42787c9495d4b2b82e06 Mon Sep 17 00:00:00 2001 From: Hariprasad Shenai Date: Tue, 4 Aug 2015 14:36:17 +0530 Subject: cxgb4: Add debugfs support to dump meminfo Add debug support to dump memory address ranges of various hardware modules of the adapter. Signed-off-by: Hariprasad Shenai Signed-off-by: David S. Miller --- drivers/net/ethernet/chelsio/cxgb4/cxgb4_debugfs.c | 285 +++++++++++++++++++++ drivers/net/ethernet/chelsio/cxgb4/t4_regs.h | 122 +++++++++ 2 files changed, 407 insertions(+) diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_debugfs.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_debugfs.c index f701a6f20c6a..b6577349cf4e 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_debugfs.c +++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_debugfs.c @@ -2275,6 +2275,290 @@ static const struct file_operations blocked_fl_fops = { .llseek = generic_file_llseek, }; +struct mem_desc { + unsigned int base; + unsigned int limit; + unsigned int idx; +}; + +static int mem_desc_cmp(const void *a, const void *b) +{ + return ((const struct mem_desc *)a)->base - + ((const struct mem_desc *)b)->base; +} + +static void mem_region_show(struct seq_file *seq, const char *name, + unsigned int from, unsigned int to) +{ + char buf[40]; + + string_get_size((u64)to - from + 1, 1, STRING_UNITS_2, buf, + sizeof(buf)); + seq_printf(seq, "%-15s %#x-%#x [%s]\n", name, from, to, buf); +} + +static int meminfo_show(struct seq_file *seq, void *v) +{ + static const char * const memory[] = { "EDC0:", "EDC1:", "MC:", + "MC0:", "MC1:"}; + static const char * const 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:" + }; + + int i, n; + u32 lo, hi, used, alloc; + struct mem_desc avail[4]; + struct mem_desc mem[ARRAY_SIZE(region) + 3]; /* up to 3 holes */ + struct mem_desc *md = mem; + struct adapter *adap = seq->private; + + for (i = 0; i < ARRAY_SIZE(mem); i++) { + mem[i].limit = 0; + mem[i].idx = i; + } + + /* Find and sort the populated memory ranges */ + i = 0; + lo = t4_read_reg(adap, MA_TARGET_MEM_ENABLE_A); + if (lo & EDRAM0_ENABLE_F) { + hi = t4_read_reg(adap, MA_EDRAM0_BAR_A); + avail[i].base = EDRAM0_BASE_G(hi) << 20; + avail[i].limit = avail[i].base + (EDRAM0_SIZE_G(hi) << 20); + avail[i].idx = 0; + i++; + } + if (lo & EDRAM1_ENABLE_F) { + hi = t4_read_reg(adap, MA_EDRAM1_BAR_A); + avail[i].base = EDRAM1_BASE_G(hi) << 20; + avail[i].limit = avail[i].base + (EDRAM1_SIZE_G(hi) << 20); + avail[i].idx = 1; + i++; + } + + if (is_t5(adap->params.chip)) { + if (lo & EXT_MEM0_ENABLE_F) { + hi = t4_read_reg(adap, MA_EXT_MEMORY0_BAR_A); + avail[i].base = EXT_MEM0_BASE_G(hi) << 20; + avail[i].limit = + avail[i].base + (EXT_MEM0_SIZE_G(hi) << 20); + avail[i].idx = 3; + i++; + } + if (lo & EXT_MEM1_ENABLE_F) { + hi = t4_read_reg(adap, MA_EXT_MEMORY1_BAR_A); + avail[i].base = EXT_MEM1_BASE_G(hi) << 20; + avail[i].limit = + avail[i].base + (EXT_MEM1_SIZE_G(hi) << 20); + avail[i].idx = 4; + i++; + } + } else { + if (lo & EXT_MEM_ENABLE_F) { + hi = t4_read_reg(adap, MA_EXT_MEMORY_BAR_A); + avail[i].base = EXT_MEM_BASE_G(hi) << 20; + avail[i].limit = + avail[i].base + (EXT_MEM_SIZE_G(hi) << 20); + avail[i].idx = 2; + i++; + } + } + if (!i) /* no memory available */ + return 0; + sort(avail, i, sizeof(struct mem_desc), mem_desc_cmp, NULL); + + (md++)->base = t4_read_reg(adap, SGE_DBQ_CTXT_BADDR_A); + (md++)->base = t4_read_reg(adap, SGE_IMSG_CTXT_BADDR_A); + (md++)->base = t4_read_reg(adap, SGE_FLM_CACHE_BADDR_A); + (md++)->base = t4_read_reg(adap, TP_CMM_TCB_BASE_A); + (md++)->base = t4_read_reg(adap, TP_CMM_MM_BASE_A); + (md++)->base = t4_read_reg(adap, TP_CMM_TIMER_BASE_A); + (md++)->base = t4_read_reg(adap, TP_CMM_MM_RX_FLST_BASE_A); + (md++)->base = t4_read_reg(adap, TP_CMM_MM_TX_FLST_BASE_A); + (md++)->base = t4_read_reg(adap, TP_CMM_MM_PS_FLST_BASE_A); + + /* the next few have explicit upper bounds */ + md->base = t4_read_reg(adap, TP_PMM_TX_BASE_A); + md->limit = md->base - 1 + + t4_read_reg(adap, TP_PMM_TX_PAGE_SIZE_A) * + PMTXMAXPAGE_G(t4_read_reg(adap, TP_PMM_TX_MAX_PAGE_A)); + md++; + + md->base = t4_read_reg(adap, TP_PMM_RX_BASE_A); + md->limit = md->base - 1 + + t4_read_reg(adap, TP_PMM_RX_PAGE_SIZE_A) * + PMRXMAXPAGE_G(t4_read_reg(adap, TP_PMM_RX_MAX_PAGE_A)); + md++; + + if (t4_read_reg(adap, LE_DB_CONFIG_A) & HASHEN_F) { + if (CHELSIO_CHIP_VERSION(adap->params.chip) <= CHELSIO_T5) { + hi = t4_read_reg(adap, LE_DB_TID_HASHBASE_A) / 4; + md->base = t4_read_reg(adap, LE_DB_HASH_TID_BASE_A); + } else { + hi = t4_read_reg(adap, LE_DB_HASH_TID_BASE_A); + md->base = t4_read_reg(adap, + LE_DB_HASH_TBL_BASE_ADDR_A); + } + md->limit = 0; + } else { + md->base = 0; + md->idx = ARRAY_SIZE(region); /* hide it */ + } + md++; + +#define ulp_region(reg) do { \ + md->base = t4_read_reg(adap, ULP_ ## reg ## _LLIMIT_A);\ + (md++)->limit = t4_read_reg(adap, 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(region); + if (!is_t4(adap->params.chip)) { + u32 size = 0; + u32 sge_ctrl = t4_read_reg(adap, SGE_CONTROL2_A); + u32 fifo_size = t4_read_reg(adap, SGE_DBVFIFO_SIZE_A); + + if (is_t5(adap->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(adap, + SGE_DBVFIFO_BADDR_A)); + md->limit = md->base + (size << 2) - 1; + } + } + + md++; + + md->base = t4_read_reg(adap, ULP_RX_CTX_BASE_A); + md->limit = 0; + md++; + md->base = t4_read_reg(adap, ULP_TX_ERR_TABLE_BASE_A); + md->limit = 0; + md++; + + md->base = adap->vres.ocq.start; + if (adap->vres.ocq.size) + md->limit = md->base + adap->vres.ocq.size - 1; + else + md->idx = ARRAY_SIZE(region); /* hide it */ + md++; + + /* add any address-space holes, there can be up to 3 */ + for (n = 0; n < i - 1; n++) + if (avail[n].limit < avail[n + 1].base) + (md++)->base = avail[n].limit; + if (avail[n].limit) + (md++)->base = avail[n].limit; + + n = md - mem; + sort(mem, n, sizeof(struct mem_desc), mem_desc_cmp, NULL); + + for (lo = 0; lo < i; lo++) + mem_region_show(seq, memory[avail[lo].idx], avail[lo].base, + avail[lo].limit - 1); + + seq_putc(seq, '\n'); + for (i = 0; i < n; i++) { + if (mem[i].idx >= ARRAY_SIZE(region)) + continue; /* skip holes */ + if (!mem[i].limit) + mem[i].limit = i < n - 1 ? mem[i + 1].base - 1 : ~0; + mem_region_show(seq, region[mem[i].idx], mem[i].base, + mem[i].limit); + } + + seq_putc(seq, '\n'); + lo = t4_read_reg(adap, CIM_SDRAM_BASE_ADDR_A); + hi = t4_read_reg(adap, CIM_SDRAM_ADDR_SIZE_A) + lo - 1; + mem_region_show(seq, "uP RAM:", lo, hi); + + lo = t4_read_reg(adap, CIM_EXTMEM2_BASE_ADDR_A); + hi = t4_read_reg(adap, CIM_EXTMEM2_ADDR_SIZE_A) + lo - 1; + mem_region_show(seq, "uP Extmem2:", lo, hi); + + lo = t4_read_reg(adap, TP_PMM_RX_MAX_PAGE_A); + seq_printf(seq, "\n%u Rx pages of size %uKiB for %u channels\n", + PMRXMAXPAGE_G(lo), + t4_read_reg(adap, TP_PMM_RX_PAGE_SIZE_A) >> 10, + (lo & PMRXNUMCHN_F) ? 2 : 1); + + lo = t4_read_reg(adap, TP_PMM_TX_MAX_PAGE_A); + hi = t4_read_reg(adap, TP_PMM_TX_PAGE_SIZE_A); + seq_printf(seq, "%u Tx pages of size %u%ciB for %u channels\n", + PMTXMAXPAGE_G(lo), + hi >= (1 << 20) ? (hi >> 20) : (hi >> 10), + hi >= (1 << 20) ? 'M' : 'K', 1 << PMTXNUMCHN_G(lo)); + seq_printf(seq, "%u p-structs\n\n", + t4_read_reg(adap, TP_CMM_MM_MAX_PSTRUCT_A)); + + for (i = 0; i < 4; i++) { + if (CHELSIO_CHIP_VERSION(adap->params.chip) > CHELSIO_T5) + lo = t4_read_reg(adap, MPS_RX_MAC_BG_PG_CNT0_A + i * 4); + else + lo = t4_read_reg(adap, MPS_RX_PG_RSV0_A + i * 4); + if (is_t5(adap->params.chip)) { + used = T5_USED_G(lo); + alloc = T5_ALLOC_G(lo); + } else { + used = USED_G(lo); + alloc = ALLOC_G(lo); + } + /* For T6 these are MAC buffer groups */ + seq_printf(seq, "Port %d using %u pages out of %u allocated\n", + i, used, alloc); + } + for (i = 0; i < adap->params.arch.nchan; i++) { + if (CHELSIO_CHIP_VERSION(adap->params.chip) > CHELSIO_T5) + lo = t4_read_reg(adap, + MPS_RX_LPBK_BG_PG_CNT0_A + i * 4); + else + lo = t4_read_reg(adap, MPS_RX_PG_RSV4_A + i * 4); + if (is_t5(adap->params.chip)) { + used = T5_USED_G(lo); + alloc = T5_ALLOC_G(lo); + } else { + used = USED_G(lo); + alloc = ALLOC_G(lo); + } + /* For T6 these are MAC buffer groups */ + seq_printf(seq, + "Loopback %d using %u pages out of %u allocated\n", + i, used, alloc); + } + return 0; +} + +static int meminfo_open(struct inode *inode, struct file *file) +{ + return single_open(file, meminfo_show, inode->i_private); +} + +static const struct file_operations meminfo_fops = { + .owner = THIS_MODULE, + .open = meminfo_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; /* Add an array of Debug FS files. */ void add_debugfs_files(struct adapter *adap, @@ -2342,6 +2626,7 @@ int t4_setup_debugfs(struct adapter *adap) { "clip_tbl", &clip_tbl_debugfs_fops, S_IRUSR, 0 }, #endif { "blocked_fl", &blocked_fl_fops, S_IRUSR | S_IWUSR, 0 }, + { "meminfo", &meminfo_fops, S_IRUSR, 0 }, }; /* Debug FS nodes common to all T5 and later adapters. diff --git a/drivers/net/ethernet/chelsio/cxgb4/t4_regs.h b/drivers/net/ethernet/chelsio/cxgb4/t4_regs.h index ed8a8f350113..06268681a279 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/t4_regs.h +++ b/drivers/net/ethernet/chelsio/cxgb4/t4_regs.h @@ -136,6 +136,20 @@ #define INGPACKBOUNDARY_G(x) (((x) >> INGPACKBOUNDARY_S) \ & INGPACKBOUNDARY_M) +#define VFIFO_ENABLE_S 10 +#define VFIFO_ENABLE_V(x) ((x) << VFIFO_ENABLE_S) +#define VFIFO_ENABLE_F VFIFO_ENABLE_V(1U) + +#define SGE_DBVFIFO_BADDR_A 0x1138 + +#define DBVFIFO_SIZE_S 6 +#define DBVFIFO_SIZE_M 0xfffU +#define DBVFIFO_SIZE_G(x) (((x) >> DBVFIFO_SIZE_S) & DBVFIFO_SIZE_M) + +#define T6_DBVFIFO_SIZE_S 0 +#define T6_DBVFIFO_SIZE_M 0x1fffU +#define T6_DBVFIFO_SIZE_G(x) (((x) >> T6_DBVFIFO_SIZE_S) & T6_DBVFIFO_SIZE_M) + #define GLOBALENABLE_S 0 #define GLOBALENABLE_V(x) ((x) << GLOBALENABLE_S) #define GLOBALENABLE_F GLOBALENABLE_V(1U) @@ -303,6 +317,8 @@ #define SGE_FL_BUFFER_SIZE7_A 0x1060 #define SGE_FL_BUFFER_SIZE8_A 0x1064 +#define SGE_IMSG_CTXT_BADDR_A 0x1088 +#define SGE_FLM_CACHE_BADDR_A 0x108c #define SGE_INGRESS_RX_THRESHOLD_A 0x10a0 #define THRESHOLD_0_S 24 @@ -357,6 +373,7 @@ #define TSVAL_G(x) (((x) >> TSVAL_S) & TSVAL_M) #define SGE_DBFIFO_STATUS_A 0x10a4 +#define SGE_DBVFIFO_SIZE_A 0x113c #define HP_INT_THRESH_S 28 #define HP_INT_THRESH_M 0xfU @@ -869,6 +886,10 @@ /* registers for module MA */ #define MA_EDRAM0_BAR_A 0x77c0 +#define EDRAM0_BASE_S 16 +#define EDRAM0_BASE_M 0xfffU +#define EDRAM0_BASE_G(x) (((x) >> EDRAM0_BASE_S) & EDRAM0_BASE_M) + #define EDRAM0_SIZE_S 0 #define EDRAM0_SIZE_M 0xfffU #define EDRAM0_SIZE_V(x) ((x) << EDRAM0_SIZE_S) @@ -876,6 +897,10 @@ #define MA_EDRAM1_BAR_A 0x77c4 +#define EDRAM1_BASE_S 16 +#define EDRAM1_BASE_M 0xfffU +#define EDRAM1_BASE_G(x) (((x) >> EDRAM1_BASE_S) & EDRAM1_BASE_M) + #define EDRAM1_SIZE_S 0 #define EDRAM1_SIZE_M 0xfffU #define EDRAM1_SIZE_V(x) ((x) << EDRAM1_SIZE_S) @@ -883,6 +908,11 @@ #define MA_EXT_MEMORY_BAR_A 0x77c8 +#define EXT_MEM_BASE_S 16 +#define EXT_MEM_BASE_M 0xfffU +#define EXT_MEM_BASE_V(x) ((x) << EXT_MEM_BASE_S) +#define EXT_MEM_BASE_G(x) (((x) >> EXT_MEM_BASE_S) & EXT_MEM_BASE_M) + #define EXT_MEM_SIZE_S 0 #define EXT_MEM_SIZE_M 0xfffU #define EXT_MEM_SIZE_V(x) ((x) << EXT_MEM_SIZE_S) @@ -890,6 +920,10 @@ #define MA_EXT_MEMORY1_BAR_A 0x7808 +#define EXT_MEM1_BASE_S 16 +#define EXT_MEM1_BASE_M 0xfffU +#define EXT_MEM1_BASE_G(x) (((x) >> EXT_MEM1_BASE_S) & EXT_MEM1_BASE_M) + #define EXT_MEM1_SIZE_S 0 #define EXT_MEM1_SIZE_M 0xfffU #define EXT_MEM1_SIZE_V(x) ((x) << EXT_MEM1_SIZE_S) @@ -897,6 +931,10 @@ #define MA_EXT_MEMORY0_BAR_A 0x77c8 +#define EXT_MEM0_BASE_S 16 +#define EXT_MEM0_BASE_M 0xfffU +#define EXT_MEM0_BASE_G(x) (((x) >> EXT_MEM0_BASE_S) & EXT_MEM0_BASE_M) + #define EXT_MEM0_SIZE_S 0 #define EXT_MEM0_SIZE_M 0xfffU #define EXT_MEM0_SIZE_V(x) ((x) << EXT_MEM0_SIZE_S) @@ -978,6 +1016,10 @@ /* registers for module CIM */ #define CIM_BOOT_CFG_A 0x7b00 +#define CIM_SDRAM_BASE_ADDR_A 0x7b14 +#define CIM_SDRAM_ADDR_SIZE_A 0x7b18 +#define CIM_EXTMEM2_BASE_ADDR_A 0x7b1c +#define CIM_EXTMEM2_ADDR_SIZE_A 0x7b20 #define CIM_PF_MAILBOX_CTRL_SHADOW_COPY_A 0x290 #define BOOTADDR_M 0xffffff00U @@ -1236,6 +1278,33 @@ #define TP_OUT_CONFIG_A 0x7d04 #define TP_GLOBAL_CONFIG_A 0x7d08 +#define TP_CMM_TCB_BASE_A 0x7d10 +#define TP_CMM_MM_BASE_A 0x7d14 +#define TP_CMM_TIMER_BASE_A 0x7d18 +#define TP_PMM_TX_BASE_A 0x7d20 +#define TP_PMM_RX_BASE_A 0x7d28 +#define TP_PMM_RX_PAGE_SIZE_A 0x7d2c +#define TP_PMM_RX_MAX_PAGE_A 0x7d30 +#define TP_PMM_TX_PAGE_SIZE_A 0x7d34 +#define TP_PMM_TX_MAX_PAGE_A 0x7d38 +#define TP_CMM_MM_MAX_PSTRUCT_A 0x7e6c + +#define PMRXNUMCHN_S 31 +#define PMRXNUMCHN_V(x) ((x) << PMRXNUMCHN_S) +#define PMRXNUMCHN_F PMRXNUMCHN_V(1U) + +#define PMTXNUMCHN_S 30 +#define PMTXNUMCHN_M 0x3U +#define PMTXNUMCHN_G(x) (((x) >> PMTXNUMCHN_S) & PMTXNUMCHN_M) + +#define PMTXMAXPAGE_S 0 +#define PMTXMAXPAGE_M 0x1fffffU +#define PMTXMAXPAGE_G(x) (((x) >> PMTXMAXPAGE_S) & PMTXMAXPAGE_M) + +#define PMRXMAXPAGE_S 0 +#define PMRXMAXPAGE_M 0x1fffffU +#define PMRXMAXPAGE_G(x) (((x) >> PMRXMAXPAGE_S) & PMRXMAXPAGE_M) + #define DBGLAMODE_S 14 #define DBGLAMODE_M 0x3U #define DBGLAMODE_G(x) (((x) >> DBGLAMODE_S) & DBGLAMODE_M) @@ -1343,6 +1412,9 @@ #define MTUVALUE_G(x) (((x) >> MTUVALUE_S) & MTUVALUE_M) #define TP_RSS_LKP_TABLE_A 0x7dec +#define TP_CMM_MM_RX_FLST_BASE_A 0x7e60 +#define TP_CMM_MM_TX_FLST_BASE_A 0x7e64 +#define TP_CMM_MM_PS_FLST_BASE_A 0x7e68 #define LKPTBLROWVLD_S 31 #define LKPTBLROWVLD_V(x) ((x) << LKPTBLROWVLD_S) @@ -1488,6 +1560,11 @@ #define TP_MIB_RQE_DFR_PKT_A 0x64 #define ULP_TX_INT_CAUSE_A 0x8dcc +#define ULP_TX_TPT_LLIMIT_A 0x8dd4 +#define ULP_TX_TPT_ULIMIT_A 0x8dd8 +#define ULP_TX_PBL_LLIMIT_A 0x8ddc +#define ULP_TX_PBL_ULIMIT_A 0x8de0 +#define ULP_TX_ERR_TABLE_BASE_A 0x8e04 #define PBL_BOUND_ERR_CH3_S 31 #define PBL_BOUND_ERR_CH3_V(x) ((x) << PBL_BOUND_ERR_CH3_S) @@ -2252,12 +2329,32 @@ #define MATCHSRAM_V(x) ((x) << MATCHSRAM_S) #define MATCHSRAM_F MATCHSRAM_V(1U) +#define MPS_RX_PG_RSV0_A 0x11010 +#define MPS_RX_PG_RSV4_A 0x11020 #define MPS_RX_PERR_INT_CAUSE_A 0x11074 +#define MPS_RX_MAC_BG_PG_CNT0_A 0x11208 +#define MPS_RX_LPBK_BG_PG_CNT0_A 0x11218 #define MPS_CLS_TCAM_Y_L_A 0xf000 #define MPS_CLS_TCAM_DATA0_A 0xf000 #define MPS_CLS_TCAM_DATA1_A 0xf004 +#define USED_S 16 +#define USED_M 0x7ffU +#define USED_G(x) (((x) >> USED_S) & USED_M) + +#define ALLOC_S 0 +#define ALLOC_M 0x7ffU +#define ALLOC_G(x) (((x) >> ALLOC_S) & ALLOC_M) + +#define T5_USED_S 16 +#define T5_USED_M 0xfffU +#define T5_USED_G(x) (((x) >> T5_USED_S) & T5_USED_M) + +#define T5_ALLOC_S 0 +#define T5_ALLOC_M 0xfffU +#define T5_ALLOC_G(x) (((x) >> T5_ALLOC_S) & T5_ALLOC_M) + #define DMACH_S 0 #define DMACH_M 0xffffU #define DMACH_G(x) (((x) >> DMACH_S) & DMACH_M) @@ -2415,8 +2512,21 @@ #define SLVFIFOPARINT_F SLVFIFOPARINT_V(1U) #define ULP_RX_INT_CAUSE_A 0x19158 +#define ULP_RX_ISCSI_LLIMIT_A 0x1915c +#define ULP_RX_ISCSI_ULIMIT_A 0x19160 #define ULP_RX_ISCSI_TAGMASK_A 0x19164 #define ULP_RX_ISCSI_PSZ_A 0x19168 +#define ULP_RX_TDDP_LLIMIT_A 0x1916c +#define ULP_RX_TDDP_ULIMIT_A 0x19170 +#define ULP_RX_STAG_LLIMIT_A 0x1917c +#define ULP_RX_STAG_ULIMIT_A 0x19180 +#define ULP_RX_RQ_LLIMIT_A 0x19184 +#define ULP_RX_RQ_ULIMIT_A 0x19188 +#define ULP_RX_PBL_LLIMIT_A 0x1918c +#define ULP_RX_PBL_ULIMIT_A 0x19190 +#define ULP_RX_CTX_BASE_A 0x19194 +#define ULP_RX_RQUDP_LLIMIT_A 0x191a4 +#define ULP_RX_RQUDP_ULIMIT_A 0x191a8 #define ULP_RX_LA_CTL_A 0x1923c #define ULP_RX_LA_RDPTR_A 0x19240 #define ULP_RX_LA_RDDATA_A 0x19244 @@ -2617,7 +2727,15 @@ #define T6_LIPMISS_V(x) ((x) << T6_LIPMISS_S) #define T6_LIPMISS_F T6_LIPMISS_V(1U) +#define LE_DB_CONFIG_A 0x19c04 +#define LE_DB_HASH_TID_BASE_A 0x19c30 +#define LE_DB_HASH_TBL_BASE_ADDR_A 0x19c30 #define LE_DB_INT_CAUSE_A 0x19c3c +#define LE_DB_TID_HASHBASE_A 0x19df8 + +#define HASHEN_S 20 +#define HASHEN_V(x) ((x) << HASHEN_S) +#define HASHEN_F HASHEN_V(1U) #define REQQPARERR_S 16 #define REQQPARERR_V(x) ((x) << REQQPARERR_S) @@ -2639,6 +2757,10 @@ #define LIP0_V(x) ((x) << LIP0_S) #define LIP0_F LIP0_V(1U) +#define BASEADDR_S 3 +#define BASEADDR_M 0x1fffffffU +#define BASEADDR_G(x) (((x) >> BASEADDR_S) & BASEADDR_M) + #define TCAMINTPERR_S 13 #define TCAMINTPERR_V(x) ((x) << TCAMINTPERR_S) #define TCAMINTPERR_F TCAMINTPERR_V(1U) -- cgit v1.2.3 From bf8ebb67dae0a07db7aebe7a65c178ff24d90842 Mon Sep 17 00:00:00 2001 From: Hariprasad Shenai Date: Tue, 4 Aug 2015 14:36:18 +0530 Subject: cxgb4: Add support to dump edc bist status Add support to dump edc bist status for ECC data errors Signed-off-by: Hariprasad Shenai Signed-off-by: David S. Miller --- drivers/net/ethernet/chelsio/cxgb4/t4_hw.c | 39 ++++++++++++++++++++++++++++ drivers/net/ethernet/chelsio/cxgb4/t4_regs.h | 5 ++-- 2 files changed, 42 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c index 800bd489dd75..b19329519dd5 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c +++ b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c @@ -345,6 +345,43 @@ int t4_wr_mbox_meat(struct adapter *adap, int mbox, const void *cmd, int size, FW_CMD_MAX_TIMEOUT); } +static int t4_edc_err_read(struct adapter *adap, int idx) +{ + u32 edc_ecc_err_addr_reg; + u32 rdata_reg; + + if (is_t4(adap->params.chip)) { + CH_WARN(adap, "%s: T4 NOT supported.\n", __func__); + return 0; + } + if (idx != 0 && idx != 1) { + CH_WARN(adap, "%s: idx %d NOT supported.\n", __func__, idx); + return 0; + } + + edc_ecc_err_addr_reg = EDC_T5_REG(EDC_H_ECC_ERR_ADDR_A, idx); + rdata_reg = EDC_T5_REG(EDC_H_BIST_STATUS_RDATA_A, idx); + + CH_WARN(adap, + "edc%d err addr 0x%x: 0x%x.\n", + idx, edc_ecc_err_addr_reg, + t4_read_reg(adap, edc_ecc_err_addr_reg)); + CH_WARN(adap, + "bist: 0x%x, status %llx %llx %llx %llx %llx %llx %llx %llx %llx.\n", + rdata_reg, + (unsigned long long)t4_read_reg64(adap, rdata_reg), + (unsigned long long)t4_read_reg64(adap, rdata_reg + 8), + (unsigned long long)t4_read_reg64(adap, rdata_reg + 16), + (unsigned long long)t4_read_reg64(adap, rdata_reg + 24), + (unsigned long long)t4_read_reg64(adap, rdata_reg + 32), + (unsigned long long)t4_read_reg64(adap, rdata_reg + 40), + (unsigned long long)t4_read_reg64(adap, rdata_reg + 48), + (unsigned long long)t4_read_reg64(adap, rdata_reg + 56), + (unsigned long long)t4_read_reg64(adap, rdata_reg + 64)); + + return 0; +} + /** * t4_memory_rw - read/write EDC 0, EDC 1 or MC via PCIE memory window * @adap: the adapter @@ -3283,6 +3320,8 @@ static void mem_intr_handler(struct adapter *adapter, int idx) if (v & ECC_CE_INT_CAUSE_F) { u32 cnt = ECC_CECNT_G(t4_read_reg(adapter, cnt_addr)); + t4_edc_err_read(adapter, idx); + t4_write_reg(adapter, cnt_addr, ECC_CECNT_V(ECC_CECNT_M)); if (printk_ratelimit()) dev_warn(adapter->pdev_dev, diff --git a/drivers/net/ethernet/chelsio/cxgb4/t4_regs.h b/drivers/net/ethernet/chelsio/cxgb4/t4_regs.h index 06268681a279..13ce018a79ad 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/t4_regs.h +++ b/drivers/net/ethernet/chelsio/cxgb4/t4_regs.h @@ -2867,10 +2867,11 @@ #define EDC_H_BIST_DATA_PATTERN_A 0x50010 #define EDC_H_BIST_STATUS_RDATA_A 0x50028 +#define EDC_H_ECC_ERR_ADDR_A 0x50084 #define EDC_T51_BASE_ADDR 0x50800 -#define EDC_STRIDE_T5 (EDC_T51_BASE_ADDR - EDC_T50_BASE_ADDR) -#define EDC_REG_T5(reg, idx) (reg + EDC_STRIDE_T5 * idx) +#define EDC_T5_STRIDE (EDC_T51_BASE_ADDR - EDC_T50_BASE_ADDR) +#define EDC_T5_REG(reg, idx) (reg + EDC_T5_STRIDE * idx) #define PL_VF_REV_A 0x4 #define PL_VF_WHOAMI_A 0x0 -- cgit v1.2.3 From d86bd29e0b31f30d5d85ab21385b59703ecc6464 Mon Sep 17 00:00:00 2001 From: Hariprasad Shenai Date: Tue, 4 Aug 2015 14:36:19 +0530 Subject: cxgb4/cxgb4vf: read the correct bits of PL Who Am I register Read the correct bits of PL Who Am I for the Source PF field which has changed in T6 Signed-off-by: Hariprasad Shenai Signed-off-by: David S. Miller --- drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c | 34 ++++++++++++++++++++++++- drivers/net/ethernet/chelsio/cxgb4/t4_hw.c | 8 ++++-- drivers/net/ethernet/chelsio/cxgb4/t4_regs.h | 4 +++ drivers/net/ethernet/chelsio/cxgb4vf/t4vf_hw.c | 3 ++- 4 files changed, 45 insertions(+), 4 deletions(-) diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c index d582e175dfb6..27e87b6baa45 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c +++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c @@ -4551,6 +4551,32 @@ static void free_some_resources(struct adapter *adapter) NETIF_F_IPV6_CSUM | NETIF_F_HIGHDMA) #define SEGMENT_SIZE 128 +static int get_chip_type(struct pci_dev *pdev, u32 pl_rev) +{ + int ver, chip; + u16 device_id; + + /* Retrieve adapter's device ID */ + pci_read_config_word(pdev, PCI_DEVICE_ID, &device_id); + ver = device_id >> 12; + switch (ver) { + case CHELSIO_T4: + chip |= CHELSIO_CHIP_CODE(CHELSIO_T4, pl_rev); + break; + case CHELSIO_T5: + chip |= CHELSIO_CHIP_CODE(CHELSIO_T5, pl_rev); + break; + case CHELSIO_T6: + chip |= CHELSIO_CHIP_CODE(CHELSIO_T6, pl_rev); + break; + default: + dev_err(&pdev->dev, "Device %d is not supported\n", + device_id); + return -EINVAL; + } + return chip; +} + static int init_one(struct pci_dev *pdev, const struct pci_device_id *ent) { int func, i, err, s_qpp, qpp, num_seg; @@ -4558,6 +4584,8 @@ static int init_one(struct pci_dev *pdev, const struct pci_device_id *ent) bool highdma = false; struct adapter *adapter = NULL; void __iomem *regs; + u32 whoami, pl_rev; + enum chip_type chip; printk_once(KERN_INFO "%s - version %s\n", DRV_DESC, DRV_VERSION); @@ -4586,7 +4614,11 @@ static int init_one(struct pci_dev *pdev, const struct pci_device_id *ent) goto out_unmap_bar0; /* We control everything through one PF */ - func = SOURCEPF_G(readl(regs + PL_WHOAMI_A)); + whoami = readl(regs + PL_WHOAMI_A); + pl_rev = REV_G(readl(regs + PL_REV_A)); + chip = get_chip_type(pdev, pl_rev); + func = CHELSIO_CHIP_VERSION(chip) <= CHELSIO_T5 ? + SOURCEPF_G(whoami) : T6_SOURCEPF_G(whoami); if (func != ent->driver_data) { iounmap(regs); pci_disable_device(pdev); diff --git a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c index b19329519dd5..5c63ceb463d6 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c +++ b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c @@ -3529,7 +3529,9 @@ int t4_slow_intr_handler(struct adapter *adapter) void t4_intr_enable(struct adapter *adapter) { u32 val = 0; - u32 pf = SOURCEPF_G(t4_read_reg(adapter, PL_WHOAMI_A)); + u32 whoami = t4_read_reg(adapter, PL_WHOAMI_A); + u32 pf = CHELSIO_CHIP_VERSION(adapter->params.chip) <= CHELSIO_T5 ? + SOURCEPF_G(whoami) : T6_SOURCEPF_G(whoami); if (CHELSIO_CHIP_VERSION(adapter->params.chip) <= CHELSIO_T5) val = ERR_DROPPED_DB_F | ERR_EGR_CTXT_PRIO_F | DBFIFO_HP_INT_F; @@ -3554,7 +3556,9 @@ void t4_intr_enable(struct adapter *adapter) */ void t4_intr_disable(struct adapter *adapter) { - u32 pf = SOURCEPF_G(t4_read_reg(adapter, PL_WHOAMI_A)); + u32 whoami = t4_read_reg(adapter, PL_WHOAMI_A); + u32 pf = CHELSIO_CHIP_VERSION(adapter->params.chip) <= CHELSIO_T5 ? + SOURCEPF_G(whoami) : T6_SOURCEPF_G(whoami); t4_write_reg(adapter, MYPF_REG(PL_PF_INT_ENABLE_A), 0); t4_set_reg_field(adapter, PL_INT_MAP0_A, 1 << pf, 0); diff --git a/drivers/net/ethernet/chelsio/cxgb4/t4_regs.h b/drivers/net/ethernet/chelsio/cxgb4/t4_regs.h index 13ce018a79ad..e444dc4ebbd8 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/t4_regs.h +++ b/drivers/net/ethernet/chelsio/cxgb4/t4_regs.h @@ -2588,6 +2588,10 @@ #define SOURCEPF_M 0x7U #define SOURCEPF_G(x) (((x) >> SOURCEPF_S) & SOURCEPF_M) +#define T6_SOURCEPF_S 9 +#define T6_SOURCEPF_M 0x7U +#define T6_SOURCEPF_G(x) (((x) >> T6_SOURCEPF_S) & T6_SOURCEPF_M) + #define PL_INT_CAUSE_A 0x1940c #define ULP_TX_S 27 diff --git a/drivers/net/ethernet/chelsio/cxgb4vf/t4vf_hw.c b/drivers/net/ethernet/chelsio/cxgb4vf/t4vf_hw.c index 0db6dc9e9ed2..63dd5fdac5b9 100644 --- a/drivers/net/ethernet/chelsio/cxgb4vf/t4vf_hw.c +++ b/drivers/net/ethernet/chelsio/cxgb4vf/t4vf_hw.c @@ -619,7 +619,8 @@ int t4vf_get_sge_params(struct adapter *adapter) */ whoami = t4_read_reg(adapter, T4VF_PL_BASE_ADDR + PL_VF_WHOAMI_A); - pf = SOURCEPF_G(whoami); + pf = CHELSIO_CHIP_VERSION(adapter->params.chip) <= CHELSIO_T5 ? + SOURCEPF_G(whoami) : T6_SOURCEPF_G(whoami); s_hps = (HOSTPAGESIZEPF0_S + (HOSTPAGESIZEPF1_S - HOSTPAGESIZEPF0_S) * pf); -- cgit v1.2.3 From f109ff110b0f3e34cea45996734da485a2fdaa42 Mon Sep 17 00:00:00 2001 From: Hariprasad Shenai Date: Tue, 4 Aug 2015 14:36:20 +0530 Subject: cxgb4: Update T6 register ranges Signed-off-by: Hariprasad Shenai Signed-off-by: David S. Miller --- drivers/net/ethernet/chelsio/cxgb4/t4_hw.c | 26 ++++++++++++-------------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c index 5c63ceb463d6..91750ad580ae 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c +++ b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c @@ -1359,9 +1359,10 @@ void t4_get_regs(struct adapter *adap, void *buf, size_t buf_size) }; static const unsigned int t6_reg_ranges[] = { - 0x1008, 0x114c, + 0x1008, 0x1124, + 0x1138, 0x114c, 0x1180, 0x11b4, - 0x11fc, 0x1250, + 0x11fc, 0x1254, 0x1280, 0x133c, 0x1800, 0x18fc, 0x3000, 0x302c, @@ -1384,16 +1385,16 @@ void t4_get_regs(struct adapter *adap, void *buf, size_t buf_size) 0x5c10, 0x5ec0, 0x5ec8, 0x5ecc, 0x6000, 0x6040, - 0x6058, 0x615c, + 0x6058, 0x619c, 0x7700, 0x7798, 0x77c0, 0x7880, 0x78cc, 0x78fc, 0x7b00, 0x7c54, 0x7d00, 0x7efc, - 0x8dc0, 0x8de0, + 0x8dc0, 0x8de4, 0x8df8, 0x8e84, 0x8ea0, 0x8f88, - 0x8fb8, 0x911c, + 0x8fb8, 0x9124, 0x9400, 0x9470, 0x9600, 0x971c, 0x9800, 0x9808, @@ -1413,9 +1414,8 @@ void t4_get_regs(struct adapter *adap, void *buf, size_t buf_size) 0xdfc0, 0xdfe0, 0xe000, 0xf008, 0x11000, 0x11014, - 0x11048, 0x11110, - 0x11118, 0x1117c, - 0x11190, 0x11264, + 0x11048, 0x1117c, + 0x11190, 0x11270, 0x11300, 0x1130c, 0x12000, 0x1206c, 0x19040, 0x1906c, @@ -1500,9 +1500,8 @@ void t4_get_regs(struct adapter *adap, void *buf, size_t buf_size) 0x1ff00, 0x1ff84, 0x1ffc0, 0x1ffc8, 0x30000, 0x30070, - 0x30100, 0x3015c, - 0x30190, 0x301d0, - 0x30200, 0x30318, + 0x30100, 0x301d0, + 0x30200, 0x30320, 0x30400, 0x3052c, 0x30540, 0x3061c, 0x30800, 0x30890, @@ -1578,9 +1577,8 @@ void t4_get_regs(struct adapter *adap, void *buf, size_t buf_size) 0x33c24, 0x33c50, 0x33cf0, 0x33cfc, 0x34000, 0x34070, - 0x34100, 0x3415c, - 0x34190, 0x341d0, - 0x34200, 0x34318, + 0x34100, 0x341d0, + 0x34200, 0x34320, 0x34400, 0x3452c, 0x34540, 0x3461c, 0x34800, 0x34890, -- cgit v1.2.3