diff options
32 files changed, 208 insertions, 123 deletions
diff --git a/drivers/net/wireless/at76c50x-usb.c b/drivers/net/wireless/at76c50x-usb.c index aff09a1cf64f..7218dbabad3e 100644 --- a/drivers/net/wireless/at76c50x-usb.c +++ b/drivers/net/wireless/at76c50x-usb.c | |||
@@ -1875,8 +1875,8 @@ static void at76_dwork_hw_scan(struct work_struct *work) | |||
1875 | /* FIXME: add maximum time for scan to complete */ | 1875 | /* FIXME: add maximum time for scan to complete */ |
1876 | 1876 | ||
1877 | if (ret != CMD_STATUS_COMPLETE) { | 1877 | if (ret != CMD_STATUS_COMPLETE) { |
1878 | queue_delayed_work(priv->hw->workqueue, &priv->dwork_hw_scan, | 1878 | ieee80211_queue_delayed_work(priv->hw, &priv->dwork_hw_scan, |
1879 | SCAN_POLL_INTERVAL); | 1879 | SCAN_POLL_INTERVAL); |
1880 | mutex_unlock(&priv->mtx); | 1880 | mutex_unlock(&priv->mtx); |
1881 | return; | 1881 | return; |
1882 | } | 1882 | } |
@@ -1937,8 +1937,8 @@ static int at76_hw_scan(struct ieee80211_hw *hw, | |||
1937 | goto exit; | 1937 | goto exit; |
1938 | } | 1938 | } |
1939 | 1939 | ||
1940 | queue_delayed_work(priv->hw->workqueue, &priv->dwork_hw_scan, | 1940 | ieee80211_queue_delayed_work(priv->hw, &priv->dwork_hw_scan, |
1941 | SCAN_POLL_INTERVAL); | 1941 | SCAN_POLL_INTERVAL); |
1942 | 1942 | ||
1943 | exit: | 1943 | exit: |
1944 | mutex_unlock(&priv->mtx); | 1944 | mutex_unlock(&priv->mtx); |
@@ -2027,7 +2027,7 @@ static void at76_configure_filter(struct ieee80211_hw *hw, | |||
2027 | } else | 2027 | } else |
2028 | return; | 2028 | return; |
2029 | 2029 | ||
2030 | queue_work(hw->workqueue, &priv->work_set_promisc); | 2030 | ieee80211_queue_work(hw, &priv->work_set_promisc); |
2031 | } | 2031 | } |
2032 | 2032 | ||
2033 | static int at76_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, | 2033 | static int at76_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, |
diff --git a/drivers/net/wireless/ath/ar9170/led.c b/drivers/net/wireless/ath/ar9170/led.c index 63fda6cd2101..86c4e79f6bc8 100644 --- a/drivers/net/wireless/ath/ar9170/led.c +++ b/drivers/net/wireless/ath/ar9170/led.c | |||
@@ -90,9 +90,12 @@ static void ar9170_update_leds(struct work_struct *work) | |||
90 | ar9170_set_leds_state(ar, led_val); | 90 | ar9170_set_leds_state(ar, led_val); |
91 | mutex_unlock(&ar->mutex); | 91 | mutex_unlock(&ar->mutex); |
92 | 92 | ||
93 | if (rerun) | 93 | if (!rerun) |
94 | queue_delayed_work(ar->hw->workqueue, &ar->led_work, | 94 | return; |
95 | msecs_to_jiffies(blink_delay)); | 95 | |
96 | ieee80211_queue_delayed_work(ar->hw, | ||
97 | &ar->led_work, | ||
98 | msecs_to_jiffies(blink_delay)); | ||
96 | } | 99 | } |
97 | 100 | ||
98 | static void ar9170_led_brightness_set(struct led_classdev *led, | 101 | static void ar9170_led_brightness_set(struct led_classdev *led, |
@@ -110,7 +113,7 @@ static void ar9170_led_brightness_set(struct led_classdev *led, | |||
110 | } | 113 | } |
111 | 114 | ||
112 | if (likely(IS_ACCEPTING_CMD(ar) && arl->toggled)) | 115 | if (likely(IS_ACCEPTING_CMD(ar) && arl->toggled)) |
113 | queue_delayed_work(ar->hw->workqueue, &ar->led_work, HZ/10); | 116 | ieee80211_queue_delayed_work(ar->hw, &ar->led_work, HZ/10); |
114 | } | 117 | } |
115 | 118 | ||
116 | static int ar9170_register_led(struct ar9170 *ar, int i, char *name, | 119 | static int ar9170_register_led(struct ar9170 *ar, int i, char *name, |
diff --git a/drivers/net/wireless/ath/ar9170/main.c b/drivers/net/wireless/ath/ar9170/main.c index 099ed3c3ba28..4fc389ae74b4 100644 --- a/drivers/net/wireless/ath/ar9170/main.c +++ b/drivers/net/wireless/ath/ar9170/main.c | |||
@@ -595,10 +595,12 @@ static void ar9170_tx_janitor(struct work_struct *work) | |||
595 | 595 | ||
596 | ar9170_tx_fake_ampdu_status(ar); | 596 | ar9170_tx_fake_ampdu_status(ar); |
597 | 597 | ||
598 | if (resched) | 598 | if (!resched) |
599 | queue_delayed_work(ar->hw->workqueue, | 599 | return; |
600 | &ar->tx_janitor, | 600 | |
601 | msecs_to_jiffies(AR9170_JANITOR_DELAY)); | 601 | ieee80211_queue_delayed_work(ar->hw, |
602 | &ar->tx_janitor, | ||
603 | msecs_to_jiffies(AR9170_JANITOR_DELAY)); | ||
602 | } | 604 | } |
603 | 605 | ||
604 | void ar9170_handle_command_response(struct ar9170 *ar, void *buf, u32 len) | 606 | void ar9170_handle_command_response(struct ar9170 *ar, void *buf, u32 len) |
@@ -648,7 +650,7 @@ void ar9170_handle_command_response(struct ar9170 *ar, void *buf, u32 len) | |||
648 | * pre-TBTT event | 650 | * pre-TBTT event |
649 | */ | 651 | */ |
650 | if (ar->vif && ar->vif->type == NL80211_IFTYPE_AP) | 652 | if (ar->vif && ar->vif->type == NL80211_IFTYPE_AP) |
651 | queue_work(ar->hw->workqueue, &ar->beacon_work); | 653 | ieee80211_queue_work(ar->hw, &ar->beacon_work); |
652 | break; | 654 | break; |
653 | 655 | ||
654 | case 0xc2: | 656 | case 0xc2: |
@@ -1825,10 +1827,12 @@ static void ar9170_tx(struct ar9170 *ar) | |||
1825 | } | 1827 | } |
1826 | } | 1828 | } |
1827 | 1829 | ||
1828 | if (schedule_garbagecollector) | 1830 | if (!schedule_garbagecollector) |
1829 | queue_delayed_work(ar->hw->workqueue, | 1831 | return; |
1830 | &ar->tx_janitor, | 1832 | |
1831 | msecs_to_jiffies(AR9170_JANITOR_DELAY)); | 1833 | ieee80211_queue_delayed_work(ar->hw, |
1834 | &ar->tx_janitor, | ||
1835 | msecs_to_jiffies(AR9170_JANITOR_DELAY)); | ||
1832 | } | 1836 | } |
1833 | 1837 | ||
1834 | static bool ar9170_tx_ampdu_queue(struct ar9170 *ar, struct sk_buff *skb) | 1838 | static bool ar9170_tx_ampdu_queue(struct ar9170 *ar, struct sk_buff *skb) |
@@ -2157,7 +2161,7 @@ static void ar9170_op_configure_filter(struct ieee80211_hw *hw, | |||
2157 | } | 2161 | } |
2158 | 2162 | ||
2159 | if (likely(IS_STARTED(ar))) | 2163 | if (likely(IS_STARTED(ar))) |
2160 | queue_work(ar->hw->workqueue, &ar->filter_config_work); | 2164 | ieee80211_queue_work(ar->hw, &ar->filter_config_work); |
2161 | } | 2165 | } |
2162 | 2166 | ||
2163 | static void ar9170_op_bss_info_changed(struct ieee80211_hw *hw, | 2167 | static void ar9170_op_bss_info_changed(struct ieee80211_hw *hw, |
@@ -2415,7 +2419,7 @@ static void ar9170_sta_notify(struct ieee80211_hw *hw, | |||
2415 | } | 2419 | } |
2416 | 2420 | ||
2417 | if (IS_STARTED(ar) && ar->filter_changed) | 2421 | if (IS_STARTED(ar) && ar->filter_changed) |
2418 | queue_work(ar->hw->workqueue, &ar->filter_config_work); | 2422 | ieee80211_queue_work(ar->hw, &ar->filter_config_work); |
2419 | } | 2423 | } |
2420 | 2424 | ||
2421 | static int ar9170_get_stats(struct ieee80211_hw *hw, | 2425 | static int ar9170_get_stats(struct ieee80211_hw *hw, |
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index cf44623b5cd2..292ac2b41891 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c | |||
@@ -973,10 +973,11 @@ static void ath_led_blink_work(struct work_struct *work) | |||
973 | ath9k_hw_set_gpio(sc->sc_ah, ATH_LED_PIN, | 973 | ath9k_hw_set_gpio(sc->sc_ah, ATH_LED_PIN, |
974 | (sc->sc_flags & SC_OP_LED_ON) ? 1 : 0); | 974 | (sc->sc_flags & SC_OP_LED_ON) ? 1 : 0); |
975 | 975 | ||
976 | queue_delayed_work(sc->hw->workqueue, &sc->ath_led_blink_work, | 976 | ieee80211_queue_delayed_work(sc->hw, |
977 | (sc->sc_flags & SC_OP_LED_ON) ? | 977 | &sc->ath_led_blink_work, |
978 | msecs_to_jiffies(sc->led_off_duration) : | 978 | (sc->sc_flags & SC_OP_LED_ON) ? |
979 | msecs_to_jiffies(sc->led_on_duration)); | 979 | msecs_to_jiffies(sc->led_off_duration) : |
980 | msecs_to_jiffies(sc->led_on_duration)); | ||
980 | 981 | ||
981 | sc->led_on_duration = sc->led_on_cnt ? | 982 | sc->led_on_duration = sc->led_on_cnt ? |
982 | max((ATH_LED_ON_DURATION_IDLE - sc->led_on_cnt), 25) : | 983 | max((ATH_LED_ON_DURATION_IDLE - sc->led_on_cnt), 25) : |
@@ -1013,8 +1014,8 @@ static void ath_led_brightness(struct led_classdev *led_cdev, | |||
1013 | case LED_FULL: | 1014 | case LED_FULL: |
1014 | if (led->led_type == ATH_LED_ASSOC) { | 1015 | if (led->led_type == ATH_LED_ASSOC) { |
1015 | sc->sc_flags |= SC_OP_LED_ASSOCIATED; | 1016 | sc->sc_flags |= SC_OP_LED_ASSOCIATED; |
1016 | queue_delayed_work(sc->hw->workqueue, | 1017 | ieee80211_queue_delayed_work(sc->hw, |
1017 | &sc->ath_led_blink_work, 0); | 1018 | &sc->ath_led_blink_work, 0); |
1018 | } else if (led->led_type == ATH_LED_RADIO) { | 1019 | } else if (led->led_type == ATH_LED_RADIO) { |
1019 | ath9k_hw_set_gpio(sc->sc_ah, ATH_LED_PIN, 0); | 1020 | ath9k_hw_set_gpio(sc->sc_ah, ATH_LED_PIN, 0); |
1020 | sc->sc_flags |= SC_OP_LED_ON; | 1021 | sc->sc_flags |= SC_OP_LED_ON; |
@@ -1972,7 +1973,7 @@ static int ath9k_start(struct ieee80211_hw *hw) | |||
1972 | 1973 | ||
1973 | ieee80211_wake_queues(hw); | 1974 | ieee80211_wake_queues(hw); |
1974 | 1975 | ||
1975 | queue_delayed_work(sc->hw->workqueue, &sc->tx_complete_work, 0); | 1976 | ieee80211_queue_delayed_work(sc->hw, &sc->tx_complete_work, 0); |
1976 | 1977 | ||
1977 | mutex_unlock: | 1978 | mutex_unlock: |
1978 | mutex_unlock(&sc->mutex); | 1979 | mutex_unlock(&sc->mutex); |
diff --git a/drivers/net/wireless/ath/ath9k/virtual.c b/drivers/net/wireless/ath/ath9k/virtual.c index e1d419e02b4a..19b88f8177fd 100644 --- a/drivers/net/wireless/ath/ath9k/virtual.c +++ b/drivers/net/wireless/ath/ath9k/virtual.c | |||
@@ -351,7 +351,7 @@ void ath9k_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
351 | * Drop from tasklet to work to allow mutex for channel | 351 | * Drop from tasklet to work to allow mutex for channel |
352 | * change. | 352 | * change. |
353 | */ | 353 | */ |
354 | queue_work(aphy->sc->hw->workqueue, | 354 | ieee80211_queue_work(aphy->sc->hw, |
355 | &aphy->sc->chan_work); | 355 | &aphy->sc->chan_work); |
356 | } | 356 | } |
357 | } | 357 | } |
@@ -367,7 +367,7 @@ static void ath9k_mark_paused(struct ath_wiphy *aphy) | |||
367 | struct ath_softc *sc = aphy->sc; | 367 | struct ath_softc *sc = aphy->sc; |
368 | aphy->state = ATH_WIPHY_PAUSED; | 368 | aphy->state = ATH_WIPHY_PAUSED; |
369 | if (!__ath9k_wiphy_pausing(sc)) | 369 | if (!__ath9k_wiphy_pausing(sc)) |
370 | queue_work(sc->hw->workqueue, &sc->chan_work); | 370 | ieee80211_queue_work(sc->hw, &sc->chan_work); |
371 | } | 371 | } |
372 | 372 | ||
373 | static void ath9k_pause_iter(void *data, u8 *mac, struct ieee80211_vif *vif) | 373 | static void ath9k_pause_iter(void *data, u8 *mac, struct ieee80211_vif *vif) |
@@ -521,7 +521,7 @@ int ath9k_wiphy_select(struct ath_wiphy *aphy) | |||
521 | spin_unlock_bh(&sc->wiphy_lock); | 521 | spin_unlock_bh(&sc->wiphy_lock); |
522 | ath_radio_disable(sc); | 522 | ath_radio_disable(sc); |
523 | ath_radio_enable(sc); | 523 | ath_radio_enable(sc); |
524 | queue_work(aphy->sc->hw->workqueue, | 524 | ieee80211_queue_work(aphy->sc->hw, |
525 | &aphy->sc->chan_work); | 525 | &aphy->sc->chan_work); |
526 | return -EBUSY; /* previous select still in progress */ | 526 | return -EBUSY; /* previous select still in progress */ |
527 | } | 527 | } |
@@ -541,7 +541,7 @@ int ath9k_wiphy_select(struct ath_wiphy *aphy) | |||
541 | 541 | ||
542 | if (now) { | 542 | if (now) { |
543 | /* Ready to request channel change immediately */ | 543 | /* Ready to request channel change immediately */ |
544 | queue_work(aphy->sc->hw->workqueue, &aphy->sc->chan_work); | 544 | ieee80211_queue_work(aphy->sc->hw, &aphy->sc->chan_work); |
545 | } | 545 | } |
546 | 546 | ||
547 | /* | 547 | /* |
@@ -648,8 +648,9 @@ try_again: | |||
648 | "change\n"); | 648 | "change\n"); |
649 | } | 649 | } |
650 | 650 | ||
651 | queue_delayed_work(sc->hw->workqueue, &sc->wiphy_work, | 651 | ieee80211_queue_delayed_work(sc->hw, |
652 | sc->wiphy_scheduler_int); | 652 | &sc->wiphy_work, |
653 | sc->wiphy_scheduler_int); | ||
653 | } | 654 | } |
654 | 655 | ||
655 | void ath9k_wiphy_set_scheduler(struct ath_softc *sc, unsigned int msec_int) | 656 | void ath9k_wiphy_set_scheduler(struct ath_softc *sc, unsigned int msec_int) |
@@ -657,8 +658,8 @@ void ath9k_wiphy_set_scheduler(struct ath_softc *sc, unsigned int msec_int) | |||
657 | cancel_delayed_work_sync(&sc->wiphy_work); | 658 | cancel_delayed_work_sync(&sc->wiphy_work); |
658 | sc->wiphy_scheduler_int = msecs_to_jiffies(msec_int); | 659 | sc->wiphy_scheduler_int = msecs_to_jiffies(msec_int); |
659 | if (sc->wiphy_scheduler_int) | 660 | if (sc->wiphy_scheduler_int) |
660 | queue_delayed_work(sc->hw->workqueue, &sc->wiphy_work, | 661 | ieee80211_queue_delayed_work(sc->hw, &sc->wiphy_work, |
661 | sc->wiphy_scheduler_int); | 662 | sc->wiphy_scheduler_int); |
662 | } | 663 | } |
663 | 664 | ||
664 | /* caller must hold wiphy_lock */ | 665 | /* caller must hold wiphy_lock */ |
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index b7806e2ca0e1..87762da0383b 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c | |||
@@ -2063,7 +2063,7 @@ static void ath_tx_complete_poll_work(struct work_struct *work) | |||
2063 | ath_reset(sc, false); | 2063 | ath_reset(sc, false); |
2064 | } | 2064 | } |
2065 | 2065 | ||
2066 | queue_delayed_work(sc->hw->workqueue, &sc->tx_complete_work, | 2066 | ieee80211_queue_delayed_work(sc->hw, &sc->tx_complete_work, |
2067 | msecs_to_jiffies(ATH_TX_COMPLETE_POLL_INT)); | 2067 | msecs_to_jiffies(ATH_TX_COMPLETE_POLL_INT)); |
2068 | } | 2068 | } |
2069 | 2069 | ||
diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c index 3f4360ad0e4e..f985938962e3 100644 --- a/drivers/net/wireless/b43/main.c +++ b/drivers/net/wireless/b43/main.c | |||
@@ -1654,7 +1654,7 @@ static void b43_update_templates(struct b43_wl *wl) | |||
1654 | wl->current_beacon = beacon; | 1654 | wl->current_beacon = beacon; |
1655 | wl->beacon0_uploaded = 0; | 1655 | wl->beacon0_uploaded = 0; |
1656 | wl->beacon1_uploaded = 0; | 1656 | wl->beacon1_uploaded = 0; |
1657 | queue_work(wl->hw->workqueue, &wl->beacon_update_trigger); | 1657 | ieee80211_queue_work(wl->hw, &wl->beacon_update_trigger); |
1658 | } | 1658 | } |
1659 | 1659 | ||
1660 | static void b43_set_beacon_int(struct b43_wldev *dev, u16 beacon_int) | 1660 | static void b43_set_beacon_int(struct b43_wldev *dev, u16 beacon_int) |
@@ -2914,7 +2914,7 @@ out_requeue: | |||
2914 | delay = msecs_to_jiffies(50); | 2914 | delay = msecs_to_jiffies(50); |
2915 | else | 2915 | else |
2916 | delay = round_jiffies_relative(HZ * 15); | 2916 | delay = round_jiffies_relative(HZ * 15); |
2917 | queue_delayed_work(wl->hw->workqueue, &dev->periodic_work, delay); | 2917 | ieee80211_queue_delayed_work(wl->hw, &dev->periodic_work, delay); |
2918 | out: | 2918 | out: |
2919 | mutex_unlock(&wl->mutex); | 2919 | mutex_unlock(&wl->mutex); |
2920 | } | 2920 | } |
@@ -2925,7 +2925,7 @@ static void b43_periodic_tasks_setup(struct b43_wldev *dev) | |||
2925 | 2925 | ||
2926 | dev->periodic_state = 0; | 2926 | dev->periodic_state = 0; |
2927 | INIT_DELAYED_WORK(work, b43_periodic_work_handler); | 2927 | INIT_DELAYED_WORK(work, b43_periodic_work_handler); |
2928 | queue_delayed_work(dev->wl->hw->workqueue, work, 0); | 2928 | ieee80211_queue_delayed_work(dev->wl->hw, work, 0); |
2929 | } | 2929 | } |
2930 | 2930 | ||
2931 | /* Check if communication with the device works correctly. */ | 2931 | /* Check if communication with the device works correctly. */ |
@@ -4871,7 +4871,7 @@ void b43_controller_restart(struct b43_wldev *dev, const char *reason) | |||
4871 | if (b43_status(dev) < B43_STAT_INITIALIZED) | 4871 | if (b43_status(dev) < B43_STAT_INITIALIZED) |
4872 | return; | 4872 | return; |
4873 | b43info(dev->wl, "Controller RESET (%s) ...\n", reason); | 4873 | b43info(dev->wl, "Controller RESET (%s) ...\n", reason); |
4874 | queue_work(dev->wl->hw->workqueue, &dev->restart_work); | 4874 | ieee80211_queue_work(dev->wl->hw, &dev->restart_work); |
4875 | } | 4875 | } |
4876 | 4876 | ||
4877 | #ifdef CONFIG_PM | 4877 | #ifdef CONFIG_PM |
diff --git a/drivers/net/wireless/b43/phy_common.c b/drivers/net/wireless/b43/phy_common.c index 6d241622210e..f537bfef690a 100644 --- a/drivers/net/wireless/b43/phy_common.c +++ b/drivers/net/wireless/b43/phy_common.c | |||
@@ -352,7 +352,7 @@ void b43_phy_txpower_check(struct b43_wldev *dev, unsigned int flags) | |||
352 | 352 | ||
353 | /* We must adjust the transmission power in hardware. | 353 | /* We must adjust the transmission power in hardware. |
354 | * Schedule b43_phy_txpower_adjust_work(). */ | 354 | * Schedule b43_phy_txpower_adjust_work(). */ |
355 | queue_work(dev->wl->hw->workqueue, &dev->wl->txpower_adjust_work); | 355 | ieee80211_queue_work(dev->wl->hw, &dev->wl->txpower_adjust_work); |
356 | } | 356 | } |
357 | 357 | ||
358 | int b43_phy_shm_tssi_read(struct b43_wldev *dev, u16 shm_offset) | 358 | int b43_phy_shm_tssi_read(struct b43_wldev *dev, u16 shm_offset) |
diff --git a/drivers/net/wireless/b43/pio.c b/drivers/net/wireless/b43/pio.c index 69138e8c1db6..73c047d8de40 100644 --- a/drivers/net/wireless/b43/pio.c +++ b/drivers/net/wireless/b43/pio.c | |||
@@ -783,7 +783,7 @@ void b43_pio_rx(struct b43_pio_rxqueue *q) | |||
783 | { | 783 | { |
784 | /* Due to latency issues we must run the RX path in | 784 | /* Due to latency issues we must run the RX path in |
785 | * a workqueue to be able to schedule between packets. */ | 785 | * a workqueue to be able to schedule between packets. */ |
786 | queue_work(q->dev->wl->hw->workqueue, &q->rx_work); | 786 | ieee80211_queue_work(q->dev->wl->hw, &q->rx_work); |
787 | } | 787 | } |
788 | 788 | ||
789 | static void b43_pio_tx_suspend_queue(struct b43_pio_txqueue *q) | 789 | static void b43_pio_tx_suspend_queue(struct b43_pio_txqueue *q) |
diff --git a/drivers/net/wireless/b43legacy/main.c b/drivers/net/wireless/b43legacy/main.c index c4973c1942bf..b1435594921a 100644 --- a/drivers/net/wireless/b43legacy/main.c +++ b/drivers/net/wireless/b43legacy/main.c | |||
@@ -1252,7 +1252,7 @@ static void b43legacy_update_templates(struct b43legacy_wl *wl) | |||
1252 | wl->current_beacon = beacon; | 1252 | wl->current_beacon = beacon; |
1253 | wl->beacon0_uploaded = 0; | 1253 | wl->beacon0_uploaded = 0; |
1254 | wl->beacon1_uploaded = 0; | 1254 | wl->beacon1_uploaded = 0; |
1255 | queue_work(wl->hw->workqueue, &wl->beacon_update_trigger); | 1255 | ieee80211_queue_work(wl->hw, &wl->beacon_update_trigger); |
1256 | } | 1256 | } |
1257 | 1257 | ||
1258 | static void b43legacy_set_beacon_int(struct b43legacy_wldev *dev, | 1258 | static void b43legacy_set_beacon_int(struct b43legacy_wldev *dev, |
@@ -2300,7 +2300,7 @@ out_requeue: | |||
2300 | delay = msecs_to_jiffies(50); | 2300 | delay = msecs_to_jiffies(50); |
2301 | else | 2301 | else |
2302 | delay = round_jiffies_relative(HZ * 15); | 2302 | delay = round_jiffies_relative(HZ * 15); |
2303 | queue_delayed_work(wl->hw->workqueue, &dev->periodic_work, delay); | 2303 | ieee80211_queue_delayed_work(wl->hw, &dev->periodic_work, delay); |
2304 | out: | 2304 | out: |
2305 | mutex_unlock(&wl->mutex); | 2305 | mutex_unlock(&wl->mutex); |
2306 | } | 2306 | } |
@@ -2311,7 +2311,7 @@ static void b43legacy_periodic_tasks_setup(struct b43legacy_wldev *dev) | |||
2311 | 2311 | ||
2312 | dev->periodic_state = 0; | 2312 | dev->periodic_state = 0; |
2313 | INIT_DELAYED_WORK(work, b43legacy_periodic_work_handler); | 2313 | INIT_DELAYED_WORK(work, b43legacy_periodic_work_handler); |
2314 | queue_delayed_work(dev->wl->hw->workqueue, work, 0); | 2314 | ieee80211_queue_delayed_work(dev->wl->hw, work, 0); |
2315 | } | 2315 | } |
2316 | 2316 | ||
2317 | /* Validate access to the chip (SHM) */ | 2317 | /* Validate access to the chip (SHM) */ |
@@ -3885,7 +3885,7 @@ void b43legacy_controller_restart(struct b43legacy_wldev *dev, | |||
3885 | if (b43legacy_status(dev) < B43legacy_STAT_INITIALIZED) | 3885 | if (b43legacy_status(dev) < B43legacy_STAT_INITIALIZED) |
3886 | return; | 3886 | return; |
3887 | b43legacyinfo(dev->wl, "Controller RESET (%s) ...\n", reason); | 3887 | b43legacyinfo(dev->wl, "Controller RESET (%s) ...\n", reason); |
3888 | queue_work(dev->wl->hw->workqueue, &dev->restart_work); | 3888 | ieee80211_queue_work(dev->wl->hw, &dev->restart_work); |
3889 | } | 3889 | } |
3890 | 3890 | ||
3891 | #ifdef CONFIG_PM | 3891 | #ifdef CONFIG_PM |
diff --git a/drivers/net/wireless/p54/led.c b/drivers/net/wireless/p54/led.c index c00115b206d4..9575ac033630 100644 --- a/drivers/net/wireless/p54/led.c +++ b/drivers/net/wireless/p54/led.c | |||
@@ -61,7 +61,7 @@ static void p54_update_leds(struct work_struct *work) | |||
61 | wiphy_name(priv->hw->wiphy), err); | 61 | wiphy_name(priv->hw->wiphy), err); |
62 | 62 | ||
63 | if (rerun) | 63 | if (rerun) |
64 | queue_delayed_work(priv->hw->workqueue, &priv->led_work, | 64 | ieee80211_queue_delayed_work(priv->hw, &priv->led_work, |
65 | msecs_to_jiffies(blink_delay)); | 65 | msecs_to_jiffies(blink_delay)); |
66 | } | 66 | } |
67 | 67 | ||
@@ -78,8 +78,7 @@ static void p54_led_brightness_set(struct led_classdev *led_dev, | |||
78 | 78 | ||
79 | if ((brightness) && (led->registered)) { | 79 | if ((brightness) && (led->registered)) { |
80 | led->toggled++; | 80 | led->toggled++; |
81 | queue_delayed_work(priv->hw->workqueue, &priv->led_work, | 81 | ieee80211_queue_delayed_work(priv->hw, &priv->led_work, HZ/10); |
82 | HZ/10); | ||
83 | } | 82 | } |
84 | } | 83 | } |
85 | 84 | ||
diff --git a/drivers/net/wireless/p54/main.c b/drivers/net/wireless/p54/main.c index 955f6d7ec16a..a0d0e726bc4e 100644 --- a/drivers/net/wireless/p54/main.c +++ b/drivers/net/wireless/p54/main.c | |||
@@ -180,7 +180,7 @@ static int p54_start(struct ieee80211_hw *dev) | |||
180 | goto out; | 180 | goto out; |
181 | } | 181 | } |
182 | 182 | ||
183 | queue_delayed_work(dev->workqueue, &priv->work, 0); | 183 | ieee80211_queue_delayed_work(dev, &priv->work, 0); |
184 | 184 | ||
185 | priv->softled_state = 0; | 185 | priv->softled_state = 0; |
186 | err = p54_set_leds(priv); | 186 | err = p54_set_leds(priv); |
diff --git a/drivers/net/wireless/p54/p54spi.c b/drivers/net/wireless/p54/p54spi.c index eef532987d05..05458d9249ce 100644 --- a/drivers/net/wireless/p54/p54spi.c +++ b/drivers/net/wireless/p54/p54spi.c | |||
@@ -391,7 +391,7 @@ static irqreturn_t p54spi_interrupt(int irq, void *config) | |||
391 | struct spi_device *spi = config; | 391 | struct spi_device *spi = config; |
392 | struct p54s_priv *priv = dev_get_drvdata(&spi->dev); | 392 | struct p54s_priv *priv = dev_get_drvdata(&spi->dev); |
393 | 393 | ||
394 | queue_work(priv->hw->workqueue, &priv->work); | 394 | ieee80211_queue_work(priv->hw, &priv->work); |
395 | 395 | ||
396 | return IRQ_HANDLED; | 396 | return IRQ_HANDLED; |
397 | } | 397 | } |
@@ -479,7 +479,7 @@ static void p54spi_op_tx(struct ieee80211_hw *dev, struct sk_buff *skb) | |||
479 | list_add_tail(&di->tx_list, &priv->tx_pending); | 479 | list_add_tail(&di->tx_list, &priv->tx_pending); |
480 | spin_unlock_irqrestore(&priv->tx_lock, flags); | 480 | spin_unlock_irqrestore(&priv->tx_lock, flags); |
481 | 481 | ||
482 | queue_work(priv->hw->workqueue, &priv->work); | 482 | ieee80211_queue_work(priv->hw, &priv->work); |
483 | } | 483 | } |
484 | 484 | ||
485 | static void p54spi_work(struct work_struct *work) | 485 | static void p54spi_work(struct work_struct *work) |
diff --git a/drivers/net/wireless/p54/txrx.c b/drivers/net/wireless/p54/txrx.c index c32a0d2fa1f7..704685fab177 100644 --- a/drivers/net/wireless/p54/txrx.c +++ b/drivers/net/wireless/p54/txrx.c | |||
@@ -380,7 +380,7 @@ static int p54_rx_data(struct p54_common *priv, struct sk_buff *skb) | |||
380 | 380 | ||
381 | ieee80211_rx_irqsafe(priv->hw, skb); | 381 | ieee80211_rx_irqsafe(priv->hw, skb); |
382 | 382 | ||
383 | queue_delayed_work(priv->hw->workqueue, &priv->work, | 383 | ieee80211_queue_delayed_work(priv->hw, &priv->work, |
384 | msecs_to_jiffies(P54_STATISTICS_UPDATE)); | 384 | msecs_to_jiffies(P54_STATISTICS_UPDATE)); |
385 | 385 | ||
386 | return -1; | 386 | return -1; |
diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c index 658a63bfb761..b717afbf3f38 100644 --- a/drivers/net/wireless/rt2x00/rt2x00dev.c +++ b/drivers/net/wireless/rt2x00/rt2x00dev.c | |||
@@ -215,7 +215,7 @@ void rt2x00lib_beacondone(struct rt2x00_dev *rt2x00dev) | |||
215 | rt2x00lib_beacondone_iter, | 215 | rt2x00lib_beacondone_iter, |
216 | rt2x00dev); | 216 | rt2x00dev); |
217 | 217 | ||
218 | queue_work(rt2x00dev->hw->workqueue, &rt2x00dev->intf_work); | 218 | ieee80211_queue_work(rt2x00dev->hw, &rt2x00dev->intf_work); |
219 | } | 219 | } |
220 | EXPORT_SYMBOL_GPL(rt2x00lib_beacondone); | 220 | EXPORT_SYMBOL_GPL(rt2x00lib_beacondone); |
221 | 221 | ||
diff --git a/drivers/net/wireless/rt2x00/rt2x00link.c b/drivers/net/wireless/rt2x00/rt2x00link.c index 79915687e744..917831689ccd 100644 --- a/drivers/net/wireless/rt2x00/rt2x00link.c +++ b/drivers/net/wireless/rt2x00/rt2x00link.c | |||
@@ -351,8 +351,8 @@ void rt2x00link_start_tuner(struct rt2x00_dev *rt2x00dev) | |||
351 | 351 | ||
352 | rt2x00link_reset_tuner(rt2x00dev, false); | 352 | rt2x00link_reset_tuner(rt2x00dev, false); |
353 | 353 | ||
354 | queue_delayed_work(rt2x00dev->hw->workqueue, | 354 | ieee80211_queue_delayed_work(rt2x00dev->hw, |
355 | &link->work, LINK_TUNE_INTERVAL); | 355 | &link->work, LINK_TUNE_INTERVAL); |
356 | } | 356 | } |
357 | 357 | ||
358 | void rt2x00link_stop_tuner(struct rt2x00_dev *rt2x00dev) | 358 | void rt2x00link_stop_tuner(struct rt2x00_dev *rt2x00dev) |
@@ -461,8 +461,8 @@ static void rt2x00link_tuner(struct work_struct *work) | |||
461 | * Increase tuner counter, and reschedule the next link tuner run. | 461 | * Increase tuner counter, and reschedule the next link tuner run. |
462 | */ | 462 | */ |
463 | link->count++; | 463 | link->count++; |
464 | queue_delayed_work(rt2x00dev->hw->workqueue, | 464 | ieee80211_queue_delayed_work(rt2x00dev->hw, |
465 | &link->work, LINK_TUNE_INTERVAL); | 465 | &link->work, LINK_TUNE_INTERVAL); |
466 | } | 466 | } |
467 | 467 | ||
468 | void rt2x00link_register(struct rt2x00_dev *rt2x00dev) | 468 | void rt2x00link_register(struct rt2x00_dev *rt2x00dev) |
diff --git a/drivers/net/wireless/rt2x00/rt2x00mac.c b/drivers/net/wireless/rt2x00/rt2x00mac.c index e92c8f99d695..81febdfd6639 100644 --- a/drivers/net/wireless/rt2x00/rt2x00mac.c +++ b/drivers/net/wireless/rt2x00/rt2x00mac.c | |||
@@ -431,7 +431,7 @@ void rt2x00mac_configure_filter(struct ieee80211_hw *hw, | |||
431 | if (!test_bit(DRIVER_REQUIRE_SCHEDULED, &rt2x00dev->flags)) | 431 | if (!test_bit(DRIVER_REQUIRE_SCHEDULED, &rt2x00dev->flags)) |
432 | rt2x00dev->ops->lib->config_filter(rt2x00dev, *total_flags); | 432 | rt2x00dev->ops->lib->config_filter(rt2x00dev, *total_flags); |
433 | else | 433 | else |
434 | queue_work(rt2x00dev->hw->workqueue, &rt2x00dev->filter_work); | 434 | ieee80211_queue_work(rt2x00dev->hw, &rt2x00dev->filter_work); |
435 | } | 435 | } |
436 | EXPORT_SYMBOL_GPL(rt2x00mac_configure_filter); | 436 | EXPORT_SYMBOL_GPL(rt2x00mac_configure_filter); |
437 | 437 | ||
diff --git a/drivers/net/wireless/rtl818x/rtl8187_dev.c b/drivers/net/wireless/rtl818x/rtl8187_dev.c index c9b9dbe584c6..53f57dc52226 100644 --- a/drivers/net/wireless/rtl818x/rtl8187_dev.c +++ b/drivers/net/wireless/rtl818x/rtl8187_dev.c | |||
@@ -220,7 +220,7 @@ static void rtl8187_tx_cb(struct urb *urb) | |||
220 | * reading a register in the device. We are in interrupt mode | 220 | * reading a register in the device. We are in interrupt mode |
221 | * here, thus queue the skb and finish on a work queue. */ | 221 | * here, thus queue the skb and finish on a work queue. */ |
222 | skb_queue_tail(&priv->b_tx_status.queue, skb); | 222 | skb_queue_tail(&priv->b_tx_status.queue, skb); |
223 | queue_delayed_work(hw->workqueue, &priv->work, 0); | 223 | ieee80211_queue_delayed_work(hw, &priv->work, 0); |
224 | } | 224 | } |
225 | } | 225 | } |
226 | 226 | ||
diff --git a/drivers/net/wireless/rtl818x/rtl8187_leds.c b/drivers/net/wireless/rtl818x/rtl8187_leds.c index cf9f899fe0e6..a6cfb7e77994 100644 --- a/drivers/net/wireless/rtl818x/rtl8187_leds.c +++ b/drivers/net/wireless/rtl818x/rtl8187_leds.c | |||
@@ -108,11 +108,11 @@ static void rtl8187_led_brightness_set(struct led_classdev *led_dev, | |||
108 | struct rtl8187_priv *priv = hw->priv; | 108 | struct rtl8187_priv *priv = hw->priv; |
109 | 109 | ||
110 | if (brightness == LED_OFF) { | 110 | if (brightness == LED_OFF) { |
111 | queue_delayed_work(hw->workqueue, &priv->led_off, 0); | 111 | ieee80211_queue_delayed_work(hw, &priv->led_off, 0); |
112 | /* The LED is off for 1/20 sec so that it just blinks. */ | 112 | /* The LED is off for 1/20 sec so that it just blinks. */ |
113 | queue_delayed_work(hw->workqueue, &priv->led_on, HZ / 20); | 113 | ieee80211_queue_delayed_work(hw, &priv->led_on, HZ / 20); |
114 | } else | 114 | } else |
115 | queue_delayed_work(hw->workqueue, &priv->led_on, 0); | 115 | ieee80211_queue_delayed_work(hw, &priv->led_on, 0); |
116 | } | 116 | } |
117 | 117 | ||
118 | static int rtl8187_register_led(struct ieee80211_hw *dev, | 118 | static int rtl8187_register_led(struct ieee80211_hw *dev, |
@@ -193,7 +193,7 @@ void rtl8187_leds_init(struct ieee80211_hw *dev, u16 custid) | |||
193 | err = rtl8187_register_led(dev, &priv->led_rx, name, | 193 | err = rtl8187_register_led(dev, &priv->led_rx, name, |
194 | ieee80211_get_rx_led_name(dev), ledpin); | 194 | ieee80211_get_rx_led_name(dev), ledpin); |
195 | if (!err) { | 195 | if (!err) { |
196 | queue_delayed_work(dev->workqueue, &priv->led_on, 0); | 196 | ieee80211_queue_delayed_work(dev, &priv->led_on, 0); |
197 | return; | 197 | return; |
198 | } | 198 | } |
199 | /* registration of RX LED failed - unregister TX */ | 199 | /* registration of RX LED failed - unregister TX */ |
@@ -209,7 +209,7 @@ void rtl8187_leds_exit(struct ieee80211_hw *dev) | |||
209 | struct rtl8187_priv *priv = dev->priv; | 209 | struct rtl8187_priv *priv = dev->priv; |
210 | 210 | ||
211 | /* turn the LED off before exiting */ | 211 | /* turn the LED off before exiting */ |
212 | queue_delayed_work(dev->workqueue, &priv->led_off, 0); | 212 | ieee80211_queue_delayed_work(dev, &priv->led_off, 0); |
213 | cancel_delayed_work_sync(&priv->led_off); | 213 | cancel_delayed_work_sync(&priv->led_off); |
214 | cancel_delayed_work_sync(&priv->led_on); | 214 | cancel_delayed_work_sync(&priv->led_on); |
215 | rtl8187_unregister_led(&priv->led_rx); | 215 | rtl8187_unregister_led(&priv->led_rx); |
diff --git a/drivers/net/wireless/zd1211rw/zd_mac.c b/drivers/net/wireless/zd1211rw/zd_mac.c index 9600b72495da..54abdd0c0045 100644 --- a/drivers/net/wireless/zd1211rw/zd_mac.c +++ b/drivers/net/wireless/zd1211rw/zd_mac.c | |||
@@ -698,7 +698,7 @@ int zd_mac_rx(struct ieee80211_hw *hw, const u8 *buffer, unsigned int length) | |||
698 | && !mac->pass_ctrl) | 698 | && !mac->pass_ctrl) |
699 | return 0; | 699 | return 0; |
700 | 700 | ||
701 | fc = *(__le16 *)buffer; | 701 | fc = get_unaligned((__le16*)buffer); |
702 | need_padding = ieee80211_is_data_qos(fc) ^ ieee80211_has_a4(fc); | 702 | need_padding = ieee80211_is_data_qos(fc) ^ ieee80211_has_a4(fc); |
703 | 703 | ||
704 | skb = dev_alloc_skb(length + (need_padding ? 2 : 0)); | 704 | skb = dev_alloc_skb(length + (need_padding ? 2 : 0)); |
diff --git a/include/net/mac80211.h b/include/net/mac80211.h index d4e09a06b4a2..5ed93f4406a8 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h | |||
@@ -73,6 +73,21 @@ | |||
73 | */ | 73 | */ |
74 | 74 | ||
75 | /** | 75 | /** |
76 | * DOC: mac80211 workqueue | ||
77 | * | ||
78 | * mac80211 provides its own workqueue for drivers and internal mac80211 use. | ||
79 | * The workqueue is a single threaded workqueue and can only be accessed by | ||
80 | * helpers for sanity checking. Drivers must ensure all work added onto the | ||
81 | * mac80211 workqueue should be cancelled on the driver stop() callback. | ||
82 | * | ||
83 | * mac80211 will flushed the workqueue upon interface removal and during | ||
84 | * suspend. | ||
85 | * | ||
86 | * All work performed on the mac80211 workqueue must not acquire the RTNL lock. | ||
87 | * | ||
88 | */ | ||
89 | |||
90 | /** | ||
76 | * enum ieee80211_max_queues - maximum number of queues | 91 | * enum ieee80211_max_queues - maximum number of queues |
77 | * | 92 | * |
78 | * @IEEE80211_MAX_QUEUES: Maximum number of regular device queues. | 93 | * @IEEE80211_MAX_QUEUES: Maximum number of regular device queues. |
@@ -913,12 +928,6 @@ enum ieee80211_hw_flags { | |||
913 | * | 928 | * |
914 | * @conf: &struct ieee80211_conf, device configuration, don't use. | 929 | * @conf: &struct ieee80211_conf, device configuration, don't use. |
915 | * | 930 | * |
916 | * @workqueue: single threaded workqueue available for driver use, | ||
917 | * allocated by mac80211 on registration and flushed when an | ||
918 | * interface is removed. | ||
919 | * NOTICE: All work performed on this workqueue must not | ||
920 | * acquire the RTNL lock. | ||
921 | * | ||
922 | * @priv: pointer to private area that was allocated for driver use | 931 | * @priv: pointer to private area that was allocated for driver use |
923 | * along with this structure. | 932 | * along with this structure. |
924 | * | 933 | * |
@@ -954,7 +963,6 @@ enum ieee80211_hw_flags { | |||
954 | struct ieee80211_hw { | 963 | struct ieee80211_hw { |
955 | struct ieee80211_conf conf; | 964 | struct ieee80211_conf conf; |
956 | struct wiphy *wiphy; | 965 | struct wiphy *wiphy; |
957 | struct workqueue_struct *workqueue; | ||
958 | const char *rate_control_algorithm; | 966 | const char *rate_control_algorithm; |
959 | void *priv; | 967 | void *priv; |
960 | u32 flags; | 968 | u32 flags; |
@@ -1301,7 +1309,8 @@ enum ieee80211_ampdu_mlme_action { | |||
1301 | * is disabled. This should turn off the hardware (at least | 1309 | * is disabled. This should turn off the hardware (at least |
1302 | * it must turn off frame reception.) | 1310 | * it must turn off frame reception.) |
1303 | * May be called right after add_interface if that rejects | 1311 | * May be called right after add_interface if that rejects |
1304 | * an interface. | 1312 | * an interface. If you added any work onto the mac80211 workqueue |
1313 | * you should ensure to cancel it on this callback. | ||
1305 | * Must be implemented. | 1314 | * Must be implemented. |
1306 | * | 1315 | * |
1307 | * @add_interface: Called when a netdevice attached to the hardware is | 1316 | * @add_interface: Called when a netdevice attached to the hardware is |
@@ -1928,6 +1937,31 @@ void ieee80211_iterate_active_interfaces_atomic(struct ieee80211_hw *hw, | |||
1928 | void *data); | 1937 | void *data); |
1929 | 1938 | ||
1930 | /** | 1939 | /** |
1940 | * ieee80211_queue_work - add work onto the mac80211 workqueue | ||
1941 | * | ||
1942 | * Drivers and mac80211 use this to add work onto the mac80211 workqueue. | ||
1943 | * This helper ensures drivers are not queueing work when they should not be. | ||
1944 | * | ||
1945 | * @hw: the hardware struct for the interface we are adding work for | ||
1946 | * @work: the work we want to add onto the mac80211 workqueue | ||
1947 | */ | ||
1948 | void ieee80211_queue_work(struct ieee80211_hw *hw, struct work_struct *work); | ||
1949 | |||
1950 | /** | ||
1951 | * ieee80211_queue_delayed_work - add work onto the mac80211 workqueue | ||
1952 | * | ||
1953 | * Drivers and mac80211 use this to queue delayed work onto the mac80211 | ||
1954 | * workqueue. | ||
1955 | * | ||
1956 | * @hw: the hardware struct for the interface we are adding work for | ||
1957 | * @dwork: delayable work to queue onto the mac80211 workqueue | ||
1958 | * @delay: number of jiffies to wait before queueing | ||
1959 | */ | ||
1960 | void ieee80211_queue_delayed_work(struct ieee80211_hw *hw, | ||
1961 | struct delayed_work *dwork, | ||
1962 | unsigned long delay); | ||
1963 | |||
1964 | /** | ||
1931 | * ieee80211_start_tx_ba_session - Start a tx Block Ack session. | 1965 | * ieee80211_start_tx_ba_session - Start a tx Block Ack session. |
1932 | * @hw: pointer as obtained from ieee80211_alloc_hw(). | 1966 | * @hw: pointer as obtained from ieee80211_alloc_hw(). |
1933 | * @ra: receiver address of the BA session recipient | 1967 | * @ra: receiver address of the BA session recipient |
diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c index 6e3cca65c460..920ec8792f4b 100644 --- a/net/mac80211/ibss.c +++ b/net/mac80211/ibss.c | |||
@@ -781,7 +781,7 @@ static void ieee80211_ibss_timer(unsigned long data) | |||
781 | } | 781 | } |
782 | 782 | ||
783 | set_bit(IEEE80211_IBSS_REQ_RUN, &ifibss->request); | 783 | set_bit(IEEE80211_IBSS_REQ_RUN, &ifibss->request); |
784 | queue_work(local->hw.workqueue, &ifibss->work); | 784 | ieee80211_queue_work(&local->hw, &ifibss->work); |
785 | } | 785 | } |
786 | 786 | ||
787 | #ifdef CONFIG_PM | 787 | #ifdef CONFIG_PM |
@@ -853,7 +853,7 @@ ieee80211_ibss_rx_mgmt(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb) | |||
853 | case IEEE80211_STYPE_PROBE_REQ: | 853 | case IEEE80211_STYPE_PROBE_REQ: |
854 | case IEEE80211_STYPE_AUTH: | 854 | case IEEE80211_STYPE_AUTH: |
855 | skb_queue_tail(&sdata->u.ibss.skb_queue, skb); | 855 | skb_queue_tail(&sdata->u.ibss.skb_queue, skb); |
856 | queue_work(local->hw.workqueue, &sdata->u.ibss.work); | 856 | ieee80211_queue_work(&local->hw, &sdata->u.ibss.work); |
857 | return RX_QUEUED; | 857 | return RX_QUEUED; |
858 | } | 858 | } |
859 | 859 | ||
@@ -912,7 +912,7 @@ int ieee80211_ibss_join(struct ieee80211_sub_if_data *sdata, | |||
912 | ieee80211_recalc_idle(sdata->local); | 912 | ieee80211_recalc_idle(sdata->local); |
913 | 913 | ||
914 | set_bit(IEEE80211_IBSS_REQ_RUN, &sdata->u.ibss.request); | 914 | set_bit(IEEE80211_IBSS_REQ_RUN, &sdata->u.ibss.request); |
915 | queue_work(sdata->local->hw.workqueue, &sdata->u.ibss.work); | 915 | ieee80211_queue_work(&sdata->local->hw, &sdata->u.ibss.work); |
916 | 916 | ||
917 | return 0; | 917 | return 0; |
918 | } | 918 | } |
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index aec6853cb435..316825be2019 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h | |||
@@ -614,6 +614,12 @@ struct ieee80211_local { | |||
614 | 614 | ||
615 | const struct ieee80211_ops *ops; | 615 | const struct ieee80211_ops *ops; |
616 | 616 | ||
617 | /* | ||
618 | * private workqueue to mac80211. mac80211 makes this accessible | ||
619 | * via ieee80211_queue_work() | ||
620 | */ | ||
621 | struct workqueue_struct *workqueue; | ||
622 | |||
617 | unsigned long queue_stop_reasons[IEEE80211_MAX_QUEUES]; | 623 | unsigned long queue_stop_reasons[IEEE80211_MAX_QUEUES]; |
618 | /* also used to protect ampdu_ac_queue and amdpu_ac_stop_refcnt */ | 624 | /* also used to protect ampdu_ac_queue and amdpu_ac_stop_refcnt */ |
619 | spinlock_t queue_stop_reason_lock; | 625 | spinlock_t queue_stop_reason_lock; |
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c index a83087f4237d..8c1284d45e69 100644 --- a/net/mac80211/iface.c +++ b/net/mac80211/iface.c | |||
@@ -312,7 +312,7 @@ static int ieee80211_open(struct net_device *dev) | |||
312 | * to fix this. | 312 | * to fix this. |
313 | */ | 313 | */ |
314 | if (sdata->vif.type == NL80211_IFTYPE_STATION) | 314 | if (sdata->vif.type == NL80211_IFTYPE_STATION) |
315 | queue_work(local->hw.workqueue, &sdata->u.mgd.work); | 315 | ieee80211_queue_work(&local->hw, &sdata->u.mgd.work); |
316 | 316 | ||
317 | netif_tx_start_all_queues(dev); | 317 | netif_tx_start_all_queues(dev); |
318 | 318 | ||
@@ -551,7 +551,7 @@ static int ieee80211_stop(struct net_device *dev) | |||
551 | 551 | ||
552 | ieee80211_led_radio(local, false); | 552 | ieee80211_led_radio(local, false); |
553 | 553 | ||
554 | flush_workqueue(local->hw.workqueue); | 554 | flush_workqueue(local->workqueue); |
555 | 555 | ||
556 | tasklet_disable(&local->tx_pending_tasklet); | 556 | tasklet_disable(&local->tx_pending_tasklet); |
557 | tasklet_disable(&local->tasklet); | 557 | tasklet_disable(&local->tasklet); |
diff --git a/net/mac80211/main.c b/net/mac80211/main.c index 5e76dd1daf71..22e07385ff60 100644 --- a/net/mac80211/main.c +++ b/net/mac80211/main.c | |||
@@ -821,9 +821,9 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) | |||
821 | if (hw->queues > IEEE80211_MAX_QUEUES) | 821 | if (hw->queues > IEEE80211_MAX_QUEUES) |
822 | hw->queues = IEEE80211_MAX_QUEUES; | 822 | hw->queues = IEEE80211_MAX_QUEUES; |
823 | 823 | ||
824 | local->hw.workqueue = | 824 | local->workqueue = |
825 | create_singlethread_workqueue(wiphy_name(local->hw.wiphy)); | 825 | create_singlethread_workqueue(wiphy_name(local->hw.wiphy)); |
826 | if (!local->hw.workqueue) { | 826 | if (!local->workqueue) { |
827 | result = -ENOMEM; | 827 | result = -ENOMEM; |
828 | goto fail_workqueue; | 828 | goto fail_workqueue; |
829 | } | 829 | } |
@@ -913,7 +913,7 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) | |||
913 | sta_info_stop(local); | 913 | sta_info_stop(local); |
914 | fail_sta_info: | 914 | fail_sta_info: |
915 | debugfs_hw_del(local); | 915 | debugfs_hw_del(local); |
916 | destroy_workqueue(local->hw.workqueue); | 916 | destroy_workqueue(local->workqueue); |
917 | fail_workqueue: | 917 | fail_workqueue: |
918 | wiphy_unregister(local->hw.wiphy); | 918 | wiphy_unregister(local->hw.wiphy); |
919 | fail_wiphy_register: | 919 | fail_wiphy_register: |
@@ -955,7 +955,7 @@ void ieee80211_unregister_hw(struct ieee80211_hw *hw) | |||
955 | skb_queue_purge(&local->skb_queue); | 955 | skb_queue_purge(&local->skb_queue); |
956 | skb_queue_purge(&local->skb_queue_unreliable); | 956 | skb_queue_purge(&local->skb_queue_unreliable); |
957 | 957 | ||
958 | destroy_workqueue(local->hw.workqueue); | 958 | destroy_workqueue(local->workqueue); |
959 | wiphy_unregister(local->hw.wiphy); | 959 | wiphy_unregister(local->hw.wiphy); |
960 | ieee80211_wep_free(local); | 960 | ieee80211_wep_free(local); |
961 | ieee80211_led_exit(local); | 961 | ieee80211_led_exit(local); |
diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c index 9a3826978b1c..2f4f518ab45c 100644 --- a/net/mac80211/mesh.c +++ b/net/mac80211/mesh.c | |||
@@ -54,7 +54,7 @@ static void ieee80211_mesh_housekeeping_timer(unsigned long data) | |||
54 | return; | 54 | return; |
55 | } | 55 | } |
56 | 56 | ||
57 | queue_work(local->hw.workqueue, &ifmsh->work); | 57 | ieee80211_queue_work(local->hw.workqueue, &ifmsh->work); |
58 | } | 58 | } |
59 | 59 | ||
60 | /** | 60 | /** |
@@ -357,7 +357,7 @@ static void ieee80211_mesh_path_timer(unsigned long data) | |||
357 | return; | 357 | return; |
358 | } | 358 | } |
359 | 359 | ||
360 | queue_work(local->hw.workqueue, &ifmsh->work); | 360 | ieee80211_queue_work(local->hw.workqueue, &ifmsh->work); |
361 | } | 361 | } |
362 | 362 | ||
363 | struct mesh_table *mesh_table_grow(struct mesh_table *tbl) | 363 | struct mesh_table *mesh_table_grow(struct mesh_table *tbl) |
@@ -471,7 +471,7 @@ void ieee80211_start_mesh(struct ieee80211_sub_if_data *sdata) | |||
471 | struct ieee80211_local *local = sdata->local; | 471 | struct ieee80211_local *local = sdata->local; |
472 | 472 | ||
473 | ifmsh->housekeeping = true; | 473 | ifmsh->housekeeping = true; |
474 | queue_work(local->hw.workqueue, &ifmsh->work); | 474 | ieee80211_queue_work(local->hw.workqueue, &ifmsh->work); |
475 | ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON | | 475 | ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON | |
476 | BSS_CHANGED_BEACON_ENABLED); | 476 | BSS_CHANGED_BEACON_ENABLED); |
477 | } | 477 | } |
@@ -619,7 +619,7 @@ void ieee80211_mesh_notify_scan_completed(struct ieee80211_local *local) | |||
619 | rcu_read_lock(); | 619 | rcu_read_lock(); |
620 | list_for_each_entry_rcu(sdata, &local->interfaces, list) | 620 | list_for_each_entry_rcu(sdata, &local->interfaces, list) |
621 | if (ieee80211_vif_is_mesh(&sdata->vif)) | 621 | if (ieee80211_vif_is_mesh(&sdata->vif)) |
622 | queue_work(local->hw.workqueue, &sdata->u.mesh.work); | 622 | ieee80211_queue_work(local->hw.workqueue, &sdata->u.mesh.work); |
623 | rcu_read_unlock(); | 623 | rcu_read_unlock(); |
624 | } | 624 | } |
625 | 625 | ||
@@ -692,7 +692,7 @@ ieee80211_mesh_rx_mgmt(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb) | |||
692 | case IEEE80211_STYPE_PROBE_RESP: | 692 | case IEEE80211_STYPE_PROBE_RESP: |
693 | case IEEE80211_STYPE_BEACON: | 693 | case IEEE80211_STYPE_BEACON: |
694 | skb_queue_tail(&ifmsh->skb_queue, skb); | 694 | skb_queue_tail(&ifmsh->skb_queue, skb); |
695 | queue_work(local->hw.workqueue, &ifmsh->work); | 695 | ieee80211_queue_work(local->hw.workqueue, &ifmsh->work); |
696 | return RX_QUEUED; | 696 | return RX_QUEUED; |
697 | } | 697 | } |
698 | 698 | ||
diff --git a/net/mac80211/mesh_hwmp.c b/net/mac80211/mesh_hwmp.c index e93c37ef6a48..11ab71a68ff9 100644 --- a/net/mac80211/mesh_hwmp.c +++ b/net/mac80211/mesh_hwmp.c | |||
@@ -660,14 +660,14 @@ static void mesh_queue_preq(struct mesh_path *mpath, u8 flags) | |||
660 | spin_unlock(&ifmsh->mesh_preq_queue_lock); | 660 | spin_unlock(&ifmsh->mesh_preq_queue_lock); |
661 | 661 | ||
662 | if (time_after(jiffies, ifmsh->last_preq + min_preq_int_jiff(sdata))) | 662 | if (time_after(jiffies, ifmsh->last_preq + min_preq_int_jiff(sdata))) |
663 | queue_work(sdata->local->hw.workqueue, &ifmsh->work); | 663 | ieee80211_queue_work(sdata->local->hw.workqueue, &ifmsh->work); |
664 | 664 | ||
665 | else if (time_before(jiffies, ifmsh->last_preq)) { | 665 | else if (time_before(jiffies, ifmsh->last_preq)) { |
666 | /* avoid long wait if did not send preqs for a long time | 666 | /* avoid long wait if did not send preqs for a long time |
667 | * and jiffies wrapped around | 667 | * and jiffies wrapped around |
668 | */ | 668 | */ |
669 | ifmsh->last_preq = jiffies - min_preq_int_jiff(sdata) - 1; | 669 | ifmsh->last_preq = jiffies - min_preq_int_jiff(sdata) - 1; |
670 | queue_work(sdata->local->hw.workqueue, &ifmsh->work); | 670 | ieee80211_queue_work(sdata->local->hw.workqueue, &ifmsh->work); |
671 | } else | 671 | } else |
672 | mod_timer(&ifmsh->mesh_path_timer, ifmsh->last_preq + | 672 | mod_timer(&ifmsh->mesh_path_timer, ifmsh->last_preq + |
673 | min_preq_int_jiff(sdata)); | 673 | min_preq_int_jiff(sdata)); |
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index ee83125ed179..0779ba150b26 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c | |||
@@ -565,7 +565,7 @@ static void ieee80211_chswitch_timer(unsigned long data) | |||
565 | return; | 565 | return; |
566 | } | 566 | } |
567 | 567 | ||
568 | queue_work(sdata->local->hw.workqueue, &ifmgd->chswitch_work); | 568 | ieee80211_queue_work(&sdata->local->hw, &ifmgd->chswitch_work); |
569 | } | 569 | } |
570 | 570 | ||
571 | void ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata, | 571 | void ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata, |
@@ -597,7 +597,7 @@ void ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata, | |||
597 | sdata->local->csa_channel = new_ch; | 597 | sdata->local->csa_channel = new_ch; |
598 | 598 | ||
599 | if (sw_elem->count <= 1) { | 599 | if (sw_elem->count <= 1) { |
600 | queue_work(sdata->local->hw.workqueue, &ifmgd->chswitch_work); | 600 | ieee80211_queue_work(&sdata->local->hw, &ifmgd->chswitch_work); |
601 | } else { | 601 | } else { |
602 | ieee80211_stop_queues_by_reason(&sdata->local->hw, | 602 | ieee80211_stop_queues_by_reason(&sdata->local->hw, |
603 | IEEE80211_QUEUE_STOP_REASON_CSA); | 603 | IEEE80211_QUEUE_STOP_REASON_CSA); |
@@ -763,7 +763,7 @@ void ieee80211_dynamic_ps_timer(unsigned long data) | |||
763 | if (local->quiescing || local->suspended) | 763 | if (local->quiescing || local->suspended) |
764 | return; | 764 | return; |
765 | 765 | ||
766 | queue_work(local->hw.workqueue, &local->dynamic_ps_enable_work); | 766 | ieee80211_queue_work(&local->hw, &local->dynamic_ps_enable_work); |
767 | } | 767 | } |
768 | 768 | ||
769 | /* MLME */ | 769 | /* MLME */ |
@@ -950,7 +950,7 @@ ieee80211_direct_probe(struct ieee80211_sub_if_data *sdata, | |||
950 | * due to work needing to be done. Hence, queue the STAs work | 950 | * due to work needing to be done. Hence, queue the STAs work |
951 | * again for that. | 951 | * again for that. |
952 | */ | 952 | */ |
953 | queue_work(local->hw.workqueue, &ifmgd->work); | 953 | ieee80211_queue_work(&local->hw, &ifmgd->work); |
954 | return RX_MGMT_CFG80211_AUTH_TO; | 954 | return RX_MGMT_CFG80211_AUTH_TO; |
955 | } | 955 | } |
956 | 956 | ||
@@ -995,7 +995,7 @@ ieee80211_authenticate(struct ieee80211_sub_if_data *sdata, | |||
995 | * due to work needing to be done. Hence, queue the STAs work | 995 | * due to work needing to be done. Hence, queue the STAs work |
996 | * again for that. | 996 | * again for that. |
997 | */ | 997 | */ |
998 | queue_work(local->hw.workqueue, &ifmgd->work); | 998 | ieee80211_queue_work(&local->hw, &ifmgd->work); |
999 | return RX_MGMT_CFG80211_AUTH_TO; | 999 | return RX_MGMT_CFG80211_AUTH_TO; |
1000 | } | 1000 | } |
1001 | 1001 | ||
@@ -1124,7 +1124,7 @@ ieee80211_associate(struct ieee80211_sub_if_data *sdata, | |||
1124 | * due to work needing to be done. Hence, queue the STAs work | 1124 | * due to work needing to be done. Hence, queue the STAs work |
1125 | * again for that. | 1125 | * again for that. |
1126 | */ | 1126 | */ |
1127 | queue_work(local->hw.workqueue, &ifmgd->work); | 1127 | ieee80211_queue_work(&local->hw, &ifmgd->work); |
1128 | return RX_MGMT_CFG80211_ASSOC_TO; | 1128 | return RX_MGMT_CFG80211_ASSOC_TO; |
1129 | } | 1129 | } |
1130 | 1130 | ||
@@ -1232,8 +1232,7 @@ void ieee80211_beacon_loss(struct ieee80211_vif *vif) | |||
1232 | { | 1232 | { |
1233 | struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif); | 1233 | struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif); |
1234 | 1234 | ||
1235 | queue_work(sdata->local->hw.workqueue, | 1235 | ieee80211_queue_work(&sdata->local->hw, &sdata->u.mgd.beacon_loss_work); |
1236 | &sdata->u.mgd.beacon_loss_work); | ||
1237 | } | 1236 | } |
1238 | EXPORT_SYMBOL(ieee80211_beacon_loss); | 1237 | EXPORT_SYMBOL(ieee80211_beacon_loss); |
1239 | 1238 | ||
@@ -1888,7 +1887,7 @@ ieee80211_rx_result ieee80211_sta_rx_mgmt(struct ieee80211_sub_if_data *sdata, | |||
1888 | case IEEE80211_STYPE_DISASSOC: | 1887 | case IEEE80211_STYPE_DISASSOC: |
1889 | case IEEE80211_STYPE_ACTION: | 1888 | case IEEE80211_STYPE_ACTION: |
1890 | skb_queue_tail(&sdata->u.mgd.skb_queue, skb); | 1889 | skb_queue_tail(&sdata->u.mgd.skb_queue, skb); |
1891 | queue_work(local->hw.workqueue, &sdata->u.mgd.work); | 1890 | ieee80211_queue_work(&local->hw, &sdata->u.mgd.work); |
1892 | return RX_QUEUED; | 1891 | return RX_QUEUED; |
1893 | } | 1892 | } |
1894 | 1893 | ||
@@ -2026,7 +2025,7 @@ static void ieee80211_sta_timer(unsigned long data) | |||
2026 | return; | 2025 | return; |
2027 | } | 2026 | } |
2028 | 2027 | ||
2029 | queue_work(local->hw.workqueue, &ifmgd->work); | 2028 | ieee80211_queue_work(&local->hw, &ifmgd->work); |
2030 | } | 2029 | } |
2031 | 2030 | ||
2032 | static void ieee80211_sta_work(struct work_struct *work) | 2031 | static void ieee80211_sta_work(struct work_struct *work) |
@@ -2051,13 +2050,11 @@ static void ieee80211_sta_work(struct work_struct *work) | |||
2051 | return; | 2050 | return; |
2052 | 2051 | ||
2053 | /* | 2052 | /* |
2054 | * Nothing should have been stuffed into the workqueue during | 2053 | * ieee80211_queue_work() should have picked up most cases, |
2055 | * the suspend->resume cycle. If this WARN is seen then there | 2054 | * here we'll pick the the rest. |
2056 | * is a bug with either the driver suspend or something in | ||
2057 | * mac80211 stuffing into the workqueue which we haven't yet | ||
2058 | * cleared during mac80211's suspend cycle. | ||
2059 | */ | 2055 | */ |
2060 | if (WARN_ON(local->suspended)) | 2056 | if (WARN(local->suspended, "STA MLME work scheduled while " |
2057 | "going to suspend\n")) | ||
2061 | return; | 2058 | return; |
2062 | 2059 | ||
2063 | ifmgd = &sdata->u.mgd; | 2060 | ifmgd = &sdata->u.mgd; |
@@ -2113,9 +2110,9 @@ static void ieee80211_sta_work(struct work_struct *work) | |||
2113 | mutex_unlock(&ifmgd->mtx); | 2110 | mutex_unlock(&ifmgd->mtx); |
2114 | 2111 | ||
2115 | if (test_and_clear_bit(IEEE80211_STA_REQ_SCAN, &ifmgd->request)) | 2112 | if (test_and_clear_bit(IEEE80211_STA_REQ_SCAN, &ifmgd->request)) |
2116 | queue_delayed_work(local->hw.workqueue, | 2113 | ieee80211_queue_delayed_work(&local->hw, |
2117 | &local->scan_work, | 2114 | &local->scan_work, |
2118 | round_jiffies_relative(0)); | 2115 | round_jiffies_relative(0)); |
2119 | return; | 2116 | return; |
2120 | } | 2117 | } |
2121 | 2118 | ||
@@ -2196,8 +2193,7 @@ static void ieee80211_sta_bcn_mon_timer(unsigned long data) | |||
2196 | if (local->quiescing) | 2193 | if (local->quiescing) |
2197 | return; | 2194 | return; |
2198 | 2195 | ||
2199 | queue_work(sdata->local->hw.workqueue, | 2196 | ieee80211_queue_work(&sdata->local->hw, &sdata->u.mgd.beacon_loss_work); |
2200 | &sdata->u.mgd.beacon_loss_work); | ||
2201 | } | 2197 | } |
2202 | 2198 | ||
2203 | static void ieee80211_sta_conn_mon_timer(unsigned long data) | 2199 | static void ieee80211_sta_conn_mon_timer(unsigned long data) |
@@ -2210,7 +2206,7 @@ static void ieee80211_sta_conn_mon_timer(unsigned long data) | |||
2210 | if (local->quiescing) | 2206 | if (local->quiescing) |
2211 | return; | 2207 | return; |
2212 | 2208 | ||
2213 | queue_work(local->hw.workqueue, &ifmgd->monitor_work); | 2209 | ieee80211_queue_work(&local->hw, &ifmgd->monitor_work); |
2214 | } | 2210 | } |
2215 | 2211 | ||
2216 | static void ieee80211_sta_monitor_work(struct work_struct *work) | 2212 | static void ieee80211_sta_monitor_work(struct work_struct *work) |
@@ -2229,10 +2225,10 @@ static void ieee80211_restart_sta_timer(struct ieee80211_sub_if_data *sdata) | |||
2229 | IEEE80211_STA_CONNECTION_POLL); | 2225 | IEEE80211_STA_CONNECTION_POLL); |
2230 | 2226 | ||
2231 | /* let's probe the connection once */ | 2227 | /* let's probe the connection once */ |
2232 | queue_work(sdata->local->hw.workqueue, | 2228 | ieee80211_queue_work(&sdata->local->hw, |
2233 | &sdata->u.mgd.monitor_work); | 2229 | &sdata->u.mgd.monitor_work); |
2234 | /* and do all the other regular work too */ | 2230 | /* and do all the other regular work too */ |
2235 | queue_work(sdata->local->hw.workqueue, | 2231 | ieee80211_queue_work(&sdata->local->hw, |
2236 | &sdata->u.mgd.work); | 2232 | &sdata->u.mgd.work); |
2237 | } | 2233 | } |
2238 | } | 2234 | } |
@@ -2393,7 +2389,7 @@ int ieee80211_mgd_auth(struct ieee80211_sub_if_data *sdata, | |||
2393 | list_add(&wk->list, &sdata->u.mgd.work_list); | 2389 | list_add(&wk->list, &sdata->u.mgd.work_list); |
2394 | mutex_unlock(&ifmgd->mtx); | 2390 | mutex_unlock(&ifmgd->mtx); |
2395 | 2391 | ||
2396 | queue_work(sdata->local->hw.workqueue, &sdata->u.mgd.work); | 2392 | ieee80211_queue_work(&sdata->local->hw, &sdata->u.mgd.work); |
2397 | return 0; | 2393 | return 0; |
2398 | } | 2394 | } |
2399 | 2395 | ||
@@ -2467,7 +2463,7 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata, | |||
2467 | else | 2463 | else |
2468 | ifmgd->flags &= ~IEEE80211_STA_CONTROL_PORT; | 2464 | ifmgd->flags &= ~IEEE80211_STA_CONTROL_PORT; |
2469 | 2465 | ||
2470 | queue_work(sdata->local->hw.workqueue, &sdata->u.mgd.work); | 2466 | ieee80211_queue_work(&sdata->local->hw, &sdata->u.mgd.work); |
2471 | 2467 | ||
2472 | err = 0; | 2468 | err = 0; |
2473 | 2469 | ||
diff --git a/net/mac80211/pm.c b/net/mac80211/pm.c index 3320f7daaf25..a5d2f1fb4417 100644 --- a/net/mac80211/pm.c +++ b/net/mac80211/pm.c | |||
@@ -26,7 +26,7 @@ int __ieee80211_suspend(struct ieee80211_hw *hw) | |||
26 | /* make quiescing visible to timers everywhere */ | 26 | /* make quiescing visible to timers everywhere */ |
27 | mb(); | 27 | mb(); |
28 | 28 | ||
29 | flush_workqueue(local->hw.workqueue); | 29 | flush_workqueue(local->workqueue); |
30 | 30 | ||
31 | /* Don't try to run timers while suspended. */ | 31 | /* Don't try to run timers while suspended. */ |
32 | del_timer_sync(&local->sta_cleanup); | 32 | del_timer_sync(&local->sta_cleanup); |
@@ -117,7 +117,7 @@ int __ieee80211_suspend(struct ieee80211_hw *hw) | |||
117 | * shouldn't be doing (or cancel everything in the | 117 | * shouldn't be doing (or cancel everything in the |
118 | * stop callback) that but better safe than sorry. | 118 | * stop callback) that but better safe than sorry. |
119 | */ | 119 | */ |
120 | flush_workqueue(local->hw.workqueue); | 120 | flush_workqueue(local->workqueue); |
121 | 121 | ||
122 | local->suspended = true; | 122 | local->suspended = true; |
123 | /* need suspended to be visible before quiescing is false */ | 123 | /* need suspended to be visible before quiescing is false */ |
diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c index 45731000eb8d..244f53f3c8b4 100644 --- a/net/mac80211/scan.c +++ b/net/mac80211/scan.c | |||
@@ -385,8 +385,9 @@ static int ieee80211_start_sw_scan(struct ieee80211_local *local) | |||
385 | spin_unlock_bh(&local->filter_lock); | 385 | spin_unlock_bh(&local->filter_lock); |
386 | 386 | ||
387 | /* TODO: start scan as soon as all nullfunc frames are ACKed */ | 387 | /* TODO: start scan as soon as all nullfunc frames are ACKed */ |
388 | queue_delayed_work(local->hw.workqueue, &local->scan_work, | 388 | ieee80211_queue_delayed_work(&local->hw, |
389 | IEEE80211_CHANNEL_TIME); | 389 | &local->scan_work, |
390 | IEEE80211_CHANNEL_TIME); | ||
390 | 391 | ||
391 | return 0; | 392 | return 0; |
392 | } | 393 | } |
@@ -715,8 +716,7 @@ void ieee80211_scan_work(struct work_struct *work) | |||
715 | } | 716 | } |
716 | } while (next_delay == 0); | 717 | } while (next_delay == 0); |
717 | 718 | ||
718 | queue_delayed_work(local->hw.workqueue, &local->scan_work, | 719 | ieee80211_queue_delayed_work(&local->hw, &local->scan_work, next_delay); |
719 | next_delay); | ||
720 | } | 720 | } |
721 | 721 | ||
722 | int ieee80211_request_scan(struct ieee80211_sub_if_data *sdata, | 722 | int ieee80211_request_scan(struct ieee80211_sub_if_data *sdata, |
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index 4e1b2ba122cd..7cffaa046b33 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c | |||
@@ -1400,7 +1400,7 @@ static void ieee80211_xmit(struct ieee80211_sub_if_data *sdata, | |||
1400 | if (local->hw.conf.flags & IEEE80211_CONF_PS) { | 1400 | if (local->hw.conf.flags & IEEE80211_CONF_PS) { |
1401 | ieee80211_stop_queues_by_reason(&local->hw, | 1401 | ieee80211_stop_queues_by_reason(&local->hw, |
1402 | IEEE80211_QUEUE_STOP_REASON_PS); | 1402 | IEEE80211_QUEUE_STOP_REASON_PS); |
1403 | queue_work(local->hw.workqueue, | 1403 | ieee80211_queue_work(&local->hw, |
1404 | &local->dynamic_ps_disable_work); | 1404 | &local->dynamic_ps_disable_work); |
1405 | } | 1405 | } |
1406 | 1406 | ||
diff --git a/net/mac80211/util.c b/net/mac80211/util.c index 8502936e5314..e55d57f559ec 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c | |||
@@ -511,6 +511,46 @@ void ieee80211_iterate_active_interfaces_atomic( | |||
511 | } | 511 | } |
512 | EXPORT_SYMBOL_GPL(ieee80211_iterate_active_interfaces_atomic); | 512 | EXPORT_SYMBOL_GPL(ieee80211_iterate_active_interfaces_atomic); |
513 | 513 | ||
514 | /* | ||
515 | * Nothing should have been stuffed into the workqueue during | ||
516 | * the suspend->resume cycle. If this WARN is seen then there | ||
517 | * is a bug with either the driver suspend or something in | ||
518 | * mac80211 stuffing into the workqueue which we haven't yet | ||
519 | * cleared during mac80211's suspend cycle. | ||
520 | */ | ||
521 | static bool ieee80211_can_queue_work(struct ieee80211_local *local) | ||
522 | { | ||
523 | if (WARN(local->suspended, "queueing ieee80211 work while " | ||
524 | "going to suspend\n")) | ||
525 | return false; | ||
526 | |||
527 | return true; | ||
528 | } | ||
529 | |||
530 | void ieee80211_queue_work(struct ieee80211_hw *hw, struct work_struct *work) | ||
531 | { | ||
532 | struct ieee80211_local *local = hw_to_local(hw); | ||
533 | |||
534 | if (!ieee80211_can_queue_work(local)) | ||
535 | return; | ||
536 | |||
537 | queue_work(local->workqueue, work); | ||
538 | } | ||
539 | EXPORT_SYMBOL(ieee80211_queue_work); | ||
540 | |||
541 | void ieee80211_queue_delayed_work(struct ieee80211_hw *hw, | ||
542 | struct delayed_work *dwork, | ||
543 | unsigned long delay) | ||
544 | { | ||
545 | struct ieee80211_local *local = hw_to_local(hw); | ||
546 | |||
547 | if (!ieee80211_can_queue_work(local)) | ||
548 | return; | ||
549 | |||
550 | queue_delayed_work(local->workqueue, dwork, delay); | ||
551 | } | ||
552 | EXPORT_SYMBOL(ieee80211_queue_delayed_work); | ||
553 | |||
514 | void ieee802_11_parse_elems(u8 *start, size_t len, | 554 | void ieee802_11_parse_elems(u8 *start, size_t len, |
515 | struct ieee802_11_elems *elems) | 555 | struct ieee802_11_elems *elems) |
516 | { | 556 | { |
@@ -1114,3 +1154,4 @@ int ieee80211_reconfig(struct ieee80211_local *local) | |||
1114 | #endif | 1154 | #endif |
1115 | return 0; | 1155 | return 0; |
1116 | } | 1156 | } |
1157 | |||