]> git.karo-electronics.de Git - karo-tx-linux.git/blobdiff - drivers/net/wireless/ath/ath9k/init.c
ath9k: Reconfigure tx power on regulatory update
[karo-tx-linux.git] / drivers / net / wireless / ath / ath9k / init.c
index 5cb0599b01c250d6ebd00168c2799e5726734f8b..c5df98139c4df7592d00d41958825d33b64220a0 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/dma-mapping.h>
 #include <linux/slab.h>
 #include <linux/ath9k_platform.h>
+#include <linux/module.h>
 
 #include "ath9k.h"
 
@@ -257,6 +258,8 @@ static void setup_ht_cap(struct ath_softc *sc,
 
        if (AR_SREV_9330(ah) || AR_SREV_9485(ah))
                max_streams = 1;
+       else if (AR_SREV_9462(ah))
+               max_streams = 2;
        else if (AR_SREV_9300_20_OR_LATER(ah))
                max_streams = 3;
        else
@@ -294,9 +297,22 @@ static int ath9k_reg_notifier(struct wiphy *wiphy,
 {
        struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);
        struct ath_softc *sc = hw->priv;
-       struct ath_regulatory *reg = ath9k_hw_regulatory(sc->sc_ah);
+       struct ath_hw *ah = sc->sc_ah;
+       struct ath_regulatory *reg = ath9k_hw_regulatory(ah);
+       int ret;
+
+       ret = ath_reg_notifier_apply(wiphy, request, reg);
+
+       /* Set tx power */
+       if (ah->curchan) {
+               sc->config.txpowlimit = 2 * ah->curchan->chan->max_power;
+               ath9k_ps_wakeup(sc);
+               ath9k_hw_set_txpowerlimit(ah, sc->config.txpowlimit, false);
+               sc->curtxpow = ath9k_hw_regulatory(ah)->power_limit;
+               ath9k_ps_restore(sc);
+       }
 
-       return ath_reg_notifier_apply(wiphy, request, reg);
+       return ret;
 }
 
 /*
@@ -407,6 +423,7 @@ fail:
 static int ath9k_init_btcoex(struct ath_softc *sc)
 {
        struct ath_txq *txq;
+       struct ath_hw *ah = sc->sc_ah;
        int r;
 
        switch (sc->sc_ah->btcoex_hw.scheme) {
@@ -422,9 +439,38 @@ static int ath9k_init_btcoex(struct ath_softc *sc)
                        return -1;
                txq = sc->tx.txq_map[WME_AC_BE];
                ath9k_hw_init_btcoex_hw(sc->sc_ah, txq->axq_qnum);
+               sc->btcoex.bt_stomp_type = ATH_BTCOEX_STOMP_LOW;
+               break;
+       case ATH_BTCOEX_CFG_MCI:
                sc->btcoex.bt_stomp_type = ATH_BTCOEX_STOMP_LOW;
                sc->btcoex.duty_cycle = ATH_BTCOEX_DEF_DUTY_CYCLE;
                INIT_LIST_HEAD(&sc->btcoex.mci.info);
+
+               r = ath_mci_setup(sc);
+               if (r)
+                       return r;
+
+               if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_MCI) {
+                       ah->btcoex_hw.mci.ready = false;
+                       ah->btcoex_hw.mci.bt_state = 0;
+                       ah->btcoex_hw.mci.bt_ver_major = 3;
+                       ah->btcoex_hw.mci.bt_ver_minor = 0;
+                       ah->btcoex_hw.mci.bt_version_known = false;
+                       ah->btcoex_hw.mci.update_2g5g = true;
+                       ah->btcoex_hw.mci.is_2g = true;
+                       ah->btcoex_hw.mci.wlan_channels_update = false;
+                       ah->btcoex_hw.mci.wlan_channels[0] = 0x00000000;
+                       ah->btcoex_hw.mci.wlan_channels[1] = 0xffffffff;
+                       ah->btcoex_hw.mci.wlan_channels[2] = 0xffffffff;
+                       ah->btcoex_hw.mci.wlan_channels[3] = 0x7fffffff;
+                       ah->btcoex_hw.mci.query_bt = true;
+                       ah->btcoex_hw.mci.unhalt_bt_gpm = true;
+                       ah->btcoex_hw.mci.halted_bt_gpm = false;
+                       ah->btcoex_hw.mci.need_flush_btinfo = false;
+                       ah->btcoex_hw.mci.wlan_cal_seq = 0;
+                       ah->btcoex_hw.mci.wlan_cal_done = 0;
+                       ah->btcoex_hw.mci.config = 0x2201;
+               }
                break;
        default:
                WARN_ON(1);
@@ -838,6 +884,9 @@ static void ath9k_deinit_softc(struct ath_softc *sc)
            sc->sc_ah->btcoex_hw.scheme == ATH_BTCOEX_CFG_3WIRE)
                ath_gen_timer_free(sc->sc_ah, sc->btcoex.no_stomp_timer);
 
+       if (sc->sc_ah->btcoex_hw.scheme == ATH_BTCOEX_CFG_MCI)
+               ath_mci_cleanup(sc);
+
        for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++)
                if (ATH_TXQ_SETUP(sc, i))
                        ath_tx_cleanupq(sc, &sc->tx.txq[i]);