netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [RFC PATCH 1/2] smsc911x: add support for sh3 RX DMA
@ 2008-11-23 16:04 Steve Glendinning
  2008-11-23 16:04 ` [RFC PATCH 2/2] smsc911x: add support for sh3 TX DMA Steve Glendinning
  2008-11-24  3:42 ` [RFC PATCH 1/2] smsc911x: add support for sh3 RX DMA Paul Mundt
  0 siblings, 2 replies; 4+ messages in thread
From: Steve Glendinning @ 2008-11-23 16:04 UTC (permalink / raw)
  To: netdev; +Cc: linux-sh, Ian Saturley, Steve Glendinning

I've been working on adding DMA support to the smsc911x driver.  As this 
family of devices is non-pci, DMA transfers must be initiated and 
controlled by the host CPU.  Unfortunately this makes some of the code 
necessarily platform-specific.

This patch adds RX DMA support for the sh architecture.  Tested on 
SH7709S (sh3), where it gives a small (~10%) iperf tcp throughput 
increase.  DMA or PIO is selected at compile-time.

My first attempt stopped NAPI polling during a DMA transfer, then used 
DMA completion interrupts to pass the packet up and re-enable polling.
Obviously this defeats the interrupt-mitigation of NAPI, and on my test 
platform actually *reduced* performance!

This patch leaves NAPI polling enabled, so a later poll completes the 
transfer.  I'm concerned this is essentially busy-waiting on the 
transfer, but it does show a small performance gain.  Is this a good or 
bad idea?

I'd be interested to hear if anyone has advice on how to make this 
patch more generic.  There's definitely been interest from arm pxa
users in adding DMA, and some of this code must be re-usable for this.

Signed-off-by: Steve Glendinning <steve.glendinning@smsc.com>
---
 drivers/net/smsc911x.c   |  131 ++++++++++++++++++++++++++++++++++++++++++++++
 drivers/net/smsc911x.h   |    4 ++
 include/linux/smsc911x.h |    3 +
 3 files changed, 138 insertions(+), 0 deletions(-)

diff --git a/drivers/net/smsc911x.c b/drivers/net/smsc911x.c
index 4b8ff84..b3d9f9e 100644
--- a/drivers/net/smsc911x.c
+++ b/drivers/net/smsc911x.c
@@ -52,6 +52,11 @@
 #include <linux/smsc911x.h>
 #include "smsc911x.h"
 
+#ifdef SMSC_USE_SH_RX_DMA
+#include <asm/dma.h>
+#include <../arch/sh/drivers/dma/dma-sh.h>
+#endif
+
 #define SMSC_CHIPNAME		"smsc911x"
 #define SMSC_MDIONAME		"smsc911x-mdio"
 #define SMSC_DRV_VERSION	"2008-10-21"
@@ -116,6 +121,10 @@ struct smsc911x_data {
 	unsigned int clear_bits_mask;
 	unsigned int hashhi;
 	unsigned int hashlo;
+
+#ifdef SMSC_USE_SH_RX_DMA
+	struct sk_buff *rx_skb;
+#endif
 };
 
 /* The 16-bit access functions are significantly slower, due to the locking
@@ -962,12 +971,37 @@ smsc911x_rx_counterrors(struct net_device *dev, unsigned int rxstat)
 	}
 }
 
+#ifdef SMSC_USE_SH_RX_DMA
+static void smsc911x_set_rx_cfg_for_dma(struct smsc911x_data *pdata)
+{
+	/* set RX Data offset and end alignment for DMA transfers */
+	switch (dma_get_cache_alignment()) {
+	case 16:
+		smsc911x_reg_write(pdata, RX_CFG, 0x40000200);
+		break;
+
+	case 32:
+		smsc911x_reg_write(pdata, RX_CFG, 0x80001200);
+		break;
+
+	default:
+		BUG();
+		break;
+	}
+}
+#endif
+
 /* Quickly dumps bad packets */
 static void
 smsc911x_rx_fastforward(struct smsc911x_data *pdata, unsigned int pktbytes)
 {
 	unsigned int pktwords = (pktbytes + NET_IP_ALIGN + 3) >> 2;
 
+#ifdef SMSC_USE_SH_RX_DMA
+	/* Remove extra DMA padding */
+	smsc911x_reg_write(pdata, RX_CFG, NET_IP_ALIGN << 8);
+#endif
+
 	if (likely(pktwords >= 4)) {
 		unsigned int timeout = 500;
 		unsigned int val;
@@ -985,6 +1019,11 @@ smsc911x_rx_fastforward(struct smsc911x_data *pdata, unsigned int pktbytes)
 		while (pktwords--)
 			temp = smsc911x_reg_read(pdata, RX_DATA_FIFO);
 	}
+
+#ifdef SMSC_USE_SH_RX_DMA
+	/* restore RX Data offset and end alignment for DMA transfers */
+	smsc911x_set_rx_cfg_for_dma(pdata);
+#endif
 }
 
 /* NAPI poll function */
@@ -995,11 +1034,33 @@ static int smsc911x_poll(struct napi_struct *napi, int budget)
 	struct net_device *dev = pdata->dev;
 	int npackets = 0;
 
+#ifdef SMSC_USE_SH_RX_DMA
+	/* check for pending transfer */
+	if (pdata->rx_skb) {
+		/* return immediately if the transfer hasn't finished */
+		if (get_dma_residue(pdata->config.rx_dma_ch))
+			return npackets;
+
+		/* transfer is complete, pass packet up */
+		pdata->rx_skb->dev = pdata->dev;
+		pdata->rx_skb->protocol =
+			eth_type_trans(pdata->rx_skb, pdata->dev);
+		pdata->rx_skb->ip_summed = CHECKSUM_NONE;
+		netif_receive_skb(pdata->rx_skb);
+		pdata->rx_skb = 0;
+	}
+#endif
+
 	while (likely(netif_running(dev)) && (npackets < budget)) {
 		unsigned int pktlength;
 		unsigned int pktwords;
 		struct sk_buff *skb;
 		unsigned int rxstat = smsc911x_rx_get_rxstatus(pdata);
+#ifdef SMSC_USE_SH_RX_DMA
+		unsigned long physaddrfrom, physaddrto;
+		int cachebytes = dma_get_cache_alignment();
+		unsigned long alignmask = cachebytes - 1;
+#endif
 
 		if (!rxstat) {
 			unsigned int temp;
@@ -1018,7 +1079,13 @@ static int smsc911x_poll(struct napi_struct *napi, int budget)
 		npackets++;
 
 		pktlength = ((rxstat & 0x3FFF0000) >> 16);
+#ifdef SMSC_USE_SH_RX_DMA
+		pktwords = (pktlength + (cachebytes - 14) + cachebytes - 1) &
+			(~alignmask);
+#else
 		pktwords = (pktlength + NET_IP_ALIGN + 3) >> 2;
+#endif
+
 		smsc911x_rx_counterrors(dev, rxstat);
 
 		if (unlikely(rxstat & RX_STS_ES_)) {
@@ -1031,7 +1098,11 @@ static int smsc911x_poll(struct napi_struct *napi, int budget)
 			continue;
 		}
 
+#ifdef SMSC_USE_SH_RX_DMA
+		skb = netdev_alloc_skb(dev, pktlength + (2 * cachebytes));
+#else
 		skb = netdev_alloc_skb(dev, pktlength + NET_IP_ALIGN);
+#endif
 		if (unlikely(!skb)) {
 			SMSC_WARNING(RX_ERR,
 				"Unable to allocate skb for rx packet");
@@ -1041,22 +1112,51 @@ static int smsc911x_poll(struct napi_struct *napi, int budget)
 			break;
 		}
 
+#ifdef SMSC_USE_SH_RX_DMA
+		pdata->rx_skb = skb;
+#endif
+
 		skb->data = skb->head;
 		skb_reset_tail_pointer(skb);
 
 		/* Align IP on 16B boundary */
+#ifdef SMSC_USE_SH_RX_DMA
+		skb_reserve(skb, cachebytes - 14);
+#else
 		skb_reserve(skb, NET_IP_ALIGN);
+#endif
 		skb_put(skb, pktlength - 4);
+
+#ifdef SMSC_USE_SH_RX_DMA
+		/* Calculate the physical transfer addresses */
+		physaddrfrom = virt_to_phys(pdata->ioaddr + RX_DATA_FIFO);
+		physaddrto = virt_to_phys(skb->head);
+		BUG_ON(physaddrfrom & alignmask);
+		BUG_ON(physaddrto & alignmask);
+
+		/* Flush cache */
+		dma_cache_sync(NULL, skb->head, pktwords, DMA_FROM_DEVICE);
+
+		/* Start the DMA transfer */
+		dma_read(pdata->config.rx_dma_ch, physaddrfrom, physaddrto,
+			 pktwords);
+#else
 		smsc911x_rx_readfifo(pdata, (unsigned int *)skb->head,
 				     pktwords);
 		skb->protocol = eth_type_trans(skb, dev);
 		skb->ip_summed = CHECKSUM_NONE;
 		netif_receive_skb(skb);
+#endif
 
 		/* Update counters */
 		dev->stats.rx_packets++;
 		dev->stats.rx_bytes += (pktlength - 4);
 		dev->last_rx = jiffies;
+
+#ifdef SMSC_USE_SH_RX_DMA
+		/* Packet scheduled, break out of loop */
+		break;
+#endif
 	}
 
 	/* Return total received packets */
@@ -1261,8 +1361,34 @@ static int smsc911x_open(struct net_device *dev)
 	temp &= ~(FIFO_INT_RX_STS_LEVEL_);
 	smsc911x_reg_write(pdata, FIFO_INT, temp);
 
+#ifdef SMSC_USE_SH_RX_DMA
+	/* set RX Data offset to 2 bytes for alignment and set end alignment
+	 * for DMA transfers */
+	smsc911x_set_rx_cfg_for_dma(pdata);
+#else
 	/* set RX Data offset to 2 bytes for alignment */
 	smsc911x_reg_write(pdata, RX_CFG, (2 << 8));
+#endif
+
+#ifdef SMSC_USE_SH_RX_DMA
+	/* Configure Rx DMA channel for fixed source address and incremented
+	 * destination address */
+	dma_configure_channel(pdata->config.rx_dma_ch,
+		DM_INC | TS_128 | 0x400 | TM_BUR);
+
+	if (request_dma(pdata->config.rx_dma_ch, SMSC_CHIPNAME) < 0) {
+		SMSC_WARNING(DRV, "Error requesting Rx DMA channel %d",
+			pdata->config.rx_dma_ch);
+		return -ENODEV;
+	}
+
+	printk(KERN_INFO "%s: Rx DMA %i\n", dev->name,
+		pdata->config.rx_dma_ch);
+#else
+	printk(KERN_INFO "%s: Rx PIO\n", dev->name);
+#endif
+
+	printk(KERN_INFO "%s: Tx PIO\n", dev->name);
 
 	/* enable NAPI polling before enabling RX interrupts */
 	napi_enable(&pdata->napi);
@@ -1307,6 +1433,11 @@ static int smsc911x_stop(struct net_device *dev)
 	/* Bring the PHY down */
 	phy_stop(pdata->phy_dev);
 
+	/* Free DMA channels */
+#ifdef SMSC_USE_SH_RX_DMA
+	free_dma(pdata->config.rx_dma_ch);
+#endif
+
 	SMSC_TRACE(IFDOWN, "Interface stopped");
 	return 0;
 }
diff --git a/drivers/net/smsc911x.h b/drivers/net/smsc911x.h
index f818cf0..4634dcf 100644
--- a/drivers/net/smsc911x.h
+++ b/drivers/net/smsc911x.h
@@ -33,6 +33,10 @@
  * can be succesfully looped back */
 #define USE_PHY_WORK_AROUND
 
+#ifdef CONFIG_SH_DMA
+#define SMSC_USE_SH_RX_DMA
+#endif /* CONFIG_SH_DMA */
+
 #define DPRINTK(nlevel, klevel, fmt, args...) \
 	((void)((NETIF_MSG_##nlevel & pdata->msg_enable) && \
 	printk(KERN_##klevel "%s: %s: " fmt "\n", \
diff --git a/include/linux/smsc911x.h b/include/linux/smsc911x.h
index 1cbf031..0d9408a 100644
--- a/include/linux/smsc911x.h
+++ b/include/linux/smsc911x.h
@@ -30,6 +30,9 @@ struct smsc911x_platform_config {
 	unsigned int irq_type;
 	unsigned int flags;
 	phy_interface_t phy_interface;
+#ifdef CONFIG_SH_DMA
+	int rx_dma_ch;
+#endif
 };
 
 /* Constants for platform_device irq polarity configuration */
-- 
1.5.6.5


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [RFC PATCH 2/2] smsc911x: add support for sh3 TX DMA
  2008-11-23 16:04 [RFC PATCH 1/2] smsc911x: add support for sh3 RX DMA Steve Glendinning
@ 2008-11-23 16:04 ` Steve Glendinning
  2008-11-24  3:42 ` [RFC PATCH 1/2] smsc911x: add support for sh3 RX DMA Paul Mundt
  1 sibling, 0 replies; 4+ messages in thread
From: Steve Glendinning @ 2008-11-23 16:04 UTC (permalink / raw)
  To: netdev; +Cc: linux-sh, Ian Saturley, Steve Glendinning

Following on from the RX DMA patch, this patch also adds TX DMA support 
for the sh architecture.  Tested on SH7709S (sh3), where it works but 
actually *reduces* throughput (by about 30%).

The patch disables TX during the transfer, and uses the DMA completion 
interrupt to re-enable TX.  This causes 1 interrupt per packet, which is 
most likely responsible for the bulk of the performance loss.

This implementation is quite a nasty hack, as the sh DMA subsystem also 
attaches a DMA completion isr (so dma-sh.c must be modified to also
request the isr as shared).  The sh dma subsystem has a wait queue for
this purpose, but I don't think we can sleep in hard_start_xmit?

As with the RX patch, I'm interested to hear any advice on making this 
more generic.

Signed-off-by: Steve Glendinning <steve.glendinning@smsc.com>
---
 drivers/net/smsc911x.c   |  139 +++++++++++++++++++++++++++++++++++++++++++++-
 drivers/net/smsc911x.h   |    1 +
 include/linux/smsc911x.h |    1 +
 3 files changed, 140 insertions(+), 1 deletions(-)

diff --git a/drivers/net/smsc911x.c b/drivers/net/smsc911x.c
index b3d9f9e..90ab783 100644
--- a/drivers/net/smsc911x.c
+++ b/drivers/net/smsc911x.c
@@ -52,7 +52,7 @@
 #include <linux/smsc911x.h>
 #include "smsc911x.h"
 
-#ifdef SMSC_USE_SH_RX_DMA
+#if defined(SMSC_USE_SH_TX_DMA) || defined(SMSC_USE_SH_RX_DMA)
 #include <asm/dma.h>
 #include <../arch/sh/drivers/dma/dma-sh.h>
 #endif
@@ -125,6 +125,10 @@ struct smsc911x_data {
 #ifdef SMSC_USE_SH_RX_DMA
 	struct sk_buff *rx_skb;
 #endif
+
+#ifdef SMSC_USE_SH_TX_DMA
+	struct sk_buff *tx_skb;
+#endif
 };
 
 /* The 16-bit access functions are significantly slower, due to the locking
@@ -1253,6 +1257,40 @@ smsc911x_set_mac_address(struct smsc911x_data *pdata, u8 dev_addr[6])
 	smsc911x_mac_write(pdata, ADDRL, mac_low32);
 }
 
+#ifdef SMSC_USE_SH_TX_DMA
+static irqreturn_t smsc911x_tx_dma_irqhandler(int irq, void *dev_id)
+{
+	struct net_device *dev = dev_id;
+	struct smsc911x_data *pdata = netdev_priv(dev);
+	unsigned int freespace;
+
+	if (!pdata->tx_skb)
+		return IRQ_NONE;
+
+	/* make sure the channel has finished running */
+	BUG_ON(get_dma_residue(pdata->config.tx_dma_ch));
+
+	dev_kfree_skb_irq(pdata->tx_skb);
+	pdata->tx_skb = NULL;
+
+	freespace = smsc911x_reg_read(pdata, TX_FIFO_INF) & TX_FIFO_INF_TDFREE_;
+
+	if (freespace < TX_FIFO_LOW_THRESHOLD) {
+		/* free space low, leave tx disabled and enable the
+		 * tx fifo level interrupt */
+		unsigned int temp = smsc911x_reg_read(pdata, FIFO_INT);
+		temp &= 0x00FFFFFF;
+		temp |= 0x32000000;
+		smsc911x_reg_write(pdata, FIFO_INT, temp);
+	} else {
+		/* free space not low, re-enable the tx queue */
+		netif_wake_queue(pdata->dev);
+	}
+
+	return IRQ_HANDLED;
+}
+#endif
+
 static int smsc911x_open(struct net_device *dev)
 {
 	struct smsc911x_data *pdata = netdev_priv(dev);
@@ -1388,7 +1426,30 @@ static int smsc911x_open(struct net_device *dev)
 	printk(KERN_INFO "%s: Rx PIO\n", dev->name);
 #endif
 
+#ifdef SMSC_USE_SH_TX_DMA
+	/* Configure Tx DMA channel for incremented source address, fixed
+	 * destination address and enable the transfer complete interrupt */
+	dma_configure_channel(pdata->config.tx_dma_ch,
+		SM_INC | TS_128 | CHCR_IE | 0x400 | TM_BUR);
+
+	if (request_dma(pdata->config.tx_dma_ch, SMSC_CHIPNAME) < 0) {
+		SMSC_WARNING(DRV, "Error requesting Tx DMA channel %d",
+			pdata->config.tx_dma_ch);
+		goto out_release_rx_dma_1;
+	}
+
+	/* TODO: fix this hardcoded IRQ */
+	if (request_irq(DMTE1_IRQ, smsc911x_tx_dma_irqhandler,
+		IRQF_SHARED | IRQF_DISABLED, SMSC_CHIPNAME " Tx DMA", dev)) {
+		SMSC_WARNING(DRV, "Error requesting Tx DMA irq");
+		goto out_release_tx_dma_2;
+	}
+
+	printk(KERN_INFO "%s: Tx DMA %i\n", dev->name,
+		pdata->config.tx_dma_ch);
+#else
 	printk(KERN_INFO "%s: Tx PIO\n", dev->name);
+#endif
 
 	/* enable NAPI polling before enabling RX interrupts */
 	napi_enable(&pdata->napi);
@@ -1407,6 +1468,16 @@ static int smsc911x_open(struct net_device *dev)
 
 	netif_start_queue(dev);
 	return 0;
+
+#ifdef SMSC_USE_SH_TX_DMA
+out_release_tx_dma_2:
+	free_dma(pdata->config.tx_dma_ch);
+out_release_rx_dma_1:
+#ifdef SMSC_USE_SH_RX_DMA
+	free_dma(pdata->config.rx_dma_ch);
+#endif
+	return -ENODEV;
+#endif
 }
 
 /* Entry point for stopping the interface */
@@ -1434,6 +1505,9 @@ static int smsc911x_stop(struct net_device *dev)
 	phy_stop(pdata->phy_dev);
 
 	/* Free DMA channels */
+#ifdef SMSC_USE_SH_TX_DMA
+	free_dma(pdata->config.tx_dma_ch);
+#endif
 #ifdef SMSC_USE_SH_RX_DMA
 	free_dma(pdata->config.rx_dma_ch);
 #endif
@@ -1449,9 +1523,23 @@ static int smsc911x_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
 	unsigned int freespace;
 	unsigned int tx_cmd_a;
 	unsigned int tx_cmd_b;
+#ifdef SMSC_USE_SH_TX_DMA
+	unsigned int dma_cnt;
+	unsigned long physaddrfrom, physaddrto;
+	int cachebytes = dma_get_cache_alignment();
+	unsigned long alignmask = cachebytes - 1;
+	void *dma_buf;
+#else
 	unsigned int temp;
 	u32 wrsz;
 	ulong bufp;
+#endif
+
+#ifdef SMSC_USE_SH_TX_DMA
+	/* make sure the channel is not already running */
+	BUG_ON(pdata->tx_skb);
+	BUG_ON(get_dma_residue(pdata->config.tx_dma_ch));
+#endif
 
 	freespace = smsc911x_reg_read(pdata, TX_FIFO_INF) & TX_FIFO_INF_TDFREE_;
 
@@ -1459,17 +1547,62 @@ static int smsc911x_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
 		SMSC_WARNING(TX_ERR,
 			"Tx data fifo low, space available: %d", freespace);
 
+#ifdef SMSC_USE_SH_TX_DMA
+	/* 16/32 Byte start alignment */
+	tx_cmd_a = (((unsigned int)skb->data) & alignmask) << 16;
+
+	switch (cachebytes) {
+	case 16:
+		tx_cmd_a |= 0x01 << 24; /* 16 byte end alignment */
+		break;
+
+	case 32:
+		tx_cmd_a |= 0x02 << 24; /* 32 byte end alignment */
+		break;
+
+	default:
+		SMSC_WARNING(DRV, "Unknown DMA alignment");
+		break;
+	}
+#else
 	/* Word alignment adjustment */
 	tx_cmd_a = (u32)((ulong)skb->data & 0x03) << 16;
+#endif
+
 	tx_cmd_a |= TX_CMD_A_FIRST_SEG_ | TX_CMD_A_LAST_SEG_;
 	tx_cmd_a |= (unsigned int)skb->len;
 
 	tx_cmd_b = ((unsigned int)skb->len) << 16;
 	tx_cmd_b |= (unsigned int)skb->len;
 
+#ifdef SMSC_USE_SH_TX_DMA
+	dma_buf = (void *)(((unsigned long)skb->data) & (~alignmask));
+	dma_cnt = (((u32)skb->len) + alignmask +
+		   (((unsigned long)skb->data) & alignmask)) & (~alignmask);
+#endif
+
 	smsc911x_reg_write(pdata, TX_DATA_FIFO, tx_cmd_a);
 	smsc911x_reg_write(pdata, TX_DATA_FIFO, tx_cmd_b);
 
+#ifdef SMSC_USE_SH_TX_DMA
+	/* store the skb for the completion isr */
+	pdata->tx_skb = skb;
+
+	/* Calculate the physical transfer addresses */
+	physaddrfrom = virt_to_phys(dma_buf);
+	physaddrto = virt_to_phys(pdata->ioaddr + TX_DATA_FIFO);
+	BUG_ON(physaddrfrom & alignmask);
+	BUG_ON(physaddrto & alignmask);
+
+	/* Flush cache */
+	dma_cache_sync(NULL, dma_buf, dma_cnt, DMA_TO_DEVICE);
+
+	/* stop Tx until the DMA transaction is complete */
+	netif_stop_queue(dev);
+
+	/* Start the DMA transfer */
+	dma_write(pdata->config.tx_dma_ch, physaddrfrom, physaddrto, dma_cnt);
+#else
 	bufp = (ulong)skb->data & (~0x3);
 	wrsz = (u32)skb->len + 3;
 	wrsz += (u32)((ulong)skb->data & 0x3);
@@ -1478,11 +1611,14 @@ static int smsc911x_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
 	smsc911x_tx_writefifo(pdata, (unsigned int *)bufp, wrsz);
 	freespace -= (skb->len + 32);
 	dev_kfree_skb(skb);
+#endif
+
 	dev->trans_start = jiffies;
 
 	if (unlikely(smsc911x_tx_get_txstatcount(pdata) >= 30))
 		smsc911x_tx_update_txcounters(dev);
 
+#ifndef SMSC_USE_SH_TX_DMA
 	if (freespace < TX_FIFO_LOW_THRESHOLD) {
 		netif_stop_queue(dev);
 		temp = smsc911x_reg_read(pdata, FIFO_INT);
@@ -1490,6 +1626,7 @@ static int smsc911x_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
 		temp |= 0x32000000;
 		smsc911x_reg_write(pdata, FIFO_INT, temp);
 	}
+#endif
 
 	return NETDEV_TX_OK;
 }
diff --git a/drivers/net/smsc911x.h b/drivers/net/smsc911x.h
index 4634dcf..c21b1f9 100644
--- a/drivers/net/smsc911x.h
+++ b/drivers/net/smsc911x.h
@@ -35,6 +35,7 @@
 
 #ifdef CONFIG_SH_DMA
 #define SMSC_USE_SH_RX_DMA
+#define SMSC_USE_SH_TX_DMA
 #endif /* CONFIG_SH_DMA */
 
 #define DPRINTK(nlevel, klevel, fmt, args...) \
diff --git a/include/linux/smsc911x.h b/include/linux/smsc911x.h
index 0d9408a..d764f01 100644
--- a/include/linux/smsc911x.h
+++ b/include/linux/smsc911x.h
@@ -32,6 +32,7 @@ struct smsc911x_platform_config {
 	phy_interface_t phy_interface;
 #ifdef CONFIG_SH_DMA
 	int rx_dma_ch;
+	int tx_dma_ch;
 #endif
 };
 
-- 
1.5.6.5


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: [RFC PATCH 1/2] smsc911x: add support for sh3 RX DMA
  2008-11-23 16:04 [RFC PATCH 1/2] smsc911x: add support for sh3 RX DMA Steve Glendinning
  2008-11-23 16:04 ` [RFC PATCH 2/2] smsc911x: add support for sh3 TX DMA Steve Glendinning
@ 2008-11-24  3:42 ` Paul Mundt
  2008-11-24 22:46   ` David Miller
  1 sibling, 1 reply; 4+ messages in thread
From: Paul Mundt @ 2008-11-24  3:42 UTC (permalink / raw)
  To: Steve Glendinning; +Cc: netdev, linux-sh, Ian Saturley

On Sun, Nov 23, 2008 at 04:04:33PM +0000, Steve Glendinning wrote:
> I've been working on adding DMA support to the smsc911x driver.  As this 
> family of devices is non-pci, DMA transfers must be initiated and 
> controlled by the host CPU.  Unfortunately this makes some of the code 
> necessarily platform-specific.
> 
> This patch adds RX DMA support for the sh architecture.  Tested on 
> SH7709S (sh3), where it gives a small (~10%) iperf tcp throughput 
> increase.  DMA or PIO is selected at compile-time.
> 
> My first attempt stopped NAPI polling during a DMA transfer, then used 
> DMA completion interrupts to pass the packet up and re-enable polling.
> Obviously this defeats the interrupt-mitigation of NAPI, and on my test 
> platform actually *reduced* performance!
> 
> This patch leaves NAPI polling enabled, so a later poll completes the 
> transfer.  I'm concerned this is essentially busy-waiting on the 
> transfer, but it does show a small performance gain.  Is this a good or 
> bad idea?
> 
> I'd be interested to hear if anyone has advice on how to make this 
> patch more generic.  There's definitely been interest from arm pxa
> users in adding DMA, and some of this code must be re-usable for this.
> 
> Signed-off-by: Steve Glendinning <steve.glendinning@smsc.com>

The intent was to move everything over to the dmaengine framework and
have drivers (especially generic ones) opt for using that instead. This
hasn't happened yet, but it doesn't seem like there is much point in
adding hacks to the smsc911x driver at present given the overhead
involved in the interrupt handling. While this is something that can
easily be improved, I would rather put more effort in to getting things
moved over to the generic frameworks now that they exist, and optimize
later.

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [RFC PATCH 1/2] smsc911x: add support for sh3 RX DMA
  2008-11-24  3:42 ` [RFC PATCH 1/2] smsc911x: add support for sh3 RX DMA Paul Mundt
@ 2008-11-24 22:46   ` David Miller
  0 siblings, 0 replies; 4+ messages in thread
From: David Miller @ 2008-11-24 22:46 UTC (permalink / raw)
  To: lethal; +Cc: steve.glendinning, netdev, linux-sh, ian.saturley

From: Paul Mundt <lethal@linux-sh.org>
Date: Mon, 24 Nov 2008 12:42:37 +0900

> On Sun, Nov 23, 2008 at 04:04:33PM +0000, Steve Glendinning wrote:
> > I've been working on adding DMA support to the smsc911x driver.  As this 
> > family of devices is non-pci, DMA transfers must be initiated and 
> > controlled by the host CPU.  Unfortunately this makes some of the code 
> > necessarily platform-specific.
> > 
> > This patch adds RX DMA support for the sh architecture.  Tested on 
> > SH7709S (sh3), where it gives a small (~10%) iperf tcp throughput 
> > increase.  DMA or PIO is selected at compile-time.
> > 
> > My first attempt stopped NAPI polling during a DMA transfer, then used 
> > DMA completion interrupts to pass the packet up and re-enable polling.
> > Obviously this defeats the interrupt-mitigation of NAPI, and on my test 
> > platform actually *reduced* performance!
> > 
> > This patch leaves NAPI polling enabled, so a later poll completes the 
> > transfer.  I'm concerned this is essentially busy-waiting on the 
> > transfer, but it does show a small performance gain.  Is this a good or 
> > bad idea?
> > 
> > I'd be interested to hear if anyone has advice on how to make this 
> > patch more generic.  There's definitely been interest from arm pxa
> > users in adding DMA, and some of this code must be re-usable for this.
> > 
> > Signed-off-by: Steve Glendinning <steve.glendinning@smsc.com>
> 
> The intent was to move everything over to the dmaengine framework and
> have drivers (especially generic ones) opt for using that instead. This
> hasn't happened yet, but it doesn't seem like there is much point in
> adding hacks to the smsc911x driver at present given the overhead
> involved in the interrupt handling. While this is something that can
> easily be improved, I would rather put more effort in to getting things
> moved over to the generic frameworks now that they exist, and optimize
> later.

I'll therefore drop these two patches for now.

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2008-11-24 22:46 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-11-23 16:04 [RFC PATCH 1/2] smsc911x: add support for sh3 RX DMA Steve Glendinning
2008-11-23 16:04 ` [RFC PATCH 2/2] smsc911x: add support for sh3 TX DMA Steve Glendinning
2008-11-24  3:42 ` [RFC PATCH 1/2] smsc911x: add support for sh3 RX DMA Paul Mundt
2008-11-24 22:46   ` David Miller

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).