netdev
[Top] [All Lists]

[RFC] tulip VLAN support

To: netdev@xxxxxxxxxxx
Subject: [RFC] tulip VLAN support
From: Johannes Erdfelt <johannes@xxxxxxxxxxx>
Date: Wed, 5 Jan 2005 11:34:25 -0800
Sender: netdev-bounce@xxxxxxxxxxx
User-agent: Mutt/1.4.1i
I recently upgraded a system running a 2.4 kernel to a 2.6 based
distribution (Fedora Core 2, 2.6.9-1.6_FC2 kernel) and ran into a
problem using NFS. After spending some tracking it down, I found out it
was an MTU problem and then remembered I had the same problem a couple
of years ago with the 2.4 kernels I was running.

The problem is that the tulip driver doesn't handle 802.1q tags
correctly. Since the VLAN tagging adds 4 bytes to the beginning of the
frame, this can cause frame sizes to be too large for the driver (chip?)
and the packets get dropped.

I've taken the 2.4 patch I found (I forget who developed it, sorry) and
ported it to the 2.6 driver. The patch is relative to the 2.6.9-1.6_FC2
kernel for FC2, but I suspect it will apply to other kernels relatively
cleanly.

Before I rediff the patch against the BK tree and double check all of
the tulip variants are updated correctly as well, is there any interest
in accepting a patch like this?

The 2.4 patch worked for a couple of years for me with no problems and
this 2.6 patch has worked for over a week now with no problems. However,
I'm worried that there is a reason why a similar patch has not been
applied already.

JE

diff -ur linux-2.6.9.orig/drivers/net/tulip/interrupt.c 
linux-2.6.9/drivers/net/tulip/interrupt.c
--- linux-2.6.9.orig/drivers/net/tulip/interrupt.c      2004-10-18 
14:55:36.000000000 -0700
+++ linux-2.6.9/drivers/net/tulip/interrupt.c   2004-12-30 15:23:51.085876693 
-0800
@@ -155,9 +155,9 @@
                        if (--rx_work_limit < 0)
                                goto not_done;
  
-                       if ((status & 0x38008300) != 0x0300) {
-                               if ((status & 0x38000300) != 0x0300) {
-                                /* Ingore earlier buffers. */
+                       if ((status & (0x38000000 | RxDescFatalErr | 
RxWholePkt)) != RxWholePkt) {
+                               if ((status & (0x38000000 | RxWholePkt)) != 
RxWholePkt) {
+                                /* Ignore earlier buffers. */
                                        if ((status & 0xffff) != 0x7fff) {
                                                if (tulip_debug > 1)
                                                        printk(KERN_WARNING 
"%s: Oversized Ethernet frame "
@@ -182,10 +182,10 @@
                                struct sk_buff *skb;
   
 #ifndef final_version
-                               if (pkt_len > 1518) {
+                               if (pkt_len > 1522) {
                                        printk(KERN_WARNING "%s: Bogus packet 
size of %d (%#x).\n",
                                               dev->name, pkt_len, pkt_len);
-                                       pkt_len = 1518;
+                                       pkt_len = 1522;
                                        tp->stats.rx_length_errors++;
                                }
 #endif
@@ -378,9 +378,9 @@
                                   dev->name, entry, status);
                if (--rx_work_limit < 0)
                        break;
-               if ((status & 0x38008300) != 0x0300) {
-                       if ((status & 0x38000300) != 0x0300) {
-                               /* Ingore earlier buffers. */
+                if ((status & (0x38000000 | RxDescFatalErr | RxWholePkt)) != 
RxWholePkt) {
+                        if ((status & (0x38000000 | RxWholePkt)) != 
RxWholePkt) {
+                               /* Ignore earlier buffers. */
                                if ((status & 0xffff) != 0x7fff) {
                                        if (tulip_debug > 1)
                                                printk(KERN_WARNING "%s: 
Oversized Ethernet frame "
@@ -405,10 +405,10 @@
                        struct sk_buff *skb;
 
 #ifndef final_version
-                       if (pkt_len > 1518) {
+                       if (pkt_len > 1522) {
                                printk(KERN_WARNING "%s: Bogus packet size of 
%d (%#x).\n",
                                           dev->name, pkt_len, pkt_len);
-                               pkt_len = 1518;
+                               pkt_len = 1522;
                                tp->stats.rx_length_errors++;
                        }
 #endif
diff -ur linux-2.6.9.orig/drivers/net/tulip/tulip.h 
linux-2.6.9/drivers/net/tulip/tulip.h
--- linux-2.6.9.orig/drivers/net/tulip/tulip.h  2004-10-18 14:55:21.000000000 
-0700
+++ linux-2.6.9/drivers/net/tulip/tulip.h       2004-12-30 15:20:21.432056171 
-0800
@@ -191,7 +191,7 @@
 
 enum desc_status_bits {
        DescOwned = 0x80000000,
-       RxDescFatalErr = 0x8000,
+       RxDescFatalErr = 0x4842,
        RxWholePkt = 0x0300,
 };
 
@@ -259,7 +259,7 @@
 #define RX_RING_SIZE   128 
 #define MEDIA_MASK     31
 
-#define PKT_BUF_SZ             1536    /* Size of each temporary Rx buffer. */
+#define PKT_BUF_SZ             1540    /* Size of each temporary Rx buffer. */
 
 #define TULIP_MIN_CACHE_LINE   8       /* in units of 32-bit words */
 
diff -ur linux-2.6.9.orig/drivers/net/tulip/tulip_core.c 
linux-2.6.9/drivers/net/tulip/tulip_core.c
--- linux-2.6.9.orig/drivers/net/tulip/tulip_core.c     2004-10-18 
14:54:32.000000000 -0700
+++ linux-2.6.9/drivers/net/tulip/tulip_core.c  2004-12-30 15:19:42.424578510 
-0800
@@ -70,7 +70,7 @@
 #if defined(__alpha__) || defined(__arm__) || defined(__hppa__) \
        || defined(__sparc_) || defined(__ia64__) \
        || defined(__sh__) || defined(__mips__)
-static int rx_copybreak = 1518;
+static int rx_copybreak = 1522;
 #else
 static int rx_copybreak = 100;
 #endif

<Prev in Thread] Current Thread [Next in Thread>