summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNélio Laranjeiro2012-06-21 11:26:53 +0200
committerNélio Laranjeiro2012-09-06 13:54:48 +0200
commitb044d33f4c9d4d41a4923a4baaf00c65a1d9318d (patch)
tree7f84c5c205b947964fa159bda63c6c8dd2ee7f69
parent590d4fce37dd211129888947c12d7d2e32a856d9 (diff)
cleo/linux/drv/net/arm/synop3504: reset rings on timeout, refs #3161
Linux network scheduler handles a timer to detect timeout TX. This timeout is configurable for the device. The watchdog only call the drivers' timeout function if the carrier is ON, so it is only used to detect problems on transmission or congestion on the medium. In our case, as the timeout is pretty long, if the first packet in the DMA has expired the last one has expired too, so the ring can be reseted. This is only true for TX DMA ring, because the timeout is configured to expire 4 seconds after the last TX has been requested. Used example from drivers/net/meth.c
-rw-r--r--cleopatre/linux-2.6.25.10-spc300/drivers/net/arm/synop3504.c21
1 files changed, 18 insertions, 3 deletions
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 f340e45d87..800f5f9034 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
@@ -591,9 +591,24 @@ static void synop3504_set_multicast(struct net_device *dev)
#ifndef CONFIG_SYNOP3504_NO_TX_TIMEOUT
static void synop3504_tx_timeout(struct net_device *dev)
{
- dev->stats.tx_errors++;
- dev->trans_start = jiffies;
- printk (KERN_WARNING DRV_NAME" %s: Transmit timed out\n",dev->name);
+ struct net_priv *priv = (struct net_priv *)dev->priv;
+ Synopsys *synop = &priv->synop;
+
+ dev->stats.tx_errors++;
+ dev->trans_start = jiffies;
+ printk (KERN_WARNING DRV_NAME" %s: Transmit timed out\n",dev->name);
+
+ //Reset TX descriptors.
+ SynopsysDisableInt(synop);
+ SynopsysStopTx(synop);
+
+ synop3504_txdesc_reset(dev);
+
+ SynopsysStartTx(synop);
+ SynopsysEnableInt(synop);
+
+ //The ring is empty, the queue can be awaken.
+ netif_wake_queue(dev);
}// synop3504_tx_timeout
#endif