ixp4xx: fix weird ethernet issues with some devices caused by the ethernet packet...
[openwrt-10.03/.git] / target / linux / ixp4xx / patches-2.6.31 / 304-ixp4xx_eth_jumboframe.patch
1 --- a/drivers/net/arm/ixp4xx_eth.c
2 +++ b/drivers/net/arm/ixp4xx_eth.c
3 @@ -52,7 +52,7 @@
4  
5  #define POOL_ALLOC_SIZE                (sizeof(struct desc) * (RX_DESCS + TX_DESCS))
6  #define REGS_SIZE              0x1000
7 -#define MAX_MRU                        1536 /* 0x600 */
8 +#define MAX_MRU                        (14320 - ETH_HLEN - ETH_FCS_LEN)
9  #define RX_BUFF_SIZE           ALIGN((NET_IP_ALIGN) + MAX_MRU, 4)
10  
11  #define NAPI_WEIGHT            16
12 @@ -1061,6 +1061,32 @@ static void destroy_queues(struct port *
13         }
14  }
15  
16 +static int eth_do_change_mtu(struct net_device *dev, int mtu)
17 +{
18 +       struct port *port;
19 +       struct msg msg;
20 +       /* adjust for ethernet headers */
21 +       int framesize = mtu + ETH_HLEN + ETH_FCS_LEN;
22 +
23 +       port = netdev_priv(dev);
24 +
25 +       memset(&msg, 0, sizeof(msg));
26 +       msg.cmd = NPE_SETMAXFRAMELENGTHS;
27 +       msg.eth_id = port->id;
28 +
29 +       /* max rx/tx 64 byte blocks */
30 +       msg.byte2 = ((framesize + 63) / 64) << 8;
31 +       msg.byte3 = ((framesize + 63) / 64) << 8;
32 +
33 +       msg.byte4 = msg.byte6 = framesize >> 8;
34 +       msg.byte5 = msg.byte7 = framesize & 0xff;
35 +
36 +       if (npe_send_recv_message(port->npe, &msg, "ETH_SET_MAX_FRAME_LENGTH"))
37 +               return -EIO;
38 +
39 +       return 0;
40 +}
41 +
42  static int eth_open(struct net_device *dev)
43  {
44         struct port *port = netdev_priv(dev);
45 @@ -1112,6 +1138,8 @@ static int eth_open(struct net_device *d
46         if (npe_send_recv_message(port->npe, &msg, "ETH_SET_FIREWALL_MODE"))
47                 return -EIO;
48  
49 +       eth_do_change_mtu(dev, dev->mtu);
50 +
51         if ((err = request_queues(port)) != 0)
52                 return err;
53  
54 @@ -1251,7 +1279,26 @@ static int eth_close(struct net_device *
55         return 0;
56  }
57  
58 +static int ixp_eth_change_mtu(struct net_device *dev, int mtu)
59 +{
60 +       int ret;
61 +
62 +       if (mtu > MAX_MRU)
63 +               return -EINVAL;
64 +
65 +       if (dev->flags & IFF_UP) {
66 +               ret = eth_do_change_mtu(dev, mtu);
67 +               if (ret < 0)
68 +                       return ret;
69 +       }
70 +
71 +       dev->mtu = mtu;
72 +
73 +       return 0;
74 +}
75 +
76  static const struct net_device_ops ixp4xx_netdev_ops = {
77 +       .ndo_change_mtu = ixp_eth_change_mtu,
78         .ndo_open = eth_open,
79         .ndo_stop = eth_close,
80         .ndo_start_xmit = eth_xmit,