diff options
author | Luis R. Rodriguez <lrodriguez@atheros.com> | 2009-07-29 20:08:07 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2009-08-04 16:44:14 -0400 |
commit | 42935ecaf4e784d0815afa9a7e5fe7e141157ca3 (patch) | |
tree | dc0a0dcfff761e98d8a2a23a7edc8f9182c2774c /drivers/net/wireless/ath | |
parent | 64344d78228f6346a0462ba2d5fc03494aef4e6b (diff) |
mac80211: redefine usage of the mac80211 workqueue
The mac80211 workqueue exists to enable mac80211 and drivers
to queue their own work on a single threaded workqueue. mac80211
takes care to flush the workqueue during suspend but we never
really had requirements on drivers for how they should use
the workqueue in consideration for suspend.
We extend mac80211 to document how the mac80211 workqueue should
be used, how it should not be used and finally move raw access to
the workqueue to mac80211 only. Drivers and mac80211 use helpers
to queue work onto the mac80211 workqueue:
* ieee80211_queue_work()
* ieee80211_queue_delayed_work()
These helpers will now warn if mac80211 already completed its
suspend cycle and someone is trying to queue work. mac80211
flushes the mac80211 workqueue prior to suspend a few times,
but we haven't taken the care to ensure drivers won't add more
work after suspend. To help with this we add a warning when
someone tries to add work and mac80211 already completed the
suspend cycle.
Drivers should ensure they cancel any work or delayed work
in the mac80211 stop() callback.
Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/ath')
-rw-r--r-- | drivers/net/wireless/ath/ar9170/led.c | 11 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ar9170/main.c | 26 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath9k/main.c | 15 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath9k/virtual.c | 17 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath9k/xmit.c | 2 |
5 files changed, 40 insertions, 31 deletions
diff --git a/drivers/net/wireless/ath/ar9170/led.c b/drivers/net/wireless/ath/ar9170/led.c index 63fda6cd210..86c4e79f6bc 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) ar9170_set_leds_state(ar, led_val); mutex_unlock(&ar->mutex); - if (rerun) - queue_delayed_work(ar->hw->workqueue, &ar->led_work, - msecs_to_jiffies(blink_delay)); + if (!rerun) + return; + + ieee80211_queue_delayed_work(ar->hw, + &ar->led_work, + msecs_to_jiffies(blink_delay)); } static void ar9170_led_brightness_set(struct led_classdev *led, @@ -110,7 +113,7 @@ static void ar9170_led_brightness_set(struct led_classdev *led, } if (likely(IS_ACCEPTING_CMD(ar) && arl->toggled)) - queue_delayed_work(ar->hw->workqueue, &ar->led_work, HZ/10); + ieee80211_queue_delayed_work(ar->hw, &ar->led_work, HZ/10); } 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 099ed3c3ba2..4fc389ae74b 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) ar9170_tx_fake_ampdu_status(ar); - if (resched) - queue_delayed_work(ar->hw->workqueue, - &ar->tx_janitor, - msecs_to_jiffies(AR9170_JANITOR_DELAY)); + if (!resched) + return; + + ieee80211_queue_delayed_work(ar->hw, + &ar->tx_janitor, + msecs_to_jiffies(AR9170_JANITOR_DELAY)); } 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) * pre-TBTT event */ if (ar->vif && ar->vif->type == NL80211_IFTYPE_AP) - queue_work(ar->hw->workqueue, &ar->beacon_work); + ieee80211_queue_work(ar->hw, &ar->beacon_work); break; case 0xc2: @@ -1825,10 +1827,12 @@ static void ar9170_tx(struct ar9170 *ar) } } - if (schedule_garbagecollector) - queue_delayed_work(ar->hw->workqueue, - &ar->tx_janitor, - msecs_to_jiffies(AR9170_JANITOR_DELAY)); + if (!schedule_garbagecollector) + return; + + ieee80211_queue_delayed_work(ar->hw, + &ar->tx_janitor, + msecs_to_jiffies(AR9170_JANITOR_DELAY)); } 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, } if (likely(IS_STARTED(ar))) - queue_work(ar->hw->workqueue, &ar->filter_config_work); + ieee80211_queue_work(ar->hw, &ar->filter_config_work); } static void ar9170_op_bss_info_changed(struct ieee80211_hw *hw, @@ -2415,7 +2419,7 @@ static void ar9170_sta_notify(struct ieee80211_hw *hw, } if (IS_STARTED(ar) && ar->filter_changed) - queue_work(ar->hw->workqueue, &ar->filter_config_work); + ieee80211_queue_work(ar->hw, &ar->filter_config_work); } 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 cf44623b5cd..292ac2b4189 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) ath9k_hw_set_gpio(sc->sc_ah, ATH_LED_PIN, (sc->sc_flags & SC_OP_LED_ON) ? 1 : 0); - queue_delayed_work(sc->hw->workqueue, &sc->ath_led_blink_work, - (sc->sc_flags & SC_OP_LED_ON) ? - msecs_to_jiffies(sc->led_off_duration) : - msecs_to_jiffies(sc->led_on_duration)); + ieee80211_queue_delayed_work(sc->hw, + &sc->ath_led_blink_work, + (sc->sc_flags & SC_OP_LED_ON) ? + msecs_to_jiffies(sc->led_off_duration) : + msecs_to_jiffies(sc->led_on_duration)); sc->led_on_duration = sc->led_on_cnt ? 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, case LED_FULL: if (led->led_type == ATH_LED_ASSOC) { sc->sc_flags |= SC_OP_LED_ASSOCIATED; - queue_delayed_work(sc->hw->workqueue, - &sc->ath_led_blink_work, 0); + ieee80211_queue_delayed_work(sc->hw, + &sc->ath_led_blink_work, 0); } else if (led->led_type == ATH_LED_RADIO) { ath9k_hw_set_gpio(sc->sc_ah, ATH_LED_PIN, 0); sc->sc_flags |= SC_OP_LED_ON; @@ -1972,7 +1973,7 @@ static int ath9k_start(struct ieee80211_hw *hw) ieee80211_wake_queues(hw); - queue_delayed_work(sc->hw->workqueue, &sc->tx_complete_work, 0); + ieee80211_queue_delayed_work(sc->hw, &sc->tx_complete_work, 0); mutex_unlock: mutex_unlock(&sc->mutex); diff --git a/drivers/net/wireless/ath/ath9k/virtual.c b/drivers/net/wireless/ath/ath9k/virtual.c index e1d419e02b4..19b88f8177f 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) * Drop from tasklet to work to allow mutex for channel * change. */ - queue_work(aphy->sc->hw->workqueue, + ieee80211_queue_work(aphy->sc->hw, &aphy->sc->chan_work); } } @@ -367,7 +367,7 @@ static void ath9k_mark_paused(struct ath_wiphy *aphy) struct ath_softc *sc = aphy->sc; aphy->state = ATH_WIPHY_PAUSED; if (!__ath9k_wiphy_pausing(sc)) - queue_work(sc->hw->workqueue, &sc->chan_work); + ieee80211_queue_work(sc->hw, &sc->chan_work); } 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) spin_unlock_bh(&sc->wiphy_lock); ath_radio_disable(sc); ath_radio_enable(sc); - queue_work(aphy->sc->hw->workqueue, + ieee80211_queue_work(aphy->sc->hw, &aphy->sc->chan_work); return -EBUSY; /* previous select still in progress */ } @@ -541,7 +541,7 @@ int ath9k_wiphy_select(struct ath_wiphy *aphy) if (now) { /* Ready to request channel change immediately */ - queue_work(aphy->sc->hw->workqueue, &aphy->sc->chan_work); + ieee80211_queue_work(aphy->sc->hw, &aphy->sc->chan_work); } /* @@ -648,8 +648,9 @@ try_again: "change\n"); } - queue_delayed_work(sc->hw->workqueue, &sc->wiphy_work, - sc->wiphy_scheduler_int); + ieee80211_queue_delayed_work(sc->hw, + &sc->wiphy_work, + sc->wiphy_scheduler_int); } 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) cancel_delayed_work_sync(&sc->wiphy_work); sc->wiphy_scheduler_int = msecs_to_jiffies(msec_int); if (sc->wiphy_scheduler_int) - queue_delayed_work(sc->hw->workqueue, &sc->wiphy_work, - sc->wiphy_scheduler_int); + ieee80211_queue_delayed_work(sc->hw, &sc->wiphy_work, + sc->wiphy_scheduler_int); } /* caller must hold wiphy_lock */ diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index b7806e2ca0e..87762da0383 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) ath_reset(sc, false); } - queue_delayed_work(sc->hw->workqueue, &sc->tx_complete_work, + ieee80211_queue_delayed_work(sc->hw, &sc->tx_complete_work, msecs_to_jiffies(ATH_TX_COMPLETE_POLL_INT)); } |