]> 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 235e037e65092045d07db64893b7cbdaa29b5785..283a8d9874ee251a0ba0e1b8d0dfa1ca1e7d6068 100644 (file)
@@ -669,8 +669,10 @@ void rt2x00mac_bss_info_changed(struct ieee80211_hw *hw,
         * When the erp information has changed, we should perform
         * additional configuration steps. For all other changes we are done.
         */
-       if (changes & ~(BSS_CHANGED_ASSOC | BSS_CHANGED_HT))
-               rt2x00lib_config_erp(rt2x00dev, intf, bss_conf);
+       if (changes & (BSS_CHANGED_ERP_CTS_PROT | BSS_CHANGED_ERP_PREAMBLE |
+                      BSS_CHANGED_ERP_SLOT | BSS_CHANGED_BASIC_RATES |
+                      BSS_CHANGED_BEACON_INT | BSS_CHANGED_HT))
+               rt2x00lib_config_erp(rt2x00dev, intf, bss_conf, changes);
 }
 EXPORT_SYMBOL_GPL(rt2x00mac_bss_info_changed);
 
@@ -717,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);