[PATCH 33/39] mv643xx_eth: work around TX hang hardware issue

!MAILaRCHIVE_VOTE_RePLACE
Previous message: [thread] [date] [author]
Next message: [thread] [date] [author]
To: Dale Farnsworth <dale@...>
Cc: <netdev@...>
Date: Tuesday, June 3, 2008 - 7:02 am

Under some conditions, the TXQ ('TX queue being served') bit can clear
before all packets queued for that TX queue have been transmitted.
This patch enables TXend interrupts, and uses those to re-kick TX
queues that claim to be idle but still have queued descriptors from
the interrupt handler.

Signed-off-by: Lennert Buytenhek <buytenh@marvell.com>
---
 drivers/net/mv643xx_eth.c |   35 ++++++++++++++++++++++++++++++-----
 1 files changed, 30 insertions(+), 5 deletions(-)

diff --git a/drivers/net/mv643xx_eth.c b/drivers/net/mv643xx_eth.c
index fd9e492..8e4ca2b 100644
--- a/drivers/net/mv643xx_eth.c
+++ b/drivers/net/mv643xx_eth.c
@@ -87,6 +87,7 @@ static char mv643xx_eth_driver_version[] = "1.0";
 #define TX_BW_MTU(p)			(0x0458 + ((p) << 10))
 #define TX_BW_BURST(p)			(0x045c + ((p) << 10))
 #define INT_CAUSE(p)			(0x0460 + ((p) << 10))
+#define  INT_TX_END			0x07f80000
 #define  INT_RX				0x0007fbfc
 #define  INT_EXT			0x00000002
 #define INT_CAUSE_EXT(p)		(0x0464 + ((p) << 10))
@@ -601,7 +602,7 @@ static int mv643xx_eth_poll(struct napi_struct *napi, int budget)
 		netif_rx_complete(mep->dev, napi);
 		wrl(mep, INT_CAUSE(mep->port_num), 0);
 		wrl(mep, INT_CAUSE_EXT(mep->port_num), 0);
-		wrl(mep, INT_MASK(mep->port_num), INT_RX | INT_EXT);
+		wrl(mep, INT_MASK(mep->port_num), INT_TX_END | INT_RX | INT_EXT);
 	}
 
 	return rx;
@@ -1603,8 +1604,10 @@ static irqreturn_t mv643xx_eth_irq(int irq, void *dev_id)
 	struct mv643xx_eth_private *mep = netdev_priv(dev);
 	u32 int_cause;
 	u32 int_cause_ext;
+	u32 txq_active;
 
-	int_cause = rdl(mep, INT_CAUSE(mep->port_num)) & (INT_RX | INT_EXT);
+	int_cause = rdl(mep, INT_CAUSE(mep->port_num)) &
+			(INT_TX_END | INT_RX | INT_EXT);
 	if (int_cause == 0)
 		return IRQ_NONE;
 
@@ -1656,6 +1659,8 @@ static irqreturn_t mv643xx_eth_irq(int irq, void *dev_id)
 	}
 #endif
 
+	txq_active = rdl(mep, TXQ_COMMAND(mep->port_num));
+
 	/*
 	 * TxBuffer or TxError set for any of the 8 queues?
 	 */
@@ -1665,8 +1670,28 @@ static irqreturn_t mv643xx_eth_irq(int irq, void *dev_id)
 		for (i = 0; i < 8; i++)
 			if (mep->txq_mask & (1 << i))
 				txq_reclaim(mep->txq + i, 0);
+	}
 
-		__txq_maybe_wake(mep->txq + mep->txq_primary);
+	/*
+	 * Any TxEnd interrupts?
+	 */
+	if (int_cause & INT_TX_END) {
+		int i;
+
+		wrl(mep, INT_CAUSE(mep->port_num), ~(int_cause & INT_TX_END));
+		for (i = 0; i < 8; i++) {
+			struct tx_queue *txq = mep->txq + i;
+			if (txq->tx_desc_count && !((txq_active >> i) & 1))
+				txq_enable(txq);
+		}
+	}
+
+	/*
+	 * Enough space again in the primary TX queue for a full packet?
+	 */
+	if (int_cause_ext & INT_EXT_TX) {
+		struct tx_queue *txq = mep->txq + mep->txq_primary;
+		__txq_maybe_wake(txq);
 	}
 
 	return IRQ_HANDLED;
@@ -1850,7 +1875,7 @@ static int mv643xx_eth_open(struct net_device *dev)
 	wrl(mep, INT_MASK_EXT(mep->port_num),
 	    INT_EXT_LINK | INT_EXT_PHY | INT_EXT_TX);
 
-	wrl(mep, INT_MASK(mep->port_num), INT_RX | INT_EXT);
+	wrl(mep, INT_MASK(mep->port_num), INT_TX_END | INT_RX | INT_EXT);
 
 	return 0;
 
@@ -1986,7 +2011,7 @@ static void mv643xx_eth_netpoll(struct net_device *dev)
 
 	mv643xx_eth_irq(dev->irq, dev);
 
-	wrl(mep, INT_MASK(mep->port_num), INT_RX | INT_CAUSE_EXT);
+	wrl(mep, INT_MASK(mep->port_num), INT_TX_END | INT_RX | INT_CAUSE_EXT);
 }
 #endif
 
-- 
1.5.3.4

--
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
Previous message: [thread] [date] [author]
Next message: [thread] [date] [author]

Messages in current thread:
[PATCH 00/39] mv643xx_eth: complete overhaul, Lennert Buytenhek, (Tue Jun 3, 7:02 am)
[PATCH 29/39] mv643xx_eth: general cleanup, Lennert Buytenhek, (Tue Jun 3, 7:02 am)
Re: [PATCH 29/39] mv643xx_eth: general cleanup, Dale Farnsworth, (Thu Jun 5, 8:33 am)
Re: [PATCH 29/39] mv643xx_eth: general cleanup, Lennert Buytenhek, (Fri Jun 6, 4:24 am)
Re: [PATCH 29/39] mv643xx_eth: general cleanup, Dale Farnsworth, (Fri Jun 6, 6:59 am)
[PATCH 19/39] mv643xx_eth: kill -&gt;rx_resource_err, Lennert Buytenhek, (Tue Jun 3, 7:02 am)
Re: [PATCH 19/39] mv643xx_eth: kill -&gt;rx_resource_err, Dale Farnsworth, (Thu Jun 5, 7:48 am)
[PATCH 10/39] mv643xx_eth: clarify irq masking and unmasking, Lennert Buytenhek, (Tue Jun 3, 7:02 am)
[PATCH 02/39] mv643xx_eth: trim unnecessary includes, Lennert Buytenhek, (Tue Jun 3, 7:02 am)
Re: [PATCH 02/39] mv643xx_eth: trim unnecessary includes, Dale Farnsworth, (Thu Jun 5, 7:02 am)
Re: [PATCH 02/39] mv643xx_eth: trim unnecessary includes, Lennert Buytenhek, (Fri Jun 6, 4:18 am)
Re: [PATCH 02/39] mv643xx_eth: trim unnecessary includes, Dale Farnsworth, (Fri Jun 6, 6:55 am)
[PATCH 03/39] mv643xx_eth: shorten reg names, Lennert Buytenhek, (Tue Jun 3, 7:02 am)
[PATCH 18/39] mv643xx_eth: kill superfluous comments, Lennert Buytenhek, (Tue Jun 3, 7:02 am)
Re: [PATCH 18/39] mv643xx_eth: kill superfluous comments, Dale Farnsworth, (Thu Jun 5, 8:03 am)
Re: [PATCH 03/39] mv643xx_eth: shorten reg names, Dale Farnsworth, (Thu Jun 5, 7:21 am)
[PATCH 12/39] mv643xx_eth: get rid of RX_BUF_OFFSET, Lennert Buytenhek, (Tue Jun 3, 7:02 am)
Re: [PATCH 12/39] mv643xx_eth: get rid of RX_BUF_OFFSET, Dale Farnsworth, (Thu Jun 5, 7:37 am)
[PATCH 11/39] mv643xx_eth: move PHY wait defines into callers, Lennert Buytenhek, (Tue Jun 3, 7:02 am)
[PATCH 09/39] mv643xx_eth: remove unused DESC_SIZE define, Lennert Buytenhek, (Tue Jun 3, 7:02 am)
[PATCH 27/39] mv643xx_eth: split out tx queue state, Lennert Buytenhek, (Tue Jun 3, 7:02 am)
[PATCH 26/39] mv643xx_eth: split out rx queue state, Lennert Buytenhek, (Tue Jun 3, 7:02 am)
Re: [PATCH 26/39] mv643xx_eth: split out rx queue state, Dale Farnsworth, (Thu Jun 5, 8:39 am)
Re: [PATCH 27/39] mv643xx_eth: split out tx queue state, Dale Farnsworth, (Thu Jun 5, 8:09 am)
[PATCH 32/39] mv643xx_eth: allow multiple TX queues, Lennert Buytenhek, (Tue Jun 3, 7:02 am)
Re: [PATCH 32/39] mv643xx_eth: allow multiple TX queues, Dale Farnsworth, (Thu Jun 5, 8:41 am)
[PATCH 31/39] mv643xx_eth: allow multiple RX queues, Lennert Buytenhek, (Tue Jun 3, 7:02 am)
Re: [PATCH 31/39] mv643xx_eth: allow multiple RX queues, Dale Farnsworth, (Thu Jun 5, 8:35 am)
[PATCH 33/39] mv643xx_eth: work around TX hang hardware issue, Lennert Buytenhek, (Tue Jun 3, 7:02 am)
[PATCH 23/39] mv643xx_eth: kill FUNC_RET_STATUS/pkt_info, Lennert Buytenhek, (Tue Jun 3, 7:02 am)
[PATCH 30/39] mv643xx_eth: add tx rate control, Lennert Buytenhek, (Tue Jun 3, 7:02 am)
Re: [PATCH 30/39] mv643xx_eth: add tx rate control, Dale Farnsworth, (Thu Jun 5, 8:51 am)
[PATCH 36/39] mv643xx_eth: be more agressive about RX refill, Lennert Buytenhek, (Tue Jun 3, 7:02 am)
[PATCH 38/39] mv643xx_eth: add PHY-less mode, Lennert Buytenhek, (Tue Jun 3, 7:02 am)
Re: [PATCH 38/39] mv643xx_eth: add PHY-less mode, Dale Farnsworth, (Thu Jun 5, 8:49 am)