return ret;
 }
 
-static void ath5k_beacon_disable(struct ath5k_softc *sc)
-{
-       sc->imask &= ~(AR5K_INT_BMISS | AR5K_INT_SWBA);
-       ath5k_hw_set_imr(sc->ah, sc->imask);
-       ath5k_hw_stop_tx_dma(sc->ah, sc->bhalq);
-}
-
 /*
  * Transmit a beacon frame at SWBA.  Dynamic updates to the
  * frame contents are done as needed and the slot time is
        struct ath5k_hw *ah = sc->ah;
        unsigned long flags;
 
-       ath5k_hw_set_imr(ah, 0);
+       spin_lock_irqsave(&sc->block, flags);
        sc->bmisscount = 0;
        sc->imask &= ~(AR5K_INT_BMISS | AR5K_INT_SWBA);
 
-       if (sc->opmode == NL80211_IFTYPE_ADHOC ||
-                       sc->opmode == NL80211_IFTYPE_MESH_POINT ||
-                       sc->opmode == NL80211_IFTYPE_AP) {
+       if (sc->enable_beacon) {
                /*
                 * In IBSS mode we use a self-linked tx descriptor and let the
                 * hardware send the beacons automatically. We have to load it
                sc->imask |= AR5K_INT_SWBA;
 
                if (sc->opmode == NL80211_IFTYPE_ADHOC) {
-                       if (ath5k_hw_hasveol(ah)) {
-                               spin_lock_irqsave(&sc->block, flags);
+                       if (ath5k_hw_hasveol(ah))
                                ath5k_beacon_send(sc);
-                               spin_unlock_irqrestore(&sc->block, flags);
-                       }
                } else
                        ath5k_beacon_update_timers(sc, -1);
+       } else {
+               ath5k_hw_stop_tx_dma(sc->ah, sc->bhalq);
        }
 
        ath5k_hw_set_imr(ah, sc->imask);
+       mmiowb();
+       spin_unlock_irqrestore(&sc->block, flags);
 }
 
 static void ath5k_tasklet_beacon(unsigned long data)
                goto end;
 
        ath5k_hw_set_lladdr(sc->ah, mac);
-       ath5k_beacon_disable(sc);
        sc->vif = NULL;
 end:
        mutex_unlock(&sc->lock);
        return ret;
 }
 
-/*
- *  Update the beacon and reconfigure the beacon queues.
- */
-static void
-ath5k_beacon_reconfig(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
-{
-       int ret;
-       unsigned long flags;
-       struct ath5k_softc *sc = hw->priv;
-
-       spin_lock_irqsave(&sc->block, flags);
-       ret = ath5k_beacon_update(hw, vif);
-       spin_unlock_irqrestore(&sc->block, flags);
-       if (ret == 0) {
-               ath5k_beacon_config(sc);
-               mmiowb();
-       }
-}
-
 static void
 set_beacon_filter(struct ieee80211_hw *hw, bool enable)
 {
 {
        struct ath5k_softc *sc = hw->priv;
        struct ath5k_hw *ah = sc->ah;
+       unsigned long flags;
 
        mutex_lock(&sc->lock);
        if (WARN_ON(sc->vif != vif))
                        AR5K_LED_ASSOC : AR5K_LED_INIT);
        }
 
-       if (changes & BSS_CHANGED_BEACON &&
-           (vif->type == NL80211_IFTYPE_ADHOC ||
-            vif->type == NL80211_IFTYPE_MESH_POINT ||
-            vif->type == NL80211_IFTYPE_AP)) {
-               ath5k_beacon_reconfig(hw, vif);
+       if (changes & BSS_CHANGED_BEACON) {
+               spin_lock_irqsave(&sc->block, flags);
+               ath5k_beacon_update(hw, vif);
+               spin_unlock_irqrestore(&sc->block, flags);
        }
 
+       if (changes & BSS_CHANGED_BEACON_ENABLED)
+               sc->enable_beacon = bss_conf->enable_beacon;
+
+       if (changes & (BSS_CHANGED_BEACON | BSS_CHANGED_BEACON_ENABLED |
+                      BSS_CHANGED_BEACON_INT))
+               ath5k_beacon_config(sc);
+
  unlock:
        mutex_unlock(&sc->lock);
 }