]> git.proxmox.com Git - mirror_ubuntu-artful-kernel.git/blobdiff - drivers/net/wireless/rt2x00/rt2x00mac.c
rt2x00: Implement flush callback
[mirror_ubuntu-artful-kernel.git] / drivers / net / wireless / rt2x00 / rt2x00mac.c
index c3c206a97d54c608da497256a7fcadd44293d9df..283a8d9874ee251a0ba0e1b8d0dfa1ca1e7d6068 100644 (file)
@@ -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);