Add a selftest for the Flexible RX Parser feature.

Signed-off-by: Jose Abreu <joab...@synopsys.com>
---
Cc: Giuseppe Cavallaro <peppe.cavall...@st.com>
Cc: Alexandre Torgue <alexandre.tor...@st.com>
Cc: Jose Abreu <joab...@synopsys.com>
Cc: "David S. Miller" <da...@davemloft.net>
Cc: Maxime Coquelin <mcoquelin.st...@gmail.com>
Cc: net...@vger.kernel.org
Cc: linux-st...@st-md-mailman.stormreply.com
Cc: linux-arm-ker...@lists.infradead.org
Cc: linux-kernel@vger.kernel.org
---
 .../net/ethernet/stmicro/stmmac/stmmac_selftests.c | 98 +++++++++++++++++++++-
 1 file changed, 97 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_selftests.c 
b/drivers/net/ethernet/stmicro/stmmac/stmmac_selftests.c
index 6b08bb15af15..abab84f2ef8b 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_selftests.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_selftests.c
@@ -11,8 +11,10 @@
 #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 @@ static int stmmac_test_dvlanfilt(struct stmmac_priv *priv)
        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,
        },
 };
 
-- 
2.7.4

Reply via email to