common/cnxk: move instruction queue enable to ROC
[dpdk.git] / drivers / common / cnxk / roc_npc_mcam_dump.c
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 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;
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_LB][0] = "NONE",
73         [NPC_LID_LB][NPC_LT_LB_CTAG] = "LB_CTAG",
74         [NPC_LID_LB][NPC_LT_LB_STAG_QINQ] = "LB_STAG_QINQ",
75         [NPC_LID_LB][NPC_LT_LB_ETAG] = "LB_ETAG",
76         [NPC_LID_LB][NPC_LT_LB_EXDSA] = "LB_EXDSA",
77         [NPC_LID_LB][NPC_LT_LB_VLAN_EXDSA] = "LB_VLAN_EXDSA",
78         [NPC_LID_LC][0] = "NONE",
79         [NPC_LID_LC][NPC_LT_LC_IP] = "LC_IP",
80         [NPC_LID_LC][NPC_LT_LC_IP6] = "LC_IP6",
81         [NPC_LID_LC][NPC_LT_LC_ARP] = "LC_ARP",
82         [NPC_LID_LC][NPC_LT_LC_IP6_EXT] = "LC_IP6_EXT",
83         [NPC_LID_LC][NPC_LT_LC_NGIO] = "LC_NGIO",
84         [NPC_LID_LD][0] = "NONE",
85         [NPC_LID_LD][NPC_LT_LD_ICMP] = "LD_ICMP",
86         [NPC_LID_LD][NPC_LT_LD_ICMP6] = "LD_ICMP6",
87         [NPC_LID_LD][NPC_LT_LD_UDP] = "LD_UDP",
88         [NPC_LID_LD][NPC_LT_LD_TCP] = "LD_TCP",
89         [NPC_LID_LD][NPC_LT_LD_SCTP] = "LD_SCTP",
90         [NPC_LID_LD][NPC_LT_LD_GRE] = "LD_GRE",
91         [NPC_LID_LD][NPC_LT_LD_NVGRE] = "LD_NVGRE",
92         [NPC_LID_LE][0] = "NONE",
93         [NPC_LID_LE][NPC_LT_LE_VXLAN] = "LE_VXLAN",
94         [NPC_LID_LE][NPC_LT_LE_ESP] = "LE_ESP",
95         [NPC_LID_LE][NPC_LT_LE_GTPC] = "LE_GTPC",
96         [NPC_LID_LE][NPC_LT_LE_GTPU] = "LE_GTPU",
97         [NPC_LID_LE][NPC_LT_LE_GENEVE] = "LE_GENEVE",
98         [NPC_LID_LE][NPC_LT_LE_VXLANGPE] = "LE_VXLANGPE",
99         [NPC_LID_LF][0] = "NONE",
100         [NPC_LID_LF][NPC_LT_LF_TU_ETHER] = "LF_TU_ETHER",
101         [NPC_LID_LG][0] = "NONE",
102         [NPC_LID_LG][NPC_LT_LG_TU_IP] = "LG_TU_IP",
103         [NPC_LID_LG][NPC_LT_LG_TU_IP6] = "LG_TU_IP6",
104         [NPC_LID_LH][0] = "NONE",
105         [NPC_LID_LH][NPC_LT_LH_TU_UDP] = "LH_TU_UDP",
106         [NPC_LID_LH][NPC_LT_LH_TU_TCP] = "LH_TU_TCP",
107         [NPC_LID_LH][NPC_LT_LH_TU_SCTP] = "LH_TU_SCTP",
108         [NPC_LID_LH][NPC_LT_LH_TU_ESP] = "LH_TU_ESP",
109 };
110
111 static uint16_t
112 npc_get_nibbles(struct roc_npc_flow *flow, uint16_t size, uint32_t bit_offset)
113 {
114         uint32_t byte_index, noffset;
115         uint16_t data, mask;
116         uint8_t *bytes;
117
118         bytes = (uint8_t *)flow->mcam_data;
119         mask = (1ULL << (size * 4)) - 1;
120         byte_index = bit_offset / 8;
121         noffset = bit_offset % 8;
122         data = *(unaligned_uint16_t *)&bytes[byte_index];
123         data >>= noffset;
124         data &= mask;
125
126         return data;
127 }
128
129 static void
130 npc_flow_print_parse_nibbles(FILE *file, struct roc_npc_flow *flow,
131                              uint64_t parse_nibbles)
132 {
133         struct npc_rx_parse_nibble_s *rx_parse;
134         uint32_t data, offset = 0;
135
136         rx_parse = (struct npc_rx_parse_nibble_s *)&parse_nibbles;
137
138         if (rx_parse->chan) {
139                 data = npc_get_nibbles(flow, 3, offset);
140                 fprintf(file, "\tNPC_PARSE_NIBBLE_CHAN:%#03X\n", data);
141                 offset += 12;
142         }
143
144         if (rx_parse->errlev) {
145                 data = npc_get_nibbles(flow, 1, offset);
146                 fprintf(file, "\tNPC_PARSE_NIBBLE_ERRLEV:%#X\n", data);
147                 offset += 4;
148         }
149
150         if (rx_parse->errcode) {
151                 data = npc_get_nibbles(flow, 2, offset);
152                 fprintf(file, "\tNPC_PARSE_NIBBLE_ERRCODE:%#02X\n", data);
153                 offset += 8;
154         }
155
156         if (rx_parse->l2l3bm) {
157                 data = npc_get_nibbles(flow, 1, offset);
158                 fprintf(file, "\tNPC_PARSE_NIBBLE_L2L3_BCAST:%#X\n", data);
159                 offset += 4;
160         }
161
162         if (rx_parse->latype) {
163                 data = npc_get_nibbles(flow, 1, offset);
164                 fprintf(file, "\tNPC_PARSE_NIBBLE_LA_LTYPE:%s\n",
165                         ltype_str[NPC_LID_LA][data]);
166                 offset += 4;
167         }
168
169         if (rx_parse->laflags) {
170                 data = npc_get_nibbles(flow, 2, offset);
171                 fprintf(file, "\tNPC_PARSE_NIBBLE_LA_FLAGS:%#02X\n", data);
172                 offset += 8;
173         }
174
175         if (rx_parse->lbtype) {
176                 data = npc_get_nibbles(flow, 1, offset);
177                 fprintf(file, "\tNPC_PARSE_NIBBLE_LB_LTYPE:%s\n",
178                         ltype_str[NPC_LID_LB][data]);
179                 offset += 4;
180         }
181
182         if (rx_parse->lbflags) {
183                 data = npc_get_nibbles(flow, 2, offset);
184                 fprintf(file, "\tNPC_PARSE_NIBBLE_LB_FLAGS:%#02X\n", data);
185                 offset += 8;
186         }
187
188         if (rx_parse->lctype) {
189                 data = npc_get_nibbles(flow, 1, offset);
190                 fprintf(file, "\tNPC_PARSE_NIBBLE_LC_LTYPE:%s\n",
191                         ltype_str[NPC_LID_LC][data]);
192                 offset += 4;
193         }
194
195         if (rx_parse->lcflags) {
196                 data = npc_get_nibbles(flow, 2, offset);
197                 fprintf(file, "\tNPC_PARSE_NIBBLE_LC_FLAGS:%#02X\n", data);
198                 offset += 8;
199         }
200
201         if (rx_parse->ldtype) {
202                 data = npc_get_nibbles(flow, 1, offset);
203                 fprintf(file, "\tNPC_PARSE_NIBBLE_LD_LTYPE:%s\n",
204                         ltype_str[NPC_LID_LD][data]);
205                 offset += 4;
206         }
207
208         if (rx_parse->ldflags) {
209                 data = npc_get_nibbles(flow, 2, offset);
210                 fprintf(file, "\tNPC_PARSE_NIBBLE_LD_FLAGS:%#02X\n", data);
211                 offset += 8;
212         }
213
214         if (rx_parse->letype) {
215                 data = npc_get_nibbles(flow, 1, offset);
216                 fprintf(file, "\tNPC_PARSE_NIBBLE_LE_LTYPE:%s\n",
217                         ltype_str[NPC_LID_LE][data]);
218                 offset += 4;
219         }
220
221         if (rx_parse->leflags) {
222                 data = npc_get_nibbles(flow, 2, offset);
223                 fprintf(file, "\tNPC_PARSE_NIBBLE_LE_FLAGS:%#02X\n", data);
224                 offset += 8;
225         }
226
227         if (rx_parse->lftype) {
228                 data = npc_get_nibbles(flow, 1, offset);
229                 fprintf(file, "\tNPC_PARSE_NIBBLE_LF_LTYPE:%s\n",
230                         ltype_str[NPC_LID_LF][data]);
231                 offset += 4;
232         }
233
234         if (rx_parse->lfflags) {
235                 data = npc_get_nibbles(flow, 2, offset);
236                 fprintf(file, "\tNPC_PARSE_NIBBLE_LF_FLAGS:%#02X\n", data);
237                 offset += 8;
238         }
239
240         if (rx_parse->lgtype) {
241                 data = npc_get_nibbles(flow, 1, offset);
242                 fprintf(file, "\tNPC_PARSE_NIBBLE_LG_LTYPE:%s\n",
243                         ltype_str[NPC_LID_LG][data]);
244                 offset += 4;
245         }
246
247         if (rx_parse->lgflags) {
248                 data = npc_get_nibbles(flow, 2, offset);
249                 fprintf(file, "\tNPC_PARSE_NIBBLE_LG_FLAGS:%#02X\n", data);
250                 offset += 8;
251         }
252
253         if (rx_parse->lhtype) {
254                 data = npc_get_nibbles(flow, 1, offset);
255                 fprintf(file, "\tNPC_PARSE_NIBBLE_LH_LTYPE:%s\n",
256                         ltype_str[NPC_LID_LH][data]);
257                 offset += 4;
258         }
259
260         if (rx_parse->lhflags) {
261                 data = npc_get_nibbles(flow, 2, offset);
262                 fprintf(file, "\tNPC_PARSE_NIBBLE_LH_FLAGS:%#02X\n", data);
263         }
264 }
265
266 static void
267 npc_flow_print_xtractinfo(FILE *file, struct npc_xtract_info *lfinfo,
268                           struct roc_npc_flow *flow, int lid, int lt)
269 {
270         uint8_t *datastart, *maskstart;
271         int i;
272
273         datastart = (uint8_t *)&flow->mcam_data + lfinfo->key_off;
274         maskstart = (uint8_t *)&flow->mcam_mask + lfinfo->key_off;
275
276         fprintf(file, "\t%s, hdr offset:%#X, len:%#X, key offset:%#X, ",
277                 ltype_str[lid][lt], lfinfo->hdr_off, lfinfo->len,
278                 lfinfo->key_off);
279
280         fprintf(file, "Data:0X");
281         for (i = lfinfo->len - 1; i >= 0; i--)
282                 fprintf(file, "%02X", datastart[i]);
283
284         fprintf(file, ", Mask:0X");
285
286         for (i = lfinfo->len - 1; i >= 0; i--)
287                 fprintf(file, "%02X", maskstart[i]);
288
289         fprintf(file, "\n");
290 }
291
292 static void
293 npc_flow_print_item(FILE *file, struct npc *npc, struct npc_xtract_info *xinfo,
294                     struct roc_npc_flow *flow, int intf, int lid, int lt,
295                     int ld)
296 {
297         struct npc_xtract_info *lflags_info;
298         int i, lf_cfg = 0;
299
300         npc_flow_print_xtractinfo(file, xinfo, flow, lid, lt);
301
302         if (xinfo->flags_enable) {
303                 lf_cfg = npc->prx_lfcfg[ld].i;
304
305                 if (lf_cfg != lid)
306                         return;
307
308                 for (i = 0; i < NPC_MAX_LFL; i++) {
309                         lflags_info = npc->prx_fxcfg[intf][ld][i].xtract;
310
311                         npc_flow_print_xtractinfo(file, lflags_info, flow, lid,
312                                                   lt);
313                 }
314         }
315 }
316
317 static void
318 npc_flow_dump_patterns(FILE *file, struct npc *npc, struct roc_npc_flow *flow)
319 {
320         struct npc_lid_lt_xtract_info *lt_xinfo;
321         struct npc_xtract_info *xinfo;
322         uint32_t intf, lid, ld, i;
323         uint64_t parse_nibbles;
324         uint16_t ltype;
325
326         intf = flow->nix_intf;
327         parse_nibbles = npc->keyx_supp_nmask[intf];
328         npc_flow_print_parse_nibbles(file, flow, parse_nibbles);
329
330         for (i = 0; i < flow->num_patterns; i++) {
331                 lid = flow->dump_data[i].lid;
332                 ltype = flow->dump_data[i].ltype;
333                 lt_xinfo = &npc->prx_dxcfg[intf][lid][ltype];
334
335                 for (ld = 0; ld < NPC_MAX_LD; ld++) {
336                         xinfo = &lt_xinfo->xtract[ld];
337                         if (!xinfo->enable)
338                                 continue;
339                         npc_flow_print_item(file, npc, xinfo, flow, intf, lid,
340                                             ltype, ld);
341                 }
342         }
343 }
344
345 static void
346 npc_flow_dump_tx_action(FILE *file, uint64_t npc_action)
347 {
348         char index_name[NPC_MAX_FIELD_NAME_SIZE] = "Index:";
349         uint32_t tx_op, index, match_id;
350
351         tx_op = npc_action & NPC_RX_ACTIONOP_MASK;
352
353         fprintf(file, "\tActionOp:");
354
355         switch (tx_op) {
356         case NIX_TX_ACTIONOP_DROP:
357                 fprintf(file, "NIX_TX_ACTIONOP_DROP (%" PRIu64 ")\n",
358                         (uint64_t)NIX_RX_ACTIONOP_DROP);
359                 break;
360         case NIX_TX_ACTIONOP_UCAST_DEFAULT:
361                 fprintf(file, "NIX_TX_ACTIONOP_UCAST_DEFAULT (%" PRIu64 ")\n",
362                         (uint64_t)NIX_TX_ACTIONOP_UCAST_DEFAULT);
363                 break;
364         case NIX_TX_ACTIONOP_UCAST_CHAN:
365                 fprintf(file, "NIX_TX_ACTIONOP_UCAST_DEFAULT (%" PRIu64 ")\n",
366                         (uint64_t)NIX_TX_ACTIONOP_UCAST_CHAN);
367                 plt_strlcpy(index_name,
368                             "Transmit Channel:", NPC_MAX_FIELD_NAME_SIZE);
369                 break;
370         case NIX_TX_ACTIONOP_MCAST:
371                 fprintf(file, "NIX_TX_ACTIONOP_MCAST (%" PRIu64 ")\n",
372                         (uint64_t)NIX_TX_ACTIONOP_MCAST);
373                 plt_strlcpy(index_name,
374                             "Multicast Table Index:", NPC_MAX_FIELD_NAME_SIZE);
375                 break;
376         case NIX_TX_ACTIONOP_DROP_VIOL:
377                 fprintf(file, "NIX_TX_ACTIONOP_DROP_VIOL (%" PRIu64 ")\n",
378                         (uint64_t)NIX_TX_ACTIONOP_DROP_VIOL);
379                 break;
380         default:
381                 plt_err("Unknown NIX_TX_ACTIONOP found");
382                 return;
383         }
384
385         index = ((npc_action & NPC_TX_ACTION_INDEX_MASK) >> 12) &
386                 GENMASK(19, 0);
387
388         fprintf(file, "\t%s:%#05X\n", index_name, index);
389
390         match_id = ((npc_action & NPC_TX_ACTION_MATCH_MASK) >> 32) &
391                    GENMASK(15, 0);
392
393         fprintf(file, "\tMatch Id:%#04X\n", match_id);
394 }
395
396 static void
397 npc_flow_dump_rx_action(FILE *file, uint64_t npc_action)
398 {
399         uint32_t rx_op, pf_func, index, match_id, flowkey_alg;
400         char index_name[NPC_MAX_FIELD_NAME_SIZE] = "Index:";
401
402         rx_op = npc_action & NPC_RX_ACTIONOP_MASK;
403
404         fprintf(file, "\tActionOp:");
405
406         switch (rx_op) {
407         case NIX_RX_ACTIONOP_DROP:
408                 fprintf(file, "NIX_RX_ACTIONOP_DROP (%" PRIu64 ")\n",
409                         (uint64_t)NIX_RX_ACTIONOP_DROP);
410                 break;
411         case NIX_RX_ACTIONOP_UCAST:
412                 fprintf(file, "NIX_RX_ACTIONOP_UCAST (%" PRIu64 ")\n",
413                         (uint64_t)NIX_RX_ACTIONOP_UCAST);
414                 plt_strlcpy(index_name, "RQ Index", NPC_MAX_FIELD_NAME_SIZE);
415                 break;
416         case NIX_RX_ACTIONOP_UCAST_IPSEC:
417                 fprintf(file, "NIX_RX_ACTIONOP_UCAST_IPSEC (%" PRIu64 ")\n",
418                         (uint64_t)NIX_RX_ACTIONOP_UCAST_IPSEC);
419                 plt_strlcpy(index_name, "RQ Index:", NPC_MAX_FIELD_NAME_SIZE);
420                 break;
421         case NIX_RX_ACTIONOP_MCAST:
422                 fprintf(file, "NIX_RX_ACTIONOP_MCAST (%" PRIu64 ")\n",
423                         (uint64_t)NIX_RX_ACTIONOP_MCAST);
424                 plt_strlcpy(index_name, "Multicast/mirror table index",
425                             NPC_MAX_FIELD_NAME_SIZE);
426                 break;
427         case NIX_RX_ACTIONOP_RSS:
428                 fprintf(file, "NIX_RX_ACTIONOP_RSS (%" PRIu64 ")\n",
429                         (uint64_t)NIX_RX_ACTIONOP_RSS);
430                 plt_strlcpy(index_name, "RSS Group Index",
431                             NPC_MAX_FIELD_NAME_SIZE);
432                 break;
433         case NIX_RX_ACTIONOP_PF_FUNC_DROP:
434                 fprintf(file, "NIX_RX_ACTIONOP_PF_FUNC_DROP (%" PRIu64 ")\n",
435                         (uint64_t)NIX_RX_ACTIONOP_PF_FUNC_DROP);
436                 break;
437         case NIX_RX_ACTIONOP_MIRROR:
438                 fprintf(file, "NIX_RX_ACTIONOP_MIRROR (%" PRIu64 ")\n",
439                         (uint64_t)NIX_RX_ACTIONOP_MIRROR);
440                 plt_strlcpy(index_name, "Multicast/mirror table index",
441                             NPC_MAX_FIELD_NAME_SIZE);
442                 break;
443         default:
444                 plt_err("Unknown NIX_RX_ACTIONOP found");
445                 return;
446         }
447
448         pf_func = ((npc_action & NPC_RX_ACTION_PFFUNC_MASK) >> 4) &
449                   GENMASK(15, 0);
450
451         fprintf(file, "\tPF_FUNC: %#04X\n", pf_func);
452
453         index = ((npc_action & NPC_RX_ACTION_INDEX_MASK) >> 20) &
454                 GENMASK(19, 0);
455
456         fprintf(file, "\t%s:%#05X\n", index_name, index);
457
458         match_id = ((npc_action & NPC_RX_ACTION_MATCH_MASK) >> 40) &
459                    GENMASK(15, 0);
460
461         fprintf(file, "\tMatch Id:%#04X\n", match_id);
462
463         flowkey_alg = ((npc_action & NPC_RX_ACTION_FLOWKEY_MASK) >> 56) &
464                       GENMASK(4, 0);
465
466         fprintf(file, "\tFlow Key Alg:%#X\n", flowkey_alg);
467 }
468
469 static void
470 npc_flow_dump_parsed_action(FILE *file, uint64_t npc_action, bool is_rx)
471 {
472         if (is_rx) {
473                 fprintf(file, "NPC RX Action:%#016lX\n", npc_action);
474                 npc_flow_dump_rx_action(file, npc_action);
475         } else {
476                 fprintf(file, "NPC TX Action:%#016lX\n", npc_action);
477                 npc_flow_dump_tx_action(file, npc_action);
478         }
479 }
480
481 static void
482 npc_flow_dump_rx_vtag_action(FILE *file, uint64_t vtag_action)
483 {
484         uint32_t type, lid, relptr;
485
486         if (vtag_action & NIX_RX_VTAGACT_VTAG0_VALID_MASK) {
487                 relptr = vtag_action & NIX_RX_VTAGACT_VTAG0_RELPTR_MASK;
488                 lid = ((vtag_action & NIX_RX_VTAGACT_VTAG0_LID_MASK) >> 8) &
489                       GENMASK(2, 0);
490                 type = ((vtag_action & NIX_RX_VTAGACT_VTAG0_TYPE_MASK) >> 12) &
491                        GENMASK(2, 0);
492
493                 fprintf(file, "\tVTAG0:relptr:%#X\n", relptr);
494                 fprintf(file, "\tlid:%#X\n", lid);
495                 fprintf(file, "\ttype:%#X\n", type);
496         }
497
498         if (vtag_action & NIX_RX_VTAGACT_VTAG1_VALID_MASK) {
499                 relptr = ((vtag_action & NIX_RX_VTAGACT_VTAG1_RELPTR_MASK) >>
500                           32) &
501                          GENMASK(7, 0);
502                 lid = ((vtag_action & NIX_RX_VTAGACT_VTAG1_LID_MASK) >> 40) &
503                       GENMASK(2, 0);
504                 type = ((vtag_action & NIX_RX_VTAGACT_VTAG1_TYPE_MASK) >> 44) &
505                        GENMASK(2, 0);
506
507                 fprintf(file, "\tVTAG1:relptr:%#X\n", relptr);
508                 fprintf(file, "\tlid:%#X\n", lid);
509                 fprintf(file, "\ttype:%#X\n", type);
510         }
511 }
512
513 static void
514 npc_get_vtag_opname(uint32_t op, char *opname, int len)
515 {
516         switch (op) {
517         case 0x0:
518                 plt_strlcpy(opname, "NOP", len - 1);
519                 break;
520         case 0x1:
521                 plt_strlcpy(opname, "INSERT", len - 1);
522                 break;
523         case 0x2:
524                 plt_strlcpy(opname, "REPLACE", len - 1);
525                 break;
526         default:
527                 plt_err("Unknown vtag op found");
528                 break;
529         }
530 }
531
532 static void
533 npc_flow_dump_tx_vtag_action(FILE *file, uint64_t vtag_action)
534 {
535         uint32_t relptr, lid, op, vtag_def;
536         char opname[10];
537
538         relptr = vtag_action & NIX_TX_VTAGACT_VTAG0_RELPTR_MASK;
539         lid = ((vtag_action & NIX_TX_VTAGACT_VTAG0_LID_MASK) >> 8) &
540               GENMASK(2, 0);
541         op = ((vtag_action & NIX_TX_VTAGACT_VTAG0_OP_MASK) >> 12) &
542              GENMASK(1, 0);
543         vtag_def = ((vtag_action & NIX_TX_VTAGACT_VTAG0_DEF_MASK) >> 16) &
544                    GENMASK(9, 0);
545
546         npc_get_vtag_opname(op, opname, sizeof(opname));
547
548         fprintf(file, "\tVTAG0 relptr:%#X\n", relptr);
549         fprintf(file, "\tlid:%#X\n", lid);
550         fprintf(file, "\top:%s\n", opname);
551         fprintf(file, "\tvtag_def:%#X\n", vtag_def);
552
553         relptr = ((vtag_action & NIX_TX_VTAGACT_VTAG1_RELPTR_MASK) >> 32) &
554                  GENMASK(7, 0);
555         lid = ((vtag_action & NIX_TX_VTAGACT_VTAG1_LID_MASK) >> 40) &
556               GENMASK(2, 0);
557         op = ((vtag_action & NIX_TX_VTAGACT_VTAG1_OP_MASK) >> 44) &
558              GENMASK(1, 0);
559         vtag_def = ((vtag_action & NIX_TX_VTAGACT_VTAG1_DEF_MASK) >> 48) &
560                    GENMASK(9, 0);
561
562         npc_get_vtag_opname(op, opname, sizeof(opname));
563
564         fprintf(file, "\tVTAG1:relptr:%#X\n", relptr);
565         fprintf(file, "\tlid:%#X\n", lid);
566         fprintf(file, "\top:%s\n", opname);
567         fprintf(file, "\tvtag_def:%#X\n", vtag_def);
568 }
569
570 static void
571 npc_flow_dump_vtag_action(FILE *file, uint64_t vtag_action, bool is_rx)
572 {
573         if (is_rx) {
574                 fprintf(file, "NPC RX VTAG Action:%#016lX\n", vtag_action);
575                 npc_flow_dump_rx_vtag_action(file, vtag_action);
576         } else {
577                 fprintf(file, "NPC TX VTAG Action:%#016lX\n", vtag_action);
578                 npc_flow_dump_tx_vtag_action(file, vtag_action);
579         }
580 }
581
582 void
583 roc_npc_flow_mcam_dump(FILE *file, struct roc_npc *roc_npc,
584                        struct roc_npc_flow *flow)
585 {
586         struct npc *npc = roc_npc_to_npc_priv(roc_npc);
587         bool is_rx = 0;
588         int i;
589
590         fprintf(file, "MCAM Index:%d\n", flow->mcam_id);
591         fprintf(file, "Interface :%s (%d)\n", intf_str[flow->nix_intf],
592                 flow->nix_intf);
593         fprintf(file, "Priority  :%d\n", flow->priority);
594
595         if (flow->nix_intf == NIX_INTF_RX)
596                 is_rx = 1;
597
598         npc_flow_dump_parsed_action(file, flow->npc_action, is_rx);
599         npc_flow_dump_vtag_action(file, flow->vtag_action, is_rx);
600         fprintf(file, "Patterns:\n");
601         npc_flow_dump_patterns(file, npc, flow);
602
603         fprintf(file, "MCAM Raw Data :\n");
604
605         for (i = 0; i < ROC_NPC_MAX_MCAM_WIDTH_DWORDS; i++) {
606                 fprintf(file, "\tDW%d     :%016lX\n", i, flow->mcam_data[i]);
607                 fprintf(file, "\tDW%d_Mask:%016lX\n", i, flow->mcam_mask[i]);
608         }
609
610         fprintf(file, "\n");
611 }