Patchwork Fix b44 RX FIFO overflow recovery.

login
register
mail settings
Submitter James Courtier-Dutton
Date June 30, 2010, 8:11 p.m.
Message ID <AANLkTik2BadzkkVcmlhgWh6rcLDm1kEu0RDqWuILnwVZ@mail.gmail.com>
Download mbox | patch
Permalink /patch/57452/
State Changes Requested
Delegated to: David Miller
Headers show

Comments

James Courtier-Dutton - June 30, 2010, 8:11 p.m.
Hi,

This patch improves the recovery after a RX FIFO overflow on the b44
Ethernet NIC.
Before it would do a complete chip reset, resulting is loss of link
for a few seconds.
This patch improves this to do recovery in about 20ms without loss of link.

Kind Regards

James

b44: Handle RX FIFO overflow better.
Signed off by: James@superbug.co.uk
David Miller - June 30, 2010, 8:25 p.m.
From: James Courtier-Dutton <james.dutton@gmail.com>
Date: Wed, 30 Jun 2010 21:11:18 +0100

> diff --git a/drivers/net/b44.c b/drivers/net/b44.c
> index 69d9f3d..72537c1 100644
> --- a/drivers/net/b44.c
> +++ b/drivers/net/b44.c
> @@ -852,12 +852,46 @@ static int b44_poll(struct napi_struct *napi, int budget)
>  		/* spin_unlock(&bp->tx_lock); */
>  	}
>  	spin_unlock_irqrestore(&bp->lock, flags);
> +	if (bp->istat & ISTAT_DSCE)
> +	{
> +		printk(KERN_INFO "b44_poll: ISTAT_DSCE\n");
> +	}

Using braces here is overkill, and even if it was appropriate it's formatted
incorrectly, it should be:

	if (x)
		y;

for single-line code blocks, and:

	if (x) {
		y;
		z;
	}

For multi-line code blocks.
--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Patch

diff --git a/drivers/net/b44.c b/drivers/net/b44.c
index 69d9f3d..72537c1 100644
--- a/drivers/net/b44.c
+++ b/drivers/net/b44.c
@@ -852,12 +852,46 @@  static int b44_poll(struct napi_struct *napi, int budget)
 		/* spin_unlock(&bp->tx_lock); */
 	}
 	spin_unlock_irqrestore(&bp->lock, flags);
+	if (bp->istat & ISTAT_DSCE)
+	{
+		printk(KERN_INFO "b44_poll: ISTAT_DSCE\n");
+	}
+	if (bp->istat & ISTAT_DATAE)
+	{
+		printk(KERN_INFO "b44_poll: ISTAT_DATAE\n");
+	}
+	if (bp->istat & ISTAT_DPE)
+	{
+		printk(KERN_INFO "b44_poll: ISTAT_DPE\n");
+	}
+	if (bp->istat & ISTAT_RDU)
+	{
+		printk(KERN_INFO "b44_poll: ISTAT_RDU\n");
+	}
+	if (bp->istat & ISTAT_RFO)
+	{
+		printk(KERN_INFO "b44_poll: ISTAT_RFO\n");
+		spin_lock_irqsave(&bp->lock, flags);
+		b44_disable_ints(bp);
+		/* This resets the ISTAT_RFO flag */
+		ssb_device_enable(bp->sdev, 0);
+		b44_init_rings(bp);
+		b44_init_hw(bp, B44_FULL_RESET_SKIP_PHY);
+		netif_wake_queue(bp->dev);
+		spin_unlock_irqrestore(&bp->lock, flags);
+		work_done = 0;
+	}
+	if (bp->istat & ISTAT_TFU)
+	{
+		printk(KERN_INFO "b44_poll: ISTAT_TFU\n");
+	}
+
 
 	work_done = 0;
 	if (bp->istat & ISTAT_RX)
 		work_done += b44_rx(bp, budget);
 
-	if (bp->istat & ISTAT_ERRORS) {
+	if ((bp->istat & ISTAT_ERRORS) && !(bp->istat & ISTAT_RFO)) {
 		spin_lock_irqsave(&bp->lock, flags);
 		b44_halt(bp);
 		b44_init_rings(bp);