mirror of
https://github.com/torvalds/linux.git
synced 2024-12-04 18:13:04 +00:00
net: microchip: sparx5: Add VCAP rule debugFS support for the VCAP API
This add support to show all rules in a VCAP instance. The information shown is: - rule id - address range - size - chain id - keyset name, subword size, register span - actionset name, subword size, register span - counter value - sticky bit (one bit width counter) Signed-off-by: Steen Hegelund <steen.hegelund@microchip.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
d4134d41e3
commit
3a7921560d
@ -502,7 +502,7 @@ int vcap_api_check(struct vcap_control *ctrl)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void vcap_erase_cache(struct vcap_rule_internal *ri)
|
||||
void vcap_erase_cache(struct vcap_rule_internal *ri)
|
||||
{
|
||||
ri->vctrl->ops->cache_erase(ri->admin);
|
||||
}
|
||||
@ -578,7 +578,7 @@ int vcap_lookup_rule_by_cookie(struct vcap_control *vctrl, u64 cookie)
|
||||
EXPORT_SYMBOL_GPL(vcap_lookup_rule_by_cookie);
|
||||
|
||||
/* Make a shallow copy of the rule without the fields */
|
||||
static struct vcap_rule_internal *vcap_dup_rule(struct vcap_rule_internal *ri)
|
||||
struct vcap_rule_internal *vcap_dup_rule(struct vcap_rule_internal *ri)
|
||||
{
|
||||
struct vcap_rule_internal *duprule;
|
||||
|
||||
@ -782,9 +782,16 @@ const char *vcap_keyfield_name(struct vcap_control *vctrl,
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(vcap_keyfield_name);
|
||||
|
||||
/* map actionset id to a string with the actionset name */
|
||||
const char *vcap_actionset_name(struct vcap_control *vctrl,
|
||||
enum vcap_actionfield_set actionset)
|
||||
{
|
||||
return vctrl->stats->actionfield_set_names[actionset];
|
||||
}
|
||||
|
||||
/* map action field id to a string with the action name */
|
||||
static const char *vcap_actionfield_name(struct vcap_control *vctrl,
|
||||
enum vcap_action_field action)
|
||||
const char *vcap_actionfield_name(struct vcap_control *vctrl,
|
||||
enum vcap_action_field action)
|
||||
{
|
||||
return vctrl->stats->actionfield_names[action];
|
||||
}
|
||||
|
@ -234,6 +234,106 @@ static int vcap_addr_keyset(struct vcap_control *vctrl,
|
||||
admin->cache.maskstream, false, 0);
|
||||
}
|
||||
|
||||
static int vcap_read_rule(struct vcap_rule_internal *ri)
|
||||
{
|
||||
struct vcap_admin *admin = ri->admin;
|
||||
int sw_idx, ent_idx = 0, act_idx = 0;
|
||||
u32 addr = ri->addr;
|
||||
|
||||
if (!ri->size || !ri->keyset_sw_regs || !ri->actionset_sw_regs) {
|
||||
pr_err("%s:%d: rule is empty\n", __func__, __LINE__);
|
||||
return -EINVAL;
|
||||
}
|
||||
vcap_erase_cache(ri);
|
||||
/* Use the values in the streams to read the VCAP cache */
|
||||
for (sw_idx = 0; sw_idx < ri->size; sw_idx++, addr++) {
|
||||
ri->vctrl->ops->update(ri->ndev, admin, VCAP_CMD_READ,
|
||||
VCAP_SEL_ALL, addr);
|
||||
ri->vctrl->ops->cache_read(ri->ndev, admin,
|
||||
VCAP_SEL_ENTRY, ent_idx,
|
||||
ri->keyset_sw_regs);
|
||||
ri->vctrl->ops->cache_read(ri->ndev, admin,
|
||||
VCAP_SEL_ACTION, act_idx,
|
||||
ri->actionset_sw_regs);
|
||||
if (sw_idx == 0)
|
||||
ri->vctrl->ops->cache_read(ri->ndev, admin,
|
||||
VCAP_SEL_COUNTER,
|
||||
ri->counter_id, 0);
|
||||
ent_idx += ri->keyset_sw_regs;
|
||||
act_idx += ri->actionset_sw_regs;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void vcap_show_admin_rule(struct vcap_control *vctrl,
|
||||
struct vcap_admin *admin,
|
||||
struct vcap_output_print *out,
|
||||
struct vcap_rule_internal *ri)
|
||||
{
|
||||
ri->counter.value = admin->cache.counter;
|
||||
ri->counter.sticky = admin->cache.sticky;
|
||||
out->prf(out->dst,
|
||||
"rule: %u, addr: [%d,%d], X%d, ctr[%d]: %d, hit: %d\n",
|
||||
ri->data.id, ri->addr, ri->addr + ri->size - 1, ri->size,
|
||||
ri->counter_id, ri->counter.value, ri->counter.sticky);
|
||||
out->prf(out->dst, " chain_id: %d\n", ri->data.vcap_chain_id);
|
||||
out->prf(out->dst, " user: %d\n", ri->data.user);
|
||||
out->prf(out->dst, " priority: %d\n", ri->data.priority);
|
||||
out->prf(out->dst, " keyset: %s\n",
|
||||
vcap_keyset_name(vctrl, ri->data.keyset));
|
||||
out->prf(out->dst, " actionset: %s\n",
|
||||
vcap_actionset_name(vctrl, ri->data.actionset));
|
||||
}
|
||||
|
||||
static void vcap_show_admin_info(struct vcap_control *vctrl,
|
||||
struct vcap_admin *admin,
|
||||
struct vcap_output_print *out)
|
||||
{
|
||||
const struct vcap_info *vcap = &vctrl->vcaps[admin->vtype];
|
||||
|
||||
out->prf(out->dst, "name: %s\n", vcap->name);
|
||||
out->prf(out->dst, "rows: %d\n", vcap->rows);
|
||||
out->prf(out->dst, "sw_count: %d\n", vcap->sw_count);
|
||||
out->prf(out->dst, "sw_width: %d\n", vcap->sw_width);
|
||||
out->prf(out->dst, "sticky_width: %d\n", vcap->sticky_width);
|
||||
out->prf(out->dst, "act_width: %d\n", vcap->act_width);
|
||||
out->prf(out->dst, "default_cnt: %d\n", vcap->default_cnt);
|
||||
out->prf(out->dst, "require_cnt_dis: %d\n", vcap->require_cnt_dis);
|
||||
out->prf(out->dst, "version: %d\n", vcap->version);
|
||||
out->prf(out->dst, "vtype: %d\n", admin->vtype);
|
||||
out->prf(out->dst, "vinst: %d\n", admin->vinst);
|
||||
out->prf(out->dst, "first_cid: %d\n", admin->first_cid);
|
||||
out->prf(out->dst, "last_cid: %d\n", admin->last_cid);
|
||||
out->prf(out->dst, "lookups: %d\n", admin->lookups);
|
||||
out->prf(out->dst, "first_valid_addr: %d\n", admin->first_valid_addr);
|
||||
out->prf(out->dst, "last_valid_addr: %d\n", admin->last_valid_addr);
|
||||
out->prf(out->dst, "last_used_addr: %d\n", admin->last_used_addr);
|
||||
}
|
||||
|
||||
static int vcap_show_admin(struct vcap_control *vctrl,
|
||||
struct vcap_admin *admin,
|
||||
struct vcap_output_print *out)
|
||||
{
|
||||
struct vcap_rule_internal *elem, *ri;
|
||||
int ret = 0;
|
||||
|
||||
vcap_show_admin_info(vctrl, admin, out);
|
||||
list_for_each_entry(elem, &admin->rules, list) {
|
||||
ri = vcap_dup_rule(elem);
|
||||
if (IS_ERR(ri))
|
||||
goto free_rule;
|
||||
/* Read data from VCAP */
|
||||
ret = vcap_read_rule(ri);
|
||||
if (ret)
|
||||
goto free_rule;
|
||||
out->prf(out->dst, "\n");
|
||||
vcap_show_admin_rule(vctrl, admin, out, ri);
|
||||
free_rule:
|
||||
vcap_free_rule((struct vcap_rule *)ri);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int vcap_show_admin_raw(struct vcap_control *vctrl,
|
||||
struct vcap_admin *admin,
|
||||
struct vcap_output_print *out)
|
||||
@ -313,6 +413,19 @@ void vcap_port_debugfs(struct device *dev, struct dentry *parent,
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(vcap_port_debugfs);
|
||||
|
||||
/* Show the full VCAP instance data (rules with all fields) */
|
||||
static int vcap_debugfs_show(struct seq_file *m, void *unused)
|
||||
{
|
||||
struct vcap_admin_debugfs_info *info = m->private;
|
||||
struct vcap_output_print out = {
|
||||
.prf = (void *)seq_printf,
|
||||
.dst = m,
|
||||
};
|
||||
|
||||
return vcap_show_admin(info->vctrl, info->admin, &out);
|
||||
}
|
||||
DEFINE_SHOW_ATTRIBUTE(vcap_debugfs);
|
||||
|
||||
/* Show the raw VCAP instance data (rules with address info) */
|
||||
static int vcap_raw_debugfs_show(struct seq_file *m, void *unused)
|
||||
{
|
||||
@ -347,6 +460,9 @@ struct dentry *vcap_debugfs(struct device *dev, struct dentry *parent,
|
||||
info->admin = admin;
|
||||
debugfs_create_file(name, 0444, dir, info,
|
||||
&vcap_raw_debugfs_fops);
|
||||
sprintf(name, "%s_%d", vctrl->vcaps[admin->vtype].name,
|
||||
admin->vinst);
|
||||
debugfs_create_file(name, 0444, dir, info, &vcap_debugfs_fops);
|
||||
}
|
||||
return dir;
|
||||
}
|
||||
|
@ -43,6 +43,10 @@ struct vcap_stream_iter {
|
||||
|
||||
/* Check that the control has a valid set of callbacks */
|
||||
int vcap_api_check(struct vcap_control *ctrl);
|
||||
/* Make a shallow copy of the rule without the fields */
|
||||
struct vcap_rule_internal *vcap_dup_rule(struct vcap_rule_internal *ri);
|
||||
/* Erase the VCAP cache area used or encoding and decoding */
|
||||
void vcap_erase_cache(struct vcap_rule_internal *ri);
|
||||
|
||||
/* Iterator functionality */
|
||||
|
||||
@ -70,4 +74,14 @@ vcap_keyfield_typegroup(struct vcap_control *vctrl,
|
||||
const struct vcap_field *vcap_keyfields(struct vcap_control *vctrl,
|
||||
enum vcap_type vt,
|
||||
enum vcap_keyfield_set keyset);
|
||||
|
||||
/* Actionset and actionfield functionality */
|
||||
|
||||
/* Map actionset id to a string with the actionset name */
|
||||
const char *vcap_actionset_name(struct vcap_control *vctrl,
|
||||
enum vcap_actionfield_set actionset);
|
||||
/* Map key field id to a string with the key name */
|
||||
const char *vcap_actionfield_name(struct vcap_control *vctrl,
|
||||
enum vcap_action_field action);
|
||||
|
||||
#endif /* __VCAP_API_PRIVATE__ */
|
||||
|
Loading…
Reference in New Issue
Block a user