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