Re: Tulip & 3c59x Drivers for 2.6 Kernels

Jan Holmberg <[email protected]>
Newsgroups gmane.linux.drivers.vlan
Organization Artech
Message-ID <[email protected]>
Hi,

I have a patch for the tulip card, works as expected for me (kernel 
2.6.11) .

Use "ip link set mtu 1504 dev eth1" to hardware device.


//&ers, Jan


Nelson Caballero wrote:

>Hi to all,
>
>I'm new with Linux VLAN support and with Linux in
>general... Last time I use it was a long time ago.
>I been reading a lot about the support of VLAN in the
>newest kernels and test it with succesful
>results....until I send a "ping -s 1476 x.x.x.x"
>packet.  Yes MTU issues :-S
>I'm using 2.6.5 and 2.6.8 kernels, but seems to me
>that the patches for the drivers are for 2.4.x
>kernels.  Their is a way to patch the drivers *.c
>files that comes with these new kernels?
>
>I even patched the 2.6.5 with a 3c59x patch I found in
>a page: http://www.oneunified.net/support/linux.html
>
>debian:/usr/src/linux-2.6.5/drivers/net# patch 3c59x.c
>3c59x-patch 
>patching file 3c59x.c
>Hunk #1 succeeded at 329 (offset 21 lines).
>Hunk #2 succeeded at 700 (offset 46 lines).
>Hunk #3 succeeded at 728 (offset 46 lines).
>Hunk #4 succeeded at 825 (offset 45 lines).
>Hunk #5 FAILED at 894.
>Hunk #6 succeeded at 1174 (offset 136 lines).
>Hunk #7 succeeded at 1627 (offset 157 lines).
>Hunk #8 succeeded at 1711 (offset 157 lines).
>Hunk #9 succeeded at 1857 (offset 164 lines).
>Hunk #10 succeeded at 2082 (offset 169 lines).
>debian:/usr/src/linux-2.6.5/drivers/net# 
>
>But it sends me an error on one of the Hunks.
>
>Can anyone help me with some information.
>Best regards and thanks,
>
>Nelson
>
>
>
>		
>__________________________________ 
>Do you Yahoo!? 
>Yahoo! Small Business - Try our new resources site!
>http://smallbusiness.yahoo.com/resources/ 
>_______________________________________________
>Vlan mailing list
>[email protected]
>http://www.lanforge.com/mailman/listinfo/vlan
>
>  
>

_______________________________________________
Vlan mailing list
[email protected]
http://www.lanforge.com/mailman/listinfo/vlan
mtu-tulip-2.6.11.patch (text/plain, 31.4 KB)
diff -Nru linux-2.6.11/drivers/net/tulip/21142.c linux-2.6.11-redbox-1.3/drivers/net/tulip/21142.c
--- linux-2.6.11/drivers/net/tulip/21142.c	Wed Mar  2 08:37:50 2005
+++ linux-2.6.11-redbox-1.3/drivers/net/tulip/21142.c	Thu Mar  3 08:03:00 2005
@@ -9,8 +9,6 @@
 	of the GNU General Public License, incorporated herein by reference.
 
 	Please refer to Documentation/DocBook/tulip-user.{pdf,ps,html}
-	for more information on this driver, or visit the project
-	Web page at http://sourceforge.net/projects/tulip/
 
 */
 
diff -Nru linux-2.6.11/drivers/net/tulip/de2104x.c linux-2.6.11-redbox-1.3/drivers/net/tulip/de2104x.c
--- linux-2.6.11/drivers/net/tulip/de2104x.c	Wed Mar  2 08:38:19 2005
+++ linux-2.6.11-redbox-1.3/drivers/net/tulip/de2104x.c	Thu Mar  3 08:03:00 2005
@@ -28,8 +28,8 @@
  */
 
 #define DRV_NAME		"de2104x"
-#define DRV_VERSION		"0.7"
-#define DRV_RELDATE		"Mar 17, 2004"
+#define DRV_VERSION		"0.8"
+#define DRV_RELDATE		"Feb 25, 2005"
 
 #include <linux/config.h>
 #include <linux/module.h>
@@ -95,7 +95,7 @@
 	  (CP)->tx_tail + (DE_TX_RING_SIZE - 1) - (CP)->tx_head :	\
 	  (CP)->tx_tail - (CP)->tx_head - 1)
 
-#define PKT_BUF_SZ		1536	/* Size of each temporary Rx buffer.*/
+#define PKT_BUF_SZ		(512*3)	/* Size of each temporary Rx buffer.*/
 #define RX_OFFSET		2
 
 #define DE_SETUP_SKB		((struct sk_buff *) 1)
@@ -370,7 +370,7 @@
 			"%s: rx err, slot %d status 0x%x len %d\n",
 			de->dev->name, rx_tail, status, len);
 
-	if ((status & 0x38000300) != 0x0300) {
+	if ((status & (0x38000000 | RxWholePkt)) != RxWholePkt) {
 		/* Ingore earlier buffers. */
 		if ((status & 0xffff) != 0x7fff) {
 			if (netif_msg_rx_err(de))
@@ -417,7 +417,9 @@
 			goto rx_next;
 		}
 
-		if (unlikely((status & 0x38008300) != 0x0300)) {
+		if (unlikely((status & (0x38000000 |
+                                        RxDescErrorSummary |
+                                        RxWholePkt)) != RxWholePkt)) {
 			de_rx_err_acct(de, rx_tail, status, len);
 			goto rx_next;
 		}
diff -Nru linux-2.6.11/drivers/net/tulip/de4x5.c linux-2.6.11-redbox-1.3/drivers/net/tulip/de4x5.c
--- linux-2.6.11/drivers/net/tulip/de4x5.c	Wed Mar  2 08:37:31 2005
+++ linux-2.6.11-redbox-1.3/drivers/net/tulip/de4x5.c	Thu Mar  3 08:03:00 2005
@@ -440,7 +440,9 @@
       0.548  30-Aug-03    Big 2.6 cleanup. Ported to PCI/EISA probing and
                            generic DMA APIs. Fixed DE425 support on Alpha.
 			   <[email protected]>
-    =========================================================================
+      0.549  25-Feb-05    Include VLAN  support
+                          <[email protected]> 	
+=========================================================================
 */
 
 #include <linux/config.h>
@@ -753,7 +755,7 @@
 */
 #define NUM_RX_DESC 8                   /* Number of RX descriptors   */
 #define NUM_TX_DESC 32                  /* Number of TX descriptors   */
-#define RX_BUFF_SZ  1536                /* Power of 2 for kmalloc and */
+#define RX_BUFF_SZ  (512*3)             /* Power of 2 for kmalloc and */
                                         /* Multiple of 4 for DC21040  */
                                         /* Allows 512 byte alignment  */
 struct de4x5_desc {
diff -Nru linux-2.6.11/drivers/net/tulip/interrupt.c linux-2.6.11-redbox-1.3/drivers/net/tulip/interrupt.c
--- linux-2.6.11/drivers/net/tulip/interrupt.c	Wed Mar  2 08:38:37 2005
+++ linux-2.6.11-redbox-1.3/drivers/net/tulip/interrupt.c	Mon Mar 28 23:55:37 2005
@@ -9,8 +9,13 @@
 	of the GNU General Public License, incorporated herein by reference.
 
 	Please refer to Documentation/DocBook/tulip-user.{pdf,ps,html}
-	for more information on this driver, or visit the project
-	Web page at http://sourceforge.net/projects/tulip/
+        and ftp://download.intel.com/design/network/manuals/27807401.pdf
+
+        Try to allways use correct mtu for a given application, if
+        vlan tagging are used; set mtu to 1504. Default mtu are 1500
+	for standard frames and let this driver invalidate any packet
+	higher than selected mtu to make driver more robust against
+	attacks.  
 
 */
 
@@ -55,7 +60,6 @@
         0x80BD0000,
         0x80CF0000,
         0x80DF0000,
-//       0x80FF0000      /* RX time = 16, RX pkts = 7, CM = 1 */
         0x80F10000      /* RX time = 16, RX pkts = 0, CM = 1 */
 };
 #endif
@@ -113,6 +117,8 @@
 	int entry = tp->cur_rx % RX_RING_SIZE;
 	int rx_work_limit = *budget;
 	int received = 0;
+        int max_packet_size_minus_crc = dev->mtu ? dev->mtu + ETH_HLEN : TULIP_MTU_MAX + ETH_HLEN;
+
 
 	if (!netif_running(dev))
 		goto done;
@@ -144,7 +150,7 @@
                /* If we own the next entry, it is a new packet. Send it up. */
                while ( ! (tp->rx_ring[entry].status & cpu_to_le32(DescOwned))) {
                        s32 status = le32_to_cpu(tp->rx_ring[entry].status);
- 
+                       short pkt_len;    
  
                        if (tp->dirty_rx + RX_RING_SIZE == tp->cur_rx)
                                break;
@@ -152,11 +158,36 @@
                        if (tulip_debug > 5)
                                printk(KERN_DEBUG "%s: In tulip_rx(), entry %d %8.8x.\n",
                                       dev->name, entry, status);
+
                        if (--rx_work_limit < 0)
                                goto not_done;
+			
+		/*
+		  Omit the four octet CRC from the length.
+		  (May not be considered valid until we have
+		  checked status for RxLengthOver2047 bits)
+                */
+		pkt_len = ((status >> 16) & 0x7ff) - 4;
+
+		/*
+		  Maximum pkt_len is 1514 exclusive crc (4 bytes)
+                  for standard mtu 1500 ( 1500 + 6 + 6 + 2 )
+		  Anything higher than this is always invalid
+		  regardless of RxLengthOver2047 bits
+		*/
+
+		if ((status & (RxLengthOver2047 |
+			       RxDescCRCError |
+			       RxDescCollisionSeen |
+			       RxDescRunt |
+			       RxDescDescErr |
+			       RxWholePkt)) != RxWholePkt
+		    || pkt_len > max_packet_size_minus_crc ) {
+			if ((status & (RxLengthOver2047 |
+				       RxWholePkt))  != RxWholePkt) {
+
+
  
-                       if ((status & 0x38008300) != 0x0300) {
-                               if ((status & 0x38000300) != 0x0300) {
                                 /* Ingore earlier buffers. */
                                        if ((status & 0xffff) != 0x7fff) {
                                                if (tulip_debug > 1)
@@ -165,30 +196,21 @@
                                                               dev->name, status);
                                                tp->stats.rx_length_errors++;
                                        }
-                               } else if (status & RxDescFatalErr) {
-                                /* There was a fatal error. */
+                               } else {
+                                       /* There was a fatal error. */
                                        if (tulip_debug > 2)
                                                printk(KERN_DEBUG "%s: Receive error, Rx status %8.8x.\n",
                                                       dev->name, status);
                                        tp->stats.rx_errors++; /* end of a packet.*/
-                                       if (status & 0x0890) tp->stats.rx_length_errors++;
-                                       if (status & 0x0004) tp->stats.rx_frame_errors++;
-                                       if (status & 0x0002) tp->stats.rx_crc_errors++;
-                                       if (status & 0x0001) tp->stats.rx_fifo_errors++;
+                                       if (pkt_len > max_packet_size_minus_crc ||
+                                           status & RxDescRunt) tp->stats.rx_length_errors++;
+                                       if (status & 0x0004)     tp->stats.rx_frame_errors++;
+                                       if (status & 0x0002)     tp->stats.rx_crc_errors++;
+                                       if (status & 0x0001)     tp->stats.rx_fifo_errors++;
                                }
                        } else {
-                               /* Omit the four octet CRC from the length. */
-                               short pkt_len = ((status >> 16) & 0x7ff) - 4;
                                struct sk_buff *skb;
   
-#ifndef final_version
-                               if (pkt_len > 1518) {
-                                       printk(KERN_WARNING "%s: Bogus packet size of %d (%#x).\n",
-                                              dev->name, pkt_len, pkt_len);
-                                       pkt_len = 1518;
-                                       tp->stats.rx_length_errors++;
-                               }
-#endif
                                /* Check if the packet is long enough to accept without copying
                                   to a minimally-sized skbuff. */
                                if (pkt_len < tulip_rx_copybreak
@@ -265,20 +287,20 @@
  #ifdef CONFIG_TULIP_NAPI_HW_MITIGATION
   
           /* We use this simplistic scheme for IM. It's proven by
-             real life installations. We can have IM enabled
+            real life installations. We can have IM enabled
             continuesly but this would cause unnecessary latency. 
             Unfortunely we can't use all the NET_RX_* feedback here. 
             This would turn on IM for devices that is not contributing 
             to backlog congestion with unnecessary latency. 
   
-             We monitor the the device RX-ring and have:
+            We monitor the the device RX-ring and have:
   
-             HW Interrupt Mitigation either ON or OFF.
+            HW Interrupt Mitigation either ON or OFF.
   
             ON:  More then 1 pkt received (per intr.) OR we are dropping 
-             OFF: Only 1 pkt received
+            OFF: Only 1 pkt received
             
-             Note. We only use min and max (0, 15) settings from mit_table */
+            Note. We only use min and max (0, 15) settings from mit_table */
   
   
           if( tp->flags &  HAS_INTR_MITIGATION) {
@@ -365,22 +387,47 @@
 	int entry = tp->cur_rx % RX_RING_SIZE;
 	int rx_work_limit = tp->dirty_rx + RX_RING_SIZE - tp->cur_rx;
 	int received = 0;
-
+        short max_packet_size_minus_crc = dev->mtu ? dev->mtu + ETH_HLEN : TULIP_MTU_MAX + ETH_HLEN;
+ 
 	if (tulip_debug > 4)
 		printk(KERN_DEBUG " In tulip_rx(), entry %d %8.8x.\n", entry,
 			   tp->rx_ring[entry].status);
 	/* If we own the next entry, it is a new packet. Send it up. */
 	while ( ! (tp->rx_ring[entry].status & cpu_to_le32(DescOwned))) {
 		s32 status = le32_to_cpu(tp->rx_ring[entry].status);
+		short pkt_len;
 
 		if (tulip_debug > 5)
 			printk(KERN_DEBUG "%s: In tulip_rx(), entry %d %8.8x.\n",
 				   dev->name, entry, status);
 		if (--rx_work_limit < 0)
-			break;
-		if ((status & 0x38008300) != 0x0300) {
-			if ((status & 0x38000300) != 0x0300) {
-				/* Ingore earlier buffers. */
+
+		        break;
+			
+		/*
+		  Omit the four octet CRC from the length.
+		  (May not be considered valid until we have
+		  checked status for RxLengthOver2047 bits)
+                */
+		pkt_len = ((status >> 16) & 0x7ff) - 4;
+
+		/*
+		  Maximum pkt_len is 1518 (1514 + vlan header)
+		  Anything higher than this is always invalid
+		  regardless of RxLengthOver2047 bits
+		*/
+
+		if ((status & (RxLengthOver2047 |
+			       RxDescCRCError |
+			       RxDescCollisionSeen |
+			       RxDescRunt |
+			       RxDescDescErr |
+			       RxWholePkt)) != RxWholePkt
+		    || pkt_len > max_packet_size_minus_crc ) {
+			if ((status & (RxLengthOver2047 |
+				       RxWholePkt)) != RxWholePkt) {
+
+				/* Ignore earlier buffers. */
 				if ((status & 0xffff) != 0x7fff) {
 					if (tulip_debug > 1)
 						printk(KERN_WARNING "%s: Oversized Ethernet frame "
@@ -388,31 +435,21 @@
 							   dev->name, status);
 					tp->stats.rx_length_errors++;
 				}
-			} else if (status & RxDescFatalErr) {
+			} else {
 				/* There was a fatal error. */
 				if (tulip_debug > 2)
 					printk(KERN_DEBUG "%s: Receive error, Rx status %8.8x.\n",
 						   dev->name, status);
 				tp->stats.rx_errors++; /* end of a packet.*/
-				if (status & 0x0890) tp->stats.rx_length_errors++;
-				if (status & 0x0004) tp->stats.rx_frame_errors++;
-				if (status & 0x0002) tp->stats.rx_crc_errors++;
-				if (status & 0x0001) tp->stats.rx_fifo_errors++;
+				if (pkt_len > max_packet_size_minus_crc ||
+				    status & RxDescRunt) tp->stats.rx_length_errors++;
+				if (status & 0x0004)     tp->stats.rx_frame_errors++;
+				if (status & 0x0002)     tp->stats.rx_crc_errors++;
+				if (status & 0x0001)     tp->stats.rx_fifo_errors++;
 			}
 		} else {
-			/* Omit the four octet CRC from the length. */
-			short pkt_len = ((status >> 16) & 0x7ff) - 4;
 			struct sk_buff *skb;
 
-#ifndef final_version
-			if (pkt_len > 1518) {
-				printk(KERN_WARNING "%s: Bogus packet size of %d (%#x).\n",
-					   dev->name, pkt_len, pkt_len);
-				pkt_len = 1518;
-				tp->stats.rx_length_errors++;
-			}
-#endif
-
 			/* Check if the packet is long enough to accept without copying
 			   to a minimally-sized skbuff. */
 			if (pkt_len < tulip_rx_copybreak
@@ -601,7 +638,7 @@
 					if (status & 0x0C00) tp->stats.tx_carrier_errors++;
 					if (status & 0x0200) tp->stats.tx_window_errors++;
 					if (status & 0x0002) tp->stats.tx_fifo_errors++;
-					if ((status & 0x0080) && tp->full_duplex == 0)
+					if((status & 0x0080) && tp->full_duplex == 0)
 						tp->stats.tx_heartbeat_errors++;
 				} else {
 					tp->stats.tx_bytes +=
diff -Nru linux-2.6.11/drivers/net/tulip/tulip.h linux-2.6.11-redbox-1.3/drivers/net/tulip/tulip.h
--- linux-2.6.11/drivers/net/tulip/tulip.h	Wed Mar  2 08:38:26 2005
+++ linux-2.6.11-redbox-1.3/drivers/net/tulip/tulip.h	Thu Mar  3 08:03:00 2005
@@ -8,9 +8,19 @@
 	of the GNU General Public License, incorporated herein by reference.
 
 	Please refer to Documentation/DocBook/tulip-user.{pdf,ps,html}
-	for more information on this driver, or visit the project
-	Web page at http://sourceforge.net/projects/tulip/
 
+        Version Date
+
+                25-Feb-05 Include VLAN support, Label status bits field for
+                          easy reading in rxcode. From Intel 21143 pdf:
+                          ftp://download.intel.com/design/network/manuals/27807401.pdf
+                          In 6.3.4.6 Fram Reception Status we can read                             
+                          Frame too long allways set for packet > 1518 bytes.
+                          Checking received bytes counter instead of this flag
+                          solve the problem with mtu > 1500.  
+                          <[email protected]>
+
+=========================================================================
 */
 
 #ifndef __NET_TULIP_H__
@@ -29,7 +39,7 @@
 
 
 /* undefine, or define to various debugging levels (>4 == obscene levels) */
-#define TULIP_DEBUG 1
+/* #define TULIP_DEBUG 1 */
 
 /* undefine USE_IO_OPS for MMIO, define for PIO */
 #ifdef CONFIG_TULIP_MMIO
@@ -195,8 +205,39 @@
 
 enum desc_status_bits {
 	DescOwned = 0x80000000,
-	RxDescFatalErr = 0x8000,
-	RxWholePkt = 0x0300,
+
+        /* 
+	   Error summary flag is logical or of 'CRC Error',
+	   'Collision Seen', 'Frame Too Long', 'Runt' and 
+	   'Descriptor Error' flags generated within tulip chip.
+	*/
+        RxDescErrorSummary = 0x8000, 
+
+	RxDescCRCError 	= 0x0002,
+        RxDescCollisionSeen = 0x0040,
+        /* 
+	   'Frame Too Long' flag is set if packet length including CRC
+	   exceeds 1518.  However, a full sized VLAN tagged frame is
+	   1522 bytes including CRC.
+	   
+	   The tulip chip does not block oversized frames, and if this
+	   flag is set on a receive descriptor it does not indicate
+	   the frame has been truncated.  The receive descriptor also
+	   includes the actual length.  Therefore we can safety ignore
+	   this flag and check the length ourselves. 
+        */
+        RxDescFrameTooLong = 0x0080,
+	RxDescRunt = 0x0800,
+	RxDescDescErr = 0x4000,
+ 	RxWholePkt = 0x0300,
+	
+	/*
+	  Top three bits of 14 bit frame length (status bits 27-29) 
+          should never be set as that would make frame over 2047 bytes.
+	  The Receive Watchdog flag (bit 4) may indicate the length is
+          over 2048 and the length field is invalid.
+	*/
+	RxLengthOver2047 = 0x38000010
 };
 
 
@@ -261,9 +302,22 @@
 
 #define TX_RING_SIZE	32
 #define RX_RING_SIZE	128 
-#define MEDIA_MASK     31
+#define MEDIA_MASK      31
+
+
+/* Keep maintainer happy with old bufferalign
+   The old hardvired TL bitflag works with 1500
+   + ethframe + crc (1518 octets) and lower value.
+   New status check included in this release, to
+   work around this problem and ignoring TL flag.    
+   <[email protected]>
+   Some code from Willy Tarreau
+*/
+
 
-#define PKT_BUF_SZ		1536	/* Size of each temporary Rx buffer. */
+#define PKT_BUF_SZ		(512*3)	/* Size of each temporary Rx buffer. */
+#define TULIP_MTU_MIN 68
+#define TULIP_MTU_MAX (PKT_BUF_SZ - 18) /* -(ethframe + crc) */
 
 #define TULIP_MIN_CACHE_LINE	8	/* in units of 32-bit words */
 
diff -Nru linux-2.6.11/drivers/net/tulip/tulip_core.c linux-2.6.11-redbox-1.3/drivers/net/tulip/tulip_core.c
--- linux-2.6.11/drivers/net/tulip/tulip_core.c	Wed Mar  2 08:38:10 2005
+++ linux-2.6.11-redbox-1.3/drivers/net/tulip/tulip_core.c	Tue Mar 29 06:34:25 2005
@@ -18,11 +18,11 @@
 
 #define DRV_NAME	"tulip"
 #ifdef CONFIG_TULIP_NAPI
-#define DRV_VERSION    "1.1.13-NAPI" /* Keep at least for test */
+#define DRV_VERSION    "1.1.14-NAPI" /* Keep at least for test */
 #else
-#define DRV_VERSION	"1.1.13"
+#define DRV_VERSION	"1.1.14"
 #endif
-#define DRV_RELDATE	"May 11, 2002"
+#define DRV_RELDATE	"Feb 25, 2005"
 
 
 #include <linux/module.h>
@@ -41,6 +41,8 @@
 #include <asm/pbm.h>
 #endif
 
+#define netdev_priv_tulip(a)	((struct tulip_private *)netdev_priv(a))
+
 static char version[] __devinitdata =
 	"Linux Tulip driver version " DRV_VERSION " (" DRV_RELDATE ")\n";
 
@@ -54,7 +56,9 @@
 /* Used to pass the full-duplex flag, etc. */
 static int full_duplex[MAX_UNITS];
 static int options[MAX_UNITS];
-static int mtu[MAX_UNITS];			/* Jumbo MTU for interfaces. */
+
+/* static int mtu[MAX_UNITS];			//Jumbo MTU for interfaces. 
+*/
 
 /*  The possible media types that can be set in options[] are: */
 const char * const medianame[32] = {
@@ -264,6 +268,16 @@
 #ifdef CONFIG_NET_POLL_CONTROLLER
 static void poll_tulip(struct net_device *dev);
 #endif
+static int change_mtu(struct net_device *dev, int new_mtu);
+
+
+static int change_mtu(struct net_device *dev, int new_mtu)
+{
+ if ((new_mtu < TULIP_MTU_MIN) || (new_mtu > TULIP_MTU_MAX))
+ return -EINVAL;
+ dev->mtu = new_mtu;
+ return 0;
+}
 
 static void tulip_set_power_state (struct tulip_private *tp,
 				   int sleep, int snooze)
@@ -393,17 +407,25 @@
 	tp->cur_index = i;
 	tp->nwayset = 0;
 
-	if (dev->if_port) {
-		if (tp->chip_id == DC21143  &&
-		    (tulip_media_cap[dev->if_port] & MediaIsMII)) {
+
+        switch ( tp->chip_id ) {
+ 
+	case  DC21143:
+                   if ( dev->if_port ) { /* Is this what we want ? JH */
+                    if (tulip_media_cap[dev->if_port] & MediaIsMII) {
 			/* We must reset the media CSRs when we force-select MII mode. */
 			iowrite32(0x0000, ioaddr + CSR13);
 			iowrite32(0x0000, ioaddr + CSR14);
 			iowrite32(0x0008, ioaddr + CSR15);
-		}
-		tulip_select_media(dev, 1);
-	} else if (tp->chip_id == DC21142) {
-		if (tp->mii_cnt) {
+                    }
+		    tulip_select_media(dev, 1);
+                  } else {
+
+/* This is old part of 21142, and share DC21143 code, selected by if_port.
+   Also MII transceiver status message depends on if_port and feels wrong in
+   this case. JH */
+
+		    if (tp->mii_cnt) {
 			tulip_select_media(dev, 1);
 			if (tulip_debug > 1)
 				printk(KERN_INFO "%s: Using MII transceiver %d, status "
@@ -414,16 +436,23 @@
 			dev->if_port = 11;
 			iowrite32(0x0000, ioaddr + CSR13);
 			iowrite32(0x0000, ioaddr + CSR14);
-		} else
+		    } else
 			t21142_start_nway(dev);
-	} else if (tp->chip_id == PNIC2) {
+               } /* End of DC21143 & DC211142 */   
+        break;
+
+	case PNIC2:
 	        /* for initial startup advertise 10/100 Full and Half */
 	        tp->sym_advertise = 0x01E0;
                 /* enable autonegotiate end interrupt */
 	        iowrite32(ioread32(ioaddr+CSR5)| 0x00008010, ioaddr + CSR5);
 	        iowrite32(ioread32(ioaddr+CSR7)| 0x00008010, ioaddr + CSR7);
 		pnic2_start_nway(dev);
-	} else if (tp->chip_id == LC82C168  &&  ! tp->medialock) {
+        break;
+
+	case LC82C168:
+
+	 if ( ! tp->medialock) {
 		if (tp->mii_cnt) {
 			dev->if_port = 11;
 			tp->csr6 = 0x814C0000 | (tp->full_duplex ? 0x0200 : 0);
@@ -438,27 +467,44 @@
 			iowrite32(0x0201B078, ioaddr + 0xB8);
 			next_tick = 1*HZ;
 		}
-	} else if ((tp->chip_id == MX98713 || tp->chip_id == COMPEX9881)
-			   && ! tp->medialock) {
+          }   
+        break;
+ 
+	case  MX98713:
+	case  COMPEX9881:
+		if ( ! tp->medialock) {
 		dev->if_port = 0;
 		tp->csr6 = 0x01880000 | (tp->full_duplex ? 0x0200 : 0);
 		iowrite32(0x0f370000 | ioread16(ioaddr + 0x80), ioaddr + 0x80);
-	} else if (tp->chip_id == MX98715 || tp->chip_id == MX98725) {
+                }  
+
+	case  MX98715:
+        case  MX98725:
 		/* Provided by BOLO, Macronix - 12/10/1998. */
 		dev->if_port = 0;
 		tp->csr6 = 0x01a80200;
 		iowrite32(0x0f370000 | ioread16(ioaddr + 0x80), ioaddr + 0x80);
 		iowrite32(0x11000 | ioread16(ioaddr + 0xa0), ioaddr + 0xa0);
-	} else if (tp->chip_id == COMET || tp->chip_id == CONEXANT) {
+        break;
+         
+	case  COMET:
+	case  CONEXANT:
 		/* Enable automatic Tx underrun recovery. */
 		iowrite32(ioread32(ioaddr + 0x88) | 1, ioaddr + 0x88);
 		dev->if_port = tp->mii_cnt ? 11 : 0;
 		tp->csr6 = 0x00040000;
-	} else if (tp->chip_id == AX88140) {
+        break;
+
+        case  AX88140:
+
 		tp->csr6 = tp->mii_cnt ? 0x00040100 : 0x00000100;
-	} else
+        break;
+
+	default:	
 		tulip_select_media(dev, 1);
 
+        }
+
 	/* Start the chip's Tx to process setup frame. */
 	tulip_stop_rxtx(tp);
 	barrier();
@@ -839,10 +885,9 @@
 
 static void tulip_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info)
 {
-	struct tulip_private *np = netdev_priv(dev);
 	strcpy(info->driver, DRV_NAME);
 	strcpy(info->version, DRV_VERSION);
-	strcpy(info->bus_info, pci_name(np->pdev));
+	strcpy(info->bus_info, pci_name(netdev_priv_tulip(dev)->pdev));
 }
 
 static struct ethtool_ops ops = {
@@ -1587,8 +1632,7 @@
 			tp->default_port = options[board_idx] & MEDIA_MASK;
 		if ((options[board_idx] & FullDuplex) || full_duplex[board_idx] > 0)
 			tp->full_duplex = 1;
-		if (mtu[board_idx] > 0)
-			dev->mtu = mtu[board_idx];
+
 	}
 	if (dev->mem_start & MEDIA_MASK)
 		tp->default_port = dev->mem_start & MEDIA_MASK;
@@ -1650,6 +1694,8 @@
 #ifdef CONFIG_NET_POLL_CONTROLLER
 	dev->poll_controller = &poll_tulip;
 #endif
+	dev->change_mtu = &change_mtu;
+
 	SET_ETHTOOL_OPS(dev, &ops);
 
 	if (register_netdev(dev))
diff -Nru linux-2.6.11/drivers/net/tulip/xircom_tulip_cb.c linux-2.6.11-redbox-1.3/drivers/net/tulip/xircom_tulip_cb.c
--- linux-2.6.11/drivers/net/tulip/xircom_tulip_cb.c	Wed Mar  2 08:37:49 2005
+++ linux-2.6.11-redbox-1.3/drivers/net/tulip/xircom_tulip_cb.c	Thu Mar  3 08:03:00 2005
@@ -47,7 +47,9 @@
 /* Used to pass the full-duplex flag, etc. */
 static int full_duplex[MAX_UNITS];
 static int options[MAX_UNITS];
-static int mtu[MAX_UNITS];			/* Jumbo MTU for interfaces. */
+
+/* static int mtu[MAX_UNITS];			/ Jumbo MTU for interfaces. 
+*/
 
 /* Keep the ring sizes a power of two for efficiency.
    Making the Tx ring too large decreases the effectiveness of channel
@@ -601,8 +603,9 @@
 		tp->default_port = options[board_idx] & 15;
 		if ((options[board_idx] & 0x90) || full_duplex[board_idx] > 0)
 			tp->full_duplex = 1;
-		if (mtu[board_idx] > 0)
+/*		if (mtu[board_idx] > 0)
 			dev->mtu = mtu[board_idx];
+*/
 	}
 	if (dev->mem_start)
 		tp->default_port = dev->mem_start;
@@ -1208,8 +1211,9 @@
 	struct xircom_private *tp = netdev_priv(dev);
 	int entry = tp->cur_rx % RX_RING_SIZE;
 	int rx_work_limit = tp->dirty_rx + RX_RING_SIZE - tp->cur_rx;
-	int work_done = 0;
-
+	int received = 0;
+        int pkt_len;
+ 
 	if (xircom_debug > 4)
 		printk(KERN_DEBUG " In xircom_rx(), entry %d %8.8x.\n", entry,
 			   tp->rx_ring[entry].status);
@@ -1222,63 +1226,101 @@
 				   tp->rx_ring[entry].status);
 		if (--rx_work_limit < 0)
 			break;
-		if ((status & 0x38008300) != 0x0300) {
-			if ((status & 0x38000300) != 0x0300) {
-				/* Ignore earlier buffers. */
-				if ((status & 0xffff) != 0x7fff) {
-					if (xircom_debug > 1)
-						printk(KERN_WARNING "%s: Oversized Ethernet frame "
-							   "spanned multiple buffers, status %8.8x!\n",
-							   dev->name, status);
-					tp->stats.rx_length_errors++;
-				}
-			} else if (status & Rx0DescError) {
-				/* There was a fatal error. */
-				if (xircom_debug > 2)
-					printk(KERN_DEBUG "%s: Receive error, Rx status %8.8x.\n",
-						   dev->name, status);
-				tp->stats.rx_errors++; /* end of a packet.*/
-				if (status & (Rx0Runt | Rx0HugeFrame)) tp->stats.rx_length_errors++;
-				if (status & Rx0CRCError) tp->stats.rx_crc_errors++;
-			}
-		} else {
-			/* Omit the four octet CRC from the length. */
-			short pkt_len = ((status >> 16) & 0x7ff) - 4;
-			struct sk_buff *skb;
-
-#ifndef final_version
-			if (pkt_len > 1518) {
-				printk(KERN_WARNING "%s: Bogus packet size of %d (%#x).\n",
-					   dev->name, pkt_len, pkt_len);
-				pkt_len = 1518;
-				tp->stats.rx_length_errors++;
-			}
-#endif
-			/* Check if the packet is long enough to accept without copying
-			   to a minimally-sized skbuff. */
-			if (pkt_len < rx_copybreak
-				&& (skb = dev_alloc_skb(pkt_len + 2)) != NULL) {
-				skb->dev = dev;
-				skb_reserve(skb, 2);	/* 16 byte align the IP header */
+                /*
+                  Omit the four octet CRC from the length.
+                  (May not be considered valid until we have
+                  checked status for RxLengthOver2047 bits)
+                */
+
+                pkt_len = ((status >> 16) & 0x7ff) - 4;
+
+                /*
+                  Maximum pkt_len is 1518 (1514 + vlan header)
+                  Anything higher than this is always invalid
+                  regardless of RxLengthOver2047 bits
+                */
+
+                if ((status & (RxLengthOver2047 |
+                               RxDescCRCError |
+                               RxDescCollisionSeen |
+                               RxDescRunt |
+                               RxDescDescErr |
+                               RxWholePkt)) != RxWholePkt
+                    || pkt_len > 1518 ) {
+                        if ((status & (RxLengthOver2047 |
+                                       RxWholePkt))  != RxWholePkt) {
+
+                                /* Ingore earlier buffers. */
+                                       if ((status & 0xffff) != 0x7fff) {
+                                               if (xircom_debug > 1)
+                                                       printk(KERN_WARNING "%s: Oversized Ethernet frame "
+                                                              "spanned multiple buffers, status %8.8x!\n",
+                                                              dev->name, status);
+                                               tp->stats.rx_length_errors++;
+                                       }
+                               } else {
+                                       /* There was a fatal error. */
+                                       if (xircom_debug > 2)
+                                               printk(KERN_DEBUG "%s: Receive error, Rx status %8.8x.\n",
+                                                      dev->name, status);
+                                       tp->stats.rx_errors++; /* end of a packet.*/
+                                       if (pkt_len > 1518 || status & RxDescRunt)
+                                                            tp->stats.rx_length_errors++;
+                                       if (status & 0x0004) tp->stats.rx_frame_errors++;
+                                       if (status & 0x0002) tp->stats.rx_crc_errors++;
+                                       if (status & 0x0001) tp->stats.rx_fifo_errors++;
+                               }
+                       } else {
+                               struct sk_buff *skb;
+
+                               /* Check if the packet is long enough to accept without copying
+                                  to a minimally-sized skbuff. */
+                               if (pkt_len < rx_copybreak
+                                   && (skb = dev_alloc_skb(pkt_len + 2)) != NULL) {
+                                       skb->dev = dev;
+                                       skb_reserve(skb, 2);    /* 16 byte align the IP header */
+                                       pci_dma_sync_single_for_cpu(tp->pdev,
+                                                                   tp->rx_buffers[entry].mapping,
+                                                                   pkt_len, PCI_DMA_FROMDEVICE);
 #if ! defined(__alpha__)
-				eth_copy_and_sum(skb, bus_to_virt(tp->rx_ring[entry].buffer1),
-								 pkt_len, 0);
-				skb_put(skb, pkt_len);
+                                       eth_copy_and_sum(skb, tp->rx_buffers[entry].skb->tail,
+                                                        pkt_len, 0);
+                                       skb_put(skb, pkt_len);
 #else
-				memcpy(skb_put(skb, pkt_len),
-					   bus_to_virt(tp->rx_ring[entry].buffer1), pkt_len);
+                                       memcpy(skb_put(skb, pkt_len),
+                                              tp->rx_buffers[entry].skb->tail,
+                                              pkt_len);
 #endif
-				work_done++;
-			} else { 	/* Pass up the skb already on the Rx ring. */
-				skb_put(skb = tp->rx_skbuff[entry], pkt_len);
-				tp->rx_skbuff[entry] = NULL;
-			}
-			skb->protocol = eth_type_trans(skb, dev);
-			netif_rx(skb);
-			dev->last_rx = jiffies;
-			tp->stats.rx_packets++;
-			tp->stats.rx_bytes += pkt_len;
-		}
+                                       pci_dma_sync_single_for_device(tp->pdev,
+                                                                      tp->rx_buffers[entry].mapping,
+                                                                      pkt_len, PCI_DMA_FROMDEVICE);
+                               } else {        /* Pass up the skb already on the Rx ring. */
+                                       char *temp = skb_put(skb = tp->rx_buffers[entry].skb,
+                                                            pkt_len);
+
+                                       pci_unmap_single(tp->pdev, tp->rx_buffers[entry].mapping,
+                                                        PKT_BUF_SZ, PCI_DMA_FROMDEVICE);
+
+                                       tp->rx_buffers[entry].skb = NULL;
+                                       tp->rx_buffers[entry].mapping = 0;
+                               }
+                               skb->protocol = eth_type_trans(skb, dev);
+
+                               netif_receive_skb(skb);
+
+                               dev->last_rx = jiffies;
+                               tp->stats.rx_packets++;
+                               tp->stats.rx_bytes += pkt_len;
+                       }
+                       received++;
+
+                       entry = (++tp->cur_rx) % RX_RING_SIZE;
+                       if (tp->cur_rx - tp->dirty_rx > RX_RING_SIZE/4)
+                               tulip_refill_rx(dev);
+
+                }
+
+
 		entry = (++tp->cur_rx) % RX_RING_SIZE;
 	}
 
@@ -1292,12 +1334,12 @@
 				break;
 			skb->dev = dev;			/* Mark as being used by this device. */
 			tp->rx_ring[entry].buffer1 = virt_to_bus(skb->tail);
-			work_done++;
+			 received++;
 		}
 		tp->rx_ring[entry].status = Rx0DescOwned;
 	}
 
-	return work_done;
+	return  received;
 }
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.