ath9k: Fix RX interrupt mitigation
[linux-drm-fsl-dcu.git] / drivers / net / wireless / ath / ath9k / hw.c
index fe3537f6ec5838aead7c6489fa06afa35d80e64f..fbf43c05713f476f9e6551ad2948dc1ff412970a 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/slab.h>
 #include <linux/module.h>
 #include <linux/time.h>
+#include <linux/bitops.h>
 #include <asm/unaligned.h>
 
 #include "hw.h"
@@ -36,99 +37,6 @@ MODULE_DESCRIPTION("Support for Atheros 802.11n wireless LAN cards.");
 MODULE_SUPPORTED_DEVICE("Atheros 802.11n WLAN cards");
 MODULE_LICENSE("Dual BSD/GPL");
 
-static int __init ath9k_init(void)
-{
-       return 0;
-}
-module_init(ath9k_init);
-
-static void __exit ath9k_exit(void)
-{
-       return;
-}
-module_exit(ath9k_exit);
-
-/* Private hardware callbacks */
-
-static void ath9k_hw_init_cal_settings(struct ath_hw *ah)
-{
-       ath9k_hw_private_ops(ah)->init_cal_settings(ah);
-}
-
-static u32 ath9k_hw_compute_pll_control(struct ath_hw *ah,
-                                       struct ath9k_channel *chan)
-{
-       return ath9k_hw_private_ops(ah)->compute_pll_control(ah, chan);
-}
-
-static void ath9k_hw_init_mode_gain_regs(struct ath_hw *ah)
-{
-       if (!ath9k_hw_private_ops(ah)->init_mode_gain_regs)
-               return;
-
-       ath9k_hw_private_ops(ah)->init_mode_gain_regs(ah);
-}
-
-static void ath9k_hw_ani_cache_ini_regs(struct ath_hw *ah)
-{
-       /* You will not have this callback if using the old ANI */
-       if (!ath9k_hw_private_ops(ah)->ani_cache_ini_regs)
-               return;
-
-       ath9k_hw_private_ops(ah)->ani_cache_ini_regs(ah);
-}
-
-/********************/
-/* Helper Functions */
-/********************/
-
-#ifdef CONFIG_ATH9K_DEBUGFS
-
-void ath9k_debug_sync_cause(struct ath_common *common, u32 sync_cause)
-{
-       struct ath_softc *sc = common->priv;
-       if (sync_cause)
-               sc->debug.stats.istats.sync_cause_all++;
-       if (sync_cause & AR_INTR_SYNC_RTC_IRQ)
-               sc->debug.stats.istats.sync_rtc_irq++;
-       if (sync_cause & AR_INTR_SYNC_MAC_IRQ)
-               sc->debug.stats.istats.sync_mac_irq++;
-       if (sync_cause & AR_INTR_SYNC_EEPROM_ILLEGAL_ACCESS)
-               sc->debug.stats.istats.eeprom_illegal_access++;
-       if (sync_cause & AR_INTR_SYNC_APB_TIMEOUT)
-               sc->debug.stats.istats.apb_timeout++;
-       if (sync_cause & AR_INTR_SYNC_PCI_MODE_CONFLICT)
-               sc->debug.stats.istats.pci_mode_conflict++;
-       if (sync_cause & AR_INTR_SYNC_HOST1_FATAL)
-               sc->debug.stats.istats.host1_fatal++;
-       if (sync_cause & AR_INTR_SYNC_HOST1_PERR)
-               sc->debug.stats.istats.host1_perr++;
-       if (sync_cause & AR_INTR_SYNC_TRCV_FIFO_PERR)
-               sc->debug.stats.istats.trcv_fifo_perr++;
-       if (sync_cause & AR_INTR_SYNC_RADM_CPL_EP)
-               sc->debug.stats.istats.radm_cpl_ep++;
-       if (sync_cause & AR_INTR_SYNC_RADM_CPL_DLLP_ABORT)
-               sc->debug.stats.istats.radm_cpl_dllp_abort++;
-       if (sync_cause & AR_INTR_SYNC_RADM_CPL_TLP_ABORT)
-               sc->debug.stats.istats.radm_cpl_tlp_abort++;
-       if (sync_cause & AR_INTR_SYNC_RADM_CPL_ECRC_ERR)
-               sc->debug.stats.istats.radm_cpl_ecrc_err++;
-       if (sync_cause & AR_INTR_SYNC_RADM_CPL_TIMEOUT)
-               sc->debug.stats.istats.radm_cpl_timeout++;
-       if (sync_cause & AR_INTR_SYNC_LOCAL_TIMEOUT)
-               sc->debug.stats.istats.local_timeout++;
-       if (sync_cause & AR_INTR_SYNC_PM_ACCESS)
-               sc->debug.stats.istats.pm_access++;
-       if (sync_cause & AR_INTR_SYNC_MAC_AWAKE)
-               sc->debug.stats.istats.mac_awake++;
-       if (sync_cause & AR_INTR_SYNC_MAC_ASLEEP)
-               sc->debug.stats.istats.mac_asleep++;
-       if (sync_cause & AR_INTR_SYNC_MAC_SLEEP_ACCESS)
-               sc->debug.stats.istats.mac_sleep_access++;
-}
-#endif
-
-
 static void ath9k_hw_set_clockrate(struct ath_hw *ah)
 {
        struct ath_common *common = ath9k_hw_common(ah);
@@ -147,10 +55,9 @@ static void ath9k_hw_set_clockrate(struct ath_hw *ah)
        else
                clockrate = ATH9K_CLOCK_RATE_5GHZ_OFDM;
 
-       if (IS_CHAN_HT40(chan))
-               clockrate *= 2;
-
-       if (ah->curchan) {
+       if (chan) {
+               if (IS_CHAN_HT40(chan))
+                       clockrate *= 2;
                if (IS_CHAN_HALF_RATE(chan))
                        clockrate /= 2;
                if (IS_CHAN_QUARTER_RATE(chan))
@@ -338,6 +245,9 @@ static void ath9k_hw_read_revisions(struct ath_hw *ah)
        case AR9300_DEVID_QCA955X:
                ah->hw_version.macVersion = AR_SREV_VERSION_9550;
                return;
+       case AR9300_DEVID_AR953X:
+               ah->hw_version.macVersion = AR_SREV_VERSION_9531;
+               return;
        }
 
        val = REG_READ(ah, AR_SREV) & AR_SREV_ID;
@@ -439,23 +349,23 @@ static bool ath9k_hw_chip_test(struct ath_hw *ah)
 
 static void ath9k_hw_init_config(struct ath_hw *ah)
 {
-       int i;
+       struct ath_common *common = ath9k_hw_common(ah);
 
        ah->config.dma_beacon_response_time = 1;
        ah->config.sw_beacon_response_time = 6;
-       ah->config.additional_swba_backoff = 0;
-       ah->config.ack_6mb = 0x0;
        ah->config.cwm_ignore_extcca = 0;
-       ah->config.pcie_clock_req = 0;
        ah->config.analog_shiftreg = 1;
 
-       for (i = 0; i < AR_EEPROM_MODAL_SPURS; i++) {
-               ah->config.spurchans[i][0] = AR_NO_SPUR;
-               ah->config.spurchans[i][1] = AR_NO_SPUR;
-       }
-
        ah->config.rx_intr_mitigation = true;
 
+       if (AR_SREV_9300_20_OR_LATER(ah)) {
+               ah->config.rimt_last = 500;
+               ah->config.rimt_first = 2000;
+       } else {
+               ah->config.rimt_last = 250;
+               ah->config.rimt_first = 700;
+       }
+
        /*
         * We need this for PCI devices only (Cardbus, PCI, miniPCI)
         * _and_ if on non-uniprocessor systems (Multiprocessor/HT).
@@ -474,6 +384,24 @@ static void ath9k_hw_init_config(struct ath_hw *ah)
         */
        if (num_possible_cpus() > 1)
                ah->config.serialize_regmode = SER_REG_MODE_AUTO;
+
+       if (NR_CPUS > 1 && ah->config.serialize_regmode == SER_REG_MODE_AUTO) {
+               if (ah->hw_version.macVersion == AR_SREV_VERSION_5416_PCI ||
+                   ((AR_SREV_9160(ah) || AR_SREV_9280(ah) || AR_SREV_9287(ah)) &&
+                    !ah->is_pciexpress)) {
+                       ah->config.serialize_regmode = SER_REG_MODE_ON;
+               } else {
+                       ah->config.serialize_regmode = SER_REG_MODE_OFF;
+               }
+       }
+
+       ath_dbg(common, RESET, "serialize_regmode is %d\n",
+               ah->config.serialize_regmode);
+
+       if (AR_SREV_9285(ah) || AR_SREV_9271(ah))
+               ah->config.max_txtrig_level = MAX_TX_FIFO_THRESHOLD >> 1;
+       else
+               ah->config.max_txtrig_level = MAX_TX_FIFO_THRESHOLD;
 }
 
 static void ath9k_hw_init_defaults(struct ath_hw *ah)
@@ -486,16 +414,24 @@ static void ath9k_hw_init_defaults(struct ath_hw *ah)
        ah->hw_version.magic = AR5416_MAGIC;
        ah->hw_version.subvendorid = 0;
 
-       ah->atim_window = 0;
-       ah->sta_id1_defaults =
-               AR_STA_ID1_CRPT_MIC_ENABLE |
-               AR_STA_ID1_MCAST_KSRCH;
+       ah->sta_id1_defaults = AR_STA_ID1_CRPT_MIC_ENABLE |
+                              AR_STA_ID1_MCAST_KSRCH;
        if (AR_SREV_9100(ah))
                ah->sta_id1_defaults |= AR_STA_ID1_AR9100_BA_FIX;
+
        ah->slottime = ATH9K_SLOT_TIME_9;
        ah->globaltxtimeout = (u32) -1;
        ah->power_mode = ATH9K_PM_UNDEFINED;
        ah->htc_reset_init = true;
+
+       ah->ani_function = ATH9K_ANI_ALL;
+       if (!AR_SREV_9300_20_OR_LATER(ah))
+               ah->ani_function &= ~ATH9K_ANI_MRC_CCK;
+
+       if (AR_SREV_9285(ah) || AR_SREV_9271(ah))
+               ah->tx_trig_level = (AR_FTRIG_256B >> AR_FTRIG_S);
+       else
+               ah->tx_trig_level = (AR_FTRIG_512B >> AR_FTRIG_S);
 }
 
 static int ath9k_hw_init_macaddr(struct ath_hw *ah)
@@ -549,11 +485,11 @@ static int ath9k_hw_post_init(struct ath_hw *ah)
         * EEPROM needs to be initialized before we do this.
         * This is required for regulatory compliance.
         */
-       if (AR_SREV_9462(ah) || AR_SREV_9565(ah)) {
+       if (AR_SREV_9300_20_OR_LATER(ah)) {
                u16 regdmn = ah->eep_ops->get_eeprom(ah, EEP_REG_0);
                if ((regdmn & 0xF0) == CTL_FCC) {
-                       ah->nf_2g.max = AR_PHY_CCA_MAX_GOOD_VAL_9462_FCC_2GHZ;
-                       ah->nf_5g.max = AR_PHY_CCA_MAX_GOOD_VAL_9462_FCC_5GHZ;
+                       ah->nf_2g.max = AR_PHY_CCA_MAX_GOOD_VAL_9300_FCC_2GHZ;
+                       ah->nf_5g.max = AR_PHY_CCA_MAX_GOOD_VAL_9300_FCC_5GHZ;
                }
        }
 
@@ -577,6 +513,31 @@ static int __ath9k_hw_init(struct ath_hw *ah)
 
        ath9k_hw_read_revisions(ah);
 
+       switch (ah->hw_version.macVersion) {
+       case AR_SREV_VERSION_5416_PCI:
+       case AR_SREV_VERSION_5416_PCIE:
+       case AR_SREV_VERSION_9160:
+       case AR_SREV_VERSION_9100:
+       case AR_SREV_VERSION_9280:
+       case AR_SREV_VERSION_9285:
+       case AR_SREV_VERSION_9287:
+       case AR_SREV_VERSION_9271:
+       case AR_SREV_VERSION_9300:
+       case AR_SREV_VERSION_9330:
+       case AR_SREV_VERSION_9485:
+       case AR_SREV_VERSION_9340:
+       case AR_SREV_VERSION_9462:
+       case AR_SREV_VERSION_9550:
+       case AR_SREV_VERSION_9565:
+       case AR_SREV_VERSION_9531:
+               break;
+       default:
+               ath_err(common,
+                       "Mac Chip Rev 0x%02x.%x is not supported by this driver\n",
+                       ah->hw_version.macVersion, ah->hw_version.macRev);
+               return -EOPNOTSUPP;
+       }
+
        /*
         * Read back AR_WA into a permanent copy and set bits 14 and 17.
         * We need to do this to avoid RMW of this register. We cannot
@@ -610,50 +571,6 @@ static int __ath9k_hw_init(struct ath_hw *ah)
                return -EIO;
        }
 
-       if (NR_CPUS > 1 && ah->config.serialize_regmode == SER_REG_MODE_AUTO) {
-               if (ah->hw_version.macVersion == AR_SREV_VERSION_5416_PCI ||
-                   ((AR_SREV_9160(ah) || AR_SREV_9280(ah) || AR_SREV_9287(ah)) &&
-                    !ah->is_pciexpress)) {
-                       ah->config.serialize_regmode =
-                               SER_REG_MODE_ON;
-               } else {
-                       ah->config.serialize_regmode =
-                               SER_REG_MODE_OFF;
-               }
-       }
-
-       ath_dbg(common, RESET, "serialize_regmode is %d\n",
-               ah->config.serialize_regmode);
-
-       if (AR_SREV_9285(ah) || AR_SREV_9271(ah))
-               ah->config.max_txtrig_level = MAX_TX_FIFO_THRESHOLD >> 1;
-       else
-               ah->config.max_txtrig_level = MAX_TX_FIFO_THRESHOLD;
-
-       switch (ah->hw_version.macVersion) {
-       case AR_SREV_VERSION_5416_PCI:
-       case AR_SREV_VERSION_5416_PCIE:
-       case AR_SREV_VERSION_9160:
-       case AR_SREV_VERSION_9100:
-       case AR_SREV_VERSION_9280:
-       case AR_SREV_VERSION_9285:
-       case AR_SREV_VERSION_9287:
-       case AR_SREV_VERSION_9271:
-       case AR_SREV_VERSION_9300:
-       case AR_SREV_VERSION_9330:
-       case AR_SREV_VERSION_9485:
-       case AR_SREV_VERSION_9340:
-       case AR_SREV_VERSION_9462:
-       case AR_SREV_VERSION_9550:
-       case AR_SREV_VERSION_9565:
-               break;
-       default:
-               ath_err(common,
-                       "Mac Chip Rev 0x%02x.%x is not supported by this driver\n",
-                       ah->hw_version.macVersion, ah->hw_version.macRev);
-               return -EOPNOTSUPP;
-       }
-
        if (AR_SREV_9271(ah) || AR_SREV_9100(ah) || AR_SREV_9340(ah) ||
            AR_SREV_9330(ah) || AR_SREV_9550(ah))
                ah->is_pciexpress = false;
@@ -661,10 +578,6 @@ static int __ath9k_hw_init(struct ath_hw *ah)
        ah->hw_version.phyRev = REG_READ(ah, AR_PHY_CHIP_ID);
        ath9k_hw_init_cal_settings(ah);
 
-       ah->ani_function = ATH9K_ANI_ALL;
-       if (!AR_SREV_9300_20_OR_LATER(ah))
-               ah->ani_function &= ~ATH9K_ANI_MRC_CCK;
-
        if (!ah->is_pciexpress)
                ath9k_hw_disablepcie(ah);
 
@@ -683,15 +596,7 @@ static int __ath9k_hw_init(struct ath_hw *ah)
                return r;
        }
 
-       if (AR_SREV_9285(ah) || AR_SREV_9271(ah))
-               ah->tx_trig_level = (AR_FTRIG_256B >> AR_FTRIG_S);
-       else
-               ah->tx_trig_level = (AR_FTRIG_512B >> AR_FTRIG_S);
-
-       if (AR_SREV_9330(ah))
-               ah->bb_watchdog_timeout_ms = 85;
-       else
-               ah->bb_watchdog_timeout_ms = 25;
+       ath9k_hw_init_hang_checks(ah);
 
        common->state = ATH_HW_INITIALIZED;
 
@@ -724,6 +629,7 @@ int ath9k_hw_init(struct ath_hw *ah)
        case AR9300_DEVID_AR9462:
        case AR9485_DEVID_AR1111:
        case AR9300_DEVID_AR9565:
+       case AR9300_DEVID_AR953X:
                break;
        default:
                if (common->bus_ops->ath_bus_type == ATH_USB)
@@ -859,7 +765,7 @@ static void ath9k_hw_init_pll(struct ath_hw *ah,
                /* program BB PLL phase_shift */
                REG_RMW_FIELD(ah, AR_CH0_BB_DPLL3,
                              AR_CH0_BB_DPLL3_PHASE_SHIFT, 0x1);
-       } else if (AR_SREV_9340(ah) || AR_SREV_9550(ah)) {
+       } else if (AR_SREV_9340(ah) || AR_SREV_9550(ah) || AR_SREV_9531(ah)) {
                u32 regval, pll2_divint, pll2_divfrac, refdiv;
 
                REG_WRITE(ah, AR_RTC_PLL_CONTROL, 0x1142c);
@@ -869,9 +775,15 @@ static void ath9k_hw_init_pll(struct ath_hw *ah,
                udelay(100);
 
                if (ah->is_clk_25mhz) {
-                       pll2_divint = 0x54;
-                       pll2_divfrac = 0x1eb85;
-                       refdiv = 3;
+                       if (AR_SREV_9531(ah)) {
+                               pll2_divint = 0x1c;
+                               pll2_divfrac = 0xa3d2;
+                               refdiv = 1;
+                       } else {
+                               pll2_divint = 0x54;
+                               pll2_divfrac = 0x1eb85;
+                               refdiv = 3;
+                       }
                } else {
                        if (AR_SREV_9340(ah)) {
                                pll2_divint = 88;
@@ -885,7 +797,10 @@ static void ath9k_hw_init_pll(struct ath_hw *ah,
                }
 
                regval = REG_READ(ah, AR_PHY_PLL_MODE);
-               regval |= (0x1 << 16);
+               if (AR_SREV_9531(ah))
+                       regval |= (0x1 << 22);
+               else
+                       regval |= (0x1 << 16);
                REG_WRITE(ah, AR_PHY_PLL_MODE, regval);
                udelay(100);
 
@@ -895,14 +810,33 @@ static void ath9k_hw_init_pll(struct ath_hw *ah,
 
                regval = REG_READ(ah, AR_PHY_PLL_MODE);
                if (AR_SREV_9340(ah))
-                       regval = (regval & 0x80071fff) | (0x1 << 30) |
-                                (0x1 << 13) | (0x4 << 26) | (0x18 << 19);
+                       regval = (regval & 0x80071fff) |
+                               (0x1 << 30) |
+                               (0x1 << 13) |
+                               (0x4 << 26) |
+                               (0x18 << 19);
+               else if (AR_SREV_9531(ah))
+                       regval = (regval & 0x01c00fff) |
+                               (0x1 << 31) |
+                               (0x2 << 29) |
+                               (0xa << 25) |
+                               (0x1 << 19) |
+                               (0x6 << 12);
                else
-                       regval = (regval & 0x80071fff) | (0x3 << 30) |
-                                (0x1 << 13) | (0x4 << 26) | (0x60 << 19);
+                       regval = (regval & 0x80071fff) |
+                               (0x3 << 30) |
+                               (0x1 << 13) |
+                               (0x4 << 26) |
+                               (0x60 << 19);
                REG_WRITE(ah, AR_PHY_PLL_MODE, regval);
-               REG_WRITE(ah, AR_PHY_PLL_MODE,
-                         REG_READ(ah, AR_PHY_PLL_MODE) & 0xfffeffff);
+
+               if (AR_SREV_9531(ah))
+                       REG_WRITE(ah, AR_PHY_PLL_MODE,
+                                 REG_READ(ah, AR_PHY_PLL_MODE) & 0xffbfffff);
+               else
+                       REG_WRITE(ah, AR_PHY_PLL_MODE,
+                                 REG_READ(ah, AR_PHY_PLL_MODE) & 0xfffeffff);
+
                udelay(1000);
        }
 
@@ -1282,6 +1216,42 @@ void ath9k_hw_get_delta_slope_vals(struct ath_hw *ah, u32 coef_scaled,
        *coef_exponent = coef_exp - 16;
 }
 
+/* AR9330 WAR:
+ * call external reset function to reset WMAC if:
+ * - doing a cold reset
+ * - we have pending frames in the TX queues.
+ */
+static bool ath9k_hw_ar9330_reset_war(struct ath_hw *ah, int type)
+{
+       int i, npend = 0;
+
+       for (i = 0; i < AR_NUM_QCU; i++) {
+               npend = ath9k_hw_numtxpending(ah, i);
+               if (npend)
+                       break;
+       }
+
+       if (ah->external_reset &&
+           (npend || type == ATH9K_RESET_COLD)) {
+               int reset_err = 0;
+
+               ath_dbg(ath9k_hw_common(ah), RESET,
+                       "reset MAC via external reset\n");
+
+               reset_err = ah->external_reset();
+               if (reset_err) {
+                       ath_err(ath9k_hw_common(ah),
+                               "External reset failed, err=%d\n",
+                               reset_err);
+                       return false;
+               }
+
+               REG_WRITE(ah, AR_RTC_RESET, 1);
+       }
+
+       return true;
+}
+
 static bool ath9k_hw_set_reset(struct ath_hw *ah, int type)
 {
        u32 rst_flags;
@@ -1332,38 +1302,8 @@ static bool ath9k_hw_set_reset(struct ath_hw *ah, int type)
        }
 
        if (AR_SREV_9330(ah)) {
-               int npend = 0;
-               int i;
-
-               /* AR9330 WAR:
-                * call external reset function to reset WMAC if:
-                * - doing a cold reset
-                * - we have pending frames in the TX queues
-                */
-
-               for (i = 0; i < AR_NUM_QCU; i++) {
-                       npend = ath9k_hw_numtxpending(ah, i);
-                       if (npend)
-                               break;
-               }
-
-               if (ah->external_reset &&
-                   (npend || type == ATH9K_RESET_COLD)) {
-                       int reset_err = 0;
-
-                       ath_dbg(ath9k_hw_common(ah), RESET,
-                               "reset MAC via external reset\n");
-
-                       reset_err = ah->external_reset();
-                       if (reset_err) {
-                               ath_err(ath9k_hw_common(ah),
-                                       "External reset failed, err=%d\n",
-                                       reset_err);
-                               return false;
-                       }
-
-                       REG_WRITE(ah, AR_RTC_RESET, 1);
-               }
+               if (!ath9k_hw_ar9330_reset_war(ah, type))
+                       return false;
        }
 
        if (ath9k_hw_mci_is_enabled(ah))
@@ -1373,7 +1313,12 @@ static bool ath9k_hw_set_reset(struct ath_hw *ah, int type)
 
        REGWRITE_BUFFER_FLUSH(ah);
 
-       udelay(50);
+       if (AR_SREV_9300_20_OR_LATER(ah))
+               udelay(50);
+       else if (AR_SREV_9100(ah))
+               udelay(10000);
+       else
+               udelay(100);
 
        REG_WRITE(ah, AR_RTC_RC, 0);
        if (!ath9k_hw_wait(ah, AR_RTC_RC, AR_RTC_RC_M, 0, AH_WAIT_TIMEOUT)) {
@@ -1409,8 +1354,7 @@ static bool ath9k_hw_set_reset_power_on(struct ath_hw *ah)
 
        REGWRITE_BUFFER_FLUSH(ah);
 
-       if (!AR_SREV_9300_20_OR_LATER(ah))
-               udelay(2);
+       udelay(2);
 
        if (!AR_SREV_9100(ah) && !AR_SREV_9300_20_OR_LATER(ah))
                REG_WRITE(ah, AR_RC, 0);
@@ -1486,7 +1430,6 @@ static bool ath9k_hw_chip_reset(struct ath_hw *ah,
        if (AR_SREV_9330(ah))
                ar9003_hw_internal_regulator_apply(ah);
        ath9k_hw_init_pll(ah, chan);
-       ath9k_hw_set_rfmode(ah, chan);
 
        return true;
 }
@@ -1575,76 +1518,6 @@ static void ath9k_hw_apply_gpio_override(struct ath_hw *ah)
        }
 }
 
-static bool ath9k_hw_check_dcs(u32 dma_dbg, u32 num_dcu_states,
-                              int *hang_state, int *hang_pos)
-{
-       static u32 dcu_chain_state[] = {5, 6, 9}; /* DCU chain stuck states */
-       u32 chain_state, dcs_pos, i;
-
-       for (dcs_pos = 0; dcs_pos < num_dcu_states; dcs_pos++) {
-               chain_state = (dma_dbg >> (5 * dcs_pos)) & 0x1f;
-               for (i = 0; i < 3; i++) {
-                       if (chain_state == dcu_chain_state[i]) {
-                               *hang_state = chain_state;
-                               *hang_pos = dcs_pos;
-                               return true;
-                       }
-               }
-       }
-       return false;
-}
-
-#define DCU_COMPLETE_STATE        1
-#define DCU_COMPLETE_STATE_MASK 0x3
-#define NUM_STATUS_READS         50
-static bool ath9k_hw_detect_mac_hang(struct ath_hw *ah)
-{
-       u32 chain_state, comp_state, dcs_reg = AR_DMADBG_4;
-       u32 i, hang_pos, hang_state, num_state = 6;
-
-       comp_state = REG_READ(ah, AR_DMADBG_6);
-
-       if ((comp_state & DCU_COMPLETE_STATE_MASK) != DCU_COMPLETE_STATE) {
-               ath_dbg(ath9k_hw_common(ah), RESET,
-                       "MAC Hang signature not found at DCU complete\n");
-               return false;
-       }
-
-       chain_state = REG_READ(ah, dcs_reg);
-       if (ath9k_hw_check_dcs(chain_state, num_state, &hang_state, &hang_pos))
-               goto hang_check_iter;
-
-       dcs_reg = AR_DMADBG_5;
-       num_state = 4;
-       chain_state = REG_READ(ah, dcs_reg);
-       if (ath9k_hw_check_dcs(chain_state, num_state, &hang_state, &hang_pos))
-               goto hang_check_iter;
-
-       ath_dbg(ath9k_hw_common(ah), RESET,
-               "MAC Hang signature 1 not found\n");
-       return false;
-
-hang_check_iter:
-       ath_dbg(ath9k_hw_common(ah), RESET,
-               "DCU registers: chain %08x complete %08x Hang: state %d pos %d\n",
-               chain_state, comp_state, hang_state, hang_pos);
-
-       for (i = 0; i < NUM_STATUS_READS; i++) {
-               chain_state = REG_READ(ah, dcs_reg);
-               chain_state = (chain_state >> (5 * hang_pos)) & 0x1f;
-               comp_state = REG_READ(ah, AR_DMADBG_6);
-
-               if (((comp_state & DCU_COMPLETE_STATE_MASK) !=
-                                       DCU_COMPLETE_STATE) ||
-                   (chain_state != hang_state))
-                       return false;
-       }
-
-       ath_dbg(ath9k_hw_common(ah), RESET, "MAC Hang signature 1 found\n");
-
-       return true;
-}
-
 void ath9k_hw_check_nav(struct ath_hw *ah)
 {
        struct ath_common *common = ath9k_hw_common(ah);
@@ -1719,7 +1592,6 @@ static void ath9k_hw_reset_opmode(struct ath_hw *ah,
 
        REG_RMW(ah, AR_STA_ID1, macStaId1
                  | AR_STA_ID1_RTS_USE_DEF
-                 | (ah->config.ack_6mb ? AR_STA_ID1_ACKCTS_6MB : 0)
                  | ah->sta_id1_defaults,
                  ~AR_STA_ID1_SADH_MASK);
        ath_hw_setbssidmask(common);
@@ -1778,7 +1650,7 @@ static void ath9k_hw_init_desc(struct ath_hw *ah)
                }
 #ifdef __BIG_ENDIAN
                else if (AR_SREV_9330(ah) || AR_SREV_9340(ah) ||
-                        AR_SREV_9550(ah))
+                        AR_SREV_9550(ah) || AR_SREV_9531(ah))
                        REG_RMW(ah, AR_CFG, AR_CFG_SWRB | AR_CFG_SWTB, 0);
                else
                        REG_WRITE(ah, AR_CFG, AR_CFG_SWTD | AR_CFG_SWRD);
@@ -1908,7 +1780,7 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
        /* Save TSF before chip reset, a cold reset clears it */
        tsf = ath9k_hw_gettsf64(ah);
        getrawmonotonic(&ts);
-       usec = ts.tv_sec * 1000 + ts.tv_nsec / 1000;
+       usec = ts.tv_sec * 1000000ULL + ts.tv_nsec / 1000;
 
        saveLedState = REG_READ(ah, AR_CFG_LED) &
                (AR_CFG_LED_ASSOC_CTL | AR_CFG_LED_MODE_SEL |
@@ -1942,7 +1814,7 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
 
        /* Restore TSF */
        getrawmonotonic(&ts);
-       usec = ts.tv_sec * 1000 + ts.tv_nsec / 1000 - usec;
+       usec = ts.tv_sec * 1000000ULL + ts.tv_nsec / 1000 - usec;
        ath9k_hw_settsf64(ah, tsf + usec);
 
        if (AR_SREV_9280_20_OR_LATER(ah))
@@ -1955,6 +1827,8 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
        if (r)
                return r;
 
+       ath9k_hw_set_rfmode(ah, chan);
+
        if (ath9k_hw_mci_is_enabled(ah))
                ar9003_mci_reset(ah, false, IS_CHAN_2GHZ(chan), save_fullsleep);
 
@@ -2010,8 +1884,8 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
                REG_WRITE(ah, AR_OBS, 8);
 
        if (ah->config.rx_intr_mitigation) {
-               REG_RMW_FIELD(ah, AR_RIMT, AR_RIMT_LAST, 500);
-               REG_RMW_FIELD(ah, AR_RIMT, AR_RIMT_FIRST, 2000);
+               REG_RMW_FIELD(ah, AR_RIMT, AR_RIMT_LAST, ah->config.rimt_last);
+               REG_RMW_FIELD(ah, AR_RIMT, AR_RIMT_FIRST, ah->config.rimt_first);
        }
 
        if (ah->config.tx_intr_mitigation) {
@@ -2049,10 +1923,11 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
        ath9k_hw_loadnf(ah, chan);
        ath9k_hw_start_nfcal(ah, true);
 
-       if (AR_SREV_9300_20_OR_LATER(ah)) {
+       if (AR_SREV_9300_20_OR_LATER(ah))
                ar9003_hw_bb_watchdog_config(ah);
+
+       if (ah->config.hw_hang_checks & HW_PHYRESTART_CLC_WAR)
                ar9003_hw_disable_phy_restart(ah);
-       }
 
        ath9k_hw_apply_gpio_override(ah);
 
@@ -2176,7 +2051,11 @@ static bool ath9k_hw_set_power_awake(struct ath_hw *ah)
 
        REG_SET_BIT(ah, AR_RTC_FORCE_WAKE,
                    AR_RTC_FORCE_WAKE_EN);
-       udelay(50);
+
+       if (AR_SREV_9100(ah))
+               udelay(10000);
+       else
+               udelay(50);
 
        for (i = POWER_UP_TIME / 50; i > 0; i--) {
                val = REG_READ(ah, AR_RTC_STATUS) & AR_RTC_STATUS_M;
@@ -2265,9 +2144,6 @@ void ath9k_hw_beaconinit(struct ath_hw *ah, u32 next_beacon, u32 beacon_period)
        case NL80211_IFTYPE_ADHOC:
                REG_SET_BIT(ah, AR_TXCFG,
                            AR_TXCFG_ADHOC_BEACON_ATIM_TX_POLICY);
-               REG_WRITE(ah, AR_NEXT_NDP_TIMER, next_beacon +
-                         TU_TO_USEC(ah->atim_window ? ah->atim_window : 1));
-               flags |= AR_NDP_TIMER_EN;
        case NL80211_IFTYPE_MESH_POINT:
        case NL80211_IFTYPE_AP:
                REG_WRITE(ah, AR_NEXT_TBTT_TIMER, next_beacon);
@@ -2288,7 +2164,6 @@ void ath9k_hw_beaconinit(struct ath_hw *ah, u32 next_beacon, u32 beacon_period)
        REG_WRITE(ah, AR_BEACON_PERIOD, beacon_period);
        REG_WRITE(ah, AR_DMA_BEACON_PERIOD, beacon_period);
        REG_WRITE(ah, AR_SWBA_PERIOD, beacon_period);
-       REG_WRITE(ah, AR_NDP_PERIOD, beacon_period);
 
        REGWRITE_BUFFER_FLUSH(ah);
 
@@ -2305,12 +2180,9 @@ void ath9k_hw_set_sta_beacon_timers(struct ath_hw *ah,
 
        ENABLE_REGWRITE_BUFFER(ah);
 
-       REG_WRITE(ah, AR_NEXT_TBTT_TIMER, TU_TO_USEC(bs->bs_nexttbtt));
-
-       REG_WRITE(ah, AR_BEACON_PERIOD,
-                 TU_TO_USEC(bs->bs_intval));
-       REG_WRITE(ah, AR_DMA_BEACON_PERIOD,
-                 TU_TO_USEC(bs->bs_intval));
+       REG_WRITE(ah, AR_NEXT_TBTT_TIMER, bs->bs_nexttbtt);
+       REG_WRITE(ah, AR_BEACON_PERIOD, bs->bs_intval);
+       REG_WRITE(ah, AR_DMA_BEACON_PERIOD, bs->bs_intval);
 
        REGWRITE_BUFFER_FLUSH(ah);
 
@@ -2338,9 +2210,8 @@ void ath9k_hw_set_sta_beacon_timers(struct ath_hw *ah,
 
        ENABLE_REGWRITE_BUFFER(ah);
 
-       REG_WRITE(ah, AR_NEXT_DTIM,
-                 TU_TO_USEC(bs->bs_nextdtim - SLEEP_SLOP));
-       REG_WRITE(ah, AR_NEXT_TIM, TU_TO_USEC(nextTbtt - SLEEP_SLOP));
+       REG_WRITE(ah, AR_NEXT_DTIM, bs->bs_nextdtim - SLEEP_SLOP);
+       REG_WRITE(ah, AR_NEXT_TIM, nextTbtt - SLEEP_SLOP);
 
        REG_WRITE(ah, AR_SLEEP1,
                  SM((CAB_TIMEOUT_VAL << 3), AR_SLEEP1_CAB_TIMEOUT)
@@ -2354,8 +2225,8 @@ void ath9k_hw_set_sta_beacon_timers(struct ath_hw *ah,
        REG_WRITE(ah, AR_SLEEP2,
                  SM(beacontimeout, AR_SLEEP2_BEACON_TIMEOUT));
 
-       REG_WRITE(ah, AR_TIM_PERIOD, TU_TO_USEC(beaconintval));
-       REG_WRITE(ah, AR_DTIM_PERIOD, TU_TO_USEC(dtimperiod));
+       REG_WRITE(ah, AR_TIM_PERIOD, beaconintval);
+       REG_WRITE(ah, AR_DTIM_PERIOD, dtimperiod);
 
        REGWRITE_BUFFER_FLUSH(ah);
 
@@ -2613,13 +2484,6 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah)
            ah->eep_ops->get_eeprom(ah, EEP_PAPRD))
                        pCap->hw_caps |= ATH9K_HW_CAP_PAPRD;
 
-       /*
-        * Fast channel change across bands is available
-        * only for AR9462 and AR9565.
-        */
-       if (AR_SREV_9462(ah) || AR_SREV_9565(ah))
-               pCap->hw_caps |= ATH9K_HW_CAP_FCC_BAND_SWITCH;
-
        return 0;
 }
 
@@ -2991,20 +2855,6 @@ static const struct ath_gen_timer_configuration gen_tmr_configuration[] =
 
 /* HW generic timer primitives */
 
-/* compute and clear index of rightmost 1 */
-static u32 rightmost_index(struct ath_gen_timer_table *timer_table, u32 *mask)
-{
-       u32 b;
-
-       b = *mask;
-       b &= (0-b);
-       *mask &= ~b;
-       b *= debruijn32;
-       b >>= 27;
-
-       return timer_table->gen_timer_index[b];
-}
-
 u32 ath9k_hw_gettsf32(struct ath_hw *ah)
 {
        return REG_READ(ah, AR_TSF_L32);
@@ -3020,6 +2870,10 @@ struct ath_gen_timer *ath_gen_timer_alloc(struct ath_hw *ah,
        struct ath_gen_timer_table *timer_table = &ah->hw_gen_timers;
        struct ath_gen_timer *timer;
 
+       if ((timer_index < AR_FIRST_NDP_TIMER) ||
+               (timer_index >= ATH_MAX_GEN_TIMER))
+               return NULL;
+
        timer = kzalloc(sizeof(struct ath_gen_timer), GFP_KERNEL);
        if (timer == NULL)
                return NULL;
@@ -3037,23 +2891,13 @@ EXPORT_SYMBOL(ath_gen_timer_alloc);
 
 void ath9k_hw_gen_timer_start(struct ath_hw *ah,
                              struct ath_gen_timer *timer,
-                             u32 trig_timeout,
+                             u32 timer_next,
                              u32 timer_period)
 {
        struct ath_gen_timer_table *timer_table = &ah->hw_gen_timers;
-       u32 tsf, timer_next;
-
-       BUG_ON(!timer_period);
-
-       set_bit(timer->index, &timer_table->timer_mask.timer_bits);
+       u32 mask = 0;
 
-       tsf = ath9k_hw_gettsf32(ah);
-
-       timer_next = tsf + trig_timeout;
-
-       ath_dbg(ath9k_hw_common(ah), BTCOEX,
-               "current tsf %x period %x timer_next %x\n",
-               tsf, timer_period, timer_next);
+       timer_table->timer_mask |= BIT(timer->index);
 
        /*
         * Program generic timer registers
@@ -3079,10 +2923,19 @@ void ath9k_hw_gen_timer_start(struct ath_hw *ah,
                                       (1 << timer->index));
        }
 
-       /* Enable both trigger and thresh interrupt masks */
-       REG_SET_BIT(ah, AR_IMR_S5,
-               (SM(AR_GENTMR_BIT(timer->index), AR_IMR_S5_GENTIMER_THRESH) |
-               SM(AR_GENTMR_BIT(timer->index), AR_IMR_S5_GENTIMER_TRIG)));
+       if (timer->trigger)
+               mask |= SM(AR_GENTMR_BIT(timer->index),
+                          AR_IMR_S5_GENTIMER_TRIG);
+       if (timer->overflow)
+               mask |= SM(AR_GENTMR_BIT(timer->index),
+                          AR_IMR_S5_GENTIMER_THRESH);
+
+       REG_SET_BIT(ah, AR_IMR_S5, mask);
+
+       if ((ah->imask & ATH9K_INT_GENTIMER) == 0) {
+               ah->imask |= ATH9K_INT_GENTIMER;
+               ath9k_hw_set_interrupts(ah);
+       }
 }
 EXPORT_SYMBOL(ath9k_hw_gen_timer_start);
 
@@ -3090,11 +2943,6 @@ void ath9k_hw_gen_timer_stop(struct ath_hw *ah, struct ath_gen_timer *timer)
 {
        struct ath_gen_timer_table *timer_table = &ah->hw_gen_timers;
 
-       if ((timer->index < AR_FIRST_NDP_TIMER) ||
-               (timer->index >= ATH_MAX_GEN_TIMER)) {
-               return;
-       }
-
        /* Clear generic timer enable bits. */
        REG_CLR_BIT(ah, gen_tmr_configuration[timer->index].mode_addr,
                        gen_tmr_configuration[timer->index].mode_mask);
@@ -3114,7 +2962,12 @@ void ath9k_hw_gen_timer_stop(struct ath_hw *ah, struct ath_gen_timer *timer)
                (SM(AR_GENTMR_BIT(timer->index), AR_IMR_S5_GENTIMER_THRESH) |
                SM(AR_GENTMR_BIT(timer->index), AR_IMR_S5_GENTIMER_TRIG)));
 
-       clear_bit(timer->index, &timer_table->timer_mask.timer_bits);
+       timer_table->timer_mask &= ~BIT(timer->index);
+
+       if (timer_table->timer_mask == 0) {
+               ah->imask &= ~ATH9K_INT_GENTIMER;
+               ath9k_hw_set_interrupts(ah);
+       }
 }
 EXPORT_SYMBOL(ath9k_hw_gen_timer_stop);
 
@@ -3135,32 +2988,32 @@ void ath_gen_timer_isr(struct ath_hw *ah)
 {
        struct ath_gen_timer_table *timer_table = &ah->hw_gen_timers;
        struct ath_gen_timer *timer;
-       struct ath_common *common = ath9k_hw_common(ah);
-       u32 trigger_mask, thresh_mask, index;
+       unsigned long trigger_mask, thresh_mask;
+       unsigned int index;
 
        /* get hardware generic timer interrupt status */
        trigger_mask = ah->intr_gen_timer_trigger;
        thresh_mask = ah->intr_gen_timer_thresh;
-       trigger_mask &= timer_table->timer_mask.val;
-       thresh_mask &= timer_table->timer_mask.val;
-
-       trigger_mask &= ~thresh_mask;
+       trigger_mask &= timer_table->timer_mask;
+       thresh_mask &= timer_table->timer_mask;
 
-       while (thresh_mask) {
-               index = rightmost_index(timer_table, &thresh_mask);
+       for_each_set_bit(index, &thresh_mask, ARRAY_SIZE(timer_table->timers)) {
                timer = timer_table->timers[index];
-               BUG_ON(!timer);
-               ath_dbg(common, BTCOEX, "TSF overflow for Gen timer %d\n",
-                       index);
+               if (!timer)
+                   continue;
+               if (!timer->overflow)
+                   continue;
+
+               trigger_mask &= ~BIT(index);
                timer->overflow(timer->arg);
        }
 
-       while (trigger_mask) {
-               index = rightmost_index(timer_table, &trigger_mask);
+       for_each_set_bit(index, &trigger_mask, ARRAY_SIZE(timer_table->timers)) {
                timer = timer_table->timers[index];
-               BUG_ON(!timer);
-               ath_dbg(common, BTCOEX,
-                       "Gen timer[%d] trigger\n", index);
+               if (!timer)
+                   continue;
+               if (!timer->trigger)
+                   continue;
                timer->trigger(timer->arg);
        }
 }