OSDN Git Service

net: microchip: sparx5: Support for displaying a list of keysets
authorSteen Hegelund <steen.hegelund@microchip.com>
Wed, 23 Nov 2022 15:25:44 +0000 (16:25 +0100)
committerDavid S. Miller <davem@davemloft.net>
Fri, 25 Nov 2022 09:42:14 +0000 (09:42 +0000)
This will display a list of keyset in case the type_id field in the VCAP
rule has been wildcarded.

Signed-off-by: Steen Hegelund <steen.hegelund@microchip.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/microchip/vcap/vcap_api_debugfs.c
drivers/net/ethernet/microchip/vcap/vcap_api_debugfs_kunit.c

index d9c7ca9..5df00e9 100644 (file)
@@ -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,
-                                            enum vcap_type vt,
-                                            u32 *keystream,
-                                            u32 *mskstream,
-                                            bool mask, int sw_max)
+static int
+vcap_find_keystream_keysets(struct vcap_control *vctrl,
+                           enum vcap_type vt,
+                           u32 *keystream,
+                           u32 *mskstream,
+                           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,
-                           struct net_device *ndev,
-                           struct vcap_admin *admin,
-                           int addr)
+static int vcap_addr_keysets(struct vcap_control *vctrl,
+                            struct net_device *ndev,
+                            struct vcap_admin *admin,
+                            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",
-                          addr,
-                          info->sw_per_item,
-                          vcap_keyset_name(vctrl, keyset));
+                               vcap_keyset_name(vctrl, kslist.keysets[0]));
+               } else {
+                       out->prf(out->dst, "  addr: %d, X%d rule, keysets:",
+                                addr,
+                                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;
 }
index ed455da..cf59466 100644 (file)
@@ -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",