Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wirel...
[GitHub/mt8127/android_kernel_alcatel_ttab.git] / drivers / net / wireless / ath / ath9k / main.c
index dede9a9aa68906408911c5310482f5b45ce6a7c8..50bdb5db23b4e1292fe20d55072353105a72fcda 100644 (file)
@@ -15,6 +15,7 @@
  */
 
 #include <linux/nl80211.h>
+#include <linux/pm_qos_params.h>
 #include "ath9k.h"
 #include "btcoex.h"
 
@@ -93,11 +94,13 @@ void ath9k_ps_wakeup(struct ath_softc *sc)
 {
        struct ath_common *common = ath9k_hw_common(sc->sc_ah);
        unsigned long flags;
+       enum ath9k_power_mode power_mode;
 
        spin_lock_irqsave(&sc->sc_pm_lock, flags);
        if (++sc->ps_usecount != 1)
                goto unlock;
 
+       power_mode = sc->sc_ah->power_mode;
        ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_AWAKE);
 
        /*
@@ -105,10 +108,12 @@ void ath9k_ps_wakeup(struct ath_softc *sc)
         * useful data. Better clear them now so that they don't mess up
         * survey data results.
         */
-       spin_lock(&common->cc_lock);
-       ath_hw_cycle_counters_update(common);
-       memset(&common->cc_survey, 0, sizeof(common->cc_survey));
-       spin_unlock(&common->cc_lock);
+       if (power_mode != ATH9K_PM_AWAKE) {
+               spin_lock(&common->cc_lock);
+               ath_hw_cycle_counters_update(common);
+               memset(&common->cc_survey, 0, sizeof(common->cc_survey));
+               spin_unlock(&common->cc_lock);
+       }
 
  unlock:
        spin_unlock_irqrestore(&sc->sc_pm_lock, flags);
@@ -1157,6 +1162,7 @@ static int ath9k_start(struct ieee80211_hw *hw)
                ah->imask |= ATH9K_INT_CST;
 
        sc->sc_flags &= ~SC_OP_INVALID;
+       sc->sc_ah->is_monitoring = false;
 
        /* Disable BMISS interrupt when we're not associated */
        ah->imask &= ~(ATH9K_INT_SWBA | ATH9K_INT_BMISS);
@@ -1178,6 +1184,8 @@ static int ath9k_start(struct ieee80211_hw *hw)
                        ath9k_btcoex_timer_resume(sc);
        }
 
+       pm_qos_update_request(&ath9k_pm_qos_req, 55);
+
 mutex_unlock:
        mutex_unlock(&sc->mutex);
 
@@ -1331,6 +1339,8 @@ static void ath9k_stop(struct ieee80211_hw *hw)
 
        sc->sc_flags |= SC_OP_INVALID;
 
+       pm_qos_update_request(&ath9k_pm_qos_req, PM_QOS_DEFAULT_VALUE);
+
        mutex_unlock(&sc->mutex);
 
        ath_print(common, ATH_DBG_CONFIG, "Driver halt\n");
@@ -1409,8 +1419,7 @@ static int ath9k_add_interface(struct ieee80211_hw *hw,
        ath9k_hw_set_interrupts(ah, ah->imask);
 
        if (vif->type == NL80211_IFTYPE_AP    ||
-           vif->type == NL80211_IFTYPE_ADHOC ||
-           vif->type == NL80211_IFTYPE_MONITOR) {
+           vif->type == NL80211_IFTYPE_ADHOC) {
                sc->sc_flags |= SC_OP_ANI_RUN;
                ath_start_ani(common);
        }
@@ -1560,8 +1569,12 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed)
        if (changed & IEEE80211_CONF_CHANGE_MONITOR) {
                if (conf->flags & IEEE80211_CONF_MONITOR) {
                        ath_print(common, ATH_DBG_CONFIG,
-                                 "HW opmode set to Monitor mode\n");
-                       sc->sc_ah->opmode = NL80211_IFTYPE_MONITOR;
+                                 "Monitor mode is enabled\n");
+                       sc->sc_ah->is_monitoring = true;
+               } else {
+                       ath_print(common, ATH_DBG_CONFIG,
+                                 "Monitor mode is disabled\n");
+                       sc->sc_ah->is_monitoring = false;
                }
        }