[rt2x00-users] [PATCH 4/4 v2] rt2x00: Implement watchdog monitoring

Ivo van Doorn ivdoorn at gmail.com
Tue Jul 6 00:33:39 AEST 2010


On Monday 05 July 2010 15:55:55 Ivo van Doorn wrote:
> Implement watchdog monitoring for USB devices (PCI support can
> be added later). This will determine if URBs being uploaded to
> the hardware are actually returning. Both rt2500usb and rt2800usb
> have shown that URBs being uploaded can remain hanging without
> being released by the hardware.
> By using this watchdog, a queue can be reset when this occurs.
> For rt2800usb it has been tested that the connection is preserved
> even though this interruption.
> 
> v2: Move watchdog handling into separate delayed_work structure
> 
> Signed-off-by: Ivo van Doorn <IvDoorn at gmail.com>

Small addition to this patch (will merge when I push this to master)

This disables the TX queue, which allows mac80211 to continue working with
the other queues, while the watchdog can make sure that all frames are canceled
in the queue.

--

diff --git a/drivers/net/wireless/rt2x00/rt2x00usb.c b/drivers/net/wireless/rt2x00/rt2x00usb.c
index ee97502..ec6984c 100644
--- a/drivers/net/wireless/rt2x00/rt2x00usb.c
+++ b/drivers/net/wireless/rt2x00/rt2x00usb.c
@@ -295,20 +295,24 @@ EXPORT_SYMBOL_GPL(rt2x00usb_kill_tx_queue);
 static void rt2x00usb_watchdog_reset_tx(struct data_queue *queue)
 {
 	struct queue_entry_priv_usb *entry_priv;
-	u32 i;
-	u32 limit;
+	unsigned short threshold = queue->threshold;
 
 	WARNING(queue->rt2x00dev, "TX queue %d timed out, invoke reset", queue->qid);
 
 	/*
-	 * Reset all currently uploaded TX frames.
-	 * Any frames uploaded during the reset, should
-	 * not be discarded since those might still succeed.
+ 	 * Temporarily disable the TX queue, this will force mac80211
+ 	 * to use the other queues until this queue has been restored.
+ 	 *
+ 	 * Set the queue threshold to the queue limit. This prevents the
+ 	 * queue from being enabled during the txdone handler.
  	 */
-	for (i = 0, limit = queue->length; i < limit; i++) {
-		if (rt2x00queue_empty(queue))
-			break;
+	queue->threshold = queue->limit;
+	ieee80211_stop_queue(queue->rt2x00dev->hw, queue->qid);
 
+	/*
+	 * Reset all currently uploaded TX frames.
+ 	 */
+	while (!rt2x00queue_empty(queue)) {
 		entry_priv = rt2x00queue_get_entry(queue, Q_INDEX_DONE)->priv_data;
 		usb_kill_urb(entry_priv->urb);
 
@@ -318,6 +322,13 @@ static void rt2x00usb_watchdog_reset_tx(struct data_queue *queue)
 		 */
 		udelay(200);
 	}
+
+	/*
+	 * The queue has been reset, and mac80211 is allowed to use the
+	 * queue again.
+	 */
+	queue->threshold = threshold;
+	ieee80211_wake_queue(queue->rt2x00dev->hw, queue->qid);
 }
 
 void rt2x00usb_watchdog(struct rt2x00_dev *rt2x00dev)




More information about the users mailing list