net: stmmac: selftests: Add a selftest for Flexible RX Parser

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>
This commit is contained in:
Jose Abreu 2019-08-07 10:03:18 +02:00 committed by David S. Miller
parent d6e1c12cf9
commit ccfc639a94
1 changed files with 97 additions and 1 deletions

View File

@ -11,8 +11,10 @@
#include <linux/ip.h> #include <linux/ip.h>
#include <linux/phy.h> #include <linux/phy.h>
#include <linux/udp.h> #include <linux/udp.h>
#include <net/pkt_cls.h>
#include <net/tcp.h> #include <net/tcp.h>
#include <net/udp.h> #include <net/udp.h>
#include <net/tc_act/tc_gact.h>
#include "stmmac.h" #include "stmmac.h"
struct stmmachdr { struct stmmachdr {
@ -229,7 +231,7 @@ static int stmmac_test_loopback_validate(struct sk_buff *skb,
goto out; goto out;
} }
if (tpriv->packet->src) { 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; goto out;
} }
@ -912,6 +914,96 @@ static int stmmac_test_dvlanfilt(struct stmmac_priv *priv)
return ret; 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_NONE 0
#define STMMAC_LOOPBACK_MAC 1 #define STMMAC_LOOPBACK_MAC 1
#define STMMAC_LOOPBACK_PHY 2 #define STMMAC_LOOPBACK_PHY 2
@ -969,6 +1061,10 @@ static const struct stmmac_test {
.name = "Double VLAN Filtering", .name = "Double VLAN Filtering",
.lb = STMMAC_LOOPBACK_PHY, .lb = STMMAC_LOOPBACK_PHY,
.fn = stmmac_test_dvlanfilt, .fn = stmmac_test_dvlanfilt,
}, {
.name = "Flexible RX Parser ",
.lb = STMMAC_LOOPBACK_PHY,
.fn = stmmac_test_rxp,
}, },
}; };