net: stmmac: selftests: Add a selftest for Flexible RX Parser
authorJose Abreu <Jose.Abreu@synopsys.com>
Wed, 7 Aug 2019 08:03:18 +0000 (10:03 +0200)
committerDavid S. Miller <davem@davemloft.net>
Fri, 9 Aug 2019 05:20:19 +0000 (22:20 -0700)
Add a selftest for the Flexible RX Parser feature.

Signed-off-by: Jose Abreu <joabreu@synopsys.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/stmicro/stmmac/stmmac_selftests.c

index 6b08bb15af159d7ca33ffbc9cab7917dee72c385..abab84f2ef8b6190ecbe6b57b1883d6267236047 100644 (file)
 #include <linux/ip.h>
 #include <linux/phy.h>
 #include <linux/udp.h>
+#include <net/pkt_cls.h>
 #include <net/tcp.h>
 #include <net/udp.h>
+#include <net/tc_act/tc_gact.h>
 #include "stmmac.h"
 
 struct stmmachdr {
@@ -229,7 +231,7 @@ static int stmmac_test_loopback_validate(struct sk_buff *skb,
                        goto out;
        }
        if (tpriv->packet->src) {
-               if (!ether_addr_equal(ehdr->h_source, orig_ndev->dev_addr))
+               if (!ether_addr_equal(ehdr->h_source, tpriv->packet->src))
                        goto out;
        }
 
@@ -912,6 +914,96 @@ cleanup:
        return ret;
 }
 
+#ifdef CONFIG_NET_CLS_ACT
+static int stmmac_test_rxp(struct stmmac_priv *priv)
+{
+       unsigned char addr[ETH_ALEN] = {0xde, 0xad, 0xbe, 0xef, 0x00, 0x00};
+       struct tc_cls_u32_offload cls_u32 = { };
+       struct stmmac_packet_attrs attr = { };
+       struct tc_action **actions, *act;
+       struct tc_u32_sel *sel;
+       struct tcf_exts *exts;
+       int ret, i, nk = 1;
+
+       if (!tc_can_offload(priv->dev))
+               return -EOPNOTSUPP;
+       if (!priv->dma_cap.frpsel)
+               return -EOPNOTSUPP;
+
+       sel = kzalloc(sizeof(*sel) + nk * sizeof(struct tc_u32_key), GFP_KERNEL);
+       if (!sel)
+               return -ENOMEM;
+
+       exts = kzalloc(sizeof(*exts), GFP_KERNEL);
+       if (!exts) {
+               ret = -ENOMEM;
+               goto cleanup_sel;
+       }
+
+       actions = kzalloc(nk * sizeof(*actions), GFP_KERNEL);
+       if (!actions) {
+               ret = -ENOMEM;
+               goto cleanup_exts;
+       }
+
+       act = kzalloc(nk * sizeof(*act), GFP_KERNEL);
+       if (!act) {
+               ret = -ENOMEM;
+               goto cleanup_actions;
+       }
+
+       cls_u32.command = TC_CLSU32_NEW_KNODE;
+       cls_u32.common.chain_index = 0;
+       cls_u32.common.protocol = htons(ETH_P_ALL);
+       cls_u32.knode.exts = exts;
+       cls_u32.knode.sel = sel;
+       cls_u32.knode.handle = 0x123;
+
+       exts->nr_actions = nk;
+       exts->actions = actions;
+       for (i = 0; i < nk; i++) {
+               struct tcf_gact *gact = to_gact(&act[i]);
+
+               actions[i] = &act[i];
+               gact->tcf_action = TC_ACT_SHOT;
+       }
+
+       sel->nkeys = nk;
+       sel->offshift = 0;
+       sel->keys[0].off = 6;
+       sel->keys[0].val = htonl(0xdeadbeef);
+       sel->keys[0].mask = ~0x0;
+
+       ret = stmmac_tc_setup_cls_u32(priv, priv, &cls_u32);
+       if (ret)
+               goto cleanup_act;
+
+       attr.dst = priv->dev->dev_addr;
+       attr.src = addr;
+
+       ret = __stmmac_test_loopback(priv, &attr);
+       ret = !ret; /* Shall NOT receive packet */
+
+       cls_u32.command = TC_CLSU32_DELETE_KNODE;
+       stmmac_tc_setup_cls_u32(priv, priv, &cls_u32);
+
+cleanup_act:
+       kfree(act);
+cleanup_actions:
+       kfree(actions);
+cleanup_exts:
+       kfree(exts);
+cleanup_sel:
+       kfree(sel);
+       return ret;
+}
+#else
+static int stmmac_test_rxp(struct stmmac_priv *priv)
+{
+       return -EOPNOTSUPP;
+}
+#endif
+
 #define STMMAC_LOOPBACK_NONE   0
 #define STMMAC_LOOPBACK_MAC    1
 #define STMMAC_LOOPBACK_PHY    2
@@ -969,6 +1061,10 @@ static const struct stmmac_test {
                .name = "Double VLAN Filtering",
                .lb = STMMAC_LOOPBACK_PHY,
                .fn = stmmac_test_dvlanfilt,
+       }, {
+               .name = "Flexible RX Parser   ",
+               .lb = STMMAC_LOOPBACK_PHY,
+               .fn = stmmac_test_rxp,
        },
 };