* [PATCH] [EXPERIMENTAL] 2.6: de2104x.c jumbo frames, take two
@ 2004-01-09 23:33 Rask Ingemann Lambertsen
2004-01-10 13:47 ` Rask Ingemann Lambertsen
0 siblings, 1 reply; 2+ messages in thread
From: Rask Ingemann Lambertsen @ 2004-01-09 23:33 UTC (permalink / raw)
To: netdev, linux-net; +Cc: jgarzik
Hi.
Attached is a patch which enables jumbo frames on DS2104x based boards. The
maximum supported MTU is 4066 bytes (but see below). Room for a VLAN tag is
included.
The maximum supported MTU is about twice as large as in my first jumbo frame
patch because both buffers of RX and TX descriptors are used (just like the
winbond-840 driver on TX). The media tables have been adjusted to disable
the RX watchdog and TX jabber timers.
Tested with a DS21041 and an MTU of 3544 on BNC media with an NE3200 board
at the other end without problems.
Known bugs and problems:
1. Although the DS21143 manual says that the RX frame descriptor size field
is 14 bits wide, the DS21041 seems to use only 11 bits. This means that
frames larger than 1518+2048 bytes can not be told apart from frames larger
than 1518 bytes but smaller than 2048 bytes. As a result, setting the MTU
larger than 3544 will cause problems.
Please report success or failure with this patch.
--
Regards,
Rask Ingemann Lambertsen
^ permalink raw reply [flat|nested] 2+ messages in thread
* Re: [PATCH] [EXPERIMENTAL] 2.6: de2104x.c jumbo frames, take two
2004-01-09 23:33 [PATCH] [EXPERIMENTAL] 2.6: de2104x.c jumbo frames, take two Rask Ingemann Lambertsen
@ 2004-01-10 13:47 ` Rask Ingemann Lambertsen
0 siblings, 0 replies; 2+ messages in thread
From: Rask Ingemann Lambertsen @ 2004-01-10 13:47 UTC (permalink / raw)
To: netdev, linux-net
[-- Attachment #1: Type: text/plain, Size: 237 bytes --]
On Sat, Jan 10, 2004 at 12:33:07AM +0100, Rask Ingemann Lambertsen wrote:
> Hi.
>
> Attached is a patch which enables jumbo frames on DS2104x based boards.
And then I forgot to include the patch. :-(
Regards,
Rask Ingemann Lambertsen
[-- Attachment #2: de2104x-mtu.patch --]
[-- Type: text/plain, Size: 6622 bytes --]
--- linux-2.6.0/drivers/net/tulip/de2104x.c-før-mtu Sun Dec 21 14:31:04 2003
+++ linux-2.6.0/drivers/net/tulip/de2104x.c Mon Jan 5 02:01:15 2004
@@ -19,7 +19,6 @@
like dl2k.c/sundance.c
* Constants (module parms?) for Rx work limit
* Complete reset on PciErr
- * Jumbo frames / dev->change_mtu
* Adjust Rx FIFO threshold and Max Rx DMA burst on Rx FIFO error
* Adjust Tx FIFO threshold and Max Tx DMA burst on Tx FIFO error
* Implement Tx software interrupt mitigation via
@@ -36,6 +35,7 @@
#include <linux/kernel.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
+#include <linux/if_vlan.h>
#include <linux/init.h>
#include <linux/pci.h>
#include <linux/delay.h>
@@ -67,11 +67,15 @@ static int debug = -1;
MODULE_PARM (debug, "i");
MODULE_PARM_DESC (debug, "de2104x bitmapped message enable number");
+/* Each descriptor has two buffers. */
+#define DESC_BUF_SZ_MAX 2044
+#define PKT_BUF_SZ_MAX 4088 /* Maximum Rx buffer size. */
+
/* Set the copy breakpoint for the copy-only-tiny-buffer Rx structure. */
#if defined(__alpha__) || defined(__arm__) || defined(__hppa__) \
|| defined(__sparc_) || defined(__ia64__) \
|| defined(__sh__) || defined(__mips__)
-static int rx_copybreak = 1518;
+static int rx_copybreak = PKT_BUF_SZ_MAX;
#else
static int rx_copybreak = 100;
#endif
@@ -356,12 +360,12 @@ static const char * const media_name[DE_
* TP AUTO(unused), BNC(unused), AUI, TP, TP FD*/
static u16 t21040_csr13[] = { 0, 0, 0x8F09, 0x8F01, 0x8F01, };
static u16 t21040_csr14[] = { 0, 0, 0x0705, 0xFFFF, 0xFFFD, };
-static u16 t21040_csr15[] = { 0, 0, 0x0006, 0x0000, 0x0000, };
+static u16 t21040_csr15[] = { 0, 0, 0x0017, 0x0011, 0x0011, };
/* 21041 transceiver register settings: TP AUTO, BNC, AUI, TP, TP FD*/
static u16 t21041_csr13[] = { 0xEF01, 0xEF09, 0xEF09, 0xEF01, 0xEF09, };
static u16 t21041_csr14[] = { 0xFFFF, 0xF7FD, 0xF7FD, 0x6F3F, 0x6F3D, };
-static u16 t21041_csr15[] = { 0x0008, 0x0006, 0x000E, 0x0008, 0x0008, };
+static u16 t21041_csr15[] = { 0x0019, 0x0017, 0x001F, 0x0019, 0x0019, };
static inline unsigned long
@@ -374,6 +378,12 @@ msec_to_jiffies(unsigned long ms)
#define dr32(reg) readl(de->regs + (reg))
#define dw32(reg,val) writel((val), de->regs + (reg))
+static inline u32 opts2_sizes (uint total_size)
+{
+ if (total_size <= DESC_BUF_SZ_MAX)
+ return (total_size);
+ return (((total_size - DESC_BUF_SZ_MAX) << 11) | DESC_BUF_SZ_MAX);
+}
static void de_rx_err_acct (struct de_private *de, unsigned rx_tail,
u32 status, u32 len)
@@ -422,7 +432,9 @@ static void de_rx (struct de_private *de
if (status & DescOwn)
break;
- len = ((status >> 16) & 0x7ff) - 4;
+ len = ((status >> 16) & 0x3fff) - 4;
+ if ((len <= 1514) && (status & RxErrLong))
+ len += 2048;
mapping = de->rx_skb[rx_tail].mapping;
if (unlikely(drop)) {
@@ -430,7 +442,7 @@ static void de_rx (struct de_private *de
goto rx_next;
}
- if (unlikely((status & 0x38008300) != 0x0300)) {
+ if (unlikely((status & 0x38004b53) != 0x0300)) {
de_rx_err_acct(de, rx_tail, status, len);
goto rx_next;
}
@@ -483,11 +495,13 @@ static void de_rx (struct de_private *de
rx_next:
de->rx_ring[rx_tail].opts1 = cpu_to_le32(DescOwn);
if (rx_tail == (DE_RX_RING_SIZE - 1))
- de->rx_ring[rx_tail].opts2 =
- cpu_to_le32(RingEnd | de->rx_buf_sz);
+ de->rx_ring[rx_tail].opts2 = cpu_to_le32(
+ RingEnd | opts2_sizes (de->rx_buf_sz));
else
- de->rx_ring[rx_tail].opts2 = cpu_to_le32(de->rx_buf_sz);
+ de->rx_ring[rx_tail].opts2 = cpu_to_le32(
+ opts2_sizes (de->rx_buf_sz));
de->rx_ring[rx_tail].addr1 = cpu_to_le32(mapping);
+ de->rx_ring[rx_tail].addr2 = cpu_to_le32(mapping + DESC_BUF_SZ_MAX);
rx_tail = NEXT_RX(rx_tail);
}
@@ -632,9 +646,10 @@ static int de_start_xmit (struct sk_buff
flags |= RingEnd;
if (!tx_free || (tx_free == (DE_TX_RING_SIZE / 2)))
flags |= TxSwInt;
- flags |= len;
+ flags |= opts2_sizes (len);
txd->opts2 = cpu_to_le32(flags);
txd->addr1 = cpu_to_le32(mapping);
+ txd->addr2 = cpu_to_le32(mapping + DESC_BUF_SZ_MAX);
de->tx_skb[entry].skb = skb;
de->tx_skb[entry].mapping = mapping;
@@ -770,6 +785,7 @@ static void __de_set_rx_mode (struct net
dummy_txd->opts2 = (entry == (DE_TX_RING_SIZE - 1)) ?
cpu_to_le32(RingEnd) : 0;
dummy_txd->addr1 = 0;
+ dummy_txd->addr2 = 0;
/* Must set DescOwned later to avoid race with chip */
@@ -788,6 +804,7 @@ static void __de_set_rx_mode (struct net
else
txd->opts2 = cpu_to_le32(SetupFrame | sizeof (de->setup_frame));
txd->addr1 = cpu_to_le32(mapping);
+ txd->addr2 = cpu_to_le32(0);
wmb();
txd->opts1 = cpu_to_le32(DescOwn);
@@ -1277,7 +1294,9 @@ static int de_init_hw (struct de_private
static int de_refill_rx (struct de_private *de)
{
unsigned i;
+ u32 opts2;
+ opts2 = opts2_sizes (de->rx_buf_sz);
for (i = 0; i < DE_RX_RING_SIZE; i++) {
struct sk_buff *skb;
@@ -1294,11 +1313,11 @@ static int de_refill_rx (struct de_priva
de->rx_ring[i].opts1 = cpu_to_le32(DescOwn);
if (i == (DE_RX_RING_SIZE - 1))
de->rx_ring[i].opts2 =
- cpu_to_le32(RingEnd | de->rx_buf_sz);
+ cpu_to_le32(RingEnd | opts2);
else
- de->rx_ring[i].opts2 = cpu_to_le32(de->rx_buf_sz);
+ de->rx_ring[i].opts2 = cpu_to_le32(opts2);
de->rx_ring[i].addr1 = cpu_to_le32(de->rx_skb[i].mapping);
- de->rx_ring[i].addr2 = 0;
+ de->rx_ring[i].addr2 = cpu_to_le32(de->rx_skb[i].mapping + DESC_BUF_SZ_MAX);
}
return 0;
@@ -1386,6 +1405,8 @@ static int de_open (struct net_device *d
printk(KERN_DEBUG "%s: enabling interface\n", dev->name);
de->rx_buf_sz = (dev->mtu <= 1500 ? PKT_BUF_SZ : dev->mtu + 32);
+ if (de->rx_buf_sz > PKT_BUF_SZ_MAX)
+ de->rx_buf_sz = PKT_BUF_SZ_MAX;
rc = de_alloc_rings(de);
if (rc) {
@@ -1476,6 +1497,18 @@ static void de_tx_timeout (struct net_de
netif_wake_queue(dev);
}
+static int de_change_mtu (struct net_device *dev, int mtu)
+{
+ if (netif_running (dev))
+ return (-EBUSY);
+
+ if (mtu < 0 || mtu > PKT_BUF_SZ_MAX - VLAN_ETH_HLEN - 4)
+ return (-EINVAL);
+
+ dev->mtu = mtu;
+ return (0);
+}
+
static void __de_get_regs(struct de_private *de, u8 *buf)
{
int i;
@@ -1980,6 +2013,7 @@ static int __devinit de_init_one (struct
dev->ethtool_ops = &de_ethtool_ops;
dev->tx_timeout = de_tx_timeout;
dev->watchdog_timeo = TX_TIMEOUT;
+ dev->change_mtu = de_change_mtu;
dev->irq = pdev->irq;
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2004-01-10 13:47 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2004-01-09 23:33 [PATCH] [EXPERIMENTAL] 2.6: de2104x.c jumbo frames, take two Rask Ingemann Lambertsen
2004-01-10 13:47 ` Rask Ingemann Lambertsen
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).