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

cxgb4: collect LE-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 8bff3685
......@@ -185,6 +185,36 @@ struct cudbg_vpd_data {
u32 vpd_vers;
};
#define CUDBG_MAX_TCAM_TID 0x800
enum cudbg_le_entry_types {
LE_ET_UNKNOWN = 0,
LE_ET_TCAM_CON = 1,
LE_ET_TCAM_SERVER = 2,
LE_ET_TCAM_FILTER = 3,
LE_ET_TCAM_CLIP = 4,
LE_ET_TCAM_ROUTING = 5,
LE_ET_HASH_CON = 6,
LE_ET_INVALID_TID = 8,
};
struct cudbg_tcam {
u32 filter_start;
u32 server_start;
u32 clip_start;
u32 routing_start;
u32 tid_hash_base;
u32 max_tid;
};
struct cudbg_tid_data {
u32 tid;
u32 dbig_cmd;
u32 dbig_conf;
u32 dbig_rsp_stat;
u32 data[NUM_LE_DB_DBGI_RSP_DATA_INSTANCES];
};
#define CUDBG_NUM_ULPTX 11
#define CUDBG_NUM_ULPTX_READ 512
......
......@@ -65,6 +65,7 @@ enum cudbg_dbg_entity_type {
CUDBG_TID_INFO = 54,
CUDBG_MPS_TCAM = 57,
CUDBG_VPD_DATA = 58,
CUDBG_LE_TCAM = 59,
CUDBG_CCTRL = 60,
CUDBG_MA_INDIRECT = 61,
CUDBG_ULPTX_LA = 62,
......
......@@ -1367,6 +1367,181 @@ int cudbg_collect_vpd_data(struct cudbg_init *pdbg_init,
return rc;
}
static int cudbg_read_tid(struct cudbg_init *pdbg_init, u32 tid,
struct cudbg_tid_data *tid_data)
{
struct adapter *padap = pdbg_init->adap;
int i, cmd_retry = 8;
u32 val;
/* Fill REQ_DATA regs with 0's */
for (i = 0; i < NUM_LE_DB_DBGI_REQ_DATA_INSTANCES; i++)
t4_write_reg(padap, LE_DB_DBGI_REQ_DATA_A + (i << 2), 0);
/* Write DBIG command */
val = DBGICMD_V(4) | DBGITID_V(tid);
t4_write_reg(padap, LE_DB_DBGI_REQ_TCAM_CMD_A, val);
tid_data->dbig_cmd = val;
val = DBGICMDSTRT_F | DBGICMDMODE_V(1); /* LE mode */
t4_write_reg(padap, LE_DB_DBGI_CONFIG_A, val);
tid_data->dbig_conf = val;
/* Poll the DBGICMDBUSY bit */
val = 1;
while (val) {
val = t4_read_reg(padap, LE_DB_DBGI_CONFIG_A);
val = val & DBGICMDBUSY_F;
cmd_retry--;
if (!cmd_retry)
return CUDBG_SYSTEM_ERROR;
}
/* Check RESP status */
val = t4_read_reg(padap, LE_DB_DBGI_RSP_STATUS_A);
tid_data->dbig_rsp_stat = val;
if (!(val & 1))
return CUDBG_SYSTEM_ERROR;
/* Read RESP data */
for (i = 0; i < NUM_LE_DB_DBGI_RSP_DATA_INSTANCES; i++)
tid_data->data[i] = t4_read_reg(padap,
LE_DB_DBGI_RSP_DATA_A +
(i << 2));
tid_data->tid = tid;
return 0;
}
static int cudbg_get_le_type(u32 tid, struct cudbg_tcam tcam_region)
{
int type = LE_ET_UNKNOWN;
if (tid < tcam_region.server_start)
type = LE_ET_TCAM_CON;
else if (tid < tcam_region.filter_start)
type = LE_ET_TCAM_SERVER;
else if (tid < tcam_region.clip_start)
type = LE_ET_TCAM_FILTER;
else if (tid < tcam_region.routing_start)
type = LE_ET_TCAM_CLIP;
else if (tid < tcam_region.tid_hash_base)
type = LE_ET_TCAM_ROUTING;
else if (tid < tcam_region.max_tid)
type = LE_ET_HASH_CON;
else
type = LE_ET_INVALID_TID;
return type;
}
static int cudbg_is_ipv6_entry(struct cudbg_tid_data *tid_data,
struct cudbg_tcam tcam_region)
{
int ipv6 = 0;
int le_type;
le_type = cudbg_get_le_type(tid_data->tid, tcam_region);
if (tid_data->tid & 1)
return 0;
if (le_type == LE_ET_HASH_CON) {
ipv6 = tid_data->data[16] & 0x8000;
} else if (le_type == LE_ET_TCAM_CON) {
ipv6 = tid_data->data[16] & 0x8000;
if (ipv6)
ipv6 = tid_data->data[9] == 0x00C00000;
} else {
ipv6 = 0;
}
return ipv6;
}
void cudbg_fill_le_tcam_info(struct adapter *padap,
struct cudbg_tcam *tcam_region)
{
u32 value;
/* Get the LE regions */
value = t4_read_reg(padap, LE_DB_TID_HASHBASE_A); /* hash base index */
tcam_region->tid_hash_base = value;
/* Get routing table index */
value = t4_read_reg(padap, LE_DB_ROUTING_TABLE_INDEX_A);
tcam_region->routing_start = value;
/*Get clip table index */
value = t4_read_reg(padap, LE_DB_CLIP_TABLE_INDEX_A);
tcam_region->clip_start = value;
/* Get filter table index */
value = t4_read_reg(padap, LE_DB_FILTER_TABLE_INDEX_A);
tcam_region->filter_start = value;
/* Get server table index */
value = t4_read_reg(padap, LE_DB_SERVER_INDEX_A);
tcam_region->server_start = value;
/* Check whether hash is enabled and calculate the max tids */
value = t4_read_reg(padap, LE_DB_CONFIG_A);
if ((value >> HASHEN_S) & 1) {
value = t4_read_reg(padap, LE_DB_HASH_CONFIG_A);
if (CHELSIO_CHIP_VERSION(padap->params.chip) > CHELSIO_T5) {
tcam_region->max_tid = (value & 0xFFFFF) +
tcam_region->tid_hash_base;
} else {
value = HASHTIDSIZE_G(value);
value = 1 << value;
tcam_region->max_tid = value +
tcam_region->tid_hash_base;
}
} else { /* hash not enabled */
tcam_region->max_tid = CUDBG_MAX_TCAM_TID;
}
}
int cudbg_collect_le_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 };
struct cudbg_tcam tcam_region = { 0 };
struct cudbg_tid_data *tid_data;
u32 bytes = 0;
int rc, size;
u32 i;
cudbg_fill_le_tcam_info(padap, &tcam_region);
size = sizeof(struct cudbg_tid_data) * tcam_region.max_tid;
size += sizeof(struct cudbg_tcam);
rc = cudbg_get_buff(dbg_buff, size, &temp_buff);
if (rc)
return rc;
memcpy(temp_buff.data, &tcam_region, sizeof(struct cudbg_tcam));
bytes = sizeof(struct cudbg_tcam);
tid_data = (struct cudbg_tid_data *)(temp_buff.data + bytes);
/* read all tid */
for (i = 0; i < tcam_region.max_tid; ) {
rc = cudbg_read_tid(pdbg_init, i, tid_data);
if (rc) {
cudbg_err->sys_err = rc;
cudbg_put_buff(&temp_buff, dbg_buff);
return rc;
}
/* ipv6 takes two tids */
cudbg_is_ipv6_entry(tid_data, tcam_region) ? i += 2 : i++;
tid_data++;
bytes += sizeof(struct cudbg_tid_data);
}
cudbg_write_and_release_buff(&temp_buff, dbg_buff);
return rc;
}
int cudbg_collect_cctrl(struct cudbg_init *pdbg_init,
struct cudbg_buffer *dbg_buff,
struct cudbg_error *cudbg_err)
......
......@@ -129,6 +129,9 @@ int cudbg_collect_mps_tcam(struct cudbg_init *pdbg_init,
int cudbg_collect_vpd_data(struct cudbg_init *pdbg_init,
struct cudbg_buffer *dbg_buff,
struct cudbg_error *cudbg_err);
int cudbg_collect_le_tcam(struct cudbg_init *pdbg_init,
struct cudbg_buffer *dbg_buff,
struct cudbg_error *cudbg_err);
int cudbg_collect_cctrl(struct cudbg_init *pdbg_init,
struct cudbg_buffer *dbg_buff,
struct cudbg_error *cudbg_err);
......@@ -155,4 +158,8 @@ struct cudbg_entity_hdr *cudbg_get_entity_hdr(void *outbuf, int i);
void cudbg_align_debug_buffer(struct cudbg_buffer *dbg_buff,
struct cudbg_entity_hdr *entity_hdr);
u32 cudbg_cim_obq_size(struct adapter *padap, int qid);
struct cudbg_tcam;
void cudbg_fill_le_tcam_info(struct adapter *padap,
struct cudbg_tcam *tcam_region);
#endif /* __CUDBG_LIB_H__ */
......@@ -62,6 +62,7 @@ static const struct cxgb4_collect_entity cxgb4_collect_hw_dump[] = {
{ CUDBG_TID_INFO, cudbg_collect_tid },
{ CUDBG_MPS_TCAM, cudbg_collect_mps_tcam },
{ CUDBG_VPD_DATA, cudbg_collect_vpd_data },
{ CUDBG_LE_TCAM, cudbg_collect_le_tcam },
{ CUDBG_CCTRL, cudbg_collect_cctrl },
{ CUDBG_MA_INDIRECT, cudbg_collect_ma_indirect },
{ CUDBG_ULPTX_LA, cudbg_collect_ulptx_la },
......@@ -72,6 +73,7 @@ static const struct cxgb4_collect_entity cxgb4_collect_hw_dump[] = {
static u32 cxgb4_get_entity_length(struct adapter *adap, u32 entity)
{
struct cudbg_tcam tcam_region = { 0 };
u32 value, n = 0, len = 0;
switch (entity) {
......@@ -223,6 +225,11 @@ static u32 cxgb4_get_entity_length(struct adapter *adap, u32 entity)
case CUDBG_VPD_DATA:
len = sizeof(struct cudbg_vpd_data);
break;
case CUDBG_LE_TCAM:
cudbg_fill_le_tcam_info(adap, &tcam_region);
len = sizeof(struct cudbg_tcam) +
sizeof(struct cudbg_tid_data) * tcam_region.max_tid;
break;
case CUDBG_CCTRL:
len = sizeof(u16) * NMTUS * NCCTRL_WIN;
break;
......
......@@ -65,6 +65,9 @@
#define PCIE_FW_REG(reg_addr, idx) ((reg_addr) + (idx) * 4)
#define NUM_LE_DB_DBGI_REQ_DATA_INSTANCES 17
#define NUM_LE_DB_DBGI_RSP_DATA_INSTANCES 17
#define SGE_PF_KDOORBELL_A 0x0
#define QID_S 15
......@@ -2273,6 +2276,35 @@
#define CHNENABLE_V(x) ((x) << CHNENABLE_S)
#define CHNENABLE_F CHNENABLE_V(1U)
#define LE_DB_DBGI_CONFIG_A 0x19cf0
#define DBGICMDBUSY_S 3
#define DBGICMDBUSY_V(x) ((x) << DBGICMDBUSY_S)
#define DBGICMDBUSY_F DBGICMDBUSY_V(1U)
#define DBGICMDSTRT_S 2
#define DBGICMDSTRT_V(x) ((x) << DBGICMDSTRT_S)
#define DBGICMDSTRT_F DBGICMDSTRT_V(1U)
#define DBGICMDMODE_S 0
#define DBGICMDMODE_M 0x3U
#define DBGICMDMODE_V(x) ((x) << DBGICMDMODE_S)
#define LE_DB_DBGI_REQ_TCAM_CMD_A 0x19cf4
#define DBGICMD_S 20
#define DBGICMD_M 0xfU
#define DBGICMD_V(x) ((x) << DBGICMD_S)
#define DBGITID_S 0
#define DBGITID_M 0xfffffU
#define DBGITID_V(x) ((x) << DBGITID_S)
#define LE_DB_DBGI_REQ_DATA_A 0x19d00
#define LE_DB_DBGI_RSP_STATUS_A 0x19d94
#define LE_DB_DBGI_RSP_DATA_A 0x19da0
#define PRTENABLE_S 29
#define PRTENABLE_V(x) ((x) << PRTENABLE_S)
#define PRTENABLE_F PRTENABLE_V(1U)
......@@ -2882,11 +2914,20 @@
#define T6_LIPMISS_F T6_LIPMISS_V(1U)
#define LE_DB_CONFIG_A 0x19c04
#define LE_DB_ROUTING_TABLE_INDEX_A 0x19c10
#define LE_DB_ACTIVE_TABLE_START_INDEX_A 0x19c10
#define LE_DB_FILTER_TABLE_INDEX_A 0x19c14
#define LE_DB_SERVER_INDEX_A 0x19c18
#define LE_DB_SRVR_START_INDEX_A 0x19c18
#define LE_DB_CLIP_TABLE_INDEX_A 0x19c1c
#define LE_DB_ACT_CNT_IPV4_A 0x19c20
#define LE_DB_ACT_CNT_IPV6_A 0x19c24
#define LE_DB_HASH_CONFIG_A 0x19c28
#define HASHTIDSIZE_S 16
#define HASHTIDSIZE_M 0x3fU
#define HASHTIDSIZE_G(x) (((x) >> HASHTIDSIZE_S) & HASHTIDSIZE_M)
#define LE_DB_HASH_TID_BASE_A 0x19c30
#define LE_DB_HASH_TBL_BASE_ADDR_A 0x19c30
#define LE_DB_INT_CAUSE_A 0x19c3c
......
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