Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless
[deliverable/linux.git] / drivers / net / wireless / ath / ath9k / main.c
index 88f7ad106e056796d7dd23c1d82241cb35ca3b55..52561b341d68798e55bbe8237e589da274b539b7 100644 (file)
@@ -150,6 +150,9 @@ static void __ath_cancel_work(struct ath_softc *sc)
        cancel_work_sync(&sc->hw_check_work);
        cancel_delayed_work_sync(&sc->tx_complete_work);
        cancel_delayed_work_sync(&sc->hw_pll_work);
+#ifdef CONFIG_ATH9K_BTCOEX_SUPPORT
+       cancel_work_sync(&sc->mci_work);
+#endif
 }
 
 static void ath_cancel_work(struct ath_softc *sc)
@@ -210,6 +213,7 @@ static bool ath_complete_reset(struct ath_softc *sc, bool start)
 {
        struct ath_hw *ah = sc->sc_ah;
        struct ath_common *common = ath9k_hw_common(ah);
+       unsigned long flags;
 
        if (ath_startrecv(sc) != 0) {
                ath_err(common, "Unable to restart recv logic\n");
@@ -224,9 +228,18 @@ static bool ath_complete_reset(struct ath_softc *sc, bool start)
        ath9k_hw_enable_interrupts(ah);
 
        if (!(sc->hw->conf.flags & IEEE80211_CONF_OFFCHANNEL) && start) {
-               if (test_bit(SC_OP_BEACONS, &sc->sc_flags))
-                       ath_set_beacon(sc);
+               if (!test_bit(SC_OP_BEACONS, &sc->sc_flags))
+                       goto work;
+
+               ath_set_beacon(sc);
 
+               if (ah->opmode == NL80211_IFTYPE_STATION &&
+                   test_bit(SC_OP_PRIM_STA_VIF, &sc->sc_flags)) {
+                       spin_lock_irqsave(&sc->sc_pm_lock, flags);
+                       sc->ps_flags |= PS_BEACON_SYNC | PS_WAIT_FOR_BEACON;
+                       spin_unlock_irqrestore(&sc->sc_pm_lock, flags);
+               }
+       work:
                ath_restart_work(sc);
        }
 
@@ -1023,15 +1036,6 @@ static int ath9k_add_interface(struct ieee80211_hw *hw,
                }
        }
 
-       if ((ah->opmode == NL80211_IFTYPE_ADHOC) ||
-           ((vif->type == NL80211_IFTYPE_ADHOC) &&
-            sc->nvifs > 0)) {
-               ath_err(common, "Cannot create ADHOC interface when other"
-                       " interfaces already exist.\n");
-               ret = -EINVAL;
-               goto out;
-       }
-
        ath_dbg(common, CONFIG, "Attach a VIF of type: %d\n", vif->type);
 
        sc->nvifs++;
@@ -1056,15 +1060,6 @@ static int ath9k_change_interface(struct ieee80211_hw *hw,
        mutex_lock(&sc->mutex);
        ath9k_ps_wakeup(sc);
 
-       /* See if new interface type is valid. */
-       if ((new_type == NL80211_IFTYPE_ADHOC) &&
-           (sc->nvifs > 1)) {
-               ath_err(common, "When using ADHOC, it must be the only"
-                       " interface.\n");
-               ret = -EINVAL;
-               goto out;
-       }
-
        if (ath9k_uses_beacons(new_type) &&
            !ath9k_uses_beacons(vif->type)) {
                if (sc->nbcnvifs >= ATH_BCBUF) {
@@ -1248,6 +1243,7 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed)
                if (ath_set_channel(sc, hw, &sc->sc_ah->channels[pos]) < 0) {
                        ath_err(common, "Unable to set channel\n");
                        mutex_unlock(&sc->mutex);
+                       ath9k_ps_restore(sc);
                        return -EINVAL;
                }
 
This page took 0.031717 seconds and 5 git commands to generate.