Commit b289593e authored by Rahul Lakkireddy's avatar Rahul Lakkireddy Committed by David S. Miller

cxgb4: collect MPS-TCAM dump

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 9030e498
......@@ -114,6 +114,27 @@ struct cudbg_tid_info_region_rev1 {
u32 reserved[16];
};
#define CUDBG_MAX_RPLC_SIZE 128
struct cudbg_mps_tcam {
u64 mask;
u32 rplc[8];
u32 idx;
u32 cls_lo;
u32 cls_hi;
u32 rplc_size;
u32 vniy;
u32 vnix;
u32 dip_hit;
u32 vlan_vld;
u32 repli;
u16 ivlan;
u8 addr[ETH_ALEN];
u8 lookup_type;
u8 port_num;
u8 reserved[2];
};
#define CUDBG_NUM_ULPTX 11
#define CUDBG_NUM_ULPTX_READ 512
......
......@@ -58,6 +58,7 @@ enum cudbg_dbg_entity_type {
CUDBG_PCIE_INDIRECT = 50,
CUDBG_PM_INDIRECT = 51,
CUDBG_TID_INFO = 54,
CUDBG_MPS_TCAM = 57,
CUDBG_MA_INDIRECT = 61,
CUDBG_ULPTX_LA = 62,
CUDBG_UP_CIM_INDIRECT = 64,
......
......@@ -987,6 +987,190 @@ int cudbg_collect_tid(struct cudbg_init *pdbg_init,
return rc;
}
static inline void cudbg_tcamxy2valmask(u64 x, u64 y, u8 *addr, u64 *mask)
{
*mask = x | y;
y = (__force u64)cpu_to_be64(y);
memcpy(addr, (char *)&y + 2, ETH_ALEN);
}
static void cudbg_mps_rpl_backdoor(struct adapter *padap,
struct fw_ldst_mps_rplc *mps_rplc)
{
if (is_t5(padap->params.chip)) {
mps_rplc->rplc255_224 = htonl(t4_read_reg(padap,
MPS_VF_RPLCT_MAP3_A));
mps_rplc->rplc223_192 = htonl(t4_read_reg(padap,
MPS_VF_RPLCT_MAP2_A));
mps_rplc->rplc191_160 = htonl(t4_read_reg(padap,
MPS_VF_RPLCT_MAP1_A));
mps_rplc->rplc159_128 = htonl(t4_read_reg(padap,
MPS_VF_RPLCT_MAP0_A));
} else {
mps_rplc->rplc255_224 = htonl(t4_read_reg(padap,
MPS_VF_RPLCT_MAP7_A));
mps_rplc->rplc223_192 = htonl(t4_read_reg(padap,
MPS_VF_RPLCT_MAP6_A));
mps_rplc->rplc191_160 = htonl(t4_read_reg(padap,
MPS_VF_RPLCT_MAP5_A));
mps_rplc->rplc159_128 = htonl(t4_read_reg(padap,
MPS_VF_RPLCT_MAP4_A));
}
mps_rplc->rplc127_96 = htonl(t4_read_reg(padap, MPS_VF_RPLCT_MAP3_A));
mps_rplc->rplc95_64 = htonl(t4_read_reg(padap, MPS_VF_RPLCT_MAP2_A));
mps_rplc->rplc63_32 = htonl(t4_read_reg(padap, MPS_VF_RPLCT_MAP1_A));
mps_rplc->rplc31_0 = htonl(t4_read_reg(padap, MPS_VF_RPLCT_MAP0_A));
}
static int cudbg_collect_tcam_index(struct adapter *padap,
struct cudbg_mps_tcam *tcam, u32 idx)
{
u64 tcamy, tcamx, val;
u32 ctl, data2;
int rc = 0;
if (CHELSIO_CHIP_VERSION(padap->params.chip) >= CHELSIO_T6) {
/* CtlReqID - 1: use Host Driver Requester ID
* CtlCmdType - 0: Read, 1: Write
* CtlTcamSel - 0: TCAM0, 1: TCAM1
* CtlXYBitSel- 0: Y bit, 1: X bit
*/
/* Read tcamy */
ctl = CTLREQID_V(1) | CTLCMDTYPE_V(0) | CTLXYBITSEL_V(0);
if (idx < 256)
ctl |= CTLTCAMINDEX_V(idx) | CTLTCAMSEL_V(0);
else
ctl |= CTLTCAMINDEX_V(idx - 256) | CTLTCAMSEL_V(1);
t4_write_reg(padap, MPS_CLS_TCAM_DATA2_CTL_A, ctl);
val = t4_read_reg(padap, MPS_CLS_TCAM_RDATA1_REQ_ID1_A);
tcamy = DMACH_G(val) << 32;
tcamy |= t4_read_reg(padap, MPS_CLS_TCAM_RDATA0_REQ_ID1_A);
data2 = t4_read_reg(padap, MPS_CLS_TCAM_RDATA2_REQ_ID1_A);
tcam->lookup_type = DATALKPTYPE_G(data2);
/* 0 - Outer header, 1 - Inner header
* [71:48] bit locations are overloaded for
* outer vs. inner lookup types.
*/
if (tcam->lookup_type && tcam->lookup_type != DATALKPTYPE_M) {
/* Inner header VNI */
tcam->vniy = (data2 & DATAVIDH2_F) | DATAVIDH1_G(data2);
tcam->vniy = (tcam->vniy << 16) | VIDL_G(val);
tcam->dip_hit = data2 & DATADIPHIT_F;
} else {
tcam->vlan_vld = data2 & DATAVIDH2_F;
tcam->ivlan = VIDL_G(val);
}
tcam->port_num = DATAPORTNUM_G(data2);
/* Read tcamx. Change the control param */
ctl |= CTLXYBITSEL_V(1);
t4_write_reg(padap, MPS_CLS_TCAM_DATA2_CTL_A, ctl);
val = t4_read_reg(padap, MPS_CLS_TCAM_RDATA1_REQ_ID1_A);
tcamx = DMACH_G(val) << 32;
tcamx |= t4_read_reg(padap, MPS_CLS_TCAM_RDATA0_REQ_ID1_A);
data2 = t4_read_reg(padap, MPS_CLS_TCAM_RDATA2_REQ_ID1_A);
if (tcam->lookup_type && tcam->lookup_type != DATALKPTYPE_M) {
/* Inner header VNI mask */
tcam->vnix = (data2 & DATAVIDH2_F) | DATAVIDH1_G(data2);
tcam->vnix = (tcam->vnix << 16) | VIDL_G(val);
}
} else {
tcamy = t4_read_reg64(padap, MPS_CLS_TCAM_Y_L(idx));
tcamx = t4_read_reg64(padap, MPS_CLS_TCAM_X_L(idx));
}
/* If no entry, return */
if (tcamx & tcamy)
return rc;
tcam->cls_lo = t4_read_reg(padap, MPS_CLS_SRAM_L(idx));
tcam->cls_hi = t4_read_reg(padap, MPS_CLS_SRAM_H(idx));
if (is_t5(padap->params.chip))
tcam->repli = (tcam->cls_lo & REPLICATE_F);
else if (is_t6(padap->params.chip))
tcam->repli = (tcam->cls_lo & T6_REPLICATE_F);
if (tcam->repli) {
struct fw_ldst_cmd ldst_cmd;
struct fw_ldst_mps_rplc mps_rplc;
memset(&ldst_cmd, 0, sizeof(ldst_cmd));
ldst_cmd.op_to_addrspace =
htonl(FW_CMD_OP_V(FW_LDST_CMD) |
FW_CMD_REQUEST_F | FW_CMD_READ_F |
FW_LDST_CMD_ADDRSPACE_V(FW_LDST_ADDRSPC_MPS));
ldst_cmd.cycles_to_len16 = htonl(FW_LEN16(ldst_cmd));
ldst_cmd.u.mps.rplc.fid_idx =
htons(FW_LDST_CMD_FID_V(FW_LDST_MPS_RPLC) |
FW_LDST_CMD_IDX_V(idx));
rc = t4_wr_mbox(padap, padap->mbox, &ldst_cmd, sizeof(ldst_cmd),
&ldst_cmd);
if (rc)
cudbg_mps_rpl_backdoor(padap, &mps_rplc);
else
mps_rplc = ldst_cmd.u.mps.rplc;
tcam->rplc[0] = ntohl(mps_rplc.rplc31_0);
tcam->rplc[1] = ntohl(mps_rplc.rplc63_32);
tcam->rplc[2] = ntohl(mps_rplc.rplc95_64);
tcam->rplc[3] = ntohl(mps_rplc.rplc127_96);
if (padap->params.arch.mps_rplc_size > CUDBG_MAX_RPLC_SIZE) {
tcam->rplc[4] = ntohl(mps_rplc.rplc159_128);
tcam->rplc[5] = ntohl(mps_rplc.rplc191_160);
tcam->rplc[6] = ntohl(mps_rplc.rplc223_192);
tcam->rplc[7] = ntohl(mps_rplc.rplc255_224);
}
}
cudbg_tcamxy2valmask(tcamx, tcamy, tcam->addr, &tcam->mask);
tcam->idx = idx;
tcam->rplc_size = padap->params.arch.mps_rplc_size;
return rc;
}
int cudbg_collect_mps_tcam(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 };
u32 size = 0, i, n, total_size = 0;
struct cudbg_mps_tcam *tcam;
int rc;
n = padap->params.arch.mps_tcam_size;
size = sizeof(struct cudbg_mps_tcam) * n;
rc = cudbg_get_buff(dbg_buff, size, &temp_buff);
if (rc)
return rc;
tcam = (struct cudbg_mps_tcam *)temp_buff.data;
for (i = 0; i < n; i++) {
rc = cudbg_collect_tcam_index(padap, tcam, i);
if (rc) {
cudbg_err->sys_err = rc;
cudbg_put_buff(&temp_buff, dbg_buff);
return rc;
}
total_size += sizeof(struct cudbg_mps_tcam);
tcam++;
}
if (!total_size) {
rc = CUDBG_SYSTEM_ERROR;
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_ma_indirect(struct cudbg_init *pdbg_init,
struct cudbg_buffer *dbg_buff,
struct cudbg_error *cudbg_err)
......
......@@ -111,6 +111,9 @@ int cudbg_collect_pm_indirect(struct cudbg_init *pdbg_init,
int cudbg_collect_tid(struct cudbg_init *pdbg_init,
struct cudbg_buffer *dbg_buff,
struct cudbg_error *cudbg_err);
int cudbg_collect_mps_tcam(struct cudbg_init *pdbg_init,
struct cudbg_buffer *dbg_buff,
struct cudbg_error *cudbg_err);
int cudbg_collect_ma_indirect(struct cudbg_init *pdbg_init,
struct cudbg_buffer *dbg_buff,
struct cudbg_error *cudbg_err);
......
......@@ -56,6 +56,7 @@ static const struct cxgb4_collect_entity cxgb4_collect_hw_dump[] = {
{ CUDBG_PCIE_INDIRECT, cudbg_collect_pcie_indirect },
{ CUDBG_PM_INDIRECT, cudbg_collect_pm_indirect },
{ CUDBG_TID_INFO, cudbg_collect_tid },
{ CUDBG_MPS_TCAM, cudbg_collect_mps_tcam },
{ CUDBG_MA_INDIRECT, cudbg_collect_ma_indirect },
{ CUDBG_ULPTX_LA, cudbg_collect_ulptx_la },
{ CUDBG_UP_CIM_INDIRECT, cudbg_collect_up_cim_indirect },
......@@ -196,6 +197,10 @@ static u32 cxgb4_get_entity_length(struct adapter *adap, u32 entity)
case CUDBG_TID_INFO:
len = sizeof(struct cudbg_tid_info_region_rev1);
break;
case CUDBG_MPS_TCAM:
len = sizeof(struct cudbg_mps_tcam) *
adap->params.arch.mps_tcam_size;
break;
case CUDBG_MA_INDIRECT:
if (CHELSIO_CHIP_VERSION(adap->params.chip) > CHELSIO_T5) {
n = sizeof(t6_ma_ireg_array) /
......
......@@ -2439,6 +2439,18 @@
#define MPS_CLS_TCAM_DATA0_A 0xf000
#define MPS_CLS_TCAM_DATA1_A 0xf004
#define CTLREQID_S 30
#define CTLREQID_V(x) ((x) << CTLREQID_S)
#define MPS_VF_RPLCT_MAP0_A 0x1111c
#define MPS_VF_RPLCT_MAP1_A 0x11120
#define MPS_VF_RPLCT_MAP2_A 0x11124
#define MPS_VF_RPLCT_MAP3_A 0x11128
#define MPS_VF_RPLCT_MAP4_A 0x11300
#define MPS_VF_RPLCT_MAP5_A 0x11304
#define MPS_VF_RPLCT_MAP6_A 0x11308
#define MPS_VF_RPLCT_MAP7_A 0x1130c
#define VIDL_S 16
#define VIDL_M 0xffffU
#define VIDL_G(x) (((x) >> VIDL_S) & VIDL_M)
......@@ -2463,6 +2475,10 @@
#define DATAVIDH1_M 0x7fU
#define DATAVIDH1_G(x) (((x) >> DATAVIDH1_S) & DATAVIDH1_M)
#define MPS_CLS_TCAM_RDATA0_REQ_ID1_A 0xf020
#define MPS_CLS_TCAM_RDATA1_REQ_ID1_A 0xf024
#define MPS_CLS_TCAM_RDATA2_REQ_ID1_A 0xf028
#define USED_S 16
#define USED_M 0x7ffU
#define USED_G(x) (((x) >> USED_S) & USED_M)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment