From: Satheesh Paul Date: Wed, 23 Jun 2021 04:46:03 +0000 (+0530) Subject: common/cnxk: support flow entry dump X-Git-Url: http://git.droids-corp.org/?a=commitdiff_plain;h=9869c39918a07e129711b9f62093dcbbf1cda167;p=dpdk.git common/cnxk: support flow entry dump Add NPC support API to dump created flow entries. Signed-off-by: Satheesh Paul Signed-off-by: Kiran Kumar K --- diff --git a/drivers/common/cnxk/hw/npc.h b/drivers/common/cnxk/hw/npc.h index e0f06bf0e7..68c5037e1c 100644 --- a/drivers/common/cnxk/hw/npc.h +++ b/drivers/common/cnxk/hw/npc.h @@ -193,6 +193,7 @@ enum npc_kpu_lb_ltype { NPC_LT_LB_EXDSA, NPC_LT_LB_EXDSA_VLAN, NPC_LT_LB_FDSA, + NPC_LT_LB_VLAN_EXDSA, NPC_LT_LB_CUSTOM0 = 0xE, NPC_LT_LB_CUSTOM1 = 0xF, }; @@ -208,6 +209,7 @@ enum npc_kpu_lc_ltype { NPC_LT_LC_MPLS, NPC_LT_LC_NSH, NPC_LT_LC_FCOE, + NPC_LT_LC_NGIO, NPC_LT_LC_CUSTOM0 = 0xE, NPC_LT_LC_CUSTOM1 = 0xF, }; diff --git a/drivers/common/cnxk/meson.build b/drivers/common/cnxk/meson.build index c0ec54932b..31ae5cfbf3 100644 --- a/drivers/common/cnxk/meson.build +++ b/drivers/common/cnxk/meson.build @@ -40,6 +40,7 @@ sources = files( 'roc_npa_irq.c', 'roc_npc.c', 'roc_npc_mcam.c', + 'roc_npc_mcam_dump.c', 'roc_npc_parse.c', 'roc_npc_utils.c', 'roc_platform.c', diff --git a/drivers/common/cnxk/roc_npc.c b/drivers/common/cnxk/roc_npc.c index abaef7768d..81c7fd939e 100644 --- a/drivers/common/cnxk/roc_npc.c +++ b/drivers/common/cnxk/roc_npc.c @@ -870,3 +870,23 @@ roc_npc_flow_destroy(struct roc_npc *roc_npc, struct roc_npc_flow *flow) plt_free(flow); return 0; } + +void +roc_npc_flow_dump(FILE *file, struct roc_npc *roc_npc) +{ + struct npc *npc = roc_npc_to_npc_priv(roc_npc); + struct roc_npc_flow *flow_iter; + struct npc_flow_list *list; + uint32_t max_prio, i; + + max_prio = npc->flow_max_priority; + + for (i = 0; i < max_prio; i++) { + list = &npc->flow_list[i]; + + /* List in ascending order of mcam entries */ + TAILQ_FOREACH(flow_iter, list, next) { + roc_npc_flow_mcam_dump(file, roc_npc, flow_iter); + } + } +} diff --git a/drivers/common/cnxk/roc_npc.h b/drivers/common/cnxk/roc_npc.h index 223c4ba40f..115bcd5f29 100644 --- a/drivers/common/cnxk/roc_npc.h +++ b/drivers/common/cnxk/roc_npc.h @@ -90,6 +90,11 @@ struct roc_npc_attr { uint32_t reserved : 30; /**< Reserved, must be zero. */ }; +struct roc_npc_flow_dump_data { + uint8_t lid; + uint16_t ltype; +}; + struct roc_npc_flow { uint8_t nix_intf; uint8_t enable; @@ -102,6 +107,9 @@ struct roc_npc_flow { uint64_t mcam_mask[ROC_NPC_MAX_MCAM_WIDTH_DWORDS]; uint64_t npc_action; uint64_t vtag_action; +#define ROC_NPC_MAX_FLOW_PATTERNS 32 + struct roc_npc_flow_dump_data dump_data[ROC_NPC_MAX_FLOW_PATTERNS]; + uint16_t num_patterns; TAILQ_ENTRY(roc_npc_flow) next; }; @@ -185,5 +193,7 @@ int __roc_api roc_npc_mcam_clear_counter(struct roc_npc *roc_npc, uint32_t ctr_id); int __roc_api roc_npc_mcam_free_all_resources(struct roc_npc *roc_npc); - +void __roc_api roc_npc_flow_dump(FILE *file, struct roc_npc *roc_npc); +void __roc_api roc_npc_flow_mcam_dump(FILE *file, struct roc_npc *roc_npc, + struct roc_npc_flow *mcam); #endif /* _ROC_NPC_H_ */ diff --git a/drivers/common/cnxk/roc_npc_mcam_dump.c b/drivers/common/cnxk/roc_npc_mcam_dump.c new file mode 100644 index 0000000000..19b4901a52 --- /dev/null +++ b/drivers/common/cnxk/roc_npc_mcam_dump.c @@ -0,0 +1,611 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(C) 2021 Marvell. + */ + +#include "roc_api.h" +#include "roc_priv.h" + +#define NPC_MAX_FIELD_NAME_SIZE 80 +#define NPC_RX_ACTIONOP_MASK GENMASK(3, 0) +#define NPC_RX_ACTION_PFFUNC_MASK GENMASK(19, 4) +#define NPC_RX_ACTION_INDEX_MASK GENMASK(39, 20) +#define NPC_RX_ACTION_MATCH_MASK GENMASK(55, 40) +#define NPC_RX_ACTION_FLOWKEY_MASK GENMASK(60, 56) + +#define NPC_TX_ACTION_INDEX_MASK GENMASK(31, 12) +#define NPC_TX_ACTION_MATCH_MASK GENMASK(47, 32) + +#define NIX_RX_VTAGACT_VTAG0_RELPTR_MASK GENMASK(7, 0) +#define NIX_RX_VTAGACT_VTAG0_LID_MASK GENMASK(10, 8) +#define NIX_RX_VTAGACT_VTAG0_TYPE_MASK GENMASK(14, 12) +#define NIX_RX_VTAGACT_VTAG0_VALID_MASK BIT_ULL(15) + +#define NIX_RX_VTAGACT_VTAG1_RELPTR_MASK GENMASK(39, 32) +#define NIX_RX_VTAGACT_VTAG1_LID_MASK GENMASK(42, 40) +#define NIX_RX_VTAGACT_VTAG1_TYPE_MASK GENMASK(46, 44) +#define NIX_RX_VTAGACT_VTAG1_VALID_MASK BIT_ULL(47) + +#define NIX_TX_VTAGACT_VTAG0_RELPTR_MASK GENMASK(7, 0) +#define NIX_TX_VTAGACT_VTAG0_LID_MASK GENMASK(10, 8) +#define NIX_TX_VTAGACT_VTAG0_OP_MASK GENMASK(13, 12) +#define NIX_TX_VTAGACT_VTAG0_DEF_MASK GENMASK(25, 16) + +#define NIX_TX_VTAGACT_VTAG1_RELPTR_MASK GENMASK(39, 32) +#define NIX_TX_VTAGACT_VTAG1_LID_MASK GENMASK(42, 40) +#define NIX_TX_VTAGACT_VTAG1_OP_MASK GENMASK(45, 44) +#define NIX_TX_VTAGACT_VTAG1_DEF_MASK GENMASK(57, 48) + +struct npc_rx_parse_nibble_s { + uint16_t chan : 3; + uint16_t errlev : 1; + uint16_t errcode : 2; + uint16_t l2l3bm : 1; + uint16_t laflags : 2; + uint16_t latype : 1; + uint16_t lbflags : 2; + uint16_t lbtype : 1; + uint16_t lcflags : 2; + uint16_t lctype : 1; + uint16_t ldflags : 2; + uint16_t ldtype : 1; + uint16_t leflags : 2; + uint16_t letype : 1; + uint16_t lfflags : 2; + uint16_t lftype : 1; + uint16_t lgflags : 2; + uint16_t lgtype : 1; + uint16_t lhflags : 2; + uint16_t lhtype : 1; +} __plt_packed; + +static const char *const intf_str[] = { + "NIX-RX", + "NIX-TX", +}; + +static const char *const ltype_str[NPC_MAX_LID][NPC_MAX_LT] = { + [NPC_LID_LA][0] = "NONE", + [NPC_LID_LA][NPC_LT_LA_ETHER] = "LA_ETHER", + [NPC_LID_LA][NPC_LT_LA_IH_NIX_ETHER] = "LA_IH_NIX_ETHER", + [NPC_LID_LA][NPC_LT_LA_HIGIG2_ETHER] = "LA_HIGIG2_ETHER", + [NPC_LID_LA][NPC_LT_LA_IH_NIX_HIGIG2_ETHER] = "LA_IH_NIX_HIGIG2_ETHER", + [NPC_LID_LB][0] = "NONE", + [NPC_LID_LB][NPC_LT_LB_CTAG] = "LB_CTAG", + [NPC_LID_LB][NPC_LT_LB_STAG_QINQ] = "LB_STAG_QINQ", + [NPC_LID_LB][NPC_LT_LB_ETAG] = "LB_ETAG", + [NPC_LID_LB][NPC_LT_LB_EXDSA] = "LB_EXDSA", + [NPC_LID_LB][NPC_LT_LB_VLAN_EXDSA] = "LB_VLAN_EXDSA", + [NPC_LID_LC][0] = "NONE", + [NPC_LID_LC][NPC_LT_LC_IP] = "LC_IP", + [NPC_LID_LC][NPC_LT_LC_IP6] = "LC_IP6", + [NPC_LID_LC][NPC_LT_LC_ARP] = "LC_ARP", + [NPC_LID_LC][NPC_LT_LC_IP6_EXT] = "LC_IP6_EXT", + [NPC_LID_LC][NPC_LT_LC_NGIO] = "LC_NGIO", + [NPC_LID_LD][0] = "NONE", + [NPC_LID_LD][NPC_LT_LD_ICMP] = "LD_ICMP", + [NPC_LID_LD][NPC_LT_LD_ICMP6] = "LD_ICMP6", + [NPC_LID_LD][NPC_LT_LD_UDP] = "LD_UDP", + [NPC_LID_LD][NPC_LT_LD_TCP] = "LD_TCP", + [NPC_LID_LD][NPC_LT_LD_SCTP] = "LD_SCTP", + [NPC_LID_LD][NPC_LT_LD_GRE] = "LD_GRE", + [NPC_LID_LD][NPC_LT_LD_NVGRE] = "LD_NVGRE", + [NPC_LID_LE][0] = "NONE", + [NPC_LID_LE][NPC_LT_LE_VXLAN] = "LE_VXLAN", + [NPC_LID_LE][NPC_LT_LE_ESP] = "LE_ESP", + [NPC_LID_LE][NPC_LT_LE_GTPC] = "LE_GTPC", + [NPC_LID_LE][NPC_LT_LE_GTPU] = "LE_GTPU", + [NPC_LID_LE][NPC_LT_LE_GENEVE] = "LE_GENEVE", + [NPC_LID_LE][NPC_LT_LE_VXLANGPE] = "LE_VXLANGPE", + [NPC_LID_LF][0] = "NONE", + [NPC_LID_LF][NPC_LT_LF_TU_ETHER] = "LF_TU_ETHER", + [NPC_LID_LG][0] = "NONE", + [NPC_LID_LG][NPC_LT_LG_TU_IP] = "LG_TU_IP", + [NPC_LID_LG][NPC_LT_LG_TU_IP6] = "LG_TU_IP6", + [NPC_LID_LH][0] = "NONE", + [NPC_LID_LH][NPC_LT_LH_TU_UDP] = "LH_TU_UDP", + [NPC_LID_LH][NPC_LT_LH_TU_TCP] = "LH_TU_TCP", + [NPC_LID_LH][NPC_LT_LH_TU_SCTP] = "LH_TU_SCTP", + [NPC_LID_LH][NPC_LT_LH_TU_ESP] = "LH_TU_ESP", +}; + +static uint16_t +npc_get_nibbles(struct roc_npc_flow *flow, uint16_t size, uint32_t bit_offset) +{ + uint32_t byte_index, noffset; + uint16_t data, mask; + uint8_t *bytes; + + bytes = (uint8_t *)flow->mcam_data; + mask = (1ULL << (size * 4)) - 1; + byte_index = bit_offset / 8; + noffset = bit_offset % 8; + data = *(unaligned_uint16_t *)&bytes[byte_index]; + data >>= noffset; + data &= mask; + + return data; +} + +static void +npc_flow_print_parse_nibbles(FILE *file, struct roc_npc_flow *flow, + uint64_t parse_nibbles) +{ + struct npc_rx_parse_nibble_s *rx_parse; + uint32_t data, offset = 0; + + rx_parse = (struct npc_rx_parse_nibble_s *)&parse_nibbles; + + if (rx_parse->chan) { + data = npc_get_nibbles(flow, 3, offset); + fprintf(file, "\tNPC_PARSE_NIBBLE_CHAN:%#03X\n", data); + offset += 12; + } + + if (rx_parse->errlev) { + data = npc_get_nibbles(flow, 1, offset); + fprintf(file, "\tNPC_PARSE_NIBBLE_ERRLEV:%#X\n", data); + offset += 4; + } + + if (rx_parse->errcode) { + data = npc_get_nibbles(flow, 2, offset); + fprintf(file, "\tNPC_PARSE_NIBBLE_ERRCODE:%#02X\n", data); + offset += 8; + } + + if (rx_parse->l2l3bm) { + data = npc_get_nibbles(flow, 1, offset); + fprintf(file, "\tNPC_PARSE_NIBBLE_L2L3_BCAST:%#X\n", data); + offset += 4; + } + + if (rx_parse->latype) { + data = npc_get_nibbles(flow, 1, offset); + fprintf(file, "\tNPC_PARSE_NIBBLE_LA_LTYPE:%s\n", + ltype_str[NPC_LID_LA][data]); + offset += 4; + } + + if (rx_parse->laflags) { + data = npc_get_nibbles(flow, 2, offset); + fprintf(file, "\tNPC_PARSE_NIBBLE_LA_FLAGS:%#02X\n", data); + offset += 8; + } + + if (rx_parse->lbtype) { + data = npc_get_nibbles(flow, 1, offset); + fprintf(file, "\tNPC_PARSE_NIBBLE_LB_LTYPE:%s\n", + ltype_str[NPC_LID_LB][data]); + offset += 4; + } + + if (rx_parse->lbflags) { + data = npc_get_nibbles(flow, 2, offset); + fprintf(file, "\tNPC_PARSE_NIBBLE_LB_FLAGS:%#02X\n", data); + offset += 8; + } + + if (rx_parse->lctype) { + data = npc_get_nibbles(flow, 1, offset); + fprintf(file, "\tNPC_PARSE_NIBBLE_LC_LTYPE:%s\n", + ltype_str[NPC_LID_LC][data]); + offset += 4; + } + + if (rx_parse->lcflags) { + data = npc_get_nibbles(flow, 2, offset); + fprintf(file, "\tNPC_PARSE_NIBBLE_LC_FLAGS:%#02X\n", data); + offset += 8; + } + + if (rx_parse->ldtype) { + data = npc_get_nibbles(flow, 1, offset); + fprintf(file, "\tNPC_PARSE_NIBBLE_LD_LTYPE:%s\n", + ltype_str[NPC_LID_LD][data]); + offset += 4; + } + + if (rx_parse->ldflags) { + data = npc_get_nibbles(flow, 2, offset); + fprintf(file, "\tNPC_PARSE_NIBBLE_LD_FLAGS:%#02X\n", data); + offset += 8; + } + + if (rx_parse->letype) { + data = npc_get_nibbles(flow, 1, offset); + fprintf(file, "\tNPC_PARSE_NIBBLE_LE_LTYPE:%s\n", + ltype_str[NPC_LID_LE][data]); + offset += 4; + } + + if (rx_parse->leflags) { + data = npc_get_nibbles(flow, 2, offset); + fprintf(file, "\tNPC_PARSE_NIBBLE_LE_FLAGS:%#02X\n", data); + offset += 8; + } + + if (rx_parse->lftype) { + data = npc_get_nibbles(flow, 1, offset); + fprintf(file, "\tNPC_PARSE_NIBBLE_LF_LTYPE:%s\n", + ltype_str[NPC_LID_LF][data]); + offset += 4; + } + + if (rx_parse->lfflags) { + data = npc_get_nibbles(flow, 2, offset); + fprintf(file, "\tNPC_PARSE_NIBBLE_LF_FLAGS:%#02X\n", data); + offset += 8; + } + + if (rx_parse->lgtype) { + data = npc_get_nibbles(flow, 1, offset); + fprintf(file, "\tNPC_PARSE_NIBBLE_LG_LTYPE:%s\n", + ltype_str[NPC_LID_LG][data]); + offset += 4; + } + + if (rx_parse->lgflags) { + data = npc_get_nibbles(flow, 2, offset); + fprintf(file, "\tNPC_PARSE_NIBBLE_LG_FLAGS:%#02X\n", data); + offset += 8; + } + + if (rx_parse->lhtype) { + data = npc_get_nibbles(flow, 1, offset); + fprintf(file, "\tNPC_PARSE_NIBBLE_LH_LTYPE:%s\n", + ltype_str[NPC_LID_LH][data]); + offset += 4; + } + + if (rx_parse->lhflags) { + data = npc_get_nibbles(flow, 2, offset); + fprintf(file, "\tNPC_PARSE_NIBBLE_LH_FLAGS:%#02X\n", data); + } +} + +static void +npc_flow_print_xtractinfo(FILE *file, struct npc_xtract_info *lfinfo, + struct roc_npc_flow *flow, int lid, int lt) +{ + uint8_t *datastart, *maskstart; + int i; + + datastart = (uint8_t *)&flow->mcam_data + lfinfo->key_off; + maskstart = (uint8_t *)&flow->mcam_mask + lfinfo->key_off; + + fprintf(file, "\t%s, hdr offset:%#X, len:%#X, key offset:%#X, ", + ltype_str[lid][lt], lfinfo->hdr_off, lfinfo->len, + lfinfo->key_off); + + fprintf(file, "Data:0X"); + for (i = lfinfo->len - 1; i >= 0; i--) + fprintf(file, "%02X", datastart[i]); + + fprintf(file, ", Mask:0X"); + + for (i = lfinfo->len - 1; i >= 0; i--) + fprintf(file, "%02X", maskstart[i]); + + fprintf(file, "\n"); +} + +static void +npc_flow_print_item(FILE *file, struct npc *npc, struct npc_xtract_info *xinfo, + struct roc_npc_flow *flow, int intf, int lid, int lt, + int ld) +{ + struct npc_xtract_info *lflags_info; + int i, lf_cfg = 0; + + npc_flow_print_xtractinfo(file, xinfo, flow, lid, lt); + + if (xinfo->flags_enable) { + lf_cfg = npc->prx_lfcfg[ld].i; + + if (lf_cfg != lid) + return; + + for (i = 0; i < NPC_MAX_LFL; i++) { + lflags_info = npc->prx_fxcfg[intf][ld][i].xtract; + + npc_flow_print_xtractinfo(file, lflags_info, flow, lid, + lt); + } + } +} + +static void +npc_flow_dump_patterns(FILE *file, struct npc *npc, struct roc_npc_flow *flow) +{ + struct npc_lid_lt_xtract_info *lt_xinfo; + struct npc_xtract_info *xinfo; + uint32_t intf, lid, ld, i; + uint64_t parse_nibbles; + uint16_t ltype; + + intf = flow->nix_intf; + parse_nibbles = npc->keyx_supp_nmask[intf]; + npc_flow_print_parse_nibbles(file, flow, parse_nibbles); + + for (i = 0; i < flow->num_patterns; i++) { + lid = flow->dump_data[i].lid; + ltype = flow->dump_data[i].ltype; + lt_xinfo = &npc->prx_dxcfg[intf][lid][ltype]; + + for (ld = 0; ld < NPC_MAX_LD; ld++) { + xinfo = <_xinfo->xtract[ld]; + if (!xinfo->enable) + continue; + npc_flow_print_item(file, npc, xinfo, flow, intf, lid, + ltype, ld); + } + } +} + +static void +npc_flow_dump_tx_action(FILE *file, uint64_t npc_action) +{ + char index_name[NPC_MAX_FIELD_NAME_SIZE] = "Index:"; + uint32_t tx_op, index, match_id; + + tx_op = npc_action & NPC_RX_ACTIONOP_MASK; + + fprintf(file, "\tActionOp:"); + + switch (tx_op) { + case NIX_TX_ACTIONOP_DROP: + fprintf(file, "NIX_TX_ACTIONOP_DROP (%" PRIu64 ")\n", + (uint64_t)NIX_RX_ACTIONOP_DROP); + break; + case NIX_TX_ACTIONOP_UCAST_DEFAULT: + fprintf(file, "NIX_TX_ACTIONOP_UCAST_DEFAULT (%" PRIu64 ")\n", + (uint64_t)NIX_TX_ACTIONOP_UCAST_DEFAULT); + break; + case NIX_TX_ACTIONOP_UCAST_CHAN: + fprintf(file, "NIX_TX_ACTIONOP_UCAST_DEFAULT (%" PRIu64 ")\n", + (uint64_t)NIX_TX_ACTIONOP_UCAST_CHAN); + plt_strlcpy(index_name, + "Transmit Channel:", NPC_MAX_FIELD_NAME_SIZE); + break; + case NIX_TX_ACTIONOP_MCAST: + fprintf(file, "NIX_TX_ACTIONOP_MCAST (%" PRIu64 ")\n", + (uint64_t)NIX_TX_ACTIONOP_MCAST); + plt_strlcpy(index_name, + "Multicast Table Index:", NPC_MAX_FIELD_NAME_SIZE); + break; + case NIX_TX_ACTIONOP_DROP_VIOL: + fprintf(file, "NIX_TX_ACTIONOP_DROP_VIOL (%" PRIu64 ")\n", + (uint64_t)NIX_TX_ACTIONOP_DROP_VIOL); + break; + default: + plt_err("Unknown NIX_TX_ACTIONOP found"); + return; + } + + index = ((npc_action & NPC_TX_ACTION_INDEX_MASK) >> 12) & + GENMASK(19, 0); + + fprintf(file, "\t%s:%#05X\n", index_name, index); + + match_id = ((npc_action & NPC_TX_ACTION_MATCH_MASK) >> 32) & + GENMASK(15, 0); + + fprintf(file, "\tMatch Id:%#04X\n", match_id); +} + +static void +npc_flow_dump_rx_action(FILE *file, uint64_t npc_action) +{ + uint32_t rx_op, pf_func, index, match_id, flowkey_alg; + char index_name[NPC_MAX_FIELD_NAME_SIZE] = "Index:"; + + rx_op = npc_action & NPC_RX_ACTIONOP_MASK; + + fprintf(file, "\tActionOp:"); + + switch (rx_op) { + case NIX_RX_ACTIONOP_DROP: + fprintf(file, "NIX_RX_ACTIONOP_DROP (%" PRIu64 ")\n", + (uint64_t)NIX_RX_ACTIONOP_DROP); + break; + case NIX_RX_ACTIONOP_UCAST: + fprintf(file, "NIX_RX_ACTIONOP_UCAST (%" PRIu64 ")\n", + (uint64_t)NIX_RX_ACTIONOP_UCAST); + plt_strlcpy(index_name, "RQ Index", NPC_MAX_FIELD_NAME_SIZE); + break; + case NIX_RX_ACTIONOP_UCAST_IPSEC: + fprintf(file, "NIX_RX_ACTIONOP_UCAST_IPSEC (%" PRIu64 ")\n", + (uint64_t)NIX_RX_ACTIONOP_UCAST_IPSEC); + plt_strlcpy(index_name, "RQ Index:", NPC_MAX_FIELD_NAME_SIZE); + break; + case NIX_RX_ACTIONOP_MCAST: + fprintf(file, "NIX_RX_ACTIONOP_MCAST (%" PRIu64 ")\n", + (uint64_t)NIX_RX_ACTIONOP_MCAST); + plt_strlcpy(index_name, "Multicast/mirror table index", + NPC_MAX_FIELD_NAME_SIZE); + break; + case NIX_RX_ACTIONOP_RSS: + fprintf(file, "NIX_RX_ACTIONOP_RSS (%" PRIu64 ")\n", + (uint64_t)NIX_RX_ACTIONOP_RSS); + plt_strlcpy(index_name, "RSS Group Index", + NPC_MAX_FIELD_NAME_SIZE); + break; + case NIX_RX_ACTIONOP_PF_FUNC_DROP: + fprintf(file, "NIX_RX_ACTIONOP_PF_FUNC_DROP (%" PRIu64 ")\n", + (uint64_t)NIX_RX_ACTIONOP_PF_FUNC_DROP); + break; + case NIX_RX_ACTIONOP_MIRROR: + fprintf(file, "NIX_RX_ACTIONOP_MIRROR (%" PRIu64 ")\n", + (uint64_t)NIX_RX_ACTIONOP_MIRROR); + plt_strlcpy(index_name, "Multicast/mirror table index", + NPC_MAX_FIELD_NAME_SIZE); + break; + default: + plt_err("Unknown NIX_RX_ACTIONOP found"); + return; + } + + pf_func = ((npc_action & NPC_RX_ACTION_PFFUNC_MASK) >> 4) & + GENMASK(15, 0); + + fprintf(file, "\tPF_FUNC: %#04X\n", pf_func); + + index = ((npc_action & NPC_RX_ACTION_INDEX_MASK) >> 20) & + GENMASK(19, 0); + + fprintf(file, "\t%s:%#05X\n", index_name, index); + + match_id = ((npc_action & NPC_RX_ACTION_MATCH_MASK) >> 40) & + GENMASK(15, 0); + + fprintf(file, "\tMatch Id:%#04X\n", match_id); + + flowkey_alg = ((npc_action & NPC_RX_ACTION_FLOWKEY_MASK) >> 56) & + GENMASK(4, 0); + + fprintf(file, "\tFlow Key Alg:%#X\n", flowkey_alg); +} + +static void +npc_flow_dump_parsed_action(FILE *file, uint64_t npc_action, bool is_rx) +{ + if (is_rx) { + fprintf(file, "NPC RX Action:%#016lX\n", npc_action); + npc_flow_dump_rx_action(file, npc_action); + } else { + fprintf(file, "NPC TX Action:%#016lX\n", npc_action); + npc_flow_dump_tx_action(file, npc_action); + } +} + +static void +npc_flow_dump_rx_vtag_action(FILE *file, uint64_t vtag_action) +{ + uint32_t type, lid, relptr; + + if (vtag_action & NIX_RX_VTAGACT_VTAG0_VALID_MASK) { + relptr = vtag_action & NIX_RX_VTAGACT_VTAG0_RELPTR_MASK; + lid = ((vtag_action & NIX_RX_VTAGACT_VTAG0_LID_MASK) >> 8) & + GENMASK(2, 0); + type = ((vtag_action & NIX_RX_VTAGACT_VTAG0_TYPE_MASK) >> 12) & + GENMASK(2, 0); + + fprintf(file, "\tVTAG0:relptr:%#X\n", relptr); + fprintf(file, "\tlid:%#X\n", lid); + fprintf(file, "\ttype:%#X\n", type); + } + + if (vtag_action & NIX_RX_VTAGACT_VTAG1_VALID_MASK) { + relptr = ((vtag_action & NIX_RX_VTAGACT_VTAG1_RELPTR_MASK) >> + 32) & + GENMASK(7, 0); + lid = ((vtag_action & NIX_RX_VTAGACT_VTAG1_LID_MASK) >> 40) & + GENMASK(2, 0); + type = ((vtag_action & NIX_RX_VTAGACT_VTAG1_TYPE_MASK) >> 44) & + GENMASK(2, 0); + + fprintf(file, "\tVTAG1:relptr:%#X\n", relptr); + fprintf(file, "\tlid:%#X\n", lid); + fprintf(file, "\ttype:%#X\n", type); + } +} + +static void +npc_get_vtag_opname(uint32_t op, char *opname, int len) +{ + switch (op) { + case 0x0: + plt_strlcpy(opname, "NOP", len - 1); + break; + case 0x1: + plt_strlcpy(opname, "INSERT", len - 1); + break; + case 0x2: + plt_strlcpy(opname, "REPLACE", len - 1); + break; + default: + plt_err("Unknown vtag op found"); + break; + } +} + +static void +npc_flow_dump_tx_vtag_action(FILE *file, uint64_t vtag_action) +{ + uint32_t relptr, lid, op, vtag_def; + char opname[10]; + + relptr = vtag_action & NIX_TX_VTAGACT_VTAG0_RELPTR_MASK; + lid = ((vtag_action & NIX_TX_VTAGACT_VTAG0_LID_MASK) >> 8) & + GENMASK(2, 0); + op = ((vtag_action & NIX_TX_VTAGACT_VTAG0_OP_MASK) >> 12) & + GENMASK(1, 0); + vtag_def = ((vtag_action & NIX_TX_VTAGACT_VTAG0_DEF_MASK) >> 16) & + GENMASK(9, 0); + + npc_get_vtag_opname(op, opname, sizeof(opname)); + + fprintf(file, "\tVTAG0 relptr:%#X\n", relptr); + fprintf(file, "\tlid:%#X\n", lid); + fprintf(file, "\top:%s\n", opname); + fprintf(file, "\tvtag_def:%#X\n", vtag_def); + + relptr = ((vtag_action & NIX_TX_VTAGACT_VTAG1_RELPTR_MASK) >> 32) & + GENMASK(7, 0); + lid = ((vtag_action & NIX_TX_VTAGACT_VTAG1_LID_MASK) >> 40) & + GENMASK(2, 0); + op = ((vtag_action & NIX_TX_VTAGACT_VTAG1_OP_MASK) >> 44) & + GENMASK(1, 0); + vtag_def = ((vtag_action & NIX_TX_VTAGACT_VTAG1_DEF_MASK) >> 48) & + GENMASK(9, 0); + + npc_get_vtag_opname(op, opname, sizeof(opname)); + + fprintf(file, "\tVTAG1:relptr:%#X\n", relptr); + fprintf(file, "\tlid:%#X\n", lid); + fprintf(file, "\top:%s\n", opname); + fprintf(file, "\tvtag_def:%#X\n", vtag_def); +} + +static void +npc_flow_dump_vtag_action(FILE *file, uint64_t vtag_action, bool is_rx) +{ + if (is_rx) { + fprintf(file, "NPC RX VTAG Action:%#016lX\n", vtag_action); + npc_flow_dump_rx_vtag_action(file, vtag_action); + } else { + fprintf(file, "NPC TX VTAG Action:%#016lX\n", vtag_action); + npc_flow_dump_tx_vtag_action(file, vtag_action); + } +} + +void +roc_npc_flow_mcam_dump(FILE *file, struct roc_npc *roc_npc, + struct roc_npc_flow *flow) +{ + struct npc *npc = roc_npc_to_npc_priv(roc_npc); + bool is_rx = 0; + int i; + + fprintf(file, "MCAM Index:%d\n", flow->mcam_id); + fprintf(file, "Interface :%s (%d)\n", intf_str[flow->nix_intf], + flow->nix_intf); + fprintf(file, "Priority :%d\n", flow->priority); + + if (flow->nix_intf == NIX_INTF_RX) + is_rx = 1; + + npc_flow_dump_parsed_action(file, flow->npc_action, is_rx); + npc_flow_dump_vtag_action(file, flow->vtag_action, is_rx); + fprintf(file, "Patterns:\n"); + npc_flow_dump_patterns(file, npc, flow); + + fprintf(file, "MCAM Raw Data :\n"); + + for (i = 0; i < ROC_NPC_MAX_MCAM_WIDTH_DWORDS; i++) { + fprintf(file, "\tDW%d :%016lX\n", i, flow->mcam_data[i]); + fprintf(file, "\tDW%d_Mask:%016lX\n", i, flow->mcam_mask[i]); + } + + fprintf(file, "\n"); +} diff --git a/drivers/common/cnxk/roc_npc_priv.h b/drivers/common/cnxk/roc_npc_priv.h index 8bc5bac2ca..961583b79b 100644 --- a/drivers/common/cnxk/roc_npc_priv.h +++ b/drivers/common/cnxk/roc_npc_priv.h @@ -47,7 +47,7 @@ #define NPC_RVUPF_MAX_9XXX 0x10 /* HRM: RVU_PRIV_CONST */ #define NPC_RVUPF_MAX_10XX 0x20 /* HRM: RVU_PRIV_CONST */ #define NPC_NIXLF_MAX 0x80 /* HRM: NIX_AF_CONST2 */ -#define NPC_MCAME_PER_PF 2 /* DRV: RSVD_MCAM_ENTRIES_PER_PF */ +#define NPC_MCAME_PER_PF 3 /* DRV: RSVD_MCAM_ENTRIES_PER_PF */ #define NPC_MCAME_PER_LF 1 /* DRV: RSVD_MCAM_ENTRIES_PER_NIXLF */ #define NPC_MCAME_RESVD_9XXX \ (NPC_NIXLF_MAX * NPC_MCAME_PER_LF + \ diff --git a/drivers/common/cnxk/roc_npc_utils.c b/drivers/common/cnxk/roc_npc_utils.c index 1fb897349f..5c97588e68 100644 --- a/drivers/common/cnxk/roc_npc_utils.c +++ b/drivers/common/cnxk/roc_npc_utils.c @@ -206,6 +206,7 @@ npc_update_parse_state(struct npc_parse_state *pst, uint8_t flags) { struct npc_lid_lt_xtract_info *xinfo; + struct roc_npc_flow_dump_data *dump; struct npc_xtract_info *lfinfo; int intf, lf_cfg; int i, j, rc = 0; @@ -248,6 +249,9 @@ npc_update_parse_state(struct npc_parse_state *pst, } done: + dump = &pst->flow->dump_data[pst->flow->num_patterns++]; + dump->lid = lid; + dump->ltype = lt; pst->pattern++; return 0; } diff --git a/drivers/common/cnxk/version.map b/drivers/common/cnxk/version.map index c0058d1a99..ecae890694 100644 --- a/drivers/common/cnxk/version.map +++ b/drivers/common/cnxk/version.map @@ -182,6 +182,8 @@ INTERNAL { roc_npc_fini; roc_npc_flow_create; roc_npc_flow_destroy; + roc_npc_flow_dump; + roc_npc_flow_mcam_dump; roc_npc_flow_parse; roc_npc_get_low_priority_mcam; roc_npc_init;