1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright(C) 2021 Marvell. 3 */ 4 5 #include "roc_api.h" 6 #include "roc_priv.h" 7 8 #define NPC_MAX_FIELD_NAME_SIZE 80 9 #define NPC_RX_ACTIONOP_MASK GENMASK(3, 0) 10 #define NPC_RX_ACTION_PFFUNC_MASK GENMASK(19, 4) 11 #define NPC_RX_ACTION_INDEX_MASK GENMASK(39, 20) 12 #define NPC_RX_ACTION_MATCH_MASK GENMASK(55, 40) 13 #define NPC_RX_ACTION_FLOWKEY_MASK GENMASK(60, 56) 14 15 #define NPC_TX_ACTION_INDEX_MASK GENMASK(31, 12) 16 #define NPC_TX_ACTION_MATCH_MASK GENMASK(47, 32) 17 18 #define NIX_RX_VTAGACT_VTAG0_RELPTR_MASK GENMASK(7, 0) 19 #define NIX_RX_VTAGACT_VTAG0_LID_MASK GENMASK(10, 8) 20 #define NIX_RX_VTAGACT_VTAG0_TYPE_MASK GENMASK(14, 12) 21 #define NIX_RX_VTAGACT_VTAG0_VALID_MASK BIT_ULL(15) 22 23 #define NIX_RX_VTAGACT_VTAG1_RELPTR_MASK GENMASK(39, 32) 24 #define NIX_RX_VTAGACT_VTAG1_LID_MASK GENMASK(42, 40) 25 #define NIX_RX_VTAGACT_VTAG1_TYPE_MASK GENMASK(46, 44) 26 #define NIX_RX_VTAGACT_VTAG1_VALID_MASK BIT_ULL(47) 27 28 #define NIX_TX_VTAGACT_VTAG0_RELPTR_MASK GENMASK(7, 0) 29 #define NIX_TX_VTAGACT_VTAG0_LID_MASK GENMASK(10, 8) 30 #define NIX_TX_VTAGACT_VTAG0_OP_MASK GENMASK(13, 12) 31 #define NIX_TX_VTAGACT_VTAG0_DEF_MASK GENMASK(25, 16) 32 33 #define NIX_TX_VTAGACT_VTAG1_RELPTR_MASK GENMASK(39, 32) 34 #define NIX_TX_VTAGACT_VTAG1_LID_MASK GENMASK(42, 40) 35 #define NIX_TX_VTAGACT_VTAG1_OP_MASK GENMASK(45, 44) 36 #define NIX_TX_VTAGACT_VTAG1_DEF_MASK GENMASK(57, 48) 37 38 struct __plt_packed_begin npc_rx_parse_nibble_s { 39 uint16_t chan : 3; 40 uint16_t errlev : 1; 41 uint16_t errcode : 2; 42 uint16_t l2l3bm : 1; 43 uint16_t laflags : 2; 44 uint16_t latype : 1; 45 uint16_t lbflags : 2; 46 uint16_t lbtype : 1; 47 uint16_t lcflags : 2; 48 uint16_t lctype : 1; 49 uint16_t ldflags : 2; 50 uint16_t ldtype : 1; 51 uint16_t leflags : 2; 52 uint16_t letype : 1; 53 uint16_t lfflags : 2; 54 uint16_t lftype : 1; 55 uint16_t lgflags : 2; 56 uint16_t lgtype : 1; 57 uint16_t lhflags : 2; 58 uint16_t lhtype : 1; 59 } __plt_packed_end; 60 61 static const char *const intf_str[] = { 62 "NIX-RX", 63 "NIX-TX", 64 }; 65 66 static const char *const ltype_str[NPC_MAX_LID][NPC_MAX_LT] = { 67 [NPC_LID_LA][0] = "NONE", 68 [NPC_LID_LA][NPC_LT_LA_ETHER] = "LA_ETHER", 69 [NPC_LID_LA][NPC_LT_LA_IH_NIX_ETHER] = "LA_IH_NIX_ETHER", 70 [NPC_LID_LA][NPC_LT_LA_HIGIG2_ETHER] = "LA_HIGIG2_ETHER", 71 [NPC_LID_LA][NPC_LT_LA_IH_NIX_HIGIG2_ETHER] = "LA_IH_NIX_HIGIG2_ETHER", 72 [NPC_LID_LA][NPC_LT_LA_CUSTOM_L2_90B_ETHER] = "LA_CUSTOM_L2_90B_ETHER", 73 [NPC_LID_LA][NPC_LT_LA_CPT_HDR] = "LA_CPT_HDR", 74 [NPC_LID_LA][NPC_LT_LA_CUSTOM_L2_24B_ETHER] = "LA_CUSTOM_L2_24B_ETHER", 75 [NPC_LID_LA][NPC_LT_LA_CUSTOM_PRE_L2_ETHER] = "NPC_LT_LA_CUSTOM_PRE_L2_ETHER", 76 [NPC_LID_LA][NPC_LT_LA_CUSTOM0] = "NPC_LT_LA_CUSTOM0", 77 [NPC_LID_LA][NPC_LT_LA_CUSTOM1] = "NPC_LT_LA_CUSTOM1", 78 [NPC_LID_LB][0] = "NONE", 79 [NPC_LID_LB][NPC_LT_LB_ETAG] = "LB_ETAG", 80 [NPC_LID_LB][NPC_LT_LB_CTAG] = "LB_CTAG", 81 [NPC_LID_LB][NPC_LT_LB_STAG_QINQ] = "LB_STAG_QINQ", 82 [NPC_LID_LB][NPC_LT_LB_BTAG] = "LB_BTAG", 83 [NPC_LID_LB][NPC_LT_LB_PPPOE] = "LB_PPPOE", 84 [NPC_LID_LB][NPC_LT_LB_DSA] = "LB_DSA", 85 [NPC_LID_LB][NPC_LT_LB_DSA_VLAN] = "LB_DSA_VLAN", 86 [NPC_LID_LB][NPC_LT_LB_EDSA] = "LB_EDSA", 87 [NPC_LID_LB][NPC_LT_LB_EDSA_VLAN] = "LB_EDSA_VLAN", 88 [NPC_LID_LB][NPC_LT_LB_EXDSA] = "LB_EXDSA", 89 [NPC_LID_LB][NPC_LT_LB_EXDSA_VLAN] = "LB_EXDSA_VLAN", 90 [NPC_LID_LB][NPC_LT_LB_FDSA] = "LB_FDSA", 91 [NPC_LID_LB][NPC_LT_LB_VLAN_EXDSA] = "LB_VLAN_EXDSA", 92 [NPC_LID_LB][NPC_LT_LB_CUSTOM0] = "LB_CUSTOM0", 93 [NPC_LID_LB][NPC_LT_LB_CUSTOM1] = "LB_CUSTOM1", 94 [NPC_LID_LC][0] = "NONE", 95 [NPC_LID_LC][NPC_LT_LC_PTP] = "LC_PTP", 96 [NPC_LID_LC][NPC_LT_LC_IP] = "LC_IP", 97 [NPC_LID_LC][NPC_LT_LC_IP_OPT] = "LC_IP_OPT", 98 [NPC_LID_LC][NPC_LT_LC_IP6] = "LC_IP6", 99 [NPC_LID_LC][NPC_LT_LC_IP6_EXT] = "LC_IP6_EXT", 100 [NPC_LID_LC][NPC_LT_LC_ARP] = "LC_ARP", 101 [NPC_LID_LC][NPC_LT_LC_RARP] = "LC_RARP", 102 [NPC_LID_LC][NPC_LT_LC_MPLS] = "LC_MPLS", 103 [NPC_LID_LC][NPC_LT_LC_NSH] = "LC_NSH", 104 [NPC_LID_LC][NPC_LT_LC_FCOE] = "LC_FCOE", 105 [NPC_LID_LC][NPC_LT_LC_NGIO] = "LC_NGIO", 106 [NPC_LID_LC][NPC_LT_LC_CUSTOM0] = "LC_CUSTOM0", 107 [NPC_LID_LC][NPC_LT_LC_CUSTOM1] = "LC_CUSTOM1", 108 [NPC_LID_LD][0] = "NONE", 109 [NPC_LID_LD][NPC_LT_LD_TCP] = "LD_TCP", 110 [NPC_LID_LD][NPC_LT_LD_UDP] = "LD_UDP", 111 [NPC_LID_LD][NPC_LT_LD_SCTP] = "LD_SCTP", 112 [NPC_LID_LD][NPC_LT_LD_ICMP6] = "LD_ICMP6", 113 [NPC_LID_LD][NPC_LT_LD_CUSTOM0] = "LD_CUSTOM0", 114 [NPC_LID_LD][NPC_LT_LD_CUSTOM1] = "LD_CUSTOM1", 115 [NPC_LID_LD][NPC_LT_LD_IGMP] = "LD_IGMP", 116 [NPC_LID_LD][NPC_LT_LD_AH] = "LD_AH", 117 [NPC_LID_LD][NPC_LT_LD_GRE] = "LD_GRE", 118 [NPC_LID_LD][NPC_LT_LD_NVGRE] = "LD_NVGRE", 119 [NPC_LID_LD][NPC_LT_LD_NSH] = "LD_NSH", 120 [NPC_LID_LD][NPC_LT_LD_TU_MPLS_IN_NSH] = "LD_TU_MPLS_IN_NSH", 121 [NPC_LID_LD][NPC_LT_LD_TU_MPLS_IN_IP] = "LD_TU_MPLS_IN_IP", 122 [NPC_LID_LD][NPC_LT_LD_ICMP] = "LD_ICMP", 123 [NPC_LID_LE][0] = "NONE", 124 [NPC_LID_LE][NPC_LT_LE_VXLAN] = "LE_VXLAN", 125 [NPC_LID_LE][NPC_LT_LE_GENEVE] = "LE_GENEVE", 126 [NPC_LID_LE][NPC_LT_LE_ESP] = "LE_ESP", 127 [NPC_LID_LE][NPC_LT_LE_GTPU] = "LE_GTPU", 128 [NPC_LID_LE][NPC_LT_LE_VXLANGPE] = "LE_VXLANGPE", 129 [NPC_LID_LE][NPC_LT_LE_GTPC] = "LE_GTPC", 130 [NPC_LID_LE][NPC_LT_LE_NSH] = "LE_NSH", 131 [NPC_LID_LE][NPC_LT_LE_TU_MPLS_IN_GRE] = "LE_TU_MPLS_IN_GRE", 132 [NPC_LID_LE][NPC_LT_LE_TU_NSH_IN_GRE] = "LE_TU_NSH_IN_GRE", 133 [NPC_LID_LE][NPC_LT_LE_TU_MPLS_IN_UDP] = "LE_TU_MPLS_IN_UDP", 134 [NPC_LID_LE][NPC_LT_LE_CUSTOM0] = "LE_CUSTOM0", 135 [NPC_LID_LE][NPC_LT_LE_CUSTOM1] = "LE_CUSTOM1", 136 [NPC_LID_LF][0] = "NONE", 137 [NPC_LID_LF][NPC_LT_LF_TU_ETHER] = "LF_TU_ETHER", 138 [NPC_LID_LF][NPC_LT_LF_TU_PPP] = "LF_TU_PPP", 139 [NPC_LID_LF][NPC_LT_LF_TU_MPLS_IN_VXLANGPE] = "LF_TU_MPLS_IN_VXLANGPE", 140 [NPC_LID_LF][NPC_LT_LF_TU_NSH_IN_VXLANGPE] = "LF_TU_NSH_IN_VXLANGPE", 141 [NPC_LID_LF][NPC_LT_LF_TU_MPLS_IN_NSH] = "LF_TU_MPLS_IN_NSH", 142 [NPC_LID_LF][NPC_LT_LF_TU_3RD_NSH] = "LF_TU_3RD_NSH", 143 [NPC_LID_LF][NPC_LT_LF_CUSTOM0] = "LF_CUSTOM0", 144 [NPC_LID_LF][NPC_LT_LF_CUSTOM1] = "LF_CUSTOM1", 145 [NPC_LID_LG][0] = "NONE", 146 [NPC_LID_LG][NPC_LT_LG_TU_IP] = "LG_TU_IP", 147 [NPC_LID_LG][NPC_LT_LG_TU_IP6] = "LG_TU_IP6", 148 [NPC_LID_LG][NPC_LT_LG_TU_ARP] = "LG_TU_ARP", 149 [NPC_LID_LG][NPC_LT_LG_TU_ETHER_IN_NSH] = "LG_TU_ETHER_IN_NSH", 150 [NPC_LID_LG][NPC_LT_LG_CUSTOM0] = "LG_CUSTOM0", 151 [NPC_LID_LG][NPC_LT_LG_CUSTOM1] = "LG_CUSTOM1", 152 [NPC_LID_LH][0] = "NONE", 153 [NPC_LID_LH][NPC_LT_LH_TU_TCP] = "LH_TU_TCP", 154 [NPC_LID_LH][NPC_LT_LH_TU_UDP] = "LH_TU_UDP", 155 [NPC_LID_LH][NPC_LT_LH_TU_SCTP] = "LH_TU_SCTP", 156 [NPC_LID_LH][NPC_LT_LH_TU_ICMP6] = "LH_TU_ICMP6", 157 [NPC_LID_LH][NPC_LT_LH_CUSTOM0] = "LH_CUSTOM0", 158 [NPC_LID_LH][NPC_LT_LH_CUSTOM1] = "LH_CUSTOM1", 159 [NPC_LID_LH][NPC_LT_LH_TU_IGMP] = "LH_TU_IGMP", 160 [NPC_LID_LH][NPC_LT_LH_TU_ESP] = "LH_TU_ESP", 161 [NPC_LID_LH][NPC_LT_LH_TU_AH] = "LH_TU_AH", 162 [NPC_LID_LH][NPC_LT_LH_TU_ICMP] = "LH_TU_ICMP", 163 }; 164 165 static uint16_t 166 npc_get_nibbles(struct roc_npc_flow *flow, uint16_t size, uint32_t bit_offset) 167 { 168 uint32_t byte_index, noffset; 169 uint16_t data, mask; 170 uint8_t *bytes; 171 172 bytes = (uint8_t *)flow->mcam_data; 173 mask = (1ULL << (size * 4)) - 1; 174 byte_index = bit_offset / 8; 175 noffset = bit_offset % 8; 176 data = *(unaligned_uint16_t *)&bytes[byte_index]; 177 data >>= noffset; 178 data &= mask; 179 180 return data; 181 } 182 183 static void 184 npc_flow_print_parse_nibbles(FILE *file, struct roc_npc_flow *flow, 185 uint64_t parse_nibbles) 186 { 187 struct npc_rx_parse_nibble_s *rx_parse; 188 uint32_t data, offset = 0; 189 190 rx_parse = (struct npc_rx_parse_nibble_s *)&parse_nibbles; 191 192 if (rx_parse->chan) { 193 data = npc_get_nibbles(flow, 3, offset); 194 fprintf(file, "\tNPC_PARSE_NIBBLE_CHAN:%#03X\n", data); 195 offset += 12; 196 } 197 198 if (rx_parse->errlev) { 199 data = npc_get_nibbles(flow, 1, offset); 200 fprintf(file, "\tNPC_PARSE_NIBBLE_ERRLEV:%#X\n", data); 201 offset += 4; 202 } 203 204 if (rx_parse->errcode) { 205 data = npc_get_nibbles(flow, 2, offset); 206 fprintf(file, "\tNPC_PARSE_NIBBLE_ERRCODE:%#02X\n", data); 207 offset += 8; 208 } 209 210 if (rx_parse->l2l3bm) { 211 data = npc_get_nibbles(flow, 1, offset); 212 fprintf(file, "\tNPC_PARSE_NIBBLE_L2L3_BCAST:%#X\n", data); 213 offset += 4; 214 } 215 216 if (rx_parse->laflags) { 217 data = npc_get_nibbles(flow, 2, offset); 218 fprintf(file, "\tNPC_PARSE_NIBBLE_LA_FLAGS:%#02X\n", data); 219 offset += 8; 220 } 221 222 if (rx_parse->latype) { 223 data = npc_get_nibbles(flow, 1, offset); 224 fprintf(file, "\tNPC_PARSE_NIBBLE_LA_LTYPE:%s\n", 225 ltype_str[NPC_LID_LA][data]); 226 offset += 4; 227 } 228 229 if (rx_parse->lbflags) { 230 data = npc_get_nibbles(flow, 2, offset); 231 fprintf(file, "\tNPC_PARSE_NIBBLE_LB_FLAGS:%#02X\n", data); 232 offset += 8; 233 } 234 235 if (rx_parse->lbtype) { 236 data = npc_get_nibbles(flow, 1, offset); 237 fprintf(file, "\tNPC_PARSE_NIBBLE_LB_LTYPE:%s\n", 238 ltype_str[NPC_LID_LB][data]); 239 offset += 4; 240 } 241 242 if (rx_parse->lcflags) { 243 data = npc_get_nibbles(flow, 2, offset); 244 fprintf(file, "\tNPC_PARSE_NIBBLE_LC_FLAGS:%#02X\n", data); 245 offset += 8; 246 } 247 248 if (rx_parse->lctype) { 249 data = npc_get_nibbles(flow, 1, offset); 250 fprintf(file, "\tNPC_PARSE_NIBBLE_LC_LTYPE:%s\n", 251 ltype_str[NPC_LID_LC][data]); 252 offset += 4; 253 } 254 255 if (rx_parse->ldflags) { 256 data = npc_get_nibbles(flow, 2, offset); 257 fprintf(file, "\tNPC_PARSE_NIBBLE_LD_FLAGS:%#02X\n", data); 258 offset += 8; 259 } 260 261 if (rx_parse->ldtype) { 262 data = npc_get_nibbles(flow, 1, offset); 263 fprintf(file, "\tNPC_PARSE_NIBBLE_LD_LTYPE:%s\n", 264 ltype_str[NPC_LID_LD][data]); 265 offset += 4; 266 } 267 268 if (rx_parse->leflags) { 269 data = npc_get_nibbles(flow, 2, offset); 270 fprintf(file, "\tNPC_PARSE_NIBBLE_LE_FLAGS:%#02X\n", data); 271 offset += 8; 272 } 273 274 if (rx_parse->letype) { 275 data = npc_get_nibbles(flow, 1, offset); 276 fprintf(file, "\tNPC_PARSE_NIBBLE_LE_LTYPE:%s\n", 277 ltype_str[NPC_LID_LE][data]); 278 offset += 4; 279 } 280 281 if (rx_parse->lfflags) { 282 data = npc_get_nibbles(flow, 2, offset); 283 fprintf(file, "\tNPC_PARSE_NIBBLE_LF_FLAGS:%#02X\n", data); 284 offset += 8; 285 } 286 287 if (rx_parse->lftype) { 288 data = npc_get_nibbles(flow, 1, offset); 289 fprintf(file, "\tNPC_PARSE_NIBBLE_LF_LTYPE:%s\n", 290 ltype_str[NPC_LID_LF][data]); 291 offset += 4; 292 } 293 294 if (rx_parse->lgflags) { 295 data = npc_get_nibbles(flow, 2, offset); 296 fprintf(file, "\tNPC_PARSE_NIBBLE_LG_FLAGS:%#02X\n", data); 297 offset += 8; 298 } 299 300 if (rx_parse->lgtype) { 301 data = npc_get_nibbles(flow, 1, offset); 302 fprintf(file, "\tNPC_PARSE_NIBBLE_LG_LTYPE:%s\n", 303 ltype_str[NPC_LID_LG][data]); 304 offset += 4; 305 } 306 307 if (rx_parse->lhflags) { 308 data = npc_get_nibbles(flow, 2, offset); 309 fprintf(file, "\tNPC_PARSE_NIBBLE_LH_FLAGS:%#02X\n", data); 310 } 311 312 if (rx_parse->lhtype) { 313 data = npc_get_nibbles(flow, 1, offset); 314 fprintf(file, "\tNPC_PARSE_NIBBLE_LH_LTYPE:%s\n", 315 ltype_str[NPC_LID_LH][data]); 316 offset += 4; 317 } 318 } 319 320 static void 321 npc_flow_print_xtractinfo(FILE *file, struct npc_xtract_info *lfinfo, 322 struct roc_npc_flow *flow, int lid, int lt) 323 { 324 uint8_t *datastart, *maskstart; 325 int i; 326 327 datastart = (uint8_t *)&flow->mcam_data + lfinfo->key_off; 328 maskstart = (uint8_t *)&flow->mcam_mask + lfinfo->key_off; 329 330 fprintf(file, "\t%s, hdr offset:%#X, len:%#X, key offset:%#X, ", 331 ltype_str[lid][lt], lfinfo->hdr_off, lfinfo->len, 332 lfinfo->key_off); 333 334 fprintf(file, "Data:0X"); 335 for (i = lfinfo->len - 1; i >= 0; i--) 336 fprintf(file, "%02X", datastart[i]); 337 338 fprintf(file, ", Mask:0X"); 339 340 for (i = lfinfo->len - 1; i >= 0; i--) 341 fprintf(file, "%02X", maskstart[i]); 342 343 fprintf(file, "\n"); 344 } 345 346 static void 347 npc_flow_print_item(FILE *file, struct npc *npc, struct npc_xtract_info *xinfo, 348 struct roc_npc_flow *flow, int intf, int lid, int lt, 349 int ld) 350 { 351 struct npc_xtract_info *lflags_info; 352 int i, lf_cfg = 0; 353 354 npc_flow_print_xtractinfo(file, xinfo, flow, lid, lt); 355 356 if (xinfo->flags_enable) { 357 lf_cfg = npc->prx_lfcfg[ld].i; 358 359 if (lf_cfg != lid) 360 return; 361 362 for (i = 0; i < NPC_MAX_LFL; i++) { 363 lflags_info = npc->prx_fxcfg[intf][ld][i].xtract; 364 365 if (!lflags_info->enable) 366 continue; 367 368 npc_flow_print_xtractinfo(file, lflags_info, flow, lid, lt); 369 } 370 } 371 } 372 373 static void 374 npc_flow_dump_patterns(FILE *file, struct npc *npc, struct roc_npc_flow *flow) 375 { 376 struct npc_lid_lt_xtract_info *lt_xinfo; 377 struct npc_xtract_info *xinfo; 378 uint32_t intf, lid, ld, i; 379 uint64_t parse_nibbles; 380 uint16_t ltype; 381 382 intf = flow->nix_intf; 383 parse_nibbles = npc->keyx_supp_nmask[intf]; 384 npc_flow_print_parse_nibbles(file, flow, parse_nibbles); 385 386 for (i = 0; i < flow->num_patterns; i++) { 387 lid = flow->dump_data[i].lid; 388 ltype = flow->dump_data[i].ltype; 389 lt_xinfo = &npc->prx_dxcfg[intf][lid][ltype]; 390 391 for (ld = 0; ld < NPC_MAX_LD; ld++) { 392 xinfo = <_xinfo->xtract[ld]; 393 if (!xinfo->enable) 394 continue; 395 npc_flow_print_item(file, npc, xinfo, flow, intf, lid, 396 ltype, ld); 397 } 398 } 399 } 400 401 static void 402 npc_flow_dump_tx_action(FILE *file, uint64_t npc_action) 403 { 404 char index_name[NPC_MAX_FIELD_NAME_SIZE] = "Index:"; 405 uint32_t tx_op, index, match_id; 406 407 tx_op = npc_action & NPC_RX_ACTIONOP_MASK; 408 409 fprintf(file, "\tActionOp:"); 410 411 switch (tx_op) { 412 case NIX_TX_ACTIONOP_DROP: 413 fprintf(file, "NIX_TX_ACTIONOP_DROP (%" PRIu64 ")\n", 414 (uint64_t)NIX_RX_ACTIONOP_DROP); 415 break; 416 case NIX_TX_ACTIONOP_UCAST_DEFAULT: 417 fprintf(file, "NIX_TX_ACTIONOP_UCAST_DEFAULT (%" PRIu64 ")\n", 418 (uint64_t)NIX_TX_ACTIONOP_UCAST_DEFAULT); 419 break; 420 case NIX_TX_ACTIONOP_UCAST_CHAN: 421 fprintf(file, "NIX_TX_ACTIONOP_UCAST_DEFAULT (%" PRIu64 ")\n", 422 (uint64_t)NIX_TX_ACTIONOP_UCAST_CHAN); 423 plt_strlcpy(index_name, 424 "Transmit Channel:", NPC_MAX_FIELD_NAME_SIZE); 425 break; 426 case NIX_TX_ACTIONOP_MCAST: 427 fprintf(file, "NIX_TX_ACTIONOP_MCAST (%" PRIu64 ")\n", 428 (uint64_t)NIX_TX_ACTIONOP_MCAST); 429 plt_strlcpy(index_name, 430 "Multicast Table Index:", NPC_MAX_FIELD_NAME_SIZE); 431 break; 432 case NIX_TX_ACTIONOP_DROP_VIOL: 433 fprintf(file, "NIX_TX_ACTIONOP_DROP_VIOL (%" PRIu64 ")\n", 434 (uint64_t)NIX_TX_ACTIONOP_DROP_VIOL); 435 break; 436 default: 437 plt_err("Unknown NIX_TX_ACTIONOP found"); 438 return; 439 } 440 441 index = ((npc_action & NPC_TX_ACTION_INDEX_MASK) >> 12) & 442 GENMASK(19, 0); 443 444 fprintf(file, "\t%s:%#05X\n", index_name, index); 445 446 match_id = ((npc_action & NPC_TX_ACTION_MATCH_MASK) >> 32) & 447 GENMASK(15, 0); 448 449 fprintf(file, "\tMatch Id:%#04X\n", match_id); 450 } 451 452 static void 453 npc_flow_dump_rx_action(FILE *file, uint64_t npc_action) 454 { 455 uint32_t rx_op, pf_func, index, match_id, flowkey_alg; 456 char index_name[NPC_MAX_FIELD_NAME_SIZE] = "Index:"; 457 458 rx_op = npc_action & NPC_RX_ACTIONOP_MASK; 459 460 fprintf(file, "\tActionOp:"); 461 462 switch (rx_op) { 463 case NIX_RX_ACTIONOP_DROP: 464 fprintf(file, "NIX_RX_ACTIONOP_DROP (%" PRIu64 ")\n", 465 (uint64_t)NIX_RX_ACTIONOP_DROP); 466 break; 467 case NIX_RX_ACTIONOP_UCAST: 468 fprintf(file, "NIX_RX_ACTIONOP_UCAST (%" PRIu64 ")\n", 469 (uint64_t)NIX_RX_ACTIONOP_UCAST); 470 plt_strlcpy(index_name, "RQ Index", NPC_MAX_FIELD_NAME_SIZE); 471 break; 472 case NIX_RX_ACTIONOP_UCAST_IPSEC: 473 fprintf(file, "NIX_RX_ACTIONOP_UCAST_IPSEC (%" PRIu64 ")\n", 474 (uint64_t)NIX_RX_ACTIONOP_UCAST_IPSEC); 475 plt_strlcpy(index_name, "RQ Index:", NPC_MAX_FIELD_NAME_SIZE); 476 break; 477 case NIX_RX_ACTIONOP_MCAST: 478 fprintf(file, "NIX_RX_ACTIONOP_MCAST (%" PRIu64 ")\n", 479 (uint64_t)NIX_RX_ACTIONOP_MCAST); 480 plt_strlcpy(index_name, "Multicast/mirror table index", 481 NPC_MAX_FIELD_NAME_SIZE); 482 break; 483 case NIX_RX_ACTIONOP_RSS: 484 fprintf(file, "NIX_RX_ACTIONOP_RSS (%" PRIu64 ")\n", 485 (uint64_t)NIX_RX_ACTIONOP_RSS); 486 plt_strlcpy(index_name, "RSS Group Index", 487 NPC_MAX_FIELD_NAME_SIZE); 488 break; 489 case NIX_RX_ACTIONOP_PF_FUNC_DROP: 490 fprintf(file, "NIX_RX_ACTIONOP_PF_FUNC_DROP (%" PRIu64 ")\n", 491 (uint64_t)NIX_RX_ACTIONOP_PF_FUNC_DROP); 492 break; 493 case NIX_RX_ACTIONOP_MIRROR: 494 fprintf(file, "NIX_RX_ACTIONOP_MIRROR (%" PRIu64 ")\n", 495 (uint64_t)NIX_RX_ACTIONOP_MIRROR); 496 plt_strlcpy(index_name, "Multicast/mirror table index", 497 NPC_MAX_FIELD_NAME_SIZE); 498 break; 499 case NIX_RX_ACTIONOP_DEFAULT: 500 fprintf(file, "NIX_RX_ACTIONOP_DEFAULT (%" PRIu64 ")\n", 501 (uint64_t)NIX_RX_ACTIONOP_DEFAULT); 502 break; 503 default: 504 plt_err("Unknown NIX_RX_ACTIONOP found"); 505 return; 506 } 507 508 pf_func = ((npc_action & NPC_RX_ACTION_PFFUNC_MASK) >> 4) & 509 GENMASK(15, 0); 510 511 fprintf(file, "\tPF_FUNC: %#04X\n", pf_func); 512 513 index = ((npc_action & NPC_RX_ACTION_INDEX_MASK) >> 20) & 514 GENMASK(19, 0); 515 516 fprintf(file, "\t%s:%#05X\n", index_name, index); 517 518 match_id = ((npc_action & NPC_RX_ACTION_MATCH_MASK) >> 40) & 519 GENMASK(15, 0); 520 521 fprintf(file, "\tMatch Id:%#04X\n", match_id); 522 523 flowkey_alg = ((npc_action & NPC_RX_ACTION_FLOWKEY_MASK) >> 56) & 524 GENMASK(4, 0); 525 526 fprintf(file, "\tFlow Key Alg:%#X\n", flowkey_alg); 527 } 528 529 static void 530 npc_flow_dump_parsed_action(FILE *file, uint64_t npc_action, bool is_rx) 531 { 532 if (is_rx) { 533 fprintf(file, "NPC RX Action:%#016lX\n", npc_action); 534 npc_flow_dump_rx_action(file, npc_action); 535 } else { 536 fprintf(file, "NPC TX Action:%#016lX\n", npc_action); 537 npc_flow_dump_tx_action(file, npc_action); 538 } 539 } 540 541 static void 542 npc_flow_dump_rx_vtag_action(FILE *file, uint64_t vtag_action) 543 { 544 uint32_t type, lid, relptr; 545 546 if (vtag_action & NIX_RX_VTAGACT_VTAG0_VALID_MASK) { 547 relptr = vtag_action & NIX_RX_VTAGACT_VTAG0_RELPTR_MASK; 548 lid = ((vtag_action & NIX_RX_VTAGACT_VTAG0_LID_MASK) >> 8) & 549 GENMASK(2, 0); 550 type = ((vtag_action & NIX_RX_VTAGACT_VTAG0_TYPE_MASK) >> 12) & 551 GENMASK(2, 0); 552 553 fprintf(file, "\tVTAG0:relptr:%#X\n", relptr); 554 fprintf(file, "\tlid:%#X\n", lid); 555 fprintf(file, "\ttype:%#X\n", type); 556 } 557 558 if (vtag_action & NIX_RX_VTAGACT_VTAG1_VALID_MASK) { 559 relptr = ((vtag_action & NIX_RX_VTAGACT_VTAG1_RELPTR_MASK) >> 560 32) & 561 GENMASK(7, 0); 562 lid = ((vtag_action & NIX_RX_VTAGACT_VTAG1_LID_MASK) >> 40) & 563 GENMASK(2, 0); 564 type = ((vtag_action & NIX_RX_VTAGACT_VTAG1_TYPE_MASK) >> 44) & 565 GENMASK(2, 0); 566 567 fprintf(file, "\tVTAG1:relptr:%#X\n", relptr); 568 fprintf(file, "\tlid:%#X\n", lid); 569 fprintf(file, "\ttype:%#X\n", type); 570 } 571 } 572 573 static void 574 npc_get_vtag_opname(uint32_t op, char *opname, int len) 575 { 576 switch (op) { 577 case 0x0: 578 plt_strlcpy(opname, "NOP", len - 1); 579 break; 580 case 0x1: 581 plt_strlcpy(opname, "INSERT", len - 1); 582 break; 583 case 0x2: 584 plt_strlcpy(opname, "REPLACE", len - 1); 585 break; 586 default: 587 plt_err("Unknown vtag op found"); 588 break; 589 } 590 } 591 592 static void 593 npc_flow_dump_tx_vtag_action(FILE *file, uint64_t vtag_action) 594 { 595 uint32_t relptr, lid, op, vtag_def; 596 char opname[10]; 597 598 relptr = vtag_action & NIX_TX_VTAGACT_VTAG0_RELPTR_MASK; 599 lid = ((vtag_action & NIX_TX_VTAGACT_VTAG0_LID_MASK) >> 8) & 600 GENMASK(2, 0); 601 op = ((vtag_action & NIX_TX_VTAGACT_VTAG0_OP_MASK) >> 12) & 602 GENMASK(1, 0); 603 vtag_def = ((vtag_action & NIX_TX_VTAGACT_VTAG0_DEF_MASK) >> 16) & 604 GENMASK(9, 0); 605 606 npc_get_vtag_opname(op, opname, sizeof(opname)); 607 608 fprintf(file, "\tVTAG0 relptr:%#X\n", relptr); 609 fprintf(file, "\tlid:%#X\n", lid); 610 fprintf(file, "\top:%s\n", opname); 611 fprintf(file, "\tvtag_def:%#X\n", vtag_def); 612 613 relptr = ((vtag_action & NIX_TX_VTAGACT_VTAG1_RELPTR_MASK) >> 32) & 614 GENMASK(7, 0); 615 lid = ((vtag_action & NIX_TX_VTAGACT_VTAG1_LID_MASK) >> 40) & 616 GENMASK(2, 0); 617 op = ((vtag_action & NIX_TX_VTAGACT_VTAG1_OP_MASK) >> 44) & 618 GENMASK(1, 0); 619 vtag_def = ((vtag_action & NIX_TX_VTAGACT_VTAG1_DEF_MASK) >> 48) & 620 GENMASK(9, 0); 621 622 npc_get_vtag_opname(op, opname, sizeof(opname)); 623 624 fprintf(file, "\tVTAG1:relptr:%#X\n", relptr); 625 fprintf(file, "\tlid:%#X\n", lid); 626 fprintf(file, "\top:%s\n", opname); 627 fprintf(file, "\tvtag_def:%#X\n", vtag_def); 628 } 629 630 static void 631 npc_flow_dump_vtag_action(FILE *file, uint64_t vtag_action, bool is_rx) 632 { 633 if (is_rx) { 634 fprintf(file, "NPC RX VTAG Action:%#016lX\n", vtag_action); 635 npc_flow_dump_rx_vtag_action(file, vtag_action); 636 } else { 637 fprintf(file, "NPC TX VTAG Action:%#016lX\n", vtag_action); 638 npc_flow_dump_tx_vtag_action(file, vtag_action); 639 } 640 } 641 642 static void 643 npc_flow_hw_mcam_entry_dump(FILE *file, struct npc *npc, struct roc_npc_flow *flow) 644 { 645 uint64_t mcam_data[ROC_NPC_MAX_MCAM_WIDTH_DWORDS]; 646 uint64_t mcam_mask[ROC_NPC_MAX_MCAM_WIDTH_DWORDS]; 647 struct npc_mcam_read_entry_req *mcam_read_req; 648 struct npc_mcam_read_entry_rsp *mcam_read_rsp; 649 struct nix_inl_dev *inl_dev = NULL; 650 struct idev_cfg *idev; 651 struct mbox *mbox; 652 uint8_t enabled; 653 int rc = 0, i; 654 655 idev = idev_get_cfg(); 656 if (idev) 657 inl_dev = idev->nix_inl_dev; 658 659 if (inl_dev && flow->use_pre_alloc) 660 mbox = inl_dev->dev.mbox; 661 else 662 mbox = npc->mbox; 663 664 mcam_read_req = mbox_alloc_msg_npc_mcam_read_entry(mbox_get(mbox)); 665 if (mcam_read_req == NULL) { 666 plt_err("Failed to alloc msg"); 667 mbox_put(mbox); 668 return; 669 } 670 671 mcam_read_req->entry = flow->mcam_id; 672 rc = mbox_process_msg(mbox, (void *)&mcam_read_rsp); 673 if (rc) { 674 mbox_put(mbox); 675 plt_err("Failed to fetch MCAM entry:%d", flow->mcam_id); 676 return; 677 } 678 679 mbox_memcpy(mcam_data, mcam_read_rsp->entry_data.kw, sizeof(mcam_data)); 680 mbox_memcpy(mcam_mask, mcam_read_rsp->entry_data.kw_mask, sizeof(mcam_data)); 681 enabled = mcam_read_rsp->enable; 682 683 fprintf(file, "HW MCAM Data :\n"); 684 685 for (i = 0; i < ROC_NPC_MAX_MCAM_WIDTH_DWORDS; i++) { 686 fprintf(file, "\tDW%d :%016lX\n", i, mcam_data[i]); 687 fprintf(file, "\tDW%d_Mask:%016lX\n", i, mcam_mask[i]); 688 } 689 fprintf(file, "\tEnabled = 0x%x\n", enabled); 690 691 fprintf(file, "\n"); 692 mbox_put(mbox); 693 } 694 695 void 696 roc_npc_flow_mcam_dump(FILE *file, struct roc_npc *roc_npc, struct roc_npc_flow *flow) 697 { 698 struct npc *npc = roc_npc_to_npc_priv(roc_npc); 699 uint64_t count = 0; 700 bool is_rx = 0; 701 int i, rc = 0; 702 703 fprintf(file, "MCAM Index:%d\n", flow->mcam_id); 704 if (flow->ctr_id != NPC_COUNTER_NONE && flow->use_ctr) { 705 if (flow->use_pre_alloc) 706 rc = roc_npc_inl_mcam_read_counter(flow->ctr_id, &count); 707 else 708 rc = roc_npc_mcam_read_counter(roc_npc, flow->ctr_id, &count); 709 710 if (rc) 711 return; 712 fprintf(file, "Hit count: %" PRIu64 "\n", count); 713 } 714 715 fprintf(file, "Interface :%s (%d)\n", intf_str[flow->nix_intf], flow->nix_intf); 716 fprintf(file, "Priority :%d\n", flow->priority); 717 718 if (flow->nix_intf == NIX_INTF_RX) 719 is_rx = 1; 720 721 npc_flow_dump_parsed_action(file, flow->npc_action, is_rx); 722 npc_flow_dump_vtag_action(file, flow->vtag_action, is_rx); 723 fprintf(file, "Patterns:\n"); 724 npc_flow_dump_patterns(file, npc, flow); 725 726 fprintf(file, "MCAM Raw Data :\n"); 727 728 for (i = 0; i < ROC_NPC_MAX_MCAM_WIDTH_DWORDS; i++) { 729 fprintf(file, "\tDW%d :%016lX\n", i, flow->mcam_data[i]); 730 fprintf(file, "\tDW%d_Mask:%016lX\n", i, flow->mcam_mask[i]); 731 } 732 733 npc_flow_hw_mcam_entry_dump(file, npc, flow); 734 } 735