strip the kernel version suffix from target directories, except for brcm-2.4 (the...
[openwrt/svn-archive/archive.git] / target / linux / rb532 / patches / 240-via_rhine_performance.patch
diff --git a/target/linux/rb532/patches/240-via_rhine_performance.patch b/target/linux/rb532/patches/240-via_rhine_performance.patch
new file mode 100644 (file)
index 0000000..e7cdf8a
--- /dev/null
@@ -0,0 +1,94 @@
+diff -ur linux.old/drivers/net/via-rhine.c linux.dev/drivers/net/via-rhine.c
+--- linux.old/drivers/net/via-rhine.c  2006-11-29 22:57:37.000000000 +0100
++++ linux.dev/drivers/net/via-rhine.c  2006-12-14 03:39:01.000000000 +0100
+@@ -33,6 +33,7 @@
+ #define DRV_VERSION   "1.4.3"
+ #define DRV_RELDATE   "2007-03-06"
++#define PKT_ALIGN 1
+ /* A few user-configurable values.
+    These may be modified when a driver module is loaded. */
+@@ -40,9 +41,11 @@
+ static int debug = 1; /* 1 normal messages, 0 quiet .. 7 verbose. */
+ static int max_interrupt_work = 20;
++#ifndef PKT_ALIGN
+ /* Set the copy breakpoint for the copy-only-tiny-frames scheme.
+    Setting to > 1518 effectively disables this feature. */
+ static int rx_copybreak;
++#endif
+ /* Work-around for broken BIOSes: they are unable to get the chip back out of
+    power state D3 so PXE booting fails. bootparam(7): via-rhine.avoid_D3=1 */
+@@ -105,6 +108,7 @@
+ #include <asm/io.h>
+ #include <asm/irq.h>
+ #include <asm/uaccess.h>
++#include <asm/unaligned.h>
+ #include <linux/dmi.h>
+ /* These identify the driver base version and may not be removed. */
+@@ -124,12 +128,14 @@
+ module_param(max_interrupt_work, int, 0);
+ module_param(debug, int, 0);
+-module_param(rx_copybreak, int, 0);
+ module_param(avoid_D3, bool, 0);
+ MODULE_PARM_DESC(max_interrupt_work, "VIA Rhine maximum events handled per interrupt");
+ MODULE_PARM_DESC(debug, "VIA Rhine debug level (0-7)");
+-MODULE_PARM_DESC(rx_copybreak, "VIA Rhine copy breakpoint for copy-only-tiny-frames");
+ MODULE_PARM_DESC(avoid_D3, "Avoid power state D3 (work-around for broken BIOSes)");
++#ifndef PKT_ALIGN
++module_param(rx_copybreak, int, 0);
++MODULE_PARM_DESC(rx_copybreak, "VIA Rhine copy breakpoint for copy-only-tiny-frames");
++#endif
+ /*
+               Theory of Operation
+@@ -924,7 +930,7 @@
+       /* Fill in the Rx buffers.  Handle allocation failure gracefully. */
+       for (i = 0; i < RX_RING_SIZE; i++) {
+-              struct sk_buff *skb = dev_alloc_skb(rp->rx_buf_sz);
++              struct sk_buff *skb = dev_alloc_skb(rp->rx_buf_sz + 4);
+               rp->rx_skbuff[i] = skb;
+               if (skb == NULL)
+                       break;
+@@ -1482,6 +1488,9 @@
+                       /* Length should omit the CRC */
+                       int pkt_len = data_size - 4;
++#ifdef PKT_ALIGN
++                      int i;
++#else
+                       /* Check if the packet is long enough to accept without
+                          copying to a minimally-sized skbuff. */
+                       if (pkt_len < rx_copybreak &&
+@@ -1501,7 +1510,9 @@
+                                                              rp->rx_skbuff_dma[entry],
+                                                              rp->rx_buf_sz,
+                                                              PCI_DMA_FROMDEVICE);
+-                      } else {
++                      } else
++#endif
++                      {
+                               skb = rp->rx_skbuff[entry];
+                               if (skb == NULL) {
+                                       printk(KERN_ERR "%s: Inconsistent Rx "
+@@ -1515,6 +1526,14 @@
+                                                rp->rx_skbuff_dma[entry],
+                                                rp->rx_buf_sz,
+                                                PCI_DMA_FROMDEVICE);
++#ifdef PKT_ALIGN              
++                              /* align the data to the ip header - should be faster than copying the entire packet */
++                              for (i = pkt_len - (pkt_len % 4); i >= 0; i -= 4) {
++                                      put_unaligned(*((u32 *) (skb->data + i)), (u32 *) (skb->data + i + 2));
++                              }
++                              skb->data += 2;
++                              skb->tail += 2;
++#endif        
+                       }
+                       skb->protocol = eth_type_trans(skb, dev);
+ #ifdef CONFIG_VIA_RHINE_NAPI
+