* [PATCH 2/3] r8169: Large Send enablement
@ 2004-11-02 18:03 Jon Mason
2004-11-02 19:11 ` Francois Romieu
2004-11-02 19:50 ` [PATCH 2/3] r8169: Large Send enablement Jeff Garzik
0 siblings, 2 replies; 7+ messages in thread
From: Jon Mason @ 2004-11-02 18:03 UTC (permalink / raw)
To: Francois Romieu; +Cc: netdev
[-- Attachment #1: Type: text/plain, Size: 3442 bytes --]
This patch enables driver support of MTUs greater than 1500. Though the
adapter documentation says that maximum MTU is 16k, the largest packet I
could send was 7440. So, I am setting that as the max mtu until I can figure
out why the adapter misbehaves with packets larger than 7440.
I have tested this code on ppc64 and x86_64.
Signed-off-by: Jon Mason <jdmason@us.ibm.com>
--- r8169-post-patch1.c 2004-11-02 10:37:18.190155864 -0600
+++ r8169.c 2004-11-02 10:37:31.035203120 -0600
@@ -114,14 +114,13 @@ static int multicast_filter_limit = 32;
#define RX_DMA_BURST 6 /* Maximum PCI burst, '6' is 1024 */
#define TX_DMA_BURST 6 /* Maximum PCI burst, '6' is 1024 */
#define EarlyTxThld 0x3F /* 0x3F means NO early transmit */
-#define RxPacketMaxSize 0x0800 /* Maximum size supported is 16K-1 */
+#define RxPacketMaxSize 0x3FE8 /* Maximum size supported is
16K-(1+Header+CRC+VLAN ) */
#define InterFrameGap 0x03 /* 3 means InterFrameGap = the shortest one */
#define R8169_REGS_SIZE 256
#define R8169_NAPI_WEIGHT 64
#define NUM_TX_DESC 64 /* Number of Tx descriptor registers */
#define NUM_RX_DESC 256 /* Number of Rx descriptor registers */
-#define RX_BUF_SIZE 1536 /* Rx Buffer size */
#define R8169_TX_RING_BYTES (NUM_TX_DESC * sizeof(struct TxDesc))
#define R8169_RX_RING_BYTES (NUM_RX_DESC * sizeof(struct RxDesc))
@@ -427,6 +426,8 @@ static void rtl8169_tx_timeout(struct ne
static struct net_device_stats *rtl8169_get_stats(struct net_device *netdev);
static int rtl8169_rx_interrupt(struct net_device *, struct rtl8169_private
*,
void __iomem *);
+static int rtl8169_change_mtu(struct net_device *netdev, int new_mtu);
+
#ifdef CONFIG_R8169_NAPI
static int rtl8169_poll(struct net_device *dev, int *budget);
#endif
@@ -1239,7 +1240,7 @@ rtl8169_init_board(struct pci_dev *pdev,
}
tp->chipset = i;
- tp->rx_buf_sz = RX_BUF_SIZE;
+ tp->rx_buf_sz = dev->mtu + ETH_HLEN + 8;
*ioaddr_out = ioaddr;
*dev_out = dev;
@@ -1322,6 +1323,7 @@ rtl8169_init_one(struct pci_dev *pdev, c
dev->watchdog_timeo = RTL8169_TX_TIMEOUT;
dev->irq = pdev->irq;
dev->base_addr = (unsigned long) ioaddr;
+ dev->change_mtu = rtl8169_change_mtu;
#ifdef CONFIG_R8169_NAPI
dev->poll = rtl8169_poll;
@@ -1536,8 +1538,8 @@ rtl8169_hw_start(struct net_device *dev)
RTL_W8(ChipCmd, CmdTxEnb | CmdRxEnb);
RTL_W8(EarlyTxThres, EarlyTxThld);
- // For gigabit rtl8169
- RTL_W16(RxMaxSize, RxPacketMaxSize);
+ // For gigabit rtl8169, MTU + header + CRC + VLAN
+ RTL_W16(RxMaxSize, tp->rx_buf_sz);
// Set Rx Config register
i = rtl8169_rx_config |
@@ -1578,6 +1580,24 @@ rtl8169_hw_start(struct net_device *dev)
netif_start_queue(dev);
}
+static int rtl8169_change_mtu(struct net_device *dev, int new_mtu)
+{
+ struct rtl8169_private *tp = netdev_priv(dev);
+
+ if (new_mtu < ETH_ZLEN || new_mtu > 7400)
+ return -EINVAL;
+
+ if (netif_running(dev))
+ rtl8169_close(dev);
+
+ dev->mtu = new_mtu;
+ tp->rx_buf_sz = new_mtu + ETH_HLEN + 8;
+
+ rtl8169_open(dev);
+
+ return 0;
+}
+
static inline void rtl8169_make_unusable_by_asic(struct RxDesc *desc)
{
desc->addr = 0x0badbadbadbadbadull;
[-- Attachment #2: r8169-large-send-2.patch --]
[-- Type: text/x-diff, Size: 2760 bytes --]
--- r8169-post-patch1.c 2004-11-02 10:37:18.190155864 -0600
+++ r8169.c 2004-11-02 10:37:31.035203120 -0600
@@ -114,14 +114,13 @@ static int multicast_filter_limit = 32;
#define RX_DMA_BURST 6 /* Maximum PCI burst, '6' is 1024 */
#define TX_DMA_BURST 6 /* Maximum PCI burst, '6' is 1024 */
#define EarlyTxThld 0x3F /* 0x3F means NO early transmit */
-#define RxPacketMaxSize 0x0800 /* Maximum size supported is 16K-1 */
+#define RxPacketMaxSize 0x3FE8 /* Maximum size supported is 16K-(1+Header+CRC+VLAN ) */
#define InterFrameGap 0x03 /* 3 means InterFrameGap = the shortest one */
#define R8169_REGS_SIZE 256
#define R8169_NAPI_WEIGHT 64
#define NUM_TX_DESC 64 /* Number of Tx descriptor registers */
#define NUM_RX_DESC 256 /* Number of Rx descriptor registers */
-#define RX_BUF_SIZE 1536 /* Rx Buffer size */
#define R8169_TX_RING_BYTES (NUM_TX_DESC * sizeof(struct TxDesc))
#define R8169_RX_RING_BYTES (NUM_RX_DESC * sizeof(struct RxDesc))
@@ -427,6 +426,8 @@ static void rtl8169_tx_timeout(struct ne
static struct net_device_stats *rtl8169_get_stats(struct net_device *netdev);
static int rtl8169_rx_interrupt(struct net_device *, struct rtl8169_private *,
void __iomem *);
+static int rtl8169_change_mtu(struct net_device *netdev, int new_mtu);
+
#ifdef CONFIG_R8169_NAPI
static int rtl8169_poll(struct net_device *dev, int *budget);
#endif
@@ -1239,7 +1240,7 @@ rtl8169_init_board(struct pci_dev *pdev,
}
tp->chipset = i;
- tp->rx_buf_sz = RX_BUF_SIZE;
+ tp->rx_buf_sz = dev->mtu + ETH_HLEN + 8;
*ioaddr_out = ioaddr;
*dev_out = dev;
@@ -1322,6 +1323,7 @@ rtl8169_init_one(struct pci_dev *pdev, c
dev->watchdog_timeo = RTL8169_TX_TIMEOUT;
dev->irq = pdev->irq;
dev->base_addr = (unsigned long) ioaddr;
+ dev->change_mtu = rtl8169_change_mtu;
#ifdef CONFIG_R8169_NAPI
dev->poll = rtl8169_poll;
@@ -1536,8 +1538,8 @@ rtl8169_hw_start(struct net_device *dev)
RTL_W8(ChipCmd, CmdTxEnb | CmdRxEnb);
RTL_W8(EarlyTxThres, EarlyTxThld);
- // For gigabit rtl8169
- RTL_W16(RxMaxSize, RxPacketMaxSize);
+ // For gigabit rtl8169, MTU + header + CRC + VLAN
+ RTL_W16(RxMaxSize, tp->rx_buf_sz);
// Set Rx Config register
i = rtl8169_rx_config |
@@ -1578,6 +1580,24 @@ rtl8169_hw_start(struct net_device *dev)
netif_start_queue(dev);
}
+static int rtl8169_change_mtu(struct net_device *dev, int new_mtu)
+{
+ struct rtl8169_private *tp = netdev_priv(dev);
+
+ if (new_mtu < ETH_ZLEN || new_mtu > 7400)
+ return -EINVAL;
+
+ if (netif_running(dev))
+ rtl8169_close(dev);
+
+ dev->mtu = new_mtu;
+ tp->rx_buf_sz = new_mtu + ETH_HLEN + 8;
+
+ rtl8169_open(dev);
+
+ return 0;
+}
+
static inline void rtl8169_make_unusable_by_asic(struct RxDesc *desc)
{
desc->addr = 0x0badbadbadbadbadull;
^ permalink raw reply [flat|nested] 7+ messages in thread* Re: [PATCH 2/3] r8169: Large Send enablement 2004-11-02 18:03 [PATCH 2/3] r8169: Large Send enablement Jon Mason @ 2004-11-02 19:11 ` Francois Romieu 2004-11-04 0:16 ` Jon Mason 2004-11-04 0:17 ` [PATCH] r8169: Large Send enablement, part 2 Jon Mason 2004-11-02 19:50 ` [PATCH 2/3] r8169: Large Send enablement Jeff Garzik 1 sibling, 2 replies; 7+ messages in thread From: Francois Romieu @ 2004-11-02 19:11 UTC (permalink / raw) To: Jon Mason; +Cc: netdev, jgarzik Jon Mason <jdmason@us.ibm.com> : [...] > @@ -1578,6 +1580,24 @@ rtl8169_hw_start(struct net_device *dev) > netif_start_queue(dev); > } > > +static int rtl8169_change_mtu(struct net_device *dev, int new_mtu) > +{ > + struct rtl8169_private *tp = netdev_priv(dev); > + > + if (new_mtu < ETH_ZLEN || new_mtu > 7400) > + return -EINVAL; > + > + if (netif_running(dev)) > + rtl8169_close(dev); > + > + dev->mtu = new_mtu; > + tp->rx_buf_sz = new_mtu + ETH_HLEN + 8; > + > + rtl8169_open(dev); > + > + return 0; > +} > + Ok. Powow: - rtl8169_close() is not protected as if it was issued during dev->close. It races with the irq handler. - I see no reason why the state of the device should change if the device was not up. Use the tool of your choice to correct me if I am wrong. - If rtl8169_open() fails [*] when the device was previously up, the driver could/should try to recover. Untested example below to clarify. [*] page allocation failure, bigger mtu/rx buffers -> I feel moderately confortable. diff -puN drivers/net/r8169.c~r8169-240 drivers/net/r8169.c --- linux-2.6.9/drivers/net/r8169.c~r8169-240 2004-10-21 21:55:45.000000000 +0200 +++ linux-2.6.9-fr/drivers/net/r8169.c 2004-11-01 23:10:25.000000000 +0100 @@ -120,6 +120,8 @@ static int multicast_filter_limit = 32; #define RX_BUF_SIZE 1536 /* Rx Buffer size */ #define R8169_TX_RING_BYTES (NUM_TX_DESC * sizeof(struct TxDesc)) #define R8169_RX_RING_BYTES (NUM_RX_DESC * sizeof(struct RxDesc)) +#define R8169_MIN_MTU 8 +#define R8169_MAX_MTU ((2 << 14) - 1) #define RTL8169_TX_TIMEOUT (6*HZ) #define RTL8169_PHY_TIMEOUT (10*HZ) @@ -412,6 +414,7 @@ MODULE_PARM_DESC(use_dac, "Enable PCI DA MODULE_LICENSE("GPL"); static int rtl8169_open(struct net_device *dev); +static int rtl8169_change_mtu(struct net_device *dev, int new_mtu); static int rtl8169_start_xmit(struct sk_buff *skb, struct net_device *dev); static irqreturn_t rtl8169_interrupt(int irq, void *dev_instance, struct pt_regs *regs); @@ -1314,6 +1317,7 @@ rtl8169_init_one(struct pci_dev *pdev, c SET_ETHTOOL_OPS(dev, &rtl8169_ethtool_ops); dev->stop = rtl8169_close; dev->tx_timeout = rtl8169_tx_timeout; + dev->change_mtu = rtl8169_change_mtu; dev->set_multicast_list = rtl8169_set_rx_mode; dev->watchdog_timeo = RTL8169_TX_TIMEOUT; dev->irq = pdev->irq; @@ -1533,7 +1537,7 @@ rtl8169_hw_start(struct net_device *dev) RTL_W8(EarlyTxThres, EarlyTxThld); // For gigabit rtl8169 - RTL_W16(RxMaxSize, RxPacketMaxSize); + RTL_W16(RxMaxSize, tp->rx_buf_sz); // Set Rx Config register i = rtl8169_rx_config | @@ -1738,6 +1742,26 @@ static void rtl8169_schedule_work(struct schedule_delayed_work(&tp->task, 4); } +static void __rtl8169_kick(struct net_device *dev) +{ + rtl8169_hw_start(dev); + netif_poll_enable(dev); + netif_wake_queue(dev); + set_bit(__LINK_STATE_START, &dev->state); +} + +static void rtl8169_refill_task(void *_data) +{ + struct net_device *dev = _data; + int err; + + err = rtl8169_init_ring(dev); + if (err < 0) + rtl8169_schedule_work(dev, rtl8169_refill_task); + else if (netif_queue_stopped(dev)) + __rtl8169_kick(dev); +} + static void rtl8169_wait_for_quiescence(struct net_device *dev) { synchronize_irq(dev->irq); @@ -2223,6 +2247,72 @@ out: return IRQ_RETVAL(handled); } +static int rtl8169_set_rxbufsize(struct rtl8169_private *tp, int mtu) +{ + if (mtu < R8169_MIN_MTU || mtu > R8169_MAX_MTU) + return -EINVAL; + + tp->rx_buf_sz = mtu; + if (mtu > ETH_DATA_LEN) { + /* MTU + ethernet header + FCS + optional VLAN tag */ + tp->rx_buf_sz += ETH_HLEN + 8; + } + return 0; +} + + +static int rtl8169_change_mtu(struct net_device *dev, int new_mtu) +{ + struct rtl8169_private *tp = netdev_priv(dev); + struct TxDesc *txd = tp->TxDescArray; + void *ioaddr = tp->mmio_addr; + int ret, i; + + ret = rtl8169_set_rxbufsize(tp, new_mtu); + if (ret < 0) + goto out; + + if (!netif_running(dev)) + goto out; + + printk(KERN_DEBUG "%s: Tx/Rx activity going down!\n", dev->name); + RTL_W8(ChipCmd, 0x00); + RTL_R8(ChipCmd); + + flush_scheduled_work(); + + netif_poll_disable(dev); + + RTL_W16(IntrMask, 0x0000); + RTL_R16(IntrMask); + + /* A bit incestuous */ + clear_bit(__LINK_STATE_START, &dev->state); + + synchronize_irq(dev->irq); + + netif_stop_queue(dev); + + /* + * At this point we do not bother with the irq/napi handlers + * any more. Tx thread may lurk. + */ + for (i = 0; i < NUM_TX_DESC; i++, txd++) + txd->opts1 = le32_to_cpu(DescOwn); + + /* Give a racing hard_start_xmit a few cycles to complete. */ + set_current_state(TASK_UNINTERRUPTIBLE); + schedule_timeout(1); + + rtl8169_rx_clear(tp); + rtl8169_tx_clear(tp); + + rtl8169_refill_task(dev); + +out: + return ret; +} + #ifdef CONFIG_R8169_NAPI static int rtl8169_poll(struct net_device *dev, int *budget) { _ ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH 2/3] r8169: Large Send enablement 2004-11-02 19:11 ` Francois Romieu @ 2004-11-04 0:16 ` Jon Mason 2004-11-04 18:45 ` Francois Romieu 2004-11-04 0:17 ` [PATCH] r8169: Large Send enablement, part 2 Jon Mason 1 sibling, 1 reply; 7+ messages in thread From: Jon Mason @ 2004-11-04 0:16 UTC (permalink / raw) To: Francois Romieu; +Cc: netdev, jgarzik On Tuesday 02 November 2004 01:11 pm, Francois Romieu wrote: [...] > - If rtl8169_open() fails [*] when the device was previously up, the driver > could/should try to recover. I disagree. It should fail, complain loudly, and let the user try and fix it (or return it to the previous state). The code provided below will act like it is successful in changing the MTU, even if it hits an error and is in the process of recovering. This will cause more difficult to diagnose problems. > Untested example below to clarify. > > [*] page allocation failure, bigger mtu/rx buffers -> I feel moderately > confortable. > > > diff -puN drivers/net/r8169.c~r8169-240 drivers/net/r8169.c > --- linux-2.6.9/drivers/net/r8169.c~r8169-240 2004-10-21 21:55:45.000000000 > +0200 +++ linux-2.6.9-fr/drivers/net/r8169.c 2004-11-01 23:10:25.000000000 > +0100 @@ -120,6 +120,8 @@ static int multicast_filter_limit = 32; > #define RX_BUF_SIZE 1536 /* Rx Buffer size */ > #define R8169_TX_RING_BYTES (NUM_TX_DESC * sizeof(struct TxDesc)) > #define R8169_RX_RING_BYTES (NUM_RX_DESC * sizeof(struct RxDesc)) > +#define R8169_MIN_MTU 8 > +#define R8169_MAX_MTU ((2 << 14) - 1) [...] > @@ -2223,6 +2247,72 @@ out: > return IRQ_RETVAL(handled); > } > > +static int rtl8169_set_rxbufsize(struct rtl8169_private *tp, int mtu) > +{ > + if (mtu < R8169_MIN_MTU || mtu > R8169_MAX_MTU) Is 8 really a valid MTU? -- Jon Mason jdmason@us.ibm.com ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH 2/3] r8169: Large Send enablement 2004-11-04 0:16 ` Jon Mason @ 2004-11-04 18:45 ` Francois Romieu 2004-11-05 5:50 ` Jon Mason 0 siblings, 1 reply; 7+ messages in thread From: Francois Romieu @ 2004-11-04 18:45 UTC (permalink / raw) To: Jon Mason; +Cc: netdev, jgarzik Jon Mason <jdmason@us.ibm.com> : > On Tuesday 02 November 2004 01:11 pm, Francois Romieu wrote: > [...] > > - If rtl8169_open() fails [*] when the device was previously up, the driver > > could/should try to recover. > > I disagree. It should fail, complain loudly, and let the user try and fix it > (or return it to the previous state). The code provided below will act like Mmmm... Actually both patches try to paper over the real issue: the driver should reserve the ressources it needs for the change of mtu first. Ok, I'll take the patch provided I can't find anything badly racy in it and focus on the 8139C+/8169 merge. It has already been delayed for too long and it seems the right place to fix the aforementionned issue with style :o) -- Ueimor ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH 2/3] r8169: Large Send enablement 2004-11-04 18:45 ` Francois Romieu @ 2004-11-05 5:50 ` Jon Mason 0 siblings, 0 replies; 7+ messages in thread From: Jon Mason @ 2004-11-05 5:50 UTC (permalink / raw) To: Francois Romieu; +Cc: netdev, jgarzik On Thursday 04 November 2004 06:45 pm, Francois Romieu wrote: > Jon Mason <jdmason@us.ibm.com> : > > On Tuesday 02 November 2004 01:11 pm, Francois Romieu wrote: > > [...] > > > > > - If rtl8169_open() fails [*] when the device was previously up, the > > > driver could/should try to recover. > > > > I disagree. It should fail, complain loudly, and let the user try and > > fix it (or return it to the previous state). The code provided below > > will act like > > Mmmm... Actually both patches try to paper over the real issue: the driver > should reserve the resources it needs for the change of mtu first. Agreed. I did a quick look in the other drivers, and didn't find any drivers that handle this possibility. Most of them ignore the fact. This sounds like an open hole in all of the drivers. ^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH] r8169: Large Send enablement, part 2 2004-11-02 19:11 ` Francois Romieu 2004-11-04 0:16 ` Jon Mason @ 2004-11-04 0:17 ` Jon Mason 1 sibling, 0 replies; 7+ messages in thread From: Jon Mason @ 2004-11-04 0:17 UTC (permalink / raw) To: Francois Romieu; +Cc: netdev, jgarzik [-- Attachment #1: Type: text/plain, Size: 6406 bytes --] I have tried to address all of the issues with the previous large send patch in the following patch (and I have confirmed it works on ppc64). --- r8169.c.orig 2004-11-02 11:01:02.000000000 -0600 +++ r8169.c 2004-11-03 17:58:49.830373784 -0600 @@ -85,10 +85,14 @@ VERSION 1.6LK <2004/04/14> #define rtl8169_rx_skb netif_receive_skb #define rtl8169_rx_hwaccel_skb vlan_hwaccel_rx #define rtl8169_rx_quota(count, quota) min(count, quota) +#define rtl8169_poll_disable(dev) netif_poll_disable(dev) +#define rtl8169_poll_enable(dev) netif_poll_enable(dev) #else #define rtl8169_rx_skb netif_rx #define rtl8169_rx_hwaccel_skb vlan_hwaccel_receive_skb #define rtl8169_rx_quota(count, quota) count +#define rtl8169_poll_disable(dev) +#define rtl8169_poll_enable(dev) #endif /* media options */ @@ -112,14 +116,13 @@ static int multicast_filter_limit = 32; #define RX_DMA_BURST 6 /* Maximum PCI burst, '6' is 1024 */ #define TX_DMA_BURST 6 /* Maximum PCI burst, '6' is 1024 */ #define EarlyTxThld 0x3F /* 0x3F means NO early transmit */ -#define RxPacketMaxSize 0x0800 /* Maximum size supported is 16K-1 */ +#define RxPacketMaxSize 0x3FFE /* Maximum size supported is 16K-1 */ #define InterFrameGap 0x03 /* 3 means InterFrameGap = the shortest one */ #define R8169_REGS_SIZE 256 #define R8169_NAPI_WEIGHT 64 #define NUM_TX_DESC 64 /* Number of Tx descriptor registers */ #define NUM_RX_DESC 256 /* Number of Rx descriptor registers */ -#define RX_BUF_SIZE 1536 /* Rx Buffer size */ #define R8169_TX_RING_BYTES (NUM_TX_DESC * sizeof(struct TxDesc)) #define R8169_RX_RING_BYTES (NUM_RX_DESC * sizeof(struct RxDesc)) @@ -425,6 +428,9 @@ static void rtl8169_tx_timeout(struct ne static struct net_device_stats *rtl8169_get_stats(struct net_device *netdev); static int rtl8169_rx_interrupt(struct net_device *, struct rtl8169_private *, void __iomem *); +static int rtl8169_change_mtu(struct net_device *netdev, int new_mtu); +static int rtl8169_down(struct net_device *dev); + #ifdef CONFIG_R8169_NAPI static int rtl8169_poll(struct net_device *dev, int *budget); #endif @@ -1237,8 +1243,6 @@ rtl8169_init_board(struct pci_dev *pdev, } tp->chipset = i; - tp->rx_buf_sz = RX_BUF_SIZE; - *ioaddr_out = ioaddr; *dev_out = dev; out: @@ -1320,6 +1324,7 @@ rtl8169_init_one(struct pci_dev *pdev, c dev->watchdog_timeo = RTL8169_TX_TIMEOUT; dev->irq = pdev->irq; dev->base_addr = (unsigned long) ioaddr; + dev->change_mtu = rtl8169_change_mtu; #ifdef CONFIG_R8169_NAPI dev->poll = rtl8169_poll; @@ -1455,6 +1460,8 @@ rtl8169_open(struct net_device *dev) struct pci_dev *pdev = tp->pci_dev; int retval; + tp->rx_buf_sz = dev->mtu + ETH_HLEN + 8; + retval = request_irq(dev->irq, rtl8169_interrupt, SA_SHIRQ, dev->name, dev); if (retval < 0) @@ -1534,8 +1541,8 @@ rtl8169_hw_start(struct net_device *dev) RTL_W8(ChipCmd, CmdTxEnb | CmdRxEnb); RTL_W8(EarlyTxThres, EarlyTxThld); - // For gigabit rtl8169 - RTL_W16(RxMaxSize, RxPacketMaxSize); + // For gigabit rtl8169, MTU + header + CRC + VLAN + RTL_W16(RxMaxSize, tp->rx_buf_sz); // Set Rx Config register i = rtl8169_rx_config | @@ -1576,6 +1583,36 @@ rtl8169_hw_start(struct net_device *dev) netif_start_queue(dev); } +static int rtl8169_change_mtu(struct net_device *dev, int new_mtu) +{ + struct rtl8169_private *tp = netdev_priv(dev); + int retval; + + if (new_mtu < ETH_ZLEN || new_mtu > RxPacketMaxSize) + return -EINVAL; + + dev->mtu = new_mtu; + + if (!netif_running(dev)) + return 0; + + rtl8169_down(dev); + + tp->rx_buf_sz = new_mtu + ETH_HLEN + 8; + + retval = rtl8169_init_ring(dev); + if (retval < 0) + return retval; + + rtl8169_hw_start(dev); + + rtl8169_poll_enable(dev); + + rtl8169_request_timer(dev); + + return 0; +} + static inline void rtl8169_make_unusable_by_asic(struct RxDesc *desc) { desc->addr = 0x0badbadbadbadbadull; @@ -1745,7 +1782,7 @@ static void rtl8169_wait_for_quiescence( synchronize_irq(dev->irq); /* Wait for any pending NAPI task to complete */ - netif_poll_disable(dev); + rtl8169_poll_disable(dev); } static void rtl8169_reinit_task(void *_data) @@ -1785,6 +1822,7 @@ static void rtl8169_reset_task(void *_da rtl8169_init_ring_indexes(tp); rtl8169_hw_start(dev); netif_wake_queue(dev); + rtl8169_poll_enable(dev); } else { if (net_ratelimit()) { printk(PFX KERN_EMERG "%s: Rx buffers shortage\n", @@ -2255,19 +2293,17 @@ static int rtl8169_poll(struct net_devic } #endif -static int -rtl8169_close(struct net_device *dev) +static int rtl8169_down(struct net_device *dev) { struct rtl8169_private *tp = netdev_priv(dev); - struct pci_dev *pdev = tp->pci_dev; void __iomem *ioaddr = tp->mmio_addr; + rtl8169_delete_timer(dev); + netif_stop_queue(dev); flush_scheduled_work(); - rtl8169_delete_timer(dev); - spin_lock_irq(&tp->lock); /* Stop the chip's Tx and Rx DMA processes. */ @@ -2282,14 +2318,30 @@ rtl8169_close(struct net_device *dev) spin_unlock_irq(&tp->lock); - free_irq(dev->irq, dev); + synchronize_irq(dev->irq); + + rtl8169_poll_disable(dev); - netif_poll_disable(dev); + /* Give a racing hard_start_xmit a few cycles to complete. */ + set_current_state(TASK_UNINTERRUPTIBLE); + schedule_timeout(1); rtl8169_tx_clear(tp); rtl8169_rx_clear(tp); + return 0; +} + +static int rtl8169_close(struct net_device *dev) +{ + struct rtl8169_private *tp = netdev_priv(dev); + struct pci_dev *pdev = tp->pci_dev; + + rtl8169_down(dev); + + free_irq(dev->irq, dev); + pci_free_consistent(pdev, R8169_RX_RING_BYTES, tp->RxDescArray, tp->RxPhyAddr); pci_free_consistent(pdev, R8169_TX_RING_BYTES, tp->TxDescArray, [-- Attachment #2: r8169-large-send.patch --] [-- Type: text/x-diff, Size: 5540 bytes --] --- r8169.c.orig 2004-11-02 11:01:02.000000000 -0600 +++ r8169.c 2004-11-03 17:58:49.830373784 -0600 @@ -85,10 +85,14 @@ VERSION 1.6LK <2004/04/14> #define rtl8169_rx_skb netif_receive_skb #define rtl8169_rx_hwaccel_skb vlan_hwaccel_rx #define rtl8169_rx_quota(count, quota) min(count, quota) +#define rtl8169_poll_disable(dev) netif_poll_disable(dev) +#define rtl8169_poll_enable(dev) netif_poll_enable(dev) #else #define rtl8169_rx_skb netif_rx #define rtl8169_rx_hwaccel_skb vlan_hwaccel_receive_skb #define rtl8169_rx_quota(count, quota) count +#define rtl8169_poll_disable(dev) +#define rtl8169_poll_enable(dev) #endif /* media options */ @@ -112,14 +116,13 @@ static int multicast_filter_limit = 32; #define RX_DMA_BURST 6 /* Maximum PCI burst, '6' is 1024 */ #define TX_DMA_BURST 6 /* Maximum PCI burst, '6' is 1024 */ #define EarlyTxThld 0x3F /* 0x3F means NO early transmit */ -#define RxPacketMaxSize 0x0800 /* Maximum size supported is 16K-1 */ +#define RxPacketMaxSize 0x3FFE /* Maximum size supported is 16K-1 */ #define InterFrameGap 0x03 /* 3 means InterFrameGap = the shortest one */ #define R8169_REGS_SIZE 256 #define R8169_NAPI_WEIGHT 64 #define NUM_TX_DESC 64 /* Number of Tx descriptor registers */ #define NUM_RX_DESC 256 /* Number of Rx descriptor registers */ -#define RX_BUF_SIZE 1536 /* Rx Buffer size */ #define R8169_TX_RING_BYTES (NUM_TX_DESC * sizeof(struct TxDesc)) #define R8169_RX_RING_BYTES (NUM_RX_DESC * sizeof(struct RxDesc)) @@ -425,6 +428,9 @@ static void rtl8169_tx_timeout(struct ne static struct net_device_stats *rtl8169_get_stats(struct net_device *netdev); static int rtl8169_rx_interrupt(struct net_device *, struct rtl8169_private *, void __iomem *); +static int rtl8169_change_mtu(struct net_device *netdev, int new_mtu); +static int rtl8169_down(struct net_device *dev); + #ifdef CONFIG_R8169_NAPI static int rtl8169_poll(struct net_device *dev, int *budget); #endif @@ -1237,8 +1243,6 @@ rtl8169_init_board(struct pci_dev *pdev, } tp->chipset = i; - tp->rx_buf_sz = RX_BUF_SIZE; - *ioaddr_out = ioaddr; *dev_out = dev; out: @@ -1320,6 +1324,7 @@ rtl8169_init_one(struct pci_dev *pdev, c dev->watchdog_timeo = RTL8169_TX_TIMEOUT; dev->irq = pdev->irq; dev->base_addr = (unsigned long) ioaddr; + dev->change_mtu = rtl8169_change_mtu; #ifdef CONFIG_R8169_NAPI dev->poll = rtl8169_poll; @@ -1455,6 +1460,8 @@ rtl8169_open(struct net_device *dev) struct pci_dev *pdev = tp->pci_dev; int retval; + tp->rx_buf_sz = dev->mtu + ETH_HLEN + 8; + retval = request_irq(dev->irq, rtl8169_interrupt, SA_SHIRQ, dev->name, dev); if (retval < 0) @@ -1534,8 +1541,8 @@ rtl8169_hw_start(struct net_device *dev) RTL_W8(ChipCmd, CmdTxEnb | CmdRxEnb); RTL_W8(EarlyTxThres, EarlyTxThld); - // For gigabit rtl8169 - RTL_W16(RxMaxSize, RxPacketMaxSize); + // For gigabit rtl8169, MTU + header + CRC + VLAN + RTL_W16(RxMaxSize, tp->rx_buf_sz); // Set Rx Config register i = rtl8169_rx_config | @@ -1576,6 +1583,36 @@ rtl8169_hw_start(struct net_device *dev) netif_start_queue(dev); } +static int rtl8169_change_mtu(struct net_device *dev, int new_mtu) +{ + struct rtl8169_private *tp = netdev_priv(dev); + int retval; + + if (new_mtu < ETH_ZLEN || new_mtu > RxPacketMaxSize) + return -EINVAL; + + dev->mtu = new_mtu; + + if (!netif_running(dev)) + return 0; + + rtl8169_down(dev); + + tp->rx_buf_sz = new_mtu + ETH_HLEN + 8; + + retval = rtl8169_init_ring(dev); + if (retval < 0) + return retval; + + rtl8169_hw_start(dev); + + rtl8169_poll_enable(dev); + + rtl8169_request_timer(dev); + + return 0; +} + static inline void rtl8169_make_unusable_by_asic(struct RxDesc *desc) { desc->addr = 0x0badbadbadbadbadull; @@ -1745,7 +1782,7 @@ static void rtl8169_wait_for_quiescence( synchronize_irq(dev->irq); /* Wait for any pending NAPI task to complete */ - netif_poll_disable(dev); + rtl8169_poll_disable(dev); } static void rtl8169_reinit_task(void *_data) @@ -1785,6 +1822,7 @@ static void rtl8169_reset_task(void *_da rtl8169_init_ring_indexes(tp); rtl8169_hw_start(dev); netif_wake_queue(dev); + rtl8169_poll_enable(dev); } else { if (net_ratelimit()) { printk(PFX KERN_EMERG "%s: Rx buffers shortage\n", @@ -2255,19 +2293,17 @@ static int rtl8169_poll(struct net_devic } #endif -static int -rtl8169_close(struct net_device *dev) +static int rtl8169_down(struct net_device *dev) { struct rtl8169_private *tp = netdev_priv(dev); - struct pci_dev *pdev = tp->pci_dev; void __iomem *ioaddr = tp->mmio_addr; + rtl8169_delete_timer(dev); + netif_stop_queue(dev); flush_scheduled_work(); - rtl8169_delete_timer(dev); - spin_lock_irq(&tp->lock); /* Stop the chip's Tx and Rx DMA processes. */ @@ -2282,14 +2318,30 @@ rtl8169_close(struct net_device *dev) spin_unlock_irq(&tp->lock); - free_irq(dev->irq, dev); + synchronize_irq(dev->irq); + + rtl8169_poll_disable(dev); - netif_poll_disable(dev); + /* Give a racing hard_start_xmit a few cycles to complete. */ + set_current_state(TASK_UNINTERRUPTIBLE); + schedule_timeout(1); rtl8169_tx_clear(tp); rtl8169_rx_clear(tp); + return 0; +} + +static int rtl8169_close(struct net_device *dev) +{ + struct rtl8169_private *tp = netdev_priv(dev); + struct pci_dev *pdev = tp->pci_dev; + + rtl8169_down(dev); + + free_irq(dev->irq, dev); + pci_free_consistent(pdev, R8169_RX_RING_BYTES, tp->RxDescArray, tp->RxPhyAddr); pci_free_consistent(pdev, R8169_TX_RING_BYTES, tp->TxDescArray, ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH 2/3] r8169: Large Send enablement 2004-11-02 18:03 [PATCH 2/3] r8169: Large Send enablement Jon Mason 2004-11-02 19:11 ` Francois Romieu @ 2004-11-02 19:50 ` Jeff Garzik 1 sibling, 0 replies; 7+ messages in thread From: Jeff Garzik @ 2004-11-02 19:50 UTC (permalink / raw) To: Jon Mason; +Cc: Francois Romieu, netdev Jon Mason wrote: > This patch enables driver support of MTUs greater than 1500. Though the > adapter documentation says that maximum MTU is 16k, the largest packet I > could send was 7440. So, I am setting that as the max mtu until I can figure > out why the adapter misbehaves with packets larger than 7440. this is dependent on hardware FIFO sizes... ^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2004-11-05 5:50 UTC | newest] Thread overview: 7+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2004-11-02 18:03 [PATCH 2/3] r8169: Large Send enablement Jon Mason 2004-11-02 19:11 ` Francois Romieu 2004-11-04 0:16 ` Jon Mason 2004-11-04 18:45 ` Francois Romieu 2004-11-05 5:50 ` Jon Mason 2004-11-04 0:17 ` [PATCH] r8169: Large Send enablement, part 2 Jon Mason 2004-11-02 19:50 ` [PATCH 2/3] r8169: Large Send enablement Jeff Garzik
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).