aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStanislaw Gruszka <stf_xl@wp.pl>2013-10-05 12:15:33 -0400
committerJohn W. Linville <linville@tuxdriver.com>2013-10-10 13:49:28 -0400
commitfdbdd25c47ac1db04a161308dfb1060869eba982 (patch)
tree6dc88a9b1c9e4fbca723c822d99a40339f9cffee
parent733aec6a5bd39ba34ddd0568b7f7394aec2541fb (diff)
rt2x00: do not pause queue on flush
Pausing queue on flush make no sense since txdone procedure un-pause queue. Before flush procedure we have to assure queue is stopped, i.e. on receive path h/w RX is disabled, on transmit path queue is disabled in mac80211. That conditions are true except one function: rt2x00usb_watchdog_tx_dma(), so add stop/start queue there. Note stop/start queue can be racy if we do this from multiple paths, but currently we stop TX queues only on rt2x00lib_disable_radio(), which also stop/sync watchdog, hance we have no race condition. Signed-off-by: Stanislaw Gruszka <stf_xl@wp.pl> Signed-off-by: John W. Linville <linville@tuxdriver.com>
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00queue.c37
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00usb.c2
2 files changed, 8 insertions, 31 deletions
diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.c b/drivers/net/wireless/rt2x00/rt2x00queue.c
index 6c8a33b6ee22..218e3206ce1b 100644
--- a/drivers/net/wireless/rt2x00/rt2x00queue.c
+++ b/drivers/net/wireless/rt2x00/rt2x00queue.c
@@ -1033,38 +1033,21 @@ EXPORT_SYMBOL_GPL(rt2x00queue_stop_queue);
1033 1033
1034void rt2x00queue_flush_queue(struct data_queue *queue, bool drop) 1034void rt2x00queue_flush_queue(struct data_queue *queue, bool drop)
1035{ 1035{
1036 bool started;
1037 bool tx_queue = 1036 bool tx_queue =
1038 (queue->qid == QID_AC_VO) || 1037 (queue->qid == QID_AC_VO) ||
1039 (queue->qid == QID_AC_VI) || 1038 (queue->qid == QID_AC_VI) ||
1040 (queue->qid == QID_AC_BE) || 1039 (queue->qid == QID_AC_BE) ||
1041 (queue->qid == QID_AC_BK); 1040 (queue->qid == QID_AC_BK);
1042 1041
1043 mutex_lock(&queue->status_lock);
1044 1042
1045 /* 1043 /*
1046 * If the queue has been started, we must stop it temporarily 1044 * If we are not supposed to drop any pending
1047 * to prevent any new frames to be queued on the device. If 1045 * frames, this means we must force a start (=kick)
1048 * we are not dropping the pending frames, the queue must 1046 * to the queue to make sure the hardware will
1049 * only be stopped in the software and not the hardware, 1047 * start transmitting.
1050 * otherwise the queue will never become empty on its own.
1051 */ 1048 */
1052 started = test_bit(QUEUE_STARTED, &queue->flags); 1049 if (!drop && tx_queue)
1053 if (started) { 1050 queue->rt2x00dev->ops->lib->kick_queue(queue);
1054 /*
1055 * Pause the queue
1056 */
1057 rt2x00queue_pause_queue(queue);
1058
1059 /*
1060 * If we are not supposed to drop any pending
1061 * frames, this means we must force a start (=kick)
1062 * to the queue to make sure the hardware will
1063 * start transmitting.
1064 */
1065 if (!drop && tx_queue)
1066 queue->rt2x00dev->ops->lib->kick_queue(queue);
1067 }
1068 1051
1069 /* 1052 /*
1070 * Check if driver supports flushing, if that is the case we can 1053 * Check if driver supports flushing, if that is the case we can
@@ -1080,14 +1063,6 @@ void rt2x00queue_flush_queue(struct data_queue *queue, bool drop)
1080 if (unlikely(!rt2x00queue_empty(queue))) 1063 if (unlikely(!rt2x00queue_empty(queue)))
1081 rt2x00_warn(queue->rt2x00dev, "Queue %d failed to flush\n", 1064 rt2x00_warn(queue->rt2x00dev, "Queue %d failed to flush\n",
1082 queue->qid); 1065 queue->qid);
1083
1084 /*
1085 * Restore the queue to the previous status
1086 */
1087 if (started)
1088 rt2x00queue_unpause_queue(queue);
1089
1090 mutex_unlock(&queue->status_lock);
1091} 1066}
1092EXPORT_SYMBOL_GPL(rt2x00queue_flush_queue); 1067EXPORT_SYMBOL_GPL(rt2x00queue_flush_queue);
1093 1068
diff --git a/drivers/net/wireless/rt2x00/rt2x00usb.c b/drivers/net/wireless/rt2x00/rt2x00usb.c
index 88289873c0cf..4e121627925d 100644
--- a/drivers/net/wireless/rt2x00/rt2x00usb.c
+++ b/drivers/net/wireless/rt2x00/rt2x00usb.c
@@ -523,7 +523,9 @@ static void rt2x00usb_watchdog_tx_dma(struct data_queue *queue)
523 rt2x00_warn(queue->rt2x00dev, "TX queue %d DMA timed out, invoke forced forced reset\n", 523 rt2x00_warn(queue->rt2x00dev, "TX queue %d DMA timed out, invoke forced forced reset\n",
524 queue->qid); 524 queue->qid);
525 525
526 rt2x00queue_stop_queue(queue);
526 rt2x00queue_flush_queue(queue, true); 527 rt2x00queue_flush_queue(queue, true);
528 rt2x00queue_start_queue(queue);
527} 529}
528 530
529static int rt2x00usb_dma_timeout(struct data_queue *queue) 531static int rt2x00usb_dma_timeout(struct data_queue *queue)