forked from Openwrt/openwrt
2eef4f7354
The IXP4xx is well supported upstream and can readily be supported with kernel v6.6. To simplify things after the DTS directory was renamed, switch to v6.6 only. Bring in some outstanding patches. Tested on the Gateworks GW2348-4. Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
133 lines
4.0 KiB
Diff
133 lines
4.0 KiB
Diff
From 6599df775e2cbb4988bdf8239acf4fbec70e5ef9 Mon Sep 17 00:00:00 2001
|
|
From: Linus Walleij <linus.walleij@linaro.org>
|
|
Date: Sat, 23 Sep 2023 20:38:22 +0200
|
|
Subject: [PATCH 3/4] net: ixp4xx_eth: Support changing the MTU
|
|
|
|
As we don't specify the MTU in the driver, the framework
|
|
will fall back to 1500 bytes and this doesn't work very
|
|
well when we try to attach a DSA switch:
|
|
|
|
eth1: mtu greater than device maximum
|
|
ixp4xx_eth c800a000.ethernet eth1: error -22 setting
|
|
MTU to 1504 to include DSA overhead
|
|
|
|
After locating an out-of-tree patch in OpenWrt I found
|
|
suitable code to set the MTU on the interface and ported
|
|
it and updated it. Now the MTU gets set properly.
|
|
|
|
Reviewed-by: Jacob Keller <jacob.e.keller@intel.com>
|
|
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
|
|
---
|
|
drivers/net/ethernet/xscale/ixp4xx_eth.c | 65 +++++++++++++++++++++++-
|
|
1 file changed, 64 insertions(+), 1 deletion(-)
|
|
|
|
--- a/drivers/net/ethernet/xscale/ixp4xx_eth.c
|
|
+++ b/drivers/net/ethernet/xscale/ixp4xx_eth.c
|
|
@@ -24,6 +24,7 @@
|
|
#include <linux/dma-mapping.h>
|
|
#include <linux/dmapool.h>
|
|
#include <linux/etherdevice.h>
|
|
+#include <linux/if_vlan.h>
|
|
#include <linux/io.h>
|
|
#include <linux/kernel.h>
|
|
#include <linux/net_tstamp.h>
|
|
@@ -63,7 +64,15 @@
|
|
|
|
#define POOL_ALLOC_SIZE (sizeof(struct desc) * (RX_DESCS + TX_DESCS))
|
|
#define REGS_SIZE 0x1000
|
|
-#define MAX_MRU 1536 /* 0x600 */
|
|
+
|
|
+/* MRU is said to be 14320 in a code dump, the SW manual says that
|
|
+ * MRU/MTU is 16320 and includes VLAN and ethernet headers.
|
|
+ * See "IXP400 Software Programmer's Guide" section 10.3.2, page 161.
|
|
+ *
|
|
+ * FIXME: we have chosen the safe default (14320) but if you can test
|
|
+ * jumboframes, experiment with 16320 and see what happens!
|
|
+ */
|
|
+#define MAX_MRU (14320 - VLAN_ETH_HLEN)
|
|
#define RX_BUFF_SIZE ALIGN((NET_IP_ALIGN) + MAX_MRU, 4)
|
|
|
|
#define NAPI_WEIGHT 16
|
|
@@ -1182,6 +1191,54 @@ static void destroy_queues(struct port *
|
|
}
|
|
}
|
|
|
|
+static int ixp4xx_do_change_mtu(struct net_device *dev, int new_mtu)
|
|
+{
|
|
+ struct port *port = netdev_priv(dev);
|
|
+ struct npe *npe = port->npe;
|
|
+ int framesize, chunks;
|
|
+ struct msg msg = {};
|
|
+
|
|
+ /* adjust for ethernet headers */
|
|
+ framesize = new_mtu + VLAN_ETH_HLEN;
|
|
+ /* max rx/tx 64 byte chunks */
|
|
+ chunks = DIV_ROUND_UP(framesize, 64);
|
|
+
|
|
+ msg.cmd = NPE_SETMAXFRAMELENGTHS;
|
|
+ msg.eth_id = port->id;
|
|
+
|
|
+ /* Firmware wants to know buffer size in 64 byte chunks */
|
|
+ msg.byte2 = chunks << 8;
|
|
+ msg.byte3 = chunks << 8;
|
|
+
|
|
+ msg.byte4 = msg.byte6 = framesize >> 8;
|
|
+ msg.byte5 = msg.byte7 = framesize & 0xff;
|
|
+
|
|
+ if (npe_send_recv_message(npe, &msg, "ETH_SET_MAX_FRAME_LENGTH"))
|
|
+ return -EIO;
|
|
+ netdev_dbg(dev, "set MTU on NPE %s to %d bytes\n",
|
|
+ npe_name(npe), new_mtu);
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+static int ixp4xx_eth_change_mtu(struct net_device *dev, int new_mtu)
|
|
+{
|
|
+ int ret;
|
|
+
|
|
+ /* MTU can only be changed when the interface is up. We also
|
|
+ * set the MTU from dev->mtu when opening the device.
|
|
+ */
|
|
+ if (dev->flags & IFF_UP) {
|
|
+ ret = ixp4xx_do_change_mtu(dev, new_mtu);
|
|
+ if (ret < 0)
|
|
+ return ret;
|
|
+ }
|
|
+
|
|
+ dev->mtu = new_mtu;
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
static int eth_open(struct net_device *dev)
|
|
{
|
|
struct port *port = netdev_priv(dev);
|
|
@@ -1232,6 +1289,8 @@ static int eth_open(struct net_device *d
|
|
if (npe_send_recv_message(port->npe, &msg, "ETH_SET_FIREWALL_MODE"))
|
|
return -EIO;
|
|
|
|
+ ixp4xx_do_change_mtu(dev, dev->mtu);
|
|
+
|
|
if ((err = request_queues(port)) != 0)
|
|
return err;
|
|
|
|
@@ -1374,6 +1433,7 @@ static int eth_close(struct net_device *
|
|
static const struct net_device_ops ixp4xx_netdev_ops = {
|
|
.ndo_open = eth_open,
|
|
.ndo_stop = eth_close,
|
|
+ .ndo_change_mtu = ixp4xx_eth_change_mtu,
|
|
.ndo_start_xmit = eth_xmit,
|
|
.ndo_set_rx_mode = eth_set_mcast_list,
|
|
.ndo_eth_ioctl = eth_ioctl,
|
|
@@ -1488,6 +1548,9 @@ static int ixp4xx_eth_probe(struct platf
|
|
ndev->dev.dma_mask = dev->dma_mask;
|
|
ndev->dev.coherent_dma_mask = dev->coherent_dma_mask;
|
|
|
|
+ ndev->min_mtu = ETH_MIN_MTU;
|
|
+ ndev->max_mtu = MAX_MRU;
|
|
+
|
|
netif_napi_add_weight(ndev, &port->napi, eth_poll, NAPI_WEIGHT);
|
|
|
|
if (!(port->npe = npe_request(NPE_ID(port->id))))
|