Add a test to validate the Jumbo Frame support in stmmac in single
channel and multichannel mode.

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 | 65 +++++++++++++++++++++-
 1 file changed, 62 insertions(+), 3 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_selftests.c 
b/drivers/net/ethernet/stmicro/stmmac/stmmac_selftests.c
index 8446b414b44d..305d24935cf4 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_selftests.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_selftests.c
@@ -43,9 +43,11 @@ struct stmmac_packet_attrs {
        int dont_wait;
        int timeout;
        int size;
+       int max_size;
        int remove_sa;
        u8 id;
        int sarc;
+       u16 queue_mapping;
 };
 
 static u8 stmmac_test_next_id;
@@ -73,12 +75,14 @@ static struct sk_buff *stmmac_test_get_udp_skb(struct 
stmmac_priv *priv,
        else
                size += sizeof(struct udphdr);
 
-       skb = netdev_alloc_skb(priv->dev, size);
+       if (attr->max_size && (attr->max_size > size))
+               size = attr->max_size;
+
+       skb = netdev_alloc_skb_ip_align(priv->dev, size);
        if (!skb)
                return NULL;
 
        prefetchw(skb->data);
-       skb_reserve(skb, NET_IP_ALIGN);
 
        if (attr->vlan > 1)
                ehdr = skb_push(skb, ETH_HLEN + 8);
@@ -147,6 +151,9 @@ static struct sk_buff *stmmac_test_get_udp_skb(struct 
stmmac_priv *priv,
                uhdr->source = htons(attr->sport);
                uhdr->dest = htons(attr->dport);
                uhdr->len = htons(sizeof(*shdr) + sizeof(*uhdr) + attr->size);
+               if (attr->max_size)
+                       uhdr->len = htons(attr->max_size -
+                                         (sizeof(*ihdr) + sizeof(*ehdr)));
                uhdr->check = 0;
        }
 
@@ -162,6 +169,10 @@ static struct sk_buff *stmmac_test_get_udp_skb(struct 
stmmac_priv *priv,
                iplen += sizeof(*thdr);
        else
                iplen += sizeof(*uhdr);
+
+       if (attr->max_size)
+               iplen = attr->max_size - sizeof(*ehdr);
+
        ihdr->tot_len = htons(iplen);
        ihdr->frag_off = 0;
        ihdr->saddr = htonl(attr->ip_src);
@@ -178,6 +189,8 @@ static struct sk_buff *stmmac_test_get_udp_skb(struct 
stmmac_priv *priv,
 
        if (attr->size)
                skb_put(skb, attr->size);
+       if (attr->max_size && (attr->max_size > skb->len))
+               skb_put(skb, attr->max_size - skb->len);
 
        skb->csum = 0;
        skb->ip_summed = CHECKSUM_PARTIAL;
@@ -324,7 +337,7 @@ static int __stmmac_test_loopback(struct stmmac_priv *priv,
                goto cleanup;
        }
 
-       skb_set_queue_mapping(skb, 0);
+       skb_set_queue_mapping(skb, attr->queue_mapping);
        ret = dev_queue_xmit(skb);
        if (ret)
                goto cleanup;
@@ -1534,6 +1547,44 @@ static int stmmac_test_arpoffload(struct stmmac_priv 
*priv)
        return ret;
 }
 
+static int __stmmac_test_jumbo(struct stmmac_priv *priv, u16 queue)
+{
+       struct stmmac_packet_attrs attr = { };
+       int size = priv->dma_buf_sz;
+
+       /* Only XGMAC has SW support for multiple RX descs in same packet */
+       if (priv->plat->has_xgmac)
+               size = priv->dev->max_mtu;
+
+       attr.dst = priv->dev->dev_addr;
+       attr.max_size = size - ETH_FCS_LEN;
+       attr.queue_mapping = queue;
+
+       return __stmmac_test_loopback(priv, &attr);
+}
+
+static int stmmac_test_jumbo(struct stmmac_priv *priv)
+{
+       return __stmmac_test_jumbo(priv, 0);
+}
+
+static int stmmac_test_mjumbo(struct stmmac_priv *priv)
+{
+       u32 chan, tx_cnt = priv->plat->tx_queues_to_use;
+       int ret;
+
+       if (tx_cnt <= 1)
+               return -EOPNOTSUPP;
+
+       for (chan = 0; chan < tx_cnt; chan++) {
+               ret = __stmmac_test_jumbo(priv, chan);
+               if (ret)
+                       return ret;
+       }
+
+       return 0;
+}
+
 #define STMMAC_LOOPBACK_NONE   0
 #define STMMAC_LOOPBACK_MAC    1
 #define STMMAC_LOOPBACK_PHY    2
@@ -1647,6 +1698,14 @@ static const struct stmmac_test {
                .name = "ARP Offload         ",
                .lb = STMMAC_LOOPBACK_PHY,
                .fn = stmmac_test_arpoffload,
+       }, {
+               .name = "Jumbo Frame         ",
+               .lb = STMMAC_LOOPBACK_PHY,
+               .fn = stmmac_test_jumbo,
+       }, {
+               .name = "Multichannel Jumbo  ",
+               .lb = STMMAC_LOOPBACK_PHY,
+               .fn = stmmac_test_mjumbo,
        },
 };
 
-- 
2.7.4

Reply via email to