xref: /linux/drivers/net/ethernet/microchip/vcap/vcap_api_debugfs.c (revision 0ea5c948cb64bab5bc7a5516774eb8536f05aa0d)
1e0305cc1SSteen Hegelund // SPDX-License-Identifier: GPL-2.0+
2e0305cc1SSteen Hegelund /* Microchip VCAP API debug file system support
3e0305cc1SSteen Hegelund  *
4e0305cc1SSteen Hegelund  * Copyright (c) 2022 Microchip Technology Inc. and its subsidiaries.
5e0305cc1SSteen Hegelund  *
6e0305cc1SSteen Hegelund  */
7e0305cc1SSteen Hegelund 
8d4134d41SSteen Hegelund #include "vcap_api_private.h"
9e0305cc1SSteen Hegelund #include "vcap_api_debugfs.h"
10e0305cc1SSteen Hegelund 
11e0305cc1SSteen Hegelund struct vcap_admin_debugfs_info {
12e0305cc1SSteen Hegelund 	struct vcap_control *vctrl;
13e0305cc1SSteen Hegelund 	struct vcap_admin *admin;
14e0305cc1SSteen Hegelund };
15e0305cc1SSteen Hegelund 
16e0305cc1SSteen Hegelund struct vcap_port_debugfs_info {
17e0305cc1SSteen Hegelund 	struct vcap_control *vctrl;
18e0305cc1SSteen Hegelund 	struct net_device *ndev;
19e0305cc1SSteen Hegelund };
20e0305cc1SSteen Hegelund 
2172d84dd6SSteen Hegelund /* Dump the keyfields value and mask values */
vcap_debugfs_show_rule_keyfield(struct vcap_control * vctrl,struct vcap_output_print * out,enum vcap_key_field key,const struct vcap_field * keyfield,struct vcap_client_keyfield_data * data)2272d84dd6SSteen Hegelund static void vcap_debugfs_show_rule_keyfield(struct vcap_control *vctrl,
2372d84dd6SSteen Hegelund 					    struct vcap_output_print *out,
2472d84dd6SSteen Hegelund 					    enum vcap_key_field key,
2572d84dd6SSteen Hegelund 					    const struct vcap_field *keyfield,
26610c32b2SHoratiu Vultur 					    struct vcap_client_keyfield_data *data)
2772d84dd6SSteen Hegelund {
2872d84dd6SSteen Hegelund 	bool hex = false;
29610c32b2SHoratiu Vultur 	u8 *value, *mask;
3072d84dd6SSteen Hegelund 	int idx, bytes;
3172d84dd6SSteen Hegelund 
3272d84dd6SSteen Hegelund 	out->prf(out->dst, "    %s: W%d: ", vcap_keyfield_name(vctrl, key),
3372d84dd6SSteen Hegelund 		 keyfield[key].width);
3472d84dd6SSteen Hegelund 
3572d84dd6SSteen Hegelund 	switch (keyfield[key].type) {
3672d84dd6SSteen Hegelund 	case VCAP_FIELD_BIT:
37610c32b2SHoratiu Vultur 		out->prf(out->dst, "%d/%d", data->u1.value, data->u1.mask);
3872d84dd6SSteen Hegelund 		break;
3972d84dd6SSteen Hegelund 	case VCAP_FIELD_U32:
40610c32b2SHoratiu Vultur 		value = (u8 *)(&data->u32.value);
41610c32b2SHoratiu Vultur 		mask = (u8 *)(&data->u32.mask);
42610c32b2SHoratiu Vultur 
4372d84dd6SSteen Hegelund 		if (key == VCAP_KF_L3_IP4_SIP || key == VCAP_KF_L3_IP4_DIP) {
44610c32b2SHoratiu Vultur 			out->prf(out->dst, "%pI4h/%pI4h", &data->u32.value,
45610c32b2SHoratiu Vultur 				 &data->u32.mask);
4672d84dd6SSteen Hegelund 		} else if (key == VCAP_KF_ETYPE ||
47b95d9e2cSSteen Hegelund 			   key == VCAP_KF_IF_IGR_PORT_MASK ||
48b95d9e2cSSteen Hegelund 			   key == VCAP_KF_IF_EGR_PORT_MASK) {
4972d84dd6SSteen Hegelund 			hex = true;
5072d84dd6SSteen Hegelund 		} else {
5172d84dd6SSteen Hegelund 			u32 fmsk = (1 << keyfield[key].width) - 1;
5272d84dd6SSteen Hegelund 
53b95d9e2cSSteen Hegelund 			if (keyfield[key].width == 32)
54b95d9e2cSSteen Hegelund 				fmsk = ~0;
55610c32b2SHoratiu Vultur 			out->prf(out->dst, "%u/%u", data->u32.value & fmsk,
56610c32b2SHoratiu Vultur 				 data->u32.mask & fmsk);
5772d84dd6SSteen Hegelund 		}
5872d84dd6SSteen Hegelund 		break;
5972d84dd6SSteen Hegelund 	case VCAP_FIELD_U48:
60610c32b2SHoratiu Vultur 		value = data->u48.value;
61610c32b2SHoratiu Vultur 		mask = data->u48.mask;
6272d84dd6SSteen Hegelund 		if (key == VCAP_KF_L2_SMAC || key == VCAP_KF_L2_DMAC)
63610c32b2SHoratiu Vultur 			out->prf(out->dst, "%pMR/%pMR", data->u48.value,
64610c32b2SHoratiu Vultur 				 data->u48.mask);
6572d84dd6SSteen Hegelund 		else
6672d84dd6SSteen Hegelund 			hex = true;
6772d84dd6SSteen Hegelund 		break;
6872d84dd6SSteen Hegelund 	case VCAP_FIELD_U56:
69610c32b2SHoratiu Vultur 		value = data->u56.value;
70610c32b2SHoratiu Vultur 		mask = data->u56.mask;
71610c32b2SHoratiu Vultur 		hex = true;
72610c32b2SHoratiu Vultur 		break;
7372d84dd6SSteen Hegelund 	case VCAP_FIELD_U64:
74610c32b2SHoratiu Vultur 		value = data->u64.value;
75610c32b2SHoratiu Vultur 		mask = data->u64.mask;
76610c32b2SHoratiu Vultur 		hex = true;
77610c32b2SHoratiu Vultur 		break;
7872d84dd6SSteen Hegelund 	case VCAP_FIELD_U72:
79610c32b2SHoratiu Vultur 		value = data->u72.value;
80610c32b2SHoratiu Vultur 		mask = data->u72.mask;
81610c32b2SHoratiu Vultur 		hex = true;
82610c32b2SHoratiu Vultur 		break;
8372d84dd6SSteen Hegelund 	case VCAP_FIELD_U112:
84610c32b2SHoratiu Vultur 		value = data->u112.value;
85610c32b2SHoratiu Vultur 		mask = data->u112.mask;
8672d84dd6SSteen Hegelund 		hex = true;
8772d84dd6SSteen Hegelund 		break;
8872d84dd6SSteen Hegelund 	case VCAP_FIELD_U128:
8910073399SHoratiu Vultur 		value = data->u128.value;
9010073399SHoratiu Vultur 		mask = data->u128.mask;
9172d84dd6SSteen Hegelund 		if (key == VCAP_KF_L3_IP6_SIP || key == VCAP_KF_L3_IP6_DIP) {
9272d84dd6SSteen Hegelund 			u8 nvalue[16], nmask[16];
9372d84dd6SSteen Hegelund 
94610c32b2SHoratiu Vultur 			vcap_netbytes_copy(nvalue, data->u128.value,
95610c32b2SHoratiu Vultur 					   sizeof(nvalue));
96610c32b2SHoratiu Vultur 			vcap_netbytes_copy(nmask, data->u128.mask,
97610c32b2SHoratiu Vultur 					   sizeof(nmask));
9872d84dd6SSteen Hegelund 			out->prf(out->dst, "%pI6/%pI6", nvalue, nmask);
9972d84dd6SSteen Hegelund 		} else {
10072d84dd6SSteen Hegelund 			hex = true;
10172d84dd6SSteen Hegelund 		}
10272d84dd6SSteen Hegelund 		break;
10372d84dd6SSteen Hegelund 	}
10472d84dd6SSteen Hegelund 	if (hex) {
10572d84dd6SSteen Hegelund 		bytes = DIV_ROUND_UP(keyfield[key].width, BITS_PER_BYTE);
10672d84dd6SSteen Hegelund 		out->prf(out->dst, "0x");
10772d84dd6SSteen Hegelund 		for (idx = 0; idx < bytes; ++idx)
10872d84dd6SSteen Hegelund 			out->prf(out->dst, "%02x", value[bytes - idx - 1]);
10972d84dd6SSteen Hegelund 		out->prf(out->dst, "/0x");
11072d84dd6SSteen Hegelund 		for (idx = 0; idx < bytes; ++idx)
11172d84dd6SSteen Hegelund 			out->prf(out->dst, "%02x", mask[bytes - idx - 1]);
11272d84dd6SSteen Hegelund 	}
11372d84dd6SSteen Hegelund 	out->prf(out->dst, "\n");
11472d84dd6SSteen Hegelund }
11572d84dd6SSteen Hegelund 
11672d84dd6SSteen Hegelund static void
vcap_debugfs_show_rule_actionfield(struct vcap_control * vctrl,struct vcap_output_print * out,enum vcap_action_field action,const struct vcap_field * actionfield,u8 * value)11772d84dd6SSteen Hegelund vcap_debugfs_show_rule_actionfield(struct vcap_control *vctrl,
11872d84dd6SSteen Hegelund 				   struct vcap_output_print *out,
11972d84dd6SSteen Hegelund 				   enum vcap_action_field action,
12072d84dd6SSteen Hegelund 				   const struct vcap_field *actionfield,
12172d84dd6SSteen Hegelund 				   u8 *value)
12272d84dd6SSteen Hegelund {
12372d84dd6SSteen Hegelund 	bool hex = false;
12472d84dd6SSteen Hegelund 	int idx, bytes;
12572d84dd6SSteen Hegelund 	u32 fmsk, val;
12672d84dd6SSteen Hegelund 
12772d84dd6SSteen Hegelund 	out->prf(out->dst, "    %s: W%d: ",
12872d84dd6SSteen Hegelund 		 vcap_actionfield_name(vctrl, action),
12972d84dd6SSteen Hegelund 		 actionfield[action].width);
13072d84dd6SSteen Hegelund 
13172d84dd6SSteen Hegelund 	switch (actionfield[action].type) {
13272d84dd6SSteen Hegelund 	case VCAP_FIELD_BIT:
13372d84dd6SSteen Hegelund 		out->prf(out->dst, "%d", value[0]);
13472d84dd6SSteen Hegelund 		break;
13572d84dd6SSteen Hegelund 	case VCAP_FIELD_U32:
13672d84dd6SSteen Hegelund 		fmsk = (1 << actionfield[action].width) - 1;
13772d84dd6SSteen Hegelund 		val = *(u32 *)value;
13872d84dd6SSteen Hegelund 		out->prf(out->dst, "%u", val & fmsk);
13972d84dd6SSteen Hegelund 		break;
14072d84dd6SSteen Hegelund 	case VCAP_FIELD_U48:
14172d84dd6SSteen Hegelund 	case VCAP_FIELD_U56:
14272d84dd6SSteen Hegelund 	case VCAP_FIELD_U64:
14372d84dd6SSteen Hegelund 	case VCAP_FIELD_U72:
14472d84dd6SSteen Hegelund 	case VCAP_FIELD_U112:
14572d84dd6SSteen Hegelund 	case VCAP_FIELD_U128:
14672d84dd6SSteen Hegelund 		hex = true;
14772d84dd6SSteen Hegelund 		break;
14872d84dd6SSteen Hegelund 	}
14972d84dd6SSteen Hegelund 	if (hex) {
15072d84dd6SSteen Hegelund 		bytes = DIV_ROUND_UP(actionfield[action].width, BITS_PER_BYTE);
15172d84dd6SSteen Hegelund 		out->prf(out->dst, "0x");
15272d84dd6SSteen Hegelund 		for (idx = 0; idx < bytes; ++idx)
15372d84dd6SSteen Hegelund 			out->prf(out->dst, "%02x", value[bytes - idx - 1]);
15472d84dd6SSteen Hegelund 	}
15572d84dd6SSteen Hegelund 	out->prf(out->dst, "\n");
15672d84dd6SSteen Hegelund }
15772d84dd6SSteen Hegelund 
vcap_debugfs_show_keysets(struct vcap_rule_internal * ri,struct vcap_output_print * out)158814e7693SSteen Hegelund static int vcap_debugfs_show_keysets(struct vcap_rule_internal *ri,
159814e7693SSteen Hegelund 				     struct vcap_output_print *out)
160814e7693SSteen Hegelund {
161814e7693SSteen Hegelund 	struct vcap_admin *admin = ri->admin;
162814e7693SSteen Hegelund 	enum vcap_keyfield_set keysets[10];
163814e7693SSteen Hegelund 	struct vcap_keyset_list matches;
164814e7693SSteen Hegelund 	int err;
165814e7693SSteen Hegelund 
166814e7693SSteen Hegelund 	matches.keysets = keysets;
167814e7693SSteen Hegelund 	matches.cnt = 0;
168814e7693SSteen Hegelund 	matches.max = ARRAY_SIZE(keysets);
169814e7693SSteen Hegelund 
17018a15c76SSteen Hegelund 	if (ri->state == VCAP_RS_DISABLED)
17118a15c76SSteen Hegelund 		err = vcap_rule_get_keysets(ri, &matches);
17218a15c76SSteen Hegelund 	else
173814e7693SSteen Hegelund 		err = vcap_find_keystream_keysets(ri->vctrl, admin->vtype,
174814e7693SSteen Hegelund 						  admin->cache.keystream,
175814e7693SSteen Hegelund 						  admin->cache.maskstream,
176814e7693SSteen Hegelund 						  false, 0, &matches);
177814e7693SSteen Hegelund 	if (err) {
178814e7693SSteen Hegelund 		pr_err("%s:%d: could not find valid keysets: %d\n",
179814e7693SSteen Hegelund 		       __func__, __LINE__, err);
180814e7693SSteen Hegelund 		return err;
181814e7693SSteen Hegelund 	}
182814e7693SSteen Hegelund 
183814e7693SSteen Hegelund 	out->prf(out->dst, "  keysets:");
184814e7693SSteen Hegelund 	for (int idx = 0; idx < matches.cnt; ++idx)
185814e7693SSteen Hegelund 		out->prf(out->dst, " %s",
186814e7693SSteen Hegelund 			 vcap_keyset_name(ri->vctrl, matches.keysets[idx]));
187814e7693SSteen Hegelund 	out->prf(out->dst, "\n");
188814e7693SSteen Hegelund 	return 0;
189814e7693SSteen Hegelund }
190814e7693SSteen Hegelund 
vcap_debugfs_show_rule_keyset(struct vcap_rule_internal * ri,struct vcap_output_print * out)19172d84dd6SSteen Hegelund static int vcap_debugfs_show_rule_keyset(struct vcap_rule_internal *ri,
19272d84dd6SSteen Hegelund 					 struct vcap_output_print *out)
19372d84dd6SSteen Hegelund {
19472d84dd6SSteen Hegelund 	struct vcap_control *vctrl = ri->vctrl;
19572d84dd6SSteen Hegelund 	struct vcap_admin *admin = ri->admin;
19672d84dd6SSteen Hegelund 	const struct vcap_field *keyfield;
197610c32b2SHoratiu Vultur 	struct vcap_client_keyfield *ckf;
19872d84dd6SSteen Hegelund 
199814e7693SSteen Hegelund 	vcap_debugfs_show_keysets(ri, out);
20072d84dd6SSteen Hegelund 	out->prf(out->dst, "  keyset_sw: %d\n", ri->keyset_sw);
20172d84dd6SSteen Hegelund 	out->prf(out->dst, "  keyset_sw_regs: %d\n", ri->keyset_sw_regs);
202610c32b2SHoratiu Vultur 
203610c32b2SHoratiu Vultur 	list_for_each_entry(ckf, &ri->data.keyfields, ctrl.list) {
204610c32b2SHoratiu Vultur 		keyfield = vcap_keyfields(vctrl, admin->vtype, ri->data.keyset);
205610c32b2SHoratiu Vultur 		vcap_debugfs_show_rule_keyfield(vctrl, out, ckf->ctrl.key,
206610c32b2SHoratiu Vultur 						keyfield, &ckf->data);
20772d84dd6SSteen Hegelund 	}
208610c32b2SHoratiu Vultur 
20972d84dd6SSteen Hegelund 	return 0;
21072d84dd6SSteen Hegelund }
21172d84dd6SSteen Hegelund 
vcap_debugfs_show_rule_actionset(struct vcap_rule_internal * ri,struct vcap_output_print * out)21272d84dd6SSteen Hegelund static int vcap_debugfs_show_rule_actionset(struct vcap_rule_internal *ri,
21372d84dd6SSteen Hegelund 					    struct vcap_output_print *out)
21472d84dd6SSteen Hegelund {
21572d84dd6SSteen Hegelund 	struct vcap_control *vctrl = ri->vctrl;
21672d84dd6SSteen Hegelund 	struct vcap_admin *admin = ri->admin;
21772d84dd6SSteen Hegelund 	const struct vcap_field *actionfield;
218610c32b2SHoratiu Vultur 	struct vcap_client_actionfield *caf;
21972d84dd6SSteen Hegelund 
22072d84dd6SSteen Hegelund 	out->prf(out->dst, "  actionset: %s\n",
22172d84dd6SSteen Hegelund 		 vcap_actionset_name(vctrl, ri->data.actionset));
22272d84dd6SSteen Hegelund 	out->prf(out->dst, "  actionset_sw: %d\n", ri->actionset_sw);
22372d84dd6SSteen Hegelund 	out->prf(out->dst, "  actionset_sw_regs: %d\n", ri->actionset_sw_regs);
224610c32b2SHoratiu Vultur 
225610c32b2SHoratiu Vultur 	list_for_each_entry(caf, &ri->data.actionfields, ctrl.list) {
226610c32b2SHoratiu Vultur 		actionfield = vcap_actionfields(vctrl, admin->vtype,
227610c32b2SHoratiu Vultur 						ri->data.actionset);
228610c32b2SHoratiu Vultur 		vcap_debugfs_show_rule_actionfield(vctrl, out, caf->ctrl.action,
229610c32b2SHoratiu Vultur 						   actionfield,
230610c32b2SHoratiu Vultur 						   &caf->data.u1.value);
23172d84dd6SSteen Hegelund 	}
232610c32b2SHoratiu Vultur 
23372d84dd6SSteen Hegelund 	return 0;
23472d84dd6SSteen Hegelund }
23572d84dd6SSteen Hegelund 
vcap_show_admin_rule(struct vcap_control * vctrl,struct vcap_admin * admin,struct vcap_output_print * out,struct vcap_rule_internal * ri)2363a792156SSteen Hegelund static void vcap_show_admin_rule(struct vcap_control *vctrl,
2373a792156SSteen Hegelund 				 struct vcap_admin *admin,
2383a792156SSteen Hegelund 				 struct vcap_output_print *out,
2393a792156SSteen Hegelund 				 struct vcap_rule_internal *ri)
2403a792156SSteen Hegelund {
2413a792156SSteen Hegelund 	ri->counter.value = admin->cache.counter;
2423a792156SSteen Hegelund 	ri->counter.sticky = admin->cache.sticky;
2433a792156SSteen Hegelund 	out->prf(out->dst,
2443a792156SSteen Hegelund 		 "rule: %u, addr: [%d,%d], X%d, ctr[%d]: %d, hit: %d\n",
2453a792156SSteen Hegelund 		 ri->data.id, ri->addr, ri->addr + ri->size - 1, ri->size,
2463a792156SSteen Hegelund 		 ri->counter_id, ri->counter.value, ri->counter.sticky);
2473a792156SSteen Hegelund 	out->prf(out->dst, "  chain_id: %d\n", ri->data.vcap_chain_id);
2483a792156SSteen Hegelund 	out->prf(out->dst, "  user: %d\n", ri->data.user);
2493a792156SSteen Hegelund 	out->prf(out->dst, "  priority: %d\n", ri->data.priority);
250814e7693SSteen Hegelund 	out->prf(out->dst, "  state: ");
251814e7693SSteen Hegelund 	switch (ri->state) {
252814e7693SSteen Hegelund 	case VCAP_RS_PERMANENT:
253814e7693SSteen Hegelund 		out->prf(out->dst, "permanent\n");
254814e7693SSteen Hegelund 		break;
255814e7693SSteen Hegelund 	case VCAP_RS_DISABLED:
256814e7693SSteen Hegelund 		out->prf(out->dst, "disabled\n");
257814e7693SSteen Hegelund 		break;
258814e7693SSteen Hegelund 	case VCAP_RS_ENABLED:
259814e7693SSteen Hegelund 		out->prf(out->dst, "enabled\n");
260814e7693SSteen Hegelund 		break;
261814e7693SSteen Hegelund 	}
26272d84dd6SSteen Hegelund 	vcap_debugfs_show_rule_keyset(ri, out);
26372d84dd6SSteen Hegelund 	vcap_debugfs_show_rule_actionset(ri, out);
2643a792156SSteen Hegelund }
2653a792156SSteen Hegelund 
vcap_show_admin_info(struct vcap_control * vctrl,struct vcap_admin * admin,struct vcap_output_print * out)2663a792156SSteen Hegelund static void vcap_show_admin_info(struct vcap_control *vctrl,
2673a792156SSteen Hegelund 				 struct vcap_admin *admin,
2683a792156SSteen Hegelund 				 struct vcap_output_print *out)
2693a792156SSteen Hegelund {
2703a792156SSteen Hegelund 	const struct vcap_info *vcap = &vctrl->vcaps[admin->vtype];
2713a792156SSteen Hegelund 
2723a792156SSteen Hegelund 	out->prf(out->dst, "name: %s\n", vcap->name);
2733a792156SSteen Hegelund 	out->prf(out->dst, "rows: %d\n", vcap->rows);
2743a792156SSteen Hegelund 	out->prf(out->dst, "sw_count: %d\n", vcap->sw_count);
2753a792156SSteen Hegelund 	out->prf(out->dst, "sw_width: %d\n", vcap->sw_width);
2763a792156SSteen Hegelund 	out->prf(out->dst, "sticky_width: %d\n", vcap->sticky_width);
2773a792156SSteen Hegelund 	out->prf(out->dst, "act_width: %d\n", vcap->act_width);
2783a792156SSteen Hegelund 	out->prf(out->dst, "default_cnt: %d\n", vcap->default_cnt);
2793a792156SSteen Hegelund 	out->prf(out->dst, "require_cnt_dis: %d\n", vcap->require_cnt_dis);
2803a792156SSteen Hegelund 	out->prf(out->dst, "version: %d\n", vcap->version);
2813a792156SSteen Hegelund 	out->prf(out->dst, "vtype: %d\n", admin->vtype);
2823a792156SSteen Hegelund 	out->prf(out->dst, "vinst: %d\n", admin->vinst);
283e7e3f514SSteen Hegelund 	out->prf(out->dst, "ingress: %d\n", admin->ingress);
2843a792156SSteen Hegelund 	out->prf(out->dst, "first_cid: %d\n", admin->first_cid);
2853a792156SSteen Hegelund 	out->prf(out->dst, "last_cid: %d\n", admin->last_cid);
2863a792156SSteen Hegelund 	out->prf(out->dst, "lookups: %d\n", admin->lookups);
2873a792156SSteen Hegelund 	out->prf(out->dst, "first_valid_addr: %d\n", admin->first_valid_addr);
2883a792156SSteen Hegelund 	out->prf(out->dst, "last_valid_addr: %d\n", admin->last_valid_addr);
2893a792156SSteen Hegelund 	out->prf(out->dst, "last_used_addr: %d\n", admin->last_used_addr);
2903a792156SSteen Hegelund }
2913a792156SSteen Hegelund 
vcap_show_admin(struct vcap_control * vctrl,struct vcap_admin * admin,struct vcap_output_print * out)2923a792156SSteen Hegelund static int vcap_show_admin(struct vcap_control *vctrl,
2933a792156SSteen Hegelund 			   struct vcap_admin *admin,
2943a792156SSteen Hegelund 			   struct vcap_output_print *out)
2953a792156SSteen Hegelund {
296610c32b2SHoratiu Vultur 	struct vcap_rule_internal *elem;
297610c32b2SHoratiu Vultur 	struct vcap_rule *vrule;
2983a792156SSteen Hegelund 	int ret = 0;
2993a792156SSteen Hegelund 
3003a792156SSteen Hegelund 	vcap_show_admin_info(vctrl, admin, out);
3013a792156SSteen Hegelund 	list_for_each_entry(elem, &admin->rules, list) {
3029579e2c2SSteen Hegelund 		vrule = vcap_decode_rule(elem);
303*788f63c4SDan Carpenter 		if (IS_ERR(vrule)) {
304610c32b2SHoratiu Vultur 			ret = PTR_ERR(vrule);
305610c32b2SHoratiu Vultur 			break;
306682f560bSDan Carpenter 		}
307682f560bSDan Carpenter 
308610c32b2SHoratiu Vultur 		out->prf(out->dst, "\n");
309610c32b2SHoratiu Vultur 		vcap_show_admin_rule(vctrl, admin, out, to_intrule(vrule));
310610c32b2SHoratiu Vultur 		vcap_free_rule(vrule);
311610c32b2SHoratiu Vultur 	}
3123a792156SSteen Hegelund 	return ret;
3133a792156SSteen Hegelund }
3143a792156SSteen Hegelund 
vcap_show_admin_raw(struct vcap_control * vctrl,struct vcap_admin * admin,struct vcap_output_print * out)315d4134d41SSteen Hegelund static int vcap_show_admin_raw(struct vcap_control *vctrl,
316d4134d41SSteen Hegelund 			       struct vcap_admin *admin,
317d4134d41SSteen Hegelund 			       struct vcap_output_print *out)
318d4134d41SSteen Hegelund {
31914b639caSSteen Hegelund 	enum vcap_keyfield_set keysets[10];
320d4134d41SSteen Hegelund 	enum vcap_type vt = admin->vtype;
32114b639caSSteen Hegelund 	struct vcap_keyset_list kslist;
322d4134d41SSteen Hegelund 	struct vcap_rule_internal *ri;
323d4134d41SSteen Hegelund 	const struct vcap_set *info;
32414b639caSSteen Hegelund 	int addr, idx;
325d4134d41SSteen Hegelund 	int ret;
326d4134d41SSteen Hegelund 
327d4134d41SSteen Hegelund 	if (list_empty(&admin->rules))
328d4134d41SSteen Hegelund 		return 0;
329d4134d41SSteen Hegelund 
330d4134d41SSteen Hegelund 	ret = vcap_api_check(vctrl);
331d4134d41SSteen Hegelund 	if (ret)
332d4134d41SSteen Hegelund 		return ret;
333d4134d41SSteen Hegelund 
334d4134d41SSteen Hegelund 	ri = list_first_entry(&admin->rules, struct vcap_rule_internal, list);
335d4134d41SSteen Hegelund 
336d4134d41SSteen Hegelund 	/* Go from higher to lower addresses searching for a keyset */
33714b639caSSteen Hegelund 	kslist.keysets = keysets;
33814b639caSSteen Hegelund 	kslist.max = ARRAY_SIZE(keysets);
339d4134d41SSteen Hegelund 	for (addr = admin->last_valid_addr; addr >= admin->first_valid_addr;
340d4134d41SSteen Hegelund 	     --addr) {
34114b639caSSteen Hegelund 		kslist.cnt = 0;
34214b639caSSteen Hegelund 		ret = vcap_addr_keysets(vctrl, ri->ndev, admin, addr, &kslist);
34314b639caSSteen Hegelund 		if (ret < 0)
344d4134d41SSteen Hegelund 			continue;
34514b639caSSteen Hegelund 		info = vcap_keyfieldset(vctrl, vt, kslist.keysets[0]);
346d4134d41SSteen Hegelund 		if (!info)
347d4134d41SSteen Hegelund 			continue;
34814b639caSSteen Hegelund 		if (addr % info->sw_per_item) {
349d4134d41SSteen Hegelund 			pr_info("addr: %d X%d error rule, keyset: %s\n",
350d4134d41SSteen Hegelund 				addr,
351d4134d41SSteen Hegelund 				info->sw_per_item,
35214b639caSSteen Hegelund 				vcap_keyset_name(vctrl, kslist.keysets[0]));
35314b639caSSteen Hegelund 		} else {
35414b639caSSteen Hegelund 			out->prf(out->dst, "  addr: %d, X%d rule, keysets:",
355d4134d41SSteen Hegelund 				 addr,
35614b639caSSteen Hegelund 				 info->sw_per_item);
35714b639caSSteen Hegelund 			for (idx = 0; idx < kslist.cnt; ++idx)
35814b639caSSteen Hegelund 				out->prf(out->dst, " %s",
35914b639caSSteen Hegelund 					 vcap_keyset_name(vctrl,
36014b639caSSteen Hegelund 							  kslist.keysets[idx]));
36114b639caSSteen Hegelund 			out->prf(out->dst, "\n");
36214b639caSSteen Hegelund 		}
363d4134d41SSteen Hegelund 	}
364d4134d41SSteen Hegelund 	return 0;
365d4134d41SSteen Hegelund }
366d4134d41SSteen Hegelund 
367e0305cc1SSteen Hegelund /* Show the port configuration and status */
vcap_port_debugfs_show(struct seq_file * m,void * unused)368e0305cc1SSteen Hegelund static int vcap_port_debugfs_show(struct seq_file *m, void *unused)
369e0305cc1SSteen Hegelund {
370e0305cc1SSteen Hegelund 	struct vcap_port_debugfs_info *info = m->private;
371e0305cc1SSteen Hegelund 	struct vcap_admin *admin;
372e0305cc1SSteen Hegelund 	struct vcap_output_print out = {
373e0305cc1SSteen Hegelund 		.prf = (void *)seq_printf,
374e0305cc1SSteen Hegelund 		.dst = m,
375e0305cc1SSteen Hegelund 	};
376e0305cc1SSteen Hegelund 
377e0305cc1SSteen Hegelund 	list_for_each_entry(admin, &info->vctrl->list, list) {
378e0305cc1SSteen Hegelund 		if (admin->vinst)
379e0305cc1SSteen Hegelund 			continue;
380e0305cc1SSteen Hegelund 		info->vctrl->ops->port_info(info->ndev, admin, &out);
381e0305cc1SSteen Hegelund 	}
382e0305cc1SSteen Hegelund 	return 0;
383e0305cc1SSteen Hegelund }
384e0305cc1SSteen Hegelund DEFINE_SHOW_ATTRIBUTE(vcap_port_debugfs);
385e0305cc1SSteen Hegelund 
vcap_port_debugfs(struct device * dev,struct dentry * parent,struct vcap_control * vctrl,struct net_device * ndev)386e0305cc1SSteen Hegelund void vcap_port_debugfs(struct device *dev, struct dentry *parent,
387e0305cc1SSteen Hegelund 		       struct vcap_control *vctrl,
388e0305cc1SSteen Hegelund 		       struct net_device *ndev)
389e0305cc1SSteen Hegelund {
390e0305cc1SSteen Hegelund 	struct vcap_port_debugfs_info *info;
391e0305cc1SSteen Hegelund 
392e0305cc1SSteen Hegelund 	info = devm_kzalloc(dev, sizeof(*info), GFP_KERNEL);
393e0305cc1SSteen Hegelund 	if (!info)
394e0305cc1SSteen Hegelund 		return;
395e0305cc1SSteen Hegelund 
396e0305cc1SSteen Hegelund 	info->vctrl = vctrl;
397e0305cc1SSteen Hegelund 	info->ndev = ndev;
398e0305cc1SSteen Hegelund 	debugfs_create_file(netdev_name(ndev), 0444, parent, info,
399e0305cc1SSteen Hegelund 			    &vcap_port_debugfs_fops);
400e0305cc1SSteen Hegelund }
401e0305cc1SSteen Hegelund EXPORT_SYMBOL_GPL(vcap_port_debugfs);
402e0305cc1SSteen Hegelund 
4033a792156SSteen Hegelund /* Show the full VCAP instance data (rules with all fields) */
vcap_debugfs_show(struct seq_file * m,void * unused)4043a792156SSteen Hegelund static int vcap_debugfs_show(struct seq_file *m, void *unused)
4053a792156SSteen Hegelund {
4063a792156SSteen Hegelund 	struct vcap_admin_debugfs_info *info = m->private;
4073a792156SSteen Hegelund 	struct vcap_output_print out = {
4083a792156SSteen Hegelund 		.prf = (void *)seq_printf,
4093a792156SSteen Hegelund 		.dst = m,
4103a792156SSteen Hegelund 	};
4119579e2c2SSteen Hegelund 	int ret;
4123a792156SSteen Hegelund 
4139579e2c2SSteen Hegelund 	mutex_lock(&info->admin->lock);
4149579e2c2SSteen Hegelund 	ret = vcap_show_admin(info->vctrl, info->admin, &out);
4159579e2c2SSteen Hegelund 	mutex_unlock(&info->admin->lock);
4169579e2c2SSteen Hegelund 	return ret;
4173a792156SSteen Hegelund }
4183a792156SSteen Hegelund DEFINE_SHOW_ATTRIBUTE(vcap_debugfs);
4193a792156SSteen Hegelund 
420e0305cc1SSteen Hegelund /* Show the raw VCAP instance data (rules with address info) */
vcap_raw_debugfs_show(struct seq_file * m,void * unused)421e0305cc1SSteen Hegelund static int vcap_raw_debugfs_show(struct seq_file *m, void *unused)
422e0305cc1SSteen Hegelund {
423d4134d41SSteen Hegelund 	struct vcap_admin_debugfs_info *info = m->private;
424d4134d41SSteen Hegelund 	struct vcap_output_print out = {
425d4134d41SSteen Hegelund 		.prf = (void *)seq_printf,
426d4134d41SSteen Hegelund 		.dst = m,
427d4134d41SSteen Hegelund 	};
4289579e2c2SSteen Hegelund 	int ret;
429d4134d41SSteen Hegelund 
4309579e2c2SSteen Hegelund 	mutex_lock(&info->admin->lock);
4319579e2c2SSteen Hegelund 	ret = vcap_show_admin_raw(info->vctrl, info->admin, &out);
4329579e2c2SSteen Hegelund 	mutex_unlock(&info->admin->lock);
4339579e2c2SSteen Hegelund 	return ret;
434e0305cc1SSteen Hegelund }
435e0305cc1SSteen Hegelund DEFINE_SHOW_ATTRIBUTE(vcap_raw_debugfs);
436e0305cc1SSteen Hegelund 
vcap_debugfs(struct device * dev,struct dentry * parent,struct vcap_control * vctrl)437e0305cc1SSteen Hegelund struct dentry *vcap_debugfs(struct device *dev, struct dentry *parent,
438e0305cc1SSteen Hegelund 			    struct vcap_control *vctrl)
439e0305cc1SSteen Hegelund {
440e0305cc1SSteen Hegelund 	struct vcap_admin_debugfs_info *info;
441e0305cc1SSteen Hegelund 	struct vcap_admin *admin;
442e0305cc1SSteen Hegelund 	struct dentry *dir;
443e0305cc1SSteen Hegelund 	char name[50];
444e0305cc1SSteen Hegelund 
445e0305cc1SSteen Hegelund 	dir = debugfs_create_dir("vcaps", parent);
446e0305cc1SSteen Hegelund 	if (PTR_ERR_OR_ZERO(dir))
447e0305cc1SSteen Hegelund 		return NULL;
448e0305cc1SSteen Hegelund 	list_for_each_entry(admin, &vctrl->list, list) {
449e0305cc1SSteen Hegelund 		sprintf(name, "raw_%s_%d", vctrl->vcaps[admin->vtype].name,
450e0305cc1SSteen Hegelund 			admin->vinst);
451e0305cc1SSteen Hegelund 		info = devm_kzalloc(dev, sizeof(*info), GFP_KERNEL);
452e0305cc1SSteen Hegelund 		if (!info)
453e0305cc1SSteen Hegelund 			return NULL;
454e0305cc1SSteen Hegelund 		info->vctrl = vctrl;
455e0305cc1SSteen Hegelund 		info->admin = admin;
456e0305cc1SSteen Hegelund 		debugfs_create_file(name, 0444, dir, info,
457e0305cc1SSteen Hegelund 				    &vcap_raw_debugfs_fops);
4583a792156SSteen Hegelund 		sprintf(name, "%s_%d", vctrl->vcaps[admin->vtype].name,
4593a792156SSteen Hegelund 			admin->vinst);
4603a792156SSteen Hegelund 		debugfs_create_file(name, 0444, dir, info, &vcap_debugfs_fops);
461e0305cc1SSteen Hegelund 	}
462e0305cc1SSteen Hegelund 	return dir;
463e0305cc1SSteen Hegelund }
464e0305cc1SSteen Hegelund EXPORT_SYMBOL_GPL(vcap_debugfs);
465552b7d13SSteen Hegelund 
466552b7d13SSteen Hegelund #ifdef CONFIG_VCAP_KUNIT_TEST
467552b7d13SSteen Hegelund #include "vcap_api_debugfs_kunit.c"
468552b7d13SSteen Hegelund #endif
469