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;
}