18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0
28c2ecf20Sopenharmony_ci/*
38c2ecf20Sopenharmony_ci * Driver for Marvell PPv2 network controller for Armada 375 SoC.
48c2ecf20Sopenharmony_ci *
58c2ecf20Sopenharmony_ci * Copyright (C) 2018 Marvell
68c2ecf20Sopenharmony_ci */
78c2ecf20Sopenharmony_ci
88c2ecf20Sopenharmony_ci#include <linux/kernel.h>
98c2ecf20Sopenharmony_ci#include <linux/slab.h>
108c2ecf20Sopenharmony_ci#include <linux/debugfs.h>
118c2ecf20Sopenharmony_ci
128c2ecf20Sopenharmony_ci#include "mvpp2.h"
138c2ecf20Sopenharmony_ci#include "mvpp2_prs.h"
148c2ecf20Sopenharmony_ci#include "mvpp2_cls.h"
158c2ecf20Sopenharmony_ci
168c2ecf20Sopenharmony_cistruct mvpp2_dbgfs_prs_entry {
178c2ecf20Sopenharmony_ci	int tid;
188c2ecf20Sopenharmony_ci	struct mvpp2 *priv;
198c2ecf20Sopenharmony_ci};
208c2ecf20Sopenharmony_ci
218c2ecf20Sopenharmony_cistruct mvpp2_dbgfs_c2_entry {
228c2ecf20Sopenharmony_ci	int id;
238c2ecf20Sopenharmony_ci	struct mvpp2 *priv;
248c2ecf20Sopenharmony_ci};
258c2ecf20Sopenharmony_ci
268c2ecf20Sopenharmony_cistruct mvpp2_dbgfs_flow_entry {
278c2ecf20Sopenharmony_ci	int flow;
288c2ecf20Sopenharmony_ci	struct mvpp2 *priv;
298c2ecf20Sopenharmony_ci};
308c2ecf20Sopenharmony_ci
318c2ecf20Sopenharmony_cistruct mvpp2_dbgfs_flow_tbl_entry {
328c2ecf20Sopenharmony_ci	int id;
338c2ecf20Sopenharmony_ci	struct mvpp2 *priv;
348c2ecf20Sopenharmony_ci};
358c2ecf20Sopenharmony_ci
368c2ecf20Sopenharmony_cistruct mvpp2_dbgfs_port_flow_entry {
378c2ecf20Sopenharmony_ci	struct mvpp2_port *port;
388c2ecf20Sopenharmony_ci	struct mvpp2_dbgfs_flow_entry *dbg_fe;
398c2ecf20Sopenharmony_ci};
408c2ecf20Sopenharmony_ci
418c2ecf20Sopenharmony_cistruct mvpp2_dbgfs_entries {
428c2ecf20Sopenharmony_ci	/* Entries for Header Parser debug info */
438c2ecf20Sopenharmony_ci	struct mvpp2_dbgfs_prs_entry prs_entries[MVPP2_PRS_TCAM_SRAM_SIZE];
448c2ecf20Sopenharmony_ci
458c2ecf20Sopenharmony_ci	/* Entries for Classifier C2 engine debug info */
468c2ecf20Sopenharmony_ci	struct mvpp2_dbgfs_c2_entry c2_entries[MVPP22_CLS_C2_N_ENTRIES];
478c2ecf20Sopenharmony_ci
488c2ecf20Sopenharmony_ci	/* Entries for Classifier Flow Table debug info */
498c2ecf20Sopenharmony_ci	struct mvpp2_dbgfs_flow_tbl_entry flt_entries[MVPP2_CLS_FLOWS_TBL_SIZE];
508c2ecf20Sopenharmony_ci
518c2ecf20Sopenharmony_ci	/* Entries for Classifier flows debug info */
528c2ecf20Sopenharmony_ci	struct mvpp2_dbgfs_flow_entry flow_entries[MVPP2_N_PRS_FLOWS];
538c2ecf20Sopenharmony_ci
548c2ecf20Sopenharmony_ci	/* Entries for per-port flows debug info */
558c2ecf20Sopenharmony_ci	struct mvpp2_dbgfs_port_flow_entry port_flow_entries[MVPP2_MAX_PORTS];
568c2ecf20Sopenharmony_ci};
578c2ecf20Sopenharmony_ci
588c2ecf20Sopenharmony_cistatic int mvpp2_dbgfs_flow_flt_hits_show(struct seq_file *s, void *unused)
598c2ecf20Sopenharmony_ci{
608c2ecf20Sopenharmony_ci	struct mvpp2_dbgfs_flow_tbl_entry *entry = s->private;
618c2ecf20Sopenharmony_ci
628c2ecf20Sopenharmony_ci	u32 hits = mvpp2_cls_flow_hits(entry->priv, entry->id);
638c2ecf20Sopenharmony_ci
648c2ecf20Sopenharmony_ci	seq_printf(s, "%u\n", hits);
658c2ecf20Sopenharmony_ci
668c2ecf20Sopenharmony_ci	return 0;
678c2ecf20Sopenharmony_ci}
688c2ecf20Sopenharmony_ci
698c2ecf20Sopenharmony_ciDEFINE_SHOW_ATTRIBUTE(mvpp2_dbgfs_flow_flt_hits);
708c2ecf20Sopenharmony_ci
718c2ecf20Sopenharmony_cistatic int mvpp2_dbgfs_flow_dec_hits_show(struct seq_file *s, void *unused)
728c2ecf20Sopenharmony_ci{
738c2ecf20Sopenharmony_ci	struct mvpp2_dbgfs_flow_entry *entry = s->private;
748c2ecf20Sopenharmony_ci
758c2ecf20Sopenharmony_ci	u32 hits = mvpp2_cls_lookup_hits(entry->priv, entry->flow);
768c2ecf20Sopenharmony_ci
778c2ecf20Sopenharmony_ci	seq_printf(s, "%u\n", hits);
788c2ecf20Sopenharmony_ci
798c2ecf20Sopenharmony_ci	return 0;
808c2ecf20Sopenharmony_ci}
818c2ecf20Sopenharmony_ci
828c2ecf20Sopenharmony_ciDEFINE_SHOW_ATTRIBUTE(mvpp2_dbgfs_flow_dec_hits);
838c2ecf20Sopenharmony_ci
848c2ecf20Sopenharmony_cistatic int mvpp2_dbgfs_flow_type_show(struct seq_file *s, void *unused)
858c2ecf20Sopenharmony_ci{
868c2ecf20Sopenharmony_ci	struct mvpp2_dbgfs_flow_entry *entry = s->private;
878c2ecf20Sopenharmony_ci	const struct mvpp2_cls_flow *f;
888c2ecf20Sopenharmony_ci	const char *flow_name;
898c2ecf20Sopenharmony_ci
908c2ecf20Sopenharmony_ci	f = mvpp2_cls_flow_get(entry->flow);
918c2ecf20Sopenharmony_ci	if (!f)
928c2ecf20Sopenharmony_ci		return -EINVAL;
938c2ecf20Sopenharmony_ci
948c2ecf20Sopenharmony_ci	switch (f->flow_type) {
958c2ecf20Sopenharmony_ci	case IPV4_FLOW:
968c2ecf20Sopenharmony_ci		flow_name = "ipv4";
978c2ecf20Sopenharmony_ci		break;
988c2ecf20Sopenharmony_ci	case IPV6_FLOW:
998c2ecf20Sopenharmony_ci		flow_name = "ipv6";
1008c2ecf20Sopenharmony_ci		break;
1018c2ecf20Sopenharmony_ci	case TCP_V4_FLOW:
1028c2ecf20Sopenharmony_ci		flow_name = "tcp4";
1038c2ecf20Sopenharmony_ci		break;
1048c2ecf20Sopenharmony_ci	case TCP_V6_FLOW:
1058c2ecf20Sopenharmony_ci		flow_name = "tcp6";
1068c2ecf20Sopenharmony_ci		break;
1078c2ecf20Sopenharmony_ci	case UDP_V4_FLOW:
1088c2ecf20Sopenharmony_ci		flow_name = "udp4";
1098c2ecf20Sopenharmony_ci		break;
1108c2ecf20Sopenharmony_ci	case UDP_V6_FLOW:
1118c2ecf20Sopenharmony_ci		flow_name = "udp6";
1128c2ecf20Sopenharmony_ci		break;
1138c2ecf20Sopenharmony_ci	default:
1148c2ecf20Sopenharmony_ci		flow_name = "other";
1158c2ecf20Sopenharmony_ci	}
1168c2ecf20Sopenharmony_ci
1178c2ecf20Sopenharmony_ci	seq_printf(s, "%s\n", flow_name);
1188c2ecf20Sopenharmony_ci
1198c2ecf20Sopenharmony_ci	return 0;
1208c2ecf20Sopenharmony_ci}
1218c2ecf20Sopenharmony_ci
1228c2ecf20Sopenharmony_ciDEFINE_SHOW_ATTRIBUTE(mvpp2_dbgfs_flow_type);
1238c2ecf20Sopenharmony_ci
1248c2ecf20Sopenharmony_cistatic int mvpp2_dbgfs_flow_id_show(struct seq_file *s, void *unused)
1258c2ecf20Sopenharmony_ci{
1268c2ecf20Sopenharmony_ci	const struct mvpp2_dbgfs_flow_entry *entry = s->private;
1278c2ecf20Sopenharmony_ci	const struct mvpp2_cls_flow *f;
1288c2ecf20Sopenharmony_ci
1298c2ecf20Sopenharmony_ci	f = mvpp2_cls_flow_get(entry->flow);
1308c2ecf20Sopenharmony_ci	if (!f)
1318c2ecf20Sopenharmony_ci		return -EINVAL;
1328c2ecf20Sopenharmony_ci
1338c2ecf20Sopenharmony_ci	seq_printf(s, "%d\n", f->flow_id);
1348c2ecf20Sopenharmony_ci
1358c2ecf20Sopenharmony_ci	return 0;
1368c2ecf20Sopenharmony_ci}
1378c2ecf20Sopenharmony_ci
1388c2ecf20Sopenharmony_ciDEFINE_SHOW_ATTRIBUTE(mvpp2_dbgfs_flow_id);
1398c2ecf20Sopenharmony_ci
1408c2ecf20Sopenharmony_cistatic int mvpp2_dbgfs_port_flow_hash_opt_show(struct seq_file *s, void *unused)
1418c2ecf20Sopenharmony_ci{
1428c2ecf20Sopenharmony_ci	struct mvpp2_dbgfs_port_flow_entry *entry = s->private;
1438c2ecf20Sopenharmony_ci	struct mvpp2_port *port = entry->port;
1448c2ecf20Sopenharmony_ci	struct mvpp2_cls_flow_entry fe;
1458c2ecf20Sopenharmony_ci	const struct mvpp2_cls_flow *f;
1468c2ecf20Sopenharmony_ci	int flow_index;
1478c2ecf20Sopenharmony_ci	u16 hash_opts;
1488c2ecf20Sopenharmony_ci
1498c2ecf20Sopenharmony_ci	f = mvpp2_cls_flow_get(entry->dbg_fe->flow);
1508c2ecf20Sopenharmony_ci	if (!f)
1518c2ecf20Sopenharmony_ci		return -EINVAL;
1528c2ecf20Sopenharmony_ci
1538c2ecf20Sopenharmony_ci	flow_index = MVPP2_CLS_FLT_HASH_ENTRY(entry->port->id, f->flow_id);
1548c2ecf20Sopenharmony_ci
1558c2ecf20Sopenharmony_ci	mvpp2_cls_flow_read(port->priv, flow_index, &fe);
1568c2ecf20Sopenharmony_ci
1578c2ecf20Sopenharmony_ci	hash_opts = mvpp2_flow_get_hek_fields(&fe);
1588c2ecf20Sopenharmony_ci
1598c2ecf20Sopenharmony_ci	seq_printf(s, "0x%04x\n", hash_opts);
1608c2ecf20Sopenharmony_ci
1618c2ecf20Sopenharmony_ci	return 0;
1628c2ecf20Sopenharmony_ci}
1638c2ecf20Sopenharmony_ci
1648c2ecf20Sopenharmony_ciDEFINE_SHOW_ATTRIBUTE(mvpp2_dbgfs_port_flow_hash_opt);
1658c2ecf20Sopenharmony_ci
1668c2ecf20Sopenharmony_cistatic int mvpp2_dbgfs_port_flow_engine_show(struct seq_file *s, void *unused)
1678c2ecf20Sopenharmony_ci{
1688c2ecf20Sopenharmony_ci	struct mvpp2_dbgfs_port_flow_entry *entry = s->private;
1698c2ecf20Sopenharmony_ci	struct mvpp2_port *port = entry->port;
1708c2ecf20Sopenharmony_ci	struct mvpp2_cls_flow_entry fe;
1718c2ecf20Sopenharmony_ci	const struct mvpp2_cls_flow *f;
1728c2ecf20Sopenharmony_ci	int flow_index, engine;
1738c2ecf20Sopenharmony_ci
1748c2ecf20Sopenharmony_ci	f = mvpp2_cls_flow_get(entry->dbg_fe->flow);
1758c2ecf20Sopenharmony_ci	if (!f)
1768c2ecf20Sopenharmony_ci		return -EINVAL;
1778c2ecf20Sopenharmony_ci
1788c2ecf20Sopenharmony_ci	flow_index = MVPP2_CLS_FLT_HASH_ENTRY(entry->port->id, f->flow_id);
1798c2ecf20Sopenharmony_ci
1808c2ecf20Sopenharmony_ci	mvpp2_cls_flow_read(port->priv, flow_index, &fe);
1818c2ecf20Sopenharmony_ci
1828c2ecf20Sopenharmony_ci	engine = mvpp2_cls_flow_eng_get(&fe);
1838c2ecf20Sopenharmony_ci
1848c2ecf20Sopenharmony_ci	seq_printf(s, "%d\n", engine);
1858c2ecf20Sopenharmony_ci
1868c2ecf20Sopenharmony_ci	return 0;
1878c2ecf20Sopenharmony_ci}
1888c2ecf20Sopenharmony_ci
1898c2ecf20Sopenharmony_ciDEFINE_SHOW_ATTRIBUTE(mvpp2_dbgfs_port_flow_engine);
1908c2ecf20Sopenharmony_ci
1918c2ecf20Sopenharmony_cistatic int mvpp2_dbgfs_flow_c2_hits_show(struct seq_file *s, void *unused)
1928c2ecf20Sopenharmony_ci{
1938c2ecf20Sopenharmony_ci	struct mvpp2_dbgfs_c2_entry *entry = s->private;
1948c2ecf20Sopenharmony_ci	u32 hits;
1958c2ecf20Sopenharmony_ci
1968c2ecf20Sopenharmony_ci	hits = mvpp2_cls_c2_hit_count(entry->priv, entry->id);
1978c2ecf20Sopenharmony_ci
1988c2ecf20Sopenharmony_ci	seq_printf(s, "%u\n", hits);
1998c2ecf20Sopenharmony_ci
2008c2ecf20Sopenharmony_ci	return 0;
2018c2ecf20Sopenharmony_ci}
2028c2ecf20Sopenharmony_ci
2038c2ecf20Sopenharmony_ciDEFINE_SHOW_ATTRIBUTE(mvpp2_dbgfs_flow_c2_hits);
2048c2ecf20Sopenharmony_ci
2058c2ecf20Sopenharmony_cistatic int mvpp2_dbgfs_flow_c2_rxq_show(struct seq_file *s, void *unused)
2068c2ecf20Sopenharmony_ci{
2078c2ecf20Sopenharmony_ci	struct mvpp2_dbgfs_c2_entry *entry = s->private;
2088c2ecf20Sopenharmony_ci	struct mvpp2_cls_c2_entry c2;
2098c2ecf20Sopenharmony_ci	u8 qh, ql;
2108c2ecf20Sopenharmony_ci
2118c2ecf20Sopenharmony_ci	mvpp2_cls_c2_read(entry->priv, entry->id, &c2);
2128c2ecf20Sopenharmony_ci
2138c2ecf20Sopenharmony_ci	qh = (c2.attr[0] >> MVPP22_CLS_C2_ATTR0_QHIGH_OFFS) &
2148c2ecf20Sopenharmony_ci	     MVPP22_CLS_C2_ATTR0_QHIGH_MASK;
2158c2ecf20Sopenharmony_ci
2168c2ecf20Sopenharmony_ci	ql = (c2.attr[0] >> MVPP22_CLS_C2_ATTR0_QLOW_OFFS) &
2178c2ecf20Sopenharmony_ci	     MVPP22_CLS_C2_ATTR0_QLOW_MASK;
2188c2ecf20Sopenharmony_ci
2198c2ecf20Sopenharmony_ci	seq_printf(s, "%d\n", (qh << 3 | ql));
2208c2ecf20Sopenharmony_ci
2218c2ecf20Sopenharmony_ci	return 0;
2228c2ecf20Sopenharmony_ci}
2238c2ecf20Sopenharmony_ci
2248c2ecf20Sopenharmony_ciDEFINE_SHOW_ATTRIBUTE(mvpp2_dbgfs_flow_c2_rxq);
2258c2ecf20Sopenharmony_ci
2268c2ecf20Sopenharmony_cistatic int mvpp2_dbgfs_flow_c2_enable_show(struct seq_file *s, void *unused)
2278c2ecf20Sopenharmony_ci{
2288c2ecf20Sopenharmony_ci	struct mvpp2_dbgfs_c2_entry *entry = s->private;
2298c2ecf20Sopenharmony_ci	struct mvpp2_cls_c2_entry c2;
2308c2ecf20Sopenharmony_ci	int enabled;
2318c2ecf20Sopenharmony_ci
2328c2ecf20Sopenharmony_ci	mvpp2_cls_c2_read(entry->priv, entry->id, &c2);
2338c2ecf20Sopenharmony_ci
2348c2ecf20Sopenharmony_ci	enabled = !!(c2.attr[2] & MVPP22_CLS_C2_ATTR2_RSS_EN);
2358c2ecf20Sopenharmony_ci
2368c2ecf20Sopenharmony_ci	seq_printf(s, "%d\n", enabled);
2378c2ecf20Sopenharmony_ci
2388c2ecf20Sopenharmony_ci	return 0;
2398c2ecf20Sopenharmony_ci}
2408c2ecf20Sopenharmony_ci
2418c2ecf20Sopenharmony_ciDEFINE_SHOW_ATTRIBUTE(mvpp2_dbgfs_flow_c2_enable);
2428c2ecf20Sopenharmony_ci
2438c2ecf20Sopenharmony_cistatic int mvpp2_dbgfs_port_vid_show(struct seq_file *s, void *unused)
2448c2ecf20Sopenharmony_ci{
2458c2ecf20Sopenharmony_ci	struct mvpp2_port *port = s->private;
2468c2ecf20Sopenharmony_ci	unsigned char byte[2], enable[2];
2478c2ecf20Sopenharmony_ci	struct mvpp2 *priv = port->priv;
2488c2ecf20Sopenharmony_ci	struct mvpp2_prs_entry pe;
2498c2ecf20Sopenharmony_ci	unsigned long pmap;
2508c2ecf20Sopenharmony_ci	u16 rvid;
2518c2ecf20Sopenharmony_ci	int tid;
2528c2ecf20Sopenharmony_ci
2538c2ecf20Sopenharmony_ci	for (tid = MVPP2_PRS_VID_PORT_FIRST(port->id);
2548c2ecf20Sopenharmony_ci	     tid <= MVPP2_PRS_VID_PORT_LAST(port->id); tid++) {
2558c2ecf20Sopenharmony_ci		mvpp2_prs_init_from_hw(priv, &pe, tid);
2568c2ecf20Sopenharmony_ci
2578c2ecf20Sopenharmony_ci		pmap = mvpp2_prs_tcam_port_map_get(&pe);
2588c2ecf20Sopenharmony_ci
2598c2ecf20Sopenharmony_ci		if (!priv->prs_shadow[tid].valid)
2608c2ecf20Sopenharmony_ci			continue;
2618c2ecf20Sopenharmony_ci
2628c2ecf20Sopenharmony_ci		if (!test_bit(port->id, &pmap))
2638c2ecf20Sopenharmony_ci			continue;
2648c2ecf20Sopenharmony_ci
2658c2ecf20Sopenharmony_ci		mvpp2_prs_tcam_data_byte_get(&pe, 2, &byte[0], &enable[0]);
2668c2ecf20Sopenharmony_ci		mvpp2_prs_tcam_data_byte_get(&pe, 3, &byte[1], &enable[1]);
2678c2ecf20Sopenharmony_ci
2688c2ecf20Sopenharmony_ci		rvid = ((byte[0] & 0xf) << 8) + byte[1];
2698c2ecf20Sopenharmony_ci
2708c2ecf20Sopenharmony_ci		seq_printf(s, "%u\n", rvid);
2718c2ecf20Sopenharmony_ci	}
2728c2ecf20Sopenharmony_ci
2738c2ecf20Sopenharmony_ci	return 0;
2748c2ecf20Sopenharmony_ci}
2758c2ecf20Sopenharmony_ci
2768c2ecf20Sopenharmony_ciDEFINE_SHOW_ATTRIBUTE(mvpp2_dbgfs_port_vid);
2778c2ecf20Sopenharmony_ci
2788c2ecf20Sopenharmony_cistatic int mvpp2_dbgfs_port_parser_show(struct seq_file *s, void *unused)
2798c2ecf20Sopenharmony_ci{
2808c2ecf20Sopenharmony_ci	struct mvpp2_port *port = s->private;
2818c2ecf20Sopenharmony_ci	struct mvpp2 *priv = port->priv;
2828c2ecf20Sopenharmony_ci	struct mvpp2_prs_entry pe;
2838c2ecf20Sopenharmony_ci	unsigned long pmap;
2848c2ecf20Sopenharmony_ci	int i;
2858c2ecf20Sopenharmony_ci
2868c2ecf20Sopenharmony_ci	for (i = 0; i < MVPP2_PRS_TCAM_SRAM_SIZE; i++) {
2878c2ecf20Sopenharmony_ci		mvpp2_prs_init_from_hw(port->priv, &pe, i);
2888c2ecf20Sopenharmony_ci
2898c2ecf20Sopenharmony_ci		pmap = mvpp2_prs_tcam_port_map_get(&pe);
2908c2ecf20Sopenharmony_ci		if (priv->prs_shadow[i].valid && test_bit(port->id, &pmap))
2918c2ecf20Sopenharmony_ci			seq_printf(s, "%03d\n", i);
2928c2ecf20Sopenharmony_ci	}
2938c2ecf20Sopenharmony_ci
2948c2ecf20Sopenharmony_ci	return 0;
2958c2ecf20Sopenharmony_ci}
2968c2ecf20Sopenharmony_ci
2978c2ecf20Sopenharmony_ciDEFINE_SHOW_ATTRIBUTE(mvpp2_dbgfs_port_parser);
2988c2ecf20Sopenharmony_ci
2998c2ecf20Sopenharmony_cistatic int mvpp2_dbgfs_filter_show(struct seq_file *s, void *unused)
3008c2ecf20Sopenharmony_ci{
3018c2ecf20Sopenharmony_ci	struct mvpp2_port *port = s->private;
3028c2ecf20Sopenharmony_ci	struct mvpp2 *priv = port->priv;
3038c2ecf20Sopenharmony_ci	struct mvpp2_prs_entry pe;
3048c2ecf20Sopenharmony_ci	unsigned long pmap;
3058c2ecf20Sopenharmony_ci	int index, tid;
3068c2ecf20Sopenharmony_ci
3078c2ecf20Sopenharmony_ci	for (tid = MVPP2_PE_MAC_RANGE_START;
3088c2ecf20Sopenharmony_ci	     tid <= MVPP2_PE_MAC_RANGE_END; tid++) {
3098c2ecf20Sopenharmony_ci		unsigned char da[ETH_ALEN], da_mask[ETH_ALEN];
3108c2ecf20Sopenharmony_ci
3118c2ecf20Sopenharmony_ci		if (!priv->prs_shadow[tid].valid ||
3128c2ecf20Sopenharmony_ci		    priv->prs_shadow[tid].lu != MVPP2_PRS_LU_MAC ||
3138c2ecf20Sopenharmony_ci		    priv->prs_shadow[tid].udf != MVPP2_PRS_UDF_MAC_DEF)
3148c2ecf20Sopenharmony_ci			continue;
3158c2ecf20Sopenharmony_ci
3168c2ecf20Sopenharmony_ci		mvpp2_prs_init_from_hw(priv, &pe, tid);
3178c2ecf20Sopenharmony_ci
3188c2ecf20Sopenharmony_ci		pmap = mvpp2_prs_tcam_port_map_get(&pe);
3198c2ecf20Sopenharmony_ci
3208c2ecf20Sopenharmony_ci		/* We only want entries active on this port */
3218c2ecf20Sopenharmony_ci		if (!test_bit(port->id, &pmap))
3228c2ecf20Sopenharmony_ci			continue;
3238c2ecf20Sopenharmony_ci
3248c2ecf20Sopenharmony_ci		/* Read mac addr from entry */
3258c2ecf20Sopenharmony_ci		for (index = 0; index < ETH_ALEN; index++)
3268c2ecf20Sopenharmony_ci			mvpp2_prs_tcam_data_byte_get(&pe, index, &da[index],
3278c2ecf20Sopenharmony_ci						     &da_mask[index]);
3288c2ecf20Sopenharmony_ci
3298c2ecf20Sopenharmony_ci		seq_printf(s, "%pM\n", da);
3308c2ecf20Sopenharmony_ci	}
3318c2ecf20Sopenharmony_ci
3328c2ecf20Sopenharmony_ci	return 0;
3338c2ecf20Sopenharmony_ci}
3348c2ecf20Sopenharmony_ci
3358c2ecf20Sopenharmony_ciDEFINE_SHOW_ATTRIBUTE(mvpp2_dbgfs_filter);
3368c2ecf20Sopenharmony_ci
3378c2ecf20Sopenharmony_cistatic int mvpp2_dbgfs_prs_lu_show(struct seq_file *s, void *unused)
3388c2ecf20Sopenharmony_ci{
3398c2ecf20Sopenharmony_ci	struct mvpp2_dbgfs_prs_entry *entry = s->private;
3408c2ecf20Sopenharmony_ci	struct mvpp2 *priv = entry->priv;
3418c2ecf20Sopenharmony_ci
3428c2ecf20Sopenharmony_ci	seq_printf(s, "%x\n", priv->prs_shadow[entry->tid].lu);
3438c2ecf20Sopenharmony_ci
3448c2ecf20Sopenharmony_ci	return 0;
3458c2ecf20Sopenharmony_ci}
3468c2ecf20Sopenharmony_ci
3478c2ecf20Sopenharmony_ciDEFINE_SHOW_ATTRIBUTE(mvpp2_dbgfs_prs_lu);
3488c2ecf20Sopenharmony_ci
3498c2ecf20Sopenharmony_cistatic int mvpp2_dbgfs_prs_pmap_show(struct seq_file *s, void *unused)
3508c2ecf20Sopenharmony_ci{
3518c2ecf20Sopenharmony_ci	struct mvpp2_dbgfs_prs_entry *entry = s->private;
3528c2ecf20Sopenharmony_ci	struct mvpp2_prs_entry pe;
3538c2ecf20Sopenharmony_ci	unsigned int pmap;
3548c2ecf20Sopenharmony_ci
3558c2ecf20Sopenharmony_ci	mvpp2_prs_init_from_hw(entry->priv, &pe, entry->tid);
3568c2ecf20Sopenharmony_ci
3578c2ecf20Sopenharmony_ci	pmap = mvpp2_prs_tcam_port_map_get(&pe);
3588c2ecf20Sopenharmony_ci	pmap &= MVPP2_PRS_PORT_MASK;
3598c2ecf20Sopenharmony_ci
3608c2ecf20Sopenharmony_ci	seq_printf(s, "%02x\n", pmap);
3618c2ecf20Sopenharmony_ci
3628c2ecf20Sopenharmony_ci	return 0;
3638c2ecf20Sopenharmony_ci}
3648c2ecf20Sopenharmony_ci
3658c2ecf20Sopenharmony_ciDEFINE_SHOW_ATTRIBUTE(mvpp2_dbgfs_prs_pmap);
3668c2ecf20Sopenharmony_ci
3678c2ecf20Sopenharmony_cistatic int mvpp2_dbgfs_prs_ai_show(struct seq_file *s, void *unused)
3688c2ecf20Sopenharmony_ci{
3698c2ecf20Sopenharmony_ci	struct mvpp2_dbgfs_prs_entry *entry = s->private;
3708c2ecf20Sopenharmony_ci	struct mvpp2_prs_entry pe;
3718c2ecf20Sopenharmony_ci	unsigned char ai, ai_mask;
3728c2ecf20Sopenharmony_ci
3738c2ecf20Sopenharmony_ci	mvpp2_prs_init_from_hw(entry->priv, &pe, entry->tid);
3748c2ecf20Sopenharmony_ci
3758c2ecf20Sopenharmony_ci	ai = pe.tcam[MVPP2_PRS_TCAM_AI_WORD] & MVPP2_PRS_AI_MASK;
3768c2ecf20Sopenharmony_ci	ai_mask = (pe.tcam[MVPP2_PRS_TCAM_AI_WORD] >> 16) & MVPP2_PRS_AI_MASK;
3778c2ecf20Sopenharmony_ci
3788c2ecf20Sopenharmony_ci	seq_printf(s, "%02x %02x\n", ai, ai_mask);
3798c2ecf20Sopenharmony_ci
3808c2ecf20Sopenharmony_ci	return 0;
3818c2ecf20Sopenharmony_ci}
3828c2ecf20Sopenharmony_ci
3838c2ecf20Sopenharmony_ciDEFINE_SHOW_ATTRIBUTE(mvpp2_dbgfs_prs_ai);
3848c2ecf20Sopenharmony_ci
3858c2ecf20Sopenharmony_cistatic int mvpp2_dbgfs_prs_hdata_show(struct seq_file *s, void *unused)
3868c2ecf20Sopenharmony_ci{
3878c2ecf20Sopenharmony_ci	struct mvpp2_dbgfs_prs_entry *entry = s->private;
3888c2ecf20Sopenharmony_ci	struct mvpp2_prs_entry pe;
3898c2ecf20Sopenharmony_ci	unsigned char data[8], mask[8];
3908c2ecf20Sopenharmony_ci	int i;
3918c2ecf20Sopenharmony_ci
3928c2ecf20Sopenharmony_ci	mvpp2_prs_init_from_hw(entry->priv, &pe, entry->tid);
3938c2ecf20Sopenharmony_ci
3948c2ecf20Sopenharmony_ci	for (i = 0; i < 8; i++)
3958c2ecf20Sopenharmony_ci		mvpp2_prs_tcam_data_byte_get(&pe, i, &data[i], &mask[i]);
3968c2ecf20Sopenharmony_ci
3978c2ecf20Sopenharmony_ci	seq_printf(s, "%*phN %*phN\n", 8, data, 8, mask);
3988c2ecf20Sopenharmony_ci
3998c2ecf20Sopenharmony_ci	return 0;
4008c2ecf20Sopenharmony_ci}
4018c2ecf20Sopenharmony_ci
4028c2ecf20Sopenharmony_ciDEFINE_SHOW_ATTRIBUTE(mvpp2_dbgfs_prs_hdata);
4038c2ecf20Sopenharmony_ci
4048c2ecf20Sopenharmony_cistatic int mvpp2_dbgfs_prs_sram_show(struct seq_file *s, void *unused)
4058c2ecf20Sopenharmony_ci{
4068c2ecf20Sopenharmony_ci	struct mvpp2_dbgfs_prs_entry *entry = s->private;
4078c2ecf20Sopenharmony_ci	struct mvpp2_prs_entry pe;
4088c2ecf20Sopenharmony_ci
4098c2ecf20Sopenharmony_ci	mvpp2_prs_init_from_hw(entry->priv, &pe, entry->tid);
4108c2ecf20Sopenharmony_ci
4118c2ecf20Sopenharmony_ci	seq_printf(s, "%*phN\n", 14, pe.sram);
4128c2ecf20Sopenharmony_ci
4138c2ecf20Sopenharmony_ci	return 0;
4148c2ecf20Sopenharmony_ci}
4158c2ecf20Sopenharmony_ci
4168c2ecf20Sopenharmony_ciDEFINE_SHOW_ATTRIBUTE(mvpp2_dbgfs_prs_sram);
4178c2ecf20Sopenharmony_ci
4188c2ecf20Sopenharmony_cistatic int mvpp2_dbgfs_prs_hits_show(struct seq_file *s, void *unused)
4198c2ecf20Sopenharmony_ci{
4208c2ecf20Sopenharmony_ci	struct mvpp2_dbgfs_prs_entry *entry = s->private;
4218c2ecf20Sopenharmony_ci	int val;
4228c2ecf20Sopenharmony_ci
4238c2ecf20Sopenharmony_ci	val = mvpp2_prs_hits(entry->priv, entry->tid);
4248c2ecf20Sopenharmony_ci	if (val < 0)
4258c2ecf20Sopenharmony_ci		return val;
4268c2ecf20Sopenharmony_ci
4278c2ecf20Sopenharmony_ci	seq_printf(s, "%d\n", val);
4288c2ecf20Sopenharmony_ci
4298c2ecf20Sopenharmony_ci	return 0;
4308c2ecf20Sopenharmony_ci}
4318c2ecf20Sopenharmony_ci
4328c2ecf20Sopenharmony_ciDEFINE_SHOW_ATTRIBUTE(mvpp2_dbgfs_prs_hits);
4338c2ecf20Sopenharmony_ci
4348c2ecf20Sopenharmony_cistatic int mvpp2_dbgfs_prs_valid_show(struct seq_file *s, void *unused)
4358c2ecf20Sopenharmony_ci{
4368c2ecf20Sopenharmony_ci	struct mvpp2_dbgfs_prs_entry *entry = s->private;
4378c2ecf20Sopenharmony_ci	struct mvpp2 *priv = entry->priv;
4388c2ecf20Sopenharmony_ci	int tid = entry->tid;
4398c2ecf20Sopenharmony_ci
4408c2ecf20Sopenharmony_ci	seq_printf(s, "%d\n", priv->prs_shadow[tid].valid ? 1 : 0);
4418c2ecf20Sopenharmony_ci
4428c2ecf20Sopenharmony_ci	return 0;
4438c2ecf20Sopenharmony_ci}
4448c2ecf20Sopenharmony_ci
4458c2ecf20Sopenharmony_ciDEFINE_SHOW_ATTRIBUTE(mvpp2_dbgfs_prs_valid);
4468c2ecf20Sopenharmony_ci
4478c2ecf20Sopenharmony_cistatic int mvpp2_dbgfs_flow_port_init(struct dentry *parent,
4488c2ecf20Sopenharmony_ci				      struct mvpp2_port *port,
4498c2ecf20Sopenharmony_ci				      struct mvpp2_dbgfs_flow_entry *entry)
4508c2ecf20Sopenharmony_ci{
4518c2ecf20Sopenharmony_ci	struct mvpp2_dbgfs_port_flow_entry *port_entry;
4528c2ecf20Sopenharmony_ci	struct dentry *port_dir;
4538c2ecf20Sopenharmony_ci
4548c2ecf20Sopenharmony_ci	port_dir = debugfs_create_dir(port->dev->name, parent);
4558c2ecf20Sopenharmony_ci
4568c2ecf20Sopenharmony_ci	port_entry = &port->priv->dbgfs_entries->port_flow_entries[port->id];
4578c2ecf20Sopenharmony_ci
4588c2ecf20Sopenharmony_ci	port_entry->port = port;
4598c2ecf20Sopenharmony_ci	port_entry->dbg_fe = entry;
4608c2ecf20Sopenharmony_ci
4618c2ecf20Sopenharmony_ci	debugfs_create_file("hash_opts", 0444, port_dir, port_entry,
4628c2ecf20Sopenharmony_ci			    &mvpp2_dbgfs_port_flow_hash_opt_fops);
4638c2ecf20Sopenharmony_ci
4648c2ecf20Sopenharmony_ci	debugfs_create_file("engine", 0444, port_dir, port_entry,
4658c2ecf20Sopenharmony_ci			    &mvpp2_dbgfs_port_flow_engine_fops);
4668c2ecf20Sopenharmony_ci
4678c2ecf20Sopenharmony_ci	return 0;
4688c2ecf20Sopenharmony_ci}
4698c2ecf20Sopenharmony_ci
4708c2ecf20Sopenharmony_cistatic int mvpp2_dbgfs_flow_entry_init(struct dentry *parent,
4718c2ecf20Sopenharmony_ci				       struct mvpp2 *priv, int flow)
4728c2ecf20Sopenharmony_ci{
4738c2ecf20Sopenharmony_ci	struct mvpp2_dbgfs_flow_entry *entry;
4748c2ecf20Sopenharmony_ci	struct dentry *flow_entry_dir;
4758c2ecf20Sopenharmony_ci	char flow_entry_name[10];
4768c2ecf20Sopenharmony_ci	int i, ret;
4778c2ecf20Sopenharmony_ci
4788c2ecf20Sopenharmony_ci	sprintf(flow_entry_name, "%02d", flow);
4798c2ecf20Sopenharmony_ci
4808c2ecf20Sopenharmony_ci	flow_entry_dir = debugfs_create_dir(flow_entry_name, parent);
4818c2ecf20Sopenharmony_ci
4828c2ecf20Sopenharmony_ci	entry = &priv->dbgfs_entries->flow_entries[flow];
4838c2ecf20Sopenharmony_ci
4848c2ecf20Sopenharmony_ci	entry->flow = flow;
4858c2ecf20Sopenharmony_ci	entry->priv = priv;
4868c2ecf20Sopenharmony_ci
4878c2ecf20Sopenharmony_ci	debugfs_create_file("dec_hits", 0444, flow_entry_dir, entry,
4888c2ecf20Sopenharmony_ci			    &mvpp2_dbgfs_flow_dec_hits_fops);
4898c2ecf20Sopenharmony_ci
4908c2ecf20Sopenharmony_ci	debugfs_create_file("type", 0444, flow_entry_dir, entry,
4918c2ecf20Sopenharmony_ci			    &mvpp2_dbgfs_flow_type_fops);
4928c2ecf20Sopenharmony_ci
4938c2ecf20Sopenharmony_ci	debugfs_create_file("id", 0444, flow_entry_dir, entry,
4948c2ecf20Sopenharmony_ci			    &mvpp2_dbgfs_flow_id_fops);
4958c2ecf20Sopenharmony_ci
4968c2ecf20Sopenharmony_ci	/* Create entry for each port */
4978c2ecf20Sopenharmony_ci	for (i = 0; i < priv->port_count; i++) {
4988c2ecf20Sopenharmony_ci		ret = mvpp2_dbgfs_flow_port_init(flow_entry_dir,
4998c2ecf20Sopenharmony_ci						 priv->port_list[i], entry);
5008c2ecf20Sopenharmony_ci		if (ret)
5018c2ecf20Sopenharmony_ci			return ret;
5028c2ecf20Sopenharmony_ci	}
5038c2ecf20Sopenharmony_ci
5048c2ecf20Sopenharmony_ci	return 0;
5058c2ecf20Sopenharmony_ci}
5068c2ecf20Sopenharmony_ci
5078c2ecf20Sopenharmony_cistatic int mvpp2_dbgfs_flow_init(struct dentry *parent, struct mvpp2 *priv)
5088c2ecf20Sopenharmony_ci{
5098c2ecf20Sopenharmony_ci	struct dentry *flow_dir;
5108c2ecf20Sopenharmony_ci	int i, ret;
5118c2ecf20Sopenharmony_ci
5128c2ecf20Sopenharmony_ci	flow_dir = debugfs_create_dir("flows", parent);
5138c2ecf20Sopenharmony_ci
5148c2ecf20Sopenharmony_ci	for (i = 0; i < MVPP2_N_PRS_FLOWS; i++) {
5158c2ecf20Sopenharmony_ci		ret = mvpp2_dbgfs_flow_entry_init(flow_dir, priv, i);
5168c2ecf20Sopenharmony_ci		if (ret)
5178c2ecf20Sopenharmony_ci			return ret;
5188c2ecf20Sopenharmony_ci	}
5198c2ecf20Sopenharmony_ci
5208c2ecf20Sopenharmony_ci	return 0;
5218c2ecf20Sopenharmony_ci}
5228c2ecf20Sopenharmony_ci
5238c2ecf20Sopenharmony_cistatic int mvpp2_dbgfs_prs_entry_init(struct dentry *parent,
5248c2ecf20Sopenharmony_ci				      struct mvpp2 *priv, int tid)
5258c2ecf20Sopenharmony_ci{
5268c2ecf20Sopenharmony_ci	struct mvpp2_dbgfs_prs_entry *entry;
5278c2ecf20Sopenharmony_ci	struct dentry *prs_entry_dir;
5288c2ecf20Sopenharmony_ci	char prs_entry_name[10];
5298c2ecf20Sopenharmony_ci
5308c2ecf20Sopenharmony_ci	if (tid >= MVPP2_PRS_TCAM_SRAM_SIZE)
5318c2ecf20Sopenharmony_ci		return -EINVAL;
5328c2ecf20Sopenharmony_ci
5338c2ecf20Sopenharmony_ci	sprintf(prs_entry_name, "%03d", tid);
5348c2ecf20Sopenharmony_ci
5358c2ecf20Sopenharmony_ci	prs_entry_dir = debugfs_create_dir(prs_entry_name, parent);
5368c2ecf20Sopenharmony_ci
5378c2ecf20Sopenharmony_ci	entry = &priv->dbgfs_entries->prs_entries[tid];
5388c2ecf20Sopenharmony_ci
5398c2ecf20Sopenharmony_ci	entry->tid = tid;
5408c2ecf20Sopenharmony_ci	entry->priv = priv;
5418c2ecf20Sopenharmony_ci
5428c2ecf20Sopenharmony_ci	/* Create each attr */
5438c2ecf20Sopenharmony_ci	debugfs_create_file("sram", 0444, prs_entry_dir, entry,
5448c2ecf20Sopenharmony_ci			    &mvpp2_dbgfs_prs_sram_fops);
5458c2ecf20Sopenharmony_ci
5468c2ecf20Sopenharmony_ci	debugfs_create_file("valid", 0644, prs_entry_dir, entry,
5478c2ecf20Sopenharmony_ci			    &mvpp2_dbgfs_prs_valid_fops);
5488c2ecf20Sopenharmony_ci
5498c2ecf20Sopenharmony_ci	debugfs_create_file("lookup_id", 0644, prs_entry_dir, entry,
5508c2ecf20Sopenharmony_ci			    &mvpp2_dbgfs_prs_lu_fops);
5518c2ecf20Sopenharmony_ci
5528c2ecf20Sopenharmony_ci	debugfs_create_file("ai", 0644, prs_entry_dir, entry,
5538c2ecf20Sopenharmony_ci			    &mvpp2_dbgfs_prs_ai_fops);
5548c2ecf20Sopenharmony_ci
5558c2ecf20Sopenharmony_ci	debugfs_create_file("header_data", 0644, prs_entry_dir, entry,
5568c2ecf20Sopenharmony_ci			    &mvpp2_dbgfs_prs_hdata_fops);
5578c2ecf20Sopenharmony_ci
5588c2ecf20Sopenharmony_ci	debugfs_create_file("hits", 0444, prs_entry_dir, entry,
5598c2ecf20Sopenharmony_ci			    &mvpp2_dbgfs_prs_hits_fops);
5608c2ecf20Sopenharmony_ci
5618c2ecf20Sopenharmony_ci	debugfs_create_file("pmap", 0444, prs_entry_dir, entry,
5628c2ecf20Sopenharmony_ci			     &mvpp2_dbgfs_prs_pmap_fops);
5638c2ecf20Sopenharmony_ci
5648c2ecf20Sopenharmony_ci	return 0;
5658c2ecf20Sopenharmony_ci}
5668c2ecf20Sopenharmony_ci
5678c2ecf20Sopenharmony_cistatic int mvpp2_dbgfs_prs_init(struct dentry *parent, struct mvpp2 *priv)
5688c2ecf20Sopenharmony_ci{
5698c2ecf20Sopenharmony_ci	struct dentry *prs_dir;
5708c2ecf20Sopenharmony_ci	int i, ret;
5718c2ecf20Sopenharmony_ci
5728c2ecf20Sopenharmony_ci	prs_dir = debugfs_create_dir("parser", parent);
5738c2ecf20Sopenharmony_ci
5748c2ecf20Sopenharmony_ci	for (i = 0; i < MVPP2_PRS_TCAM_SRAM_SIZE; i++) {
5758c2ecf20Sopenharmony_ci		ret = mvpp2_dbgfs_prs_entry_init(prs_dir, priv, i);
5768c2ecf20Sopenharmony_ci		if (ret)
5778c2ecf20Sopenharmony_ci			return ret;
5788c2ecf20Sopenharmony_ci	}
5798c2ecf20Sopenharmony_ci
5808c2ecf20Sopenharmony_ci	return 0;
5818c2ecf20Sopenharmony_ci}
5828c2ecf20Sopenharmony_ci
5838c2ecf20Sopenharmony_cistatic int mvpp2_dbgfs_c2_entry_init(struct dentry *parent,
5848c2ecf20Sopenharmony_ci				     struct mvpp2 *priv, int id)
5858c2ecf20Sopenharmony_ci{
5868c2ecf20Sopenharmony_ci	struct mvpp2_dbgfs_c2_entry *entry;
5878c2ecf20Sopenharmony_ci	struct dentry *c2_entry_dir;
5888c2ecf20Sopenharmony_ci	char c2_entry_name[10];
5898c2ecf20Sopenharmony_ci
5908c2ecf20Sopenharmony_ci	if (id >= MVPP22_CLS_C2_N_ENTRIES)
5918c2ecf20Sopenharmony_ci		return -EINVAL;
5928c2ecf20Sopenharmony_ci
5938c2ecf20Sopenharmony_ci	sprintf(c2_entry_name, "%03d", id);
5948c2ecf20Sopenharmony_ci
5958c2ecf20Sopenharmony_ci	c2_entry_dir = debugfs_create_dir(c2_entry_name, parent);
5968c2ecf20Sopenharmony_ci	if (!c2_entry_dir)
5978c2ecf20Sopenharmony_ci		return -ENOMEM;
5988c2ecf20Sopenharmony_ci
5998c2ecf20Sopenharmony_ci	entry = &priv->dbgfs_entries->c2_entries[id];
6008c2ecf20Sopenharmony_ci
6018c2ecf20Sopenharmony_ci	entry->id = id;
6028c2ecf20Sopenharmony_ci	entry->priv = priv;
6038c2ecf20Sopenharmony_ci
6048c2ecf20Sopenharmony_ci	debugfs_create_file("hits", 0444, c2_entry_dir, entry,
6058c2ecf20Sopenharmony_ci			    &mvpp2_dbgfs_flow_c2_hits_fops);
6068c2ecf20Sopenharmony_ci
6078c2ecf20Sopenharmony_ci	debugfs_create_file("default_rxq", 0444, c2_entry_dir, entry,
6088c2ecf20Sopenharmony_ci			    &mvpp2_dbgfs_flow_c2_rxq_fops);
6098c2ecf20Sopenharmony_ci
6108c2ecf20Sopenharmony_ci	debugfs_create_file("rss_enable", 0444, c2_entry_dir, entry,
6118c2ecf20Sopenharmony_ci			    &mvpp2_dbgfs_flow_c2_enable_fops);
6128c2ecf20Sopenharmony_ci
6138c2ecf20Sopenharmony_ci	return 0;
6148c2ecf20Sopenharmony_ci}
6158c2ecf20Sopenharmony_ci
6168c2ecf20Sopenharmony_cistatic int mvpp2_dbgfs_flow_tbl_entry_init(struct dentry *parent,
6178c2ecf20Sopenharmony_ci					   struct mvpp2 *priv, int id)
6188c2ecf20Sopenharmony_ci{
6198c2ecf20Sopenharmony_ci	struct mvpp2_dbgfs_flow_tbl_entry *entry;
6208c2ecf20Sopenharmony_ci	struct dentry *flow_tbl_entry_dir;
6218c2ecf20Sopenharmony_ci	char flow_tbl_entry_name[10];
6228c2ecf20Sopenharmony_ci
6238c2ecf20Sopenharmony_ci	if (id >= MVPP2_CLS_FLOWS_TBL_SIZE)
6248c2ecf20Sopenharmony_ci		return -EINVAL;
6258c2ecf20Sopenharmony_ci
6268c2ecf20Sopenharmony_ci	sprintf(flow_tbl_entry_name, "%03d", id);
6278c2ecf20Sopenharmony_ci
6288c2ecf20Sopenharmony_ci	flow_tbl_entry_dir = debugfs_create_dir(flow_tbl_entry_name, parent);
6298c2ecf20Sopenharmony_ci	if (!flow_tbl_entry_dir)
6308c2ecf20Sopenharmony_ci		return -ENOMEM;
6318c2ecf20Sopenharmony_ci
6328c2ecf20Sopenharmony_ci	entry = &priv->dbgfs_entries->flt_entries[id];
6338c2ecf20Sopenharmony_ci
6348c2ecf20Sopenharmony_ci	entry->id = id;
6358c2ecf20Sopenharmony_ci	entry->priv = priv;
6368c2ecf20Sopenharmony_ci
6378c2ecf20Sopenharmony_ci	debugfs_create_file("hits", 0444, flow_tbl_entry_dir, entry,
6388c2ecf20Sopenharmony_ci			    &mvpp2_dbgfs_flow_flt_hits_fops);
6398c2ecf20Sopenharmony_ci
6408c2ecf20Sopenharmony_ci	return 0;
6418c2ecf20Sopenharmony_ci}
6428c2ecf20Sopenharmony_ci
6438c2ecf20Sopenharmony_cistatic int mvpp2_dbgfs_cls_init(struct dentry *parent, struct mvpp2 *priv)
6448c2ecf20Sopenharmony_ci{
6458c2ecf20Sopenharmony_ci	struct dentry *cls_dir, *c2_dir, *flow_tbl_dir;
6468c2ecf20Sopenharmony_ci	int i, ret;
6478c2ecf20Sopenharmony_ci
6488c2ecf20Sopenharmony_ci	cls_dir = debugfs_create_dir("classifier", parent);
6498c2ecf20Sopenharmony_ci	if (!cls_dir)
6508c2ecf20Sopenharmony_ci		return -ENOMEM;
6518c2ecf20Sopenharmony_ci
6528c2ecf20Sopenharmony_ci	c2_dir = debugfs_create_dir("c2", cls_dir);
6538c2ecf20Sopenharmony_ci	if (!c2_dir)
6548c2ecf20Sopenharmony_ci		return -ENOMEM;
6558c2ecf20Sopenharmony_ci
6568c2ecf20Sopenharmony_ci	for (i = 0; i < MVPP22_CLS_C2_N_ENTRIES; i++) {
6578c2ecf20Sopenharmony_ci		ret = mvpp2_dbgfs_c2_entry_init(c2_dir, priv, i);
6588c2ecf20Sopenharmony_ci		if (ret)
6598c2ecf20Sopenharmony_ci			return ret;
6608c2ecf20Sopenharmony_ci	}
6618c2ecf20Sopenharmony_ci
6628c2ecf20Sopenharmony_ci	flow_tbl_dir = debugfs_create_dir("flow_table", cls_dir);
6638c2ecf20Sopenharmony_ci	if (!flow_tbl_dir)
6648c2ecf20Sopenharmony_ci		return -ENOMEM;
6658c2ecf20Sopenharmony_ci
6668c2ecf20Sopenharmony_ci	for (i = 0; i < MVPP2_CLS_FLOWS_TBL_SIZE; i++) {
6678c2ecf20Sopenharmony_ci		ret = mvpp2_dbgfs_flow_tbl_entry_init(flow_tbl_dir, priv, i);
6688c2ecf20Sopenharmony_ci		if (ret)
6698c2ecf20Sopenharmony_ci			return ret;
6708c2ecf20Sopenharmony_ci	}
6718c2ecf20Sopenharmony_ci
6728c2ecf20Sopenharmony_ci	return 0;
6738c2ecf20Sopenharmony_ci}
6748c2ecf20Sopenharmony_ci
6758c2ecf20Sopenharmony_cistatic int mvpp2_dbgfs_port_init(struct dentry *parent,
6768c2ecf20Sopenharmony_ci				 struct mvpp2_port *port)
6778c2ecf20Sopenharmony_ci{
6788c2ecf20Sopenharmony_ci	struct dentry *port_dir;
6798c2ecf20Sopenharmony_ci
6808c2ecf20Sopenharmony_ci	port_dir = debugfs_create_dir(port->dev->name, parent);
6818c2ecf20Sopenharmony_ci
6828c2ecf20Sopenharmony_ci	debugfs_create_file("parser_entries", 0444, port_dir, port,
6838c2ecf20Sopenharmony_ci			    &mvpp2_dbgfs_port_parser_fops);
6848c2ecf20Sopenharmony_ci
6858c2ecf20Sopenharmony_ci	debugfs_create_file("mac_filter", 0444, port_dir, port,
6868c2ecf20Sopenharmony_ci			    &mvpp2_dbgfs_filter_fops);
6878c2ecf20Sopenharmony_ci
6888c2ecf20Sopenharmony_ci	debugfs_create_file("vid_filter", 0444, port_dir, port,
6898c2ecf20Sopenharmony_ci			    &mvpp2_dbgfs_port_vid_fops);
6908c2ecf20Sopenharmony_ci
6918c2ecf20Sopenharmony_ci	return 0;
6928c2ecf20Sopenharmony_ci}
6938c2ecf20Sopenharmony_ci
6948c2ecf20Sopenharmony_cistatic struct dentry *mvpp2_root;
6958c2ecf20Sopenharmony_ci
6968c2ecf20Sopenharmony_civoid mvpp2_dbgfs_exit(void)
6978c2ecf20Sopenharmony_ci{
6988c2ecf20Sopenharmony_ci	debugfs_remove(mvpp2_root);
6998c2ecf20Sopenharmony_ci}
7008c2ecf20Sopenharmony_ci
7018c2ecf20Sopenharmony_civoid mvpp2_dbgfs_cleanup(struct mvpp2 *priv)
7028c2ecf20Sopenharmony_ci{
7038c2ecf20Sopenharmony_ci	debugfs_remove_recursive(priv->dbgfs_dir);
7048c2ecf20Sopenharmony_ci
7058c2ecf20Sopenharmony_ci	kfree(priv->dbgfs_entries);
7068c2ecf20Sopenharmony_ci}
7078c2ecf20Sopenharmony_ci
7088c2ecf20Sopenharmony_civoid mvpp2_dbgfs_init(struct mvpp2 *priv, const char *name)
7098c2ecf20Sopenharmony_ci{
7108c2ecf20Sopenharmony_ci	struct dentry *mvpp2_dir;
7118c2ecf20Sopenharmony_ci	int ret, i;
7128c2ecf20Sopenharmony_ci
7138c2ecf20Sopenharmony_ci	if (!mvpp2_root)
7148c2ecf20Sopenharmony_ci		mvpp2_root = debugfs_create_dir(MVPP2_DRIVER_NAME, NULL);
7158c2ecf20Sopenharmony_ci
7168c2ecf20Sopenharmony_ci	mvpp2_dir = debugfs_create_dir(name, mvpp2_root);
7178c2ecf20Sopenharmony_ci
7188c2ecf20Sopenharmony_ci	priv->dbgfs_dir = mvpp2_dir;
7198c2ecf20Sopenharmony_ci	priv->dbgfs_entries = kzalloc(sizeof(*priv->dbgfs_entries), GFP_KERNEL);
7208c2ecf20Sopenharmony_ci	if (!priv->dbgfs_entries)
7218c2ecf20Sopenharmony_ci		goto err;
7228c2ecf20Sopenharmony_ci
7238c2ecf20Sopenharmony_ci	ret = mvpp2_dbgfs_prs_init(mvpp2_dir, priv);
7248c2ecf20Sopenharmony_ci	if (ret)
7258c2ecf20Sopenharmony_ci		goto err;
7268c2ecf20Sopenharmony_ci
7278c2ecf20Sopenharmony_ci	ret = mvpp2_dbgfs_cls_init(mvpp2_dir, priv);
7288c2ecf20Sopenharmony_ci	if (ret)
7298c2ecf20Sopenharmony_ci		goto err;
7308c2ecf20Sopenharmony_ci
7318c2ecf20Sopenharmony_ci	for (i = 0; i < priv->port_count; i++) {
7328c2ecf20Sopenharmony_ci		ret = mvpp2_dbgfs_port_init(mvpp2_dir, priv->port_list[i]);
7338c2ecf20Sopenharmony_ci		if (ret)
7348c2ecf20Sopenharmony_ci			goto err;
7358c2ecf20Sopenharmony_ci	}
7368c2ecf20Sopenharmony_ci
7378c2ecf20Sopenharmony_ci	ret = mvpp2_dbgfs_flow_init(mvpp2_dir, priv);
7388c2ecf20Sopenharmony_ci	if (ret)
7398c2ecf20Sopenharmony_ci		goto err;
7408c2ecf20Sopenharmony_ci
7418c2ecf20Sopenharmony_ci	return;
7428c2ecf20Sopenharmony_cierr:
7438c2ecf20Sopenharmony_ci	mvpp2_dbgfs_cleanup(priv);
7448c2ecf20Sopenharmony_ci}
745