121da57a2SMaxime Chevallier // SPDX-License-Identifier: GPL-2.0
221da57a2SMaxime Chevallier /*
321da57a2SMaxime Chevallier * Driver for Marvell PPv2 network controller for Armada 375 SoC.
421da57a2SMaxime Chevallier *
521da57a2SMaxime Chevallier * Copyright (C) 2018 Marvell
621da57a2SMaxime Chevallier */
721da57a2SMaxime Chevallier
821da57a2SMaxime Chevallier #include <linux/kernel.h>
921da57a2SMaxime Chevallier #include <linux/slab.h>
1021da57a2SMaxime Chevallier #include <linux/debugfs.h>
1121da57a2SMaxime Chevallier
1221da57a2SMaxime Chevallier #include "mvpp2.h"
1321da57a2SMaxime Chevallier #include "mvpp2_prs.h"
14dba1d918SMaxime Chevallier #include "mvpp2_cls.h"
1521da57a2SMaxime Chevallier
1621da57a2SMaxime Chevallier struct mvpp2_dbgfs_prs_entry {
1721da57a2SMaxime Chevallier int tid;
1821da57a2SMaxime Chevallier struct mvpp2 *priv;
1921da57a2SMaxime Chevallier };
2021da57a2SMaxime Chevallier
21b607cc61SMaxime Chevallier struct mvpp2_dbgfs_c2_entry {
22b607cc61SMaxime Chevallier int id;
23b607cc61SMaxime Chevallier struct mvpp2 *priv;
24b607cc61SMaxime Chevallier };
25b607cc61SMaxime Chevallier
26dba1d918SMaxime Chevallier struct mvpp2_dbgfs_flow_entry {
27dba1d918SMaxime Chevallier int flow;
28dba1d918SMaxime Chevallier struct mvpp2 *priv;
29dba1d918SMaxime Chevallier };
30dba1d918SMaxime Chevallier
318aa65106SMaxime Chevallier struct mvpp2_dbgfs_flow_tbl_entry {
328aa65106SMaxime Chevallier int id;
338aa65106SMaxime Chevallier struct mvpp2 *priv;
348aa65106SMaxime Chevallier };
358aa65106SMaxime Chevallier
36dba1d918SMaxime Chevallier struct mvpp2_dbgfs_port_flow_entry {
37dba1d918SMaxime Chevallier struct mvpp2_port *port;
38dba1d918SMaxime Chevallier struct mvpp2_dbgfs_flow_entry *dbg_fe;
39dba1d918SMaxime Chevallier };
40dba1d918SMaxime Chevallier
417cb5e368SMaxime Chevallier struct mvpp2_dbgfs_entries {
427cb5e368SMaxime Chevallier /* Entries for Header Parser debug info */
437cb5e368SMaxime Chevallier struct mvpp2_dbgfs_prs_entry prs_entries[MVPP2_PRS_TCAM_SRAM_SIZE];
447cb5e368SMaxime Chevallier
45b607cc61SMaxime Chevallier /* Entries for Classifier C2 engine debug info */
46b607cc61SMaxime Chevallier struct mvpp2_dbgfs_c2_entry c2_entries[MVPP22_CLS_C2_N_ENTRIES];
47b607cc61SMaxime Chevallier
488aa65106SMaxime Chevallier /* Entries for Classifier Flow Table debug info */
498aa65106SMaxime Chevallier struct mvpp2_dbgfs_flow_tbl_entry flt_entries[MVPP2_CLS_FLOWS_TBL_SIZE];
508aa65106SMaxime Chevallier
517cb5e368SMaxime Chevallier /* Entries for Classifier flows debug info */
527cb5e368SMaxime Chevallier struct mvpp2_dbgfs_flow_entry flow_entries[MVPP2_N_PRS_FLOWS];
537cb5e368SMaxime Chevallier
547cb5e368SMaxime Chevallier /* Entries for per-port flows debug info */
557cb5e368SMaxime Chevallier struct mvpp2_dbgfs_port_flow_entry port_flow_entries[MVPP2_MAX_PORTS];
567cb5e368SMaxime Chevallier };
577cb5e368SMaxime Chevallier
mvpp2_dbgfs_flow_flt_hits_show(struct seq_file * s,void * unused)58f9d30d5bSMaxime Chevallier static int mvpp2_dbgfs_flow_flt_hits_show(struct seq_file *s, void *unused)
59f9d30d5bSMaxime Chevallier {
608aa65106SMaxime Chevallier struct mvpp2_dbgfs_flow_tbl_entry *entry = s->private;
61f9d30d5bSMaxime Chevallier
628aa65106SMaxime Chevallier u32 hits = mvpp2_cls_flow_hits(entry->priv, entry->id);
63f9d30d5bSMaxime Chevallier
64f9d30d5bSMaxime Chevallier seq_printf(s, "%u\n", hits);
65f9d30d5bSMaxime Chevallier
66f9d30d5bSMaxime Chevallier return 0;
67f9d30d5bSMaxime Chevallier }
68f9d30d5bSMaxime Chevallier
69f9d30d5bSMaxime Chevallier DEFINE_SHOW_ATTRIBUTE(mvpp2_dbgfs_flow_flt_hits);
70f9d30d5bSMaxime Chevallier
mvpp2_dbgfs_flow_dec_hits_show(struct seq_file * s,void * unused)71f9d30d5bSMaxime Chevallier static int mvpp2_dbgfs_flow_dec_hits_show(struct seq_file *s, void *unused)
72f9d30d5bSMaxime Chevallier {
73f9d30d5bSMaxime Chevallier struct mvpp2_dbgfs_flow_entry *entry = s->private;
74f9d30d5bSMaxime Chevallier
75f9d30d5bSMaxime Chevallier u32 hits = mvpp2_cls_lookup_hits(entry->priv, entry->flow);
76f9d30d5bSMaxime Chevallier
77f9d30d5bSMaxime Chevallier seq_printf(s, "%u\n", hits);
78f9d30d5bSMaxime Chevallier
79f9d30d5bSMaxime Chevallier return 0;
80f9d30d5bSMaxime Chevallier }
81f9d30d5bSMaxime Chevallier
82f9d30d5bSMaxime Chevallier DEFINE_SHOW_ATTRIBUTE(mvpp2_dbgfs_flow_dec_hits);
83f9d30d5bSMaxime Chevallier
mvpp2_dbgfs_flow_type_show(struct seq_file * s,void * unused)84dba1d918SMaxime Chevallier static int mvpp2_dbgfs_flow_type_show(struct seq_file *s, void *unused)
85dba1d918SMaxime Chevallier {
86dba1d918SMaxime Chevallier struct mvpp2_dbgfs_flow_entry *entry = s->private;
870b27f865SMaxime Chevallier const struct mvpp2_cls_flow *f;
88dba1d918SMaxime Chevallier const char *flow_name;
89dba1d918SMaxime Chevallier
90dba1d918SMaxime Chevallier f = mvpp2_cls_flow_get(entry->flow);
91dba1d918SMaxime Chevallier if (!f)
92dba1d918SMaxime Chevallier return -EINVAL;
93dba1d918SMaxime Chevallier
94dba1d918SMaxime Chevallier switch (f->flow_type) {
95dba1d918SMaxime Chevallier case IPV4_FLOW:
96dba1d918SMaxime Chevallier flow_name = "ipv4";
97dba1d918SMaxime Chevallier break;
98dba1d918SMaxime Chevallier case IPV6_FLOW:
99dba1d918SMaxime Chevallier flow_name = "ipv6";
100dba1d918SMaxime Chevallier break;
101dba1d918SMaxime Chevallier case TCP_V4_FLOW:
102dba1d918SMaxime Chevallier flow_name = "tcp4";
103dba1d918SMaxime Chevallier break;
104dba1d918SMaxime Chevallier case TCP_V6_FLOW:
105dba1d918SMaxime Chevallier flow_name = "tcp6";
106dba1d918SMaxime Chevallier break;
107dba1d918SMaxime Chevallier case UDP_V4_FLOW:
108dba1d918SMaxime Chevallier flow_name = "udp4";
109dba1d918SMaxime Chevallier break;
110dba1d918SMaxime Chevallier case UDP_V6_FLOW:
111dba1d918SMaxime Chevallier flow_name = "udp6";
112dba1d918SMaxime Chevallier break;
113dba1d918SMaxime Chevallier default:
114dba1d918SMaxime Chevallier flow_name = "other";
115dba1d918SMaxime Chevallier }
116dba1d918SMaxime Chevallier
117dba1d918SMaxime Chevallier seq_printf(s, "%s\n", flow_name);
118dba1d918SMaxime Chevallier
119dba1d918SMaxime Chevallier return 0;
120dba1d918SMaxime Chevallier }
121dba1d918SMaxime Chevallier
1227cb5e368SMaxime Chevallier DEFINE_SHOW_ATTRIBUTE(mvpp2_dbgfs_flow_type);
123dba1d918SMaxime Chevallier
mvpp2_dbgfs_flow_id_show(struct seq_file * s,void * unused)124dba1d918SMaxime Chevallier static int mvpp2_dbgfs_flow_id_show(struct seq_file *s, void *unused)
125dba1d918SMaxime Chevallier {
1260b27f865SMaxime Chevallier const struct mvpp2_dbgfs_flow_entry *entry = s->private;
1270b27f865SMaxime Chevallier const struct mvpp2_cls_flow *f;
128dba1d918SMaxime Chevallier
129dba1d918SMaxime Chevallier f = mvpp2_cls_flow_get(entry->flow);
130dba1d918SMaxime Chevallier if (!f)
131dba1d918SMaxime Chevallier return -EINVAL;
132dba1d918SMaxime Chevallier
133dba1d918SMaxime Chevallier seq_printf(s, "%d\n", f->flow_id);
134dba1d918SMaxime Chevallier
135dba1d918SMaxime Chevallier return 0;
136dba1d918SMaxime Chevallier }
137dba1d918SMaxime Chevallier
138dba1d918SMaxime Chevallier DEFINE_SHOW_ATTRIBUTE(mvpp2_dbgfs_flow_id);
139dba1d918SMaxime Chevallier
mvpp2_dbgfs_port_flow_hash_opt_show(struct seq_file * s,void * unused)140dba1d918SMaxime Chevallier static int mvpp2_dbgfs_port_flow_hash_opt_show(struct seq_file *s, void *unused)
141dba1d918SMaxime Chevallier {
142dba1d918SMaxime Chevallier struct mvpp2_dbgfs_port_flow_entry *entry = s->private;
143dba1d918SMaxime Chevallier struct mvpp2_port *port = entry->port;
144dba1d918SMaxime Chevallier struct mvpp2_cls_flow_entry fe;
1450b27f865SMaxime Chevallier const struct mvpp2_cls_flow *f;
146dba1d918SMaxime Chevallier int flow_index;
147dba1d918SMaxime Chevallier u16 hash_opts;
148dba1d918SMaxime Chevallier
149dba1d918SMaxime Chevallier f = mvpp2_cls_flow_get(entry->dbg_fe->flow);
150dba1d918SMaxime Chevallier if (!f)
151dba1d918SMaxime Chevallier return -EINVAL;
152dba1d918SMaxime Chevallier
153ff2f3cb6SMaxime Chevallier flow_index = MVPP2_CLS_FLT_HASH_ENTRY(entry->port->id, f->flow_id);
154dba1d918SMaxime Chevallier
155dba1d918SMaxime Chevallier mvpp2_cls_flow_read(port->priv, flow_index, &fe);
156dba1d918SMaxime Chevallier
157dba1d918SMaxime Chevallier hash_opts = mvpp2_flow_get_hek_fields(&fe);
158dba1d918SMaxime Chevallier
159dba1d918SMaxime Chevallier seq_printf(s, "0x%04x\n", hash_opts);
160dba1d918SMaxime Chevallier
161dba1d918SMaxime Chevallier return 0;
162dba1d918SMaxime Chevallier }
163dba1d918SMaxime Chevallier
1647cb5e368SMaxime Chevallier DEFINE_SHOW_ATTRIBUTE(mvpp2_dbgfs_port_flow_hash_opt);
165dba1d918SMaxime Chevallier
mvpp2_dbgfs_port_flow_engine_show(struct seq_file * s,void * unused)166dba1d918SMaxime Chevallier static int mvpp2_dbgfs_port_flow_engine_show(struct seq_file *s, void *unused)
167dba1d918SMaxime Chevallier {
168dba1d918SMaxime Chevallier struct mvpp2_dbgfs_port_flow_entry *entry = s->private;
169dba1d918SMaxime Chevallier struct mvpp2_port *port = entry->port;
170dba1d918SMaxime Chevallier struct mvpp2_cls_flow_entry fe;
1710b27f865SMaxime Chevallier const struct mvpp2_cls_flow *f;
172dba1d918SMaxime Chevallier int flow_index, engine;
173dba1d918SMaxime Chevallier
174dba1d918SMaxime Chevallier f = mvpp2_cls_flow_get(entry->dbg_fe->flow);
175dba1d918SMaxime Chevallier if (!f)
176dba1d918SMaxime Chevallier return -EINVAL;
177dba1d918SMaxime Chevallier
178ff2f3cb6SMaxime Chevallier flow_index = MVPP2_CLS_FLT_HASH_ENTRY(entry->port->id, f->flow_id);
179dba1d918SMaxime Chevallier
180dba1d918SMaxime Chevallier mvpp2_cls_flow_read(port->priv, flow_index, &fe);
181dba1d918SMaxime Chevallier
182dba1d918SMaxime Chevallier engine = mvpp2_cls_flow_eng_get(&fe);
183dba1d918SMaxime Chevallier
184dba1d918SMaxime Chevallier seq_printf(s, "%d\n", engine);
185dba1d918SMaxime Chevallier
186dba1d918SMaxime Chevallier return 0;
187dba1d918SMaxime Chevallier }
188dba1d918SMaxime Chevallier
189dba1d918SMaxime Chevallier DEFINE_SHOW_ATTRIBUTE(mvpp2_dbgfs_port_flow_engine);
190dba1d918SMaxime Chevallier
mvpp2_dbgfs_flow_c2_hits_show(struct seq_file * s,void * unused)191f9d30d5bSMaxime Chevallier static int mvpp2_dbgfs_flow_c2_hits_show(struct seq_file *s, void *unused)
192f9d30d5bSMaxime Chevallier {
193b607cc61SMaxime Chevallier struct mvpp2_dbgfs_c2_entry *entry = s->private;
194f9d30d5bSMaxime Chevallier u32 hits;
195f9d30d5bSMaxime Chevallier
196b607cc61SMaxime Chevallier hits = mvpp2_cls_c2_hit_count(entry->priv, entry->id);
197f9d30d5bSMaxime Chevallier
198f9d30d5bSMaxime Chevallier seq_printf(s, "%u\n", hits);
199f9d30d5bSMaxime Chevallier
200f9d30d5bSMaxime Chevallier return 0;
201f9d30d5bSMaxime Chevallier }
202f9d30d5bSMaxime Chevallier
203f9d30d5bSMaxime Chevallier DEFINE_SHOW_ATTRIBUTE(mvpp2_dbgfs_flow_c2_hits);
204f9d30d5bSMaxime Chevallier
mvpp2_dbgfs_flow_c2_rxq_show(struct seq_file * s,void * unused)205dba1d918SMaxime Chevallier static int mvpp2_dbgfs_flow_c2_rxq_show(struct seq_file *s, void *unused)
206dba1d918SMaxime Chevallier {
207b607cc61SMaxime Chevallier struct mvpp2_dbgfs_c2_entry *entry = s->private;
208dba1d918SMaxime Chevallier struct mvpp2_cls_c2_entry c2;
209dba1d918SMaxime Chevallier u8 qh, ql;
210dba1d918SMaxime Chevallier
211b607cc61SMaxime Chevallier mvpp2_cls_c2_read(entry->priv, entry->id, &c2);
212dba1d918SMaxime Chevallier
213dba1d918SMaxime Chevallier qh = (c2.attr[0] >> MVPP22_CLS_C2_ATTR0_QHIGH_OFFS) &
214dba1d918SMaxime Chevallier MVPP22_CLS_C2_ATTR0_QHIGH_MASK;
215dba1d918SMaxime Chevallier
216dba1d918SMaxime Chevallier ql = (c2.attr[0] >> MVPP22_CLS_C2_ATTR0_QLOW_OFFS) &
217dba1d918SMaxime Chevallier MVPP22_CLS_C2_ATTR0_QLOW_MASK;
218dba1d918SMaxime Chevallier
219dba1d918SMaxime Chevallier seq_printf(s, "%d\n", (qh << 3 | ql));
220dba1d918SMaxime Chevallier
221dba1d918SMaxime Chevallier return 0;
222dba1d918SMaxime Chevallier }
223dba1d918SMaxime Chevallier
224dba1d918SMaxime Chevallier DEFINE_SHOW_ATTRIBUTE(mvpp2_dbgfs_flow_c2_rxq);
225dba1d918SMaxime Chevallier
mvpp2_dbgfs_flow_c2_enable_show(struct seq_file * s,void * unused)226dba1d918SMaxime Chevallier static int mvpp2_dbgfs_flow_c2_enable_show(struct seq_file *s, void *unused)
227dba1d918SMaxime Chevallier {
228b607cc61SMaxime Chevallier struct mvpp2_dbgfs_c2_entry *entry = s->private;
229dba1d918SMaxime Chevallier struct mvpp2_cls_c2_entry c2;
230dba1d918SMaxime Chevallier int enabled;
231dba1d918SMaxime Chevallier
232b607cc61SMaxime Chevallier mvpp2_cls_c2_read(entry->priv, entry->id, &c2);
233dba1d918SMaxime Chevallier
234e146471fSGustavo A. R. Silva enabled = !!(c2.attr[2] & MVPP22_CLS_C2_ATTR2_RSS_EN);
235dba1d918SMaxime Chevallier
236dba1d918SMaxime Chevallier seq_printf(s, "%d\n", enabled);
237dba1d918SMaxime Chevallier
238dba1d918SMaxime Chevallier return 0;
239dba1d918SMaxime Chevallier }
240dba1d918SMaxime Chevallier
241dba1d918SMaxime Chevallier DEFINE_SHOW_ATTRIBUTE(mvpp2_dbgfs_flow_c2_enable);
242dba1d918SMaxime Chevallier
mvpp2_dbgfs_port_vid_show(struct seq_file * s,void * unused)24321da57a2SMaxime Chevallier static int mvpp2_dbgfs_port_vid_show(struct seq_file *s, void *unused)
24421da57a2SMaxime Chevallier {
24521da57a2SMaxime Chevallier struct mvpp2_port *port = s->private;
24621da57a2SMaxime Chevallier unsigned char byte[2], enable[2];
24721da57a2SMaxime Chevallier struct mvpp2 *priv = port->priv;
24821da57a2SMaxime Chevallier struct mvpp2_prs_entry pe;
24921da57a2SMaxime Chevallier unsigned long pmap;
25021da57a2SMaxime Chevallier u16 rvid;
25121da57a2SMaxime Chevallier int tid;
25221da57a2SMaxime Chevallier
25321da57a2SMaxime Chevallier for (tid = MVPP2_PRS_VID_PORT_FIRST(port->id);
25421da57a2SMaxime Chevallier tid <= MVPP2_PRS_VID_PORT_LAST(port->id); tid++) {
25521da57a2SMaxime Chevallier mvpp2_prs_init_from_hw(priv, &pe, tid);
25621da57a2SMaxime Chevallier
25721da57a2SMaxime Chevallier pmap = mvpp2_prs_tcam_port_map_get(&pe);
25821da57a2SMaxime Chevallier
25921da57a2SMaxime Chevallier if (!priv->prs_shadow[tid].valid)
26021da57a2SMaxime Chevallier continue;
26121da57a2SMaxime Chevallier
26221da57a2SMaxime Chevallier if (!test_bit(port->id, &pmap))
26321da57a2SMaxime Chevallier continue;
26421da57a2SMaxime Chevallier
26521da57a2SMaxime Chevallier mvpp2_prs_tcam_data_byte_get(&pe, 2, &byte[0], &enable[0]);
26621da57a2SMaxime Chevallier mvpp2_prs_tcam_data_byte_get(&pe, 3, &byte[1], &enable[1]);
26721da57a2SMaxime Chevallier
26821da57a2SMaxime Chevallier rvid = ((byte[0] & 0xf) << 8) + byte[1];
26921da57a2SMaxime Chevallier
27021da57a2SMaxime Chevallier seq_printf(s, "%u\n", rvid);
27121da57a2SMaxime Chevallier }
27221da57a2SMaxime Chevallier
27321da57a2SMaxime Chevallier return 0;
27421da57a2SMaxime Chevallier }
27521da57a2SMaxime Chevallier
27621da57a2SMaxime Chevallier DEFINE_SHOW_ATTRIBUTE(mvpp2_dbgfs_port_vid);
27721da57a2SMaxime Chevallier
mvpp2_dbgfs_port_parser_show(struct seq_file * s,void * unused)27821da57a2SMaxime Chevallier static int mvpp2_dbgfs_port_parser_show(struct seq_file *s, void *unused)
27921da57a2SMaxime Chevallier {
28021da57a2SMaxime Chevallier struct mvpp2_port *port = s->private;
28121da57a2SMaxime Chevallier struct mvpp2 *priv = port->priv;
28221da57a2SMaxime Chevallier struct mvpp2_prs_entry pe;
28321da57a2SMaxime Chevallier unsigned long pmap;
28421da57a2SMaxime Chevallier int i;
28521da57a2SMaxime Chevallier
28621da57a2SMaxime Chevallier for (i = 0; i < MVPP2_PRS_TCAM_SRAM_SIZE; i++) {
28721da57a2SMaxime Chevallier mvpp2_prs_init_from_hw(port->priv, &pe, i);
28821da57a2SMaxime Chevallier
28921da57a2SMaxime Chevallier pmap = mvpp2_prs_tcam_port_map_get(&pe);
29021da57a2SMaxime Chevallier if (priv->prs_shadow[i].valid && test_bit(port->id, &pmap))
29121da57a2SMaxime Chevallier seq_printf(s, "%03d\n", i);
29221da57a2SMaxime Chevallier }
29321da57a2SMaxime Chevallier
29421da57a2SMaxime Chevallier return 0;
29521da57a2SMaxime Chevallier }
29621da57a2SMaxime Chevallier
29721da57a2SMaxime Chevallier DEFINE_SHOW_ATTRIBUTE(mvpp2_dbgfs_port_parser);
29821da57a2SMaxime Chevallier
mvpp2_dbgfs_filter_show(struct seq_file * s,void * unused)29921da57a2SMaxime Chevallier static int mvpp2_dbgfs_filter_show(struct seq_file *s, void *unused)
30021da57a2SMaxime Chevallier {
30121da57a2SMaxime Chevallier struct mvpp2_port *port = s->private;
30221da57a2SMaxime Chevallier struct mvpp2 *priv = port->priv;
30321da57a2SMaxime Chevallier struct mvpp2_prs_entry pe;
30421da57a2SMaxime Chevallier unsigned long pmap;
30521da57a2SMaxime Chevallier int index, tid;
30621da57a2SMaxime Chevallier
30721da57a2SMaxime Chevallier for (tid = MVPP2_PE_MAC_RANGE_START;
30821da57a2SMaxime Chevallier tid <= MVPP2_PE_MAC_RANGE_END; tid++) {
30921da57a2SMaxime Chevallier unsigned char da[ETH_ALEN], da_mask[ETH_ALEN];
31021da57a2SMaxime Chevallier
31121da57a2SMaxime Chevallier if (!priv->prs_shadow[tid].valid ||
31221da57a2SMaxime Chevallier priv->prs_shadow[tid].lu != MVPP2_PRS_LU_MAC ||
31321da57a2SMaxime Chevallier priv->prs_shadow[tid].udf != MVPP2_PRS_UDF_MAC_DEF)
31421da57a2SMaxime Chevallier continue;
31521da57a2SMaxime Chevallier
31621da57a2SMaxime Chevallier mvpp2_prs_init_from_hw(priv, &pe, tid);
31721da57a2SMaxime Chevallier
31821da57a2SMaxime Chevallier pmap = mvpp2_prs_tcam_port_map_get(&pe);
31921da57a2SMaxime Chevallier
32021da57a2SMaxime Chevallier /* We only want entries active on this port */
32121da57a2SMaxime Chevallier if (!test_bit(port->id, &pmap))
32221da57a2SMaxime Chevallier continue;
32321da57a2SMaxime Chevallier
32421da57a2SMaxime Chevallier /* Read mac addr from entry */
32521da57a2SMaxime Chevallier for (index = 0; index < ETH_ALEN; index++)
32621da57a2SMaxime Chevallier mvpp2_prs_tcam_data_byte_get(&pe, index, &da[index],
32721da57a2SMaxime Chevallier &da_mask[index]);
32821da57a2SMaxime Chevallier
32921da57a2SMaxime Chevallier seq_printf(s, "%pM\n", da);
33021da57a2SMaxime Chevallier }
33121da57a2SMaxime Chevallier
33221da57a2SMaxime Chevallier return 0;
33321da57a2SMaxime Chevallier }
33421da57a2SMaxime Chevallier
33521da57a2SMaxime Chevallier DEFINE_SHOW_ATTRIBUTE(mvpp2_dbgfs_filter);
33621da57a2SMaxime Chevallier
mvpp2_dbgfs_prs_lu_show(struct seq_file * s,void * unused)33721da57a2SMaxime Chevallier static int mvpp2_dbgfs_prs_lu_show(struct seq_file *s, void *unused)
33821da57a2SMaxime Chevallier {
33921da57a2SMaxime Chevallier struct mvpp2_dbgfs_prs_entry *entry = s->private;
34021da57a2SMaxime Chevallier struct mvpp2 *priv = entry->priv;
34121da57a2SMaxime Chevallier
34221da57a2SMaxime Chevallier seq_printf(s, "%x\n", priv->prs_shadow[entry->tid].lu);
34321da57a2SMaxime Chevallier
34421da57a2SMaxime Chevallier return 0;
34521da57a2SMaxime Chevallier }
34621da57a2SMaxime Chevallier
34721da57a2SMaxime Chevallier DEFINE_SHOW_ATTRIBUTE(mvpp2_dbgfs_prs_lu);
34821da57a2SMaxime Chevallier
mvpp2_dbgfs_prs_pmap_show(struct seq_file * s,void * unused)34921da57a2SMaxime Chevallier static int mvpp2_dbgfs_prs_pmap_show(struct seq_file *s, void *unused)
35021da57a2SMaxime Chevallier {
35121da57a2SMaxime Chevallier struct mvpp2_dbgfs_prs_entry *entry = s->private;
35221da57a2SMaxime Chevallier struct mvpp2_prs_entry pe;
35321da57a2SMaxime Chevallier unsigned int pmap;
35421da57a2SMaxime Chevallier
35521da57a2SMaxime Chevallier mvpp2_prs_init_from_hw(entry->priv, &pe, entry->tid);
35621da57a2SMaxime Chevallier
35721da57a2SMaxime Chevallier pmap = mvpp2_prs_tcam_port_map_get(&pe);
35821da57a2SMaxime Chevallier pmap &= MVPP2_PRS_PORT_MASK;
35921da57a2SMaxime Chevallier
36021da57a2SMaxime Chevallier seq_printf(s, "%02x\n", pmap);
36121da57a2SMaxime Chevallier
36221da57a2SMaxime Chevallier return 0;
36321da57a2SMaxime Chevallier }
36421da57a2SMaxime Chevallier
36521da57a2SMaxime Chevallier DEFINE_SHOW_ATTRIBUTE(mvpp2_dbgfs_prs_pmap);
36621da57a2SMaxime Chevallier
mvpp2_dbgfs_prs_ai_show(struct seq_file * s,void * unused)36721da57a2SMaxime Chevallier static int mvpp2_dbgfs_prs_ai_show(struct seq_file *s, void *unused)
36821da57a2SMaxime Chevallier {
36921da57a2SMaxime Chevallier struct mvpp2_dbgfs_prs_entry *entry = s->private;
37021da57a2SMaxime Chevallier struct mvpp2_prs_entry pe;
37121da57a2SMaxime Chevallier unsigned char ai, ai_mask;
37221da57a2SMaxime Chevallier
37321da57a2SMaxime Chevallier mvpp2_prs_init_from_hw(entry->priv, &pe, entry->tid);
37421da57a2SMaxime Chevallier
37521da57a2SMaxime Chevallier ai = pe.tcam[MVPP2_PRS_TCAM_AI_WORD] & MVPP2_PRS_AI_MASK;
37621da57a2SMaxime Chevallier ai_mask = (pe.tcam[MVPP2_PRS_TCAM_AI_WORD] >> 16) & MVPP2_PRS_AI_MASK;
37721da57a2SMaxime Chevallier
37821da57a2SMaxime Chevallier seq_printf(s, "%02x %02x\n", ai, ai_mask);
37921da57a2SMaxime Chevallier
38021da57a2SMaxime Chevallier return 0;
38121da57a2SMaxime Chevallier }
38221da57a2SMaxime Chevallier
38321da57a2SMaxime Chevallier DEFINE_SHOW_ATTRIBUTE(mvpp2_dbgfs_prs_ai);
38421da57a2SMaxime Chevallier
mvpp2_dbgfs_prs_hdata_show(struct seq_file * s,void * unused)38521da57a2SMaxime Chevallier static int mvpp2_dbgfs_prs_hdata_show(struct seq_file *s, void *unused)
38621da57a2SMaxime Chevallier {
38721da57a2SMaxime Chevallier struct mvpp2_dbgfs_prs_entry *entry = s->private;
38821da57a2SMaxime Chevallier struct mvpp2_prs_entry pe;
38921da57a2SMaxime Chevallier unsigned char data[8], mask[8];
39021da57a2SMaxime Chevallier int i;
39121da57a2SMaxime Chevallier
39221da57a2SMaxime Chevallier mvpp2_prs_init_from_hw(entry->priv, &pe, entry->tid);
39321da57a2SMaxime Chevallier
39421da57a2SMaxime Chevallier for (i = 0; i < 8; i++)
39521da57a2SMaxime Chevallier mvpp2_prs_tcam_data_byte_get(&pe, i, &data[i], &mask[i]);
39621da57a2SMaxime Chevallier
39721da57a2SMaxime Chevallier seq_printf(s, "%*phN %*phN\n", 8, data, 8, mask);
39821da57a2SMaxime Chevallier
39921da57a2SMaxime Chevallier return 0;
40021da57a2SMaxime Chevallier }
40121da57a2SMaxime Chevallier
40221da57a2SMaxime Chevallier DEFINE_SHOW_ATTRIBUTE(mvpp2_dbgfs_prs_hdata);
40321da57a2SMaxime Chevallier
mvpp2_dbgfs_prs_sram_show(struct seq_file * s,void * unused)40421da57a2SMaxime Chevallier static int mvpp2_dbgfs_prs_sram_show(struct seq_file *s, void *unused)
40521da57a2SMaxime Chevallier {
40621da57a2SMaxime Chevallier struct mvpp2_dbgfs_prs_entry *entry = s->private;
40721da57a2SMaxime Chevallier struct mvpp2_prs_entry pe;
40821da57a2SMaxime Chevallier
40921da57a2SMaxime Chevallier mvpp2_prs_init_from_hw(entry->priv, &pe, entry->tid);
41021da57a2SMaxime Chevallier
41121da57a2SMaxime Chevallier seq_printf(s, "%*phN\n", 14, pe.sram);
41221da57a2SMaxime Chevallier
41321da57a2SMaxime Chevallier return 0;
41421da57a2SMaxime Chevallier }
41521da57a2SMaxime Chevallier
41621da57a2SMaxime Chevallier DEFINE_SHOW_ATTRIBUTE(mvpp2_dbgfs_prs_sram);
41721da57a2SMaxime Chevallier
mvpp2_dbgfs_prs_hits_show(struct seq_file * s,void * unused)4181203341cSMaxime Chevallier static int mvpp2_dbgfs_prs_hits_show(struct seq_file *s, void *unused)
4191203341cSMaxime Chevallier {
4201203341cSMaxime Chevallier struct mvpp2_dbgfs_prs_entry *entry = s->private;
4211203341cSMaxime Chevallier int val;
4221203341cSMaxime Chevallier
4231203341cSMaxime Chevallier val = mvpp2_prs_hits(entry->priv, entry->tid);
4241203341cSMaxime Chevallier if (val < 0)
4251203341cSMaxime Chevallier return val;
4261203341cSMaxime Chevallier
4271203341cSMaxime Chevallier seq_printf(s, "%d\n", val);
4281203341cSMaxime Chevallier
4291203341cSMaxime Chevallier return 0;
4301203341cSMaxime Chevallier }
4311203341cSMaxime Chevallier
4321203341cSMaxime Chevallier DEFINE_SHOW_ATTRIBUTE(mvpp2_dbgfs_prs_hits);
4331203341cSMaxime Chevallier
mvpp2_dbgfs_prs_valid_show(struct seq_file * s,void * unused)43421da57a2SMaxime Chevallier static int mvpp2_dbgfs_prs_valid_show(struct seq_file *s, void *unused)
43521da57a2SMaxime Chevallier {
43621da57a2SMaxime Chevallier struct mvpp2_dbgfs_prs_entry *entry = s->private;
43721da57a2SMaxime Chevallier struct mvpp2 *priv = entry->priv;
43821da57a2SMaxime Chevallier int tid = entry->tid;
43921da57a2SMaxime Chevallier
44021da57a2SMaxime Chevallier seq_printf(s, "%d\n", priv->prs_shadow[tid].valid ? 1 : 0);
44121da57a2SMaxime Chevallier
44221da57a2SMaxime Chevallier return 0;
44321da57a2SMaxime Chevallier }
44421da57a2SMaxime Chevallier
4457cb5e368SMaxime Chevallier DEFINE_SHOW_ATTRIBUTE(mvpp2_dbgfs_prs_valid);
44621da57a2SMaxime Chevallier
mvpp2_dbgfs_flow_port_init(struct dentry * parent,struct mvpp2_port * port,struct mvpp2_dbgfs_flow_entry * entry)447dba1d918SMaxime Chevallier static int mvpp2_dbgfs_flow_port_init(struct dentry *parent,
448dba1d918SMaxime Chevallier struct mvpp2_port *port,
449dba1d918SMaxime Chevallier struct mvpp2_dbgfs_flow_entry *entry)
450dba1d918SMaxime Chevallier {
451dba1d918SMaxime Chevallier struct mvpp2_dbgfs_port_flow_entry *port_entry;
452dba1d918SMaxime Chevallier struct dentry *port_dir;
453dba1d918SMaxime Chevallier
454dba1d918SMaxime Chevallier port_dir = debugfs_create_dir(port->dev->name, parent);
455dba1d918SMaxime Chevallier
4567cb5e368SMaxime Chevallier port_entry = &port->priv->dbgfs_entries->port_flow_entries[port->id];
457dba1d918SMaxime Chevallier
458dba1d918SMaxime Chevallier port_entry->port = port;
459dba1d918SMaxime Chevallier port_entry->dbg_fe = entry;
460dba1d918SMaxime Chevallier
461dba1d918SMaxime Chevallier debugfs_create_file("hash_opts", 0444, port_dir, port_entry,
462dba1d918SMaxime Chevallier &mvpp2_dbgfs_port_flow_hash_opt_fops);
463dba1d918SMaxime Chevallier
464dba1d918SMaxime Chevallier debugfs_create_file("engine", 0444, port_dir, port_entry,
465dba1d918SMaxime Chevallier &mvpp2_dbgfs_port_flow_engine_fops);
466dba1d918SMaxime Chevallier
467dba1d918SMaxime Chevallier return 0;
468dba1d918SMaxime Chevallier }
469dba1d918SMaxime Chevallier
mvpp2_dbgfs_flow_entry_init(struct dentry * parent,struct mvpp2 * priv,int flow)470dba1d918SMaxime Chevallier static int mvpp2_dbgfs_flow_entry_init(struct dentry *parent,
471dba1d918SMaxime Chevallier struct mvpp2 *priv, int flow)
472dba1d918SMaxime Chevallier {
473dba1d918SMaxime Chevallier struct mvpp2_dbgfs_flow_entry *entry;
474dba1d918SMaxime Chevallier struct dentry *flow_entry_dir;
475dba1d918SMaxime Chevallier char flow_entry_name[10];
476dba1d918SMaxime Chevallier int i, ret;
477dba1d918SMaxime Chevallier
478dba1d918SMaxime Chevallier sprintf(flow_entry_name, "%02d", flow);
479dba1d918SMaxime Chevallier
480dba1d918SMaxime Chevallier flow_entry_dir = debugfs_create_dir(flow_entry_name, parent);
481dba1d918SMaxime Chevallier
4827cb5e368SMaxime Chevallier entry = &priv->dbgfs_entries->flow_entries[flow];
483dba1d918SMaxime Chevallier
484dba1d918SMaxime Chevallier entry->flow = flow;
485dba1d918SMaxime Chevallier entry->priv = priv;
486dba1d918SMaxime Chevallier
487f9d30d5bSMaxime Chevallier debugfs_create_file("dec_hits", 0444, flow_entry_dir, entry,
488f9d30d5bSMaxime Chevallier &mvpp2_dbgfs_flow_dec_hits_fops);
489f9d30d5bSMaxime Chevallier
490dba1d918SMaxime Chevallier debugfs_create_file("type", 0444, flow_entry_dir, entry,
491dba1d918SMaxime Chevallier &mvpp2_dbgfs_flow_type_fops);
492dba1d918SMaxime Chevallier
493dba1d918SMaxime Chevallier debugfs_create_file("id", 0444, flow_entry_dir, entry,
494dba1d918SMaxime Chevallier &mvpp2_dbgfs_flow_id_fops);
495dba1d918SMaxime Chevallier
496dba1d918SMaxime Chevallier /* Create entry for each port */
497dba1d918SMaxime Chevallier for (i = 0; i < priv->port_count; i++) {
498dba1d918SMaxime Chevallier ret = mvpp2_dbgfs_flow_port_init(flow_entry_dir,
499dba1d918SMaxime Chevallier priv->port_list[i], entry);
500dba1d918SMaxime Chevallier if (ret)
501dba1d918SMaxime Chevallier return ret;
502dba1d918SMaxime Chevallier }
503b607cc61SMaxime Chevallier
504dba1d918SMaxime Chevallier return 0;
505dba1d918SMaxime Chevallier }
506dba1d918SMaxime Chevallier
mvpp2_dbgfs_flow_init(struct dentry * parent,struct mvpp2 * priv)507dba1d918SMaxime Chevallier static int mvpp2_dbgfs_flow_init(struct dentry *parent, struct mvpp2 *priv)
508dba1d918SMaxime Chevallier {
509dba1d918SMaxime Chevallier struct dentry *flow_dir;
510dba1d918SMaxime Chevallier int i, ret;
511dba1d918SMaxime Chevallier
512dba1d918SMaxime Chevallier flow_dir = debugfs_create_dir("flows", parent);
513dba1d918SMaxime Chevallier
51493c2589cSMaxime Chevallier for (i = 0; i < MVPP2_N_PRS_FLOWS; i++) {
515dba1d918SMaxime Chevallier ret = mvpp2_dbgfs_flow_entry_init(flow_dir, priv, i);
516dba1d918SMaxime Chevallier if (ret)
517dba1d918SMaxime Chevallier return ret;
518dba1d918SMaxime Chevallier }
519dba1d918SMaxime Chevallier
520dba1d918SMaxime Chevallier return 0;
521dba1d918SMaxime Chevallier }
522dba1d918SMaxime Chevallier
mvpp2_dbgfs_prs_entry_init(struct dentry * parent,struct mvpp2 * priv,int tid)52321da57a2SMaxime Chevallier static int mvpp2_dbgfs_prs_entry_init(struct dentry *parent,
52421da57a2SMaxime Chevallier struct mvpp2 *priv, int tid)
52521da57a2SMaxime Chevallier {
52621da57a2SMaxime Chevallier struct mvpp2_dbgfs_prs_entry *entry;
52721da57a2SMaxime Chevallier struct dentry *prs_entry_dir;
52821da57a2SMaxime Chevallier char prs_entry_name[10];
52921da57a2SMaxime Chevallier
53021da57a2SMaxime Chevallier if (tid >= MVPP2_PRS_TCAM_SRAM_SIZE)
53121da57a2SMaxime Chevallier return -EINVAL;
53221da57a2SMaxime Chevallier
53321da57a2SMaxime Chevallier sprintf(prs_entry_name, "%03d", tid);
53421da57a2SMaxime Chevallier
53521da57a2SMaxime Chevallier prs_entry_dir = debugfs_create_dir(prs_entry_name, parent);
53621da57a2SMaxime Chevallier
5377cb5e368SMaxime Chevallier entry = &priv->dbgfs_entries->prs_entries[tid];
53821da57a2SMaxime Chevallier
53921da57a2SMaxime Chevallier entry->tid = tid;
54021da57a2SMaxime Chevallier entry->priv = priv;
54121da57a2SMaxime Chevallier
54221da57a2SMaxime Chevallier /* Create each attr */
54321da57a2SMaxime Chevallier debugfs_create_file("sram", 0444, prs_entry_dir, entry,
54421da57a2SMaxime Chevallier &mvpp2_dbgfs_prs_sram_fops);
54521da57a2SMaxime Chevallier
54621da57a2SMaxime Chevallier debugfs_create_file("valid", 0644, prs_entry_dir, entry,
54721da57a2SMaxime Chevallier &mvpp2_dbgfs_prs_valid_fops);
54821da57a2SMaxime Chevallier
54921da57a2SMaxime Chevallier debugfs_create_file("lookup_id", 0644, prs_entry_dir, entry,
55021da57a2SMaxime Chevallier &mvpp2_dbgfs_prs_lu_fops);
55121da57a2SMaxime Chevallier
55221da57a2SMaxime Chevallier debugfs_create_file("ai", 0644, prs_entry_dir, entry,
55321da57a2SMaxime Chevallier &mvpp2_dbgfs_prs_ai_fops);
55421da57a2SMaxime Chevallier
55521da57a2SMaxime Chevallier debugfs_create_file("header_data", 0644, prs_entry_dir, entry,
55621da57a2SMaxime Chevallier &mvpp2_dbgfs_prs_hdata_fops);
55721da57a2SMaxime Chevallier
5581203341cSMaxime Chevallier debugfs_create_file("hits", 0444, prs_entry_dir, entry,
5591203341cSMaxime Chevallier &mvpp2_dbgfs_prs_hits_fops);
5601203341cSMaxime Chevallier
5618110a7a7SNathan Huckleberry debugfs_create_file("pmap", 0444, prs_entry_dir, entry,
5628110a7a7SNathan Huckleberry &mvpp2_dbgfs_prs_pmap_fops);
5638110a7a7SNathan Huckleberry
56421da57a2SMaxime Chevallier return 0;
56521da57a2SMaxime Chevallier }
56621da57a2SMaxime Chevallier
mvpp2_dbgfs_prs_init(struct dentry * parent,struct mvpp2 * priv)56721da57a2SMaxime Chevallier static int mvpp2_dbgfs_prs_init(struct dentry *parent, struct mvpp2 *priv)
56821da57a2SMaxime Chevallier {
56921da57a2SMaxime Chevallier struct dentry *prs_dir;
57021da57a2SMaxime Chevallier int i, ret;
57121da57a2SMaxime Chevallier
57221da57a2SMaxime Chevallier prs_dir = debugfs_create_dir("parser", parent);
57321da57a2SMaxime Chevallier
57421da57a2SMaxime Chevallier for (i = 0; i < MVPP2_PRS_TCAM_SRAM_SIZE; i++) {
57521da57a2SMaxime Chevallier ret = mvpp2_dbgfs_prs_entry_init(prs_dir, priv, i);
57621da57a2SMaxime Chevallier if (ret)
57721da57a2SMaxime Chevallier return ret;
57821da57a2SMaxime Chevallier }
57921da57a2SMaxime Chevallier
58021da57a2SMaxime Chevallier return 0;
58121da57a2SMaxime Chevallier }
58221da57a2SMaxime Chevallier
mvpp2_dbgfs_c2_entry_init(struct dentry * parent,struct mvpp2 * priv,int id)583b607cc61SMaxime Chevallier static int mvpp2_dbgfs_c2_entry_init(struct dentry *parent,
584b607cc61SMaxime Chevallier struct mvpp2 *priv, int id)
585b607cc61SMaxime Chevallier {
586b607cc61SMaxime Chevallier struct mvpp2_dbgfs_c2_entry *entry;
587b607cc61SMaxime Chevallier struct dentry *c2_entry_dir;
588b607cc61SMaxime Chevallier char c2_entry_name[10];
589b607cc61SMaxime Chevallier
590b607cc61SMaxime Chevallier if (id >= MVPP22_CLS_C2_N_ENTRIES)
591b607cc61SMaxime Chevallier return -EINVAL;
592b607cc61SMaxime Chevallier
593b607cc61SMaxime Chevallier sprintf(c2_entry_name, "%03d", id);
594b607cc61SMaxime Chevallier
595b607cc61SMaxime Chevallier c2_entry_dir = debugfs_create_dir(c2_entry_name, parent);
596b607cc61SMaxime Chevallier
597b607cc61SMaxime Chevallier entry = &priv->dbgfs_entries->c2_entries[id];
598b607cc61SMaxime Chevallier
599b607cc61SMaxime Chevallier entry->id = id;
600b607cc61SMaxime Chevallier entry->priv = priv;
601b607cc61SMaxime Chevallier
602b607cc61SMaxime Chevallier debugfs_create_file("hits", 0444, c2_entry_dir, entry,
603b607cc61SMaxime Chevallier &mvpp2_dbgfs_flow_c2_hits_fops);
604b607cc61SMaxime Chevallier
605b607cc61SMaxime Chevallier debugfs_create_file("default_rxq", 0444, c2_entry_dir, entry,
606b607cc61SMaxime Chevallier &mvpp2_dbgfs_flow_c2_rxq_fops);
607b607cc61SMaxime Chevallier
608b607cc61SMaxime Chevallier debugfs_create_file("rss_enable", 0444, c2_entry_dir, entry,
609b607cc61SMaxime Chevallier &mvpp2_dbgfs_flow_c2_enable_fops);
610b607cc61SMaxime Chevallier
611b607cc61SMaxime Chevallier return 0;
612b607cc61SMaxime Chevallier }
613b607cc61SMaxime Chevallier
mvpp2_dbgfs_flow_tbl_entry_init(struct dentry * parent,struct mvpp2 * priv,int id)6148aa65106SMaxime Chevallier static int mvpp2_dbgfs_flow_tbl_entry_init(struct dentry *parent,
6158aa65106SMaxime Chevallier struct mvpp2 *priv, int id)
6168aa65106SMaxime Chevallier {
6178aa65106SMaxime Chevallier struct mvpp2_dbgfs_flow_tbl_entry *entry;
6188aa65106SMaxime Chevallier struct dentry *flow_tbl_entry_dir;
6198aa65106SMaxime Chevallier char flow_tbl_entry_name[10];
6208aa65106SMaxime Chevallier
6218aa65106SMaxime Chevallier if (id >= MVPP2_CLS_FLOWS_TBL_SIZE)
6228aa65106SMaxime Chevallier return -EINVAL;
6238aa65106SMaxime Chevallier
6248aa65106SMaxime Chevallier sprintf(flow_tbl_entry_name, "%03d", id);
6258aa65106SMaxime Chevallier
6268aa65106SMaxime Chevallier flow_tbl_entry_dir = debugfs_create_dir(flow_tbl_entry_name, parent);
6278aa65106SMaxime Chevallier
6288aa65106SMaxime Chevallier entry = &priv->dbgfs_entries->flt_entries[id];
6298aa65106SMaxime Chevallier
6308aa65106SMaxime Chevallier entry->id = id;
6318aa65106SMaxime Chevallier entry->priv = priv;
6328aa65106SMaxime Chevallier
6338aa65106SMaxime Chevallier debugfs_create_file("hits", 0444, flow_tbl_entry_dir, entry,
6348aa65106SMaxime Chevallier &mvpp2_dbgfs_flow_flt_hits_fops);
6358aa65106SMaxime Chevallier
6368aa65106SMaxime Chevallier return 0;
6378aa65106SMaxime Chevallier }
6388aa65106SMaxime Chevallier
mvpp2_dbgfs_cls_init(struct dentry * parent,struct mvpp2 * priv)6398aa65106SMaxime Chevallier static int mvpp2_dbgfs_cls_init(struct dentry *parent, struct mvpp2 *priv)
6408aa65106SMaxime Chevallier {
641b607cc61SMaxime Chevallier struct dentry *cls_dir, *c2_dir, *flow_tbl_dir;
6428aa65106SMaxime Chevallier int i, ret;
6438aa65106SMaxime Chevallier
6448aa65106SMaxime Chevallier cls_dir = debugfs_create_dir("classifier", parent);
6458aa65106SMaxime Chevallier
646b607cc61SMaxime Chevallier c2_dir = debugfs_create_dir("c2", cls_dir);
647b607cc61SMaxime Chevallier
648b607cc61SMaxime Chevallier for (i = 0; i < MVPP22_CLS_C2_N_ENTRIES; i++) {
649b607cc61SMaxime Chevallier ret = mvpp2_dbgfs_c2_entry_init(c2_dir, priv, i);
650b607cc61SMaxime Chevallier if (ret)
651b607cc61SMaxime Chevallier return ret;
652b607cc61SMaxime Chevallier }
653b607cc61SMaxime Chevallier
6548aa65106SMaxime Chevallier flow_tbl_dir = debugfs_create_dir("flow_table", cls_dir);
6558aa65106SMaxime Chevallier
6568aa65106SMaxime Chevallier for (i = 0; i < MVPP2_CLS_FLOWS_TBL_SIZE; i++) {
6578aa65106SMaxime Chevallier ret = mvpp2_dbgfs_flow_tbl_entry_init(flow_tbl_dir, priv, i);
6588aa65106SMaxime Chevallier if (ret)
6598aa65106SMaxime Chevallier return ret;
6608aa65106SMaxime Chevallier }
6618aa65106SMaxime Chevallier
6628aa65106SMaxime Chevallier return 0;
6638aa65106SMaxime Chevallier }
6648aa65106SMaxime Chevallier
mvpp2_dbgfs_port_init(struct dentry * parent,struct mvpp2_port * port)66521da57a2SMaxime Chevallier static int mvpp2_dbgfs_port_init(struct dentry *parent,
66621da57a2SMaxime Chevallier struct mvpp2_port *port)
66721da57a2SMaxime Chevallier {
66821da57a2SMaxime Chevallier struct dentry *port_dir;
66921da57a2SMaxime Chevallier
67021da57a2SMaxime Chevallier port_dir = debugfs_create_dir(port->dev->name, parent);
67121da57a2SMaxime Chevallier
67221da57a2SMaxime Chevallier debugfs_create_file("parser_entries", 0444, port_dir, port,
67321da57a2SMaxime Chevallier &mvpp2_dbgfs_port_parser_fops);
67421da57a2SMaxime Chevallier
67521da57a2SMaxime Chevallier debugfs_create_file("mac_filter", 0444, port_dir, port,
67621da57a2SMaxime Chevallier &mvpp2_dbgfs_filter_fops);
67721da57a2SMaxime Chevallier
67821da57a2SMaxime Chevallier debugfs_create_file("vid_filter", 0444, port_dir, port,
67921da57a2SMaxime Chevallier &mvpp2_dbgfs_port_vid_fops);
68021da57a2SMaxime Chevallier
68121da57a2SMaxime Chevallier return 0;
68221da57a2SMaxime Chevallier }
68321da57a2SMaxime Chevallier
684*0152dfeeSRussell King (Oracle) static struct dentry *mvpp2_root;
685*0152dfeeSRussell King (Oracle)
mvpp2_dbgfs_exit(void)686*0152dfeeSRussell King (Oracle) void mvpp2_dbgfs_exit(void)
687*0152dfeeSRussell King (Oracle) {
688*0152dfeeSRussell King (Oracle) debugfs_remove(mvpp2_root);
689*0152dfeeSRussell King (Oracle) }
690*0152dfeeSRussell King (Oracle)
mvpp2_dbgfs_cleanup(struct mvpp2 * priv)69121da57a2SMaxime Chevallier void mvpp2_dbgfs_cleanup(struct mvpp2 *priv)
69221da57a2SMaxime Chevallier {
69321da57a2SMaxime Chevallier debugfs_remove_recursive(priv->dbgfs_dir);
6947cb5e368SMaxime Chevallier
6957cb5e368SMaxime Chevallier kfree(priv->dbgfs_entries);
69621da57a2SMaxime Chevallier }
69721da57a2SMaxime Chevallier
mvpp2_dbgfs_init(struct mvpp2 * priv,const char * name)69821da57a2SMaxime Chevallier void mvpp2_dbgfs_init(struct mvpp2 *priv, const char *name)
69921da57a2SMaxime Chevallier {
700*0152dfeeSRussell King (Oracle) struct dentry *mvpp2_dir;
70121da57a2SMaxime Chevallier int ret, i;
70221da57a2SMaxime Chevallier
703e6882aa6SGreg Kroah-Hartman if (!mvpp2_root)
70421da57a2SMaxime Chevallier mvpp2_root = debugfs_create_dir(MVPP2_DRIVER_NAME, NULL);
70521da57a2SMaxime Chevallier
70621da57a2SMaxime Chevallier mvpp2_dir = debugfs_create_dir(name, mvpp2_root);
70721da57a2SMaxime Chevallier
70821da57a2SMaxime Chevallier priv->dbgfs_dir = mvpp2_dir;
7097cb5e368SMaxime Chevallier priv->dbgfs_entries = kzalloc(sizeof(*priv->dbgfs_entries), GFP_KERNEL);
7107cb5e368SMaxime Chevallier if (!priv->dbgfs_entries)
7117cb5e368SMaxime Chevallier goto err;
71221da57a2SMaxime Chevallier
71321da57a2SMaxime Chevallier ret = mvpp2_dbgfs_prs_init(mvpp2_dir, priv);
71421da57a2SMaxime Chevallier if (ret)
71521da57a2SMaxime Chevallier goto err;
71621da57a2SMaxime Chevallier
7178aa65106SMaxime Chevallier ret = mvpp2_dbgfs_cls_init(mvpp2_dir, priv);
7188aa65106SMaxime Chevallier if (ret)
7198aa65106SMaxime Chevallier goto err;
7208aa65106SMaxime Chevallier
72121da57a2SMaxime Chevallier for (i = 0; i < priv->port_count; i++) {
72221da57a2SMaxime Chevallier ret = mvpp2_dbgfs_port_init(mvpp2_dir, priv->port_list[i]);
72321da57a2SMaxime Chevallier if (ret)
72421da57a2SMaxime Chevallier goto err;
72521da57a2SMaxime Chevallier }
72621da57a2SMaxime Chevallier
727dba1d918SMaxime Chevallier ret = mvpp2_dbgfs_flow_init(mvpp2_dir, priv);
728dba1d918SMaxime Chevallier if (ret)
729dba1d918SMaxime Chevallier goto err;
730dba1d918SMaxime Chevallier
73121da57a2SMaxime Chevallier return;
73221da57a2SMaxime Chevallier err:
73321da57a2SMaxime Chevallier mvpp2_dbgfs_cleanup(priv);
73421da57a2SMaxime Chevallier }
735