aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/rt2x00/rt2x00usb.c
diff options
context:
space:
mode:
authorIvo van Doorn <ivdoorn@gmail.com>2010-12-13 06:35:40 -0500
committerJohn W. Linville <linville@tuxdriver.com>2010-12-13 15:23:35 -0500
commit5be65609fec2e331c7d804471be3d59089a30d98 (patch)
tree6c6967c7835d6ec3a8ce79c2c9b84bf95aefca31 /drivers/net/wireless/rt2x00/rt2x00usb.c
parent0b7fde54f94979edc67bbf86b5adba702ebfefe8 (diff)
rt2x00: Add "flush" queue command
Add a new command to the queue handlers: "flush", this moves the flush() callback from mac80211 into rt2x00queue and adds support for flushing the RX queue as well. Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com> Acked-by: Helmut Schaa <helmut.schaa@googlemail.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.c70
1 files changed, 47 insertions, 23 deletions
diff --git a/drivers/net/wireless/rt2x00/rt2x00usb.c b/drivers/net/wireless/rt2x00/rt2x00usb.c
index fca29ae57e71..cd80eec5ff51 100644
--- a/drivers/net/wireless/rt2x00/rt2x00usb.c
+++ b/drivers/net/wireless/rt2x00/rt2x00usb.c
@@ -366,7 +366,7 @@ void rt2x00usb_kick_queue(struct data_queue *queue)
366} 366}
367EXPORT_SYMBOL_GPL(rt2x00usb_kick_queue); 367EXPORT_SYMBOL_GPL(rt2x00usb_kick_queue);
368 368
369static void rt2x00usb_kill_entry(struct queue_entry *entry) 369static void rt2x00usb_flush_entry(struct queue_entry *entry)
370{ 370{
371 struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; 371 struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
372 struct queue_entry_priv_usb *entry_priv = entry->priv_data; 372 struct queue_entry_priv_usb *entry_priv = entry->priv_data;
@@ -385,37 +385,61 @@ static void rt2x00usb_kill_entry(struct queue_entry *entry)
385 usb_kill_urb(bcn_priv->guardian_urb); 385 usb_kill_urb(bcn_priv->guardian_urb);
386} 386}
387 387
388void rt2x00usb_stop_queue(struct data_queue *queue) 388void rt2x00usb_flush_queue(struct data_queue *queue)
389{ 389{
390 struct work_struct *completion;
391 unsigned int i;
392
390 rt2x00queue_for_each_entry(queue, Q_INDEX_DONE, Q_INDEX, 393 rt2x00queue_for_each_entry(queue, Q_INDEX_DONE, Q_INDEX,
391 rt2x00usb_kill_entry); 394 rt2x00usb_flush_entry);
395
396 /*
397 * Obtain the queue completion handler
398 */
399 switch (queue->qid) {
400 case QID_AC_BE:
401 case QID_AC_BK:
402 case QID_AC_VI:
403 case QID_AC_VO:
404 completion = &queue->rt2x00dev->txdone_work;
405 break;
406 case QID_RX:
407 completion = &queue->rt2x00dev->rxdone_work;
408 break;
409 default:
410 return;
411 }
412
413 for (i = 0; i < 20; i++) {
414 /*
415 * Check if the driver is already done, otherwise we
416 * have to sleep a little while to give the driver/hw
417 * the oppurtunity to complete interrupt process itself.
418 */
419 if (rt2x00queue_empty(queue))
420 break;
421
422 /*
423 * Schedule the completion handler manually, when this
424 * worker function runs, it should cleanup the queue.
425 */
426 ieee80211_queue_work(queue->rt2x00dev->hw, completion);
427
428 /*
429 * Wait for a little while to give the driver
430 * the oppurtunity to recover itself.
431 */
432 msleep(10);
433 }
392} 434}
393EXPORT_SYMBOL_GPL(rt2x00usb_stop_queue); 435EXPORT_SYMBOL_GPL(rt2x00usb_flush_queue);
394 436
395static void rt2x00usb_watchdog_tx_dma(struct data_queue *queue) 437static void rt2x00usb_watchdog_tx_dma(struct data_queue *queue)
396{ 438{
397 struct rt2x00_dev *rt2x00dev = queue->rt2x00dev;
398
399 WARNING(queue->rt2x00dev, "TX queue %d DMA timed out," 439 WARNING(queue->rt2x00dev, "TX queue %d DMA timed out,"
400 " invoke forced forced reset\n", queue->qid); 440 " invoke forced forced reset\n", queue->qid);
401 441
402 /* 442 rt2x00queue_flush_queue(queue, true);
403 * Temporarily disable the TX queue, this will force mac80211
404 * to use the other queues until this queue has been restored.
405 */
406 rt2x00queue_stop_queue(queue);
407
408 /*
409 * In case that a driver has overriden the txdone_work
410 * function, we invoke the TX done through there.
411 */
412 rt2x00dev->txdone_work.func(&rt2x00dev->txdone_work);
413
414 /*
415 * The queue has been reset, and mac80211 is allowed to use the
416 * queue again.
417 */
418 rt2x00queue_start_queue(queue);
419} 443}
420 444
421static void rt2x00usb_watchdog_tx_status(struct data_queue *queue) 445static void rt2x00usb_watchdog_tx_status(struct data_queue *queue)