Commit 14b639ca authored by Steen Hegelund's avatar Steen Hegelund Committed by David S. Miller

net: microchip: sparx5: Support for displaying a list of keysets

This will display a list of keyset in case the type_id field in the VCAP
rule has been wildcarded.
Signed-off-by: default avatarSteen Hegelund <steen.hegelund@microchip.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 0ca60948
......@@ -192,22 +192,22 @@ static bool vcap_verify_keystream_keyset(struct vcap_control *vctrl,
vcap_iter_init(&iter, vcap->sw_width, tgt, typefld->offset);
vcap_decode_field(keystream, &iter, typefld->width, (u8 *)&value);
return (value == info->type_id);
return (value & mask) == (info->type_id & mask);
}
/* Verify that the typegroup information, subword count, keyset and type id
* are in sync and correct, return the keyset
* are in sync and correct, return the list of matching keysets
*/
static enum
vcap_keyfield_set vcap_find_keystream_keyset(struct vcap_control *vctrl,
static int
vcap_find_keystream_keysets(struct vcap_control *vctrl,
enum vcap_type vt,
u32 *keystream,
u32 *mskstream,
bool mask, int sw_max)
bool mask, int sw_max,
struct vcap_keyset_list *kslist)
{
const struct vcap_set *keyfield_set;
int sw_count, idx;
bool res;
sw_count = vcap_find_keystream_typegroup_sw(vctrl, vt, keystream, mask,
sw_max);
......@@ -219,11 +219,12 @@ vcap_keyfield_set vcap_find_keystream_keyset(struct vcap_control *vctrl,
if (keyfield_set[idx].sw_per_item != sw_count)
continue;
res = vcap_verify_keystream_keyset(vctrl, vt, keystream,
mskstream, idx);
if (res)
return idx;
if (vcap_verify_keystream_keyset(vctrl, vt, keystream,
mskstream, idx))
vcap_keyset_list_add(kslist, idx);
}
if (kslist->cnt > 0)
return 0;
return -EINVAL;
}
......@@ -296,13 +297,14 @@ vcap_find_actionstream_actionset(struct vcap_control *vctrl,
return -EINVAL;
}
/* Read key data from a VCAP address and discover if there is a rule keyset
/* Read key data from a VCAP address and discover if there are any rule keysets
* here
*/
static int vcap_addr_keyset(struct vcap_control *vctrl,
static int vcap_addr_keysets(struct vcap_control *vctrl,
struct net_device *ndev,
struct vcap_admin *admin,
int addr)
int addr,
struct vcap_keyset_list *kslist)
{
enum vcap_type vt = admin->vtype;
int keyset_sw_regs, idx;
......@@ -320,9 +322,10 @@ static int vcap_addr_keyset(struct vcap_control *vctrl,
}
if (key == 0 && mask == 0)
return -EINVAL;
/* Decode and locate the keyset */
return vcap_find_keystream_keyset(vctrl, vt, admin->cache.keystream,
admin->cache.maskstream, false, 0);
/* Decode and locate the keysets */
return vcap_find_keystream_keysets(vctrl, vt, admin->cache.keystream,
admin->cache.maskstream, false, 0,
kslist);
}
static int vcap_read_rule(struct vcap_rule_internal *ri)
......@@ -471,9 +474,11 @@ static int vcap_debugfs_show_rule_keyset(struct vcap_rule_internal *ri,
struct vcap_control *vctrl = ri->vctrl;
struct vcap_stream_iter kiter, miter;
struct vcap_admin *admin = ri->admin;
enum vcap_keyfield_set keysets[10];
const struct vcap_field *keyfield;
enum vcap_type vt = admin->vtype;
const struct vcap_typegroup *tgt;
struct vcap_keyset_list matches;
enum vcap_keyfield_set keyset;
int idx, res, keyfield_count;
u32 *maskstream;
......@@ -483,16 +488,22 @@ static int vcap_debugfs_show_rule_keyset(struct vcap_rule_internal *ri,
keystream = admin->cache.keystream;
maskstream = admin->cache.maskstream;
res = vcap_find_keystream_keyset(vctrl, vt, keystream, maskstream,
false, 0);
matches.keysets = keysets;
matches.cnt = 0;
matches.max = ARRAY_SIZE(keysets);
res = vcap_find_keystream_keysets(vctrl, vt, keystream, maskstream,
false, 0, &matches);
if (res < 0) {
pr_err("%s:%d: could not find valid keyset: %d\n",
pr_err("%s:%d: could not find valid keysets: %d\n",
__func__, __LINE__, res);
return -EINVAL;
}
keyset = res;
out->prf(out->dst, " keyset: %s\n",
vcap_keyset_name(vctrl, ri->data.keyset));
keyset = matches.keysets[0];
out->prf(out->dst, " keysets:");
for (idx = 0; idx < matches.cnt; ++idx)
out->prf(out->dst, " %s",
vcap_keyset_name(vctrl, matches.keysets[idx]));
out->prf(out->dst, "\n");
out->prf(out->dst, " keyset_sw: %d\n", ri->keyset_sw);
out->prf(out->dst, " keyset_sw_regs: %d\n", ri->keyset_sw_regs);
keyfield_count = vcap_keyfield_count(vctrl, vt, keyset);
......@@ -647,11 +658,12 @@ static int vcap_show_admin_raw(struct vcap_control *vctrl,
struct vcap_admin *admin,
struct vcap_output_print *out)
{
enum vcap_keyfield_set keysets[10];
enum vcap_type vt = admin->vtype;
struct vcap_keyset_list kslist;
struct vcap_rule_internal *ri;
const struct vcap_set *info;
int keyset;
int addr;
int addr, idx;
int ret;
if (list_empty(&admin->rules))
......@@ -664,24 +676,32 @@ static int vcap_show_admin_raw(struct vcap_control *vctrl,
ri = list_first_entry(&admin->rules, struct vcap_rule_internal, list);
/* Go from higher to lower addresses searching for a keyset */
kslist.keysets = keysets;
kslist.max = ARRAY_SIZE(keysets);
for (addr = admin->last_valid_addr; addr >= admin->first_valid_addr;
--addr) {
keyset = vcap_addr_keyset(vctrl, ri->ndev, admin, addr);
if (keyset < 0)
kslist.cnt = 0;
ret = vcap_addr_keysets(vctrl, ri->ndev, admin, addr, &kslist);
if (ret < 0)
continue;
info = vcap_keyfieldset(vctrl, vt, keyset);
info = vcap_keyfieldset(vctrl, vt, kslist.keysets[0]);
if (!info)
continue;
if (addr % info->sw_per_item)
if (addr % info->sw_per_item) {
pr_info("addr: %d X%d error rule, keyset: %s\n",
addr,
info->sw_per_item,
vcap_keyset_name(vctrl, keyset));
else
out->prf(out->dst, " addr: %d, X%d rule, keyset: %s\n",
vcap_keyset_name(vctrl, kslist.keysets[0]));
} else {
out->prf(out->dst, " addr: %d, X%d rule, keysets:",
addr,
info->sw_per_item,
vcap_keyset_name(vctrl, keyset));
info->sw_per_item);
for (idx = 0; idx < kslist.cnt; ++idx)
out->prf(out->dst, " %s",
vcap_keyset_name(vctrl,
kslist.keysets[idx]));
out->prf(out->dst, "\n");
}
}
return 0;
}
......
......@@ -316,24 +316,34 @@ static void vcap_api_addr_keyset_test(struct kunit *test)
.actionstream = actdata,
},
};
enum vcap_keyfield_set keysets[10];
struct vcap_keyset_list matches;
int ret, idx, addr;
vcap_test_api_init(&admin);
/* Go from higher to lower addresses searching for a keyset */
matches.keysets = keysets;
matches.cnt = 0;
matches.max = ARRAY_SIZE(keysets);
for (idx = ARRAY_SIZE(keydata) - 1, addr = 799; idx > 0;
--idx, --addr) {
admin.cache.keystream = &keydata[idx];
admin.cache.maskstream = &mskdata[idx];
ret = vcap_addr_keyset(&test_vctrl, &test_netdev, &admin, addr);
ret = vcap_addr_keysets(&test_vctrl, &test_netdev, &admin,
addr, &matches);
KUNIT_EXPECT_EQ(test, -EINVAL, ret);
}
/* Finally we hit the start of the rule */
admin.cache.keystream = &keydata[idx];
admin.cache.maskstream = &mskdata[idx];
ret = vcap_addr_keyset(&test_vctrl, &test_netdev, &admin, addr);
KUNIT_EXPECT_EQ(test, VCAP_KFS_MAC_ETYPE, ret);
matches.cnt = 0;
ret = vcap_addr_keysets(&test_vctrl, &test_netdev, &admin,
addr, &matches);
KUNIT_EXPECT_EQ(test, 0, ret);
KUNIT_EXPECT_EQ(test, matches.cnt, 1);
KUNIT_EXPECT_EQ(test, matches.keysets[0], VCAP_KFS_MAC_ETYPE);
}
static void vcap_api_show_admin_raw_test(struct kunit *test)
......@@ -362,7 +372,7 @@ static void vcap_api_show_admin_raw_test(struct kunit *test)
.prf = (void *)test_prf,
};
const char *test_expected =
" addr: 786, X6 rule, keyset: VCAP_KFS_MAC_ETYPE\n";
" addr: 786, X6 rule, keysets: VCAP_KFS_MAC_ETYPE\n";
int ret;
vcap_test_api_init(&admin);
......@@ -442,7 +452,7 @@ static const char * const test_admin_expect[] = {
" chain_id: 0\n",
" user: 0\n",
" priority: 0\n",
" keyset: VCAP_KFS_MAC_ETYPE\n",
" keysets: VCAP_KFS_MAC_ETYPE\n",
" keyset_sw: 6\n",
" keyset_sw_regs: 2\n",
" ETYPE_LEN_IS: W1: 1/1\n",
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment