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;
        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);
                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;
        }
 
                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);
 
        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;
                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;
        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
                .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,
        },
 };