Skip to content

Commit

Permalink
net/macb: move to circ_buf macros and fix initial condition
Browse files Browse the repository at this point in the history
Move to circular buffers management macro and correct an error
with circular buffer initial condition.

Without this patch, the macb_tx_ring_avail() function was
not reporting the proper ring availability at startup:
macb macb: eth0: BUG! Tx Ring full when queue awake!
macb macb: eth0: tx_head = 0, tx_tail = 0
And hanginig forever...

I remove the macb_tx_ring_avail() function and use the
proven macros from circ_buf.h. CIRC_CNT() is used in the
"consumer" part of the driver: macb_tx_interrupt() to match
advice from Documentation/circular-buffers.txt.

Reported-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
Signed-off-by: Nicolas Ferre <nicolas.ferre@atmel.com>
Tested-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Nicolas Ferre authored and David S. Miller committed Nov 19, 2012
1 parent e5ef39e commit 909a858
Showing 1 changed file with 7 additions and 10 deletions.
17 changes: 7 additions & 10 deletions drivers/net/ethernet/cadence/macb.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
#include <linux/moduleparam.h>
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/circ_buf.h>
#include <linux/slab.h>
#include <linux/init.h>
#include <linux/gpio.h>
Expand All @@ -38,8 +39,8 @@
#define TX_RING_SIZE 128 /* must be power of 2 */
#define TX_RING_BYTES (sizeof(struct macb_dma_desc) * TX_RING_SIZE)

/* minimum number of free TX descriptors before waking up TX process */
#define MACB_TX_WAKEUP_THRESH (TX_RING_SIZE / 4)
/* level of occupied TX descriptors under which we wake up TX process */
#define MACB_TX_WAKEUP_THRESH (3 * TX_RING_SIZE / 4)

#define MACB_RX_INT_FLAGS (MACB_BIT(RCOMP) | MACB_BIT(RXUBR) \
| MACB_BIT(ISR_ROVR))
Expand All @@ -60,11 +61,6 @@ static unsigned int macb_tx_ring_wrap(unsigned int index)
return index & (TX_RING_SIZE - 1);
}

static unsigned int macb_tx_ring_avail(struct macb *bp)
{
return (bp->tx_tail - bp->tx_head) & (TX_RING_SIZE - 1);
}

static struct macb_dma_desc *macb_tx_desc(struct macb *bp, unsigned int index)
{
return &bp->tx_ring[macb_tx_ring_wrap(index)];
Expand Down Expand Up @@ -524,7 +520,8 @@ static void macb_tx_interrupt(struct macb *bp)

bp->tx_tail = tail;
if (netif_queue_stopped(bp->dev)
&& macb_tx_ring_avail(bp) > MACB_TX_WAKEUP_THRESH)
&& CIRC_CNT(bp->tx_head, bp->tx_tail,
TX_RING_SIZE) <= MACB_TX_WAKEUP_THRESH)
netif_wake_queue(bp->dev);
}

Expand Down Expand Up @@ -818,7 +815,7 @@ static int macb_start_xmit(struct sk_buff *skb, struct net_device *dev)
spin_lock_irqsave(&bp->lock, flags);

/* This is a hard error, log it. */
if (macb_tx_ring_avail(bp) < 1) {
if (CIRC_SPACE(bp->tx_head, bp->tx_tail, TX_RING_SIZE) < 1) {
netif_stop_queue(dev);
spin_unlock_irqrestore(&bp->lock, flags);
netdev_err(bp->dev, "BUG! Tx Ring full when queue awake!\n");
Expand Down Expand Up @@ -855,7 +852,7 @@ static int macb_start_xmit(struct sk_buff *skb, struct net_device *dev)

macb_writel(bp, NCR, macb_readl(bp, NCR) | MACB_BIT(TSTART));

if (macb_tx_ring_avail(bp) < 1)
if (CIRC_SPACE(bp->tx_head, bp->tx_tail, TX_RING_SIZE) < 1)
netif_stop_queue(dev);

spin_unlock_irqrestore(&bp->lock, flags);
Expand Down

0 comments on commit 909a858

Please sign in to comment.