d82b6f7055ac13f23f2697afdc86678894ced87f
[openwrt.git] / target / linux / rb532 / patches / 240-via_rhine_performance.patch
1 Index: linux-2.6.23.17/drivers/net/via-rhine.c
2 ===================================================================
3 --- linux-2.6.23.17.orig/drivers/net/via-rhine.c
4 +++ linux-2.6.23.17/drivers/net/via-rhine.c
5 @@ -33,6 +33,8 @@
6  #define DRV_VERSION    "1.4.3"
7  #define DRV_RELDATE    "2007-03-06"
8  
9 +#define PKT_ALIGN 1
10 +
11  
12  /* A few user-configurable values.
13     These may be modified when a driver module is loaded. */
14 @@ -40,6 +42,7 @@
15  static int debug = 1;  /* 1 normal messages, 0 quiet .. 7 verbose. */
16  static int max_interrupt_work = 20;
17  
18 +#ifndef PKT_ALIGN
19  /* Set the copy breakpoint for the copy-only-tiny-frames scheme.
20     Setting to > 1518 effectively disables this feature. */
21  #if defined(__alpha__) || defined(__arm__) || defined(__hppa__) \
22 @@ -49,6 +52,7 @@ static int rx_copybreak = 1518;
23  #else
24  static int rx_copybreak;
25  #endif
26 +#endif /* PKT_ALIGN */
27  
28  /* Work-around for broken BIOSes: they are unable to get the chip back out of
29     power state D3 so PXE booting fails. bootparam(7): via-rhine.avoid_D3=1 */
30 @@ -111,6 +115,7 @@ static const int multicast_filter_limit 
31  #include <asm/io.h>
32  #include <asm/irq.h>
33  #include <asm/uaccess.h>
34 +#include <asm/unaligned.h>
35  #include <linux/dmi.h>
36  
37  /* These identify the driver base version and may not be removed. */
38 @@ -130,12 +135,14 @@ MODULE_LICENSE("GPL");
39  
40  module_param(max_interrupt_work, int, 0);
41  module_param(debug, int, 0);
42 -module_param(rx_copybreak, int, 0);
43  module_param(avoid_D3, bool, 0);
44  MODULE_PARM_DESC(max_interrupt_work, "VIA Rhine maximum events handled per interrupt");
45  MODULE_PARM_DESC(debug, "VIA Rhine debug level (0-7)");
46 -MODULE_PARM_DESC(rx_copybreak, "VIA Rhine copy breakpoint for copy-only-tiny-frames");
47  MODULE_PARM_DESC(avoid_D3, "Avoid power state D3 (work-around for broken BIOSes)");
48 +#ifndef PKT_ALIGN
49 +module_param(rx_copybreak, int, 0);
50 +MODULE_PARM_DESC(rx_copybreak, "VIA Rhine copy breakpoint for copy-only-tiny-frames");
51 +#endif
52  
53  /*
54                 Theory of Operation
55 @@ -927,7 +934,7 @@ static void alloc_rbufs(struct net_devic
56  
57         /* Fill in the Rx buffers.  Handle allocation failure gracefully. */
58         for (i = 0; i < RX_RING_SIZE; i++) {
59 -               struct sk_buff *skb = dev_alloc_skb(rp->rx_buf_sz);
60 +               struct sk_buff *skb = dev_alloc_skb(rp->rx_buf_sz + 4);
61                 rp->rx_skbuff[i] = skb;
62                 if (skb == NULL)
63                         break;
64 @@ -1484,7 +1491,9 @@ static int rhine_rx(struct net_device *d
65                         struct sk_buff *skb;
66                         /* Length should omit the CRC */
67                         int pkt_len = data_size - 4;
68 -
69 +#ifdef PKT_ALIGN
70 +                       int i;
71 +#else
72                         /* Check if the packet is long enough to accept without
73                            copying to a minimally-sized skbuff. */
74                         if (pkt_len < rx_copybreak &&
75 @@ -1503,7 +1512,9 @@ static int rhine_rx(struct net_device *d
76                                                                rp->rx_skbuff_dma[entry],
77                                                                rp->rx_buf_sz,
78                                                                PCI_DMA_FROMDEVICE);
79 -                       } else {
80 +                       } else
81 +#endif
82 +                       {
83                                 skb = rp->rx_skbuff[entry];
84                                 if (skb == NULL) {
85                                         printk(KERN_ERR "%s: Inconsistent Rx "
86 @@ -1517,6 +1528,14 @@ static int rhine_rx(struct net_device *d
87                                                  rp->rx_skbuff_dma[entry],
88                                                  rp->rx_buf_sz,
89                                                  PCI_DMA_FROMDEVICE);
90 +#ifdef PKT_ALIGN
91 +                               /* align the data to the ip header - should be faster than copying the entire packet */
92 +                               for (i = pkt_len - (pkt_len % 4); i >= 0; i -= 4) {
93 +                                       put_unaligned(*((u32 *) (skb->data + i)), (u32 *) (skb->data + i + 2));
94 +                               }
95 +                               skb->data += 2;
96 +                               skb->tail += 2;
97 +#endif
98                         }
99                         skb->protocol = eth_type_trans(skb, dev);
100  #ifdef CONFIG_VIA_RHINE_NAPI