brintos

brintos / linux-shallow public Read only

0
0
Text · 16.4 KiB · 0f9bc4f Raw
735 lines · c
1// SPDX-License-Identifier: GPL-2.02/*3 * Driver for Marvell PPv2 network controller for Armada 375 SoC.4 *5 * Copyright (C) 2018 Marvell6 */7 8#include <linux/kernel.h>9#include <linux/slab.h>10#include <linux/debugfs.h>11 12#include "mvpp2.h"13#include "mvpp2_prs.h"14#include "mvpp2_cls.h"15 16struct mvpp2_dbgfs_prs_entry {17	int tid;18	struct mvpp2 *priv;19};20 21struct mvpp2_dbgfs_c2_entry {22	int id;23	struct mvpp2 *priv;24};25 26struct mvpp2_dbgfs_flow_entry {27	int flow;28	struct mvpp2 *priv;29};30 31struct mvpp2_dbgfs_flow_tbl_entry {32	int id;33	struct mvpp2 *priv;34};35 36struct mvpp2_dbgfs_port_flow_entry {37	struct mvpp2_port *port;38	struct mvpp2_dbgfs_flow_entry *dbg_fe;39};40 41struct mvpp2_dbgfs_entries {42	/* Entries for Header Parser debug info */43	struct mvpp2_dbgfs_prs_entry prs_entries[MVPP2_PRS_TCAM_SRAM_SIZE];44 45	/* Entries for Classifier C2 engine debug info */46	struct mvpp2_dbgfs_c2_entry c2_entries[MVPP22_CLS_C2_N_ENTRIES];47 48	/* Entries for Classifier Flow Table debug info */49	struct mvpp2_dbgfs_flow_tbl_entry flt_entries[MVPP2_CLS_FLOWS_TBL_SIZE];50 51	/* Entries for Classifier flows debug info */52	struct mvpp2_dbgfs_flow_entry flow_entries[MVPP2_N_PRS_FLOWS];53 54	/* Entries for per-port flows debug info */55	struct mvpp2_dbgfs_port_flow_entry port_flow_entries[MVPP2_MAX_PORTS];56};57 58static int mvpp2_dbgfs_flow_flt_hits_show(struct seq_file *s, void *unused)59{60	struct mvpp2_dbgfs_flow_tbl_entry *entry = s->private;61 62	u32 hits = mvpp2_cls_flow_hits(entry->priv, entry->id);63 64	seq_printf(s, "%u\n", hits);65 66	return 0;67}68 69DEFINE_SHOW_ATTRIBUTE(mvpp2_dbgfs_flow_flt_hits);70 71static int mvpp2_dbgfs_flow_dec_hits_show(struct seq_file *s, void *unused)72{73	struct mvpp2_dbgfs_flow_entry *entry = s->private;74 75	u32 hits = mvpp2_cls_lookup_hits(entry->priv, entry->flow);76 77	seq_printf(s, "%u\n", hits);78 79	return 0;80}81 82DEFINE_SHOW_ATTRIBUTE(mvpp2_dbgfs_flow_dec_hits);83 84static int mvpp2_dbgfs_flow_type_show(struct seq_file *s, void *unused)85{86	struct mvpp2_dbgfs_flow_entry *entry = s->private;87	const struct mvpp2_cls_flow *f;88	const char *flow_name;89 90	f = mvpp2_cls_flow_get(entry->flow);91	if (!f)92		return -EINVAL;93 94	switch (f->flow_type) {95	case IPV4_FLOW:96		flow_name = "ipv4";97		break;98	case IPV6_FLOW:99		flow_name = "ipv6";100		break;101	case TCP_V4_FLOW:102		flow_name = "tcp4";103		break;104	case TCP_V6_FLOW:105		flow_name = "tcp6";106		break;107	case UDP_V4_FLOW:108		flow_name = "udp4";109		break;110	case UDP_V6_FLOW:111		flow_name = "udp6";112		break;113	default:114		flow_name = "other";115	}116 117	seq_printf(s, "%s\n", flow_name);118 119	return 0;120}121 122DEFINE_SHOW_ATTRIBUTE(mvpp2_dbgfs_flow_type);123 124static int mvpp2_dbgfs_flow_id_show(struct seq_file *s, void *unused)125{126	const struct mvpp2_dbgfs_flow_entry *entry = s->private;127	const struct mvpp2_cls_flow *f;128 129	f = mvpp2_cls_flow_get(entry->flow);130	if (!f)131		return -EINVAL;132 133	seq_printf(s, "%d\n", f->flow_id);134 135	return 0;136}137 138DEFINE_SHOW_ATTRIBUTE(mvpp2_dbgfs_flow_id);139 140static int mvpp2_dbgfs_port_flow_hash_opt_show(struct seq_file *s, void *unused)141{142	struct mvpp2_dbgfs_port_flow_entry *entry = s->private;143	struct mvpp2_port *port = entry->port;144	struct mvpp2_cls_flow_entry fe;145	const struct mvpp2_cls_flow *f;146	int flow_index;147	u16 hash_opts;148 149	f = mvpp2_cls_flow_get(entry->dbg_fe->flow);150	if (!f)151		return -EINVAL;152 153	flow_index = MVPP2_CLS_FLT_HASH_ENTRY(entry->port->id, f->flow_id);154 155	mvpp2_cls_flow_read(port->priv, flow_index, &fe);156 157	hash_opts = mvpp2_flow_get_hek_fields(&fe);158 159	seq_printf(s, "0x%04x\n", hash_opts);160 161	return 0;162}163 164DEFINE_SHOW_ATTRIBUTE(mvpp2_dbgfs_port_flow_hash_opt);165 166static int mvpp2_dbgfs_port_flow_engine_show(struct seq_file *s, void *unused)167{168	struct mvpp2_dbgfs_port_flow_entry *entry = s->private;169	struct mvpp2_port *port = entry->port;170	struct mvpp2_cls_flow_entry fe;171	const struct mvpp2_cls_flow *f;172	int flow_index, engine;173 174	f = mvpp2_cls_flow_get(entry->dbg_fe->flow);175	if (!f)176		return -EINVAL;177 178	flow_index = MVPP2_CLS_FLT_HASH_ENTRY(entry->port->id, f->flow_id);179 180	mvpp2_cls_flow_read(port->priv, flow_index, &fe);181 182	engine = mvpp2_cls_flow_eng_get(&fe);183 184	seq_printf(s, "%d\n", engine);185 186	return 0;187}188 189DEFINE_SHOW_ATTRIBUTE(mvpp2_dbgfs_port_flow_engine);190 191static int mvpp2_dbgfs_flow_c2_hits_show(struct seq_file *s, void *unused)192{193	struct mvpp2_dbgfs_c2_entry *entry = s->private;194	u32 hits;195 196	hits = mvpp2_cls_c2_hit_count(entry->priv, entry->id);197 198	seq_printf(s, "%u\n", hits);199 200	return 0;201}202 203DEFINE_SHOW_ATTRIBUTE(mvpp2_dbgfs_flow_c2_hits);204 205static int mvpp2_dbgfs_flow_c2_rxq_show(struct seq_file *s, void *unused)206{207	struct mvpp2_dbgfs_c2_entry *entry = s->private;208	struct mvpp2_cls_c2_entry c2;209	u8 qh, ql;210 211	mvpp2_cls_c2_read(entry->priv, entry->id, &c2);212 213	qh = (c2.attr[0] >> MVPP22_CLS_C2_ATTR0_QHIGH_OFFS) &214	     MVPP22_CLS_C2_ATTR0_QHIGH_MASK;215 216	ql = (c2.attr[0] >> MVPP22_CLS_C2_ATTR0_QLOW_OFFS) &217	     MVPP22_CLS_C2_ATTR0_QLOW_MASK;218 219	seq_printf(s, "%d\n", (qh << 3 | ql));220 221	return 0;222}223 224DEFINE_SHOW_ATTRIBUTE(mvpp2_dbgfs_flow_c2_rxq);225 226static int mvpp2_dbgfs_flow_c2_enable_show(struct seq_file *s, void *unused)227{228	struct mvpp2_dbgfs_c2_entry *entry = s->private;229	struct mvpp2_cls_c2_entry c2;230	int enabled;231 232	mvpp2_cls_c2_read(entry->priv, entry->id, &c2);233 234	enabled = !!(c2.attr[2] & MVPP22_CLS_C2_ATTR2_RSS_EN);235 236	seq_printf(s, "%d\n", enabled);237 238	return 0;239}240 241DEFINE_SHOW_ATTRIBUTE(mvpp2_dbgfs_flow_c2_enable);242 243static int mvpp2_dbgfs_port_vid_show(struct seq_file *s, void *unused)244{245	struct mvpp2_port *port = s->private;246	unsigned char byte[2], enable[2];247	struct mvpp2 *priv = port->priv;248	struct mvpp2_prs_entry pe;249	unsigned long pmap;250	u16 rvid;251	int tid;252 253	for (tid = MVPP2_PRS_VID_PORT_FIRST(port->id);254	     tid <= MVPP2_PRS_VID_PORT_LAST(port->id); tid++) {255		mvpp2_prs_init_from_hw(priv, &pe, tid);256 257		pmap = mvpp2_prs_tcam_port_map_get(&pe);258 259		if (!priv->prs_shadow[tid].valid)260			continue;261 262		if (!test_bit(port->id, &pmap))263			continue;264 265		mvpp2_prs_tcam_data_byte_get(&pe, 2, &byte[0], &enable[0]);266		mvpp2_prs_tcam_data_byte_get(&pe, 3, &byte[1], &enable[1]);267 268		rvid = ((byte[0] & 0xf) << 8) + byte[1];269 270		seq_printf(s, "%u\n", rvid);271	}272 273	return 0;274}275 276DEFINE_SHOW_ATTRIBUTE(mvpp2_dbgfs_port_vid);277 278static int mvpp2_dbgfs_port_parser_show(struct seq_file *s, void *unused)279{280	struct mvpp2_port *port = s->private;281	struct mvpp2 *priv = port->priv;282	struct mvpp2_prs_entry pe;283	unsigned long pmap;284	int i;285 286	for (i = 0; i < MVPP2_PRS_TCAM_SRAM_SIZE; i++) {287		mvpp2_prs_init_from_hw(port->priv, &pe, i);288 289		pmap = mvpp2_prs_tcam_port_map_get(&pe);290		if (priv->prs_shadow[i].valid && test_bit(port->id, &pmap))291			seq_printf(s, "%03d\n", i);292	}293 294	return 0;295}296 297DEFINE_SHOW_ATTRIBUTE(mvpp2_dbgfs_port_parser);298 299static int mvpp2_dbgfs_filter_show(struct seq_file *s, void *unused)300{301	struct mvpp2_port *port = s->private;302	struct mvpp2 *priv = port->priv;303	struct mvpp2_prs_entry pe;304	unsigned long pmap;305	int index, tid;306 307	for (tid = MVPP2_PE_MAC_RANGE_START;308	     tid <= MVPP2_PE_MAC_RANGE_END; tid++) {309		unsigned char da[ETH_ALEN], da_mask[ETH_ALEN];310 311		if (!priv->prs_shadow[tid].valid ||312		    priv->prs_shadow[tid].lu != MVPP2_PRS_LU_MAC ||313		    priv->prs_shadow[tid].udf != MVPP2_PRS_UDF_MAC_DEF)314			continue;315 316		mvpp2_prs_init_from_hw(priv, &pe, tid);317 318		pmap = mvpp2_prs_tcam_port_map_get(&pe);319 320		/* We only want entries active on this port */321		if (!test_bit(port->id, &pmap))322			continue;323 324		/* Read mac addr from entry */325		for (index = 0; index < ETH_ALEN; index++)326			mvpp2_prs_tcam_data_byte_get(&pe, index, &da[index],327						     &da_mask[index]);328 329		seq_printf(s, "%pM\n", da);330	}331 332	return 0;333}334 335DEFINE_SHOW_ATTRIBUTE(mvpp2_dbgfs_filter);336 337static int mvpp2_dbgfs_prs_lu_show(struct seq_file *s, void *unused)338{339	struct mvpp2_dbgfs_prs_entry *entry = s->private;340	struct mvpp2 *priv = entry->priv;341 342	seq_printf(s, "%x\n", priv->prs_shadow[entry->tid].lu);343 344	return 0;345}346 347DEFINE_SHOW_ATTRIBUTE(mvpp2_dbgfs_prs_lu);348 349static int mvpp2_dbgfs_prs_pmap_show(struct seq_file *s, void *unused)350{351	struct mvpp2_dbgfs_prs_entry *entry = s->private;352	struct mvpp2_prs_entry pe;353	unsigned int pmap;354 355	mvpp2_prs_init_from_hw(entry->priv, &pe, entry->tid);356 357	pmap = mvpp2_prs_tcam_port_map_get(&pe);358	pmap &= MVPP2_PRS_PORT_MASK;359 360	seq_printf(s, "%02x\n", pmap);361 362	return 0;363}364 365DEFINE_SHOW_ATTRIBUTE(mvpp2_dbgfs_prs_pmap);366 367static int mvpp2_dbgfs_prs_ai_show(struct seq_file *s, void *unused)368{369	struct mvpp2_dbgfs_prs_entry *entry = s->private;370	struct mvpp2_prs_entry pe;371	unsigned char ai, ai_mask;372 373	mvpp2_prs_init_from_hw(entry->priv, &pe, entry->tid);374 375	ai = pe.tcam[MVPP2_PRS_TCAM_AI_WORD] & MVPP2_PRS_AI_MASK;376	ai_mask = (pe.tcam[MVPP2_PRS_TCAM_AI_WORD] >> 16) & MVPP2_PRS_AI_MASK;377 378	seq_printf(s, "%02x %02x\n", ai, ai_mask);379 380	return 0;381}382 383DEFINE_SHOW_ATTRIBUTE(mvpp2_dbgfs_prs_ai);384 385static int mvpp2_dbgfs_prs_hdata_show(struct seq_file *s, void *unused)386{387	struct mvpp2_dbgfs_prs_entry *entry = s->private;388	struct mvpp2_prs_entry pe;389	unsigned char data[8], mask[8];390	int i;391 392	mvpp2_prs_init_from_hw(entry->priv, &pe, entry->tid);393 394	for (i = 0; i < 8; i++)395		mvpp2_prs_tcam_data_byte_get(&pe, i, &data[i], &mask[i]);396 397	seq_printf(s, "%*phN %*phN\n", 8, data, 8, mask);398 399	return 0;400}401 402DEFINE_SHOW_ATTRIBUTE(mvpp2_dbgfs_prs_hdata);403 404static int mvpp2_dbgfs_prs_sram_show(struct seq_file *s, void *unused)405{406	struct mvpp2_dbgfs_prs_entry *entry = s->private;407	struct mvpp2_prs_entry pe;408 409	mvpp2_prs_init_from_hw(entry->priv, &pe, entry->tid);410 411	seq_printf(s, "%*phN\n", 14, pe.sram);412 413	return 0;414}415 416DEFINE_SHOW_ATTRIBUTE(mvpp2_dbgfs_prs_sram);417 418static int mvpp2_dbgfs_prs_hits_show(struct seq_file *s, void *unused)419{420	struct mvpp2_dbgfs_prs_entry *entry = s->private;421	int val;422 423	val = mvpp2_prs_hits(entry->priv, entry->tid);424	if (val < 0)425		return val;426 427	seq_printf(s, "%d\n", val);428 429	return 0;430}431 432DEFINE_SHOW_ATTRIBUTE(mvpp2_dbgfs_prs_hits);433 434static int mvpp2_dbgfs_prs_valid_show(struct seq_file *s, void *unused)435{436	struct mvpp2_dbgfs_prs_entry *entry = s->private;437	struct mvpp2 *priv = entry->priv;438	int tid = entry->tid;439 440	seq_printf(s, "%d\n", priv->prs_shadow[tid].valid ? 1 : 0);441 442	return 0;443}444 445DEFINE_SHOW_ATTRIBUTE(mvpp2_dbgfs_prs_valid);446 447static int mvpp2_dbgfs_flow_port_init(struct dentry *parent,448				      struct mvpp2_port *port,449				      struct mvpp2_dbgfs_flow_entry *entry)450{451	struct mvpp2_dbgfs_port_flow_entry *port_entry;452	struct dentry *port_dir;453 454	port_dir = debugfs_create_dir(port->dev->name, parent);455 456	port_entry = &port->priv->dbgfs_entries->port_flow_entries[port->id];457 458	port_entry->port = port;459	port_entry->dbg_fe = entry;460 461	debugfs_create_file("hash_opts", 0444, port_dir, port_entry,462			    &mvpp2_dbgfs_port_flow_hash_opt_fops);463 464	debugfs_create_file("engine", 0444, port_dir, port_entry,465			    &mvpp2_dbgfs_port_flow_engine_fops);466 467	return 0;468}469 470static int mvpp2_dbgfs_flow_entry_init(struct dentry *parent,471				       struct mvpp2 *priv, int flow)472{473	struct mvpp2_dbgfs_flow_entry *entry;474	struct dentry *flow_entry_dir;475	char flow_entry_name[10];476	int i, ret;477 478	sprintf(flow_entry_name, "%02d", flow);479 480	flow_entry_dir = debugfs_create_dir(flow_entry_name, parent);481 482	entry = &priv->dbgfs_entries->flow_entries[flow];483 484	entry->flow = flow;485	entry->priv = priv;486 487	debugfs_create_file("dec_hits", 0444, flow_entry_dir, entry,488			    &mvpp2_dbgfs_flow_dec_hits_fops);489 490	debugfs_create_file("type", 0444, flow_entry_dir, entry,491			    &mvpp2_dbgfs_flow_type_fops);492 493	debugfs_create_file("id", 0444, flow_entry_dir, entry,494			    &mvpp2_dbgfs_flow_id_fops);495 496	/* Create entry for each port */497	for (i = 0; i < priv->port_count; i++) {498		ret = mvpp2_dbgfs_flow_port_init(flow_entry_dir,499						 priv->port_list[i], entry);500		if (ret)501			return ret;502	}503 504	return 0;505}506 507static int mvpp2_dbgfs_flow_init(struct dentry *parent, struct mvpp2 *priv)508{509	struct dentry *flow_dir;510	int i, ret;511 512	flow_dir = debugfs_create_dir("flows", parent);513 514	for (i = 0; i < MVPP2_N_PRS_FLOWS; i++) {515		ret = mvpp2_dbgfs_flow_entry_init(flow_dir, priv, i);516		if (ret)517			return ret;518	}519 520	return 0;521}522 523static int mvpp2_dbgfs_prs_entry_init(struct dentry *parent,524				      struct mvpp2 *priv, int tid)525{526	struct mvpp2_dbgfs_prs_entry *entry;527	struct dentry *prs_entry_dir;528	char prs_entry_name[10];529 530	if (tid >= MVPP2_PRS_TCAM_SRAM_SIZE)531		return -EINVAL;532 533	sprintf(prs_entry_name, "%03d", tid);534 535	prs_entry_dir = debugfs_create_dir(prs_entry_name, parent);536 537	entry = &priv->dbgfs_entries->prs_entries[tid];538 539	entry->tid = tid;540	entry->priv = priv;541 542	/* Create each attr */543	debugfs_create_file("sram", 0444, prs_entry_dir, entry,544			    &mvpp2_dbgfs_prs_sram_fops);545 546	debugfs_create_file("valid", 0644, prs_entry_dir, entry,547			    &mvpp2_dbgfs_prs_valid_fops);548 549	debugfs_create_file("lookup_id", 0644, prs_entry_dir, entry,550			    &mvpp2_dbgfs_prs_lu_fops);551 552	debugfs_create_file("ai", 0644, prs_entry_dir, entry,553			    &mvpp2_dbgfs_prs_ai_fops);554 555	debugfs_create_file("header_data", 0644, prs_entry_dir, entry,556			    &mvpp2_dbgfs_prs_hdata_fops);557 558	debugfs_create_file("hits", 0444, prs_entry_dir, entry,559			    &mvpp2_dbgfs_prs_hits_fops);560 561	debugfs_create_file("pmap", 0444, prs_entry_dir, entry,562			     &mvpp2_dbgfs_prs_pmap_fops);563 564	return 0;565}566 567static int mvpp2_dbgfs_prs_init(struct dentry *parent, struct mvpp2 *priv)568{569	struct dentry *prs_dir;570	int i, ret;571 572	prs_dir = debugfs_create_dir("parser", parent);573 574	for (i = 0; i < MVPP2_PRS_TCAM_SRAM_SIZE; i++) {575		ret = mvpp2_dbgfs_prs_entry_init(prs_dir, priv, i);576		if (ret)577			return ret;578	}579 580	return 0;581}582 583static int mvpp2_dbgfs_c2_entry_init(struct dentry *parent,584				     struct mvpp2 *priv, int id)585{586	struct mvpp2_dbgfs_c2_entry *entry;587	struct dentry *c2_entry_dir;588	char c2_entry_name[10];589 590	if (id >= MVPP22_CLS_C2_N_ENTRIES)591		return -EINVAL;592 593	sprintf(c2_entry_name, "%03d", id);594 595	c2_entry_dir = debugfs_create_dir(c2_entry_name, parent);596 597	entry = &priv->dbgfs_entries->c2_entries[id];598 599	entry->id = id;600	entry->priv = priv;601 602	debugfs_create_file("hits", 0444, c2_entry_dir, entry,603			    &mvpp2_dbgfs_flow_c2_hits_fops);604 605	debugfs_create_file("default_rxq", 0444, c2_entry_dir, entry,606			    &mvpp2_dbgfs_flow_c2_rxq_fops);607 608	debugfs_create_file("rss_enable", 0444, c2_entry_dir, entry,609			    &mvpp2_dbgfs_flow_c2_enable_fops);610 611	return 0;612}613 614static int mvpp2_dbgfs_flow_tbl_entry_init(struct dentry *parent,615					   struct mvpp2 *priv, int id)616{617	struct mvpp2_dbgfs_flow_tbl_entry *entry;618	struct dentry *flow_tbl_entry_dir;619	char flow_tbl_entry_name[10];620 621	if (id >= MVPP2_CLS_FLOWS_TBL_SIZE)622		return -EINVAL;623 624	sprintf(flow_tbl_entry_name, "%03d", id);625 626	flow_tbl_entry_dir = debugfs_create_dir(flow_tbl_entry_name, parent);627 628	entry = &priv->dbgfs_entries->flt_entries[id];629 630	entry->id = id;631	entry->priv = priv;632 633	debugfs_create_file("hits", 0444, flow_tbl_entry_dir, entry,634			    &mvpp2_dbgfs_flow_flt_hits_fops);635 636	return 0;637}638 639static int mvpp2_dbgfs_cls_init(struct dentry *parent, struct mvpp2 *priv)640{641	struct dentry *cls_dir, *c2_dir, *flow_tbl_dir;642	int i, ret;643 644	cls_dir = debugfs_create_dir("classifier", parent);645 646	c2_dir = debugfs_create_dir("c2", cls_dir);647 648	for (i = 0; i < MVPP22_CLS_C2_N_ENTRIES; i++) {649		ret = mvpp2_dbgfs_c2_entry_init(c2_dir, priv, i);650		if (ret)651			return ret;652	}653 654	flow_tbl_dir = debugfs_create_dir("flow_table", cls_dir);655 656	for (i = 0; i < MVPP2_CLS_FLOWS_TBL_SIZE; i++) {657		ret = mvpp2_dbgfs_flow_tbl_entry_init(flow_tbl_dir, priv, i);658		if (ret)659			return ret;660	}661 662	return 0;663}664 665static int mvpp2_dbgfs_port_init(struct dentry *parent,666				 struct mvpp2_port *port)667{668	struct dentry *port_dir;669 670	port_dir = debugfs_create_dir(port->dev->name, parent);671 672	debugfs_create_file("parser_entries", 0444, port_dir, port,673			    &mvpp2_dbgfs_port_parser_fops);674 675	debugfs_create_file("mac_filter", 0444, port_dir, port,676			    &mvpp2_dbgfs_filter_fops);677 678	debugfs_create_file("vid_filter", 0444, port_dir, port,679			    &mvpp2_dbgfs_port_vid_fops);680 681	return 0;682}683 684static struct dentry *mvpp2_root;685 686void mvpp2_dbgfs_exit(void)687{688	debugfs_remove(mvpp2_root);689}690 691void mvpp2_dbgfs_cleanup(struct mvpp2 *priv)692{693	debugfs_remove_recursive(priv->dbgfs_dir);694 695	kfree(priv->dbgfs_entries);696}697 698void mvpp2_dbgfs_init(struct mvpp2 *priv, const char *name)699{700	struct dentry *mvpp2_dir;701	int ret, i;702 703	if (!mvpp2_root)704		mvpp2_root = debugfs_create_dir(MVPP2_DRIVER_NAME, NULL);705 706	mvpp2_dir = debugfs_create_dir(name, mvpp2_root);707 708	priv->dbgfs_dir = mvpp2_dir;709	priv->dbgfs_entries = kzalloc(sizeof(*priv->dbgfs_entries), GFP_KERNEL);710	if (!priv->dbgfs_entries)711		goto err;712 713	ret = mvpp2_dbgfs_prs_init(mvpp2_dir, priv);714	if (ret)715		goto err;716 717	ret = mvpp2_dbgfs_cls_init(mvpp2_dir, priv);718	if (ret)719		goto err;720 721	for (i = 0; i < priv->port_count; i++) {722		ret = mvpp2_dbgfs_port_init(mvpp2_dir, priv->port_list[i]);723		if (ret)724			goto err;725	}726 727	ret = mvpp2_dbgfs_flow_init(mvpp2_dir, priv);728	if (ret)729		goto err;730 731	return;732err:733	mvpp2_dbgfs_cleanup(priv);734}735