mirror of
https://github.com/openwrt/openwrt.git
synced 2024-12-25 16:31:13 +00:00
255268ce1a
xrx200 max MTU is reduced so that it works correctly when set to the max, and the max MTU of the switch is increased to match. In 5.10, the switch driver now enables non-standard MTUs on a per-port basis, with the overall frame size set based on the cpu port. When the MTU is not used, this should have no effect. The maximum packet size is limited as large packets cause the switch to lock up. 0702-net-lantiq-add-support-for-jumbo-frames.patch comes from net-next commit 998ac358019e491217e752bc6dcbb3afb2a6fa3e. In 5.4, all switch ports are configured to accept the max MTU, as 5.4 does not have port_max_mtu/port_change_mtu callbacks. Signed-off-by: Thomas Nixon <tom@tomn.co.uk>
146 lines
3.9 KiB
Diff
146 lines
3.9 KiB
Diff
From 998ac358019e491217e752bc6dcbb3afb2a6fa3e Mon Sep 17 00:00:00 2001
|
|
From: Aleksander Jan Bajkowski <olek2@wp.pl>
|
|
Date: Sun, 19 Sep 2021 20:24:28 +0200
|
|
Subject: [PATCH] net: lantiq: add support for jumbo frames
|
|
|
|
Add support for jumbo frames. Full support for jumbo frames requires
|
|
changes in the DSA switch driver (lantiq_gswip.c).
|
|
|
|
Tested on BT Hone Hub 5A.
|
|
|
|
Signed-off-by: Aleksander Jan Bajkowski <olek2@wp.pl>
|
|
Signed-off-by: David S. Miller <davem@davemloft.net>
|
|
---
|
|
drivers/net/ethernet/lantiq_xrx200.c | 64 +++++++++++++++++++++++++---
|
|
1 file changed, 57 insertions(+), 7 deletions(-)
|
|
|
|
--- a/drivers/net/ethernet/lantiq_xrx200.c
|
|
+++ b/drivers/net/ethernet/lantiq_xrx200.c
|
|
@@ -14,13 +14,15 @@
|
|
#include <linux/clk.h>
|
|
#include <linux/delay.h>
|
|
|
|
+#include <linux/if_vlan.h>
|
|
+
|
|
#include <linux/of_net.h>
|
|
#include <linux/of_platform.h>
|
|
|
|
#include <xway_dma.h>
|
|
|
|
/* DMA */
|
|
-#define XRX200_DMA_DATA_LEN 0x600
|
|
+#define XRX200_DMA_DATA_LEN (SZ_64K - 1)
|
|
#define XRX200_DMA_RX 0
|
|
#define XRX200_DMA_TX 1
|
|
|
|
@@ -106,7 +108,8 @@ static void xrx200_flush_dma(struct xrx2
|
|
break;
|
|
|
|
desc->ctl = LTQ_DMA_OWN | LTQ_DMA_RX_OFFSET(NET_IP_ALIGN) |
|
|
- XRX200_DMA_DATA_LEN;
|
|
+ (ch->priv->net_dev->mtu + VLAN_ETH_HLEN +
|
|
+ ETH_FCS_LEN);
|
|
ch->dma.desc++;
|
|
ch->dma.desc %= LTQ_DESC_NUM;
|
|
}
|
|
@@ -154,19 +157,20 @@ static int xrx200_close(struct net_devic
|
|
|
|
static int xrx200_alloc_skb(struct xrx200_chan *ch)
|
|
{
|
|
+ int len = ch->priv->net_dev->mtu + VLAN_ETH_HLEN + ETH_FCS_LEN;
|
|
struct sk_buff *skb = ch->skb[ch->dma.desc];
|
|
dma_addr_t mapping;
|
|
int ret = 0;
|
|
|
|
ch->skb[ch->dma.desc] = netdev_alloc_skb_ip_align(ch->priv->net_dev,
|
|
- XRX200_DMA_DATA_LEN);
|
|
+ len);
|
|
if (!ch->skb[ch->dma.desc]) {
|
|
ret = -ENOMEM;
|
|
goto skip;
|
|
}
|
|
|
|
mapping = dma_map_single(ch->priv->dev, ch->skb[ch->dma.desc]->data,
|
|
- XRX200_DMA_DATA_LEN, DMA_FROM_DEVICE);
|
|
+ len, DMA_FROM_DEVICE);
|
|
if (unlikely(dma_mapping_error(ch->priv->dev, mapping))) {
|
|
dev_kfree_skb_any(ch->skb[ch->dma.desc]);
|
|
ch->skb[ch->dma.desc] = skb;
|
|
@@ -179,8 +183,7 @@ static int xrx200_alloc_skb(struct xrx20
|
|
wmb();
|
|
skip:
|
|
ch->dma.desc_base[ch->dma.desc].ctl =
|
|
- LTQ_DMA_OWN | LTQ_DMA_RX_OFFSET(NET_IP_ALIGN) |
|
|
- XRX200_DMA_DATA_LEN;
|
|
+ LTQ_DMA_OWN | LTQ_DMA_RX_OFFSET(NET_IP_ALIGN) | len;
|
|
|
|
return ret;
|
|
}
|
|
@@ -340,10 +343,57 @@ err_drop:
|
|
return NETDEV_TX_OK;
|
|
}
|
|
|
|
+static int
|
|
+xrx200_change_mtu(struct net_device *net_dev, int new_mtu)
|
|
+{
|
|
+ struct xrx200_priv *priv = netdev_priv(net_dev);
|
|
+ struct xrx200_chan *ch_rx = &priv->chan_rx;
|
|
+ int old_mtu = net_dev->mtu;
|
|
+ bool running = false;
|
|
+ struct sk_buff *skb;
|
|
+ int curr_desc;
|
|
+ int ret = 0;
|
|
+
|
|
+ net_dev->mtu = new_mtu;
|
|
+
|
|
+ if (new_mtu <= old_mtu)
|
|
+ return ret;
|
|
+
|
|
+ running = netif_running(net_dev);
|
|
+ if (running) {
|
|
+ napi_disable(&ch_rx->napi);
|
|
+ ltq_dma_close(&ch_rx->dma);
|
|
+ }
|
|
+
|
|
+ xrx200_poll_rx(&ch_rx->napi, LTQ_DESC_NUM);
|
|
+ curr_desc = ch_rx->dma.desc;
|
|
+
|
|
+ for (ch_rx->dma.desc = 0; ch_rx->dma.desc < LTQ_DESC_NUM;
|
|
+ ch_rx->dma.desc++) {
|
|
+ skb = ch_rx->skb[ch_rx->dma.desc];
|
|
+ ret = xrx200_alloc_skb(ch_rx);
|
|
+ if (ret) {
|
|
+ net_dev->mtu = old_mtu;
|
|
+ break;
|
|
+ }
|
|
+ dev_kfree_skb_any(skb);
|
|
+ }
|
|
+
|
|
+ ch_rx->dma.desc = curr_desc;
|
|
+ if (running) {
|
|
+ napi_enable(&ch_rx->napi);
|
|
+ ltq_dma_open(&ch_rx->dma);
|
|
+ ltq_dma_enable_irq(&ch_rx->dma);
|
|
+ }
|
|
+
|
|
+ return ret;
|
|
+}
|
|
+
|
|
static const struct net_device_ops xrx200_netdev_ops = {
|
|
.ndo_open = xrx200_open,
|
|
.ndo_stop = xrx200_close,
|
|
.ndo_start_xmit = xrx200_start_xmit,
|
|
+ .ndo_change_mtu = xrx200_change_mtu,
|
|
.ndo_set_mac_address = eth_mac_addr,
|
|
.ndo_validate_addr = eth_validate_addr,
|
|
};
|
|
@@ -454,7 +504,7 @@ static int xrx200_probe(struct platform_
|
|
net_dev->netdev_ops = &xrx200_netdev_ops;
|
|
SET_NETDEV_DEV(net_dev, dev);
|
|
net_dev->min_mtu = ETH_ZLEN;
|
|
- net_dev->max_mtu = XRX200_DMA_DATA_LEN;
|
|
+ net_dev->max_mtu = XRX200_DMA_DATA_LEN - VLAN_ETH_HLEN - ETH_FCS_LEN;
|
|
|
|
/* load the memory ranges */
|
|
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|