[VLAN] Tulip & 3c59x Drivers for 2.6 Kernels

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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
>Vlan@xxxxxxxxxxxxxxx
>http://www.lanforge.com/mailman/listinfo/vlan
>
>  
>

-------------- next part --------------
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.
 			   <maz@xxxxxxxxxxxxxxxxxxx>
-    =========================================================================
+      0.549  25-Feb-05    Include VLAN  support
+                          <jan@xxxxxxxxxx> 	
+=========================================================================
 */
 
 #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.  
+                          <jan@xxxxxxxxxx>
+
+=========================================================================
 */
 
 #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.    
+   <jan@xxxxxxxxxx>
+   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;
 }
 
 

[Index of Archives]     [Netdev]     [Ethernet Bridging]     [Linux Wireless]     [Kernel Newbies]     [Security]     [Linux for Hams]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux RAID]     [Linux Admin]     [Samba]     [Video 4 Linux]

  Powered by Linux