aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/rt2x00/rt2x00usb.c
diff options
context:
space:
mode:
authorIvo van Doorn <ivdoorn@gmail.com>2010-07-11 06:25:46 -0400
committerJohn W. Linville <linville@tuxdriver.com>2010-07-12 16:05:34 -0400
commitc965c74bbc650e5466d2f3e32bd28112ebcdd00c (patch)
treeb24e5a745a40b5f7d83b8fb7b04a5abd1c32445f /drivers/net/wireless/rt2x00/rt2x00usb.c
parent223dcc26591aa8e4a6bf623164b775b5bd89c9e1 (diff)
rt2x00: Implement watchdog monitoring
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. Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/rt2x00/rt2x00usb.c')
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00usb.c50
1 files changed, 50 insertions, 0 deletions
diff --git a/drivers/net/wireless/rt2x00/rt2x00usb.c b/drivers/net/wireless/rt2x00/rt2x00usb.c
index a22837c560fd..ff3a36622d1b 100644
--- a/drivers/net/wireless/rt2x00/rt2x00usb.c
+++ b/drivers/net/wireless/rt2x00/rt2x00usb.c
@@ -292,6 +292,56 @@ void rt2x00usb_kill_tx_queue(struct rt2x00_dev *rt2x00dev,
292} 292}
293EXPORT_SYMBOL_GPL(rt2x00usb_kill_tx_queue); 293EXPORT_SYMBOL_GPL(rt2x00usb_kill_tx_queue);
294 294
295static void rt2x00usb_watchdog_reset_tx(struct data_queue *queue)
296{
297 struct queue_entry_priv_usb *entry_priv;
298 unsigned short threshold = queue->threshold;
299
300 WARNING(queue->rt2x00dev, "TX queue %d timed out, invoke reset", queue->qid);
301
302 /*
303 * Temporarily disable the TX queue, this will force mac80211
304 * to use the other queues until this queue has been restored.
305 *
306 * Set the queue threshold to the queue limit. This prevents the
307 * queue from being enabled during the txdone handler.
308 */
309 queue->threshold = queue->limit;
310 ieee80211_stop_queue(queue->rt2x00dev->hw, queue->qid);
311
312 /*
313 * Reset all currently uploaded TX frames.
314 */
315 while (!rt2x00queue_empty(queue)) {
316 entry_priv = rt2x00queue_get_entry(queue, Q_INDEX_DONE)->priv_data;
317 usb_kill_urb(entry_priv->urb);
318
319 /*
320 * We need a short delay here to wait for
321 * the URB to be canceled and invoked the tx_done handler.
322 */
323 udelay(200);
324 }
325
326 /*
327 * The queue has been reset, and mac80211 is allowed to use the
328 * queue again.
329 */
330 queue->threshold = threshold;
331 ieee80211_wake_queue(queue->rt2x00dev->hw, queue->qid);
332}
333
334void rt2x00usb_watchdog(struct rt2x00_dev *rt2x00dev)
335{
336 struct data_queue *queue;
337
338 tx_queue_for_each(rt2x00dev, queue) {
339 if (rt2x00queue_timeout(queue))
340 rt2x00usb_watchdog_reset_tx(queue);
341 }
342}
343EXPORT_SYMBOL_GPL(rt2x00usb_watchdog);
344
295/* 345/*
296 * RX data handlers. 346 * RX data handlers.
297 */ 347 */