1
0
mirror of git://projects.qi-hardware.com/openwrt-xburst.git synced 2025-04-10 15:57:27 +03: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

87 lines
2.0 KiB
Diff

--- a/drivers/net/arm/ixp4xx_eth.c
+++ b/drivers/net/arm/ixp4xx_eth.c
@@ -54,7 +54,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
@@ -1011,6 +1011,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);
@@ -1061,6 +1087,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;
@@ -1238,6 +1266,24 @@ static void eth_init_mii(struct net_devi
}
+static int 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 int __devinit eth_init_one(struct platform_device *pdev)
{
struct port *port;
@@ -1272,6 +1318,7 @@ static int __devinit eth_init_one(struct
goto err_free;
}
+ dev->change_mtu = eth_change_mtu;
dev->open = eth_open;
dev->hard_start_xmit = eth_xmit;
dev->stop = eth_close;