ath9k_hw: Fix full sleep setup for AR9271
[safe/jmp/linux-2.6] / drivers / net / wireless / ath / ath9k / hw.c
index b25eedf..023c38b 100644 (file)
@@ -52,28 +52,6 @@ module_exit(ath9k_exit);
 /* Helper Functions */
 /********************/
 
-static u32 ath9k_hw_mac_usec(struct ath_hw *ah, u32 clks)
-{
-       struct ieee80211_conf *conf = &ath9k_hw_common(ah)->hw->conf;
-
-       if (!ah->curchan) /* should really check for CCK instead */
-               return clks / ATH9K_CLOCK_RATE_CCK;
-       if (conf->channel->band == IEEE80211_BAND_2GHZ)
-               return clks / ATH9K_CLOCK_RATE_2GHZ_OFDM;
-
-       return clks / ATH9K_CLOCK_RATE_5GHZ_OFDM;
-}
-
-static u32 ath9k_hw_mac_to_usec(struct ath_hw *ah, u32 clks)
-{
-       struct ieee80211_conf *conf = &ath9k_hw_common(ah)->hw->conf;
-
-       if (conf_is_ht40(conf))
-               return ath9k_hw_mac_usec(ah, clks) / 2;
-       else
-               return ath9k_hw_mac_usec(ah, clks);
-}
-
 static u32 ath9k_hw_mac_clks(struct ath_hw *ah, u32 usecs)
 {
        struct ieee80211_conf *conf = &ath9k_hw_common(ah)->hw->conf;
@@ -148,22 +126,19 @@ bool ath9k_get_channel_edges(struct ath_hw *ah,
 }
 
 u16 ath9k_hw_computetxtime(struct ath_hw *ah,
-                          const struct ath_rate_table *rates,
+                          u8 phy, int kbps,
                           u32 frameLen, u16 rateix,
                           bool shortPreamble)
 {
        u32 bitsPerSymbol, numBits, numSymbols, phyTime, txTime;
-       u32 kbps;
-
-       kbps = rates->info[rateix].ratekbps;
 
        if (kbps == 0)
                return 0;
 
-       switch (rates->info[rateix].phy) {
+       switch (phy) {
        case WLAN_RC_PHY_CCK:
                phyTime = CCK_PREAMBLE_BITS + CCK_PLCP_BITS;
-               if (shortPreamble && rates->info[rateix].short_preamble)
+               if (shortPreamble)
                        phyTime >>= 1;
                numBits = frameLen << 3;
                txTime = CCK_SIFS_TIME + phyTime + ((numBits * 1000) / kbps);
@@ -194,8 +169,7 @@ u16 ath9k_hw_computetxtime(struct ath_hw *ah,
                break;
        default:
                ath_print(ath9k_hw_common(ah), ATH_DBG_FATAL,
-                         "Unknown phy %u (rate ix %u)\n",
-                         rates->info[rateix].phy, rateix);
+                         "Unknown phy %u (rate ix %u)\n", phy, rateix);
                txTime = 0;
                break;
        }
@@ -347,30 +321,6 @@ static bool ath9k_hw_chip_test(struct ath_hw *ah)
        return true;
 }
 
-static const char *ath9k_hw_devname(u16 devid)
-{
-       switch (devid) {
-       case AR5416_DEVID_PCI:
-               return "Atheros 5416";
-       case AR5416_DEVID_PCIE:
-               return "Atheros 5418";
-       case AR9160_DEVID_PCI:
-               return "Atheros 9160";
-       case AR5416_AR9100_DEVID:
-               return "Atheros 9100";
-       case AR9280_DEVID_PCI:
-       case AR9280_DEVID_PCIE:
-               return "Atheros 9280";
-       case AR9285_DEVID_PCIE:
-               return "Atheros 9285";
-       case AR5416_DEVID_AR9287_PCI:
-       case AR5416_DEVID_AR9287_PCIE:
-               return "Atheros 9287";
-       }
-
-       return NULL;
-}
-
 static void ath9k_hw_init_config(struct ath_hw *ah)
 {
        int i;
@@ -384,21 +334,23 @@ static void ath9k_hw_init_config(struct ath_hw *ah)
        ah->config.pcie_clock_req = 0;
        ah->config.pcie_waen = 0;
        ah->config.analog_shiftreg = 1;
-       ah->config.ht_enable = 1;
        ah->config.ofdm_trig_low = 200;
        ah->config.ofdm_trig_high = 500;
        ah->config.cck_trig_high = 200;
        ah->config.cck_trig_low = 100;
        ah->config.enable_ani = 1;
-       ah->config.diversity_control = ATH9K_ANT_VARIABLE;
-       ah->config.antenna_switch_swap = 0;
 
        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.intr_mitigation = true;
+       if (ah->hw_version.devid != AR2427_DEVID_PCIE)
+               ah->config.ht_enable = 1;
+       else
+               ah->config.ht_enable = 0;
+
+       ah->config.rx_intr_mitigation = true;
 
        /*
         * We need this for PCI devices only (Cardbus, PCI, miniPCI)
@@ -443,12 +395,7 @@ static void ath9k_hw_init_defaults(struct ath_hw *ah)
        ah->beacon_interval = 100;
        ah->enable_32kHz_clock = DONT_USE_32KHZ;
        ah->slottime = (u32) -1;
-       ah->acktimeout = (u32) -1;
-       ah->ctstimeout = (u32) -1;
        ah->globaltxtimeout = (u32) -1;
-
-       ah->gbeacon_rate = 0;
-
        ah->power_mode = ATH9K_PM_UNDEFINED;
 }
 
@@ -552,8 +499,10 @@ static int ath9k_hw_post_init(struct ath_hw *ah)
 {
        int ecode;
 
-       if (!ath9k_hw_chip_test(ah))
-               return -ENODEV;
+       if (!AR_SREV_9271(ah)) {
+               if (!ath9k_hw_chip_test(ah))
+                       return -ENODEV;
+       }
 
        ecode = ath9k_hw_rf_claim(ah);
        if (ecode != 0)
@@ -599,6 +548,7 @@ static bool ath9k_hw_devid_supported(u16 devid)
        case AR5416_DEVID_AR9287_PCI:
        case AR5416_DEVID_AR9287_PCIE:
        case AR9271_USB:
+       case AR2427_DEVID_PCIE:
                return true;
        default:
                break;
@@ -655,9 +605,23 @@ static void ath9k_hw_init_mode_regs(struct ath_hw *ah)
                               ARRAY_SIZE(ar9271Modes_9271), 6);
                INIT_INI_ARRAY(&ah->iniCommon, ar9271Common_9271,
                               ARRAY_SIZE(ar9271Common_9271), 2);
+               INIT_INI_ARRAY(&ah->iniCommon_normal_cck_fir_coeff_9271,
+                              ar9271Common_normal_cck_fir_coeff_9271,
+                              ARRAY_SIZE(ar9271Common_normal_cck_fir_coeff_9271), 2);
+               INIT_INI_ARRAY(&ah->iniCommon_japan_2484_cck_fir_coeff_9271,
+                              ar9271Common_japan_2484_cck_fir_coeff_9271,
+                              ARRAY_SIZE(ar9271Common_japan_2484_cck_fir_coeff_9271), 2);
                INIT_INI_ARRAY(&ah->iniModes_9271_1_0_only,
                               ar9271Modes_9271_1_0_only,
                               ARRAY_SIZE(ar9271Modes_9271_1_0_only), 6);
+               INIT_INI_ARRAY(&ah->iniModes_9271_ANI_reg, ar9271Modes_9271_ANI_reg,
+                              ARRAY_SIZE(ar9271Modes_9271_ANI_reg), 6);
+               INIT_INI_ARRAY(&ah->iniModes_high_power_tx_gain_9271,
+                              ar9271Modes_high_power_tx_gain_9271,
+                              ARRAY_SIZE(ar9271Modes_high_power_tx_gain_9271), 6);
+               INIT_INI_ARRAY(&ah->iniModes_normal_power_tx_gain_9271,
+                              ar9271Modes_normal_power_tx_gain_9271,
+                              ARRAY_SIZE(ar9271Modes_normal_power_tx_gain_9271), 6);
                return;
        }
 
@@ -864,12 +828,11 @@ static void ath9k_hw_init_mode_gain_regs(struct ath_hw *ah)
        }
 }
 
-static void ath9k_hw_init_11a_eeprom_fix(struct ath_hw *ah)
+static void ath9k_hw_init_eeprom_fix(struct ath_hw *ah)
 {
        u32 i, j;
 
-       if ((ah->hw_version.devid == AR9280_DEVID_PCI) &&
-           test_bit(ATH9K_MODE_11A, ah->caps.wireless_modes)) {
+       if (ah->hw_version.devid == AR9280_DEVID_PCI) {
 
                /* EEPROM Fixup */
                for (i = 0; i < ah->iniModes.ia_rows; i++) {
@@ -927,6 +890,11 @@ int ath9k_hw_init(struct ath_hw *ah)
        ath_print(common, ATH_DBG_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;
+
        if (!ath9k_hw_macversion_supported(ah->hw_version.macVersion)) {
                ath_print(common, ATH_DBG_FATAL,
                          "Mac Chip Rev 0x%02x.%x is not supported by "
@@ -980,8 +948,11 @@ int ath9k_hw_init(struct ath_hw *ah)
                return r;
 
        ath9k_hw_init_mode_gain_regs(ah);
-       ath9k_hw_fill_cap_info(ah);
-       ath9k_hw_init_11a_eeprom_fix(ah);
+       r = ath9k_hw_fill_cap_info(ah);
+       if (r)
+               return r;
+
+       ath9k_hw_init_eeprom_fix(ah);
 
        r = ath9k_hw_init_macaddr(ah);
        if (r) {
@@ -1151,7 +1122,7 @@ static void ath9k_hw_init_chain_masks(struct ath_hw *ah)
                REG_SET_BIT(ah, AR_PHY_ANALOG_SWAP,
                            AR_PHY_SWAP_ALT_CHAIN);
        case 0x3:
-               if (((ah)->hw_version.macVersion <= AR_SREV_VERSION_9160)) {
+               if (ah->hw_version.macVersion == AR_SREV_REVISION_5416_10) {
                        REG_WRITE(ah, AR_PHY_RX_CHAINMASK, 0x7);
                        REG_WRITE(ah, AR_PHY_CAL_CHAINMASK, 0x7);
                        break;
@@ -1185,7 +1156,7 @@ static void ath9k_hw_init_interrupt_masks(struct ath_hw *ah,
                AR_IMR_RXORN |
                AR_IMR_BCNMISC;
 
-       if (ah->config.intr_mitigation)
+       if (ah->config.rx_intr_mitigation)
                ah->mask_reg |= AR_IMR_RXINTM | AR_IMR_RXMINTR;
        else
                ah->mask_reg |= AR_IMR_RXOK;
@@ -1196,7 +1167,8 @@ static void ath9k_hw_init_interrupt_masks(struct ath_hw *ah,
                ah->mask_reg |= AR_IMR_MIB;
 
        REG_WRITE(ah, AR_IMR, ah->mask_reg);
-       REG_WRITE(ah, AR_IMR_S2, REG_READ(ah, AR_IMR_S2) | AR_IMR_S2_GTT);
+       ah->imrs2_reg |= AR_IMR_S2_GTT;
+       REG_WRITE(ah, AR_IMR_S2, ah->imrs2_reg);
 
        if (!AR_SREV_9100(ah)) {
                REG_WRITE(ah, AR_INTR_SYNC_CAUSE, 0xFFFFFFFF);
@@ -1205,34 +1177,25 @@ static void ath9k_hw_init_interrupt_masks(struct ath_hw *ah,
        }
 }
 
-static bool ath9k_hw_set_ack_timeout(struct ath_hw *ah, u32 us)
+static void ath9k_hw_setslottime(struct ath_hw *ah, u32 us)
 {
-       if (us > ath9k_hw_mac_to_usec(ah, MS(0xffffffff, AR_TIME_OUT_ACK))) {
-               ath_print(ath9k_hw_common(ah), ATH_DBG_RESET,
-                         "bad ack timeout %u\n", us);
-               ah->acktimeout = (u32) -1;
-               return false;
-       } else {
-               REG_RMW_FIELD(ah, AR_TIME_OUT,
-                             AR_TIME_OUT_ACK, ath9k_hw_mac_to_clks(ah, us));
-               ah->acktimeout = us;
-               return true;
-       }
+       u32 val = ath9k_hw_mac_to_clks(ah, us);
+       val = min(val, (u32) 0xFFFF);
+       REG_WRITE(ah, AR_D_GBL_IFS_SLOT, val);
 }
 
-static bool ath9k_hw_set_cts_timeout(struct ath_hw *ah, u32 us)
+static void ath9k_hw_set_ack_timeout(struct ath_hw *ah, u32 us)
 {
-       if (us > ath9k_hw_mac_to_usec(ah, MS(0xffffffff, AR_TIME_OUT_CTS))) {
-               ath_print(ath9k_hw_common(ah), ATH_DBG_RESET,
-                         "bad cts timeout %u\n", us);
-               ah->ctstimeout = (u32) -1;
-               return false;
-       } else {
-               REG_RMW_FIELD(ah, AR_TIME_OUT,
-                             AR_TIME_OUT_CTS, ath9k_hw_mac_to_clks(ah, us));
-               ah->ctstimeout = us;
-               return true;
-       }
+       u32 val = ath9k_hw_mac_to_clks(ah, us);
+       val = min(val, (u32) MS(0xFFFFFFFF, AR_TIME_OUT_ACK));
+       REG_RMW_FIELD(ah, AR_TIME_OUT, AR_TIME_OUT_ACK, val);
+}
+
+static void ath9k_hw_set_cts_timeout(struct ath_hw *ah, u32 us)
+{
+       u32 val = ath9k_hw_mac_to_clks(ah, us);
+       val = min(val, (u32) MS(0xFFFFFFFF, AR_TIME_OUT_CTS));
+       REG_RMW_FIELD(ah, AR_TIME_OUT, AR_TIME_OUT_CTS, val);
 }
 
 static bool ath9k_hw_set_global_txtimeout(struct ath_hw *ah, u32 tu)
@@ -1249,31 +1212,48 @@ static bool ath9k_hw_set_global_txtimeout(struct ath_hw *ah, u32 tu)
        }
 }
 
-static void ath9k_hw_init_user_settings(struct ath_hw *ah)
+void ath9k_hw_init_global_settings(struct ath_hw *ah)
 {
+       struct ieee80211_conf *conf = &ath9k_hw_common(ah)->hw->conf;
+       int acktimeout;
+       int slottime;
+       int sifstime;
+
        ath_print(ath9k_hw_common(ah), ATH_DBG_RESET, "ah->misc_mode 0x%x\n",
                  ah->misc_mode);
 
        if (ah->misc_mode != 0)
                REG_WRITE(ah, AR_PCU_MISC,
                          REG_READ(ah, AR_PCU_MISC) | ah->misc_mode);
-       if (ah->slottime != (u32) -1)
-               ath9k_hw_setslottime(ah, ah->slottime);
-       if (ah->acktimeout != (u32) -1)
-               ath9k_hw_set_ack_timeout(ah, ah->acktimeout);
-       if (ah->ctstimeout != (u32) -1)
-               ath9k_hw_set_cts_timeout(ah, ah->ctstimeout);
+
+       if (conf->channel && conf->channel->band == IEEE80211_BAND_5GHZ)
+               sifstime = 16;
+       else
+               sifstime = 10;
+
+       /* As defined by IEEE 802.11-2007 17.3.8.6 */
+       slottime = ah->slottime + 3 * ah->coverage_class;
+       acktimeout = slottime + sifstime;
+
+       /*
+        * Workaround for early ACK timeouts, add an offset to match the
+        * initval's 64us ack timeout value.
+        * This was initially only meant to work around an issue with delayed
+        * BA frames in some implementations, but it has been found to fix ACK
+        * timeout issues in other cases as well.
+        */
+       if (conf->channel && conf->channel->band == IEEE80211_BAND_2GHZ)
+               acktimeout += 64 - sifstime - ah->slottime;
+
+       ath9k_hw_setslottime(ah, slottime);
+       ath9k_hw_set_ack_timeout(ah, acktimeout);
+       ath9k_hw_set_cts_timeout(ah, acktimeout);
        if (ah->globaltxtimeout != (u32) -1)
                ath9k_hw_set_global_txtimeout(ah, ah->globaltxtimeout);
 }
+EXPORT_SYMBOL(ath9k_hw_init_global_settings);
 
-const char *ath9k_hw_probe(u16 vendorid, u16 devid)
-{
-       return vendorid == ATHEROS_VENDOR_ID ?
-               ath9k_hw_devname(devid) : NULL;
-}
-
-void ath9k_hw_detach(struct ath_hw *ah)
+void ath9k_hw_deinit(struct ath_hw *ah)
 {
        struct ath_common *common = ath9k_hw_common(ah);
 
@@ -1291,7 +1271,7 @@ free_hw:
        kfree(ah);
        ah = NULL;
 }
-EXPORT_SYMBOL(ath9k_hw_detach);
+EXPORT_SYMBOL(ath9k_hw_deinit);
 
 /*******/
 /* INI */
@@ -1302,26 +1282,6 @@ static void ath9k_hw_override_ini(struct ath_hw *ah,
 {
        u32 val;
 
-       if (AR_SREV_9271(ah)) {
-               /*
-                * Enable spectral scan to solution for issues with stuck
-                * beacons on AR9271 1.0. The beacon stuck issue is not seeon on
-                * AR9271 1.1
-                */
-               if (AR_SREV_9271_10(ah)) {
-                       val = REG_READ(ah, AR_PHY_SPECTRAL_SCAN) |
-                             AR_PHY_SPECTRAL_SCAN_ENABLE;
-                       REG_WRITE(ah, AR_PHY_SPECTRAL_SCAN, val);
-               }
-               else if (AR_SREV_9271_11(ah))
-                       /*
-                        * change AR_PHY_RF_CTL3 setting to fix MAC issue
-                        * present on AR9271 1.1
-                        */
-                       REG_WRITE(ah, AR_PHY_RF_CTL3, 0x3a020001);
-               return;
-       }
-
        /*
         * Set the RX_ABORT and RX_DIS and clear if off only after
         * RXE is set for MAC. This prevents frames with corrupted
@@ -1330,8 +1290,10 @@ static void ath9k_hw_override_ini(struct ath_hw *ah,
        REG_SET_BIT(ah, AR_DIAG_SW, (AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT));
 
        if (AR_SREV_9280_10_OR_LATER(ah)) {
-               val = REG_READ(ah, AR_PCU_MISC_MODE2) &
-                              (~AR_PCU_MISC_MODE2_HWWAR1);
+               val = REG_READ(ah, AR_PCU_MISC_MODE2);
+
+               if (!AR_SREV_9271(ah))
+                       val &= ~AR_PCU_MISC_MODE2_HWWAR1;
 
                if (AR_SREV_9287_10_OR_LATER(ah))
                        val = val & (~AR_PCU_MISC_MODE2_HWWAR2);
@@ -1347,6 +1309,16 @@ static void ath9k_hw_override_ini(struct ath_hw *ah,
         * Necessary to avoid issues on AR5416 2.0
         */
        REG_WRITE(ah, 0x9800 + (651 << 2), 0x11);
+
+       /*
+        * Disable RIFS search on some chips to avoid baseband
+        * hang issues.
+        */
+       if (AR_SREV_9100(ah) || AR_SREV_9160(ah)) {
+               val = REG_READ(ah, AR_PHY_HEAVY_CLIP_FACTOR_RIFS);
+               val &= ~AR_PHY_RIFS_INIT_DELAY;
+               REG_WRITE(ah, AR_PHY_HEAVY_CLIP_FACTOR_RIFS, val);
+       }
 }
 
 static u32 ath9k_hw_def_ini_fixup(struct ath_hw *ah,
@@ -1465,7 +1437,10 @@ static int ath9k_hw_process_ini(struct ath_hw *ah,
                return -EINVAL;
        }
 
+       /* Set correct baseband to analog shift setting to access analog chips */
        REG_WRITE(ah, AR_PHY(0), 0x00000007);
+
+       /* Write ADDAC shifts */
        REG_WRITE(ah, AR_PHY_ADC_SERIAL_CTL, AR_PHY_SEL_EXTERNAL_RADIO);
        ah->eep_ops->set_addac(ah, chan);
 
@@ -1477,9 +1452,11 @@ static int ath9k_hw_process_ini(struct ath_hw *ah,
                        sizeof(u32) * ah->iniAddac.ia_rows *
                        ah->iniAddac.ia_columns;
 
+               /* For AR5416 2.0/2.1 */
                memcpy(ah->addac5416_21,
                       ah->iniAddac.ia_array, addacSize);
 
+               /* override CLKDRV value at [row, column] = [31, 1] */
                (ah->addac5416_21)[31 * ah->iniAddac.ia_columns + 1] = 0;
 
                temp.ia_array = ah->addac5416_21;
@@ -1511,6 +1488,11 @@ static int ath9k_hw_process_ini(struct ath_hw *ah,
            AR_SREV_9287_10_OR_LATER(ah))
                REG_WRITE_ARRAY(&ah->iniModesTxGain, modesIndex, regWrites);
 
+       if (AR_SREV_9271_10(ah))
+               REG_WRITE_ARRAY(&ah->iniModes_9271_1_0_only,
+                               modesIndex, regWrites);
+
+       /* Write common array parameters */
        for (i = 0; i < ah->iniCommon.ia_rows; i++) {
                u32 reg = INI_RA(&ah->iniCommon, i, 0);
                u32 val = INI_RA(&ah->iniCommon, i, 1);
@@ -1525,11 +1507,16 @@ static int ath9k_hw_process_ini(struct ath_hw *ah,
                DO_DELAY(regWrites);
        }
 
-       ath9k_hw_write_regs(ah, freqIndex, regWrites);
+       if (AR_SREV_9271(ah)) {
+               if (ah->eep_ops->get_eeprom(ah, EEP_TXGAIN_TYPE) == 1)
+                       REG_WRITE_ARRAY(&ah->iniModes_high_power_tx_gain_9271,
+                                       modesIndex, regWrites);
+               else
+                       REG_WRITE_ARRAY(&ah->iniModes_normal_power_tx_gain_9271,
+                                       modesIndex, regWrites);
+       }
 
-       if (AR_SREV_9271_10(ah))
-               REG_WRITE_ARRAY(&ah->iniModes_9271_1_0_only,
-                               modesIndex, regWrites);
+       ath9k_hw_write_regs(ah, freqIndex, regWrites);
 
        if (AR_SREV_9280_20(ah) && IS_CHAN_A_5MHZ_SPACED(chan)) {
                REG_WRITE_ARRAY(&ah->iniModesAdditional, modesIndex,
@@ -1543,6 +1530,7 @@ static int ath9k_hw_process_ini(struct ath_hw *ah,
        if (OLC_FOR_AR9280_20_LATER)
                ath9k_olc_init(ah);
 
+       /* Set TX power */
        ah->eep_ops->set_txpower(ah, chan,
                                 ath9k_regd_get_ctl(regulatory, chan),
                                 channel->max_antenna_gain * 2,
@@ -1550,6 +1538,7 @@ static int ath9k_hw_process_ini(struct ath_hw *ah,
                                 min((u32) MAX_RATE_POWER,
                                 (u32) regulatory->power_limit));
 
+       /* Write analog registers */
        if (!ath9k_hw_set_rf_regs(ah, chan, freqIndex)) {
                ath_print(ath9k_hw_common(ah), ATH_DBG_FATAL,
                          "ar5416SetRfRegs failed\n");
@@ -2056,9 +2045,6 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
        ah->ath9k_hw_spur_mitigate_freq(ah, chan);
        ah->eep_ops->set_board_values(ah, chan);
 
-       if (AR_SREV_5416(ah))
-               ath9k_hw_decrease_chain_power(ah, chan);
-
        REG_WRITE(ah, AR_STA_ID0, get_unaligned_le32(common->macaddr));
        REG_WRITE(ah, AR_STA_ID1, get_unaligned_le16(common->macaddr + 4)
                  | macStaId1
@@ -2095,7 +2081,7 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
        if (ah->caps.hw_caps & ATH9K_HW_CAP_RFSILENT)
                ath9k_enable_rfkill(ah);
 
-       ath9k_hw_init_user_settings(ah);
+       ath9k_hw_init_global_settings(ah);
 
        if (AR_SREV_9287_12_OR_LATER(ah)) {
                REG_WRITE(ah, AR_D_GBL_IFS_SIFS,
@@ -2125,7 +2111,7 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
 
        REG_WRITE(ah, AR_OBS, 8);
 
-       if (ah->config.intr_mitigation) {
+       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);
        }
@@ -2467,7 +2453,7 @@ static void ath9k_set_power_sleep(struct ath_hw *ah, int setChip)
                if (!AR_SREV_9100(ah))
                        REG_WRITE(ah, AR_RC, AR_RC_AHB | AR_RC_HOSTIF);
 
-               if(!AR_SREV_5416(ah))
+               if (!AR_SREV_5416(ah) && !AR_SREV_9271(ah))
                        REG_CLR_BIT(ah, (AR_RTC_RESET),
                                    AR_RTC_RESET_EN);
        }
@@ -2785,7 +2771,7 @@ bool ath9k_hw_getisr(struct ath_hw *ah, enum ath9k_int *masked)
 
                *masked = isr & ATH9K_INT_COMMON;
 
-               if (ah->config.intr_mitigation) {
+               if (ah->config.rx_intr_mitigation) {
                        if (isr & (AR_ISR_RXMINTR | AR_ISR_RXINTM))
                                *masked |= ATH9K_INT_RX;
                }
@@ -2918,7 +2904,7 @@ enum ath9k_int ath9k_hw_set_interrupts(struct ath_hw *ah, enum ath9k_int ints)
        }
        if (ints & ATH9K_INT_RX) {
                mask |= AR_IMR_RXERR;
-               if (ah->config.intr_mitigation)
+               if (ah->config.rx_intr_mitigation)
                        mask |= AR_IMR_RXMINTR | AR_IMR_RXINTM;
                else
                        mask |= AR_IMR_RXOK | AR_IMR_RXDESC;
@@ -2950,14 +2936,11 @@ enum ath9k_int ath9k_hw_set_interrupts(struct ath_hw *ah, enum ath9k_int ints)
 
        ath_print(common, ATH_DBG_INTERRUPT, "new IMR 0x%x\n", mask);
        REG_WRITE(ah, AR_IMR, mask);
-       mask = REG_READ(ah, AR_IMR_S2) & ~(AR_IMR_S2_TIM |
-                                          AR_IMR_S2_DTIM |
-                                          AR_IMR_S2_DTIMSYNC |
-                                          AR_IMR_S2_CABEND |
-                                          AR_IMR_S2_CABTO |
-                                          AR_IMR_S2_TSFOOR |
-                                          AR_IMR_S2_GTT | AR_IMR_S2_CST);
-       REG_WRITE(ah, AR_IMR_S2, mask | mask2);
+       ah->imrs2_reg &= ~(AR_IMR_S2_TIM | AR_IMR_S2_DTIM | AR_IMR_S2_DTIMSYNC |
+                          AR_IMR_S2_CABEND | AR_IMR_S2_CABTO |
+                          AR_IMR_S2_TSFOOR | AR_IMR_S2_GTT | AR_IMR_S2_CST);
+       ah->imrs2_reg |= mask2;
+       REG_WRITE(ah, AR_IMR_S2, ah->imrs2_reg);
        ah->mask_reg = ints;
 
        if (!(pCap->hw_caps & ATH9K_HW_CAP_AUTOSLEEP)) {
@@ -3119,7 +3102,7 @@ EXPORT_SYMBOL(ath9k_hw_set_sta_beacon_timers);
 /* HW Capabilities */
 /*******************/
 
-void ath9k_hw_fill_cap_info(struct ath_hw *ah)
+int ath9k_hw_fill_cap_info(struct ath_hw *ah)
 {
        struct ath9k_hw_capabilities *pCap = &ah->caps;
        struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah);
@@ -3150,6 +3133,12 @@ void ath9k_hw_fill_cap_info(struct ath_hw *ah)
        }
 
        eeval = ah->eep_ops->get_eeprom(ah, EEP_OP_MODE);
+       if ((eeval & (AR5416_OPFLAGS_11G | AR5416_OPFLAGS_11A)) == 0) {
+               ath_print(common, ATH_DBG_FATAL,
+                         "no band has been marked as supported in EEPROM.\n");
+               return -EINVAL;
+       }
+
        bitmap_zero(pCap->wireless_modes, ATH9K_MODE_MAX);
 
        if (eeval & AR5416_OPFLAGS_11A) {
@@ -3236,9 +3225,15 @@ void ath9k_hw_fill_cap_info(struct ath_hw *ah)
                pCap->keycache_size = AR_KEYTABLE_SIZE;
 
        pCap->hw_caps |= ATH9K_HW_CAP_FASTCC;
-       pCap->tx_triglevel_max = MAX_TX_FIFO_THRESHOLD;
 
-       if (AR_SREV_9285_10_OR_LATER(ah))
+       if (AR_SREV_9285(ah) || AR_SREV_9271(ah))
+               pCap->tx_triglevel_max = MAX_TX_FIFO_THRESHOLD >> 1;
+       else
+               pCap->tx_triglevel_max = MAX_TX_FIFO_THRESHOLD;
+
+       if (AR_SREV_9271(ah))
+               pCap->num_gpio_pins = AR9271_NUM_GPIO;
+       else if (AR_SREV_9285_10_OR_LATER(ah))
                pCap->num_gpio_pins = AR9285_NUM_GPIO;
        else if (AR_SREV_9280_10_OR_LATER(ah))
                pCap->num_gpio_pins = AR928X_NUM_GPIO;
@@ -3309,6 +3304,8 @@ void ath9k_hw_fill_cap_info(struct ath_hw *ah)
        } else {
                btcoex_hw->scheme = ATH_BTCOEX_CFG_NONE;
        }
+
+       return 0;
 }
 
 bool ath9k_hw_getcapability(struct ath_hw *ah, enum ath9k_capability_type type,
@@ -3472,7 +3469,9 @@ u32 ath9k_hw_gpio_get(struct ath_hw *ah, u32 gpio)
        if (gpio >= ah->caps.num_gpio_pins)
                return 0xffffffff;
 
-       if (AR_SREV_9287_10_OR_LATER(ah))
+       if (AR_SREV_9271(ah))
+               return MS_REG_READ(AR9271, gpio) != 0;
+       else if (AR_SREV_9287_10_OR_LATER(ah))
                return MS_REG_READ(AR9287, gpio) != 0;
        else if (AR_SREV_9285_10_OR_LATER(ah))
                return MS_REG_READ(AR9285, gpio) != 0;
@@ -3501,6 +3500,9 @@ EXPORT_SYMBOL(ath9k_hw_cfg_output);
 
 void ath9k_hw_set_gpio(struct ath_hw *ah, u32 gpio, u32 val)
 {
+       if (AR_SREV_9271(ah))
+               val = ~val;
+
        REG_RMW(ah, AR_GPIO_IN_OUT, ((val & 1) << gpio),
                AR_GPIO_BIT(gpio));
 }
@@ -3518,51 +3520,6 @@ void ath9k_hw_setantenna(struct ath_hw *ah, u32 antenna)
 }
 EXPORT_SYMBOL(ath9k_hw_setantenna);
 
-bool ath9k_hw_setantennaswitch(struct ath_hw *ah,
-                              enum ath9k_ant_setting settings,
-                              struct ath9k_channel *chan,
-                              u8 *tx_chainmask,
-                              u8 *rx_chainmask,
-                              u8 *antenna_cfgd)
-{
-       static u8 tx_chainmask_cfg, rx_chainmask_cfg;
-
-       if (AR_SREV_9280(ah)) {
-               if (!tx_chainmask_cfg) {
-
-                       tx_chainmask_cfg = *tx_chainmask;
-                       rx_chainmask_cfg = *rx_chainmask;
-               }
-
-               switch (settings) {
-               case ATH9K_ANT_FIXED_A:
-                       *tx_chainmask = ATH9K_ANTENNA0_CHAINMASK;
-                       *rx_chainmask = ATH9K_ANTENNA0_CHAINMASK;
-                       *antenna_cfgd = true;
-                       break;
-               case ATH9K_ANT_FIXED_B:
-                       if (ah->caps.tx_chainmask >
-                           ATH9K_ANTENNA1_CHAINMASK) {
-                               *tx_chainmask = ATH9K_ANTENNA1_CHAINMASK;
-                       }
-                       *rx_chainmask = ATH9K_ANTENNA1_CHAINMASK;
-                       *antenna_cfgd = true;
-                       break;
-               case ATH9K_ANT_VARIABLE:
-                       *tx_chainmask = tx_chainmask_cfg;
-                       *rx_chainmask = rx_chainmask_cfg;
-                       *antenna_cfgd = true;
-                       break;
-               default:
-                       break;
-               }
-       } else {
-               ah->config.diversity_control = settings;
-       }
-
-       return true;
-}
-
 /*********************/
 /* General Operation */
 /*********************/
@@ -3725,21 +3682,6 @@ u64 ath9k_hw_extend_tsf(struct ath_hw *ah, u32 rstamp)
 }
 EXPORT_SYMBOL(ath9k_hw_extend_tsf);
 
-bool ath9k_hw_setslottime(struct ath_hw *ah, u32 us)
-{
-       if (us < ATH9K_SLOT_TIME_9 || us > ath9k_hw_mac_to_usec(ah, 0xffff)) {
-               ath_print(ath9k_hw_common(ah), ATH_DBG_RESET,
-                         "bad slot time %u\n", us);
-               ah->slottime = (u32) -1;
-               return false;
-       } else {
-               REG_WRITE(ah, AR_D_GBL_IFS_SLOT, ath9k_hw_mac_to_clks(ah, us));
-               ah->slottime = us;
-               return true;
-       }
-}
-EXPORT_SYMBOL(ath9k_hw_setslottime);
-
 void ath9k_hw_set11nmac2040(struct ath_hw *ah)
 {
        struct ieee80211_conf *conf = &ath9k_hw_common(ah)->hw->conf;