1
0
mirror of git://projects.qi-hardware.com/openwrt-xburst.git synced 2025-01-22 01:01:06 +02:00
nbd 17747ab1ac ixp4xx: fix weird ethernet issues with some devices caused by the ethernet packet size increase.
despite what the docs day, 14320 is the largest working MRU value, not 16320
fixes  for me

git-svn-id: svn://svn.openwrt.org/openwrt/trunk@18262 3c298f89-4303-0410-b956-a3cf2f4a3e73
2009-11-02 00:44:01 +00:00

81 lines
1.9 KiB
Diff

--- a/drivers/net/arm/ixp4xx_eth.c
+++ b/drivers/net/arm/ixp4xx_eth.c
@@ -52,7 +52,7 @@
#define POOL_ALLOC_SIZE (sizeof(struct desc) * (RX_DESCS + TX_DESCS))
#define REGS_SIZE 0x1000
-#define MAX_MRU 1536 /* 0x600 */
+#define MAX_MRU (14320 - ETH_HLEN - ETH_FCS_LEN)
#define RX_BUFF_SIZE ALIGN((NET_IP_ALIGN) + MAX_MRU, 4)
#define NAPI_WEIGHT 16
@@ -1061,6 +1061,32 @@ static void destroy_queues(struct port *
}
}
+static int eth_do_change_mtu(struct net_device *dev, int mtu)
+{
+ struct port *port;
+ struct msg msg;
+ /* adjust for ethernet headers */
+ int framesize = mtu + ETH_HLEN + ETH_FCS_LEN;
+
+ port = netdev_priv(dev);
+
+ memset(&msg, 0, sizeof(msg));
+ msg.cmd = NPE_SETMAXFRAMELENGTHS;
+ msg.eth_id = port->id;
+
+ /* max rx/tx 64 byte blocks */
+ msg.byte2 = ((framesize + 63) / 64) << 8;
+ msg.byte3 = ((framesize + 63) / 64) << 8;
+
+ msg.byte4 = msg.byte6 = framesize >> 8;
+ msg.byte5 = msg.byte7 = framesize & 0xff;
+
+ if (npe_send_recv_message(port->npe, &msg, "ETH_SET_MAX_FRAME_LENGTH"))
+ return -EIO;
+
+ return 0;
+}
+
static int eth_open(struct net_device *dev)
{
struct port *port = netdev_priv(dev);
@@ -1112,6 +1138,8 @@ static int eth_open(struct net_device *d
if (npe_send_recv_message(port->npe, &msg, "ETH_SET_FIREWALL_MODE"))
return -EIO;
+ eth_do_change_mtu(dev, dev->mtu);
+
if ((err = request_queues(port)) != 0)
return err;
@@ -1251,7 +1279,26 @@ static int eth_close(struct net_device *
return 0;
}
+static int ixp_eth_change_mtu(struct net_device *dev, int mtu)
+{
+ int ret;
+
+ if (mtu > MAX_MRU)
+ return -EINVAL;
+
+ if (dev->flags & IFF_UP) {
+ ret = eth_do_change_mtu(dev, mtu);
+ if (ret < 0)
+ return ret;
+ }
+
+ dev->mtu = mtu;
+
+ return 0;
+}
+
static const struct net_device_ops ixp4xx_netdev_ops = {
+ .ndo_change_mtu = ixp_eth_change_mtu,
.ndo_open = eth_open,
.ndo_stop = eth_close,
.ndo_start_xmit = eth_xmit,