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, ...@@ -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_iter_init(&iter, vcap->sw_width, tgt, typefld->offset);
vcap_decode_field(keystream, &iter, typefld->width, (u8 *)&value); 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 /* 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 static int
vcap_keyfield_set vcap_find_keystream_keyset(struct vcap_control *vctrl, vcap_find_keystream_keysets(struct vcap_control *vctrl,
enum vcap_type vt, enum vcap_type vt,
u32 *keystream, u32 *keystream,
u32 *mskstream, u32 *mskstream,
bool mask, int sw_max) bool mask, int sw_max,
struct vcap_keyset_list *kslist)
{ {
const struct vcap_set *keyfield_set; const struct vcap_set *keyfield_set;
int sw_count, idx; int sw_count, idx;
bool res;
sw_count = vcap_find_keystream_typegroup_sw(vctrl, vt, keystream, mask, sw_count = vcap_find_keystream_typegroup_sw(vctrl, vt, keystream, mask,
sw_max); sw_max);
...@@ -219,11 +219,12 @@ vcap_keyfield_set vcap_find_keystream_keyset(struct vcap_control *vctrl, ...@@ -219,11 +219,12 @@ vcap_keyfield_set vcap_find_keystream_keyset(struct vcap_control *vctrl,
if (keyfield_set[idx].sw_per_item != sw_count) if (keyfield_set[idx].sw_per_item != sw_count)
continue; continue;
res = vcap_verify_keystream_keyset(vctrl, vt, keystream, if (vcap_verify_keystream_keyset(vctrl, vt, keystream,
mskstream, idx); mskstream, idx))
if (res) vcap_keyset_list_add(kslist, idx);
return idx;
} }
if (kslist->cnt > 0)
return 0;
return -EINVAL; return -EINVAL;
} }
...@@ -296,13 +297,14 @@ vcap_find_actionstream_actionset(struct vcap_control *vctrl, ...@@ -296,13 +297,14 @@ vcap_find_actionstream_actionset(struct vcap_control *vctrl,
return -EINVAL; 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 * here
*/ */
static int vcap_addr_keyset(struct vcap_control *vctrl, static int vcap_addr_keysets(struct vcap_control *vctrl,
struct net_device *ndev, struct net_device *ndev,
struct vcap_admin *admin, struct vcap_admin *admin,
int addr) int addr,
struct vcap_keyset_list *kslist)
{ {
enum vcap_type vt = admin->vtype; enum vcap_type vt = admin->vtype;
int keyset_sw_regs, idx; int keyset_sw_regs, idx;
...@@ -320,9 +322,10 @@ static int vcap_addr_keyset(struct vcap_control *vctrl, ...@@ -320,9 +322,10 @@ static int vcap_addr_keyset(struct vcap_control *vctrl,
} }
if (key == 0 && mask == 0) if (key == 0 && mask == 0)
return -EINVAL; return -EINVAL;
/* Decode and locate the keyset */ /* Decode and locate the keysets */
return vcap_find_keystream_keyset(vctrl, vt, admin->cache.keystream, return vcap_find_keystream_keysets(vctrl, vt, admin->cache.keystream,
admin->cache.maskstream, false, 0); admin->cache.maskstream, false, 0,
kslist);
} }
static int vcap_read_rule(struct vcap_rule_internal *ri) 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, ...@@ -471,9 +474,11 @@ static int vcap_debugfs_show_rule_keyset(struct vcap_rule_internal *ri,
struct vcap_control *vctrl = ri->vctrl; struct vcap_control *vctrl = ri->vctrl;
struct vcap_stream_iter kiter, miter; struct vcap_stream_iter kiter, miter;
struct vcap_admin *admin = ri->admin; struct vcap_admin *admin = ri->admin;
enum vcap_keyfield_set keysets[10];
const struct vcap_field *keyfield; const struct vcap_field *keyfield;
enum vcap_type vt = admin->vtype; enum vcap_type vt = admin->vtype;
const struct vcap_typegroup *tgt; const struct vcap_typegroup *tgt;
struct vcap_keyset_list matches;
enum vcap_keyfield_set keyset; enum vcap_keyfield_set keyset;
int idx, res, keyfield_count; int idx, res, keyfield_count;
u32 *maskstream; u32 *maskstream;
...@@ -483,16 +488,22 @@ static int vcap_debugfs_show_rule_keyset(struct vcap_rule_internal *ri, ...@@ -483,16 +488,22 @@ static int vcap_debugfs_show_rule_keyset(struct vcap_rule_internal *ri,
keystream = admin->cache.keystream; keystream = admin->cache.keystream;
maskstream = admin->cache.maskstream; maskstream = admin->cache.maskstream;
res = vcap_find_keystream_keyset(vctrl, vt, keystream, maskstream, matches.keysets = keysets;
false, 0); matches.cnt = 0;
matches.max = ARRAY_SIZE(keysets);
res = vcap_find_keystream_keysets(vctrl, vt, keystream, maskstream,
false, 0, &matches);
if (res < 0) { 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); __func__, __LINE__, res);
return -EINVAL; return -EINVAL;
} }
keyset = res; keyset = matches.keysets[0];
out->prf(out->dst, " keyset: %s\n", out->prf(out->dst, " keysets:");
vcap_keyset_name(vctrl, ri->data.keyset)); 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: %d\n", ri->keyset_sw);
out->prf(out->dst, " keyset_sw_regs: %d\n", ri->keyset_sw_regs); out->prf(out->dst, " keyset_sw_regs: %d\n", ri->keyset_sw_regs);
keyfield_count = vcap_keyfield_count(vctrl, vt, keyset); keyfield_count = vcap_keyfield_count(vctrl, vt, keyset);
...@@ -647,11 +658,12 @@ static int vcap_show_admin_raw(struct vcap_control *vctrl, ...@@ -647,11 +658,12 @@ static int vcap_show_admin_raw(struct vcap_control *vctrl,
struct vcap_admin *admin, struct vcap_admin *admin,
struct vcap_output_print *out) struct vcap_output_print *out)
{ {
enum vcap_keyfield_set keysets[10];
enum vcap_type vt = admin->vtype; enum vcap_type vt = admin->vtype;
struct vcap_keyset_list kslist;
struct vcap_rule_internal *ri; struct vcap_rule_internal *ri;
const struct vcap_set *info; const struct vcap_set *info;
int keyset; int addr, idx;
int addr;
int ret; int ret;
if (list_empty(&admin->rules)) if (list_empty(&admin->rules))
...@@ -664,24 +676,32 @@ static int vcap_show_admin_raw(struct vcap_control *vctrl, ...@@ -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); ri = list_first_entry(&admin->rules, struct vcap_rule_internal, list);
/* Go from higher to lower addresses searching for a keyset */ /* 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; for (addr = admin->last_valid_addr; addr >= admin->first_valid_addr;
--addr) { --addr) {
keyset = vcap_addr_keyset(vctrl, ri->ndev, admin, addr); kslist.cnt = 0;
if (keyset < 0) ret = vcap_addr_keysets(vctrl, ri->ndev, admin, addr, &kslist);
if (ret < 0)
continue; continue;
info = vcap_keyfieldset(vctrl, vt, keyset); info = vcap_keyfieldset(vctrl, vt, kslist.keysets[0]);
if (!info) if (!info)
continue; continue;
if (addr % info->sw_per_item) if (addr % info->sw_per_item) {
pr_info("addr: %d X%d error rule, keyset: %s\n", pr_info("addr: %d X%d error rule, keyset: %s\n",
addr, addr,
info->sw_per_item, info->sw_per_item,
vcap_keyset_name(vctrl, keyset)); vcap_keyset_name(vctrl, kslist.keysets[0]));
else } else {
out->prf(out->dst, " addr: %d, X%d rule, keyset: %s\n", out->prf(out->dst, " addr: %d, X%d rule, keysets:",
addr, addr,
info->sw_per_item, info->sw_per_item);
vcap_keyset_name(vctrl, keyset)); 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; return 0;
} }
......
...@@ -316,24 +316,34 @@ static void vcap_api_addr_keyset_test(struct kunit *test) ...@@ -316,24 +316,34 @@ static void vcap_api_addr_keyset_test(struct kunit *test)
.actionstream = actdata, .actionstream = actdata,
}, },
}; };
enum vcap_keyfield_set keysets[10];
struct vcap_keyset_list matches;
int ret, idx, addr; int ret, idx, addr;
vcap_test_api_init(&admin); vcap_test_api_init(&admin);
/* Go from higher to lower addresses searching for a keyset */ /* 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; for (idx = ARRAY_SIZE(keydata) - 1, addr = 799; idx > 0;
--idx, --addr) { --idx, --addr) {
admin.cache.keystream = &keydata[idx]; admin.cache.keystream = &keydata[idx];
admin.cache.maskstream = &mskdata[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); KUNIT_EXPECT_EQ(test, -EINVAL, ret);
} }
/* Finally we hit the start of the rule */ /* Finally we hit the start of the rule */
admin.cache.keystream = &keydata[idx]; admin.cache.keystream = &keydata[idx];
admin.cache.maskstream = &mskdata[idx]; admin.cache.maskstream = &mskdata[idx];
ret = vcap_addr_keyset(&test_vctrl, &test_netdev, &admin, addr); matches.cnt = 0;
KUNIT_EXPECT_EQ(test, VCAP_KFS_MAC_ETYPE, ret); 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) 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) ...@@ -362,7 +372,7 @@ static void vcap_api_show_admin_raw_test(struct kunit *test)
.prf = (void *)test_prf, .prf = (void *)test_prf,
}; };
const char *test_expected = 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; int ret;
vcap_test_api_init(&admin); vcap_test_api_init(&admin);
...@@ -442,7 +452,7 @@ static const char * const test_admin_expect[] = { ...@@ -442,7 +452,7 @@ static const char * const test_admin_expect[] = {
" chain_id: 0\n", " chain_id: 0\n",
" user: 0\n", " user: 0\n",
" priority: 0\n", " priority: 0\n",
" keyset: VCAP_KFS_MAC_ETYPE\n", " keysets: VCAP_KFS_MAC_ETYPE\n",
" keyset_sw: 6\n", " keyset_sw: 6\n",
" keyset_sw_regs: 2\n", " keyset_sw_regs: 2\n",
" ETYPE_LEN_IS: W1: 1/1\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