From 8a2396e6be243738446b7e69b5a94927145782df Mon Sep 17 00:00:00 2001 From: save Date: Thu, 10 Jun 2010 08:13:07 +0000 Subject: cleo/linux/drivers/eth: re-adapt netif_tx_queue, closes #1606 Before this modification tx queue could be waked-up even if there was no place on DMA_TX_RING (due to synop3504_tx_done(ONE) called on rx process). git-svn-id: svn+ssh://pessac/svn/cesar/trunk@7186 017c9cb6-072f-447c-8318-d5b54f68fe89 --- .../drivers/net/arm/synop3504.c | 35 +++++++++++++--------- 1 file changed, 21 insertions(+), 14 deletions(-) (limited to 'cleopatre/linux-2.6.25.10-spc300') diff --git a/cleopatre/linux-2.6.25.10-spc300/drivers/net/arm/synop3504.c b/cleopatre/linux-2.6.25.10-spc300/drivers/net/arm/synop3504.c index 13e508803d..8445aa88a8 100644 --- a/cleopatre/linux-2.6.25.10-spc300/drivers/net/arm/synop3504.c +++ b/cleopatre/linux-2.6.25.10-spc300/drivers/net/arm/synop3504.c @@ -71,9 +71,9 @@ /** Watchdog timeout for Tx frames */ #define TX_TIMEOUT (4 * HZ) /** Size of the DMA ring for tx */ -#define TX_RING_SIZE 64 +#define TX_RING_SIZE 128 /** Size of the DMA ring for rx */ -#define RX_RING_SIZE 64 +#define RX_RING_SIZE 128 /** Bit fields for MII_PHY identifier */ #define PHYSID_GET_ID(id1, id2) (id1 << 16 | id2) @@ -1104,6 +1104,10 @@ static int synop3504_tx(struct sk_buff *skb, struct net_device *dev) n = tx->head_ptr; + //Increase head pointer and check end of ring + if(++(tx->head_ptr) >= TX_RING_SIZE) + tx->head_ptr = 0; + //Check a free descriptor //No free buffer found : DMA use all the ring if(tx->ring[n].status.bf.dma_own) @@ -1119,6 +1123,13 @@ static int synop3504_tx(struct sk_buff *skb, struct net_device *dev) if(tx->skbs[n] != NULL) { synop3504_tx_done(dev, ONE); + netif_stop_queue(dev); + } + + //DMA own the next descriptor: stop TX queue + if(tx->ring[tx->head_ptr].status.bf.dma_own) + { + netif_stop_queue(dev); } tx->skbs[n] = skb; @@ -1136,10 +1147,6 @@ static int synop3504_tx(struct sk_buff *skb, struct net_device *dev) tx->ring[n].status.val = 0; tx->ring[n].status.bf.dma_own = 1; - //Increase head pointer and check end of ring - if(++(tx->head_ptr) >= TX_RING_SIZE) - tx->head_ptr = 0; - //Invalidate cached areas dma_cache_maint(skb->data, skb->len, DMA_BIDIRECTIONAL); @@ -1285,12 +1292,14 @@ static void synop3504_tx_done(struct net_device *dev, enum tx_clean_buff clean) struct net_priv *priv = (struct net_priv*)dev->priv; struct dma_tx *tx = (struct dma_tx*)&priv->tx; uint32_t n; + uint32_t free_area = 0; TRACE("%s: Transmit Done (num=%d)\n", dev->name, tx->tail_ptr); while((tx->skbs[tx->tail_ptr] != NULL) && (!tx->ring[tx->tail_ptr].status.bf.dma_own)) { n = tx->tail_ptr; + free_area++; TRACE("Found\n"); //Check errors for the current TX frame @@ -1340,6 +1349,12 @@ static void synop3504_tx_done(struct net_device *dev, enum tx_clean_buff clean) if(clean == ONE) break; } + //At least one free area, re-enable TX queue + if(free_area && netif_queue_stopped(dev)) + { + netif_wake_queue(dev); + TRACE("%s: TX queue Waked Up\n", dev->name); + } }// synop3504_tx_done /** @@ -1374,13 +1389,6 @@ static int synop3504_poll(struct napi_struct *napi, int budget) if(status.bf.intTxCompleted) { synop3504_tx_done(dev, ALL); - - //Check the TX queue and re-enable it - if(netif_queue_stopped(dev)) - { - netif_wake_queue(dev); - TRACE("%s: TX queue Waked Up\n", dev->name); - } } //RX completed @@ -1403,7 +1411,6 @@ static int synop3504_poll(struct napi_struct *napi, int budget) { //Remove old buffers from TX descriptors synop3504_tx_done(dev, ALL); - netif_start_queue(dev); printk(KERN_ERR DRV_NAME ": %s: TX FIFO Error\n", dev->name); } -- cgit v1.2.3