Commit fdbdd25c authored by Stanislaw Gruszka's avatar Stanislaw Gruszka Committed by John W. Linville

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: default avatarStanislaw Gruszka <stf_xl@wp.pl>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent 733aec6a
...@@ -1033,38 +1033,21 @@ EXPORT_SYMBOL_GPL(rt2x00queue_stop_queue); ...@@ -1033,38 +1033,21 @@ EXPORT_SYMBOL_GPL(rt2x00queue_stop_queue);
void rt2x00queue_flush_queue(struct data_queue *queue, bool drop) void rt2x00queue_flush_queue(struct data_queue *queue, bool drop)
{ {
bool started;
bool tx_queue = bool tx_queue =
(queue->qid == QID_AC_VO) || (queue->qid == QID_AC_VO) ||
(queue->qid == QID_AC_VI) || (queue->qid == QID_AC_VI) ||
(queue->qid == QID_AC_BE) || (queue->qid == QID_AC_BE) ||
(queue->qid == QID_AC_BK); (queue->qid == QID_AC_BK);
mutex_lock(&queue->status_lock);
/* /*
* If the queue has been started, we must stop it temporarily * If we are not supposed to drop any pending
* to prevent any new frames to be queued on the device. If * frames, this means we must force a start (=kick)
* we are not dropping the pending frames, the queue must * to the queue to make sure the hardware will
* only be stopped in the software and not the hardware, * start transmitting.
* otherwise the queue will never become empty on its own.
*/ */
started = test_bit(QUEUE_STARTED, &queue->flags); if (!drop && tx_queue)
if (started) { queue->rt2x00dev->ops->lib->kick_queue(queue);
/*
* Pause the queue
*/
rt2x00queue_pause_queue(queue);
/*
* If we are not supposed to drop any pending
* frames, this means we must force a start (=kick)
* to the queue to make sure the hardware will
* start transmitting.
*/
if (!drop && tx_queue)
queue->rt2x00dev->ops->lib->kick_queue(queue);
}
/* /*
* Check if driver supports flushing, if that is the case we can * 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,14 +1063,6 @@ void rt2x00queue_flush_queue(struct data_queue *queue, bool drop)
if (unlikely(!rt2x00queue_empty(queue))) if (unlikely(!rt2x00queue_empty(queue)))
rt2x00_warn(queue->rt2x00dev, "Queue %d failed to flush\n", rt2x00_warn(queue->rt2x00dev, "Queue %d failed to flush\n",
queue->qid); queue->qid);
/*
* Restore the queue to the previous status
*/
if (started)
rt2x00queue_unpause_queue(queue);
mutex_unlock(&queue->status_lock);
} }
EXPORT_SYMBOL_GPL(rt2x00queue_flush_queue); EXPORT_SYMBOL_GPL(rt2x00queue_flush_queue);
......
...@@ -523,7 +523,9 @@ static void rt2x00usb_watchdog_tx_dma(struct data_queue *queue) ...@@ -523,7 +523,9 @@ static void rt2x00usb_watchdog_tx_dma(struct data_queue *queue)
rt2x00_warn(queue->rt2x00dev, "TX queue %d DMA timed out, invoke forced forced reset\n", rt2x00_warn(queue->rt2x00dev, "TX queue %d DMA timed out, invoke forced forced reset\n",
queue->qid); queue->qid);
rt2x00queue_stop_queue(queue);
rt2x00queue_flush_queue(queue, true); rt2x00queue_flush_queue(queue, true);
rt2x00queue_start_queue(queue);
} }
static int rt2x00usb_dma_timeout(struct data_queue *queue) static int rt2x00usb_dma_timeout(struct data_queue *queue)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment