diff options
author | Ivo van Doorn <ivdoorn@gmail.com> | 2010-11-04 20:40:11 +0100 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2010-11-15 13:26:04 -0500 |
commit | f44df18c58d4debe3ec0bb76a490aa2f3929fd8b (patch) | |
tree | 9085f6c5eefc694bb5c5d05e0bc3bb356021afeb /drivers/net/wireless/rt2x00/rt2x00mac.c | |
parent | aaf886bd215396f295bc0489e8ae09d1c03d9aa0 (diff) |
rt2x00: Implement flush callback
Implement a basic flush callback function, which simply loops
over all TX queues and waits until all frames have been transmitted
and the status reports have been gathered.
At this moment we don't support dropping any frames during the
flush, but mac80211 will only send 'false' for this argument anyway,
so this is not important at this time.
Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com>
Acked-by: Helmut Schaa <helmut.schaa@googlemail.com>
Acked-by: Gertjan van Wingerde <gwingerde@gmail.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/rt2x00/rt2x00mac.c')
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2x00mac.c | 38 |
1 files changed, 38 insertions, 0 deletions
diff --git a/drivers/net/wireless/rt2x00/rt2x00mac.c b/drivers/net/wireless/rt2x00/rt2x00mac.c index c3c206a97d5..283a8d9874e 100644 --- a/drivers/net/wireless/rt2x00/rt2x00mac.c +++ b/drivers/net/wireless/rt2x00/rt2x00mac.c @@ -719,3 +719,41 @@ void rt2x00mac_rfkill_poll(struct ieee80211_hw *hw) wiphy_rfkill_set_hw_state(hw->wiphy, !active); } EXPORT_SYMBOL_GPL(rt2x00mac_rfkill_poll); + +void rt2x00mac_flush(struct ieee80211_hw *hw, bool drop) +{ + struct rt2x00_dev *rt2x00dev = hw->priv; + struct data_queue *queue; + unsigned int i = 0; + + ieee80211_stop_queues(hw); + + /* + * Run over all queues to kick them, this will force + * any pending frames to be transmitted. + */ + tx_queue_for_each(rt2x00dev, queue) { + rt2x00dev->ops->lib->kick_tx_queue(queue); + } + + /** + * All queues have been kicked, now wait for each queue + * to become empty. With a bit of luck, we only have to wait + * for the first queue to become empty, because while waiting + * for the that queue, the other queues will have transmitted + * all their frames as well (since they were already kicked). + */ + tx_queue_for_each(rt2x00dev, queue) { + for (i = 0; i < 10; i++) { + if (rt2x00queue_empty(queue)) + break; + msleep(100); + } + + if (!rt2x00queue_empty(queue)) + WARNING(rt2x00dev, "Failed to flush queue %d", queue->qid); + } + + ieee80211_wake_queues(hw); +} +EXPORT_SYMBOL_GPL(rt2x00mac_flush); |