/drivers/platform/mips/

T SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #include #include #include "ath9k.h" #include "btcoex.h" static void ath9k_set_assoc_state(struct ath_softc *sc, struct ieee80211_vif *vif); u8 ath9k_parse_mpdudensity(u8 mpdudensity) { /* * 802.11n D2.0 defined values for "Minimum MPDU Start Spacing": * 0 for no restriction * 1 for 1/4 us * 2 for 1/2 us * 3 for 1 us * 4 for 2 us * 5 for 4 us * 6 for 8 us * 7 for 16 us */ switch (mpdudensity) { case 0: return 0; case 1: case 2: case 3: /* Our lower layer calculations limit our precision to 1 microsecond */ return 1; case 4: return 2; case 5: return 4; case 6: return 8; case 7: return 16; default: return 0; } } static bool ath9k_has_pending_frames(struct ath_softc *sc, struct ath_txq *txq) { bool pending = false; spin_lock_bh(&txq->axq_lock); if (txq->axq_depth || !list_empty(&txq->axq_acq)) pending = true; spin_unlock_bh(&txq->axq_lock); return pending; } static bool ath9k_setpower(struct ath_softc *sc, enum ath9k_power_mode mode) { unsigned long flags; bool ret; spin_lock_irqsave(&sc->sc_pm_lock, flags); ret = ath9k_hw_setpower(sc->sc_ah, mode); spin_unlock_irqrestore(&sc->sc_pm_lock, flags); return ret; } void ath_ps_full_sleep(unsigned long data) { struct ath_softc *sc = (struct ath_softc *) data; struct ath_common *common = ath9k_hw_common(sc->sc_ah); bool reset; spin_lock(&common->cc_lock); ath_hw_cycle_counters_update(common); spin_unlock(&common->cc_lock); ath9k_hw_setrxabort(sc->sc_ah, 1); ath9k_hw_stopdmarecv(sc->sc_ah, &reset); ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_FULL_SLEEP); } 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; del_timer_sync(&sc->sleep_timer); power_mode = sc->sc_ah->power_mode; ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_AWAKE); /* * While the hardware is asleep, the cycle counters contain no * useful data. Better clear them now so that they don't mess up * survey data results. */ 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)); memset(&common->cc_ani, 0, sizeof(common->cc_ani)); spin_unlock(&common->cc_lock); } unlock: spin_unlock_irqrestore(&sc->sc_pm_lock, flags); } void ath9k_ps_restore(struct ath_softc *sc) { struct ath_common *common = ath9k_hw_common(sc->sc_ah); enum ath9k_power_mode mode; unsigned long flags; spin_lock_irqsave(&sc->sc_pm_lock, flags); if (--sc->ps_usecount != 0) goto unlock; if (sc->ps_idle) { mod_timer(&sc->sleep_timer, jiffies + HZ / 10); goto unlock; } if (sc->ps_enabled && !(sc->ps_f